mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-05 01:10:24 +00:00
LibWeb: Support non-fixed <random-value-sharing>
This works by generating random values using XorShift128PlusRNG at compute time and then caching them on the document using the relevant random-caching-key
This commit is contained in:
Notes:
github-actions[bot]
2025-12-01 11:01:47 +00:00
Author: https://github.com/Calme1709 Commit: https://github.com/LadybirdBrowser/ladybird/commit/12e8f503aa4 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6707 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/gmta
@@ -192,6 +192,7 @@
|
||||
"ease-in",
|
||||
"ease-in-out",
|
||||
"ease-out",
|
||||
"element-shared",
|
||||
"ellipsis",
|
||||
"embed",
|
||||
"emoji",
|
||||
|
||||
@@ -1724,6 +1724,15 @@ bool Parser::context_allows_random_functions() const
|
||||
return m_value_context.find_first_index_if([](ValueParsingContext context) { return context.has<PropertyID>(); }).has_value();
|
||||
}
|
||||
|
||||
FlyString Parser::random_value_sharing_auto_name() const
|
||||
{
|
||||
auto top_level_property_context_index = m_value_context.find_first_index_if([](ValueParsingContext const& context) { return context.has<PropertyID>(); });
|
||||
|
||||
auto property_name = string_from_property_id(m_value_context[top_level_property_context_index.value()].get<PropertyID>());
|
||||
|
||||
return MUST(String::formatted("{} {}", property_name, m_random_function_index));
|
||||
}
|
||||
|
||||
Vector<ComponentValue> Parser::parse_as_list_of_component_values()
|
||||
{
|
||||
return parse_a_list_of_component_values(m_token_stream);
|
||||
|
||||
@@ -603,6 +603,7 @@ private:
|
||||
bool context_allows_quirky_length() const;
|
||||
bool context_allows_tree_counting_functions() const;
|
||||
bool context_allows_random_functions() const;
|
||||
FlyString random_value_sharing_auto_name() const;
|
||||
|
||||
Vector<RuleContext> m_rule_context;
|
||||
HashTable<FlyString> m_declared_namespaces;
|
||||
|
||||
@@ -3798,6 +3798,9 @@ RefPtr<RandomValueSharingStyleValue const> Parser::parse_random_value_sharing(To
|
||||
|
||||
tokens.discard_whitespace();
|
||||
|
||||
if (!tokens.has_next_token())
|
||||
return nullptr;
|
||||
|
||||
// fixed <number [0,1]>
|
||||
if (tokens.next_token().is_ident("fixed"sv)) {
|
||||
tokens.discard_a_token();
|
||||
@@ -3820,8 +3823,51 @@ RefPtr<RandomValueSharingStyleValue const> Parser::parse_random_value_sharing(To
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// FIXME: Support non-fixed values
|
||||
return nullptr;
|
||||
// [ [ auto | <dashed-ident> ] || element-shared ]
|
||||
bool has_explicit_auto = false;
|
||||
Optional<FlyString> dashed_ident;
|
||||
bool element_shared = false;
|
||||
|
||||
while (tokens.has_next_token()) {
|
||||
if (auto maybe_dashed_ident_value = parse_dashed_ident_value(tokens)) {
|
||||
if (has_explicit_auto || dashed_ident.has_value())
|
||||
return nullptr;
|
||||
|
||||
dashed_ident = maybe_dashed_ident_value->custom_ident();
|
||||
|
||||
tokens.discard_whitespace();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto maybe_keyword_value = parse_keyword_value(tokens);
|
||||
|
||||
if (maybe_keyword_value && maybe_keyword_value->to_keyword() == Keyword::Auto) {
|
||||
if (has_explicit_auto || dashed_ident.has_value())
|
||||
return nullptr;
|
||||
|
||||
has_explicit_auto = true;
|
||||
|
||||
tokens.discard_whitespace();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (maybe_keyword_value && maybe_keyword_value->to_keyword() == Keyword::ElementShared) {
|
||||
if (element_shared)
|
||||
return nullptr;
|
||||
|
||||
element_shared = true;
|
||||
|
||||
tokens.discard_whitespace();
|
||||
continue;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!dashed_ident.has_value())
|
||||
return RandomValueSharingStyleValue::create_auto(random_value_sharing_auto_name(), element_shared);
|
||||
|
||||
return RandomValueSharingStyleValue::create_dashed_ident(dashed_ident.value(), element_shared);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-values-4/#typedef-dashed-ident
|
||||
|
||||
@@ -2595,7 +2595,9 @@ String RandomCalculationNode::to_string(CalculationContext const& context, Seria
|
||||
StringBuilder builder;
|
||||
|
||||
builder.append("random("sv);
|
||||
builder.appendff("{}, ", m_random_value_sharing->to_string(serialization_mode));
|
||||
auto random_value_sharing_stringified = m_random_value_sharing->to_string(serialization_mode);
|
||||
if (!random_value_sharing_stringified.is_empty())
|
||||
builder.appendff("{}, ", random_value_sharing_stringified);
|
||||
builder.appendff("{}, ", serialize_a_calculation_tree(m_minimum, context, serialization_mode));
|
||||
builder.append(serialize_a_calculation_tree(m_maximum, context, serialization_mode));
|
||||
if (m_step)
|
||||
|
||||
@@ -7,11 +7,15 @@
|
||||
#include "RandomValueSharingStyleValue.h"
|
||||
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
ValueComparingNonnullRefPtr<StyleValue const> RandomValueSharingStyleValue::absolutized(ComputationContext const& computation_context) const
|
||||
{
|
||||
// https://drafts.csswg.org/css-values-5/#random-caching
|
||||
// Each instance of a random function in styles has an associated random base value.
|
||||
// If the random function’s <random-value-sharing> is fixed <number>, the random base value is that number.
|
||||
if (m_fixed_value) {
|
||||
auto const& absolutized_fixed_value = m_fixed_value->absolutized(computation_context);
|
||||
|
||||
@@ -21,7 +25,29 @@ ValueComparingNonnullRefPtr<StyleValue const> RandomValueSharingStyleValue::abso
|
||||
return RandomValueSharingStyleValue::create_fixed(absolutized_fixed_value);
|
||||
}
|
||||
|
||||
TODO();
|
||||
// Otherwise, the random base value is a pseudo-random real number in the range `[0, 1)` (greater than or equal to 0
|
||||
// and less than 1), generated from a uniform distribution, and influenced by the function’s random caching key.
|
||||
|
||||
// A random caching key is a tuple of:
|
||||
RandomCachingKey random_caching_key {
|
||||
// 1. A string name: the value of the <dashed-ident>, if specified in <random-value-sharing>; or else a string
|
||||
// of the form "PROPERTY N", where PROPERTY is the name of the property the random function is used in
|
||||
// (before shorthand expansion, if relevant), and N is the index of the random function among other random
|
||||
// functions in the same property value.
|
||||
.name = m_name.value(),
|
||||
|
||||
// 2. An element ID identifying the element the style is being applied to, or null if element-shared is
|
||||
// specified in <random-value-sharing>.
|
||||
// FIXME: Use the pseudo element's unique_id() when that's accessible
|
||||
.element_id = m_element_shared ? Optional<UniqueNodeID> { OptionalNone {} } : Optional<UniqueNodeID> { computation_context.abstract_element->element().unique_id() },
|
||||
|
||||
// 3. A document ID identifying the Document the styles are from.
|
||||
// NB: This is implicit since the cache is stored on the document or the element (which is a child of the document).
|
||||
};
|
||||
|
||||
auto random_base_value = const_cast<DOM::Element&>(computation_context.abstract_element->element()).ensure_css_random_base_value(random_caching_key);
|
||||
|
||||
return RandomValueSharingStyleValue::create_fixed(NumberStyleValue::create(random_base_value));
|
||||
}
|
||||
|
||||
double RandomValueSharingStyleValue::random_base_value() const
|
||||
@@ -43,7 +69,18 @@ String RandomValueSharingStyleValue::to_string(SerializationMode serialization_m
|
||||
if (m_fixed_value)
|
||||
return MUST(String::formatted("fixed {}", m_fixed_value->to_string(serialization_mode)));
|
||||
|
||||
TODO();
|
||||
StringBuilder builder;
|
||||
|
||||
if (!m_is_auto)
|
||||
builder.appendff("{}", m_name.value());
|
||||
|
||||
if (m_element_shared) {
|
||||
if (!builder.is_empty())
|
||||
builder.append(' ');
|
||||
builder.append("element-shared"sv);
|
||||
}
|
||||
|
||||
return builder.to_string_without_validation();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,11 +11,26 @@
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
struct RandomCachingKey {
|
||||
FlyString name;
|
||||
Optional<Web::UniqueNodeID> element_id;
|
||||
};
|
||||
|
||||
class RandomValueSharingStyleValue : public StyleValueWithDefaultOperators<RandomValueSharingStyleValue> {
|
||||
public:
|
||||
static ValueComparingNonnullRefPtr<RandomValueSharingStyleValue const> create_fixed(NonnullRefPtr<StyleValue const> const& fixed_value)
|
||||
{
|
||||
return adopt_ref(*new (nothrow) RandomValueSharingStyleValue(fixed_value));
|
||||
return adopt_ref(*new (nothrow) RandomValueSharingStyleValue(fixed_value, false, {}, false));
|
||||
}
|
||||
|
||||
static ValueComparingNonnullRefPtr<RandomValueSharingStyleValue const> create_auto(FlyString name, bool element_shared)
|
||||
{
|
||||
return adopt_ref(*new (nothrow) RandomValueSharingStyleValue({}, true, move(name), element_shared));
|
||||
}
|
||||
|
||||
static ValueComparingNonnullRefPtr<RandomValueSharingStyleValue const> create_dashed_ident(FlyString name, bool element_shared)
|
||||
{
|
||||
return adopt_ref(*new (nothrow) RandomValueSharingStyleValue({}, false, move(name), element_shared));
|
||||
}
|
||||
|
||||
virtual ~RandomValueSharingStyleValue() override = default;
|
||||
@@ -28,17 +43,46 @@ public:
|
||||
|
||||
bool properties_equal(RandomValueSharingStyleValue const& other) const
|
||||
{
|
||||
return m_fixed_value == other.m_fixed_value;
|
||||
return m_fixed_value == other.m_fixed_value
|
||||
&& m_is_auto == other.m_is_auto
|
||||
&& m_name == other.m_name
|
||||
&& m_element_shared == other.m_element_shared;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit RandomValueSharingStyleValue(RefPtr<StyleValue const> fixed_value)
|
||||
explicit RandomValueSharingStyleValue(RefPtr<StyleValue const> fixed_value, bool is_auto, Optional<FlyString> name, bool element_shared)
|
||||
: StyleValueWithDefaultOperators(Type::RandomValueSharing)
|
||||
, m_fixed_value(move(fixed_value))
|
||||
, m_is_auto(is_auto)
|
||||
, m_name(move(name))
|
||||
, m_element_shared(element_shared)
|
||||
{
|
||||
}
|
||||
|
||||
ValueComparingRefPtr<StyleValue const> m_fixed_value;
|
||||
bool m_is_auto;
|
||||
Optional<FlyString> m_name;
|
||||
bool m_element_shared;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
|
||||
template<>
|
||||
struct Traits<Web::CSS::RandomCachingKey> : public DefaultTraits<Web::CSS::RandomCachingKey> {
|
||||
static unsigned hash(Web::CSS::RandomCachingKey const& key)
|
||||
{
|
||||
if (!key.element_id.has_value())
|
||||
return key.name.hash();
|
||||
|
||||
return pair_int_hash(key.name.hash(), Traits<i64>::hash(key.element_id->value()));
|
||||
}
|
||||
|
||||
static bool equals(Web::CSS::RandomCachingKey const& a, Web::CSS::RandomCachingKey const& b)
|
||||
{
|
||||
return a.element_id == b.element_id && a.name == b.name;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibCrypto/SecureRandom.h>
|
||||
#include <LibGC/RootVector.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
@@ -48,6 +49,7 @@
|
||||
#include <LibWeb/CSS/StyleSheetIdentifier.h>
|
||||
#include <LibWeb/CSS/StyleValues/ColorSchemeStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/GuaranteedInvalidStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/RandomValueSharingStyleValue.h>
|
||||
#include <LibWeb/CSS/SystemColor.h>
|
||||
#include <LibWeb/CSS/TransitionEvent.h>
|
||||
#include <LibWeb/CSS/VisualViewport.h>
|
||||
@@ -6014,6 +6016,14 @@ void Document::for_each_active_css_style_sheet(Function<void(CSS::CSSStyleSheet&
|
||||
}
|
||||
}
|
||||
|
||||
double Document::ensure_element_shared_css_random_base_value(CSS::RandomCachingKey const& random_caching_key)
|
||||
{
|
||||
return m_element_shared_css_random_base_value_cache.ensure(random_caching_key, []() {
|
||||
static XorShift128PlusRNG random_number_generator;
|
||||
return random_number_generator.get();
|
||||
});
|
||||
}
|
||||
|
||||
static Optional<CSS::CSSStyleSheet&> find_style_sheet_with_url(String const& url, CSS::CSSStyleSheet& style_sheet)
|
||||
{
|
||||
if (style_sheet.href() == url)
|
||||
|
||||
@@ -267,6 +267,8 @@ public:
|
||||
|
||||
CSS::StyleSheetList* style_sheets_for_bindings() { return &style_sheets(); }
|
||||
|
||||
double ensure_element_shared_css_random_base_value(CSS::RandomCachingKey const&);
|
||||
|
||||
Optional<String> get_style_sheet_source(CSS::StyleSheetIdentifier const&) const;
|
||||
|
||||
virtual FlyString node_name() const override { return "#document"_fly_string; }
|
||||
@@ -1351,6 +1353,9 @@ private:
|
||||
HashMap<FlyString, GC::Ref<Web::CSS::CSSPropertyRule>> m_registered_custom_properties;
|
||||
|
||||
CSS::StyleScope m_style_scope;
|
||||
|
||||
// https://drafts.csswg.org/css-values-5/#random-caching
|
||||
HashMap<CSS::RandomCachingKey, double> m_element_shared_css_random_base_value_cache;
|
||||
};
|
||||
|
||||
template<>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/RandomValueSharingStyleValue.h>
|
||||
#include <LibWeb/DOM/Attr.h>
|
||||
#include <LibWeb/DOM/DOMTokenList.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
@@ -4311,6 +4312,19 @@ GC::Ref<CSS::StylePropertyMapReadOnly> Element::computed_style_map()
|
||||
return *m_computed_style_map_cache;
|
||||
}
|
||||
|
||||
double Element::ensure_css_random_base_value(CSS::RandomCachingKey const& random_caching_key)
|
||||
{
|
||||
// NB: We cache element-shared random base values on the Document and non-element-shared ones on the Element itself
|
||||
// so that when an element is removed it takes its non-shared cache with it.
|
||||
if (!random_caching_key.element_id.has_value())
|
||||
return document().ensure_element_shared_css_random_base_value(random_caching_key);
|
||||
|
||||
return m_element_specific_css_random_base_value_cache.ensure(random_caching_key, []() {
|
||||
static XorShift128PlusRNG random_number_generator;
|
||||
return random_number_generator.get();
|
||||
});
|
||||
}
|
||||
|
||||
// The element to inherit style from.
|
||||
// If a pseudo-element is specified, this will return the element itself.
|
||||
// Otherwise, if this element is slotted somewhere, it will return the slot's element to inherit style from.
|
||||
|
||||
@@ -520,6 +520,8 @@ public:
|
||||
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#implicitly-potentially-render-blocking
|
||||
virtual bool is_implicitly_potentially_render_blocking() const { return false; }
|
||||
|
||||
double ensure_css_random_base_value(CSS::RandomCachingKey const&);
|
||||
|
||||
protected:
|
||||
Element(Document&, DOM::QualifiedName);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
@@ -656,6 +658,9 @@ private:
|
||||
bool m_captured_in_a_view_transition { false };
|
||||
|
||||
bool m_is_contained_in_list_subtree { false };
|
||||
|
||||
// https://drafts.csswg.org/css-values-5/#random-caching
|
||||
HashMap<CSS::RandomCachingKey, double> m_element_specific_css_random_base_value_cache;
|
||||
};
|
||||
|
||||
template<>
|
||||
|
||||
@@ -410,6 +410,7 @@ struct CalculationResolutionContext;
|
||||
struct CSSStyleSheetInit;
|
||||
struct GridRepeatParams;
|
||||
struct LogicalAliasMappingContext;
|
||||
struct RandomCachingKey;
|
||||
struct StyleSheetIdentifier;
|
||||
|
||||
using PaintOrderList = Array<PaintOrder, 3>;
|
||||
|
||||
@@ -98,7 +98,6 @@ ErrorOr<void> generate_implementation_file(JsonObject& functions_data, Core::Fil
|
||||
#include <LibWeb/CSS/Parser/ErrorReporter.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/RandomValueSharingStyleValue.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
@@ -312,8 +311,7 @@ RefPtr<CalculationNode const> Parser::parse_math_function(Function const& functi
|
||||
parameter_generator.set("parse_function", MUST(String::formatted("parse_random_value_sharing(tokens_{})", parameter_index)));
|
||||
parameter_generator.set("check_function", " != nullptr"_string);
|
||||
parameter_generator.set("release_function", ".release_nonnull()"_string);
|
||||
// FIXME: This should be 'auto' rather than 'fixed 0' by default
|
||||
parameter_generator.set("parameter_default", MUST(String::formatted(" = RandomValueSharingStyleValue::create_fixed(NumberStyleValue::create(0))")));
|
||||
parameter_generator.set("parameter_default", MUST(String::formatted(" = RandomValueSharingStyleValue::create_auto(random_value_sharing_auto_name(), false)")));
|
||||
} else {
|
||||
// NOTE: This assumes everything not handled above is a calculation node of some kind.
|
||||
parameter_is_calculation = true;
|
||||
|
||||
@@ -2,16 +2,15 @@ Harness status: OK
|
||||
|
||||
Found 72 tests
|
||||
|
||||
59 Pass
|
||||
13 Fail
|
||||
72 Pass
|
||||
Pass Property scale value 'random(1, 11)'
|
||||
Fail Property scale value 'random(--foo, 2, 12)'
|
||||
Fail Property scale value 'random(--foo element-shared, 3, 13)'
|
||||
Fail Property scale value 'random(element-shared --foo, 4, 14)'
|
||||
Pass Property scale value 'random(--foo, 2, 12)'
|
||||
Pass Property scale value 'random(--foo element-shared, 3, 13)'
|
||||
Pass Property scale value 'random(element-shared --foo, 4, 14)'
|
||||
Pass Property scale value 'random(0, 10, 5)'
|
||||
Fail Property scale value 'random(--foo, 10, 20, 5)'
|
||||
Fail Property scale value 'random(--foo element-shared, 20, 30, 5)'
|
||||
Fail Property scale value 'random(element-shared --foo, 30, 40, 5)'
|
||||
Pass Property scale value 'random(--foo, 10, 20, 5)'
|
||||
Pass Property scale value 'random(--foo element-shared, 20, 30, 5)'
|
||||
Pass Property scale value 'random(element-shared --foo, 30, 40, 5)'
|
||||
Pass Property scale value 'random(100, 10)'
|
||||
Pass Property scale value 'random(-10, -100)'
|
||||
Pass Property scale value 'random(-100, -10)'
|
||||
@@ -61,18 +60,18 @@ Pass Property scale value 'calc(10 + random(10, 100, infinity))'
|
||||
Pass Property scale value 'random(10, 100, -infinity)'
|
||||
Pass Property scale value 'calc(10 + random(10, 100, -infinity))'
|
||||
Pass Property scale value on pseudo element '::before' 'random(7, 17)'
|
||||
Fail Property scale value on pseudo element '::before' 'random(--bar, 8, 18)'
|
||||
Fail Property scale value on pseudo element '::before' 'random(element-shared, 9, 19)'
|
||||
Fail Property scale value on pseudo element '::before' 'random(element-shared --foo, 10, 20)'
|
||||
Pass Property scale value on pseudo element '::before' 'random(--bar, 8, 18)'
|
||||
Pass Property scale value on pseudo element '::before' 'random(element-shared, 9, 19)'
|
||||
Pass Property scale value on pseudo element '::before' 'random(element-shared --foo, 10, 20)'
|
||||
Pass Property translate value 'random(10%, 100%)'
|
||||
Pass Property translate value 'random(fixed random(1, 2), 10%, 100%)'
|
||||
Pass Property translate value 'random(fixed random(-2, -1), 10%, 100%)'
|
||||
Fail Maximum random: 'random(a, b)'
|
||||
Fail Maximum random - shorthand: random(a, b))
|
||||
Fail Shared by name within an element: 'random(--identifier, a, b)'
|
||||
Pass Maximum random: 'random(a, b)'
|
||||
Pass Maximum random - shorthand: random(a, b))
|
||||
Pass Shared by name within an element: 'random(--identifier, a, b)'
|
||||
Pass Shared by name within an element - shorthand: random(--identifier, a, b))
|
||||
Pass Shared between elements within a property: random(element-shared, a, b)
|
||||
Pass Shared between elements within a property - shorthand: random(element-shared, a, b))
|
||||
Fail Shared globally: random(--identifier element-shared, a, b)
|
||||
Pass Shared globally: random(--identifier element-shared, a, b)
|
||||
Pass Shared globally - shorthand: random(element-shared, a, b))
|
||||
Pass Fixed: random(fixed <number>, a, b)
|
||||
@@ -2,37 +2,37 @@ Harness status: OK
|
||||
|
||||
Found 32 tests
|
||||
|
||||
3 Pass
|
||||
29 Fail
|
||||
Fail e.style['width'] = "random(0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "random(0px, 100px, 50px)" should set the property value
|
||||
Fail e.style['width'] = "random(--foo, 0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "random(auto, 0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "random(--foo element-shared, 0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "random(auto element-shared, 0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "random(element-shared --foo, 0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "random(element-shared auto, 0px, 100px)" should set the property value
|
||||
29 Pass
|
||||
3 Fail
|
||||
Pass e.style['width'] = "random(0px, 100px)" should set the property value
|
||||
Pass e.style['width'] = "random(0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(--foo, 0px, 100px)" should set the property value
|
||||
Pass e.style['width'] = "random(auto, 0px, 100px)" should set the property value
|
||||
Pass e.style['width'] = "random(--foo element-shared, 0px, 100px)" should set the property value
|
||||
Pass e.style['width'] = "random(auto element-shared, 0px, 100px)" should set the property value
|
||||
Pass e.style['width'] = "random(element-shared --foo, 0px, 100px)" should set the property value
|
||||
Pass e.style['width'] = "random(element-shared auto, 0px, 100px)" should set the property value
|
||||
Pass e.style['width'] = "random(fixed 0.5, 0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "random(--foo, 0px, 100px, 50px)" should set the property value
|
||||
Fail e.style['width'] = "random(auto, 0px, 100px, 50px)" should set the property value
|
||||
Fail e.style['width'] = "random(--foo element-shared, 0px, 100px, 50px)" should set the property value
|
||||
Fail e.style['width'] = "random(auto element-shared, 0px, 100px, 50px)" should set the property value
|
||||
Fail e.style['width'] = "random(element-shared --foo, 0px, 100px, 50px)" should set the property value
|
||||
Fail e.style['width'] = "random(element-shared auto, 0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(--foo, 0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(auto, 0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(--foo element-shared, 0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(auto element-shared, 0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(element-shared --foo, 0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(element-shared auto, 0px, 100px, 50px)" should set the property value
|
||||
Pass e.style['width'] = "random(fixed 0.5, 0px, 100px, 50px)" should set the property value
|
||||
Fail e.style['width'] = "random(10px, 20%)" should set the property value
|
||||
Fail e.style['width'] = "random(100px, 0px)" should set the property value
|
||||
Fail e.style['width'] = "random(-100px, -10px)" should set the property value
|
||||
Fail e.style['width'] = "random(-100px, -10px, -5px)" should set the property value
|
||||
Fail e.style['width'] = "random(1em, 200rem)" should set the property value
|
||||
Pass e.style['width'] = "random(10px, 20%)" should set the property value
|
||||
Pass e.style['width'] = "random(100px, 0px)" should set the property value
|
||||
Pass e.style['width'] = "random(-100px, -10px)" should set the property value
|
||||
Pass e.style['width'] = "random(-100px, -10px, -5px)" should set the property value
|
||||
Pass e.style['width'] = "random(1em, 200rem)" should set the property value
|
||||
Fail e.style['width'] = "random(10 * 100px, 200em / 2)" should set the property value
|
||||
Pass e.style['width'] = "random(fixed calc(2 / 4), 0px, 100px)" should set the property value
|
||||
Fail e.style['width'] = "calc(2 * random(0px, 100px))" should set the property value
|
||||
Pass e.style['width'] = "calc(2 * random(0px, 100px))" should set the property value
|
||||
Fail e.style['max-lines'] = "random(25, 50)" should set the property value
|
||||
Fail e.style['max-lines'] = "random(25, 50, 5)" should set the property value
|
||||
Fail e.style['scale'] = "random(0.5, 2.5)" should set the property value
|
||||
Fail e.style['scale'] = "random(0.5, 2.5, 0.1)" should set the property value
|
||||
Fail e.style['rotate'] = "random(25deg, 1turn)" should set the property value
|
||||
Fail e.style['rotate'] = "random(25deg, 1turn, 5deg)" should set the property value
|
||||
Fail e.style['transition-delay'] = "random(25ms, 50s)" should set the property value
|
||||
Fail e.style['transition-delay'] = "random(25ms, 50s, 5s)" should set the property value
|
||||
Pass e.style['scale'] = "random(0.5, 2.5)" should set the property value
|
||||
Pass e.style['scale'] = "random(0.5, 2.5, 0.1)" should set the property value
|
||||
Pass e.style['rotate'] = "random(25deg, 1turn)" should set the property value
|
||||
Pass e.style['rotate'] = "random(25deg, 1turn, 5deg)" should set the property value
|
||||
Pass e.style['transition-delay'] = "random(25ms, 50s)" should set the property value
|
||||
Pass e.style['transition-delay'] = "random(25ms, 50s, 5s)" should set the property value
|
||||
Reference in New Issue
Block a user