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

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 65a62298cce0df18ec5385e44e6dabffda759bac..9a283310240d920a3fa06eccad9c7b224430fe81 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"
@@ -95,7 +97,8 @@ HTMLImageElement::HTMLImageElement(Document& document, bool createdByParser)
m_formWasSetByParser(false),
m_elementCreatedByParser(createdByParser),
m_isFallbackImage(false),
- m_referrerPolicy(ReferrerPolicyDefault) {
+ m_referrerPolicy(ReferrerPolicyDefault),
+ m_weakPtrFactory(this) {
setHasCustomStyleCallbacks();
}
@@ -108,13 +111,16 @@ HTMLImageElement* HTMLImageElement::create(Document& document,
return new HTMLImageElement(document, createdByParser);
}
-HTMLImageElement::~HTMLImageElement() {}
+HTMLImageElement::~HTMLImageElement() {
+ m_weakPtrFactory.revokeAll();
+}
DEFINE_TRACE(HTMLImageElement) {
visitor->trace(m_imageLoader);
visitor->trace(m_listener);
visitor->trace(m_form);
visitor->trace(m_source);
+ visitor->trace(m_decodePromiseResolvers);
HTMLElement::trace(visitor);
}
@@ -125,6 +131,37 @@ void HTMLImageElement::notifyViewportChanged() {
selectSourceURL(ImageLoader::UpdateSizeChanged);
}
+void HTMLImageElement::requestDecode() {
+ DCHECK(!m_decodePromiseResolvers.isEmpty());
+ if (!imageLoader().image() || !imageLoader().image()->getImage()) {
+ didDecode(false);
+ return;
+ }
+ Image* image = imageLoader().image()->getImage();
+ auto* page = document().page();
+ if (page) {
+ page->chromeClient().requestDecode(
dcheng 2017/04/12 06:53:16 After reading this through, I think it's fine to j
vmpstr 2017/04/17 18:13:11 Done. Let me know if this looks better...
+ image->imageForCurrentFrame(),
+ WTF::bind(&HTMLImageElement::didDecode,
+ m_weakPtrFactory.createWeakPtr()));
kouhei (in TOK) 2017/04/07 14:26:28 wrapWeakPersistent(this)?
vmpstr 2017/04/07 20:43:43 Hmm, we have to revoke the weak ptrs if the src of
dcheng 2017/04/12 06:53:16 Other potential options: - PostCancellableTask, wh
vmpstr 2017/04/17 18:13:11 Done, I used a sequence number here with wrapWeakP
+ }
+}
+
+void HTMLImageElement::didDecode(bool success) {
+ if (m_decodePromiseResolvers.isEmpty())
+ return;
+ if (success) {
+ for (auto& resolver : m_decodePromiseResolvers)
+ resolver->resolve();
+ } else {
+ for (auto& resolver : m_decodePromiseResolvers) {
+ resolver->reject(DOMException::create(
+ EncodingError, "The source image cannot be decoded"));
+ }
+ }
+ m_decodePromiseResolvers.clear();
+}
+
HTMLImageElement* HTMLImageElement::createForJSConstructor(Document& document) {
HTMLImageElement* image = new HTMLImageElement(document);
image->m_elementCreatedByParser = false;
@@ -260,6 +297,12 @@ void HTMLImageElement::parseAttribute(
}
} else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
selectSourceURL(ImageLoader::UpdateIgnorePreviousError);
+ // Ensure to fail any pending decodes on possible source changes.
+ if (!m_decodePromiseResolvers.isEmpty() &&
+ params.oldValue != params.newValue) {
+ didDecode(false);
+ m_weakPtrFactory.revokeAll();
+ }
} else if (name == usemapAttr) {
setIsLink(!params.newValue.isNull());
} else if (name == referrerpolicyAttr) {
@@ -415,9 +458,8 @@ Node::InsertionNotificationRequest HTMLImageElement::insertedInto(
}
void HTMLImageElement::removedFrom(ContainerNode* insertionPoint) {
- if (!m_form ||
- NodeTraversal::highestAncestorOrSelf(*m_form.get()) !=
- NodeTraversal::highestAncestorOrSelf(*this))
+ if (!m_form || NodeTraversal::highestAncestorOrSelf(*m_form.get()) !=
+ NodeTraversal::highestAncestorOrSelf(*this))
resetFormOwner();
if (m_listener) {
document().mediaQueryMatcher().removeViewportListener(m_listener);
@@ -524,9 +566,9 @@ const String& HTMLImageElement::currentSrc() const {
// Return the picked URL string in case of load error.
if (imageLoader().hadError())
return m_bestFitImageURL;
- // Initially, the pending request turns into current request when it is either
- // available or broken. We use the image's dimensions as a proxy to it being
- // in any of these states.
+ // Initially, the pending request turns into current request when it is
+ // either available or broken. We use the image's dimensions as a proxy to
+ // it being in any of these states.
if (!imageLoader().image() || !imageLoader().image()->getImage() ||
!imageLoader().image()->getImage()->width())
return emptyAtom;
@@ -592,6 +634,17 @@ int HTMLImageElement::y() const {
return absPos.y();
}
+ScriptPromise HTMLImageElement::decode(ScriptState* scriptState,
+ ExceptionState& exceptionState) {
+ exceptionState.clearException();
+ m_decodePromiseResolvers.push_back(
+ ScriptPromiseResolver::create(scriptState));
+ ScriptPromise promise = m_decodePromiseResolvers.back()->promise();
+ if (complete())
+ requestDecode();
+ return promise;
+}
+
bool HTMLImageElement::complete() const {
return imageLoader().imageComplete();
}
@@ -608,8 +661,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;
@@ -799,8 +852,8 @@ void HTMLImageElement::setLayoutDisposition(LayoutDisposition layoutDisposition,
m_layoutDisposition = layoutDisposition;
- // This can happen inside of attachLayoutTree() in the middle of a recalcStyle
- // so we need to reattach synchronously here.
+ // This can happen inside of attachLayoutTree() in the middle of a
+ // recalcStyle so we need to reattach synchronously here.
if (document().inStyleRecalc()) {
reattachLayoutTree();
} else {
@@ -826,6 +879,15 @@ PassRefPtr<ComputedStyle> HTMLImageElement::customStyleForLayoutObject() {
}
}
+void HTMLImageElement::imageNotifyFinished(bool success) {
+ if (m_decodePromiseResolvers.isEmpty())
+ return;
+ if (success)
+ requestDecode();
+ else
+ didDecode(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