Title: [252828] trunk
Revision
252828
Author
[email protected]
Date
2019-11-23 02:19:42 -0800 (Sat, 23 Nov 2019)

Log Message

Media queries in img sizes attribute don't evaluate dynamically
https://bugs.webkit.org/show_bug.cgi?id=204521

Reviewed by Simon Fraser.

Source/WebCore:

Tests: fast/images/sizes-dynamic-001.html
       fast/images/sizes-dynamic-002.html

* css/MediaQueryEvaluator.cpp:
(WebCore::MediaQueryEvaluator::evaluateForChanges const):

Add a helper function for evaluating dynamic results for changes.

* css/MediaQueryEvaluator.h:
(WebCore::MediaQueryDynamicResults::isEmpty const):
* css/parser/SizesAttributeParser.cpp:
(WebCore::SizesAttributeParser::SizesAttributeParser):
(WebCore::SizesAttributeParser::mediaConditionMatches):

Gather MediaQueryDynamicResults

* css/parser/SizesAttributeParser.h:
* dom/Document.cpp:
(WebCore::Document::updateElementsAffectedByMediaQueries):
(WebCore::Document::addDynamicMediaQueryDependentImage):
(WebCore::Document::removeDynamicMediaQueryDependentImage):

Replace viewport/appearance specific mechanism with a unified one (they were all invoked together anyway).
Make it about HTMLImageElement rather than HTMLPictureElement since that is the only client in this patch.

(WebCore::Document::checkViewportDependentPictures): Deleted.
(WebCore::Document::checkAppearanceDependentPictures): Deleted.
(WebCore::Document::addViewportDependentPicture): Deleted.
(WebCore::Document::removeViewportDependentPicture): Deleted.
(WebCore::Document::addAppearanceDependentPicture): Deleted.
(WebCore::Document::removeAppearanceDependentPicture): Deleted.
* dom/Document.h:
* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::~HTMLImageElement):
(WebCore::HTMLImageElement::bestFitSourceFromPictureElement):
(WebCore::HTMLImageElement::evaluateDynamicMediaQueryDependencies):
(WebCore::HTMLImageElement::selectImageSource):

Gather MediaQueryDynamicResults from all paths.

(WebCore::HTMLImageElement::didMoveToNewDocument):
* html/HTMLImageElement.h:
* html/HTMLPictureElement.cpp:
(WebCore::HTMLPictureElement::~HTMLPictureElement):
(WebCore::HTMLPictureElement::didMoveToNewDocument):
(WebCore::HTMLPictureElement::viewportChangeAffectedPicture const): Deleted.
(WebCore::HTMLPictureElement::appearanceChangeAffectedPicture const): Deleted.

Move the media query dependency code to HTMLImageElement since thats where it is actually needed.

* html/HTMLPictureElement.h:
* rendering/RenderImage.cpp:
(WebCore::RenderImage::setImageDevicePixelRatio):

Update rendering also if only the pixel ratio changes.

* rendering/RenderImage.h:
(WebCore::RenderImage::setImageDevicePixelRatio): Deleted.

LayoutTests:

* fast/images/sizes-dynamic-001-expected.html: Added.
* fast/images/sizes-dynamic-001.html: Added.
* fast/images/sizes-dynamic-002-expected.html: Added.
* fast/images/sizes-dynamic-002.html: Added.

Copied and modified from imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/sizes/sizes-dynamic-*
because we don't support reftest-wait (webkit.org/b/186045).

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (252827 => 252828)


--- trunk/LayoutTests/ChangeLog	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/LayoutTests/ChangeLog	2019-11-23 10:19:42 UTC (rev 252828)
@@ -1,3 +1,18 @@
+2019-11-23  Antti Koivisto  <[email protected]>
+
+        Media queries in img sizes attribute don't evaluate dynamically
+        https://bugs.webkit.org/show_bug.cgi?id=204521
+
+        Reviewed by Simon Fraser.
+
+        * fast/images/sizes-dynamic-001-expected.html: Added.
+        * fast/images/sizes-dynamic-001.html: Added.
+        * fast/images/sizes-dynamic-002-expected.html: Added.
+        * fast/images/sizes-dynamic-002.html: Added.
+
+        Copied and modified from imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/sizes/sizes-dynamic-*
+        because we don't support reftest-wait (webkit.org/b/186045).
+
 2019-11-22  Per Arne Vollan  <[email protected]>
 
         Some tests are failing on Win64

