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

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

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

Powered by Google App Engine
This is Rietveld 408576698