Title: [225119] trunk/Source/WebCore
Revision
225119
Author
d...@apple.com
Date
2017-11-23 11:00:20 -0800 (Thu, 23 Nov 2017)

Log Message

Add a base class for HTMLCanvasElement and OffscreenCanvas
https://bugs.webkit.org/show_bug.cgi?id=179701
<rdar://problem/35545195>

Post-review updates from Darin Adler review.

* html/CanvasBase.cpp:
(WebCore::CanvasBase::asHTMLCanvasElement): Deleted. Replaced by having the call
sites get the reference and do the correct downcast<>.
* html/CanvasBase.h: Remove asHTMLCanvasElement. Add pure virtual ref/deref functions
so they can be overridden by subclasses. Unfortunately they can't be called ref/deref otherwise
they conflict with Node.
* html/HTMLCanvasElement.h: Add the type traits, so is<HTMLCanvasElement>(canvasBase) will
work.
* html/HTMLTagNames.in: Specify the <canvas> element as having custom type traits.
* html/OffscreenCanvas.h: Lots of overrides to finals.
* html/canvas/CanvasRenderingContext.cpp: Use canvasBase.de/refCanvasBase rather than
casting.
(WebCore::CanvasRenderingContext::ref):
(WebCore::CanvasRenderingContext::deref):
* html/canvas/CanvasRenderingContext.h: Lots of overrides to finals.
* html/canvas/CanvasRenderingContext2D.h:
* html/canvas/ImageBitmapRenderingContext.cpp:
(WebCore::ImageBitmapRenderingContext::canvas const):
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::create):
(WebCore::WebGLRenderingContextBase::canvas):
* html/canvas/WebGPURenderingContext.cpp:
(WebCore::WebGPURenderingContext::canvas const):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::recordCanvasAction):
* inspector/agents/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::recordCanvasAction):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (225118 => 225119)


--- trunk/Source/WebCore/ChangeLog	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/ChangeLog	2017-11-23 19:00:20 UTC (rev 225119)
@@ -1,3 +1,39 @@
+2017-11-22  Dean Jackson  <d...@apple.com>
+
+        Add a base class for HTMLCanvasElement and OffscreenCanvas
+        https://bugs.webkit.org/show_bug.cgi?id=179701
+        <rdar://problem/35545195>
+
+        Post-review updates from Darin Adler review.
+
+        * html/CanvasBase.cpp:
+        (WebCore::CanvasBase::asHTMLCanvasElement): Deleted. Replaced by having the call
+        sites get the reference and do the correct downcast<>.
+        * html/CanvasBase.h: Remove asHTMLCanvasElement. Add pure virtual ref/deref functions
+        so they can be overridden by subclasses. Unfortunately they can't be called ref/deref otherwise
+        they conflict with Node.
+        * html/HTMLCanvasElement.h: Add the type traits, so is<HTMLCanvasElement>(canvasBase) will
+        work.
+        * html/HTMLTagNames.in: Specify the <canvas> element as having custom type traits.
+        * html/OffscreenCanvas.h: Lots of overrides to finals.
+        * html/canvas/CanvasRenderingContext.cpp: Use canvasBase.de/refCanvasBase rather than
+        casting.
+        (WebCore::CanvasRenderingContext::ref):
+        (WebCore::CanvasRenderingContext::deref):
+        * html/canvas/CanvasRenderingContext.h: Lots of overrides to finals.
+        * html/canvas/CanvasRenderingContext2D.h:
+        * html/canvas/ImageBitmapRenderingContext.cpp:
+        (WebCore::ImageBitmapRenderingContext::canvas const):
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::create):
+        (WebCore::WebGLRenderingContextBase::canvas):
+        * html/canvas/WebGPURenderingContext.cpp:
+        (WebCore::WebGPURenderingContext::canvas const):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::recordCanvasAction):
+        * inspector/agents/InspectorCanvasAgent.cpp:
+        (WebCore::InspectorCanvasAgent::recordCanvasAction):
+
 2017-11-23  Darin Adler  <da...@apple.com>
 
         Reduce WTF::String operations that do unnecessary Unicode operations instead of ASCII

Modified: trunk/Source/WebCore/html/CanvasBase.cpp (225118 => 225119)


--- trunk/Source/WebCore/html/CanvasBase.cpp	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/CanvasBase.cpp	2017-11-23 19:00:20 UTC (rev 225119)
@@ -35,11 +35,4 @@
 {
 }
 
