Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLImageElement.cpp

Issue 2769823002: Add decode() functionality to image elements. (Closed)
Patch Set: diff plumbing Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLImageElement.h ('k') | third_party/WebKit/Source/core/html/HTMLImageElement.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698