mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-23 16:40:03 +00:00
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
When we compute style for elements inside a UA-internal shadow tree that represent a pseudo-element (e.g ::placeholder), we actually run the StyleComputer machinery for (host element :: pseudo-element). While that lets us match the correct selectors, it was incorrectly applying CSS inheritance, since we'd also then inherit from whatever was above the host element in the tree. This patch fixes the issue by introducing an inheritance override in AbstractElement and then using that to force inheritance from whatever is actually directly above in the DOM for these elements instead of jumping all the way up past the host. This fixes an issue where `text-align: center` on input type=text elements would render the main text centered but placeholder text was still left-aligned.
80 lines
2.8 KiB
C++
80 lines
2.8 KiB
C++
/*
|
|
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibGC/Cell.h>
|
|
#include <LibWeb/CSS/PseudoElement.h>
|
|
#include <LibWeb/CSS/StyleProperty.h>
|
|
#include <LibWeb/Forward.h>
|
|
|
|
namespace Web::DOM {
|
|
|
|
// Either an Element or a PseudoElement
|
|
class WEB_API AbstractElement {
|
|
public:
|
|
AbstractElement(GC::Ref<Element>, Optional<CSS::PseudoElement> = {});
|
|
|
|
Document& document() const;
|
|
|
|
Element& element() { return m_element; }
|
|
Element const& element() const { return m_element; }
|
|
Optional<CSS::PseudoElement> pseudo_element() const { return m_pseudo_element; }
|
|
|
|
GC::Ptr<Layout::NodeWithStyle> layout_node();
|
|
GC::Ptr<Layout::NodeWithStyle const> layout_node() const { return const_cast<AbstractElement*>(this)->layout_node(); }
|
|
|
|
CSS::TreeCountingFunctionResolutionContext tree_counting_function_resolution_context() const;
|
|
|
|
GC::Ptr<Element const> parent_element() const;
|
|
Optional<AbstractElement> element_to_inherit_style_from() const;
|
|
Optional<AbstractElement> previous_in_tree_order() { return walk_layout_tree(WalkMethod::Previous); }
|
|
Optional<AbstractElement> previous_sibling_in_tree_order() { return walk_layout_tree(WalkMethod::PreviousSibling); }
|
|
bool is_before(AbstractElement const&) const;
|
|
|
|
void set_inheritance_override(GC::Ref<Element> element) { m_inheritance_override = element; }
|
|
|
|
GC::Ptr<CSS::ComputedProperties const> computed_properties() const;
|
|
|
|
void set_custom_properties(OrderedHashMap<FlyString, CSS::StyleProperty>&& custom_properties);
|
|
[[nodiscard]] OrderedHashMap<FlyString, CSS::StyleProperty> const& custom_properties() const;
|
|
RefPtr<CSS::StyleValue const> get_custom_property(FlyString const& name) const;
|
|
|
|
GC::Ptr<CSS::CascadedProperties> cascaded_properties() const;
|
|
void set_cascaded_properties(GC::Ptr<CSS::CascadedProperties>);
|
|
|
|
bool has_non_empty_counters_set() const;
|
|
Optional<CSS::CountersSet const&> counters_set() const;
|
|
CSS::CountersSet& ensure_counters_set();
|
|
void set_counters_set(OwnPtr<CSS::CountersSet>&&);
|
|
|
|
void visit(GC::Cell::Visitor& visitor) const;
|
|
|
|
String debug_description() const;
|
|
bool operator==(AbstractElement const&) const = default;
|
|
|
|
private:
|
|
enum class WalkMethod : u8 {
|
|
Previous,
|
|
PreviousSibling,
|
|
};
|
|
Optional<AbstractElement> walk_layout_tree(WalkMethod);
|
|
|
|
GC::Ref<Element> m_element;
|
|
Optional<CSS::PseudoElement> m_pseudo_element;
|
|
|
|
GC::Ptr<Element> m_inheritance_override;
|
|
};
|
|
|
|
}
|
|
|
|
template<>
|
|
struct AK::Traits<Web::DOM::AbstractElement> : public DefaultTraits<Web::DOM::AbstractElement> {
|
|
static unsigned hash(Web::DOM::AbstractElement const& key)
|
|
{
|
|
return pair_int_hash(ptr_hash(&key.element()), key.pseudo_element().has_value() ? to_underlying(key.pseudo_element().value()) : -1);
|
|
}
|
|
};
|