diff options
Diffstat (limited to 'components/script/dom/blob.rs')
-rw-r--r-- | components/script/dom/blob.rs | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 27aa382c3fc..c5c5c480707 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -7,7 +7,7 @@ use std::ptr; use std::rc::Rc; use base::id::{BlobId, BlobIndex}; -use constellation_traits::BlobImpl; +use constellation_traits::{BlobData, BlobImpl}; use dom_struct::dom_struct; use encoding_rs::UTF_8; use js::jsapi::JSObject; @@ -33,7 +33,7 @@ use crate::dom::readablestream::ReadableStream; use crate::realms::{AlreadyInRealm, InRealm}; use crate::script_runtime::CanGc; -// https://w3c.github.io/FileAPI/#blob +/// <https://w3c.github.io/FileAPI/#dfn-Blob> #[dom_struct] pub(crate) struct Blob { reflector_: Reflector, @@ -198,7 +198,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob { self.get_stream(can_gc) } - // https://w3c.github.io/FileAPI/#slice-method-algo + /// <https://w3c.github.io/FileAPI/#slice-method-algo> fn Slice( &self, start: Option<i64>, @@ -206,11 +206,24 @@ impl BlobMethods<crate::DomTypeHolder> for Blob { content_type: Option<DOMString>, can_gc: CanGc, ) -> DomRoot<Blob> { - let type_string = - normalize_type_string(content_type.unwrap_or(DOMString::from("")).as_ref()); - let rel_pos = RelativePos::from_opts(start, end); - let blob_impl = BlobImpl::new_sliced(rel_pos, self.blob_id, type_string); - Blob::new(&self.global(), blob_impl, can_gc) + let global = self.global(); + let type_string = normalize_type_string(&content_type.unwrap_or_default()); + + // If our parent is already a sliced blob then we reference the data from the grandparent instead, + // to keep the blob ancestry chain short. + let (parent, range) = match *global.get_blob_data(&self.blob_id) { + BlobData::Sliced(grandparent, parent_range) => { + let range = RelativePos { + start: parent_range.start + start.unwrap_or_default(), + end: end.map(|end| end + parent_range.start).or(parent_range.end), + }; + (grandparent, range) + }, + _ => (self.blob_id, RelativePos::from_opts(start, end)), + }; + + let blob_impl = BlobImpl::new_sliced(range, parent, type_string); + Blob::new(&global, blob_impl, can_gc) } // https://w3c.github.io/FileAPI/#text-method-algo |