Added: trunk/LayoutTests/fast/images/sizes-dynamic-001-expected.html (0 => 252828)


--- trunk/LayoutTests/fast/images/sizes-dynamic-001-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/sizes-dynamic-001-expected.html	2019-11-23 10:19:42 UTC (rev 252828)
@@ -0,0 +1,4 @@
+<!doctype html>
+<title>Test reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href=""
+<iframe width="500" height="500" srcdoc='<!doctype html><img alt="FAIL" srcset="../../imported/w3c/web-platform-tests/images/green-256x256.png 100w" style="max-width: 100%" sizes="10px">'></iframe>

Added: trunk/LayoutTests/fast/images/sizes-dynamic-001.html (0 => 252828)


--- trunk/LayoutTests/fast/images/sizes-dynamic-001.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/sizes-dynamic-001.html	2019-11-23 10:19:42 UTC (rev 252828)
@@ -0,0 +1,28 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>Image intrinsic size specified via sizes attribute reacts properly to media changes</title>
+<link rel="author" title="Emilio Cobos Álvarez" href=""
+<link rel="match" href=""
+<link rel="help" href=""
+<link rel="help" href=""
+<script>
+// Use WPT version after reftest-wait is implemented.
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+function frameLoaded(frame) {
+  frame.width = "500";
+  let img = frame.contentDocument.querySelector('img');
+
+  // Trigger the viewport resize, which will trigger the image load task.
+  img.offsetWidth;
+
+  // Wait for the image load task to run.
+  setTimeout(() => {
+     document.documentElement.removeAttribute("class");
+     if (window.testRunner)
+         testRunner.notifyDone();
+  }, 0);
+}
+</script>
+<iframe _onload_="frameLoaded(this)" width="200" height="500" srcdoc='<!doctype html><img srcset="../../imported/w3c/web-platform-tests/images/green-256x256.png 100w" style="max-width: 100%" sizes="(min-width: 400px) 10px, 20px">'></iframe>

Added: trunk/LayoutTests/fast/images/sizes-dynamic-002-expected.html (0 => 252828)


--- trunk/LayoutTests/fast/images/sizes-dynamic-002-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/sizes-dynamic-002-expected.html	2019-11-23 10:19:42 UTC (rev 252828)
@@ -0,0 +1,4 @@
+<!doctype html>
+<title>Test reference</title>
+<link rel="author" title="Emilio Cobos Álvarez" href=""
+<iframe width="500" height="500" srcdoc='<!doctype html><img alt="FAIL" srcset="../../imported/w3c/web-platform-tests/images/green-256x256.png 100w" style="max-width: 100%" sizes="10px">'></iframe>

Added: trunk/LayoutTests/fast/images/sizes-dynamic-002.html (0 => 252828)


--- trunk/LayoutTests/fast/images/sizes-dynamic-002.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/sizes-dynamic-002.html	2019-11-23 10:19:42 UTC (rev 252828)
@@ -0,0 +1,41 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>Image intrinsic size specified via sizes attribute reacts properly to media changes in Shadow DOM</title>
+<link rel="author" title="Emilio Cobos Álvarez" href=""
+<link rel="match" href=""
+<link rel="help" href=""
+<link rel="help" href=""
+<script>
+// Use WPT version after reftest-wait is implemented.
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+function frameLoaded(frame) {
+  let doc = frame.contentDocument;
+  let shadow = doc.getElementById("host").attachShadow({ mode: "open" });
+
+  let img = doc.createElement("img");
+  img.srcset = "../../imported/w3c/web-platform-tests/images/green-256x256.png 100w";
+  img.style.maxWidth = "100%";
+  img.setAttribute("sizes", "(min-width: 400px) 10px, 20px");
+
+  img._onload_ = function() {
+    img.offsetWidth; // Flush layout.
+
+    frame.width = "500";
+
+    // Trigger the viewport resize, which will trigger the image load task.
+    img.offsetWidth;
+
+  // Wait for the image load task to run.
+  setTimeout(() => {
+     document.documentElement.removeAttribute("class");
+     if (window.testRunner)
+         testRunner.notifyDone();
+  }, 0);
+  };
+
+  shadow.appendChild(img);
+}
+</script>
+<iframe _onload_="frameLoaded(this)" width="200" height="500" srcdoc='<!doctype html><div id="host"></div>'></iframe>

