diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2021-10-14 16:50:43 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-10-16 15:16:27 +0100 |
commit | 75c9313d7db2cd9b231bf7fedbd4219b0c67b431 (patch) | |
tree | 3e1971c113753c7fdf141187cedf4effc2b63509 /Userland/Libraries/LibWeb/CSS | |
parent | 5c1427f3e04d83e41e2007ec8d0dd953455db5bc (diff) | |
download | serenity-75c9313d7db2cd9b231bf7fedbd4219b0c67b431.zip |
LibWeb: Implement more CSS serializers and make them more ergonomic
This implements these algorithms from the CSSOM-1 spec:
- serialize a string
- serialize a URL
Also, we now have two versions of each of the serialization functions:
One that returns a String as before, and the other that takes a
StringBuilder to write into. This saves creating extra StringBuilders
when they are not needed. :^)
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Serialize.cpp | 97 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Serialize.h | 10 |
2 files changed, 94 insertions, 13 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Serialize.cpp b/Userland/Libraries/LibWeb/CSS/Serialize.cpp index 3989f64787..7e1d6f3a19 100644 --- a/Userland/Libraries/LibWeb/CSS/Serialize.cpp +++ b/Userland/Libraries/LibWeb/CSS/Serialize.cpp @@ -11,24 +11,21 @@ namespace Web::CSS { // https://www.w3.org/TR/cssom-1/#escape-a-character -String escape_a_character(u32 character) +void escape_a_character(StringBuilder builder, u32 character) { - StringBuilder builder; builder.append('\\'); builder.append_code_point(character); - return builder.to_string(); } // https://www.w3.org/TR/cssom-1/#escape-a-character-as-code-point -String escape_a_character_as_code_point(u32 character) +void escape_a_character_as_code_point(StringBuilder builder, u32 character) { - return String::formatted("\\{:x} ", character); + builder.appendff("\\{:x} ", character); } // https://www.w3.org/TR/cssom-1/#serialize-an-identifier -String serialize_an_identifier(StringView const& ident) +void serialize_an_identifier(StringBuilder builder, StringView const& ident) { - StringBuilder builder; Utf8View characters { ident }; auto first_character = characters.is_empty() ? 0 : *characters.begin(); @@ -43,25 +40,25 @@ String serialize_an_identifier(StringView const& ident) // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, // then the character escaped as code point. if ((character >= 0x0001 && character <= 0x001F) || (character == 0x007F)) { - builder.append(escape_a_character_as_code_point(character)); + escape_a_character_as_code_point(builder, character); continue; } // If the character is the first character and is in the range [0-9] (U+0030 to U+0039), // then the character escaped as code point. if (builder.is_empty() && character >= '0' && character <= '9') { - builder.append(escape_a_character_as_code_point(character)); + escape_a_character_as_code_point(builder, character); continue; } // If the character is the second character and is in the range [0-9] (U+0030 to U+0039) // and the first character is a "-" (U+002D), then the character escaped as code point. if (builder.length() == 1 && first_character == '-' && character >= '0' && character <= '9') { - builder.append(escape_a_character_as_code_point(character)); + escape_a_character_as_code_point(builder, character); continue; } // If the character is the first character and is a "-" (U+002D), and there is no second // character, then the escaped character. if (builder.is_empty() && character == '-' && characters.length() == 1) { - builder.append(escape_a_character(character)); + escape_a_character(builder, character); continue; } // If the character is not handled by one of the above rules and is greater than or equal to U+0080, is "-" (U+002D) or "_" (U+005F), or is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to U+005A), or \[a-z] (U+0061 to U+007A), then the character itself. @@ -74,8 +71,84 @@ String serialize_an_identifier(StringView const& ident) continue; } // Otherwise, the escaped character. - builder.append(escape_a_character(character)); + escape_a_character(builder, character); } +} + +// https://www.w3.org/TR/cssom-1/#serialize-a-string +void serialize_a_string(StringBuilder builder, StringView const& string) +{ + Utf8View characters { string }; + + // To serialize a string means to create a string represented by '"' (U+0022), followed by the result + // of applying the rules below to each character of the given string, followed by '"' (U+0022): + builder.append('"'); + + for (auto character : characters) { + // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD). + if (character == 0) { + builder.append_code_point(0xFFFD); + continue; + } + // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is U+007F, the character escaped as code point. + if ((character >= 0x0001 && character <= 0x001F) || (character == 0x007F)) { + escape_a_character_as_code_point(builder, character); + continue; + } + // If the character is '"' (U+0022) or "\" (U+005C), the escaped character. + if (character == 0x0022 || character == 0x005C) { + escape_a_character(builder, character); + continue; + } + // Otherwise, the character itself. + builder.append_code_point(character); + } + + builder.append('"'); +} + +// https://www.w3.org/TR/cssom-1/#serialize-a-url +void serialize_a_url(StringBuilder builder, StringView const& url) +{ + // To serialize a URL means to create a string represented by "url(", + // followed by the serialization of the URL as a string, followed by ")". + builder.append("url("); + serialize_a_string(builder, url.to_string()); + builder.append(')'); +} + +String escape_a_character(u32 character) +{ + StringBuilder builder; + escape_a_character(builder, character); + return builder.to_string(); +} + +String escape_a_character_as_code_point(u32 character) +{ + StringBuilder builder; + escape_a_character_as_code_point(builder, character); + return builder.to_string(); +} + +String serialize_an_identifier(StringView const& ident) +{ + StringBuilder builder; + serialize_an_identifier(builder, ident); + return builder.to_string(); +} + +String serialize_a_string(StringView const& string) +{ + StringBuilder builder; + serialize_a_string(builder, string); + return builder.to_string(); +} + +String serialize_a_url(StringView const& url) +{ + StringBuilder builder; + serialize_a_url(builder, url); return builder.to_string(); } diff --git a/Userland/Libraries/LibWeb/CSS/Serialize.h b/Userland/Libraries/LibWeb/CSS/Serialize.h index 08264ebc81..8b0f240008 100644 --- a/Userland/Libraries/LibWeb/CSS/Serialize.h +++ b/Userland/Libraries/LibWeb/CSS/Serialize.h @@ -7,13 +7,21 @@ #pragma once #include <AK/String.h> +#include <AK/StringBuilder.h> #include <AK/StringView.h> namespace Web::CSS { +void escape_a_character(StringBuilder, u32 character); +void escape_a_character_as_code_point(StringBuilder, u32 character); +void serialize_an_identifier(StringBuilder, StringView const& ident); +void serialize_a_string(StringBuilder, StringView const& string); +void serialize_a_url(StringBuilder, StringView const& url); + String escape_a_character(u32 character); String escape_a_character_as_code_point(u32 character); - String serialize_an_identifier(StringView const& ident); +String serialize_a_string(StringView const& string); +String serialize_a_url(StringView const& url); } |