Skip to content

Commit 5350909

Browse files
[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. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@221064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 3a241fb commit 5350909

File tree

57 files changed

+870
-336
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+870
-336
lines changed

LayoutTests/ChangeLog

+65
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,68 @@
1+
2017-08-22 Wenson Hsieh <[email protected]>
2+
3+
[WK2] EditorState updates should be rolled into the layer update lifecycle when possible
4+
https://bugs.webkit.org/show_bug.cgi?id=175370
5+
<rdar://problem/33799806>
6+
7+
Reviewed by Ryosuke Niwa.
8+
9+
Rebaseline and adjust LayoutTests.
10+
11+
* editing/caret/ios/absolute-caret-position-after-scroll-expected.txt:
12+
* editing/caret/ios/absolute-caret-position-after-scroll.html:
13+
* editing/caret/ios/fixed-caret-position-after-scroll-expected.txt:
14+
* editing/caret/ios/fixed-caret-position-after-scroll.html:
15+
* editing/secure-input/password-input-changed-type.html:
16+
* editing/secure-input/password-input-focusing.html:
17+
* editing/secure-input/removed-password-input.html:
18+
* editing/secure-input/reset-state-on-navigation.html:
19+
* editing/selection/character-granularity-rect.html:
20+
21+
Delay checking for secure input state and caret rects until after the next presentation update.
22+
23+
* editing/selection/ios/absolute-selection-after-scroll-expected.txt:
24+
* editing/selection/ios/absolute-selection-after-scroll.html:
25+
* editing/selection/ios/fixed-selection-after-scroll-expected.txt:
26+
* editing/selection/ios/fixed-selection-after-scroll.html:
27+
28+
Refactor and simplify these tests. These tests are not run on the OpenSource bots, since they depend on long
29+
press and tap gestures.
30+
31+
* platform/ios-wk2/editing/inserting/insert-div-024-expected.txt:
32+
* platform/ios-wk2/editing/inserting/insert-div-026-expected.txt:
33+
* platform/ios-wk2/editing/style/5084241-expected.txt:
34+
35+
Rebaselines these tests, removing an anonymous RenderBlock inserted as a result of inserting and removing a
36+
dummy span in order to compute a RenderStyle in WebPage::editorState. This is because editorState is no longer
37+
invoked immediately on page load; https://bugs.webkit.org/show_bug.cgi?id=175116 tracks preventing this render
38+
tree thrashing altogether.
39+
40+
* platform/mac-wk2/TestExpectations:
41+
* platform/mac-wk2/editing/style/unbold-in-bold-expected.txt:
42+
* resources/ui-helper.js:
43+
44+
Introduce new UIHelper functions.
45+
46+
(window.UIHelper.ensurePresentationUpdate.return.new.Promise):
47+
(window.UIHelper.ensurePresentationUpdate):
48+
49+
Returns a Promise, resolved after the next presentation update.
50+
51+
(window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise.):
52+
(window.UIHelper.activateAndWaitForInputSessionAt.return.new.Promise):
53+
(window.UIHelper.activateAndWaitForInputSessionAt):
54+
55+
Returns a Promise, resolved after tapping at the given location and waiting for the keyboard to appear on iOS.
56+
57+
(window.UIHelper.getUICaretRect.return.new.Promise.):
58+
(window.UIHelper.getUICaretRect.return.new.Promise):
59+
(window.UIHelper.getUICaretRect):
60+
(window.UIHelper.getUISelectionRects.return.new.Promise.):
61+
(window.UIHelper.getUISelectionRects.return.new.Promise):
62+
(window.UIHelper.getUISelectionRects):
63+
64+
Helpers to fetch selection and caret rect information in the UI process.
65+
166
2017-08-21 Ryosuke Niwa <[email protected]>
267

368
Consolidate the code to normalize MIME type in DataTransfer
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
PASS initialCaretRect.left is 6
2+
PASS initialCaretRect.top is 21
3+
PASS initialCaretRect.width is 3
4+
PASS initialCaretRect.height is 15
5+
PASS finalCaretRect.left is 6
6+
PASS finalCaretRect.top is 21
7+
PASS finalCaretRect.width is 3
8+
PASS finalCaretRect.height is 15
19
PASS successfullyParsed is true
210

311
TEST COMPLETE
4-
The initial caret rect is: [6 21 ; 3 15]
5-
The caret rect after scrolling 1000px down is: [6 21 ; 3 15]
6-
PASS finalCaretRect.top is initialCaretRect.top
7-
PASS finalCaretRect.left is initialCaretRect.left
8-
PASS finalCaretRect.width is initialCaretRect.width
9-
PASS finalCaretRect.height is initialCaretRect.height
1012

LayoutTests/editing/caret/ios/absolute-caret-position-after-scroll.html

+35-59
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<html>
33
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
44
<head>
5+
<script src="../../../resources/ui-helper.js"></script>
56
<script src="../../../resources/js-test.js"></script>
67
<style>
78
body {
@@ -18,68 +19,43 @@
1819

1920
div {
2021
background-image: linear-gradient(0deg, blue, red);
21-
height: 4000px;
22+
height: 10000px;
2223
}
2324
</style>
24-
<script>
25-
jsTestIsAsync = true;
26-
27-
function tapInInputScript(tapX, tapY)
28-
{
29-
return `(function() {
30-
uiController.didShowKeyboardCallback = function() {
31-
uiController.doAfterNextStablePresentationUpdate(function() {
32-
uiController.uiScriptComplete(JSON.stringify(uiController.textSelectionCaretRect));
33-
});
34-
};
35-
uiController.singleTapAtPoint(${tapX}, ${tapY}, function() { });
36-
})()`;
37-
}
38-
39-
function simulateScrollingScript(distance)
40-
{
41-
return `(function() {
42-
uiController.stableStateOverride = false;
43-
uiController.immediateScrollToOffset(0, ${distance});
44-
uiController.stableStateOverride = true;
45-
uiController.doAfterNextStablePresentationUpdate(function() {
46-
uiController.uiScriptComplete(JSON.stringify(uiController.textSelectionCaretRect));
47-
});
48-
})()`;
49-
}
50-
51-
function toString(rect)
52-
{
53-
return `[${rect.left} ${rect.top} ; ${rect.width} ${rect.height}]`;
54-
}
55-
56-
function run()
57-
{
58-
if (!window.testRunner || !testRunner.runUIScript) {
59-
description("To manually test, tap this input field and scroll up. The text caret should not end up outside of the input.");
60-
return;
61-
}
62-
63-
testRunner.runUIScript(tapInInputScript(window.innerWidth / 2, 30), initialCaretRect => {
64-
initialCaretRect = JSON.parse(initialCaretRect);
65-
window.initialCaretRect = initialCaretRect;
66-
debug(`The initial caret rect is: ${toString(initialCaretRect)}`);
67-
testRunner.runUIScript(simulateScrollingScript(1000), finalCaretRect => {
68-
finalCaretRect = JSON.parse(finalCaretRect);
69-
window.finalCaretRect = finalCaretRect;
70-
debug(`The caret rect after scrolling 1000px down is: ${toString(finalCaretRect)}`);
71-
shouldBe("finalCaretRect.top", "initialCaretRect.top");
72-
shouldBe("finalCaretRect.left", "initialCaretRect.left");
73-
shouldBe("finalCaretRect.width", "initialCaretRect.width");
74-
shouldBe("finalCaretRect.height", "initialCaretRect.height");
75-
finishJSTest();
76-
});
77-
});
78-
}
79-
</script>
8025
</head>
81-
<body onload=run()>
82-
<input></input>
26+
<body>
27+
<div>
28+
<input id="input"></input>
29+
</div>
8330
</body>
31+
<script>
32+
jsTestIsAsync = true;
33+
34+
(() => {
35+
if (!window.testRunner || !testRunner.runUIScript) {
36+
description("To manually test, tap this input field and scroll up. The text caret should not end up outside of the input.");
37+
return;
38+
}
8439

40+
UIHelper.activateAndWaitForInputSessionAt(innerWidth / 2, 30)
41+
.then(() => UIHelper.getUICaretRect())
42+
.then((rect) => {
43+
initialCaretRect = rect;
44+
shouldBe("initialCaretRect.left", "6");
45+
shouldBe("initialCaretRect.top", "21");
46+
shouldBe("initialCaretRect.width", "3");
47+
shouldBe("initialCaretRect.height", "15");
48+
document.body.scrollTop += 5000;
49+
return UIHelper.getUICaretRect();
50+
})
51+
.then((rect) => {
52+
finalCaretRect = rect;
53+
shouldBe("finalCaretRect.left", "6");
54+
shouldBe("finalCaretRect.top", "21");
55+
shouldBe("finalCaretRect.width", "3");
56+
shouldBe("finalCaretRect.height", "15");
57+
finishJSTest();
58+
});
59+
})();
60+
</script>
8561
</html>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
PASS initialCaretRect.left is 6
2+
PASS initialCaretRect.top is 21
3+
PASS initialCaretRect.width is 3
4+
PASS initialCaretRect.height is 15
5+
PASS finalCaretRect.left is 6
6+
PASS finalCaretRect.top is 5021
7+
PASS finalCaretRect.width is 3
8+
PASS finalCaretRect.height is 15
19
PASS successfullyParsed is true
210

311
TEST COMPLETE
4-
PASS finalCaretRect.top - initialCaretRect.top is 500
512

LayoutTests/editing/caret/ios/fixed-caret-position-after-scroll.html

+35-55
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<html>
33
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
44
<head>
5+
<script src="../../../resources/ui-helper.js"></script>
56
<script src="../../../resources/js-test.js"></script>
67
<style>
78
body {
@@ -18,64 +19,43 @@
1819

1920
div {
2021
background-image: linear-gradient(blue, red);
21-
height: 4000px;
22+
height: 10000px;
2223
}
2324
</style>
24-
<script>
25-
jsTestIsAsync = true;
26-
27-
function getInputViewBoundsAfterTappingInInputScript(tapX, tapY)
28-
{
29-
return `(function() {
30-
uiController.didShowKeyboardCallback = function() {
31-
uiController.doAfterNextStablePresentationUpdate(function() {
32-
uiController.uiScriptComplete(JSON.stringify(uiController.inputViewBounds));
33-
});
34-
};
35-
uiController.singleTapAtPoint(${tapX}, ${tapY}, function() { });
36-
})()`;
37-
}
38-
39-
function getCaretRectAfterScrollToOffsetScript(distance)
40-
{
41-
return `(function() {
42-
uiController.stableStateOverride = false;
43-
uiController.immediateScrollToOffset(0, ${distance});
44-
uiController.stableStateOverride = true;
45-
uiController.doAfterNextStablePresentationUpdate(function() {
46-
uiController.uiScriptComplete(JSON.stringify(uiController.textSelectionCaretRect));
47-
});
48-
})()`;
49-
}
50-
51-
function toString(rect)
52-
{
53-
return `[${rect.left} ${rect.top} ; ${rect.width} ${rect.height}]`;
54-
}
55-
56-
function run()
57-
{
58-
if (!window.testRunner || !testRunner.runUIScript) {
59-
description("To manually test, tap this input field and scroll up. The text caret should not end up outside of the input.");
60-
return;
61-
}
62-
63-
testRunner.runUIScript(getInputViewBoundsAfterTappingInInputScript(window.innerWidth / 2, 30), (inputViewBounds) => {
64-
window.inputViewBounds = inputViewBounds = JSON.parse(inputViewBounds);
65-
testRunner.runUIScript(getCaretRectAfterScrollToOffsetScript(inputViewBounds.height), initialCaretRect => {
66-
window.initialCaretRect = initialCaretRect = JSON.parse(initialCaretRect);
67-
testRunner.runUIScript(getCaretRectAfterScrollToOffsetScript(inputViewBounds.height + 500), finalCaretRect => {
68-
window.finalCaretRect = finalCaretRect = JSON.parse(finalCaretRect);
69-
shouldBe("finalCaretRect.top - initialCaretRect.top", "500");
70-
finishJSTest();
71-
});
72-
});
73-
});
74-
}
75-
</script>
7625
</head>
77-
<body onload=run()>
78-
<input id="input"></input>
26+
<body>
27+
<div>
28+
<input id="input"></input>
29+
</div>
7930
</body>
31+
<script>
32+
jsTestIsAsync = true;
33+
34+
(() => {
35+
if (!window.testRunner || !testRunner.runUIScript) {
36+
description("To manually test, tap this input field and scroll up. The text caret should not end up outside of the input.");
37+
return;
38+
}
8039

40+
UIHelper.activateAndWaitForInputSessionAt(innerWidth / 2, 30)
41+
.then(() => UIHelper.getUICaretRect())
42+
.then((rect) => {
43+
initialCaretRect = rect;
44+
shouldBe("initialCaretRect.left", "6");
45+
shouldBe("initialCaretRect.top", "21");
46+
shouldBe("initialCaretRect.width", "3");
47+
shouldBe("initialCaretRect.height", "15");
48+
document.body.scrollTop += 5000;
49+
return UIHelper.getUICaretRect();
50+
})
51+
.then((rect) => {
52+
finalCaretRect = rect;
53+
shouldBe("finalCaretRect.left", "6");
54+
shouldBe("finalCaretRect.top", "5021");
55+
shouldBe("finalCaretRect.width", "3");
56+
shouldBe("finalCaretRect.height", "15");
57+
finishJSTest();
58+
});
59+
})();
60+
</script>
8161
</html>

LayoutTests/editing/secure-input/password-input-changed-type.html

+20-7
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,40 @@
22
<html>
33
<head>
44
<meta charset="utf-8">
5+
<script src="../../resources/ui-helper.js"></script>
56
<script src="../../resources/js-test-pre.js"></script>
67
</head>
78
<body>
89
<input type=password>
910
<script>
1011

12+
jsTestIsAsync = true;
13+
1114
description("Verify that changing a password input's type updates secure input state.");
1215

1316
var passwordInput = document.getElementsByTagName("input")[0];
1417

1518
debug("A password input is focused:");
1619
passwordInput.focus();
17-
shouldBe("testRunner.secureEventInputIsEnabled", "true");
1820

19-
debug("\nAfter changing the type to text:");
20-
passwordInput.type = "text";
21-
shouldBe("testRunner.secureEventInputIsEnabled", "false");
21+
UIHelper.ensurePresentationUpdate().then(() => {
22+
shouldBe("testRunner.secureEventInputIsEnabled", "true");
23+
debug("\nAfter changing the type to text:");
24+
passwordInput.type = "text";
25+
})
26+
27+
.then(() => UIHelper.ensurePresentationUpdate())
28+
.then(() => {
29+
shouldBe("testRunner.secureEventInputIsEnabled", "false");
30+
debug("\nAfter changing the type back to password:");
31+
passwordInput.type = "password";
32+
})
2233

23-
debug("\nAfter changing the type back to password:");
24-
passwordInput.type = "password";
25-
shouldBe("testRunner.secureEventInputIsEnabled", "true");
34+
.then(() => UIHelper.ensurePresentationUpdate())
35+
.then(() => {
36+
shouldBe("testRunner.secureEventInputIsEnabled", "true");
37+
finishJSTest();
38+
});
2639

2740
</script>
2841
<script src="../../resources/js-test-post.js"></script>

0 commit comments

Comments
 (0)