Pārlūkot izejas kodu

LibWeb/CSS: Add parsing for `<opentype-tag>`

This is a special form of `<string>` so doesn't need its own style value
type. It's used in a couple of font-related properties. For completeness
it's included in ValueType.
Sam Atkins 9 mēneši atpakaļ
vecāks
revīzija
cd13b30fb8

+ 4 - 0
Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp

@@ -35,6 +35,7 @@ static bool type_name_is_enum(StringView type_name)
         "integer"sv,
         "integer"sv,
         "length"sv,
         "length"sv,
         "number"sv,
         "number"sv,
+        "opentype-tag"sv,
         "paint"sv,
         "paint"sv,
         "percentage"sv,
         "percentage"sv,
         "position"sv,
         "position"sv,
@@ -235,6 +236,7 @@ enum class ValueType {
     Integer,
     Integer,
     Length,
     Length,
     Number,
     Number,
+    OpenTypeTag,
     Paint,
     Paint,
     Percentage,
     Percentage,
     Position,
     Position,
@@ -805,6 +807,8 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type)
                     property_generator.appendln("        case ValueType::Length:");
                     property_generator.appendln("        case ValueType::Length:");
                 } else if (type_name == "number") {
                 } else if (type_name == "number") {
                     property_generator.appendln("        case ValueType::Number:");
                     property_generator.appendln("        case ValueType::Number:");
+                } else if (type_name == "opentype-tag") {
+                    property_generator.appendln("        case ValueType::OpenTypeTag:");
                 } else if (type_name == "paint") {
                 } else if (type_name == "paint") {
                     property_generator.appendln("        case ValueType::Paint:");
                     property_generator.appendln("        case ValueType::Paint:");
                 } else if (type_name == "percentage") {
                 } else if (type_name == "percentage") {

+ 2 - 1
Userland/Libraries/LibWeb/CSS/CSSNumericType.cpp

@@ -42,8 +42,9 @@ Optional<CSSNumericType::BaseType> CSSNumericType::base_type_from_value_type(Val
     case ValueType::FilterValueList:
     case ValueType::FilterValueList:
     case ValueType::Image:
     case ValueType::Image:
     case ValueType::Integer:
     case ValueType::Integer:
-    case ValueType::Paint:
     case ValueType::Number:
     case ValueType::Number:
+    case ValueType::OpenTypeTag:
+    case ValueType::Paint:
     case ValueType::Position:
     case ValueType::Position:
     case ValueType::Ratio:
     case ValueType::Ratio:
     case ValueType::Rect:
     case ValueType::Rect:

+ 30 - 0
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -7899,6 +7899,11 @@ Optional<Parser::PropertyAndValue> Parser::parse_css_value_for_properties(Readon
         }
         }
     }
     }
 
 
+    if (auto property = any_property_accepts_type(property_ids, ValueType::OpenTypeTag); property.has_value()) {
+        if (auto maybe_rect = parse_opentype_tag_value(tokens))
+            return PropertyAndValue { *property, maybe_rect };
+    }
+
     if (peek_token.is(Token::Type::Percentage)) {
     if (peek_token.is(Token::Type::Percentage)) {
         auto percentage = Percentage(peek_token.token().percentage());
         auto percentage = Percentage(peek_token.token().percentage());
         if (auto property = any_property_accepts_type(property_ids, ValueType::Percentage); property.has_value() && property_accepts_percentage(*property, percentage)) {
         if (auto property = any_property_accepts_type(property_ids, ValueType::Percentage); property.has_value() && property_accepts_percentage(*property, percentage)) {
@@ -8864,4 +8869,29 @@ bool Parser::substitute_attr_function(DOM::Element& element, FlyString const& pr
     return false;
     return false;
 }
 }
 
 
+// https://drafts.csswg.org/css-fonts/#typedef-opentype-tag
+RefPtr<StringStyleValue> Parser::parse_opentype_tag_value(TokenStream<ComponentValue>& tokens)
+{
+    // <opentype-tag> = <string>
+    // The <opentype-tag> is a case-sensitive OpenType feature tag.
+    // As specified in the OpenType specification [OPENTYPE], feature tags contain four ASCII characters.
+    // Tag strings longer or shorter than four characters, or containing characters outside the U+20–7E codepoint range are invalid.
+
+    auto transaction = tokens.begin_transaction();
+    auto string_value = parse_string_value(tokens);
+    if (string_value == nullptr)
+        return nullptr;
+
+    auto string = string_value->string_value().bytes_as_string_view();
+    if (string.length() != 4)
+        return nullptr;
+    for (char c : string) {
+        if (c < 0x20 || c > 0x7E)
+            return nullptr;
+    }
+
+    transaction.commit();
+    return string_value;
+}
+
 }
 }

+ 1 - 0
Userland/Libraries/LibWeb/CSS/Parser/Parser.h

@@ -265,6 +265,7 @@ private:
     };
     };
     RefPtr<PositionStyleValue> parse_position_value(TokenStream<ComponentValue>&, PositionParsingMode = PositionParsingMode::Normal);
     RefPtr<PositionStyleValue> parse_position_value(TokenStream<ComponentValue>&, PositionParsingMode = PositionParsingMode::Normal);
     RefPtr<CSSStyleValue> parse_filter_value_list_value(TokenStream<ComponentValue>&);
     RefPtr<CSSStyleValue> parse_filter_value_list_value(TokenStream<ComponentValue>&);
+    RefPtr<StringStyleValue> parse_opentype_tag_value(TokenStream<ComponentValue>&);
 
 
     RefPtr<CSSStyleValue> parse_dimension_value(TokenStream<ComponentValue>&);
     RefPtr<CSSStyleValue> parse_dimension_value(TokenStream<ComponentValue>&);
     RefPtr<CSSStyleValue> parse_angle_value(TokenStream<ComponentValue>&);
     RefPtr<CSSStyleValue> parse_angle_value(TokenStream<ComponentValue>&);