ladybird/Userland/Libraries/LibWeb/CSS/StyleResolver.h
Andreas Kling 23a08fd35a LibWeb: Start absolutizing lengths after performing the CSS cascade
Once we've performed the cascade on a set of values for an element,
we should have enough information to resolve/absolutize some lengths.

Basically, any CSS length that isn't "auto" or a percentage can be
turned into an absolute length (in pixels) as long as we have the
following information:

- The viewport rect
- The parent element's font
- The document element's font
- The element's own font

To ensure that we can absolutize lengths relative to the element's own
font, we now do a separate first pass where font-related properties are
defaulted (in the cascade spec sense of the word) and become usable.

There's a lot more work to do here, but this should open up a lot of
simplification in layout code, since it will no longer need to care
about relative lengths. Layout still needs to resolve percentages, since
we can't do that for some properties until the containing block
dimensions are known.
2021-09-24 15:01:49 +02:00

75 lines
2.3 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/NonnullRefPtrVector.h>
#include <AK/OwnPtr.h>
#include <LibWeb/CSS/CSSStyleDeclaration.h>
#include <LibWeb/CSS/StyleProperties.h>
#include <LibWeb/Forward.h>
namespace Web::CSS {
struct MatchingRule {
RefPtr<CSSStyleRule> rule;
size_t style_sheet_index { 0 };
size_t rule_index { 0 };
size_t selector_index { 0 };
u32 specificity { 0 };
};
class StyleResolver {
public:
explicit StyleResolver(DOM::Document&);
~StyleResolver();
DOM::Document& document() { return m_document; }
DOM::Document const& document() const { return m_document; }
NonnullRefPtr<StyleProperties> resolve_style(DOM::Element&) const;
// https://www.w3.org/TR/css-cascade/#origin
enum class CascadeOrigin {
Any, // FIXME: This is not part of the spec. Get rid of it.
Author,
User,
UserAgent,
Animation,
Transition,
};
Vector<MatchingRule> collect_matching_rules(DOM::Element const&, CascadeOrigin = CascadeOrigin::Any) const;
void sort_matching_rules(Vector<MatchingRule>&) const;
struct CustomPropertyResolutionTuple {
Optional<StyleProperty> style {};
u32 specificity { 0 };
};
CustomPropertyResolutionTuple resolve_custom_property_with_specificity(DOM::Element&, String const&) const;
Optional<StyleProperty> resolve_custom_property(DOM::Element&, String const&) const;
private:
void compute_cascaded_values(StyleProperties&, DOM::Element&) const;
void compute_font(StyleProperties&, DOM::Element const&) const;
void compute_defaulted_values(StyleProperties&, DOM::Element const&) const;
void absolutize_values(StyleProperties&, DOM::Element const&) const;
void compute_defaulted_property_value(StyleProperties&, DOM::Element const&, CSS::PropertyID) const;
template<typename Callback>
void for_each_stylesheet(CascadeOrigin, Callback) const;
struct MatchingRuleSet {
Vector<MatchingRule> user_agent_rules;
Vector<MatchingRule> author_rules;
};
void cascade_declarations(StyleProperties&, DOM::Element&, Vector<MatchingRule> const&, CascadeOrigin, bool important) const;
DOM::Document& m_document;
};
}