Skip to content

Commit e58064d

Browse files
committed
LocalFrame::setPrinting doesn't set printing state on remote frame children.
https://bugs.webkit.org/show_bug.cgi?id=299049 <rdar://problem/160808134> Reviewed by Alex Christensen. Makes the recursive setPrinting frame walk work correctly across local/remote frame boundaries, and also synchronizes the boolean printing state to all processes such that LocalFrame::shouldUsePrintingLayout can correctly detect if it's the root printing frame. The latter of these would be a good candidate for being moved to FrameTreeSyncData, once that supports broadcasting mutations from a web process. Adds a new test that checks that the print bool state is propagated recursively into remote descendants by using an @media print rule in a cross origin iframe. It also checks that LocalFrame::shouldUsePrintingLayout correctly reads the bool printing state from remote ancestors by using a percentage width in the iframe. If remote ancestor state isn't available, the frame contents will layout to the page size instead of the viewport created by the iframe element (since it will think it is the print root). Test: http/tests/site-isolation/print-with-iframe.html * LayoutTests/http/tests/site-isolation/print-with-iframe-expected.txt: Added. * LayoutTests/http/tests/site-isolation/print-with-iframe.html: Added. * LayoutTests/http/tests/site-isolation/resources/green-square-if-printed.html: Added. * Source/WebCore/loader/EmptyClients.cpp: (WebCore::EmptyFrameLoaderClient::setPrinting): * Source/WebCore/loader/EmptyFrameLoaderClient.h: * Source/WebCore/loader/FrameLoaderClient.h: * Source/WebCore/page/Frame.cpp: (WebCore::Frame::isPrinting const): (WebCore::Frame::setPrinting): * Source/WebCore/page/Frame.h: * Source/WebCore/page/LocalFrame.cpp: (WebCore::LocalFrame::setPrinting): (WebCore::LocalFrame::shouldUsePrintingLayout const): * Source/WebCore/page/LocalFrame.h: * Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in: * Source/WebKit/UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::setFramePrinting): * Source/WebKit/UIProcess/WebPageProxy.h: * Source/WebKit/UIProcess/WebPageProxy.messages.in: * Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::setPrinting): * Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h: * Source/WebKit/WebProcess/WebCoreSupport/WebLocalFrameLoaderClient.cpp: (WebKit::WebLocalFrameLoaderClient::setPrinting): * Source/WebKit/WebProcess/WebCoreSupport/WebLocalFrameLoaderClient.h: * Source/WebKit/WebProcess/WebCoreSupport/WebRemoteFrameClient.cpp: (WebKit::WebRemoteFrameClient::setPrinting): * Source/WebKit/WebProcess/WebCoreSupport/WebRemoteFrameClient.h: * Source/WebKit/WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::updateOpener): (WebKit::WebPage::setFramePrinting): * Source/WebKit/WebProcess/WebPage/WebPage.h: * Source/WebKit/WebProcess/WebPage/WebPage.messages.in: * Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h: (WebFrameLoaderClient::setPrinting): Canonical link: https://commits.webkit.org/300374@main
1 parent 7bf168f commit e58064d

25 files changed

