mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
Previously, the LibWeb bindings generator would output multiple per interface files like Prototype/Constructor/Namespace/GlobalMixin depending on the contents of that IDL file. This complicates the build system as it means that it does not know what files will be generated without knowledge of the contents of that IDL file. Instead, for each IDL file only generate a single Bindings/<IDLFile>.h and Bindings/<IDLFile>.cpp.
144 lines
4.4 KiB
C++
144 lines
4.4 KiB
C++
/*
|
|
* Copyright (c) 2021, the SerenityOS developers.
|
|
* Copyright (c) 2022-2025, Sam Atkins <sam@ladybird.org>
|
|
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/Bindings/CSSRule.h>
|
|
#include <LibWeb/CSS/CSSImportRule.h>
|
|
#include <LibWeb/CSS/CSSLayerBlockRule.h>
|
|
#include <LibWeb/CSS/CSSRule.h>
|
|
#include <LibWeb/CSS/CSSStyleSheet.h>
|
|
#include <LibWeb/Dump.h>
|
|
|
|
namespace Web::CSS {
|
|
|
|
CSSRule::CSSRule(JS::Realm& realm, Type type)
|
|
: PlatformObject(realm)
|
|
, m_type(type)
|
|
{
|
|
}
|
|
|
|
void CSSRule::visit_edges(Cell::Visitor& visitor)
|
|
{
|
|
Base::visit_edges(visitor);
|
|
visitor.visit(m_parent_style_sheet);
|
|
visitor.visit(m_parent_rule);
|
|
}
|
|
|
|
// https://www.w3.org/TR/cssom/#dom-cssrule-type
|
|
WebIDL::UnsignedShort CSSRule::type_for_bindings() const
|
|
{
|
|
// NOTE: Types that aren't defined in the spec must return 0.
|
|
// To do this, we arbitrarily make non-spec ones start at 100.
|
|
auto type = to_underlying(m_type);
|
|
if (type >= 100)
|
|
return 0;
|
|
return type;
|
|
}
|
|
|
|
// https://www.w3.org/TR/cssom/#dom-cssrule-csstext
|
|
String CSSRule::css_text() const
|
|
{
|
|
// The cssText attribute must return a serialization of the CSS rule.
|
|
return serialized();
|
|
}
|
|
|
|
// https://www.w3.org/TR/cssom/#dom-cssrule-csstext
|
|
void CSSRule::set_css_text(StringView)
|
|
{
|
|
// On setting the cssText attribute must do nothing.
|
|
}
|
|
|
|
void CSSRule::set_parent_rule(CSSRule* parent_rule)
|
|
{
|
|
clear_caches();
|
|
m_parent_rule = parent_rule;
|
|
|
|
if (parent_rule == nullptr)
|
|
set_parent_style_sheet(nullptr);
|
|
else
|
|
set_parent_style_sheet(parent_rule->parent_style_sheet());
|
|
clear_caches();
|
|
}
|
|
|
|
void CSSRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet)
|
|
{
|
|
clear_caches();
|
|
m_parent_style_sheet = parent_style_sheet;
|
|
clear_caches();
|
|
}
|
|
|
|
void CSSRule::dump(StringBuilder& builder, int indent_levels) const
|
|
{
|
|
dump_indent(builder, indent_levels);
|
|
builder.appendff("{}:\n", class_name());
|
|
}
|
|
|
|
void CSSRule::clear_caches()
|
|
{
|
|
m_cached_layer_name.clear();
|
|
}
|
|
|
|
FlyString CSSRule::parent_layer_internal_qualified_name_slow_case() const
|
|
{
|
|
Vector<FlyString> layer_names;
|
|
for (auto* rule = parent_rule(); rule; rule = rule->parent_rule()) {
|
|
switch (rule->type()) {
|
|
case Type::Import:
|
|
// @import is only a parent to style sheets, not to rules directly. It's handled below this loop.
|
|
VERIFY_NOT_REACHED();
|
|
break;
|
|
|
|
case Type::LayerBlock: {
|
|
auto& layer_block = as<CSSLayerBlockRule>(*rule);
|
|
layer_names.append(layer_block.internal_name());
|
|
break;
|
|
}
|
|
|
|
// Ignore everything else
|
|
// Note that LayerStatement cannot have child rules so we still ignore it here.
|
|
case Type::Container:
|
|
case Type::CounterStyle:
|
|
case Type::LayerStatement:
|
|
case Type::Style:
|
|
case Type::Media:
|
|
case Type::FontFace:
|
|
case Type::FontFeatureValues:
|
|
case Type::Function:
|
|
case Type::FunctionDeclarations:
|
|
case Type::Keyframes:
|
|
case Type::Keyframe:
|
|
case Type::Namespace:
|
|
case Type::Supports:
|
|
case Type::NestedDeclarations:
|
|
case Type::Property:
|
|
case Type::Page:
|
|
case Type::Margin:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If this style sheet is owned by a rule, include its qualified layer name.
|
|
if (m_parent_style_sheet && m_parent_style_sheet->owner_rule()) {
|
|
if (auto* import = as_if<CSSImportRule>(*m_parent_style_sheet->owner_rule())) {
|
|
// https://drafts.csswg.org/css-cascade-5/#at-import
|
|
// The layer is added to the layer order even if the import fails to load the stylesheet, but is subject to
|
|
// any import conditions (just as if declared by an @layer rule wrapped in the appropriate conditional
|
|
// group rules).
|
|
if (auto layer_name = import->internal_layer_name(); layer_name.has_value() && import->matches()) {
|
|
layer_names.append(layer_name.release_value());
|
|
auto parent_qualified_layer_name = m_parent_style_sheet->owner_rule()->parent_layer_internal_qualified_name();
|
|
if (!parent_qualified_layer_name.is_empty())
|
|
layer_names.append(move(parent_qualified_layer_name));
|
|
}
|
|
}
|
|
}
|
|
|
|
return MUST(String::join('.', layer_names.in_reverse()));
|
|
}
|
|
|
|
}
|