Skip to content

Commit eb97bb4

Browse files
mstenshoCommit Bot
authored andcommitted
Save/restore scroll offsets while printing.
When attempting to clamp the scroll offset during printing, save the scroll offset before clamping, so that it can be restored after printing. Note that there are still issues to fix here. Right now, this CL doesn't fix anything at all, but it will prevent a regression that would otherwise be introduced by crrev.com/2362749. This is what's tested in PrintBrowserTest.NoScrollingVerticalRl PrintBrowserTest.NoScrolling tests scrolling of an iframe and a scrollable DIV, and another scrollable DIV that turns into a non-scrollable flexbox when printed. The iframe part also passes without this CL, and the scrollable DIV ones fail both without and with this CL (and is therefore disabled for now). Same problem for framesets - still not fixed. Added a test. The remaining known scrolling issues when printing are reported as bug 1131598. Based on WIP CL:2402190 by szager. Bug: 1125972 Change-Id: I6c3f5853d329e4731b02b33d67cbd4b016f2675f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2418651 Reviewed-by: Lei Zhang <[email protected]> Reviewed-by: Xianzhu Wang <[email protected]> Reviewed-by: Stefan Zager <[email protected]> Commit-Queue: Morten Stenshorne <[email protected]> Cr-Commit-Position: refs/heads/master@{#810103}
1 parent c5f5ffb commit eb97bb4

File tree

14 files changed

+253
-21
lines changed

14 files changed

+253
-21
lines changed

chrome/browser/printing/print_browsertest.cc

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,69 @@ IN_PROC_BROWSER_TEST_F(PrintBrowserTest, SelectionContainsIframe) {
530530
PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/true);
531531
}
532532

