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

Unified Diff: third_party/WebKit/Source/core/html/HTMLImageElement.cpp

Issue 2769823002: Add decode() functionality to image elements. (Closed)
Patch Set: update 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/HTMLImageElement.cpp
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index 54cb6398f39bbe0b44d7e9ec637f1c15d4378e72..1103f6bf1c29abe392c2649c44e7d6299dfe38c4 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -31,6 +31,7 @@
#include "core/css/MediaValuesDynamic.h"
#include "core/css/parser/SizesAttributeParser.h"
#include "core/dom/Attribute.h"
+#include "core/dom/DOMException.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/frame/Deprecation.h"
@@ -51,6 +52,7 @@
#include "core/layout/LayoutImage.h"
#include "core/layout/api/LayoutImageItem.h"
#include "core/loader/resource/ImageResourceContent.h"
+#include "core/page/ChromeClient.h"
#include "core/page/Page.h"
#include "core/style/ContentData.h"
#include "core/svg/graphics/SVGImageForContainer.h"
@@ -92,6 +94,7 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser)
image_device_pixel_ratio_(1.0f),
source_(nullptr),
layout_disposition_(LayoutDisposition::kPrimaryContent),
+ decode_sequence_id_(0),
form_was_set_by_parser_(false),
element_created_by_parser_(created_by_parser),
is_fallback_image_(false),
@@ -115,6 +118,7 @@ DEFINE_TRACE(HTMLImageElement) {
visitor->Trace(listener_);
visitor->Trace(form_);
visitor->Trace(source_);
+ visitor->Trace(decode_promise_resolvers_);
HTMLElement::Trace(visitor);
}
@@ -125,6 +129,44 @@ void HTMLImageElement::NotifyViewportChanged() {
SelectSourceURL(ImageLoader::kUpdateSizeChanged);
}
+void HTMLImageElement::RequestDecode() {
+ DCHECK(!decode_promise_resolvers_.IsEmpty());
+ LocalFrame* frame = GetDocument().GetFrame();
+ // If we don't have the image, or the document doesn't have a frame, then
+ // reject the decode, since we can't plumb the request to the correct place.
+ if (!GetImageLoader().GetImage() ||
+ !GetImageLoader().GetImage()->GetImage() || !frame) {
dcheng 2017/04/17 21:01:37 It would be nice to have coverage for the !frame c
+ DidDecode(decode_sequence_id_, false);
+ return;
+ }
+ Image* image = GetImageLoader().GetImage()->GetImage();
+ frame->GetChromeClient().RequestDecode(
+ frame, image->ImageForCurrentFrame(),
+ WTF::Bind(&HTMLImageElement::DidDecode, WrapWeakPersistent(this),
+ decode_sequence_id_));
+}
+
+void HTMLImageElement::DidDecode(uint32_t sequence_id, bool success) {
+ // If the sequence id attached with this callback doesn't match our current
+ // sequence id, then the source of the image has changed. In other words, the
+ // decode resolved/rejected by this callback was already rejected. Since we
+ // could have had a new decode request, we have to make sure not to
+ // resolve/reject those using the stale callback.
+ if (sequence_id != decode_sequence_id_)
+ return;
+
+ if (success) {
+ for (auto& resolver : decode_promise_resolvers_)
+ resolver->Resolve();
+ } else {
+ for (auto& resolver : decode_promise_resolvers_) {
+ resolver->Reject(DOMException::Create(
+ kEncodingError, "The source image cannot be decoded"));
+ }
+ }
+ decode_promise_resolvers_.Clear();
+}
+
HTMLImageElement* HTMLImageElement::CreateForJSConstructor(Document& document) {
HTMLImageElement* image = new HTMLImageElement(document);
image->element_created_by_parser_ = false;
@@ -260,6 +302,14 @@ void HTMLImageElement::ParseAttribute(
}
} else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
SelectSourceURL(ImageLoader::kUpdateIgnorePreviousError);
+ // Ensure to fail any pending decodes on possible source changes.
+ if (!decode_promise_resolvers_.IsEmpty() &&
+ params.old_value != params.new_value) {
+ DidDecode(decode_sequence_id_, false);
+ // Increment the sequence id so that any in flight decode completion tasks
+ // will not trigger promise resolution for new decode requests.
+ ++decode_sequence_id_;
+ }
} else if (name == usemapAttr) {
SetIsLink(!params.new_value.IsNull());
} else if (name == referrerpolicyAttr) {
@@ -596,6 +646,17 @@ int HTMLImageElement::y() const {
return abs_pos.Y();
}
+ScriptPromise HTMLImageElement::decode(ScriptState* scriptState,
+ ExceptionState& exceptionState) {
+ exceptionState.ClearException();
+ decode_promise_resolvers_.push_back(
+ ScriptPromiseResolver::Create(scriptState));
+ ScriptPromise promise = decode_promise_resolvers_.back()->Promise();
+ if (complete())
+ RequestDecode();
+ return promise;
+}
+
bool HTMLImageElement::complete() const {
return GetImageLoader().ImageComplete();
}
@@ -612,8 +673,8 @@ bool HTMLImageElement::IsServerMap() const {
const AtomicString& usemap = FastGetAttribute(usemapAttr);
- // If the usemap attribute starts with '#', it refers to a map element in the
- // document.
+ // If the usemap attribute starts with '#', it refers to a map element in
+ // the document.
if (usemap[0] == '#')
return false;
@@ -833,6 +894,15 @@ PassRefPtr<ComputedStyle> HTMLImageElement::CustomStyleForLayoutObject() {
}
}
+void HTMLImageElement::ImageNotifyFinished(bool success) {
+ if (decode_promise_resolvers_.IsEmpty())
+ return;
+ if (success)
+ RequestDecode();
+ else
+ DidDecode(decode_sequence_id_, false);
+}
+
IntSize HTMLImageElement::BitmapSourceSize() const {
ImageResourceContent* image = CachedImage();
if (!image)
« 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