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

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

Issue 2769823002: Add decode() functionality to image elements. (Closed)
Patch Set: rebase Created 3 years, 6 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 LocalFrame* frame = GetDocument().GetFrame();
135 // If we don't have the image, or the document doesn't have a frame, then
136 // reject the decode, since we can't plumb the request to the correct place.
137 if (!GetImageLoader().GetImage() ||
138 !GetImageLoader().GetImage()->GetImage() || !frame) {
139 DecodeRequestFinished(decode_sequence_id_, false);
140 return;
141 }
142 Image* image = GetImageLoader().GetImage()->GetImage();
143 frame->GetChromeClient().RequestDecode(
144 frame, image->ImageForCurrentFrame(),
145 WTF::Bind(&HTMLImageElement::DecodeRequestFinished,
146 WrapWeakPersistent(this), decode_sequence_id_));
147 }
148
149 void HTMLImageElement::DecodeRequestFinished(uint32_t sequence_id,
150 bool success) {
151 // If the sequence id attached with this callback doesn't match our current
152 // sequence id, then the source of the image has changed. In other words, the
153 // decode resolved/rejected by this callback was already rejected. Since we
154 // could have had a new decode request, we have to make sure not to
155 // resolve/reject those using the stale callback.
156 if (sequence_id != decode_sequence_id_)
157 return;
158
159 if (success) {
160 for (auto& resolver : decode_promise_resolvers_)
161 resolver->Resolve();
162 } else {
163 for (auto& resolver : decode_promise_resolvers_) {
164 resolver->Reject(DOMException::Create(
165 kEncodingError, "The source image cannot be decoded"));
166 }
167 }
168 decode_promise_resolvers_.clear();
169 }
170
128 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document) { 171 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document) {
129 HTMLImageElement* image = new HTMLImageElement(document); 172 HTMLImageElement* image = new HTMLImageElement(document);
130 image->element_created_by_parser_ = false; 173 image->element_created_by_parser_ = false;
131 return image; 174 return image;
132 } 175 }
133 176
134 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document, 177 HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document,
135 unsigned width) { 178 unsigned width) {
136 HTMLImageElement* image = new HTMLImageElement(document); 179 HTMLImageElement* image = new HTMLImageElement(document);
137 image->setWidth(width); 180 image->setWidth(width);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 const QualifiedName& name = params.name; 296 const QualifiedName& name = params.name;
254 if (name == altAttr || name == titleAttr) { 297 if (name == altAttr || name == titleAttr) {
255 if (UserAgentShadowRoot()) { 298 if (UserAgentShadowRoot()) {
256 Element* text = UserAgentShadowRoot()->getElementById("alttext"); 299 Element* text = UserAgentShadowRoot()->getElementById("alttext");
257 String value = AltText(); 300 String value = AltText();
258 if (text && text->textContent() != params.new_value) 301 if (text && text->textContent() != params.new_value)
259 text->setTextContent(AltText()); 302 text->setTextContent(AltText());
260 } 303 }
261 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) { 304 } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
262 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError); 305 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError);
306 // Ensure to fail any pending decodes on possible source changes.
307 if (!decode_promise_resolvers_.IsEmpty() &&
308 params.old_value != params.new_value) {
309 DecodeRequestFinished(decode_sequence_id_, false);
310 // Increment the sequence id so that any in flight decode completion tasks
311 // will not trigger promise resolution for new decode requests.
312 ++decode_sequence_id_;
313 }
263 } else if (name == usemapAttr) { 314 } else if (name == usemapAttr) {
264 SetIsLink(!params.new_value.IsNull()); 315 SetIsLink(!params.new_value.IsNull());
265 } else if (name == referrerpolicyAttr) { 316 } else if (name == referrerpolicyAttr) {
266 referrer_policy_ = kReferrerPolicyDefault; 317 referrer_policy_ = kReferrerPolicyDefault;
267 if (!params.new_value.IsNull()) { 318 if (!params.new_value.IsNull()) {
268 SecurityPolicy::ReferrerPolicyFromString( 319 SecurityPolicy::ReferrerPolicyFromString(
269 params.new_value, kSupportReferrerPolicyLegacyKeywords, 320 params.new_value, kSupportReferrerPolicyLegacyKeywords,
270 &referrer_policy_); 321 &referrer_policy_);
271 UseCounter::Count(GetDocument(), 322 UseCounter::Count(GetDocument(),
272 UseCounter::kHTMLImageElementReferrerPolicyAttribute); 323 UseCounter::kHTMLImageElementReferrerPolicyAttribute);
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); 641 GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
591 LayoutObject* r = GetLayoutObject(); 642 LayoutObject* r = GetLayoutObject();
592 if (!r) 643 if (!r)
593 return 0; 644 return 0;
594 645
595 // FIXME: This doesn't work correctly with transforms. 646 // FIXME: This doesn't work correctly with transforms.
596 FloatPoint abs_pos = r->LocalToAbsolute(); 647 FloatPoint abs_pos = r->LocalToAbsolute();
597 return abs_pos.Y(); 648 return abs_pos.Y();
598 } 649 }
599 650
651 ScriptPromise HTMLImageElement::decode(ScriptState* script_state,
652 ExceptionState& exception_state) {
653 if (!script_state->ContextIsValid()) {
654 exception_state.ThrowDOMException(kEncodingError,
655 "The source image cannot be decoded");
656 return ScriptPromise();
657 }
658 exception_state.ClearException();
659 decode_promise_resolvers_.push_back(
660 ScriptPromiseResolver::Create(script_state));
661 ScriptPromise promise = decode_promise_resolvers_.back()->Promise();
662 if (complete())
663 RequestDecode();
664 return promise;
665 }
666
600 bool HTMLImageElement::complete() const { 667 bool HTMLImageElement::complete() const {
601 return GetImageLoader().ImageComplete(); 668 return GetImageLoader().ImageComplete();
602 } 669 }
603 670
604 void HTMLImageElement::DidMoveToNewDocument(Document& old_document) { 671 void HTMLImageElement::DidMoveToNewDocument(Document& old_document) {
605 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError); 672 SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError);
606 GetImageLoader().ElementDidMoveToNewDocument(); 673 GetImageLoader().ElementDidMoveToNewDocument();
607 HTMLElement::DidMoveToNewDocument(old_document); 674 HTMLElement::DidMoveToNewDocument(old_document);
608 } 675 }
609 676
610 bool HTMLImageElement::IsServerMap() const { 677 bool HTMLImageElement::IsServerMap() const {
611 if (!FastHasAttribute(ismapAttr)) 678 if (!FastHasAttribute(ismapAttr))
612 return false; 679 return false;
613 680
614 const AtomicString& usemap = FastGetAttribute(usemapAttr); 681 const AtomicString& usemap = FastGetAttribute(usemapAttr);
615 682
616 // If the usemap attribute starts with '#', it refers to a map element in the 683 // If the usemap attribute starts with '#', it refers to a map element in
617 // document. 684 // the document.
618 if (usemap[0] == '#') 685 if (usemap[0] == '#')
619 return false; 686 return false;
620 687
621 return GetDocument() 688 return GetDocument()
622 .CompleteURL(StripLeadingAndTrailingHTMLSpaces(usemap)) 689 .CompleteURL(StripLeadingAndTrailingHTMLSpaces(usemap))
623 .IsEmpty(); 690 .IsEmpty();
624 } 691 }
625 692
626 Image* HTMLImageElement::ImageContents() { 693 Image* HTMLImageElement::ImageContents() {
627 if (!GetImageLoader().ImageComplete()) 694 if (!GetImageLoader().ImageComplete())
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 return OriginalStyleForLayoutObject(); 872 return OriginalStyleForLayoutObject();
806 case LayoutDisposition::kFallbackContent: 873 case LayoutDisposition::kFallbackContent:
807 return HTMLImageFallbackHelper::CustomStyleForAltText( 874 return HTMLImageFallbackHelper::CustomStyleForAltText(
808 *this, ComputedStyle::Clone(*OriginalStyleForLayoutObject())); 875 *this, ComputedStyle::Clone(*OriginalStyleForLayoutObject()));
809 default: 876 default:
810 NOTREACHED(); 877 NOTREACHED();
811 return nullptr; 878 return nullptr;
812 } 879 }
813 } 880 }
814 881
882 void HTMLImageElement::ImageNotifyFinished(bool success) {
883 if (decode_promise_resolvers_.IsEmpty())
884 return;
885 if (success)
886 RequestDecode();
887 else
888 DecodeRequestFinished(decode_sequence_id_, false);
889 }
890
815 void HTMLImageElement::AssociateWith(HTMLFormElement* form) { 891 void HTMLImageElement::AssociateWith(HTMLFormElement* form) {
816 if (form && form->isConnected()) { 892 if (form && form->isConnected()) {
817 form_ = form; 893 form_ = form;
818 form_was_set_by_parser_ = true; 894 form_was_set_by_parser_ = true;
819 form_->Associate(*this); 895 form_->Associate(*this);
820 form_->DidAssociateByParser(); 896 form_->DidAssociateByParser();
821 } 897 }
822 }; 898 };
823 899
824 FloatSize HTMLImageElement::SourceDefaultObjectSize() { 900 FloatSize HTMLImageElement::SourceDefaultObjectSize() {
825 return FloatSize(width(), height()); 901 return FloatSize(width(), height());
826 } 902 }
827 903
828 } // namespace blink 904 } // 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