-HTMLCanvasElement* CanvasBase::asHTMLCanvasElement()
-{
-    if (!isHTMLCanvasElement())
-        return nullptr;
-    return static_cast<HTMLCanvasElement*>(this);
 }
-
-}

Modified: trunk/Source/WebCore/html/CanvasBase.h (225118 => 225119)


--- trunk/Source/WebCore/html/CanvasBase.h	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/CanvasBase.h	2017-11-23 19:00:20 UTC (rev 225119)
@@ -38,11 +38,12 @@
 public:
     virtual ~CanvasBase() = default;
 
+    virtual void refCanvasBase() = 0;
+    virtual void derefCanvasBase() = 0;
+
     virtual bool isHTMLCanvasElement() const { return false; }
     virtual bool isOffscreenCanvas() const { return false; }
 
-    HTMLCanvasElement* asHTMLCanvasElement();
-
     virtual unsigned width() const = 0;
     virtual unsigned height() const = 0;
     virtual const IntSize& size() const  = 0;

Modified: trunk/Source/WebCore/html/HTMLCanvasElement.h (225118 => 225119)


--- trunk/Source/WebCore/html/HTMLCanvasElement.h	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.h	2017-11-23 19:00:20 UTC (rev 225119)
@@ -82,13 +82,13 @@
     void removeObserver(CanvasObserver&);
     HashSet<Element*> cssCanvasClients() const;
 
-    unsigned width() const override { return size().width(); }
-    unsigned height() const override { return size().height(); }
+    unsigned width() const final { return size().width(); }
+    unsigned height() const final { return size().height(); }
 
     WEBCORE_EXPORT ExceptionOr<void> setWidth(unsigned);
     WEBCORE_EXPORT ExceptionOr<void> setHeight(unsigned);
 
-    const IntSize& size() const override { return m_size; }
+    const IntSize& size() const final { return m_size; }
 
     void setSize(const IntSize& newSize) override
     { 
@@ -101,8 +101,6 @@
         reset();
     }
 
-    bool isHTMLCanvasElement() const override { return true; }
-
     ExceptionOr<std::optional<RenderingContext>> getContext(JSC::ExecState&, const String& contextId, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
 
     CanvasRenderingContext* getContext(const String&);
@@ -153,7 +151,7 @@
     void makePresentationCopy();
     void clearPresentationCopy();
 
-    SecurityOrigin* securityOrigin() const override;
+    SecurityOrigin* securityOrigin() const final;
 
     AffineTransform baseTransform() const;
 
@@ -177,6 +175,8 @@
 private:
     HTMLCanvasElement(const QualifiedName&, Document&);
 
+    bool isHTMLCanvasElement() const final { return true; }
+
     void parseAttribute(const QualifiedName&, const AtomicString&) final;
     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
 
@@ -196,6 +196,9 @@
 
     bool isGPUBased() const;
 
+    void refCanvasBase() final { HTMLElement::ref(); }
+    void derefCanvasBase() final { HTMLElement::deref(); }
+
     HashSet<CanvasObserver*> m_observers;
     std::unique_ptr<CanvasRenderingContext> m_context;
 
@@ -220,3 +223,16 @@
 };
 
 } // namespace WebCore
+
+namespace WTF {
+template<typename ArgType> class TypeCastTraits<const WebCore::HTMLCanvasElement, ArgType, false /* isBaseType */> {
+public:
+    static bool isOfType(ArgType& node) { return checkTagName(node); }
+private:
+    static bool checkTagName(const WebCore::CanvasBase& base) { return base.isHTMLCanvasElement(); }
+    static bool checkTagName(const WebCore::HTMLElement& element) { return element.hasTagName(WebCore::HTMLNames::canvasTag); }
+    static bool checkTagName(const WebCore::Node& node) { return node.hasTagName(WebCore::HTMLNames::canvasTag); }
+    static bool checkTagName(const WebCore::EventTarget& target) { return is<WebCore::Node>(target) && checkTagName(downcast<WebCore::Node>(target)); }
+};
+}
+

Modified: trunk/Source/WebCore/html/HTMLTagNames.in (225118 => 225119)


--- trunk/Source/WebCore/html/HTMLTagNames.in	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/HTMLTagNames.in	2017-11-23 19:00:20 UTC (rev 225119)
@@ -25,7 +25,7 @@
 body
 br interfaceName=HTMLBRElement
 button constructorNeedsFormElement
