Changeset 195064 in webkit


Ignore:
Timestamp:
Jan 14, 2016 11:13:26 AM (8 years ago)
Author:
hyatt@apple.com
Message:

Avoid downloading the wrong image for <picture> elements.
https://bugs.webkit.org/show_bug.cgi?id=153027

Reviewed by Dean Jackson.

Source/WebCore:

Added test in fast/picture.

  • html/HTMLImageElement.cpp:

(WebCore::HTMLImageElement::HTMLImageElement):
(WebCore::HTMLImageElement::~HTMLImageElement):
(WebCore::HTMLImageElement::createForJSConstructor):
(WebCore::HTMLImageElement::bestFitSourceFromPictureElement):
(WebCore::HTMLImageElement::insertedInto):
(WebCore::HTMLImageElement::removedFrom):
(WebCore::HTMLImageElement::pictureElement):
(WebCore::HTMLImageElement::setPictureElement):
(WebCore::HTMLImageElement::width):

  • html/HTMLImageElement.h:

(WebCore::HTMLImageElement::hasShadowControls):

  • html/HTMLPictureElement.h:
  • html/parser/HTMLConstructionSite.cpp:

(WebCore::HTMLConstructionSite::createHTMLElement):

  • html/parser/HTMLPreloadScanner.cpp:

(WebCore::TokenPreloadScanner::StartTagScanner::processAttribute):

Images that are built underneath a <picture> element are now connected
to that picture element via a setPictureNode call from the parser. This
ensures that the correct <source> elements are examined before checking the image.

This connection between images and their picture owners is handled using a static
HashMap in HTMLImageElement. This connection is made both from the parser and from
DOM insertions, and the map is queried now instead of looking directly at the
image's parentNode().

LayoutTests:

  • fast/picture/image-picture-loads-1x-expected.txt: Added.
  • fast/picture/image-picture-loads-1x.html: Added.
