From b959d06ace0d17bdf37870e7a11a0daf292aa3af Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 21 Jun 2020 15:37:13 +0200 Subject: [PATCH] LibWeb: Generate HTMLCanvasElement bindings from IDL :^) --- .../Bindings/HTMLCanvasElementWrapper.cpp | 106 ------------------ .../Bindings/HTMLCanvasElementWrapper.h | 53 --------- Libraries/LibWeb/CMakeLists.txt | 2 +- .../CodeGenerators/WrapperGenerator.cpp | 11 ++ Libraries/LibWeb/DOM/HTMLCanvasElement.cpp | 18 ++- Libraries/LibWeb/DOM/HTMLCanvasElement.h | 4 +- Libraries/LibWeb/DOM/HTMLCanvasElement.idl | 7 ++ Libraries/LibWeb/Layout/LayoutCanvas.cpp | 4 +- 8 files changed, 30 insertions(+), 175 deletions(-) delete mode 100644 Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp delete mode 100644 Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h create mode 100644 Libraries/LibWeb/DOM/HTMLCanvasElement.idl diff --git a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp deleted file mode 100644 index 954bd3baf8b..00000000000 --- a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2020, Andreas Kling - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Web { -namespace Bindings { - -HTMLCanvasElementWrapper::HTMLCanvasElementWrapper(JS::GlobalObject& global_object, HTMLCanvasElement& element) - : HTMLElementWrapper(global_object, element) -{ -} - -void HTMLCanvasElementWrapper::initialize(JS::Interpreter& interpreter, JS::GlobalObject& global_object) -{ - ElementWrapper::initialize(interpreter, global_object); - define_native_function("getContext", get_context, 1); - define_native_property("width", width_getter, nullptr); - define_native_property("height", height_getter, nullptr); -} - -HTMLCanvasElementWrapper::~HTMLCanvasElementWrapper() -{ -} - -HTMLCanvasElement& HTMLCanvasElementWrapper::node() -{ - return static_cast(NodeWrapper::impl()); -} - -const HTMLCanvasElement& HTMLCanvasElementWrapper::node() const -{ - return static_cast(NodeWrapper::impl()); -} - -static HTMLCanvasElement* impl_from(JS::Interpreter& interpreter, JS::GlobalObject& global_object) -{ - auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object); - if (!this_object) - return nullptr; - // FIXME: Verify that it's a HTMLCanvasElementWrapper somehow! - return &static_cast(this_object)->node(); -} - -JS_DEFINE_NATIVE_FUNCTION(HTMLCanvasElementWrapper::get_context) -{ - auto* impl = impl_from(interpreter, global_object); - if (!impl) - return {}; - auto context_type = interpreter.argument(0).to_string(interpreter); - if (interpreter.exception()) - return {}; - if (context_type != "2d") - return JS::js_null(); - auto* context = impl->get_context(context_type); - return wrap(interpreter.heap(), *context); -} - -JS_DEFINE_NATIVE_GETTER(HTMLCanvasElementWrapper::width_getter) -{ - if (auto* impl = impl_from(interpreter, global_object)) - return JS::Value(impl->requested_width()); - return {}; -} - -JS_DEFINE_NATIVE_GETTER(HTMLCanvasElementWrapper::height_getter) -{ - if (auto* impl = impl_from(interpreter, global_object)) - return JS::Value(impl->requested_height()); - return {}; -} - -} -} diff --git a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h deleted file mode 100644 index d981484b7e9..00000000000 --- a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020, Andreas Kling - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include - -namespace Web { -namespace Bindings { - -class HTMLCanvasElementWrapper : public HTMLElementWrapper { -public: - HTMLCanvasElementWrapper(JS::GlobalObject&, HTMLCanvasElement&); - virtual void initialize(JS::Interpreter&, JS::GlobalObject&) override; - virtual ~HTMLCanvasElementWrapper() override; - - HTMLCanvasElement& node(); - const HTMLCanvasElement& node() const; - -private: - virtual const char* class_name() const override { return "HTMLCanvasElementWrapper"; } - - JS_DECLARE_NATIVE_FUNCTION(get_context); - - JS_DECLARE_NATIVE_GETTER(width_getter); - JS_DECLARE_NATIVE_GETTER(height_getter); -}; - -} -} diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 0d406bde373..64a01ec1f8a 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -2,7 +2,6 @@ set(SOURCES Bindings/CanvasRenderingContext2DWrapper.cpp Bindings/EventListenerWrapper.cpp Bindings/EventWrapper.cpp - Bindings/HTMLCanvasElementWrapper.cpp Bindings/ImageDataWrapper.cpp Bindings/LocationObject.cpp Bindings/MouseEventWrapper.cpp @@ -158,6 +157,7 @@ libweb_js_wrapper(Document) libweb_js_wrapper(Element) libweb_js_wrapper(HTMLElement) libweb_js_wrapper(HTMLImageElement) +libweb_js_wrapper(HTMLCanvasElement) get_property(WRAPPER_SOURCES GLOBAL PROPERTY wrapper_sources) set(SOURCES ${SOURCES} ${WRAPPER_SOURCES}) diff --git a/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp b/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp index 65edacd1d15..701c2576431 100644 --- a/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp +++ b/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp @@ -75,6 +75,7 @@ struct Function { struct Attribute { bool readonly { false }; + bool unsigned_ { false }; Type type; String name; @@ -175,6 +176,7 @@ OwnPtr parse_interface(const StringView& input) auto parse_attribute = [&] { bool readonly = false; + bool unsigned_ = false; if (next_is("readonly")) { consume_string("readonly"); readonly = true; @@ -184,12 +186,18 @@ OwnPtr parse_interface(const StringView& input) consume_string("attribute"); consume_whitespace(); } + if (next_is("unsigned")) { + consume_string("unsigned"); + unsigned_ = true; + consume_whitespace(); + } auto type = parse_type(); consume_whitespace(); auto name = consume_while([](auto ch) { return !isspace(ch) && ch != ';'; }); consume_specific(';'); Attribute attribute; attribute.readonly = readonly; + attribute.unsigned_ = unsigned_; attribute.type = type; attribute.name = name; attribute.getter_callback_name = String::format("%s_getter", snake_name(attribute.name).characters()); @@ -370,6 +378,7 @@ void generate_implementation(const IDL::Interface& interface) out() << "#include "; out() << "#include "; out() << "#include "; + out() << "#include "; out() << "namespace Web {"; out() << "namespace Bindings {"; @@ -488,6 +497,8 @@ void generate_implementation(const IDL::Interface& interface) out() << " new_array->indexed_properties().append(wrap(interpreter.heap(), element));"; out() << " }"; out() << " return new_array;"; + } else if (return_type.name == "long") { + out() << " return JS::Value(retval);"; } else { out() << " return wrap(interpreter.heap(), const_cast<" << return_type.name << "&>(*retval));"; } diff --git a/Libraries/LibWeb/DOM/HTMLCanvasElement.cpp b/Libraries/LibWeb/DOM/HTMLCanvasElement.cpp index 4b7149082f9..6052dd2b830 100644 --- a/Libraries/LibWeb/DOM/HTMLCanvasElement.cpp +++ b/Libraries/LibWeb/DOM/HTMLCanvasElement.cpp @@ -45,14 +45,14 @@ HTMLCanvasElement::~HTMLCanvasElement() { } -int HTMLCanvasElement::requested_width() const +unsigned HTMLCanvasElement::width() const { - return attribute(HTML::AttributeNames::width).to_int().value_or(300); + return attribute(HTML::AttributeNames::width).to_uint().value_or(300); } -int HTMLCanvasElement::requested_height() const +unsigned HTMLCanvasElement::height() const { - return attribute(HTML::AttributeNames::height).to_int().value_or(150); + return attribute(HTML::AttributeNames::height).to_uint().value_or(150); } RefPtr HTMLCanvasElement::create_layout_node(const StyleProperties* parent_style) const @@ -74,12 +74,8 @@ CanvasRenderingContext2D* HTMLCanvasElement::get_context(String type) static Gfx::IntSize bitmap_size_for_canvas(const HTMLCanvasElement& canvas) { - int width = canvas.requested_width(); - int height = canvas.requested_height(); - if (width < 0 || height < 0) { - dbg() << "Refusing to create canvas with negative size"; - return {}; - } + auto width = canvas.width(); + auto height = canvas.height(); Checked area = width; area *= height; @@ -92,7 +88,7 @@ static Gfx::IntSize bitmap_size_for_canvas(const HTMLCanvasElement& canvas) dbg() << "Refusing to create " << width << "x" << height << " canvas (exceeds maximum size)"; return {}; } - return { width, height }; + return Gfx::IntSize(width, height); } bool HTMLCanvasElement::create_bitmap() diff --git a/Libraries/LibWeb/DOM/HTMLCanvasElement.h b/Libraries/LibWeb/DOM/HTMLCanvasElement.h index ce2f8c38d1a..7c9f16f1f37 100644 --- a/Libraries/LibWeb/DOM/HTMLCanvasElement.h +++ b/Libraries/LibWeb/DOM/HTMLCanvasElement.h @@ -47,8 +47,8 @@ public: CanvasRenderingContext2D* get_context(String type); - int requested_width() const; - int requested_height() const; + unsigned width() const; + unsigned height() const; private: virtual RefPtr create_layout_node(const StyleProperties* parent_style) const override; diff --git a/Libraries/LibWeb/DOM/HTMLCanvasElement.idl b/Libraries/LibWeb/DOM/HTMLCanvasElement.idl new file mode 100644 index 00000000000..2e65d3aba67 --- /dev/null +++ b/Libraries/LibWeb/DOM/HTMLCanvasElement.idl @@ -0,0 +1,7 @@ +interface HTMLCanvasElement : HTMLElement { + + CanvasRenderingContext2D? getContext(DOMString contextId); + readonly attribute unsigned long width; + readonly attribute unsigned long height; + +} diff --git a/Libraries/LibWeb/Layout/LayoutCanvas.cpp b/Libraries/LibWeb/Layout/LayoutCanvas.cpp index 2b905219c48..5c6fbd25913 100644 --- a/Libraries/LibWeb/Layout/LayoutCanvas.cpp +++ b/Libraries/LibWeb/Layout/LayoutCanvas.cpp @@ -44,8 +44,8 @@ void LayoutCanvas::layout(LayoutMode layout_mode) { set_has_intrinsic_width(true); set_has_intrinsic_height(true); - set_intrinsic_width(node().requested_width()); - set_intrinsic_height(node().requested_height()); + set_intrinsic_width(node().width()); + set_intrinsic_height(node().height()); LayoutReplaced::layout(layout_mode); }