| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights |
| 5 * reserved. | 5 * reserved. |
| 6 * Copyright (C) 2010 Google Inc. All rights reserved. | 6 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 HTMLImageElement::HTMLImageElement(Document& document, | 89 HTMLImageElement::HTMLImageElement(Document& document, |
| 90 HTMLFormElement* form, | 90 HTMLFormElement* form, |
| 91 bool createdByParser) | 91 bool createdByParser) |
| 92 : HTMLElement(imgTag, document), | 92 : HTMLElement(imgTag, document), |
| 93 ActiveScriptWrappable(this), | 93 ActiveScriptWrappable(this), |
| 94 m_imageLoader(HTMLImageLoader::create(this)), | 94 m_imageLoader(HTMLImageLoader::create(this)), |
| 95 m_imageDevicePixelRatio(1.0f), | 95 m_imageDevicePixelRatio(1.0f), |
| 96 m_source(nullptr), | 96 m_source(nullptr), |
| 97 m_layoutDisposition(LayoutDisposition::PrimaryContent), |
| 97 m_formWasSetByParser(false), | 98 m_formWasSetByParser(false), |
| 98 m_elementCreatedByParser(createdByParser), | 99 m_elementCreatedByParser(createdByParser), |
| 99 m_useFallbackContent(false), | |
| 100 m_isFallbackImage(false), | 100 m_isFallbackImage(false), |
| 101 m_referrerPolicy(ReferrerPolicyDefault) { | 101 m_referrerPolicy(ReferrerPolicyDefault) { |
| 102 setHasCustomStyleCallbacks(); | 102 setHasCustomStyleCallbacks(); |
| 103 if (form && form->isConnected()) { | 103 if (form && form->isConnected()) { |
| 104 m_form = form; | 104 m_form = form; |
| 105 m_formWasSetByParser = true; | 105 m_formWasSetByParser = true; |
| 106 m_form->associate(*this); | 106 m_form->associate(*this); |
| 107 m_form->didAssociateByParser(); | 107 m_form->didAssociateByParser(); |
| 108 } | 108 } |
| 109 } | 109 } |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 document().devicePixelRatio(), sourceSize(*source), | 333 document().devicePixelRatio(), sourceSize(*source), |
| 334 source->fastGetAttribute(srcsetAttr), &document()); | 334 source->fastGetAttribute(srcsetAttr), &document()); |
| 335 if (candidate.isEmpty()) | 335 if (candidate.isEmpty()) |
| 336 continue; | 336 continue; |
| 337 m_source = source; | 337 m_source = source; |
| 338 return candidate; | 338 return candidate; |
| 339 } | 339 } |
| 340 return ImageCandidate(); | 340 return ImageCandidate(); |
| 341 } | 341 } |
| 342 | 342 |
| 343 bool HTMLImageElement::layoutObjectIsNeeded(const ComputedStyle& style) { |
| 344 return m_layoutDisposition != LayoutDisposition::Collapsed && |
| 345 HTMLElement::layoutObjectIsNeeded(style); |
| 346 } |
| 347 |
| 343 LayoutObject* HTMLImageElement::createLayoutObject(const ComputedStyle& style) { | 348 LayoutObject* HTMLImageElement::createLayoutObject(const ComputedStyle& style) { |
| 344 const ContentData* contentData = style.contentData(); | 349 const ContentData* contentData = style.contentData(); |
| 345 if (contentData && contentData->isImage()) { | 350 if (contentData && contentData->isImage()) { |
| 346 const StyleImage* contentImage = toImageContentData(contentData)->image(); | 351 const StyleImage* contentImage = toImageContentData(contentData)->image(); |
| 347 bool errorOccurred = contentImage && contentImage->cachedImage() && | 352 bool errorOccurred = contentImage && contentImage->cachedImage() && |
| 348 contentImage->cachedImage()->errorOccurred(); | 353 contentImage->cachedImage()->errorOccurred(); |
| 349 if (!errorOccurred) | 354 if (!errorOccurred) |
| 350 return LayoutObject::createObject(this, style); | 355 return LayoutObject::createObject(this, style); |
| 351 } | 356 } |
| 352 | 357 |
| 353 if (m_useFallbackContent) | 358 switch (m_layoutDisposition) { |
| 354 return new LayoutBlockFlow(this); | 359 case LayoutDisposition::FallbackContent: |
| 355 | 360 return new LayoutBlockFlow(this); |
| 356 LayoutImage* image = new LayoutImage(this); | 361 case LayoutDisposition::PrimaryContent: { |
| 357 image->setImageResource(LayoutImageResource::create()); | 362 LayoutImage* image = new LayoutImage(this); |
| 358 image->setImageDevicePixelRatio(m_imageDevicePixelRatio); | 363 image->setImageResource(LayoutImageResource::create()); |
| 359 return image; | 364 image->setImageDevicePixelRatio(m_imageDevicePixelRatio); |
| 365 return image; |
| 366 } |
| 367 case LayoutDisposition::Collapsed: // Falls through. |
| 368 default: |
| 369 NOTREACHED(); |
| 370 return nullptr; |
| 371 } |
| 360 } | 372 } |
| 361 | 373 |
| 362 void HTMLImageElement::attachLayoutTree(const AttachContext& context) { | 374 void HTMLImageElement::attachLayoutTree(const AttachContext& context) { |
| 363 HTMLElement::attachLayoutTree(context); | 375 HTMLElement::attachLayoutTree(context); |
| 364 | 376 |
| 365 if (layoutObject() && layoutObject()->isImage()) { | 377 if (layoutObject() && layoutObject()->isImage()) { |
| 366 LayoutImage* layoutImage = toLayoutImage(layoutObject()); | 378 LayoutImage* layoutImage = toLayoutImage(layoutObject()); |
| 367 LayoutImageResource* layoutImageResource = layoutImage->imageResource(); | 379 LayoutImageResource* layoutImageResource = layoutImage->imageResource(); |
| 368 if (m_isFallbackImage) { | 380 if (m_isFallbackImage) { |
| 369 float deviceScaleFactor = blink::deviceScaleFactor(layoutImage->frame()); | 381 float deviceScaleFactor = blink::deviceScaleFactor(layoutImage->frame()); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 setBestFitURLAndDPRFromImageCandidate(candidate); | 776 setBestFitURLAndDPRFromImageCandidate(candidate); |
| 765 foundURL = true; | 777 foundURL = true; |
| 766 } | 778 } |
| 767 | 779 |
| 768 if (!foundURL) { | 780 if (!foundURL) { |
| 769 candidate = bestFitSourceForImageAttributes( | 781 candidate = bestFitSourceForImageAttributes( |
| 770 document().devicePixelRatio(), sourceSize(*this), | 782 document().devicePixelRatio(), sourceSize(*this), |
| 771 fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr), &document()); | 783 fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr), &document()); |
| 772 setBestFitURLAndDPRFromImageCandidate(candidate); | 784 setBestFitURLAndDPRFromImageCandidate(candidate); |
| 773 } | 785 } |
| 786 |
| 774 imageLoader().updateFromElement(behavior, m_referrerPolicy); | 787 imageLoader().updateFromElement(behavior, m_referrerPolicy); |
| 775 | 788 |
| 776 // Images such as data: uri's can return immediately and may already have | 789 // Images such as data: uri's can return immediately and may already have |
| 777 // errored out. | 790 // errored out. |
| 778 bool imageHasLoaded = imageLoader().image() && | 791 bool imageHasLoaded = imageLoader().image() && |
| 779 !imageLoader().image()->isLoading() && | 792 !imageLoader().image()->isLoading() && |
| 780 !imageLoader().image()->errorOccurred(); | 793 !imageLoader().image()->errorOccurred(); |
| 781 bool imageStillLoading = | 794 bool imageStillLoading = |
| 782 !imageHasLoaded && imageLoader().hasPendingActivity() && | 795 !imageHasLoaded && imageLoader().hasPendingActivity() && |
| 783 !imageLoader().hasPendingError() && !imageSourceURL().isEmpty(); | 796 !imageLoader().hasPendingError() && !imageSourceURL().isEmpty(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 795 // sufficient, because a deferred image does have pending activity, does not | 808 // sufficient, because a deferred image does have pending activity, does not |
| 796 // have a pending error, and does have a source URL, so if imageHasLoaded | 809 // have a pending error, and does have a source URL, so if imageHasLoaded |
| 797 // was correct, imageStillLoading would become wrong. | 810 // was correct, imageStillLoading would become wrong. |
| 798 // | 811 // |
| 799 // Instead of dealing with that, there's a separate check that the | 812 // Instead of dealing with that, there's a separate check that the |
| 800 // ImageResource has non-null image data associated with it, which isn't | 813 // ImageResource has non-null image data associated with it, which isn't |
| 801 // folded into imageHasLoaded above. | 814 // folded into imageHasLoaded above. |
| 802 if ((imageHasLoaded && imageHasImage) || imageStillLoading || imageIsDocument) | 815 if ((imageHasLoaded && imageHasImage) || imageStillLoading || imageIsDocument) |
| 803 ensurePrimaryContent(); | 816 ensurePrimaryContent(); |
| 804 else | 817 else |
| 805 ensureFallbackContent(); | 818 ensureCollapsedOrFallbackContent(); |
| 806 } | 819 } |
| 807 | 820 |
| 808 const KURL& HTMLImageElement::sourceURL() const { | 821 const KURL& HTMLImageElement::sourceURL() const { |
| 809 return cachedImage()->response().url(); | 822 return cachedImage()->response().url(); |
| 810 } | 823 } |
| 811 | 824 |
| 812 void HTMLImageElement::didAddUserAgentShadowRoot(ShadowRoot&) { | 825 void HTMLImageElement::didAddUserAgentShadowRoot(ShadowRoot&) { |
| 813 HTMLImageFallbackHelper::createAltTextShadowTree(*this); | 826 HTMLImageFallbackHelper::createAltTextShadowTree(*this); |
| 814 } | 827 } |
| 815 | 828 |
| 816 void HTMLImageElement::ensureFallbackForGeneratedContent() { | 829 void HTMLImageElement::ensureFallbackForGeneratedContent() { |
| 817 setUseFallbackContent(); | 830 // The special casing for generated content in createLayoutObject breaks the |
| 818 reattachFallbackContent(); | 831 // invariant that the layout object attached to this element will always be |
| 832 // appropriate for |m_layoutDisposition|. Force recreate it. |
| 833 // TODO(engedy): Remove this hack. See: https://crbug.com/671953. |
| 834 setLayoutDisposition(LayoutDisposition::FallbackContent, |
| 835 true /* forceReattach */); |
| 819 } | 836 } |
| 820 | 837 |
| 821 void HTMLImageElement::ensureFallbackContent() { | 838 void HTMLImageElement::ensureCollapsedOrFallbackContent() { |
| 822 if (m_useFallbackContent || m_isFallbackImage) | 839 if (m_isFallbackImage) |
| 823 return; | 840 return; |
| 824 setUseFallbackContent(); | 841 |
| 825 reattachFallbackContent(); | 842 bool resourceErrorIndicatesElementShouldBeCollapsed = |
| 843 imageLoader().image() && |
| 844 imageLoader().image()->resourceError().shouldCollapseInitiator(); |
| 845 setLayoutDisposition(resourceErrorIndicatesElementShouldBeCollapsed |
| 846 ? LayoutDisposition::Collapsed |
| 847 : LayoutDisposition::FallbackContent); |
| 826 } | 848 } |
| 827 | 849 |
| 828 void HTMLImageElement::ensurePrimaryContent() { | 850 void HTMLImageElement::ensurePrimaryContent() { |
| 829 if (!m_useFallbackContent) | 851 setLayoutDisposition(LayoutDisposition::PrimaryContent); |
| 830 return; | |
| 831 m_useFallbackContent = false; | |
| 832 reattachFallbackContent(); | |
| 833 } | 852 } |
| 834 | 853 |
| 835 void HTMLImageElement::reattachFallbackContent() { | 854 void HTMLImageElement::setLayoutDisposition(LayoutDisposition layoutDisposition, |
| 855 bool forceReattach) { |
| 856 if (m_layoutDisposition == layoutDisposition && !forceReattach) |
| 857 return; |
| 858 |
| 859 m_layoutDisposition = layoutDisposition; |
| 860 |
| 836 // This can happen inside of attachLayoutTree() in the middle of a recalcStyle | 861 // This can happen inside of attachLayoutTree() in the middle of a recalcStyle |
| 837 // so we need to reattach synchronously here. | 862 // so we need to reattach synchronously here. |
| 838 if (document().inStyleRecalc()) | 863 if (document().inStyleRecalc()) { |
| 839 reattachLayoutTree(); | 864 reattachLayoutTree(); |
| 840 else | 865 } else { |
| 866 if (m_layoutDisposition == LayoutDisposition::FallbackContent) { |
| 867 EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents; |
| 868 ensureUserAgentShadowRoot(); |
| 869 } |
| 841 lazyReattachIfAttached(); | 870 lazyReattachIfAttached(); |
| 871 } |
| 842 } | 872 } |
| 843 | 873 |
| 844 PassRefPtr<ComputedStyle> HTMLImageElement::customStyleForLayoutObject() { | 874 PassRefPtr<ComputedStyle> HTMLImageElement::customStyleForLayoutObject() { |
| 845 RefPtr<ComputedStyle> newStyle = originalStyleForLayoutObject(); | 875 switch (m_layoutDisposition) { |
| 846 | 876 case LayoutDisposition::PrimaryContent: // Fall through. |
| 847 if (!m_useFallbackContent) | 877 case LayoutDisposition::Collapsed: |
| 848 return newStyle; | 878 return originalStyleForLayoutObject(); |
| 849 | 879 case LayoutDisposition::FallbackContent: |
| 850 RefPtr<ComputedStyle> style = ComputedStyle::clone(*newStyle); | 880 return HTMLImageFallbackHelper::customStyleForAltText( |
| 851 return HTMLImageFallbackHelper::customStyleForAltText(*this, style); | 881 *this, ComputedStyle::clone(*originalStyleForLayoutObject())); |
| 852 } | 882 default: |
| 853 | 883 NOTREACHED(); |
| 854 void HTMLImageElement::setUseFallbackContent() { | 884 return nullptr; |
| 855 m_useFallbackContent = true; | 885 } |
| 856 if (document().inStyleRecalc()) | |
| 857 return; | |
| 858 EventDispatchForbiddenScope::AllowUserAgentEvents allowEvents; | |
| 859 ensureUserAgentShadowRoot(); | |
| 860 } | 886 } |
| 861 | 887 |
| 862 bool HTMLImageElement::isOpaque() const { | 888 bool HTMLImageElement::isOpaque() const { |
| 863 Image* image = const_cast<HTMLImageElement*>(this)->imageContents(); | 889 Image* image = const_cast<HTMLImageElement*>(this)->imageContents(); |
| 864 return image && image->currentFrameKnownToBeOpaque(); | 890 return image && image->currentFrameKnownToBeOpaque(); |
| 865 } | 891 } |
| 866 | 892 |
| 867 int HTMLImageElement::sourceWidth() { | 893 int HTMLImageElement::sourceWidth() { |
| 868 SourceImageStatus status; | 894 SourceImageStatus status; |
| 869 FloatSize defaultObjectSize(width(), height()); | 895 FloatSize defaultObjectSize(width(), height()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 888 return IntSize(); | 914 return IntSize(); |
| 889 LayoutSize lSize = image->imageSize( | 915 LayoutSize lSize = image->imageSize( |
| 890 LayoutObject::shouldRespectImageOrientation(layoutObject()), 1.0f); | 916 LayoutObject::shouldRespectImageOrientation(layoutObject()), 1.0f); |
| 891 DCHECK(lSize.fraction().isZero()); | 917 DCHECK(lSize.fraction().isZero()); |
| 892 return IntSize(lSize.width().toInt(), lSize.height().toInt()); | 918 return IntSize(lSize.width().toInt(), lSize.height().toInt()); |
| 893 } | 919 } |
| 894 | 920 |
| 895 void HTMLImageElement::associateWith(HTMLFormElement*){}; | 921 void HTMLImageElement::associateWith(HTMLFormElement*){}; |
| 896 | 922 |
| 897 } // namespace blink | 923 } // namespace blink |
| OLD | NEW |