haikuwebkit/LayoutTests/resources/ui-helper.js

1731 lines
56 KiB
JavaScript
Raw Permalink Normal View History

:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
window.UIHelper = class UIHelper {
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
static isIOSFamily()
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
return testRunner.isIOSFamily;
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
}
iOS: An element with tabindex is not focusable unless there is no mouse event handler https://bugs.webkit.org/show_bug.cgi?id=165843 Reviewed by Antti Koivisto. Source/WebCore: The bug was caused by ancestorRespondingToClickEvents not checking the precense of tabindex attribute. Check that condition along with event listeners. Test: fast/events/focusing-element-with-tabindex-by-tap-or-click.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): Tools: Add testRunner.isWebKit2 which is always true in WebKitTestRunner. Without this, it's really hard to reliably differentiate DumpRenderTree and WebKitTestRunner, and DumpRenderTree's runUIScript would hit an assertion :( * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isWebKit2): LayoutTests: Added a regression test for focusing an element with just tabindex using UIHelper. Also fixed UIHelper to work in iOS DumpRenderTree which was hitting an assertion by explicitly checking testRunner.isWebKit2. Prior to fixing this, it was hitting an assertion in RunLoop::main() which was asserting that there is a runloop, which doesn't exist in DumpRenderTree. * fast/events/focusing-element-with-tabindex-by-tap-or-click-expected.txt: Added. * fast/events/focusing-element-with-tabindex-by-tap-or-click.html: Added. * platform/ios-simulator-wk2/TestExpectations: * resources/ui-helper.js: (window.UIHelper.isWebKit2): (window.UIHelper.wait): Added the support for js-test.js / js-test-pre.js style tests. Canonical link: https://commits.webkit.org/183477@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209833 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-14 21:57:37 +00:00
static isWebKit2()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
return testRunner.isWebKit2;
iOS: An element with tabindex is not focusable unless there is no mouse event handler https://bugs.webkit.org/show_bug.cgi?id=165843 Reviewed by Antti Koivisto. Source/WebCore: The bug was caused by ancestorRespondingToClickEvents not checking the precense of tabindex attribute. Check that condition along with event listeners. Test: fast/events/focusing-element-with-tabindex-by-tap-or-click.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): Tools: Add testRunner.isWebKit2 which is always true in WebKitTestRunner. Without this, it's really hard to reliably differentiate DumpRenderTree and WebKitTestRunner, and DumpRenderTree's runUIScript would hit an assertion :( * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isWebKit2): LayoutTests: Added a regression test for focusing an element with just tabindex using UIHelper. Also fixed UIHelper to work in iOS DumpRenderTree which was hitting an assertion by explicitly checking testRunner.isWebKit2. Prior to fixing this, it was hitting an assertion in RunLoop::main() which was asserting that there is a runloop, which doesn't exist in DumpRenderTree. * fast/events/focusing-element-with-tabindex-by-tap-or-click-expected.txt: Added. * fast/events/focusing-element-with-tabindex-by-tap-or-click.html: Added. * platform/ios-simulator-wk2/TestExpectations: * resources/ui-helper.js: (window.UIHelper.isWebKit2): (window.UIHelper.wait): Added the support for js-test.js / js-test-pre.js style tests. Canonical link: https://commits.webkit.org/183477@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209833 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-14 21:57:37 +00:00
}
static doubleClickAt(x, y)
{
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
eventSender.mouseUp();
eventSender.mouseDown();
eventSender.mouseUp();
}
static doubleClickAtMouseDown(x1, y1)
{
eventSender.mouseMoveTo(x1, y1);
eventSender.mouseDown();
eventSender.mouseUp();
eventSender.mouseDown();
}
static mouseUp()
{
eventSender.mouseUp();
}
static doubleClickAtThenDragTo(x1, y1, x2, y2)
{
eventSender.mouseMoveTo(x1, y1);
eventSender.mouseDown();
eventSender.mouseUp();
eventSender.mouseDown();
eventSender.mouseMoveTo(x2, y2);
eventSender.mouseUp();
}
[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
static dragMouseAcrossElement(element)
{
const x1 = element.offsetLeft + element.offsetWidth;
const x2 = element.offsetLeft + element.offsetWidth * .75;
const x3 = element.offsetLeft + element.offsetWidth / 2;
const x4 = element.offsetLeft + element.offsetWidth / 4;
const x5 = element.offsetLeft;
const y = element.offsetTop + element.offsetHeight / 2;
eventSender.mouseMoveTo(x1, y);
eventSender.mouseMoveTo(x2, y);
eventSender.mouseMoveTo(x3, y);
eventSender.mouseMoveTo(x4, y);
eventSender.mouseMoveTo(x5, y);
}
static doubleClickElementMouseDown(element1)
{
const x1 = element1.offsetLeft + element1.offsetWidth / 2;
const y1 = element1.offsetTop + element1.offsetHeight / 2;
return UIHelper.doubleClickAtMouseDown(x1, y1);
}
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
static async moveMouseAndWaitForFrame(x, y)
{
eventSender.mouseMoveTo(x, y);
await UIHelper.animationFrame();
}
[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
static async mouseWheelScrollAt(x, y, beginX, beginY, deltaX, deltaY)
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
{
[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
if (beginX === undefined)
beginX = 0;
if (beginY === undefined)
beginY = -1;
if (deltaX === undefined)
deltaX = 0;
if (deltaY === undefined)
deltaY = -10;
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
eventSender.monitorWheelEvents();
eventSender.mouseMoveTo(x, y);
[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
eventSender.mouseScrollByWithWheelAndMomentumPhases(beginX, beginY, "began", "none");
eventSender.mouseScrollByWithWheelAndMomentumPhases(deltaX, deltaY, "changed", "none");
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
eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "ended", "none");
return new Promise(resolve => {
eventSender.callAfterScrollingCompletes(() => {
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
requestAnimationFrame(resolve);
});
});
}
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
static async mouseWheelMayBeginAt(x, y)
{
eventSender.mouseMoveTo(x, y);
eventSender.mouseScrollByWithWheelAndMomentumPhases(x, y, "maybegin", "none");
await UIHelper.animationFrame();
}
static async mouseWheelCancelAt(x, y)
{
eventSender.mouseMoveTo(x, y);
eventSender.mouseScrollByWithWheelAndMomentumPhases(x, y, "cancelled", "none");
await UIHelper.animationFrame();
}
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
static async waitForScrollCompletion()
{
return new Promise(resolve => {
eventSender.callAfterScrollingCompletes(() => {
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
requestAnimationFrame(resolve);
});
});
}
static async animationFrame()
{
return new Promise(requestAnimationFrame);
}
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
static async renderingUpdate()
{
await UIHelper.animationFrame();
await UIHelper.delayFor(0);
}
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
static async waitForCondition(conditionFunc)
{
while (!conditionFunc()) {
await UIHelper.animationFrame();
}
}
[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
static sendEventStream(eventStream)
{
const eventStreamAsString = JSON.stringify(eventStream);
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
uiController.sendEventStream(\`${eventStreamAsString}\`, () => {
uiController.uiScriptComplete();
});
})();
`, resolve);
});
}
[iOS] Mouse/Touch/Pointer events are missing modifier keys https://bugs.webkit.org/show_bug.cgi?id=191446 <rdar://problem/45929460> Reviewed by Tim Horton. Source/WebCore: Extract the modifier flags from the WebEvent. This code is only used by Legacy WebKit on iOS and we will need to fix <rdar://problem/47929759> in order for modifier flags to be passed to WebKit. Tests: fast/events/touch/ios/mouse-events-with-modifiers.html fast/events/touch/ios/pointer-events-with-modifiers.html fast/events/touch/ios/touch-events-with-modifiers.html * platform/ios/PlatformEventFactoryIOS.mm: (WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder): * platform/ios/WebEvent.h: * platform/ios/WebEvent.mm: (-[WebEvent initWithMouseEventType:timeStamp:location:]): (-[WebEvent initWithMouseEventType:timeStamp:location:modifiers:]): Source/WebKit: Make use of UIKit SPI to retreive the modifier flags when dispatching mouse and touch events. Add new WebKit SPI for iOS, -[WKNavigationAction modifierFlags], to retrieve the the modifier flags held when a navigation action was initiated. * Platform/spi/ios/UIKitSPI.h: Expose SPI. * Shared/NativeWebTouchEvent.h: Re-arrange macro guards so that we can expose the helper function WebKit::webEventModifierFlags(). This is a bit more involved that usual since this header is included from both C++ and Objective-C source files. It only makes sense to expose this function when compiling as part of an Objective-C source file. * Shared/ios/NativeWebTouchEventIOS.mm: (WebKit::NativeWebTouchEvent::NativeWebTouchEvent): Modified to take the modifier flags held down when the platform touch event was received and pass them through to the base constructor. (WebKit::webEventModifierFlags): Added. Converts from the platform-speciifc UIKeyModifierFlags to OptionSet<WebKit::WebEvent::Modifier>. * Shared/ios/WebIOSEventFactory.h: * Shared/ios/WebIOSEventFactory.mm: (WebIOSEventFactory::toUIKeyModifierFlags): Added. Converts from OptionSet<WebKit::WebEvent::Modifier> to the platform-specific UIKeyModifierFlags. * UIProcess/API/Cocoa/WKNavigationAction.mm: (-[WKNavigationAction modifierFlags]): Added. * UIProcess/API/Cocoa/WKNavigationActionPrivate.h: * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (gestureRecognizerModifierFlags): Added. (-[WKContentView _webTouchEventsRecognized:]): (-[WKContentView _highlightLongPressRecognized:]): (-[WKContentView _twoFingerSingleTapGestureRecognized:]): (-[WKContentView _singleTapCommited:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:modifierFlags:]): Added. (-[WKContentView actionSheetAssistant:openElementAtLocation:]): This is invoked when a person opens a link via the action sheet. We don't have access to the modifier flags to pass. It also seems like an implementation detail that this action is implemented via mouse click and we should re-evaluate this decision in light of the fact tht the action sheet is browser UI and we tend to be very reserved on what UI actions are visible to the page. On Mac, opening a link via the context menu is not visible to the page, at least from a mouse event perspective. (webEventFlagsForUIKeyModifierFlags): Added. (-[WKContentView _hoverGestureRecognizerChanged:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::handleTwoFingerTapAtPoint): (WebKit::WebPageProxy::commitPotentialTap): (WebKit::WebPageProxy::handleTap): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::handleSyntheticClick): (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver): (WebKit::WebPage::completeSyntheticClick): (WebKit::WebPage::handleTap): (WebKit::WebPage::handleTwoFingerTapAtPoint): (WebKit::WebPage::commitPotentialTap): Pass modifier flags through. Tools: Add support infrastructure for testing touch and stylus taps when holding modifier keys. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::arrayLength): (WTR::parseModifierArray): (WTR::UIScriptController::singleTapAtPoint): Implemented in terms of singleTapAtPointWithModifiers(). (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPoint): Implemented in terms of stylusTapAtPointWithModifiers(). (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. LayoutTests: Refactor existing iOS key events tests to share code. Add new tests to ensure touch and mouse events have accurate modifier key details. * fast/events/ios/key-events-meta-alt-combinations.html: * fast/events/ios/resources/key-tester.js: (computeSubsets.compareByModifierOrder): Deleted. * fast/events/resources/compute-subsets.js: Added. (computeSubsets.compareByOriginalArrayOrder): (computeSubsets): * fast/events/touch/ios/mouse-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/mouse-events-with-modifiers.html: Added. * fast/events/touch/ios/pointer-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/pointer-events-with-modifiers.html: Added. * fast/events/touch/ios/touch-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/touch-events-with-modifiers.html: Added. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Update expected result due to changes to ui-helper.js. * http/tests/security/anchor-download-block-crossorigin-expected.txt: Ditto. * platform/ios/TestExpectations: * resources/ui-helper.js: (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208941@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 23:24:23 +00:00
static tapAt(x, y, modifiers=[])
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
console.assert(this.isIOSFamily());
if (!this.isWebKit2()) {
[iOS] Mouse/Touch/Pointer events are missing modifier keys https://bugs.webkit.org/show_bug.cgi?id=191446 <rdar://problem/45929460> Reviewed by Tim Horton. Source/WebCore: Extract the modifier flags from the WebEvent. This code is only used by Legacy WebKit on iOS and we will need to fix <rdar://problem/47929759> in order for modifier flags to be passed to WebKit. Tests: fast/events/touch/ios/mouse-events-with-modifiers.html fast/events/touch/ios/pointer-events-with-modifiers.html fast/events/touch/ios/touch-events-with-modifiers.html * platform/ios/PlatformEventFactoryIOS.mm: (WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder): * platform/ios/WebEvent.h: * platform/ios/WebEvent.mm: (-[WebEvent initWithMouseEventType:timeStamp:location:]): (-[WebEvent initWithMouseEventType:timeStamp:location:modifiers:]): Source/WebKit: Make use of UIKit SPI to retreive the modifier flags when dispatching mouse and touch events. Add new WebKit SPI for iOS, -[WKNavigationAction modifierFlags], to retrieve the the modifier flags held when a navigation action was initiated. * Platform/spi/ios/UIKitSPI.h: Expose SPI. * Shared/NativeWebTouchEvent.h: Re-arrange macro guards so that we can expose the helper function WebKit::webEventModifierFlags(). This is a bit more involved that usual since this header is included from both C++ and Objective-C source files. It only makes sense to expose this function when compiling as part of an Objective-C source file. * Shared/ios/NativeWebTouchEventIOS.mm: (WebKit::NativeWebTouchEvent::NativeWebTouchEvent): Modified to take the modifier flags held down when the platform touch event was received and pass them through to the base constructor. (WebKit::webEventModifierFlags): Added. Converts from the platform-speciifc UIKeyModifierFlags to OptionSet<WebKit::WebEvent::Modifier>. * Shared/ios/WebIOSEventFactory.h: * Shared/ios/WebIOSEventFactory.mm: (WebIOSEventFactory::toUIKeyModifierFlags): Added. Converts from OptionSet<WebKit::WebEvent::Modifier> to the platform-specific UIKeyModifierFlags. * UIProcess/API/Cocoa/WKNavigationAction.mm: (-[WKNavigationAction modifierFlags]): Added. * UIProcess/API/Cocoa/WKNavigationActionPrivate.h: * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (gestureRecognizerModifierFlags): Added. (-[WKContentView _webTouchEventsRecognized:]): (-[WKContentView _highlightLongPressRecognized:]): (-[WKContentView _twoFingerSingleTapGestureRecognized:]): (-[WKContentView _singleTapCommited:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:modifierFlags:]): Added. (-[WKContentView actionSheetAssistant:openElementAtLocation:]): This is invoked when a person opens a link via the action sheet. We don't have access to the modifier flags to pass. It also seems like an implementation detail that this action is implemented via mouse click and we should re-evaluate this decision in light of the fact tht the action sheet is browser UI and we tend to be very reserved on what UI actions are visible to the page. On Mac, opening a link via the context menu is not visible to the page, at least from a mouse event perspective. (webEventFlagsForUIKeyModifierFlags): Added. (-[WKContentView _hoverGestureRecognizerChanged:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::handleTwoFingerTapAtPoint): (WebKit::WebPageProxy::commitPotentialTap): (WebKit::WebPageProxy::handleTap): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::handleSyntheticClick): (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver): (WebKit::WebPage::completeSyntheticClick): (WebKit::WebPage::handleTap): (WebKit::WebPage::handleTwoFingerTapAtPoint): (WebKit::WebPage::commitPotentialTap): Pass modifier flags through. Tools: Add support infrastructure for testing touch and stylus taps when holding modifier keys. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::arrayLength): (WTR::parseModifierArray): (WTR::UIScriptController::singleTapAtPoint): Implemented in terms of singleTapAtPointWithModifiers(). (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPoint): Implemented in terms of stylusTapAtPointWithModifiers(). (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. LayoutTests: Refactor existing iOS key events tests to share code. Add new tests to ensure touch and mouse events have accurate modifier key details. * fast/events/ios/key-events-meta-alt-combinations.html: * fast/events/ios/resources/key-tester.js: (computeSubsets.compareByModifierOrder): Deleted. * fast/events/resources/compute-subsets.js: Added. (computeSubsets.compareByOriginalArrayOrder): (computeSubsets): * fast/events/touch/ios/mouse-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/mouse-events-with-modifiers.html: Added. * fast/events/touch/ios/pointer-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/pointer-events-with-modifiers.html: Added. * fast/events/touch/ios/touch-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/touch-events-with-modifiers.html: Added. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Update expected result due to changes to ui-helper.js. * http/tests/security/anchor-download-block-crossorigin-expected.txt: Ditto. * platform/ios/TestExpectations: * resources/ui-helper.js: (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208941@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 23:24:23 +00:00
console.assert(!modifiers || !modifiers.length);
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
return Promise.resolve();
}
return new Promise((resolve) => {
testRunner.runUIScript(`
[iOS] Mouse/Touch/Pointer events are missing modifier keys https://bugs.webkit.org/show_bug.cgi?id=191446 <rdar://problem/45929460> Reviewed by Tim Horton. Source/WebCore: Extract the modifier flags from the WebEvent. This code is only used by Legacy WebKit on iOS and we will need to fix <rdar://problem/47929759> in order for modifier flags to be passed to WebKit. Tests: fast/events/touch/ios/mouse-events-with-modifiers.html fast/events/touch/ios/pointer-events-with-modifiers.html fast/events/touch/ios/touch-events-with-modifiers.html * platform/ios/PlatformEventFactoryIOS.mm: (WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder): * platform/ios/WebEvent.h: * platform/ios/WebEvent.mm: (-[WebEvent initWithMouseEventType:timeStamp:location:]): (-[WebEvent initWithMouseEventType:timeStamp:location:modifiers:]): Source/WebKit: Make use of UIKit SPI to retreive the modifier flags when dispatching mouse and touch events. Add new WebKit SPI for iOS, -[WKNavigationAction modifierFlags], to retrieve the the modifier flags held when a navigation action was initiated. * Platform/spi/ios/UIKitSPI.h: Expose SPI. * Shared/NativeWebTouchEvent.h: Re-arrange macro guards so that we can expose the helper function WebKit::webEventModifierFlags(). This is a bit more involved that usual since this header is included from both C++ and Objective-C source files. It only makes sense to expose this function when compiling as part of an Objective-C source file. * Shared/ios/NativeWebTouchEventIOS.mm: (WebKit::NativeWebTouchEvent::NativeWebTouchEvent): Modified to take the modifier flags held down when the platform touch event was received and pass them through to the base constructor. (WebKit::webEventModifierFlags): Added. Converts from the platform-speciifc UIKeyModifierFlags to OptionSet<WebKit::WebEvent::Modifier>. * Shared/ios/WebIOSEventFactory.h: * Shared/ios/WebIOSEventFactory.mm: (WebIOSEventFactory::toUIKeyModifierFlags): Added. Converts from OptionSet<WebKit::WebEvent::Modifier> to the platform-specific UIKeyModifierFlags. * UIProcess/API/Cocoa/WKNavigationAction.mm: (-[WKNavigationAction modifierFlags]): Added. * UIProcess/API/Cocoa/WKNavigationActionPrivate.h: * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (gestureRecognizerModifierFlags): Added. (-[WKContentView _webTouchEventsRecognized:]): (-[WKContentView _highlightLongPressRecognized:]): (-[WKContentView _twoFingerSingleTapGestureRecognized:]): (-[WKContentView _singleTapCommited:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:modifierFlags:]): Added. (-[WKContentView actionSheetAssistant:openElementAtLocation:]): This is invoked when a person opens a link via the action sheet. We don't have access to the modifier flags to pass. It also seems like an implementation detail that this action is implemented via mouse click and we should re-evaluate this decision in light of the fact tht the action sheet is browser UI and we tend to be very reserved on what UI actions are visible to the page. On Mac, opening a link via the context menu is not visible to the page, at least from a mouse event perspective. (webEventFlagsForUIKeyModifierFlags): Added. (-[WKContentView _hoverGestureRecognizerChanged:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::handleTwoFingerTapAtPoint): (WebKit::WebPageProxy::commitPotentialTap): (WebKit::WebPageProxy::handleTap): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::handleSyntheticClick): (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver): (WebKit::WebPage::completeSyntheticClick): (WebKit::WebPage::handleTap): (WebKit::WebPage::handleTwoFingerTapAtPoint): (WebKit::WebPage::commitPotentialTap): Pass modifier flags through. Tools: Add support infrastructure for testing touch and stylus taps when holding modifier keys. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::arrayLength): (WTR::parseModifierArray): (WTR::UIScriptController::singleTapAtPoint): Implemented in terms of singleTapAtPointWithModifiers(). (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPoint): Implemented in terms of stylusTapAtPointWithModifiers(). (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. LayoutTests: Refactor existing iOS key events tests to share code. Add new tests to ensure touch and mouse events have accurate modifier key details. * fast/events/ios/key-events-meta-alt-combinations.html: * fast/events/ios/resources/key-tester.js: (computeSubsets.compareByModifierOrder): Deleted. * fast/events/resources/compute-subsets.js: Added. (computeSubsets.compareByOriginalArrayOrder): (computeSubsets): * fast/events/touch/ios/mouse-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/mouse-events-with-modifiers.html: Added. * fast/events/touch/ios/pointer-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/pointer-events-with-modifiers.html: Added. * fast/events/touch/ios/touch-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/touch-events-with-modifiers.html: Added. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Update expected result due to changes to ui-helper.js. * http/tests/security/anchor-download-block-crossorigin-expected.txt: Ditto. * platform/ios/TestExpectations: * resources/ui-helper.js: (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208941@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 23:24:23 +00:00
uiController.singleTapAtPointWithModifiers(${x}, ${y}, ${JSON.stringify(modifiers)}, function() {
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
});`, resolve);
});
}
static tapElement(element, delay = 0)
{
const x = element.offsetLeft + (element.offsetWidth / 2);
const y = element.offsetTop + (element.offsetHeight / 2);
this.tapAt(x, y);
}
[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
static doubleTapElement(element, delay = 0)
{
const x = element.offsetLeft + (element.offsetWidth / 2);
const y = element.offsetTop + (element.offsetHeight / 2);
this.doubleTapAt(x, y, delay);
}
REGRESSION (iOS 13): Tests that simulate multiple back-to-back single taps fail or time out https://bugs.webkit.org/show_bug.cgi?id=201129 <rdar://problem/51857277> Reviewed by Tim Horton. Source/WebKit: Adds a new SPI hook in WebKit to let clients know when a synthetic tap gesture that has ended has been reset. See Tools/ChangeLog and LayoutTests/ChangeLog for more details. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _doAfterResettingSingleTapGesture:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _singleTapDidReset:]): (-[WKContentView _doAfterResettingSingleTapGesture:]): Tools: The tests in editing/pasteboard/ios were timing out on iOS 13 before this change. This is because they simulate back-to-back single taps; while this is recognized as two single taps on iOS 12 and prior, only the first single tap is recognized on iOS 13 (and the second is simply dropped on the floor). This occurs because the synthetic single tap gesture is reset slightly later on iOS 13 compared to iOS 12, so when the second tap is dispatched, the gesture recognizer is still in "ended" state after the first tap on iOS 13, which means the gesture isn't capable of recognizing further touches yet. In UIKit, a gesture recognizer is only reset once its UIGestureEnvironment's containing dependency subgraph no longer contains gestures that are active. In iOS 12, the synthetic click gesture is a part of a dependency subgraph that contains only itself and the normal (blocking) double tap gesture which requires the click to fail before it can be recognized; immediately after simulating the tap, both these gestures are inactive, which allows both of them to be reset. However, in iOS 13, the synthetic click gesture is part of a gesture dependency graph that contains the double tap for double click gesture, as well as the non-blocking double tap gesture, both of which are still active immediately after sending the first tap. This change in dependencies is caused by the introduction of UIUndoGestureInteraction's single and double three-finger tap gestures, which (in -[UIUndoGestureInteraction gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]) explicitly add all other taps as failure requirements. This effectively links the synthetic single tap gesture to most of the other gestures in WKContentView's dependency graph by way of these tap gestures for the undo interaction. All this means that there is now a short (~50 ms) delay after the synthetic single tap gestures is recognized, before it can be recognized again. To account for this new delay in our test infrastructure, simply wait for single tap gestures that have ended to reset before attempting to send subsequent single taps. We do this by introducing WebKit testing SPI to invoke a completion handler after resetting the synthetic click gesture (only if necessary - i.e., if the gesture is in ended state when we are about to begin simulating the tap). This allows calls to `UIScriptController::singleTapAtPoint` to be reliably recognized as single taps without requiring arbitrary 120 ms "human speed" delays. This fixes a number of flaky or failing layout tests, including the tests in editing/pasteboard/ios. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::doubleTapAtPoint): Add a `delay` parameter to `doubleTapAtPoint`. A number of layout tests were actually simulating double click gestures by simulating two back-to-back single taps; this is done for the purposes of being able to add a "human speed" delay prior to the second single tap gesture. After the change to wait for the single tap gesture to reset before attempting to simulate the next tap, this strategy no longer works, since the second gesture is recognized only as a single tap instead of a double tap. Instead, we add a delay parameter to `UIScriptController::doubleTapAtPoint`, which the "human speed" double tap gestures use instead to wait after simulating the first tap. * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (-[HIDEventGenerator _waitFor:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:delay:completionBlock:]): Plumb the tap gesture delay through to this helper method. (-[HIDEventGenerator tap:completionBlock:]): (-[HIDEventGenerator doubleTap:delay:completionBlock:]): (-[HIDEventGenerator twoFingerTap:completionBlock:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:completionBlock:]): Deleted. (-[HIDEventGenerator doubleTap:completionBlock:]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::waitForSingleTapToReset const): Add a new helper to wait for the content view's single tap gesture to reset if needed; call this before attempting to simulate single taps (either using a stylus, or with a regular touch). (WTR::UIScriptControllerIOS::singleTapAtPointWithModifiers): (WTR::UIScriptControllerIOS::doubleTapAtPoint): (WTR::UIScriptControllerIOS::stylusTapAtPointWithModifiers): LayoutTests: Adjusts a few layout tests after changes to UIScriptController::doubleTapAtPoint and UIScriptController::singleTapAtPoint. * editing/selection/ios/change-selection-by-tapping.html: Tweak this test to tap the page 12 times instead of 20 (which seems to cause occasional timeouts locally, when running all layout tests with a dozen active simulators). * fast/events/ios/double-tap-zoom.html: * fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html: * fast/events/ios/viewport-shrink-to-fit-allows-double-tap.html: Augment a few call sites of `doubleTapAtPoint` with a 0 delay. Ideally, these should just use ui-helper.js, but we can refactor these tests as a part of folding basic-gestures.js into ui-helper.js. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: * http/tests/security/anchor-download-block-crossorigin-expected.txt: Rebaseline these layout tests, due to change in line numbers. * platform/ipad/TestExpectations: Unskip these tests on iPad, now that they should pass. * pointerevents/utils.js: (const.ui.new.UIController.prototype.doubleTapToZoom): * resources/basic-gestures.js: (return.new.Promise.): (return.new.Promise): Adjust some more call sites of `doubleTapAtPoint`. Ideally, these should use just `ui-helper.js` too. * resources/ui-helper.js: (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): Add a delay parameter to `doubleTapAt` to specify a delay after each simulated tap. By default, this is 0, but the `humanSpeed*` helpers add a delay of 120 milliseconds. Additionally, these helpers were previously calling `singleTapAtPoint` twice, with a timeout in between to add a delay. Instead, call `doubleTapAtPoint` with a nonzero delay; otherwise, we'll end up waiting in `singleTapAtPoint` for the gesture subgraph containing both the double tap gestures and the synthetic single tap gesture to reset, which causes these two single taps to no longer be recognized as a double tap gesture. (window.UIHelper.zoomByDoubleTappingAt): Canonical link: https://commits.webkit.org/214834@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-26 19:37:29 +00:00
static doubleTapAt(x, y, delay = 0)
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
console.assert(this.isIOSFamily());
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
if (!this.isWebKit2()) {
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
return Promise.resolve();
}
return new Promise((resolve) => {
testRunner.runUIScript(`
REGRESSION (iOS 13): Tests that simulate multiple back-to-back single taps fail or time out https://bugs.webkit.org/show_bug.cgi?id=201129 <rdar://problem/51857277> Reviewed by Tim Horton. Source/WebKit: Adds a new SPI hook in WebKit to let clients know when a synthetic tap gesture that has ended has been reset. See Tools/ChangeLog and LayoutTests/ChangeLog for more details. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _doAfterResettingSingleTapGesture:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _singleTapDidReset:]): (-[WKContentView _doAfterResettingSingleTapGesture:]): Tools: The tests in editing/pasteboard/ios were timing out on iOS 13 before this change. This is because they simulate back-to-back single taps; while this is recognized as two single taps on iOS 12 and prior, only the first single tap is recognized on iOS 13 (and the second is simply dropped on the floor). This occurs because the synthetic single tap gesture is reset slightly later on iOS 13 compared to iOS 12, so when the second tap is dispatched, the gesture recognizer is still in "ended" state after the first tap on iOS 13, which means the gesture isn't capable of recognizing further touches yet. In UIKit, a gesture recognizer is only reset once its UIGestureEnvironment's containing dependency subgraph no longer contains gestures that are active. In iOS 12, the synthetic click gesture is a part of a dependency subgraph that contains only itself and the normal (blocking) double tap gesture which requires the click to fail before it can be recognized; immediately after simulating the tap, both these gestures are inactive, which allows both of them to be reset. However, in iOS 13, the synthetic click gesture is part of a gesture dependency graph that contains the double tap for double click gesture, as well as the non-blocking double tap gesture, both of which are still active immediately after sending the first tap. This change in dependencies is caused by the introduction of UIUndoGestureInteraction's single and double three-finger tap gestures, which (in -[UIUndoGestureInteraction gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]) explicitly add all other taps as failure requirements. This effectively links the synthetic single tap gesture to most of the other gestures in WKContentView's dependency graph by way of these tap gestures for the undo interaction. All this means that there is now a short (~50 ms) delay after the synthetic single tap gestures is recognized, before it can be recognized again. To account for this new delay in our test infrastructure, simply wait for single tap gestures that have ended to reset before attempting to send subsequent single taps. We do this by introducing WebKit testing SPI to invoke a completion handler after resetting the synthetic click gesture (only if necessary - i.e., if the gesture is in ended state when we are about to begin simulating the tap). This allows calls to `UIScriptController::singleTapAtPoint` to be reliably recognized as single taps without requiring arbitrary 120 ms "human speed" delays. This fixes a number of flaky or failing layout tests, including the tests in editing/pasteboard/ios. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::doubleTapAtPoint): Add a `delay` parameter to `doubleTapAtPoint`. A number of layout tests were actually simulating double click gestures by simulating two back-to-back single taps; this is done for the purposes of being able to add a "human speed" delay prior to the second single tap gesture. After the change to wait for the single tap gesture to reset before attempting to simulate the next tap, this strategy no longer works, since the second gesture is recognized only as a single tap instead of a double tap. Instead, we add a delay parameter to `UIScriptController::doubleTapAtPoint`, which the "human speed" double tap gestures use instead to wait after simulating the first tap. * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (-[HIDEventGenerator _waitFor:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:delay:completionBlock:]): Plumb the tap gesture delay through to this helper method. (-[HIDEventGenerator tap:completionBlock:]): (-[HIDEventGenerator doubleTap:delay:completionBlock:]): (-[HIDEventGenerator twoFingerTap:completionBlock:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:completionBlock:]): Deleted. (-[HIDEventGenerator doubleTap:completionBlock:]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::waitForSingleTapToReset const): Add a new helper to wait for the content view's single tap gesture to reset if needed; call this before attempting to simulate single taps (either using a stylus, or with a regular touch). (WTR::UIScriptControllerIOS::singleTapAtPointWithModifiers): (WTR::UIScriptControllerIOS::doubleTapAtPoint): (WTR::UIScriptControllerIOS::stylusTapAtPointWithModifiers): LayoutTests: Adjusts a few layout tests after changes to UIScriptController::doubleTapAtPoint and UIScriptController::singleTapAtPoint. * editing/selection/ios/change-selection-by-tapping.html: Tweak this test to tap the page 12 times instead of 20 (which seems to cause occasional timeouts locally, when running all layout tests with a dozen active simulators). * fast/events/ios/double-tap-zoom.html: * fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html: * fast/events/ios/viewport-shrink-to-fit-allows-double-tap.html: Augment a few call sites of `doubleTapAtPoint` with a 0 delay. Ideally, these should just use ui-helper.js, but we can refactor these tests as a part of folding basic-gestures.js into ui-helper.js. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: * http/tests/security/anchor-download-block-crossorigin-expected.txt: Rebaseline these layout tests, due to change in line numbers. * platform/ipad/TestExpectations: Unskip these tests on iPad, now that they should pass. * pointerevents/utils.js: (const.ui.new.UIController.prototype.doubleTapToZoom): * resources/basic-gestures.js: (return.new.Promise.): (return.new.Promise): Adjust some more call sites of `doubleTapAtPoint`. Ideally, these should use just `ui-helper.js` too. * resources/ui-helper.js: (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): Add a delay parameter to `doubleTapAt` to specify a delay after each simulated tap. By default, this is 0, but the `humanSpeed*` helpers add a delay of 120 milliseconds. Additionally, these helpers were previously calling `singleTapAtPoint` twice, with a timeout in between to add a delay. Instead, call `doubleTapAtPoint` with a nonzero delay; otherwise, we'll end up waiting in `singleTapAtPoint` for the gesture subgraph containing both the double tap gestures and the synthetic single tap gesture to reset, which causes these two single taps to no longer be recognized as a double tap gesture. (window.UIHelper.zoomByDoubleTappingAt): Canonical link: https://commits.webkit.org/214834@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-26 19:37:29 +00:00
uiController.doubleTapAtPoint(${x}, ${y}, ${delay}, function() {
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
});`, resolve);
});
}
[iOS] Implement a faster click detection that intercepts double-tap-to-zoom if possible https://bugs.webkit.org/show_bug.cgi?id=195473 <rdar://problem/48718396> Reviewed by Wenson Hsieh (with some help from Dan Bates). Source/WebKit: Adds a new algorithm, behind a flag FasterClicksEnabled, that can trigger a click event without waiting to see if a double tap will occur. It does this by examining the amount of zoom that would be triggered if it was a double tap, and if that value doesn't exceed a set threshold, commits to the click event instead. This is implemented by having the Web Process respond to the potential click with some geometry information. If the UI Process receives the information before the second tap in a double tap, it can decide to trigger a click. * Shared/WebPreferences.yaml: New internal feature so this can be toggled in a UI for testing. * SourcesCocoa.txt: Renamed WKSyntheticTapGestureRecognizer. * WebKit.xcodeproj/project.pbxproj: Ditto. * UIProcess/ios/WKSyntheticTapGestureRecognizer.h: * UIProcess/ios/WKSyntheticTapGestureRecognizer.m: (-[WKSyntheticTapGestureRecognizer setGestureIdentifiedTarget:action:]): (-[WKSyntheticTapGestureRecognizer setGestureFailedTarget:action:]): (-[WKSyntheticTapGestureRecognizer setResetTarget:action:]): (-[WKSyntheticTapGestureRecognizer setState:]): (-[WKSyntheticTapGestureRecognizer reset]): Renamed WKSyntheticClickTapGestureRecognizer to WKSyntheticTapGestureRecognizer, changed the signature of the main function to be a bit more clear about what it does, and added a gesture failed target. * UIProcess/API/Cocoa/WKWebViewInternal.h: * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _initialScaleFactor]): (-[WKWebView _contentZoomScale]): (-[WKWebView _targetContentZoomScaleForRect:currentScale:fitEntireRect:minimumScale:maximumScale:]): Exposed the initial content scale, the current scale and added a declaration that was missing from the .h. * UIProcess/WebPageProxy.messages.in: Add a new message, HandleSmartMagnificationInformationForPotentialTap, to communicate the geometry of the clicked node to the UI Process. * UIProcess/PageClient.h: Pure virtual function for the geometry message response. * UIProcess/WebPageProxy.h: Ditto. * UIProcess/ios/PageClientImplIOS.h: Calls into the WKContentView. * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::handleSmartMagnificationInformationForPotentialTap): * UIProcess/ios/SmartMagnificationController.h: * UIProcess/ios/SmartMagnificationController.mm: (WebKit::SmartMagnificationController::calculatePotentialZoomParameters): A new method that asks the WKContentView to work out what the zoom factor will be for a potential double tap at a location. (WebKit::SmartMagnificationController::smartMagnificationTargetRectAndZoomScales): New implementation of this function to avoid multiple out-arguments. * UIProcess/ios/WKContentView.h: * UIProcess/ios/WKContentView.mm: (-[WKContentView _initialScaleFactor]): (-[WKContentView _contentZoomScale]): (-[WKContentView _targetContentZoomScaleForRect:currentScale:fitEntireRect:minimumScale:maximumScale:]): Exposed the initial content scale, the current scale and the target zoom scale. These all just call into the WKWebView implementation. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _createAndConfigureDoubleTapGestureRecognizer]): Use a WKSyntheticTapGestureRecognizer instead of a generic one, so we can capture the failure. (-[WKContentView setupInteraction]): (-[WKContentView cleanupInteraction]): (-[WKContentView _handleSmartMagnificationInformationForPotentialTap:origin:renderRect:fitEntireRect:viewportMinimumScale:viewportMaximumScale:]): New method that responds to the incoming Web Process message, and decides if any potential zoom would be "significant". (-[WKContentView _singleTapIdentified:]): (-[WKContentView _doubleTapDidFail:]): (-[WKContentView _didCompleteSyntheticClick]): (-[WKContentView _singleTapRecognized:]): (-[WKContentView _doubleTapRecognized:]): Add some release logging. (-[WKContentView _singleTapCommited:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::potentialTapAtPosition): (WebKit::WebPageProxy::handleSmartMagnificationInformationForPotentialTap): * WebProcess/WebPage/ViewGestureGeometryCollector.h: * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Removed an unused parameter from the existing message. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::potentialTapAtPosition): Calculates the geometry of the element if requested, and sends it to the UIProcess. LayoutTests: Implement a test (iPad only) that sets up a page with zoomable content but not quite at a significant scale, meaning we should dispatch a click event rather than Double Tap To Zoom. In order to do this, a humanSpeedDoubleTapAt() method was added to UIHelper that sleeps a bit between taps, otherwise the double tap gesture is recognized before the Web Process has had a chance to evaluate the potential click. * fast/events/ios/ipad/fast-click-double-tap-sends-click-on-insignificant-zoom-expected.txt: Added. * fast/events/ios/ipad/fast-click-double-tap-sends-click-on-insignificant-zoom.html: Added. * platform/ios/TestExpectations: * platform/ipad/TestExpectations: * resources/ui-helper.js: (window.UIHelper.humanSpeedDoubleTapAt): Canonical link: https://commits.webkit.org/209887@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242757 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-03-11 23:43:04 +00:00
static humanSpeedDoubleTapAt(x, y)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
console.assert(this.isIOSFamily());
[iOS] Implement a faster click detection that intercepts double-tap-to-zoom if possible https://bugs.webkit.org/show_bug.cgi?id=195473 <rdar://problem/48718396> Reviewed by Wenson Hsieh (with some help from Dan Bates). Source/WebKit: Adds a new algorithm, behind a flag FasterClicksEnabled, that can trigger a click event without waiting to see if a double tap will occur. It does this by examining the amount of zoom that would be triggered if it was a double tap, and if that value doesn't exceed a set threshold, commits to the click event instead. This is implemented by having the Web Process respond to the potential click with some geometry information. If the UI Process receives the information before the second tap in a double tap, it can decide to trigger a click. * Shared/WebPreferences.yaml: New internal feature so this can be toggled in a UI for testing. * SourcesCocoa.txt: Renamed WKSyntheticTapGestureRecognizer. * WebKit.xcodeproj/project.pbxproj: Ditto. * UIProcess/ios/WKSyntheticTapGestureRecognizer.h: * UIProcess/ios/WKSyntheticTapGestureRecognizer.m: (-[WKSyntheticTapGestureRecognizer setGestureIdentifiedTarget:action:]): (-[WKSyntheticTapGestureRecognizer setGestureFailedTarget:action:]): (-[WKSyntheticTapGestureRecognizer setResetTarget:action:]): (-[WKSyntheticTapGestureRecognizer setState:]): (-[WKSyntheticTapGestureRecognizer reset]): Renamed WKSyntheticClickTapGestureRecognizer to WKSyntheticTapGestureRecognizer, changed the signature of the main function to be a bit more clear about what it does, and added a gesture failed target. * UIProcess/API/Cocoa/WKWebViewInternal.h: * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _initialScaleFactor]): (-[WKWebView _contentZoomScale]): (-[WKWebView _targetContentZoomScaleForRect:currentScale:fitEntireRect:minimumScale:maximumScale:]): Exposed the initial content scale, the current scale and added a declaration that was missing from the .h. * UIProcess/WebPageProxy.messages.in: Add a new message, HandleSmartMagnificationInformationForPotentialTap, to communicate the geometry of the clicked node to the UI Process. * UIProcess/PageClient.h: Pure virtual function for the geometry message response. * UIProcess/WebPageProxy.h: Ditto. * UIProcess/ios/PageClientImplIOS.h: Calls into the WKContentView. * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::handleSmartMagnificationInformationForPotentialTap): * UIProcess/ios/SmartMagnificationController.h: * UIProcess/ios/SmartMagnificationController.mm: (WebKit::SmartMagnificationController::calculatePotentialZoomParameters): A new method that asks the WKContentView to work out what the zoom factor will be for a potential double tap at a location. (WebKit::SmartMagnificationController::smartMagnificationTargetRectAndZoomScales): New implementation of this function to avoid multiple out-arguments. * UIProcess/ios/WKContentView.h: * UIProcess/ios/WKContentView.mm: (-[WKContentView _initialScaleFactor]): (-[WKContentView _contentZoomScale]): (-[WKContentView _targetContentZoomScaleForRect:currentScale:fitEntireRect:minimumScale:maximumScale:]): Exposed the initial content scale, the current scale and the target zoom scale. These all just call into the WKWebView implementation. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _createAndConfigureDoubleTapGestureRecognizer]): Use a WKSyntheticTapGestureRecognizer instead of a generic one, so we can capture the failure. (-[WKContentView setupInteraction]): (-[WKContentView cleanupInteraction]): (-[WKContentView _handleSmartMagnificationInformationForPotentialTap:origin:renderRect:fitEntireRect:viewportMinimumScale:viewportMaximumScale:]): New method that responds to the incoming Web Process message, and decides if any potential zoom would be "significant". (-[WKContentView _singleTapIdentified:]): (-[WKContentView _doubleTapDidFail:]): (-[WKContentView _didCompleteSyntheticClick]): (-[WKContentView _singleTapRecognized:]): (-[WKContentView _doubleTapRecognized:]): Add some release logging. (-[WKContentView _singleTapCommited:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::potentialTapAtPosition): (WebKit::WebPageProxy::handleSmartMagnificationInformationForPotentialTap): * WebProcess/WebPage/ViewGestureGeometryCollector.h: * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Removed an unused parameter from the existing message. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::potentialTapAtPosition): Calculates the geometry of the element if requested, and sends it to the UIProcess. LayoutTests: Implement a test (iPad only) that sets up a page with zoomable content but not quite at a significant scale, meaning we should dispatch a click event rather than Double Tap To Zoom. In order to do this, a humanSpeedDoubleTapAt() method was added to UIHelper that sleeps a bit between taps, otherwise the double tap gesture is recognized before the Web Process has had a chance to evaluate the potential click. * fast/events/ios/ipad/fast-click-double-tap-sends-click-on-insignificant-zoom-expected.txt: Added. * fast/events/ios/ipad/fast-click-double-tap-sends-click-on-insignificant-zoom.html: Added. * platform/ios/TestExpectations: * platform/ipad/TestExpectations: * resources/ui-helper.js: (window.UIHelper.humanSpeedDoubleTapAt): Canonical link: https://commits.webkit.org/209887@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242757 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-03-11 23:43:04 +00:00
if (!this.isWebKit2()) {
// FIXME: Add a sleep in here.
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
return Promise.resolve();
}
REGRESSION (iOS 13): Tests that simulate multiple back-to-back single taps fail or time out https://bugs.webkit.org/show_bug.cgi?id=201129 <rdar://problem/51857277> Reviewed by Tim Horton. Source/WebKit: Adds a new SPI hook in WebKit to let clients know when a synthetic tap gesture that has ended has been reset. See Tools/ChangeLog and LayoutTests/ChangeLog for more details. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _doAfterResettingSingleTapGesture:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _singleTapDidReset:]): (-[WKContentView _doAfterResettingSingleTapGesture:]): Tools: The tests in editing/pasteboard/ios were timing out on iOS 13 before this change. This is because they simulate back-to-back single taps; while this is recognized as two single taps on iOS 12 and prior, only the first single tap is recognized on iOS 13 (and the second is simply dropped on the floor). This occurs because the synthetic single tap gesture is reset slightly later on iOS 13 compared to iOS 12, so when the second tap is dispatched, the gesture recognizer is still in "ended" state after the first tap on iOS 13, which means the gesture isn't capable of recognizing further touches yet. In UIKit, a gesture recognizer is only reset once its UIGestureEnvironment's containing dependency subgraph no longer contains gestures that are active. In iOS 12, the synthetic click gesture is a part of a dependency subgraph that contains only itself and the normal (blocking) double tap gesture which requires the click to fail before it can be recognized; immediately after simulating the tap, both these gestures are inactive, which allows both of them to be reset. However, in iOS 13, the synthetic click gesture is part of a gesture dependency graph that contains the double tap for double click gesture, as well as the non-blocking double tap gesture, both of which are still active immediately after sending the first tap. This change in dependencies is caused by the introduction of UIUndoGestureInteraction's single and double three-finger tap gestures, which (in -[UIUndoGestureInteraction gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]) explicitly add all other taps as failure requirements. This effectively links the synthetic single tap gesture to most of the other gestures in WKContentView's dependency graph by way of these tap gestures for the undo interaction. All this means that there is now a short (~50 ms) delay after the synthetic single tap gestures is recognized, before it can be recognized again. To account for this new delay in our test infrastructure, simply wait for single tap gestures that have ended to reset before attempting to send subsequent single taps. We do this by introducing WebKit testing SPI to invoke a completion handler after resetting the synthetic click gesture (only if necessary - i.e., if the gesture is in ended state when we are about to begin simulating the tap). This allows calls to `UIScriptController::singleTapAtPoint` to be reliably recognized as single taps without requiring arbitrary 120 ms "human speed" delays. This fixes a number of flaky or failing layout tests, including the tests in editing/pasteboard/ios. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::doubleTapAtPoint): Add a `delay` parameter to `doubleTapAtPoint`. A number of layout tests were actually simulating double click gestures by simulating two back-to-back single taps; this is done for the purposes of being able to add a "human speed" delay prior to the second single tap gesture. After the change to wait for the single tap gesture to reset before attempting to simulate the next tap, this strategy no longer works, since the second gesture is recognized only as a single tap instead of a double tap. Instead, we add a delay parameter to `UIScriptController::doubleTapAtPoint`, which the "human speed" double tap gestures use instead to wait after simulating the first tap. * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (-[HIDEventGenerator _waitFor:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:delay:completionBlock:]): Plumb the tap gesture delay through to this helper method. (-[HIDEventGenerator tap:completionBlock:]): (-[HIDEventGenerator doubleTap:delay:completionBlock:]): (-[HIDEventGenerator twoFingerTap:completionBlock:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:completionBlock:]): Deleted. (-[HIDEventGenerator doubleTap:completionBlock:]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::waitForSingleTapToReset const): Add a new helper to wait for the content view's single tap gesture to reset if needed; call this before attempting to simulate single taps (either using a stylus, or with a regular touch). (WTR::UIScriptControllerIOS::singleTapAtPointWithModifiers): (WTR::UIScriptControllerIOS::doubleTapAtPoint): (WTR::UIScriptControllerIOS::stylusTapAtPointWithModifiers): LayoutTests: Adjusts a few layout tests after changes to UIScriptController::doubleTapAtPoint and UIScriptController::singleTapAtPoint. * editing/selection/ios/change-selection-by-tapping.html: Tweak this test to tap the page 12 times instead of 20 (which seems to cause occasional timeouts locally, when running all layout tests with a dozen active simulators). * fast/events/ios/double-tap-zoom.html: * fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html: * fast/events/ios/viewport-shrink-to-fit-allows-double-tap.html: Augment a few call sites of `doubleTapAtPoint` with a 0 delay. Ideally, these should just use ui-helper.js, but we can refactor these tests as a part of folding basic-gestures.js into ui-helper.js. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: * http/tests/security/anchor-download-block-crossorigin-expected.txt: Rebaseline these layout tests, due to change in line numbers. * platform/ipad/TestExpectations: Unskip these tests on iPad, now that they should pass. * pointerevents/utils.js: (const.ui.new.UIController.prototype.doubleTapToZoom): * resources/basic-gestures.js: (return.new.Promise.): (return.new.Promise): Adjust some more call sites of `doubleTapAtPoint`. Ideally, these should use just `ui-helper.js` too. * resources/ui-helper.js: (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): Add a delay parameter to `doubleTapAt` to specify a delay after each simulated tap. By default, this is 0, but the `humanSpeed*` helpers add a delay of 120 milliseconds. Additionally, these helpers were previously calling `singleTapAtPoint` twice, with a timeout in between to add a delay. Instead, call `doubleTapAtPoint` with a nonzero delay; otherwise, we'll end up waiting in `singleTapAtPoint` for the gesture subgraph containing both the double tap gestures and the synthetic single tap gesture to reset, which causes these two single taps to no longer be recognized as a double tap gesture. (window.UIHelper.zoomByDoubleTappingAt): Canonical link: https://commits.webkit.org/214834@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-26 19:37:29 +00:00
return UIHelper.doubleTapAt(x, y, 0.12);
[iOS] Implement a faster click detection that intercepts double-tap-to-zoom if possible https://bugs.webkit.org/show_bug.cgi?id=195473 <rdar://problem/48718396> Reviewed by Wenson Hsieh (with some help from Dan Bates). Source/WebKit: Adds a new algorithm, behind a flag FasterClicksEnabled, that can trigger a click event without waiting to see if a double tap will occur. It does this by examining the amount of zoom that would be triggered if it was a double tap, and if that value doesn't exceed a set threshold, commits to the click event instead. This is implemented by having the Web Process respond to the potential click with some geometry information. If the UI Process receives the information before the second tap in a double tap, it can decide to trigger a click. * Shared/WebPreferences.yaml: New internal feature so this can be toggled in a UI for testing. * SourcesCocoa.txt: Renamed WKSyntheticTapGestureRecognizer. * WebKit.xcodeproj/project.pbxproj: Ditto. * UIProcess/ios/WKSyntheticTapGestureRecognizer.h: * UIProcess/ios/WKSyntheticTapGestureRecognizer.m: (-[WKSyntheticTapGestureRecognizer setGestureIdentifiedTarget:action:]): (-[WKSyntheticTapGestureRecognizer setGestureFailedTarget:action:]): (-[WKSyntheticTapGestureRecognizer setResetTarget:action:]): (-[WKSyntheticTapGestureRecognizer setState:]): (-[WKSyntheticTapGestureRecognizer reset]): Renamed WKSyntheticClickTapGestureRecognizer to WKSyntheticTapGestureRecognizer, changed the signature of the main function to be a bit more clear about what it does, and added a gesture failed target. * UIProcess/API/Cocoa/WKWebViewInternal.h: * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _initialScaleFactor]): (-[WKWebView _contentZoomScale]): (-[WKWebView _targetContentZoomScaleForRect:currentScale:fitEntireRect:minimumScale:maximumScale:]): Exposed the initial content scale, the current scale and added a declaration that was missing from the .h. * UIProcess/WebPageProxy.messages.in: Add a new message, HandleSmartMagnificationInformationForPotentialTap, to communicate the geometry of the clicked node to the UI Process. * UIProcess/PageClient.h: Pure virtual function for the geometry message response. * UIProcess/WebPageProxy.h: Ditto. * UIProcess/ios/PageClientImplIOS.h: Calls into the WKContentView. * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::handleSmartMagnificationInformationForPotentialTap): * UIProcess/ios/SmartMagnificationController.h: * UIProcess/ios/SmartMagnificationController.mm: (WebKit::SmartMagnificationController::calculatePotentialZoomParameters): A new method that asks the WKContentView to work out what the zoom factor will be for a potential double tap at a location. (WebKit::SmartMagnificationController::smartMagnificationTargetRectAndZoomScales): New implementation of this function to avoid multiple out-arguments. * UIProcess/ios/WKContentView.h: * UIProcess/ios/WKContentView.mm: (-[WKContentView _initialScaleFactor]): (-[WKContentView _contentZoomScale]): (-[WKContentView _targetContentZoomScaleForRect:currentScale:fitEntireRect:minimumScale:maximumScale:]): Exposed the initial content scale, the current scale and the target zoom scale. These all just call into the WKWebView implementation. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _createAndConfigureDoubleTapGestureRecognizer]): Use a WKSyntheticTapGestureRecognizer instead of a generic one, so we can capture the failure. (-[WKContentView setupInteraction]): (-[WKContentView cleanupInteraction]): (-[WKContentView _handleSmartMagnificationInformationForPotentialTap:origin:renderRect:fitEntireRect:viewportMinimumScale:viewportMaximumScale:]): New method that responds to the incoming Web Process message, and decides if any potential zoom would be "significant". (-[WKContentView _singleTapIdentified:]): (-[WKContentView _doubleTapDidFail:]): (-[WKContentView _didCompleteSyntheticClick]): (-[WKContentView _singleTapRecognized:]): (-[WKContentView _doubleTapRecognized:]): Add some release logging. (-[WKContentView _singleTapCommited:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::potentialTapAtPosition): (WebKit::WebPageProxy::handleSmartMagnificationInformationForPotentialTap): * WebProcess/WebPage/ViewGestureGeometryCollector.h: * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Removed an unused parameter from the existing message. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::potentialTapAtPosition): Calculates the geometry of the element if requested, and sends it to the UIProcess. LayoutTests: Implement a test (iPad only) that sets up a page with zoomable content but not quite at a significant scale, meaning we should dispatch a click event rather than Double Tap To Zoom. In order to do this, a humanSpeedDoubleTapAt() method was added to UIHelper that sleeps a bit between taps, otherwise the double tap gesture is recognized before the Web Process has had a chance to evaluate the potential click. * fast/events/ios/ipad/fast-click-double-tap-sends-click-on-insignificant-zoom-expected.txt: Added. * fast/events/ios/ipad/fast-click-double-tap-sends-click-on-insignificant-zoom.html: Added. * platform/ios/TestExpectations: * platform/ipad/TestExpectations: * resources/ui-helper.js: (window.UIHelper.humanSpeedDoubleTapAt): Canonical link: https://commits.webkit.org/209887@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242757 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-03-11 23:43:04 +00:00
}
static humanSpeedZoomByDoubleTappingAt(x, y)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
console.assert(this.isIOSFamily());
if (!this.isWebKit2()) {
// FIXME: Add a sleep in here.
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
return Promise.resolve();
}
return new Promise(async (resolve) => {
REGRESSION (iOS 13): Tests that simulate multiple back-to-back single taps fail or time out https://bugs.webkit.org/show_bug.cgi?id=201129 <rdar://problem/51857277> Reviewed by Tim Horton. Source/WebKit: Adds a new SPI hook in WebKit to let clients know when a synthetic tap gesture that has ended has been reset. See Tools/ChangeLog and LayoutTests/ChangeLog for more details. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _doAfterResettingSingleTapGesture:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _singleTapDidReset:]): (-[WKContentView _doAfterResettingSingleTapGesture:]): Tools: The tests in editing/pasteboard/ios were timing out on iOS 13 before this change. This is because they simulate back-to-back single taps; while this is recognized as two single taps on iOS 12 and prior, only the first single tap is recognized on iOS 13 (and the second is simply dropped on the floor). This occurs because the synthetic single tap gesture is reset slightly later on iOS 13 compared to iOS 12, so when the second tap is dispatched, the gesture recognizer is still in "ended" state after the first tap on iOS 13, which means the gesture isn't capable of recognizing further touches yet. In UIKit, a gesture recognizer is only reset once its UIGestureEnvironment's containing dependency subgraph no longer contains gestures that are active. In iOS 12, the synthetic click gesture is a part of a dependency subgraph that contains only itself and the normal (blocking) double tap gesture which requires the click to fail before it can be recognized; immediately after simulating the tap, both these gestures are inactive, which allows both of them to be reset. However, in iOS 13, the synthetic click gesture is part of a gesture dependency graph that contains the double tap for double click gesture, as well as the non-blocking double tap gesture, both of which are still active immediately after sending the first tap. This change in dependencies is caused by the introduction of UIUndoGestureInteraction's single and double three-finger tap gestures, which (in -[UIUndoGestureInteraction gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]) explicitly add all other taps as failure requirements. This effectively links the synthetic single tap gesture to most of the other gestures in WKContentView's dependency graph by way of these tap gestures for the undo interaction. All this means that there is now a short (~50 ms) delay after the synthetic single tap gestures is recognized, before it can be recognized again. To account for this new delay in our test infrastructure, simply wait for single tap gestures that have ended to reset before attempting to send subsequent single taps. We do this by introducing WebKit testing SPI to invoke a completion handler after resetting the synthetic click gesture (only if necessary - i.e., if the gesture is in ended state when we are about to begin simulating the tap). This allows calls to `UIScriptController::singleTapAtPoint` to be reliably recognized as single taps without requiring arbitrary 120 ms "human speed" delays. This fixes a number of flaky or failing layout tests, including the tests in editing/pasteboard/ios. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::doubleTapAtPoint): Add a `delay` parameter to `doubleTapAtPoint`. A number of layout tests were actually simulating double click gestures by simulating two back-to-back single taps; this is done for the purposes of being able to add a "human speed" delay prior to the second single tap gesture. After the change to wait for the single tap gesture to reset before attempting to simulate the next tap, this strategy no longer works, since the second gesture is recognized only as a single tap instead of a double tap. Instead, we add a delay parameter to `UIScriptController::doubleTapAtPoint`, which the "human speed" double tap gestures use instead to wait after simulating the first tap. * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (-[HIDEventGenerator _waitFor:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:delay:completionBlock:]): Plumb the tap gesture delay through to this helper method. (-[HIDEventGenerator tap:completionBlock:]): (-[HIDEventGenerator doubleTap:delay:completionBlock:]): (-[HIDEventGenerator twoFingerTap:completionBlock:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:completionBlock:]): Deleted. (-[HIDEventGenerator doubleTap:completionBlock:]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::waitForSingleTapToReset const): Add a new helper to wait for the content view's single tap gesture to reset if needed; call this before attempting to simulate single taps (either using a stylus, or with a regular touch). (WTR::UIScriptControllerIOS::singleTapAtPointWithModifiers): (WTR::UIScriptControllerIOS::doubleTapAtPoint): (WTR::UIScriptControllerIOS::stylusTapAtPointWithModifiers): LayoutTests: Adjusts a few layout tests after changes to UIScriptController::doubleTapAtPoint and UIScriptController::singleTapAtPoint. * editing/selection/ios/change-selection-by-tapping.html: Tweak this test to tap the page 12 times instead of 20 (which seems to cause occasional timeouts locally, when running all layout tests with a dozen active simulators). * fast/events/ios/double-tap-zoom.html: * fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html: * fast/events/ios/viewport-shrink-to-fit-allows-double-tap.html: Augment a few call sites of `doubleTapAtPoint` with a 0 delay. Ideally, these should just use ui-helper.js, but we can refactor these tests as a part of folding basic-gestures.js into ui-helper.js. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: * http/tests/security/anchor-download-block-crossorigin-expected.txt: Rebaseline these layout tests, due to change in line numbers. * platform/ipad/TestExpectations: Unskip these tests on iPad, now that they should pass. * pointerevents/utils.js: (const.ui.new.UIController.prototype.doubleTapToZoom): * resources/basic-gestures.js: (return.new.Promise.): (return.new.Promise): Adjust some more call sites of `doubleTapAtPoint`. Ideally, these should use just `ui-helper.js` too. * resources/ui-helper.js: (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): Add a delay parameter to `doubleTapAt` to specify a delay after each simulated tap. By default, this is 0, but the `humanSpeed*` helpers add a delay of 120 milliseconds. Additionally, these helpers were previously calling `singleTapAtPoint` twice, with a timeout in between to add a delay. Instead, call `doubleTapAtPoint` with a nonzero delay; otherwise, we'll end up waiting in `singleTapAtPoint` for the gesture subgraph containing both the double tap gestures and the synthetic single tap gesture to reset, which causes these two single taps to no longer be recognized as a double tap gesture. (window.UIHelper.zoomByDoubleTappingAt): Canonical link: https://commits.webkit.org/214834@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-26 19:37:29 +00:00
testRunner.runUIScript(`
uiController.didEndZoomingCallback = () => {
uiController.didEndZoomingCallback = null;
uiController.uiScriptComplete(uiController.zoomScale);
};
uiController.doubleTapAtPoint(${x}, ${y}, 0.12, () => { });`, resolve);
});
}
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
static zoomByDoubleTappingAt(x, y)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
console.assert(this.isIOSFamily());
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
if (!this.isWebKit2()) {
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
eventSender.addTouchPoint(x, y);
eventSender.touchStart();
eventSender.releaseTouchPoint(0);
eventSender.touchEnd();
return Promise.resolve();
}
return new Promise((resolve) => {
testRunner.runUIScript(`
uiController.didEndZoomingCallback = () => {
uiController.didEndZoomingCallback = null;
uiController.uiScriptComplete(uiController.zoomScale);
};
REGRESSION (iOS 13): Tests that simulate multiple back-to-back single taps fail or time out https://bugs.webkit.org/show_bug.cgi?id=201129 <rdar://problem/51857277> Reviewed by Tim Horton. Source/WebKit: Adds a new SPI hook in WebKit to let clients know when a synthetic tap gesture that has ended has been reset. See Tools/ChangeLog and LayoutTests/ChangeLog for more details. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _doAfterResettingSingleTapGesture:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _singleTapDidReset:]): (-[WKContentView _doAfterResettingSingleTapGesture:]): Tools: The tests in editing/pasteboard/ios were timing out on iOS 13 before this change. This is because they simulate back-to-back single taps; while this is recognized as two single taps on iOS 12 and prior, only the first single tap is recognized on iOS 13 (and the second is simply dropped on the floor). This occurs because the synthetic single tap gesture is reset slightly later on iOS 13 compared to iOS 12, so when the second tap is dispatched, the gesture recognizer is still in "ended" state after the first tap on iOS 13, which means the gesture isn't capable of recognizing further touches yet. In UIKit, a gesture recognizer is only reset once its UIGestureEnvironment's containing dependency subgraph no longer contains gestures that are active. In iOS 12, the synthetic click gesture is a part of a dependency subgraph that contains only itself and the normal (blocking) double tap gesture which requires the click to fail before it can be recognized; immediately after simulating the tap, both these gestures are inactive, which allows both of them to be reset. However, in iOS 13, the synthetic click gesture is part of a gesture dependency graph that contains the double tap for double click gesture, as well as the non-blocking double tap gesture, both of which are still active immediately after sending the first tap. This change in dependencies is caused by the introduction of UIUndoGestureInteraction's single and double three-finger tap gestures, which (in -[UIUndoGestureInteraction gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]) explicitly add all other taps as failure requirements. This effectively links the synthetic single tap gesture to most of the other gestures in WKContentView's dependency graph by way of these tap gestures for the undo interaction. All this means that there is now a short (~50 ms) delay after the synthetic single tap gestures is recognized, before it can be recognized again. To account for this new delay in our test infrastructure, simply wait for single tap gestures that have ended to reset before attempting to send subsequent single taps. We do this by introducing WebKit testing SPI to invoke a completion handler after resetting the synthetic click gesture (only if necessary - i.e., if the gesture is in ended state when we are about to begin simulating the tap). This allows calls to `UIScriptController::singleTapAtPoint` to be reliably recognized as single taps without requiring arbitrary 120 ms "human speed" delays. This fixes a number of flaky or failing layout tests, including the tests in editing/pasteboard/ios. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::doubleTapAtPoint): Add a `delay` parameter to `doubleTapAtPoint`. A number of layout tests were actually simulating double click gestures by simulating two back-to-back single taps; this is done for the purposes of being able to add a "human speed" delay prior to the second single tap gesture. After the change to wait for the single tap gesture to reset before attempting to simulate the next tap, this strategy no longer works, since the second gesture is recognized only as a single tap instead of a double tap. Instead, we add a delay parameter to `UIScriptController::doubleTapAtPoint`, which the "human speed" double tap gestures use instead to wait after simulating the first tap. * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (-[HIDEventGenerator _waitFor:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:delay:completionBlock:]): Plumb the tap gesture delay through to this helper method. (-[HIDEventGenerator tap:completionBlock:]): (-[HIDEventGenerator doubleTap:delay:completionBlock:]): (-[HIDEventGenerator twoFingerTap:completionBlock:]): (-[HIDEventGenerator sendTaps:location:withNumberOfTouches:completionBlock:]): Deleted. (-[HIDEventGenerator doubleTap:completionBlock:]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::waitForSingleTapToReset const): Add a new helper to wait for the content view's single tap gesture to reset if needed; call this before attempting to simulate single taps (either using a stylus, or with a regular touch). (WTR::UIScriptControllerIOS::singleTapAtPointWithModifiers): (WTR::UIScriptControllerIOS::doubleTapAtPoint): (WTR::UIScriptControllerIOS::stylusTapAtPointWithModifiers): LayoutTests: Adjusts a few layout tests after changes to UIScriptController::doubleTapAtPoint and UIScriptController::singleTapAtPoint. * editing/selection/ios/change-selection-by-tapping.html: Tweak this test to tap the page 12 times instead of 20 (which seems to cause occasional timeouts locally, when running all layout tests with a dozen active simulators). * fast/events/ios/double-tap-zoom.html: * fast/events/ios/viewport-device-width-allows-double-tap-zoom-out.html: * fast/events/ios/viewport-shrink-to-fit-allows-double-tap.html: Augment a few call sites of `doubleTapAtPoint` with a 0 delay. Ideally, these should just use ui-helper.js, but we can refactor these tests as a part of folding basic-gestures.js into ui-helper.js. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: * http/tests/security/anchor-download-block-crossorigin-expected.txt: Rebaseline these layout tests, due to change in line numbers. * platform/ipad/TestExpectations: Unskip these tests on iPad, now that they should pass. * pointerevents/utils.js: (const.ui.new.UIController.prototype.doubleTapToZoom): * resources/basic-gestures.js: (return.new.Promise.): (return.new.Promise): Adjust some more call sites of `doubleTapAtPoint`. Ideally, these should use just `ui-helper.js` too. * resources/ui-helper.js: (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): Add a delay parameter to `doubleTapAt` to specify a delay after each simulated tap. By default, this is 0, but the `humanSpeed*` helpers add a delay of 120 milliseconds. Additionally, these helpers were previously calling `singleTapAtPoint` twice, with a timeout in between to add a delay. Instead, call `doubleTapAtPoint` with a nonzero delay; otherwise, we'll end up waiting in `singleTapAtPoint` for the gesture subgraph containing both the double tap gestures and the synthetic single tap gesture to reset, which causes these two single taps to no longer be recognized as a double tap gesture. (window.UIHelper.zoomByDoubleTappingAt): Canonical link: https://commits.webkit.org/214834@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-26 19:37:29 +00:00
uiController.doubleTapAtPoint(${x}, ${y}, 0, () => { });`, resolve);
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
});
}
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
static activateAt(x, y, modifiers=[])
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily()) {
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
eventSender.mouseMoveTo(x, y);
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
eventSender.mouseDown(0, modifiers);
eventSender.mouseUp(0, modifiers);
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
return Promise.resolve();
}
return new Promise((resolve) => {
testRunner.runUIScript(`
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
uiController.singleTapAtPointWithModifiers(${x}, ${y}, ${JSON.stringify(modifiers)}, function() {
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
});`, resolve);
});
}
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
static activateElement(element, modifiers=[])
[Payment Request] show() should only be called with user activation https://bugs.webkit.org/show_bug.cgi?id=179056 Reviewed by Sam Weinig. Source/WebCore: Updated existing tests to call PaymentRequest.show() with user activation. * Modules/paymentrequest/PaymentRequest.cpp: (WebCore::PaymentRequest::show): LayoutTests: * http/tests/paymentrequest/payment-address-attributes-and-toJSON-method.https.html: * http/tests/paymentrequest/payment-request-canmakepayment-method.https.html: * http/tests/paymentrequest/payment-request-change-shipping-address.https.html: * http/tests/paymentrequest/payment-request-change-shipping-option.https.html: * http/tests/paymentrequest/payment-request-show-method.https.html: * http/tests/paymentrequest/payment-response-complete-method.https.html: * http/tests/paymentrequest/payment-response-methodName-attribute.https.html: * http/tests/paymentrequest/payment-response-payerEmail-attribute.https.html: * http/tests/paymentrequest/payment-response-payerName-attribute.https.html: * http/tests/paymentrequest/payment-response-payerPhone-attribute.https.html: * http/tests/paymentrequest/resources/helpers.js: (async.getPaymentRequestResponse): * http/tests/paymentrequest/updateWith-method-pmi-handling.https.html: * http/tests/resources/payment-request.js: Added. (activateThen): * http/tests/ssl/applepay/ApplePayMerchantValidationEvent.https.html: * http/tests/ssl/applepay/ApplePayPaymentMethodUpdateEvent.https.html: * http/tests/ssl/applepay/PaymentRequest.https.html: * resources/ui-helper.js: (window.UIHelper.activateElement): Canonical link: https://commits.webkit.org/195340@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224402 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-03 16:35:59 +00:00
{
const x = element.offsetLeft + element.offsetWidth / 2;
const y = element.offsetTop + element.offsetHeight / 2;
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
return UIHelper.activateAt(x, y, modifiers);
[Payment Request] show() should only be called with user activation https://bugs.webkit.org/show_bug.cgi?id=179056 Reviewed by Sam Weinig. Source/WebCore: Updated existing tests to call PaymentRequest.show() with user activation. * Modules/paymentrequest/PaymentRequest.cpp: (WebCore::PaymentRequest::show): LayoutTests: * http/tests/paymentrequest/payment-address-attributes-and-toJSON-method.https.html: * http/tests/paymentrequest/payment-request-canmakepayment-method.https.html: * http/tests/paymentrequest/payment-request-change-shipping-address.https.html: * http/tests/paymentrequest/payment-request-change-shipping-option.https.html: * http/tests/paymentrequest/payment-request-show-method.https.html: * http/tests/paymentrequest/payment-response-complete-method.https.html: * http/tests/paymentrequest/payment-response-methodName-attribute.https.html: * http/tests/paymentrequest/payment-response-payerEmail-attribute.https.html: * http/tests/paymentrequest/payment-response-payerName-attribute.https.html: * http/tests/paymentrequest/payment-response-payerPhone-attribute.https.html: * http/tests/paymentrequest/resources/helpers.js: (async.getPaymentRequestResponse): * http/tests/paymentrequest/updateWith-method-pmi-handling.https.html: * http/tests/resources/payment-request.js: Added. (activateThen): * http/tests/ssl/applepay/ApplePayMerchantValidationEvent.https.html: * http/tests/ssl/applepay/ApplePayPaymentMethodUpdateEvent.https.html: * http/tests/ssl/applepay/PaymentRequest.https.html: * resources/ui-helper.js: (window.UIHelper.activateElement): Canonical link: https://commits.webkit.org/195340@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224402 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-03 16:35:59 +00:00
}
Turn On Smart Delete https://bugs.webkit.org/show_bug.cgi?id=194320 Reviewed by Ryosuke Niwa. Source/WebCore: Updated the following tests to work with iOS: * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: Turn on Smart delete for iOS at all times. Modify checks to allow Mac and iOS and other platforms to turn on smart delete when desired. * editing/Editor.cpp: (WebCore::Editor::shouldSmartDelete): Allow platfroms to determine if smart delete should be on. On mac, this is via word granularity, on iOS this is just on all the time. (WebCore::Editor::canSmartCopyOrDelete): (WebCore::Editor::performCutOrCopy): * editing/Editor.h: * editing/EditorCommand.cpp: (WebCore::executeDelete): * editing/ios/EditorIOS.mm: (WebCore::Editor::shouldSmartDelete): * editing/mac/EditorMac.mm: (WebCore::Editor::shouldSmartDelete): LayoutTests: Update smart-delete-* tests, and rebase many other tests to work with the new smart delete setting. * editing/deleting/smart-delete-001-expected.txt: Added. * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002-expected.txt: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-004-expected.txt. * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: * platform/ios-wk1/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk1/editing/deleting/smart-delete-004-expected.txt: Removed. * platform/ios-wk2/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk2/editing/pasteboard/cut-text-001-expected.png: Removed. * platform/ios/TestExpectations: * platform/ios/editing/deleting/5206311-1-expected.txt: * platform/ios/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/delete-across-editable-content-boundaries-3-expected.txt: Added. * platform/ios/editing/deleting/delete-and-undo-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-012-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-017-expected.txt: * platform/ios/editing/deleting/delete-contiguous-ws-001-expected.txt: * platform/ios/editing/deleting/delete-image-003-expected.txt: * platform/ios/editing/deleting/delete-leading-ws-001-expected.txt: * platform/ios/editing/deleting/delete-selection-001-expected.txt: * platform/ios/editing/deleting/delete-trailing-ws-001-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-002-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-003-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-004-expected.txt: * platform/ios/editing/deleting/smart-delete-001-expected.txt: * platform/ios/editing/deleting/smart-delete-002-expected.txt: Added. * platform/ios/editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/table-cells-expected.txt: * platform/ios/editing/execCommand/delete-line-and-insert-text-in-font-inside-blockquote-expected.txt: Added. * platform/ios/editing/pasteboard/cut-text-001-expected.txt: Renamed from LayoutTests/platform/ios-wk2/editing/pasteboard/cut-text-001-expected.txt. * platform/ios/editing/pasteboard/paste-2-expected.txt: * platform/mac/editing/deleting/smart-delete-001-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-001-expected.txt: Removed. * platform/mac/editing/deleting/smart-delete-002-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-003-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-004-expected.png: Removed. * resources/ui-helper.js: (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): Canonical link: https://commits.webkit.org/209155@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241719 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 16:53:32 +00:00
static async doubleActivateAt(x, y)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (this.isIOSFamily())
Turn On Smart Delete https://bugs.webkit.org/show_bug.cgi?id=194320 Reviewed by Ryosuke Niwa. Source/WebCore: Updated the following tests to work with iOS: * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: Turn on Smart delete for iOS at all times. Modify checks to allow Mac and iOS and other platforms to turn on smart delete when desired. * editing/Editor.cpp: (WebCore::Editor::shouldSmartDelete): Allow platfroms to determine if smart delete should be on. On mac, this is via word granularity, on iOS this is just on all the time. (WebCore::Editor::canSmartCopyOrDelete): (WebCore::Editor::performCutOrCopy): * editing/Editor.h: * editing/EditorCommand.cpp: (WebCore::executeDelete): * editing/ios/EditorIOS.mm: (WebCore::Editor::shouldSmartDelete): * editing/mac/EditorMac.mm: (WebCore::Editor::shouldSmartDelete): LayoutTests: Update smart-delete-* tests, and rebase many other tests to work with the new smart delete setting. * editing/deleting/smart-delete-001-expected.txt: Added. * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002-expected.txt: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-004-expected.txt. * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: * platform/ios-wk1/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk1/editing/deleting/smart-delete-004-expected.txt: Removed. * platform/ios-wk2/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk2/editing/pasteboard/cut-text-001-expected.png: Removed. * platform/ios/TestExpectations: * platform/ios/editing/deleting/5206311-1-expected.txt: * platform/ios/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/delete-across-editable-content-boundaries-3-expected.txt: Added. * platform/ios/editing/deleting/delete-and-undo-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-012-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-017-expected.txt: * platform/ios/editing/deleting/delete-contiguous-ws-001-expected.txt: * platform/ios/editing/deleting/delete-image-003-expected.txt: * platform/ios/editing/deleting/delete-leading-ws-001-expected.txt: * platform/ios/editing/deleting/delete-selection-001-expected.txt: * platform/ios/editing/deleting/delete-trailing-ws-001-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-002-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-003-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-004-expected.txt: * platform/ios/editing/deleting/smart-delete-001-expected.txt: * platform/ios/editing/deleting/smart-delete-002-expected.txt: Added. * platform/ios/editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/table-cells-expected.txt: * platform/ios/editing/execCommand/delete-line-and-insert-text-in-font-inside-blockquote-expected.txt: Added. * platform/ios/editing/pasteboard/cut-text-001-expected.txt: Renamed from LayoutTests/platform/ios-wk2/editing/pasteboard/cut-text-001-expected.txt. * platform/ios/editing/pasteboard/paste-2-expected.txt: * platform/mac/editing/deleting/smart-delete-001-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-001-expected.txt: Removed. * platform/mac/editing/deleting/smart-delete-002-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-003-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-004-expected.png: Removed. * resources/ui-helper.js: (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): Canonical link: https://commits.webkit.org/209155@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241719 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 16:53:32 +00:00
await UIHelper.doubleTapAt(x, y);
else
await UIHelper.doubleClickAt(x, y);
}
static async doubleActivateAtSelectionStart()
{
const rects = window.getSelection().getRangeAt(0).getClientRects();
const x = rects[0].left;
const y = rects[0].top;
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (this.isIOSFamily()) {
Turn On Smart Delete https://bugs.webkit.org/show_bug.cgi?id=194320 Reviewed by Ryosuke Niwa. Source/WebCore: Updated the following tests to work with iOS: * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: Turn on Smart delete for iOS at all times. Modify checks to allow Mac and iOS and other platforms to turn on smart delete when desired. * editing/Editor.cpp: (WebCore::Editor::shouldSmartDelete): Allow platfroms to determine if smart delete should be on. On mac, this is via word granularity, on iOS this is just on all the time. (WebCore::Editor::canSmartCopyOrDelete): (WebCore::Editor::performCutOrCopy): * editing/Editor.h: * editing/EditorCommand.cpp: (WebCore::executeDelete): * editing/ios/EditorIOS.mm: (WebCore::Editor::shouldSmartDelete): * editing/mac/EditorMac.mm: (WebCore::Editor::shouldSmartDelete): LayoutTests: Update smart-delete-* tests, and rebase many other tests to work with the new smart delete setting. * editing/deleting/smart-delete-001-expected.txt: Added. * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002-expected.txt: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-004-expected.txt. * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: * platform/ios-wk1/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk1/editing/deleting/smart-delete-004-expected.txt: Removed. * platform/ios-wk2/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk2/editing/pasteboard/cut-text-001-expected.png: Removed. * platform/ios/TestExpectations: * platform/ios/editing/deleting/5206311-1-expected.txt: * platform/ios/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/delete-across-editable-content-boundaries-3-expected.txt: Added. * platform/ios/editing/deleting/delete-and-undo-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-012-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-017-expected.txt: * platform/ios/editing/deleting/delete-contiguous-ws-001-expected.txt: * platform/ios/editing/deleting/delete-image-003-expected.txt: * platform/ios/editing/deleting/delete-leading-ws-001-expected.txt: * platform/ios/editing/deleting/delete-selection-001-expected.txt: * platform/ios/editing/deleting/delete-trailing-ws-001-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-002-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-003-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-004-expected.txt: * platform/ios/editing/deleting/smart-delete-001-expected.txt: * platform/ios/editing/deleting/smart-delete-002-expected.txt: Added. * platform/ios/editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/table-cells-expected.txt: * platform/ios/editing/execCommand/delete-line-and-insert-text-in-font-inside-blockquote-expected.txt: Added. * platform/ios/editing/pasteboard/cut-text-001-expected.txt: Renamed from LayoutTests/platform/ios-wk2/editing/pasteboard/cut-text-001-expected.txt. * platform/ios/editing/pasteboard/paste-2-expected.txt: * platform/mac/editing/deleting/smart-delete-001-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-001-expected.txt: Removed. * platform/mac/editing/deleting/smart-delete-002-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-003-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-004-expected.png: Removed. * resources/ui-helper.js: (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): Canonical link: https://commits.webkit.org/209155@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241719 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 16:53:32 +00:00
await UIHelper.activateAndWaitForInputSessionAt(x, y);
await UIHelper.doubleTapAt(x, y);
// This is only here to deal with async/sync copy/paste calls, so
// once <rdar://problem/16207002> is resolved, should be able to remove for faster tests.
await new Promise(resolve => testRunner.runUIScript("uiController.uiScriptComplete()", resolve));
} else
await UIHelper.doubleClickAt(x, y);
}
static async selectWordByDoubleTapOrClick(element, relativeX = 5, relativeY = 5)
{
const boundingRect = element.getBoundingClientRect();
const x = boundingRect.x + relativeX;
const y = boundingRect.y + relativeY;
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (this.isIOSFamily()) {
Turn On Smart Delete https://bugs.webkit.org/show_bug.cgi?id=194320 Reviewed by Ryosuke Niwa. Source/WebCore: Updated the following tests to work with iOS: * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: Turn on Smart delete for iOS at all times. Modify checks to allow Mac and iOS and other platforms to turn on smart delete when desired. * editing/Editor.cpp: (WebCore::Editor::shouldSmartDelete): Allow platfroms to determine if smart delete should be on. On mac, this is via word granularity, on iOS this is just on all the time. (WebCore::Editor::canSmartCopyOrDelete): (WebCore::Editor::performCutOrCopy): * editing/Editor.h: * editing/EditorCommand.cpp: (WebCore::executeDelete): * editing/ios/EditorIOS.mm: (WebCore::Editor::shouldSmartDelete): * editing/mac/EditorMac.mm: (WebCore::Editor::shouldSmartDelete): LayoutTests: Update smart-delete-* tests, and rebase many other tests to work with the new smart delete setting. * editing/deleting/smart-delete-001-expected.txt: Added. * editing/deleting/smart-delete-001.html: * editing/deleting/smart-delete-002-expected.txt: * editing/deleting/smart-delete-002.html: * editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * editing/deleting/smart-delete-003.html: * editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-004-expected.txt. * editing/deleting/smart-delete-004.html: * editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: * editing/deleting/smart-delete-across-editable-boundaries-2.html: * editing/selection/delete-word-granularity-text-control.html: * platform/ios-wk1/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk1/editing/deleting/smart-delete-004-expected.txt: Removed. * platform/ios-wk2/editing/deleting/smart-delete-003-expected.txt: Removed. * platform/ios-wk2/editing/pasteboard/cut-text-001-expected.png: Removed. * platform/ios/TestExpectations: * platform/ios/editing/deleting/5206311-1-expected.txt: * platform/ios/editing/deleting/delete-across-editable-content-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/delete-across-editable-content-boundaries-3-expected.txt: Added. * platform/ios/editing/deleting/delete-and-undo-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-012-expected.txt: * platform/ios/editing/deleting/delete-block-merge-contents-017-expected.txt: * platform/ios/editing/deleting/delete-contiguous-ws-001-expected.txt: * platform/ios/editing/deleting/delete-image-003-expected.txt: * platform/ios/editing/deleting/delete-leading-ws-001-expected.txt: * platform/ios/editing/deleting/delete-selection-001-expected.txt: * platform/ios/editing/deleting/delete-trailing-ws-001-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-002-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-003-expected.txt: * platform/ios/editing/deleting/delete-ws-fixup-004-expected.txt: * platform/ios/editing/deleting/smart-delete-001-expected.txt: * platform/ios/editing/deleting/smart-delete-002-expected.txt: Added. * platform/ios/editing/deleting/smart-delete-003-expected.txt: Copied from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-004-expected.txt: Renamed from LayoutTests/platform/mac/editing/deleting/smart-delete-003-expected.txt. * platform/ios/editing/deleting/smart-delete-across-editable-boundaries-2-expected.txt: Added. * platform/ios/editing/deleting/table-cells-expected.txt: * platform/ios/editing/execCommand/delete-line-and-insert-text-in-font-inside-blockquote-expected.txt: Added. * platform/ios/editing/pasteboard/cut-text-001-expected.txt: Renamed from LayoutTests/platform/ios-wk2/editing/pasteboard/cut-text-001-expected.txt. * platform/ios/editing/pasteboard/paste-2-expected.txt: * platform/mac/editing/deleting/smart-delete-001-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-001-expected.txt: Removed. * platform/mac/editing/deleting/smart-delete-002-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-003-expected.png: Removed. * platform/mac/editing/deleting/smart-delete-004-expected.png: Removed. * resources/ui-helper.js: (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): Canonical link: https://commits.webkit.org/209155@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241719 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-18 16:53:32 +00:00
await UIHelper.activateAndWaitForInputSessionAt(x, y);
await UIHelper.doubleTapAt(x, y);
// This is only here to deal with async/sync copy/paste calls, so
// once <rdar://problem/16207002> is resolved, should be able to remove for faster tests.
await new Promise(resolve => testRunner.runUIScript("uiController.uiScriptComplete()", resolve));
} else {
await UIHelper.doubleClickAt(x, y);
}
}
[iOS] Shift + Tab does not focus previous field https://bugs.webkit.org/show_bug.cgi?id=191596 <rdar://problem/45892053> Reviewed by Wenson Hsieh. Source/WebKit: Wire up the the tab and shift + tab key commands to the WKWebView/WKContentView's action forwarding mechanism. Also rename -_prevAccessoryTab to -_previousAccessoryTab. * Platform/spi/ios/UIKitSPI.h: Add more SPI. * UIProcess/API/Cocoa/WKWebViewInternal.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView canPerformActionForWebView:withSender:]): (-[WKContentView keyCommands]): (-[WKContentView _nextAccessoryTabForWebView:]): Added. (-[WKContentView _previousAccessoryTabForWebView:]): Added. (-[WKContentView _nextAccessoryTab:]): Deleted. (-[WKContentView _prevAccessoryTab:]): Deleted. Tools: Add infrastructure to support testing a key down event with modifiers by creating and dispatching a UIEvent. This infrastructure replaces the previous mechanism in Tools/WebKitTestRunner/ios/HIDEventGenerator.mm to generate a IOHIDEvent for a keydown as it did not support creating an event with modifier key state that would be recognized by UIKit. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::keyDown): (WTR::UIScriptController::keyDownUsingHardwareKeyboard): Deleted. (WTR::UIScriptController::keyUpUsingHardwareKeyboard): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: Add function uiController.keyDown() that takes a character that represents a keyboard key and an array of modifier keys. The behavior of this function is analogous to eventSender.keyDown(). Remove functions uiController.keyDownUsingHardwareKeyboard() and uiController.keyUpUsingHardwareKeyboard() as the former is replaced by uiController.keyDown() and the latter was never used. * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::keyDown): Added. (WTR::UIScriptController::keyUpUsingHardwareKeyboard): Deleted. (WTR::UIScriptController::keyDownUsingHardwareKeyboard): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (createHIDKeyDownEvent): Added. (-[HIDEventGenerator keyDown:completionBlock:]): Deleted. (-[HIDEventGenerator keyUp:completionBlock:]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::arrayLength): Added. (WTR::parseModifier): Added. (WTR::parseModifierArray): Added. (WTR::UIScriptController::keyDown): (WTR::UIScriptController::keyDownUsingHardwareKeyboard): Deleted. (WTR::UIScriptController::keyUpUsingHardwareKeyboard): Deleted. LayoutTests: Add tests to ensure that we do not regress the tab and shift + tab key commands. * fast/events/ios/focus-tab-next-field-expected.txt: Added. * fast/events/ios/focus-tab-next-field.html: Added. * fast/events/ios/focus-tab-previous-field-expected.txt: Added. * fast/events/ios/focus-tab-previous-field.html: Added. * platform/ios-wk1/TestExpectations: Skip test focus-tab-previous-field.html in Legacy WebKit as we do not support testing key commands with modifier keys. * resources/ui-helper.js: (window.UIHelper.keyDown): Updated to support taking an optional array of modifiers (defaults: []) and use the new infrastructure to generate a key down event for the specified character. Canonical link: https://commits.webkit.org/206435@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238235 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-15 19:15:28 +00:00
static keyDown(key, modifiers=[])
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily()) {
REGRESSION (r237738): Command Down Arrow doesn't scroll to the end of a page anymore https://bugs.webkit.org/show_bug.cgi?id=191967 <rdar://problem/45976390> Reviewed by Tim Horton. Source/WebKit: Fixes an issue where pressing Command + Down Arrow does not scroll the view to the end of the page. Following r237738 the value of the enumerations used to identify modifier keys (e.g. Shift) changed to match the values of the corresponding enumerations in GraphicsServices, which are the enumerations UIKit uses to computes the modifier flags bitmask when instantiating a WebEvent to pass to WebKit. Before r237738 WebKit was using enumerations whose values matched the values of the corresponding UIKit public API UIKeyModifier* enumerations. For non-content editable elements, WebKit intercepts UIKit events in -_handleKeyUIEvent, synthesizes and dispatches its own WebEvent. However it was creating WebEvents with a modifier flags bitmask built from the UIKeyModifier* enumerations, -_modifierFlags, as opposed to a bitmask from the GraphicsServices enumerations, -_gsModifierFlags. Instead WebKit should call -_gsModifierFlags to compute the GraphicsServices-compatible modifier flags bitmask when instantiating a WebEvent. * Platform/spi/ios/UIKitSPI.h: Expose -_gsModifierFlags and remove -_modifierFlags. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _handleKeyUIEvent:]): Remove unnecessary code to update the current modifier state. This will be done by the WebProcess when it receives the keyboard event. (-[WKContentView _didHandleKeyEvent:eventWasHandled:]): Do not pass modifier flags changed events to the scrolling animator as it does not know how to handle these kinds of events and triggers an assertion failure when it tries to read the input string from the event (calls -charactersIgnoringModifiers). FlagsChanged WebEvents events do not have an input string just like a FlagsChanged NSEvent that they model on Mac. * UIProcess/ios/WKWebEvent.mm: (-[WKWebEvent initWithEvent:]): Pass the value of -_gsModifierFlags for the modifier flags bitmask instead of the value of -_modifierFlags. Tools: Add more test infrastructure to dispatch key up events. * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (createHIDKeyEvent): Renamed from createHIDKeyDownEvent() and modified to take a boolean as to whether to create an event for a key down or key up. (createHIDKeyDownEvent): Deleted; renamed to createHIDKeyEvent(). * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::createUIPhysicalKeyboardEvent): Added. Convenience function to create a UIPhysicalKeyboardEvent. (WTR::UIScriptController::keyDown): Modified to dispatch a key up event in addition to dispatching a key down event. LayoutTests: Add tests to ensure that Command + Down Arrow and Command + Up Arrow scroll to the end of the page and the top of the page, respectively. * fast/scrolling/ios/key-command-scroll-to-bottom-expected.html: Added. * fast/scrolling/ios/key-command-scroll-to-bottom.html: Added. * fast/scrolling/ios/key-command-scroll-to-top-expected.html: Added. * fast/scrolling/ios/key-command-scroll-to-top.html: Added. * resources/ui-helper.js: (window.UIHelper.keyDown): Pass the modifiers array to EventSender.keyDown() to make this function work on Mac. Canonical link: https://commits.webkit.org/206692@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238526 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-26 22:57:44 +00:00
eventSender.keyDown(key, modifiers);
return Promise.resolve();
}
return new Promise((resolve) => {
[iOS] Shift + Tab does not focus previous field https://bugs.webkit.org/show_bug.cgi?id=191596 <rdar://problem/45892053> Reviewed by Wenson Hsieh. Source/WebKit: Wire up the the tab and shift + tab key commands to the WKWebView/WKContentView's action forwarding mechanism. Also rename -_prevAccessoryTab to -_previousAccessoryTab. * Platform/spi/ios/UIKitSPI.h: Add more SPI. * UIProcess/API/Cocoa/WKWebViewInternal.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView canPerformActionForWebView:withSender:]): (-[WKContentView keyCommands]): (-[WKContentView _nextAccessoryTabForWebView:]): Added. (-[WKContentView _previousAccessoryTabForWebView:]): Added. (-[WKContentView _nextAccessoryTab:]): Deleted. (-[WKContentView _prevAccessoryTab:]): Deleted. Tools: Add infrastructure to support testing a key down event with modifiers by creating and dispatching a UIEvent. This infrastructure replaces the previous mechanism in Tools/WebKitTestRunner/ios/HIDEventGenerator.mm to generate a IOHIDEvent for a keydown as it did not support creating an event with modifier key state that would be recognized by UIKit. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::keyDown): (WTR::UIScriptController::keyDownUsingHardwareKeyboard): Deleted. (WTR::UIScriptController::keyUpUsingHardwareKeyboard): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: Add function uiController.keyDown() that takes a character that represents a keyboard key and an array of modifier keys. The behavior of this function is analogous to eventSender.keyDown(). Remove functions uiController.keyDownUsingHardwareKeyboard() and uiController.keyUpUsingHardwareKeyboard() as the former is replaced by uiController.keyDown() and the latter was never used. * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::keyDown): Added. (WTR::UIScriptController::keyUpUsingHardwareKeyboard): Deleted. (WTR::UIScriptController::keyDownUsingHardwareKeyboard): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/HIDEventGenerator.h: * WebKitTestRunner/ios/HIDEventGenerator.mm: (createHIDKeyDownEvent): Added. (-[HIDEventGenerator keyDown:completionBlock:]): Deleted. (-[HIDEventGenerator keyUp:completionBlock:]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::arrayLength): Added. (WTR::parseModifier): Added. (WTR::parseModifierArray): Added. (WTR::UIScriptController::keyDown): (WTR::UIScriptController::keyDownUsingHardwareKeyboard): Deleted. (WTR::UIScriptController::keyUpUsingHardwareKeyboard): Deleted. LayoutTests: Add tests to ensure that we do not regress the tab and shift + tab key commands. * fast/events/ios/focus-tab-next-field-expected.txt: Added. * fast/events/ios/focus-tab-next-field.html: Added. * fast/events/ios/focus-tab-previous-field-expected.txt: Added. * fast/events/ios/focus-tab-previous-field.html: Added. * platform/ios-wk1/TestExpectations: Skip test focus-tab-previous-field.html in Legacy WebKit as we do not support testing key commands with modifier keys. * resources/ui-helper.js: (window.UIHelper.keyDown): Updated to support taking an optional array of modifiers (defaults: []) and use the new infrastructure to generate a key down event for the specified character. Canonical link: https://commits.webkit.org/206435@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238235 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-15 19:15:28 +00:00
testRunner.runUIScript(`uiController.keyDown("${key}", ${JSON.stringify(modifiers)});`, resolve);
});
}
Move testRunner.toggleCapsLock() to uiController https://bugs.webkit.org/show_bug.cgi?id=191972 Reviewed by Tim Horton. Tools: Move testRunner.toggleCapsLock() to uiController as uiController is the preferred JavaScript object for UI test functions. Having this functionality be on uiController makes it an asynchronous function naturally and complements use of onkeydown, onkeyup listeners to know when the Caps Lock key event is dispatched. It also facilitates its use directly as part of scripts with other uiController functions invocations that are passed in a single invocation of testRunner.runUIScript(). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::toggleCapsLock): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::toggleCapsLock): Added stub functions that invoke the callback. We do not support toggling caps lock in Legacy WebKit at the moment. Legacy WebKit reads the caps lock key state directly from the OS. Modern WebKit caches the caps lock state in the WebProcess as a natural side effect of the fact that the UIProcess is the only process capable of querying the caps lock key state from the OS and hence the UIProcess must send over this state to the WebProcess. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: Add IDL for new function. * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::toggleCapsLock): Added empty implementation for ports non-Cocoa ports. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::toggleCapsLock): Deleted. * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/TestController.h: * WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::toggleCapsLock): Deleted; moved to UIScriptController::toggleCapsLock(). Removed logic to handle testRunner.toggleCapsLock(). * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::toggleCapsLock): Add stub function that invokes the callback and a FIXME comment that explains that we will implement this function in <https://bugs.webkit.org/show_bug.cgi?id=191815>. * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::toggleCapsLock): Moved the implementation from TestController::toggleCapsLock(). LayoutTests: Updated existing test to use UIHelper.toggleCapsLock(), which calls uiController.toggleCapsLock(), now that testRunner.toggleCapsLock() was removed. * fast/events/detect-caps-lock.html: * resources/ui-helper.js: (window.UIHelper.toggleCapsLock): Added. Convenience function to call uiController.toggleCapsLock() and return a Promise that is resolved once the UIProcess has dispatched the NSEvent to simulate pressing the caps lock key. Canonical link: https://commits.webkit.org/206679@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-26 20:41:19 +00:00
static toggleCapsLock()
{
return new Promise((resolve) => {
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
testRunner.runUIScript(`uiController.toggleCapsLock(() => uiController.uiScriptComplete());`, resolve);
Move testRunner.toggleCapsLock() to uiController https://bugs.webkit.org/show_bug.cgi?id=191972 Reviewed by Tim Horton. Tools: Move testRunner.toggleCapsLock() to uiController as uiController is the preferred JavaScript object for UI test functions. Having this functionality be on uiController makes it an asynchronous function naturally and complements use of onkeydown, onkeyup listeners to know when the Caps Lock key event is dispatched. It also facilitates its use directly as part of scripts with other uiController functions invocations that are passed in a single invocation of testRunner.runUIScript(). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::toggleCapsLock): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::toggleCapsLock): Added stub functions that invoke the callback. We do not support toggling caps lock in Legacy WebKit at the moment. Legacy WebKit reads the caps lock key state directly from the OS. Modern WebKit caches the caps lock state in the WebProcess as a natural side effect of the fact that the UIProcess is the only process capable of querying the caps lock key state from the OS and hence the UIProcess must send over this state to the WebProcess. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: Add IDL for new function. * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::toggleCapsLock): Added empty implementation for ports non-Cocoa ports. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::toggleCapsLock): Deleted. * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/TestController.h: * WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::toggleCapsLock): Deleted; moved to UIScriptController::toggleCapsLock(). Removed logic to handle testRunner.toggleCapsLock(). * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::toggleCapsLock): Add stub function that invokes the callback and a FIXME comment that explains that we will implement this function in <https://bugs.webkit.org/show_bug.cgi?id=191815>. * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::toggleCapsLock): Moved the implementation from TestController::toggleCapsLock(). LayoutTests: Updated existing test to use UIHelper.toggleCapsLock(), which calls uiController.toggleCapsLock(), now that testRunner.toggleCapsLock() was removed. * fast/events/detect-caps-lock.html: * resources/ui-helper.js: (window.UIHelper.toggleCapsLock): Added. Convenience function to call uiController.toggleCapsLock() and return a Promise that is resolved once the UIProcess has dispatched the NSEvent to simulate pressing the caps lock key. Canonical link: https://commits.webkit.org/206679@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-26 20:41:19 +00:00
});
}
[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
static keyboardIsAutomaticallyShifted()
{
return new Promise(resolve => {
testRunner.runUIScript(`uiController.keyboardIsAutomaticallyShifted`, result => resolve(result === "true"));
});
}
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
static isAnimatingDragCancel()
{
return new Promise(resolve => {
testRunner.runUIScript(`uiController.isAnimatingDragCancel`, result => resolve(result === "true"));
});
}
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
static ensurePresentationUpdate()
{
if (!this.isWebKit2()) {
testRunner.display();
return Promise.resolve();
}
return new Promise(resolve => {
testRunner.runUIScript(`
uiController.doAfterPresentationUpdate(function() {
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
});`, resolve);
});
}
[iOS WK2] A top fixed bar can flicker when scrolling with the keyboard up https://bugs.webkit.org/show_bug.cgi?id=200105 rdar://problem/52871975 Reviewed by Wenson Hsieh. Source/WebCore: ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition() computes a visual viewport from the current scroll position and scrollableAreaSize(). This doesn't know anything about the impact of keyboards on the visual viewport, so it computes a too-large visual viewport when the keyboard is up, triggering incorrect manipulations of the layout viewport. This leads to the top bar flashing to position 0 when it should be hidden off the top. Fix by feeding into the scrolling tree the height of the visual viewport which takes FrameView::visualViewportOverrideRect() into account. This is stored on ScrollingStateFrameScrollingNode/ ScrollingTreeFrameScrollingNode. Test: scrollingcoordinator/ios/fixed-scrolling-with-keyboard.html * page/FrameView.h: * page/scrolling/AsyncScrollingCoordinator.cpp: (WebCore::AsyncScrollingCoordinator::setFrameScrollingNodeState): * page/scrolling/ScrollingStateFrameScrollingNode.cpp: (WebCore::ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode): (WebCore::ScrollingStateFrameScrollingNode::setPropertyChangedBitsAfterReattach): (WebCore::ScrollingStateFrameScrollingNode::setOverrideVisualViewportSize): (WebCore::ScrollingStateFrameScrollingNode::dumpProperties const): * page/scrolling/ScrollingStateFrameScrollingNode.h: * page/scrolling/ScrollingTree.cpp: (WebCore::ScrollingTree::commitTreeState): LOG_WITH_STREAM() doesn't evaluate scrollingTreeAsText() every time. * page/scrolling/ScrollingTreeFrameScrollingNode.cpp: (WebCore::ScrollingTreeFrameScrollingNode::commitStateBeforeChildren): (WebCore::ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition const): (WebCore::ScrollingTreeFrameScrollingNode::dumpProperties const): * page/scrolling/ScrollingTreeFrameScrollingNode.h: Source/WebKit: ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition() computes a visual viewport from the current scroll position and scrollableAreaSize(). This doesn't know anything about the impact of keyboards on the visual viewport, so it computes a too-large visual viewport when the keyboard is up, triggering incorrect manipulations of the layout viewport. This leads to the top bar flashing to position 0 when it should be hidden off the top. Fix by feeding into the scrolling tree the height of the visual viewport which takes FrameView::visualViewportOverrideRect() into account. This is stored on ScrollingStateFrameScrollingNode/ ScrollingTreeFrameScrollingNode. * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp: (ArgumentCoder<ScrollingStateFrameScrollingNode>::encode): (ArgumentCoder<ScrollingStateFrameScrollingNode>::decode): LayoutTests: * resources/ui-helper.js: (window.UIHelper.ensureStablePresentationUpdate.return.new.Promise): (window.UIHelper.ensureStablePresentationUpdate): * scrollingcoordinator/ios/fixed-scrolling-with-keyboard-expected.txt: Added. * scrollingcoordinator/ios/fixed-scrolling-with-keyboard.html: Added. Canonical link: https://commits.webkit.org/213962@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247839 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-25 21:12:01 +00:00
static ensureStablePresentationUpdate()
{
if (!this.isWebKit2()) {
testRunner.display();
return Promise.resolve();
}
return new Promise(resolve => {
testRunner.runUIScript(`
uiController.doAfterNextStablePresentationUpdate(function() {
uiController.uiScriptComplete();
});`, resolve);
});
}
[iOS] Crash in WebKit::WebPage::positionInformation via Range::startPosition https://bugs.webkit.org/show_bug.cgi?id=199503 Reviewed by Wenson Hsieh. Source/WebCore: * editing/Editor.cpp: (WebCore::Editor::compositionRange const): Added a FIXME. Source/WebKit: The crash was caused because focusedElementPositionInformation asssumes Editor::compositionRange is not null whenever Editor::hasComposition returns true, which is not necessary the case when Editor::m_compositionNode contains no text (data is of length 0). Fixed the crash by adding an early return for when Editor::compositionRange returns nullptr. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::focusedElementPositionInformation): Tools: Added UIScriptController.ensurePositionInformationIsUpToDateAt using the existing WKWebView SPI: _requestActivatedElementAtPosition * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt): * WebKitTestRunner/ios/UIScriptControllerMac.mm: (WTR::UIScriptController::ensurePositionInformationIsUpToDateAt): LayoutTests: Added a regression test for the crash. * editing/input/delete-text-in-composition-expected.txt: Added. * editing/input/delete-text-in-composition.html: Added. * resources/ui-helper.js: (window.UIHelper.ensurePositionInformationUpdateForElement): Added. Canonical link: https://commits.webkit.org/213440@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247180 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-05 21:56:58 +00:00
static ensurePositionInformationUpdateForElement(element)
{
const boundingRect = element.getBoundingClientRect();
const x = boundingRect.x + 5;
const y = boundingRect.y + 5;
if (!this.isWebKit2()) {
testRunner.display();
return Promise.resolve();
}
return new Promise(resolve => {
testRunner.runUIScript(`
uiController.ensurePositionInformationIsUpToDateAt(${x}, ${y}, function () {
uiController.uiScriptComplete();
});`, resolve);
});
}
Make it possible to test scrolling tree layer manipulation more easily https://bugs.webkit.org/show_bug.cgi?id=195780 Reviewed by Tim Horton. Source/WebKit: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _scrollingUpdatesDisabledForTesting]): (-[WKWebView _setScrollingUpdatesDisabledForTesting:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/Cocoa/PageClientImplCocoa.h: * UIProcess/Cocoa/PageClientImplCocoa.mm: (WebKit::PageClientImplCocoa::scrollingUpdatesDisabledForTesting): * UIProcess/Cocoa/WebPageProxyCocoa.mm: (WebKit::WebPageProxy::scrollingUpdatesDisabledForTesting): * UIProcess/PageClient.h: (WebKit::PageClient::scrollingUpdatesDisabledForTesting): * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp: (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll): * UIProcess/WebPageProxy.h: Tools: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView _scrollingUpdatesDisabledForTesting]): (-[TestRunnerWKWebView _setScrollingUpdatesDisabledForTesting:]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): LayoutTests: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * resources/ui-helper.js: Some 'async' functions that awaited promises should just return the promise. (window.UIHelper.immediateScrollTo): (window.UIHelper.immediateUnstableScrollTo): (window.UIHelper.async.delayFor): Deleted. (window.UIHelper.async.immediateScrollTo): Deleted. (window.UIHelper.async.immediateUnstableScrollTo): Deleted. Canonical link: https://commits.webkit.org/210066@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242979 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-03-15 01:10:09 +00:00
static delayFor(ms)
{
return new Promise(resolve => setTimeout(resolve, ms));
}
[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
static scrollTo(x, y, unconstrained)
{
if (!this.isWebKit2()) {
window.scrollTo(x, y);
return Promise.resolve();
}
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
uiController.didEndScrollingCallback = function() {
uiController.uiScriptComplete();
}
uiController.scrollToOffset(${x}, ${y}, { unconstrained: ${unconstrained} });
})()`, resolve);
});
}
[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
static immediateScrollTo(x, y, unconstrained)
{
if (!this.isWebKit2()) {
window.scrollTo(x, y);
return Promise.resolve();
}
Make it possible to test scrolling tree layer manipulation more easily https://bugs.webkit.org/show_bug.cgi?id=195780 Reviewed by Tim Horton. Source/WebKit: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _scrollingUpdatesDisabledForTesting]): (-[WKWebView _setScrollingUpdatesDisabledForTesting:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/Cocoa/PageClientImplCocoa.h: * UIProcess/Cocoa/PageClientImplCocoa.mm: (WebKit::PageClientImplCocoa::scrollingUpdatesDisabledForTesting): * UIProcess/Cocoa/WebPageProxyCocoa.mm: (WebKit::WebPageProxy::scrollingUpdatesDisabledForTesting): * UIProcess/PageClient.h: (WebKit::PageClient::scrollingUpdatesDisabledForTesting): * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp: (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll): * UIProcess/WebPageProxy.h: Tools: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView _scrollingUpdatesDisabledForTesting]): (-[TestRunnerWKWebView _setScrollingUpdatesDisabledForTesting:]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): LayoutTests: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * resources/ui-helper.js: Some 'async' functions that awaited promises should just return the promise. (window.UIHelper.immediateScrollTo): (window.UIHelper.immediateUnstableScrollTo): (window.UIHelper.async.delayFor): Deleted. (window.UIHelper.async.immediateScrollTo): Deleted. (window.UIHelper.async.immediateUnstableScrollTo): Deleted. Canonical link: https://commits.webkit.org/210066@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242979 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-03-15 01:10:09 +00:00
return new Promise(resolve => {
testRunner.runUIScript(`
[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
uiController.immediateScrollToOffset(${x}, ${y}, { unconstrained: ${unconstrained} });`, resolve);
});
}
[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
static immediateUnstableScrollTo(x, y, unconstrained)
{
if (!this.isWebKit2()) {
window.scrollTo(x, y);
return Promise.resolve();
}
Make it possible to test scrolling tree layer manipulation more easily https://bugs.webkit.org/show_bug.cgi?id=195780 Reviewed by Tim Horton. Source/WebKit: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _scrollingUpdatesDisabledForTesting]): (-[WKWebView _setScrollingUpdatesDisabledForTesting:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/Cocoa/PageClientImplCocoa.h: * UIProcess/Cocoa/PageClientImplCocoa.mm: (WebKit::PageClientImplCocoa::scrollingUpdatesDisabledForTesting): * UIProcess/Cocoa/WebPageProxyCocoa.mm: (WebKit::WebPageProxy::scrollingUpdatesDisabledForTesting): * UIProcess/PageClient.h: (WebKit::PageClient::scrollingUpdatesDisabledForTesting): * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp: (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll): * UIProcess/WebPageProxy.h: Tools: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView _scrollingUpdatesDisabledForTesting]): (-[TestRunnerWKWebView _setScrollingUpdatesDisabledForTesting:]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::scrollUpdatesDisabled const): (WTR::UIScriptController::setScrollUpdatesDisabled): LayoutTests: Add a boolean attribute 'scrollUpdatesDisabled' on UIScriptController that cuts off communication of scrolling tree scrolls back to the web process (in RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()). This allows tests to trigger scrolls which run the scrolling tree layer positioning logic, but never get another commit from the web process that might mask scrolling tree bugs. WKWebView's testing protocol get @property _scrollingUpdatesDisabledForTesting, whose getters and setters are overridden by TestRunnerWKWebView. Plumbing via PageClient and WebPageProxy makes this flag reachable by RemoteScrollingCoordinatorProxy. * resources/ui-helper.js: Some 'async' functions that awaited promises should just return the promise. (window.UIHelper.immediateScrollTo): (window.UIHelper.immediateUnstableScrollTo): (window.UIHelper.async.delayFor): Deleted. (window.UIHelper.async.immediateScrollTo): Deleted. (window.UIHelper.async.immediateUnstableScrollTo): Deleted. Canonical link: https://commits.webkit.org/210066@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242979 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-03-15 01:10:09 +00:00
return new Promise(resolve => {
testRunner.runUIScript(`
uiController.stableStateOverride = false;
[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
uiController.immediateScrollToOffset(${x}, ${y}, { unconstrained: ${unconstrained} });`, resolve);
});
}
static immediateScrollElementAtContentPointToOffset(x, y, scrollX, scrollY, scrollUpdatesDisabled = false)
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
uiController.scrollUpdatesDisabled = ${scrollUpdatesDisabled};
uiController.immediateScrollElementAtContentPointToOffset(${x}, ${y}, ${scrollX}, ${scrollY});`, resolve);
});
}
static ensureVisibleContentRectUpdate()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
const visibleContentRectUpdateScript = "uiController.doAfterVisibleContentRectUpdate(() => uiController.uiScriptComplete())";
testRunner.runUIScript(visibleContentRectUpdateScript, resolve);
});
}
Rename force-press-related functions to refer to context menus, and fix a former force-press test https://bugs.webkit.org/show_bug.cgi?id=202663 <rdar://problem/52699530> Reviewed by Dean Jackson. Source/WebKit: Add plumbing for contextMenu tests to function again, and rename all relevant fuctions to more correctly reflect that this does not specifically require a force press to activate any longer. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _didShowContextMenu]): (-[WKWebView _didDismissContextMenu]): (-[WKWebView _didShowForcePressPreview]): Deleted. (-[WKWebView _didDismissForcePressPreview]): Deleted. * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _contextMenuInteraction:configurationForMenuAtLocation:completion:]): (-[WKContentView _presentedViewControllerForPreviewItemController:]): (-[WKContentView _previewItemController:didDismissPreview:committing:]): (-[WKContentView _previewItemControllerDidCancelPreview:]): Tools: Rename all relevant fuctions to more correctly reflect that this does not specifically require a force press to activate any longer. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptContext.h: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setDidShowContextMenuCallback): (WTR::UIScriptController::didShowContextMenuCallback const): (WTR::UIScriptController::setDidDismissContextMenuCallback): (WTR::UIScriptController::didDismissContextMenuCallback const): (WTR::UIScriptController::setDidShowForcePressPreviewCallback): Deleted. (WTR::UIScriptController::didShowForcePressPreviewCallback const): Deleted. (WTR::UIScriptController::setDidDismissForcePressPreviewCallback): Deleted. (WTR::UIScriptController::didDismissForcePressPreviewCallback const): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView resetInteractionCallbacks]): (-[TestRunnerWKWebView _didShowContextMenu]): (-[TestRunnerWKWebView _didDismissContextMenu]): (-[TestRunnerWKWebView _didShowForcePressPreview]): Deleted. (-[TestRunnerWKWebView _didDismissForcePressPreview]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::setDidShowContextMenuCallback): (WTR::UIScriptControllerIOS::setDidDismissContextMenuCallback): (WTR::UIScriptControllerIOS::setDidShowForcePressPreviewCallback): Deleted. (WTR::UIScriptControllerIOS::setDidDismissForcePressPreviewCallback): Deleted. LayoutTests: Move and rename force press test to correctly test context menu functionality. * fast/events/touch/ios/long-press-on-link-expected.txt: Renamed from LayoutTests/platform/iphone-7/fast/events/touch/force-press-on-link-expected.txt. * fast/events/touch/ios/long-press-on-link.html: Added. * platform/iphone-7/fast/events/touch/force-press-on-link.html: Removed. * resources/ui-helper.js: (window.UIHelper.longPressAndGetContextMenuContentAt.return.new.Promise.): (window.UIHelper.longPressAndGetContextMenuContentAt.return.new.Promise): (window.UIHelper.longPressAndGetContextMenuContentAt): (window.UIHelper.waitForInputSessionAt.return.new.Promise.): (window.UIHelper.waitForInputSessionAt.return.new.Promise): (window.UIHelper.waitForInputSessionAt): Canonical link: https://commits.webkit.org/216755@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251522 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-24 02:22:45 +00:00
static longPressAndGetContextMenuContentAt(x, y)
{
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
uiController.didShowContextMenuCallback = function() {
uiController.uiScriptComplete(JSON.stringify(uiController.contentsOfUserInterfaceItem('contextMenu')));
};
uiController.longPressAtPoint(${x}, ${y}, function() { });
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
})();`, result => resolve(JSON.parse(result)));
Rename force-press-related functions to refer to context menus, and fix a former force-press test https://bugs.webkit.org/show_bug.cgi?id=202663 <rdar://problem/52699530> Reviewed by Dean Jackson. Source/WebKit: Add plumbing for contextMenu tests to function again, and rename all relevant fuctions to more correctly reflect that this does not specifically require a force press to activate any longer. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _didShowContextMenu]): (-[WKWebView _didDismissContextMenu]): (-[WKWebView _didShowForcePressPreview]): Deleted. (-[WKWebView _didDismissForcePressPreview]): Deleted. * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _contextMenuInteraction:configurationForMenuAtLocation:completion:]): (-[WKContentView _presentedViewControllerForPreviewItemController:]): (-[WKContentView _previewItemController:didDismissPreview:committing:]): (-[WKContentView _previewItemControllerDidCancelPreview:]): Tools: Rename all relevant fuctions to more correctly reflect that this does not specifically require a force press to activate any longer. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptContext.h: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setDidShowContextMenuCallback): (WTR::UIScriptController::didShowContextMenuCallback const): (WTR::UIScriptController::setDidDismissContextMenuCallback): (WTR::UIScriptController::didDismissContextMenuCallback const): (WTR::UIScriptController::setDidShowForcePressPreviewCallback): Deleted. (WTR::UIScriptController::didShowForcePressPreviewCallback const): Deleted. (WTR::UIScriptController::setDidDismissForcePressPreviewCallback): Deleted. (WTR::UIScriptController::didDismissForcePressPreviewCallback const): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView resetInteractionCallbacks]): (-[TestRunnerWKWebView _didShowContextMenu]): (-[TestRunnerWKWebView _didDismissContextMenu]): (-[TestRunnerWKWebView _didShowForcePressPreview]): Deleted. (-[TestRunnerWKWebView _didDismissForcePressPreview]): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::setDidShowContextMenuCallback): (WTR::UIScriptControllerIOS::setDidDismissContextMenuCallback): (WTR::UIScriptControllerIOS::setDidShowForcePressPreviewCallback): Deleted. (WTR::UIScriptControllerIOS::setDidDismissForcePressPreviewCallback): Deleted. LayoutTests: Move and rename force press test to correctly test context menu functionality. * fast/events/touch/ios/long-press-on-link-expected.txt: Renamed from LayoutTests/platform/iphone-7/fast/events/touch/force-press-on-link-expected.txt. * fast/events/touch/ios/long-press-on-link.html: Added. * platform/iphone-7/fast/events/touch/force-press-on-link.html: Removed. * resources/ui-helper.js: (window.UIHelper.longPressAndGetContextMenuContentAt.return.new.Promise.): (window.UIHelper.longPressAndGetContextMenuContentAt.return.new.Promise): (window.UIHelper.longPressAndGetContextMenuContentAt): (window.UIHelper.waitForInputSessionAt.return.new.Promise.): (window.UIHelper.waitForInputSessionAt.return.new.Promise): (window.UIHelper.waitForInputSessionAt): Canonical link: https://commits.webkit.org/216755@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251522 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-24 02:22:45 +00:00
});
}
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
static activateAndWaitForInputSessionAt(x, y)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
return this.activateAt(x, y);
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
function clearCallbacksAndScriptComplete() {
[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
uiController.didShowContextMenuCallback = null;
uiController.didShowKeyboardCallback = null;
uiController.willPresentPopoverCallback = null;
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
}
[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
uiController.didShowContextMenuCallback = clearCallbacksAndScriptComplete;
uiController.didShowKeyboardCallback = clearCallbacksAndScriptComplete;
uiController.willPresentPopoverCallback = clearCallbacksAndScriptComplete;
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
uiController.singleTapAtPoint(${x}, ${y}, function() { });
})()`, resolve);
});
}
static waitForInputSessionToDismiss()
{
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
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
if (!uiController.isShowingKeyboard && !uiController.isShowingContextMenu && !uiController.isShowingPopover) {
uiController.uiScriptComplete();
return;
}
function clearCallbacksAndScriptComplete() {
uiController.didHideKeyboardCallback = null;
uiController.didDismissPopoverCallback = null;
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
uiController.didDismissContextMenuCallback = null;
uiController.uiScriptComplete();
}
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
uiController.didHideKeyboardCallback = clearCallbacksAndScriptComplete;
uiController.didDismissPopoverCallback = clearCallbacksAndScriptComplete;
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
uiController.didDismissContextMenuCallback = clearCallbacksAndScriptComplete;
})()`, resolve);
});
}
Native text selection UI is incorrectly suppressed in Microsoft Visio https://bugs.webkit.org/show_bug.cgi?id=195178 <rdar://problem/48519394> Reviewed by Darin Adler. Source/WebCore: Currently, our heuristics for detecting hidden editable areas attempt to search for empty parent renderers with "overflow: hidden". It does this by ascending the layer tree in search of renderers that have an empty content size, and whose renderers' styles indicate that they have overflow: hidden in the X or Y directions. This fails in the case where a child renderer is positioned out of flow, relative to one of its parent layers, since the child will be visible, but we'll incorrectly believe that it is hidden. This leads to selection UI unexpectedly disappearing in the online version of Microsoft Visio. To fix this, we check whether the enclosing layer around the editable element has an empty clip rect; if the element is inside of a subframe, we additionally walk up to each enclosing frame's layer and check if that frame's layer has an empty clip rect. Test: editing/selection/ios/do-not-hide-selection-in-visible-container.html * rendering/RenderObject.cpp: (WebCore::RenderObject::isTransparentOrFullyClippedRespectingParentFrames const): LayoutTests: Add a new layout test that focuses several different text fields and checks whether or not editing UI is shown: 1. A text field inside an overflow: hidden container, all within an absolutely positioned iframe, such that the text field is not visible. The caret should be hidden. 2. A text field inside an absolutely positioned iframe, inside an overflow: hidden container, such that the text field is visible. The caret should be visible. 3. A text field inside a relatively positioned iframe in an overflow: hidden container, such that the text field is not visible. The caret should be hidden. 4. A text field that is position: fixed inside an overflow: hidden container, such that the text field is visible. The caret should be visible. * editing/selection/ios/do-not-hide-selection-in-visible-container-expected.txt: Added. * editing/selection/ios/do-not-hide-selection-in-visible-container.html: Added. * editing/selection/ios/hide-selection-in-empty-overflow-hidden-container.html: * resources/ui-helper.js: (window.UIHelper.activateElementAndWaitForInputSession): Add a convenience function in UIHelper that taps a given element and waits for the keyboard to show. Canonical link: https://commits.webkit.org/209653@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242401 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-03-05 00:31:31 +00:00
static activateElementAndWaitForInputSession(element)
{
const x = element.offsetLeft + element.offsetWidth / 2;
const y = element.offsetTop + element.offsetHeight / 2;
return this.activateAndWaitForInputSessionAt(x, y);
}
[iOS] Support inputmode=none https://bugs.webkit.org/show_bug.cgi?id=188896 Reviewed by Tim Horton. LayoutTests/imported/w3c: * web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaseline. Source/WebCore: Updated InputMode.cpp to ensure that "none" is recognized as a valid value for the inputmode attribute. This keyword is useful for content that renders its own keyboard control. Spec: https://html.spec.whatwg.org/multipage/interaction.html#input-modalities%3A-the-inputmode-attribute Test: fast/forms/ios/inputmode-none.html * html/InputMode.cpp: (WebCore::inputModeForAttributeValue): (WebCore::stringForInputMode): (WebCore::InputModeNames::none): * html/InputMode.h: Source/WebKit: inputmode=none is used by content that renders its own keyboard control. Consequently, we should not display the virtual keyboard when a user interacts with an element that has the inputmode attribute set to the "none" value. In order to achieve this behavior, we return a UIView with a bounds of CGRectZero as the inputView of the WKContentView when inputmode=none is present. Furthermore, we do not provide an accessory view in this case. Updated the logic that zooms and scrolls to a control when it gains focus, as that behavior currently relies on an accessory view being present. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): (-[WKContentView inputView]): (-[WKContentView requiresAccessoryView]): (-[WKContentView textInputTraits]): LayoutTests: Added new test to verify that the system keyboard does not show for inputs with inputmode=none. Updated existing inputmode tests to reflect the addition of the "none" value. * fast/forms/inputmode-attribute-contenteditable-expected.txt: * fast/forms/inputmode-attribute-contenteditable.html: * fast/forms/inputmode-attribute-input-expected.txt: * fast/forms/inputmode-attribute-input.html: * fast/forms/inputmode-attribute-textarea-expected.txt: * fast/forms/inputmode-attribute-textarea.html: * fast/forms/ios/inputmode-none-expected.txt: Added. * fast/forms/ios/inputmode-none.html: Added. * resources/ui-helper.js: (window.UIHelper.activateFormControl): (window.UIHelper.inputViewBounds): Canonical link: https://commits.webkit.org/204080@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235426 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-28 16:34:25 +00:00
static activateFormControl(element)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] Support inputmode=none https://bugs.webkit.org/show_bug.cgi?id=188896 Reviewed by Tim Horton. LayoutTests/imported/w3c: * web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaseline. Source/WebCore: Updated InputMode.cpp to ensure that "none" is recognized as a valid value for the inputmode attribute. This keyword is useful for content that renders its own keyboard control. Spec: https://html.spec.whatwg.org/multipage/interaction.html#input-modalities%3A-the-inputmode-attribute Test: fast/forms/ios/inputmode-none.html * html/InputMode.cpp: (WebCore::inputModeForAttributeValue): (WebCore::stringForInputMode): (WebCore::InputModeNames::none): * html/InputMode.h: Source/WebKit: inputmode=none is used by content that renders its own keyboard control. Consequently, we should not display the virtual keyboard when a user interacts with an element that has the inputmode attribute set to the "none" value. In order to achieve this behavior, we return a UIView with a bounds of CGRectZero as the inputView of the WKContentView when inputmode=none is present. Furthermore, we do not provide an accessory view in this case. Updated the logic that zooms and scrolls to a control when it gains focus, as that behavior currently relies on an accessory view being present. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): (-[WKContentView inputView]): (-[WKContentView requiresAccessoryView]): (-[WKContentView textInputTraits]): LayoutTests: Added new test to verify that the system keyboard does not show for inputs with inputmode=none. Updated existing inputmode tests to reflect the addition of the "none" value. * fast/forms/inputmode-attribute-contenteditable-expected.txt: * fast/forms/inputmode-attribute-contenteditable.html: * fast/forms/inputmode-attribute-input-expected.txt: * fast/forms/inputmode-attribute-input.html: * fast/forms/inputmode-attribute-textarea-expected.txt: * fast/forms/inputmode-attribute-textarea.html: * fast/forms/ios/inputmode-none-expected.txt: Added. * fast/forms/ios/inputmode-none.html: Added. * resources/ui-helper.js: (window.UIHelper.activateFormControl): (window.UIHelper.inputViewBounds): Canonical link: https://commits.webkit.org/204080@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235426 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-28 16:34:25 +00:00
return this.activateElement(element);
const x = element.offsetLeft + element.offsetWidth / 2;
const y = element.offsetTop + element.offsetHeight / 2;
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
uiController.didStartFormControlInteractionCallback = function() {
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
[iOS] Support inputmode=none https://bugs.webkit.org/show_bug.cgi?id=188896 Reviewed by Tim Horton. LayoutTests/imported/w3c: * web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaseline. Source/WebCore: Updated InputMode.cpp to ensure that "none" is recognized as a valid value for the inputmode attribute. This keyword is useful for content that renders its own keyboard control. Spec: https://html.spec.whatwg.org/multipage/interaction.html#input-modalities%3A-the-inputmode-attribute Test: fast/forms/ios/inputmode-none.html * html/InputMode.cpp: (WebCore::inputModeForAttributeValue): (WebCore::stringForInputMode): (WebCore::InputModeNames::none): * html/InputMode.h: Source/WebKit: inputmode=none is used by content that renders its own keyboard control. Consequently, we should not display the virtual keyboard when a user interacts with an element that has the inputmode attribute set to the "none" value. In order to achieve this behavior, we return a UIView with a bounds of CGRectZero as the inputView of the WKContentView when inputmode=none is present. Furthermore, we do not provide an accessory view in this case. Updated the logic that zooms and scrolls to a control when it gains focus, as that behavior currently relies on an accessory view being present. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): (-[WKContentView inputView]): (-[WKContentView requiresAccessoryView]): (-[WKContentView textInputTraits]): LayoutTests: Added new test to verify that the system keyboard does not show for inputs with inputmode=none. Updated existing inputmode tests to reflect the addition of the "none" value. * fast/forms/inputmode-attribute-contenteditable-expected.txt: * fast/forms/inputmode-attribute-contenteditable.html: * fast/forms/inputmode-attribute-input-expected.txt: * fast/forms/inputmode-attribute-input.html: * fast/forms/inputmode-attribute-textarea-expected.txt: * fast/forms/inputmode-attribute-textarea.html: * fast/forms/ios/inputmode-none-expected.txt: Added. * fast/forms/ios/inputmode-none.html: Added. * resources/ui-helper.js: (window.UIHelper.activateFormControl): (window.UIHelper.inputViewBounds): Canonical link: https://commits.webkit.org/204080@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235426 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-28 16:34:25 +00:00
};
uiController.singleTapAtPoint(${x}, ${y}, function() { });
})()`, resolve);
});
}
REGRESSION (r240757): Cannot dismiss the keyboard on http://apple.com/apple-tv-plus https://bugs.webkit.org/show_bug.cgi?id=198922 <rdar://problem/50300056> Reviewed by Wenson Hsieh. Source/WebKit: Actually dismiss the keyboard as intended in r240757. Do not wait for the round-trip to the WebProcess to run through the -elementDidBlur steps in the UIProcess and hide the keyboard when a person explicitly dismisses the keyboard via the Done button (iPhone) or hide keyboard button (iPad). Note that r240757 revealed another bug in this code, <https://bugs.webkit.org/show_bug.cgi?id=198928>. I am unclear of the implications of that bug, but it is clear for this bug that it never makes sense to round-trip to the WebProcess when the keyboard is dismissed by a user gesture. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView endEditingAndUpdateFocusAppearanceWithReason:]): Invoke -_elementDidBlur to blur the element in the UIProcess and hide the keyboard. (-[WKContentView _elementDidBlur]): Prevent duplicate invocations of -didEndFormControlInteraction and setIsShowingInputViewForFocusedElement messages by only doing these actions when editablity changes. This covers the case where -_elementDidBlur may be invoked a second time (the reply in the round-trip). In that case we don't need to do these actions. LayoutTests: Add a test to ensure that pressing Done hides the keyboard after tapping outside the focused element's frame. * fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field-expected.txt: Added. * fast/events/ios/should-be-able-to-dismiss-form-accessory-after-tapping-outside-iframe-with-focused-field.html: Added. * resources/ui-helper.js: (window.UIHelper.dismissFormAccessoryView): Added. Canonical link: https://commits.webkit.org/212962@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246570 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-18 21:50:20 +00:00
static dismissFormAccessoryView()
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
uiController.dismissFormAccessoryView();
uiController.uiScriptComplete();
})()`, resolve);
});
}
fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html does not work on iPad https://bugs.webkit.org/show_bug.cgi?id=194313 Reviewed by Tim Horton. Source/WebKit: Make `-dateTimePickerCalendarType` work on iPad by handling the case where the date picker control is a WKDateTimePopover. This fixes UIScriptController::calendarType() returning null on iPad. * UIProcess/ios/forms/WKFormInputControl.mm: (-[WKFormInputControl dateTimePickerCalendarType]): (-[WKDateTimePopover calendarType]): Tools: Add a helper to determine whether the web view is presenting modal UI. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::calendarType const): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): (WTR::UIScriptController::calendarType const): * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::calendarType const): LayoutTests: Adjusts an existing layout test to work on both iPhone and iPad simulators. * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry-expected.txt: * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html: Make this test wait after blurring the currently focused element, such that tapping to focus the next form control doesn't fail. Notably on iPad, not waiting for the popover to dismiss meant that subsequent taps would be dispatched too soon, and hit-test to the popover view being dismissed rather than WKWebView. * platform/ipad/TestExpectations: Unskip the test on iPad. * resources/ui-helper.js: Add helpers to query whether or not the keyboard is shown, and whether or not a view controller is being modally presented over the current root view controller (this is the case when interacting with date pickers on iPad). (window.UIHelper.isShowingKeyboard): (window.UIHelper.isPresentingModally): (window.UIHelper.deactivateFormControl): Add a new helper method to blur the given form control element and wait for web view chrome to finish dismissing (on iOS, this is either the date picker input view in the keyboard on iPhone, or the date picker popover view controller on iPad). (window.UIHelper.isShowingDataListSuggestions): Drive-by fix: remove an extraneous ternary conditional statement. Canonical link: https://commits.webkit.org/208934@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241275 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 19:30:05 +00:00
static isShowingKeyboard()
{
return new Promise(resolve => {
testRunner.runUIScript("uiController.isShowingKeyboard", result => resolve(result === "true"));
});
}
[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
static isShowingPopover()
{
return new Promise(resolve => {
testRunner.runUIScript("uiController.isShowingPopover", result => resolve(result === "true"));
});
}
Touching media controls sometimes shows software keyboard https://bugs.webkit.org/show_bug.cgi?id=199490 <rdar://problem/52076270> Reviewed by Eric Carlson. Source/WebKit: In r243044, we added a compatibility hack for Google Slides (and other G-suite properties) to allow the on- screen keyboard to show up after a prevented touch event in the case where an element was already focused, even if the touch event handler doesn't explicitly refocus the element. However, this means that if a regular text field (or other form control) has been programmatically focused, then interacting with any other element that prevents default on touchstart will cause us to show the keyboard for that focused element. To mitigate this, only fall down this refocusing codepath in the case where the focused element is a hidden editable element (in the style of many Google productivity web apps). For non-hidden editable elements that are already focused, this refocusing logic is not necessary, since the user should be able to interact with the control to show the keyboard anyways; for hidden editable areas, this compatibility hack is actually needed, since there is typically no other way for a user to focus these elements and show an on-screen keyboard. Tests: fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::dispatchTouchEvent): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::isTransparentOrFullyClipped const): Renamed from enclosingLayerIsTransparentOrFullyClipped, and pulled out into a private helper method. (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::requestEvasionRectsAboveSelection): (WebKit::WebPage::getFocusedElementInformation): (WebKit::enclosingLayerIsTransparentOrFullyClipped): Deleted. Tools: Adds plumbing for a new testing hook to check whether or not there is an active input session. See other ChangeLog entries for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::hasInputSession const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::hasInputSession const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::hasInputSession const): LayoutTests: Adds a new layout test to verify that the keyboard only appears after a handled touch event if the focused element is inside a hidden editable area; otherwise, the keyboard should not be present. * fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt: Added. * fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html: Added. This test passes as long as we didn't begin showing the keyboard after tapping. * fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt: * fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html: Adjust this existing test to make the focused textarea hidden. * resources/ui-helper.js: (window.UIHelper.hasInputSession): Add a new testing hook to check whether there is an active input session. Canonical link: https://commits.webkit.org/213421@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247158 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-05 16:22:42 +00:00
static hasInputSession()
{
return new Promise(resolve => {
testRunner.runUIScript("uiController.hasInputSession", result => resolve(result === "true"));
});
}
fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html does not work on iPad https://bugs.webkit.org/show_bug.cgi?id=194313 Reviewed by Tim Horton. Source/WebKit: Make `-dateTimePickerCalendarType` work on iPad by handling the case where the date picker control is a WKDateTimePopover. This fixes UIScriptController::calendarType() returning null on iPad. * UIProcess/ios/forms/WKFormInputControl.mm: (-[WKFormInputControl dateTimePickerCalendarType]): (-[WKDateTimePopover calendarType]): Tools: Add a helper to determine whether the web view is presenting modal UI. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::calendarType const): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): (WTR::UIScriptController::calendarType const): * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::calendarType const): LayoutTests: Adjusts an existing layout test to work on both iPhone and iPad simulators. * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry-expected.txt: * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html: Make this test wait after blurring the currently focused element, such that tapping to focus the next form control doesn't fail. Notably on iPad, not waiting for the popover to dismiss meant that subsequent taps would be dispatched too soon, and hit-test to the popover view being dismissed rather than WKWebView. * platform/ipad/TestExpectations: Unskip the test on iPad. * resources/ui-helper.js: Add helpers to query whether or not the keyboard is shown, and whether or not a view controller is being modally presented over the current root view controller (this is the case when interacting with date pickers on iPad). (window.UIHelper.isShowingKeyboard): (window.UIHelper.isPresentingModally): (window.UIHelper.deactivateFormControl): Add a new helper method to blur the given form control element and wait for web view chrome to finish dismissing (on iOS, this is either the date picker input view in the keyboard on iPhone, or the date picker popover view controller on iPad). (window.UIHelper.isShowingDataListSuggestions): Drive-by fix: remove an extraneous ternary conditional statement. Canonical link: https://commits.webkit.org/208934@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241275 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 19:30:05 +00:00
static isPresentingModally()
{
return new Promise(resolve => {
testRunner.runUIScript("uiController.isPresentingModally", result => resolve(result === "true"));
});
}
static deactivateFormControl(element)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily()) {
fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html does not work on iPad https://bugs.webkit.org/show_bug.cgi?id=194313 Reviewed by Tim Horton. Source/WebKit: Make `-dateTimePickerCalendarType` work on iPad by handling the case where the date picker control is a WKDateTimePopover. This fixes UIScriptController::calendarType() returning null on iPad. * UIProcess/ios/forms/WKFormInputControl.mm: (-[WKFormInputControl dateTimePickerCalendarType]): (-[WKDateTimePopover calendarType]): Tools: Add a helper to determine whether the web view is presenting modal UI. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::calendarType const): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): (WTR::UIScriptController::calendarType const): * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::calendarType const): LayoutTests: Adjusts an existing layout test to work on both iPhone and iPad simulators. * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry-expected.txt: * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html: Make this test wait after blurring the currently focused element, such that tapping to focus the next form control doesn't fail. Notably on iPad, not waiting for the popover to dismiss meant that subsequent taps would be dispatched too soon, and hit-test to the popover view being dismissed rather than WKWebView. * platform/ipad/TestExpectations: Unskip the test on iPad. * resources/ui-helper.js: Add helpers to query whether or not the keyboard is shown, and whether or not a view controller is being modally presented over the current root view controller (this is the case when interacting with date pickers on iPad). (window.UIHelper.isShowingKeyboard): (window.UIHelper.isPresentingModally): (window.UIHelper.deactivateFormControl): Add a new helper method to blur the given form control element and wait for web view chrome to finish dismissing (on iOS, this is either the date picker input view in the keyboard on iPhone, or the date picker popover view controller on iPad). (window.UIHelper.isShowingDataListSuggestions): Drive-by fix: remove an extraneous ternary conditional statement. Canonical link: https://commits.webkit.org/208934@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241275 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 19:30:05 +00:00
element.blur();
return Promise.resolve();
}
return new Promise(async resolve => {
element.blur();
while (await this.isPresentingModally())
continue;
while (await this.isShowingKeyboard())
continue;
resolve();
});
}
[iPad] Should open popover when the spacebar is pressed https://bugs.webkit.org/show_bug.cgi?id=196360 <rdar://problem/49389129> Patch by Daniel Bates <dabates@apple.com> on 2019-04-09 Reviewed by Brent Fulgham. Source/WebKit: Pressing the spacebar should open the popover for a focused popup button (e.g. <select>) on iOS just like it does on the Mac. For now, we keep the iPhone behavior of blurring the element when the Done button is pressed and hence pressing spacebar does nothing (because there is no focused element). * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView accessoryOpen]): Added. Extracted the logic from -_elementDidFocus to scroll to the focused element, update the accessory and then tell the accessory to begin editing. (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): Write in terms of -accessoryOpen. * UIProcess/ios/forms/WKFormPeripheralBase.mm: (-[WKFormPeripheralBase handleKeyEvent:]): Interpret the spacebar when the peripheral is closed (!_editing) and call -accessoryOpen to ultimately call back to this peripheral to tell it to begin editing, which will cause the popover to appear again. Tools: Add testing infrastructure to support waiting for a popover to be presented or dismissed. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptContext.h: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setWillPresentPopoverCallback): Added. (WTR::UIScriptController::willPresentPopoverCallback const): Added. (WTR::UIScriptController::setDidDismissPopoverCallback): Added. (WTR::UIScriptController::didDismissPopoverCallback const): Added. (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): Update some state. (-[TestRunnerWKWebView resetInteractionCallbacks]): Ditto. (-[TestRunnerWKWebView _willPresentPopover]): Added. (-[TestRunnerWKWebView _didDismissPopover]): Added. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. LayoutTests: Add an iPad-specific test to ensure that pressing the spacebar opens the popover and scrolls the form control into view. * fast/forms/ios/ipad/open-picker-using-keyboard-expected.txt: Added. * fast/forms/ios/ipad/open-picker-using-keyboard.html: Added. * platform/ios/TestExpectations: Skip tests in fast/forms/ios/ipad. We will unskip for iPad below. * platform/ipad/TestExpectations: Mark tests in fast/forms/ios/ipad as PASS so we run them. * resources/ui-helper.js: (window.UIHelper.waitForPopoverToPresent): (window.UIHelper.waitForPopoverToDismiss): Canonical link: https://commits.webkit.org/211030@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244096 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-09 21:45:03 +00:00
static waitForPopoverToPresent()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iPad] Should open popover when the spacebar is pressed https://bugs.webkit.org/show_bug.cgi?id=196360 <rdar://problem/49389129> Patch by Daniel Bates <dabates@apple.com> on 2019-04-09 Reviewed by Brent Fulgham. Source/WebKit: Pressing the spacebar should open the popover for a focused popup button (e.g. <select>) on iOS just like it does on the Mac. For now, we keep the iPhone behavior of blurring the element when the Done button is pressed and hence pressing spacebar does nothing (because there is no focused element). * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView accessoryOpen]): Added. Extracted the logic from -_elementDidFocus to scroll to the focused element, update the accessory and then tell the accessory to begin editing. (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): Write in terms of -accessoryOpen. * UIProcess/ios/forms/WKFormPeripheralBase.mm: (-[WKFormPeripheralBase handleKeyEvent:]): Interpret the spacebar when the peripheral is closed (!_editing) and call -accessoryOpen to ultimately call back to this peripheral to tell it to begin editing, which will cause the popover to appear again. Tools: Add testing infrastructure to support waiting for a popover to be presented or dismissed. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptContext.h: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setWillPresentPopoverCallback): Added. (WTR::UIScriptController::willPresentPopoverCallback const): Added. (WTR::UIScriptController::setDidDismissPopoverCallback): Added. (WTR::UIScriptController::didDismissPopoverCallback const): Added. (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): Update some state. (-[TestRunnerWKWebView resetInteractionCallbacks]): Ditto. (-[TestRunnerWKWebView _willPresentPopover]): Added. (-[TestRunnerWKWebView _didDismissPopover]): Added. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. LayoutTests: Add an iPad-specific test to ensure that pressing the spacebar opens the popover and scrolls the form control into view. * fast/forms/ios/ipad/open-picker-using-keyboard-expected.txt: Added. * fast/forms/ios/ipad/open-picker-using-keyboard.html: Added. * platform/ios/TestExpectations: Skip tests in fast/forms/ios/ipad. We will unskip for iPad below. * platform/ipad/TestExpectations: Mark tests in fast/forms/ios/ipad as PASS so we run them. * resources/ui-helper.js: (window.UIHelper.waitForPopoverToPresent): (window.UIHelper.waitForPopoverToDismiss): Canonical link: https://commits.webkit.org/211030@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244096 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-09 21:45:03 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (uiController.isShowingPopover)
uiController.uiScriptComplete();
else
uiController.willPresentPopoverCallback = () => uiController.uiScriptComplete();
})()`, resolve);
});
}
static waitForPopoverToDismiss()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iPad] Should open popover when the spacebar is pressed https://bugs.webkit.org/show_bug.cgi?id=196360 <rdar://problem/49389129> Patch by Daniel Bates <dabates@apple.com> on 2019-04-09 Reviewed by Brent Fulgham. Source/WebKit: Pressing the spacebar should open the popover for a focused popup button (e.g. <select>) on iOS just like it does on the Mac. For now, we keep the iPhone behavior of blurring the element when the Done button is pressed and hence pressing spacebar does nothing (because there is no focused element). * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView accessoryOpen]): Added. Extracted the logic from -_elementDidFocus to scroll to the focused element, update the accessory and then tell the accessory to begin editing. (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): Write in terms of -accessoryOpen. * UIProcess/ios/forms/WKFormPeripheralBase.mm: (-[WKFormPeripheralBase handleKeyEvent:]): Interpret the spacebar when the peripheral is closed (!_editing) and call -accessoryOpen to ultimately call back to this peripheral to tell it to begin editing, which will cause the popover to appear again. Tools: Add testing infrastructure to support waiting for a popover to be presented or dismissed. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptContext.h: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setWillPresentPopoverCallback): Added. (WTR::UIScriptController::willPresentPopoverCallback const): Added. (WTR::UIScriptController::setDidDismissPopoverCallback): Added. (WTR::UIScriptController::didDismissPopoverCallback const): Added. (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): Update some state. (-[TestRunnerWKWebView resetInteractionCallbacks]): Ditto. (-[TestRunnerWKWebView _willPresentPopover]): Added. (-[TestRunnerWKWebView _didDismissPopover]): Added. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingPopover const): Added. (WTR::UIScriptController::platformSetWillPresentPopoverCallback): Added. (WTR::UIScriptController::platformSetDidDismissPopoverCallback): Added. LayoutTests: Add an iPad-specific test to ensure that pressing the spacebar opens the popover and scrolls the form control into view. * fast/forms/ios/ipad/open-picker-using-keyboard-expected.txt: Added. * fast/forms/ios/ipad/open-picker-using-keyboard.html: Added. * platform/ios/TestExpectations: Skip tests in fast/forms/ios/ipad. We will unskip for iPad below. * platform/ipad/TestExpectations: Mark tests in fast/forms/ios/ipad as PASS so we run them. * resources/ui-helper.js: (window.UIHelper.waitForPopoverToPresent): (window.UIHelper.waitForPopoverToDismiss): Canonical link: https://commits.webkit.org/211030@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244096 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-09 21:45:03 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (uiController.isShowingPopover)
uiController.didDismissPopoverCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
})()`, resolve);
});
}
[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
static waitForContextMenuToShow()
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (!uiController.isShowingContextMenu)
uiController.didShowContextMenuCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
})()`, resolve);
});
}
[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
static waitForContextMenuToHide()
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (uiController.isShowingContextMenu)
uiController.didDismissContextMenuCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
})()`, resolve);
});
}
[Extra zoom mode] Programmatically changing focus when an element already has focus is a confusing experience https://bugs.webkit.org/show_bug.cgi?id=184635 <rdar://problem/39440642> Reviewed by Tim Horton. Source/WebKit: Currently on iOS, we allow element focus to present UI if the keyboard is already shown. In extra zoom mode, this would lead to a confusing experience when the focus form control overlay is disabled, since fullscreen input view controllers are swapped out from underneath the user. Currently, this also puts the UI process into a bad state where the focused form control overlay is active, but still hidden. This patch makes some tweaks to input view controller handling in the UI process to address these issues, and also adds WebKitTestRunner support for simulating interactions with select menus in extra zoom mode. See comments below for more detail. Test: fast/events/extrazoom/change-focus-during-change-event.html * UIProcess/API/Cocoa/WKUIDelegatePrivate.h: Add new SPI delegate hooks to notify the UI delegate when view controllers are presented or dismissed in extra zoom mode. See -presentViewControllerForCurrentAssistedNode and -dismissAllInputViewControllers. * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::takeBackgroundActivityTokenForFullscreenInput): (WebKit::WebProcessProxy::releaseBackgroundActivityTokenForFullscreenInput): See the comment below -dismissAllInputViewControllers. * UIProcess/WebProcessProxy.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): In extra zoom mode, when changing focus from one assisted node to another, only allow the second node to be assisted if the focused form control overlay is being shown. Otherwise, (i.e. when a fullscreen input view controller is being presented), don't allow focus to start an input session. Additionally, make a minor tweak to allow the previous node to blur, even if we are not showing the keyboard for the new focused element. Without this adjustment, in the case where the page has programmatically focused another element while a fullscreen input view controller is presented, we'll show the old view controller for the new focused element. (-[WKContentView presentViewControllerForCurrentAssistedNode]): (-[WKContentView dismissAllInputViewControllers:]): Currently, when a fullscreen input view controller is presented, the web process gets backgrounded. This prevents event handlers from executing, which leads to strange behaviors in many cases (for instance: if we have a multiple select, and the "change" event handler blurs the select, the user may check or uncheck multiple items, but only the first change will actually take effect). To fix this, we maintain a background activity token while presenting an input view controller. (-[WKContentView focusedFormControlViewDidBeginEditing:]): Start hiding the focused form overlay when re-presenting an input view controller. This allows us to bail from showing fullscreen input UI for another focused element if focus programmatically changes while the current fullscreen input view controller is presented, due to the -isHidden check in -_startAssistingNode:. (-[WKContentView selectFormAccessoryPickerRow:]): Simulate tapping a given row in select menu UI in extra zoom mode. Tools: Add plumbing to support invoking `didHideKeyboardCallback` and `didShowKeyboardCallback` when (respectively) dismissing or presenting fullscreen input view controllers in extra zoom mode. * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView dealloc]): (-[TestRunnerWKWebView _invokeShowKeyboardCallbackIfNecessary]): (-[TestRunnerWKWebView _invokeHideKeyboardCallbackIfNecessary]): (-[TestRunnerWKWebView _keyboardDidShow:]): (-[TestRunnerWKWebView _keyboardDidHide:]): (-[TestRunnerWKWebView _webView:didPresentFocusedElementViewController:]): (-[TestRunnerWKWebView _webView:didDismissFocusedElementViewController:]): LayoutTests: Add a new layout test to exercise the following sequence of events in extra zoom mode: 1. Focus select element #1. 2. Choose an unselected option. 3. Programmatically focus select element #2 in the "change" event handler. 4. Choose an unselected option. 5. Programmatically blur select element #2 in the "change" event handler. * fast/events/extrazoom/change-focus-during-change-event-expected.txt: Added. * fast/events/extrazoom/change-focus-during-change-event.html: Added. * resources/ui-helper.js: (window.UIHelper.waitForKeyboardToHide.return.new.Promise): (window.UIHelper.waitForKeyboardToHide): Canonical link: https://commits.webkit.org/200238@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230752 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-18 06:03:06 +00:00
static waitForKeyboardToHide()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] [Datalist] Can't pick datalist suggestions in a stock WKWebView https://bugs.webkit.org/show_bug.cgi?id=190621 <rdar://problem/45310649> Reviewed by Tim Horton. Source/WebKit: Fixes the bug by refactoring datalist suggestion information on iOS; currently, we override text suggestions on _WKFormInputSession. This only works for a few internal clients (including Safari) that set a _WKInputDelegate and also implement either -_webView:willStartInputSession: or -_webView:didStartInputSession:, which is necessary in order to ensure that WebKit creates and maintains a form input session. The two pieces of information that datalist code needs to vend to WKContentView are a list of UITextSuggestions and a custom input view, which are both currently properties of _WKFormInputSession. This patch lifts these out of the input session and makes them properties of WKContentView, which are used in WebDataListSuggestionsDropdownIOS. Test: fast/forms/datalist/datalist-textinput-suggestions-order.html * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: Add new properties to WKContentView: an input view for datalist suggestions, and a list of text suggestions. (-[WKFormInputSession setSuggestions:]): (-[WKContentView setupInteraction]): (-[WKContentView cleanupInteraction]): (-[WKContentView _endEditing]): Pull out common logic when resigning first responder or tabbing to the next or previous text field into a new helper. This helper notifies `_inputPeripheral`, `_formInputSession`, and `_dataListTextSuggestionsInputView` when editing has ended; the input peripheral and suggestions input view use this chance to send the value of the form control to the web process. (-[WKContentView resignFirstResponderForWebView]): (-[WKContentView inputView]): If a custom input view is not set but we have an input view for a datalist's text suggestions, use the datalist input view. (-[WKContentView accessoryTab:]): (-[WKContentView _stopAssistingNode]): Clear datalist state on WKContentView. (-[WKContentView dataListTextSuggestionsInputView]): (-[WKContentView dataListTextSuggestions]): (-[WKContentView setDataListTextSuggestionsInputView:]): (-[WKContentView setDataListTextSuggestions:]): (-[WKContentView updateTextSuggestionsForInputDelegate]): Pull out logic for setting suggestions on UIKit's `inputDelegate` (i.e. UIKeyboardImpl). We now first consult internally-vended text suggestions from _WKFormInputSession; if an internal client has not overridden our text suggestions, then we simply use suggestions from the current datalist (if present). * UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm: (-[WKDataListSuggestionsPicker updateWithInformation:]): (-[WKDataListSuggestionsPicker showSuggestionsDropdown:activationType:]): (-[WKDataListSuggestionsPicker invalidate]): (-[WKDataListSuggestionsPopover updateWithInformation:]): (-[WKDataListSuggestionsPopover showSuggestionsDropdown:activationType:]): (-[WKDataListSuggestionsPopover didSelectOptionAtIndex:]): Change all the places that currently manipulate WKContentView's form input session to directly set text suggestions and the text suggestion input view on the content view instead. Tools: Add a UIScriptController hook to resign first responder on WKWebView. See LayoutTests/ChangeLog for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::resignFirstResponder): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::resignFirstResponder): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::resignFirstResponder): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::resignFirstResponder): * WebKitTestRunner/ios/PlatformWebViewIOS.mm: (WTR::PlatformWebView::makeWebViewFirstResponder): Implement this method stub on iOS, to ensure that TestController::resetStateToConsistentValues restores first responder on the WKWebView when running iOS layout tests. * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): After resigning first responder to dismiss any on-screen keyboard, ensure that we restore first responder. LayoutTests: Refactor an existing layout test to run on both iOS and macOS. On both platforms, it checks that the top suggestion respects option element order in the document, as well as the current contents of the text field. On macOS, we use arrow keys and hit return to select a suggestion; on iOS, we tap the suggestions button and simulate hitting the done button on the input view to dismiss the keyboard. * fast/forms/datalist/datalist-textinput-suggestions-order-expected.txt: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * platform/ios/TestExpectations: Enable this test on iOS. * resources/ui-helper.js: (window.UIHelper.resignFirstResponder): (window.UIHelper): Canonical link: https://commits.webkit.org/205670@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237305 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-19 22:00:32 +00:00
return Promise.resolve();
[Extra zoom mode] Programmatically changing focus when an element already has focus is a confusing experience https://bugs.webkit.org/show_bug.cgi?id=184635 <rdar://problem/39440642> Reviewed by Tim Horton. Source/WebKit: Currently on iOS, we allow element focus to present UI if the keyboard is already shown. In extra zoom mode, this would lead to a confusing experience when the focus form control overlay is disabled, since fullscreen input view controllers are swapped out from underneath the user. Currently, this also puts the UI process into a bad state where the focused form control overlay is active, but still hidden. This patch makes some tweaks to input view controller handling in the UI process to address these issues, and also adds WebKitTestRunner support for simulating interactions with select menus in extra zoom mode. See comments below for more detail. Test: fast/events/extrazoom/change-focus-during-change-event.html * UIProcess/API/Cocoa/WKUIDelegatePrivate.h: Add new SPI delegate hooks to notify the UI delegate when view controllers are presented or dismissed in extra zoom mode. See -presentViewControllerForCurrentAssistedNode and -dismissAllInputViewControllers. * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::takeBackgroundActivityTokenForFullscreenInput): (WebKit::WebProcessProxy::releaseBackgroundActivityTokenForFullscreenInput): See the comment below -dismissAllInputViewControllers. * UIProcess/WebProcessProxy.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): In extra zoom mode, when changing focus from one assisted node to another, only allow the second node to be assisted if the focused form control overlay is being shown. Otherwise, (i.e. when a fullscreen input view controller is being presented), don't allow focus to start an input session. Additionally, make a minor tweak to allow the previous node to blur, even if we are not showing the keyboard for the new focused element. Without this adjustment, in the case where the page has programmatically focused another element while a fullscreen input view controller is presented, we'll show the old view controller for the new focused element. (-[WKContentView presentViewControllerForCurrentAssistedNode]): (-[WKContentView dismissAllInputViewControllers:]): Currently, when a fullscreen input view controller is presented, the web process gets backgrounded. This prevents event handlers from executing, which leads to strange behaviors in many cases (for instance: if we have a multiple select, and the "change" event handler blurs the select, the user may check or uncheck multiple items, but only the first change will actually take effect). To fix this, we maintain a background activity token while presenting an input view controller. (-[WKContentView focusedFormControlViewDidBeginEditing:]): Start hiding the focused form overlay when re-presenting an input view controller. This allows us to bail from showing fullscreen input UI for another focused element if focus programmatically changes while the current fullscreen input view controller is presented, due to the -isHidden check in -_startAssistingNode:. (-[WKContentView selectFormAccessoryPickerRow:]): Simulate tapping a given row in select menu UI in extra zoom mode. Tools: Add plumbing to support invoking `didHideKeyboardCallback` and `didShowKeyboardCallback` when (respectively) dismissing or presenting fullscreen input view controllers in extra zoom mode. * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView dealloc]): (-[TestRunnerWKWebView _invokeShowKeyboardCallbackIfNecessary]): (-[TestRunnerWKWebView _invokeHideKeyboardCallbackIfNecessary]): (-[TestRunnerWKWebView _keyboardDidShow:]): (-[TestRunnerWKWebView _keyboardDidHide:]): (-[TestRunnerWKWebView _webView:didPresentFocusedElementViewController:]): (-[TestRunnerWKWebView _webView:didDismissFocusedElementViewController:]): LayoutTests: Add a new layout test to exercise the following sequence of events in extra zoom mode: 1. Focus select element #1. 2. Choose an unselected option. 3. Programmatically focus select element #2 in the "change" event handler. 4. Choose an unselected option. 5. Programmatically blur select element #2 in the "change" event handler. * fast/events/extrazoom/change-focus-during-change-event-expected.txt: Added. * fast/events/extrazoom/change-focus-during-change-event.html: Added. * resources/ui-helper.js: (window.UIHelper.waitForKeyboardToHide.return.new.Promise): (window.UIHelper.waitForKeyboardToHide): Canonical link: https://commits.webkit.org/200238@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230752 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-18 06:03:06 +00:00
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
[iOS] Can't select text after dismissing the keyboard when changing focus https://bugs.webkit.org/show_bug.cgi?id=190563 <rdar://problem/44613559> Reviewed by Tim Horton. Source/WebKit: In r230686, we switched from using UIWKSelectionAssistant to UIWKTextInteractionAssistant for handling selection in non-editable content on iOS; as such, when an editable element loses focus, instead of switching from the text interaction assistant to the web selection assistant as we've previously done, we now reset our text interaction assistant by calling `-[UIWKTextInteractionAssistant setGestureRecognizers]`, which removes all of the current text selection gesture recognizers from WKContentView and regenerates them by building up a tree of `UITextInteraction`s and adding them to the assistant (see `-[UITextInteractionAssistant addGestureRecognizersToView:]`). In particular, `_UITextSelectionForceGesture` is the gesture recognizer used to trigger text selection when long pressing. After dismissing the keyboard by tapping the "Done" button, the UITextInteractions and gesture recognizers on the interaction assistant include: <UITextInteraction> … <UITextIndirectNonEditableInteraction> <_UIKeyboardBasedNonEditableTextSelectionInteraction> ↳ "_UIKeyboardTextSelectionGestureForcePress" → <_UITextSelectionForceGesture> However, after the keyboard dismisses due to an editable element losing focus, the UITextInteractions on the interaction assistant look like this: <UITextInteraction> … <UITextIndirectNonEditableInteraction> Subsequently, the lack of a `_UIKeyboardBasedNonEditableTextSelectionInteraction` makes text selection by long pressing impossible, since the `_UITextSelectionForceGesture` is never introduced to `WKContentView`. In UIKit, `UITextIndirectNonEditableInteraction` only adds `_UIKeyboardBasedNonEditableTextSelectionInteraction` as a child if the text input view — in our case, WKContentView — is missing an input delegate (see `-initWithView:`). In the case where the Done button is used to dismiss the keyboard, WKContentView loses first responder, and the input delegate of WKContentView is cleared out early on, before we call `-stopAssistingKeyboard`: -[WKContentView(WKInteraction) setInputDelegate:] -[UIKeyboardImpl setDelegate:force:] -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] -[UIResponder _finishResignFirstResponder] -[UIResponder resignFirstResponder] -[WKContentView(WKInteraction) resignFirstResponderForWebView] -[UIKeyboardImpl dismissKeyboard] However, in the case where the focused element is blurred, we end up clearing out the delegate in `-_stopAssistingNode`, *after* we've already called `-setGestureRecognizers` on the interaction assistant. This means UIKit will skip adding `_UIKeyboardBasedNonEditableTextSelectionInteraction` to the text interaction assistant. -[WKContentView(WKInteraction) setInputDelegate:] -[UIKeyboardImpl setDelegate:force:] -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] -[UIResponder(UIResponderInputViewAdditions) reloadInputViews] -[WKContentView(WKInteraction) _stopAssistingNode] To fix this, we simply reset our `inputDelegate` earlier in `_stopAssistingKeyboard` instead of waiting until we reload input views. This ensures that UIKit sets up the text interaction assistant's gestures when changing focus in the same way as we would when the keyboard is dismissed via `-resignFirstResponder` (e.g. when pressing the Done button). Test: editing/selection/ios/select-text-after-changing-focus.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView setupInteraction]): (-[WKContentView setUpTextSelectionAssistant]): (-[WKContentView _startAssistingKeyboard]): (-[WKContentView _stopAssistingKeyboard]): (-[WKContentView useSelectionAssistantWithGranularity:]): Deleted. Additionally rename this to -setUpTextSelectionAssistant and remove the selection granularity argument. This was previously used to switch between web and text interaction assistants. Tools: * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingKeyboard const): Add a new UIScriptController method that returns whether the keyboard is shown. See `ui-helper.js` for more details. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isShowingKeyboard const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: Also rename the `isShowingKeyboard` Objective-C property to the more canonical `showingKeyboard`, with `isShowingKeyboard` as the getter method. (-[TestRunnerWKWebView _invokeShowKeyboardCallbackIfNecessary]): (-[TestRunnerWKWebView _invokeHideKeyboardCallbackIfNecessary]): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingKeyboard const): LayoutTests: Add a new layout test to check that the user can make a selection by long pressing after the keyboard is dismissed due to changing the focused element. * editing/selection/ios/select-text-after-changing-focus-expected.txt: Added. * editing/selection/ios/select-text-after-changing-focus.html: Added. * resources/ui-helper.js: Also tweak the behavior of `UIHelper.waitForKeyboardToHide()`, so that it resolves immediately if the keyboard is not shown. This allows us to ensure that tests which use `UIHelper.waitForKeyboardToHide()` are robust in the case where they wait for another action to complete (e.g. a simulated tap) prior to registering a keyboard hiding callback. (window.UIHelper.waitForKeyboardToHide.return.new.Promise): (window.UIHelper.waitForKeyboardToHide): Canonical link: https://commits.webkit.org/205509@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237135 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-15 19:47:03 +00:00
if (uiController.isShowingKeyboard)
uiController.didHideKeyboardCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
[Extra zoom mode] Programmatically changing focus when an element already has focus is a confusing experience https://bugs.webkit.org/show_bug.cgi?id=184635 <rdar://problem/39440642> Reviewed by Tim Horton. Source/WebKit: Currently on iOS, we allow element focus to present UI if the keyboard is already shown. In extra zoom mode, this would lead to a confusing experience when the focus form control overlay is disabled, since fullscreen input view controllers are swapped out from underneath the user. Currently, this also puts the UI process into a bad state where the focused form control overlay is active, but still hidden. This patch makes some tweaks to input view controller handling in the UI process to address these issues, and also adds WebKitTestRunner support for simulating interactions with select menus in extra zoom mode. See comments below for more detail. Test: fast/events/extrazoom/change-focus-during-change-event.html * UIProcess/API/Cocoa/WKUIDelegatePrivate.h: Add new SPI delegate hooks to notify the UI delegate when view controllers are presented or dismissed in extra zoom mode. See -presentViewControllerForCurrentAssistedNode and -dismissAllInputViewControllers. * UIProcess/WebProcessProxy.cpp: (WebKit::WebProcessProxy::takeBackgroundActivityTokenForFullscreenInput): (WebKit::WebProcessProxy::releaseBackgroundActivityTokenForFullscreenInput): See the comment below -dismissAllInputViewControllers. * UIProcess/WebProcessProxy.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): In extra zoom mode, when changing focus from one assisted node to another, only allow the second node to be assisted if the focused form control overlay is being shown. Otherwise, (i.e. when a fullscreen input view controller is being presented), don't allow focus to start an input session. Additionally, make a minor tweak to allow the previous node to blur, even if we are not showing the keyboard for the new focused element. Without this adjustment, in the case where the page has programmatically focused another element while a fullscreen input view controller is presented, we'll show the old view controller for the new focused element. (-[WKContentView presentViewControllerForCurrentAssistedNode]): (-[WKContentView dismissAllInputViewControllers:]): Currently, when a fullscreen input view controller is presented, the web process gets backgrounded. This prevents event handlers from executing, which leads to strange behaviors in many cases (for instance: if we have a multiple select, and the "change" event handler blurs the select, the user may check or uncheck multiple items, but only the first change will actually take effect). To fix this, we maintain a background activity token while presenting an input view controller. (-[WKContentView focusedFormControlViewDidBeginEditing:]): Start hiding the focused form overlay when re-presenting an input view controller. This allows us to bail from showing fullscreen input UI for another focused element if focus programmatically changes while the current fullscreen input view controller is presented, due to the -isHidden check in -_startAssistingNode:. (-[WKContentView selectFormAccessoryPickerRow:]): Simulate tapping a given row in select menu UI in extra zoom mode. Tools: Add plumbing to support invoking `didHideKeyboardCallback` and `didShowKeyboardCallback` when (respectively) dismissing or presenting fullscreen input view controllers in extra zoom mode. * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView dealloc]): (-[TestRunnerWKWebView _invokeShowKeyboardCallbackIfNecessary]): (-[TestRunnerWKWebView _invokeHideKeyboardCallbackIfNecessary]): (-[TestRunnerWKWebView _keyboardDidShow:]): (-[TestRunnerWKWebView _keyboardDidHide:]): (-[TestRunnerWKWebView _webView:didPresentFocusedElementViewController:]): (-[TestRunnerWKWebView _webView:didDismissFocusedElementViewController:]): LayoutTests: Add a new layout test to exercise the following sequence of events in extra zoom mode: 1. Focus select element #1. 2. Choose an unselected option. 3. Programmatically focus select element #2 in the "change" event handler. 4. Choose an unselected option. 5. Programmatically blur select element #2 in the "change" event handler. * fast/events/extrazoom/change-focus-during-change-event-expected.txt: Added. * fast/events/extrazoom/change-focus-during-change-event.html: Added. * resources/ui-helper.js: (window.UIHelper.waitForKeyboardToHide.return.new.Promise): (window.UIHelper.waitForKeyboardToHide): Canonical link: https://commits.webkit.org/200238@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230752 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-18 06:03:06 +00:00
})()`, resolve);
});
}
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
static getUICaretRect()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(function() {
uiController.doAfterNextStablePresentationUpdate(function() {
uiController.uiScriptComplete(JSON.stringify(uiController.textSelectionCaretRect));
});
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
static getUISelectionRects()
[iOS] Do not show selection UI for editable elements with opacity near zero https://bugs.webkit.org/show_bug.cgi?id=191442 <rdar://problem/45958625> Reviewed by Simon Fraser. Source/WebCore: Tests: editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable.html editing/selection/ios/hide-selection-after-hiding-contenteditable.html editing/selection/ios/hide-selection-in-contenteditable-nested-transparency.html editing/selection/ios/hide-selection-in-hidden-contenteditable-frame.html editing/selection/ios/hide-selection-in-hidden-contenteditable.html * rendering/RenderObject.cpp: (WebCore::RenderObject::isTransparentRespectingParentFrames const): Add a helper function to determine whether a RenderObject is contained within a transparent layer, taking parent frames into account. A layer is considered transparent if its opacity is less than a small threshold (i.e. 0.01). Opacity on ancestor elements is applied multiplicatively. * rendering/RenderObject.h: Source/WebKit: Add support for suppressing native selection UI (for instance, selection highlight views, selection handles, and selection-related gestures) when the selection is inside a transparent editable element. This helps maintain compatibility with text editors that work by capturing key events and input events hidden contenteditable elements, and reflect these changes in different document or different part of the document. Since selection UI is rendered in the UI process on iOS using element geometry propagated from the web process, selection rendering is entirely decoupled from the process of painting in the web process. This means that if the editable root has an opacity of 0, we would correctly hide the caret and selection on macOS, but draw over the transparent element on iOS. When these hidden editable elements are focused, this often results in unwanted behaviors, such as double caret painting, native and custom selection UI from the page being drawn on top of one another, and the ability to change selection via tap and loupe gestures within hidden text. To fix this, we compute whether the focused element is transparent when an element is focused, or when the selection changes, and send this information over to the UI process via `AssistedNodeInformation` and `EditorState`. In the UI process, we then respect this information by suppressing the selection assistant if the focused element is transparent; this disables showing and laying out selection views, as well as gestures associated with selection overlays. However, this still allows for contextual autocorrection and spell checking. * Shared/AssistedNodeInformation.cpp: (WebKit::AssistedNodeInformation::encode const): (WebKit::AssistedNodeInformation::decode): * Shared/AssistedNodeInformation.h: * Shared/EditorState.cpp: (WebKit::EditorState::PostLayoutData::encode const): (WebKit::EditorState::PostLayoutData::decode): * Shared/EditorState.h: Add `elementIsTransparent` flags, and also add boilerplate IPC code. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): Prevent zooming to the focused element if the focused element is hidden. (-[WKContentView hasSelectablePositionAtPoint:]): (-[WKContentView pointIsNearMarkedText:]): (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]): Don't allow these text interaction gestures to begin while suppressing the selection assistant. (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): When an element is focused, begin suppressing the selection assistant if the element is fully transparent. (-[WKContentView _stopAssistingNode]): When the focused element is blurred, reset state by ending selection assistant suppression (additionally reactivating the selection assistant if needed). This ensures that selection in non-editable text isn't broken after focusing a hidden editable element. (-[WKContentView _updateChangedSelection:]): If needed, suppress or un-suppress the selection assistant when the selection changes. On certain rich text editors, a combination of custom selection UI and native selection UI is used. For instance, on Microsoft Office 365, caret selections are rendered using the native caret view, but as soon as the selection becomes ranged, the editable root becomes fully transparent, and Office's selection UI takes over. (-[WKContentView _shouldSuppressSelectionCommands]): Override this UIKit SPI hook to suppress selection commands (e.g. the callout bar) when suppressing the selection assistant. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::getAssistedNodeInformation): Compute and set `elementIsTransparent` using the assisted node. Tools: Add a couple of new testing helpers to UIScriptController. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::textSelectionRangeRects const): (WTR::UIScriptController::selectionCaretViewRect const): (WTR::UIScriptController::selectionRangeViewRects const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::textSelectionRangeRects const): Rename `selectionRangeViewRects` to `textSelectionRangeRects`. This allows us to draw a distinction between `textSelectionRangeRects`/`textSelectionCaretRect`, which retrieve information about selection rects known to the text interaction assistant, and `selectionCaretViewRect`/`selectionRangeViewRects`, which retrieve the actual frames of the selection views used to draw overlaid selection UI. This difference is important in the new layout tests added in this patch, which only suppress caret rendering (i.e. selection views remain hidden). Also, drive-by fix a leaked `NSMutableArray`. (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::selectionCaretViewRect const): (WTR::UIScriptController::selectionRangeViewRects const): Testing helpers to grab the frames of caret and selection views, in WKContentView's coordinate space. These rects are also clamped to WKContentView bounds. LayoutTests: Add 5 new layout tests. See below for more details. * editing/selection/character-granularity-rect.html: Adjust for a renamed UIScriptController function. * editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable-expected.txt: Added. * editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable.html: Added. Add a test to verify that we don't zoom to fit the focused element, if the focused element is completely transparent. * editing/selection/ios/hide-selection-after-hiding-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-after-hiding-contenteditable.html: Added. Add a test to verify that selection UI is hidden after making an editable root transparent, and shown again when the editable root becomes opaque. * editing/selection/ios/hide-selection-in-contenteditable-nested-transparency-expected.txt: Added. * editing/selection/ios/hide-selection-in-contenteditable-nested-transparency.html: Added. Add a test to verify that transparency applied on an editable root via nested transparent containers causes selection UI to be suppressed. * editing/selection/ios/hide-selection-in-hidden-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-in-hidden-contenteditable-frame-expected.txt: Added. * editing/selection/ios/hide-selection-in-hidden-contenteditable-frame.html: Added. Add a test to verify that selection UI is suppressed when an editable element inside a subframe is focused. This test checks that the caret, selection rects and selection handle views are not shown, and additionally verifies that the selection in a hidden contenteditable area cannot be changed via tap gesture. * editing/selection/ios/hide-selection-in-hidden-contenteditable.html: Added. Same test as above, but in a regular editable element in the main document instead of a subframe. * resources/ui-helper.js: (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): (window.UIHelper.getUICaretViewRect.return.new.Promise.): (window.UIHelper.getUICaretViewRect.return.new.Promise): (window.UIHelper.getUICaretViewRect): Add new UIHelper wrapper methods. See Tools/ChangeLog for more detail. Canonical link: https://commits.webkit.org/206355@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238146 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-13 22:30:27 +00:00
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] Do not show selection UI for editable elements with opacity near zero https://bugs.webkit.org/show_bug.cgi?id=191442 <rdar://problem/45958625> Reviewed by Simon Fraser. Source/WebCore: Tests: editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable.html editing/selection/ios/hide-selection-after-hiding-contenteditable.html editing/selection/ios/hide-selection-in-contenteditable-nested-transparency.html editing/selection/ios/hide-selection-in-hidden-contenteditable-frame.html editing/selection/ios/hide-selection-in-hidden-contenteditable.html * rendering/RenderObject.cpp: (WebCore::RenderObject::isTransparentRespectingParentFrames const): Add a helper function to determine whether a RenderObject is contained within a transparent layer, taking parent frames into account. A layer is considered transparent if its opacity is less than a small threshold (i.e. 0.01). Opacity on ancestor elements is applied multiplicatively. * rendering/RenderObject.h: Source/WebKit: Add support for suppressing native selection UI (for instance, selection highlight views, selection handles, and selection-related gestures) when the selection is inside a transparent editable element. This helps maintain compatibility with text editors that work by capturing key events and input events hidden contenteditable elements, and reflect these changes in different document or different part of the document. Since selection UI is rendered in the UI process on iOS using element geometry propagated from the web process, selection rendering is entirely decoupled from the process of painting in the web process. This means that if the editable root has an opacity of 0, we would correctly hide the caret and selection on macOS, but draw over the transparent element on iOS. When these hidden editable elements are focused, this often results in unwanted behaviors, such as double caret painting, native and custom selection UI from the page being drawn on top of one another, and the ability to change selection via tap and loupe gestures within hidden text. To fix this, we compute whether the focused element is transparent when an element is focused, or when the selection changes, and send this information over to the UI process via `AssistedNodeInformation` and `EditorState`. In the UI process, we then respect this information by suppressing the selection assistant if the focused element is transparent; this disables showing and laying out selection views, as well as gestures associated with selection overlays. However, this still allows for contextual autocorrection and spell checking. * Shared/AssistedNodeInformation.cpp: (WebKit::AssistedNodeInformation::encode const): (WebKit::AssistedNodeInformation::decode): * Shared/AssistedNodeInformation.h: * Shared/EditorState.cpp: (WebKit::EditorState::PostLayoutData::encode const): (WebKit::EditorState::PostLayoutData::decode): * Shared/EditorState.h: Add `elementIsTransparent` flags, and also add boilerplate IPC code. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): Prevent zooming to the focused element if the focused element is hidden. (-[WKContentView hasSelectablePositionAtPoint:]): (-[WKContentView pointIsNearMarkedText:]): (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]): Don't allow these text interaction gestures to begin while suppressing the selection assistant. (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): When an element is focused, begin suppressing the selection assistant if the element is fully transparent. (-[WKContentView _stopAssistingNode]): When the focused element is blurred, reset state by ending selection assistant suppression (additionally reactivating the selection assistant if needed). This ensures that selection in non-editable text isn't broken after focusing a hidden editable element. (-[WKContentView _updateChangedSelection:]): If needed, suppress or un-suppress the selection assistant when the selection changes. On certain rich text editors, a combination of custom selection UI and native selection UI is used. For instance, on Microsoft Office 365, caret selections are rendered using the native caret view, but as soon as the selection becomes ranged, the editable root becomes fully transparent, and Office's selection UI takes over. (-[WKContentView _shouldSuppressSelectionCommands]): Override this UIKit SPI hook to suppress selection commands (e.g. the callout bar) when suppressing the selection assistant. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::getAssistedNodeInformation): Compute and set `elementIsTransparent` using the assisted node. Tools: Add a couple of new testing helpers to UIScriptController. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::textSelectionRangeRects const): (WTR::UIScriptController::selectionCaretViewRect const): (WTR::UIScriptController::selectionRangeViewRects const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::textSelectionRangeRects const): Rename `selectionRangeViewRects` to `textSelectionRangeRects`. This allows us to draw a distinction between `textSelectionRangeRects`/`textSelectionCaretRect`, which retrieve information about selection rects known to the text interaction assistant, and `selectionCaretViewRect`/`selectionRangeViewRects`, which retrieve the actual frames of the selection views used to draw overlaid selection UI. This difference is important in the new layout tests added in this patch, which only suppress caret rendering (i.e. selection views remain hidden). Also, drive-by fix a leaked `NSMutableArray`. (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::selectionCaretViewRect const): (WTR::UIScriptController::selectionRangeViewRects const): Testing helpers to grab the frames of caret and selection views, in WKContentView's coordinate space. These rects are also clamped to WKContentView bounds. LayoutTests: Add 5 new layout tests. See below for more details. * editing/selection/character-granularity-rect.html: Adjust for a renamed UIScriptController function. * editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable-expected.txt: Added. * editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable.html: Added. Add a test to verify that we don't zoom to fit the focused element, if the focused element is completely transparent. * editing/selection/ios/hide-selection-after-hiding-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-after-hiding-contenteditable.html: Added. Add a test to verify that selection UI is hidden after making an editable root transparent, and shown again when the editable root becomes opaque. * editing/selection/ios/hide-selection-in-contenteditable-nested-transparency-expected.txt: Added. * editing/selection/ios/hide-selection-in-contenteditable-nested-transparency.html: Added. Add a test to verify that transparency applied on an editable root via nested transparent containers causes selection UI to be suppressed. * editing/selection/ios/hide-selection-in-hidden-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-in-hidden-contenteditable-frame-expected.txt: Added. * editing/selection/ios/hide-selection-in-hidden-contenteditable-frame.html: Added. Add a test to verify that selection UI is suppressed when an editable element inside a subframe is focused. This test checks that the caret, selection rects and selection handle views are not shown, and additionally verifies that the selection in a hidden contenteditable area cannot be changed via tap gesture. * editing/selection/ios/hide-selection-in-hidden-contenteditable.html: Added. Same test as above, but in a regular editable element in the main document instead of a subframe. * resources/ui-helper.js: (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): (window.UIHelper.getUICaretViewRect.return.new.Promise.): (window.UIHelper.getUICaretViewRect.return.new.Promise): (window.UIHelper.getUICaretViewRect): Add new UIHelper wrapper methods. See Tools/ChangeLog for more detail. Canonical link: https://commits.webkit.org/206355@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238146 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-13 22:30:27 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(function() {
uiController.doAfterNextStablePresentationUpdate(function() {
uiController.uiScriptComplete(JSON.stringify(uiController.textSelectionRangeRects));
});
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
static getUICaretViewRect()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] Do not show selection UI for editable elements with opacity near zero https://bugs.webkit.org/show_bug.cgi?id=191442 <rdar://problem/45958625> Reviewed by Simon Fraser. Source/WebCore: Tests: editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable.html editing/selection/ios/hide-selection-after-hiding-contenteditable.html editing/selection/ios/hide-selection-in-contenteditable-nested-transparency.html editing/selection/ios/hide-selection-in-hidden-contenteditable-frame.html editing/selection/ios/hide-selection-in-hidden-contenteditable.html * rendering/RenderObject.cpp: (WebCore::RenderObject::isTransparentRespectingParentFrames const): Add a helper function to determine whether a RenderObject is contained within a transparent layer, taking parent frames into account. A layer is considered transparent if its opacity is less than a small threshold (i.e. 0.01). Opacity on ancestor elements is applied multiplicatively. * rendering/RenderObject.h: Source/WebKit: Add support for suppressing native selection UI (for instance, selection highlight views, selection handles, and selection-related gestures) when the selection is inside a transparent editable element. This helps maintain compatibility with text editors that work by capturing key events and input events hidden contenteditable elements, and reflect these changes in different document or different part of the document. Since selection UI is rendered in the UI process on iOS using element geometry propagated from the web process, selection rendering is entirely decoupled from the process of painting in the web process. This means that if the editable root has an opacity of 0, we would correctly hide the caret and selection on macOS, but draw over the transparent element on iOS. When these hidden editable elements are focused, this often results in unwanted behaviors, such as double caret painting, native and custom selection UI from the page being drawn on top of one another, and the ability to change selection via tap and loupe gestures within hidden text. To fix this, we compute whether the focused element is transparent when an element is focused, or when the selection changes, and send this information over to the UI process via `AssistedNodeInformation` and `EditorState`. In the UI process, we then respect this information by suppressing the selection assistant if the focused element is transparent; this disables showing and laying out selection views, as well as gestures associated with selection overlays. However, this still allows for contextual autocorrection and spell checking. * Shared/AssistedNodeInformation.cpp: (WebKit::AssistedNodeInformation::encode const): (WebKit::AssistedNodeInformation::decode): * Shared/AssistedNodeInformation.h: * Shared/EditorState.cpp: (WebKit::EditorState::PostLayoutData::encode const): (WebKit::EditorState::PostLayoutData::decode): * Shared/EditorState.h: Add `elementIsTransparent` flags, and also add boilerplate IPC code. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): Prevent zooming to the focused element if the focused element is hidden. (-[WKContentView hasSelectablePositionAtPoint:]): (-[WKContentView pointIsNearMarkedText:]): (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]): Don't allow these text interaction gestures to begin while suppressing the selection assistant. (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): When an element is focused, begin suppressing the selection assistant if the element is fully transparent. (-[WKContentView _stopAssistingNode]): When the focused element is blurred, reset state by ending selection assistant suppression (additionally reactivating the selection assistant if needed). This ensures that selection in non-editable text isn't broken after focusing a hidden editable element. (-[WKContentView _updateChangedSelection:]): If needed, suppress or un-suppress the selection assistant when the selection changes. On certain rich text editors, a combination of custom selection UI and native selection UI is used. For instance, on Microsoft Office 365, caret selections are rendered using the native caret view, but as soon as the selection becomes ranged, the editable root becomes fully transparent, and Office's selection UI takes over. (-[WKContentView _shouldSuppressSelectionCommands]): Override this UIKit SPI hook to suppress selection commands (e.g. the callout bar) when suppressing the selection assistant. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::getAssistedNodeInformation): Compute and set `elementIsTransparent` using the assisted node. Tools: Add a couple of new testing helpers to UIScriptController. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::textSelectionRangeRects const): (WTR::UIScriptController::selectionCaretViewRect const): (WTR::UIScriptController::selectionRangeViewRects const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::textSelectionRangeRects const): Rename `selectionRangeViewRects` to `textSelectionRangeRects`. This allows us to draw a distinction between `textSelectionRangeRects`/`textSelectionCaretRect`, which retrieve information about selection rects known to the text interaction assistant, and `selectionCaretViewRect`/`selectionRangeViewRects`, which retrieve the actual frames of the selection views used to draw overlaid selection UI. This difference is important in the new layout tests added in this patch, which only suppress caret rendering (i.e. selection views remain hidden). Also, drive-by fix a leaked `NSMutableArray`. (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::selectionCaretViewRect const): (WTR::UIScriptController::selectionRangeViewRects const): Testing helpers to grab the frames of caret and selection views, in WKContentView's coordinate space. These rects are also clamped to WKContentView bounds. LayoutTests: Add 5 new layout tests. See below for more details. * editing/selection/character-granularity-rect.html: Adjust for a renamed UIScriptController function. * editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable-expected.txt: Added. * editing/selection/ios/do-not-zoom-to-focused-hidden-contenteditable.html: Added. Add a test to verify that we don't zoom to fit the focused element, if the focused element is completely transparent. * editing/selection/ios/hide-selection-after-hiding-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-after-hiding-contenteditable.html: Added. Add a test to verify that selection UI is hidden after making an editable root transparent, and shown again when the editable root becomes opaque. * editing/selection/ios/hide-selection-in-contenteditable-nested-transparency-expected.txt: Added. * editing/selection/ios/hide-selection-in-contenteditable-nested-transparency.html: Added. Add a test to verify that transparency applied on an editable root via nested transparent containers causes selection UI to be suppressed. * editing/selection/ios/hide-selection-in-hidden-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-in-hidden-contenteditable-frame-expected.txt: Added. * editing/selection/ios/hide-selection-in-hidden-contenteditable-frame.html: Added. Add a test to verify that selection UI is suppressed when an editable element inside a subframe is focused. This test checks that the caret, selection rects and selection handle views are not shown, and additionally verifies that the selection in a hidden contenteditable area cannot be changed via tap gesture. * editing/selection/ios/hide-selection-in-hidden-contenteditable.html: Added. Same test as above, but in a regular editable element in the main document instead of a subframe. * resources/ui-helper.js: (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): (window.UIHelper.getUICaretViewRect.return.new.Promise.): (window.UIHelper.getUICaretViewRect.return.new.Promise): (window.UIHelper.getUICaretViewRect): Add new UIHelper wrapper methods. See Tools/ChangeLog for more detail. Canonical link: https://commits.webkit.org/206355@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238146 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-13 22:30:27 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(function() {
uiController.doAfterNextStablePresentationUpdate(function() {
uiController.uiScriptComplete(JSON.stringify(uiController.selectionCaretViewRect));
});
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
static getUISelectionViewRects()
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible https://bugs.webkit.org/show_bug.cgi?id=175370 <rdar://problem/33799806> Reviewed by Ryosuke Niwa. Source/WebCore: Remove didChangeSelectionAndUpdateLayout -- EditorState updates that are scheduled due to missing post-layout data will now be scheduled for the next presentation update. Additionally, add editor client hooks to notify the WebKit layer when we've updated the current composition. See WebKit ChangeLog for more details. This patch adjusts and rebaselines existing layout tests. * editing/Editor.cpp: (WebCore::SetCompositionScope::SetCompositionScope): (WebCore::SetCompositionScope::~SetCompositionScope): Introduce a helper RAII class to ensure that we ignore selection changes during the scope of Editor::setComposition and call out to the client with WebEditorClient::didUpdateComposition afterwards. This also maintains a UserTypingGestureIndicator over its lifetime, so we don't additionally need to create a UserTypingGestureIndicator in Editor::setComposition. (WebCore::Editor::setComposition): * editing/FrameSelection.cpp: (WebCore::FrameSelection::setSelection): (WebCore::FrameSelection::updateAndRevealSelection): (WebCore::FrameSelection::setSelectedRange): * editing/FrameSelection.h: (WebCore::FrameSelection::defaultSetSelectionOptions): Plumb state about whether or not the selection change was triggered by the user to FrameSelection::setSelection, and if so, notify the editing client. A separate SetSelectionOptions flag is used here instead of RevealSelection to avoid calling out to the client in places where we want to reveal the selection regardless of whether or not the selection is user triggered. * loader/EmptyClients.cpp: * page/EditorClient.h: Source/WebKit: See per-method comments for more detail. WebPage::didChangeSelection now schedules EditorState updates to be sent during the next layer tree transaction rather than sending them synchronously. To ensure that iOS and Mac continue to behave correctly w.r.t. EditorState updates, we immediately dispatch EditorStates in the following cases: - After the composition changes, is confirmed, or is canceled. - After an edit command is executed. - After ending user-triggered selection changes. * Shared/mac/RemoteLayerTreeTransaction.h: (WebKit::RemoteLayerTreeTransaction::hasEditorState const): (WebKit::RemoteLayerTreeTransaction::editorState const): (WebKit::RemoteLayerTreeTransaction::setEditorState): Attaches an optional EditorState to the RemoteLayerTreeTransaction. This EditorState is computed and sent over when setting up the transaction in WebPage, if something previously scheduled an EditorState update. * Shared/mac/RemoteLayerTreeTransaction.mm: (WebKit::RemoteLayerTreeTransaction::encode const): (WebKit::RemoteLayerTreeTransaction::decode): Add coder support for sending over a layer tree transaction's EditorState. * UIProcess/API/Cocoa/WKViewPrivate.h: * UIProcess/API/mac/WKView.mm: (-[WKView _doAfterNextPresentationUpdate:]): Add _doAfterNextPresentationUpdate to WKView (used in TestWebKitAPI -- refer to WebKitAgnosticTest::waitForNextPresentationUpdate). * UIProcess/DrawingAreaProxy.h: (WebKit::DrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): * UIProcess/DrawingAreaProxy.messages.in: Add a new IPC messages, DispatchPresentationCallbacksAfterFlushingLayers, to invoke in-flight presentation callbacks in the UI process following a layer flush in the web process. * UIProcess/WebPageProxy.h: * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm: (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree): * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h: * UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm: (WebKit::TiledCoreAnimationDrawingAreaProxy::~TiledCoreAnimationDrawingAreaProxy): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchAfterEnsuringDrawing): (WebKit::TiledCoreAnimationDrawingAreaProxy::dispatchPresentationCallbacksAfterFlushingLayers): Run all pending _doAfterNextPresentationUpdate callbacks. * WebProcess/WebCoreSupport/WebEditorClient.cpp: (WebKit::WebEditorClient::didApplyStyle): (WebKit::WebEditorClient::respondToChangedContents): (WebKit::WebEditorClient::didEndUserTriggeredSelectionChanges): (WebKit::WebEditorClient::didUpdateComposition): Forward editor client calls to the WebPage. (WebKit::WebEditorClient::didChangeSelectionAndUpdateLayout): Deleted. * WebProcess/WebCoreSupport/WebEditorClient.h: * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::editorState const): (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged): (WebKit::WebPage::willCommitLayerTree): (WebKit::WebPage::didApplyStyle): Allow style application to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeContents): Allow applying top-level edit commands to immediately trigger EditorState updates, if we're not currently ignoring selection changes in the Editor. (WebKit::WebPage::didChangeSelection): (WebKit::WebPage::didUpdateComposition): (WebKit::WebPage::didEndUserTriggeredSelectionChanges): (WebKit::WebPage::discardedComposition): (WebKit::WebPage::canceledComposition): When handling composition updates, always send an EditorState to the UI process. Unlike other cases, IME requires immediate EditorState data, so we need to be explicit here in sending updates right away. (WebKit::WebPage::sendEditorStateUpdate): (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate): (WebKit::WebPage::flushPendingEditorStateUpdate): Helper methods to schedule an EditorState update to be sent upon the next layer tree update, or flush any pending EditorState update that has been scheduled. The private, more aggressive variant of this is sendEditorStateUpdate, which ignores whether or not there was already an EditorState update scheduled, and sends one anyways (this still fulfills any EditorState update that was previously scheduled). These helper methods are treated as no-ops when invoked while ignoring selection changes. This is to prevent temporary selection state and editor commands during operations such as text indicator snapshotting from pushing bogus information about transient editor states to the UI process. (WebKit::WebPage::sendPostLayoutEditorStateIfNeeded): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): (WebKit::WebPage::executeEditCommandWithCallback): (WebKit::selectionIsInsideFixedPositionContainer): (WebKit::WebPage::updateVisibleContentRects): Fix a hack that was computing an EditorState to figure out whether the current selection starts or ends in a fixed position container. Factors out relevant logic into a separate helper, and also schedules an EditorState update instead of immediately computing it. * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: (WebKit::TiledCoreAnimationDrawingArea::addTransactionCallbackID): Add support for registering and dispatching presentation callbacks that hook into the layer flush lifecycle, using the tiled CA drawing area. These are used by Mac LayoutTests and API tests that need to wait until the next flush before checking for state that depends on EditorState updates in the UI process. (WebKit::TiledCoreAnimationDrawingArea::flushLayers): Tell the WebPage to flush any pending EditorState updates. * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): Source/WebKitLegacy/mac: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Source/WebKitLegacy/win: Adjust WebEditorClient for interface changes. * WebCoreSupport/WebEditorClient.h: Tools: Tweaks API tests that involve editing to wait for a presentation update before checking against UI process-side information sent via EditorState updates. This allows any EditorState update scheduled by the test to propagate to the UI process. * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewCandidateTests.mm: (-[CandidateTestWebView typeString:inputMessage:]): (+[CandidateTestWebView setUpWithFrame:testPage:]): * TestWebKitAPI/Tests/WebKit2Cocoa/WKWebViewTextInput.mm: * TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm: (TestWebKitAPI::AcceptsFirstMouse::runTest): * TestWebKitAPI/Tests/mac/WKWebViewMacEditingTests.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView waitForNextPresentationUpdate]): Add a new helper method to spin until the next presentation update. * TestWebKitAPI/mac/WebKitAgnosticTest.h: * TestWebKitAPI/mac/WebKitAgnosticTest.mm: (TestWebKitAPI::WebKitAgnosticTest::waitForNextPresentationUpdate): LayoutTests: Rebaseline and adjust LayoutTests. * editing/caret/ios/absolute-caret-position-after-scroll-expected.txt: * editing/caret/ios/absolute-caret-position-after-scroll.html: * editing/caret/ios/fixed-caret-position-after-scroll-expected.txt: * editing/caret/ios/fixed-caret-position-after-scroll.html: * editing/secure-input/password-input-changed-type.html: * editing/secure-input/password-input-focusing.html: * editing/secure-input/removed-password-input.html: * editing/secure-input/reset-state-on-navigation.html: * editing/selection/character-granularity-rect.html: Delay checking for secure input state and caret rects until after the next presentation update. * editing/selection/ios/absolute-selection-after-scroll-expected.txt: * editing/selection/ios/absolute-selection-after-scroll.html: * editing/selection/ios/fixed-selection-after-scroll-expected.txt: * editing/selection/ios/fixed-selection-after-scroll.html: Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long press and tap gestures. * platform/ios-wk2/editing/inserting/insert-div-024-expected.txt: * platform/ios-wk2/editing/inserting/insert-div-026-expected.txt: * platform/ios-wk2/editing/style/5084241-expected.txt: Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render tree thrashing altogether. * platform/mac-wk2/TestExpectations: * platform/mac-wk2/editing/style/unbold-in-bold-expected.txt: * resources/ui-helper.js: Introduce new UIHelper functions. (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): Returns a Promise, resolved after the next presentation update. (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise): (window.UIHelper.activateAndWaitForInputSessionAt): Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS. (window.UIHelper.getUICaretRect.return.new.Promise.): (window.UIHelper.getUICaretRect.return.new.Promise): (window.UIHelper.getUICaretRect): (window.UIHelper.getUISelectionRects.return.new.Promise.): (window.UIHelper.getUISelectionRects.return.new.Promise): (window.UIHelper.getUISelectionRects): Helpers to fetch selection and caret rect information in the UI process. Canonical link: https://commits.webkit.org/192519@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-23 03:15:38 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(function() {
uiController.doAfterNextStablePresentationUpdate(function() {
uiController.uiScriptComplete(JSON.stringify(uiController.selectionRangeViewRects));
});
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
[iOS] Caret disappears after resigning and becoming first responder if active focus state is retained https://bugs.webkit.org/show_bug.cgi?id=188322 <rdar://problem/42455270> Reviewed by Tim Horton. Source/WebKit: Prior to r230745, when a user selects a word in non-editable web content without a prior selection, we would always try to activate the text interaction assistant, creating a selection view (a UITextSelectionView). After the long press is recognized, this text selection view is configured for "highlight mode", which is a special mode for presenting selection UI where the grabber handles at the start and end of the selection are suppressed. UIKit then prepares to show the selection by asking WKContentView for the number of selection rects; if this number is zero, the UITextSelectionView is removed from the superview, and state that keeps track of whether the selection view is in "highlight mode" is reset. In the case where there's no prior selection, our cached EditorState in the UI process will not be up to date yet when the gesture is recognized. This means that when UIKit asks us for the number of selection rects, we'll return 0, which causes any state tracking "highlight mode" for the selection to be reset, subsequently resulting in selection handles showing up before the user has ended the initial loupe gesture. r230745 addressed this bug by removing logic to activate the text selection when becoming first responder, instead deferring until the next `-_selectionChanged` call with post-layout editor state data to activate the selection. While this does ensure that selection handles don't erroneously appear, it also means that clients that call -becomeFirstResponder to show selection UI and the keyboard in a web view while an element is already focused will not have an active selection assistant (i.e. the selection view will still be hidden). One way this happens is when Safari uses `-_retainActiveFocusedState` in combination with `-resignFirstResponder` and `-becomeFirstResponder` to temporarily switch focus away from the web view when the URL bar is tapped. To fix both the inactive selection after `-becomeFirstResponder` as well as the selection handles showing up when performing a loupe gesture, we simply make the check in `-becomeFirstResponderForWebView` more nuanced. Instead of always activating the selection or never activating the selection, only activate the selection if the current editor state has information about a selection to avoid causing the selection view to be immediately removed and "highlight mode" to be reset when selecting a word via loupe gesture for the first time. Tests: KeyboardInputTests.CaretSelectionRectAfterRestoringFirstResponder KeyboardInputTests.RangedSelectionRectAfterRestoringFirstResponder editing/selection/ios/selection-handles-after-touch-end.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView becomeFirstResponderForWebView]): (-[WKContentView canShowNonEmptySelectionView]): Tools: Adds plumbing in UIScriptController to grab the start and end selection handle rects for use in the new layout test. Also adds new API tests to verify that when a web view resigns first responder, both caret and range selection views are hidden, and when first responder status is restored, both caret and range selection views are made visible again. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm: (-[TestWKWebView waitForCaretViewFrameToBecome:]): (-[TestWKWebView waitForSelectionViewRectsToBecome:]): (webViewWithAutofocusedInput): Pull out some common logic for creating a web view that allows programmatic focus to present the keyboard, and immediately loading a web page with an autofocusing text field. (TestWebKitAPI::TEST): * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView caretViewRectInContentCoordinates]): (-[TestWKWebView selectionViewRectsInContentCoordinates]): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): LayoutTests: Adds a new layout test to verify that (1) selection handles are not shown when selecting a word by long pressing prior to ending the touch, and (2) selection handles are shown after ending the touch. * editing/selection/ios/selection-handles-after-touch-end-expected.txt: Added. * editing/selection/ios/selection-handles-after-touch-end.html: Added. * platform/win/TestExpectations: Skip iOS selection tests on Windows. * resources/ui-helper.js: Introduces new hooks in UIHelper to grab the frames of the start and end selection handle views. (window.UIHelper.getSelectionStartGrabberViewRect.return.new.Promise.): (window.UIHelper.getSelectionStartGrabberViewRect.return.new.Promise): (window.UIHelper.getSelectionStartGrabberViewRect): (window.UIHelper.getSelectionEndGrabberViewRect.return.new.Promise.): (window.UIHelper.getSelectionEndGrabberViewRect.return.new.Promise): (window.UIHelper.getSelectionEndGrabberViewRect): Canonical link: https://commits.webkit.org/203447@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-06 14:14:42 +00:00
static getSelectionStartGrabberViewRect()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] Caret disappears after resigning and becoming first responder if active focus state is retained https://bugs.webkit.org/show_bug.cgi?id=188322 <rdar://problem/42455270> Reviewed by Tim Horton. Source/WebKit: Prior to r230745, when a user selects a word in non-editable web content without a prior selection, we would always try to activate the text interaction assistant, creating a selection view (a UITextSelectionView). After the long press is recognized, this text selection view is configured for "highlight mode", which is a special mode for presenting selection UI where the grabber handles at the start and end of the selection are suppressed. UIKit then prepares to show the selection by asking WKContentView for the number of selection rects; if this number is zero, the UITextSelectionView is removed from the superview, and state that keeps track of whether the selection view is in "highlight mode" is reset. In the case where there's no prior selection, our cached EditorState in the UI process will not be up to date yet when the gesture is recognized. This means that when UIKit asks us for the number of selection rects, we'll return 0, which causes any state tracking "highlight mode" for the selection to be reset, subsequently resulting in selection handles showing up before the user has ended the initial loupe gesture. r230745 addressed this bug by removing logic to activate the text selection when becoming first responder, instead deferring until the next `-_selectionChanged` call with post-layout editor state data to activate the selection. While this does ensure that selection handles don't erroneously appear, it also means that clients that call -becomeFirstResponder to show selection UI and the keyboard in a web view while an element is already focused will not have an active selection assistant (i.e. the selection view will still be hidden). One way this happens is when Safari uses `-_retainActiveFocusedState` in combination with `-resignFirstResponder` and `-becomeFirstResponder` to temporarily switch focus away from the web view when the URL bar is tapped. To fix both the inactive selection after `-becomeFirstResponder` as well as the selection handles showing up when performing a loupe gesture, we simply make the check in `-becomeFirstResponderForWebView` more nuanced. Instead of always activating the selection or never activating the selection, only activate the selection if the current editor state has information about a selection to avoid causing the selection view to be immediately removed and "highlight mode" to be reset when selecting a word via loupe gesture for the first time. Tests: KeyboardInputTests.CaretSelectionRectAfterRestoringFirstResponder KeyboardInputTests.RangedSelectionRectAfterRestoringFirstResponder editing/selection/ios/selection-handles-after-touch-end.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView becomeFirstResponderForWebView]): (-[WKContentView canShowNonEmptySelectionView]): Tools: Adds plumbing in UIScriptController to grab the start and end selection handle rects for use in the new layout test. Also adds new API tests to verify that when a web view resigns first responder, both caret and range selection views are hidden, and when first responder status is restored, both caret and range selection views are made visible again. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm: (-[TestWKWebView waitForCaretViewFrameToBecome:]): (-[TestWKWebView waitForSelectionViewRectsToBecome:]): (webViewWithAutofocusedInput): Pull out some common logic for creating a web view that allows programmatic focus to present the keyboard, and immediately loading a web page with an autofocusing text field. (TestWebKitAPI::TEST): * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView caretViewRectInContentCoordinates]): (-[TestWKWebView selectionViewRectsInContentCoordinates]): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): LayoutTests: Adds a new layout test to verify that (1) selection handles are not shown when selecting a word by long pressing prior to ending the touch, and (2) selection handles are shown after ending the touch. * editing/selection/ios/selection-handles-after-touch-end-expected.txt: Added. * editing/selection/ios/selection-handles-after-touch-end.html: Added. * platform/win/TestExpectations: Skip iOS selection tests on Windows. * resources/ui-helper.js: Introduces new hooks in UIHelper to grab the frames of the start and end selection handle views. (window.UIHelper.getSelectionStartGrabberViewRect.return.new.Promise.): (window.UIHelper.getSelectionStartGrabberViewRect.return.new.Promise): (window.UIHelper.getSelectionStartGrabberViewRect): (window.UIHelper.getSelectionEndGrabberViewRect.return.new.Promise.): (window.UIHelper.getSelectionEndGrabberViewRect.return.new.Promise): (window.UIHelper.getSelectionEndGrabberViewRect): Canonical link: https://commits.webkit.org/203447@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-06 14:14:42 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(function() {
uiController.doAfterNextStablePresentationUpdate(function() {
uiController.uiScriptComplete(JSON.stringify(uiController.selectionStartGrabberViewRect));
});
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
static getSelectionEndGrabberViewRect()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] Caret disappears after resigning and becoming first responder if active focus state is retained https://bugs.webkit.org/show_bug.cgi?id=188322 <rdar://problem/42455270> Reviewed by Tim Horton. Source/WebKit: Prior to r230745, when a user selects a word in non-editable web content without a prior selection, we would always try to activate the text interaction assistant, creating a selection view (a UITextSelectionView). After the long press is recognized, this text selection view is configured for "highlight mode", which is a special mode for presenting selection UI where the grabber handles at the start and end of the selection are suppressed. UIKit then prepares to show the selection by asking WKContentView for the number of selection rects; if this number is zero, the UITextSelectionView is removed from the superview, and state that keeps track of whether the selection view is in "highlight mode" is reset. In the case where there's no prior selection, our cached EditorState in the UI process will not be up to date yet when the gesture is recognized. This means that when UIKit asks us for the number of selection rects, we'll return 0, which causes any state tracking "highlight mode" for the selection to be reset, subsequently resulting in selection handles showing up before the user has ended the initial loupe gesture. r230745 addressed this bug by removing logic to activate the text selection when becoming first responder, instead deferring until the next `-_selectionChanged` call with post-layout editor state data to activate the selection. While this does ensure that selection handles don't erroneously appear, it also means that clients that call -becomeFirstResponder to show selection UI and the keyboard in a web view while an element is already focused will not have an active selection assistant (i.e. the selection view will still be hidden). One way this happens is when Safari uses `-_retainActiveFocusedState` in combination with `-resignFirstResponder` and `-becomeFirstResponder` to temporarily switch focus away from the web view when the URL bar is tapped. To fix both the inactive selection after `-becomeFirstResponder` as well as the selection handles showing up when performing a loupe gesture, we simply make the check in `-becomeFirstResponderForWebView` more nuanced. Instead of always activating the selection or never activating the selection, only activate the selection if the current editor state has information about a selection to avoid causing the selection view to be immediately removed and "highlight mode" to be reset when selecting a word via loupe gesture for the first time. Tests: KeyboardInputTests.CaretSelectionRectAfterRestoringFirstResponder KeyboardInputTests.RangedSelectionRectAfterRestoringFirstResponder editing/selection/ios/selection-handles-after-touch-end.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView becomeFirstResponderForWebView]): (-[WKContentView canShowNonEmptySelectionView]): Tools: Adds plumbing in UIScriptController to grab the start and end selection handle rects for use in the new layout test. Also adds new API tests to verify that when a web view resigns first responder, both caret and range selection views are hidden, and when first responder status is restored, both caret and range selection views are made visible again. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestWebKitAPI/Tests/ios/KeyboardInputTestsIOS.mm: (-[TestWKWebView waitForCaretViewFrameToBecome:]): (-[TestWKWebView waitForSelectionViewRectsToBecome:]): (webViewWithAutofocusedInput): Pull out some common logic for creating a web view that allows programmatic focus to present the keyboard, and immediately loading a web page with an autofocusing text field. (TestWebKitAPI::TEST): * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebView caretViewRectInContentCoordinates]): (-[TestWKWebView selectionViewRectsInContentCoordinates]): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionStartGrabberViewRect const): (WTR::UIScriptController::selectionEndGrabberViewRect const): LayoutTests: Adds a new layout test to verify that (1) selection handles are not shown when selecting a word by long pressing prior to ending the touch, and (2) selection handles are shown after ending the touch. * editing/selection/ios/selection-handles-after-touch-end-expected.txt: Added. * editing/selection/ios/selection-handles-after-touch-end.html: Added. * platform/win/TestExpectations: Skip iOS selection tests on Windows. * resources/ui-helper.js: Introduces new hooks in UIHelper to grab the frames of the start and end selection handle views. (window.UIHelper.getSelectionStartGrabberViewRect.return.new.Promise.): (window.UIHelper.getSelectionStartGrabberViewRect.return.new.Promise): (window.UIHelper.getSelectionStartGrabberViewRect): (window.UIHelper.getSelectionEndGrabberViewRect.return.new.Promise.): (window.UIHelper.getSelectionEndGrabberViewRect.return.new.Promise): (window.UIHelper.getSelectionEndGrabberViewRect): Canonical link: https://commits.webkit.org/203447@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-06 14:14:42 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(function() {
uiController.doAfterNextStablePresentationUpdate(function() {
uiController.uiScriptComplete(JSON.stringify(uiController.selectionEndGrabberViewRect));
});
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
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
static selectionCaretBackgroundColor()
{
return new Promise(resolve => {
testRunner.runUIScript("uiController.uiScriptComplete(uiController.selectionCaretBackgroundColor)", resolve);
});
}
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
static tapHighlightViewRect()
{
return new Promise(resolve => {
testRunner.runUIScript("JSON.stringify(uiController.tapHighlightViewRect)", jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
Picking an emoji via the emoji dialog (Ctrl+Cmd+Space) fires inconsistent beforeinput events. https://bugs.webkit.org/show_bug.cgi?id=170955 <rdar://problem/31697653> Reviewed by Ryosuke Niwa. Source/WebKit: Currently, we insert text with TextEventInputAutocompletion as the text event input type if any text range to replace was specified by the platform. Instead, limit this only to when the text replacement range is not empty. This more closely matches the intention of the spec, which states that the "insertReplacementText" inputType should be used when "[replacing] existing text by means of a spell checker, auto-correct or similar". * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::insertTextAsync): Source/WebKitLegacy/mac: Tweak -insertText: to pass TextEventInputAutocompletion to Editor::insertText when inserting text, if existing text is being replaced. * WebView/WebHTMLView.mm: (-[WebHTMLView insertText:]): Tools: Replace UIScriptController.insertText with UIScriptController.replaceTextAtRange, and implement replaceTextAtRange in WebKit1. See corresponding layout tests (input-event-insert-replacement.html and before-input-prevent-insert-replacement.html) for more detail. * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: * DumpRenderTree/mac/AppKitTestSPI.h: Added. Introduce an SPI header for private AppKit headers needed to support DumpRenderTree. * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::replaceTextAtRange): (WTR::UIScriptController::insertText): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::replaceTextAtRange): (WTR::UIScriptController::insertText): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::replaceTextAtRange): (WTR::UIScriptController::insertText): Deleted. Replace UIScriptController.insertText with UIScriptController.replaceTextAtRange, which better describes the behavior of this function. LayoutTests: Augments two existing layout tests to check for additional cases of inserting text with replacement ranges. Also enables this test for WebKit1 on Mac. Both these tests are currently enabled only for WebKit2, and also only check the case where we're replacing an existing non-empty range of text. * fast/events/before-input-prevent-insert-replacement-expected.txt: * fast/events/before-input-prevent-insert-replacement.html: * fast/events/input-event-insert-replacement-expected.txt: * fast/events/input-event-insert-replacement.html: Tests for cases of replacing existing text ranges, and inserting text at a position. * platform/mac-wk1/TestExpectations: * resources/ui-helper.js: Add a new UIHelper function to insert text at a given replacement range. This codepath is taken when selecting an emoji using the emoji picker menu on Mac, and also when selecting a dead key option after holding down on a vowel key. (window.UIHelper.replaceTextAtRange): Canonical link: https://commits.webkit.org/192681@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221234 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-28 05:12:56 +00:00
static replaceTextAtRange(text, location, length) {
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.replaceTextAtRange("${text}", ${location}, ${length});
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
Picking an emoji via the emoji dialog (Ctrl+Cmd+Space) fires inconsistent beforeinput events. https://bugs.webkit.org/show_bug.cgi?id=170955 <rdar://problem/31697653> Reviewed by Ryosuke Niwa. Source/WebKit: Currently, we insert text with TextEventInputAutocompletion as the text event input type if any text range to replace was specified by the platform. Instead, limit this only to when the text replacement range is not empty. This more closely matches the intention of the spec, which states that the "insertReplacementText" inputType should be used when "[replacing] existing text by means of a spell checker, auto-correct or similar". * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::insertTextAsync): Source/WebKitLegacy/mac: Tweak -insertText: to pass TextEventInputAutocompletion to Editor::insertText when inserting text, if existing text is being replaced. * WebView/WebHTMLView.mm: (-[WebHTMLView insertText:]): Tools: Replace UIScriptController.insertText with UIScriptController.replaceTextAtRange, and implement replaceTextAtRange in WebKit1. See corresponding layout tests (input-event-insert-replacement.html and before-input-prevent-insert-replacement.html) for more detail. * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: * DumpRenderTree/mac/AppKitTestSPI.h: Added. Introduce an SPI header for private AppKit headers needed to support DumpRenderTree. * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::replaceTextAtRange): (WTR::UIScriptController::insertText): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::replaceTextAtRange): (WTR::UIScriptController::insertText): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::replaceTextAtRange): (WTR::UIScriptController::insertText): Deleted. Replace UIScriptController.insertText with UIScriptController.replaceTextAtRange, which better describes the behavior of this function. LayoutTests: Augments two existing layout tests to check for additional cases of inserting text with replacement ranges. Also enables this test for WebKit1 on Mac. Both these tests are currently enabled only for WebKit2, and also only check the case where we're replacing an existing non-empty range of text. * fast/events/before-input-prevent-insert-replacement-expected.txt: * fast/events/before-input-prevent-insert-replacement.html: * fast/events/input-event-insert-replacement-expected.txt: * fast/events/input-event-insert-replacement.html: Tests for cases of replacing existing text ranges, and inserting text at a position. * platform/mac-wk1/TestExpectations: * resources/ui-helper.js: Add a new UIHelper function to insert text at a given replacement range. This codepath is taken when selecting an emoji using the emoji picker menu on Mac, and also when selecting a dead key option after holding down on a vowel key. (window.UIHelper.replaceTextAtRange): Canonical link: https://commits.webkit.org/192681@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221234 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-28 05:12:56 +00:00
})()`, resolve);
});
}
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
static wait(promise)
{
testRunner.waitUntilDone();
iOS: An element with tabindex is not focusable unless there is no mouse event handler https://bugs.webkit.org/show_bug.cgi?id=165843 Reviewed by Antti Koivisto. Source/WebCore: The bug was caused by ancestorRespondingToClickEvents not checking the precense of tabindex attribute. Check that condition along with event listeners. Test: fast/events/focusing-element-with-tabindex-by-tap-or-click.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): Tools: Add testRunner.isWebKit2 which is always true in WebKitTestRunner. Without this, it's really hard to reliably differentiate DumpRenderTree and WebKitTestRunner, and DumpRenderTree's runUIScript would hit an assertion :( * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isWebKit2): LayoutTests: Added a regression test for focusing an element with just tabindex using UIHelper. Also fixed UIHelper to work in iOS DumpRenderTree which was hitting an assertion by explicitly checking testRunner.isWebKit2. Prior to fixing this, it was hitting an assertion in RunLoop::main() which was asserting that there is a runloop, which doesn't exist in DumpRenderTree. * fast/events/focusing-element-with-tabindex-by-tap-or-click-expected.txt: Added. * fast/events/focusing-element-with-tabindex-by-tap-or-click.html: Added. * platform/ios-simulator-wk2/TestExpectations: * resources/ui-helper.js: (window.UIHelper.isWebKit2): (window.UIHelper.wait): Added the support for js-test.js / js-test-pre.js style tests. Canonical link: https://commits.webkit.org/183477@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209833 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-14 21:57:37 +00:00
if (window.finishJSTest)
window.jsTestIsAsync = true;
let finish = () => {
if (window.finishJSTest)
finishJSTest();
else
testRunner.notifyDone();
}
return promise.then(finish, finish);
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
}
Web Inspector: Show Internal properties of PaymentRequest in Web Inspector Console https://bugs.webkit.org/show_bug.cgi?id=179276 Reviewed by Andy Estes. Source/JavaScriptCore: * inspector/InjectedScriptHost.h: * inspector/JSInjectedScriptHost.cpp: (Inspector::JSInjectedScriptHost::getInternalProperties): Call through to virtual implementation so that WebCore can provide custom internal properties for Web / DOM objects. Source/WebCore: Test: http/tests/inspector/runtime/internal-properties-payment-request.https.html * Modules/paymentrequest/PaymentRequest.h: Expose access to internal state. * inspector/WebInjectedScriptHost.h: * inspector/WebInjectedScriptHost.cpp: (WebCore::constructInternalProperty): (WebCore::WebInjectedScriptHost::getInternalProperties): Provide internal properties for a PaymentRequest. * testing/Internals.cpp: (WebCore::Internals::withUserGesture): * testing/Internals.h: * testing/Internals.idl: Provide a simple way to run code inside of a user gesture. Source/WebInspectorUI: * UserInterface/Test.html: * UserInterface/Test/FrontendTestHarness.js: (FrontendTestHarness.prototype.evaluateInPage): * UserInterface/Test/TestUtilities.js: Added. (promisify): Make async tests a little easier to work with by providing promises in some cases that would normally take a callback. LayoutTests: * TestExpectations: * platform/mac-wk2/TestExpectations: Pass test on platforms that support Payment Requests. * http/tests/inspector/paymentrequest/payment-request-internal-properties.https-expected.txt: Added. * http/tests/inspector/paymentrequest/payment-request-internal-properties.https.html: Added. Test for internal properties on PaymentRequest instances. * resources/ui-helper.js: (window.UIHelper.withUserGesture): Provide an easier way to simulate work inside of a user gesture. Canonical link: https://commits.webkit.org/195505@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224606 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-09 00:36:15 +00:00
static withUserGesture(callback)
{
internals.withUserGesture(callback);
}
[Extra zoom mode] Missing label when focusing a <select> with a title attribute but no associated <label> https://bugs.webkit.org/show_bug.cgi?id=184352 <rdar://problem/39237683> Reviewed by Andy Estes. Source/WebKit: Currently, AssistedNodeInformation only sends the `title` of input elements to the UI process. This means that any information requested in the UI process that is dependent on the `title` of the focused element is broken in the case of select elements. An existing example of this is the title of the table view controller used to present select menus on iPad. To fix this, we simply send the `title` of the focused element across, as long as the focused element is an HTMLElement. This ensures that there's label text when focusing unlabeled select elements with titles in extra zoom mode, and also fixes a currenly broken codepath where we show the title of the select in the presented view controller's title. Test: fast/forms/ios/ipad/select-with-title.html * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView selectFormPopoverTitle]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add new testing SPI to fetch the title of the UITableViewController presented for the currently focused select element. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView selectFormPopoverTitle]): * UIProcess/ios/forms/WKFormSelectControl.h: * UIProcess/ios/forms/WKFormSelectControl.mm: (-[WKFormSelectControl selectFormPopoverTitle]): * UIProcess/ios/forms/WKFormSelectPopover.h: * UIProcess/ios/forms/WKFormSelectPopover.mm: (-[WKSelectPopover initWithView:hasGroups:]): (-[WKSelectPopover tableViewController]): * WebProcess/WebPage/ios/WebPageIOS.mm: Always send the title across if the focused node is an HTMLElement. (WebKit::WebPage::getAssistedNodeInformation): Tools: Add support for UIScriptController::selectFormPopoverTitle, which returns the title of the current select popover's UITableViewController (for testing purposes). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectFormPopoverTitle const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectFormPopoverTitle const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectFormPopoverTitle const): LayoutTests: Add a new layout test to check that the title of select elements is propagated to the UI process upon focus. This title is used for several purposes, one of them being the title of select menus in the table view controller presented when tapping on a select on an iPad, so the test checks that the title of the select is shown here. Also moves a select-related helper into UIHelper from basic-gestures.js (since this doesn't involve user gesture simulation in any way) and also introduces a new UIHelper method for querying the title of the select menu that is currently being presented. * fast/forms/ios/ipad/multiple-select-updates-renderer.html: * fast/forms/ios/ipad/select-with-title-expected.txt: Added. * fast/forms/ios/ipad/select-with-title.html: Copied from LayoutTests/fast/forms/ios/ipad/multiple-select-updates-renderer.html. * resources/basic-gestures.js: * resources/ui-helper.js: (window.UIHelper.selectFormAccessoryPickerRow): (window.UIHelper.selectFormPopoverTitle): (window.UIHelper): Canonical link: https://commits.webkit.org/200052@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230527 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-11 16:43:53 +00:00
static selectFormAccessoryPickerRow(rowIndex)
{
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
const selectRowScript = `uiController.selectFormAccessoryPickerRow(${rowIndex})`;
[Extra zoom mode] Missing label when focusing a <select> with a title attribute but no associated <label> https://bugs.webkit.org/show_bug.cgi?id=184352 <rdar://problem/39237683> Reviewed by Andy Estes. Source/WebKit: Currently, AssistedNodeInformation only sends the `title` of input elements to the UI process. This means that any information requested in the UI process that is dependent on the `title` of the focused element is broken in the case of select elements. An existing example of this is the title of the table view controller used to present select menus on iPad. To fix this, we simply send the `title` of the focused element across, as long as the focused element is an HTMLElement. This ensures that there's label text when focusing unlabeled select elements with titles in extra zoom mode, and also fixes a currenly broken codepath where we show the title of the select in the presented view controller's title. Test: fast/forms/ios/ipad/select-with-title.html * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView selectFormPopoverTitle]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add new testing SPI to fetch the title of the UITableViewController presented for the currently focused select element. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView selectFormPopoverTitle]): * UIProcess/ios/forms/WKFormSelectControl.h: * UIProcess/ios/forms/WKFormSelectControl.mm: (-[WKFormSelectControl selectFormPopoverTitle]): * UIProcess/ios/forms/WKFormSelectPopover.h: * UIProcess/ios/forms/WKFormSelectPopover.mm: (-[WKSelectPopover initWithView:hasGroups:]): (-[WKSelectPopover tableViewController]): * WebProcess/WebPage/ios/WebPageIOS.mm: Always send the title across if the focused node is an HTMLElement. (WebKit::WebPage::getAssistedNodeInformation): Tools: Add support for UIScriptController::selectFormPopoverTitle, which returns the title of the current select popover's UITableViewController (for testing purposes). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectFormPopoverTitle const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectFormPopoverTitle const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectFormPopoverTitle const): LayoutTests: Add a new layout test to check that the title of select elements is propagated to the UI process upon focus. This title is used for several purposes, one of them being the title of select menus in the table view controller presented when tapping on a select on an iPad, so the test checks that the title of the select is shown here. Also moves a select-related helper into UIHelper from basic-gestures.js (since this doesn't involve user gesture simulation in any way) and also introduces a new UIHelper method for querying the title of the select menu that is currently being presented. * fast/forms/ios/ipad/multiple-select-updates-renderer.html: * fast/forms/ios/ipad/select-with-title-expected.txt: Added. * fast/forms/ios/ipad/select-with-title.html: Copied from LayoutTests/fast/forms/ios/ipad/multiple-select-updates-renderer.html. * resources/basic-gestures.js: * resources/ui-helper.js: (window.UIHelper.selectFormAccessoryPickerRow): (window.UIHelper.selectFormPopoverTitle): (window.UIHelper): Canonical link: https://commits.webkit.org/200052@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230527 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-11 16:43:53 +00:00
return new Promise(resolve => testRunner.runUIScript(selectRowScript, resolve));
}
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
static selectFormAccessoryHasCheckedItemAtRow(rowIndex)
{
return new Promise(resolve => testRunner.runUIScript(`uiController.selectFormAccessoryHasCheckedItemAtRow(${rowIndex})`, result => {
resolve(result === "true");
}));
}
[Extra zoom mode] Missing label when focusing a <select> with a title attribute but no associated <label> https://bugs.webkit.org/show_bug.cgi?id=184352 <rdar://problem/39237683> Reviewed by Andy Estes. Source/WebKit: Currently, AssistedNodeInformation only sends the `title` of input elements to the UI process. This means that any information requested in the UI process that is dependent on the `title` of the focused element is broken in the case of select elements. An existing example of this is the title of the table view controller used to present select menus on iPad. To fix this, we simply send the `title` of the focused element across, as long as the focused element is an HTMLElement. This ensures that there's label text when focusing unlabeled select elements with titles in extra zoom mode, and also fixes a currenly broken codepath where we show the title of the select in the presented view controller's title. Test: fast/forms/ios/ipad/select-with-title.html * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView selectFormPopoverTitle]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add new testing SPI to fetch the title of the UITableViewController presented for the currently focused select element. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView selectFormPopoverTitle]): * UIProcess/ios/forms/WKFormSelectControl.h: * UIProcess/ios/forms/WKFormSelectControl.mm: (-[WKFormSelectControl selectFormPopoverTitle]): * UIProcess/ios/forms/WKFormSelectPopover.h: * UIProcess/ios/forms/WKFormSelectPopover.mm: (-[WKSelectPopover initWithView:hasGroups:]): (-[WKSelectPopover tableViewController]): * WebProcess/WebPage/ios/WebPageIOS.mm: Always send the title across if the focused node is an HTMLElement. (WebKit::WebPage::getAssistedNodeInformation): Tools: Add support for UIScriptController::selectFormPopoverTitle, which returns the title of the current select popover's UITableViewController (for testing purposes). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectFormPopoverTitle const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectFormPopoverTitle const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectFormPopoverTitle const): LayoutTests: Add a new layout test to check that the title of select elements is propagated to the UI process upon focus. This title is used for several purposes, one of them being the title of select menus in the table view controller presented when tapping on a select on an iPad, so the test checks that the title of the select is shown here. Also moves a select-related helper into UIHelper from basic-gestures.js (since this doesn't involve user gesture simulation in any way) and also introduces a new UIHelper method for querying the title of the select menu that is currently being presented. * fast/forms/ios/ipad/multiple-select-updates-renderer.html: * fast/forms/ios/ipad/select-with-title-expected.txt: Added. * fast/forms/ios/ipad/select-with-title.html: Copied from LayoutTests/fast/forms/ios/ipad/multiple-select-updates-renderer.html. * resources/basic-gestures.js: * resources/ui-helper.js: (window.UIHelper.selectFormAccessoryPickerRow): (window.UIHelper.selectFormPopoverTitle): (window.UIHelper): Canonical link: https://commits.webkit.org/200052@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230527 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-11 16:43:53 +00:00
static selectFormPopoverTitle()
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.selectFormPopoverTitle);
})()`, resolve);
});
}
[Extra zoom mode] Injected bundle form client should be notified when editing text fields https://bugs.webkit.org/show_bug.cgi?id=184822 <rdar://problem/38807319> Reviewed by Tim Horton. Source/WebCore: Export the constructor and destructor of UserTypingGestureIndicator for use in WebKit (see WebPage.cpp). Test: fast/forms/extrazoom/edit-text-field-calls-injected-bundle.html * dom/UserTypingGestureIndicator.h: Source/WebKit: Fixes the bug by making a couple of tweaks: (1) don't use a separate codepath for inserting text in text inputs, and (2) force a user typing gesture when inserting text using this codepath (i.e. WKTextInputListViewController). Also adds plumbing to enable testing text entry with WKTextInputListViewController in extra zoom mode. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _simulateTextEntered:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Introduce testing SPI to simulate text entry. Additionally, add a missing availability annotation around testing SPI added in 2017 to help test drag and drop for iOS 11. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _simulateTextEntered:]): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::setTextAsync): Tools: Add WebKitTestRunner support for listening to form editing SPI hooks in the injected bundle. The new layout test installs callbacks that listen for "begin editing", "end editing", and "text changed" calls to injected bundle SPI. See other ChangeLogs for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::enterText): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: Add UIScriptController support for simulating text entry in the currently focused element. * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::enterText): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: Add TestRunner bindings for registering injected bundle form client callbacks. * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: (WTR::handleTextDidChangeInTextField): (WTR::handleTextFieldDidBeginEditing): (WTR::handleTextFieldDidEndEditing): (WTR::InjectedBundle::didCreatePage): Set the injected bundle form editor client. (WTR::InjectedBundle::setUpInjectedBundleClients): (WTR::InjectedBundle::textDidChangeInTextField): (WTR::InjectedBundle::textFieldDidBeginEditing): (WTR::InjectedBundle::textFieldDidEndEditing): * WebKitTestRunner/InjectedBundle/InjectedBundle.h: * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::installTextDidChangeInTextFieldCallback): (WTR::TestRunner::textDidChangeInTextFieldCallback): (WTR::TestRunner::installTextFieldDidBeginEditingCallback): (WTR::TestRunner::textFieldDidBeginEditingCallback): (WTR::TestRunner::installTextFieldDidEndEditingCallback): (WTR::TestRunner::textFieldDidEndEditingCallback): * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::enterText): LayoutTests: Add a new layout test that focuses an input field, simulates text entry, and verifies that the injected bundle form client's textDidChangeInTextField, textFieldDidBeginEditing and textFieldDidEndEditing functions are called. * TestExpectations: Skip tests in fast/forms/extrazoom by default. * fast/forms/extrazoom/edit-text-field-calls-injected-bundle-expected.txt: Added. * fast/forms/extrazoom/edit-text-field-calls-injected-bundle.html: Added. * resources/ui-helper.js: (window.UIHelper.enterText): Introduce a new UIHelper method to simulate text entry in the currently focused element. (window.UIHelper): Canonical link: https://commits.webkit.org/200336@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230860 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-20 22:21:54 +00:00
[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
static setSelectedColorForColorPicker(red, green, blue)
{
const selectColorScript = `uiController.setSelectedColorForColorPicker(${red}, ${green}, ${blue})`;
return new Promise(resolve => testRunner.runUIScript(selectColorScript, resolve));
}
[Extra zoom mode] Injected bundle form client should be notified when editing text fields https://bugs.webkit.org/show_bug.cgi?id=184822 <rdar://problem/38807319> Reviewed by Tim Horton. Source/WebCore: Export the constructor and destructor of UserTypingGestureIndicator for use in WebKit (see WebPage.cpp). Test: fast/forms/extrazoom/edit-text-field-calls-injected-bundle.html * dom/UserTypingGestureIndicator.h: Source/WebKit: Fixes the bug by making a couple of tweaks: (1) don't use a separate codepath for inserting text in text inputs, and (2) force a user typing gesture when inserting text using this codepath (i.e. WKTextInputListViewController). Also adds plumbing to enable testing text entry with WKTextInputListViewController in extra zoom mode. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _simulateTextEntered:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Introduce testing SPI to simulate text entry. Additionally, add a missing availability annotation around testing SPI added in 2017 to help test drag and drop for iOS 11. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _simulateTextEntered:]): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::setTextAsync): Tools: Add WebKitTestRunner support for listening to form editing SPI hooks in the injected bundle. The new layout test installs callbacks that listen for "begin editing", "end editing", and "text changed" calls to injected bundle SPI. See other ChangeLogs for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::enterText): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: Add UIScriptController support for simulating text entry in the currently focused element. * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::enterText): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: Add TestRunner bindings for registering injected bundle form client callbacks. * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: (WTR::handleTextDidChangeInTextField): (WTR::handleTextFieldDidBeginEditing): (WTR::handleTextFieldDidEndEditing): (WTR::InjectedBundle::didCreatePage): Set the injected bundle form editor client. (WTR::InjectedBundle::setUpInjectedBundleClients): (WTR::InjectedBundle::textDidChangeInTextField): (WTR::InjectedBundle::textFieldDidBeginEditing): (WTR::InjectedBundle::textFieldDidEndEditing): * WebKitTestRunner/InjectedBundle/InjectedBundle.h: * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::installTextDidChangeInTextFieldCallback): (WTR::TestRunner::textDidChangeInTextFieldCallback): (WTR::TestRunner::installTextFieldDidBeginEditingCallback): (WTR::TestRunner::textFieldDidBeginEditingCallback): (WTR::TestRunner::installTextFieldDidEndEditingCallback): (WTR::TestRunner::textFieldDidEndEditingCallback): * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::enterText): LayoutTests: Add a new layout test that focuses an input field, simulates text entry, and verifies that the injected bundle form client's textDidChangeInTextField, textFieldDidBeginEditing and textFieldDidEndEditing functions are called. * TestExpectations: Skip tests in fast/forms/extrazoom by default. * fast/forms/extrazoom/edit-text-field-calls-injected-bundle-expected.txt: Added. * fast/forms/extrazoom/edit-text-field-calls-injected-bundle.html: Added. * resources/ui-helper.js: (window.UIHelper.enterText): Introduce a new UIHelper method to simulate text entry in the currently focused element. (window.UIHelper): Canonical link: https://commits.webkit.org/200336@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230860 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-20 22:21:54 +00:00
static enterText(text)
{
const escapedText = text.replace(/`/g, "\\`");
const enterTextScript = `(() => uiController.enterText(\`${escapedText}\`))()`;
return new Promise(resolve => testRunner.runUIScript(enterTextScript, resolve));
}
[Extra zoom mode] REGRESSION(230860) Unable to change time input values using UI https://bugs.webkit.org/show_bug.cgi?id=184901 <rdar://problem/39664797> Reviewed by Tim Horton. Source/WebKit: Fixes the bug by falling back to setting the value of the focused input element in the case where the selection is not editable. Also adds plumbing to make time pickers testable in extra zoom mode. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView setTimePickerValueToHour:minute:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView setTimePickerValueToHour:minute:]): Add plumbing to make it possible for WebKitTestRunner to simulate picking a time from the given hours and minutes. This is currently only implemented for extra zoom mode, but may be implemented for UIKit's time picker as well in the future by adjusting -[WKContentView setTimePickerValueToHour:minute:]. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::setTextAsync): Tools: Introduce a new UIScriptController method to set the value of a currently focused input of type time, by interacting with the UI. See WebKit ChangeLogs for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setTimePickerValue): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setTimePickerValue): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setTimePickerValue): LayoutTests: Adds a basic test to verify that tapping on an input of type `time` and choosing a time actually changes the value of the input. Also adds a new UIHelper function to set the value of the currently focused input of type time to the given hours and minutes. * fast/forms/extrazoom/time-picker-value-change-expected.txt: Added. * fast/forms/extrazoom/time-picker-value-change.html: Added. * resources/ui-helper.js: (window.UIHelper.setTimePickerValue): (window.UIHelper): Canonical link: https://commits.webkit.org/200415@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230941 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-24 02:45:32 +00:00
static setTimePickerValue(hours, minutes)
{
const setValueScript = `(() => uiController.setTimePickerValue(${hours}, ${minutes}))()`;
return new Promise(resolve => testRunner.runUIScript(setValueScript, resolve));
}
[Extra zoom mode] The search field on www.bing.com is missing label text https://bugs.webkit.org/show_bug.cgi?id=184975 <rdar://problem/39723081> Reviewed by Tim Horton. Source/WebKit: Adds support for displaying the "aria-label" attribute as the input view's label text in extra zoom mode. Also adds support for grabbing the input label's text for testing. Test: fast/forms/extrazoom/form-control-label-text.html * Shared/AssistedNodeInformation.cpp: (WebKit::AssistedNodeInformation::encode const): (WebKit::AssistedNodeInformation::decode): * Shared/AssistedNodeInformation.h: * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView formInputLabel]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView formInputLabel]): * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::getAssistedNodeInformation): Tools: Adds UIScriptController.formInputLabel, which asynchronously requests the input label text for the currently focused element in extra zoom mode. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::formInputLabel const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::formInputLabel const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::formInputLabel const): LayoutTests: Adds a layout test to check that the label text of the focused form control in the input view can be sourced from (1) the "placeholder" attribute, (2) the "title" attribute, (3) the "aria-label" attribute, or (4) an associated label element. * fast/forms/extrazoom/form-control-label-text-expected.txt: Added. * fast/forms/extrazoom/form-control-label-text.html: Added. * resources/ui-helper.js: (window.UIHelper.formInputLabel): (window.UIHelper): Canonical link: https://commits.webkit.org/200493@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231022 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-25 21:23:27 +00:00
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
static timerPickerValues()
{
if (!this.isIOSFamily())
return Promise.resolve();
const uiScript = "JSON.stringify([uiController.timePickerValueHour, uiController.timePickerValueMinute])";
return new Promise(resolve => testRunner.runUIScript(uiScript, result => {
const [hour, minute] = JSON.parse(result)
resolve({ hour: hour, minute: minute });
}));
}
[WebKit on watchOS] Vend username text content type when using scribble in login fields https://bugs.webkit.org/show_bug.cgi?id=186791 <rdar://problem/41226935> Reviewed by Beth Dakin. Source/WebCore: Expose AutofillElements' autofillable username input element. See WebKit ChangeLog for more details. * editing/ios/AutofillElements.h: (WebCore::AutofillElements::username const): Source/WebKit: Vend additional context to Quickboard when focusing an element that is likely to be a username field. Test: fast/forms/watchos/username-text-content-type.html * Shared/AssistedNodeInformation.cpp: (WebKit::AssistedNodeInformation::encode const): (WebKit::AssistedNodeInformation::decode): * Shared/AssistedNodeInformation.h: Add a new flag to tell the UI process when the currently focused element is an autofillable username input field (using existing app autofill heuristics). * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView textContentTypeForTesting]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add new testing SPI to grab the computed text content type for the focused element. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (contentTypeFromFieldName): If `autocomplete="username"` is specified, return a username text content type. This was not originally added in r197626 because UITextContentTypeUsername was only introduced later, in iOS 11. (-[WKContentView textContentTypeForListViewController:]): (-[WKContentView textContentTypeForTesting]): * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::getAssistedNodeInformation): Tools: Add testing support for grabbing the current text content type of the focused element. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::textContentType const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::textContentType const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::textContentType const): LayoutTests: Add a new layout test verifying that: 1. There is no text content type for a lone plain text input. 2. The text content type for a plain text input preceding a password field is "username". 3. The text content type for a lone plain text input with `autocomplete="username"` is "username". * fast/forms/watchos/username-text-content-type-expected.txt: Added. * fast/forms/watchos/username-text-content-type.html: Added. * resources/ui-helper.js: (window.UIHelper.textContentType): Canonical link: https://commits.webkit.org/202071@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232968 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-06-19 18:09:49 +00:00
static textContentType()
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.textContentType);
})()`, resolve);
});
}
[Extra zoom mode] The search field on www.bing.com is missing label text https://bugs.webkit.org/show_bug.cgi?id=184975 <rdar://problem/39723081> Reviewed by Tim Horton. Source/WebKit: Adds support for displaying the "aria-label" attribute as the input view's label text in extra zoom mode. Also adds support for grabbing the input label's text for testing. Test: fast/forms/extrazoom/form-control-label-text.html * Shared/AssistedNodeInformation.cpp: (WebKit::AssistedNodeInformation::encode const): (WebKit::AssistedNodeInformation::decode): * Shared/AssistedNodeInformation.h: * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView formInputLabel]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView formInputLabel]): * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::getAssistedNodeInformation): Tools: Adds UIScriptController.formInputLabel, which asynchronously requests the input label text for the currently focused element in extra zoom mode. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::formInputLabel const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::formInputLabel const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::formInputLabel const): LayoutTests: Adds a layout test to check that the label text of the focused form control in the input view can be sourced from (1) the "placeholder" attribute, (2) the "title" attribute, (3) the "aria-label" attribute, or (4) an associated label element. * fast/forms/extrazoom/form-control-label-text-expected.txt: Added. * fast/forms/extrazoom/form-control-label-text.html: Added. * resources/ui-helper.js: (window.UIHelper.formInputLabel): (window.UIHelper): Canonical link: https://commits.webkit.org/200493@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231022 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-25 21:23:27 +00:00
static formInputLabel()
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.formInputLabel);
})()`, resolve);
});
}
[Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode https://bugs.webkit.org/show_bug.cgi?id=185050 <rdar://problem/39624038> Reviewed by Tim Horton. Source/WebCore: Currently, in extra zoom mode, there's no way for web pages to opt out of the default viewport behaviors (namely, laying out at a larger width and shrinking to fit) when the web view is very tall and narrow. This patch adds a new experimental viewport attribute, "min-device-width", that can be used to prevent WebKit from automatically clamping the web view width to a greater value for the device width in this scenario. Note that after this patch, logic that plumbs a minimumLayoutSize from WKWebView to the viewport configuration will need to be renamed to reflect that this size is no longer the minimum layout size, but rather, the view size that is used for viewport device dimensions by default. This refactoring will be done in a followup part. See per-method comments below for more detail. Test: fast/viewport/extrazoom/viewport-change-min-device-width.html * dom/ViewportArguments.cpp: (WebCore::setViewportFeature): (WebCore::operator<<): * dom/ViewportArguments.h: Removes `m_forceHorizontalShrinkToFit` (more detail below). * page/ViewportConfiguration.cpp: (WebCore::computedMinDeviceWidth): (WebCore::ViewportConfiguration::ViewportConfiguration): (WebCore::ViewportConfiguration::setMinimumLayoutSize): Instead of directly setting the minimum layout size, setMinimumLayoutSize now first sets the view size (i.e. the size we use for `device-width` in the viewport meta tag), and then updates the minimum layout size. (WebCore::ViewportConfiguration::shouldOverrideDeviceWidthWithMinDeviceWidth const): Replaces `m_forceHorizontalShrinkToFit`. Whether or not we shrink to fit is now determined by whether the min-device-width attribute is actively clamping the width of the view. (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const): (WebCore::ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize const): (WebCore::ViewportConfiguration::updateMinimumLayoutSize): Computes and sets the minimum layout size using the view size, taking the minimum device width into account if needed. (WebCore::ViewportConfiguration::description const): (WebCore::ViewportConfiguration::setForceHorizontalShrinkToFit): Deleted. * page/ViewportConfiguration.h: Source/WebKit: Remove the forceHorizontalViewportShrinkToFit and minimumAllowedLayoutWidth SPI hooks from WebKit, and additionally remove all logic for plumbing viewSize to WebCore. See WebCore/ChangeLog for more information. * Shared/VisibleContentRectUpdateInfo.cpp: (WebKit::VisibleContentRectUpdateInfo::encode const): (WebKit::VisibleContentRectUpdateInfo::decode): (WebKit::operator<<): * Shared/VisibleContentRectUpdateInfo.h: (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo): (WebKit::VisibleContentRectUpdateInfo::allowShrinkToFit const): (WebKit::operator==): (WebKit::VisibleContentRectUpdateInfo::forceHorizontalShrinkToFit const): Deleted. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _initializeWithConfiguration:]): (-[WKWebView activeMinimumLayoutSize:]): (-[WKWebView _dispatchSetMinimumLayoutSize:]): (-[WKWebView _frameOrBoundsChanged]): (-[WKWebView _setMinimumLayoutSizeOverride:]): (-[WKWebView _beginAnimatedResizeWithUpdates:]): (-[WKWebView _endAnimatedResize]): (-[WKWebView _minimumAllowedLayoutWidth]): Deleted. (-[WKWebView _setMinimumAllowedLayoutWidth:]): Deleted. (-[WKWebView activeMinimumLayoutSizes:]): Deleted. (-[WKWebView _dispatchSetMinimumLayoutSize:viewSize:]): Deleted. (-[WKWebView _setForceHorizontalViewportShrinkToFit:]): Deleted. (-[WKWebView _forceHorizontalViewportShrinkToFit]): Deleted. * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::creationParameters): * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentView.mm: (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::dynamicViewportSizeUpdate): (WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize): * WebProcess/WebPage/WebPage.cpp: (WebKit::m_credentialsMessenger): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationMinimumLayoutSize): (WebKit::WebPage::dynamicViewportSizeUpdate): (WebKit::WebPage::updateVisibleContentRects): Tools: Remove a test that's no longer useful, now that the SPI it was testing is gone. This functionality is now tested by the layout test added in this patch. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/ios/ViewportSizingTests.mm: Removed. LayoutTests: Add a new layout test to check that: • By default (with no `min-device-width` override), shrink-to-fit and expanded minimum layout sizes takes effect. • `min-device-width` can be used to bail out of shrink-to-fit and viewport behaviors. • A large `min-device-width` can be used to make extra zoom mode viewport heuristics even more aggressive. * TestExpectations: * fast/viewport/extrazoom/viewport-change-min-device-width.html: Added. * resources/ui-helper.js: (window.UIHelper.zoomScale): (window.UIHelper): Canonical link: https://commits.webkit.org/200561@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231095 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-27 15:35:50 +00:00
[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
static dismissFilePicker()
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve();
const script = `uiController.dismissFilePicker(() => {
uiController.uiScriptComplete();
})`;
return new Promise(resolve => testRunner.runUIScript(script, resolve));
}
static filePickerAcceptedTypeIdentifiers()
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(JSON.stringify(uiController.filePickerAcceptedTypeIdentifiers));
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
Native text substitutions interfere with HTML <datalist> options resulting in crash https://bugs.webkit.org/show_bug.cgi?id=203116 <rdar://problem/49875932> Reviewed by Tim Horton. Source/WebKit: On macOS, an NSTableView inside a separate window is used to render suggestions when showing a datalist. The crash happens when this table view is reloaded while clicking a datalist suggestion; that is, if -[NSTableView reloadData] is invoked after the user sends a platform MouseDown event on the table view cell but before the MouseUp is received, the selected row of the table view will be -1 when the action, `-selectedRow:`, is invoked. In this particular case, the table view reload is triggered as a result of hiding the autocorrection bubble on macOS, thereby committing the alternative text suggestion and changing the value of the text field via an editing command. To avoid crashing, we simply make `-selectedRow:` robust in the case where the index is invalid. Test: fast/forms/datalist/datalist-click-crash.html * UIProcess/mac/WebDataListSuggestionsDropdownMac.mm: (-[WKDataListSuggestionsController selectedRow:]): Tools: Add a new testing hook to wait for datalist suggestions to show up and choose the suggestion at the given index. * DumpRenderTree/mac/UIScriptControllerMac.h: * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptControllerMac::activateDataListSuggestion): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::activateDataListSuggestion): * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::activateDataListSuggestion): * WebKitTestRunner/mac/UIScriptControllerMac.h: * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptControllerMac::isShowingDataListSuggestions const): (WTR::UIScriptControllerMac::activateDataListSuggestion): Dig through the view hierarchy of the NSWindow subclass used to show datalist suggestions for the table view containing the suggestions; then, select the given row, and invoke the action on the target. (WTR::UIScriptControllerMac::dataListSuggestionsTableView const): LayoutTests: Add a new layout test to exercise the crash. * fast/forms/datalist/datalist-click-crash-expected.txt: Added. * fast/forms/datalist/datalist-click-crash.html: Added. * resources/ui-helper.js: (window.UIHelper.activateDataListSuggestion): Canonical link: https://commits.webkit.org/217216@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252062 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-11-05 18:52:12 +00:00
static activateDataListSuggestion(index) {
const script = `uiController.activateDataListSuggestion(${index}, () => {
uiController.uiScriptComplete("");
});`;
return new Promise(resolve => testRunner.runUIScript(script, resolve));
}
[Datalist][macOS] Add suggestions UI for TextFieldInputTypes https://bugs.webkit.org/show_bug.cgi?id=186531 Patch by Aditya Keerthi <akeerthi@apple.com> on 2018-07-16 Reviewed by Tim Horton. Source/WebCore: Tests: fast/forms/datalist/datalist-show-hide.html fast/forms/datalist/datalist-textinput-keydown.html * html/TextFieldInputType.cpp: (WebCore::TextFieldInputType::handleKeydownEvent): (WebCore::TextFieldInputType::handleKeydownEventForSpinButton): The suggestions view takes precedence when handling arrow key events. Source/WebKit: Created WebDataListSuggestionsDropdownMac as a wrapper around the suggestions view. The suggestions for TextFieldInputTypes are displayed using an NSTableView in it's own child window. This is done so that suggestions can be presented outside of the page if the parent window's size is too small. The maximum number of suggestions that are visible at one time is 6, with additional suggestions made available by scrolling. Suggestions in the view can be selected via click or by using arrow keys. If the input element associated with the suggestions is blurred, or the page is moved in any way, the suggestions view is hidden. Added IPC messages to the UIProcess to enable the display of the suggestions view. This required a new ArgumentCoder for DataListSuggestionInformation. * Shared/WebCoreArgumentCoders.cpp: (IPC::ArgumentCoder<DataListSuggestionInformation>::encode): (IPC::ArgumentCoder<DataListSuggestionInformation>::decode): * Shared/WebCoreArgumentCoders.h: * UIProcess/PageClient.h: * UIProcess/WebDataListSuggestionsDropdown.cpp: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h. (WebKit::WebDataListSuggestionsDropdown::WebDataListSuggestionsDropdown): (WebKit::WebDataListSuggestionsDropdown::~WebDataListSuggestionsDropdown): (WebKit::WebDataListSuggestionsDropdown::close): * UIProcess/WebDataListSuggestionsDropdown.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h. (WebKit::WebDataListSuggestionsDropdown::Client::~Client): * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::viewWillStartLiveResize): (WebKit::WebPageProxy::viewDidLeaveWindow): (WebKit::WebPageProxy::handleWheelEvent): (WebKit::WebPageProxy::setPageZoomFactor): (WebKit::WebPageProxy::setPageAndTextZoomFactors): (WebKit::WebPageProxy::didStartProvisionalLoadForFrame): (WebKit::WebPageProxy::pageDidScroll): (WebKit::WebPageProxy::showDataListSuggestions): (WebKit::WebPageProxy::handleKeydownInDataList): (WebKit::WebPageProxy::endDataListSuggestions): (WebKit::WebPageProxy::didCloseSuggestions): (WebKit::WebPageProxy::didSelectOption): (WebKit::WebPageProxy::resetState): (WebKit::WebPageProxy::closeOverlayedViews): * UIProcess/WebPageProxy.h: * UIProcess/WebPageProxy.messages.in: * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::createDataListSuggestionsDropdown): * UIProcess/mac/PageClientImplMac.h: * UIProcess/mac/PageClientImplMac.mm: (WebKit::PageClientImpl::createDataListSuggestionsDropdown): * UIProcess/mac/WebDataListSuggestionsDropdownMac.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h. * UIProcess/mac/WebDataListSuggestionsDropdownMac.mm: Added. (WebKit::WebDataListSuggestionsDropdownMac::create): (WebKit::WebDataListSuggestionsDropdownMac::~WebDataListSuggestionsDropdownMac): (WebKit::WebDataListSuggestionsDropdownMac::WebDataListSuggestionsDropdownMac): (WebKit::WebDataListSuggestionsDropdownMac::show): (WebKit::WebDataListSuggestionsDropdownMac::didSelectOption): (WebKit::WebDataListSuggestionsDropdownMac::selectOption): (WebKit::WebDataListSuggestionsDropdownMac::handleKeydownWithIdentifier): (WebKit::WebDataListSuggestionsDropdownMac::close): (-[WKDataListSuggestionCell initWithFrame:]): (-[WKDataListSuggestionCell setText:]): (-[WKDataListSuggestionCell setActive:]): (-[WKDataListSuggestionCell drawRect:]): (-[WKDataListSuggestionCell mouseEntered:]): (-[WKDataListSuggestionCell mouseExited:]): (-[WKDataListSuggestionCell acceptsFirstResponder]): (-[WKDataListSuggestionTable initWithElementRect:]): (-[WKDataListSuggestionTable setVisibleRect:]): (-[WKDataListSuggestionTable currentActiveRow]): (-[WKDataListSuggestionTable setActiveRow:]): (-[WKDataListSuggestionTable reload]): (-[WKDataListSuggestionTable acceptsFirstResponder]): (-[WKDataListSuggestionTable enclosingScrollView]): (-[WKDataListSuggestionTable removeFromSuperviewWithoutNeedingDisplay]): (-[WKDataListSuggestionsView initWithInformation:inView:]): (-[WKDataListSuggestionsView currentSelectedString]): (-[WKDataListSuggestionsView updateWithInformation:]): (-[WKDataListSuggestionsView moveSelectionByDirection:]): (-[WKDataListSuggestionsView invalidate]): (-[WKDataListSuggestionsView dropdownRectForElementRect:]): (-[WKDataListSuggestionsView showSuggestionsDropdown:]): (-[WKDataListSuggestionsView selectedRow:]): (-[WKDataListSuggestionsView numberOfRowsInTableView:]): (-[WKDataListSuggestionsView tableView:heightOfRow:]): (-[WKDataListSuggestionsView tableView:viewForTableColumn:row:]): * WebKit.xcodeproj/project.pbxproj: * WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp: (WebKit::WebDataListSuggestionPicker::handleKeydownWithIdentifier): (WebKit::WebDataListSuggestionPicker::didSelectOption): (WebKit::WebDataListSuggestionPicker::didCloseSuggestions): (WebKit::WebDataListSuggestionPicker::close): (WebKit::WebDataListSuggestionPicker::displayWithActivationType): * WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h: Tools: Added isShowingDatalistSuggestions testing hook in order to enable testing of the visibility of the suggestions view. * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::isShowingDataListSuggestions const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isShowingDataListSuggestions const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::isShowingDataListSuggestions const): LayoutTests: Added tests to verify that the suggestions are correctly shown and hidden, and that suggestions can be selected and inserted into an input field. * fast/forms/datalist/datalist-show-hide-expected.txt: Added. * fast/forms/datalist/datalist-show-hide.html: Added. * fast/forms/datalist/datalist-textinput-keydown-expected.txt: Added. * fast/forms/datalist/datalist-textinput-keydown.html: Added. * platform/ios/TestExpectations: * resources/ui-helper.js: (window.UIHelper.isShowingDataListSuggestions): Canonical link: https://commits.webkit.org/202914@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233866 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-07-16 21:15:57 +00:00
static isShowingDataListSuggestions()
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.isShowingDataListSuggestions);
fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html does not work on iPad https://bugs.webkit.org/show_bug.cgi?id=194313 Reviewed by Tim Horton. Source/WebKit: Make `-dateTimePickerCalendarType` work on iPad by handling the case where the date picker control is a WKDateTimePopover. This fixes UIScriptController::calendarType() returning null on iPad. * UIProcess/ios/forms/WKFormInputControl.mm: (-[WKFormInputControl dateTimePickerCalendarType]): (-[WKDateTimePopover calendarType]): Tools: Add a helper to determine whether the web view is presenting modal UI. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isPresentingModally const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::calendarType const): Deleted. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isPresentingModally const): (WTR::UIScriptController::calendarType const): * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::calendarType const): LayoutTests: Adjusts an existing layout test to work on both iPhone and iPad simulators. * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry-expected.txt: * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html: Make this test wait after blurring the currently focused element, such that tapping to focus the next form control doesn't fail. Notably on iPad, not waiting for the popover to dismiss meant that subsequent taps would be dispatched too soon, and hit-test to the popover view being dismissed rather than WKWebView. * platform/ipad/TestExpectations: Unskip the test on iPad. * resources/ui-helper.js: Add helpers to query whether or not the keyboard is shown, and whether or not a view controller is being modally presented over the current root view controller (this is the case when interacting with date pickers on iPad). (window.UIHelper.isShowingKeyboard): (window.UIHelper.isPresentingModally): (window.UIHelper.deactivateFormControl): Add a new helper method to blur the given form control element and wait for web view chrome to finish dismissing (on iOS, this is either the date picker input view in the keyboard on iPhone, or the date picker popover view controller on iPad). (window.UIHelper.isShowingDataListSuggestions): Drive-by fix: remove an extraneous ternary conditional statement. Canonical link: https://commits.webkit.org/208934@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241275 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 19:30:05 +00:00
})()`, result => resolve(result === "true"));
[Datalist][macOS] Add suggestions UI for TextFieldInputTypes https://bugs.webkit.org/show_bug.cgi?id=186531 Patch by Aditya Keerthi <akeerthi@apple.com> on 2018-07-16 Reviewed by Tim Horton. Source/WebCore: Tests: fast/forms/datalist/datalist-show-hide.html fast/forms/datalist/datalist-textinput-keydown.html * html/TextFieldInputType.cpp: (WebCore::TextFieldInputType::handleKeydownEvent): (WebCore::TextFieldInputType::handleKeydownEventForSpinButton): The suggestions view takes precedence when handling arrow key events. Source/WebKit: Created WebDataListSuggestionsDropdownMac as a wrapper around the suggestions view. The suggestions for TextFieldInputTypes are displayed using an NSTableView in it's own child window. This is done so that suggestions can be presented outside of the page if the parent window's size is too small. The maximum number of suggestions that are visible at one time is 6, with additional suggestions made available by scrolling. Suggestions in the view can be selected via click or by using arrow keys. If the input element associated with the suggestions is blurred, or the page is moved in any way, the suggestions view is hidden. Added IPC messages to the UIProcess to enable the display of the suggestions view. This required a new ArgumentCoder for DataListSuggestionInformation. * Shared/WebCoreArgumentCoders.cpp: (IPC::ArgumentCoder<DataListSuggestionInformation>::encode): (IPC::ArgumentCoder<DataListSuggestionInformation>::decode): * Shared/WebCoreArgumentCoders.h: * UIProcess/PageClient.h: * UIProcess/WebDataListSuggestionsDropdown.cpp: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h. (WebKit::WebDataListSuggestionsDropdown::WebDataListSuggestionsDropdown): (WebKit::WebDataListSuggestionsDropdown::~WebDataListSuggestionsDropdown): (WebKit::WebDataListSuggestionsDropdown::close): * UIProcess/WebDataListSuggestionsDropdown.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h. (WebKit::WebDataListSuggestionsDropdown::Client::~Client): * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::viewWillStartLiveResize): (WebKit::WebPageProxy::viewDidLeaveWindow): (WebKit::WebPageProxy::handleWheelEvent): (WebKit::WebPageProxy::setPageZoomFactor): (WebKit::WebPageProxy::setPageAndTextZoomFactors): (WebKit::WebPageProxy::didStartProvisionalLoadForFrame): (WebKit::WebPageProxy::pageDidScroll): (WebKit::WebPageProxy::showDataListSuggestions): (WebKit::WebPageProxy::handleKeydownInDataList): (WebKit::WebPageProxy::endDataListSuggestions): (WebKit::WebPageProxy::didCloseSuggestions): (WebKit::WebPageProxy::didSelectOption): (WebKit::WebPageProxy::resetState): (WebKit::WebPageProxy::closeOverlayedViews): * UIProcess/WebPageProxy.h: * UIProcess/WebPageProxy.messages.in: * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::createDataListSuggestionsDropdown): * UIProcess/mac/PageClientImplMac.h: * UIProcess/mac/PageClientImplMac.mm: (WebKit::PageClientImpl::createDataListSuggestionsDropdown): * UIProcess/mac/WebDataListSuggestionsDropdownMac.h: Copied from Source/WebKit/WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h. * UIProcess/mac/WebDataListSuggestionsDropdownMac.mm: Added. (WebKit::WebDataListSuggestionsDropdownMac::create): (WebKit::WebDataListSuggestionsDropdownMac::~WebDataListSuggestionsDropdownMac): (WebKit::WebDataListSuggestionsDropdownMac::WebDataListSuggestionsDropdownMac): (WebKit::WebDataListSuggestionsDropdownMac::show): (WebKit::WebDataListSuggestionsDropdownMac::didSelectOption): (WebKit::WebDataListSuggestionsDropdownMac::selectOption): (WebKit::WebDataListSuggestionsDropdownMac::handleKeydownWithIdentifier): (WebKit::WebDataListSuggestionsDropdownMac::close): (-[WKDataListSuggestionCell initWithFrame:]): (-[WKDataListSuggestionCell setText:]): (-[WKDataListSuggestionCell setActive:]): (-[WKDataListSuggestionCell drawRect:]): (-[WKDataListSuggestionCell mouseEntered:]): (-[WKDataListSuggestionCell mouseExited:]): (-[WKDataListSuggestionCell acceptsFirstResponder]): (-[WKDataListSuggestionTable initWithElementRect:]): (-[WKDataListSuggestionTable setVisibleRect:]): (-[WKDataListSuggestionTable currentActiveRow]): (-[WKDataListSuggestionTable setActiveRow:]): (-[WKDataListSuggestionTable reload]): (-[WKDataListSuggestionTable acceptsFirstResponder]): (-[WKDataListSuggestionTable enclosingScrollView]): (-[WKDataListSuggestionTable removeFromSuperviewWithoutNeedingDisplay]): (-[WKDataListSuggestionsView initWithInformation:inView:]): (-[WKDataListSuggestionsView currentSelectedString]): (-[WKDataListSuggestionsView updateWithInformation:]): (-[WKDataListSuggestionsView moveSelectionByDirection:]): (-[WKDataListSuggestionsView invalidate]): (-[WKDataListSuggestionsView dropdownRectForElementRect:]): (-[WKDataListSuggestionsView showSuggestionsDropdown:]): (-[WKDataListSuggestionsView selectedRow:]): (-[WKDataListSuggestionsView numberOfRowsInTableView:]): (-[WKDataListSuggestionsView tableView:heightOfRow:]): (-[WKDataListSuggestionsView tableView:viewForTableColumn:row:]): * WebKit.xcodeproj/project.pbxproj: * WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp: (WebKit::WebDataListSuggestionPicker::handleKeydownWithIdentifier): (WebKit::WebDataListSuggestionPicker::didSelectOption): (WebKit::WebDataListSuggestionPicker::didCloseSuggestions): (WebKit::WebDataListSuggestionPicker::close): (WebKit::WebDataListSuggestionPicker::displayWithActivationType): * WebProcess/WebCoreSupport/WebDataListSuggestionPicker.h: Tools: Added isShowingDatalistSuggestions testing hook in order to enable testing of the visibility of the suggestions view. * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::isShowingDataListSuggestions const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isShowingDataListSuggestions const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::isShowingDataListSuggestions const): LayoutTests: Added tests to verify that the suggestions are correctly shown and hidden, and that suggestions can be selected and inserted into an input field. * fast/forms/datalist/datalist-show-hide-expected.txt: Added. * fast/forms/datalist/datalist-show-hide.html: Added. * fast/forms/datalist/datalist-textinput-keydown-expected.txt: Added. * fast/forms/datalist/datalist-textinput-keydown.html: Added. * platform/ios/TestExpectations: * resources/ui-helper.js: (window.UIHelper.isShowingDataListSuggestions): Canonical link: https://commits.webkit.org/202914@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233866 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-07-16 21:15:57 +00:00
});
}
[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
static isShowingDateTimePicker()
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.isShowingDateTimePicker);
})()`, result => resolve(result === "true"));
});
}
[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
static dateTimePickerValue()
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.dateTimePickerValue);
})()`, valueAsString => resolve(parseFloat(valueAsString)));
});
}
[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
static chooseDateTimePickerValue()
{
return new Promise((resolve) => {
testRunner.runUIScript(`
uiController.chooseDateTimePickerValue();
uiController.uiScriptComplete();
`, resolve);
});
}
[Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode https://bugs.webkit.org/show_bug.cgi?id=185050 <rdar://problem/39624038> Reviewed by Tim Horton. Source/WebCore: Currently, in extra zoom mode, there's no way for web pages to opt out of the default viewport behaviors (namely, laying out at a larger width and shrinking to fit) when the web view is very tall and narrow. This patch adds a new experimental viewport attribute, "min-device-width", that can be used to prevent WebKit from automatically clamping the web view width to a greater value for the device width in this scenario. Note that after this patch, logic that plumbs a minimumLayoutSize from WKWebView to the viewport configuration will need to be renamed to reflect that this size is no longer the minimum layout size, but rather, the view size that is used for viewport device dimensions by default. This refactoring will be done in a followup part. See per-method comments below for more detail. Test: fast/viewport/extrazoom/viewport-change-min-device-width.html * dom/ViewportArguments.cpp: (WebCore::setViewportFeature): (WebCore::operator<<): * dom/ViewportArguments.h: Removes `m_forceHorizontalShrinkToFit` (more detail below). * page/ViewportConfiguration.cpp: (WebCore::computedMinDeviceWidth): (WebCore::ViewportConfiguration::ViewportConfiguration): (WebCore::ViewportConfiguration::setMinimumLayoutSize): Instead of directly setting the minimum layout size, setMinimumLayoutSize now first sets the view size (i.e. the size we use for `device-width` in the viewport meta tag), and then updates the minimum layout size. (WebCore::ViewportConfiguration::shouldOverrideDeviceWidthWithMinDeviceWidth const): Replaces `m_forceHorizontalShrinkToFit`. Whether or not we shrink to fit is now determined by whether the min-device-width attribute is actively clamping the width of the view. (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const): (WebCore::ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize const): (WebCore::ViewportConfiguration::updateMinimumLayoutSize): Computes and sets the minimum layout size using the view size, taking the minimum device width into account if needed. (WebCore::ViewportConfiguration::description const): (WebCore::ViewportConfiguration::setForceHorizontalShrinkToFit): Deleted. * page/ViewportConfiguration.h: Source/WebKit: Remove the forceHorizontalViewportShrinkToFit and minimumAllowedLayoutWidth SPI hooks from WebKit, and additionally remove all logic for plumbing viewSize to WebCore. See WebCore/ChangeLog for more information. * Shared/VisibleContentRectUpdateInfo.cpp: (WebKit::VisibleContentRectUpdateInfo::encode const): (WebKit::VisibleContentRectUpdateInfo::decode): (WebKit::operator<<): * Shared/VisibleContentRectUpdateInfo.h: (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo): (WebKit::VisibleContentRectUpdateInfo::allowShrinkToFit const): (WebKit::operator==): (WebKit::VisibleContentRectUpdateInfo::forceHorizontalShrinkToFit const): Deleted. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _initializeWithConfiguration:]): (-[WKWebView activeMinimumLayoutSize:]): (-[WKWebView _dispatchSetMinimumLayoutSize:]): (-[WKWebView _frameOrBoundsChanged]): (-[WKWebView _setMinimumLayoutSizeOverride:]): (-[WKWebView _beginAnimatedResizeWithUpdates:]): (-[WKWebView _endAnimatedResize]): (-[WKWebView _minimumAllowedLayoutWidth]): Deleted. (-[WKWebView _setMinimumAllowedLayoutWidth:]): Deleted. (-[WKWebView activeMinimumLayoutSizes:]): Deleted. (-[WKWebView _dispatchSetMinimumLayoutSize:viewSize:]): Deleted. (-[WKWebView _setForceHorizontalViewportShrinkToFit:]): Deleted. (-[WKWebView _forceHorizontalViewportShrinkToFit]): Deleted. * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::creationParameters): * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentView.mm: (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::dynamicViewportSizeUpdate): (WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize): * WebProcess/WebPage/WebPage.cpp: (WebKit::m_credentialsMessenger): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationMinimumLayoutSize): (WebKit::WebPage::dynamicViewportSizeUpdate): (WebKit::WebPage::updateVisibleContentRects): Tools: Remove a test that's no longer useful, now that the SPI it was testing is gone. This functionality is now tested by the layout test added in this patch. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/ios/ViewportSizingTests.mm: Removed. LayoutTests: Add a new layout test to check that: • By default (with no `min-device-width` override), shrink-to-fit and expanded minimum layout sizes takes effect. • `min-device-width` can be used to bail out of shrink-to-fit and viewport behaviors. • A large `min-device-width` can be used to make extra zoom mode viewport heuristics even more aggressive. * TestExpectations: * fast/viewport/extrazoom/viewport-change-min-device-width.html: Added. * resources/ui-helper.js: (window.UIHelper.zoomScale): (window.UIHelper): Canonical link: https://commits.webkit.org/200561@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231095 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-27 15:35:50 +00:00
static zoomScale()
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.zoomScale);
[iOS] Changing view scale sometimes does not zoom the page to the new initial scale, when the page is at initial scale https://bugs.webkit.org/show_bug.cgi?id=191180 <rdar://problem/45744786> Reviewed by Simon Fraser. Source/WebCore: When computing the minimum scale in ViewportConfiguration::minimumScale, if our content width or height is shorter than the view width or height, then we recompute the minimum scale such that the content dimensions will fill the bounds of the view by setting the minimum scale to the view width or height divided by the content width or height. Suppose the minimum scale is equal to some value `s`; additionally, let `w_c` denote the content width and `w_v` denote the view width (as integers). If `w_v / s` is not an integral value, the computed content width `w_c` may be rounded, such that `w_v / w_c` is not precisely equal to `s`. In the case that `w_v / w_c` is ever so slightly larger than `s`, we will end up overriding the minimum scale `s` with `w_v / w_c`. As a result, specifying a viewport with a decimal `minimum-scale` will sometimes cause the computed minimum scale of the viewport (and platform view) to be very slightly different from the minimum scale. The new layout test below exercises this scenario, specifying a viewport with minimum and initial scales of 0.94 that results in `ViewportConfiguration::minimumScale` returning 0.94158. With the `WebPage::setViewportConfigurationViewLayoutSize` check added in r237127, this means setting `_viewScale:` when the page is at initial scale sometimes doesn't zoom the page to the new initial scale when it should, since the page scale factor and the initial scale are different enough such that `areEssentiallyEqualAsFloat` returns false. This patch addresses these issues by snapping to the minimum scale if the computed scale that fits content dimensions to view dimensions results in a minimum scale that is close enough to the configuration's minimum scale, such that the difference can be attributed to rounding error when computing content or view dimensions. Test: fast/viewport/ios/viewport-minimum-and-initial-scale.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::minimumScale const): LayoutTests: Add a layout test, and make some adjustments to UIHelper. * fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html: * fast/viewport/ios/device-width-viewport-after-changing-view-scale.html: * fast/viewport/ios/viewport-minimum-and-initial-scale-expected.txt: Added. * fast/viewport/ios/viewport-minimum-and-initial-scale.html: Added. Add a new layout test that contains a viewport meta tag with minimum and initial scales set to 0.94, and checks that the resulting minimum and initial scales are 0.94 instead of 0.94158. * fast/viewport/watchos/viewport-disable-extra-zoom-adaptations.html: * resources/ui-helper.js: Make UIHelper.zoomScale return a number rather than a string, and adjust a few call sites. (window.UIHelper.zoomScale): (window.UIHelper.minimumZoomScale): (window.UIHelper): Canonical link: https://commits.webkit.org/206009@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237743 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-02 18:10:23 +00:00
})()`, scaleAsString => resolve(parseFloat(scaleAsString)));
[Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode https://bugs.webkit.org/show_bug.cgi?id=185050 <rdar://problem/39624038> Reviewed by Tim Horton. Source/WebCore: Currently, in extra zoom mode, there's no way for web pages to opt out of the default viewport behaviors (namely, laying out at a larger width and shrinking to fit) when the web view is very tall and narrow. This patch adds a new experimental viewport attribute, "min-device-width", that can be used to prevent WebKit from automatically clamping the web view width to a greater value for the device width in this scenario. Note that after this patch, logic that plumbs a minimumLayoutSize from WKWebView to the viewport configuration will need to be renamed to reflect that this size is no longer the minimum layout size, but rather, the view size that is used for viewport device dimensions by default. This refactoring will be done in a followup part. See per-method comments below for more detail. Test: fast/viewport/extrazoom/viewport-change-min-device-width.html * dom/ViewportArguments.cpp: (WebCore::setViewportFeature): (WebCore::operator<<): * dom/ViewportArguments.h: Removes `m_forceHorizontalShrinkToFit` (more detail below). * page/ViewportConfiguration.cpp: (WebCore::computedMinDeviceWidth): (WebCore::ViewportConfiguration::ViewportConfiguration): (WebCore::ViewportConfiguration::setMinimumLayoutSize): Instead of directly setting the minimum layout size, setMinimumLayoutSize now first sets the view size (i.e. the size we use for `device-width` in the viewport meta tag), and then updates the minimum layout size. (WebCore::ViewportConfiguration::shouldOverrideDeviceWidthWithMinDeviceWidth const): Replaces `m_forceHorizontalShrinkToFit`. Whether or not we shrink to fit is now determined by whether the min-device-width attribute is actively clamping the width of the view. (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const): (WebCore::ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize const): (WebCore::ViewportConfiguration::updateMinimumLayoutSize): Computes and sets the minimum layout size using the view size, taking the minimum device width into account if needed. (WebCore::ViewportConfiguration::description const): (WebCore::ViewportConfiguration::setForceHorizontalShrinkToFit): Deleted. * page/ViewportConfiguration.h: Source/WebKit: Remove the forceHorizontalViewportShrinkToFit and minimumAllowedLayoutWidth SPI hooks from WebKit, and additionally remove all logic for plumbing viewSize to WebCore. See WebCore/ChangeLog for more information. * Shared/VisibleContentRectUpdateInfo.cpp: (WebKit::VisibleContentRectUpdateInfo::encode const): (WebKit::VisibleContentRectUpdateInfo::decode): (WebKit::operator<<): * Shared/VisibleContentRectUpdateInfo.h: (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo): (WebKit::VisibleContentRectUpdateInfo::allowShrinkToFit const): (WebKit::operator==): (WebKit::VisibleContentRectUpdateInfo::forceHorizontalShrinkToFit const): Deleted. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _initializeWithConfiguration:]): (-[WKWebView activeMinimumLayoutSize:]): (-[WKWebView _dispatchSetMinimumLayoutSize:]): (-[WKWebView _frameOrBoundsChanged]): (-[WKWebView _setMinimumLayoutSizeOverride:]): (-[WKWebView _beginAnimatedResizeWithUpdates:]): (-[WKWebView _endAnimatedResize]): (-[WKWebView _minimumAllowedLayoutWidth]): Deleted. (-[WKWebView _setMinimumAllowedLayoutWidth:]): Deleted. (-[WKWebView activeMinimumLayoutSizes:]): Deleted. (-[WKWebView _dispatchSetMinimumLayoutSize:viewSize:]): Deleted. (-[WKWebView _setForceHorizontalViewportShrinkToFit:]): Deleted. (-[WKWebView _forceHorizontalViewportShrinkToFit]): Deleted. * UIProcess/API/Cocoa/WKWebViewPrivate.h: * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::creationParameters): * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentView.mm: (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::dynamicViewportSizeUpdate): (WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize): * WebProcess/WebPage/WebPage.cpp: (WebKit::m_credentialsMessenger): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationMinimumLayoutSize): (WebKit::WebPage::dynamicViewportSizeUpdate): (WebKit::WebPage::updateVisibleContentRects): Tools: Remove a test that's no longer useful, now that the SPI it was testing is gone. This functionality is now tested by the layout test added in this patch. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/ios/ViewportSizingTests.mm: Removed. LayoutTests: Add a new layout test to check that: • By default (with no `min-device-width` override), shrink-to-fit and expanded minimum layout sizes takes effect. • `min-device-width` can be used to bail out of shrink-to-fit and viewport behaviors. • A large `min-device-width` can be used to make extra zoom mode viewport heuristics even more aggressive. * TestExpectations: * fast/viewport/extrazoom/viewport-change-min-device-width.html: Added. * resources/ui-helper.js: (window.UIHelper.zoomScale): (window.UIHelper): Canonical link: https://commits.webkit.org/200561@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231095 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-27 15:35:50 +00:00
});
}
[iOS] Tests that try to interact with the QuickType bar time out on iOS 11+ https://bugs.webkit.org/show_bug.cgi?id=188335 <rdar://problem/32542437> and <rdar://problem/32542433> Reviewed by Tim Horton. Tools: Remove a UIScriptController helper method that attempted to wait for QuickType buttons to appear, and then send touch events to the buttons. These were only used for the two tests which this patch refactors. See the LayoutTests ChangeLog for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestRunnerShared/spi/UIKitTestSPI.h: Remove an internal class declaration that is now unnecessary. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. LayoutTests: Refactors a couple of tests that currently rely on the QuickType bar being shown when the hardware keyboard is presented in the iOS simulator, so that it can insert text suggestions by tapping QuickType bar buttons; in the first place, it was never guaranteed that this bar would show up, or even have more than 1 text suggestion. Instead, we use the existing UIScriptController::applyAutocorrection method to trigger text replacement in the same way tapping a button on the QuickType bar would replace the current word with the suggested word. * fast/events/ios/before-input-events-prevent-candidate-insertion-expected.txt: * fast/events/ios/before-input-events-prevent-candidate-insertion.html: * fast/events/ios/input-events-insert-replacement-text-expected.txt: * fast/events/ios/input-events-insert-replacement-text.html: * platform/ios/TestExpectations: Removes a [Timeout] expectation. * resources/ui-helper.js: (window.UIHelper.typeCharacter): Add a new UIHelper method to type a character using the keyboard. Sends hardware keyboard events on the WebKit2 port of iOS, and uses EventSender elsewhere. (window.UIHelper.applyAutocorrection): Add a new UIHelper method that wraps UIScriptController::applyAutocorrection. Only supported in WebKit2 currently. (window.UIHelper): Canonical link: https://commits.webkit.org/203448@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234601 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-06 15:01:47 +00:00
[iOS] Suppress native selection behaviors when focusing a very small editable element https://bugs.webkit.org/show_bug.cgi?id=193005 <rdar://problem/46583527> Reviewed by Tim Horton. Source/WebKit: In r238146, I added a mechanism to detect when the selection is hidden within transparent editable elements, and used this to suppress native selection on iOS (such as selection handles, highlight, callout bar, etc.) to avoid conflicts between the page's editing UI and the platform. However, one additional technique observed on some websites involves hiding the selection by moving it into a tiny (1x1) editable element. Here, we currently still present a callout bar with editing actions, as well as show a selection caret or handles on iOS. To fix this, we extend the mechanism added in r238146 by also suppressing the selection assistant in the case where the editable element's area is beneath a tiny minimum threshold. Test: editing/selection/ios/hide-selection-in-tiny-contenteditable.html * Shared/EditorState.cpp: (WebKit::EditorState::PostLayoutData::encode const): (WebKit::EditorState::PostLayoutData::decode): (WebKit::operator<<): * Shared/EditorState.h: Rename selectionClipRect to focusedElementRect. We currently propagate the bounds of the focused element to the UI process through EditorState updates, but only for the purpose of returning it in the computed selection clip rect; instead, rename this member to something more general-purpose, so we can also use it when determining whether to suppress the selection assistant. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _candidateRect]): * UIProcess/Cocoa/WebViewImpl.mm: (WebKit::WebViewImpl::handleRequestedCandidates): * UIProcess/ios/WKContentViewInteraction.h: Add a new SuppressSelectionAssistantReason that corresponds to focusing tiny editable elements. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _zoomToRevealFocusedElement]): (-[WKContentView _selectionClipRect]): (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): (-[WKContentView _updateChangedSelection:]): Check the size of the focused element, and begin or stop suppressing the selection assistant accordingly. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): LayoutTests: Add a new layout test to verify that native selection UI is suppressed when focusing a tiny (1px by 1px) editable element. * editing/selection/ios/hide-selection-in-tiny-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-in-tiny-contenteditable.html: Added. * resources/ui-helper.js: (window.UIHelper.zoomToScale): Canonical link: https://commits.webkit.org/207574@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239543 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-23 06:38:24 +00:00
static zoomToScale(scale)
{
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
const uiScript = `uiController.zoomToScale(${scale}, () => uiController.uiScriptComplete(uiController.zoomScale))`;
[iOS] Suppress native selection behaviors when focusing a very small editable element https://bugs.webkit.org/show_bug.cgi?id=193005 <rdar://problem/46583527> Reviewed by Tim Horton. Source/WebKit: In r238146, I added a mechanism to detect when the selection is hidden within transparent editable elements, and used this to suppress native selection on iOS (such as selection handles, highlight, callout bar, etc.) to avoid conflicts between the page's editing UI and the platform. However, one additional technique observed on some websites involves hiding the selection by moving it into a tiny (1x1) editable element. Here, we currently still present a callout bar with editing actions, as well as show a selection caret or handles on iOS. To fix this, we extend the mechanism added in r238146 by also suppressing the selection assistant in the case where the editable element's area is beneath a tiny minimum threshold. Test: editing/selection/ios/hide-selection-in-tiny-contenteditable.html * Shared/EditorState.cpp: (WebKit::EditorState::PostLayoutData::encode const): (WebKit::EditorState::PostLayoutData::decode): (WebKit::operator<<): * Shared/EditorState.h: Rename selectionClipRect to focusedElementRect. We currently propagate the bounds of the focused element to the UI process through EditorState updates, but only for the purpose of returning it in the computed selection clip rect; instead, rename this member to something more general-purpose, so we can also use it when determining whether to suppress the selection assistant. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _candidateRect]): * UIProcess/Cocoa/WebViewImpl.mm: (WebKit::WebViewImpl::handleRequestedCandidates): * UIProcess/ios/WKContentViewInteraction.h: Add a new SuppressSelectionAssistantReason that corresponds to focusing tiny editable elements. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _zoomToRevealFocusedElement]): (-[WKContentView _selectionClipRect]): (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): (-[WKContentView _updateChangedSelection:]): Check the size of the focused element, and begin or stop suppressing the selection assistant accordingly. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::platformEditorState const): * WebProcess/WebPage/mac/WebPageMac.mm: (WebKit::WebPage::platformEditorState const): LayoutTests: Add a new layout test to verify that native selection UI is suppressed when focusing a tiny (1px by 1px) editable element. * editing/selection/ios/hide-selection-in-tiny-contenteditable-expected.txt: Added. * editing/selection/ios/hide-selection-in-tiny-contenteditable.html: Added. * resources/ui-helper.js: (window.UIHelper.zoomToScale): Canonical link: https://commits.webkit.org/207574@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239543 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-23 06:38:24 +00:00
return new Promise(resolve => testRunner.runUIScript(uiScript, resolve));
}
static immediateZoomToScale(scale)
{
const uiScript = `uiController.immediateZoomToScale(${scale})`;
return new Promise(resolve => testRunner.runUIScript(uiScript, resolve));
}
[iOS] Tests that try to interact with the QuickType bar time out on iOS 11+ https://bugs.webkit.org/show_bug.cgi?id=188335 <rdar://problem/32542437> and <rdar://problem/32542433> Reviewed by Tim Horton. Tools: Remove a UIScriptController helper method that attempted to wait for QuickType buttons to appear, and then send touch events to the buttons. These were only used for the two tests which this patch refactors. See the LayoutTests ChangeLog for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestRunnerShared/spi/UIKitTestSPI.h: Remove an internal class declaration that is now unnecessary. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. LayoutTests: Refactors a couple of tests that currently rely on the QuickType bar being shown when the hardware keyboard is presented in the iOS simulator, so that it can insert text suggestions by tapping QuickType bar buttons; in the first place, it was never guaranteed that this bar would show up, or even have more than 1 text suggestion. Instead, we use the existing UIScriptController::applyAutocorrection method to trigger text replacement in the same way tapping a button on the QuickType bar would replace the current word with the suggested word. * fast/events/ios/before-input-events-prevent-candidate-insertion-expected.txt: * fast/events/ios/before-input-events-prevent-candidate-insertion.html: * fast/events/ios/input-events-insert-replacement-text-expected.txt: * fast/events/ios/input-events-insert-replacement-text.html: * platform/ios/TestExpectations: Removes a [Timeout] expectation. * resources/ui-helper.js: (window.UIHelper.typeCharacter): Add a new UIHelper method to type a character using the keyboard. Sends hardware keyboard events on the WebKit2 port of iOS, and uses EventSender elsewhere. (window.UIHelper.applyAutocorrection): Add a new UIHelper method that wraps UIScriptController::applyAutocorrection. Only supported in WebKit2 currently. (window.UIHelper): Canonical link: https://commits.webkit.org/203448@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234601 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-06 15:01:47 +00:00
static typeCharacter(characterString)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily()) {
[iOS] Special keys are misidentified in DOM keyboard events https://bugs.webkit.org/show_bug.cgi?id=189974 Reviewed by Wenson Hsieh. Source/WebCore: This patch fixes two issues: 1. Special keyboard keys would be misidentified in dispatched DOM keyboard events. 2. DOM keypress events may not be dispatched for some special keys. UIKit uses special input strings to identify the Page Up, Page Down, Escape, Up Arrow, Down Arrow, Left Arrow, and Right Arrow keys. It also uses ASCII control characters to represent some other special keys, including Num Lock / Clear, Home, End, Forward Delete, and F1, ..., F24. We need to explicitly handle these special keyboard keys in order to be able to identify the key that was pressed as well as to correctly disambiguate a key down to know whether to dispatch a DOM keypress event for the key. Unlike UIKit, AppKit reserves Unicode Private Use Area (PUA) code points in 0xF700–0xF8FF to represent special keyboard keys. This makes it straightforward to disambiguate such keys using the input string of the keyboard event alone. To simplify the implementation for iOS we normalize the input string be AppKit compatible. See the explaination for WebCore::windowsKeyCodeForCharCode() below for more details on why this is done. Tests: fast/events/ios/keydown-keyup-arrow-keys-in-non-editable-element.html fast/events/ios/keypress-keys-in-non-editable-element.html * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: Do not use unified source build strategy when building WebEvent.mm as it makes use of SoftLinking macros that are incompatible with this strategy. * platform/ios/KeyEventIOS.mm: (WebCore::windowsKeyCodeForCharCode): Recognize some special AppKit special char codes. These special char codes are generated by WebKit. WebKit uses the same special char codes as AppKit as a convenience instead of defining our own constants for the same purpose. Encoding the special UIKit input strings (e.g. up arrow) as distinct char codes allows us to use integer arithmetic and switch blocks to map characters to Windows virtual key codes as opposed to special cased branches to perform pointer or string comparisions. The latter would be necessary in Modern WebKit in order for key down events to be properly disambiguated to dispatch a DOM keypress event because pointers are not perserved, though what they point to is, when sending the WebEvent from UIProcess to the WebProcess and vice versa. (WebCore::isFunctionKey): Convenience function that determines whether the specified char code corresponds to a function key on the keyboard. The term "function key" is taken from AppKit parlance to describe a special keyboard key. These keys include F1, F2, ..., F24, and cursor keys among other special keyboard keys. (WebCore::PlatformKeyboardEvent::disambiguateKeyDownEvent): Write in terms of isFunctionKey(). * platform/ios/PlatformEventFactoryIOS.h: * platform/ios/PlatformEventFactoryIOS.mm: (WebCore::keyIdentifierForKeyEvent): Remove code to handle UIKit special input strings as we now map such special input strings to char codes and hence can use the default code path. (WebCore::keyForKeyEvent): Ditto. (WebCore::codeForKeyEvent): Remove code to compute the Window virtual key code corresponding to a UIKit special key command now that we map such special input strings to char codes and subsequently map the char codes to the Windows virtual key code (see -[WebEvent initWithKeyEventType:...] constructors). So, we can now use WebEvent.keyCode directly to compute the DOM UIEvents code for the event. (WebCore::PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder): Remove code to fix up WebEvent.keyCode to account for UIKit special input strings now that we map such special key commands to char codes and subsequently map the char codes to the Windows virtual key code (see -[WebEvent initWithKeyEventType:...] constructors). So, we can now take WebEvent.keyCode verbatim to be the Window virtual key code. (WebCore::convertSpecialKeyToCharCode): Deleted. (WebCore::keyCodeForEvent): Deleted. * platform/ios/WebEvent.mm: (normalizedStringWithAppKitCompatibilityMapping): Added; converts a UIKit character string to the corresponding AppKit-compatible one (if not already compatible). See the explaination for WebCore::windowsKeyCodeForCharCode() above for more details on why this is done. (-[WebEvent initWithKeyEventType:timeStamp:characters:charactersIgnoringModifiers:modifiers:isRepeating:withFlags:keyCode:isTabKey:characterSet:]): (-[WebEvent initWithKeyEventType:timeStamp:characters:charactersIgnoringModifiers:modifiers:isRepeating:withFlags:withInputManagerHint:keyCode:isTabKey:]): Normalize the character strings to be AppKit compatible. Source/WebCore/PAL: Forward declare or define more SPI. * pal/spi/cocoa/IOKitSPI.h: * pal/spi/ios/UIKitSPI.h: Source/WebKit: Take the key code of WebEvent to be the key code for the new WebKeyboardEvent verbatim now that we normalize the character strings of the WebEvent to account for the special UIKit input strings. * Shared/ios/WebIOSEventFactory.mm: (WebIOSEventFactory::createWebKeyboardEvent): Tools: Add support for testing keys Forward Delete and Num Lock / Clear. * WebKitTestRunner/ios/HIDEventGenerator.mm: (hidUsageCodeForCharacter): LayoutTests: Add tests to ensure that we do not regress key identification for special keys. Update the expected results for test fast/events/ios/keydown-keyup-special-keys-in-non-editable-element.html now that we correctly identify some more keys. * fast/events/ios/keydown-keyup-arrow-keys-in-non-editable-element-expected.txt: Added. * fast/events/ios/keydown-keyup-arrow-keys-in-non-editable-element.html: Added. * fast/events/ios/keydown-keyup-special-keys-in-non-editable-element-expected.txt: * fast/events/ios/keypress-keys-in-non-editable-element-expected.txt: Added. * fast/events/ios/keypress-keys-in-non-editable-element.html: Added. * resources/ui-helper.js: (window.UIHelper.typeCharacter): Actually type the specified character in DumpRenderTree. Canonical link: https://commits.webkit.org/205106@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236678 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-01 18:35:37 +00:00
eventSender.keyDown(characterString);
[iOS] Tests that try to interact with the QuickType bar time out on iOS 11+ https://bugs.webkit.org/show_bug.cgi?id=188335 <rdar://problem/32542437> and <rdar://problem/32542433> Reviewed by Tim Horton. Tools: Remove a UIScriptController helper method that attempted to wait for QuickType buttons to appear, and then send touch events to the buttons. These were only used for the two tests which this patch refactors. See the LayoutTests ChangeLog for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestRunnerShared/spi/UIKitTestSPI.h: Remove an internal class declaration that is now unnecessary. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. LayoutTests: Refactors a couple of tests that currently rely on the QuickType bar being shown when the hardware keyboard is presented in the iOS simulator, so that it can insert text suggestions by tapping QuickType bar buttons; in the first place, it was never guaranteed that this bar would show up, or even have more than 1 text suggestion. Instead, we use the existing UIScriptController::applyAutocorrection method to trigger text replacement in the same way tapping a button on the QuickType bar would replace the current word with the suggested word. * fast/events/ios/before-input-events-prevent-candidate-insertion-expected.txt: * fast/events/ios/before-input-events-prevent-candidate-insertion.html: * fast/events/ios/input-events-insert-replacement-text-expected.txt: * fast/events/ios/input-events-insert-replacement-text.html: * platform/ios/TestExpectations: Removes a [Timeout] expectation. * resources/ui-helper.js: (window.UIHelper.typeCharacter): Add a new UIHelper method to type a character using the keyboard. Sends hardware keyboard events on the WebKit2 port of iOS, and uses EventSender elsewhere. (window.UIHelper.applyAutocorrection): Add a new UIHelper method that wraps UIScriptController::applyAutocorrection. Only supported in WebKit2 currently. (window.UIHelper): Canonical link: https://commits.webkit.org/203448@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234601 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-06 15:01:47 +00:00
return;
}
const escapedString = characterString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
[iOS] Tests that try to interact with the QuickType bar time out on iOS 11+ https://bugs.webkit.org/show_bug.cgi?id=188335 <rdar://problem/32542437> and <rdar://problem/32542433> Reviewed by Tim Horton. Tools: Remove a UIScriptController helper method that attempted to wait for QuickType buttons to appear, and then send touch events to the buttons. These were only used for the two tests which this patch refactors. See the LayoutTests ChangeLog for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestRunnerShared/spi/UIKitTestSPI.h: Remove an internal class declaration that is now unnecessary. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectTextCandidateAtIndex): Deleted. (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex): Deleted. LayoutTests: Refactors a couple of tests that currently rely on the QuickType bar being shown when the hardware keyboard is presented in the iOS simulator, so that it can insert text suggestions by tapping QuickType bar buttons; in the first place, it was never guaranteed that this bar would show up, or even have more than 1 text suggestion. Instead, we use the existing UIScriptController::applyAutocorrection method to trigger text replacement in the same way tapping a button on the QuickType bar would replace the current word with the suggested word. * fast/events/ios/before-input-events-prevent-candidate-insertion-expected.txt: * fast/events/ios/before-input-events-prevent-candidate-insertion.html: * fast/events/ios/input-events-insert-replacement-text-expected.txt: * fast/events/ios/input-events-insert-replacement-text.html: * platform/ios/TestExpectations: Removes a [Timeout] expectation. * resources/ui-helper.js: (window.UIHelper.typeCharacter): Add a new UIHelper method to type a character using the keyboard. Sends hardware keyboard events on the WebKit2 port of iOS, and uses EventSender elsewhere. (window.UIHelper.applyAutocorrection): Add a new UIHelper method that wraps UIScriptController::applyAutocorrection. Only supported in WebKit2 currently. (window.UIHelper): Canonical link: https://commits.webkit.org/203448@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234601 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-06 15:01:47 +00:00
const uiScript = `uiController.typeCharacterUsingHardwareKeyboard(\`${escapedString}\`, () => uiController.uiScriptComplete())`;
return new Promise(resolve => testRunner.runUIScript(uiScript, resolve));
}
static applyAutocorrection(newText, oldText)
{
if (!this.isWebKit2())
return;
const [escapedNewText, escapedOldText] = [newText.replace(/`/g, "\\`"), oldText.replace(/`/g, "\\`")];
const uiScript = `uiController.applyAutocorrection(\`${escapedNewText}\`, \`${escapedOldText}\`, () => uiController.uiScriptComplete())`;
return new Promise(resolve => testRunner.runUIScript(uiScript, resolve));
}
[iOS] Support inputmode=none https://bugs.webkit.org/show_bug.cgi?id=188896 Reviewed by Tim Horton. LayoutTests/imported/w3c: * web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaseline. Source/WebCore: Updated InputMode.cpp to ensure that "none" is recognized as a valid value for the inputmode attribute. This keyword is useful for content that renders its own keyboard control. Spec: https://html.spec.whatwg.org/multipage/interaction.html#input-modalities%3A-the-inputmode-attribute Test: fast/forms/ios/inputmode-none.html * html/InputMode.cpp: (WebCore::inputModeForAttributeValue): (WebCore::stringForInputMode): (WebCore::InputModeNames::none): * html/InputMode.h: Source/WebKit: inputmode=none is used by content that renders its own keyboard control. Consequently, we should not display the virtual keyboard when a user interacts with an element that has the inputmode attribute set to the "none" value. In order to achieve this behavior, we return a UIView with a bounds of CGRectZero as the inputView of the WKContentView when inputmode=none is present. Furthermore, we do not provide an accessory view in this case. Updated the logic that zooms and scrolls to a control when it gains focus, as that behavior currently relies on an accessory view being present. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): (-[WKContentView inputView]): (-[WKContentView requiresAccessoryView]): (-[WKContentView textInputTraits]): LayoutTests: Added new test to verify that the system keyboard does not show for inputs with inputmode=none. Updated existing inputmode tests to reflect the addition of the "none" value. * fast/forms/inputmode-attribute-contenteditable-expected.txt: * fast/forms/inputmode-attribute-contenteditable.html: * fast/forms/inputmode-attribute-input-expected.txt: * fast/forms/inputmode-attribute-input.html: * fast/forms/inputmode-attribute-textarea-expected.txt: * fast/forms/inputmode-attribute-textarea.html: * fast/forms/ios/inputmode-none-expected.txt: Added. * fast/forms/ios/inputmode-none.html: Added. * resources/ui-helper.js: (window.UIHelper.activateFormControl): (window.UIHelper.inputViewBounds): Canonical link: https://commits.webkit.org/204080@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235426 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-28 16:34:25 +00:00
static inputViewBounds()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] Support inputmode=none https://bugs.webkit.org/show_bug.cgi?id=188896 Reviewed by Tim Horton. LayoutTests/imported/w3c: * web-platform-tests/html/dom/reflection-misc-expected.txt: Rebaseline. Source/WebCore: Updated InputMode.cpp to ensure that "none" is recognized as a valid value for the inputmode attribute. This keyword is useful for content that renders its own keyboard control. Spec: https://html.spec.whatwg.org/multipage/interaction.html#input-modalities%3A-the-inputmode-attribute Test: fast/forms/ios/inputmode-none.html * html/InputMode.cpp: (WebCore::inputModeForAttributeValue): (WebCore::stringForInputMode): (WebCore::InputModeNames::none): * html/InputMode.h: Source/WebKit: inputmode=none is used by content that renders its own keyboard control. Consequently, we should not display the virtual keyboard when a user interacts with an element that has the inputmode attribute set to the "none" value. In order to achieve this behavior, we return a UIView with a bounds of CGRectZero as the inputView of the WKContentView when inputmode=none is present. Furthermore, we do not provide an accessory view in this case. Updated the logic that zooms and scrolls to a control when it gains focus, as that behavior currently relies on an accessory view being present. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _displayFormNodeInputView]): (-[WKContentView inputView]): (-[WKContentView requiresAccessoryView]): (-[WKContentView textInputTraits]): LayoutTests: Added new test to verify that the system keyboard does not show for inputs with inputmode=none. Updated existing inputmode tests to reflect the addition of the "none" value. * fast/forms/inputmode-attribute-contenteditable-expected.txt: * fast/forms/inputmode-attribute-contenteditable.html: * fast/forms/inputmode-attribute-input-expected.txt: * fast/forms/inputmode-attribute-input.html: * fast/forms/inputmode-attribute-textarea-expected.txt: * fast/forms/inputmode-attribute-textarea.html: * fast/forms/ios/inputmode-none-expected.txt: Added. * fast/forms/ios/inputmode-none.html: Added. * resources/ui-helper.js: (window.UIHelper.activateFormControl): (window.UIHelper.inputViewBounds): Canonical link: https://commits.webkit.org/204080@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235426 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-28 16:34:25 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(JSON.stringify(uiController.inputViewBounds));
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
[iOS] Allow SPI clients to lay out at arbitrarily scaled sizes and scale to fit the view https://bugs.webkit.org/show_bug.cgi?id=190504 <rdar://problem/45117760> Reviewed by Tim Horton. Source/WebCore: Add support in ViewportConfiguration for applying a layout size scale factor to the viewport. See below for more details. Tests: fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html fast/viewport/ios/device-width-viewport-after-changing-view-scale.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::setViewLayoutSize): The viewport's layout size may now be changed alongside the layout size scale factor. If either of these two variables change, we recompute our minimum layout size and viewport configuration parameters. (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const): (WebCore::ViewportConfiguration::nativeWebpageParameters): (WebCore::ViewportConfiguration::testingParameters): (WebCore::ViewportConfiguration::updateConfiguration): Multiply the minimum scale, initial scale, and maximum scale by the layout size scale factor. This allows us to keep the document well-proportioned within the viewport, while still laying out at a different layout size. (WebCore::ViewportConfiguration::updateMinimumLayoutSize): Compute the minimum layout size by scaling the default layout size derived from our view's size. (WebCore::ViewportConfiguration::layoutWidth const): (WebCore::ViewportConfiguration::layoutHeight const): * page/ViewportConfiguration.h: Maintain the original initial scale, unaffected by the layout size scale factor. This is used when computing layout width and height to prevent scaling by the layout size scale factor twice when computing layout sizes. (WebCore::ViewportConfiguration::description const): Include the layout size scale factor in ViewportConfiguration's description string. (WebCore::ViewportConfiguration::Parameters::operator== const): (WebCore::operator<<): Source/WebKit: Add support for _setViewScale: and _viewScale on iOS. While similar in concept to macOS, changing this property on iOS uses viewport configurations to change the minimum layout size of the document and apply view scaling. Setting the view scale on iOS to a value `s` multiplies the minimium layout size by a factor `1 / s`, but also multiplies the initial, minimum and maximum scales by a factor of `s`. The net effect of applying this scale causes the page to lay out at a larger width and shrink (or a smaller width and expand) to fit the viewport. * Shared/WebPageCreationParameters.cpp: (WebKit::WebPageCreationParameters::encode const): (WebKit::WebPageCreationParameters::decode): * Shared/WebPageCreationParameters.h: Send `viewportConfigurationLayoutSizeScaleFactor` alongside `viewportConfigurationViewLayoutSize`. (-[WKWebView _dispatchSetViewLayoutSize:]): (-[WKWebView _viewScale]): (-[WKWebView _setViewScale:]): Provide a different implementation of `_setViewScale:` on iOS, by scaling the effective minimum layout size. (See above for more detail). * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add missing API availability annotations for the _viewScale property. * UIProcess/API/mac/WKView.mm: (-[WKView _setViewScale:]): * UIProcess/Cocoa/WebViewImpl.mm: Both -[WKView _setViewScale:] and -[WKWebView _setViewScale:] throw Objective C exceptions upon receiving a bad argument (e.g. scale <= 0). However, logic for throwing this exception is specific to iOS in WKWebView, and handled in WebViewImpl on macOS. To make this less confusing, move the exception throwing code out of !PLATFORM(MAC) in WKWebView, and move the path for raising this exception in WKView on macOS from WebViewImpl to WKView. * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::creationParameters): * UIProcess/WebPageProxy.h: (WebKit::WebPageProxy::layoutSizeScaleFactor const): Tie the notion of "view scale" on iOS to `layoutSizeScaleFactor`. As its name suggests, this is a scale factor by which we transform the layout size. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::setViewportConfigurationViewLayoutSize): * WebProcess/WebPage/WebPage.cpp: * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Plumb the layout size scale factor over to the web process, along with the layout size. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationViewLayoutSize): Tools: Teach UIScriptController to set WKWebView's view scale via a new `setViewScale` method, supported in WebKit2 on macOS and iOS. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setViewScale): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::setViewScale): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setViewScale): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: Added. Add a new file for UIScriptController methods on Cocoa platforms. (WTR::UIScriptController::setViewScale): * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::cocoaResetStateToConsistentValues): Ensure that _viewScale is reset to 1 after running a layout test. LayoutTests: Add two new layout tests on iOS that change WKWebView's view scale, and measure the resulting window sizes and lengths of viewport units. * fast/viewport/ios/constant-width-viewport-after-changing-view-scale-expected.txt: Added. * fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html: Added. Add a test page with a viewport meta tag that has a constant width and an explicit initial scale of 0.5. * fast/viewport/ios/device-width-viewport-after-changing-view-scale-expected.txt: Added. * fast/viewport/ios/device-width-viewport-after-changing-view-scale.html: Added. Add a test page with a viewport meta tag at device-width, with initial scale 1. * resources/ui-helper.js: (window.UIHelper.setViewScale): Add a convenience function that wraps a UI script invocation of `setViewScale` in a promise. (window.UIHelper): Canonical link: https://commits.webkit.org/205461@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237087 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-12 23:13:37 +00:00
Source/WebKit: Force a gregorian calendar to show for credit card expiration date inputs (autocomplete='cc-exp'*) regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Added some plumbing code to expose the calendar identifier of the calendar used by a presented date picker. Added shouldPresentGregorianCalendar:, to be used for determining what property values a date input control must present a Gregorian calendar for. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView formInputPeripheral]): * UIProcess/ios/forms/WKFormInputControl.mm: Tools: Force a gregorian calendar to show for credit card expiration date inputs (autocomplete='cc-exp'*) regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Implemented simulateForeignDefaultCalendar and calendarType to be used for changing the default calendar returned by the system (ie. [NSCalendar currentCalendar]) and getting the calendar type identifier of a presented date picker. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingDataListSuggestions const): (WTR::UIScriptController::calendarType const): (WTR::UIScriptController::setDefaultCalendarType): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::calendarType const): (WTR::UIScriptController::setDefaultCalendarType): * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::calendarType const): Deleted. * WebKitTestRunner/TestController.cpp: * WebKitTestRunner/TestController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::calendarType const): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::swizzledCalendar): (WTR::TestController::getOverriddenCalendarIdentifier const): (WTR::TestController::setDefaultCalendarType): (WTR::TestController::cocoaResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::calendarType const): Deleted. LayoutTests: Created a layout test to ensure that date controls marked as credit card expiry fields present a Gregorian calendar regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Added two new methods to UIHelper, helping to facilitate this. calendarType returns the calendar identifier of the NSCalendar instance used by the presented date picker and setDefaultCalendarType accepts a calendar identifier as an argument for changing the default system settings. * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html: * platform/win/TestExpectations: * resources/ui-helper.js: (window.UIHelper.calendarType): (window.UIHelper.setDefaultCalendarType): Canonical link: https://commits.webkit.org/206163@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237924 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-07 14:57:40 +00:00
static calendarType()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.doAfterNextStablePresentationUpdate(() => {
uiController.uiScriptComplete(JSON.stringify(uiController.calendarType));
})
})()`, jsonString => {
resolve(JSON.parse(jsonString));
});
});
}
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
static setDefaultCalendarType(calendarIdentifier, localeIdentifier)
Source/WebKit: Force a gregorian calendar to show for credit card expiration date inputs (autocomplete='cc-exp'*) regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Added some plumbing code to expose the calendar identifier of the calendar used by a presented date picker. Added shouldPresentGregorianCalendar:, to be used for determining what property values a date input control must present a Gregorian calendar for. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView formInputPeripheral]): * UIProcess/ios/forms/WKFormInputControl.mm: Tools: Force a gregorian calendar to show for credit card expiration date inputs (autocomplete='cc-exp'*) regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Implemented simulateForeignDefaultCalendar and calendarType to be used for changing the default calendar returned by the system (ie. [NSCalendar currentCalendar]) and getting the calendar type identifier of a presented date picker. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingDataListSuggestions const): (WTR::UIScriptController::calendarType const): (WTR::UIScriptController::setDefaultCalendarType): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::calendarType const): (WTR::UIScriptController::setDefaultCalendarType): * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::calendarType const): Deleted. * WebKitTestRunner/TestController.cpp: * WebKitTestRunner/TestController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::calendarType const): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::swizzledCalendar): (WTR::TestController::getOverriddenCalendarIdentifier const): (WTR::TestController::setDefaultCalendarType): (WTR::TestController::cocoaResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::calendarType const): Deleted. LayoutTests: Created a layout test to ensure that date controls marked as credit card expiry fields present a Gregorian calendar regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Added two new methods to UIHelper, helping to facilitate this. calendarType returns the calendar identifier of the NSCalendar instance used by the presented date picker and setDefaultCalendarType accepts a calendar identifier as an argument for changing the default system settings. * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html: * platform/win/TestExpectations: * resources/ui-helper.js: (window.UIHelper.calendarType): (window.UIHelper.setDefaultCalendarType): Canonical link: https://commits.webkit.org/206163@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237924 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-07 14:57:40 +00:00
{
if (!this.isWebKit2())
return Promise.resolve();
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
return new Promise(resolve => testRunner.runUIScript(`uiController.setDefaultCalendarType('${calendarIdentifier}', '${localeIdentifier}')`, resolve));
Source/WebKit: Force a gregorian calendar to show for credit card expiration date inputs (autocomplete='cc-exp'*) regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Added some plumbing code to expose the calendar identifier of the calendar used by a presented date picker. Added shouldPresentGregorianCalendar:, to be used for determining what property values a date input control must present a Gregorian calendar for. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView formInputPeripheral]): * UIProcess/ios/forms/WKFormInputControl.mm: Tools: Force a gregorian calendar to show for credit card expiration date inputs (autocomplete='cc-exp'*) regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Implemented simulateForeignDefaultCalendar and calendarType to be used for changing the default calendar returned by the system (ie. [NSCalendar currentCalendar]) and getting the calendar type identifier of a presented date picker. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isShowingDataListSuggestions const): (WTR::UIScriptController::calendarType const): (WTR::UIScriptController::setDefaultCalendarType): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::calendarType const): (WTR::UIScriptController::setDefaultCalendarType): * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::calendarType const): Deleted. * WebKitTestRunner/TestController.cpp: * WebKitTestRunner/TestController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::calendarType const): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::swizzledCalendar): (WTR::TestController::getOverriddenCalendarIdentifier const): (WTR::TestController::setDefaultCalendarType): (WTR::TestController::cocoaResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::selectionEndGrabberViewRect const): (WTR::UIScriptController::calendarType const): Deleted. LayoutTests: Created a layout test to ensure that date controls marked as credit card expiry fields present a Gregorian calendar regardless of default system settings. https://bugs.webkit.org/show_bug.cgi?id=191096 rdar://problem/42640256 Patch by Zamiul Haque <zhaque@apple.com> on 2018-11-07 Reviewed by Tim Horton. Added two new methods to UIHelper, helping to facilitate this. calendarType returns the calendar identifier of the NSCalendar instance used by the presented date picker and setDefaultCalendarType accepts a calendar identifier as an argument for changing the default system settings. * fast/forms/ios/force-gregorian-calendar-for-credit-card-expiry.html: * platform/win/TestExpectations: * resources/ui-helper.js: (window.UIHelper.calendarType): (window.UIHelper.setDefaultCalendarType): Canonical link: https://commits.webkit.org/206163@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237924 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-07 14:57:40 +00:00
}
[iOS] Allow SPI clients to lay out at arbitrarily scaled sizes and scale to fit the view https://bugs.webkit.org/show_bug.cgi?id=190504 <rdar://problem/45117760> Reviewed by Tim Horton. Source/WebCore: Add support in ViewportConfiguration for applying a layout size scale factor to the viewport. See below for more details. Tests: fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html fast/viewport/ios/device-width-viewport-after-changing-view-scale.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::setViewLayoutSize): The viewport's layout size may now be changed alongside the layout size scale factor. If either of these two variables change, we recompute our minimum layout size and viewport configuration parameters. (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const): (WebCore::ViewportConfiguration::nativeWebpageParameters): (WebCore::ViewportConfiguration::testingParameters): (WebCore::ViewportConfiguration::updateConfiguration): Multiply the minimum scale, initial scale, and maximum scale by the layout size scale factor. This allows us to keep the document well-proportioned within the viewport, while still laying out at a different layout size. (WebCore::ViewportConfiguration::updateMinimumLayoutSize): Compute the minimum layout size by scaling the default layout size derived from our view's size. (WebCore::ViewportConfiguration::layoutWidth const): (WebCore::ViewportConfiguration::layoutHeight const): * page/ViewportConfiguration.h: Maintain the original initial scale, unaffected by the layout size scale factor. This is used when computing layout width and height to prevent scaling by the layout size scale factor twice when computing layout sizes. (WebCore::ViewportConfiguration::description const): Include the layout size scale factor in ViewportConfiguration's description string. (WebCore::ViewportConfiguration::Parameters::operator== const): (WebCore::operator<<): Source/WebKit: Add support for _setViewScale: and _viewScale on iOS. While similar in concept to macOS, changing this property on iOS uses viewport configurations to change the minimum layout size of the document and apply view scaling. Setting the view scale on iOS to a value `s` multiplies the minimium layout size by a factor `1 / s`, but also multiplies the initial, minimum and maximum scales by a factor of `s`. The net effect of applying this scale causes the page to lay out at a larger width and shrink (or a smaller width and expand) to fit the viewport. * Shared/WebPageCreationParameters.cpp: (WebKit::WebPageCreationParameters::encode const): (WebKit::WebPageCreationParameters::decode): * Shared/WebPageCreationParameters.h: Send `viewportConfigurationLayoutSizeScaleFactor` alongside `viewportConfigurationViewLayoutSize`. (-[WKWebView _dispatchSetViewLayoutSize:]): (-[WKWebView _viewScale]): (-[WKWebView _setViewScale:]): Provide a different implementation of `_setViewScale:` on iOS, by scaling the effective minimum layout size. (See above for more detail). * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add missing API availability annotations for the _viewScale property. * UIProcess/API/mac/WKView.mm: (-[WKView _setViewScale:]): * UIProcess/Cocoa/WebViewImpl.mm: Both -[WKView _setViewScale:] and -[WKWebView _setViewScale:] throw Objective C exceptions upon receiving a bad argument (e.g. scale <= 0). However, logic for throwing this exception is specific to iOS in WKWebView, and handled in WebViewImpl on macOS. To make this less confusing, move the exception throwing code out of !PLATFORM(MAC) in WKWebView, and move the path for raising this exception in WKView on macOS from WebViewImpl to WKView. * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::creationParameters): * UIProcess/WebPageProxy.h: (WebKit::WebPageProxy::layoutSizeScaleFactor const): Tie the notion of "view scale" on iOS to `layoutSizeScaleFactor`. As its name suggests, this is a scale factor by which we transform the layout size. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::setViewportConfigurationViewLayoutSize): * WebProcess/WebPage/WebPage.cpp: * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Plumb the layout size scale factor over to the web process, along with the layout size. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationViewLayoutSize): Tools: Teach UIScriptController to set WKWebView's view scale via a new `setViewScale` method, supported in WebKit2 on macOS and iOS. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setViewScale): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::setViewScale): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setViewScale): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: Added. Add a new file for UIScriptController methods on Cocoa platforms. (WTR::UIScriptController::setViewScale): * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::cocoaResetStateToConsistentValues): Ensure that _viewScale is reset to 1 after running a layout test. LayoutTests: Add two new layout tests on iOS that change WKWebView's view scale, and measure the resulting window sizes and lengths of viewport units. * fast/viewport/ios/constant-width-viewport-after-changing-view-scale-expected.txt: Added. * fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html: Added. Add a test page with a viewport meta tag that has a constant width and an explicit initial scale of 0.5. * fast/viewport/ios/device-width-viewport-after-changing-view-scale-expected.txt: Added. * fast/viewport/ios/device-width-viewport-after-changing-view-scale.html: Added. Add a test page with a viewport meta tag at device-width, with initial scale 1. * resources/ui-helper.js: (window.UIHelper.setViewScale): Add a convenience function that wraps a UI script invocation of `setViewScale` in a promise. (window.UIHelper): Canonical link: https://commits.webkit.org/205461@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237087 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-12 23:13:37 +00:00
static setViewScale(scale)
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => testRunner.runUIScript(`uiController.setViewScale(${scale})`, resolve));
}
[iOS] [Datalist] Can't pick datalist suggestions in a stock WKWebView https://bugs.webkit.org/show_bug.cgi?id=190621 <rdar://problem/45310649> Reviewed by Tim Horton. Source/WebKit: Fixes the bug by refactoring datalist suggestion information on iOS; currently, we override text suggestions on _WKFormInputSession. This only works for a few internal clients (including Safari) that set a _WKInputDelegate and also implement either -_webView:willStartInputSession: or -_webView:didStartInputSession:, which is necessary in order to ensure that WebKit creates and maintains a form input session. The two pieces of information that datalist code needs to vend to WKContentView are a list of UITextSuggestions and a custom input view, which are both currently properties of _WKFormInputSession. This patch lifts these out of the input session and makes them properties of WKContentView, which are used in WebDataListSuggestionsDropdownIOS. Test: fast/forms/datalist/datalist-textinput-suggestions-order.html * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: Add new properties to WKContentView: an input view for datalist suggestions, and a list of text suggestions. (-[WKFormInputSession setSuggestions:]): (-[WKContentView setupInteraction]): (-[WKContentView cleanupInteraction]): (-[WKContentView _endEditing]): Pull out common logic when resigning first responder or tabbing to the next or previous text field into a new helper. This helper notifies `_inputPeripheral`, `_formInputSession`, and `_dataListTextSuggestionsInputView` when editing has ended; the input peripheral and suggestions input view use this chance to send the value of the form control to the web process. (-[WKContentView resignFirstResponderForWebView]): (-[WKContentView inputView]): If a custom input view is not set but we have an input view for a datalist's text suggestions, use the datalist input view. (-[WKContentView accessoryTab:]): (-[WKContentView _stopAssistingNode]): Clear datalist state on WKContentView. (-[WKContentView dataListTextSuggestionsInputView]): (-[WKContentView dataListTextSuggestions]): (-[WKContentView setDataListTextSuggestionsInputView:]): (-[WKContentView setDataListTextSuggestions:]): (-[WKContentView updateTextSuggestionsForInputDelegate]): Pull out logic for setting suggestions on UIKit's `inputDelegate` (i.e. UIKeyboardImpl). We now first consult internally-vended text suggestions from _WKFormInputSession; if an internal client has not overridden our text suggestions, then we simply use suggestions from the current datalist (if present). * UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm: (-[WKDataListSuggestionsPicker updateWithInformation:]): (-[WKDataListSuggestionsPicker showSuggestionsDropdown:activationType:]): (-[WKDataListSuggestionsPicker invalidate]): (-[WKDataListSuggestionsPopover updateWithInformation:]): (-[WKDataListSuggestionsPopover showSuggestionsDropdown:activationType:]): (-[WKDataListSuggestionsPopover didSelectOptionAtIndex:]): Change all the places that currently manipulate WKContentView's form input session to directly set text suggestions and the text suggestion input view on the content view instead. Tools: Add a UIScriptController hook to resign first responder on WKWebView. See LayoutTests/ChangeLog for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::resignFirstResponder): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::resignFirstResponder): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::resignFirstResponder): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::resignFirstResponder): * WebKitTestRunner/ios/PlatformWebViewIOS.mm: (WTR::PlatformWebView::makeWebViewFirstResponder): Implement this method stub on iOS, to ensure that TestController::resetStateToConsistentValues restores first responder on the WKWebView when running iOS layout tests. * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): After resigning first responder to dismiss any on-screen keyboard, ensure that we restore first responder. LayoutTests: Refactor an existing layout test to run on both iOS and macOS. On both platforms, it checks that the top suggestion respects option element order in the document, as well as the current contents of the text field. On macOS, we use arrow keys and hit return to select a suggestion; on iOS, we tap the suggestions button and simulate hitting the done button on the input view to dismiss the keyboard. * fast/forms/datalist/datalist-textinput-suggestions-order-expected.txt: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * platform/ios/TestExpectations: Enable this test on iOS. * resources/ui-helper.js: (window.UIHelper.resignFirstResponder): (window.UIHelper): Canonical link: https://commits.webkit.org/205670@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237305 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-19 22:00:32 +00:00
static resignFirstResponder()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => testRunner.runUIScript(`uiController.resignFirstResponder()`, resolve));
}
[iOS] Changing view scale sometimes does not zoom the page to the new initial scale, when the page is at initial scale https://bugs.webkit.org/show_bug.cgi?id=191180 <rdar://problem/45744786> Reviewed by Simon Fraser. Source/WebCore: When computing the minimum scale in ViewportConfiguration::minimumScale, if our content width or height is shorter than the view width or height, then we recompute the minimum scale such that the content dimensions will fill the bounds of the view by setting the minimum scale to the view width or height divided by the content width or height. Suppose the minimum scale is equal to some value `s`; additionally, let `w_c` denote the content width and `w_v` denote the view width (as integers). If `w_v / s` is not an integral value, the computed content width `w_c` may be rounded, such that `w_v / w_c` is not precisely equal to `s`. In the case that `w_v / w_c` is ever so slightly larger than `s`, we will end up overriding the minimum scale `s` with `w_v / w_c`. As a result, specifying a viewport with a decimal `minimum-scale` will sometimes cause the computed minimum scale of the viewport (and platform view) to be very slightly different from the minimum scale. The new layout test below exercises this scenario, specifying a viewport with minimum and initial scales of 0.94 that results in `ViewportConfiguration::minimumScale` returning 0.94158. With the `WebPage::setViewportConfigurationViewLayoutSize` check added in r237127, this means setting `_viewScale:` when the page is at initial scale sometimes doesn't zoom the page to the new initial scale when it should, since the page scale factor and the initial scale are different enough such that `areEssentiallyEqualAsFloat` returns false. This patch addresses these issues by snapping to the minimum scale if the computed scale that fits content dimensions to view dimensions results in a minimum scale that is close enough to the configuration's minimum scale, such that the difference can be attributed to rounding error when computing content or view dimensions. Test: fast/viewport/ios/viewport-minimum-and-initial-scale.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::minimumScale const): LayoutTests: Add a layout test, and make some adjustments to UIHelper. * fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html: * fast/viewport/ios/device-width-viewport-after-changing-view-scale.html: * fast/viewport/ios/viewport-minimum-and-initial-scale-expected.txt: Added. * fast/viewport/ios/viewport-minimum-and-initial-scale.html: Added. Add a new layout test that contains a viewport meta tag with minimum and initial scales set to 0.94, and checks that the resulting minimum and initial scales are 0.94 instead of 0.94158. * fast/viewport/watchos/viewport-disable-extra-zoom-adaptations.html: * resources/ui-helper.js: Make UIHelper.zoomScale return a number rather than a string, and adjust a few call sites. (window.UIHelper.zoomScale): (window.UIHelper.minimumZoomScale): (window.UIHelper): Canonical link: https://commits.webkit.org/206009@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237743 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-02 18:10:23 +00:00
[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
static becomeFirstResponder()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => testRunner.runUIScript(`uiController.becomeFirstResponder()`, resolve));
}
static removeViewFromWindow()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => testRunner.runUIScript(`uiController.removeViewFromWindow()`, resolve));
}
static addViewToWindow()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => testRunner.runUIScript(`uiController.addViewToWindow()`, resolve));
}
[iOS] Changing view scale sometimes does not zoom the page to the new initial scale, when the page is at initial scale https://bugs.webkit.org/show_bug.cgi?id=191180 <rdar://problem/45744786> Reviewed by Simon Fraser. Source/WebCore: When computing the minimum scale in ViewportConfiguration::minimumScale, if our content width or height is shorter than the view width or height, then we recompute the minimum scale such that the content dimensions will fill the bounds of the view by setting the minimum scale to the view width or height divided by the content width or height. Suppose the minimum scale is equal to some value `s`; additionally, let `w_c` denote the content width and `w_v` denote the view width (as integers). If `w_v / s` is not an integral value, the computed content width `w_c` may be rounded, such that `w_v / w_c` is not precisely equal to `s`. In the case that `w_v / w_c` is ever so slightly larger than `s`, we will end up overriding the minimum scale `s` with `w_v / w_c`. As a result, specifying a viewport with a decimal `minimum-scale` will sometimes cause the computed minimum scale of the viewport (and platform view) to be very slightly different from the minimum scale. The new layout test below exercises this scenario, specifying a viewport with minimum and initial scales of 0.94 that results in `ViewportConfiguration::minimumScale` returning 0.94158. With the `WebPage::setViewportConfigurationViewLayoutSize` check added in r237127, this means setting `_viewScale:` when the page is at initial scale sometimes doesn't zoom the page to the new initial scale when it should, since the page scale factor and the initial scale are different enough such that `areEssentiallyEqualAsFloat` returns false. This patch addresses these issues by snapping to the minimum scale if the computed scale that fits content dimensions to view dimensions results in a minimum scale that is close enough to the configuration's minimum scale, such that the difference can be attributed to rounding error when computing content or view dimensions. Test: fast/viewport/ios/viewport-minimum-and-initial-scale.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::minimumScale const): LayoutTests: Add a layout test, and make some adjustments to UIHelper. * fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html: * fast/viewport/ios/device-width-viewport-after-changing-view-scale.html: * fast/viewport/ios/viewport-minimum-and-initial-scale-expected.txt: Added. * fast/viewport/ios/viewport-minimum-and-initial-scale.html: Added. Add a new layout test that contains a viewport meta tag with minimum and initial scales set to 0.94, and checks that the resulting minimum and initial scales are 0.94 instead of 0.94158. * fast/viewport/watchos/viewport-disable-extra-zoom-adaptations.html: * resources/ui-helper.js: Make UIHelper.zoomScale return a number rather than a string, and adjust a few call sites. (window.UIHelper.zoomScale): (window.UIHelper.minimumZoomScale): (window.UIHelper): Canonical link: https://commits.webkit.org/206009@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237743 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-02 18:10:23 +00:00
static minimumZoomScale()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(uiController.minimumZoomScale);
})()`, scaleAsString => resolve(parseFloat(scaleAsString)))
});
}
Make it possible to edit images inline https://bugs.webkit.org/show_bug.cgi?id=191352 <rdar://problem/30107985> Reviewed by Dean Jackson. Source/WebCore: Tests: editing/images/basic-editable-image.html editing/images/reparent-editable-image-maintains-strokes.html Add the beginnings of a mechanism to replace images with a special attribute with a native drawing view in the UI process. * page/Settings.yaml: Add a setting to control whether images become natively editable when they have the x-apple-editable-image attribute. * html/HTMLImageElement.cpp: (WebCore::HTMLImageElement::editableImageViewID const): Lazily generate an EmbeddedViewID and persist it on the <img> element. * html/HTMLImageElement.h: Rearrange the service controls methods to sit before the members. Add m_editableImageViewID and editableImageViewID(). * platform/graphics/GraphicsLayer.cpp: (WebCore::GraphicsLayer::nextEmbeddedViewID): * platform/graphics/GraphicsLayer.h: (WebCore::GraphicsLayer::setContentsToEmbeddedView): Add a new ContentsLayerPurpose, EmbeddedView, which is only supported on Cocoa platforms and when using RemoteLayerTree. Add ContentsLayerEmbeddedViewType, which currently only has the EditableImage type. Add setContentsToEmbeddedView, which takes a ContentsLayerEmbeddedViewType and an EmbeddedViewID to uniquely identify and communicate about the embedded view (which may move between layers, since it is tied to an element). * platform/graphics/ca/GraphicsLayerCA.cpp: (WebCore::GraphicsLayerCA::createPlatformCALayerForEmbeddedView): (WebCore::GraphicsLayerCA::setContentsToEmbeddedView): When setting GraphicsLayer's contents to an embedded view, we use a special PlatformCALayer factory that takes the EmbeddedViewID and type. GraphicsLayerCARemote will override this and make a correctly-initialized PlatformCALayerRemote that keeps track of the EmbeddedViewID. * 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): Add stubs and logging for EmbeddedViewID on PlatformCALayer. These will be overridden by PlatformCALayerRemote to do more interesting things. * rendering/RenderImage.cpp: (WebCore::RenderImage::isEditableImage const): Add a getter that return true if the setting is enabled and x-apple-editable-image is empty or true. (WebCore::RenderImage::requiresLayer const): RenderImage requires a layer either if RenderReplaced does, or we are an editable image. * rendering/RenderImage.h: * rendering/RenderLayer.cpp: (WebCore::RenderLayer::shouldBeNormalFlowOnly const): (WebCore::RenderLayer::calculateClipRects const): * rendering/RenderLayerBacking.cpp: (WebCore::RenderLayerBacking::updateConfiguration): Push the EmbeddedViewID and type down to GraphicsLayer for editable images. * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::requiresCompositingLayer const): (WebCore::RenderLayerCompositor::requiresOwnBackingStore const): (WebCore::RenderLayerCompositor::reasonsForCompositing const): (WebCore::RenderLayerCompositor::requiresCompositingForEditableImage const): * rendering/RenderLayerCompositor.h: Make editable images require compositing implicitly. Source/WebKit: * Platform/spi/ios/PencilKitSPI.h: Added. * 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): * WebProcess/WebPage/RemoteLayerTree/GraphicsLayerCARemote.cpp: (WebKit::GraphicsLayerCARemote::createPlatformCALayerForEmbeddedView): * WebProcess/WebPage/RemoteLayerTree/GraphicsLayerCARemote.h: * WebProcess/WebPage/RemoteLayerTree/PlatformCALayerRemote.cpp: (WebKit::PlatformCALayerRemote::createForEmbeddedView): (WebKit::PlatformCALayerRemote::PlatformCALayerRemote): (WebKit::PlatformCALayerRemote::embeddedViewID const): * WebProcess/WebPage/RemoteLayerTree/PlatformCALayerRemote.h: * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm: (WebKit::RemoteLayerTreeContext::layerWasCreated): Propagate EmbeddedViewID through the PlatformCALayer constructor and through the layer creation parameters to the UI process. * Shared/WebPreferences.yaml: * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _initializeWithConfiguration:]): * UIProcess/API/Cocoa/WKWebViewConfiguration.mm: (-[WKWebViewConfiguration init]): (-[WKWebViewConfiguration copyWithZone:]): (-[WKWebViewConfiguration _setEditableImagesEnabled:]): (-[WKWebViewConfiguration _editableImagesEnabled]): * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h: Add a preference to enable editable images. * UIProcess/RemoteLayerTree/RemoteLayerTreeHost.h: * UIProcess/RemoteLayerTree/RemoteLayerTreeHost.mm: (WebKit::RemoteLayerTreeHost::layerWillBeRemoved): (WebKit::RemoteLayerTreeHost::clearLayers): (WebKit::RemoteLayerTreeHost::createLayer): Keep track of "embedded views" in two maps: embeddedViewID->UIView, and layerID->embeddedViewID. Clean them up when layers go away. If a embedded view is reparented, currently it must be added to a new layer in the same commit as it is removed from the previous layer in order to persist the view's state (otherwise the view will be destroyed and recreated). This will be less of a problem after future patches introduce serialization of image data and whatnot. * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm: (WebKit::RemoteLayerTreeHost::createLayer): (WebKit::RemoteLayerTreeHost::createEmbeddedView): Move the various remote layer tree UIView subclasses out into a separate file. Add createEmbeddedView, which is used for LayerTypeEditableImageLayer, and creates a WKDrawingView and sticks it in the maps. * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h: Added. * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm: Added. (-[UIView _web_recursiveFindDescendantInteractibleViewAtPoint:withEvent:]): (-[UIView _web_findDescendantViewAtPoint:withEvent:]): (-[WKCompositingView hitTest:withEvent:]): (-[WKCompositingView description]): (+[WKTransformView layerClass]): (+[WKSimpleBackdropView layerClass]): (+[WKShapeView layerClass]): (-[WKRemoteView initWithFrame:contextID:]): (+[WKRemoteView layerClass]): (-[WKBackdropView hitTest:withEvent:]): (-[WKBackdropView description]): (-[WKChildScrollView initWithFrame:]): Move various remote layer tree UIView subclasses here, to their own file. Make our UIView hit testing override test for views that conform to the protocol "WKNativelyInteractible", which switches to normal UIView hit testing. WKDrawingView will be the one such view. Add WKChildScrollView and pull the one thing we customize out into it, to make RemoteLayerTreeHost::createLayer less logic-ful. * UIProcess/ios/WKDrawingView.h: Added. * UIProcess/ios/WKDrawingView.mm: Added. (-[WKDrawingView init]): (-[WKDrawingView layoutSubviews]): Add a very simple WKDrawingView, which uses PKCanvasView to edit the image. * WebKit.xcodeproj/project.pbxproj: * SourcesCocoa.txt: Add the new files. Tools: * WebKitTestRunner/TestController.cpp: (WTR::updateTestOptionsFromTestHeader): * WebKitTestRunner/TestOptions.h: (WTR::TestOptions::hasSameInitializationOptions const): * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::platformCreateWebView): Add a test option to enable editable images. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::drawSquareInEditableImage): (WTR::UIScriptController::numberOfStrokesInEditableImage): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::drawSquareInEditableImage): (WTR::UIScriptController::numberOfStrokesInEditableImage): * TestRunnerShared/UIScriptContext/UIScriptController.h: * TestRunnerShared/spi/PencilKitTestSPI.h: Added. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::findEditableImageCanvas): (WTR::UIScriptController::drawSquareInEditableImage): (WTR::UIScriptController::numberOfStrokesInEditableImage): Add the ability to draw on a PKCanvasView that is a subview of the WKWebView, and also to retrieve the number of strokes currently on the PKCanvasView. Currently this just takes the first canvas; we might need to make it take an identifier or something in the future if we need tests with multiple canvases. The indirect testing mechanism is required because PKCanvasView can currently not actually paint its strokes in the Simulator. LayoutTests: * TestExpectations: * editing/images/basic-editable-image-expected.txt: Added. * editing/images/basic-editable-image.html: Added. * editing/images/reparent-editable-image-maintains-strokes-expected.txt: Added. * editing/images/reparent-editable-image-maintains-strokes.html: Added. * platform/ios-wk2/TestExpectations: * resources/ui-helper.js: (window.UIHelper.drawSquareInEditableImage): (window.UIHelper.numberOfStrokesInEditableImage): (window.UIHelper): Add tests that we can find and draw in editable images, and that if the element is moved around in the DOM, it persists its strokes. Canonical link: https://commits.webkit.org/206319@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238108 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-12 22:04:47 +00:00
[iOS] Mouse/Touch/Pointer events are missing modifier keys https://bugs.webkit.org/show_bug.cgi?id=191446 <rdar://problem/45929460> Reviewed by Tim Horton. Source/WebCore: Extract the modifier flags from the WebEvent. This code is only used by Legacy WebKit on iOS and we will need to fix <rdar://problem/47929759> in order for modifier flags to be passed to WebKit. Tests: fast/events/touch/ios/mouse-events-with-modifiers.html fast/events/touch/ios/pointer-events-with-modifiers.html fast/events/touch/ios/touch-events-with-modifiers.html * platform/ios/PlatformEventFactoryIOS.mm: (WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder): * platform/ios/WebEvent.h: * platform/ios/WebEvent.mm: (-[WebEvent initWithMouseEventType:timeStamp:location:]): (-[WebEvent initWithMouseEventType:timeStamp:location:modifiers:]): Source/WebKit: Make use of UIKit SPI to retreive the modifier flags when dispatching mouse and touch events. Add new WebKit SPI for iOS, -[WKNavigationAction modifierFlags], to retrieve the the modifier flags held when a navigation action was initiated. * Platform/spi/ios/UIKitSPI.h: Expose SPI. * Shared/NativeWebTouchEvent.h: Re-arrange macro guards so that we can expose the helper function WebKit::webEventModifierFlags(). This is a bit more involved that usual since this header is included from both C++ and Objective-C source files. It only makes sense to expose this function when compiling as part of an Objective-C source file. * Shared/ios/NativeWebTouchEventIOS.mm: (WebKit::NativeWebTouchEvent::NativeWebTouchEvent): Modified to take the modifier flags held down when the platform touch event was received and pass them through to the base constructor. (WebKit::webEventModifierFlags): Added. Converts from the platform-speciifc UIKeyModifierFlags to OptionSet<WebKit::WebEvent::Modifier>. * Shared/ios/WebIOSEventFactory.h: * Shared/ios/WebIOSEventFactory.mm: (WebIOSEventFactory::toUIKeyModifierFlags): Added. Converts from OptionSet<WebKit::WebEvent::Modifier> to the platform-specific UIKeyModifierFlags. * UIProcess/API/Cocoa/WKNavigationAction.mm: (-[WKNavigationAction modifierFlags]): Added. * UIProcess/API/Cocoa/WKNavigationActionPrivate.h: * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (gestureRecognizerModifierFlags): Added. (-[WKContentView _webTouchEventsRecognized:]): (-[WKContentView _highlightLongPressRecognized:]): (-[WKContentView _twoFingerSingleTapGestureRecognized:]): (-[WKContentView _singleTapCommited:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:modifierFlags:]): Added. (-[WKContentView actionSheetAssistant:openElementAtLocation:]): This is invoked when a person opens a link via the action sheet. We don't have access to the modifier flags to pass. It also seems like an implementation detail that this action is implemented via mouse click and we should re-evaluate this decision in light of the fact tht the action sheet is browser UI and we tend to be very reserved on what UI actions are visible to the page. On Mac, opening a link via the context menu is not visible to the page, at least from a mouse event perspective. (webEventFlagsForUIKeyModifierFlags): Added. (-[WKContentView _hoverGestureRecognizerChanged:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::handleTwoFingerTapAtPoint): (WebKit::WebPageProxy::commitPotentialTap): (WebKit::WebPageProxy::handleTap): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::handleSyntheticClick): (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver): (WebKit::WebPage::completeSyntheticClick): (WebKit::WebPage::handleTap): (WebKit::WebPage::handleTwoFingerTapAtPoint): (WebKit::WebPage::commitPotentialTap): Pass modifier flags through. Tools: Add support infrastructure for testing touch and stylus taps when holding modifier keys. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::arrayLength): (WTR::parseModifierArray): (WTR::UIScriptController::singleTapAtPoint): Implemented in terms of singleTapAtPointWithModifiers(). (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPoint): Implemented in terms of stylusTapAtPointWithModifiers(). (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. LayoutTests: Refactor existing iOS key events tests to share code. Add new tests to ensure touch and mouse events have accurate modifier key details. * fast/events/ios/key-events-meta-alt-combinations.html: * fast/events/ios/resources/key-tester.js: (computeSubsets.compareByModifierOrder): Deleted. * fast/events/resources/compute-subsets.js: Added. (computeSubsets.compareByOriginalArrayOrder): (computeSubsets): * fast/events/touch/ios/mouse-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/mouse-events-with-modifiers.html: Added. * fast/events/touch/ios/pointer-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/pointer-events-with-modifiers.html: Added. * fast/events/touch/ios/touch-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/touch-events-with-modifiers.html: Added. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Update expected result due to changes to ui-helper.js. * http/tests/security/anchor-download-block-crossorigin-expected.txt: Ditto. * platform/ios/TestExpectations: * resources/ui-helper.js: (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208941@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 23:24:23 +00:00
static stylusTapAt(x, y, modifiers=[])
UI process crash when focusing an editable image https://bugs.webkit.org/show_bug.cgi?id=192839 <rdar://problem/46786670> Reviewed by Wenson Hsieh. Source/WebKit: * SourcesCocoa.txt: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _requiresKeyboardWhenFirstResponder]): (-[WKContentView inputView]): (-[WKContentView requiresAccessoryView]): (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): (-[WKContentView _stopAssistingNode]): (-[WKContentView _installInkPickerForDrawingViewWithID:]): (-[WKContentView _uninstallInkPicker]): * UIProcess/ios/WKInkPickerView.h: Renamed from Source/WebKit/UIProcess/ios/WKInkPickerControl.h. * UIProcess/ios/WKInkPickerView.mm: Renamed from Source/WebKit/UIProcess/ios/WKInkPickerControl.mm. (-[WKInkPickerView initWithDrawingView:]): (-[WKInkPickerView didPickInk]): (-[WKInkPickerView inlineInkPickerDidToggleRuler:]): (-[WKInkPickerView inlineInkPicker:didSelectTool:]): (-[WKInkPickerView inlineInkPicker:didSelectColor:]): (-[WKInkPickerView inkPickerSize]): (-[WKInkPickerView layoutSubviews]): (-[WKInkPickerView sizeThatFits:]): (-[WKInkPickerView viewControllerForPopoverPresentationFromInlineInkPicker:]): * WebKit.xcodeproj/project.pbxproj: Make WKInkPickerView a WKWebView subview instead of an inputView. Also, don't force the keyboard to be visible when an editable image is focused. LayoutTests: * editing/images/basic-editable-image-with-gesture.html: Added. * editing/images/basic-editable-image-with-gesture-expected.txt: Added. * resources/ui-helper.js: (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Add a test that ensures that adding an editable image from a gesture doesn't crash, and can be drawn on. Canonical link: https://commits.webkit.org/207445@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239400 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-19 23:37:02 +00:00
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise((resolve) => {
testRunner.runUIScript(`
[iOS] Mouse/Touch/Pointer events are missing modifier keys https://bugs.webkit.org/show_bug.cgi?id=191446 <rdar://problem/45929460> Reviewed by Tim Horton. Source/WebCore: Extract the modifier flags from the WebEvent. This code is only used by Legacy WebKit on iOS and we will need to fix <rdar://problem/47929759> in order for modifier flags to be passed to WebKit. Tests: fast/events/touch/ios/mouse-events-with-modifiers.html fast/events/touch/ios/pointer-events-with-modifiers.html fast/events/touch/ios/touch-events-with-modifiers.html * platform/ios/PlatformEventFactoryIOS.mm: (WebCore::PlatformMouseEventBuilder::PlatformMouseEventBuilder): * platform/ios/WebEvent.h: * platform/ios/WebEvent.mm: (-[WebEvent initWithMouseEventType:timeStamp:location:]): (-[WebEvent initWithMouseEventType:timeStamp:location:modifiers:]): Source/WebKit: Make use of UIKit SPI to retreive the modifier flags when dispatching mouse and touch events. Add new WebKit SPI for iOS, -[WKNavigationAction modifierFlags], to retrieve the the modifier flags held when a navigation action was initiated. * Platform/spi/ios/UIKitSPI.h: Expose SPI. * Shared/NativeWebTouchEvent.h: Re-arrange macro guards so that we can expose the helper function WebKit::webEventModifierFlags(). This is a bit more involved that usual since this header is included from both C++ and Objective-C source files. It only makes sense to expose this function when compiling as part of an Objective-C source file. * Shared/ios/NativeWebTouchEventIOS.mm: (WebKit::NativeWebTouchEvent::NativeWebTouchEvent): Modified to take the modifier flags held down when the platform touch event was received and pass them through to the base constructor. (WebKit::webEventModifierFlags): Added. Converts from the platform-speciifc UIKeyModifierFlags to OptionSet<WebKit::WebEvent::Modifier>. * Shared/ios/WebIOSEventFactory.h: * Shared/ios/WebIOSEventFactory.mm: (WebIOSEventFactory::toUIKeyModifierFlags): Added. Converts from OptionSet<WebKit::WebEvent::Modifier> to the platform-specific UIKeyModifierFlags. * UIProcess/API/Cocoa/WKNavigationAction.mm: (-[WKNavigationAction modifierFlags]): Added. * UIProcess/API/Cocoa/WKNavigationActionPrivate.h: * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (gestureRecognizerModifierFlags): Added. (-[WKContentView _webTouchEventsRecognized:]): (-[WKContentView _highlightLongPressRecognized:]): (-[WKContentView _twoFingerSingleTapGestureRecognized:]): (-[WKContentView _singleTapCommited:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:modifierFlags:]): Added. (-[WKContentView actionSheetAssistant:openElementAtLocation:]): This is invoked when a person opens a link via the action sheet. We don't have access to the modifier flags to pass. It also seems like an implementation detail that this action is implemented via mouse click and we should re-evaluate this decision in light of the fact tht the action sheet is browser UI and we tend to be very reserved on what UI actions are visible to the page. On Mac, opening a link via the context menu is not visible to the page, at least from a mouse event perspective. (webEventFlagsForUIKeyModifierFlags): Added. (-[WKContentView _hoverGestureRecognizerChanged:]): Pass modifier flags through. (-[WKContentView _attemptClickAtLocation:]): Deleted. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::handleTwoFingerTapAtPoint): (WebKit::WebPageProxy::commitPotentialTap): (WebKit::WebPageProxy::handleTap): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::handleSyntheticClick): (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver): (WebKit::WebPage::completeSyntheticClick): (WebKit::WebPage::handleTap): (WebKit::WebPage::handleTwoFingerTapAtPoint): (WebKit::WebPage::commitPotentialTap): Pass modifier flags through. Tools: Add support infrastructure for testing touch and stylus taps when holding modifier keys. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::arrayLength): (WTR::parseModifierArray): (WTR::UIScriptController::singleTapAtPoint): Implemented in terms of singleTapAtPointWithModifiers(). (WTR::UIScriptController::singleTapAtPointWithModifiers): Added. (WTR::UIScriptController::stylusTapAtPoint): Implemented in terms of stylusTapAtPointWithModifiers(). (WTR::UIScriptController::stylusTapAtPointWithModifiers): Added. LayoutTests: Refactor existing iOS key events tests to share code. Add new tests to ensure touch and mouse events have accurate modifier key details. * fast/events/ios/key-events-meta-alt-combinations.html: * fast/events/ios/resources/key-tester.js: (computeSubsets.compareByModifierOrder): Deleted. * fast/events/resources/compute-subsets.js: Added. (computeSubsets.compareByOriginalArrayOrder): (computeSubsets): * fast/events/touch/ios/mouse-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/mouse-events-with-modifiers.html: Added. * fast/events/touch/ios/pointer-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/pointer-events-with-modifiers.html: Added. * fast/events/touch/ios/touch-events-with-modifiers-expected.txt: Added. * fast/events/touch/ios/touch-events-with-modifiers.html: Added. * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Update expected result due to changes to ui-helper.js. * http/tests/security/anchor-download-block-crossorigin-expected.txt: Ditto. * platform/ios/TestExpectations: * resources/ui-helper.js: (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208941@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-11 23:24:23 +00:00
uiController.stylusTapAtPointWithModifiers(${x}, ${y}, 2, 1, 0.5, ${JSON.stringify(modifiers)}, function() {
(iPad) Link tapping is sluggish on many sites https://bugs.webkit.org/show_bug.cgi?id=193522 <rdar://problem/47102987> Reviewed by Wenson Hsieh. Source/WebKit: Some WKWebView clients might set the initial zoom scale of the page to something other than 1, which disables the "fast tap" behaviour. The fix is very simple -- just check against the initial scale rather than 1. The most likely regression from this would be pages designed for desktop, but provide a viewport tag saying width=device-width and initial-scale. They might stop allowing double-tap-to-zoom. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _allowsDoubleTapGestures]): Check against initial page scale. LayoutTests: Add a test that checks a double tap will trigger a click event on a page that is at initial scale. Extra bonus: for some reason adding this test, or making this code change, uncovered a couple of bugs in existing tests. The viewport-zooms-from-element-to-initial-scale test was completely wrong because it was expecting the incorrect result, which was triggered by the zoom callback firing early at a forced scale value. The viewport-no-width-value-allows-double-tap test was triggering a JS error in its UI script. I modernised both of these to use UIHelper instead. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale-expected.txt: Added. * fast/events/ios/fast-click-double-tap-sends-click-when-initial-scale.html: Added. * fast/events/ios/viewport-no-width-value-allows-double-tap.html: * fast/events/ios/viewport-zooms-from-element-to-initial-scale-expected.txt: * fast/events/ios/viewport-zooms-from-element-to-initial-scale.html: * resources/ui-helper.js: Add doubleTapAt and zoomByDoubleTapAt helpers. Remove the unnecessary "Done" return value from many of the callbacks. Give zoomToScale a return value. (window.UIHelper.tapAt.return.new.Promise): (window.UIHelper.tapAt): (window.UIHelper.doubleTapAt.return.new.Promise): (window.UIHelper.doubleTapAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.toggleCapsLock): (window.UIHelper.ensurePresentationUpdate.return.new.Promise): (window.UIHelper.ensurePresentationUpdate): (window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.): (window.UIHelper.activateFormControl.return.new.Promise.): (window.UIHelper.replaceTextAtRange): (window.UIHelper.zoomToScale): (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Canonical link: https://commits.webkit.org/208047@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-17 19:15:57 +00:00
uiController.uiScriptComplete();
UI process crash when focusing an editable image https://bugs.webkit.org/show_bug.cgi?id=192839 <rdar://problem/46786670> Reviewed by Wenson Hsieh. Source/WebKit: * SourcesCocoa.txt: * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _requiresKeyboardWhenFirstResponder]): (-[WKContentView inputView]): (-[WKContentView requiresAccessoryView]): (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): (-[WKContentView _stopAssistingNode]): (-[WKContentView _installInkPickerForDrawingViewWithID:]): (-[WKContentView _uninstallInkPicker]): * UIProcess/ios/WKInkPickerView.h: Renamed from Source/WebKit/UIProcess/ios/WKInkPickerControl.h. * UIProcess/ios/WKInkPickerView.mm: Renamed from Source/WebKit/UIProcess/ios/WKInkPickerControl.mm. (-[WKInkPickerView initWithDrawingView:]): (-[WKInkPickerView didPickInk]): (-[WKInkPickerView inlineInkPickerDidToggleRuler:]): (-[WKInkPickerView inlineInkPicker:didSelectTool:]): (-[WKInkPickerView inlineInkPicker:didSelectColor:]): (-[WKInkPickerView inkPickerSize]): (-[WKInkPickerView layoutSubviews]): (-[WKInkPickerView sizeThatFits:]): (-[WKInkPickerView viewControllerForPopoverPresentationFromInlineInkPicker:]): * WebKit.xcodeproj/project.pbxproj: Make WKInkPickerView a WKWebView subview instead of an inputView. Also, don't force the keyboard to be visible when an editable image is focused. LayoutTests: * editing/images/basic-editable-image-with-gesture.html: Added. * editing/images/basic-editable-image-with-gesture-expected.txt: Added. * resources/ui-helper.js: (window.UIHelper.stylusTapAt.return.new.Promise): (window.UIHelper.stylusTapAt): Add a test that ensures that adding an editable image from a gesture doesn't crash, and can be drawn on. Canonical link: https://commits.webkit.org/207445@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239400 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-19 23:37:02 +00:00
});`, resolve);
});
}
Insert <attachment> elements under editable images to make their backing data accessible https://bugs.webkit.org/show_bug.cgi?id=191844 <rdar://problem/30900149> Reviewed by Simon Fraser. Source/WebCore: Test: editing/images/editable-image-creates-attachment.html * html/HTMLImageElement.cpp: (WebCore::HTMLImageElement::parseAttribute): (WebCore::HTMLImageElement::insertedIntoAncestor): (WebCore::HTMLImageElement::removedFromAncestor): When the x-apple-editable-image attribute changes, or the element is moved into or out of a document, call updateEditableImage. (WebCore::HTMLImageElement::editableImageViewID const): Adopt EditableImageReference. (WebCore::HTMLImageElement::updateEditableImage): When the image element moves into a document, the setting is on, and the appropriate attribute is applied, add an <attachment> into the shadow DOM, and inform the UI process both of the editable image's creation and that it should be associated with the new attachment. Use an EditableImageReference to extend the lifetime of the corresponding editable image in the UI process, and to communicate the attachment association. If the element was cloned from another editable image element, use the EditableImageReference and attachmentID from the original; the embedded view will be re-parented under this element's layer, and the attachment will be cloned (with a new ID) by editing code if the element is parented. (WebCore::HTMLImageElement::attachmentIdentifier const): (WebCore::HTMLImageElement::copyNonAttributePropertiesFromElement): Store the aforementioned bits of information when cloned so that we can reconstitute the appropriate attachment data and embedded view. * html/HTMLImageElement.h: * page/ChromeClient.h: * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * page/EditableImageReference.cpp: Added. (WebCore::EditableImageReference::EditableImageReference): (WebCore::EditableImageReference::~EditableImageReference): (WebCore::EditableImageReference::associateWithAttachment): * page/EditableImageReference.h: Added. (WebCore::EditableImageReference::create): (WebCore::EditableImageReference::embeddedViewID const): Add EditableImageReference, which manages the lifetime of the UI-side EditableImage and helps clients communicate about it. It is refcounted so that cloned <img> elements can potentially borrow the UI-side state (in the case where they end up getting parented). * page/NavigatorBase.cpp: Fix an unrelated unified build failure that I exposed. Source/WebKit: * DerivedSources.make: * SourcesCocoa.txt: * UIProcess/API/APIAttachment.h: fileWrapper() is no longer a trivial getter; it can now construct the file wrapper from a file wrapper generator if necessary. Add setFileWrapperGenerator() and invalidateGeneratedFileWrapper(). Make m_fileWrapper mutable so it can be adjusted inside its own getter. * UIProcess/API/Cocoa/APIAttachmentCocoa.mm: (API::Attachment::fileWrapper const): If we have a fileWrapperGenerator and don't have a cached file wrapper, create one before returning it. (API::Attachment::invalidateGeneratedFileWrapper): Invalidate the currently-cached file wrapper. The next time a client requests the file wrapper it will be regenerated. (API::Attachment::fileName const): (API::Attachment::fileSizeForDisplay const): (API::Attachment::enclosingImageData const): (API::Attachment::isEmpty const): (API::Attachment::createSerializedRepresentation const): Make use of fileWrapper() instead of m_fileWrapper directly, to ensure that it is created lazily if necessary. (API::Attachment::setFileWrapperGenerator): * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm: (WebKit::RemoteLayerTreeHost::createEmbeddedView): * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h: * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm: (-[WKEmbeddedView initWithEmbeddedViewID:]): Defer to EditableImageController for creating WKDrawingViews for editable images. This is done primarily so we don't have to pollute Remote Layer Tree and DrawingArea interfaces with editable-image-specific messages. * UIProcess/WebPageProxy.cpp: (WebKit::m_editableImageController): (WebKit::m_resetRecentCrashCountTimer): Deleted. * UIProcess/WebPageProxy.h: (WebKit::WebPageProxy::editableImageController): Keep an EditableImageController on the WebPageProxy. * UIProcess/ios/EditableImageController.h: Added. * UIProcess/ios/EditableImageController.messages.in: Added. * UIProcess/ios/EditableImageController.mm: Added. (WebKit::EditableImageController::EditableImageController): (WebKit::EditableImageController::~EditableImageController): (WebKit::EditableImageController::ensureEditableImage): (WebKit::EditableImageController::editableImage): (WebKit::EditableImageController::didCreateEditableImage): (WebKit::EditableImageController::didDestroyEditableImage): (WebKit::EditableImageController::associateWithAttachment): (WebKit::EditableImageController::invalidateAttachmentForEditableImage): Add EditableImageController, which keeps track of EditableImages. It can be messaged directly to create or destroy the UI-side state of an editable image, and also to associate a WKDrawingView with a particular attachment. * UIProcess/ios/WKDrawingView.h: * UIProcess/ios/WKDrawingView.mm: (-[WKDrawingView initWithEmbeddedViewID:webPageProxy:]): Store the WebPageProxy (weakly) so that we can get to the EditableImageController. (-[WKDrawingView layoutSubviews]): (-[WKDrawingView PNGRepresentation]): Synchronously render the PKCanvasView to PNG. (-[WKDrawingView drawingDidChange:]): If the drawing changes, inform the APIAttachment that it needs to discard its NSFileWrapper; a new one will be generated lazily. (-[WKDrawingView init]): Deleted. * WebKit.xcodeproj/project.pbxproj: * WebProcess/WebCoreSupport/WebChromeClient.h: * WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm: (WebKit::WebChromeClient::associateEditableImageWithAttachment): (WebKit::WebChromeClient::didCreateEditableImage): (WebKit::WebChromeClient::didDestroyEditableImage): Tools: * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::attachmentInfo): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::attachmentInfo): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::attachmentInfo): Add a UIScriptController mechanism to retrieve information about a given attachment. LayoutTests: * editing/images/editable-image-creates-attachment-expected.txt: Added. * editing/images/editable-image-creates-attachment.html: Added. * resources/ui-helper.js: (window.UIHelper.attachmentInfo): (window.UIHelper): Canonical link: https://commits.webkit.org/206700@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238538 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-27 01:37:22 +00:00
static attachmentInfo(attachmentIdentifier)
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.uiScriptComplete(JSON.stringify(uiController.attachmentInfo('${attachmentIdentifier}')));
})()`, jsonString => {
resolve(JSON.parse(jsonString));
})
});
}
Allow WebKit clients to specify a minimum effective width for layout. https://bugs.webkit.org/show_bug.cgi?id=191499 <rdar://problem/45362678> Patch by Yongjun Zhang <yongjun_zhang@apple.com> on 2018-11-28 Reviewed by Wenson Hsieh. Source/WebCore: If we ignore the meta viewport (_shouldIgnoreMetaViewport is true), the default layout width will be device width. For clients that wish to lay out the content with a different width value, we would need to add a way to specify the effective width for layout. Tests: fast/viewport/ios/ipad/viewport-overriden-by-minimum-effective-width-if-ignore-meta-viewport.html fast/viewport/ios/ipad/viewport-unchanged-by-minimum-effective-width-if-not-ignore-meta-viewport.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::setViewLayoutSize): Add a new argument effectiveWidth. (WebCore::ViewportConfiguration::nativeWebpageParameters): Make sure minimumScale for nativeWebpageParameters is small enough so that it won't clamp out the initial scale. If content is wider than the viewport, this ensures we can still zoom out the page. (WebCore::ViewportConfiguration::updateConfiguration): update _minimumEffectiveDeviceWidth and apply that to the layout size scale computation. (WebCore::ViewportConfiguration::effectiveLayoutSizeScaleFactor): A helper method to return the effective layout scale factor which is also effected by _minimumEffectiveDeviceWidth. (WebCore::ViewportConfiguration::updateMinimumLayoutSize): Update m_minimumLayoutSize based on effectiveLayoutSizeScaleFactor(). (WebCore::ViewportConfiguration::description const): Also dump m_minimumEffectiveDeviceWidth. * page/ViewportConfiguration.h: Add a member variable m_minimumEffectiveDeviceWidth. Source/WebKit: If we ignore the meta viewport (_shouldIgnoreMetaViewport is true), the default layout width will be device width. For clients that wish to lay out the content with a different width value, we would need to add a way to specify the effective width for layout. * UIProcess/API/Cocoa/WKWebView.mm: Add an iVar _minimumEffectiveDeviceWidth. (-[WKWebView _dispatchSetViewLayoutSize:]): Call the new setViewportConfigurationViewLayoutSize method. (-[WKWebView _setViewScale:]): Ditto. (-[WKWebView _setMinimumEffectiveWidth:]): The setter for _minimumEffectiveDeviceWidth. (-[WKWebView _minimumEffectiveWidth]): Getter for _minimumEffectiveDeviceWidth * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add a property _minimumEffectiveDeviceWidth to WKWebView. * UIProcess/WebPageProxy.h: Change setViewportConfigurationViewLayoutSize to take another argument minimumEffectiveDeviceWidth. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::setViewportConfigurationViewLayoutSize): Also send effectiveWidth to WebContent process. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::WebPage): Set the initial effective width to 0 when creating a web page, this tells ViewportConfiguration to ignore the minimum effective width value. * WebProcess/WebPage/WebPage.h: Change setViewportConfigurationViewLayoutSize to take another argument effectiveWidth. * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationViewLayoutSize): Also pass effectiveWidth value to ViewportConfiguration. Tools: Allow UIScriptController to set WKWebView's minimum effective width with a new `setMinimumEffectiveWidth` method. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setMinimumEffectiveWidth): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::setViewScale): (WTR::UIScriptController::setMinimumEffectiveWidth): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setMinimumEffectiveWidth): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::setMinimumEffectiveWidth): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::cocoaResetStateToConsistentValues): LayoutTests: Add two new tests. The first test verifies if we ignore meta viewport, setting a different effective width value will change the layout width of the page. The second test verifies if we don't ignore meta viewport, we will always respect that (980pt) and setting a different effective width value won't change the layout width. * fast/viewport/ios/ipad/viewport-overriden-by-minimum-effective-width-if-ignore-meta-viewport-expected.txt: Added. * fast/viewport/ios/ipad/viewport-overriden-by-minimum-effective-width-if-ignore-meta-viewport.html: Added. * fast/viewport/ios/ipad/viewport-unchanged-by-minimum-effective-width-if-not-ignore-meta-viewport-expected.txt: Added. * fast/viewport/ios/ipad/viewport-unchanged-by-minimum-effective-width-if-not-ignore-meta-viewport.html: Added. * resources/ui-helper.js: (window.UIHelper.setMinimumEffectiveWidth): Add a helper method to set the minimum effective width from a test. (window.UIHelper): Canonical link: https://commits.webkit.org/206776@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238623 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-28 18:50:23 +00:00
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
static insertAttachmentForFilePath(path, contentType)
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
uiController.insertAttachmentForFilePath('${path}', '${contentType}', function() {
uiController.uiScriptComplete();
});`, resolve);
});
}
Allow WebKit clients to specify a minimum effective width for layout. https://bugs.webkit.org/show_bug.cgi?id=191499 <rdar://problem/45362678> Patch by Yongjun Zhang <yongjun_zhang@apple.com> on 2018-11-28 Reviewed by Wenson Hsieh. Source/WebCore: If we ignore the meta viewport (_shouldIgnoreMetaViewport is true), the default layout width will be device width. For clients that wish to lay out the content with a different width value, we would need to add a way to specify the effective width for layout. Tests: fast/viewport/ios/ipad/viewport-overriden-by-minimum-effective-width-if-ignore-meta-viewport.html fast/viewport/ios/ipad/viewport-unchanged-by-minimum-effective-width-if-not-ignore-meta-viewport.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::setViewLayoutSize): Add a new argument effectiveWidth. (WebCore::ViewportConfiguration::nativeWebpageParameters): Make sure minimumScale for nativeWebpageParameters is small enough so that it won't clamp out the initial scale. If content is wider than the viewport, this ensures we can still zoom out the page. (WebCore::ViewportConfiguration::updateConfiguration): update _minimumEffectiveDeviceWidth and apply that to the layout size scale computation. (WebCore::ViewportConfiguration::effectiveLayoutSizeScaleFactor): A helper method to return the effective layout scale factor which is also effected by _minimumEffectiveDeviceWidth. (WebCore::ViewportConfiguration::updateMinimumLayoutSize): Update m_minimumLayoutSize based on effectiveLayoutSizeScaleFactor(). (WebCore::ViewportConfiguration::description const): Also dump m_minimumEffectiveDeviceWidth. * page/ViewportConfiguration.h: Add a member variable m_minimumEffectiveDeviceWidth. Source/WebKit: If we ignore the meta viewport (_shouldIgnoreMetaViewport is true), the default layout width will be device width. For clients that wish to lay out the content with a different width value, we would need to add a way to specify the effective width for layout. * UIProcess/API/Cocoa/WKWebView.mm: Add an iVar _minimumEffectiveDeviceWidth. (-[WKWebView _dispatchSetViewLayoutSize:]): Call the new setViewportConfigurationViewLayoutSize method. (-[WKWebView _setViewScale:]): Ditto. (-[WKWebView _setMinimumEffectiveWidth:]): The setter for _minimumEffectiveDeviceWidth. (-[WKWebView _minimumEffectiveWidth]): Getter for _minimumEffectiveDeviceWidth * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add a property _minimumEffectiveDeviceWidth to WKWebView. * UIProcess/WebPageProxy.h: Change setViewportConfigurationViewLayoutSize to take another argument minimumEffectiveDeviceWidth. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::setViewportConfigurationViewLayoutSize): Also send effectiveWidth to WebContent process. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::WebPage): Set the initial effective width to 0 when creating a web page, this tells ViewportConfiguration to ignore the minimum effective width value. * WebProcess/WebPage/WebPage.h: Change setViewportConfigurationViewLayoutSize to take another argument effectiveWidth. * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationViewLayoutSize): Also pass effectiveWidth value to ViewportConfiguration. Tools: Allow UIScriptController to set WKWebView's minimum effective width with a new `setMinimumEffectiveWidth` method. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setMinimumEffectiveWidth): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::setViewScale): (WTR::UIScriptController::setMinimumEffectiveWidth): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setMinimumEffectiveWidth): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::setMinimumEffectiveWidth): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::cocoaResetStateToConsistentValues): LayoutTests: Add two new tests. The first test verifies if we ignore meta viewport, setting a different effective width value will change the layout width of the page. The second test verifies if we don't ignore meta viewport, we will always respect that (980pt) and setting a different effective width value won't change the layout width. * fast/viewport/ios/ipad/viewport-overriden-by-minimum-effective-width-if-ignore-meta-viewport-expected.txt: Added. * fast/viewport/ios/ipad/viewport-overriden-by-minimum-effective-width-if-ignore-meta-viewport.html: Added. * fast/viewport/ios/ipad/viewport-unchanged-by-minimum-effective-width-if-not-ignore-meta-viewport-expected.txt: Added. * fast/viewport/ios/ipad/viewport-unchanged-by-minimum-effective-width-if-not-ignore-meta-viewport.html: Added. * resources/ui-helper.js: (window.UIHelper.setMinimumEffectiveWidth): Add a helper method to set the minimum effective width from a test. (window.UIHelper): Canonical link: https://commits.webkit.org/206776@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238623 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-28 18:50:23 +00:00
static setMinimumEffectiveWidth(effectiveWidth)
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => testRunner.runUIScript(`uiController.setMinimumEffectiveWidth(${effectiveWidth})`, resolve));
}
[iOS] WKWebView should match UITextView behavior when editing text with an RTL keyboard https://bugs.webkit.org/show_bug.cgi?id=187554 <rdar://problem/42075638> Reviewed by Tim Horton. Source/WebKit: Add support for automatically switching the base writing direction to the default writing direction with respect to the current keyboard in an editable WKWebView by implementing `-setBaseWritingDirection:forRange:`. On iOS 12 and earlier, UIKit invokes this protocol method whenever the keyboard is changed to one with a different writing direction, although in some other versions of iOS, this only happens when first focusing an editable area. Test: editing/input/ios/rtl-keyboard-input-on-focus.html * Platform/spi/ios/UIKitSPI.h: Declare UIKeyboardImpl IPI methods mostly for use in WebKitTestRunner (with the exception of `-setInitialDirection`, which we may invoke when we receive the first post-layout EditorState update after focusing an editable element). * UIProcess/PageClient.h: * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::increaseListLevel): (WebKit::WebPageProxy::decreaseListLevel): (WebKit::WebPageProxy::changeListType): (WebKit::WebPageProxy::setBaseWritingDirection): Drive-by style fixes: make these bail and return early if `!isValid()`. (WebKit::WebPageProxy::resetStateAfterProcessExited): Reset assisted node state in the UI process upon web process termination. * UIProcess/WebPageProxy.h: Add plumbing for `setBaseWritingDirection`, from `WebPageProxy` to `WebPage` to `Editor`. * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::didReceiveEditorStateUpdateAfterFocus): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView baseWritingDirectionForPosition:inDirection:]): (coreWritingDirection): (-[WKContentView setBaseWritingDirection:forRange:]): Support `-setBaseWritingDirectionForPosition:forRange:`, but only in the case where the given range is the selected range. This is all that's currently needed to fulfill the requirements in <rdar://problem/42075638>, though we could potentially add full support for this in the future by mapping the given text range to a DOM range and moving the selection prior to setting the base writing direction. (-[WKContentView _didReceiveEditorStateUpdateAfterFocus]): Add a hook to notify WKContentView when the first post-layout EditorState has been received in the UI process. When this is invoked, if the web view is editable and the selection is not a range, we call into `UIKeyboardImpl` to change the initial writing direction if necessary. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::startAssistingNode): (WebKit::WebPageProxy::stopAssistingNode): (WebKit::WebPageProxy::editorStateChanged): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::setBaseWritingDirection): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Tools: Add support for simulating the keyboard input mode in layout tests using UIScriptController, as well as a new `TestOption` to make the web view editable. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setKeyboardInputModeIdentifier): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setKeyboardInputModeIdentifier): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/PlatformWebView.h: * WebKitTestRunner/TestController.cpp: (WTR::updateTestOptionsFromTestHeader): * WebKitTestRunner/TestController.h: (WTR::TestController::overriddenKeyboardInputMode const): * WebKitTestRunner/TestOptions.h: (WTR::TestOptions::hasSameInitializationOptions const): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::platformCreateWebView): * WebKitTestRunner/gtk/PlatformWebViewGtk.cpp: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/ios/PlatformWebViewIOS.mm: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): (WTR::swizzleCurrentInputMode): (WTR::TestController::setKeyboardInputModeIdentifier): Swizzle out several `UIKeyboardInputModeController` methods in order to convince UIKit that the user has selected a `UIKeyboardInputMode` corresponding to the given identifier. The call to `-prepareKeyboardInputModeFromPreferences:` is also necessary on iOS 12 in order to update cached writing direction state in UIKit. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setKeyboardInputModeIdentifier): * WebKitTestRunner/mac/PlatformWebViewMac.mm: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/win/PlatformWebViewWin.cpp: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/wpe/PlatformWebViewWPE.cpp: (WTR::PlatformWebView::setEditable): LayoutTests: Add a new layout test to verify that when focusing an editable WKWebView using a right-to-left keyboard input mode, we will set the base writing direction to be right-to-left, and vice versa. * TestExpectations: * editing/input/ios/rtl-keyboard-input-on-focus-expected.txt: Added. * editing/input/ios/rtl-keyboard-input-on-focus.html: Added. * platform/ios-wk2/TestExpectations: * resources/ui-helper.js: Add a UIHelper method to set the keyboard input mode to the given identifier. Example identifiers are "en_US" (the default U.S. English keyboard) and "he_IL" (the Hebrew keyboard, which is right-to-left). (window.UIHelper.setKeyboardInputModeIdentifier): (window.UIHelper): Canonical link: https://commits.webkit.org/207064@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238939 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-06 21:22:19 +00:00
scalableNativeWebpageParameters() is not preserved on new page navigation. https://bugs.webkit.org/show_bug.cgi?id=194892 <rdar://problem/47538280> Source/WebCore: If a page's current default viewport configuration is scalableNativeWebpageParameters due to the fact that m_canIgnoreScalingConstraints is true, loading a new page should preserve this configuration until we derive the right values from viewport meta-tag. Patch by Yongjun Zhang <yongjun_zhang@apple.com> on 2019-02-25 Reviewed by Wenson Hsieh. Test: fast/viewport/ios/viewport-shrink-to-fit-on-new-navigation.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::canOverrideConfigurationParameters const): Use fixedNativeWebpageParameters(). (WebCore::ViewportConfiguration::updateDefaultConfiguration): Use nativeWebpageParameters. (WebCore::ViewportConfiguration::nativeWebpageParameters): Return the appropriate default configuration based on m_canIgnoreScalingConstraints and shouldIgnoreMinimumEffectiveDeviceWidth(). (WebCore::ViewportConfiguration::fixedNativeWebpageParameters): Renamed from nativeWebpageParameters() (WebCore::ViewportConfiguration::scalableNativeWebpageParameters): Use fixedNativeWebpageParameters. * page/ViewportConfiguration.h: Make nativeWebpageParameters() an instance method and change the old static method to fixedNativeWebpageParameters which better reflects the actual behavior. Source/WebKit: If a page's current default viewport configuration is scalableNativeWebpageParameters due to the fact that m_canIgnoreScalingConstraints is true, loading a new page should preserve this configuration until we derive the right values from viewport meta-tag. Patch by Yongjun Zhang <yongjun_zhang@apple.com> on 2019-02-25 Reviewed by Wenson Hsieh. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::resetViewportDefaultConfiguration): Use nativeWebpageParameters() instance method to get the appropriate default configuration. Tools: Patch by Yongjun Zhang <yongjun_zhang@apple.com> on 2019-02-25 Reviewed by Wenson Hsieh. Allow UIScriptController to set WKWebView's _allowsViewportShrinkToFit property with a new `setAllowsViewportShrinkToFit` method. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setAllowsViewportShrinkToFit): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::allowsViewportShrinkToFit): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setAllowsViewportShrinkToFit): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::setAllowsViewportShrinkToFit): LayoutTests: Patch by Yongjun Zhang <yongjun_zhang@apple.com> on 2019-02-25 Reviewed by Wenson Hsieh. * fast/viewport/ios/resources/go-back.html: Added. * fast/viewport/ios/viewport-shrink-to-fit-on-new-navigation-expected.txt: Added. * fast/viewport/ios/viewport-shrink-to-fit-on-new-navigation.html: Added. * fast/viewport/ios/minimum-scale-after-changing-view-scale.html: When shouldIgnoreMetaViewport setting is on, for pages don't have viewport meta-tag, the default configuration is now changed to scalableNativeWebpageParameters(). The original test was under the assumption that the default configuration is always fixedNativeWebpageParameters(). To keep the test still valid, add a viewport meta-tag to it. * resources/ui-helper.js: (window.UIHelper.setAllowsViewportShrinkToFit): Canonical link: https://commits.webkit.org/209392@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242069 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-26 04:37:59 +00:00
static setAllowsViewportShrinkToFit(allows)
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => testRunner.runUIScript(`uiController.setAllowsViewportShrinkToFit(${allows})`, resolve));
}
[iOS] WKWebView should match UITextView behavior when editing text with an RTL keyboard https://bugs.webkit.org/show_bug.cgi?id=187554 <rdar://problem/42075638> Reviewed by Tim Horton. Source/WebKit: Add support for automatically switching the base writing direction to the default writing direction with respect to the current keyboard in an editable WKWebView by implementing `-setBaseWritingDirection:forRange:`. On iOS 12 and earlier, UIKit invokes this protocol method whenever the keyboard is changed to one with a different writing direction, although in some other versions of iOS, this only happens when first focusing an editable area. Test: editing/input/ios/rtl-keyboard-input-on-focus.html * Platform/spi/ios/UIKitSPI.h: Declare UIKeyboardImpl IPI methods mostly for use in WebKitTestRunner (with the exception of `-setInitialDirection`, which we may invoke when we receive the first post-layout EditorState update after focusing an editable element). * UIProcess/PageClient.h: * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::increaseListLevel): (WebKit::WebPageProxy::decreaseListLevel): (WebKit::WebPageProxy::changeListType): (WebKit::WebPageProxy::setBaseWritingDirection): Drive-by style fixes: make these bail and return early if `!isValid()`. (WebKit::WebPageProxy::resetStateAfterProcessExited): Reset assisted node state in the UI process upon web process termination. * UIProcess/WebPageProxy.h: Add plumbing for `setBaseWritingDirection`, from `WebPageProxy` to `WebPage` to `Editor`. * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::didReceiveEditorStateUpdateAfterFocus): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView baseWritingDirectionForPosition:inDirection:]): (coreWritingDirection): (-[WKContentView setBaseWritingDirection:forRange:]): Support `-setBaseWritingDirectionForPosition:forRange:`, but only in the case where the given range is the selected range. This is all that's currently needed to fulfill the requirements in <rdar://problem/42075638>, though we could potentially add full support for this in the future by mapping the given text range to a DOM range and moving the selection prior to setting the base writing direction. (-[WKContentView _didReceiveEditorStateUpdateAfterFocus]): Add a hook to notify WKContentView when the first post-layout EditorState has been received in the UI process. When this is invoked, if the web view is editable and the selection is not a range, we call into `UIKeyboardImpl` to change the initial writing direction if necessary. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::startAssistingNode): (WebKit::WebPageProxy::stopAssistingNode): (WebKit::WebPageProxy::editorStateChanged): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::setBaseWritingDirection): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Tools: Add support for simulating the keyboard input mode in layout tests using UIScriptController, as well as a new `TestOption` to make the web view editable. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setKeyboardInputModeIdentifier): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setKeyboardInputModeIdentifier): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/PlatformWebView.h: * WebKitTestRunner/TestController.cpp: (WTR::updateTestOptionsFromTestHeader): * WebKitTestRunner/TestController.h: (WTR::TestController::overriddenKeyboardInputMode const): * WebKitTestRunner/TestOptions.h: (WTR::TestOptions::hasSameInitializationOptions const): * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::platformCreateWebView): * WebKitTestRunner/gtk/PlatformWebViewGtk.cpp: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/ios/PlatformWebViewIOS.mm: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): (WTR::swizzleCurrentInputMode): (WTR::TestController::setKeyboardInputModeIdentifier): Swizzle out several `UIKeyboardInputModeController` methods in order to convince UIKit that the user has selected a `UIKeyboardInputMode` corresponding to the given identifier. The call to `-prepareKeyboardInputModeFromPreferences:` is also necessary on iOS 12 in order to update cached writing direction state in UIKit. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setKeyboardInputModeIdentifier): * WebKitTestRunner/mac/PlatformWebViewMac.mm: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/win/PlatformWebViewWin.cpp: (WTR::PlatformWebView::setEditable): * WebKitTestRunner/wpe/PlatformWebViewWPE.cpp: (WTR::PlatformWebView::setEditable): LayoutTests: Add a new layout test to verify that when focusing an editable WKWebView using a right-to-left keyboard input mode, we will set the base writing direction to be right-to-left, and vice versa. * TestExpectations: * editing/input/ios/rtl-keyboard-input-on-focus-expected.txt: Added. * editing/input/ios/rtl-keyboard-input-on-focus.html: Added. * platform/ios-wk2/TestExpectations: * resources/ui-helper.js: Add a UIHelper method to set the keyboard input mode to the given identifier. Example identifiers are "en_US" (the default U.S. English keyboard) and "he_IL" (the Hebrew keyboard, which is right-to-left). (window.UIHelper.setKeyboardInputModeIdentifier): (window.UIHelper): Canonical link: https://commits.webkit.org/207064@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238939 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-06 21:22:19 +00:00
static setKeyboardInputModeIdentifier(identifier)
{
if (!this.isWebKit2())
return Promise.resolve();
const escapedIdentifier = identifier.replace(/`/g, "\\`");
return new Promise(resolve => testRunner.runUIScript(`uiController.setKeyboardInputModeIdentifier(\`${escapedIdentifier}\`)`, resolve));
}
[iOS] Content offset jumps erratically when autoscrolling near scroll view content inset areas https://bugs.webkit.org/show_bug.cgi?id=193494 <rdar://problem/46859627> Reviewed by Simon Fraser and Tim Horton. Source/WebCore: When computing the content offset to scroll to when revealing a given rect in content coordinates, we currently just use the unobscured content rect. As a result, when scrolling to reveal a rect, we'll clamp the final scroll position such that only content is visible. For example, when asked to reveal the rect `(0, 0, 1, 1)`, we adjust the scroll position to be the origin. However, consider the case where a client (e.g. Mail on iOS) has added a content inset to the web view's scroll view. If we're asked to reveal a rect that is outside the content area but within a content inset, we will still end up clamping the scroll position to the unobscured rect. This manifests in a bug where selecting text and autoscrolling in iOS Mail compose while the scroll view is scrolled all the way to the top to reveal the To/Cc/ Subject fields causes the content offset to jump to the origin, rather than staying at (0, -topContentInset). To fix this, we teach `RenderLayer::scrollRectToVisible` about content insets that are visible. Rather than use the content rects as-is, expand to encompass visible content insets as well. This ensures that revealing a position which is already visible won't cause us to scroll away the content inset area and only show the unobscured rect. Tests: editing/selection/ios/autoscroll-with-top-content-inset.html fast/scrolling/ios/scroll-into-view-with-top-content-inset.html * page/FrameView.cpp: (WebCore::FrameView::unobscuredContentRectExpandedByContentInsets const): Introduce a helper method that expands the unobscured content rect to include surrounding content insets. * page/FrameView.h: * page/Page.h: (WebCore::Page::contentInsets const): (WebCore::Page::setContentInsets): * rendering/RenderLayer.cpp: (WebCore::RenderLayer::scrollRectToVisible): (WebCore::RenderLayer::getRectToExpose const): Source/WebKit: Adds `contentInsets` to `VisibleContentRectUpdateInfo`. This keeps track of the visible content insets surrounding the unobscured content rect. See WebCore ChangeLog for more details. * Shared/VisibleContentRectUpdateInfo.cpp: (WebKit::VisibleContentRectUpdateInfo::encode const): (WebKit::VisibleContentRectUpdateInfo::decode): (WebKit::operator<<): * Shared/VisibleContentRectUpdateInfo.h: (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo): (WebKit::VisibleContentRectUpdateInfo::contentInsets const): (WebKit::operator==): * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _computedObscuredInset]): (-[WKWebView _computedContentInset]): (-[WKWebView _computedUnobscuredSafeAreaInset]): We don't care about source compatibility with iOS 10 and below anymore, so we should change these >= iOS 11 target checks to simply `PLATFORM(IOS)`. (-[WKWebView _updateVisibleContentRects]): Compute the visible content insets on all sides of the unobscured content rect. These insets are scaled to content coordinates. * UIProcess/ios/WKContentView.h: * UIProcess/ios/WKContentView.mm: (floatBoxExtent): Add a helper to convert `UIEdgeInsets` to `WebCore::FloatBoxExtent`, and use it in a few places below. (-[WKContentView didUpdateVisibleRect:unobscuredRect:contentInsets:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): Deleted. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::updateVisibleContentRects): Update the Page's content insets. Tools: Add a new test option to add a top content inset to the test runner's WKWebView's scroll view, and automatically scroll to reveal this top content inset area when beginning the test (i.e., scroll to (0, -topContentInset)). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::contentOffsetX const): (WTR::UIScriptController::contentOffsetY const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::contentOffsetX const): (WTR::UIScriptController::contentOffsetY const): * TestRunnerShared/UIScriptContext/UIScriptController.h: Also add new UIScriptController methods to ask for the content offset of the platform scroll view. * WebKitTestRunner/TestController.cpp: (WTR::updateTestOptionsFromTestHeader): * WebKitTestRunner/TestOptions.h: (WTR::TestOptions::hasSameInitializationOptions const): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::contentOffsetX const): (WTR::UIScriptController::contentOffsetY const): LayoutTests: * editing/selection/ios/autoscroll-with-top-content-inset-expected.txt: Added. * editing/selection/ios/autoscroll-with-top-content-inset.html: Added. Add a new test to verify that moving the selection by autoscrolling near the top content inset area does not cause the scroll view's content offset to jump. * fast/scrolling/ios/scroll-into-view-with-top-content-inset-expected.txt: Added. * fast/scrolling/ios/scroll-into-view-with-top-content-inset.html: Added. Add a new test to verify that programmatically scrolling an element that's already visible into view does not scroll away the scroll view's content inset. * resources/ui-helper.js: (window.UIHelper.contentOffset): (window.UIHelper): Canonical link: https://commits.webkit.org/208065@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240139 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-18 04:15:24 +00:00
static contentOffset()
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isIOSFamily())
[iOS] Content offset jumps erratically when autoscrolling near scroll view content inset areas https://bugs.webkit.org/show_bug.cgi?id=193494 <rdar://problem/46859627> Reviewed by Simon Fraser and Tim Horton. Source/WebCore: When computing the content offset to scroll to when revealing a given rect in content coordinates, we currently just use the unobscured content rect. As a result, when scrolling to reveal a rect, we'll clamp the final scroll position such that only content is visible. For example, when asked to reveal the rect `(0, 0, 1, 1)`, we adjust the scroll position to be the origin. However, consider the case where a client (e.g. Mail on iOS) has added a content inset to the web view's scroll view. If we're asked to reveal a rect that is outside the content area but within a content inset, we will still end up clamping the scroll position to the unobscured rect. This manifests in a bug where selecting text and autoscrolling in iOS Mail compose while the scroll view is scrolled all the way to the top to reveal the To/Cc/ Subject fields causes the content offset to jump to the origin, rather than staying at (0, -topContentInset). To fix this, we teach `RenderLayer::scrollRectToVisible` about content insets that are visible. Rather than use the content rects as-is, expand to encompass visible content insets as well. This ensures that revealing a position which is already visible won't cause us to scroll away the content inset area and only show the unobscured rect. Tests: editing/selection/ios/autoscroll-with-top-content-inset.html fast/scrolling/ios/scroll-into-view-with-top-content-inset.html * page/FrameView.cpp: (WebCore::FrameView::unobscuredContentRectExpandedByContentInsets const): Introduce a helper method that expands the unobscured content rect to include surrounding content insets. * page/FrameView.h: * page/Page.h: (WebCore::Page::contentInsets const): (WebCore::Page::setContentInsets): * rendering/RenderLayer.cpp: (WebCore::RenderLayer::scrollRectToVisible): (WebCore::RenderLayer::getRectToExpose const): Source/WebKit: Adds `contentInsets` to `VisibleContentRectUpdateInfo`. This keeps track of the visible content insets surrounding the unobscured content rect. See WebCore ChangeLog for more details. * Shared/VisibleContentRectUpdateInfo.cpp: (WebKit::VisibleContentRectUpdateInfo::encode const): (WebKit::VisibleContentRectUpdateInfo::decode): (WebKit::operator<<): * Shared/VisibleContentRectUpdateInfo.h: (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo): (WebKit::VisibleContentRectUpdateInfo::contentInsets const): (WebKit::operator==): * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _computedObscuredInset]): (-[WKWebView _computedContentInset]): (-[WKWebView _computedUnobscuredSafeAreaInset]): We don't care about source compatibility with iOS 10 and below anymore, so we should change these >= iOS 11 target checks to simply `PLATFORM(IOS)`. (-[WKWebView _updateVisibleContentRects]): Compute the visible content insets on all sides of the unobscured content rect. These insets are scaled to content coordinates. * UIProcess/ios/WKContentView.h: * UIProcess/ios/WKContentView.mm: (floatBoxExtent): Add a helper to convert `UIEdgeInsets` to `WebCore::FloatBoxExtent`, and use it in a few places below. (-[WKContentView didUpdateVisibleRect:unobscuredRect:contentInsets:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]): Deleted. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::updateVisibleContentRects): Update the Page's content insets. Tools: Add a new test option to add a top content inset to the test runner's WKWebView's scroll view, and automatically scroll to reveal this top content inset area when beginning the test (i.e., scroll to (0, -topContentInset)). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::contentOffsetX const): (WTR::UIScriptController::contentOffsetY const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::contentOffsetX const): (WTR::UIScriptController::contentOffsetY const): * TestRunnerShared/UIScriptContext/UIScriptController.h: Also add new UIScriptController methods to ask for the content offset of the platform scroll view. * WebKitTestRunner/TestController.cpp: (WTR::updateTestOptionsFromTestHeader): * WebKitTestRunner/TestOptions.h: (WTR::TestOptions::hasSameInitializationOptions const): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::contentOffsetX const): (WTR::UIScriptController::contentOffsetY const): LayoutTests: * editing/selection/ios/autoscroll-with-top-content-inset-expected.txt: Added. * editing/selection/ios/autoscroll-with-top-content-inset.html: Added. Add a new test to verify that moving the selection by autoscrolling near the top content inset area does not cause the scroll view's content offset to jump. * fast/scrolling/ios/scroll-into-view-with-top-content-inset-expected.txt: Added. * fast/scrolling/ios/scroll-into-view-with-top-content-inset.html: Added. Add a new test to verify that programmatically scrolling an element that's already visible into view does not scroll away the scroll view's content inset. * resources/ui-helper.js: (window.UIHelper.contentOffset): (window.UIHelper): Canonical link: https://commits.webkit.org/208065@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240139 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-18 04:15:24 +00:00
return Promise.resolve();
const uiScript = "JSON.stringify([uiController.contentOffsetX, uiController.contentOffsetY])";
return new Promise(resolve => testRunner.runUIScript(uiScript, result => {
const [offsetX, offsetY] = JSON.parse(result)
resolve({ x: offsetX, y: offsetY });
}));
}
Need a way for JavaScript (or bundle) code to participate in undo https://bugs.webkit.org/show_bug.cgi?id=190009 <rdar://problem/44807048> Reviewed by Ryosuke Niwa. Source/WebCore: Finish hooking up `UndoManager::addItems()` to CustomUndoStep. Tests: editing/undo-manager/undo-manager-add-item-exceptions.html editing/undo-manager/undo-manager-add-item.html editing/undo-manager/undo-manager-delete-stale-undo-items.html editing/undo-manager/undo-manager-item-labels.html editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html * editing/CompositeEditCommand.h: * editing/CustomUndoStep.cpp: (WebCore::CustomUndoStep::didRemoveFromUndoManager): Add a method to invalidate CustomUndoStep. This clears out the pointer to the undo item, and also invalidates the UndoItem, removing it from its UndoManager. * editing/CustomUndoStep.h: * editing/Editor.cpp: (WebCore::Editor::registerCustomUndoStep): Add a helper method to register a CustomUndoStep as a platform undoable step. * editing/Editor.h: * editing/UndoStep.h: * page/UndoItem.h: (WebCore::UndoItem::undoManager const): * page/UndoManager.cpp: (WebCore::UndoManager::addItem): Create a CustomUndoStep with the given UndoItem, and register it with the platform undo manager. * page/UndoManager.h: * page/UndoManager.idl: Mark addItem() as capable of throwing exceptions. Source/WebKit: Invalidate undo steps when removing them from WebPage. Invalidation is a no-op for editing actions that come from the UA, but for custom undo steps backed by an UndoItem, we clear out the custom undo step's pointer to its UndoItem and additionally disconnect the UndoItem from its UndoManager. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::addWebUndoStep): (WebKit::WebPage::removeWebEditCommand): * WebProcess/WebPage/WebUndoStep.h: (WebKit::WebUndoStep::invalidate): Tools: Add UIScriptController helpers to grab the platform undo and redo action labels. Currently only implemented for Cocoa platforms in WebKit2. See other ChangeLogs for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::lastUndoLabel const): (WTR::UIScriptController::firstRedoLabel const): (WTR::UIScriptController::platformUndoManager const): * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::lastUndoLabel const): (WTR::UIScriptController::firstRedoLabel const): (WTR::UIScriptController::platformUndoManager const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::lastUndoLabel const): (WTR::UIScriptController::firstRedoLabel const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/UIScriptControllerCocoa.mm: (WTR::UIScriptController::lastUndoLabel const): (WTR::UIScriptController::firstRedoLabel const): * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::platformUndoManager const): * WebKitTestRunner/mac/UIScriptControllerMac.mm: (WTR::UIScriptController::platformUndoManager const): LayoutTests: Add a few new layout tests covering `UndoManager.addItem()`. * editing/undo-manager/undo-manager-add-item-exceptions-expected.txt: Added. * editing/undo-manager/undo-manager-add-item-exceptions.html: Added. Add a test to verify that we throw exceptions when calling addItem() in a couple of circumstances. * editing/undo-manager/undo-manager-add-item-expected.txt: Added. * editing/undo-manager/undo-manager-add-item.html: Added. Add a test that exercises the new API in both the top-level context and a child frame. * editing/undo-manager/undo-manager-delete-stale-undo-items-expected.txt: Added. * editing/undo-manager/undo-manager-delete-stale-undo-items.html: Added. Add a test to verify that after adding undo items, undoing, and then performing other edit actions, garbage collection will destroy JS wrappers for the previously added UndoItems, since these undo items' handlers can no longer be invoked. * editing/undo-manager/undo-manager-item-labels-expected.txt: Added. * editing/undo-manager/undo-manager-item-labels.html: Added. Add a test verifying that the undo and redo action labels are updated correctly when undoing and redoing. * editing/undo-manager/undo-manager-undo-redo-after-garbage-collection-expected.txt: Added. * editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html: Added. Add a test to verify that triggering garbage collection after adding an undo item without keeping references to the item (or its undo/redo handlers) doesn't break the API. * resources/ui-helper.js: (window.UIHelper.undoAndRedoLabels): Add a helper method to grab the platform's current undo and redo action names. (window.UIHelper): Canonical link: https://commits.webkit.org/208316@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240476 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-01-25 17:23:06 +00:00
static undoAndRedoLabels()
{
if (!this.isWebKit2())
return Promise.resolve();
const script = "JSON.stringify([uiController.lastUndoLabel, uiController.firstRedoLabel])";
return new Promise(resolve => testRunner.runUIScript(script, result => resolve(JSON.parse(result))));
}
[iOS] Callout menu overlaps in-page controls when editing a comment in github.com's issue tracker https://bugs.webkit.org/show_bug.cgi?id=194873 <rdar://problem/46701974> Reviewed by Tim Horton. Source/WebKit: On the topic of supporting web-based rich text editors on iOS, one problematic area has always been handling conflicts between platform UI (i.e., the system callout menu) and in-page text editing controls. This issue comes up in websites that don't use the "hidden contenteditable" approach to rich text editing, but also show additional controls in a toolbar or contextual menu above the selection. In these cases, what often happens is that system controls overlap controls in the page. Luckily, the iOS callout menu (i.e. the private UICalloutBar) is capable of presenting with a list of "evasion rects" to avoid; if the callout bar would normally intersect with one of these rects, then a different orientation that does not intersect with one of these rects is chosen instead. Currently, the only rect added here by UIKit when presenting the callout menu is the bounding rect of the on-screen keyboard, but after <rdar://problem/48128337>, we now have a generalized mechanism for offering additional evasion rects before UIKit presents the callout menu. This patch adopts the mechanism introduced in <rdar://problem/48128337>, and introduces a heuristic for determining the approximate location of controls in the page which might overlap the callout menu. This heuristic works by hit-testing for clickable (but non-editable) nodes above the bounds of the selection, which are additionally not hit-tested by advancing outwards from any of the other edges of the selection bounds. Additionally, any hit-tested nodes whose bounding rects are very large (relative to the content view size) are ignored (this deals with scenarios where the body or a large container element has a click handler). We then add the bounding rects of each of the nodes that fit this criteria to the list of rects for UIKit to avoid when presenting the system callout menu. The result is that WebKit will, by default, avoid overlapping anything that looks like controls in the page when showing a callout menu in editable content. In practice, this fixes overlapping controls on most websites that roll their own context menu or toolbar in their rich text editor. Test: editing/selection/ios/avoid-showing-callout-menu-over-controls.html * Platform/spi/ios/UIKitSPI.h: * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView requestAutocorrectionRectsForString:withCompletionHandler:]): (-[WKContentView requestRectsToEvadeForSelectionCommandsWithCompletionHandler:]): (-[WKContentView requestAutocorrectionContextWithCompletionHandler:]): Drive-by: handle null completion handler arguments more gracefully, by raising an NSException and bailing before attempting to invoke a nil block. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::requestEvasionRectsAboveSelection): See above for more detail. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::requestEvasionRectsAboveSelection): Tools: Add a couple of UIScriptController methods to make callout menu testing on iOS easier (see below). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::menuRect const): (WTR::UIScriptController::isShowingMenu const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::menuRect const): Add a function to query the bounds of the callout menu in content coordinates. (WTR::UIScriptController::isShowingMenu const): Add a function to query whether the callout menu is shown (i.e., has finished its appearance animation). * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::rectForMenuAction const): (WTR::UIScriptController::menuRect const): (WTR::UIScriptController::isShowingMenu const): (WTR::findViewInHierarchyOfType): Deleted. LayoutTests: Add a test to ensure that the we dodge clickable elements when showing the callout bar. * editing/selection/ios/avoid-showing-callout-menu-over-controls-expected.txt: Added. * editing/selection/ios/avoid-showing-callout-menu-over-controls.html: Added. * resources/ui-helper.js: (window.UIHelper.waitForMenuToShow.return.new.Promise): (window.UIHelper.waitForMenuToShow): (window.UIHelper.menuRect): (window.UIHelper): Canonical link: https://commits.webkit.org/209323@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241971 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-23 00:48:16 +00:00
static waitForMenuToShow()
{
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (!uiController.isShowingMenu)
uiController.didShowMenuCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
})()`, resolve);
});
}
[iOS] Add a quirk to synthesize mouse events when modifying the selection https://bugs.webkit.org/show_bug.cgi?id=197683 <rdar://problem/48003980> Reviewed by Tim Horton. Source/WebCore: See WebKit ChangeLog for more details. Test: editing/selection/ios/dispatch-mouse-events-when-modifying-selection-quirk.html * page/EventHandler.cpp: (WebCore::EventHandler::handleMousePressEvent): (WebCore::EventHandler::supportsSelectionUpdatesOnMouseDrag const): Add some platform hooks to prevent mousemove events from updating the selection on iOS. (WebCore::EventHandler::shouldAllowMouseDownToStartDrag const): Add some platform hooks to prevent drag and drop from kicking in when sending synthetic mousemove events to the page on iOS (drag and drop is instead triggered by EventHandler::tryToBeginDragAtPoint). (WebCore::EventHandler::updateSelectionForMouseDrag): * page/EventHandler.h: * page/Quirks.cpp: (WebCore::Quirks::shouldDispatchSyntheticMouseEventsWhenModifyingSelection const): * page/Quirks.h: Add the new site-specific quirk. * page/Settings.yaml: * page/ios/EventHandlerIOS.mm: (WebCore::EventHandler::tryToBeginDragAtPoint): (WebCore::EventHandler::supportsSelectionUpdatesOnMouseDrag const): (WebCore::EventHandler::shouldAllowMouseDownToStartDrag const): * testing/InternalSettings.cpp: (WebCore::InternalSettings::Backup::Backup): (WebCore::InternalSettings::Backup::restoreTo): (WebCore::InternalSettings::setShouldDispatchSyntheticMouseEventsWhenModifyingSelection): * testing/InternalSettings.h: * testing/InternalSettings.idl: Add an internal settings hook to opt into this quirk, for use in layout tests. Source/WebKit: Introduces support for dispatching synthetic mouse events when modifying the selection on some websites. See below for more details. * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::selectAll): * UIProcess/WebPageProxy.h: Instead of executing a "SelectAll" editing command using the generic WebPage::executeEditCommand method, introduce a separate method for selectAll that executes the "SelectAll" edit command and then does some platform-specific work. See platformDidSelectAll. * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView selectAllForWebView:]): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::selectAll): (WebKit::WebPage::shouldDispatchSyntheticMouseEventsWhenModifyingSelection const): Add a helper method to determine whether the quirk should be enabled. (WebKit::WebPage::platformDidSelectAll): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::elementRectInRootViewCoordinates): Move this function closer to the top of the file so that it can be used in dispatchSyntheticMouseEventsForSelectionGesture. (WebKit::WebPage::clearSelection): (WebKit::WebPage::dispatchSyntheticMouseEventsForSelectionGesture): Add a helper method to dispatch a synthetic mouse event for a given selection gesture type. Used in several places in WebPageIOS to synthesize and dispatch mouse events during selection. (WebKit::WebPage::updateSelectionWithTouches): When changing the selection with selection handles, fake mousedown when the user first touches down on the selection handle; mousemove as the user is moving the handle around; and finally, mouseup when the user lets go. (WebKit::WebPage::extendSelection): (WebKit::WebPage::platformDidSelectAll): When tapping "Select All" and/or "Select" in the callout menu, fake a mousedown at the selection start, then a mousemove at selection end, and finally, a mouseup at selection end. (WebKit::WebPage::getFocusedElementInformation): LayoutTests: Adds a new layout test to enable the site-specific quirk and verify that mouse events are dispatched when changing selection, both via the callout menu and by moving the selection grabber using gestures. * editing/selection/ios/dispatch-mouse-events-when-modifying-selection-quirk-expected.txt: Added. * editing/selection/ios/dispatch-mouse-events-when-modifying-selection-quirk.html: Added. * resources/ui-helper.js: (window.UIHelper.waitForMenuToHide.return.new.Promise): (window.UIHelper.waitForMenuToHide): Introduce a new helper method to wait for the menu to hide (on iOS, this refers to the callout menu). Canonical link: https://commits.webkit.org/211841@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245062 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-08 19:36:33 +00:00
static waitForMenuToHide()
{
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (uiController.isShowingMenu)
uiController.didHideMenuCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
})()`, resolve);
});
}
[iOS] [WebKit2] Add support for honoring -[UIMenuItem dontDismiss] https://bugs.webkit.org/show_bug.cgi?id=196919 <rdar://problem/41630459> Reviewed by Tim Horton. Source/WebKit: Adds modern WebKit support for -dontDismiss by implementing a couple of new platform hooks. Covered by a new layout test: editing/selection/ios/selection-after-changing-text-with-callout-menu.html. * Platform/spi/ios/UIKitSPI.h: Declare the private -dontDismiss property of UIMenuItem. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): Additionally teach the web view (not just the content view) to respond to the hook. This matters in the case where the WebKit client (most notably, Mail) overrides WKWebView methods to define custom actions in the menu controller. This scenario is exercised by the new layout test. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): If an action was performed where callout bar fading was ignored, then in WebKit, don't allow selection changes to fade the callout bar until after the next remote layer tree commit. (-[WKContentView _updateChangedSelection:]): Stop suppressing selection updates when showing B/I/U controls, now that we can properly honor the -dontDismiss property. This was originally introduced in <rdar://problem/15199925>, presumably to ensure that B/I/U buttons (which have -dontDismiss set to YES) don't trigger selection change and end up dismissing themselves; however, if triggering B/I/U actually changes the selection rects, this also means that the selection rects on-screen would be stale after triggering these actions. This effect is most noticeable when bolding text. (-[WKContentView shouldAllowHidingSelectionCommands]): Tools: Add iOS support for several new testing hooks. See below for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): Add a new script controller method to query whether the platform menu (on iOS, the callout bar) is done dismissing. We consider the menu to be dismissing in between the `-WillHide` and `-DidHide` notifications sent by UIKit when dismissing the callout bar (i.e. UIMenuController). * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isDismissingMenu const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: (WTR::InjectedBundle::didReceiveMessageToPage): * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::setAllowedMenuActions): Add a new helper method to specify a list of allowed actions when bringing up the menu. On iOS, in the case of actions supported by the platform, this matches against method selector names (for instance, "SelectAll", or "Copy", or "Paste"). In the case of the custom actions installed via `installCustomMenuAction`, we instead match against the name of the custom action. (WTR::TestRunner::installCustomMenuAction): Add a new helper method to install a custom action for the context menu (on iOS, this is the callout bar). This takes the name of the action (which appears in a button in the callout bar), whether the action should cause the callout bar to automatically dismiss, and finally, a JavaScript callback that is invoked when the action is triggered. (WTR::TestRunner::performCustomMenuAction): Invoked when the custom menu action is triggered. * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/TestController.cpp: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/TestController.h: * WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): (WTR::TestInvocation::performCustomMenuAction): Add plumbing to call back into the injected bundle when performing the custom action. * WebKitTestRunner/TestInvocation.h: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView becomeFirstResponder]): (-[TestRunnerWKWebView _addCustomItemToMenuControllerIfNecessary]): Helper method that converts web view's current custom menu action info into a UIMenuItem, and adds it to the shared menu controller. This is also invoked when the web view becomes first responder, which matches behavior in the Mail app on iOS. (-[TestRunnerWKWebView installCustomMenuAction:dismissesAutomatically:callback:]): (-[TestRunnerWKWebView setAllowedMenuActions:]): (-[TestRunnerWKWebView resetCustomMenuAction]): (-[TestRunnerWKWebView performCustomAction:]): (-[TestRunnerWKWebView canPerformAction:withSender:]): (-[TestRunnerWKWebView _willHideMenu]): (-[TestRunnerWKWebView _didHideMenu]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): Reset both any custom installed actions on the shared menu controller, as well as the list of allowed actions, if specified. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): LayoutTests: Add a new iOS layout test that installs a custom, non-dismissing action in the callout menu that enlarges text. The test then activates this custom menu item and checks that the selection rects after triggering this custom action are updated, and the callout bar is still showing. * editing/selection/ios/selection-after-changing-text-with-callout-menu-expected.txt: Added. * editing/selection/ios/selection-after-changing-text-with-callout-menu.html: Added. This test additionally suppresses all callout bar menu items except for the custom "Embiggen" action, to ensure that the "Embiggen" option can be tapped from the layout test without having to navigate callout bar items by tapping on the "Next" and "Show styles" buttons. This latter approach is very challenging to make reliable in automation; when navigating submenus in the callout bar, the next button can't be tapped until the current callout bar transition animation is complete, but there's no delegate method invoked or notification posted when this happens. * resources/ui-helper.js: (window.UIHelper.isShowingMenu): (window.UIHelper.isDismissingMenu): (window.UIHelper.rectForMenuAction): (window.UIHelper.async.chooseMenuAction): Additionally add a few more UIHelper methods. (window.UIHelper): Canonical link: https://commits.webkit.org/211257@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244370 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-17 03:34:10 +00:00
static isShowingMenu()
{
return new Promise(resolve => {
testRunner.runUIScript(`uiController.isShowingMenu`, result => resolve(result === "true"));
});
}
static isDismissingMenu()
{
return new Promise(resolve => {
testRunner.runUIScript(`uiController.isDismissingMenu`, result => resolve(result === "true"));
});
}
[iOS] Callout menu overlaps in-page controls when editing a comment in github.com's issue tracker https://bugs.webkit.org/show_bug.cgi?id=194873 <rdar://problem/46701974> Reviewed by Tim Horton. Source/WebKit: On the topic of supporting web-based rich text editors on iOS, one problematic area has always been handling conflicts between platform UI (i.e., the system callout menu) and in-page text editing controls. This issue comes up in websites that don't use the "hidden contenteditable" approach to rich text editing, but also show additional controls in a toolbar or contextual menu above the selection. In these cases, what often happens is that system controls overlap controls in the page. Luckily, the iOS callout menu (i.e. the private UICalloutBar) is capable of presenting with a list of "evasion rects" to avoid; if the callout bar would normally intersect with one of these rects, then a different orientation that does not intersect with one of these rects is chosen instead. Currently, the only rect added here by UIKit when presenting the callout menu is the bounding rect of the on-screen keyboard, but after <rdar://problem/48128337>, we now have a generalized mechanism for offering additional evasion rects before UIKit presents the callout menu. This patch adopts the mechanism introduced in <rdar://problem/48128337>, and introduces a heuristic for determining the approximate location of controls in the page which might overlap the callout menu. This heuristic works by hit-testing for clickable (but non-editable) nodes above the bounds of the selection, which are additionally not hit-tested by advancing outwards from any of the other edges of the selection bounds. Additionally, any hit-tested nodes whose bounding rects are very large (relative to the content view size) are ignored (this deals with scenarios where the body or a large container element has a click handler). We then add the bounding rects of each of the nodes that fit this criteria to the list of rects for UIKit to avoid when presenting the system callout menu. The result is that WebKit will, by default, avoid overlapping anything that looks like controls in the page when showing a callout menu in editable content. In practice, this fixes overlapping controls on most websites that roll their own context menu or toolbar in their rich text editor. Test: editing/selection/ios/avoid-showing-callout-menu-over-controls.html * Platform/spi/ios/UIKitSPI.h: * UIProcess/WebPageProxy.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView requestAutocorrectionRectsForString:withCompletionHandler:]): (-[WKContentView requestRectsToEvadeForSelectionCommandsWithCompletionHandler:]): (-[WKContentView requestAutocorrectionContextWithCompletionHandler:]): Drive-by: handle null completion handler arguments more gracefully, by raising an NSException and bailing before attempting to invoke a nil block. * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::requestEvasionRectsAboveSelection): See above for more detail. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::requestEvasionRectsAboveSelection): Tools: Add a couple of UIScriptController methods to make callout menu testing on iOS easier (see below). * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::menuRect const): (WTR::UIScriptController::isShowingMenu const): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::menuRect const): Add a function to query the bounds of the callout menu in content coordinates. (WTR::UIScriptController::isShowingMenu const): Add a function to query whether the callout menu is shown (i.e., has finished its appearance animation). * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::rectForMenuAction const): (WTR::UIScriptController::menuRect const): (WTR::UIScriptController::isShowingMenu const): (WTR::findViewInHierarchyOfType): Deleted. LayoutTests: Add a test to ensure that the we dodge clickable elements when showing the callout bar. * editing/selection/ios/avoid-showing-callout-menu-over-controls-expected.txt: Added. * editing/selection/ios/avoid-showing-callout-menu-over-controls.html: Added. * resources/ui-helper.js: (window.UIHelper.waitForMenuToShow.return.new.Promise): (window.UIHelper.waitForMenuToShow): (window.UIHelper.menuRect): (window.UIHelper): Canonical link: https://commits.webkit.org/209323@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@241971 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-02-23 00:48:16 +00:00
static menuRect()
{
return new Promise(resolve => {
testRunner.runUIScript("JSON.stringify(uiController.menuRect)", result => resolve(JSON.parse(result)));
});
}
[iOS] Software keyboard is shown too frequently on some websites https://bugs.webkit.org/show_bug.cgi?id=195856 <rdar://problem/49191395> Reviewed by Darin Adler. Source/WebCore/PAL: Declare new GraphicsServices SPI. * pal/spi/ios/GraphicsServicesSPI.h: Source/WebKit: On some websites, hidden editable elements are very frequently focused upon user interaction. Currently, this causes the software keyboard to pop in and out unexpectedly; luckily, these same sites also apply inputmode="none" to the hidden editable element, which ought to ensure that the software keyboard doesn't appear when the element is focused. However, since we disabled support for inputmode="none" in r240497, the software keyboard is no longer suppressed, and becomes a big nuissance. r240497 removed support for this feature because, when using a hardware keyboard, pressing the globe key no longer showed UI for switching languages. However, support for inputmode none makes a much larger impact when a software keyboard is used (since the entire software keyboard animates in and out), whereas a hardware keyboard only displays an input accessory view. For this reason, we can mitigate this bug without reintroducing <rdar://problem/47406553> by re-enabling inputmode="none", but only when a hardware keyboard is not attached. * UIProcess/API/Cocoa/WKWebView.mm: (hardwareKeyboardAvailabilityChangedCallback): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView shouldShowAutomaticKeyboardUI]): Don't show the keyboard if inputmode is none and a hardware keyboard is not attached. (-[WKContentView _hardwareKeyboardAvailabilityChanged]): Reload input views if the inputmode is none to ensure that if a hardware keyboard is attached while editing an element with inputmode="none", we'll show the input accessory view once again. Tools: Add support for attaching or detaching the hardware keyboard on iOS in layout tests. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::setHardwareKeyboardAttached): * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::setHardwareKeyboardAttached): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/Configurations/WebKitTestRunnerApp.xcconfig: Additionally link against GraphicsServices in WebKitTestRunner. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): (WTR::UIScriptController::setHardwareKeyboardAttached): WebKitLibraries: Add a symbol for GSEventSetHardwareKeyboardAttached. * WebKitPrivateFrameworkStubs/iOS/12/GraphicsServices.framework/GraphicsServices.tbd: LayoutTests: Fix a failing layout test, which (among other reasons) is currently failing because support for inputmode="none" is disabled. * fast/forms/ios/inputmode-none-expected.txt: * fast/forms/ios/inputmode-none.html: * resources/ui-helper.js: Add a UIHelper method for attaching or detaching the hardware keyboard. (window.UIHelper.setHardwareKeyboardAttached): (window.UIHelper): Canonical link: https://commits.webkit.org/211129@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244220 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-12 17:30:00 +00:00
static setHardwareKeyboardAttached(attached)
{
return new Promise(resolve => testRunner.runUIScript(`uiController.setHardwareKeyboardAttached(${attached ? "true" : "false"})`, resolve));
}
[iOS] [WebKit2] Add support for honoring -[UIMenuItem dontDismiss] https://bugs.webkit.org/show_bug.cgi?id=196919 <rdar://problem/41630459> Reviewed by Tim Horton. Source/WebKit: Adds modern WebKit support for -dontDismiss by implementing a couple of new platform hooks. Covered by a new layout test: editing/selection/ios/selection-after-changing-text-with-callout-menu.html. * Platform/spi/ios/UIKitSPI.h: Declare the private -dontDismiss property of UIMenuItem. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): Additionally teach the web view (not just the content view) to respond to the hook. This matters in the case where the WebKit client (most notably, Mail) overrides WKWebView methods to define custom actions in the menu controller. This scenario is exercised by the new layout test. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): If an action was performed where callout bar fading was ignored, then in WebKit, don't allow selection changes to fade the callout bar until after the next remote layer tree commit. (-[WKContentView _updateChangedSelection:]): Stop suppressing selection updates when showing B/I/U controls, now that we can properly honor the -dontDismiss property. This was originally introduced in <rdar://problem/15199925>, presumably to ensure that B/I/U buttons (which have -dontDismiss set to YES) don't trigger selection change and end up dismissing themselves; however, if triggering B/I/U actually changes the selection rects, this also means that the selection rects on-screen would be stale after triggering these actions. This effect is most noticeable when bolding text. (-[WKContentView shouldAllowHidingSelectionCommands]): Tools: Add iOS support for several new testing hooks. See below for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): Add a new script controller method to query whether the platform menu (on iOS, the callout bar) is done dismissing. We consider the menu to be dismissing in between the `-WillHide` and `-DidHide` notifications sent by UIKit when dismissing the callout bar (i.e. UIMenuController). * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isDismissingMenu const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: (WTR::InjectedBundle::didReceiveMessageToPage): * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::setAllowedMenuActions): Add a new helper method to specify a list of allowed actions when bringing up the menu. On iOS, in the case of actions supported by the platform, this matches against method selector names (for instance, "SelectAll", or "Copy", or "Paste"). In the case of the custom actions installed via `installCustomMenuAction`, we instead match against the name of the custom action. (WTR::TestRunner::installCustomMenuAction): Add a new helper method to install a custom action for the context menu (on iOS, this is the callout bar). This takes the name of the action (which appears in a button in the callout bar), whether the action should cause the callout bar to automatically dismiss, and finally, a JavaScript callback that is invoked when the action is triggered. (WTR::TestRunner::performCustomMenuAction): Invoked when the custom menu action is triggered. * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/TestController.cpp: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/TestController.h: * WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): (WTR::TestInvocation::performCustomMenuAction): Add plumbing to call back into the injected bundle when performing the custom action. * WebKitTestRunner/TestInvocation.h: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView becomeFirstResponder]): (-[TestRunnerWKWebView _addCustomItemToMenuControllerIfNecessary]): Helper method that converts web view's current custom menu action info into a UIMenuItem, and adds it to the shared menu controller. This is also invoked when the web view becomes first responder, which matches behavior in the Mail app on iOS. (-[TestRunnerWKWebView installCustomMenuAction:dismissesAutomatically:callback:]): (-[TestRunnerWKWebView setAllowedMenuActions:]): (-[TestRunnerWKWebView resetCustomMenuAction]): (-[TestRunnerWKWebView performCustomAction:]): (-[TestRunnerWKWebView canPerformAction:withSender:]): (-[TestRunnerWKWebView _willHideMenu]): (-[TestRunnerWKWebView _didHideMenu]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): Reset both any custom installed actions on the shared menu controller, as well as the list of allowed actions, if specified. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): LayoutTests: Add a new iOS layout test that installs a custom, non-dismissing action in the callout menu that enlarges text. The test then activates this custom menu item and checks that the selection rects after triggering this custom action are updated, and the callout bar is still showing. * editing/selection/ios/selection-after-changing-text-with-callout-menu-expected.txt: Added. * editing/selection/ios/selection-after-changing-text-with-callout-menu.html: Added. This test additionally suppresses all callout bar menu items except for the custom "Embiggen" action, to ensure that the "Embiggen" option can be tapped from the layout test without having to navigate callout bar items by tapping on the "Next" and "Show styles" buttons. This latter approach is very challenging to make reliable in automation; when navigating submenus in the callout bar, the next button can't be tapped until the current callout bar transition animation is complete, but there's no delegate method invoked or notification posted when this happens. * resources/ui-helper.js: (window.UIHelper.isShowingMenu): (window.UIHelper.isDismissingMenu): (window.UIHelper.rectForMenuAction): (window.UIHelper.async.chooseMenuAction): Additionally add a few more UIHelper methods. (window.UIHelper): Canonical link: https://commits.webkit.org/211257@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244370 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-17 03:34:10 +00:00
static rectForMenuAction(action)
{
return new Promise(resolve => {
testRunner.runUIScript(`
(() => {
const rect = uiController.rectForMenuAction("${action}");
uiController.uiScriptComplete(rect ? JSON.stringify(rect) : "");
})();
[iOS] [WebKit2] Add support for honoring -[UIMenuItem dontDismiss] https://bugs.webkit.org/show_bug.cgi?id=196919 <rdar://problem/41630459> Reviewed by Tim Horton. Source/WebKit: Adds modern WebKit support for -dontDismiss by implementing a couple of new platform hooks. Covered by a new layout test: editing/selection/ios/selection-after-changing-text-with-callout-menu.html. * Platform/spi/ios/UIKitSPI.h: Declare the private -dontDismiss property of UIMenuItem. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): Additionally teach the web view (not just the content view) to respond to the hook. This matters in the case where the WebKit client (most notably, Mail) overrides WKWebView methods to define custom actions in the menu controller. This scenario is exercised by the new layout test. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): If an action was performed where callout bar fading was ignored, then in WebKit, don't allow selection changes to fade the callout bar until after the next remote layer tree commit. (-[WKContentView _updateChangedSelection:]): Stop suppressing selection updates when showing B/I/U controls, now that we can properly honor the -dontDismiss property. This was originally introduced in <rdar://problem/15199925>, presumably to ensure that B/I/U buttons (which have -dontDismiss set to YES) don't trigger selection change and end up dismissing themselves; however, if triggering B/I/U actually changes the selection rects, this also means that the selection rects on-screen would be stale after triggering these actions. This effect is most noticeable when bolding text. (-[WKContentView shouldAllowHidingSelectionCommands]): Tools: Add iOS support for several new testing hooks. See below for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): Add a new script controller method to query whether the platform menu (on iOS, the callout bar) is done dismissing. We consider the menu to be dismissing in between the `-WillHide` and `-DidHide` notifications sent by UIKit when dismissing the callout bar (i.e. UIMenuController). * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isDismissingMenu const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: (WTR::InjectedBundle::didReceiveMessageToPage): * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::setAllowedMenuActions): Add a new helper method to specify a list of allowed actions when bringing up the menu. On iOS, in the case of actions supported by the platform, this matches against method selector names (for instance, "SelectAll", or "Copy", or "Paste"). In the case of the custom actions installed via `installCustomMenuAction`, we instead match against the name of the custom action. (WTR::TestRunner::installCustomMenuAction): Add a new helper method to install a custom action for the context menu (on iOS, this is the callout bar). This takes the name of the action (which appears in a button in the callout bar), whether the action should cause the callout bar to automatically dismiss, and finally, a JavaScript callback that is invoked when the action is triggered. (WTR::TestRunner::performCustomMenuAction): Invoked when the custom menu action is triggered. * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/TestController.cpp: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/TestController.h: * WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): (WTR::TestInvocation::performCustomMenuAction): Add plumbing to call back into the injected bundle when performing the custom action. * WebKitTestRunner/TestInvocation.h: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView becomeFirstResponder]): (-[TestRunnerWKWebView _addCustomItemToMenuControllerIfNecessary]): Helper method that converts web view's current custom menu action info into a UIMenuItem, and adds it to the shared menu controller. This is also invoked when the web view becomes first responder, which matches behavior in the Mail app on iOS. (-[TestRunnerWKWebView installCustomMenuAction:dismissesAutomatically:callback:]): (-[TestRunnerWKWebView setAllowedMenuActions:]): (-[TestRunnerWKWebView resetCustomMenuAction]): (-[TestRunnerWKWebView performCustomAction:]): (-[TestRunnerWKWebView canPerformAction:withSender:]): (-[TestRunnerWKWebView _willHideMenu]): (-[TestRunnerWKWebView _didHideMenu]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): Reset both any custom installed actions on the shared menu controller, as well as the list of allowed actions, if specified. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): LayoutTests: Add a new iOS layout test that installs a custom, non-dismissing action in the callout menu that enlarges text. The test then activates this custom menu item and checks that the selection rects after triggering this custom action are updated, and the callout bar is still showing. * editing/selection/ios/selection-after-changing-text-with-callout-menu-expected.txt: Added. * editing/selection/ios/selection-after-changing-text-with-callout-menu.html: Added. This test additionally suppresses all callout bar menu items except for the custom "Embiggen" action, to ensure that the "Embiggen" option can be tapped from the layout test without having to navigate callout bar items by tapping on the "Next" and "Show styles" buttons. This latter approach is very challenging to make reliable in automation; when navigating submenus in the callout bar, the next button can't be tapped until the current callout bar transition animation is complete, but there's no delegate method invoked or notification posted when this happens. * resources/ui-helper.js: (window.UIHelper.isShowingMenu): (window.UIHelper.isDismissingMenu): (window.UIHelper.rectForMenuAction): (window.UIHelper.async.chooseMenuAction): Additionally add a few more UIHelper methods. (window.UIHelper): Canonical link: https://commits.webkit.org/211257@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244370 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-17 03:34:10 +00:00
`, stringResult => {
resolve(stringResult.length ? JSON.parse(stringResult) : null);
});
});
}
[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
static chooseMenuAction(action)
[iOS] [WebKit2] Add support for honoring -[UIMenuItem dontDismiss] https://bugs.webkit.org/show_bug.cgi?id=196919 <rdar://problem/41630459> Reviewed by Tim Horton. Source/WebKit: Adds modern WebKit support for -dontDismiss by implementing a couple of new platform hooks. Covered by a new layout test: editing/selection/ios/selection-after-changing-text-with-callout-menu.html. * Platform/spi/ios/UIKitSPI.h: Declare the private -dontDismiss property of UIMenuItem. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): Additionally teach the web view (not just the content view) to respond to the hook. This matters in the case where the WebKit client (most notably, Mail) overrides WKWebView methods to define custom actions in the menu controller. This scenario is exercised by the new layout test. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): If an action was performed where callout bar fading was ignored, then in WebKit, don't allow selection changes to fade the callout bar until after the next remote layer tree commit. (-[WKContentView _updateChangedSelection:]): Stop suppressing selection updates when showing B/I/U controls, now that we can properly honor the -dontDismiss property. This was originally introduced in <rdar://problem/15199925>, presumably to ensure that B/I/U buttons (which have -dontDismiss set to YES) don't trigger selection change and end up dismissing themselves; however, if triggering B/I/U actually changes the selection rects, this also means that the selection rects on-screen would be stale after triggering these actions. This effect is most noticeable when bolding text. (-[WKContentView shouldAllowHidingSelectionCommands]): Tools: Add iOS support for several new testing hooks. See below for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): Add a new script controller method to query whether the platform menu (on iOS, the callout bar) is done dismissing. We consider the menu to be dismissing in between the `-WillHide` and `-DidHide` notifications sent by UIKit when dismissing the callout bar (i.e. UIMenuController). * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isDismissingMenu const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: (WTR::InjectedBundle::didReceiveMessageToPage): * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::setAllowedMenuActions): Add a new helper method to specify a list of allowed actions when bringing up the menu. On iOS, in the case of actions supported by the platform, this matches against method selector names (for instance, "SelectAll", or "Copy", or "Paste"). In the case of the custom actions installed via `installCustomMenuAction`, we instead match against the name of the custom action. (WTR::TestRunner::installCustomMenuAction): Add a new helper method to install a custom action for the context menu (on iOS, this is the callout bar). This takes the name of the action (which appears in a button in the callout bar), whether the action should cause the callout bar to automatically dismiss, and finally, a JavaScript callback that is invoked when the action is triggered. (WTR::TestRunner::performCustomMenuAction): Invoked when the custom menu action is triggered. * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/TestController.cpp: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/TestController.h: * WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): (WTR::TestInvocation::performCustomMenuAction): Add plumbing to call back into the injected bundle when performing the custom action. * WebKitTestRunner/TestInvocation.h: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView becomeFirstResponder]): (-[TestRunnerWKWebView _addCustomItemToMenuControllerIfNecessary]): Helper method that converts web view's current custom menu action info into a UIMenuItem, and adds it to the shared menu controller. This is also invoked when the web view becomes first responder, which matches behavior in the Mail app on iOS. (-[TestRunnerWKWebView installCustomMenuAction:dismissesAutomatically:callback:]): (-[TestRunnerWKWebView setAllowedMenuActions:]): (-[TestRunnerWKWebView resetCustomMenuAction]): (-[TestRunnerWKWebView performCustomAction:]): (-[TestRunnerWKWebView canPerformAction:withSender:]): (-[TestRunnerWKWebView _willHideMenu]): (-[TestRunnerWKWebView _didHideMenu]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): Reset both any custom installed actions on the shared menu controller, as well as the list of allowed actions, if specified. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): LayoutTests: Add a new iOS layout test that installs a custom, non-dismissing action in the callout menu that enlarges text. The test then activates this custom menu item and checks that the selection rects after triggering this custom action are updated, and the callout bar is still showing. * editing/selection/ios/selection-after-changing-text-with-callout-menu-expected.txt: Added. * editing/selection/ios/selection-after-changing-text-with-callout-menu.html: Added. This test additionally suppresses all callout bar menu items except for the custom "Embiggen" action, to ensure that the "Embiggen" option can be tapped from the layout test without having to navigate callout bar items by tapping on the "Next" and "Show styles" buttons. This latter approach is very challenging to make reliable in automation; when navigating submenus in the callout bar, the next button can't be tapped until the current callout bar transition animation is complete, but there's no delegate method invoked or notification posted when this happens. * resources/ui-helper.js: (window.UIHelper.isShowingMenu): (window.UIHelper.isDismissingMenu): (window.UIHelper.rectForMenuAction): (window.UIHelper.async.chooseMenuAction): Additionally add a few more UIHelper methods. (window.UIHelper): Canonical link: https://commits.webkit.org/211257@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244370 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-17 03:34:10 +00:00
{
[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
return new Promise(resolve => {
testRunner.runUIScript(`
(() => {
uiController.chooseMenuAction("${action}", () => {
uiController.uiScriptComplete();
});
})();
`, resolve);
});
[iOS] [WebKit2] Add support for honoring -[UIMenuItem dontDismiss] https://bugs.webkit.org/show_bug.cgi?id=196919 <rdar://problem/41630459> Reviewed by Tim Horton. Source/WebKit: Adds modern WebKit support for -dontDismiss by implementing a couple of new platform hooks. Covered by a new layout test: editing/selection/ios/selection-after-changing-text-with-callout-menu.html. * Platform/spi/ios/UIKitSPI.h: Declare the private -dontDismiss property of UIMenuItem. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): Additionally teach the web view (not just the content view) to respond to the hook. This matters in the case where the WebKit client (most notably, Mail) overrides WKWebView methods to define custom actions in the menu controller. This scenario is exercised by the new layout test. * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView willFinishIgnoringCalloutBarFadeAfterPerformingAction]): If an action was performed where callout bar fading was ignored, then in WebKit, don't allow selection changes to fade the callout bar until after the next remote layer tree commit. (-[WKContentView _updateChangedSelection:]): Stop suppressing selection updates when showing B/I/U controls, now that we can properly honor the -dontDismiss property. This was originally introduced in <rdar://problem/15199925>, presumably to ensure that B/I/U buttons (which have -dontDismiss set to YES) don't trigger selection change and end up dismissing themselves; however, if triggering B/I/U actually changes the selection rects, this also means that the selection rects on-screen would be stale after triggering these actions. This effect is most noticeable when bolding text. (-[WKContentView shouldAllowHidingSelectionCommands]): Tools: Add iOS support for several new testing hooks. See below for more detail. * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): Add a new script controller method to query whether the platform menu (on iOS, the callout bar) is done dismissing. We consider the menu to be dismissing in between the `-WillHide` and `-DidHide` notifications sent by UIKit when dismissing the callout bar (i.e. UIMenuController). * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.cpp: (WTR::UIScriptController::isDismissingMenu const): * TestRunnerShared/UIScriptContext/UIScriptController.h: * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp: (WTR::InjectedBundle::didReceiveMessageToPage): * WebKitTestRunner/InjectedBundle/TestRunner.cpp: (WTR::TestRunner::setAllowedMenuActions): Add a new helper method to specify a list of allowed actions when bringing up the menu. On iOS, in the case of actions supported by the platform, this matches against method selector names (for instance, "SelectAll", or "Copy", or "Paste"). In the case of the custom actions installed via `installCustomMenuAction`, we instead match against the name of the custom action. (WTR::TestRunner::installCustomMenuAction): Add a new helper method to install a custom action for the context menu (on iOS, this is the callout bar). This takes the name of the action (which appears in a button in the callout bar), whether the action should cause the callout bar to automatically dismiss, and finally, a JavaScript callback that is invoked when the action is triggered. (WTR::TestRunner::performCustomMenuAction): Invoked when the custom menu action is triggered. * WebKitTestRunner/InjectedBundle/TestRunner.h: * WebKitTestRunner/TestController.cpp: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/TestController.h: * WebKitTestRunner/TestInvocation.cpp: (WTR::TestInvocation::didReceiveMessageFromInjectedBundle): (WTR::TestInvocation::performCustomMenuAction): Add plumbing to call back into the injected bundle when performing the custom action. * WebKitTestRunner/TestInvocation.h: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::installCustomMenuAction): (WTR::TestController::setAllowedMenuActions): * WebKitTestRunner/cocoa/TestRunnerWKWebView.h: * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm: (-[TestRunnerWKWebView initWithFrame:configuration:]): (-[TestRunnerWKWebView becomeFirstResponder]): (-[TestRunnerWKWebView _addCustomItemToMenuControllerIfNecessary]): Helper method that converts web view's current custom menu action info into a UIMenuItem, and adds it to the shared menu controller. This is also invoked when the web view becomes first responder, which matches behavior in the Mail app on iOS. (-[TestRunnerWKWebView installCustomMenuAction:dismissesAutomatically:callback:]): (-[TestRunnerWKWebView setAllowedMenuActions:]): (-[TestRunnerWKWebView resetCustomMenuAction]): (-[TestRunnerWKWebView performCustomAction:]): (-[TestRunnerWKWebView canPerformAction:withSender:]): (-[TestRunnerWKWebView _willHideMenu]): (-[TestRunnerWKWebView _didHideMenu]): * WebKitTestRunner/ios/TestControllerIOS.mm: (WTR::TestController::platformResetStateToConsistentValues): Reset both any custom installed actions on the shared menu controller, as well as the list of allowed actions, if specified. * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptController::isDismissingMenu const): LayoutTests: Add a new iOS layout test that installs a custom, non-dismissing action in the callout menu that enlarges text. The test then activates this custom menu item and checks that the selection rects after triggering this custom action are updated, and the callout bar is still showing. * editing/selection/ios/selection-after-changing-text-with-callout-menu-expected.txt: Added. * editing/selection/ios/selection-after-changing-text-with-callout-menu.html: Added. This test additionally suppresses all callout bar menu items except for the custom "Embiggen" action, to ensure that the "Embiggen" option can be tapped from the layout test without having to navigate callout bar items by tapping on the "Next" and "Show styles" buttons. This latter approach is very challenging to make reliable in automation; when navigating submenus in the callout bar, the next button can't be tapped until the current callout bar transition animation is complete, but there's no delegate method invoked or notification posted when this happens. * resources/ui-helper.js: (window.UIHelper.isShowingMenu): (window.UIHelper.isDismissingMenu): (window.UIHelper.rectForMenuAction): (window.UIHelper.async.chooseMenuAction): Additionally add a few more UIHelper methods. (window.UIHelper): Canonical link: https://commits.webkit.org/211257@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244370 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-04-17 03:34:10 +00:00
}
[iOS] Cannot scroll to beginning of document after scrolling to end of document and vice versa via key commands https://bugs.webkit.org/show_bug.cgi?id=197848 <rdar://problem/49523065> Patch by Daniel Bates <dabates@apple.com> on 2019-05-14 Reviewed by Brent Fulgham. Source/WebKit: Following the fix for <rdar://problem/49523065>, UIKit no longer emits a keyup event for a Command- modified key. This breaks WebKit's own implementation of key command handling for scrolling to the beginning or end of the document (triggered using Command + Arrow Up and Command + Arrow Down, respectively) because it watches for keyup events to reset state after initiating a scroll. If state is not reset then the scroll key command logic becomes confused and may not perform a subsequent scroll. It seems like we can actually get away with supporting these key commands and future Command modified commands by preemptively reseting state on keydown if the Command modifier is held down. If this does not work out then we can do something more complicated. * UIProcess/ios/WKKeyboardScrollingAnimator.mm: (-[WKKeyboardScrollingAnimator handleKeyEvent:]): LayoutTests: Add a test to ensure that key commands can be used to scroll to the end of the page and then to the beginning of the page. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document-expected.txt: Added. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document.html: Added. * resources/ui-helper.js: (window.UIHelper.callFunctionAndWaitForScrollToFinish): Added. Convenience function that invokes the specified function and returns a Promise that is resolved once the page has finished scrolling. To know if the page has finished scrolling we listen for DOM scroll events and repeatedly reset a 300ms timer. The delay of 300ms was chosen to be > 250ms (to give some margin of error), which is the upper bound delay between scroll event firings, last I recall. When the timer expires we assume that page has finished scrolling. (window.UIHelper): Canonical link: https://commits.webkit.org/212007@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245285 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-14 16:43:51 +00:00
static waitForEvent(target, eventName)
{
return new Promise(resolve => target.addEventListener(eventName, resolve, { once: true }));
}
static callFunctionAndWaitForEvent(functionToCall, target, eventName)
{
[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
return new Promise(async resolve => {
let event;
await Promise.all([
new Promise((eventListenerResolve) => {
target.addEventListener(eventName, (e) => {
event = e;
eventListenerResolve();
}, {once: true});
}),
new Promise(async functionResolve => {
await functionToCall();
functionResolve();
})
]);
resolve(event);
});
}
[iOS] Cannot scroll to beginning of document after scrolling to end of document and vice versa via key commands https://bugs.webkit.org/show_bug.cgi?id=197848 <rdar://problem/49523065> Patch by Daniel Bates <dabates@apple.com> on 2019-05-14 Reviewed by Brent Fulgham. Source/WebKit: Following the fix for <rdar://problem/49523065>, UIKit no longer emits a keyup event for a Command- modified key. This breaks WebKit's own implementation of key command handling for scrolling to the beginning or end of the document (triggered using Command + Arrow Up and Command + Arrow Down, respectively) because it watches for keyup events to reset state after initiating a scroll. If state is not reset then the scroll key command logic becomes confused and may not perform a subsequent scroll. It seems like we can actually get away with supporting these key commands and future Command modified commands by preemptively reseting state on keydown if the Command modifier is held down. If this does not work out then we can do something more complicated. * UIProcess/ios/WKKeyboardScrollingAnimator.mm: (-[WKKeyboardScrollingAnimator handleKeyEvent:]): LayoutTests: Add a test to ensure that key commands can be used to scroll to the end of the page and then to the beginning of the page. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document-expected.txt: Added. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document.html: Added. * resources/ui-helper.js: (window.UIHelper.callFunctionAndWaitForScrollToFinish): Added. Convenience function that invokes the specified function and returns a Promise that is resolved once the page has finished scrolling. To know if the page has finished scrolling we listen for DOM scroll events and repeatedly reset a 300ms timer. The delay of 300ms was chosen to be > 250ms (to give some margin of error), which is the upper bound delay between scroll event firings, last I recall. When the timer expires we assume that page has finished scrolling. (window.UIHelper): Canonical link: https://commits.webkit.org/212007@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245285 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-14 16:43:51 +00:00
static callFunctionAndWaitForScrollToFinish(functionToCall, ...theArguments)
{
return UIHelper.callFunctionAndWaitForTargetScrollToFinish(window, functionToCall, theArguments)
}
static callFunctionAndWaitForTargetScrollToFinish(scrollTarget, functionToCall, ...theArguments)
[iOS] Cannot scroll to beginning of document after scrolling to end of document and vice versa via key commands https://bugs.webkit.org/show_bug.cgi?id=197848 <rdar://problem/49523065> Patch by Daniel Bates <dabates@apple.com> on 2019-05-14 Reviewed by Brent Fulgham. Source/WebKit: Following the fix for <rdar://problem/49523065>, UIKit no longer emits a keyup event for a Command- modified key. This breaks WebKit's own implementation of key command handling for scrolling to the beginning or end of the document (triggered using Command + Arrow Up and Command + Arrow Down, respectively) because it watches for keyup events to reset state after initiating a scroll. If state is not reset then the scroll key command logic becomes confused and may not perform a subsequent scroll. It seems like we can actually get away with supporting these key commands and future Command modified commands by preemptively reseting state on keydown if the Command modifier is held down. If this does not work out then we can do something more complicated. * UIProcess/ios/WKKeyboardScrollingAnimator.mm: (-[WKKeyboardScrollingAnimator handleKeyEvent:]): LayoutTests: Add a test to ensure that key commands can be used to scroll to the end of the page and then to the beginning of the page. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document-expected.txt: Added. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document.html: Added. * resources/ui-helper.js: (window.UIHelper.callFunctionAndWaitForScrollToFinish): Added. Convenience function that invokes the specified function and returns a Promise that is resolved once the page has finished scrolling. To know if the page has finished scrolling we listen for DOM scroll events and repeatedly reset a 300ms timer. The delay of 300ms was chosen to be > 250ms (to give some margin of error), which is the upper bound delay between scroll event firings, last I recall. When the timer expires we assume that page has finished scrolling. (window.UIHelper): Canonical link: https://commits.webkit.org/212007@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245285 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-14 16:43:51 +00:00
{
return new Promise((resolved) => {
function scrollDidFinish() {
scrollTarget.removeEventListener("scroll", handleScroll, true);
[iOS] Cannot scroll to beginning of document after scrolling to end of document and vice versa via key commands https://bugs.webkit.org/show_bug.cgi?id=197848 <rdar://problem/49523065> Patch by Daniel Bates <dabates@apple.com> on 2019-05-14 Reviewed by Brent Fulgham. Source/WebKit: Following the fix for <rdar://problem/49523065>, UIKit no longer emits a keyup event for a Command- modified key. This breaks WebKit's own implementation of key command handling for scrolling to the beginning or end of the document (triggered using Command + Arrow Up and Command + Arrow Down, respectively) because it watches for keyup events to reset state after initiating a scroll. If state is not reset then the scroll key command logic becomes confused and may not perform a subsequent scroll. It seems like we can actually get away with supporting these key commands and future Command modified commands by preemptively reseting state on keydown if the Command modifier is held down. If this does not work out then we can do something more complicated. * UIProcess/ios/WKKeyboardScrollingAnimator.mm: (-[WKKeyboardScrollingAnimator handleKeyEvent:]): LayoutTests: Add a test to ensure that key commands can be used to scroll to the end of the page and then to the beginning of the page. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document-expected.txt: Added. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document.html: Added. * resources/ui-helper.js: (window.UIHelper.callFunctionAndWaitForScrollToFinish): Added. Convenience function that invokes the specified function and returns a Promise that is resolved once the page has finished scrolling. To know if the page has finished scrolling we listen for DOM scroll events and repeatedly reset a 300ms timer. The delay of 300ms was chosen to be > 250ms (to give some margin of error), which is the upper bound delay between scroll event firings, last I recall. When the timer expires we assume that page has finished scrolling. (window.UIHelper): Canonical link: https://commits.webkit.org/212007@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245285 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-14 16:43:51 +00:00
resolved();
}
let lastScrollTimerId = 0; // When the timer with this id fires then the page has finished scrolling.
function handleScroll() {
if (lastScrollTimerId) {
window.clearTimeout(lastScrollTimerId);
lastScrollTimerId = 0;
}
lastScrollTimerId = window.setTimeout(scrollDidFinish, 300); // Over 250ms to give some room for error.
}
scrollTarget.addEventListener("scroll", handleScroll, true);
[iOS] Cannot scroll to beginning of document after scrolling to end of document and vice versa via key commands https://bugs.webkit.org/show_bug.cgi?id=197848 <rdar://problem/49523065> Patch by Daniel Bates <dabates@apple.com> on 2019-05-14 Reviewed by Brent Fulgham. Source/WebKit: Following the fix for <rdar://problem/49523065>, UIKit no longer emits a keyup event for a Command- modified key. This breaks WebKit's own implementation of key command handling for scrolling to the beginning or end of the document (triggered using Command + Arrow Up and Command + Arrow Down, respectively) because it watches for keyup events to reset state after initiating a scroll. If state is not reset then the scroll key command logic becomes confused and may not perform a subsequent scroll. It seems like we can actually get away with supporting these key commands and future Command modified commands by preemptively reseting state on keydown if the Command modifier is held down. If this does not work out then we can do something more complicated. * UIProcess/ios/WKKeyboardScrollingAnimator.mm: (-[WKKeyboardScrollingAnimator handleKeyEvent:]): LayoutTests: Add a test to ensure that key commands can be used to scroll to the end of the page and then to the beginning of the page. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document-expected.txt: Added. * fast/scrolling/ios/scroll-to-beginning-and-end-of-document.html: Added. * resources/ui-helper.js: (window.UIHelper.callFunctionAndWaitForScrollToFinish): Added. Convenience function that invokes the specified function and returns a Promise that is resolved once the page has finished scrolling. To know if the page has finished scrolling we listen for DOM scroll events and repeatedly reset a 300ms timer. The delay of 300ms was chosen to be > 250ms (to give some margin of error), which is the upper bound delay between scroll event firings, last I recall. When the timer expires we assume that page has finished scrolling. (window.UIHelper): Canonical link: https://commits.webkit.org/212007@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245285 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-14 16:43:51 +00:00
functionToCall.apply(this, theArguments);
});
}
[iOS] Layout viewport size on google.com increases after rotating to landscape and back https://bugs.webkit.org/show_bug.cgi?id=198062 <rdar://problem/50547895> Reviewed by Maciej Stachowiak. Source/WebKit: During an animated resize (e.g. when rotating the device on iOS), we currently immediately trigger the new shrink-to-fit content size heuristic in the middle of dynamicViewportSizeUpdate, after the new view layout size has been applied to the viewport configuration but before we've issued a resize event to the page. Thus, on pages that use listen to the resize event and adjust their content accordingly to fit within the new layout width, we prematurely declare that the page has horizontally overflowed, and try to lay out at a larger width and scale down. This causes the page to unnecessarily shrink after rotating to landscale orientation and back. To fix this, we simply move the call to shrink-to-fit-content to the end of the dynamic viewport size update, such that the page has had a chance to adjust to the new layout size. Test: fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation.html * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::dynamicViewportSizeUpdate): LayoutTests: Add a UIHelper method to simulate device rotation to a given orientation, and use it in a new layout test that simulates rotation to and from landscape orientation, and verifies that the initial scale did not change from its expected value of 1. * fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation-expected.txt: Added. * fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation.html: Added. * resources/ui-helper.js: (window.UIHelper.rotateDevice.return.new.Promise.): (window.UIHelper.rotateDevice): (window.UIHelper): Canonical link: https://commits.webkit.org/212154@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245561 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-21 05:01:54 +00:00
[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
static waitForTargetScrollAnimationToSettle(scrollTarget)
{
return new Promise((resolved) => {
let lastObservedScrollPosition = [scrollTarget.scrollLeft, scrollTarget.scrollTop];
let frameOfLastChange = 0;
let totalFrames = 0;
function animationFrame() {
if (lastObservedScrollPosition[0] != scrollTarget.scrollLeft ||
lastObservedScrollPosition[1] != scrollTarget.scrollTop) {
lastObservedScrollPosition = [scrollTarget.scrollLeft, scrollTarget.scrollTop];
frameOfLastChange = totalFrames;
}
// If we have gone 20 frames without changing, resolve. If we have gone 500, then time out.
// This matches the amount of frames used in the WPT scroll animation helper.
if (totalFrames - frameOfLastChange >= 20 || totalFrames > 500)
resolved();
totalFrames++;
requestAnimationFrame(animationFrame);
}
requestAnimationFrame(animationFrame);
});
}
[iOS] Layout viewport size on google.com increases after rotating to landscape and back https://bugs.webkit.org/show_bug.cgi?id=198062 <rdar://problem/50547895> Reviewed by Maciej Stachowiak. Source/WebKit: During an animated resize (e.g. when rotating the device on iOS), we currently immediately trigger the new shrink-to-fit content size heuristic in the middle of dynamicViewportSizeUpdate, after the new view layout size has been applied to the viewport configuration but before we've issued a resize event to the page. Thus, on pages that use listen to the resize event and adjust their content accordingly to fit within the new layout width, we prematurely declare that the page has horizontally overflowed, and try to lay out at a larger width and scale down. This causes the page to unnecessarily shrink after rotating to landscale orientation and back. To fix this, we simply move the call to shrink-to-fit-content to the end of the dynamic viewport size update, such that the page has had a chance to adjust to the new layout size. Test: fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation.html * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::dynamicViewportSizeUpdate): LayoutTests: Add a UIHelper method to simulate device rotation to a given orientation, and use it in a new layout test that simulates rotation to and from landscape orientation, and verifies that the initial scale did not change from its expected value of 1. * fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation-expected.txt: Added. * fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation.html: Added. * resources/ui-helper.js: (window.UIHelper.rotateDevice.return.new.Promise.): (window.UIHelper.rotateDevice): (window.UIHelper): Canonical link: https://commits.webkit.org/212154@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245561 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-21 05:01:54 +00:00
static rotateDevice(orientationName, animatedResize = false)
{
Make tests that use UIHelper more robust under certain configurations https://bugs.webkit.org/show_bug.cgi?id=198442 <rdar://problem/51301737> Reviewed by Megan Gardner. Tools: For a certain device class, many tests that attempt to use UIHelper.isIOS are currently failing. We can fix this by making the `isIOS` check more robust; this patch also renames `isIOS` to `isIOSFamily`, which is more accurate (and consistent with the corresponding PLATFORM macro name). * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: * WebKitTestRunner/InjectedBundle/TestRunner.h: (WTR::TestRunner::isIOSFamily const): LayoutTests: Replace usages of `UIHelper.isIOS` with `UIHelper.isIOSFamily`. * fast/dom/iframe-inner-size-scaling.html: * fast/forms/datalist/datalist-show-hide.html: * fast/forms/datalist/datalist-textinput-suggestions-order.html: * fast/scrolling/ios/reveal-focused-element-right-above-keyboard-on-ipad.html: Also remove a workaround here that forces `isIOS` to return `true`. * resources/ui-helper.js: (window.UIHelper.isIOSFamily): (window.UIHelper.isWebKit2): (window.UIHelper.humanSpeedDoubleTapAt): (window.UIHelper.humanSpeedZoomByDoubleTappingAt): (window.UIHelper.zoomByDoubleTappingAt): (window.UIHelper.async.doubleActivateAt): (window.UIHelper.async.doubleActivateAtSelectionStart): (window.UIHelper.async.selectWordByDoubleTapOrClick): (window.UIHelper.keyDown): (window.UIHelper.deactivateFormControl): (window.UIHelper.typeCharacter): (window.UIHelper.inputViewBounds): (window.UIHelper.contentOffset): (window.UIHelper.isIOS): Deleted. Canonical link: https://commits.webkit.org/212473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-06-01 00:43:56 +00:00
if (!this.isWebKit2() || !this.isIOSFamily())
[iOS] Layout viewport size on google.com increases after rotating to landscape and back https://bugs.webkit.org/show_bug.cgi?id=198062 <rdar://problem/50547895> Reviewed by Maciej Stachowiak. Source/WebKit: During an animated resize (e.g. when rotating the device on iOS), we currently immediately trigger the new shrink-to-fit content size heuristic in the middle of dynamicViewportSizeUpdate, after the new view layout size has been applied to the viewport configuration but before we've issued a resize event to the page. Thus, on pages that use listen to the resize event and adjust their content accordingly to fit within the new layout width, we prematurely declare that the page has horizontally overflowed, and try to lay out at a larger width and scale down. This causes the page to unnecessarily shrink after rotating to landscale orientation and back. To fix this, we simply move the call to shrink-to-fit-content to the end of the dynamic viewport size update, such that the page has had a chance to adjust to the new layout size. Test: fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation.html * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::dynamicViewportSizeUpdate): LayoutTests: Add a UIHelper method to simulate device rotation to a given orientation, and use it in a new layout test that simulates rotation to and from landscape orientation, and verifies that the initial scale did not change from its expected value of 1. * fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation-expected.txt: Added. * fast/events/ios/rotation/do-not-shrink-to-fit-content-after-rotation.html: Added. * resources/ui-helper.js: (window.UIHelper.rotateDevice.return.new.Promise.): (window.UIHelper.rotateDevice): (window.UIHelper): Canonical link: https://commits.webkit.org/212154@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245561 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-05-21 05:01:54 +00:00
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.${animatedResize ? "simulateRotationLikeSafari" : "simulateRotation"}("${orientationName}", function() {
uiController.doAfterVisibleContentRectUpdate(() => uiController.uiScriptComplete());
});
})()`, resolve);
});
}
[iOS WK2] A top fixed bar can flicker when scrolling with the keyboard up https://bugs.webkit.org/show_bug.cgi?id=200105 rdar://problem/52871975 Reviewed by Wenson Hsieh. Source/WebCore: ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition() computes a visual viewport from the current scroll position and scrollableAreaSize(). This doesn't know anything about the impact of keyboards on the visual viewport, so it computes a too-large visual viewport when the keyboard is up, triggering incorrect manipulations of the layout viewport. This leads to the top bar flashing to position 0 when it should be hidden off the top. Fix by feeding into the scrolling tree the height of the visual viewport which takes FrameView::visualViewportOverrideRect() into account. This is stored on ScrollingStateFrameScrollingNode/ ScrollingTreeFrameScrollingNode. Test: scrollingcoordinator/ios/fixed-scrolling-with-keyboard.html * page/FrameView.h: * page/scrolling/AsyncScrollingCoordinator.cpp: (WebCore::AsyncScrollingCoordinator::setFrameScrollingNodeState): * page/scrolling/ScrollingStateFrameScrollingNode.cpp: (WebCore::ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode): (WebCore::ScrollingStateFrameScrollingNode::setPropertyChangedBitsAfterReattach): (WebCore::ScrollingStateFrameScrollingNode::setOverrideVisualViewportSize): (WebCore::ScrollingStateFrameScrollingNode::dumpProperties const): * page/scrolling/ScrollingStateFrameScrollingNode.h: * page/scrolling/ScrollingTree.cpp: (WebCore::ScrollingTree::commitTreeState): LOG_WITH_STREAM() doesn't evaluate scrollingTreeAsText() every time. * page/scrolling/ScrollingTreeFrameScrollingNode.cpp: (WebCore::ScrollingTreeFrameScrollingNode::commitStateBeforeChildren): (WebCore::ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition const): (WebCore::ScrollingTreeFrameScrollingNode::dumpProperties const): * page/scrolling/ScrollingTreeFrameScrollingNode.h: Source/WebKit: ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition() computes a visual viewport from the current scroll position and scrollableAreaSize(). This doesn't know anything about the impact of keyboards on the visual viewport, so it computes a too-large visual viewport when the keyboard is up, triggering incorrect manipulations of the layout viewport. This leads to the top bar flashing to position 0 when it should be hidden off the top. Fix by feeding into the scrolling tree the height of the visual viewport which takes FrameView::visualViewportOverrideRect() into account. This is stored on ScrollingStateFrameScrollingNode/ ScrollingTreeFrameScrollingNode. * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp: (ArgumentCoder<ScrollingStateFrameScrollingNode>::encode): (ArgumentCoder<ScrollingStateFrameScrollingNode>::decode): LayoutTests: * resources/ui-helper.js: (window.UIHelper.ensureStablePresentationUpdate.return.new.Promise): (window.UIHelper.ensureStablePresentationUpdate): * scrollingcoordinator/ios/fixed-scrolling-with-keyboard-expected.txt: Added. * scrollingcoordinator/ios/fixed-scrolling-with-keyboard.html: Added. Canonical link: https://commits.webkit.org/213962@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247839 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-07-25 21:12:01 +00:00
static getScrollingTree()
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
return uiController.scrollingTreeAsText;
})()`, resolve);
});
}
[iOS 13] Taps that interrupt momentum scrolling are recognized as clicks https://bugs.webkit.org/show_bug.cgi?id=200516 <rdar://problem/53889373> Reviewed by Tim Horton. Source/WebKit: After <https://trac.webkit.org/r247656>, the -tracksImmediatelyWhileDecelerating property of WKScrollView and WKChildScrollView is set to NO. This means that if a user interacts with the page while the scroll view is decelerating (e.g. after momentum scrolling), the pan gesture recognizer will not be immediately recognized. This gives other gesture recognizers, such as the synthetic click (single tap) gesture a chance to instead recognize first. In this particular bug, this causes taps on the web view that are intended to only stop momentum scrolling to instead activate clickable elements beneath the touch, such as links and buttons. To mitigate this, we add some logic to prevent the click gesture recognizer from firing in the case where the tap also causes the scroll view to decelerate. This heuristic is similar to the one introduced in r219310, which has the same purpose of hiding gestures that stop momentum scrolling from the page, and also consults -[UIScrollView _isInterruptingDeceleration]. Tests: fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame.html fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body.html fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView gestureRecognizerShouldBegin:]): Return NO in the case of the single tap gesture if the UIScrollView most recently touched by the single tap gesture (or one of its enclosing scroll views, up to the main WKScrollView) is being interrupted while decelerating. * UIProcess/ios/WKSyntheticTapGestureRecognizer.h: * UIProcess/ios/WKSyntheticTapGestureRecognizer.mm: (-[WKSyntheticTapGestureRecognizer reset]): (-[WKSyntheticTapGestureRecognizer touchesBegan:withEvent:]): Teach WKSyntheticTapGestureRecognizer to keep track of the last WKScrollView that was touched, for later use in -gestureRecognizerShouldBegin:. To do this, we keep a weak reference to the first UIScrollView we find in the set of touches. (-[WKSyntheticTapGestureRecognizer lastTouchedScrollView]): LayoutTests: Add new layout tests. See below for details. * fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame.html: Added. Add a test to verify that interrupting scrolling in the main frame using a tap doesn't fire a click event. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body.html: Added. Add a test to verify that after triggering momentum scrolling in a fast subscrollable region, tapping outside of the scroller will still fire a click event. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow.html: Added. Add a test to verify that interrupting scrolling in a fast subscrollable region using a tap doesn't fire a click event. * resources/ui-helper.js: (window.UIHelper.dragFromPointToPoint): (window.UIHelper): Canonical link: https://commits.webkit.org/214316@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248433 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-08 18:54:06 +00:00
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
static getUIViewTree()
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
return uiController.uiViewTreeAsText;
})()`, resolve);
});
}
[iOS 13] Taps that interrupt momentum scrolling are recognized as clicks https://bugs.webkit.org/show_bug.cgi?id=200516 <rdar://problem/53889373> Reviewed by Tim Horton. Source/WebKit: After <https://trac.webkit.org/r247656>, the -tracksImmediatelyWhileDecelerating property of WKScrollView and WKChildScrollView is set to NO. This means that if a user interacts with the page while the scroll view is decelerating (e.g. after momentum scrolling), the pan gesture recognizer will not be immediately recognized. This gives other gesture recognizers, such as the synthetic click (single tap) gesture a chance to instead recognize first. In this particular bug, this causes taps on the web view that are intended to only stop momentum scrolling to instead activate clickable elements beneath the touch, such as links and buttons. To mitigate this, we add some logic to prevent the click gesture recognizer from firing in the case where the tap also causes the scroll view to decelerate. This heuristic is similar to the one introduced in r219310, which has the same purpose of hiding gestures that stop momentum scrolling from the page, and also consults -[UIScrollView _isInterruptingDeceleration]. Tests: fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame.html fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body.html fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView gestureRecognizerShouldBegin:]): Return NO in the case of the single tap gesture if the UIScrollView most recently touched by the single tap gesture (or one of its enclosing scroll views, up to the main WKScrollView) is being interrupted while decelerating. * UIProcess/ios/WKSyntheticTapGestureRecognizer.h: * UIProcess/ios/WKSyntheticTapGestureRecognizer.mm: (-[WKSyntheticTapGestureRecognizer reset]): (-[WKSyntheticTapGestureRecognizer touchesBegan:withEvent:]): Teach WKSyntheticTapGestureRecognizer to keep track of the last WKScrollView that was touched, for later use in -gestureRecognizerShouldBegin:. To do this, we keep a weak reference to the first UIScrollView we find in the set of touches. (-[WKSyntheticTapGestureRecognizer lastTouchedScrollView]): LayoutTests: Add new layout tests. See below for details. * fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame.html: Added. Add a test to verify that interrupting scrolling in the main frame using a tap doesn't fire a click event. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body.html: Added. Add a test to verify that after triggering momentum scrolling in a fast subscrollable region, tapping outside of the scroller will still fire a click event. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow.html: Added. Add a test to verify that interrupting scrolling in a fast subscrollable region using a tap doesn't fire a click event. * resources/ui-helper.js: (window.UIHelper.dragFromPointToPoint): (window.UIHelper): Canonical link: https://commits.webkit.org/214316@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248433 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-08 18:54:06 +00:00
static dragFromPointToPoint(fromX, fromY, toX, toY, duration)
{
if (!this.isWebKit2() || !this.isIOSFamily()) {
eventSender.mouseMoveTo(fromX, fromY);
eventSender.mouseDown();
eventSender.leapForward(duration * 1000);
eventSender.mouseMoveTo(toX, toY);
eventSender.mouseUp();
return Promise.resolve();
}
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.dragFromPointToPoint(${fromX}, ${fromY}, ${toX}, ${toY}, ${duration}, () => {
uiController.uiScriptComplete();
[iOS 13] Taps that interrupt momentum scrolling are recognized as clicks https://bugs.webkit.org/show_bug.cgi?id=200516 <rdar://problem/53889373> Reviewed by Tim Horton. Source/WebKit: After <https://trac.webkit.org/r247656>, the -tracksImmediatelyWhileDecelerating property of WKScrollView and WKChildScrollView is set to NO. This means that if a user interacts with the page while the scroll view is decelerating (e.g. after momentum scrolling), the pan gesture recognizer will not be immediately recognized. This gives other gesture recognizers, such as the synthetic click (single tap) gesture a chance to instead recognize first. In this particular bug, this causes taps on the web view that are intended to only stop momentum scrolling to instead activate clickable elements beneath the touch, such as links and buttons. To mitigate this, we add some logic to prevent the click gesture recognizer from firing in the case where the tap also causes the scroll view to decelerate. This heuristic is similar to the one introduced in r219310, which has the same purpose of hiding gestures that stop momentum scrolling from the page, and also consults -[UIScrollView _isInterruptingDeceleration]. Tests: fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame.html fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body.html fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView gestureRecognizerShouldBegin:]): Return NO in the case of the single tap gesture if the UIScrollView most recently touched by the single tap gesture (or one of its enclosing scroll views, up to the main WKScrollView) is being interrupted while decelerating. * UIProcess/ios/WKSyntheticTapGestureRecognizer.h: * UIProcess/ios/WKSyntheticTapGestureRecognizer.mm: (-[WKSyntheticTapGestureRecognizer reset]): (-[WKSyntheticTapGestureRecognizer touchesBegan:withEvent:]): Teach WKSyntheticTapGestureRecognizer to keep track of the last WKScrollView that was touched, for later use in -gestureRecognizerShouldBegin:. To do this, we keep a weak reference to the first UIScrollView we find in the set of touches. (-[WKSyntheticTapGestureRecognizer lastTouchedScrollView]): LayoutTests: Add new layout tests. See below for details. * fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-main-frame.html: Added. Add a test to verify that interrupting scrolling in the main frame using a tap doesn't fire a click event. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body.html: Added. Add a test to verify that after triggering momentum scrolling in a fast subscrollable region, tapping outside of the scroller will still fire a click event. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-expected.txt: Added. * fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow.html: Added. Add a test to verify that interrupting scrolling in a fast subscrollable region using a tap doesn't fire a click event. * resources/ui-helper.js: (window.UIHelper.dragFromPointToPoint): (window.UIHelper): Canonical link: https://commits.webkit.org/214316@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248433 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-08 18:54:06 +00:00
});
})();`, resolve);
});
}
Remove UIHelper.activateElementAtHumanSpeed https://bugs.webkit.org/show_bug.cgi?id=201147 Reviewed by Tim Horton. Tools: Add plumbing for a new script controller hook to wait for the double tap delay to pass. On non-iOS, this resolves immediately; on iOS, we inspect the content view for tap gestures that require more than one tap, and find the value of the maximum double tap delay. We then delay for this amount of time before resolving. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::doAfterDoubleTapDelay): * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::doAfterDoubleTapDelay): LayoutTests: This was used in layout tests that simulate repeated taps to work around <webkit.org/b/201129>, and should no longer be needed after <https://trac.webkit.org/changeset/249112/webkit>. Instead, we can just use UIHelper's activateElement as intended in cases where successive taps in the test does not result in a double-click; for the cases where we need to avoid triggering double clicks when tapping (e.g. in several payment tests), use a new script controller hook to wait for the double tap gesture delay before continuing. * fast/forms/ios/file-upload-panel.html: * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Rebaseline more line numbers. * http/tests/adClickAttribution/anchor-tag-attributes-validation.html: Refactor this test so that the links are laid out in two (or more) columns to avoid firing the double click gesture recognizer instead of the synthetic click gesture. * http/tests/resources/payment-request.js: (activateThen): Instead of using activateElementAtHumanSpeed, wait for the platform double tap delay first, and then simulate a click using activateElement. * resources/ui-helper.js: (window.UIHelper.waitForDoubleTapDelay): Add a new UIHelper method to wait for the platform double tap delay. See Tools ChangeLog for more details. (window.UIHelper): (window.UIHelper.activateElementAtHumanSpeed.return.new.Promise): Deleted. (window.UIHelper.activateElementAtHumanSpeed): Deleted. Canonical link: https://commits.webkit.org/214846@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249125 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-27 00:18:57 +00:00
[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
static setWindowIsKey(isKey)
{
const script = `uiController.windowIsKey = ${isKey}`;
return new Promise(resolve => testRunner.runUIScript(script, resolve));
}
static windowIsKey()
{
const script = "uiController.uiScriptComplete(uiController.windowIsKey)";
return new Promise(resolve => testRunner.runUIScript(script, (result) => {
resolve(result === "true");
}));
}
Remove UIHelper.activateElementAtHumanSpeed https://bugs.webkit.org/show_bug.cgi?id=201147 Reviewed by Tim Horton. Tools: Add plumbing for a new script controller hook to wait for the double tap delay to pass. On non-iOS, this resolves immediately; on iOS, we inspect the content view for tap gestures that require more than one tap, and find the value of the maximum double tap delay. We then delay for this amount of time before resolving. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::doAfterDoubleTapDelay): * WebKitTestRunner/ios/UIScriptControllerIOS.h: * WebKitTestRunner/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::doAfterDoubleTapDelay): LayoutTests: This was used in layout tests that simulate repeated taps to work around <webkit.org/b/201129>, and should no longer be needed after <https://trac.webkit.org/changeset/249112/webkit>. Instead, we can just use UIHelper's activateElement as intended in cases where successive taps in the test does not result in a double-click; for the cases where we need to avoid triggering double clicks when tapping (e.g. in several payment tests), use a new script controller hook to wait for the double tap gesture delay before continuing. * fast/forms/ios/file-upload-panel.html: * http/tests/adClickAttribution/anchor-tag-attributes-validation-expected.txt: Rebaseline more line numbers. * http/tests/adClickAttribution/anchor-tag-attributes-validation.html: Refactor this test so that the links are laid out in two (or more) columns to avoid firing the double click gesture recognizer instead of the synthetic click gesture. * http/tests/resources/payment-request.js: (activateThen): Instead of using activateElementAtHumanSpeed, wait for the platform double tap delay first, and then simulate a click using activateElement. * resources/ui-helper.js: (window.UIHelper.waitForDoubleTapDelay): Add a new UIHelper method to wait for the platform double tap delay. See Tools ChangeLog for more details. (window.UIHelper): (window.UIHelper.activateElementAtHumanSpeed.return.new.Promise): Deleted. (window.UIHelper.activateElementAtHumanSpeed): Deleted. Canonical link: https://commits.webkit.org/214846@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249125 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-08-27 00:18:57 +00:00
static waitForDoubleTapDelay()
{
const uiScript = `uiController.doAfterDoubleTapDelay(() => uiController.uiScriptComplete(""))`;
return new Promise(resolve => testRunner.runUIScript(uiScript, resolve));
}
[iOS 13] Tapping on a non-editable text selection should toggle callout bar visibility instead of clearing selection https://bugs.webkit.org/show_bug.cgi?id=202254 <rdar://problem/54410263> Reviewed by Megan Gardner. Source/WebKit: In iOS 13, tapping a text selection should toggle callout bar visibility (i.e. "selection commands" in UIKit). This currently does not work for non-editable text, since the synthetic click gesture simultaneously fires alongside the text interaction assistant's non-editable tap gesture, which dispatches a click to the page which then clears the selection. To remedy this and match platform behavior, we avoid recognizing clicks that occur over the text selection, but only in the case where the bounding rect of the text selection doesn't cover a large portion of the visible content rect of the web view. This ensures that the user doesn't get stuck in a state where it's impossible to dismiss a very large text selection (e.g. after selecting all the content on the page). Tests: editing/selection/ios/clear-selection-after-tap-in-large-selected-non-editable-text.html editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _shouldToggleSelectionCommandsAfterTapAt:]): Check the last known selection rects (on _lastSelectionDrawingInfo) to see if the tapped point lies within at least one of the selection rects. (-[WKContentView gestureRecognizerShouldBegin:]): LayoutTests: * editing/selection/ios/clear-selection-after-tap-in-large-selected-non-editable-text-expected.txt: Added. * editing/selection/ios/clear-selection-after-tap-in-large-selected-non-editable-text.html: Added. Add a new layout test to verify that when tapping in a text selection that encompasses the entire page, we allow the tap to dismiss the selection instead of toggling callout bar visibility. * editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text-expected.txt: Added. * editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text.html: Added. Add another layout test to verify that when tapping inside a text selection, the callout bar is toggled, and when tapping outside the selected text, the selection is dismissed. * resources/ui-helper.js: (window.UIHelper.async.waitForSelectionToAppear): (window.UIHelper.async.waitForSelectionToDisappear): New helper methods to wait for selection rects to appear or disappear. (window.UIHelper): Canonical link: https://commits.webkit.org/215825@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250392 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-09-26 19:03:47 +00:00
static async waitForSelectionToAppear() {
while (true) {
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
let selectionRects = await this.getUISelectionViewRects();
if (selectionRects.length > 0)
return selectionRects;
[iOS 13] Tapping on a non-editable text selection should toggle callout bar visibility instead of clearing selection https://bugs.webkit.org/show_bug.cgi?id=202254 <rdar://problem/54410263> Reviewed by Megan Gardner. Source/WebKit: In iOS 13, tapping a text selection should toggle callout bar visibility (i.e. "selection commands" in UIKit). This currently does not work for non-editable text, since the synthetic click gesture simultaneously fires alongside the text interaction assistant's non-editable tap gesture, which dispatches a click to the page which then clears the selection. To remedy this and match platform behavior, we avoid recognizing clicks that occur over the text selection, but only in the case where the bounding rect of the text selection doesn't cover a large portion of the visible content rect of the web view. This ensures that the user doesn't get stuck in a state where it's impossible to dismiss a very large text selection (e.g. after selecting all the content on the page). Tests: editing/selection/ios/clear-selection-after-tap-in-large-selected-non-editable-text.html editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text.html * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _shouldToggleSelectionCommandsAfterTapAt:]): Check the last known selection rects (on _lastSelectionDrawingInfo) to see if the tapped point lies within at least one of the selection rects. (-[WKContentView gestureRecognizerShouldBegin:]): LayoutTests: * editing/selection/ios/clear-selection-after-tap-in-large-selected-non-editable-text-expected.txt: Added. * editing/selection/ios/clear-selection-after-tap-in-large-selected-non-editable-text.html: Added. Add a new layout test to verify that when tapping in a text selection that encompasses the entire page, we allow the tap to dismiss the selection instead of toggling callout bar visibility. * editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text-expected.txt: Added. * editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text.html: Added. Add another layout test to verify that when tapping inside a text selection, the callout bar is toggled, and when tapping outside the selected text, the selection is dismissed. * resources/ui-helper.js: (window.UIHelper.async.waitForSelectionToAppear): (window.UIHelper.async.waitForSelectionToDisappear): New helper methods to wait for selection rects to appear or disappear. (window.UIHelper): Canonical link: https://commits.webkit.org/215825@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250392 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-09-26 19:03:47 +00:00
}
}
static async waitForSelectionToDisappear() {
while (true) {
if (!(await this.getUISelectionViewRects()).length)
break;
}
}
[Clipboard API] Implement ClipboardItem.getType() for platform clipboard items https://bugs.webkit.org/show_bug.cgi?id=203168 Reviewed by Tim Horton. Source/WebCore: This patch completes support for ClipboardItem.getType(). Tests: editing/async-clipboard/clipboard-change-data-while-getting-type.html editing/async-clipboard/clipboard-get-type-with-old-items.html editing/async-clipboard/clipboard-item-get-type-basic.html ClipboardTests.ReadMultipleItems * Modules/async-clipboard/Clipboard.cpp: (WebCore::Clipboard::getType): Implement getType(). If the given clipboard item is being tracked as one of the active clipboard items, then allow it to read data from the platform pasteboard. We use existing pasteboard reading methods and classes (PasteboardPlainText and WebContentMarkupReader) to ask the platform pasteboard for text and markup data, respectively, and go through readURL() for "text/uri-list". Before exposing any data to the page, we additionally check that the change count of the pasteboard is still what we started with when setting up the current session. If this is not the case, we reject the promise and immediately clear out the session. (WebCore::Clipboard::activePasteboard): * Modules/async-clipboard/Clipboard.h: * dom/DataTransfer.h: Drive-by tweak: make the WebContentReadingPolicy enum class narrower. * platform/Pasteboard.h: Add an enum flag for allowing or ignoring the platform URL type when reading plain text from the platform pasteboard. We use this in Clipboard::getType() to ignore URLs on the platform pasteboard when plain text, since the plain text reader would otherwise prefer URLs over plain text by default, and read the URL type instead of the plain text type. * platform/StaticPasteboard.h: * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::read): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::read): * platform/libwpe/PasteboardLibWPE.cpp: (WebCore::Pasteboard::read): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::read): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::read): Tools: Add support for the new layout tests, as well as a new API test. * DumpRenderTree/ios/UIScriptControllerIOS.h: * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::copyText): Implement UIScriptController.copyText in WebKit1. This is used in one of the new layout tests, which passes in WebKit1 on macOS and iOS. * DumpRenderTree/mac/DumpRenderTreePasteboard.mm: (-[LocalPasteboard declareTypes:owner:]): (-[LocalPasteboard addTypes:owner:]): (-[LocalPasteboard _addTypesWithoutUpdatingChangeCount:owner:]): Adjust logic when declaring types on the platform pasteboard, such that it behaves more like the platform; when declaring types, even if the owner doesn't change, the change count should still get bumped up by 1. * DumpRenderTree/mac/UIScriptControllerMac.h: * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptControllerMac::copyText): * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/ClipboardTests.mm: Added. (-[TestWKWebView readClipboard]): (createWebViewForClipboardTests): (writeMultipleObjectsToPlatformPasteboard): Add a new API test to verify that clipboard items contain the right data when writing multiple items (each with different sets of types) to the platform pasteboard using native APIs. * TestWebKitAPI/Tests/WebKitCocoa/clipboard.html: Added. * WebKitTestRunner/mac/WebKitTestRunnerPasteboard.mm: (-[LocalPasteboard declareTypes:owner:]): (-[LocalPasteboard addTypes:owner:]): (-[LocalPasteboard _addTypesWithoutUpdatingChangeCount:owner:]): LayoutTests: Add 3 new layout tests. * editing/async-clipboard/clipboard-change-data-while-getting-type-expected.txt: Added. * editing/async-clipboard/clipboard-change-data-while-getting-type.html: Added. Add a layout test to verify that if the pasteboard changes right after the page has obtained clipboard items, the page should not be able to fetch the new contents of the pasteboard using these clipboard items. * editing/async-clipboard/clipboard-get-type-with-old-items.html: Added. * editing/async-clipboard/clipboard-get-type-with-old-items-expected.txt: Added. Add a layout test to verify that after attempting to get data from invalid (stale) items, the page is still capable of reading data from valid clipboard items. * editing/async-clipboard/clipboard-item-get-type-basic-expected.txt: Added. * editing/async-clipboard/clipboard-item-get-type-basic.html: Added. Add a layout test to verify that after writing multiple types to the clipboard using the DataTransfer API, we should be able to read them back using the async clipboard API, as a single ClipboardItem, and also get data out of the clipboard item using ClipboardItem.getType. * editing/async-clipboard/resources/async-clipboard-helpers.js: * platform/win/TestExpectations: * resources/ui-helper.js: (window.UIHelper.async.copyText): (window.UIHelper): Canonical link: https://commits.webkit.org/216615@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251377 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-21 20:19:53 +00:00
static async copyText(text) {
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
const copyTextScript = `uiController.copyText(\`${text.replace(/`/g, "\\`")}\`)`;
[Clipboard API] Implement ClipboardItem.getType() for platform clipboard items https://bugs.webkit.org/show_bug.cgi?id=203168 Reviewed by Tim Horton. Source/WebCore: This patch completes support for ClipboardItem.getType(). Tests: editing/async-clipboard/clipboard-change-data-while-getting-type.html editing/async-clipboard/clipboard-get-type-with-old-items.html editing/async-clipboard/clipboard-item-get-type-basic.html ClipboardTests.ReadMultipleItems * Modules/async-clipboard/Clipboard.cpp: (WebCore::Clipboard::getType): Implement getType(). If the given clipboard item is being tracked as one of the active clipboard items, then allow it to read data from the platform pasteboard. We use existing pasteboard reading methods and classes (PasteboardPlainText and WebContentMarkupReader) to ask the platform pasteboard for text and markup data, respectively, and go through readURL() for "text/uri-list". Before exposing any data to the page, we additionally check that the change count of the pasteboard is still what we started with when setting up the current session. If this is not the case, we reject the promise and immediately clear out the session. (WebCore::Clipboard::activePasteboard): * Modules/async-clipboard/Clipboard.h: * dom/DataTransfer.h: Drive-by tweak: make the WebContentReadingPolicy enum class narrower. * platform/Pasteboard.h: Add an enum flag for allowing or ignoring the platform URL type when reading plain text from the platform pasteboard. We use this in Clipboard::getType() to ignore URLs on the platform pasteboard when plain text, since the plain text reader would otherwise prefer URLs over plain text by default, and read the URL type instead of the plain text type. * platform/StaticPasteboard.h: * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::read): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::read): * platform/libwpe/PasteboardLibWPE.cpp: (WebCore::Pasteboard::read): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::read): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::read): Tools: Add support for the new layout tests, as well as a new API test. * DumpRenderTree/ios/UIScriptControllerIOS.h: * DumpRenderTree/ios/UIScriptControllerIOS.mm: (WTR::UIScriptControllerIOS::copyText): Implement UIScriptController.copyText in WebKit1. This is used in one of the new layout tests, which passes in WebKit1 on macOS and iOS. * DumpRenderTree/mac/DumpRenderTreePasteboard.mm: (-[LocalPasteboard declareTypes:owner:]): (-[LocalPasteboard addTypes:owner:]): (-[LocalPasteboard _addTypesWithoutUpdatingChangeCount:owner:]): Adjust logic when declaring types on the platform pasteboard, such that it behaves more like the platform; when declaring types, even if the owner doesn't change, the change count should still get bumped up by 1. * DumpRenderTree/mac/UIScriptControllerMac.h: * DumpRenderTree/mac/UIScriptControllerMac.mm: (WTR::UIScriptControllerMac::copyText): * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/ClipboardTests.mm: Added. (-[TestWKWebView readClipboard]): (createWebViewForClipboardTests): (writeMultipleObjectsToPlatformPasteboard): Add a new API test to verify that clipboard items contain the right data when writing multiple items (each with different sets of types) to the platform pasteboard using native APIs. * TestWebKitAPI/Tests/WebKitCocoa/clipboard.html: Added. * WebKitTestRunner/mac/WebKitTestRunnerPasteboard.mm: (-[LocalPasteboard declareTypes:owner:]): (-[LocalPasteboard addTypes:owner:]): (-[LocalPasteboard _addTypesWithoutUpdatingChangeCount:owner:]): LayoutTests: Add 3 new layout tests. * editing/async-clipboard/clipboard-change-data-while-getting-type-expected.txt: Added. * editing/async-clipboard/clipboard-change-data-while-getting-type.html: Added. Add a layout test to verify that if the pasteboard changes right after the page has obtained clipboard items, the page should not be able to fetch the new contents of the pasteboard using these clipboard items. * editing/async-clipboard/clipboard-get-type-with-old-items.html: Added. * editing/async-clipboard/clipboard-get-type-with-old-items-expected.txt: Added. Add a layout test to verify that after attempting to get data from invalid (stale) items, the page is still capable of reading data from valid clipboard items. * editing/async-clipboard/clipboard-item-get-type-basic-expected.txt: Added. * editing/async-clipboard/clipboard-item-get-type-basic.html: Added. Add a layout test to verify that after writing multiple types to the clipboard using the DataTransfer API, we should be able to read them back using the async clipboard API, as a single ClipboardItem, and also get data out of the clipboard item using ClipboardItem.getType. * editing/async-clipboard/resources/async-clipboard-helpers.js: * platform/win/TestExpectations: * resources/ui-helper.js: (window.UIHelper.async.copyText): (window.UIHelper): Canonical link: https://commits.webkit.org/216615@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251377 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-21 20:19:53 +00:00
return new Promise(resolve => testRunner.runUIScript(copyTextScript, resolve));
}
[iOS] WKWebView does not respect system spellchecking preference https://bugs.webkit.org/show_bug.cgi?id=204100 <rdar://problem/56653808> Reviewed by Tim Horton. Source/WebKit: Implements a platform hook on iOS (-setContinuousSpellCheckingEnabled:) to allow UIKit to inform us when the system spellchecking preference changes, and adds logic to propagate these changes to the web process. See below for more details. Test: editing/spelling/toggle-spellchecking.html * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _setContinuousSpellCheckingEnabledForTesting:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add testing SPI to enable or disable continuous spellchecking, for both iOS and macOS. * UIProcess/Cocoa/WebViewImpl.h: * UIProcess/Cocoa/WebViewImpl.mm: (WebKit::WebViewImpl::setContinuousSpellCheckingEnabled): * UIProcess/TextChecker.h: * UIProcess/gtk/TextCheckerGtk.cpp: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/ios/TextCheckerIOS.mm: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView setupInteraction]): (-[WKContentView setContinuousSpellCheckingEnabled:]): Implement this method to handle changes to the system spellchecking preference. This hook is also used by legacy WebKit on iOS to turn spellchecking on or off. If the value of the preference changed, we additionally notify the web process. In the future, we should consider refactoring TextCheckerState to be per-web view and per-page, since Cocoa platform APIs would allow for different WKWebViews to have different spell checking preferences. * UIProcess/mac/TextCheckerMac.mm: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/win/TextCheckerWin.cpp: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/wpe/TextCheckerWPE.cpp: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): Adjusted setContinuousSpellCheckingEnabled to return whether or not the continuous spellchecking state changed. Tools: * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: * DumpRenderTree/cocoa/UIScriptControllerCocoa.h: * DumpRenderTree/cocoa/UIScriptControllerCocoa.mm: (WTR::UIScriptControllerCocoa::UIScriptControllerCocoa): (WTR::UIScriptControllerCocoa::setContinuousSpellCheckingEnabled): Add a new UIScriptControllerCocoa subclass for DumpRenderTree. For now, this will just contain the cross- platform implementation of setContinuousSpellCheckingEnabled. * DumpRenderTree/ios/UIScriptControllerIOS.h: (WTR::UIScriptControllerIOS::UIScriptControllerIOS): * DumpRenderTree/mac/UIScriptControllerMac.h: (WTR::UIScriptControllerMac::UIScriptControllerMac): Make both -IOS and -Mac subclasses inherit from UIScriptControllerCocoa. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::setContinuousSpellCheckingEnabled): Add a new script controller method to change the platform spell checking preference during a layout test. * WebKitTestRunner/TestController.cpp: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::cocoaResetStateToConsistentValues): Adjust this to explicitly turn continuous spellchecking on or off based on the `shouldShowSpellCheckingDots` test option flag, instead of toggling it on and then off when resetting state before and after the layout test. * WebKitTestRunner/cocoa/UIScriptControllerCocoa.h: * WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm: (WTR::UIScriptControllerCocoa::setContinuousSpellCheckingEnabled): LayoutTests: Add a new layout test to verify that the changes to platform spellchecking preferences are reflected in editable content. See other changelogs for more information. * editing/spelling/toggle-spellchecking-expected.txt: Added. * editing/spelling/toggle-spellchecking.html: Added. * platform/win/TestExpectations: * platform/wincairo/TestExpectations: * resources/ui-helper.js: (window.UIHelper.async.setContinuousSpellCheckingEnabled): Also, add a new UIHelper method to enable or disable continuous spellchecking during a layout test. (window.UIHelper): Canonical link: https://commits.webkit.org/217428@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252377 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-11-13 00:07:00 +00:00
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
static async paste() {
return new Promise(resolve => testRunner.runUIScript(`uiController.paste()`, resolve));
}
[iOS] WKWebView does not respect system spellchecking preference https://bugs.webkit.org/show_bug.cgi?id=204100 <rdar://problem/56653808> Reviewed by Tim Horton. Source/WebKit: Implements a platform hook on iOS (-setContinuousSpellCheckingEnabled:) to allow UIKit to inform us when the system spellchecking preference changes, and adds logic to propagate these changes to the web process. See below for more details. Test: editing/spelling/toggle-spellchecking.html * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _setContinuousSpellCheckingEnabledForTesting:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add testing SPI to enable or disable continuous spellchecking, for both iOS and macOS. * UIProcess/Cocoa/WebViewImpl.h: * UIProcess/Cocoa/WebViewImpl.mm: (WebKit::WebViewImpl::setContinuousSpellCheckingEnabled): * UIProcess/TextChecker.h: * UIProcess/gtk/TextCheckerGtk.cpp: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/ios/TextCheckerIOS.mm: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView setupInteraction]): (-[WKContentView setContinuousSpellCheckingEnabled:]): Implement this method to handle changes to the system spellchecking preference. This hook is also used by legacy WebKit on iOS to turn spellchecking on or off. If the value of the preference changed, we additionally notify the web process. In the future, we should consider refactoring TextCheckerState to be per-web view and per-page, since Cocoa platform APIs would allow for different WKWebViews to have different spell checking preferences. * UIProcess/mac/TextCheckerMac.mm: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/win/TextCheckerWin.cpp: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): * UIProcess/wpe/TextCheckerWPE.cpp: (WebKit::TextChecker::setContinuousSpellCheckingEnabled): Adjusted setContinuousSpellCheckingEnabled to return whether or not the continuous spellchecking state changed. Tools: * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj: * DumpRenderTree/cocoa/UIScriptControllerCocoa.h: * DumpRenderTree/cocoa/UIScriptControllerCocoa.mm: (WTR::UIScriptControllerCocoa::UIScriptControllerCocoa): (WTR::UIScriptControllerCocoa::setContinuousSpellCheckingEnabled): Add a new UIScriptControllerCocoa subclass for DumpRenderTree. For now, this will just contain the cross- platform implementation of setContinuousSpellCheckingEnabled. * DumpRenderTree/ios/UIScriptControllerIOS.h: (WTR::UIScriptControllerIOS::UIScriptControllerIOS): * DumpRenderTree/mac/UIScriptControllerMac.h: (WTR::UIScriptControllerMac::UIScriptControllerMac): Make both -IOS and -Mac subclasses inherit from UIScriptControllerCocoa. * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: * TestRunnerShared/UIScriptContext/UIScriptController.h: (WTR::UIScriptController::setContinuousSpellCheckingEnabled): Add a new script controller method to change the platform spell checking preference during a layout test. * WebKitTestRunner/TestController.cpp: * WebKitTestRunner/cocoa/TestControllerCocoa.mm: (WTR::TestController::cocoaResetStateToConsistentValues): Adjust this to explicitly turn continuous spellchecking on or off based on the `shouldShowSpellCheckingDots` test option flag, instead of toggling it on and then off when resetting state before and after the layout test. * WebKitTestRunner/cocoa/UIScriptControllerCocoa.h: * WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm: (WTR::UIScriptControllerCocoa::setContinuousSpellCheckingEnabled): LayoutTests: Add a new layout test to verify that the changes to platform spellchecking preferences are reflected in editable content. See other changelogs for more information. * editing/spelling/toggle-spellchecking-expected.txt: Added. * editing/spelling/toggle-spellchecking.html: Added. * platform/win/TestExpectations: * platform/wincairo/TestExpectations: * resources/ui-helper.js: (window.UIHelper.async.setContinuousSpellCheckingEnabled): Also, add a new UIHelper method to enable or disable continuous spellchecking during a layout test. (window.UIHelper): Canonical link: https://commits.webkit.org/217428@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252377 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-11-13 00:07:00 +00:00
static async setContinuousSpellCheckingEnabled(enabled) {
return new Promise(resolve => {
testRunner.runUIScript(`uiController.setContinuousSpellCheckingEnabled(${enabled})`, resolve);
});
}
[iOS] Two layout tests in editing/selection/ios time out when waiting for selection views to appear https://bugs.webkit.org/show_bug.cgi?id=204231 <rdar://problem/56096961> Reviewed by Megan Gardner. Adjust these layout tests to select text by long pressing, instead of selecting text by tapping a button that programmatically selects a range of text. The latter only results in platform selection views if the user (or, in this case, a previous test in the same web view) has already manually selected text. This isn't guaranteed, given that the previous test may have timed out, or may have different test options which require a new WKWebView to have been created. * editing/selection/ios/clear-selection-after-tap-in-large-selected-non-editable-text.html: * editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text-expected.txt: * editing/selection/ios/toggle-callout-bar-after-tap-in-selected-non-editable-text.html: * resources/ui-helper.js: (window.UIHelper.async.longPressElement): (window.UIHelper.async.longPressAtPoint.return.new.Promise.): (window.UIHelper.async.longPressAtPoint.return.new.Promise): (window.UIHelper.async.longPressAtPoint): Also add helper methods in ui-helper.js to trigger long press gestures, so that we can start moving away from the helper methods in basic-gestures.js. (window.UIHelper): Canonical link: https://commits.webkit.org/217533@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@252496 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-11-15 19:56:09 +00:00
static async longPressElement(element)
{
return this.longPressAtPoint(element.offsetLeft + element.offsetWidth / 2, element.offsetTop + element.offsetHeight / 2);
}
static async longPressAtPoint(x, y)
{
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
uiController.longPressAtPoint(${x}, ${y}, function() {
uiController.uiScriptComplete();
});
})();`, resolve);
});
}
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
[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
static async setSpellCheckerResults(results)
{
return new Promise(resolve => {
testRunner.runUIScript(`(() => {
uiController.setSpellCheckerResults(${JSON.stringify(results)});
uiController.uiScriptComplete();
})()`, resolve);
});
}
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
static async activateElementAfterInstallingTapGestureOnWindow(element)
{
if (!this.isWebKit2() || !this.isIOSFamily())
return activateElement(element);
const x = element.offsetLeft + element.offsetWidth / 2;
const y = element.offsetTop + element.offsetHeight / 2;
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
let progress = 0;
function incrementProgress() {
if (++progress == 2)
uiController.uiScriptComplete();
}
uiController.installTapGestureOnWindow(incrementProgress);
uiController.singleTapAtPoint(${x}, ${y}, incrementProgress);
})();`, resolve);
});
}
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
static mayContainEditableElementsInRect(x, y, width, height)
{
if (!this.isWebKit2() || !this.isIOSFamily())
return Promise.resolve(false);
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
uiController.doAfterPresentationUpdate(function() {
uiController.uiScriptComplete(uiController.mayContainEditableElementsInRect(${x}, ${y}, ${width}, ${height}));
})
})();`, result => resolve(result === "true"));
});
}
static moveToNextByKeyboardAccessoryBar()
{
return new Promise((resolve) => {
testRunner.runUIScript(`
uiController.keyboardAccessoryBarNext();
uiController.uiScriptComplete();
`, resolve);
});
}
static moveToPrevByKeyboardAccessoryBar()
{
return new Promise((resolve) => {
testRunner.runUIScript(`
uiController.keyboardAccessoryBarPrevious();
uiController.uiScriptComplete();
`, resolve);
});
}
[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
static waitForContactPickerToShow()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (!uiController.isShowingContactPicker)
uiController.didShowContactPickerCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
})()`, resolve);
});
}
static waitForContactPickerToHide()
{
if (!this.isWebKit2())
return Promise.resolve();
return new Promise(resolve => {
testRunner.runUIScript(`
(function() {
if (uiController.isShowingContactPicker)
uiController.didHideContactPickerCallback = () => uiController.uiScriptComplete();
else
uiController.uiScriptComplete();
})()`, resolve);
});
}
static dismissContactPickerWithContacts(contacts)
{
const script = `(() => uiController.dismissContactPickerWithContacts(${JSON.stringify(contacts)}))()`;
return new Promise(resolve => testRunner.runUIScript(script, resolve));
}
[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
static addChromeInputField()
{
return new Promise(resolve => testRunner.addChromeInputField(resolve));
}
static removeChromeInputField()
{
return new Promise(resolve => testRunner.removeChromeInputField(resolve));
}
static setTextInChromeInputField(text)
{
return new Promise(resolve => testRunner.setTextInChromeInputField(text, resolve));
}
static selectChromeInputField()
{
return new Promise(resolve => testRunner.selectChromeInputField(resolve));
}
static getSelectedTextInChromeInputField()
{
return new Promise(resolve => testRunner.getSelectedTextInChromeInputField(resolve));
}
:hover rule causes a single tap to not activate a slotted anchor element https://bugs.webkit.org/show_bug.cgi?id=165551 Reviewed by Antti Koivisto. Source/WebCore: Fixed a bug in ancestorRespondingToClickEvents that we were traversing the ancestor nodes without taking shadow roots and slots into account. This prevented tapping on a text node assigned to a slot inside an anchor element to activate the hyperlink on iOS. This bug was supposed to be fixed in r206605, and it was still broken on iOS due to the bug in ancestorRespondingToClickEvents. It is now tested by click-text-inside-linked-slot.html. Tests: fast/shadow-dom/click-on-slotted-anchor-with-hover.html fast/shadow-dom/click-text-inside-linked-slot.html * page/ios/FrameIOS.mm: (WebCore::ancestorRespondingToClickEvents): (WebCore::Frame::qualifyingNodeAtViewportLocation): LayoutTests: Added a test for tapping on an anchor element assigned to a slot, which has been fixed in r209065. Also added a new helper JS wrapepr, UIHelper, defined inside LayoutTests/resources/js-helper.js to provide an abstraction around EventSender and UIScriptController. Fixed click-text-inside-linked-slot.html on iOS using UIHelper. * fast/shadow-dom/click-on-slotted-anchor-with-hover-expected.txt: Added. * fast/shadow-dom/click-on-slotted-anchor-with-hover.html: Added. * fast/shadow-dom/click-text-inside-linked-slot.html: * platform/ios-simulator/fast/shadow-dom/click-text-inside-linked-slot-expected.txt: Added. * resources/ui-helper.js: Added. (window.UIHelper.isIOS): (window.UIHelper.activateAt.return.new.Promise): (window.UIHelper.activateAt): (window.UIHelper.wait): (window.UIHelper): * platform/ios-simulator-wk2/TestExpectations: Skip the test in the open source iOS's WebKit2. Canonical link: https://commits.webkit.org/183426@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209780 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-12-13 23:22:03 +00:00
}
[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
UIHelper.EventStreamBuilder = class {
constructor()
{
// FIXME: This could support additional customization options, such as interpolation, timestep, and different
// digitizer indices in the future. For now, just make it simpler to string together sequences of pan gestures.
this._reset();
}
_reset() {
this.events = [];
this.currentTimeOffset = 0;
this.currentX = 0;
this.currentY = 0;
}
begin(x, y) {
console.assert(this.currentTimeOffset === 0);
this.events.push({
interpolate : "linear",
timestep : 0.016,
coordinateSpace : "content",
startEvent : {
inputType : "hand",
timeOffset : this.currentTimeOffset,
touches : [{ inputType : "finger", phase : "began", id : 1, x : x, y : y, pressure : 0 }]
},
endEvent : {
inputType : "hand",
timeOffset : this.currentTimeOffset,
touches : [{ inputType : "finger", phase : "began", id : 1, x : x, y : y, pressure : 0 }]
}
});
this.currentX = x;
this.currentY = y;
return this;
}
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
wait(duration) {
this.currentTimeOffset += duration;
return this;
}
[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
move(x, y, duration = 0) {
const previousTimeOffset = this.currentTimeOffset;
this.currentTimeOffset += duration;
this.events.push({
interpolate : "linear",
timestep : 0.016,
coordinateSpace : "content",
startEvent : {
inputType : "hand",
timeOffset : previousTimeOffset,
touches : [{ inputType : "finger", phase : "moved", id : 1, x : this.currentX, y : this.currentY, pressure : 0 }]
},
endEvent : {
inputType : "hand",
timeOffset : this.currentTimeOffset,
touches : [{ inputType : "finger", phase : "moved", id : 1, x : x, y : y, pressure : 0 }]
}
});
this.currentX = x;
this.currentY = y;
return this;
}
end() {
this.events.push({
interpolate : "linear",
timestep : 0.016,
coordinateSpace : "content",
startEvent : {
inputType : "hand",
timeOffset : this.currentTimeOffset,
touches : [{ inputType : "finger", phase : "ended", id : 1, x : this.currentX, y : this.currentY, pressure : 0 }]
},
endEvent : {
inputType : "hand",
timeOffset : this.currentTimeOffset,
touches : [{ inputType : "finger", phase : "ended", id : 1, x : this.currentX, y : this.currentY, pressure : 0 }]
}
});
return this;
}
takeResult() {
const events = this.events;
this._reset();
return { "events": events };
}
}