Make DOM geometry structs serializable (#38828)

Makes the following DOM geometry structs serializable:
- `DOMRect`
- `DOMRectReadOnly`
- `DOMQuad`
- `DOMMatrix`
- `DOMMatrixReadOnly`

Testing: Covered by WPT (`css/geometry/structured-serialization.html`).

---------

Signed-off-by: lumiscosity <averyrudelphe@gmail.com>
This commit is contained in:
lumiscosity 2025-08-22 01:19:42 +02:00 committed by GitHub
parent e00f39d827
commit 39f3ce7a2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 529 additions and 89 deletions

View file

@ -3,8 +3,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::Cell;
use std::collections::HashMap;
use std::{f64, ptr};
use base::id::{DomMatrixId, DomMatrixIndex};
use constellation_traits::DomMatrix;
use cssparser::{Parser, ParserInput};
use dom_struct::dom_struct;
use euclid::Angle;
@ -30,7 +33,9 @@ use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::serializable::Serializable;
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::structuredclone::StructuredData;
use crate::dom::dommatrix::DOMMatrix;
use crate::dom::dompoint::DOMPoint;
use crate::dom::globalscope::GlobalScope;
@ -924,6 +929,89 @@ impl DOMMatrixReadOnlyMethods<crate::DomTypeHolder> for DOMMatrixReadOnly {
}
}
impl Serializable for DOMMatrixReadOnly {
type Index = DomMatrixIndex;
type Data = DomMatrix;
fn serialize(&self) -> Result<(DomMatrixId, Self::Data), ()> {
let serialized = if self.is2D() {
DomMatrix {
matrix: Transform3D::new(
self.M11(),
self.M12(),
f64::NAN,
f64::NAN,
self.M21(),
self.M22(),
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
f64::NAN,
self.M41(),
self.M42(),
f64::NAN,
f64::NAN,
),
is_2d: true,
}
} else {
DomMatrix {
matrix: *self.matrix(),
is_2d: false,
}
};
Ok((DomMatrixId::new(), serialized))
}
fn deserialize(
owner: &GlobalScope,
serialized: Self::Data,
can_gc: CanGc,
) -> Result<DomRoot<Self>, ()>
where
Self: Sized,
{
if serialized.is_2d {
Ok(Self::new(
owner,
true,
Transform3D::new(
serialized.matrix.m11,
serialized.matrix.m12,
0.0,
0.0,
serialized.matrix.m21,
serialized.matrix.m22,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
serialized.matrix.m41,
serialized.matrix.m42,
0.0,
1.0,
),
can_gc,
))
} else {
Ok(Self::new(owner, false, serialized.matrix, can_gc))
}
}
fn serialized_storage<'a>(
data: StructuredData<'a, '_>,
) -> &'a mut Option<HashMap<DomMatrixId, Self::Data>> {
match data {
StructuredData::Reader(reader) => &mut reader.matrices,
StructuredData::Writer(writer) => &mut writer.matrices,
}
}
}
// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly-numbersequence
pub(crate) fn entries_to_matrix(entries: &[f64]) -> Fallible<(bool, Transform3D<f64>)> {
if let Ok(array) = entries.try_into() {