Location:
trunk
Files:
3 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r195060 r195064  
     12016-01-14  Dave Hyatt  <hyatt@apple.com>
     2
     3        Avoid downloading the wrong image for <picture> elements.
     4        https://bugs.webkit.org/show_bug.cgi?id=153027
     5
     6        Reviewed by Dean Jackson.
     7
     8        * fast/picture/image-picture-loads-1x-expected.txt: Added.
     9        * fast/picture/image-picture-loads-1x.html: Added.
     10
    1112016-01-14  Youenn Fablet  <youenn.fablet@crf.canon.fr>
    212
  • trunk/LayoutTests/platform/ios-simulator/TestExpectations

    r194937 r195064  
    28402840webkit.org/b/152141 fast/picture/image-picture-invalid.html [ Skip ]
    28412841webkit.org/b/152141 fast/picture/image-picture-nested.html [ Skip ]
    2842 webkit.org/b/153043 fast/picture/image-picture-loads-1x.html [ Skip ]
    28432842webkit.org/b/152992 http/tests/loading/preload-picture-invalid.html [ Skip ]
    28442843webkit.org/b/152992 http/tests/loading/preload-picture-nested.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r195059 r195064  
     12016-01-14  Dave Hyatt  <hyatt@apple.com>
     2
     3        Avoid downloading the wrong image for <picture> elements.
     4        https://bugs.webkit.org/show_bug.cgi?id=153027
     5
     6        Reviewed by Dean Jackson.
     7
     8        Added test in fast/picture.
     9
     10        * html/HTMLImageElement.cpp:
     11        (WebCore::HTMLImageElement::HTMLImageElement):
     12        (WebCore::HTMLImageElement::~HTMLImageElement):
     13        (WebCore::HTMLImageElement::createForJSConstructor):
     14        (WebCore::HTMLImageElement::bestFitSourceFromPictureElement):
     15        (WebCore::HTMLImageElement::insertedInto):
     16        (WebCore::HTMLImageElement::removedFrom):
     17        (WebCore::HTMLImageElement::pictureElement):
     18        (WebCore::HTMLImageElement::setPictureElement):
     19        (WebCore::HTMLImageElement::width):
     20        * html/HTMLImageElement.h:
     21        (WebCore::HTMLImageElement::hasShadowControls):
     22        * html/HTMLPictureElement.h:
     23        * html/parser/HTMLConstructionSite.cpp:
     24        (WebCore::HTMLConstructionSite::createHTMLElement):
     25        * html/parser/HTMLPreloadScanner.cpp:
     26        (WebCore::TokenPreloadScanner::StartTagScanner::processAttribute):
     27
     28        Images that are built underneath a <picture> element are now connected
     29        to that picture element via a setPictureNode call from the parser. This
     30        ensures that the correct <source> elements are examined before checking the image.
     31
     32        This connection between images and their picture owners is handled using a static
     33        HashMap in HTMLImageElement. This connection is made both from the parser and from
     34        DOM insertions, and the map is queried now instead of looking directly at the
     35        image's parentNode().
     36
    1372016-01-14  Commit Queue  <commit-queue@webkit.org>
    238
  • trunk/Source/WebCore/html/HTMLImageElement.cpp

    r194934 r195064  
    5454using namespace HTMLNames;
    5555
     56typedef HashMap<const HTMLImageElement*, WeakPtr<HTMLPictureElement>> PictureOwnerMap;
     57static PictureOwnerMap* gPictureOwnerMap = nullptr;
     58
    5659HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
    5760    : HTMLElement(tagName, document)
     
    8386    if (m_form)
    8487        m_form->removeImgElement(this);
     88    setPictureElement(nullptr);
    8589}
    8690
     
    141145ImageCandidate HTMLImageElement::bestFitSourceFromPictureElement()
    142146{
    143     auto* parent = parentNode();
    144     if (!is<HTMLPictureElement>(parent))
     147    auto* picture = pictureElement();
     148    if (!picture)
    145149        return { };
    146     auto* picture = downcast<HTMLPictureElement>(parent);
    147150    picture->clearViewportDependentResults();
    148151    document().removeViewportDependentPicture(*picture);
    149     for (Node* child = parent->firstChild(); child && child != this; child = child->nextSibling()) {
     152    for (Node* child = picture->firstChild(); child && child != this; child = child->nextSibling()) {
    150153        if (!is<HTMLSourceElement>(*child))
    151154            continue;
     
    164167                continue;
    165168        }
    166         MediaQueryEvaluator evaluator(document().printing() ? "print" : "screen", document().frame(), computedStyle());
     169        MediaQueryEvaluator evaluator(document().printing() ? "print" : "screen", document().frame(), document().documentElement() ? document().documentElement()->computedStyle() : nullptr);
    167170        bool evaluation = evaluator.evalCheckingViewportDependentResults(source.mediaQuerySet(), picture->viewportDependentResults());
    168171        if (picture->hasViewportDependentResults())
     
    314317        document().addImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
    315318
    316     if (is<HTMLPictureElement>(parentNode()))
     319    if (is<HTMLPictureElement>(parentNode())) {
     320        setPictureElement(&downcast<HTMLPictureElement>(*parentNode()));
    317321        selectImageSource();
     322    }
    318323
    319324    // If we have been inserted from a renderer-less document,
     
    332337    if (insertionPoint.inDocument() && !m_lowercasedUsemap.isNull())
    333338        document().removeImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
    334 
     339   
     340    if (is<HTMLPictureElement>(parentNode()))
     341        setPictureElement(nullptr);
     342   
    335343    m_form = nullptr;
    336344    HTMLElement::removedFrom(insertionPoint);
    337345}
    338346
     347HTMLPictureElement* HTMLImageElement::pictureElement() const
     348{
     349    if (!gPictureOwnerMap || !gPictureOwnerMap->contains(this))
     350        return nullptr;
     351    HTMLPictureElement* result = gPictureOwnerMap->get(this).get();
     352    if (!result)
     353        gPictureOwnerMap->remove(this);
     354    return result;
     355}
     356   
     357void HTMLImageElement::setPictureElement(HTMLPictureElement* pictureElement)
     358{
     359    if (!pictureElement) {
     360        if (gPictureOwnerMap)
     361            gPictureOwnerMap->remove(this);
     362        return;
     363    }
     364   
     365    if (!gPictureOwnerMap)
     366        gPictureOwnerMap = new PictureOwnerMap();
     367    gPictureOwnerMap->add(this, pictureElement->createWeakPtr());
     368}
     369   
    339370int HTMLImageElement::width(bool ignorePendingStylesheets)
    340371{
  • trunk/Source/WebCore/html/HTMLImageElement.h

    r194934 r195064  
    8888
    8989    bool hasShadowControls() const { return m_experimentalImageMenuEnabled; }
     90   
     91    HTMLPictureElement* pictureElement() const;
     92    void setPictureElement(HTMLPictureElement*);
    9093
    9194protected:
     
    128131    HTMLFormElement* m_form;
    129132    HTMLFormElement* m_formSetByParser;
     133
    130134    CompositeOperator m_compositeOperator;
    131135    AtomicString m_bestFitImageURL;
  • trunk/Source/WebCore/html/HTMLPictureElement.h

    r193859 r195064  
    4747    bool viewportChangeAffectedPicture();
    4848
     49    WeakPtr<HTMLPictureElement> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
     50
    4951private:
    5052    HTMLPictureElement(const QualifiedName&, Document&);
    5153   
     54    WeakPtrFactory<HTMLPictureElement> m_weakFactory { this };
    5255    Vector<std::unique_ptr<MediaQueryResult>> m_viewportDependentMediaQueryResults;
    5356
  • trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp

    r194934 r195064  
    3737#include "HTMLFormElement.h"
    3838#include "HTMLHtmlElement.h"
     39#include "HTMLImageElement.h"
    3940#include "HTMLOptGroupElement.h"
    4041#include "HTMLOptionElement.h"
    4142#include "HTMLParserIdioms.h"
     43#include "HTMLPictureElement.h"
    4244#include "HTMLScriptElement.h"
    4345#include "HTMLTemplateElement.h"
     
    641643    bool insideTemplateElement = !ownerDocument.frame();
    642644    RefPtr<Element> element = HTMLElementFactory::createElement(tagName, ownerDocument, insideTemplateElement ? nullptr : form(), true);
     645   
     646    // FIXME: This is a hack to connect images to pictures before the image has
     647    // been inserted into the document. It can be removed once asynchronous image
     648    // loading is working.
     649    if (is<HTMLPictureElement>(currentNode()) && is<HTMLImageElement>(*element.get()))
     650        downcast<HTMLImageElement>(*element.get()).setPictureElement(&downcast<HTMLPictureElement>(currentNode()));
     651
    643652    setAttributes(element.get(), token, m_parserContentPolicy);
    644653    ASSERT(element->isHTMLElement());
  • trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp

    r194865 r195064  
    209209                Ref<MediaQuerySet> mediaSet = MediaQuerySet::createAllowingDescriptionSyntax(attributeValue);
    210210                Vector<std::unique_ptr<MediaQueryResult>> viewportDependentMediaQueryResults;
    211                 MediaQueryEvaluator evaluator(document.printing() ? "print" : "screen", document.frame(), document.documentElement()->computedStyle());
     211                MediaQueryEvaluator evaluator(document.printing() ? "print" : "screen", document.frame(), document.documentElement() ? document.documentElement()->computedStyle() : nullptr);
    212212                m_mediaMatched = evaluator.evalCheckingViewportDependentResults(mediaSet.ptr(), viewportDependentMediaQueryResults);
    213213            }
Note: See TracChangeset for help on using the changeset viewer.