Modified: trunk/Source/WebCore/ChangeLog (252827 => 252828)


--- trunk/Source/WebCore/ChangeLog	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/ChangeLog	2019-11-23 10:19:42 UTC (rev 252828)
@@ -1,3 +1,69 @@
+2019-11-23  Antti Koivisto  <[email protected]>
+
+        Media queries in img sizes attribute don't evaluate dynamically
+        https://bugs.webkit.org/show_bug.cgi?id=204521
+
+        Reviewed by Simon Fraser.
+
+        Tests: fast/images/sizes-dynamic-001.html
+               fast/images/sizes-dynamic-002.html
+
+        * css/MediaQueryEvaluator.cpp:
+        (WebCore::MediaQueryEvaluator::evaluateForChanges const):
+
+        Add a helper function for evaluating dynamic results for changes.
+
+        * css/MediaQueryEvaluator.h:
+        (WebCore::MediaQueryDynamicResults::isEmpty const):
+        * css/parser/SizesAttributeParser.cpp:
+        (WebCore::SizesAttributeParser::SizesAttributeParser):
+        (WebCore::SizesAttributeParser::mediaConditionMatches):
+
+        Gather MediaQueryDynamicResults
+
+        * css/parser/SizesAttributeParser.h:
+        * dom/Document.cpp:
+        (WebCore::Document::updateElementsAffectedByMediaQueries):
+        (WebCore::Document::addDynamicMediaQueryDependentImage):
+        (WebCore::Document::removeDynamicMediaQueryDependentImage):
+
+        Replace viewport/appearance specific mechanism with a unified one (they were all invoked together anyway).
+        Make it about HTMLImageElement rather than HTMLPictureElement since that is the only client in this patch.
+
+        (WebCore::Document::checkViewportDependentPictures): Deleted.
+        (WebCore::Document::checkAppearanceDependentPictures): Deleted.
+        (WebCore::Document::addViewportDependentPicture): Deleted.
+        (WebCore::Document::removeViewportDependentPicture): Deleted.
+        (WebCore::Document::addAppearanceDependentPicture): Deleted.
+        (WebCore::Document::removeAppearanceDependentPicture): Deleted.
+        * dom/Document.h:
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::~HTMLImageElement):
+        (WebCore::HTMLImageElement::bestFitSourceFromPictureElement):
+        (WebCore::HTMLImageElement::evaluateDynamicMediaQueryDependencies):
+        (WebCore::HTMLImageElement::selectImageSource):
+
+        Gather MediaQueryDynamicResults from all paths.
+
+        (WebCore::HTMLImageElement::didMoveToNewDocument):
+        * html/HTMLImageElement.h:
+        * html/HTMLPictureElement.cpp:
+        (WebCore::HTMLPictureElement::~HTMLPictureElement):
+        (WebCore::HTMLPictureElement::didMoveToNewDocument):
+        (WebCore::HTMLPictureElement::viewportChangeAffectedPicture const): Deleted.
+        (WebCore::HTMLPictureElement::appearanceChangeAffectedPicture const): Deleted.
+
+        Move the media query dependency code to HTMLImageElement since thats where it is actually needed.
+
+        * html/HTMLPictureElement.h:
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::setImageDevicePixelRatio):
+
+        Update rendering also if only the pixel ratio changes.
+
+        * rendering/RenderImage.h:
+        (WebCore::RenderImage::setImageDevicePixelRatio): Deleted.
+
 2019-11-21  Ryosuke Niwa  <[email protected]>
 
         Use the event loop instead of DocumentEventQueue and WorkerEventQueue

Modified: trunk/Source/WebCore/css/MediaQueryEvaluator.cpp (252827 => 252828)


