mirror of
https://github.com/lexmount/moli.git
synced 2026-11-01 16:05:37 +00:00
fix(dom): resolve detached nodes in their owning host
This commit is contained in:
@@ -10,7 +10,7 @@ use moli_webapi_declare::WebApiFunctionTemplate;
|
||||
use super::super::{
|
||||
document_runtime::DomHandle,
|
||||
util::{
|
||||
call_global_bridge_method, context_host_ptr_from_global_bridge, get_private_value,
|
||||
call_global_bridge_method, context_host_ptr_from_context_slot, get_private_value,
|
||||
throw_type_error, v8_string, v8str,
|
||||
},
|
||||
};
|
||||
@@ -813,8 +813,13 @@ pub(crate) fn node_runtime_and_handle_from_object_or_detached<'s>(
|
||||
if let Ok(node) = node_runtime_and_handle_from_object(scope, object) {
|
||||
return Ok(node);
|
||||
}
|
||||
let runtime_ptr = context_host_ptr_from_global_bridge(scope)
|
||||
.context("current context has no JsContextHost")?;
|
||||
// Detached node indices are host-local too. Borrowed bindings and
|
||||
// structuredClone can run in another Page, so resolve the producer's
|
||||
// lifecycle-checked context instead of looking in the caller's arena.
|
||||
let runtime_ptr = object
|
||||
.get_creation_context(scope)
|
||||
.and_then(context_host_ptr_from_context_slot)
|
||||
.context("detached node's context has no JsContextHost")?;
|
||||
let handle = super::document::detached_native_handle_for_runtime(scope, runtime_ptr, object)
|
||||
.context("object is neither a Node wrapper nor a detached node")?;
|
||||
Ok((runtime_ptr, handle))
|
||||
|
||||
@@ -10,7 +10,7 @@ fn svg_rect_uses_shared_geometry_in_live_and_windowless_realms() {
|
||||
"[]"
|
||||
);
|
||||
assert_eq!(
|
||||
vm.eval("__uiEventResults.complete && __uiEventResults.total === 3522 && __uiEventResults.passed === 3522")
|
||||
vm.eval("__uiEventResults.complete && __uiEventResults.total === 4122 && __uiEventResults.passed === 4122")
|
||||
.unwrap(),
|
||||
"true"
|
||||
);
|
||||
|
||||
@@ -60,7 +60,19 @@
|
||||
if (kind === 'DOMRect') clone.width = .1;
|
||||
return owner.getAttribute('viewBox') === previous && (kind !== 'DOMRect' || clone.width === .1);
|
||||
});
|
||||
check(`${prefix}/${kind}/cross realm JSON`, () => Object.getPrototypeOf(DOMRectReadOnly.prototype.toJSON.call(rect)) === Object.prototype);
|
||||
check(`${prefix}/${kind}/cross realm JSON`, () => {
|
||||
owner.setAttribute('viewBox','10 20 30 40');
|
||||
const json = DOMRectReadOnly.prototype.toJSON.call(rect);
|
||||
return Object.getPrototypeOf(json) === Object.prototype && fields.every((name,i) => json[name] === [10,20,30,40][i]) && json.right === 40 && json.bottom === 60;
|
||||
});
|
||||
check(`${prefix}/${kind}/borrowed coordinate getters`, () => {
|
||||
owner.setAttribute('viewBox','11 22 33 44');
|
||||
return fields.every((name,i) => Object.getOwnPropertyDescriptor(DOMRectReadOnly.prototype,name).get.call(rect) === [11,22,33,44][i]);
|
||||
});
|
||||
check(`${prefix}/${kind}/borrowed side getters`, () => {
|
||||
owner.setAttribute('viewBox','-5 -7 3 4');
|
||||
return ['left','top','right','bottom'].every((name,i) => Object.getOwnPropertyDescriptor(DOMRectReadOnly.prototype,name).get.call(rect) === [-5,-7,-2,-3][i]);
|
||||
});
|
||||
check(`${prefix}/${kind}/fromRect snapshot`, () => {
|
||||
const copy = w.DOMRect.fromRect(rect);
|
||||
const x = copy.x; owner.setAttribute('viewBox','5 6 7 8');
|
||||
@@ -82,6 +94,13 @@
|
||||
const expected = [10,20,30,40]; expected[fields.indexOf(name)] = .1;
|
||||
return conversions === 1 && fields.every((key,i) => base[key] === expected[i] && anim[key] === expected[i]) && owner.getAttribute('viewBox') === expected.join(' ');
|
||||
});
|
||||
check(`${prefix}/${name}/borrowed setter reentrant mutation`, () => {
|
||||
let conversions = 0;
|
||||
const borrowed = Object.getOwnPropertyDescriptor(DOMRect.prototype,name).set;
|
||||
borrowed.call(base,{valueOf(){conversions++;owner.setAttribute('viewBox','50 60 70 80');return .2;}});
|
||||
const expected = [50,60,70,80]; expected[fields.indexOf(name)] = .2;
|
||||
return conversions === 1 && fields.every((key,i) => base[key] === expected[i] && anim[key] === expected[i]) && owner.getAttribute('viewBox') === expected.join(' ');
|
||||
});
|
||||
check(`${prefix}/${name}/throwing conversion preserved`, () => {
|
||||
const sentinel = {}, previous = owner.getAttribute('viewBox');
|
||||
return thrown(() => setter.call(base,{valueOf(){throw sentinel;}})) === sentinel && owner.getAttribute('viewBox') === previous;
|
||||
|
||||
Reference in New Issue
Block a user