-canvas
+canvas customTypeHelper
 caption interfaceName=HTMLTableCaptionElement
 center interfaceName=HTMLElement
 cite interfaceName=HTMLElement

Modified: trunk/Source/WebCore/html/OffscreenCanvas.h (225118 => 225119)


--- trunk/Source/WebCore/html/OffscreenCanvas.h	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/OffscreenCanvas.h	2017-11-23 19:00:20 UTC (rev 225119)
@@ -47,7 +47,7 @@
 // RefPtr<OffscreenCanvasRenderingContext2D>
 // >;
 
-class OffscreenCanvas : public RefCounted<OffscreenCanvas>, public CanvasBase, public EventTargetWithInlineData {
+class OffscreenCanvas final : public RefCounted<OffscreenCanvas>, public CanvasBase, public EventTargetWithInlineData {
     WTF_MAKE_FAST_ALLOCATED;
 public:
 
@@ -64,16 +64,14 @@
     static Ref<OffscreenCanvas> create(ScriptExecutionContext&, unsigned width, unsigned height);
     ~OffscreenCanvas();
 
-    unsigned width() const override;
+    unsigned width() const final;
     void setWidth(unsigned);
-    unsigned height() const override;
+    unsigned height() const final;
     void setHeight(unsigned);
 
-    const IntSize& size() const override;
-    void setSize(const IntSize&) override;
+    const IntSize& size() const final;
+    void setSize(const IntSize&) final;
 
-    bool isOffscreenCanvas() const override { return true; }
-
 #if ENABLE(WEBGL)
     // FIXME: Should be optional<OffscreenRenderingContext> from above.
     ExceptionOr<RefPtr<WebGLRenderingContext>> getContext(JSC::ExecState&, RenderingContextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
@@ -88,12 +86,17 @@
 
     OffscreenCanvas(ScriptExecutionContext&, unsigned width, unsigned height);
 
-    ScriptExecutionContext* scriptExecutionContext() const override { return CanvasBase::scriptExecutionContext(); }
+    bool isOffscreenCanvas() const final { return true; }
 
+    ScriptExecutionContext* scriptExecutionContext() const final { return CanvasBase::scriptExecutionContext(); }
+
     EventTargetInterface eventTargetInterface() const final { return OffscreenCanvasEventTargetInterfaceType; }
     void refEventTarget() final { ref(); }
     void derefEventTarget() final { deref(); }
 
+    void refCanvasBase() final { ref(); }
+    void derefCanvasBase() final { deref(); }
+
     IntSize m_size;
 };
 

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext.cpp (225118 => 225119)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext.cpp	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext.cpp	2017-11-23 19:00:20 UTC (rev 225119)
@@ -45,30 +45,12 @@
 
 void CanvasRenderingContext::ref()
 {
-    if (m_canvas.isHTMLCanvasElement()) {
-        auto* htmlCanvas = static_cast<HTMLCanvasElement*>(&m_canvas);
-        htmlCanvas->ref();
-        return;
-    }
-    if (is<OffscreenCanvas>(m_canvas)) {
-        auto* offscreenCanvas = static_cast<OffscreenCanvas*>(&m_canvas);
-        offscreenCanvas->ref();
-        return;
-    }
+    m_canvas.refCanvasBase();
 }
 
 void CanvasRenderingContext::deref()
 {
-    if (m_canvas.isHTMLCanvasElement()) {
-        auto* htmlCanvas = static_cast<HTMLCanvasElement*>(&m_canvas);
-        htmlCanvas->deref();
-        return;
-    }
-    if (is<OffscreenCanvas>(m_canvas)) {
-        auto* offscreenCanvas = static_cast<OffscreenCanvas*>(&m_canvas);
-        offscreenCanvas->deref();
-        return;
-    }
+    m_canvas.derefCanvasBase();
 }
 
 bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h (225118 => 225119)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext.h	2017-11-23 19:00:20 UTC (rev 225119)
@@ -70,7 +70,7 @@
     void setCallTracingActive(bool callTracingActive) { m_callTracingActive = callTracingActive; }
 
 protected:
-    CanvasRenderingContext(CanvasBase&);
+    explicit CanvasRenderingContext(CanvasBase&);
     bool wouldTaintOrigin(const CanvasPattern*);
     bool wouldTaintOrigin(const HTMLCanvasElement*);
     bool wouldTaintOrigin(const HTMLImageElement*);

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h (225118 => 225119)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h	2017-11-23 19:00:20 UTC (rev 225119)
@@ -76,7 +76,7 @@
     CanvasRenderingContext2D(CanvasBase&, bool usesCSSCompatibilityParseMode, bool usesDashboardCompatibilityMode);
     virtual ~CanvasRenderingContext2D();
 
-    HTMLCanvasElement& canvas() const { return static_cast<HTMLCanvasElement&>(canvasBase()); }
+    HTMLCanvasElement& canvas() const { return downcast<HTMLCanvasElement>(canvasBase()); }
 
     float lineWidth() const;
     void setLineWidth(float);

Modified: trunk/Source/WebCore/html/canvas/ImageBitmapRenderingContext.cpp (225118 => 225119)


--- trunk/Source/WebCore/html/canvas/ImageBitmapRenderingContext.cpp	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/canvas/ImageBitmapRenderingContext.cpp	2017-11-23 19:00:20 UTC (rev 225119)
@@ -48,7 +48,10 @@
 
 HTMLCanvasElement* ImageBitmapRenderingContext::canvas() const
 {
-    return canvasBase().asHTMLCanvasElement();
+    auto& base = canvasBase();
+    if (!is<HTMLCanvasElement>(base))
+        return nullptr;
+    return &downcast<HTMLCanvasElement>(base);
 }
 
 bool ImageBitmapRenderingContext::isAccelerated() const

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (225118 => 225119)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2017-11-23 19:00:20 UTC (rev 225119)
@@ -373,7 +373,7 @@
     bool isPendingPolicyResolution = false;
     HostWindow* hostWindow = nullptr;
 
-    auto* canvasElement = canvas.asHTMLCanvasElement();
+    auto* canvasElement = is<HTMLCanvasElement>(canvas) ? &downcast<HTMLCanvasElement>(canvas) : nullptr;
 
     if (canvasElement) {
         Document& document = canvasElement->document();
@@ -515,7 +515,10 @@
 
 HTMLCanvasElement* WebGLRenderingContextBase::canvas()
 {
-    return canvasBase().asHTMLCanvasElement();
+    auto& base = canvasBase();
+    if (!is<HTMLCanvasElement>(base))
+        return nullptr;
+    return &downcast<HTMLCanvasElement>(base);
 }
 
 // We check for context loss handling after a few seconds to give the JS a chance to register the event listeners

Modified: trunk/Source/WebCore/html/canvas/WebGPURenderingContext.cpp (225118 => 225119)


--- trunk/Source/WebCore/html/canvas/WebGPURenderingContext.cpp	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/html/canvas/WebGPURenderingContext.cpp	2017-11-23 19:00:20 UTC (rev 225119)
@@ -96,7 +96,10 @@
 
 HTMLCanvasElement* WebGPURenderingContext::canvas() const
 {
-    return canvasBase().asHTMLCanvasElement();
+    auto& base = canvasBase();
+    if (!is<HTMLCanvasElement>(base))
+        return nullptr;
+    return &downcast<HTMLCanvasElement>(base);
 }
 
 void WebGPURenderingContext::initializeNewContext()

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (225118 => 225119)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-11-23 19:00:20 UTC (rev 225119)
@@ -1236,7 +1236,8 @@
 inline void InspectorInstrumentation::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
-    auto* canvasElement = canvasRenderingContext.canvasBase().asHTMLCanvasElement();
+    auto& canvasBase = canvasRenderingContext.canvasBase();
+    auto* canvasElement = is<HTMLCanvasElement>(canvasBase) ? &downcast<HTMLCanvasElement>(canvasBase) : nullptr;
     if (canvasElement) {
         if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement->document()))
             recordCanvasActionImpl(*instrumentingAgents, canvasRenderingContext, name, WTFMove(parameters));

Modified: trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp (225118 => 225119)


--- trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp	2017-11-23 17:51:46 UTC (rev 225118)
+++ trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp	2017-11-23 19:00:20 UTC (rev 225119)
@@ -425,7 +425,8 @@
 
 void InspectorCanvasAgent::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
 {
-    auto* canvasElement = canvasRenderingContext.canvasBase().asHTMLCanvasElement();
+    auto& canvasBase = canvasRenderingContext.canvasBase();
+    auto* canvasElement = is<HTMLCanvasElement>(canvasBase) ? &downcast<HTMLCanvasElement>(canvasBase) : nullptr;
     if (!canvasElement)
         return;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to