2020-08-01 03:07:00 +01:00
/*
2021-04-28 22:46:44 +02:00
* Copyright ( c ) 2020 , the SerenityOS developers .
2024-10-04 13:19:50 +02:00
* Copyright ( c ) 2022 , Andreas Kling < andreas @ ladybird . org >
2020-08-01 03:07:00 +01:00
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-08-01 03:07:00 +01:00
*/
2026-04-18 10:54:06 +02:00
# include <LibWeb/Bindings/HTMLTableSectionElement.h>
2022-09-30 17:16:16 -06:00
# include <LibWeb/Bindings/Intrinsics.h>
2024-12-20 11:32:17 +01:00
# include <LibWeb/CSS/ComputedProperties.h>
2025-08-08 11:24:15 +01:00
# include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
2024-10-01 17:45:10 +01:00
# include <LibWeb/CSS/StyleValues/ImageStyleValue.h>
2025-12-09 10:47:00 +13:00
# include <LibWeb/CSS/StyleValues/StyleValueList.h>
2024-10-01 17:45:10 +01:00
# include <LibWeb/DOM/Document.h>
2022-03-12 23:50:35 +02:00
# include <LibWeb/DOM/ElementFactory.h>
2022-02-26 11:43:52 +01:00
# include <LibWeb/DOM/HTMLCollection.h>
# include <LibWeb/HTML/HTMLTableRowElement.h>
2020-08-01 03:07:00 +01:00
# include <LibWeb/HTML/HTMLTableSectionElement.h>
2024-10-01 17:45:10 +01:00
# include <LibWeb/HTML/Parser/HTMLParser.h>
2022-03-12 23:50:35 +02:00
# include <LibWeb/Namespace.h>
2020-08-01 03:07:00 +01:00
namespace Web : : HTML {
2024-11-15 04:01:23 +13:00
GC_DEFINE_ALLOCATOR ( HTMLTableSectionElement ) ;
2023-11-19 19:47:52 +01:00
2022-02-18 21:00:52 +01:00
HTMLTableSectionElement : : HTMLTableSectionElement ( DOM : : Document & document , DOM : : QualifiedName qualified_name )
2021-02-07 11:20:15 +01:00
: HTMLElement ( document , move ( qualified_name ) )
2020-08-01 03:07:00 +01:00
{
}
2022-03-14 13:21:51 -06:00
HTMLTableSectionElement : : ~ HTMLTableSectionElement ( ) = default ;
2020-08-01 03:07:00 +01:00
2023-08-07 08:41:28 +02:00
void HTMLTableSectionElement : : initialize ( JS : : Realm & realm )
2023-01-10 06:28:20 -05:00
{
2024-03-16 13:13:08 +01:00
WEB_SET_PROTOTYPE_FOR_INTERFACE ( HTMLTableSectionElement ) ;
2025-04-20 16:22:57 +02:00
Base : : initialize ( realm ) ;
2023-01-10 06:28:20 -05:00
}
2022-11-24 19:04:27 +01:00
void HTMLTableSectionElement : : visit_edges ( Cell : : Visitor & visitor )
{
Base : : visit_edges ( visitor ) ;
visitor . visit ( m_rows ) ;
}
2022-02-26 11:43:52 +01:00
// https://html.spec.whatwg.org/multipage/tables.html#dom-tbody-rows
2024-11-15 04:01:23 +13:00
GC : : Ref < DOM : : HTMLCollection > HTMLTableSectionElement : : rows ( ) const
2022-02-26 11:43:52 +01:00
{
// The rows attribute must return an HTMLCollection rooted at this element,
// whose filter matches only tr elements that are children of this element.
2022-11-24 19:04:27 +01:00
if ( ! m_rows ) {
2023-05-23 11:25:07 +02:00
m_rows = DOM : : HTMLCollection : : create ( const_cast < HTMLTableSectionElement & > ( * this ) , DOM : : HTMLCollection : : Scope : : Children , [ ] ( Element const & element ) {
return is < HTMLTableRowElement > ( element ) ;
2023-08-13 13:05:26 +02:00
} ) ;
2022-11-24 19:04:27 +01:00
}
return * m_rows ;
2022-02-26 11:43:52 +01:00
}
2022-03-12 23:50:35 +02:00
// https://html.spec.whatwg.org/multipage/tables.html#dom-tbody-insertrow
2024-11-15 04:01:23 +13:00
WebIDL : : ExceptionOr < GC : : Ref < HTMLTableRowElement > > HTMLTableSectionElement : : insert_row ( WebIDL : : Long index )
2022-03-12 23:50:35 +02:00
{
auto rows_collection = rows ( ) ;
auto rows_collection_size = static_cast < long > ( rows_collection - > length ( ) ) ;
// 1. If index is less than − 1 or greater than the number of elements in the rows collection, throw an "IndexSizeError" DOMException.
if ( index < - 1 | | index > rows_collection_size )
2025-08-07 19:31:52 -04:00
return WebIDL : : IndexSizeError : : create ( realm ( ) , " Index is negative or greater than the number of rows " _utf16 ) ;
2022-03-12 23:50:35 +02:00
2024-12-18 17:01:03 +00:00
// 2. Let table row be the result of creating an element given this element's node document, "tr", and the HTML namespace.
2023-11-04 18:42:04 +01:00
auto & table_row = static_cast < HTMLTableRowElement & > ( * TRY ( DOM : : create_element ( document ( ) , TagNames : : tr , Namespace : : HTML ) ) ) ;
2022-03-12 23:50:35 +02:00
// 3. If index is − 1 or equal to the number of items in the rows collection, then append table row to this element.
if ( index = = - 1 | | index = = rows_collection_size )
2022-10-30 17:50:04 +00:00
TRY ( append_child ( table_row ) ) ;
2022-03-12 23:50:35 +02:00
// 4. Otherwise, insert table row as a child of this element, immediately before the index-th tr element in the rows collection.
else
2024-03-12 10:22:19 +01:00
insert_before ( table_row , rows_collection - > item ( index ) ) ;
2022-03-12 23:50:35 +02:00
// 5. Return table row.
2024-11-15 04:01:23 +13:00
return GC : : Ref ( table_row ) ;
2022-03-12 23:50:35 +02:00
}
2022-03-12 23:50:53 +02:00
// https://html.spec.whatwg.org/multipage/tables.html#dom-tbody-deleterow
2024-02-26 18:54:36 +01:00
WebIDL : : ExceptionOr < void > HTMLTableSectionElement : : delete_row ( WebIDL : : Long index )
2022-03-12 23:50:53 +02:00
{
auto rows_collection = rows ( ) ;
auto rows_collection_size = static_cast < long > ( rows_collection - > length ( ) ) ;
// 1. If index is less than − 1 or greater than or equal to the number of elements in the rows collection, then throw an "IndexSizeError" DOMException.
if ( index < - 1 | | index > = rows_collection_size )
2025-08-07 19:31:52 -04:00
return WebIDL : : IndexSizeError : : create ( realm ( ) , " Index is negative or greater than or equal to the number of rows " _utf16 ) ;
2022-03-12 23:50:53 +02:00
// 2. If index is − 1, then remove the last element in the rows collection from this element, or do nothing if the rows collection is empty.
if ( index = = - 1 ) {
if ( rows_collection_size > 0 )
rows_collection - > item ( rows_collection_size - 1 ) - > remove ( ) ;
}
// 3. Otherwise, remove the indexth element in the rows collection from this element.
else {
rows_collection - > item ( index ) - > remove ( ) ;
}
return { } ;
}
2024-12-23 17:51:10 +01:00
bool HTMLTableSectionElement : : is_presentational_hint ( FlyString const & name ) const
{
if ( Base : : is_presentational_hint ( name ) )
return true ;
return first_is_one_of ( name ,
2026-04-30 11:15:16 +01:00
HTML : : AttributeNames : : align ,
2024-12-23 17:51:10 +01:00
HTML : : AttributeNames : : background ,
2025-02-18 12:45:47 +00:00
HTML : : AttributeNames : : bgcolor ,
HTML : : AttributeNames : : height ) ;
2024-12-23 17:51:10 +01:00
}
2026-04-30 10:44:26 +01:00
void HTMLTableSectionElement : : apply_presentational_hints ( Vector < CSS : : StyleProperty > & properties ) const
2024-10-01 17:45:10 +01:00
{
2026-04-30 10:44:26 +01:00
Base : : apply_presentational_hints ( properties ) ;
2024-10-01 17:45:10 +01:00
for_each_attribute ( [ & ] ( auto & name , auto & value ) {
2026-04-30 11:15:16 +01:00
if ( name = = HTML : : AttributeNames : : align ) {
if ( auto parsed_value = parse_table_child_element_align_value ( value ) )
2026-04-30 10:44:26 +01:00
properties . append ( { . property_id = CSS : : PropertyID : : TextAlign , . value = parsed_value . release_nonnull ( ) } ) ;
2026-04-30 11:15:16 +01:00
}
2024-10-01 17:45:10 +01:00
// https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url
2026-04-30 11:15:16 +01:00
else if ( name = = HTML : : AttributeNames : : background ) {
2025-01-23 19:40:57 +13:00
if ( auto parsed_value = document ( ) . encoding_parse_url ( value ) ; parsed_value . has_value ( ) )
2026-04-30 10:44:26 +01:00
properties . append ( { . property_id = CSS : : PropertyID : : BackgroundImage , . value = CSS : : StyleValueList : : create ( { CSS : : ImageStyleValue : : create ( * parsed_value ) } , CSS : : StyleValueList : : Separator : : Comma ) } ) ;
2024-10-01 17:45:10 +01:00
}
// https://html.spec.whatwg.org/multipage/rendering.html#tables-2:rules-for-parsing-a-legacy-colour-value
else if ( name = = HTML : : AttributeNames : : bgcolor ) {
if ( auto color = parse_legacy_color_value ( value ) ; color . has_value ( ) )
2026-04-30 10:44:26 +01:00
properties . append ( { . property_id = CSS : : PropertyID : : BackgroundColor , . value = CSS : : ColorStyleValue : : create_from_color ( color . value ( ) , CSS : : ColorSyntax : : Legacy ) } ) ;
2025-02-18 12:45:47 +00:00
} else if ( name = = HTML : : AttributeNames : : height ) {
if ( auto parsed_value = parse_dimension_value ( value ) )
2026-04-30 10:44:26 +01:00
properties . append ( { . property_id = CSS : : PropertyID : : Height , . value = parsed_value . release_nonnull ( ) } ) ;
2024-10-01 17:45:10 +01:00
}
} ) ;
}
2020-08-01 03:07:00 +01:00
}