mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-07-31 17:55:59 -04:00
webapi: Add Select.add
This commit is contained in:
@@ -251,6 +251,96 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="options_add_errors">
|
||||
{
|
||||
const sel = document.createElement('select')
|
||||
const opts = sel.options
|
||||
const opt = document.createElement('option')
|
||||
|
||||
// `before` element that isn't in this select -> NotFoundError
|
||||
const foreign = document.createElement('option')
|
||||
testing.expectError('NotFoundError', () => { opts.add(opt, foreign) })
|
||||
testing.expectEqual(0, opts.length)
|
||||
|
||||
// element and before being the same is a no-op (does not throw)
|
||||
opts.add(opt, null)
|
||||
testing.expectEqual(1, opts.length)
|
||||
opts.add(opt, opt)
|
||||
testing.expectEqual(1, opts.length)
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="select_add">
|
||||
{
|
||||
const sel = document.createElement('select')
|
||||
testing.expectEqual(0, sel.length)
|
||||
|
||||
// Add an option
|
||||
const opt1 = document.createElement('option')
|
||||
opt1.value = 'a'
|
||||
sel.add(opt1, null)
|
||||
testing.expectEqual(1, sel.length)
|
||||
testing.expectEqual('a', sel.options[0].value)
|
||||
|
||||
// Add another, no before arg
|
||||
const opt2 = document.createElement('option')
|
||||
opt2.value = 'b'
|
||||
sel.add(opt2)
|
||||
testing.expectEqual(2, sel.length)
|
||||
testing.expectEqual('b', sel.options[1].value)
|
||||
|
||||
// Add before an option element
|
||||
const opt0 = document.createElement('option')
|
||||
opt0.value = 'zero'
|
||||
sel.add(opt0, opt1)
|
||||
testing.expectEqual(3, sel.length)
|
||||
testing.expectEqual('zero', sel.options[0].value)
|
||||
testing.expectEqual('a', sel.options[1].value)
|
||||
testing.expectEqual('b', sel.options[2].value)
|
||||
|
||||
// Add before an index
|
||||
const opt3 = document.createElement('option')
|
||||
opt3.value = 'mid'
|
||||
sel.add(opt3, 1)
|
||||
testing.expectEqual(4, sel.length)
|
||||
testing.expectEqual('zero', sel.options[0].value)
|
||||
testing.expectEqual('mid', sel.options[1].value)
|
||||
testing.expectEqual('a', sel.options[2].value)
|
||||
testing.expectEqual('b', sel.options[3].value)
|
||||
|
||||
// Out-of-range index appends
|
||||
const opt4 = document.createElement('option')
|
||||
opt4.value = 'end'
|
||||
sel.add(opt4, 999)
|
||||
testing.expectEqual(5, sel.length)
|
||||
testing.expectEqual('end', sel.options[4].value)
|
||||
|
||||
// Re-adding an already-attached option moves it (no duplicate)
|
||||
sel.add(opt4, opt3)
|
||||
testing.expectEqual(5, sel.length)
|
||||
testing.expectEqual('end', sel.options[1].value)
|
||||
testing.expectEqual('mid', sel.options[2].value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="select_add_errors">
|
||||
{
|
||||
const sel = document.createElement('select')
|
||||
const opt = document.createElement('option')
|
||||
|
||||
// `before` element that isn't in this select -> NotFoundError
|
||||
const foreign = document.createElement('option')
|
||||
testing.expectError('NotFoundError', () => { sel.add(opt, foreign) })
|
||||
testing.expectEqual(0, sel.length)
|
||||
|
||||
// element and before being the same is a no-op (does not throw)
|
||||
sel.add(opt, null)
|
||||
testing.expectEqual(1, sel.length)
|
||||
sel.add(opt, opt)
|
||||
testing.expectEqual(1, sel.length)
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="selectedOptions">
|
||||
{
|
||||
const sel = document.createElement('select')
|
||||
|
||||
@@ -104,6 +104,6 @@ pub const JsApi = struct {
|
||||
pub const @"[str]" = bridge.namedIndexed(HTMLOptionsCollection.getByName, null, null, .{ .null_as_undefined = true });
|
||||
|
||||
pub const selectedIndex = bridge.accessor(HTMLOptionsCollection.getSelectedIndex, HTMLOptionsCollection.setSelectedIndex, .{});
|
||||
pub const add = bridge.function(HTMLOptionsCollection.add, .{ .ce_reactions = true });
|
||||
pub const add = bridge.function(HTMLOptionsCollection.add, .{ .dom_exception = true, .ce_reactions = true });
|
||||
pub const remove = bridge.function(HTMLOptionsCollection.remove, .{ .ce_reactions = true });
|
||||
};
|
||||
|
||||
@@ -222,6 +222,37 @@ pub fn getLength(self: *Select) u32 {
|
||||
return i;
|
||||
}
|
||||
|
||||
const AddBeforeOption = union(enum) {
|
||||
option: *Option,
|
||||
index: u32,
|
||||
};
|
||||
|
||||
pub fn add(self: *Select, element: *Option, before_: ?AddBeforeOption, frame: *Frame) !void {
|
||||
const self_node = self.asNode();
|
||||
|
||||
var before_node: ?*Node = null;
|
||||
if (before_) |before| {
|
||||
switch (before) {
|
||||
.index => |idx| {
|
||||
var i: u32 = 0;
|
||||
var it = self_node.childrenIterator();
|
||||
while (it.next()) |child| {
|
||||
if (child.is(Option) == null) {
|
||||
continue;
|
||||
}
|
||||
if (i == idx) {
|
||||
before_node = child;
|
||||
break;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
},
|
||||
.option => |before_option| before_node = before_option.asNode(),
|
||||
}
|
||||
}
|
||||
_ = try self_node.insertBefore(element.asElement().asNode(), before_node, frame);
|
||||
}
|
||||
|
||||
pub fn getSelectedOptions(self: *Select, frame: *Frame) !collections.NodeLive(.selected_options) {
|
||||
return collections.NodeLive(.selected_options).init(self.asNode(), {}, frame);
|
||||
}
|
||||
@@ -340,6 +371,7 @@ pub const JsApi = struct {
|
||||
pub const willValidate = bridge.accessor(Select.getWillValidate, null, .{});
|
||||
pub const validity = bridge.accessor(Select.getValidity, null, .{});
|
||||
pub const validationMessage = bridge.accessor(Select.getValidationMessage, null, .{});
|
||||
pub const add = bridge.function(Select.add, .{ .dom_exception = true, .ce_reactions = true });
|
||||
pub const checkValidity = bridge.function(Select.checkValidity, .{});
|
||||
pub const reportValidity = bridge.function(Select.reportValidity, .{});
|
||||
pub const setCustomValidity = bridge.function(Select.setCustomValidity, .{});
|
||||
|
||||
Reference in New Issue
Block a user