diff options
Diffstat (limited to 'components/script/dom/imagebitmap.rs')
-rw-r--r-- | components/script/dom/imagebitmap.rs | 128 |
1 files changed, 125 insertions, 3 deletions
diff --git a/components/script/dom/imagebitmap.rs b/components/script/dom/imagebitmap.rs index ef6538e7451..b7073d1b49c 100644 --- a/components/script/dom/imagebitmap.rs +++ b/components/script/dom/imagebitmap.rs @@ -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::vec::Vec; +use base::id::{ImageBitmapId, ImageBitmapIndex}; +use constellation_traits::SerializableImageBitmap; use dom_struct::dom_struct; use crate::dom::bindings::cell::DomRefCell; @@ -12,6 +15,9 @@ use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::ImageBitmapMeth use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::{Reflector, reflect_dom_object}; use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::serializable::Serializable; +use crate::dom::bindings::structuredclone::StructuredData; +use crate::dom::bindings::transferable::Transferable; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::CanGc; @@ -29,11 +35,11 @@ pub(crate) struct ImageBitmap { } impl ImageBitmap { - fn new_inherited(width_arg: u32, height_arg: u32) -> ImageBitmap { + fn new_inherited(width: u32, height: u32) -> ImageBitmap { ImageBitmap { reflector_: Reflector::new(), - width: width_arg, - height: height_arg, + width, + height, bitmap_data: DomRefCell::new(Some(vec![])), origin_clean: Cell::new(true), } @@ -56,6 +62,10 @@ impl ImageBitmap { *self.bitmap_data.borrow_mut() = Some(data); } + pub(crate) fn origin_is_clean(&self) -> bool { + self.origin_clean.get() + } + pub(crate) fn set_origin_clean(&self, origin_is_clean: bool) { self.origin_clean.set(origin_is_clean); } @@ -67,6 +77,118 @@ impl ImageBitmap { } } +impl Serializable for ImageBitmap { + type Index = ImageBitmapIndex; + type Data = SerializableImageBitmap; + + /// <https://html.spec.whatwg.org/multipage/#the-imagebitmap-interface:serialization-steps> + fn serialize(&self) -> Result<(ImageBitmapId, Self::Data), ()> { + // Step 1. If value's origin-clean flag is not set, then throw a "DataCloneError" DOMException. + if !self.origin_is_clean() { + return Err(()); + } + + // If value has a [[Detached]] internal slot whose value is true, + // then throw a "DataCloneError" DOMException. + if self.is_detached() { + return Err(()); + } + + // Step 2. Set serialized.[[BitmapData]] to a copy of value's bitmap data. + let serialized = SerializableImageBitmap { + width: self.width, + height: self.height, + bitmap_data: self.bitmap_data.borrow().clone().unwrap(), + }; + + Ok((ImageBitmapId::new(), serialized)) + } + + /// <https://html.spec.whatwg.org/multipage/#the-imagebitmap-interface:deserialization-steps> + fn deserialize( + owner: &GlobalScope, + serialized: Self::Data, + can_gc: CanGc, + ) -> Result<DomRoot<Self>, ()> { + let image_bitmap = + ImageBitmap::new(owner, serialized.width, serialized.height, can_gc).unwrap(); + + // Step 1. Set value's bitmap data to serialized.[[BitmapData]]. + image_bitmap.set_bitmap_data(serialized.bitmap_data); + + Ok(image_bitmap) + } + + fn serialized_storage<'a>( + reader: StructuredData<'a, '_>, + ) -> &'a mut Option<HashMap<ImageBitmapId, Self::Data>> { + match reader { + StructuredData::Reader(r) => &mut r.image_bitmaps, + StructuredData::Writer(w) => &mut w.image_bitmaps, + } + } +} + +impl Transferable for ImageBitmap { + type Index = ImageBitmapIndex; + type Data = SerializableImageBitmap; + + fn can_transfer(&self) -> bool { + if !self.origin_is_clean() || self.is_detached() { + return false; + } + true + } + + /// <https://html.spec.whatwg.org/multipage/#the-imagebitmap-interface:transfer-steps> + fn transfer(&self) -> Result<(ImageBitmapId, SerializableImageBitmap), ()> { + // Step 1. If value's origin-clean flag is not set, then throw a "DataCloneError" DOMException. + if !self.origin_is_clean() { + return Err(()); + } + + // If value has a [[Detached]] internal slot whose value is true, + // then throw a "DataCloneError" DOMException. + if self.is_detached() { + return Err(()); + } + + // Step 2. Set dataHolder.[[BitmapData]] to value's bitmap data. + // Step 3. Unset value's bitmap data. + let serialized = SerializableImageBitmap { + width: self.width, + height: self.height, + bitmap_data: self.bitmap_data.borrow_mut().take().unwrap(), + }; + + Ok((ImageBitmapId::new(), serialized)) + } + + /// <https://html.spec.whatwg.org/multipage/#the-imagebitmap-interface:transfer-receiving-steps> + fn transfer_receive( + owner: &GlobalScope, + _: ImageBitmapId, + serialized: SerializableImageBitmap, + ) -> Result<DomRoot<Self>, ()> { + let image_bitmap = + ImageBitmap::new(owner, serialized.width, serialized.height, CanGc::note()).unwrap(); + + // Step 1. Set value's bitmap data to serialized.[[BitmapData]]. + image_bitmap.set_bitmap_data(serialized.bitmap_data); + + Ok(image_bitmap) + } + + fn serialized_storage<'a>( + data: StructuredData<'a, '_>, + ) -> &'a mut Option<HashMap<ImageBitmapId, Self::Data>> { + match data { + StructuredData::Reader(r) => &mut r.transferred_image_bitmaps, + StructuredData::Writer(w) => &mut w.transferred_image_bitmaps, + } + } +} + impl ImageBitmapMethods<crate::DomTypeHolder> for ImageBitmap { /// <https://html.spec.whatwg.org/multipage/#dom-imagebitmap-height> fn Height(&self) -> u32 { |