mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-10-08 20:32:00 -04:00
Batch option creation
This commit is contained in:
3 files changed
+43
-5
No files matched your search
@@ -443,6 +443,14 @@ fn GetterQuery(comptime getter: anytype, comptime attrs: u32) type {
|
||||
const params = @typeInfo(@TypeOf(getter)).@"fn".params;
|
||||
const Self = params[0].type.?;
|
||||
const Index = params[1].type.?;
|
||||
|
||||
// A getter that can return neither null nor error.NotHandled would report
|
||||
// every index as present.
|
||||
switch (@typeInfo(@typeInfo(@TypeOf(getter)).@"fn".return_type.?)) {
|
||||
.optional, .error_union => {},
|
||||
else => @compileError(@typeName(Self) ++ ": an indexed getter that can't return null or error.NotHandled needs an explicit query"),
|
||||
}
|
||||
|
||||
return struct {
|
||||
const query = if (params.len == 3) withGlobal else plain;
|
||||
|
||||
|
||||
@@ -313,6 +313,25 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="options_indexed_setter_padding">
|
||||
{
|
||||
const sel = document.createElement('select')
|
||||
const make = (v) => { const o = document.createElement('option'); o.value = v; return o }
|
||||
const records = []
|
||||
new MutationObserver((r) => records.push(...r)).observe(sel, { childList: true })
|
||||
|
||||
// The spec pads with one DocumentFragment (we do, so 2 records); Chrome
|
||||
// appends each blank option on its own. Only what was added is common.
|
||||
sel.options[3] = make('d')
|
||||
testing.expectEqual(4, sel.options.length)
|
||||
|
||||
testing.onload(() => {
|
||||
const added = records.flatMap((r) => Array.from(r.addedNodes, (n) => n.value))
|
||||
testing.expectEqual(['', '', '', 'd'], added)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="select_add">
|
||||
{
|
||||
const sel = document.createElement('select')
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const lp = @import("lightpanda");
|
||||
|
||||
const js = @import("../../js/js.zig");
|
||||
const Page = @import("../../Page.zig");
|
||||
const Frame = @import("../../Frame.zig");
|
||||
@@ -105,7 +107,8 @@ pub fn remove(self: *HTMLOptionsCollection, index: i32, frame: *Frame) void {
|
||||
}
|
||||
|
||||
// Chrome's cap (kMaxListItems): padding up to a huge index would otherwise
|
||||
// create that many options.
|
||||
// create that many options. Past it, Chrome ignores the set (with a console
|
||||
// warning); Firefox has no cap.
|
||||
const max_list_items = 100_000;
|
||||
|
||||
// The indexed setter: null removes the option at index; an index past the
|
||||
@@ -127,14 +130,22 @@ fn setAtIndex(self: *HTMLOptionsCollection, index: u32, option_: ?*Option, frame
|
||||
}
|
||||
|
||||
if (index >= max_list_items) {
|
||||
lp.log.warn(.js, "select overflow", .{ .max_list_items = max_list_items, .request = index });
|
||||
return;
|
||||
}
|
||||
|
||||
const select_node = self._select.asNode();
|
||||
const doc = select_node.ownerDocument(frame).?;
|
||||
for (self.length(frame)..index) |_| {
|
||||
const blank = try doc.createElementNS("http://www.w3.org/1999/xhtml", "option", frame);
|
||||
_ = try select_node.appendChild(blank.asNode(), frame);
|
||||
const len = self.length(frame);
|
||||
if (index > len) {
|
||||
// Per spec, the padding goes in as one DocumentFragment, so observers
|
||||
// get one record rather than one per blank option.
|
||||
const doc = select_node.ownerDocument(frame).?;
|
||||
const fragment = (try Node.DocumentFragment.init(doc, frame)).asNode();
|
||||
for (len..index) |_| {
|
||||
const blank = try doc.createElementNS("http://www.w3.org/1999/xhtml", "option", frame);
|
||||
_ = try fragment.appendChild(blank.asNode(), frame);
|
||||
}
|
||||
_ = try select_node.appendChild(fragment, frame);
|
||||
}
|
||||
_ = try select_node.appendChild(option, frame);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user