From 26b0801a785c668b851106b4cb6a63c2080e4a4c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 22 Jun 2026 14:15:11 +0200 Subject: [PATCH] LibWeb: Return Utf16String from CSS Typed OM serialization Make CSS Typed OM to_string() implementations produce Utf16String instead of building UTF-8 strings and converting at the JS binding boundary. Use Utf16StringBuilder for numeric, math, and transform serialization paths that already feed CSS Typed OM stringification. Keep the older CSSOM StyleValue serializer on StringBuilder for now, and convert only where Typed OM source values or parser re-entry still need the existing UTF-8 representation. --- Libraries/LibWeb/CSS/CSSImageValue.cpp | 2 +- Libraries/LibWeb/CSS/CSSImageValue.h | 2 +- Libraries/LibWeb/CSS/CSSKeywordValue.cpp | 11 +++++----- Libraries/LibWeb/CSS/CSSKeywordValue.h | 5 +++-- Libraries/LibWeb/CSS/CSSMathClamp.cpp | 10 ++++----- Libraries/LibWeb/CSS/CSSMathClamp.h | 2 +- Libraries/LibWeb/CSS/CSSMathInvert.cpp | 10 ++++----- Libraries/LibWeb/CSS/CSSMathInvert.h | 2 +- Libraries/LibWeb/CSS/CSSMathMax.cpp | 8 +++---- Libraries/LibWeb/CSS/CSSMathMax.h | 2 +- Libraries/LibWeb/CSS/CSSMathMin.cpp | 8 +++---- Libraries/LibWeb/CSS/CSSMathMin.h | 2 +- Libraries/LibWeb/CSS/CSSMathNegate.cpp | 10 ++++----- Libraries/LibWeb/CSS/CSSMathNegate.h | 2 +- Libraries/LibWeb/CSS/CSSMathProduct.cpp | 12 +++++------ Libraries/LibWeb/CSS/CSSMathProduct.h | 2 +- Libraries/LibWeb/CSS/CSSMathSum.cpp | 12 +++++------ Libraries/LibWeb/CSS/CSSMathSum.h | 2 +- Libraries/LibWeb/CSS/CSSMathValue.h | 2 +- Libraries/LibWeb/CSS/CSSNumericValue.cpp | 9 ++++---- Libraries/LibWeb/CSS/CSSNumericValue.h | 7 ++++--- Libraries/LibWeb/CSS/CSSPerspective.cpp | 21 ++++++++++--------- Libraries/LibWeb/CSS/CSSRotate.cpp | 20 +++++++++--------- Libraries/LibWeb/CSS/CSSScale.cpp | 20 +++++++++--------- Libraries/LibWeb/CSS/CSSSkew.cpp | 14 ++++++------- Libraries/LibWeb/CSS/CSSSkewX.cpp | 8 +++---- Libraries/LibWeb/CSS/CSSSkewY.cpp | 8 +++---- Libraries/LibWeb/CSS/CSSStyleValue.cpp | 6 +++--- Libraries/LibWeb/CSS/CSSStyleValue.h | 3 ++- Libraries/LibWeb/CSS/CSSTransformValue.cpp | 9 ++++---- Libraries/LibWeb/CSS/CSSTransformValue.h | 2 +- Libraries/LibWeb/CSS/CSSTranslate.cpp | 20 +++++++++--------- Libraries/LibWeb/CSS/CSSUnitValue.cpp | 10 ++++----- Libraries/LibWeb/CSS/CSSUnitValue.h | 2 +- Libraries/LibWeb/CSS/CSSUnparsedValue.cpp | 14 +++++++------ Libraries/LibWeb/CSS/CSSUnparsedValue.h | 2 +- .../LibWeb/CSS/CSSVariableReferenceValue.cpp | 15 ++++++------- .../LibWeb/CSS/CSSVariableReferenceValue.h | 3 ++- Libraries/LibWeb/CSS/Serialize.cpp | 18 ++++++++++++++++ Libraries/LibWeb/CSS/Serialize.h | 2 ++ 40 files changed, 173 insertions(+), 146 deletions(-) diff --git a/Libraries/LibWeb/CSS/CSSImageValue.cpp b/Libraries/LibWeb/CSS/CSSImageValue.cpp index d175c8ea32..2438a748e8 100644 --- a/Libraries/LibWeb/CSS/CSSImageValue.cpp +++ b/Libraries/LibWeb/CSS/CSSImageValue.cpp @@ -32,7 +32,7 @@ void CSSImageValue::initialize(JS::Realm& realm) } // https://drafts.css-houdini.org/css-typed-om-1/#stylevalue-serialization -WebIDL::ExceptionOr CSSImageValue::to_string() const +WebIDL::ExceptionOr CSSImageValue::to_string() const { // AD-HOC: The spec doesn't say how to serialize this, as it's intentionally a black box. // We just rely on CSSStyleValue serializing its held StyleValue. diff --git a/Libraries/LibWeb/CSS/CSSImageValue.h b/Libraries/LibWeb/CSS/CSSImageValue.h index 6c40f75fc9..7c563db8e2 100644 --- a/Libraries/LibWeb/CSS/CSSImageValue.h +++ b/Libraries/LibWeb/CSS/CSSImageValue.h @@ -20,7 +20,7 @@ public: virtual ~CSSImageValue() override = default; - virtual WebIDL::ExceptionOr to_string() const override; + virtual WebIDL::ExceptionOr to_string() const override; virtual WebIDL::ExceptionOr> create_an_internal_representation(PropertyNameAndID const&, PerformTypeCheck) const override; private: diff --git a/Libraries/LibWeb/CSS/CSSKeywordValue.cpp b/Libraries/LibWeb/CSS/CSSKeywordValue.cpp index 0881f198fe..fc31ea2b7a 100644 --- a/Libraries/LibWeb/CSS/CSSKeywordValue.cpp +++ b/Libraries/LibWeb/CSS/CSSKeywordValue.cpp @@ -5,7 +5,6 @@ */ #include "CSSKeywordValue.h" -#include #include #include #include @@ -61,19 +60,19 @@ WebIDL::ExceptionOr CSSKeywordValue::set_value(FlyString value) } // https://drafts.css-houdini.org/css-typed-om-1/#keywordvalue-serialization -void CSSKeywordValue::serialize(StringBuilder& builder) const +void CSSKeywordValue::serialize(Utf16StringBuilder& builder) const { // To serialize a CSSKeywordValue this: // 1. Return this’s value internal slot. // AD-HOC: Serialize it as an identifier. Spec issue: https://github.com/w3c/csswg-drafts/issues/12545 - serialize_an_identifier(builder, m_value); + builder.append(Utf16String::from_utf8_without_validation(serialize_an_identifier(m_value))); } -WebIDL::ExceptionOr CSSKeywordValue::to_string() const +WebIDL::ExceptionOr CSSKeywordValue::to_string() const { - StringBuilder builder; + Utf16StringBuilder builder; serialize(builder); - return builder.to_string_without_validation(); + return builder.to_string(); } // https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation diff --git a/Libraries/LibWeb/CSS/CSSKeywordValue.h b/Libraries/LibWeb/CSS/CSSKeywordValue.h index 80c87ce8f1..e1968cdad9 100644 --- a/Libraries/LibWeb/CSS/CSSKeywordValue.h +++ b/Libraries/LibWeb/CSS/CSSKeywordValue.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace Web::CSS { @@ -28,8 +29,8 @@ public: FlyString const& value() const { return m_value; } WebIDL::ExceptionOr set_value(FlyString value); - void serialize(StringBuilder&) const; - virtual WebIDL::ExceptionOr to_string() const override; + void serialize(Utf16StringBuilder&) const; + virtual WebIDL::ExceptionOr to_string() const override; virtual WebIDL::ExceptionOr> create_an_internal_representation(PropertyNameAndID const&, PerformTypeCheck) const override; private: diff --git a/Libraries/LibWeb/CSS/CSSMathClamp.cpp b/Libraries/LibWeb/CSS/CSSMathClamp.cpp index ad71ec8096..2326d4898f 100644 --- a/Libraries/LibWeb/CSS/CSSMathClamp.cpp +++ b/Libraries/LibWeb/CSS/CSSMathClamp.cpp @@ -68,16 +68,16 @@ void CSSMathClamp::visit_edges(Visitor& visitor) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssmathvalue -void CSSMathClamp::serialize_math_value(StringBuilder& s, Nested, Parens) const +void CSSMathClamp::serialize_math_value(Utf16StringBuilder& s, Nested, Parens) const { // AD-HOC: The spec is missing serialization rules for CSSMathClamp: https://github.com/w3c/css-houdini-drafts/issues/1152 - s.append("clamp("sv); + s.append_ascii("clamp("sv); m_lower->serialize(s, { .nested = true, .parenless = true }); - s.append(", "sv); + s.append_ascii(", "sv); m_value->serialize(s, { .nested = true, .parenless = true }); - s.append(", "sv); + s.append_ascii(", "sv); m_upper->serialize(s, { .nested = true, .parenless = true }); - s.append(')'); + s.append_ascii(')'); } // https://drafts.css-houdini.org/css-typed-om-1/#dom-cssmathclamp-lower diff --git a/Libraries/LibWeb/CSS/CSSMathClamp.h b/Libraries/LibWeb/CSS/CSSMathClamp.h index d5f22d87ad..ed4cb74607 100644 --- a/Libraries/LibWeb/CSS/CSSMathClamp.h +++ b/Libraries/LibWeb/CSS/CSSMathClamp.h @@ -28,7 +28,7 @@ public: GC::Ref value() const; GC::Ref upper() const; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const override; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const override; virtual bool is_equal_numeric_value(GC::Ref other) const override; virtual Optional create_a_sum_value() const override; diff --git a/Libraries/LibWeb/CSS/CSSMathInvert.cpp b/Libraries/LibWeb/CSS/CSSMathInvert.cpp index d2607a3907..1f9b8b379b 100644 --- a/Libraries/LibWeb/CSS/CSSMathInvert.cpp +++ b/Libraries/LibWeb/CSS/CSSMathInvert.cpp @@ -54,7 +54,7 @@ void CSSMathInvert::visit_edges(Visitor& visitor) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssmathvalue -void CSSMathInvert::serialize_math_value(StringBuilder& s, Nested nested, Parens parens) const +void CSSMathInvert::serialize_math_value(Utf16StringBuilder& s, Nested nested, Parens parens) const { // NB: Only steps 1 and 6 apply here. // 1. Let s initially be the empty string. @@ -65,21 +65,21 @@ void CSSMathInvert::serialize_math_value(StringBuilder& s, Nested nested, Parens // otherwise, append "calc(" to s. if (parens == Parens::With) { if (nested == Nested::Yes) { - s.append('('); + s.append_ascii('('); } else { - s.append("calc("sv); + s.append_ascii("calc("sv); } } // 2. Append "1 / " to s. - s.append("1 / "sv); + s.append_ascii("1 / "sv); // 3. Serialize this’s value internal slot with nested set to true, and append the result to s. m_value->serialize(s, { .nested = true }); // 4. If paren-less is false, append ")" to s, if (parens == Parens::With) - s.append(')'); + s.append_ascii(')'); // 5. Return s. } diff --git a/Libraries/LibWeb/CSS/CSSMathInvert.h b/Libraries/LibWeb/CSS/CSSMathInvert.h index 93195a57d7..7c635f6ec5 100644 --- a/Libraries/LibWeb/CSS/CSSMathInvert.h +++ b/Libraries/LibWeb/CSS/CSSMathInvert.h @@ -26,7 +26,7 @@ public: GC::Ref value() const; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const override; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const override; virtual bool is_equal_numeric_value(GC::Ref other) const override; virtual Optional create_a_sum_value() const override; diff --git a/Libraries/LibWeb/CSS/CSSMathMax.cpp b/Libraries/LibWeb/CSS/CSSMathMax.cpp index 58e3f9961c..15bedb1a17 100644 --- a/Libraries/LibWeb/CSS/CSSMathMax.cpp +++ b/Libraries/LibWeb/CSS/CSSMathMax.cpp @@ -86,7 +86,7 @@ void CSSMathMax::visit_edges(Visitor& visitor) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssmathvalue -void CSSMathMax::serialize_math_value(StringBuilder& s, Nested, Parens) const +void CSSMathMax::serialize_math_value(Utf16StringBuilder& s, Nested, Parens) const { // NB: Only steps 1 and 2 apply here. // 1. Let s initially be the empty string. @@ -94,7 +94,7 @@ void CSSMathMax::serialize_math_value(StringBuilder& s, Nested, Parens) const // 2. If this is a CSSMathMin or CSSMathMax: { // 1. Append "min(" or "max(" to s, as appropriate. - s.append("max("sv); + s.append_ascii("max("sv); // 2. For each arg in this’s values internal slot, serialize arg with nested and paren-less both true, and // append the result to s, appending a ", " between successive values. @@ -103,13 +103,13 @@ void CSSMathMax::serialize_math_value(StringBuilder& s, Nested, Parens) const if (first) { first = false; } else { - s.append(", "sv); + s.append_ascii(", "sv); } arg->serialize(s, { .nested = true, .parenless = true }); } // 3. Append ")" to s and return s. - s.append(')'); + s.append_ascii(')'); } } diff --git a/Libraries/LibWeb/CSS/CSSMathMax.h b/Libraries/LibWeb/CSS/CSSMathMax.h index d6de4fa4b4..b02df0e1f2 100644 --- a/Libraries/LibWeb/CSS/CSSMathMax.h +++ b/Libraries/LibWeb/CSS/CSSMathMax.h @@ -27,7 +27,7 @@ public: GC::Ref values() const; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const override; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const override; virtual bool is_equal_numeric_value(GC::Ref other) const override; virtual Optional create_a_sum_value() const override; diff --git a/Libraries/LibWeb/CSS/CSSMathMin.cpp b/Libraries/LibWeb/CSS/CSSMathMin.cpp index 886f62f664..e68dea919c 100644 --- a/Libraries/LibWeb/CSS/CSSMathMin.cpp +++ b/Libraries/LibWeb/CSS/CSSMathMin.cpp @@ -87,7 +87,7 @@ void CSSMathMin::visit_edges(Visitor& visitor) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssmathvalue -void CSSMathMin::serialize_math_value(StringBuilder& s, Nested, Parens) const +void CSSMathMin::serialize_math_value(Utf16StringBuilder& s, Nested, Parens) const { // NB: Only steps 1 and 2 apply here. // 1. Let s initially be the empty string. @@ -95,7 +95,7 @@ void CSSMathMin::serialize_math_value(StringBuilder& s, Nested, Parens) const // 2. If this is a CSSMathMin or CSSMathMax: { // 1. Append "min(" or "max(" to s, as appropriate. - s.append("min("sv); + s.append_ascii("min("sv); // 2. For each arg in this’s values internal slot, serialize arg with nested and paren-less both true, and // append the result to s, appending a ", " between successive values. @@ -104,13 +104,13 @@ void CSSMathMin::serialize_math_value(StringBuilder& s, Nested, Parens) const if (first) { first = false; } else { - s.append(", "sv); + s.append_ascii(", "sv); } arg->serialize(s, { .nested = true, .parenless = true }); } // 3. Append ")" to s and return s. - s.append(')'); + s.append_ascii(')'); } } diff --git a/Libraries/LibWeb/CSS/CSSMathMin.h b/Libraries/LibWeb/CSS/CSSMathMin.h index 8698aeb46d..a2a7d198d7 100644 --- a/Libraries/LibWeb/CSS/CSSMathMin.h +++ b/Libraries/LibWeb/CSS/CSSMathMin.h @@ -27,7 +27,7 @@ public: GC::Ref values() const; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const override; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const override; virtual bool is_equal_numeric_value(GC::Ref other) const override; virtual Optional create_a_sum_value() const override; diff --git a/Libraries/LibWeb/CSS/CSSMathNegate.cpp b/Libraries/LibWeb/CSS/CSSMathNegate.cpp index 2b38bd20a1..c3719ec669 100644 --- a/Libraries/LibWeb/CSS/CSSMathNegate.cpp +++ b/Libraries/LibWeb/CSS/CSSMathNegate.cpp @@ -51,7 +51,7 @@ void CSSMathNegate::visit_edges(Visitor& visitor) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssmathvalue -void CSSMathNegate::serialize_math_value(StringBuilder& s, Nested nested, Parens parens) const +void CSSMathNegate::serialize_math_value(Utf16StringBuilder& s, Nested nested, Parens parens) const { // NB: Only steps 1 and 4 apply here. // 1. Let s initially be the empty string. @@ -62,21 +62,21 @@ void CSSMathNegate::serialize_math_value(StringBuilder& s, Nested nested, Parens // otherwise, append "calc(" to s. if (parens == Parens::With) { if (nested == Nested::Yes) { - s.append('('); + s.append_ascii('('); } else { - s.append("calc("sv); + s.append_ascii("calc("sv); } } // 2. Append "-" to s. - s.append('-'); + s.append_ascii('-'); // 3. Serialize this’s value internal slot with nested set to true, and append the result to s. m_value->serialize(s, { .nested = true }); // 4. If paren-less is false, append ")" to s, if (parens == Parens::With) - s.append(')'); + s.append_ascii(')'); // 5. Return s. } diff --git a/Libraries/LibWeb/CSS/CSSMathNegate.h b/Libraries/LibWeb/CSS/CSSMathNegate.h index 3acc816403..7dbd503d3d 100644 --- a/Libraries/LibWeb/CSS/CSSMathNegate.h +++ b/Libraries/LibWeb/CSS/CSSMathNegate.h @@ -26,7 +26,7 @@ public: GC::Ref value() const; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const override; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const override; virtual bool is_equal_numeric_value(GC::Ref other) const override; virtual Optional create_a_sum_value() const override; diff --git a/Libraries/LibWeb/CSS/CSSMathProduct.cpp b/Libraries/LibWeb/CSS/CSSMathProduct.cpp index 92e80ee194..605bb01a31 100644 --- a/Libraries/LibWeb/CSS/CSSMathProduct.cpp +++ b/Libraries/LibWeb/CSS/CSSMathProduct.cpp @@ -86,7 +86,7 @@ void CSSMathProduct::visit_edges(Visitor& visitor) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssmathvalue -void CSSMathProduct::serialize_math_value(StringBuilder& s, Nested nested, Parens parens) const +void CSSMathProduct::serialize_math_value(Utf16StringBuilder& s, Nested nested, Parens parens) const { // NB: Only steps 1 and 5 apply here. // 1. Let s initially be the empty string. @@ -97,9 +97,9 @@ void CSSMathProduct::serialize_math_value(StringBuilder& s, Nested nested, Paren // otherwise, append "calc(" to s. if (parens == Parens::With) { if (nested == Nested::Yes) { - s.append('('); + s.append_ascii('('); } else { - s.append("calc("sv); + s.append_ascii("calc("sv); } } @@ -117,20 +117,20 @@ void CSSMathProduct::serialize_math_value(StringBuilder& s, Nested nested, Paren // 1. If arg is a CSSMathInvert, append " / " to s, then serialize arg’s value internal slot with nested // set to true, and append the result to s. if (auto* invert = as_if(*arg)) { - s.append(" / "sv); + s.append_ascii(" / "sv); invert->value()->serialize(s, { .nested = true }); } // 2. Otherwise, append " * " to s, then serialize arg with nested set to true, and append the result to s. else { - s.append(" * "sv); + s.append_ascii(" * "sv); arg->serialize(s, { .nested = true }); } } // 4. If paren-less is false, append ")" to s, if (parens == Parens::With) - s.append(')'); + s.append_ascii(')'); // 5. Return s. } diff --git a/Libraries/LibWeb/CSS/CSSMathProduct.h b/Libraries/LibWeb/CSS/CSSMathProduct.h index 57ebb305d4..69e5705f08 100644 --- a/Libraries/LibWeb/CSS/CSSMathProduct.h +++ b/Libraries/LibWeb/CSS/CSSMathProduct.h @@ -27,7 +27,7 @@ public: GC::Ref values() const; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const override; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const override; virtual bool is_equal_numeric_value(GC::Ref other) const override; virtual Optional create_a_sum_value() const override; diff --git a/Libraries/LibWeb/CSS/CSSMathSum.cpp b/Libraries/LibWeb/CSS/CSSMathSum.cpp index 4db823068b..e6bbfb0cba 100644 --- a/Libraries/LibWeb/CSS/CSSMathSum.cpp +++ b/Libraries/LibWeb/CSS/CSSMathSum.cpp @@ -84,7 +84,7 @@ void CSSMathSum::visit_edges(Visitor& visitor) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssmathvalue -void CSSMathSum::serialize_math_value(StringBuilder& s, Nested nested, Parens parens) const +void CSSMathSum::serialize_math_value(Utf16StringBuilder& s, Nested nested, Parens parens) const { // NB: Only steps 1 and 3 apply here. // 1. Let s initially be the empty string. @@ -95,9 +95,9 @@ void CSSMathSum::serialize_math_value(StringBuilder& s, Nested nested, Parens pa // otherwise, append "calc(" to s. if (parens == Parens::With) { if (nested == Nested::Yes) { - s.append('('); + s.append_ascii('('); } else { - s.append("calc("sv); + s.append_ascii("calc("sv); } } @@ -116,20 +116,20 @@ void CSSMathSum::serialize_math_value(StringBuilder& s, Nested nested, Parens pa // 1. If arg is a CSSMathNegate, append " - " to s, then serialize arg’s value internal slot with nested // set to true, and append the result to s. if (auto* negate = as_if(*arg)) { - s.append(" - "sv); + s.append_ascii(" - "sv); negate->value()->serialize(s, { .nested = true }); } // 2. Otherwise, append " + " to s, then serialize arg with nested set to true, and append the result to s. else { - s.append(" + "sv); + s.append_ascii(" + "sv); arg->serialize(s, { .nested = true }); } } // 4. If paren-less is false, append ")" to s, if (parens == Parens::With) - s.append(')'); + s.append_ascii(')'); // 5. Return s. } diff --git a/Libraries/LibWeb/CSS/CSSMathSum.h b/Libraries/LibWeb/CSS/CSSMathSum.h index 84f3fce027..747f4c76b4 100644 --- a/Libraries/LibWeb/CSS/CSSMathSum.h +++ b/Libraries/LibWeb/CSS/CSSMathSum.h @@ -27,7 +27,7 @@ public: GC::Ref values() const; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const override; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const override; virtual bool is_equal_numeric_value(GC::Ref other) const override; virtual Optional create_a_sum_value() const override; diff --git a/Libraries/LibWeb/CSS/CSSMathValue.h b/Libraries/LibWeb/CSS/CSSMathValue.h index aa715a32e7..c603253986 100644 --- a/Libraries/LibWeb/CSS/CSSMathValue.h +++ b/Libraries/LibWeb/CSS/CSSMathValue.h @@ -30,7 +30,7 @@ public: With, Without, }; - virtual void serialize_math_value(StringBuilder&, Nested, Parens) const = 0; + virtual void serialize_math_value(Utf16StringBuilder&, Nested, Parens) const = 0; virtual WebIDL::ExceptionOr> create_an_internal_representation(PropertyNameAndID const&, PerformTypeCheck) const final override; diff --git a/Libraries/LibWeb/CSS/CSSNumericValue.cpp b/Libraries/LibWeb/CSS/CSSNumericValue.cpp index e62bb28917..23b633e6d3 100644 --- a/Libraries/LibWeb/CSS/CSSNumericValue.cpp +++ b/Libraries/LibWeb/CSS/CSSNumericValue.cpp @@ -5,7 +5,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include #include @@ -404,7 +403,7 @@ Bindings::CSSNumericType CSSNumericValue::type_for_bindings() const } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssnumericvalue -void CSSNumericValue::serialize(StringBuilder& builder, SerializationParams const& params) const +void CSSNumericValue::serialize(Utf16StringBuilder& builder, SerializationParams const& params) const { // To serialize a CSSNumericValue this, given an optional minimum, a numeric value, and optional maximum, a numeric value: // 1. If this is a CSSUnitValue, serialize a CSSUnitValue from this, passing minimum and maximum. Return the result. @@ -419,11 +418,11 @@ void CSSNumericValue::serialize(StringBuilder& builder, SerializationParams cons params.parenless ? CSSMathValue::Parens::Without : CSSMathValue::Parens::With); } -String CSSNumericValue::to_string(SerializationParams const& params) const +Utf16String CSSNumericValue::to_string(SerializationParams const& params) const { - StringBuilder builder; + Utf16StringBuilder builder; serialize(builder, params); - return builder.to_string_without_validation(); + return builder.to_string(); } // https://drafts.css-houdini.org/css-typed-om-1/#rectify-a-numberish-value diff --git a/Libraries/LibWeb/CSS/CSSNumericValue.h b/Libraries/LibWeb/CSS/CSSNumericValue.h index 5c8c8d4c77..13487fdc4e 100644 --- a/Libraries/LibWeb/CSS/CSSNumericValue.h +++ b/Libraries/LibWeb/CSS/CSSNumericValue.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include #include @@ -56,9 +57,9 @@ public: Bindings::CSSNumericType type_for_bindings() const; NumericType const& type() const { return m_type; } - virtual WebIDL::ExceptionOr to_string() const final override { return to_string({}); } - void serialize(StringBuilder&, SerializationParams const&) const; - String to_string(SerializationParams const&) const; + virtual WebIDL::ExceptionOr to_string() const final override { return to_string({}); } + void serialize(Utf16StringBuilder&, SerializationParams const&) const; + Utf16String to_string(SerializationParams const&) const; static WebIDL::ExceptionOr> parse(JS::VM&, String const& css_text); diff --git a/Libraries/LibWeb/CSS/CSSPerspective.cpp b/Libraries/LibWeb/CSS/CSSPerspective.cpp index 8004b88e5d..43adb2cfb7 100644 --- a/Libraries/LibWeb/CSS/CSSPerspective.cpp +++ b/Libraries/LibWeb/CSS/CSSPerspective.cpp @@ -87,22 +87,23 @@ void CSSPerspective::visit_edges(Visitor& visitor) WebIDL::ExceptionOr CSSPerspective::to_string() const { // 1. Let s initially be "perspective(". - StringBuilder builder { StringBuilder::Mode::UTF16 }; - builder.append("perspective("sv); + Utf16StringBuilder builder; + builder.append_ascii("perspective("sv); // 2. Serialize this’s length internal slot, with a minimum of 0px, and append it to s. - auto serialized_length = TRY(m_length.visit( - [](GC::Ref const& numeric_value) -> WebIDL::ExceptionOr { - return numeric_value->to_string({ .minimum = 0 }); + TRY(m_length.visit( + [&](GC::Ref const& numeric_value) -> WebIDL::ExceptionOr { + numeric_value->serialize(builder, { .minimum = 0 }); + return {}; }, - [](GC::Ref const& keyword_value) -> WebIDL::ExceptionOr { - return keyword_value->to_string(); + [&](GC::Ref const& keyword_value) -> WebIDL::ExceptionOr { + builder.append(TRY(keyword_value->to_string())); + return {}; })); - builder.append(serialized_length); // 3. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } WebIDL::ExceptionOr> CSSPerspective::to_matrix() const diff --git a/Libraries/LibWeb/CSS/CSSRotate.cpp b/Libraries/LibWeb/CSS/CSSRotate.cpp index 5d49a98516..af2402ff14 100644 --- a/Libraries/LibWeb/CSS/CSSRotate.cpp +++ b/Libraries/LibWeb/CSS/CSSRotate.cpp @@ -98,49 +98,49 @@ void CSSRotate::visit_edges(Visitor& visitor) WebIDL::ExceptionOr CSSRotate::to_string() const { // 1. Let s initially be the empty string. - StringBuilder builder { StringBuilder::Mode::UTF16 }; + Utf16StringBuilder builder; // 2. If this’s is2D internal slot is false: if (!is_2d()) { // 1. Append "rotate3d(" to s. - builder.append("rotate3d("sv); + builder.append_ascii("rotate3d("sv); // 2. Serialize this’s x internal slot, and append it to s. m_x->serialize(builder, {}); // 3. Append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 4. Serialize this’s y internal slot, and append it to s. m_y->serialize(builder, {}); // 5. Append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 6. Serialize this’s z internal slot, and append it to s. m_z->serialize(builder, {}); // 7. Append "," to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 8. Serialize this’s angle internal slot, and append it to s. m_angle->serialize(builder, {}); // 9. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } // 2. Otherwise: else { // 1. Append "rotate(" to s. - builder.append("rotate("sv); + builder.append_ascii("rotate("sv); // 2. Serialize this’s angle internal slot, and append it to s. m_angle->serialize(builder, {}); // 3. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } } diff --git a/Libraries/LibWeb/CSS/CSSScale.cpp b/Libraries/LibWeb/CSS/CSSScale.cpp index 88e83456f3..ee49356594 100644 --- a/Libraries/LibWeb/CSS/CSSScale.cpp +++ b/Libraries/LibWeb/CSS/CSSScale.cpp @@ -82,38 +82,38 @@ void CSSScale::visit_edges(Visitor& visitor) WebIDL::ExceptionOr CSSScale::to_string() const { // 1. Let s initially be the empty string. - StringBuilder builder { StringBuilder::Mode::UTF16 }; + Utf16StringBuilder builder; // 2. If this’s is2D internal slot is false: if (!is_2d()) { // 1. Append "scale3d(" to s. - builder.append("scale3d("sv); + builder.append_ascii("scale3d("sv); // 2. Serialize this’s x internal slot, and append it to s. m_x->serialize(builder, {}); // 3. Append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 4. Serialize this’s y internal slot, and append it to s. m_y->serialize(builder, {}); // 5. Append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 6. Serialize this’s z internal slot, and append it to s. m_z->serialize(builder, {}); // 7. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } // 3. Otherwise: else { // 1. Append "scale(" to s. - builder.append("scale("sv); + builder.append_ascii("scale("sv); // 2. Serialize this’s x internal slot, and append it to s. m_x->serialize(builder, {}); @@ -123,14 +123,14 @@ WebIDL::ExceptionOr CSSScale::to_string() const // Upstream issue: https://github.com/w3c/css-houdini-drafts/issues/1161 // 4. Otherwise, append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 5. Serialize this’s y internal slot, and append it to s. m_y->serialize(builder, {}); // 6. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } } diff --git a/Libraries/LibWeb/CSS/CSSSkew.cpp b/Libraries/LibWeb/CSS/CSSSkew.cpp index 5004057fe8..ab5f4380ba 100644 --- a/Libraries/LibWeb/CSS/CSSSkew.cpp +++ b/Libraries/LibWeb/CSS/CSSSkew.cpp @@ -65,27 +65,27 @@ void CSSSkew::visit_edges(Visitor& visitor) WebIDL::ExceptionOr CSSSkew::to_string() const { // 1. Let s initially be "skew(". - StringBuilder builder { StringBuilder::Mode::UTF16 }; - builder.append("skew("sv); + Utf16StringBuilder builder; + builder.append_ascii("skew("sv); // 2. Serialize this’s ax internal slot, and append it to s. m_ax->serialize(builder, {}); // 3. If this’s ay internal slot is a CSSUnitValue with a value of 0, then append ")" to s and return s. if (auto* ay_unit_value = as_if(*m_ay); ay_unit_value && ay_unit_value->value() == 0) { - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } // 4. Otherwise, append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 5. Serialize this’s ay internal slot, and append it to s. m_ay->serialize(builder, {}); // 6. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } // https://drafts.css-houdini.org/css-typed-om-1/#dom-csstransformcomponent-tomatrix diff --git a/Libraries/LibWeb/CSS/CSSSkewX.cpp b/Libraries/LibWeb/CSS/CSSSkewX.cpp index 9bbd9edaf2..2aeb05a6b0 100644 --- a/Libraries/LibWeb/CSS/CSSSkewX.cpp +++ b/Libraries/LibWeb/CSS/CSSSkewX.cpp @@ -60,15 +60,15 @@ void CSSSkewX::visit_edges(Visitor& visitor) WebIDL::ExceptionOr CSSSkewX::to_string() const { // 1. Let s initially be "skewX(". - StringBuilder builder { StringBuilder::Mode::UTF16 }; - builder.append("skewX("sv); + Utf16StringBuilder builder; + builder.append_ascii("skewX("sv); // 2. Serialize this’s ax internal slot, and append it to s. m_ax->serialize(builder, {}); // 3. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } // https://drafts.css-houdini.org/css-typed-om-1/#dom-csstransformcomponent-tomatrix diff --git a/Libraries/LibWeb/CSS/CSSSkewY.cpp b/Libraries/LibWeb/CSS/CSSSkewY.cpp index 094247a324..0d89a7b7fb 100644 --- a/Libraries/LibWeb/CSS/CSSSkewY.cpp +++ b/Libraries/LibWeb/CSS/CSSSkewY.cpp @@ -60,15 +60,15 @@ void CSSSkewY::visit_edges(Visitor& visitor) WebIDL::ExceptionOr CSSSkewY::to_string() const { // 1. Let s initially be "skewY(". - StringBuilder builder { StringBuilder::Mode::UTF16 }; - builder.append("skewY("sv); + Utf16StringBuilder builder; + builder.append_ascii("skewY("sv); // 2. Serialize this’s ay internal slot, and append it to s. m_ay->serialize(builder, {}); // 3. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } // https://drafts.css-houdini.org/css-typed-om-1/#dom-csstransformcomponent-tomatrix diff --git a/Libraries/LibWeb/CSS/CSSStyleValue.cpp b/Libraries/LibWeb/CSS/CSSStyleValue.cpp index 283f525f37..3c72863719 100644 --- a/Libraries/LibWeb/CSS/CSSStyleValue.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleValue.cpp @@ -104,7 +104,7 @@ WebIDL::ExceptionOr, GC::RootVector CSSStyleValue::to_string() const +WebIDL::ExceptionOr CSSStyleValue::to_string() const { // FIXME: if the value was constructed from a USVString // NB: Basically, if this was constructed with "parse a CSSStyleValue", regardless of what CSSStyleValue type it is now. @@ -119,11 +119,11 @@ WebIDL::ExceptionOr CSSStyleValue::to_string() const // FIXME: otherwise, if the value was extracted from the CSSOM // NB: For CSSStyleValue itself, we use the source value we were created from. if (m_source_value) - return m_source_value->to_string(SerializationMode::Normal); + return Utf16String::from_utf8_without_validation(m_source_value->to_string(SerializationMode::Normal)); { // the serialization is specified in §6.7 Serialization from CSSOM Values below. } - return String {}; + return Utf16String::from_utf8_without_validation(""sv); } // https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation diff --git a/Libraries/LibWeb/CSS/CSSStyleValue.h b/Libraries/LibWeb/CSS/CSSStyleValue.h index cd0adada1b..9d606caf96 100644 --- a/Libraries/LibWeb/CSS/CSSStyleValue.h +++ b/Libraries/LibWeb/CSS/CSSStyleValue.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace Web::CSS { @@ -35,7 +36,7 @@ public: }; static WebIDL::ExceptionOr, GC::RootVector>>> parse_a_css_style_value(JS::VM&, Utf16FlyString property, String css_text, ParseMultiple); - virtual WebIDL::ExceptionOr to_string() const; + virtual WebIDL::ExceptionOr to_string() const; // FIXME: Temporary hack. Really we want to pass something like a CalculationContext with the valid types and ranges. enum class PerformTypeCheck : u8 { diff --git a/Libraries/LibWeb/CSS/CSSTransformValue.cpp b/Libraries/LibWeb/CSS/CSSTransformValue.cpp index 069da23187..298b9e193d 100644 --- a/Libraries/LibWeb/CSS/CSSTransformValue.cpp +++ b/Libraries/LibWeb/CSS/CSSTransformValue.cpp @@ -5,6 +5,7 @@ */ #include "CSSTransformValue.h" +#include #include #include #include @@ -141,19 +142,19 @@ WebIDL::ExceptionOr> CSSTransformValue::to_matrix() } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-csstransformvalue -WebIDL::ExceptionOr CSSTransformValue::to_string() const +WebIDL::ExceptionOr CSSTransformValue::to_string() const { // 1. Return the result of serializing each item in this’s values to iterate over, then concatenating them // separated by " ". - StringBuilder builder; + Utf16StringBuilder builder; bool first = true; for (auto const& transform : m_transforms) { if (!first) - builder.append(" "sv); + builder.append_ascii(' '); first = false; builder.append(TRY(transform->to_string())); } - return builder.to_string_without_validation(); + return builder.to_string(); } // https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation diff --git a/Libraries/LibWeb/CSS/CSSTransformValue.h b/Libraries/LibWeb/CSS/CSSTransformValue.h index a830defd0b..3c2567f5f2 100644 --- a/Libraries/LibWeb/CSS/CSSTransformValue.h +++ b/Libraries/LibWeb/CSS/CSSTransformValue.h @@ -30,7 +30,7 @@ public: bool is_2d() const; WebIDL::ExceptionOr> to_matrix() const; - virtual WebIDL::ExceptionOr to_string() const override; + virtual WebIDL::ExceptionOr to_string() const override; virtual WebIDL::ExceptionOr> create_an_internal_representation(PropertyNameAndID const&, PerformTypeCheck) const override; diff --git a/Libraries/LibWeb/CSS/CSSTranslate.cpp b/Libraries/LibWeb/CSS/CSSTranslate.cpp index 53f1694573..2fee033d86 100644 --- a/Libraries/LibWeb/CSS/CSSTranslate.cpp +++ b/Libraries/LibWeb/CSS/CSSTranslate.cpp @@ -81,49 +81,49 @@ void CSSTranslate::visit_edges(Visitor& visitor) WebIDL::ExceptionOr CSSTranslate::to_string() const { // 1. Let s initially be the empty string. - StringBuilder builder { StringBuilder::Mode::UTF16 }; + Utf16StringBuilder builder; // 2. If this’s is2D internal slot is false: if (!is_2d()) { // 1. Append "translate3d(" to s. - builder.append("translate3d("sv); + builder.append_ascii("translate3d("sv); // 2. Serialize this’s x internal slot, and append it to s. m_x->serialize(builder, {}); // 3. Append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 4. Serialize this’s y internal slot, and append it to s. m_y->serialize(builder, {}); // 5. Append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 6. Serialize this’s z internal slot, and append it to s. m_z->serialize(builder, {}); // 7. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } // 3. Otherwise: else { // 1. Append "translate(" to s. - builder.append("translate("sv); + builder.append_ascii("translate("sv); // 2. Serialize this’s x internal slot, and append it to s. m_x->serialize(builder, {}); // 3. Append ", " to s. - builder.append(", "sv); + builder.append_ascii(", "sv); // 4. Serialize this’s y internal slot, and append it to s. m_y->serialize(builder, {}); // 5. Append ")" to s, and return s. - builder.append(")"sv); - return builder.to_utf16_string(); + builder.append_ascii(')'); + return builder.to_string(); } } diff --git a/Libraries/LibWeb/CSS/CSSUnitValue.cpp b/Libraries/LibWeb/CSS/CSSUnitValue.cpp index ab56e875a2..49e788fcbe 100644 --- a/Libraries/LibWeb/CSS/CSSUnitValue.cpp +++ b/Libraries/LibWeb/CSS/CSSUnitValue.cpp @@ -92,7 +92,7 @@ void CSSUnitValue::set_value(double value) } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssunitvalue -void CSSUnitValue::serialize_unit_value(StringBuilder& builder, Optional minimum, Optional maximum) const +void CSSUnitValue::serialize_unit_value(Utf16StringBuilder& builder, Optional minimum, Optional maximum) const { // To serialize a CSSUnitValue this, with optional arguments minimum, a numeric value, and maximum, a numeric value: @@ -107,7 +107,7 @@ void CSSUnitValue::serialize_unit_value(StringBuilder& builder, Optional || (maximum.has_value() && m_value > maximum.value()); if (needs_calc_wrapper) - builder.append("calc("sv); + builder.append_ascii("calc("sv); // 2. Set s to the result of serializing a from value, per CSSOM §6.7.2 Serializing CSS Values. serialize_a_number(builder, m_value); @@ -120,16 +120,16 @@ void CSSUnitValue::serialize_unit_value(StringBuilder& builder, Optional // -> "percent" else if (m_unit == "percent"_fly_string) { // Append "%" to s. - builder.append('%'); + builder.append_ascii('%'); } // -> anything else else { // Append unit to s. - builder.append(m_unit.to_ascii_lowercase()); + builder.append_ascii(m_unit.to_ascii_lowercase().bytes_as_string_view()); } if (needs_calc_wrapper) - builder.append(')'); + builder.append_ascii(')'); // 5. Return s. } diff --git a/Libraries/LibWeb/CSS/CSSUnitValue.h b/Libraries/LibWeb/CSS/CSSUnitValue.h index 1ceb0cae71..5c64763117 100644 --- a/Libraries/LibWeb/CSS/CSSUnitValue.h +++ b/Libraries/LibWeb/CSS/CSSUnitValue.h @@ -28,7 +28,7 @@ public: FlyString const& unit() const { return m_unit; } - void serialize_unit_value(StringBuilder&, Optional minimum, Optional maximum) const; + void serialize_unit_value(Utf16StringBuilder&, Optional minimum, Optional maximum) const; GC::Ptr converted_to_unit(FlyString const& unit) const; diff --git a/Libraries/LibWeb/CSS/CSSUnparsedValue.cpp b/Libraries/LibWeb/CSS/CSSUnparsedValue.cpp index 628e87e8c2..23b0702041 100644 --- a/Libraries/LibWeb/CSS/CSSUnparsedValue.cpp +++ b/Libraries/LibWeb/CSS/CSSUnparsedValue.cpp @@ -5,6 +5,7 @@ */ #include "CSSUnparsedValue.h" +#include #include #include #include @@ -131,17 +132,17 @@ bool CSSUnparsedValue::contains_unparsed_value(CSSUnparsedValue const& needle) c } // https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssunparsedvalue -WebIDL::ExceptionOr CSSUnparsedValue::to_string() const +WebIDL::ExceptionOr CSSUnparsedValue::to_string() const { // AD-HOC: It's possible for one of the m_tokens to contain this in its fallback slot, or a similar situation with // more levels of nesting. To avoid crashing, do a scan for that first and return the empty string. // Spec issue: https://github.com/w3c/css-houdini-drafts/issues/1158 if (contains_unparsed_value(*this)) - return ""_string; + return Utf16String::from_utf8_without_validation(""sv); // To serialize a CSSUnparsedValue this: // 1. Let s initially be the empty string. - StringBuilder s; + Utf16StringBuilder s; // 2. For each item in this’s [[tokens]] internal slot: for (auto const& item : m_tokens) { @@ -150,7 +151,7 @@ WebIDL::ExceptionOr CSSUnparsedValue::to_string() const TRY(item.visit( // 1. If item is a USVString, append it to s. [&](String const& string) -> WebIDL::ExceptionOr { - s.append(string); + s.append(Utf16String::from_utf8_without_validation(string)); return {}; }, // 2. Otherwise, item is a CSSVariableReferenceValue. Serialize it, then append the result to s. @@ -161,7 +162,7 @@ WebIDL::ExceptionOr CSSUnparsedValue::to_string() const } // 3. Return s. - return s.to_string_without_validation(); + return s.to_string(); } // https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation @@ -181,7 +182,8 @@ WebIDL::ExceptionOr> CSSUnparsedValue::create_an // NB: CSSUnparsedValue stores a list of strings, each of which may contain any number of tokens. So the simplest // way to convert it to ComponentValues is to serialize and then parse it. - auto string = TRY(to_string()); + auto utf16_string = TRY(to_string()); + auto string = MUST(utf16_string.utf16_view().to_utf8()); auto parser = Parser::Parser::create(Parser::ParsingParams {}, string); auto component_values = parser.parse_as_list_of_component_values(); diff --git a/Libraries/LibWeb/CSS/CSSUnparsedValue.h b/Libraries/LibWeb/CSS/CSSUnparsedValue.h index 7127575190..e72560d7d7 100644 --- a/Libraries/LibWeb/CSS/CSSUnparsedValue.h +++ b/Libraries/LibWeb/CSS/CSSUnparsedValue.h @@ -29,7 +29,7 @@ public: virtual WebIDL::ExceptionOr set_value_of_existing_indexed_property(u32, JS::Value) override; virtual WebIDL::ExceptionOr set_value_of_new_indexed_property(u32, JS::Value) override; - virtual WebIDL::ExceptionOr to_string() const override; + virtual WebIDL::ExceptionOr to_string() const override; virtual WebIDL::ExceptionOr> create_an_internal_representation(PropertyNameAndID const&, PerformTypeCheck) const override; private: diff --git a/Libraries/LibWeb/CSS/CSSVariableReferenceValue.cpp b/Libraries/LibWeb/CSS/CSSVariableReferenceValue.cpp index ac8ec9efba..dea540fb7c 100644 --- a/Libraries/LibWeb/CSS/CSSVariableReferenceValue.cpp +++ b/Libraries/LibWeb/CSS/CSSVariableReferenceValue.cpp @@ -5,6 +5,7 @@ */ #include "CSSVariableReferenceValue.h" +#include #include #include #include @@ -89,26 +90,26 @@ WebIDL::ExceptionOr CSSVariableReferenceValue::set_fallback(GC::Ptr CSSVariableReferenceValue::to_string() const +WebIDL::ExceptionOr CSSVariableReferenceValue::to_string() const { // To serialize a CSSVariableReferenceValue this: // 1. Let s initially be "var(". - StringBuilder s; - s.append("var("sv); + Utf16StringBuilder s; + s.append_ascii("var("sv); // 2. Append this’s variable internal slot to s. - s.append(m_variable); + s.append(Utf16String::from_utf8_without_validation(m_variable)); // 3. If this’s fallback internal slot is not null, append ", " to s, then serialize the fallback internal slot and append it to s. if (m_fallback) { // AD-HOC: Tested behaviour requires we append "," without the space. https://github.com/w3c/css-houdini-drafts/issues/1148 - s.append(","sv); + s.append_ascii(','); s.append(TRY(m_fallback->to_string())); } // 4. Append ")" to s and return s. - s.append(")"sv); - return s.to_string_without_validation(); + s.append_ascii(')'); + return s.to_string(); } } diff --git a/Libraries/LibWeb/CSS/CSSVariableReferenceValue.h b/Libraries/LibWeb/CSS/CSSVariableReferenceValue.h index 30f52c4b57..25bf326fef 100644 --- a/Libraries/LibWeb/CSS/CSSVariableReferenceValue.h +++ b/Libraries/LibWeb/CSS/CSSVariableReferenceValue.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include namespace Web::CSS { @@ -27,7 +28,7 @@ public: GC::Ptr fallback() const; WebIDL::ExceptionOr set_fallback(GC::Ptr); - WebIDL::ExceptionOr to_string() const; + WebIDL::ExceptionOr to_string() const; private: CSSVariableReferenceValue(JS::Realm&, FlyString variable, GC::Ptr fallback); diff --git a/Libraries/LibWeb/CSS/Serialize.cpp b/Libraries/LibWeb/CSS/Serialize.cpp index 0651313de3..eff0c79dd0 100644 --- a/Libraries/LibWeb/CSS/Serialize.cpp +++ b/Libraries/LibWeb/CSS/Serialize.cpp @@ -149,6 +149,24 @@ void serialize_a_number(StringBuilder& builder, double value) builder.appendff("{:.6}", value); } +void serialize_a_number(Utf16StringBuilder& builder, double value) +{ + // -> + // A base-ten number using digits 0-9 (U+0030 to U+0039) in the shortest form possible, using "." to separate + // decimals (if any), rounding the value if necessary to not produce more than 6 decimals, preceded by "-" + // (U+002D) if it is negative. + // NOTE: scientific notation is not used. + + // AD-HOC: If the number is small enough that it would not print any digits when rounded, serialize it as 0. + if (AK::abs(value) < 0.0000005) { + builder.append_ascii('0'); + return; + } + + // FIXME: Prevent scientific notation for large values. + builder.appendff("{:.6}", value); +} + String serialize_an_identifier(StringView ident) { StringBuilder builder; diff --git a/Libraries/LibWeb/CSS/Serialize.h b/Libraries/LibWeb/CSS/Serialize.h index 099119b883..5917dcc86f 100644 --- a/Libraries/LibWeb/CSS/Serialize.h +++ b/Libraries/LibWeb/CSS/Serialize.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ void serialize_a_string(StringBuilder&, StringView string); WEB_API void serialize_a_url(StringBuilder&, StringView url); void serialize_unicode_ranges(StringBuilder&, Vector const& unicode_ranges); WEB_API void serialize_a_number(StringBuilder&, double value); +WEB_API void serialize_a_number(Utf16StringBuilder&, double value); String serialize_an_identifier(StringView ident); String serialize_a_string(StringView string);