mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 04:57:45 +00:00
LibWeb: Add ol start and li value attributes support
This commit is contained in:
parent
d2fbc15f5d
commit
1cdbfc2ff1
10 changed files with 189 additions and 16 deletions
|
@ -223,6 +223,7 @@ namespace AttributeNames {
|
|||
__ENUMERATE_HTML_ATTRIBUTE(srclang) \
|
||||
__ENUMERATE_HTML_ATTRIBUTE(srcset) \
|
||||
__ENUMERATE_HTML_ATTRIBUTE(standby) \
|
||||
__ENUMERATE_HTML_ATTRIBUTE(start) \
|
||||
__ENUMERATE_HTML_ATTRIBUTE(step) \
|
||||
__ENUMERATE_HTML_ATTRIBUTE(style) \
|
||||
__ENUMERATE_HTML_ATTRIBUTE(summary) \
|
||||
|
|
|
@ -20,6 +20,12 @@ public:
|
|||
// https://www.w3.org/TR/html-aria/#el-li
|
||||
virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::listitem; }
|
||||
|
||||
i32 value() { return get_attribute(AttributeNames::value).value_or("0"_string).to_number<i32>().value_or(0); }
|
||||
void set_value(i32 value)
|
||||
{
|
||||
set_attribute(AttributeNames::value, MUST(String::number(value))).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
private:
|
||||
HTMLLIElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ interface HTMLLIElement : HTMLElement {
|
|||
|
||||
[HTMLConstructor] constructor();
|
||||
|
||||
// FIXME: [CEReactions] attribute long value;
|
||||
[CEReactions] attribute long value;
|
||||
|
||||
// Obsolete
|
||||
[CEReactions, Reflect] attribute DOMString type;
|
||||
|
|
|
@ -20,6 +20,12 @@ public:
|
|||
// https://www.w3.org/TR/html-aria/#el-ol
|
||||
virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::list; }
|
||||
|
||||
i32 start() { return get_attribute(AttributeNames::start).value_or("1"_string).to_number<i32>().value_or(1); }
|
||||
void set_start(i32 start)
|
||||
{
|
||||
set_attribute(AttributeNames::start, MUST(String::number(start))).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
private:
|
||||
HTMLOListElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ interface HTMLOListElement : HTMLElement {
|
|||
[HTMLConstructor] constructor();
|
||||
|
||||
[CEReactions, Reflect] attribute boolean reversed;
|
||||
// FIXME: [CEReactions] attribute long start;
|
||||
[CEReactions] attribute long start;
|
||||
[CEReactions, Reflect] attribute DOMString type;
|
||||
|
||||
// Obsolete
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/HTML/HTMLButtonElement.h>
|
||||
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||
#include <LibWeb/HTML/HTMLLIElement.h>
|
||||
#include <LibWeb/HTML/HTMLOListElement.h>
|
||||
#include <LibWeb/HTML/HTMLProgressElement.h>
|
||||
#include <LibWeb/HTML/HTMLSlotElement.h>
|
||||
#include <LibWeb/Layout/ListItemBox.h>
|
||||
|
@ -251,6 +253,30 @@ static bool is_ignorable_whitespace(Layout::Node const& node)
|
|||
return false;
|
||||
}
|
||||
|
||||
i32 TreeBuilder::calculate_list_item_index(DOM::Node& dom_node)
|
||||
{
|
||||
if (is<HTML::HTMLLIElement>(dom_node)) {
|
||||
auto& li = static_cast<HTML::HTMLLIElement&>(dom_node);
|
||||
if (li.value() != 0)
|
||||
return li.value();
|
||||
}
|
||||
|
||||
if (dom_node.previous_sibling() != nullptr) {
|
||||
DOM::Node* current = dom_node.previous_sibling();
|
||||
while (current != nullptr) {
|
||||
if (is<HTML::HTMLLIElement>(*current))
|
||||
return calculate_list_item_index(*current) + 1;
|
||||
current = current->previous_sibling();
|
||||
}
|
||||
}
|
||||
|
||||
if (is<HTML::HTMLOListElement>(*dom_node.parent())) {
|
||||
auto& ol = static_cast<HTML::HTMLOListElement&>(*dom_node.parent());
|
||||
return ol.start();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context& context)
|
||||
{
|
||||
JS::GCPtr<Layout::Node> layout_node;
|
||||
|
@ -349,9 +375,8 @@ ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::
|
|||
|
||||
if (is<ListItemBox>(*layout_node)) {
|
||||
auto& element = static_cast<DOM::Element&>(dom_node);
|
||||
int child_index = layout_node->parent()->index_of_child<ListItemBox>(*layout_node).value();
|
||||
auto marker_style = TRY(style_computer.compute_style(element, CSS::Selector::PseudoElement::Marker));
|
||||
auto list_item_marker = document.heap().allocate_without_realm<ListItemMarkerBox>(document, layout_node->computed_values().list_style_type(), layout_node->computed_values().list_style_position(), child_index + 1, *marker_style);
|
||||
auto list_item_marker = document.heap().allocate_without_realm<ListItemMarkerBox>(document, layout_node->computed_values().list_style_type(), layout_node->computed_values().list_style_position(), calculate_list_item_index(dom_node), *marker_style);
|
||||
static_cast<ListItemBox&>(*layout_node).set_marker(list_item_marker);
|
||||
element.set_pseudo_element_node({}, CSS::Selector::PseudoElement::Marker, list_item_marker);
|
||||
layout_node->append_child(*list_item_marker);
|
||||
|
|
|
@ -25,6 +25,8 @@ private:
|
|||
bool has_svg_root = false;
|
||||
};
|
||||
|
||||
i32 calculate_list_item_index(DOM::Node&);
|
||||
|
||||
ErrorOr<void> create_layout_tree(DOM::Node&, Context&);
|
||||
|
||||
void push_parent(Layout::NodeWithStyle& node) { m_ancestor_stack.append(node); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue