CTTE: ImageLoader is always owned by an Element.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Feb 2014 18:25:26 +0000 (18:25 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Feb 2014 18:25:26 +0000 (18:25 +0000)
<https://webkit.org/b/128254>

- Codify this by making the constructor take Element& or better.
- Make element() return Element&.
- Marked HTMLImageLoader and SVGImageLoader final.
- Made the ImageLoader constructor protected.

Reviewed by Sam Weinig.

* html/HTMLEmbedElement.cpp:
(WebCore::HTMLEmbedElement::parseAttribute):
* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::HTMLImageElement):
* html/HTMLImageLoader.cpp:
(WebCore::HTMLImageLoader::HTMLImageLoader):
(WebCore::HTMLImageLoader::dispatchLoadEvent):
(WebCore::HTMLImageLoader::sourceURI):
(WebCore::HTMLImageLoader::notifyFinished):
* html/HTMLImageLoader.h:
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::imageLoader):
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::parseAttribute):
* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::startLoadingImage):
* html/HTMLVideoElement.cpp:
(WebCore::HTMLVideoElement::didAttachRenderers):
(WebCore::HTMLVideoElement::parseAttribute):
* loader/ImageLoader.cpp:
(WebCore::ImageLoader::ImageLoader):
(WebCore::ImageLoader::~ImageLoader):
(WebCore::ImageLoader::updateFromElement):
(WebCore::ImageLoader::notifyFinished):
(WebCore::ImageLoader::renderImageResource):
(WebCore::ImageLoader::updatedHasPendingEvent):
(WebCore::ImageLoader::timerFired):
(WebCore::ImageLoader::dispatchPendingBeforeLoadEvent):
(WebCore::ImageLoader::dispatchPendingLoadEvent):
(WebCore::ImageLoader::dispatchPendingErrorEvent):
* loader/ImageLoader.h:
(WebCore::ImageLoader::element):
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::SVGImageElement):
* svg/SVGImageLoader.cpp:
(WebCore::SVGImageLoader::SVGImageLoader):
(WebCore::SVGImageLoader::~SVGImageLoader):
(WebCore::SVGImageLoader::dispatchLoadEvent):
(WebCore::SVGImageLoader::sourceURI):
* svg/SVGImageLoader.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@163457 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLEmbedElement.cpp
Source/WebCore/html/HTMLImageElement.cpp
Source/WebCore/html/HTMLImageLoader.cpp
Source/WebCore/html/HTMLImageLoader.h
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLObjectElement.cpp
Source/WebCore/html/HTMLPlugInImageElement.cpp
Source/WebCore/html/HTMLVideoElement.cpp
Source/WebCore/loader/ImageLoader.cpp
Source/WebCore/loader/ImageLoader.h
Source/WebCore/svg/SVGImageElement.cpp
Source/WebCore/svg/SVGImageLoader.cpp
Source/WebCore/svg/SVGImageLoader.h

index 119db853822ece45517d1c2ff26bb0b1e084cf50..e22f0744b6b1462fc470c07da8242e87b131698a 100644 (file)
@@ -1,3 +1,56 @@
+2014-02-05  Andreas Kling  <akling@apple.com>
+
+        CTTE: ImageLoader is always owned by an Element.
+        <https://webkit.org/b/128254>
+
+        - Codify this by making the constructor take Element& or better.
+        - Make element() return Element&.
+        - Marked HTMLImageLoader and SVGImageLoader final.
+        - Made the ImageLoader constructor protected.
+
+        Reviewed by Sam Weinig.
+
+        * html/HTMLEmbedElement.cpp:
+        (WebCore::HTMLEmbedElement::parseAttribute):
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::HTMLImageElement):
+        * html/HTMLImageLoader.cpp:
+        (WebCore::HTMLImageLoader::HTMLImageLoader):
+        (WebCore::HTMLImageLoader::dispatchLoadEvent):
+        (WebCore::HTMLImageLoader::sourceURI):
+        (WebCore::HTMLImageLoader::notifyFinished):
+        * html/HTMLImageLoader.h:
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::imageLoader):
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::parseAttribute):
+        * html/HTMLPlugInImageElement.cpp:
+        (WebCore::HTMLPlugInImageElement::startLoadingImage):
+        * html/HTMLVideoElement.cpp:
+        (WebCore::HTMLVideoElement::didAttachRenderers):
+        (WebCore::HTMLVideoElement::parseAttribute):
+        * loader/ImageLoader.cpp:
+        (WebCore::ImageLoader::ImageLoader):
+        (WebCore::ImageLoader::~ImageLoader):
+        (WebCore::ImageLoader::updateFromElement):
+        (WebCore::ImageLoader::notifyFinished):
+        (WebCore::ImageLoader::renderImageResource):
+        (WebCore::ImageLoader::updatedHasPendingEvent):
+        (WebCore::ImageLoader::timerFired):
+        (WebCore::ImageLoader::dispatchPendingBeforeLoadEvent):
+        (WebCore::ImageLoader::dispatchPendingLoadEvent):
+        (WebCore::ImageLoader::dispatchPendingErrorEvent):
+        * loader/ImageLoader.h:
+        (WebCore::ImageLoader::element):
+        * svg/SVGImageElement.cpp:
+        (WebCore::SVGImageElement::SVGImageElement):
+        * svg/SVGImageLoader.cpp:
+        (WebCore::SVGImageLoader::SVGImageLoader):
+        (WebCore::SVGImageLoader::~SVGImageLoader):
+        (WebCore::SVGImageLoader::dispatchLoadEvent):
+        (WebCore::SVGImageLoader::sourceURI):
+        * svg/SVGImageLoader.h:
+
 2014-02-05  Sergio Correia  <sergio.correia@openbossa.org>
 
         SVG preserveAspectRatio=none is not honored.
