Chromium Code Reviews| 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 13 matching lines...) Expand all Loading... | |
| 24 #include "core/html/HTMLImageElement.h" | 24 #include "core/html/HTMLImageElement.h" |
| 25 | 25 |
| 26 #include "bindings/core/v8/ScriptEventListener.h" | 26 #include "bindings/core/v8/ScriptEventListener.h" |
| 27 #include "core/CSSPropertyNames.h" | 27 #include "core/CSSPropertyNames.h" |
| 28 #include "core/HTMLNames.h" | 28 #include "core/HTMLNames.h" |
| 29 #include "core/MediaTypeNames.h" | 29 #include "core/MediaTypeNames.h" |
| 30 #include "core/css/MediaQueryMatcher.h" | 30 #include "core/css/MediaQueryMatcher.h" |
| 31 #include "core/css/MediaValuesDynamic.h" | 31 #include "core/css/MediaValuesDynamic.h" |
| 32 #include "core/css/parser/SizesAttributeParser.h" | 32 #include "core/css/parser/SizesAttributeParser.h" |
| 33 #include "core/dom/Attribute.h" | 33 #include "core/dom/Attribute.h" |
| 34 #include "core/dom/DOMException.h" | |
| 34 #include "core/dom/NodeTraversal.h" | 35 #include "core/dom/NodeTraversal.h" |
| 35 #include "core/dom/shadow/ShadowRoot.h" | 36 #include "core/dom/shadow/ShadowRoot.h" |
| 36 #include "core/frame/Deprecation.h" | 37 #include "core/frame/Deprecation.h" |
| 37 #include "core/frame/ImageBitmap.h" | 38 #include "core/frame/ImageBitmap.h" |
| 38 #include "core/frame/LocalDOMWindow.h" | 39 #include "core/frame/LocalDOMWindow.h" |
| 39 #include "core/html/FormAssociated.h" | 40 #include "core/html/FormAssociated.h" |
| 40 #include "core/html/HTMLAnchorElement.h" | 41 #include "core/html/HTMLAnchorElement.h" |
| 41 #include "core/html/HTMLCanvasElement.h" | 42 #include "core/html/HTMLCanvasElement.h" |
| 42 #include "core/html/HTMLFormElement.h" | 43 #include "core/html/HTMLFormElement.h" |
| 43 #include "core/html/HTMLImageFallbackHelper.h" | 44 #include "core/html/HTMLImageFallbackHelper.h" |
| 44 #include "core/html/HTMLPictureElement.h" | 45 #include "core/html/HTMLPictureElement.h" |
| 45 #include "core/html/HTMLSourceElement.h" | 46 #include "core/html/HTMLSourceElement.h" |
| 46 #include "core/html/parser/HTMLParserIdioms.h" | 47 #include "core/html/parser/HTMLParserIdioms.h" |
| 47 #include "core/html/parser/HTMLSrcsetParser.h" | 48 #include "core/html/parser/HTMLSrcsetParser.h" |
| 48 #include "core/imagebitmap/ImageBitmapOptions.h" | 49 #include "core/imagebitmap/ImageBitmapOptions.h" |
| 49 #include "core/inspector/ConsoleMessage.h" | 50 #include "core/inspector/ConsoleMessage.h" |
| 50 #include "core/layout/LayoutBlockFlow.h" | 51 #include "core/layout/LayoutBlockFlow.h" |
| 51 #include "core/layout/LayoutImage.h" | 52 #include "core/layout/LayoutImage.h" |
| 52 #include "core/layout/api/LayoutImageItem.h" | 53 #include "core/layout/api/LayoutImageItem.h" |
| 53 #include "core/loader/resource/ImageResourceContent.h" | 54 #include "core/loader/resource/ImageResourceContent.h" |
| 55 #include "core/page/ChromeClient.h" | |
| 54 #include "core/page/Page.h" | 56 #include "core/page/Page.h" |
| 55 #include "core/style/ContentData.h" | 57 #include "core/style/ContentData.h" |
| 56 #include "core/svg/graphics/SVGImageForContainer.h" | 58 #include "core/svg/graphics/SVGImageForContainer.h" |
| 57 #include "platform/EventDispatchForbiddenScope.h" | 59 #include "platform/EventDispatchForbiddenScope.h" |
| 58 #include "platform/network/mime/ContentType.h" | 60 #include "platform/network/mime/ContentType.h" |
| 59 #include "platform/network/mime/MIMETypeRegistry.h" | 61 #include "platform/network/mime/MIMETypeRegistry.h" |
| 60 #include "platform/weborigin/SecurityPolicy.h" | 62 #include "platform/weborigin/SecurityPolicy.h" |
| 61 | 63 |
| 62 namespace blink { | 64 namespace blink { |
| 63 | 65 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 85 : element_(element) {} | 87 : element_(element) {} |
| 86 Member<HTMLImageElement> element_; | 88 Member<HTMLImageElement> element_; |
| 87 }; | 89 }; |
| 88 | 90 |
| 89 HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser) | 91 HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser) |
| 90 : HTMLElement(imgTag, document), | 92 : HTMLElement(imgTag, document), |
| 91 image_loader_(HTMLImageLoader::Create(this)), | 93 image_loader_(HTMLImageLoader::Create(this)), |
| 92 image_device_pixel_ratio_(1.0f), | 94 image_device_pixel_ratio_(1.0f), |
| 93 source_(nullptr), | 95 source_(nullptr), |
| 94 layout_disposition_(LayoutDisposition::kPrimaryContent), | 96 layout_disposition_(LayoutDisposition::kPrimaryContent), |
| 97 decode_sequence_id_(0), | |
| 95 form_was_set_by_parser_(false), | 98 form_was_set_by_parser_(false), |
| 96 element_created_by_parser_(created_by_parser), | 99 element_created_by_parser_(created_by_parser), |
| 97 is_fallback_image_(false), | 100 is_fallback_image_(false), |
| 98 referrer_policy_(kReferrerPolicyDefault) { | 101 referrer_policy_(kReferrerPolicyDefault) { |
| 99 SetHasCustomStyleCallbacks(); | 102 SetHasCustomStyleCallbacks(); |
| 100 } | 103 } |
| 101 | 104 |
| 102 HTMLImageElement* HTMLImageElement::Create(Document& document) { | 105 HTMLImageElement* HTMLImageElement::Create(Document& document) { |
| 103 return new HTMLImageElement(document); | 106 return new HTMLImageElement(document); |
| 104 } | 107 } |
| 105 | 108 |
| 106 HTMLImageElement* HTMLImageElement::Create(Document& document, | 109 HTMLImageElement* HTMLImageElement::Create(Document& document, |
| 107 bool created_by_parser) { | 110 bool created_by_parser) { |
| 108 return new HTMLImageElement(document, created_by_parser); | 111 return new HTMLImageElement(document, created_by_parser); |
| 109 } | 112 } |
| 110 | 113 |
| 111 HTMLImageElement::~HTMLImageElement() {} | 114 HTMLImageElement::~HTMLImageElement() {} |
| 112 | 115 |
| 113 DEFINE_TRACE(HTMLImageElement) { | 116 DEFINE_TRACE(HTMLImageElement) { |
| 114 visitor->Trace(image_loader_); | 117 visitor->Trace(image_loader_); |
| 115 visitor->Trace(listener_); | 118 visitor->Trace(listener_); |
| 116 visitor->Trace(form_); | 119 visitor->Trace(form_); |
| 117 visitor->Trace(source_); | 120 visitor->Trace(source_); |
| 121 visitor->Trace(decode_promise_resolvers_); | |
| 118 HTMLElement::Trace(visitor); | 122 HTMLElement::Trace(visitor); |
| 119 } | 123 } |
| 120 | 124 |
| 121 void HTMLImageElement::NotifyViewportChanged() { | 125 void HTMLImageElement::NotifyViewportChanged() { |
| 122 // Re-selecting the source URL in order to pick a more fitting resource | 126 // Re-selecting the source URL in order to pick a more fitting resource |
| 123 // And update the image's intrinsic dimensions when the viewport changes. | 127 // And update the image's intrinsic dimensions when the viewport changes. |
| 124 // Picking of a better fitting resource is UA dependant, not spec required. | 128 // Picking of a better fitting resource is UA dependant, not spec required. |
| 125 SelectSourceURL(ImageLoader::kUpdateSizeChanged); | 129 SelectSourceURL(ImageLoader::kUpdateSizeChanged); |
| 126 } | 130 } |
| 127 | 131 |
| 132 void HTMLImageElement::RequestDecode() { | |
| 133 DCHECK(!decode_promise_resolvers_.IsEmpty()); | |
| 134 if (!GetImageLoader().GetImage() || | |
| 135 !GetImageLoader().GetImage()->GetImage()) { | |
| 136 DidDecode(decode_sequence_id_, false); | |
| 137 return; | |
| 138 } | |
| 139 Image* image = GetImageLoader().GetImage()->GetImage(); | |
| 140 LocalFrame* frame = GetDocument().GetFrame(); | |
|
dcheng
2017/04/17 18:48:02
Hmm. I think we might need to null check here.
I
vmpstr
2017/04/17 20:51:25
Done.
| |
| 141 frame->GetChromeClient().RequestDecode( | |
| 142 frame, image->ImageForCurrentFrame(), | |
| 143 WTF::Bind(&HTMLImageElement::DidDecode, WrapWeakPersistent(this), | |
| 144 decode_sequence_id_)); | |
| 145 } | |
| 146 | |
| 147 void HTMLImageElement::DidDecode(uint32_t sequence_id, bool success) { | |
| 148 // If the sequence id attached with this callback doesn't match our current | |
| 149 // sequence id, then the source of the image has changed. In other words, the | |
| 150 // decode resolved/rejected by this callback was already rejected. Since we | |
| 151 // could have had a new decode request, we have to make sure not to | |
| 152 // resolve/reject those using the stale callback. | |
| 153 if (sequence_id != decode_sequence_id_) | |
| 154 return; | |
| 155 | |
| 156 if (success) { | |
| 157 for (auto& resolver : decode_promise_resolvers_) | |
| 158 resolver->Resolve(); | |
| 159 } else { | |
| 160 for (auto& resolver : decode_promise_resolvers_) { | |
| 161 resolver->Reject(DOMException::Create( | |
| 162 kEncodingError, "The source image cannot be decoded")); | |
| 163 } | |
| 164 } | |
| 165 decode_promise_resolvers_.Clear(); | |
| 166 } | |
| 167 | |
| 128 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document) { | 168 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document) { |
| 129 HTMLImageElement* image = new HTMLImageElement(document); | 169 HTMLImageElement* image = new HTMLImageElement(document); |
| 130 image->element_created_by_parser_ = false; | 170 image->element_created_by_parser_ = false; |
| 131 return image; | 171 return image; |
| 132 } | 172 } |
| 133 | 173 |
| 134 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document, | 174 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document, |
| 135 unsigned width) { | 175 unsigned width) { |
| 136 HTMLImageElement* image = new HTMLImageElement(document); | 176 HTMLImageElement* image = new HTMLImageElement(document); |
| 137 image->setWidth(width); | 177 image->setWidth(width); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 const QualifiedName& name = params.name; | 293 const QualifiedName& name = params.name; |
| 254 if (name == altAttr || name == titleAttr) { | 294 if (name == altAttr || name == titleAttr) { |
| 255 if (UserAgentShadowRoot()) { | 295 if (UserAgentShadowRoot()) { |
| 256 Element* text = UserAgentShadowRoot()->GetElementById("alttext"); | 296 Element* text = UserAgentShadowRoot()->GetElementById("alttext"); |
| 257 String value = AltText(); | 297 String value = AltText(); |
| 258 if (text && text->textContent() != params.new_value) | 298 if (text && text->textContent() != params.new_value) |
| 259 text->setTextContent(AltText()); | 299 text->setTextContent(AltText()); |
| 260 } | 300 } |
| 261 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { | 301 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { |
| 262 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError); | 302 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError); |
| 303 // Ensure to fail any pending decodes on possible source changes. | |
| 304 if (!decode_promise_resolvers_.IsEmpty() && | |
| 305 params.old_value != params.new_value) { | |
| 306 DidDecode(decode_sequence_id_, false); | |
| 307 // Increment the sequence id so that any in flight decode completion tasks | |
| 308 // will not trigger promise resolution for new decode requests. | |
| 309 ++decode_sequence_id_; | |
| 310 } | |
| 263 } else if (name == usemapAttr) { | 311 } else if (name == usemapAttr) { |
| 264 SetIsLink(!params.new_value.IsNull()); | 312 SetIsLink(!params.new_value.IsNull()); |
| 265 } else if (name == referrerpolicyAttr) { | 313 } else if (name == referrerpolicyAttr) { |
| 266 referrer_policy_ = kReferrerPolicyDefault; | 314 referrer_policy_ = kReferrerPolicyDefault; |
| 267 if (!params.new_value.IsNull()) { | 315 if (!params.new_value.IsNull()) { |
| 268 SecurityPolicy::ReferrerPolicyFromString( | 316 SecurityPolicy::ReferrerPolicyFromString( |
| 269 params.new_value, kSupportReferrerPolicyLegacyKeywords, | 317 params.new_value, kSupportReferrerPolicyLegacyKeywords, |
| 270 &referrer_policy_); | 318 &referrer_policy_); |
| 271 UseCounter::Count(GetDocument(), | 319 UseCounter::Count(GetDocument(), |
| 272 UseCounter::kHTMLImageElementReferrerPolicyAttribute); | 320 UseCounter::kHTMLImageElementReferrerPolicyAttribute); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); | 637 GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); |
| 590 LayoutObject* r = GetLayoutObject(); | 638 LayoutObject* r = GetLayoutObject(); |
| 591 if (!r) | 639 if (!r) |
| 592 return 0; | 640 return 0; |
| 593 | 641 |
| 594 // FIXME: This doesn't work correctly with transforms. | 642 // FIXME: This doesn't work correctly with transforms. |
| 595 FloatPoint abs_pos = r->LocalToAbsolute(); | 643 FloatPoint abs_pos = r->LocalToAbsolute(); |
| 596 return abs_pos.Y(); | 644 return abs_pos.Y(); |
| 597 } | 645 } |
| 598 | 646 |
| 647 ScriptPromise HTMLImageElement::decode(ScriptState* scriptState, | |
| 648 ExceptionState& exceptionState) { | |
| 649 exceptionState.ClearException(); | |
| 650 decode_promise_resolvers_.push_back( | |
| 651 ScriptPromiseResolver::Create(scriptState)); | |
| 652 ScriptPromise promise = decode_promise_resolvers_.back()->Promise(); | |
| 653 if (complete()) | |
| 654 RequestDecode(); | |
| 655 return promise; | |
| 656 } | |
| 657 | |
| 599 bool HTMLImageElement::complete() const { | 658 bool HTMLImageElement::complete() const { |
| 600 return GetImageLoader().ImageComplete(); | 659 return GetImageLoader().ImageComplete(); |
| 601 } | 660 } |
| 602 | 661 |
| 603 void HTMLImageElement::DidMoveToNewDocument(Document& old_document) { | 662 void HTMLImageElement::DidMoveToNewDocument(Document& old_document) { |
| 604 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError); | 663 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError); |
| 605 GetImageLoader().ElementDidMoveToNewDocument(); | 664 GetImageLoader().ElementDidMoveToNewDocument(); |
| 606 HTMLElement::DidMoveToNewDocument(old_document); | 665 HTMLElement::DidMoveToNewDocument(old_document); |
| 607 } | 666 } |
| 608 | 667 |
| 609 bool HTMLImageElement::IsServerMap() const { | 668 bool HTMLImageElement::IsServerMap() const { |
| 610 if (!FastHasAttribute(ismapAttr)) | 669 if (!FastHasAttribute(ismapAttr)) |
| 611 return false; | 670 return false; |
| 612 | 671 |
| 613 const AtomicString& usemap = FastGetAttribute(usemapAttr); | 672 const AtomicString& usemap = FastGetAttribute(usemapAttr); |
| 614 | 673 |
| 615 // If the usemap attribute starts with '#', it refers to a map element in the | 674 // If the usemap attribute starts with '#', it refers to a map element in |
| 616 // document. | 675 // the document. |
| 617 if (usemap[0] == '#') | 676 if (usemap[0] == '#') |
| 618 return false; | 677 return false; |
| 619 | 678 |
| 620 return GetDocument() | 679 return GetDocument() |
| 621 .CompleteURL(StripLeadingAndTrailingHTMLSpaces(usemap)) | 680 .CompleteURL(StripLeadingAndTrailingHTMLSpaces(usemap)) |
| 622 .IsEmpty(); | 681 .IsEmpty(); |
| 623 } | 682 } |
| 624 | 683 |
| 625 Image* HTMLImageElement::ImageContents() { | 684 Image* HTMLImageElement::ImageContents() { |
| 626 if (!GetImageLoader().ImageComplete()) | 685 if (!GetImageLoader().ImageComplete()) |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 return OriginalStyleForLayoutObject(); | 885 return OriginalStyleForLayoutObject(); |
| 827 case LayoutDisposition::kFallbackContent: | 886 case LayoutDisposition::kFallbackContent: |
| 828 return HTMLImageFallbackHelper::CustomStyleForAltText( | 887 return HTMLImageFallbackHelper::CustomStyleForAltText( |
| 829 *this, ComputedStyle::Clone(*OriginalStyleForLayoutObject())); | 888 *this, ComputedStyle::Clone(*OriginalStyleForLayoutObject())); |
| 830 default: | 889 default: |
| 831 NOTREACHED(); | 890 NOTREACHED(); |
| 832 return nullptr; | 891 return nullptr; |
| 833 } | 892 } |
| 834 } | 893 } |
| 835 | 894 |
| 895 void HTMLImageElement::ImageNotifyFinished(bool success) { | |
| 896 if (decode_promise_resolvers_.IsEmpty()) | |
| 897 return; | |
| 898 if (success) | |
| 899 RequestDecode(); | |
| 900 else | |
| 901 DidDecode(decode_sequence_id_, false); | |
| 902 } | |
| 903 | |
| 836 IntSize HTMLImageElement::BitmapSourceSize() const { | 904 IntSize HTMLImageElement::BitmapSourceSize() const { |
| 837 ImageResourceContent* image = CachedImage(); | 905 ImageResourceContent* image = CachedImage(); |
| 838 if (!image) | 906 if (!image) |
| 839 return IntSize(); | 907 return IntSize(); |
| 840 LayoutSize l_size = image->ImageSize( | 908 LayoutSize l_size = image->ImageSize( |
| 841 LayoutObject::ShouldRespectImageOrientation(GetLayoutObject()), 1.0f); | 909 LayoutObject::ShouldRespectImageOrientation(GetLayoutObject()), 1.0f); |
| 842 DCHECK(l_size.Fraction().IsZero()); | 910 DCHECK(l_size.Fraction().IsZero()); |
| 843 return IntSize(l_size.Width().ToInt(), l_size.Height().ToInt()); | 911 return IntSize(l_size.Width().ToInt(), l_size.Height().ToInt()); |
| 844 } | 912 } |
| 845 | 913 |
| 846 void HTMLImageElement::AssociateWith(HTMLFormElement* form) { | 914 void HTMLImageElement::AssociateWith(HTMLFormElement* form) { |
| 847 if (form && form->isConnected()) { | 915 if (form && form->isConnected()) { |
| 848 form_ = form; | 916 form_ = form; |
| 849 form_was_set_by_parser_ = true; | 917 form_was_set_by_parser_ = true; |
| 850 form_->Associate(*this); | 918 form_->Associate(*this); |
| 851 form_->DidAssociateByParser(); | 919 form_->DidAssociateByParser(); |
| 852 } | 920 } |
| 853 }; | 921 }; |
| 854 | 922 |
| 855 FloatSize HTMLImageElement::SourceDefaultObjectSize() { | 923 FloatSize HTMLImageElement::SourceDefaultObjectSize() { |
| 856 return FloatSize(width(), height()); | 924 return FloatSize(width(), height()); |
| 857 } | 925 } |
| 858 | 926 |
| 859 } // namespace blink | 927 } // namespace blink |
| OLD | NEW |