+171
-16
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
layer at (0,0) size 1000x170
2+
RenderView at (0,0) size 1000x170
3+
layer at (0,0) size 1000x170
4+
RenderBlock {HTML} at (0,0) size 1000x170
5+
RenderBody {BODY} at (8,8) size 984x154 [bgcolor=#0000FF]
6+
RenderText {#text} at (0,0) size 0x0
7+
layer at (8,8) size 300x150
8+
RenderIFrame {IFRAME} at (0,0) size 300x150
9+
layer at (0,0) size 300x150
10+
RenderView at (0,0) size 300x150
11+
layer at (0,0) size 300x116
12+
RenderBlock {HTML} at (0,0) size 300x116
13+
RenderBody {BODY} at (8,8) size 284x100 [bgcolor=#FFFFFF]
14+
RenderBlock {DIV} at (0,0) size 284x100 [bgcolor=#008000]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!-- webkit-test-runner [ SiteIsolationEnabled=true ] -->
2+
<!DOCTYPE HTML>
3+
<head>
4+
<script>
5+
if (window.testRunner) {
6+
testRunner.waitUntilDone();
7+
testRunner.setPrinting();
8+
}
9+
10+
onmessage = async (event) => {
11+
if (window.testRunner && event.data == "onload") {
12+
testRunner.notifyDone();
13+
}
14+
}
15+
</script>
16+
</head>
17+
<body bgcolor=blue>
18+
<iframe src="http://localhost:8000/site-isolation/resources/green-square-if-printed.html" frameborder=0></iframe>
19+
</body>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE HTML>
2+
<html>
3+
<head>
4+
<style>
5+
body {
6+
background: white;
7+
}
8+
div {
9+
width: 100%;
10+
height: 10px;
11+
background: red;
12+
}
13+
@media print {
14+
div {
15+
height: 100px;
16+
background: green;
17+
}
18+
}
19+
</style>
20+
</head>
21+
<body>
22+
<div></div>
23+
<script>
24+
onload = () => { window.parent.postMessage("onload", "*"); }
25+
</script>
26+
</body>
27+
</html>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
layer at (0,0) size 1000x171
2+
RenderView at (0,0) size 1000x171
3+
layer at (0,0) size 1000x171
4+
RenderBlock {HTML} at (0,0) size 1000x171
5+
RenderBody {BODY} at (8,8) size 984x155 [bgcolor=#0000FF]
6+
RenderText {#text} at (0,0) size 0x0
7+
layer at (8,8) size 300x150
8+
RenderIFrame {IFRAME} at (0,0) size 300x150
9+
layer at (0,0) size 300x150
10+
RenderView at (0,0) size 300x150
11+
layer at (0,0) size 300x116
12+
RenderBlock {HTML} at (0,0) size 300x116
13+
RenderBody {BODY} at (8,8) size 284x100 [bgcolor=#FFFFFF]
14+
RenderBlock {DIV} at (0,0) size 284x100 [bgcolor=#008000]

Source/WebCore/loader/EmptyClients.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,10 @@ void EmptyFrameLoaderClient::updateOpener(const Frame&)
674674
{
675675
}
676676

677+
void EmptyFrameLoaderClient::setPrinting(bool, FloatSize, FloatSize, float, AdjustViewSize)
678+
{
679+
}
680+
677681
void EmptyFrameLoaderClient::dispatchWillSendSubmitEvent(Ref<FormState>&&)
678682
{
679683
}

Source/WebCore/loader/EmptyFrameLoaderClient.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class WEBCORE_EXPORT EmptyFrameLoaderClient : public LocalFrameLoaderClient {
104104
void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, const ResourceResponse& redirectResponse, FormState*, const String&, std::optional<NavigationIdentifier>, std::optional<HitTestResult>&&, bool, IsPerformingHTTPFallback, SandboxFlags, PolicyDecisionMode, FramePolicyFunction&&) final;
105105
void updateSandboxFlags(SandboxFlags) final;
106106
void updateOpener(const Frame&) final;
107+
void setPrinting(bool, FloatSize, FloatSize, float, AdjustViewSize) final;
107108
void cancelPolicyCheck() final;
108109

109110
void dispatchUnableToImplementPolicy(const ResourceError&) final;

Source/WebCore/loader/FrameLoaderClient.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class NavigationAction;
3838
class ResourceRequest;
3939
class ResourceResponse;
4040

41+
enum class AdjustViewSize : bool;
4142
enum class PolicyDecisionMode;
4243
enum class SandboxFlag : uint16_t;
4344

@@ -51,6 +52,7 @@ class FrameLoaderClient {
5152
virtual void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, const ResourceResponse& redirectResponse, FormState*, const String& clientRedirectSourceForHistory, std::optional<NavigationIdentifier>, std::optional<HitTestResult>&&, bool hasOpener, IsPerformingHTTPFallback, SandboxFlags, PolicyDecisionMode, FramePolicyFunction&&) = 0;
5253
virtual void updateSandboxFlags(SandboxFlags) = 0;
5354
virtual void updateOpener(const Frame&) = 0;
55+
virtual void setPrinting(bool printing, FloatSize pageSize, FloatSize originalPageSize, float maximumShrinkRatio, AdjustViewSize) = 0;
5456
virtual ~FrameLoaderClient() = default;
5557
};
5658

Source/WebCore/page/Frame.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,16 @@ Ref<FrameInspectorController> Frame::protectedInspectorController()
345345
return m_inspectorController.get();
346346
}
347347

348+
bool Frame::isPrinting() const
349+
{
350+
return m_isPrinting;
351+
}
352+
353+
void Frame::setPrinting(bool printing, FloatSize pageSize, FloatSize originalPageSize, float maximumShrinkRatio, AdjustViewSize shouldAdjustViewSize, NotifyUIProcess notifyUIProcess)
354+
{
355+
m_isPrinting = printing;
356+
if (notifyUIProcess == NotifyUIProcess::Yes && m_settings->siteIsolationEnabled())
357+
loaderClient().setPrinting(printing, pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
358+
}
359+
348360
} // namespace WebCore

Source/WebCore/page/Frame.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace WebCore {
4040

4141
class DOMWindow;
4242
class Event;
43+
class FloatSize;
4344
class FrameConsoleClient;
4445
class FrameInspectorController;
4546
class FrameLoaderClient;
@@ -53,6 +54,8 @@ class Settings;
5354
class WeakPtrImplWithEventTargetData;
5455
class WindowProxy;
5556

57+
enum class AdjustViewSize : bool;
58+
5659
struct OwnerPermissionsPolicyData;
5760

5861
enum class AdvancedPrivacyProtections : uint16_t;
@@ -151,6 +154,9 @@ class Frame : public RefCountedAndCanMakeWeakPtr<Frame> {
151154
FrameConsoleClient& console() { return m_consoleClient.get(); }
152155
const FrameConsoleClient& console() const { return m_consoleClient.get(); }
153156

157+
WEBCORE_EXPORT virtual void setPrinting(bool printing, FloatSize pageSize, FloatSize originalPageSize, float maximumShrinkRatio, AdjustViewSize, NotifyUIProcess = NotifyUIProcess::Yes);
158+
WEBCORE_EXPORT bool isPrinting() const;
159+
154160
protected:
155161
Frame(Page&, FrameIdentifier, FrameType, HTMLFrameOwnerElement*, Frame* parent, Frame* opener, Ref<FrameTreeSyncData>&&, AddToFrameTree = AddToFrameTree::Yes);
156162
void resetWindowProxy();
@@ -173,6 +179,7 @@ class Frame : public RefCountedAndCanMakeWeakPtr<Frame> {
173179
WeakPtr<Frame> m_opener;
174180
WeakHashSet<Frame> m_openedFrames;
175181
std::unique_ptr<OwnerPermissionsPolicyData> m_ownerPermisssionsPolicyOverride;
182+
bool m_isPrinting { false };
176183

177184
Ref<FrameTreeSyncData> m_frameTreeSyncData;
178185

Source/WebCore/page/LocalFrame.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -671,11 +671,13 @@ bool LocalFrame::requestDOMPasteAccess(DOMPasteAccessCategory pasteAccessCategor
671671
return false;
672672
}
673673

674-
void LocalFrame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSize shouldAdjustViewSize)
674+
void LocalFrame::setPrinting(bool printing, FloatSize pageSize, FloatSize originalPageSize, float maximumShrinkRatio, AdjustViewSize shouldAdjustViewSize, NotifyUIProcess notifyUIProcess)
675675
{
676676
if (!view() || !document())
677677
return;
678678

679+
Frame::setPrinting(printing, pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize, notifyUIProcess);
680+
679681
RefPtr document = m_doc;
680682
// In setting printing, we should not validate resources already cached for the document.
681683
// See https://bugs.webkit.org/show_bug.cgi?id=43704
@@ -700,18 +702,15 @@ void LocalFrame::setPrinting(bool printing, const FloatSize& pageSize, const Flo
700702
}
701703

702704
// Subframes of the one we're printing don't lay out to the page size.
703-
for (RefPtr child = tree().firstChild(); child; child = child->tree().nextSibling()) {
704-
if (RefPtr localFrame = dynamicDowncast<LocalFrame>(child.get()))
705-
localFrame->setPrinting(printing, FloatSize(), FloatSize(), 0, shouldAdjustViewSize);
706-
}
705+
for (RefPtr child = tree().firstChild(); child; child = child->tree().nextSibling())
706+
child->setPrinting(printing, FloatSize(), FloatSize(), 0, shouldAdjustViewSize);
707707
}
708708

709709
bool LocalFrame::shouldUsePrintingLayout() const
710710
{
711711
// Only top frame being printed should be fit to page size.
712712
// Subframes should be constrained by parents only.
713-
SUPPRESS_UNCOUNTED_LOCAL auto* parent = dynamicDowncast<LocalFrame>(tree().parent());
714-
return m_doc->printing() && (!parent || !parent->m_doc->printing());
713+
return isPrinting() && (!tree().parent() || !tree().parent()->isPrinting());
715714
}
716715

717716
FloatSize LocalFrame::resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize)

0 commit comments

Comments
 (0)