- Revision
- 282020
- Author
- akeer...@apple.com
- Date
- 2021-09-03 13:33:19 -0700 (Fri, 03 Sep 2021)
Log Message
iframes should get an opaque background when the embedding element and embedded root color-schemes do not match
https://bugs.webkit.org/show_bug.cgi?id=228124
<rdar://problem/80922070>
Reviewed by Simon Fraser.
LayoutTests/imported/w3c:
Add missing support file.
* web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/support/dark-frame-ref.html: Added.
Source/WebCore:
Currently, iframes always have a transparent underlying background
color. The existing behavior is undesirable, as it can result in
scenarios where text in iframes is illegible, due to a mismatch between
the used color scheme of the embedding element and embedded root.
To address this problem, it has been resolved [1] that iframes should get
an opaque background when the embedding element and embedded root color-schemes
do not match. The background color used should be appropriate to the
embedded root color-scheme.
[1] https://drafts.csswg.org/css-color-adjust-1/#color-scheme-effect
Test: imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/support/dark-frame-ref.html
* page/FrameView.cpp:
(WebCore::FrameView::updateBackgroundRecursively):
Ensure subframes have a base background color appropriate to their
color-scheme, rather than simply inheriting their parent's base
background color.
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
Moved root element background painting logic into RenderView.
* rendering/RenderView.cpp:
(WebCore::RenderView::shouldPaintBaseBackground const):
Paint the base background for the root element of an iframe if its used
color scheme does not match the color scheme of the embedding element.
* rendering/RenderView.h:
LayoutTests:
Remove failure expectations for newly passing tests.
* TestExpectations:
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (282019 => 282020)
--- trunk/LayoutTests/ChangeLog 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/LayoutTests/ChangeLog 2021-09-03 20:33:19 UTC (rev 282020)
@@ -1,3 +1,15 @@
+2021-09-03 Aditya Keerthi <akeer...@apple.com>
+
+ iframes should get an opaque background when the embedding element and embedded root color-schemes do not match
+ https://bugs.webkit.org/show_bug.cgi?id=228124
+ <rdar://problem/80922070>
+
+ Reviewed by Simon Fraser.
+
+ Remove failure expectations for newly passing tests.
+
+ * TestExpectations:
+
2021-09-03 Alan Bujtas <za...@apple.com>
Add a layout test for custom scrollbars with relative width/height values
Modified: trunk/LayoutTests/TestExpectations (282019 => 282020)
--- trunk/LayoutTests/TestExpectations 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/LayoutTests/TestExpectations 2021-09-03 20:33:19 UTC (rev 282020)
@@ -4523,10 +4523,6 @@
webkit.org/b/214454 imported/w3c/web-platform-tests/css/css-backgrounds/border-width-pixel-snapping-001-a.html [ ImageOnlyFailure ]
webkit.org/b/214455 imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-change-checkbox.html [ ImageOnlyFailure ]
-webkit.org/b/214455 imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background.html [ ImageOnlyFailure ]
-webkit.org/b/214455 imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-mismatch-alpha.html [ ImageOnlyFailure ]
-webkit.org/b/214455 imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-mismatch-opaque.html [ ImageOnlyFailure ]
-webkit.org/b/214455 imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-mismatch-opaque-cross-origin.sub.html [ ImageOnlyFailure ]
webkit.org/b/214455 imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-visited-link-initial.html [ ImageOnlyFailure ]
webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/conic-gradient-angle.html [ ImageOnlyFailure ]
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (282019 => 282020)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-09-03 20:33:19 UTC (rev 282020)
@@ -1,3 +1,15 @@
+2021-09-03 Aditya Keerthi <akeer...@apple.com>
+
+ iframes should get an opaque background when the embedding element and embedded root color-schemes do not match
+ https://bugs.webkit.org/show_bug.cgi?id=228124
+ <rdar://problem/80922070>
+
+ Reviewed by Simon Fraser.
+
+ Add missing support file.
+
+ * web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/support/dark-frame-ref.html: Added.
+
2021-09-03 Myles C. Maxfield <mmaxfi...@apple.com>
@font-face rules accessed over file: urls to a file which does not exist are not visible to document.fonts
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/support/dark-frame-ref.html (0 => 282020)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/support/dark-frame-ref.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/support/dark-frame-ref.html 2021-09-03 20:33:19 UTC (rev 282020)
@@ -0,0 +1,5 @@
+<!doctype html>
+<style>
+ p { color: green }
+</style>
+<p>This text should be green and the background should be the same as the top document.</p>
Modified: trunk/Source/WebCore/ChangeLog (282019 => 282020)
--- trunk/Source/WebCore/ChangeLog 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/Source/WebCore/ChangeLog 2021-09-03 20:33:19 UTC (rev 282020)
@@ -1,3 +1,45 @@
+2021-09-03 Aditya Keerthi <akeer...@apple.com>
+
+ iframes should get an opaque background when the embedding element and embedded root color-schemes do not match
+ https://bugs.webkit.org/show_bug.cgi?id=228124
+ <rdar://problem/80922070>
+
+ Reviewed by Simon Fraser.
+
+ Currently, iframes always have a transparent underlying background
+ color. The existing behavior is undesirable, as it can result in
+ scenarios where text in iframes is illegible, due to a mismatch between
+ the used color scheme of the embedding element and embedded root.
+
+ To address this problem, it has been resolved [1] that iframes should get
+ an opaque background when the embedding element and embedded root color-schemes
+ do not match. The background color used should be appropriate to the
+ embedded root color-scheme.
+
+ [1] https://drafts.csswg.org/css-color-adjust-1/#color-scheme-effect
+
+ Test: imported/w3c/web-platform-tests/css/css-color-adjust/rendering/dark-color-scheme/support/dark-frame-ref.html
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::updateBackgroundRecursively):
+
+ Ensure subframes have a base background color appropriate to their
+ color-scheme, rather than simply inheriting their parent's base
+ background color.
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+
+ Moved root element background painting logic into RenderView.
+
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::shouldPaintBaseBackground const):
+
+ Paint the base background for the root element of an iframe if its used
+ color scheme does not match the color scheme of the embedding element.
+
+ * rendering/RenderView.h:
+
2021-09-03 Myles C. Maxfield <mmaxfi...@apple.com>
@font-face rules accessed over file: urls to a file which does not exist are not visible to document.fonts
Modified: trunk/Source/WebCore/page/FrameView.cpp (282019 => 282020)
--- trunk/Source/WebCore/page/FrameView.cpp 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/Source/WebCore/page/FrameView.cpp 2021-09-03 20:33:19 UTC (rev 282020)
@@ -3034,13 +3034,15 @@
#else
static const auto cssValueControlBackground = CSSValueWindow;
#endif
- Color baseBackgroundColor = backgroundColor.value_or(RenderTheme::singleton().systemColor(cssValueControlBackground, styleColorOptions()));
-#else
- Color baseBackgroundColor = backgroundColor.value_or(Color::white);
#endif
for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
- if (FrameView* view = frame->view()) {
+ if (auto* view = frame->view()) {
+#if HAVE(OS_DARK_MODE_SUPPORT)
+ auto baseBackgroundColor = backgroundColor.value_or(RenderTheme::singleton().systemColor(cssValueControlBackground, view->styleColorOptions()));
+#else
+ auto baseBackgroundColor = backgroundColor.value_or(Color::white);
+#endif
view->setTransparent(!baseBackgroundColor.isVisible());
view->setBaseBackgroundColor(baseBackgroundColor);
if (view->needsLayout())
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (282019 => 282020)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2021-09-03 20:33:19 UTC (rev 282020)
@@ -37,8 +37,6 @@
#include "FrameView.h"
#include "GeometryUtilities.h"
#include "GraphicsContext.h"
-#include "HTMLFrameOwnerElement.h"
-#include "HTMLFrameSetElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "ImageBuffer.h"
@@ -898,30 +896,9 @@
context.beginTransparencyLayer(1);
}
- // Only fill with a base color (e.g., white) if we're the root document, since iframes/frames with
- // no background in the child document should show the parent's background.
- bool isOpaqueRoot = false;
+ auto isOpaqueRoot = false;
if (isRoot) {
- isOpaqueRoot = true;
- if (!bgLayer.next() && !bgColor.isOpaque()) {
- HTMLFrameOwnerElement* ownerElement = document().ownerElement();
- if (ownerElement) {
- if (!ownerElement->hasTagName(frameTag)) {
- // Locate the <body> element using the DOM. This is easier than trying
- // to crawl around a render tree with potential :before/:after content and
- // anonymous blocks created by inline <body> tags etc. We can locate the <body>
- // render object very easily via the DOM.
- if (HTMLElement* body = document().bodyOrFrameset()) {
- // Can't scroll a frameset document anyway.
- isOpaqueRoot = is<HTMLFrameSetElement>(*body);
- } else {
- // SVG documents and XML documents with SVG root nodes are transparent.
- isOpaqueRoot = !document().hasSVGRootNode();
- }
- }
- } else
- isOpaqueRoot = !view().frameView().isTransparent();
- }
+ isOpaqueRoot = bgLayer.next() || bgColor.isOpaque() || view().shouldPaintBaseBackground();
view().frameView().setContentIsOpaque(isOpaqueRoot);
}
Modified: trunk/Source/WebCore/rendering/RenderView.cpp (282019 => 282020)
--- trunk/Source/WebCore/rendering/RenderView.cpp 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/Source/WebCore/rendering/RenderView.cpp 2021-09-03 20:33:19 UTC (rev 282020)
@@ -29,6 +29,7 @@
#include "GraphicsContext.h"
#include "HTMLBodyElement.h"
#include "HTMLFrameOwnerElement.h"
+#include "HTMLFrameSetElement.h"
#include "HTMLHtmlElement.h"
#include "HTMLIFrameElement.h"
#include "HitTestResult.h"
@@ -593,6 +594,46 @@
return rootBackgroundRenderer->style().hasEntirelyFixedBackground();
return false;
}
+
+bool RenderView::shouldPaintBaseBackground() const
+{
+ auto& document = this->document();
+ auto& frameView = this->frameView();
+ auto* ownerElement = document.ownerElement();
+
+ // Fill with a base color if we're the root document.
+ if (!ownerElement)
+ return !frameView.isTransparent();
+
+ if (ownerElement->hasTagName(frameTag))
+ return true;
+
+ // Locate the <body> element using the DOM. This is easier than trying
+ // to crawl around a render tree with potential :before/:after content and
+ // anonymous blocks created by inline <body> tags etc. We can locate the <body>
+ // render object very easily via the DOM.
+ auto* body = document.bodyOrFrameset();
+
+ // SVG documents and XML documents with SVG root nodes are transparent.
+ if (!body)
+ return !document.hasSVGRootNode();
+
+ // Can't scroll a frameset document anyway.
+ if (is<HTMLFrameSetElement>(*body))
+ return true;
+
+ auto* frameRenderer = ownerElement->renderer();
+ if (!frameRenderer)
+ return false;
+
+ // iframes should fill with a base color if the used color scheme of the
+ // element and the used color scheme of the embedded document’s root
+ // element do not match.
+ if (frameView.useDarkAppearance() != frameRenderer->useDarkAppearance())
+ return !frameView.isTransparent();
+
+ return false;
+}
LayoutRect RenderView::unextendedBackgroundRect() const
{
Modified: trunk/Source/WebCore/rendering/RenderView.h (282019 => 282020)
--- trunk/Source/WebCore/rendering/RenderView.h 2021-09-03 20:29:31 UTC (rev 282019)
+++ trunk/Source/WebCore/rendering/RenderView.h 2021-09-03 20:33:19 UTC (rev 282020)
@@ -141,6 +141,8 @@
// Renderer that paints the root background has background-images which all have background-attachment: fixed.
bool rootBackgroundIsEntirelyFixed() const;
+ bool shouldPaintBaseBackground() const;
+
IntSize viewportSizeForCSSViewportUnits() const;
bool hasQuotesNeedingUpdate() const { return m_hasQuotesNeedingUpdate; }