From 4559faf8d879eb18d2b5729c19d3af9c6482d39f Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 14 Mar 2021 17:05:02 +0100 Subject: [PATCH] LibWeb: Support named CSS properties on CSSStyleDeclaration wrapper Use the new CustomGet/CustomPut wrapper mechansim to intercept gets and puts on CSSStyleDeclaration objects. This allows content to get and set individual CSS properties from JavaScript. :^) --- .../CSSStyleDeclarationWrapperCustom.cpp | 78 +++++++++++++++++++ Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../LibWeb/CSS/CSSStyleDeclaration.h | 2 + .../LibWeb/CSS/CSSStyleDeclaration.idl | 1 + 4 files changed, 82 insertions(+) create mode 100644 Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp diff --git a/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp b/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp new file mode 100644 index 0000000000..f240181086 --- /dev/null +++ b/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021, 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 + +namespace Web::Bindings { + +JS::Value CSSStyleDeclarationWrapper::get(const JS::PropertyName& name, JS::Value receiver) const +{ + // FIXME: These should actually use camelCase versions of the property names! + auto property_id = CSS::property_id_from_string(name.to_string()); + if (property_id == CSS::PropertyID::Invalid) + return Base::get(name, receiver); + for (auto& property : impl().properties()) { + if (property.property_id == property_id) + return js_string(vm(), property.value->to_string()); + } + return js_string(vm(), String::empty()); +} + +bool CSSStyleDeclarationWrapper::put(const JS::PropertyName& name, JS::Value value, JS::Value receiver) +{ + // FIXME: These should actually use camelCase versions of the property names! + auto property_id = CSS::property_id_from_string(name.to_string()); + if (property_id == CSS::PropertyID::Invalid) + return Base::put(name, value, receiver); + + auto css_text = value.to_string(global_object()); + if (vm().exception()) + return false; + + auto new_value = parse_css_value(CSS::ParsingContext {}, css_text, property_id); + // FIXME: What are we supposed to do if we can't parse it? + if (!new_value) + return false; + + // FIXME: I don't think '!important' is being handled correctly here.. + + for (auto& property : impl().m_properties) { + if (property.property_id == property_id) { + property.value = new_value.release_nonnull(); + return true; + } + } + + impl().m_properties.append(CSS::StyleProperty { + .property_id = property_id, + .value = new_value.release_nonnull(), + .important = false, + }); + return true; +} + +} diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 4b062f0118..f183d154aa 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -1,4 +1,5 @@ set(SOURCES + Bindings/CSSStyleDeclarationWrapperCustom.cpp Bindings/EventListenerWrapper.cpp Bindings/EventWrapperFactory.cpp Bindings/EventTargetWrapperFactory.cpp diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h index ec553198b8..d96b94a687 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h @@ -58,6 +58,8 @@ public: String item(size_t index) const; private: + friend class Bindings::CSSStyleDeclarationWrapper; + explicit CSSStyleDeclaration(Vector&&); Vector m_properties; diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl index d894e72cda..6b5ad0ffce 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl @@ -1,3 +1,4 @@ +[CustomGet,CustomPut] interface CSSStyleDeclaration { readonly attribute unsigned long length;