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;