mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-28 14:43:28 +00:00
Merge pull request #1107 from lightpanda-io/mutation_observer_improvement
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
Use correct 'this' on MutationObserver callback
This commit is contained in:
@@ -36,8 +36,8 @@ const Walker = @import("../dom/walker.zig").WalkerChildren;
|
||||
pub const MutationObserver = struct {
|
||||
page: *Page,
|
||||
cbk: Env.Function,
|
||||
connected: bool,
|
||||
scheduled: bool,
|
||||
observers: std.ArrayListUnmanaged(*Observer),
|
||||
|
||||
// List of records which were observed. When the call scope ends, we need to
|
||||
// execute our callback with it.
|
||||
@@ -48,8 +48,8 @@ pub const MutationObserver = struct {
|
||||
.cbk = cbk,
|
||||
.page = page,
|
||||
.observed = .{},
|
||||
.connected = true,
|
||||
.scheduled = false,
|
||||
.observers = .empty,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -68,15 +68,17 @@ pub const MutationObserver = struct {
|
||||
.event_node = .{ .id = self.cbk.id, .func = Observer.handle },
|
||||
};
|
||||
|
||||
try self.observers.append(arena, observer);
|
||||
|
||||
// register node's events
|
||||
if (options.childList or options.subtree) {
|
||||
_ = try parser.eventTargetAddEventListener(
|
||||
observer.dom_node_inserted_listener = try parser.eventTargetAddEventListener(
|
||||
parser.toEventTarget(parser.Node, node),
|
||||
"DOMNodeInserted",
|
||||
&observer.event_node,
|
||||
false,
|
||||
);
|
||||
_ = try parser.eventTargetAddEventListener(
|
||||
observer.dom_node_removed_listener = try parser.eventTargetAddEventListener(
|
||||
parser.toEventTarget(parser.Node, node),
|
||||
"DOMNodeRemoved",
|
||||
&observer.event_node,
|
||||
@@ -84,7 +86,7 @@ pub const MutationObserver = struct {
|
||||
);
|
||||
}
|
||||
if (options.attr()) {
|
||||
_ = try parser.eventTargetAddEventListener(
|
||||
observer.dom_node_attribute_modified_listener = try parser.eventTargetAddEventListener(
|
||||
parser.toEventTarget(parser.Node, node),
|
||||
"DOMAttrModified",
|
||||
&observer.event_node,
|
||||
@@ -92,7 +94,7 @@ pub const MutationObserver = struct {
|
||||
);
|
||||
}
|
||||
if (options.cdata()) {
|
||||
_ = try parser.eventTargetAddEventListener(
|
||||
observer.dom_cdata_modified_listener = try parser.eventTargetAddEventListener(
|
||||
parser.toEventTarget(parser.Node, node),
|
||||
"DOMCharacterDataModified",
|
||||
&observer.event_node,
|
||||
@@ -100,7 +102,7 @@ pub const MutationObserver = struct {
|
||||
);
|
||||
}
|
||||
if (options.subtree) {
|
||||
_ = try parser.eventTargetAddEventListener(
|
||||
observer.dom_subtree_modified_listener = try parser.eventTargetAddEventListener(
|
||||
parser.toEventTarget(parser.Node, node),
|
||||
"DOMSubtreeModified",
|
||||
&observer.event_node,
|
||||
@@ -111,10 +113,6 @@ pub const MutationObserver = struct {
|
||||
|
||||
fn callback(ctx: *anyopaque) ?u32 {
|
||||
const self: *MutationObserver = @ptrCast(@alignCast(ctx));
|
||||
if (self.connected == false) {
|
||||
self.scheduled = true;
|
||||
return null;
|
||||
}
|
||||
self.scheduled = false;
|
||||
|
||||
const records = self.observed.items;
|
||||
@@ -125,7 +123,7 @@ pub const MutationObserver = struct {
|
||||
defer self.observed.clearRetainingCapacity();
|
||||
|
||||
var result: Env.Function.Result = undefined;
|
||||
self.cbk.tryCall(void, .{records}, &result) catch {
|
||||
self.cbk.tryCallWithThis(void, self, .{records}, &result) catch {
|
||||
log.debug(.user_script, "callback error", .{
|
||||
.err = result.exception,
|
||||
.stack = result.stack,
|
||||
@@ -135,9 +133,55 @@ pub const MutationObserver = struct {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO
|
||||
pub fn _disconnect(self: *MutationObserver) !void {
|
||||
self.connected = false;
|
||||
for (self.observers.items) |observer| {
|
||||
const event_target = parser.toEventTarget(parser.Node, observer.node);
|
||||
if (observer.dom_node_inserted_listener) |listener| {
|
||||
try parser.eventTargetRemoveEventListener(
|
||||
event_target,
|
||||
"DOMNodeInserted",
|
||||
listener,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
if (observer.dom_node_removed_listener) |listener| {
|
||||
try parser.eventTargetRemoveEventListener(
|
||||
event_target,
|
||||
"DOMNodeRemoved",
|
||||
listener,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
if (observer.dom_node_attribute_modified_listener) |listener| {
|
||||
try parser.eventTargetRemoveEventListener(
|
||||
event_target,
|
||||
"DOMAttrModified",
|
||||
listener,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
if (observer.dom_cdata_modified_listener) |listener| {
|
||||
try parser.eventTargetRemoveEventListener(
|
||||
event_target,
|
||||
"DOMCharacterDataModified",
|
||||
listener,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
if (observer.dom_subtree_modified_listener) |listener| {
|
||||
try parser.eventTargetRemoveEventListener(
|
||||
event_target,
|
||||
"DOMSubtreeModified",
|
||||
listener,
|
||||
false,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.observers.clearRetainingCapacity();
|
||||
}
|
||||
|
||||
// TODO
|
||||
@@ -222,6 +266,12 @@ const Observer = struct {
|
||||
|
||||
event_node: parser.EventNode,
|
||||
|
||||
dom_node_inserted_listener: ?*parser.EventListener = null,
|
||||
dom_node_removed_listener: ?*parser.EventListener = null,
|
||||
dom_node_attribute_modified_listener: ?*parser.EventListener = null,
|
||||
dom_cdata_modified_listener: ?*parser.EventListener = null,
|
||||
dom_subtree_modified_listener: ?*parser.EventListener = null,
|
||||
|
||||
fn appliesTo(
|
||||
self: *const Observer,
|
||||
target: *parser.Node,
|
||||
|
||||
@@ -11,15 +11,19 @@
|
||||
|
||||
var nb = 0;
|
||||
var mrs;
|
||||
new MutationObserver((mu) => {
|
||||
let cb_this1;
|
||||
let mu1 = new MutationObserver(function(mu) {
|
||||
mrs = mu;
|
||||
nb++;
|
||||
}).observe(document.firstElementChild, { attributes: true, attributeOldValue: true });
|
||||
cb_this1 = this;
|
||||
});
|
||||
mu1.observe(document.firstElementChild, { attributes: true, attributeOldValue: true });
|
||||
document.firstElementChild.setAttribute("foo", "bar");
|
||||
document.firstElementChild.firstChild.setAttribute("foo", "bar");
|
||||
|
||||
testing.eventually(() => {
|
||||
testing.expectEqual(1, nb);
|
||||
testing.expectEqual(cb_this1, mu1);
|
||||
testing.expectEqual('attributes', mrs[0].type);
|
||||
testing.expectEqual(document.firstElementChild, mrs[0].target);
|
||||
testing.expectEqual('bar', mrs[0].target.getAttribute('foo'));
|
||||
@@ -30,14 +34,17 @@
|
||||
var nb2 = 0;
|
||||
var mrs2;
|
||||
var node1 = $('#p1').firstChild;
|
||||
new MutationObserver((mu) => {
|
||||
let mu2 = new MutationObserver((mu) => {
|
||||
mrs2 = mu;
|
||||
nb2++;
|
||||
}).observe(node1, { characterData: true, characterDataOldValue: true });
|
||||
cb_this2 = this;
|
||||
})
|
||||
mu2.observe(node1, { characterData: true, characterDataOldValue: true });
|
||||
node1.data = "foo";
|
||||
|
||||
testing.eventually(() => {
|
||||
testing.expectEqual(1, nb2);
|
||||
testing.expectEqual(window, cb_this2);
|
||||
testing.expectEqual('characterData', mrs2[0].type);
|
||||
testing.expectEqual(node1, mrs2[0].target);
|
||||
testing.expectEqual('foo', mrs2[0].target.data);
|
||||
|
||||
Reference in New Issue
Block a user