LibWeb: Parse @function rules
This commit is contained in:
parent
01394322ac
commit
c7b402eff5
9 changed files with 338 additions and 93 deletions
|
|
@ -259,6 +259,17 @@
|
|||
},
|
||||
"function": {
|
||||
"spec": "https://drafts.csswg.org/css-mixins-1/#function-rule",
|
||||
"descriptors": {}
|
||||
"descriptors": {
|
||||
"result": {
|
||||
"syntax": [
|
||||
"<declaration-value>?"
|
||||
]
|
||||
}
|
||||
},
|
||||
"custom-descriptors": {
|
||||
"syntax": [
|
||||
"<declaration-value>?"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include <LibGfx/ImmutableBitmap.h>
|
||||
#include <LibURL/Parser.h>
|
||||
#include <LibWeb/CSS/CSSFontFeatureValuesRule.h>
|
||||
#include <LibWeb/CSS/CSSFunctionDescriptors.h>
|
||||
#include <LibWeb/CSS/CSSFunctionDeclarations.h>
|
||||
#include <LibWeb/CSS/CSSMarginRule.h>
|
||||
#include <LibWeb/CSS/CSSStyleDeclaration.h>
|
||||
#include <LibWeb/CSS/CSSStyleProperties.h>
|
||||
|
|
@ -1474,7 +1474,7 @@ Vector<Descriptor> Parser::parse_as_descriptor_declaration_block(AtRuleID at_rul
|
|||
case AtRuleID::FontFace:
|
||||
return RuleContext::AtFontFace;
|
||||
case AtRuleID::Function:
|
||||
TODO();
|
||||
return RuleContext::AtFunction;
|
||||
case AtRuleID::Page:
|
||||
return RuleContext::AtPage;
|
||||
case AtRuleID::Property:
|
||||
|
|
@ -1536,13 +1536,17 @@ bool Parser::is_valid_in_the_current_context(Declaration const&) const
|
|||
case RuleContext::AtLayer:
|
||||
case RuleContext::AtMedia:
|
||||
case RuleContext::AtSupports:
|
||||
// Grouping rules can contain declarations if they are themselves inside a style rule
|
||||
return m_rule_context.contains_slow(RuleContext::Style);
|
||||
// Grouping rules can contain declarations if they are themselves inside a style or function rule
|
||||
return m_rule_context.contains([](auto const& context) { return context == RuleContext::Style || context == RuleContext::AtFunction; });
|
||||
|
||||
case RuleContext::FontFeatureValue:
|
||||
// Each feature value block accepts a list of declarations
|
||||
return true;
|
||||
|
||||
case RuleContext::AtFunction:
|
||||
// @function rules contain descriptor declarations
|
||||
return true;
|
||||
|
||||
case RuleContext::AtCounterStyle:
|
||||
case RuleContext::AtFontFace:
|
||||
case RuleContext::AtFontFeatureValues:
|
||||
|
|
@ -1574,6 +1578,12 @@ bool Parser::is_valid_in_the_current_context(AtRule const& at_rule) const
|
|||
if (m_rule_context.contains_slow(RuleContext::Style))
|
||||
return first_is_one_of(at_rule.name, "layer", "media", "supports");
|
||||
|
||||
if (m_rule_context.contains_slow(RuleContext::AtFunction)) {
|
||||
// https://drafts.csswg.org/css-mixins-1/#function-body
|
||||
// The body of a @function rule accepts conditional group rules
|
||||
return first_is_one_of(at_rule.name, "media", "supports");
|
||||
}
|
||||
|
||||
switch (m_rule_context.last()) {
|
||||
case RuleContext::Unknown:
|
||||
// If the context is an unknown type, we don't accept anything.
|
||||
|
|
@ -1608,6 +1618,9 @@ bool Parser::is_valid_in_the_current_context(AtRule const& at_rule) const
|
|||
return false;
|
||||
case RuleContext::AtFontFeatureValues:
|
||||
return CSSFontFeatureValuesRule::is_font_feature_value_type_at_keyword(at_rule.name);
|
||||
case RuleContext::AtFunction:
|
||||
// Already handled above
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
|
|
@ -1648,6 +1661,7 @@ bool Parser::is_valid_in_the_current_context(QualifiedRule const&) const
|
|||
case RuleContext::AtFontFace:
|
||||
case RuleContext::AtFontFeatureValues:
|
||||
case RuleContext::FontFeatureValue:
|
||||
case RuleContext::AtFunction:
|
||||
case RuleContext::AtPage:
|
||||
case RuleContext::AtProperty:
|
||||
case RuleContext::Keyframe:
|
||||
|
|
|
|||
|
|
@ -292,6 +292,13 @@ private:
|
|||
Optional<FlyString> parse_layer_name(TokenStream<ComponentValue>&, AllowBlankLayerName);
|
||||
Optional<Vector<FlyString>> parse_comma_separated_family_name_list(TokenStream<ComponentValue>&);
|
||||
|
||||
struct FunctionPrelude {
|
||||
FlyString name;
|
||||
Vector<FunctionParameterInternal> parameters;
|
||||
NonnullOwnPtr<SyntaxNode> return_type;
|
||||
};
|
||||
Optional<FunctionPrelude> parse_function_prelude(TokenStream<ComponentValue>&);
|
||||
|
||||
bool is_valid_in_the_current_context(Declaration const&) const;
|
||||
bool is_valid_in_the_current_context(AtRule const&) const;
|
||||
bool is_valid_in_the_current_context(QualifiedRule const&) const;
|
||||
|
|
@ -302,6 +309,7 @@ private:
|
|||
GC::Ptr<CSSCounterStyleRule> convert_to_counter_style_rule(AtRule const&);
|
||||
GC::Ptr<CSSFontFaceRule> convert_to_font_face_rule(AtRule const&);
|
||||
GC::Ptr<CSSFontFeatureValuesRule> convert_to_font_feature_values_rule(AtRule const&);
|
||||
GC::Ptr<CSSFunctionRule> convert_to_function_rule(AtRule const&);
|
||||
GC::Ptr<CSSKeyframesRule> convert_to_keyframes_rule(AtRule const&);
|
||||
GC::Ptr<CSSImportRule> convert_to_import_rule(AtRule const&);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@ RuleContext rule_context_type_for_rule(CSSRule::Type rule_type)
|
|||
case CSSRule::Type::FontFeatureValues:
|
||||
return RuleContext::AtFontFeatureValues;
|
||||
case CSSRule::Type::Function:
|
||||
TODO();
|
||||
case CSSRule::Type::FunctionDeclarations:
|
||||
TODO();
|
||||
return RuleContext::AtFunction;
|
||||
case CSSRule::Type::Keyframes:
|
||||
return RuleContext::AtKeyframes;
|
||||
case CSSRule::Type::Keyframe:
|
||||
|
|
@ -47,6 +45,7 @@ RuleContext rule_context_type_for_rule(CSSRule::Type rule_type)
|
|||
case CSSRule::Type::Import:
|
||||
case CSSRule::Type::LayerStatement:
|
||||
case CSSRule::Type::Namespace:
|
||||
case CSSRule::Type::FunctionDeclarations:
|
||||
break;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
|
|
@ -64,6 +63,8 @@ RuleContext rule_context_type_for_at_rule(FlyString const& name)
|
|||
return RuleContext::AtKeyframes;
|
||||
if (name.equals_ignoring_ascii_case("font-feature-values"sv))
|
||||
return RuleContext::AtFontFeatureValues;
|
||||
if (name.equals_ignoring_ascii_case("function"sv))
|
||||
return RuleContext::AtFunction;
|
||||
if (CSSFontFeatureValuesRule::is_font_feature_value_type_at_keyword(name))
|
||||
return RuleContext::FontFeatureValue;
|
||||
if (name.equals_ignoring_ascii_case("supports"sv))
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ enum class RuleContext : u8 {
|
|||
AtFontFace,
|
||||
AtFontFeatureValues,
|
||||
FontFeatureValue,
|
||||
AtFunction,
|
||||
AtKeyframes,
|
||||
Keyframe,
|
||||
AtSupports,
|
||||
|
|
|
|||
|
|
@ -12,10 +12,12 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibGC/HeapVector.h>
|
||||
#include <LibWeb/CSS/CSSCounterStyleRule.h>
|
||||
#include <LibWeb/CSS/CSSFontFaceRule.h>
|
||||
#include <LibWeb/CSS/CSSFontFeatureValuesRule.h>
|
||||
#include <LibWeb/CSS/CSSFunctionDeclarations.h>
|
||||
#include <LibWeb/CSS/CSSFunctionRule.h>
|
||||
#include <LibWeb/CSS/CSSImportRule.h>
|
||||
#include <LibWeb/CSS/CSSKeyframeRule.h>
|
||||
#include <LibWeb/CSS/CSSKeyframesRule.h>
|
||||
|
|
@ -44,6 +46,7 @@
|
|||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||
#include <LibWeb/CSS/StyleValues/UnresolvedStyleValue.h>
|
||||
|
||||
namespace Web::CSS::Parser {
|
||||
|
||||
|
|
@ -112,6 +115,9 @@ GC::Ptr<CSSRule> Parser::convert_to_rule(Rule const& rule, Nested nested)
|
|||
if (at_rule.name.equals_ignoring_ascii_case("font-feature-values"sv))
|
||||
return convert_to_font_feature_values_rule(at_rule);
|
||||
|
||||
if (at_rule.name.equals_ignoring_ascii_case("function"sv))
|
||||
return convert_to_function_rule(at_rule);
|
||||
|
||||
if (at_rule.name.equals_ignoring_ascii_case("import"sv))
|
||||
return convert_to_import_rule(at_rule);
|
||||
|
||||
|
|
@ -1123,6 +1129,210 @@ GC::Ptr<CSSFontFeatureValuesRule> Parser::convert_to_font_feature_values_rule(At
|
|||
return font_feature_values_rule;
|
||||
}
|
||||
|
||||
static OwnPtr<SyntaxNode> parse_css_type(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// https://drafts.csswg.org/css-mixins-1/#function-rule
|
||||
// <css-type> = <syntax-component> | <type()>
|
||||
// <type()> = type( <syntax> )
|
||||
|
||||
auto transaction = tokens.begin_transaction();
|
||||
tokens.discard_whitespace();
|
||||
|
||||
// <syntax-component>
|
||||
if (auto maybe_syntax_component = parse_syntax_component(tokens)) {
|
||||
transaction.commit();
|
||||
return maybe_syntax_component;
|
||||
}
|
||||
|
||||
// <type()>
|
||||
auto maybe_type_function_token = tokens.consume_a_token();
|
||||
|
||||
if (!maybe_type_function_token.is_function("type"sv))
|
||||
return nullptr;
|
||||
|
||||
if (auto maybe_type_function_syntax = parse_as_syntax(maybe_type_function_token.function().value)) {
|
||||
transaction.commit();
|
||||
return maybe_type_function_syntax;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Optional<Parser::FunctionPrelude> Parser::parse_function_prelude(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// https://drafts.csswg.org/css-mixins-1/#function-rule
|
||||
// <function-token> <function-parameter>#? ) [ returns <css-type> ]?
|
||||
// <function-parameter> = <custom-property-name> <css-type>? [ : <default-value> ]?
|
||||
// <default-value> = <declaration-value>
|
||||
auto transaction = tokens.begin_transaction();
|
||||
|
||||
tokens.discard_whitespace();
|
||||
|
||||
auto const& function_token = tokens.consume_a_token();
|
||||
|
||||
if (!function_token.is_function()) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = tokens.dump_string(),
|
||||
.description = "Prelude must start with a function token."_string,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
auto function_name = function_token.function().name;
|
||||
|
||||
// The <function-token> production must start with two dashes (U+002D HYPHEN-MINUS), similar to <dashed-ident>, or
|
||||
// else the definition is invalid.
|
||||
if (!function_name.starts_with_bytes("--"sv)) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = tokens.dump_string(),
|
||||
.description = "Function name must start with two dashes."_string,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
Vector<FunctionParameterInternal> parsed_parameters;
|
||||
|
||||
TokenStream parameters_tokens { function_token.function().value };
|
||||
parameters_tokens.discard_whitespace();
|
||||
auto parameters_component_values = parse_a_comma_separated_list_of_component_values(parameters_tokens);
|
||||
|
||||
// <function-parameter>#?
|
||||
for (auto const& parameter_component_values : parameters_component_values) {
|
||||
TokenStream parameter_tokens { parameter_component_values };
|
||||
parameter_tokens.discard_whitespace();
|
||||
|
||||
// <custom-property-name>
|
||||
auto maybe_name = parse_dashed_ident(parameter_tokens);
|
||||
if (!maybe_name.has_value() || !is_a_custom_property_name_string(maybe_name.value())) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = parameter_tokens.dump_string(),
|
||||
.description = "Parameter must have a name."_string,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
// <css-type>?
|
||||
NonnullOwnPtr<SyntaxNode> type = UniversalSyntaxNode::create();
|
||||
if (auto maybe_type = parse_css_type(parameter_tokens))
|
||||
type = maybe_type.release_nonnull();
|
||||
|
||||
parameter_tokens.discard_whitespace();
|
||||
|
||||
// [ : <default-value> ]?
|
||||
Optional<Vector<ComponentValue>> default_value;
|
||||
if (parameter_tokens.peek_token().is(Token::Type::Colon)) {
|
||||
parameter_tokens.discard_a_token(); // :
|
||||
parameter_tokens.discard_whitespace();
|
||||
|
||||
auto maybe_default_value = parse_declaration_value(parameter_tokens);
|
||||
|
||||
if (!maybe_default_value.has_value()) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = parameter_tokens.dump_string(),
|
||||
.description = "Expected default value after ':' in parameter"_string,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
// If a default value and a parameter type are both provided, then the default value must parse successfully
|
||||
// according to that parameter type’s syntax. Otherwise, the @function rule is invalid.
|
||||
TokenStream default_value_token_stream { maybe_default_value.value() };
|
||||
if (!parse_according_to_syntax_node(default_value_token_stream, *type) || !default_value_token_stream.is_empty())
|
||||
return {};
|
||||
|
||||
default_value = maybe_default_value;
|
||||
}
|
||||
|
||||
parameter_tokens.discard_whitespace();
|
||||
|
||||
if (!parameter_tokens.is_empty()) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = parameter_tokens.dump_string(),
|
||||
.description = "Trailing tokens after parameter"_string,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
parsed_parameters.append({ maybe_name.release_value(), move(type), move(default_value) });
|
||||
}
|
||||
|
||||
tokens.discard_whitespace();
|
||||
|
||||
NonnullOwnPtr<SyntaxNode> return_type = UniversalSyntaxNode::create();
|
||||
if (tokens.peek_token().is_ident("returns"sv)) {
|
||||
tokens.discard_a_token();
|
||||
tokens.discard_whitespace();
|
||||
|
||||
auto maybe_return_type = parse_css_type(tokens);
|
||||
|
||||
if (!maybe_return_type) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = tokens.dump_string(),
|
||||
.description = "Expected return type after 'returns' in prelude."_string,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
return_type = maybe_return_type.release_nonnull();
|
||||
}
|
||||
|
||||
tokens.discard_whitespace();
|
||||
|
||||
if (tokens.has_next_token()) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = tokens.dump_string(),
|
||||
.description = "Trailing tokens in prelude."_string,
|
||||
});
|
||||
return {};
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
return FunctionPrelude { move(function_name), move(parsed_parameters), move(return_type) };
|
||||
}
|
||||
|
||||
GC::Ptr<CSSFunctionRule> Parser::convert_to_function_rule(AtRule const& function_rule)
|
||||
{
|
||||
// https://drafts.csswg.org/css-mixins-1/#function-rule
|
||||
TokenStream prelude_stream { function_rule.prelude };
|
||||
|
||||
if (!function_rule.is_block_rule) {
|
||||
ErrorReporter::the().report(CSS::Parser::InvalidRuleError {
|
||||
.rule_name = "@function"_fly_string,
|
||||
.prelude = prelude_stream.dump_string(),
|
||||
.description = "Must be a block, not a statement."_string,
|
||||
});
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto prelude = parse_function_prelude(prelude_stream);
|
||||
|
||||
if (!prelude.has_value())
|
||||
return nullptr;
|
||||
|
||||
Vector<GC::Ref<CSSRule>> child_rules {};
|
||||
|
||||
// https://drafts.csswg.org/css-mixins-1/#function-body
|
||||
for (auto const& child : function_rule.child_rules_and_lists_of_declarations) {
|
||||
child.visit(
|
||||
[&](Rule const& rule) {
|
||||
if (auto child_rule = convert_to_rule<CSSFunctionDeclarations>(rule, Nested::Yes))
|
||||
child_rules.append(*child_rule);
|
||||
},
|
||||
[&](Vector<Declaration> const& declarations) {
|
||||
child_rules.append(CSSFunctionDeclarations::create(realm(), *this, declarations));
|
||||
});
|
||||
}
|
||||
|
||||
return CSSFunctionRule::create(realm(), CSSRuleList::create(realm(), child_rules), move(prelude->name), move(prelude->parameters), move(prelude->return_type));
|
||||
}
|
||||
|
||||
GC::Ptr<CSSPageRule> Parser::convert_to_page_rule(AtRule const& page_rule)
|
||||
{
|
||||
// https://drafts.csswg.org/css-page-3/#syntax-page-selector
|
||||
|
|
|
|||
|
|
@ -483,6 +483,7 @@ struct BackgroundLayerData;
|
|||
struct CalculationContext;
|
||||
struct CalculationResolutionContext;
|
||||
struct CSSStyleSheetInit;
|
||||
struct FunctionParameterInternal;
|
||||
struct GridRepeatParams;
|
||||
struct LogicalAliasMappingContext;
|
||||
struct RandomCachingKey;
|
||||
|
|
|
|||
|
|
@ -2,38 +2,38 @@ Harness status: OK
|
|||
|
||||
Found 34 tests
|
||||
|
||||
34 Fail
|
||||
Fail Empty CSSFunctionRule
|
||||
Fail Single CSSFunctionDeclarations
|
||||
Fail CSSFunctionDescriptors (result)
|
||||
Fail CSSFunctionDescriptors (result, repeated)
|
||||
Fail CSSFunctionDescriptors (local variables)
|
||||
Fail CSSFunctionDescriptors (local variables, repeated)
|
||||
Fail CSSFunctionDescriptors (local variables and result)
|
||||
Fail CSSFunctionDescriptors serialization
|
||||
Fail Unknown descriptors
|
||||
Fail Unknown descriptors (mutation)
|
||||
Fail item()
|
||||
Fail Indexed property getter
|
||||
Fail @supports in body
|
||||
Fail CSSFunctionRule.name
|
||||
Fail CSSFunctionRule.getParameters()
|
||||
Fail CSSFunctionRule.returnType
|
||||
Fail CSSFunctionRule escapes
|
||||
Fail CSSFunctionRule.cssText (--empty)
|
||||
Fail CSSFunctionRule.cssText (--ret-length)
|
||||
Fail CSSFunctionRule.cssText (--ret-length-auto)
|
||||
Fail CSSFunctionRule.cssText (--param-single)
|
||||
Fail CSSFunctionRule.cssText (--param-typed)
|
||||
Fail CSSFunctionRule.cssText (--param-typed-default)
|
||||
Fail CSSFunctionRule.cssText (--param-default)
|
||||
Fail CSSFunctionRule.cssText (--param-multi)
|
||||
Fail CSSFunctionRule.cssText (--param-multi-mixed)
|
||||
Fail CSSFunctionRule.cssText (--body-result)
|
||||
Fail CSSFunctionRule.cssText (--body-locals)
|
||||
Fail CSSFunctionRule.cssText (--param-type-fn)
|
||||
Fail CSSFunctionRule.cssText (--param-type-fn-uni)
|
||||
Fail CSSFunctionRule.cssText (--ret-type-fn)
|
||||
Fail CSSFunctionRule.cssText (--ret-type-fn-uni)
|
||||
Fail CSSFunctionRule.cssText (--body-result-multi)
|
||||
Fail CSSFunctionRule.cssText (--escaped-)
|
||||
34 Pass
|
||||
Pass Empty CSSFunctionRule
|
||||
Pass Single CSSFunctionDeclarations
|
||||
Pass CSSFunctionDescriptors (result)
|
||||
Pass CSSFunctionDescriptors (result, repeated)
|
||||
Pass CSSFunctionDescriptors (local variables)
|
||||
Pass CSSFunctionDescriptors (local variables, repeated)
|
||||
Pass CSSFunctionDescriptors (local variables and result)
|
||||
Pass CSSFunctionDescriptors serialization
|
||||
Pass Unknown descriptors
|
||||
Pass Unknown descriptors (mutation)
|
||||
Pass item()
|
||||
Pass Indexed property getter
|
||||
Pass @supports in body
|
||||
Pass CSSFunctionRule.name
|
||||
Pass CSSFunctionRule.getParameters()
|
||||
Pass CSSFunctionRule.returnType
|
||||
Pass CSSFunctionRule escapes
|
||||
Pass CSSFunctionRule.cssText (--empty)
|
||||
Pass CSSFunctionRule.cssText (--ret-length)
|
||||
Pass CSSFunctionRule.cssText (--ret-length-auto)
|
||||
Pass CSSFunctionRule.cssText (--param-single)
|
||||
Pass CSSFunctionRule.cssText (--param-typed)
|
||||
Pass CSSFunctionRule.cssText (--param-typed-default)
|
||||
Pass CSSFunctionRule.cssText (--param-default)
|
||||
Pass CSSFunctionRule.cssText (--param-multi)
|
||||
Pass CSSFunctionRule.cssText (--param-multi-mixed)
|
||||
Pass CSSFunctionRule.cssText (--body-result)
|
||||
Pass CSSFunctionRule.cssText (--body-locals)
|
||||
Pass CSSFunctionRule.cssText (--param-type-fn)
|
||||
Pass CSSFunctionRule.cssText (--param-type-fn-uni)
|
||||
Pass CSSFunctionRule.cssText (--ret-type-fn)
|
||||
Pass CSSFunctionRule.cssText (--ret-type-fn-uni)
|
||||
Pass CSSFunctionRule.cssText (--body-result-multi)
|
||||
Pass CSSFunctionRule.cssText (--escaped-)
|
||||
|
|
@ -2,58 +2,57 @@ Harness status: OK
|
|||
|
||||
Found 86 tests
|
||||
|
||||
38 Pass
|
||||
48 Fail
|
||||
Fail @function --foo() is valid
|
||||
Fail @function --foo( ) is valid
|
||||
Fail @function --foo(--x) is valid
|
||||
Fail @function --foo( --x ) is valid
|
||||
86 Pass
|
||||
Pass @function --foo() is valid
|
||||
Pass @function --foo( ) is valid
|
||||
Pass @function --foo(--x) is valid
|
||||
Pass @function --foo( --x ) is valid
|
||||
Pass @function --foo () is invalid
|
||||
Pass @function --foo (--x) is invalid
|
||||
Fail @function --foo(--x auto) is valid
|
||||
Fail @function --foo(--x <angle>) is valid
|
||||
Fail @function --foo(--x <color>) is valid
|
||||
Fail @function --foo(--x <custom-ident>) is valid
|
||||
Fail @function --foo(--x <image>) is valid
|
||||
Fail @function --foo(--x <integer>) is valid
|
||||
Fail @function --foo(--x <length>) is valid
|
||||
Fail @function --foo(--x <length-percentage>) is valid
|
||||
Fail @function --foo(--x <number>) is valid
|
||||
Fail @function --foo(--x <percentage>) is valid
|
||||
Fail @function --foo(--x <resolution>) is valid
|
||||
Fail @function --foo(--x <string>) is valid
|
||||
Fail @function --foo(--x <time>) is valid
|
||||
Fail @function --foo(--x <url>) is valid
|
||||
Fail @function --foo(--x <transform-function>) is valid
|
||||
Fail @function --foo(--x <transform-list>) is valid
|
||||
Fail @function --foo(--x type(auto)) is valid
|
||||
Fail @function --foo(--x type(<length>)) is valid
|
||||
Fail @function --foo(--x type(<length> | auto)) is valid
|
||||
Fail @function --foo(--x type(none | auto)) is valid
|
||||
Fail @function --foo(--x type(*)) is valid
|
||||
Fail @function --foo(--x, --y) is valid
|
||||
Fail @function --foo(--x, --y, --z) is valid
|
||||
Fail @function --foo(--x <length>, --y, --z) is valid
|
||||
Fail @function --foo(--x, --y <number>, --z <angle>) is valid
|
||||
Fail @function --foo(--x : 10px) is valid
|
||||
Fail @function --foo(--x type(*): 10px) is valid
|
||||
Fail @function --foo(--x <length>: 10px) is valid
|
||||
Fail @function --foo(--x <length>: 10px, --y) is valid
|
||||
Fail @function --foo(--x, --y <length>: 10px) is valid
|
||||
Fail @function --foo(--x type(<length> | auto): auto) is valid
|
||||
Fail @function --foo(--x type(<length> | auto) : auto) is valid
|
||||
Fail @function --foo(--x:1px, --y, --z:2px) is valid
|
||||
Pass @function --foo(--x auto) is valid
|
||||
Pass @function --foo(--x <angle>) is valid
|
||||
Pass @function --foo(--x <color>) is valid
|
||||
Pass @function --foo(--x <custom-ident>) is valid
|
||||
Pass @function --foo(--x <image>) is valid
|
||||
Pass @function --foo(--x <integer>) is valid
|
||||
Pass @function --foo(--x <length>) is valid
|
||||
Pass @function --foo(--x <length-percentage>) is valid
|
||||
Pass @function --foo(--x <number>) is valid
|
||||
Pass @function --foo(--x <percentage>) is valid
|
||||
Pass @function --foo(--x <resolution>) is valid
|
||||
Pass @function --foo(--x <string>) is valid
|
||||
Pass @function --foo(--x <time>) is valid
|
||||
Pass @function --foo(--x <url>) is valid
|
||||
Pass @function --foo(--x <transform-function>) is valid
|
||||
Pass @function --foo(--x <transform-list>) is valid
|
||||
Pass @function --foo(--x type(auto)) is valid
|
||||
Pass @function --foo(--x type(<length>)) is valid
|
||||
Pass @function --foo(--x type(<length> | auto)) is valid
|
||||
Pass @function --foo(--x type(none | auto)) is valid
|
||||
Pass @function --foo(--x type(*)) is valid
|
||||
Pass @function --foo(--x, --y) is valid
|
||||
Pass @function --foo(--x, --y, --z) is valid
|
||||
Pass @function --foo(--x <length>, --y, --z) is valid
|
||||
Pass @function --foo(--x, --y <number>, --z <angle>) is valid
|
||||
Pass @function --foo(--x : 10px) is valid
|
||||
Pass @function --foo(--x type(*): 10px) is valid
|
||||
Pass @function --foo(--x <length>: 10px) is valid
|
||||
Pass @function --foo(--x <length>: 10px, --y) is valid
|
||||
Pass @function --foo(--x, --y <length>: 10px) is valid
|
||||
Pass @function --foo(--x type(<length> | auto): auto) is valid
|
||||
Pass @function --foo(--x type(<length> | auto) : auto) is valid
|
||||
Pass @function --foo(--x:1px, --y, --z:2px) is valid
|
||||
Pass @function --foo(--x: 10px !important) is invalid
|
||||
Pass @function --foo(--x <length>: 10deg) is invalid
|
||||
Pass @function --foo(--x <angle>: 10px) is invalid
|
||||
Pass @function --foo(--x <color>: 10px) is invalid
|
||||
Pass @function --foo(--x type(<color>+): red 5) is invalid
|
||||
Pass @function --foo(--x type(auto | none): thing) is invalid
|
||||
Fail @function --foo(--x <length>#) is valid
|
||||
Fail @function --foo(--x <length>+) is valid
|
||||
Fail @function --foo(--x type(<length>+)) is valid
|
||||
Fail @function --foo(--x <transform-function>#) is valid
|
||||
Fail @function --foo(--x <transform-function>+) is valid
|
||||
Pass @function --foo(--x <length>#) is valid
|
||||
Pass @function --foo(--x <length>+) is valid
|
||||
Pass @function --foo(--x type(<length>+)) is valid
|
||||
Pass @function --foo(--x <transform-function>#) is valid
|
||||
Pass @function --foo(--x <transform-function>+) is valid
|
||||
Pass @function --foo(--x <transform-list>#) is invalid
|
||||
Pass @function --foo(--x <transform-list>+) is invalid
|
||||
Pass @function --foo(--x *) is invalid
|
||||
|
|
@ -71,12 +70,12 @@ Pass @function --foo(--x, ;) is invalid
|
|||
Pass @function --foo(;) is invalid
|
||||
Pass @function --foo(]) is invalid
|
||||
Pass @function --foo(, --x]) is invalid
|
||||
Fail @function --foo(--x) returns type(*) is valid
|
||||
Fail @function --foo(--x) returns <length> is valid
|
||||
Fail @function --foo(--x) returns <length>+ is valid
|
||||
Fail @function --foo(--x) returns type(<length>) is valid
|
||||
Fail @function --foo(--x) returns type(<length> | auto) is valid
|
||||
Fail @function --foo(--x) returns type(foo | bar) is valid
|
||||
Pass @function --foo(--x) returns type(*) is valid
|
||||
Pass @function --foo(--x) returns <length> is valid
|
||||
Pass @function --foo(--x) returns <length>+ is valid
|
||||
Pass @function --foo(--x) returns type(<length>) is valid
|
||||
Pass @function --foo(--x) returns type(<length> | auto) is valid
|
||||
Pass @function --foo(--x) returns type(foo | bar) is valid
|
||||
Pass @function --foo(--x) ! is invalid
|
||||
Pass @function --foo(--x) ! <length> is invalid
|
||||
Pass @function --foo(--x) returns <length>! is invalid
|
||||
|
|
|
|||
Loading…
Reference in a new issue