533+
// https://crbug.com/1125972
534+
// https://crbug.com/1131598
535+
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, NoScrolling) {
536+
ASSERT_TRUE(embedded_test_server()->Started());
537+
GURL url(embedded_test_server()->GetURL("/printing/with-scrollable.html"));
538+
ui_test_utils::NavigateToURL(browser(), url);
539+
540+
auto* contents = browser()->tab_strip_model()->GetActiveWebContents();
541+
const char kExpression1[] = "iframe.contentWindow.scrollY";
542+
const char kExpression2[] = "scrollable.scrollTop";
543+
const char kExpression3[] = "shapeshifter.scrollTop";
544+
545+
double old_scroll1 = content::EvalJs(contents, kExpression1).ExtractDouble();
546+
double old_scroll2 = content::EvalJs(contents, kExpression2).ExtractDouble();
547+
double old_scroll3 = content::EvalJs(contents, kExpression3).ExtractDouble();
548+
549+
PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false);
550+
551+
double new_scroll1 = content::EvalJs(contents, kExpression1).ExtractDouble();
552+
553+
// TODO(crbug.com/1131598): Perform the corresponding EvalJs() calls here and
554+
// assign to new_scroll2 and new_scroll3, once the printing code has been
555+
// fixed to handle these cases. Right now, the scroll offset jumps.
556+
double new_scroll2 = old_scroll2;
557+
double new_scroll3 = old_scroll3;
558+
559+
EXPECT_EQ(old_scroll1, new_scroll1);
560+
EXPECT_EQ(old_scroll2, new_scroll2);
561+
EXPECT_EQ(old_scroll3, new_scroll3);
562+
}
563+
564+
// https://crbug.com/1131598
565+
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, DISABLED_NoScrollingFrameset) {
566+
ASSERT_TRUE(embedded_test_server()->Started());
567+
GURL url(embedded_test_server()->GetURL("/printing/frameset.html"));
568+
ui_test_utils::NavigateToURL(browser(), url);
569+
570+
auto* contents = browser()->tab_strip_model()->GetActiveWebContents();
571+
const char kExpression[] =
572+
"document.getElementById('frame').contentWindow.scrollY";
573+
574+
double old_scroll = content::EvalJs(contents, kExpression).ExtractDouble();
575+
576+
PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false);
577+
578+
double new_scroll = content::EvalJs(contents, kExpression).ExtractDouble();
579+
580+
EXPECT_EQ(old_scroll, new_scroll);
581+
}
582+
583+
// https://crbug.com/1125972
584+
IN_PROC_BROWSER_TEST_F(PrintBrowserTest, NoScrollingVerticalRl) {
585+
ASSERT_TRUE(embedded_test_server()->Started());
586+
GURL url(embedded_test_server()->GetURL("/printing/vertical-rl.html"));
587+
ui_test_utils::NavigateToURL(browser(), url);
588+
PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false);
589+
590+
// Test that entering print preview didn't mess up the scroll position.
591+
EXPECT_EQ(
592+
0, content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
593+
"window.scrollX"));
594+
}
595+
533596
// Printing frame content for the main frame of a generic webpage.
534597
// This test passes when the printed result is sent back and checked in
535598
// TestPrintRenderFrame::OnDidPrintFrameContent().
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!DOCTYPE html>
2+
<frameset cols="100%">
3+
<frame id="frame" src="scrolled-frame.html"></frame>
4+
</frameset>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!DOCTYPE html>
2+
<style>
3+
body { margin:0; }
4+
</style>
5+
filler filler filler filler filler filler filler filler filler filler filler
6+
filler filler filler filler filler filler filler filler filler filler filler
7+
filler filler filler filler filler filler filler filler filler filler filler
8+
filler filler filler filler filler filler filler filler filler filler filler
9+
filler filler filler filler filler filler filler filler filler filler filler
10+
filler filler filler filler filler filler filler filler filler filler filler
11+
filler filler filler filler filler filler filler filler filler filler filler
12+
filler filler filler filler filler filler filler filler filler filler filler
13+
filler filler filler filler filler filler filler filler filler filler filler
14+
filler filler filler filler filler filler filler filler filler filler filler
15+
filler filler filler filler filler filler filler filler filler filler filler
16+
filler filler filler filler filler filler filler filler filler filler filler
17+
filler filler filler filler filler filler filler filler filler filler filler
18+
filler filler filler filler filler filler filler filler filler filler filler
19+
<div id="target" style="width:100px; height:100px; background:green;"></div>
20+
filler filler filler filler filler filler filler filler filler filler filler
21+
filler filler filler filler filler filler filler filler filler filler filler
22+
filler filler filler filler filler filler filler filler filler filler filler
23+
filler filler filler filler filler filler filler filler filler filler filler
24+
filler filler filler filler filler filler filler filler filler filler filler
25+
filler filler filler filler filler filler filler filler filler filler filler
26+
filler filler filler filler filler filler filler filler filler filler filler
27+
filler filler filler filler filler filler filler filler filler filler filler
28+
filler filler filler filler filler filler filler filler filler filler filler
29+
filler filler filler filler filler filler filler filler filler filler filler
30+
filler filler filler filler filler filler filler filler filler filler filler
31+
filler filler filler filler filler filler filler filler filler filler filler
32+
filler filler filler filler filler filler filler filler filler filler filler
33+
filler filler filler filler filler filler filler filler filler filler filler
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<style>
3+
body { margin: 0; }
4+
</style>
5+
<script>
6+
for (var i = 0; i < 10000; i++)
7+
document.write("filler ");
8+
</script>
9+
10+
<div id="target" style="width:100px; height:100px; background:green;"></div>
11+
12+
<script>
13+
for (var i = 0; i < 10000; i++)
14+
document.write("filler ");
15+
window.scrollTo(0, target.offsetTop);
16+
</script>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<style>
3+
html { writing-mode:vertical-rl; }
4+
</style>
5+
<div style="block-size:10000px;"></div>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<!DOCTYPE html>
2+
<style>
3+
#iframe {
4+
display: block;
5+
width: 100%;
6+
height: 100px;
7+
}
8+
#scrollable {
9+
position: relative;
10+
overflow: auto;
11+
height: 100px;
12+
}
13+
#shapeshifter {
14+
position: relative;
15+
overflow: auto;
16+
height: 100px;
17+
}
18+
@media print {
19+
#shapeshifter {
20+
display: flex;
21+
overflow: visible;
22+
}
23+
24+
#shapeshifter * {
25+
display: none;
26+
}
27+
}
28+
</style>
29+
<iframe id="iframe" src="iframe-with-square.html"></iframe>
30+
<div id="scrollable">
31+
<script>
32+
for (var i = 0; i < 200; i++)
33+
document.write("filler ");
34+
</script>
35+
<div id="scrollabletarget" style="width:100px; height:100px; background:green;"></div>
36+
<script>
37+
for (var i = 0; i < 200; i++)
38+
document.write("filler ");
39+
</script>
40+
</div>
41+
<div id="shapeshifter">
42+
<script>
43+
for (var i = 0; i < 200; i++)
44+
document.write("filler ");
45+
</script>
46+
<div id="shapeshiftertarget" style="width:100px; height:100px; background:green;"></div>
47+
<script>
48+
for (var i = 0; i < 200; i++)
49+
document.write("filler ");
50+
</script>
51+
</div>
52+
53+
<script>
54+
onload = function() {
55+
var scroll = iframe.contentWindow.document.getElementById("target").offsetTop;
56+
iframe.contentWindow.scrollTo(0, scroll);
57+
scrollable.scrollTop = scrollabletarget.offsetTop;
58+
shapeshifter.scrollTop = shapeshiftertarget.offsetTop;
59+
}
60+
</script>