index 47c9da9deda8f7d86d3f8abd054323927eb3a7a2..096f6fa3180d00d30f1f304e324db7ea721dcfa8 100644 (file)
@@ -108,7 +108,7 @@ void HTMLEmbedElement::parseAttribute(const QualifiedName& name, const AtomicStr
         document().updateStyleIfNeeded();
         if (renderer() && isImageType()) {
             if (!m_imageLoader)
-                m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+                m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
             m_imageLoader->updateFromElementIgnoringPreviousError();
         }
     } else
index 51f86e59b778d243feb813d2a3fca89751745945..9878c78af74b0d8f1bff9401cf1d00a8e14d2b84 100644 (file)
@@ -42,7 +42,7 @@ using namespace HTMLNames;
 
 HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
     : HTMLElement(tagName, document)
-    , m_imageLoader(this)
+    , m_imageLoader(*this)
     , m_form(form)
     , m_compositeOperator(CompositeSourceOver)
     , m_imageDevicePixelRatio(1.0f)
index 4743dcb22ce155d158075d5175b67fd9bb4dd90f..543c2f9427517942174f7b67486bb2dac4065ee4 100644 (file)
@@ -37,8 +37,8 @@
 
 namespace WebCore {
 
-HTMLImageLoader::HTMLImageLoader(Element* node)
-    : ImageLoader(node)
+HTMLImageLoader::HTMLImageLoader(Element& element)
+    : ImageLoader(element)
 {
 }
 
@@ -55,13 +55,13 @@ void HTMLImageLoader::dispatchLoadEvent()
     bool errorOccurred = image()->errorOccurred();
     if (!errorOccurred && image()->response().httpStatusCode() >= 400)
         errorOccurred = isHTMLObjectElement(element()); // An <object> considers a 404 to be an error and should fire onerror.
-    element()->dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false));
+    element().dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false));
 }
 
 String HTMLImageLoader::sourceURI(const AtomicString& attr) const
 {
 #if ENABLE(DASHBOARD_SUPPORT)
-    Settings* settings = element()->document().settings();
+    Settings* settings = element().document().settings();
     if (settings && settings->usesDashboardBackwardCompatibilityMode() && attr.length() > 7 && attr.startsWith("url(\"") && attr.endsWith("\")"))
         return attr.string().substring(5, attr.length() - 7);
 #endif
@@ -73,20 +73,20 @@ void HTMLImageLoader::notifyFinished(CachedResource*)
 {
     CachedImage* cachedImage = image();
 
-    RefPtr<Element> element = this->element();
+    Ref<Element> protect(element());
     ImageLoader::notifyFinished(cachedImage);
 
     bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400;
     if (!loadError) {
-        if (!element->inDocument()) {
+        if (!element().inDocument()) {
             JSC::VM* vm = JSDOMWindowBase::commonVM();
             JSC::JSLockHolder lock(vm);
             vm->heap.reportExtraMemoryCost(cachedImage->encodedSize());
         }
     }
 
-    if (loadError && isHTMLObjectElement(element.get()))
-        toHTMLObjectElement(element.get())->renderFallbackContent();
+    if (loadError && isHTMLObjectElement(element()))
+        toHTMLObjectElement(element()).renderFallbackContent();
 }
 
 }
index 14ea2bc3a15d50fd6a7caaaf4579cb631969a087..9df2a6fd4714f246775de492c24bce079d78679c 100644 (file)
@@ -27,9 +27,9 @@
 
 namespace WebCore {
 
-class HTMLImageLoader : public ImageLoader {
+class HTMLImageLoader final : public ImageLoader {
 public:
-    HTMLImageLoader(Element*);
+    explicit HTMLImageLoader(Element&);
     virtual ~HTMLImageLoader();
 
     virtual void dispatchLoadEvent() override;
index 99219f99706b27040fde7e15b23ed6d78c43c41d..0ec3782604f86876372e1f94cf5b294ce7e3f0cf 100644 (file)
@@ -142,7 +142,7 @@ PassRefPtr<HTMLInputElement> HTMLInputElement::create(const QualifiedName& tagNa
 HTMLImageLoader* HTMLInputElement::imageLoader()
 {
     if (!m_imageLoader)
-        m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+        m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
     return m_imageLoader.get();
 }
 
index 84286d2d509643d17170c5332cbd82a7e86ddfae..0b42d52294a591f2d3f5bcfa4744502bf4ea30f8 100644 (file)
@@ -120,7 +120,7 @@ void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicSt
             setNeedsWidgetUpdate(true);
             if (isImageType()) {
                 if (!m_imageLoader)
-                    m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+                    m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
                 m_imageLoader->updateFromElementIgnoringPreviousError();
             }
         }
index 18ef20628c5f5f99d9a6b0e07c80f0c7b3dc7802..1db121cb80d2b9252d6ad207d7d9e6ab67a42ac5 100644 (file)
@@ -329,7 +329,7 @@ void HTMLPlugInImageElement::updateWidgetCallback(Node& node, unsigned)
 void HTMLPlugInImageElement::startLoadingImage()
 {
     if (!m_imageLoader)
-        m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+        m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
     m_imageLoader->updateFromElement();
 }
 
index 69237e4350e4ca1dac1fbd685f3ccde470b41594..bb9fe355b0a10aeac719e87740138efc1721ccf6 100644 (file)
@@ -86,7 +86,7 @@ void HTMLVideoElement::didAttachRenderers()
         updateDisplayState();
         if (shouldDisplayPosterImage()) {
             if (!m_imageLoader)
-                m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+                m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
             m_imageLoader->updateFromElement();
             if (renderer())
                 toRenderImage(renderer())->imageResource().setCachedImage(m_imageLoader->image());
@@ -125,7 +125,7 @@ void HTMLVideoElement::parseAttribute(const QualifiedName& name, const AtomicStr
 #endif
         if (shouldDisplayPosterImage()) {
             if (!m_imageLoader)
-                m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+                m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
             m_imageLoader->updateFromElementIgnoringPreviousError();
         } else {
             if (renderer())
index 29ce43b25e6700954f1ae8cdcf7c4cde7e0891d4..60ac464dfc5d668d67ea6d4518bfb70d7e16c7cc 100644 (file)
@@ -53,8 +53,7 @@ template<> struct ValueCheck<WebCore::ImageLoader*> {
     {
         if (!p)
             return;
-        ASSERT(p->element());
-        ValueCheck<WebCore::Element*>::checkConsistency(p->element());
+        ValueCheck<WebCore::Element*>::checkConsistency(&p->element());
     }
 };
 
@@ -87,7 +86,7 @@ static inline bool pageIsBeingDismissed(Document& document)
     return frame && frame->loader().pageDismissalEventBeingDispatched() != FrameLoader::NoDismissal;
 }
 
-ImageLoader::ImageLoader(Element* element)
+ImageLoader::ImageLoader(Element& element)
     : m_element(element)
     , m_image(0)
     , m_derefElementTimer(this, &ImageLoader::timerFired)
@@ -120,7 +119,7 @@ ImageLoader::~ImageLoader()
     // If the ImageLoader is being destroyed but it is still protecting its image-loading Element,
     // remove that protection here.
     if (m_elementIsProtected)
-        m_element->deref();
+        element().deref();
 }
 
 void ImageLoader::setImage(CachedImage* newImage)
@@ -165,11 +164,11 @@ void ImageLoader::updateFromElement()
 {
     // If we're not making renderers for the page, then don't load images.  We don't want to slow
     // down the raw HTML parsing case by loading images we don't intend to display.
-    Document& document = m_element->document();
+    Document& document = element().document();
     if (!document.hasLivingRenderTree())
         return;
 
-    AtomicString attr = m_element->imageSourceURL();
+    AtomicString attr = element().imageSourceURL();
 
     if (attr == m_failedLoadURL)
         return;
@@ -179,9 +178,9 @@ void ImageLoader::updateFromElement()
     CachedResourceHandle<CachedImage> newImage = 0;
     if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) {
         CachedResourceRequest request(ResourceRequest(document.completeURL(sourceURI(attr))));
-        request.setInitiator(element());
+        request.setInitiator(&element());
 
-        String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
+        String crossOriginMode = element().fastGetAttribute(HTMLNames::crossoriginAttr);
         if (!crossOriginMode.isNull()) {
             StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
             updateRequestForAccessControl(request.mutableResourceRequest(), document.securityOrigin(), allowCredentials);
@@ -284,9 +283,9 @@ void ImageLoader::notifyFinished(CachedResource* resource)
     if (!m_hasPendingLoadEvent)
         return;
 
-    if (m_element->fastHasAttribute(HTMLNames::crossoriginAttr)
-        && !m_element->document().securityOrigin()->canRequest(image()->response().url())
-        && !resource->passesAccessControlCheck(m_element->document().securityOrigin())) {
+    if (element().fastHasAttribute(HTMLNames::crossoriginAttr)
+        && !element().document().securityOrigin()->canRequest(image()->response().url())
+        && !resource->passesAccessControlCheck(element().document().securityOrigin())) {
 
         setImageWithoutConsideringPendingLoadEvent(0);
 
@@ -294,7 +293,7 @@ void ImageLoader::notifyFinished(CachedResource* resource)
         errorEventSender().dispatchEventSoon(this);
 
         DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Cross-origin image load denied by Cross-Origin Resource Sharing policy.")));
-        m_element->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage);
+        element().document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage);
 
         ASSERT(!m_hasPendingLoadEvent);
 
@@ -317,7 +316,7 @@ void ImageLoader::notifyFinished(CachedResource* resource)
 
 RenderImageResource* ImageLoader::renderImageResource()
 {
-    auto renderer = m_element->renderer();
+    auto renderer = element().renderer();
     if (!renderer)
         return nullptr;
 
@@ -367,7 +366,7 @@ void ImageLoader::updatedHasPendingEvent()
         if (m_derefElementTimer.isActive())
             m_derefElementTimer.stop();
         else
-            m_element->ref();
+            element().ref();
     } else {
         ASSERT(!m_derefElementTimer.isActive());
         m_derefElementTimer.startOneShot(0);
@@ -376,7 +375,7 @@ void ImageLoader::updatedHasPendingEvent()
 
 void ImageLoader::timerFired(Timer<ImageLoader>&)
 {
-    m_element->deref();
+    element().deref();
 }
 
 void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender)
@@ -397,10 +396,10 @@ void ImageLoader::dispatchPendingBeforeLoadEvent()
         return;
     if (!m_image)
         return;
-    if (!m_element->document().hasLivingRenderTree())
+    if (!element().document().hasLivingRenderTree())
         return;
     m_hasPendingBeforeLoadEvent = false;
-    if (m_element->dispatchBeforeLoadEvent(m_image->url())) {
+    if (element().dispatchBeforeLoadEvent(m_image->url())) {
         updateRenderer();
         return;
     }
@@ -412,8 +411,8 @@ void ImageLoader::dispatchPendingBeforeLoadEvent()
     loadEventSender().cancelEvent(this);
     m_hasPendingLoadEvent = false;
     
-    if (isHTMLObjectElement(m_element))
-        toHTMLObjectElement(m_element)->renderFallbackContent();
+    if (isHTMLObjectElement(element()))
+        toHTMLObjectElement(element()).renderFallbackContent();
 
     // Only consider updating the protection ref-count of the Element immediately before returning
     // from this function as doing so might result in the destruction of this ImageLoader.
@@ -427,7 +426,7 @@ void ImageLoader::dispatchPendingLoadEvent()
     if (!m_image)
         return;
     m_hasPendingLoadEvent = false;
-    if (m_element->document().hasLivingRenderTree())
+    if (element().document().hasLivingRenderTree())
         dispatchLoadEvent();
 
     // Only consider updating the protection ref-count of the Element immediately before returning
@@ -440,8 +439,8 @@ void ImageLoader::dispatchPendingErrorEvent()
     if (!m_hasPendingErrorEvent)
         return;
     m_hasPendingErrorEvent = false;
-    if (m_element->document().hasLivingRenderTree())
-        m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false));
+    if (element().document().hasLivingRenderTree())
+        element().dispatchEvent(Event::create(eventNames().errorEvent, false, false));
 
     // Only consider updating the protection ref-count of the Element immediately before returning
     // from this function as doing so might result in the destruction of this ImageLoader.
index d76fa3a85d2b7abfa2949b33fd9b7fe96017ed82..6d4d883d379085c40c731cf504426454d84b8b73 100644 (file)
@@ -39,7 +39,6 @@ typedef EventSender<ImageLoader> ImageEventSender;
 
 class ImageLoader : public CachedImageClient {
 public:
-    explicit ImageLoader(Element*);
     virtual ~ImageLoader();
 
     // This function should be called when the element is attached to a document; starts
@@ -52,7 +51,9 @@ public:
 
     void elementDidMoveToNewDocument();
 
-    Element* element() const { return m_element; }
+    Element& element() { return m_element; }
+    const Element& element() const { return m_element; }
+
     bool imageComplete() const { return m_imageComplete; }
 
     CachedImage* image() const { return m_image.get(); }
@@ -70,6 +71,7 @@ public:
     static void dispatchPendingErrorEvents();
 
 protected:
+    explicit ImageLoader(Element&);
     virtual void notifyFinished(CachedResource*) override;
 
 private:
@@ -90,7 +92,7 @@ private:
 
     void timerFired(Timer<ImageLoader>&);
 
-    Element* m_element;
+    Element& m_element;
     CachedResourceHandle<CachedImage> m_image;
     Timer<ImageLoader> m_derefElementTimer;
     AtomicString m_failedLoadURL;
index 1140a0a6f646ba2065a323643e57a042ee30b684..9fc2b5d40acff573f1cb518f45899f1411f2e514 100644 (file)
@@ -60,7 +60,7 @@ inline SVGImageElement::SVGImageElement(const QualifiedName& tagName, Document&
     , m_y(LengthModeHeight)
     , m_width(LengthModeWidth)
     , m_height(LengthModeHeight)
-    , m_imageLoader(this)
+    , m_imageLoader(*this)
 {
     registerAnimatedPropertiesForSVGImageElement();
 }
index 510f3f0447d3900bf35bcab73f2dde0f2ac155b9..9c8ea4afce994eec760603c2fc8b60148ffa1a4e 100644 (file)
 #include "Event.h"
 #include "EventNames.h"
 #include "HTMLParserIdioms.h"
-#include "RenderImage.h"
 #include "SVGImageElement.h"
 
 namespace WebCore {
 
-SVGImageLoader::SVGImageLoader(SVGImageElement* node)
-    : ImageLoader(node)
+SVGImageLoader::SVGImageLoader(SVGImageElement& element)
+    : ImageLoader(element)
+{
+}
+
+SVGImageLoader::~SVGImageLoader()
 {
 }
 
 void SVGImageLoader::dispatchLoadEvent()
 {
     if (image()->errorOccurred())
-        element()->dispatchEvent(Event::create(eventNames().errorEvent, false, false));
+        element().dispatchEvent(Event::create(eventNames().errorEvent, false, false));
     else {
-        SVGImageElement* imageElement = toSVGImageElement(element());
-        if (imageElement->externalResourcesRequiredBaseValue())
-            imageElement->sendSVGLoadEventIfPossible(true);
+        if (toSVGImageElement(element()).externalResourcesRequiredBaseValue())
+            toSVGImageElement(ImageLoader::element()).sendSVGLoadEventIfPossible(true);
     }
 }
 
 String SVGImageLoader::sourceURI(const AtomicString& attribute) const
 {
-    URL base = element()->baseURI();
+    URL base = element().baseURI();
     if (base.isValid())
         return URL(base, stripLeadingAndTrailingHTMLSpaces(attribute)).string();
-    return element()->document().completeURL(stripLeadingAndTrailingHTMLSpaces(attribute));
+    return element().document().completeURL(stripLeadingAndTrailingHTMLSpaces(attribute));
 }
 
 }
index d718ba319618ac0900810df30a7f13d0c617a5f7..30a09fcbc5d23f01d72e5a4c4d1d70630d715f98 100644 (file)
@@ -26,9 +26,10 @@ namespace WebCore {
 
 class SVGImageElement;
 
-class SVGImageLoader : public ImageLoader {
+class SVGImageLoader final : public ImageLoader {
 public:
-    SVGImageLoader(SVGImageElement*);
+    explicit SVGImageLoader(SVGImageElement&);
+    virtual ~SVGImageLoader();
 
 private:
     virtual void dispatchLoadEvent() override;