--- trunk/Source/WebCore/css/MediaQueryEvaluator.cpp	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/css/MediaQueryEvaluator.cpp	2019-11-23 10:19:42 UTC (rev 252828)
@@ -192,6 +192,19 @@
     return result;
 }
 
+bool MediaQueryEvaluator::evaluateForChanges(const MediaQueryDynamicResults& dynamicResults) const
+{
+    auto hasChanges = [&](auto& dynamicResultsVector) {
+        for (auto& dynamicResult : dynamicResultsVector) {
+            if (evaluate(dynamicResult._expression_) != dynamicResult.result)
+                return true;
+        }
+        return false;
+    };
+
+    return hasChanges(dynamicResults.viewport) || hasChanges(dynamicResults.appearance) || hasChanges(dynamicResults.accessibilitySettings);
+}
+
 template<typename T, typename U> bool compareValue(T a, U b, MediaFeaturePrefix op)
 {
     switch (op) {

Modified: trunk/Source/WebCore/css/MediaQueryEvaluator.h (252827 => 252828)


--- trunk/Source/WebCore/css/MediaQueryEvaluator.h	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/css/MediaQueryEvaluator.h	2019-11-23 10:19:42 UTC (rev 252828)
@@ -57,6 +57,7 @@
         appearance.appendVector(other.appearance);
         accessibilitySettings.appendVector(other.accessibilitySettings);
     }
+    bool isEmpty() const { return viewport.isEmpty() && appearance.isEmpty() && accessibilitySettings.isEmpty(); }
 };
 
 // Some of the constructors are used for cases where the device characteristics are not known.
@@ -80,6 +81,7 @@
 
     // Evaluates media query subexpression, ie "and (media-feature: value)" part.
     bool evaluate(const MediaQueryExpression&) const;
+    bool evaluateForChanges(const MediaQueryDynamicResults&) const;
 
     WEBCORE_EXPORT bool evaluate(const MediaQuerySet&, MediaQueryDynamicResults* = nullptr) const;
 

Modified: trunk/Source/WebCore/css/parser/SizesAttributeParser.cpp (252827 => 252828)


--- trunk/Source/WebCore/css/parser/SizesAttributeParser.cpp	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/css/parser/SizesAttributeParser.cpp	2019-11-23 10:19:42 UTC (rev 252828)
@@ -69,10 +69,9 @@
     return clampTo<float>(CSSPrimitiveValue::computeNonCalcLengthDouble(conversionData, type, value));
 }
     
-SizesAttributeParser::SizesAttributeParser(const String& attribute, const Document& document)
+SizesAttributeParser::SizesAttributeParser(const String& attribute, const Document& document, MediaQueryDynamicResults* mediaQueryDynamicResults)
     : m_document(document)
-    , m_length(0)
-    , m_lengthWasSet(false)
+    , m_mediaQueryDynamicResults(mediaQueryDynamicResults)
 {
     m_isValid = parse(CSSTokenizer(attribute).tokenRange());
 }
@@ -115,7 +114,7 @@
     if (!renderer)
         return false;
     auto& style = renderer->style();
-    return MediaQueryEvaluator { "screen", m_document, &style }.evaluate(mediaCondition);
+    return MediaQueryEvaluator { "screen", m_document, &style }.evaluate(mediaCondition, m_mediaQueryDynamicResults);
 }
 
 bool SizesAttributeParser::parse(CSSParserTokenRange range)

Modified: trunk/Source/WebCore/css/parser/SizesAttributeParser.h (252827 => 252828)


--- trunk/Source/WebCore/css/parser/SizesAttributeParser.h	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/css/parser/SizesAttributeParser.h	2019-11-23 10:19:42 UTC (rev 252828)
@@ -38,10 +38,11 @@
 class CSSValue;
 class Document;
 class MediaQuerySet;
