2017-12-18 20:13:56 +00:00
|
|
|
function didShowKeyboard()
|
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
|
|
|
uiController.didShowKeyboardCallback = function() {
|
|
|
|
uiController.uiScriptComplete();
|
|
|
|
}
|
|
|
|
})();`, resolve);
|
|
|
|
});
|
2017-12-18 20:13:56 +00:00
|
|
|
}
|
|
|
|
|
[Extra zoom mode] Double tap to zoom should account for text legibility in extra zoom mode
https://bugs.webkit.org/show_bug.cgi?id=184631
<rdar://problem/39303706>
Reviewed by Tim Horton.
Source/WebKit:
Implement the text legibility heuristic alluded to in r230506 by iterating through text runs in the document (up
to a maximum of 200) and building a histogram of font sizes that appear in the document, where each tally
represents a character.
The first and second text legibility zoom scales are then computed based on the zoom scales needed to
make 50% and 90% of the text legible, respectively. Here, a zoom scale that makes text legible is such that the
text would have an apparent font size of a hard-coded constant (currently, 12) after zooming. This means the
first and second text legibility scales may end up being close to one another, or even the same (in the case
where there is only a single font size in the entire document). In this case, we just snap the first scale to
the second, so that double tapping will only toggle between two zoom scales. In another case where the document
has no text (e.g. an image document), we just fall back to a zoom scale of 1.
Test: fast/events/extrazoom/double-tap-to-zoom-on-full-width-text.html
* WebProcess/WebPage/ViewGestureGeometryCollector.cpp:
(WebKit::ViewGestureGeometryCollector::computeTextLegibilityScales):
LayoutTests:
Add a layout test to check that double tap to zoom works in extra zoom mode, even when text spans the entire
width of the document.
* TestExpectations:
* fast/events/extrazoom/double-tap-to-zoom-on-full-width-text-expected.txt: Added.
* fast/events/extrazoom/double-tap-to-zoom-on-full-width-text.html: Added.
* resources/basic-gestures.js:
Add a helper method to double tap at a given location, and wait for zooming to finish.
(return.new.Promise):
Canonical link: https://commits.webkit.org/200232@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230746 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-18 02:50:25 +00:00
|
|
|
function doubleTapToZoomAtPoint(x, y)
|
|
|
|
{
|
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
2018-10-15 17:36:31 +00:00
|
|
|
let completionCount = 0;
|
|
|
|
const checkDone = () => {
|
|
|
|
if (++completionCount == 3)
|
|
|
|
uiController.uiScriptComplete();
|
|
|
|
};
|
|
|
|
uiController.didEndZoomingCallback = checkDone;
|
|
|
|
uiController.singleTapAtPoint(${x}, ${y}, checkDone);
|
|
|
|
uiController.singleTapAtPoint(${x}, ${y}, checkDone);
|
[Extra zoom mode] Double tap to zoom should account for text legibility in extra zoom mode
https://bugs.webkit.org/show_bug.cgi?id=184631
<rdar://problem/39303706>
Reviewed by Tim Horton.
Source/WebKit:
Implement the text legibility heuristic alluded to in r230506 by iterating through text runs in the document (up
to a maximum of 200) and building a histogram of font sizes that appear in the document, where each tally
represents a character.
The first and second text legibility zoom scales are then computed based on the zoom scales needed to
make 50% and 90% of the text legible, respectively. Here, a zoom scale that makes text legible is such that the
text would have an apparent font size of a hard-coded constant (currently, 12) after zooming. This means the
first and second text legibility scales may end up being close to one another, or even the same (in the case
where there is only a single font size in the entire document). In this case, we just snap the first scale to
the second, so that double tapping will only toggle between two zoom scales. In another case where the document
has no text (e.g. an image document), we just fall back to a zoom scale of 1.
Test: fast/events/extrazoom/double-tap-to-zoom-on-full-width-text.html
* WebProcess/WebPage/ViewGestureGeometryCollector.cpp:
(WebKit::ViewGestureGeometryCollector::computeTextLegibilityScales):
LayoutTests:
Add a layout test to check that double tap to zoom works in extra zoom mode, even when text spans the entire
width of the document.
* TestExpectations:
* fast/events/extrazoom/double-tap-to-zoom-on-full-width-text-expected.txt: Added.
* fast/events/extrazoom/double-tap-to-zoom-on-full-width-text.html: Added.
* resources/basic-gestures.js:
Add a helper method to double tap at a given location, and wait for zooming to finish.
(return.new.Promise):
Canonical link: https://commits.webkit.org/200232@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230746 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-18 02:50:25 +00:00
|
|
|
})();`, resolve);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-04-20 20:40:51 +00:00
|
|
|
function doubleTapAtPoint(x, y)
|
|
|
|
{
|
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
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, function() {
|
2018-04-20 20:40:51 +00:00
|
|
|
uiController.uiScriptComplete();
|
|
|
|
});
|
|
|
|
})();`, resolve);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-09-29 02:22:22 +00:00
|
|
|
function longPressAtPoint(x, y)
|
2017-01-19 23:30:33 +00:00
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
|
|
|
uiController.longPressAtPoint(${x}, ${y}, function() {
|
|
|
|
uiController.uiScriptComplete();
|
|
|
|
});
|
|
|
|
})();`, resolve);
|
|
|
|
});
|
2017-01-19 23:30:33 +00:00
|
|
|
}
|
|
|
|
|
2017-12-18 20:13:56 +00:00
|
|
|
function liftUpAtPoint(x, y)
|
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
|
|
|
uiController.liftUpAtPoint(${x}, ${y}, 1, function() {
|
|
|
|
uiController.uiScriptComplete();
|
|
|
|
});
|
|
|
|
})();`, resolve);
|
|
|
|
});
|
2017-12-18 20:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function longPressAndHoldAtPoint(x, y)
|
2017-10-03 22:12:37 +00:00
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
2019-08-16 00:37:20 +00:00
|
|
|
const eventStream = {
|
|
|
|
events : [
|
|
|
|
{
|
|
|
|
interpolate : "linear",
|
|
|
|
timestep: 0.1,
|
|
|
|
coordinateSpace : "content",
|
|
|
|
startEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 0,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "began",
|
|
|
|
id : 1,
|
|
|
|
x : ${x},
|
|
|
|
y : ${y},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
endEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 2.0,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "moved",
|
|
|
|
id : 1,
|
|
|
|
x : ${x},
|
|
|
|
y : ${y},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
2018-01-19 16:45:49 +00:00
|
|
|
}
|
2019-08-16 00:37:20 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
2018-01-19 16:45:49 +00:00
|
|
|
|
2019-08-16 00:37:20 +00:00
|
|
|
uiController.sendEventStream(JSON.stringify(eventStream), () => uiController.uiScriptComplete());
|
2018-01-19 16:45:49 +00:00
|
|
|
})();`, resolve);
|
|
|
|
});
|
2017-10-03 22:12:37 +00:00
|
|
|
}
|
|
|
|
|
2017-09-29 02:22:22 +00:00
|
|
|
function tapAtPoint(x, y)
|
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
|
|
|
uiController.singleTapAtPoint(${x}, ${y}, function() {
|
|
|
|
uiController.uiScriptComplete();
|
|
|
|
});
|
|
|
|
})();`, resolve);
|
|
|
|
});
|
2017-09-29 02:22:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function touchAndDragFromPointToPoint(startX, startY, endX, endY)
|
2017-01-19 23:30:33 +00:00
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
2019-08-16 00:37:20 +00:00
|
|
|
const eventStream = {
|
|
|
|
events : [
|
|
|
|
{
|
|
|
|
interpolate : "linear",
|
|
|
|
timestep: 0.1,
|
|
|
|
coordinateSpace : "content",
|
|
|
|
startEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 0,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "began",
|
|
|
|
id : 1,
|
|
|
|
x : ${startX},
|
|
|
|
y : ${startY},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
endEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 0.5,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "moved",
|
|
|
|
id : 1,
|
|
|
|
x : ${endX},
|
|
|
|
y : ${endY},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
2018-01-19 16:45:49 +00:00
|
|
|
}
|
2019-08-16 00:37:20 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
2018-01-19 16:45:49 +00:00
|
|
|
|
2019-08-16 00:37:20 +00:00
|
|
|
uiController.sendEventStream(JSON.stringify(eventStream), () => uiController.uiScriptComplete());
|
2018-01-19 16:45:49 +00:00
|
|
|
})();`, resolve);
|
|
|
|
});
|
2017-01-19 23:30:33 +00:00
|
|
|
}
|
2017-10-03 22:12:37 +00:00
|
|
|
|
2017-12-18 20:13:56 +00:00
|
|
|
function holdAtPoint(x, y)
|
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
2019-08-16 00:37:20 +00:00
|
|
|
const eventStream = {
|
|
|
|
events : [
|
|
|
|
{
|
|
|
|
interpolate : "linear",
|
|
|
|
timestep: 0.1,
|
|
|
|
coordinateSpace : "content",
|
|
|
|
startEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 0,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "moved",
|
|
|
|
id : 1,
|
|
|
|
x : ${x},
|
|
|
|
y : ${y},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
endEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 5.0,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "moved",
|
|
|
|
id : 1,
|
|
|
|
x : ${x},
|
|
|
|
y : ${y},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
2018-01-19 16:45:49 +00:00
|
|
|
}
|
2019-08-16 00:37:20 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
2018-01-19 16:45:49 +00:00
|
|
|
|
2019-08-16 00:37:20 +00:00
|
|
|
uiController.sendEventStream(JSON.stringify(eventStream), () => uiController.uiScriptComplete());
|
2018-01-19 16:45:49 +00:00
|
|
|
})();`, resolve);
|
|
|
|
});
|
2017-12-18 20:13:56 +00:00
|
|
|
}
|
|
|
|
|
2017-10-03 22:12:37 +00:00
|
|
|
function continueTouchAndDragFromPointToPoint(startX, startY, endX, endY)
|
|
|
|
{
|
2018-01-19 16:45:49 +00:00
|
|
|
return new Promise(resolve => {
|
|
|
|
testRunner.runUIScript(`
|
|
|
|
(function() {
|
2019-08-16 00:37:20 +00:00
|
|
|
const eventStream = {
|
|
|
|
events : [
|
|
|
|
{
|
|
|
|
interpolate : "linear",
|
|
|
|
timestep: 0.1,
|
|
|
|
coordinateSpace : "content",
|
|
|
|
startEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 0,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "moved",
|
|
|
|
id : 1,
|
|
|
|
x : ${startX},
|
|
|
|
y : ${startY},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
endEvent : {
|
|
|
|
inputType : "hand",
|
|
|
|
timeOffset : 0.5,
|
|
|
|
touches : [
|
|
|
|
{
|
|
|
|
inputType : "finger",
|
|
|
|
phase : "moved",
|
|
|
|
id : 1,
|
|
|
|
x : ${endX},
|
|
|
|
y : ${endY},
|
|
|
|
pressure : 0
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
2018-01-19 16:45:49 +00:00
|
|
|
|
2019-08-16 00:37:20 +00:00
|
|
|
uiController.sendEventStream(JSON.stringify(eventStream), () => uiController.uiScriptComplete());
|
|
|
|
})();`, resolve);
|
2018-01-19 16:45:49 +00:00
|
|
|
});
|
2017-10-03 22:12:37 +00:00
|
|
|
}
|