mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 03:25:13 +00:00
LibWeb: Implement the HTMLInputElement.list
attribute
This returns the `HTMLDataListElement` pointed to by the `list` content attribute.
This commit is contained in:
parent
a37315da87
commit
6178557a07
Notes:
github-actions[bot]
2025-03-09 15:11:49 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/6178557a07f Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3782
7 changed files with 164 additions and 1 deletions
|
@ -32,6 +32,7 @@
|
|||
#include <LibWeb/HTML/Dates.h>
|
||||
#include <LibWeb/HTML/DecodedImageData.h>
|
||||
#include <LibWeb/HTML/EventNames.h>
|
||||
#include <LibWeb/HTML/HTMLDataListElement.h>
|
||||
#include <LibWeb/HTML/HTMLDivElement.h>
|
||||
#include <LibWeb/HTML/HTMLFormElement.h>
|
||||
#include <LibWeb/HTML/HTMLInputElement.h>
|
||||
|
@ -190,6 +191,39 @@ void HTMLInputElement::set_indeterminate(bool value)
|
|||
m_indeterminate = value;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#dom-input-list
|
||||
GC::Ptr<HTMLDataListElement const> HTMLInputElement::list() const
|
||||
{
|
||||
// The list IDL attribute must return the current suggestions source element, if any, or null otherwise.
|
||||
if (auto data_list_element = suggestions_source_element(); data_list_element.has_value())
|
||||
return *data_list_element;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#concept-input-list
|
||||
Optional<GC::Ref<HTMLDataListElement const>> HTMLInputElement::suggestions_source_element() const
|
||||
{
|
||||
// The suggestions source element is the first element in the tree in tree order to have an ID equal to the value of the list attribute,
|
||||
// if that element is a datalist element. If there is no list attribute, or if there is no element with that ID,
|
||||
// or if the first element with that ID is not a datalist element, then there is no suggestions source element.
|
||||
Optional<GC::Ref<HTMLDataListElement const>> result;
|
||||
if (auto list_attribute_value = get_attribute(HTML::AttributeNames::list); list_attribute_value.has_value()) {
|
||||
root().for_each_in_inclusive_subtree_of_type<DOM::Element>([&](auto& element) {
|
||||
if (element.id() == *list_attribute_value) {
|
||||
if (auto data_list_element = as_if<HTMLDataListElement>(element))
|
||||
result = *data_list_element;
|
||||
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#compiled-pattern-regular-expression
|
||||
Optional<Regex<ECMA262>> HTMLInputElement::compiled_pattern_regular_expression() const
|
||||
{
|
||||
|
|
|
@ -106,6 +106,8 @@ public:
|
|||
bool indeterminate() const { return m_indeterminate; }
|
||||
void set_indeterminate(bool);
|
||||
|
||||
GC::Ptr<HTMLDataListElement const> list() const;
|
||||
|
||||
void did_pick_color(Optional<Color> picked_color, ColorPickerUpdateState state);
|
||||
|
||||
enum class MultipleHandling {
|
||||
|
@ -356,6 +358,8 @@ private:
|
|||
|
||||
Optional<Regex<ECMA262>> compiled_pattern_regular_expression() const;
|
||||
|
||||
Optional<GC::Ref<HTMLDataListElement const>> suggestions_source_element() const;
|
||||
|
||||
Optional<DOM::DocumentLoadEventDelayer> m_load_event_delayer;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/input.html#dom-input-indeterminate
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#import <HTML/HTMLDataListElement.idl>
|
||||
#import <HTML/HTMLElement.idl>
|
||||
#import <HTML/HTMLFormElement.idl>
|
||||
#import <HTML/PopoverInvokerElement.idl>
|
||||
|
@ -25,7 +26,7 @@ interface HTMLInputElement : HTMLElement {
|
|||
[CEReactions, Reflect=formtarget] attribute DOMString formTarget;
|
||||
[CEReactions] attribute unsigned long height;
|
||||
attribute boolean indeterminate;
|
||||
[FIXME] readonly attribute HTMLDataListElement? list;
|
||||
readonly attribute HTMLDataListElement? list;
|
||||
[CEReactions, Reflect] attribute DOMString max;
|
||||
[CEReactions] attribute long maxLength;
|
||||
[CEReactions, Reflect] attribute DOMString min;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 6 tests
|
||||
|
||||
6 Pass
|
||||
Pass getting .list of input must return the datalist with that id
|
||||
Pass getting .list of input must return null if it has no list attribute
|
||||
Pass getting .list of input must return null if the list attribute is a non-datalist's id
|
||||
Pass getting .list of input must return null if the list attribute is no element's id
|
||||
Pass getting .list of input must return null if the list attribute is used in a non-datalist earlier than a datalist
|
||||
Pass getting .list of input must return the datalist with that id even if a later non-datalist also has the id
|
|
@ -0,0 +1,7 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 2 tests
|
||||
|
||||
2 Pass
|
||||
Pass Input element's list attribute should point to the datalist element.
|
||||
Pass Input element's list attribute should point to the datalist element in Shadow DOM.
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>input list attribute</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<h3>input_list</h3>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<form method="post"
|
||||
enctype="application/x-www-form-urlencoded"
|
||||
action=""
|
||||
name="input_form">
|
||||
<datalist id="thelist">
|
||||
<option value="one">one</option>
|
||||
<option value="two">two</option>
|
||||
</datalist>
|
||||
|
||||
<p id="non_datalist_first">
|
||||
<datalist id="non_datalist_first">
|
||||
<option value="one">one</option>
|
||||
<option value="two">two</option>
|
||||
</datalist>
|
||||
|
||||
<datalist id="datalist_first">
|
||||
<option value="one">one</option>
|
||||
<option value="two">two</option>
|
||||
</datalist>
|
||||
<p id="datalist_first">
|
||||
|
||||
<p><input list="thelist" id='input_with_list'></p>
|
||||
<p><input id='input_without_list'></p>
|
||||
<p><input list="input_with_list" id='input_with_nondatalist_list'></p>
|
||||
<p><input list="not_an_id" id='input_with_missing_list'></p>
|
||||
<p><input list="non_datalist_first" id='input_with_non_datalist_first'></p>
|
||||
<p><input list="datalist_first" id='input_with_datalist_first'></p>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
test(function() {
|
||||
assert_equals(document.getElementById("input_with_list").list, document.getElementById("thelist"));
|
||||
}, "getting .list of input must return the datalist with that id");
|
||||
test(function() {
|
||||
assert_equals(document.getElementById("input_without_list").list, null);
|
||||
}, "getting .list of input must return null if it has no list attribute");
|
||||
test(function() {
|
||||
assert_equals(document.getElementById("input_with_nondatalist_list").list, null);
|
||||
}, "getting .list of input must return null if the list attribute is a non-datalist's id");
|
||||
test(function() {
|
||||
assert_equals(document.getElementById("input_with_missing_list").list, null);
|
||||
}, "getting .list of input must return null if the list attribute is no element's id");
|
||||
test(function() {
|
||||
assert_equals(document.getElementById("input_with_non_datalist_first").list, null);
|
||||
}, "getting .list of input must return null if the list attribute is used in a non-datalist earlier than a datalist");
|
||||
test(function() {
|
||||
assert_equals(document.getElementById("input_with_datalist_first").list, document.querySelector("datalist#datalist_first"));
|
||||
}, "getting .list of input must return the datalist with that id even if a later non-datalist also has the id");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,39 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Input.list</title>
|
||||
<script src=../resources/testharness.js></script>
|
||||
<script src=../resources/testharnessreport.js></script>
|
||||
<div id="testcontent">
|
||||
<input id="input" list="datalist">
|
||||
</div>
|
||||
<script>
|
||||
|
||||
test(() => {
|
||||
assert_equals(document.getElementById('input').list, null);
|
||||
var dl = document.createElement("datalist");
|
||||
dl.id = "datalist";
|
||||
document.getElementById("testcontent").appendChild(dl);
|
||||
assert_equals(document.getElementById('input').list, dl);
|
||||
}, "Input element's list attribute should point to the datalist element.");
|
||||
|
||||
|
||||
test(() => {
|
||||
var host = document.createElement("div");
|
||||
document.getElementById("testcontent").appendChild(host);
|
||||
var sr = host.attachShadow({mode: "open"});
|
||||
var input = document.createElement("input");
|
||||
input.setAttribute("list", "datalist");
|
||||
sr.appendChild(input);
|
||||
assert_equals(input.list, null);
|
||||
|
||||
var dl = document.createElement("datalist");
|
||||
dl.id = "datalist";
|
||||
sr.appendChild(dl);
|
||||
assert_equals(input.list, dl);
|
||||
|
||||
dl.remove();
|
||||
assert_equals(input.list, null);
|
||||
}, "Input element's list attribute should point to the datalist element in Shadow DOM.");
|
||||
|
||||
|
||||
</script>
|
Loading…
Add table
Reference in a new issue