+struct MediaQueryDynamicResults;
     
 class SizesAttributeParser {
 public:
-    explicit SizesAttributeParser(const String&, const Document&);
+    SizesAttributeParser(const String&, const Document&, MediaQueryDynamicResults* = nullptr);
 
     float length();
 
@@ -57,9 +58,10 @@
 
     const Document& m_document;
     RefPtr<MediaQuerySet> m_mediaCondition;
-    float m_length;
-    bool m_lengthWasSet;
-    bool m_isValid;
+    MediaQueryDynamicResults* m_mediaQueryDynamicResults { nullptr };
+    float m_length { 0 };
+    bool m_lengthWasSet { false };
+    bool m_isValid { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/Document.cpp (252827 => 252828)


--- trunk/Source/WebCore/dom/Document.cpp	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/dom/Document.cpp	2019-11-23 10:19:42 UTC (rev 252828)
@@ -3946,8 +3946,15 @@
 void Document::updateElementsAffectedByMediaQueries()
 {
     ScriptDisallowedScope::InMainThread scriptDisallowedScope;
-    checkViewportDependentPictures();
-    checkAppearanceDependentPictures();
+
+    // FIXME: copyToVector doesn't work with WeakHashSet
+    Vector<Ref<HTMLImageElement>> images;
+    images.reserveInitialCapacity(m_dynamicMediaQueryDependentImages.computeSize());
+    for (auto& image : m_dynamicMediaQueryDependentImages)
+        images.append(image);
+
+    for (auto& image : images)
+        image->evaluateDynamicMediaQueryDependencies();
 }
 
 void Document::evaluateMediaQueriesAndReportChanges()
@@ -3958,30 +3965,6 @@
     m_mediaQueryMatcher->evaluateAll();
 }
 
-void Document::checkViewportDependentPictures()
-{
-    Vector<HTMLPictureElement*, 16> changedPictures;
-    HashSet<HTMLPictureElement*>::iterator end = m_viewportDependentPictures.end();
-    for (HashSet<HTMLPictureElement*>::iterator it = m_viewportDependentPictures.begin(); it != end; ++it) {
-        if ((*it)->viewportChangeAffectedPicture())
-            changedPictures.append(*it);
-    }
-    for (auto* picture : changedPictures)
-        picture->sourcesChanged();
-}
-
-void Document::checkAppearanceDependentPictures()
-{
-    Vector<HTMLPictureElement*, 16> changedPictures;
-    for (auto* picture : m_appearanceDependentPictures) {
-        if (picture->appearanceChangeAffectedPicture())
-            changedPictures.append(picture);
-    }
-
-    for (auto* picture : changedPictures)
-        picture->sourcesChanged();
-}
-
 void Document::updateViewportUnitsOnResize()
 {
     if (!hasStyleWithViewportUnits())
@@ -7432,26 +7415,16 @@
         enforceSandboxFlags(SandboxOrigin);
 }
 
-void Document::addViewportDependentPicture(HTMLPictureElement& picture)
+void Document::addDynamicMediaQueryDependentImage(HTMLImageElement& element)
 {
-    m_viewportDependentPictures.add(&picture);
+    m_dynamicMediaQueryDependentImages.add(element);
 }
 
-void Document::removeViewportDependentPicture(HTMLPictureElement& picture)
+void Document::removeDynamicMediaQueryDependentImage(HTMLImageElement& element)
 {
-    m_viewportDependentPictures.remove(&picture);
+    m_dynamicMediaQueryDependentImages.remove(element);
 }
 
-void Document::addAppearanceDependentPicture(HTMLPictureElement& picture)
-{
-    m_appearanceDependentPictures.add(&picture);
-}
-
-void Document::removeAppearanceDependentPicture(HTMLPictureElement& picture)
-{
-    m_appearanceDependentPictures.remove(&picture);
-}
-
 void Document::scheduleTimedRenderingUpdate()
 {
 #if ENABLE(INTERSECTION_OBSERVER)

Modified: trunk/Source/WebCore/dom/Document.h (252827 => 252828)


--- trunk/Source/WebCore/dom/Document.h	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/dom/Document.h	2019-11-23 10:19:42 UTC (rev 252828)
@@ -144,7 +144,6 @@
 class HTMLMapElement;
 class HTMLMediaElement;
 class HTMLVideoElement;
-class HTMLPictureElement;
 class HTMLScriptElement;
 class HitTestLocation;
 class HitTestRequest;
@@ -1393,12 +1392,9 @@
     bool shouldEnforceContentDispositionAttachmentSandbox() const;
     void applyContentDispositionAttachmentSandbox();
 
-    void addViewportDependentPicture(HTMLPictureElement&);
-    void removeViewportDependentPicture(HTMLPictureElement&);
+    void addDynamicMediaQueryDependentImage(HTMLImageElement&);
+    void removeDynamicMediaQueryDependentImage(HTMLImageElement&);
 
-    void addAppearanceDependentPicture(HTMLPictureElement&);
-    void removeAppearanceDependentPicture(HTMLPictureElement&);
-
     void scheduleTimedRenderingUpdate();
 
 #if ENABLE(INTERSECTION_OBSERVER)
@@ -1654,9 +1650,6 @@
     void invalidateDOMCookieCache();
     void didLoadResourceSynchronously() final;
 
-    void checkViewportDependentPictures();
-    void checkAppearanceDependentPictures();
-
     bool canNavigateInternal(Frame& targetFrame);
     bool isNavigationBlockedByThirdPartyIFrameRedirectBlocking(Frame& targetFrame, const URL& destinationURL);
 
@@ -1831,8 +1824,7 @@
     UniqueRef<FullscreenManager> m_fullscreenManager;
 #endif
 
-    HashSet<HTMLPictureElement*> m_viewportDependentPictures;
-    HashSet<HTMLPictureElement*> m_appearanceDependentPictures;
+    WeakHashSet<HTMLImageElement> m_dynamicMediaQueryDependentImages;
 
 #if ENABLE(INTERSECTION_OBSERVER)
     Vector<WeakPtr<IntersectionObserver>> m_intersectionObservers;

Modified: trunk/Source/WebCore/html/HTMLImageElement.cpp (252827 => 252828)


--- trunk/Source/WebCore/html/HTMLImageElement.cpp	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/html/HTMLImageElement.cpp	2019-11-23 10:19:42 UTC (rev 252828)
@@ -95,6 +95,8 @@
 
 HTMLImageElement::~HTMLImageElement()
 {
+    document().removeDynamicMediaQueryDependentImage(*this);
+
     if (m_form)
         m_form->removeImgElement(this);
     setPictureElement(nullptr);
@@ -160,10 +162,6 @@
     if (!picture)
         return { };
 
-    document().removeViewportDependentPicture(*picture);
-    document().removeAppearanceDependentPicture(*picture);
-
-    MediaQueryDynamicResults mediaQueryDynamicResults;
     ImageCandidate candidate;
 
     for (RefPtr<Node> child = picture->firstChild(); child && child != this; child = child->nextSibling()) {
@@ -189,38 +187,50 @@
         auto* queries = source.parsedMediaAttribute(document());
         LOG(MediaQueries, "HTMLImageElement %p bestFitSourceFromPictureElement evaluating media queries", this);
 
-        auto evaluation = !queries || evaluator.evaluate(*queries, &mediaQueryDynamicResults);
+        auto evaluation = !queries || evaluator.evaluate(*queries, &m_mediaQueryDynamicResults);
         if (!evaluation)
             continue;
 
-        auto sourceSize = SizesAttributeParser(source.attributeWithoutSynchronization(sizesAttr).string(), document()).length();
+        SizesAttributeParser sizesParser(source.attributeWithoutSynchronization(sizesAttr).string(), document(), &m_mediaQueryDynamicResults);
+        auto sourceSize = sizesParser.length();
+
         candidate = bestFitSourceForImageAttributes(document().deviceScaleFactor(), nullAtom(), srcset, sourceSize);
         if (!candidate.isEmpty())
             break;
     }
 
-    picture->setMediaQueryDynamicResults(WTFMove(mediaQueryDynamicResults));
+    return candidate;
+}
 
-    // FIXME: This is not handling accessibility settings dependent media queries.
-    if (picture->hasViewportDependentResults())
-        document().addViewportDependentPicture(*picture);
-    if (picture->hasAppearanceDependentResults())
-        document().addAppearanceDependentPicture(*picture);
+void HTMLImageElement::evaluateDynamicMediaQueryDependencies()
+{
+    auto documentElement = makeRefPtr(document().documentElement());
+    MediaQueryEvaluator evaluator { document().printing() ? "print" : "screen", document(), documentElement ? documentElement->computedStyle() : nullptr };
 
-    return candidate;
+    if (!evaluator.evaluateForChanges(m_mediaQueryDynamicResults))
+        return;
+
+    selectImageSource();
 }
 
 void HTMLImageElement::selectImageSource()
 {
+    m_mediaQueryDynamicResults = { };
+    document().removeDynamicMediaQueryDependentImage(*this);
+
     // First look for the best fit source from our <picture> parent if we have one.
     ImageCandidate candidate = bestFitSourceFromPictureElement();
     if (candidate.isEmpty()) {
         // If we don't have a <picture> or didn't find a source, then we use our own attributes.
-        auto sourceSize = SizesAttributeParser(attributeWithoutSynchronization(sizesAttr).string(), document()).length();
+        SizesAttributeParser sizesParser(attributeWithoutSynchronization(sizesAttr).string(), document(), &m_mediaQueryDynamicResults);
+        auto sourceSize = sizesParser.length();
         candidate = bestFitSourceForImageAttributes(document().deviceScaleFactor(), attributeWithoutSynchronization(srcAttr), attributeWithoutSynchronization(srcsetAttr), sourceSize);
     }
     setBestFitURLAndDPRFromImageCandidate(candidate);
     m_imageLoader->updateFromElementIgnoringPreviousError();
+
+    if (!m_mediaQueryDynamicResults.isEmpty())
+        document().addDynamicMediaQueryDependentImage(*this);
 }
 
 void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomString& value)
@@ -671,6 +681,8 @@
 
 void HTMLImageElement::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
 {
+    oldDocument.removeDynamicMediaQueryDependentImage(*this);
+
     m_imageLoader->elementDidMoveToNewDocument();
     HTMLElement::didMoveToNewDocument(oldDocument, newDocument);
 }

Modified: trunk/Source/WebCore/html/HTMLImageElement.h (252827 => 252828)


--- trunk/Source/WebCore/html/HTMLImageElement.h	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/html/HTMLImageElement.h	2019-11-23 10:19:42 UTC (rev 252828)
@@ -28,6 +28,8 @@
 #include "GraphicsLayer.h"
 #include "GraphicsTypes.h"
 #include "HTMLElement.h"
+#include "MediaQueryEvaluator.h"
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -131,6 +133,8 @@
     bool isDroppedImagePlaceholder() const { return m_isDroppedImagePlaceholder; }
     void setIsDroppedImagePlaceholder() { m_isDroppedImagePlaceholder = true; }
 
+    void evaluateDynamicMediaQueryDependencies();
+
 protected:
     HTMLImageElement(const QualifiedName&, Document&, HTMLFormElement* = nullptr, bool createdByParser = false);
 
@@ -198,6 +202,7 @@
 
     RefPtr<EditableImageReference> m_editableImage;
     WeakPtr<HTMLPictureElement> m_pictureElement;
+    MediaQueryDynamicResults m_mediaQueryDynamicResults;
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     String m_pendingClonedAttachmentID;

Modified: trunk/Source/WebCore/html/HTMLPictureElement.cpp (252827 => 252828)


--- trunk/Source/WebCore/html/HTMLPictureElement.cpp	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/html/HTMLPictureElement.cpp	2019-11-23 10:19:42 UTC (rev 252828)
@@ -44,14 +44,10 @@
 
 HTMLPictureElement::~HTMLPictureElement()
 {
-    document().removeViewportDependentPicture(*this);
-    document().removeAppearanceDependentPicture(*this);
 }
 
 void HTMLPictureElement::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
 {
-    oldDocument.removeViewportDependentPicture(*this);
-    oldDocument.removeAppearanceDependentPicture(*this);
     HTMLElement::didMoveToNewDocument(oldDocument, newDocument);
     sourcesChanged();
 }
@@ -67,30 +63,6 @@
         element.selectImageSource();
 }
 
