| Index: Source/core/html/HTMLImageElement.cpp
|
| diff --git a/Source/core/html/HTMLImageElement.cpp b/Source/core/html/HTMLImageElement.cpp
|
| index ceeb1ede0923b0b2912ddc8e3cd7f60df49ccb64..96c18ae7921a80ebb1cb716318768c4a626d8550 100644
|
| --- a/Source/core/html/HTMLImageElement.cpp
|
| +++ b/Source/core/html/HTMLImageElement.cpp
|
| @@ -47,6 +47,30 @@ namespace WebCore {
|
|
|
| using namespace HTMLNames;
|
|
|
| +class HTMLImageElement::Listener FINAL : public MediaQueryListListener {
|
| +public:
|
| + static RefPtrWillBeRawPtr<Listener> create(HTMLImageElement* element)
|
| + {
|
| + return adoptRefWillBeNoop(new Listener(element));
|
| + }
|
| +
|
| + virtual void call() OVERRIDE
|
| + {
|
| + if (m_element)
|
| + m_element->notifyMediaQueryChanged();
|
| + }
|
| +
|
| + void clearElement() { m_element = nullptr; }
|
| + virtual void trace(Visitor* visitor) OVERRIDE
|
| + {
|
| + visitor->trace(m_element);
|
| + MediaQueryListListener::trace(visitor);
|
| + }
|
| +private:
|
| + Listener(HTMLImageElement* element) : m_element(element) { }
|
| + RawPtrWillBeMember<HTMLImageElement> m_element;
|
| +};
|
| +
|
| HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bool createdByParser)
|
| : HTMLElement(imgTag, document)
|
| , m_imageLoader(HTMLImageLoader::create(this))
|
| @@ -54,6 +78,8 @@ HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bo
|
| , m_imageDevicePixelRatio(1.0f)
|
| , m_formWasSetByParser(false)
|
| , m_elementCreatedByParser(createdByParser)
|
| + , m_intrinsicSizingViewportDependant(false)
|
| + , m_effectiveSizeViewportDependant(false)
|
| {
|
| ScriptWrappable::init(this);
|
| if (form && form->inDocument()) {
|
| @@ -81,18 +107,41 @@ PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& docu
|
| HTMLImageElement::~HTMLImageElement()
|
| {
|
| #if !ENABLE(OILPAN)
|
| + if (m_listener)
|
| + m_listener->clearElement();
|
| if (m_form)
|
| m_form->disassociate(*this);
|
| #endif
|
| }
|
|
|
| +void HTMLImageElement::createMediaQueryListIfDoesNotExist()
|
| +{
|
| + if (m_mediaQueryList)
|
| + return;
|
| + RefPtrWillBeRawPtr<MediaQuerySet> set = MediaQuerySet::create(MediaTypeNames::all);
|
| + m_listener = Listener::create(this);
|
| + m_mediaQueryList = MediaQueryList::create(&document().mediaQueryMatcher(), set.release());
|
| + m_mediaQueryList->addListener(m_listener);
|
| + m_mediaQueryList->alwaysUpdate();
|
| +}
|
| +
|
| void HTMLImageElement::trace(Visitor* visitor)
|
| {
|
| visitor->trace(m_imageLoader);
|
| visitor->trace(m_form);
|
| + visitor->trace(m_listener);
|
| + visitor->trace(m_mediaQueryList);
|
| HTMLElement::trace(visitor);
|
| }
|
|
|
| +void HTMLImageElement::notifyMediaQueryChanged()
|
| +{
|
| + // Re-selecting the source URL in order to pick a more fitting resource
|
| + // And update the image's intrinsic dimensions when the viewport changes.
|
| + // Picking of a better fitting resource is UA dependant, not spec required.
|
| + selectSourceURL(ImageLoader::UpdateForce);
|
| +}
|
| +
|
| PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document& document, int width, int height)
|
| {
|
| RefPtrWillBeRawPtr<HTMLImageElement> image = adoptRefWillBeNoop(new HTMLImageElement(document));
|
| @@ -181,6 +230,8 @@ void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidat
|
| float candidateDensity = candidate.density();
|
| if (candidateDensity >= 0)
|
| m_imageDevicePixelRatio = 1.0 / candidateDensity;
|
| + if (candidate.resourceWidth() > 0)
|
| + m_intrinsicSizingViewportDependant = true;
|
| if (renderer() && renderer()->isImage())
|
| toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRatio);
|
| }
|
| @@ -246,7 +297,9 @@ ImageCandidate HTMLImageElement::findBestFitImageFromPictureParent()
|
| if (!source->mediaQueryMatches())
|
| continue;
|
|
|
| - unsigned effectiveSize = SizesAttributeParser::findEffectiveSize(source->fastGetAttribute(sizesAttr), MediaValuesDynamic::create(document()));
|
| + SizesAttributeParser parser = SizesAttributeParser(MediaValuesDynamic::create(document()), source->fastGetAttribute(sizesAttr));
|
| + unsigned effectiveSize = parser.length();
|
| + m_effectiveSizeViewportDependant = parser.viewportDependant();
|
| ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().devicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr));
|
| if (candidate.isEmpty())
|
| continue;
|
| @@ -568,11 +621,18 @@ void HTMLImageElement::selectSourceURL(ImageLoader::UpdateFromElementBehavior be
|
|
|
| if (!foundURL) {
|
| unsigned effectiveSize = 0;
|
| - if (RuntimeEnabledFeatures::pictureSizesEnabled())
|
| - effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttribute(sizesAttr), MediaValuesDynamic::create(document()));
|
| + if (RuntimeEnabledFeatures::pictureSizesEnabled()) {
|
| + SizesAttributeParser parser = SizesAttributeParser(MediaValuesDynamic::create(document()), fastGetAttribute(sizesAttr));
|
| + effectiveSize = parser.length();
|
| + m_effectiveSizeViewportDependant = parser.viewportDependant();
|
| + }
|
| ImageCandidate candidate = bestFitSourceForImageAttributes(document().devicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
|
| setBestFitURLAndDPRFromImageCandidate(candidate);
|
| }
|
| + if (m_intrinsicSizingViewportDependant && m_effectiveSizeViewportDependant) {
|
| + createMediaQueryListIfDoesNotExist();
|
| + document().mediaQueryMatcher().addMediaQueryList(m_mediaQueryList.get());
|
| + }
|
| imageLoader().updateFromElement(behavior);
|
| }
|
|
|
|
|