components/printing/renderer/print_render_frame_helper.cc

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,6 @@ class PrepareFrameAndViewForPrint : public blink::WebViewClient,
825825
bool owns_web_view_ = false;
826826
blink::WebPrintParams web_print_params_;
827827
gfx::Size prev_view_size_;
828-
gfx::Size prev_scroll_offset_;
829828
uint32_t expected_pages_count_ = 0;
830829
base::OnceClosure on_ready_;
831830
const bool should_print_backgrounds_;
@@ -895,15 +894,6 @@ void PrepareFrameAndViewForPrint::ResizeForPrinting() {
895894
if (IsPrintingNodeOrPdfFrame(frame(), node_to_print_))
896895
return;
897896

898-
// Backup size and offset if it's a local frame.
899-
blink::WebView* web_view = frame_.view();
900-
if (blink::WebFrame* web_frame = web_view->MainFrame()) {
901-
// TODO(lukasza, weili): Support restoring scroll offset of a remote main
902-
// frame - https://crbug.com/734815.
903-
if (web_frame->IsWebLocalFrame())
904-
prev_scroll_offset_ = web_frame->ToWebLocalFrame()->GetScrollOffset();
905-
}
906-
907897
prev_view_size_ = frame()->LocalRoot()->FrameWidget()->Size();
908898
frame()->LocalRoot()->FrameWidget()->Resize(print_layout_size);
909899
}
@@ -1036,13 +1026,6 @@ void PrepareFrameAndViewForPrint::RestoreSize() {
10361026
return;
10371027

10381028
frame()->LocalRoot()->FrameWidget()->Resize(prev_view_size_);
1039-
blink::WebView* web_view = frame_.GetFrame()->View();
1040-
if (blink::WebFrame* web_frame = web_view->MainFrame()) {
1041-
// TODO(lukasza, weili): Support restoring scroll offset of a remote main
1042-
// frame - https://crbug.com/734815.
1043-
if (web_frame->IsWebLocalFrame())
1044-
web_frame->ToWebLocalFrame()->SetScrollOffset(prev_scroll_offset_);
1045-
}
10461029
}
10471030

10481031
void PrepareFrameAndViewForPrint::FinishPrinting() {

third_party/blink/renderer/core/dom/container_node.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,10 @@ void ContainerNode::WillRemoveChildren() {
658658
ChildFrameDisconnector::kDescendantsOnly);
659659
}
660660

661+
LayoutBox* ContainerNode::GetLayoutBoxForScrolling() const {
662+
return GetLayoutBox();
663+
}
664+
661665
void ContainerNode::Trace(Visitor* visitor) const {
662666
visitor->Trace(first_child_);
663667
visitor->Trace(last_child_);

third_party/blink/renderer/core/dom/container_node.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ class CORE_EXPORT ContainerNode : public Node {
385385

386386
virtual bool ChildrenCanHaveStyle() const { return true; }
387387

388+
// This is similar to GetLayoutBox(), but returns nullptr if it's not
389+
// scrollable. Some elements override this to delegate scroll operations to
390+
// a descendant LayoutBox.
391+
virtual LayoutBox* GetLayoutBoxForScrolling() const;
392+
388393
void Trace(Visitor*) const override;
389394

390395
protected:

third_party/blink/renderer/core/dom/element.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
323323
void scrollBy(const ScrollToOptions*);
324324
void scrollTo(double x, double y);
325325
void scrollTo(const ScrollToOptions*);
326-
// This is similar to GetLayoutBox(), but returns nullptr if it's not
327-
// scrollable. Some elements override this to delegate scroll operations to
328-
// a descendant LayoutBox.
329-
virtual LayoutBox* GetLayoutBoxForScrolling() const;
326+
LayoutBox* GetLayoutBoxForScrolling() const override;
330327

331328
IntRect BoundsInViewport() const;
332329
// Returns an intersection rectangle of the bounds rectangle and the visual

0 commit comments

Comments
 (0)