-bool HTMLPictureElement::viewportChangeAffectedPicture() const
-{
-    auto documentElement = makeRefPtr(document().documentElement());
-    MediaQueryEvaluator evaluator { document().printing() ? "print" : "screen", document(), documentElement ? documentElement->computedStyle() : nullptr };
-    for (auto& result : m_mediaQueryDynamicResults.viewport) {
-        LOG(MediaQueries, "HTMLPictureElement %p viewportChangeAffectedPicture evaluating media queries", this);
-        if (evaluator.evaluate(result._expression_) != result.result)
-            return true;
-    }
-    return false;
-}
-
-bool HTMLPictureElement::appearanceChangeAffectedPicture() const
-{
-    auto documentElement = makeRefPtr(document().documentElement());
-    MediaQueryEvaluator evaluator { document().printing() ? "print" : "screen", document(), documentElement ? documentElement->computedStyle() : nullptr };
-    for (auto& result : m_mediaQueryDynamicResults.appearance) {
-        LOG(MediaQueries, "HTMLPictureElement %p appearanceChangeAffectedPicture evaluating media queries", this);
-        if (evaluator.evaluate(result._expression_) != result.result)
-            return true;
-    }
-    return false;
-}
-
 #if USE(SYSTEM_PREVIEW)
 bool HTMLPictureElement::isSystemPreviewImage() const
 {

Modified: trunk/Source/WebCore/html/HTMLPictureElement.h (252827 => 252828)


--- trunk/Source/WebCore/html/HTMLPictureElement.h	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/html/HTMLPictureElement.h	2019-11-23 10:19:42 UTC (rev 252828)
@@ -26,7 +26,6 @@
 #pragma once
 
 #include "HTMLElement.h"
-#include "MediaQueryEvaluator.h"
 
 namespace WebCore {
 
@@ -38,15 +37,6 @@
 
     void sourcesChanged();
 
-
-    void setMediaQueryDynamicResults(MediaQueryDynamicResults&& results) { m_mediaQueryDynamicResults = results; }
-
-    bool hasViewportDependentResults() const { return m_mediaQueryDynamicResults.viewport.size(); }
-    bool hasAppearanceDependentResults() const { return m_mediaQueryDynamicResults.appearance.size(); }
-
-    bool viewportChangeAffectedPicture() const;
-    bool appearanceChangeAffectedPicture() const;
-
 #if USE(SYSTEM_PREVIEW)
     WEBCORE_EXPORT bool isSystemPreviewImage() const;
 #endif
@@ -55,8 +45,6 @@
     HTMLPictureElement(const QualifiedName&, Document&);
 
     void didMoveToNewDocument(Document& oldDocument, Document& newDocument) final;
-
-    MediaQueryDynamicResults m_mediaQueryDynamicResults;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderImage.cpp (252827 => 252828)


--- trunk/Source/WebCore/rendering/RenderImage.cpp	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/rendering/RenderImage.cpp	2019-11-23 10:19:42 UTC (rev 252828)
@@ -380,6 +380,15 @@
         page().didFinishLoadingImageForElement(downcast<HTMLImageElement>(*element()));
 }
 
+void RenderImage::setImageDevicePixelRatio(float factor)
+{
+    if (m_imageDevicePixelRatio == factor)
+        return;
+
+    m_imageDevicePixelRatio = factor;
+    intrinsicSizeChanged();
+}
+
 bool RenderImage::isShowingMissingOrImageError() const
 {
     return !imageResource().cachedImage() || imageResource().errorOccurred();

Modified: trunk/Source/WebCore/rendering/RenderImage.h (252827 => 252828)


--- trunk/Source/WebCore/rendering/RenderImage.h	2019-11-23 05:37:46 UTC (rev 252827)
+++ trunk/Source/WebCore/rendering/RenderImage.h	2019-11-23 10:19:42 UTC (rev 252828)
@@ -66,7 +66,7 @@
     const String& altText() const { return m_altText; }
     void setAltText(const String& altText) { m_altText = altText; }
 
-    inline void setImageDevicePixelRatio(float factor) { m_imageDevicePixelRatio = factor; }
+    void setImageDevicePixelRatio(float factor);
     float imageDevicePixelRatio() const { return m_imageDevicePixelRatio; }
 
     void setHasShadowControls(bool hasShadowControls) { m_hasShadowControls = hasShadowControls; }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to