diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/canvas_context.rs | 188 | ||||
-rw-r--r-- | components/script/canvas_state.rs | 13 | ||||
-rw-r--r-- | components/script/dom/canvasrenderingcontext2d.rs | 8 | ||||
-rw-r--r-- | components/script/dom/element.rs | 24 | ||||
-rw-r--r-- | components/script/dom/gpucanvascontext.rs | 3 | ||||
-rw-r--r-- | components/script/dom/htmlcanvaselement.rs | 101 | ||||
-rw-r--r-- | components/script/dom/htmltablecellelement.rs | 35 | ||||
-rw-r--r-- | components/script/dom/htmltablecolelement.rs | 17 | ||||
-rw-r--r-- | components/script/dom/macros.rs | 20 | ||||
-rw-r--r-- | components/script/dom/node.rs | 45 | ||||
-rw-r--r-- | components/script/dom/offscreencanvas.rs | 58 | ||||
-rw-r--r-- | components/script/dom/offscreencanvasrenderingcontext2d.rs | 29 | ||||
-rw-r--r-- | components/script/dom/shadowroot.rs | 9 | ||||
-rw-r--r-- | components/script/dom/webgl2renderingcontext.rs | 4 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 8 | ||||
-rw-r--r-- | components/script/dom/webgpu/gpucanvascontext.rs | 9 | ||||
-rw-r--r-- | components/script/script_module.rs | 5 |
17 files changed, 385 insertions, 191 deletions
diff --git a/components/script/canvas_context.rs b/components/script/canvas_context.rs index d49d31997e1..0a7545e9594 100644 --- a/components/script/canvas_context.rs +++ b/components/script/canvas_context.rs @@ -5,16 +5,23 @@ //! Common interfaces for Canvas Contexts use euclid::default::Size2D; -use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; +use script_bindings::root::Dom; +use script_layout_interface::HTMLCanvasData; use snapshot::Snapshot; +use webrender_api::ImageKey; use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas; use crate::dom::bindings::inheritance::Castable; use crate::dom::htmlcanvaselement::HTMLCanvasElement; use crate::dom::node::{Node, NodeDamage}; +use crate::dom::types::{ + CanvasRenderingContext2D, GPUCanvasContext, OffscreenCanvas, OffscreenCanvasRenderingContext2D, + WebGL2RenderingContext, WebGLRenderingContext, +}; pub(crate) trait LayoutCanvasRenderingContextHelpers { - fn canvas_data_source(self) -> HTMLCanvasDataSource; + /// `None` is rendered as transparent black (cleared canvas) + fn canvas_data_source(self) -> Option<ImageKey>; } pub(crate) trait LayoutHTMLCanvasElementHelpers { @@ -85,3 +92,180 @@ impl CanvasHelpers for HTMLCanvasElementOrOffscreenCanvas { } } } + +/// Non rooted variant of [`crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::RenderingContext`] +#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] +#[derive(Clone, JSTraceable, MallocSizeOf)] +pub(crate) enum RenderingContext { + Placeholder(Dom<OffscreenCanvas>), + Context2d(Dom<CanvasRenderingContext2D>), + WebGL(Dom<WebGLRenderingContext>), + WebGL2(Dom<WebGL2RenderingContext>), + #[cfg(feature = "webgpu")] + WebGPU(Dom<GPUCanvasContext>), +} + +impl CanvasContext for RenderingContext { + type ID = (); + + fn context_id(&self) -> Self::ID {} + + fn canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas { + match self { + RenderingContext::Placeholder(context) => (*context.context().unwrap()).canvas(), + RenderingContext::Context2d(context) => context.canvas(), + RenderingContext::WebGL(context) => context.canvas(), + RenderingContext::WebGL2(context) => context.canvas(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.canvas(), + } + } + + fn resize(&self) { + match self { + RenderingContext::Placeholder(context) => (*context.context().unwrap()).resize(), + RenderingContext::Context2d(context) => context.resize(), + RenderingContext::WebGL(context) => context.resize(), + RenderingContext::WebGL2(context) => context.resize(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.resize(), + } + } + + fn get_image_data(&self) -> Option<Snapshot> { + match self { + RenderingContext::Placeholder(context) => { + (*context.context().unwrap()).get_image_data() + }, + RenderingContext::Context2d(context) => context.get_image_data(), + RenderingContext::WebGL(context) => context.get_image_data(), + RenderingContext::WebGL2(context) => context.get_image_data(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.get_image_data(), + } + } + + fn origin_is_clean(&self) -> bool { + match self { + RenderingContext::Placeholder(context) => { + (*context.context().unwrap()).origin_is_clean() + }, + RenderingContext::Context2d(context) => context.origin_is_clean(), + RenderingContext::WebGL(context) => context.origin_is_clean(), + RenderingContext::WebGL2(context) => context.origin_is_clean(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.origin_is_clean(), + } + } + + fn size(&self) -> Size2D<u64> { + match self { + RenderingContext::Placeholder(context) => (*context.context().unwrap()).size(), + RenderingContext::Context2d(context) => context.size(), + RenderingContext::WebGL(context) => context.size(), + RenderingContext::WebGL2(context) => context.size(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.size(), + } + } + + fn mark_as_dirty(&self) { + match self { + RenderingContext::Placeholder(context) => (*context.context().unwrap()).mark_as_dirty(), + RenderingContext::Context2d(context) => context.mark_as_dirty(), + RenderingContext::WebGL(context) => context.mark_as_dirty(), + RenderingContext::WebGL2(context) => context.mark_as_dirty(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.mark_as_dirty(), + } + } + + fn update_rendering(&self) { + match self { + RenderingContext::Placeholder(context) => { + (*context.context().unwrap()).update_rendering() + }, + RenderingContext::Context2d(context) => context.update_rendering(), + RenderingContext::WebGL(context) => context.update_rendering(), + RenderingContext::WebGL2(context) => context.update_rendering(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.update_rendering(), + } + } + + fn onscreen(&self) -> bool { + match self { + RenderingContext::Placeholder(context) => (*context.context().unwrap()).onscreen(), + RenderingContext::Context2d(context) => context.onscreen(), + RenderingContext::WebGL(context) => context.onscreen(), + RenderingContext::WebGL2(context) => context.onscreen(), + #[cfg(feature = "webgpu")] + RenderingContext::WebGPU(context) => context.onscreen(), + } + } +} + +/// Non rooted variant of [`crate::dom::bindings::codegen::Bindings::OffscreenCanvasBinding::OffscreenRenderingContext`] +#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] +#[derive(Clone, JSTraceable, MallocSizeOf)] +pub(crate) enum OffscreenRenderingContext { + Context2d(Dom<OffscreenCanvasRenderingContext2D>), + //WebGL(Dom<WebGLRenderingContext>), + //WebGL2(Dom<WebGL2RenderingContext>), + //#[cfg(feature = "webgpu")] + //WebGPU(Dom<GPUCanvasContext>), +} + +impl CanvasContext for OffscreenRenderingContext { + type ID = (); + + fn context_id(&self) -> Self::ID {} + + fn canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas { + match self { + OffscreenRenderingContext::Context2d(context) => context.canvas(), + } + } + + fn resize(&self) { + match self { + OffscreenRenderingContext::Context2d(context) => context.resize(), + } + } + + fn get_image_data(&self) -> Option<Snapshot> { + match self { + OffscreenRenderingContext::Context2d(context) => context.get_image_data(), + } + } + + fn origin_is_clean(&self) -> bool { + match self { + OffscreenRenderingContext::Context2d(context) => context.origin_is_clean(), + } + } + + fn size(&self) -> Size2D<u64> { + match self { + OffscreenRenderingContext::Context2d(context) => context.size(), + } + } + + fn mark_as_dirty(&self) { + match self { + OffscreenRenderingContext::Context2d(context) => context.mark_as_dirty(), + } + } + + fn update_rendering(&self) { + match self { + OffscreenRenderingContext::Context2d(context) => context.update_rendering(), + } + } + + fn onscreen(&self) -> bool { + match self { + OffscreenRenderingContext::Context2d(context) => context.onscreen(), + } + } +} diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index e9892818e92..dabe6a5728b 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -36,6 +36,7 @@ use style_traits::{CssWriter, ParsingMode}; use url::Url; use webrender_api::ImageKey; +use crate::canvas_context::{OffscreenRenderingContext, RenderingContext}; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{ CanvasDirection, CanvasFillRule, CanvasImageSource, CanvasLineCap, CanvasLineJoin, @@ -52,10 +53,10 @@ use crate::dom::canvaspattern::CanvasPattern; use crate::dom::dommatrix::DOMMatrix; use crate::dom::element::{Element, cors_setting_for_element}; use crate::dom::globalscope::GlobalScope; -use crate::dom::htmlcanvaselement::{CanvasContext, HTMLCanvasElement}; +use crate::dom::htmlcanvaselement::HTMLCanvasElement; use crate::dom::imagedata::ImageData; use crate::dom::node::{Node, NodeTraits}; -use crate::dom::offscreencanvas::{OffscreenCanvas, OffscreenCanvasContext}; +use crate::dom::offscreencanvas::OffscreenCanvas; use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope; use crate::dom::textmetrics::TextMetrics; use crate::script_runtime::CanGc; @@ -522,7 +523,7 @@ impl CanvasState { if let Some(context) = canvas.context() { match *context { - OffscreenCanvasContext::OffscreenContext2d(ref context) => { + OffscreenRenderingContext::Context2d(ref context) => { context.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther( self.get_canvas_id(), image_size, @@ -577,7 +578,7 @@ impl CanvasState { if let Some(context) = canvas.context() { match *context { - CanvasContext::Context2d(ref context) => { + RenderingContext::Context2d(ref context) => { context.send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther( self.get_canvas_id(), image_size, @@ -586,12 +587,12 @@ impl CanvasState { smoothing_enabled, )); }, - CanvasContext::Placeholder(ref context) => { + RenderingContext::Placeholder(ref context) => { let Some(context) = context.context() else { return Err(Error::InvalidState); }; match *context { - OffscreenCanvasContext::OffscreenContext2d(ref context) => context + OffscreenRenderingContext::Context2d(ref context) => context .send_canvas_2d_msg(Canvas2dMsg::DrawImageInOther( self.get_canvas_id(), image_size, diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 38bd38ad511..046d478e49d 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -7,9 +7,9 @@ use dom_struct::dom_struct; use euclid::default::Size2D; use profile_traits::ipc; use script_bindings::inheritance::Castable; -use script_layout_interface::HTMLCanvasDataSource; use servo_url::ServoUrl; use snapshot::Snapshot; +use webrender_api::ImageKey; use crate::canvas_context::{CanvasContext, CanvasHelpers, LayoutCanvasRenderingContextHelpers}; use crate::canvas_state::CanvasState; @@ -98,13 +98,13 @@ impl CanvasRenderingContext2D { } impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, CanvasRenderingContext2D> { - fn canvas_data_source(self) -> HTMLCanvasDataSource { + fn canvas_data_source(self) -> Option<ImageKey> { let canvas_state = &self.unsafe_get().canvas_state; if canvas_state.is_paintable() { - HTMLCanvasDataSource::Image(canvas_state.image_key()) + Some(canvas_state.image_key()) } else { - HTMLCanvasDataSource::Empty + None } } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 2831fc3d8f0..c040078f707 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -3025,28 +3025,8 @@ impl ElementMethods<crate::DomTypeHolder> for Element { DomRoot::from_ref(self.upcast()) }; - // Step 3. Unsafely set HTML given target, this, and compliantHTML. - // Let newChildren be the result of the HTML fragment parsing algorithm. - let new_children = ServoParser::parse_html_fragment(self, html, true, can_gc); - - let context_document = { - if let Some(template) = self.downcast::<HTMLTemplateElement>() { - template.Content(can_gc).upcast::<Node>().owner_doc() - } else { - self.owner_document() - } - }; - - // Let fragment be a new DocumentFragment whose node document is contextElement's node document. - let frag = DocumentFragment::new(&context_document, can_gc); - - // For each node in newChildren, append node to fragment. - for child in new_children { - frag.upcast::<Node>().AppendChild(&child, can_gc).unwrap(); - } - - // Replace all with fragment within target. - Node::replace_all(Some(frag.upcast()), &target, can_gc); + // Step 3. Unsafely set HTML given target, this, and compliantHTML + Node::unsafely_set_html(&target, self, html, can_gc); } /// <https://html.spec.whatwg.org/multipage/#dom-element-gethtml> diff --git a/components/script/dom/gpucanvascontext.rs b/components/script/dom/gpucanvascontext.rs index 5304d0f5d3b..2bdabf3e0ab 100644 --- a/components/script/dom/gpucanvascontext.rs +++ b/components/script/dom/gpucanvascontext.rs @@ -3,7 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use dom_struct::dom_struct; -use script_layout_interface::HTMLCanvasDataSource; use crate::dom::bindings::codegen::Bindings::GPUCanvasContextBinding::GPUCanvasContextMethods; use crate::dom::bindings::codegen::UnionTypes; @@ -31,7 +30,7 @@ impl GPUCanvasContextMethods<crate::DomTypeHolder> for GPUCanvasContext { } impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, GPUCanvasContext> { - fn canvas_data_source(self) -> HTMLCanvasDataSource { + fn canvas_data_source(self) -> Option<ImageKey> { unimplemented!() } } diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index bb27d28cea8..56e008839ba 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -21,20 +21,19 @@ use image::{ColorType, ImageEncoder}; use ipc_channel::ipc::{self as ipcchan}; use js::error::throw_type_error; use js::rust::{HandleObject, HandleValue}; -use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; +use script_layout_interface::HTMLCanvasData; use servo_media::streams::MediaStreamType; use servo_media::streams::registry::MediaStreamId; use snapshot::Snapshot; use style::attr::AttrValue; -use crate::canvas_context::CanvasContext as _; pub(crate) use crate::canvas_context::*; use crate::conversions::Convert; use crate::dom::attr::Attr; use crate::dom::bindings::callback::ExceptionHandling; use crate::dom::bindings::cell::{DomRefCell, Ref, ref_filter_map}; use crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::{ - BlobCallback, HTMLCanvasElementMethods, RenderingContext, + BlobCallback, HTMLCanvasElementMethods, RenderingContext as RootedRenderingContext, }; use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::MediaStreamMethods; use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes; @@ -104,21 +103,10 @@ impl EncodedImageType { } } -#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] -#[derive(Clone, JSTraceable, MallocSizeOf)] -pub(crate) enum CanvasContext { - Placeholder(Dom<OffscreenCanvas>), - Context2d(Dom<CanvasRenderingContext2D>), - WebGL(Dom<WebGLRenderingContext>), - WebGL2(Dom<WebGL2RenderingContext>), - #[cfg(feature = "webgpu")] - WebGPU(Dom<GPUCanvasContext>), -} - #[dom_struct] pub(crate) struct HTMLCanvasElement { htmlelement: HTMLElement, - context: DomRefCell<Option<CanvasContext>>, + context: DomRefCell<Option<RenderingContext>>, // This id and hashmap are used to keep track of ongoing toBlob() calls. callback_id: Cell<u32>, #[ignore_malloc_size_of = "not implemented for webidl callbacks"] @@ -159,14 +147,7 @@ impl HTMLCanvasElement { fn recreate_contexts_after_resize(&self) { if let Some(ref context) = *self.context.borrow() { - match *context { - CanvasContext::Context2d(ref context) => context.resize(), - CanvasContext::WebGL(ref context) => context.resize(), - CanvasContext::WebGL2(ref context) => context.resize(), - #[cfg(feature = "webgpu")] - CanvasContext::WebGPU(ref context) => context.resize(), - CanvasContext::Placeholder(ref context) => context.resize(self.get_size().cast()), - } + context.resize() } } @@ -176,23 +157,14 @@ impl HTMLCanvasElement { pub(crate) fn origin_is_clean(&self) -> bool { match *self.context.borrow() { - Some(CanvasContext::Context2d(ref context)) => context.origin_is_clean(), + Some(ref context) => context.origin_is_clean(), _ => true, } } pub(crate) fn mark_as_dirty(&self) { if let Some(ref context) = *self.context.borrow() { - match *context { - CanvasContext::Context2d(ref context) => context.mark_as_dirty(), - CanvasContext::WebGL(ref context) => context.mark_as_dirty(), - CanvasContext::WebGL2(ref context) => context.mark_as_dirty(), - #[cfg(feature = "webgpu")] - CanvasContext::WebGPU(ref context) => context.mark_as_dirty(), - CanvasContext::Placeholder(ref _context) => { - // TODO: Should this be marked as dirty? - }, - } + context.mark_as_dirty() } } @@ -222,12 +194,14 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> { fn data(self) -> HTMLCanvasData { let source = unsafe { match self.unsafe_get().context.borrow_for_layout().as_ref() { - Some(CanvasContext::Context2d(context)) => context.to_layout().canvas_data_source(), - Some(CanvasContext::WebGL(context)) => context.to_layout().canvas_data_source(), - Some(CanvasContext::WebGL2(context)) => context.to_layout().canvas_data_source(), + Some(RenderingContext::Context2d(context)) => { + context.to_layout().canvas_data_source() + }, + Some(RenderingContext::WebGL(context)) => context.to_layout().canvas_data_source(), + Some(RenderingContext::WebGL2(context)) => context.to_layout().canvas_data_source(), #[cfg(feature = "webgpu")] - Some(CanvasContext::WebGPU(context)) => context.to_layout().canvas_data_source(), - Some(CanvasContext::Placeholder(_)) | None => HTMLCanvasDataSource::Empty, + Some(RenderingContext::WebGPU(context)) => context.to_layout().canvas_data_source(), + Some(RenderingContext::Placeholder(_)) | None => None, } }; @@ -246,14 +220,14 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> { } impl HTMLCanvasElement { - pub(crate) fn context(&self) -> Option<Ref<CanvasContext>> { + pub(crate) fn context(&self) -> Option<Ref<RenderingContext>> { ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) } fn get_or_init_2d_context(&self, can_gc: CanGc) -> Option<DomRoot<CanvasRenderingContext2D>> { if let Some(ctx) = self.context() { return match *ctx { - CanvasContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)), + RenderingContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)), _ => None, }; } @@ -261,7 +235,7 @@ impl HTMLCanvasElement { let window = self.owner_window(); let size = self.get_size(); let context = CanvasRenderingContext2D::new(window.as_global_scope(), self, size, can_gc); - *self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context))); + *self.context.borrow_mut() = Some(RenderingContext::Context2d(Dom::from_ref(&*context))); Some(context) } @@ -273,7 +247,7 @@ impl HTMLCanvasElement { ) -> Option<DomRoot<WebGLRenderingContext>> { if let Some(ctx) = self.context() { return match *ctx { - CanvasContext::WebGL(ref ctx) => Some(DomRoot::from_ref(ctx)), + RenderingContext::WebGL(ref ctx) => Some(DomRoot::from_ref(ctx)), _ => None, }; } @@ -289,7 +263,7 @@ impl HTMLCanvasElement { attrs, can_gc, )?; - *self.context.borrow_mut() = Some(CanvasContext::WebGL(Dom::from_ref(&*context))); + *self.context.borrow_mut() = Some(RenderingContext::WebGL(Dom::from_ref(&*context))); Some(context) } @@ -305,7 +279,7 @@ impl HTMLCanvasElement { } if let Some(ctx) = self.context() { return match *ctx { - CanvasContext::WebGL2(ref ctx) => Some(DomRoot::from_ref(ctx)), + RenderingContext::WebGL2(ref ctx) => Some(DomRoot::from_ref(ctx)), _ => None, }; } @@ -314,7 +288,7 @@ impl HTMLCanvasElement { let attrs = Self::get_gl_attributes(cx, options)?; let canvas = HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(DomRoot::from_ref(self)); let context = WebGL2RenderingContext::new(&window, &canvas, size, attrs, can_gc)?; - *self.context.borrow_mut() = Some(CanvasContext::WebGL2(Dom::from_ref(&*context))); + *self.context.borrow_mut() = Some(RenderingContext::WebGL2(Dom::from_ref(&*context))); Some(context) } @@ -327,7 +301,7 @@ impl HTMLCanvasElement { fn get_or_init_webgpu_context(&self, can_gc: CanGc) -> Option<DomRoot<GPUCanvasContext>> { if let Some(ctx) = self.context() { return match *ctx { - CanvasContext::WebGPU(ref ctx) => Some(DomRoot::from_ref(ctx)), + RenderingContext::WebGPU(ref ctx) => Some(DomRoot::from_ref(ctx)), _ => None, }; } @@ -341,7 +315,8 @@ impl HTMLCanvasElement { .expect("Failed to get WebGPU channel") .map(|channel| { let context = GPUCanvasContext::new(&global_scope, self, channel, can_gc); - *self.context.borrow_mut() = Some(CanvasContext::WebGPU(Dom::from_ref(&*context))); + *self.context.borrow_mut() = + Some(RenderingContext::WebGPU(Dom::from_ref(&*context))); context }) } @@ -349,8 +324,8 @@ impl HTMLCanvasElement { /// Gets the base WebGLRenderingContext for WebGL or WebGL 2, if exists. pub(crate) fn get_base_webgl_context(&self) -> Option<DomRoot<WebGLRenderingContext>> { match *self.context.borrow() { - Some(CanvasContext::WebGL(ref context)) => Some(DomRoot::from_ref(context)), - Some(CanvasContext::WebGL2(ref context)) => Some(context.base_context()), + Some(RenderingContext::WebGL(ref context)) => Some(DomRoot::from_ref(context)), + Some(RenderingContext::WebGL2(ref context)) => Some(context.base_context()), _ => None, } } @@ -378,12 +353,7 @@ impl HTMLCanvasElement { pub(crate) fn get_image_data(&self) -> Option<Snapshot> { match self.context.borrow().as_ref() { - Some(CanvasContext::Context2d(context)) => context.get_image_data(), - Some(CanvasContext::WebGL(context)) => context.get_image_data(), - Some(CanvasContext::WebGL2(context)) => context.get_image_data(), - #[cfg(feature = "webgpu")] - Some(CanvasContext::WebGPU(context)) => context.get_image_data(), - Some(CanvasContext::Placeholder(context)) => context.get_image_data(), + Some(context) => context.get_image_data(), None => { let size = self.get_size(); if size.width == 0 || size.height == 0 { @@ -466,7 +436,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { // is set to placeholder, the user agent must throw an "InvalidStateError" DOMException and leave the // attribute's value unchanged. fn SetWidth(&self, value: u32, can_gc: CanGc) -> Fallible<()> { - if let Some(CanvasContext::Placeholder(_)) = *self.context.borrow() { + if let Some(RenderingContext::Placeholder(_)) = *self.context.borrow() { return Err(Error::InvalidState); } @@ -485,7 +455,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { // https://html.spec.whatwg.org/multipage/#dom-canvas-height fn SetHeight(&self, value: u32, can_gc: CanGc) -> Fallible<()> { - if let Some(CanvasContext::Placeholder(_)) = *self.context.borrow() { + if let Some(RenderingContext::Placeholder(_)) = *self.context.borrow() { return Err(Error::InvalidState); } @@ -506,26 +476,26 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { id: DOMString, options: HandleValue, can_gc: CanGc, - ) -> Fallible<Option<RenderingContext>> { + ) -> Fallible<Option<RootedRenderingContext>> { // Always throw an InvalidState exception when the canvas is in Placeholder mode (See table in the spec). - if let Some(CanvasContext::Placeholder(_)) = *self.context.borrow() { + if let Some(RenderingContext::Placeholder(_)) = *self.context.borrow() { return Err(Error::InvalidState); } Ok(match &*id { "2d" => self .get_or_init_2d_context(can_gc) - .map(RenderingContext::CanvasRenderingContext2D), + .map(RootedRenderingContext::CanvasRenderingContext2D), "webgl" | "experimental-webgl" => self .get_or_init_webgl_context(cx, options, can_gc) - .map(RenderingContext::WebGLRenderingContext), + .map(RootedRenderingContext::WebGLRenderingContext), "webgl2" | "experimental-webgl2" => self .get_or_init_webgl2_context(cx, options, can_gc) - .map(RenderingContext::WebGL2RenderingContext), + .map(RootedRenderingContext::WebGL2RenderingContext), #[cfg(feature = "webgpu")] "webgpu" => self .get_or_init_webgpu_context(can_gc) - .map(RenderingContext::GPUCanvasContext), + .map(RootedRenderingContext::GPUCanvasContext), _ => None, }) } @@ -672,7 +642,8 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { can_gc, ); // Step 4. Set this canvas element's context mode to placeholder. - *self.context.borrow_mut() = Some(CanvasContext::Placeholder(offscreen_canvas.as_traced())); + *self.context.borrow_mut() = + Some(RenderingContext::Placeholder(offscreen_canvas.as_traced())); // Step 5. Return offscreenCanvas. Ok(offscreen_canvas) diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index 4f312e928c4..8b553923230 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -70,13 +70,17 @@ impl HTMLTableCellElementMethods<crate::DomTypeHolder> for HTMLTableCellElement make_uint_getter!(ColSpan, "colspan", DEFAULT_COLSPAN); // https://html.spec.whatwg.org/multipage/#dom-tdth-colspan - make_uint_setter!(SetColSpan, "colspan", DEFAULT_COLSPAN); + // > The colSpan IDL attribute must reflect the colspan content attribute. It is clamped to + // > the range [1, 1000], and its default value is 1. + make_clamped_uint_setter!(SetColSpan, "colspan", 1, 1000, 1); // https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan make_uint_getter!(RowSpan, "rowspan", DEFAULT_ROWSPAN); // https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan - make_uint_setter!(SetRowSpan, "rowspan", DEFAULT_ROWSPAN); + // > The rowSpan IDL attribute must reflect the rowspan content attribute. It is clamped to + // > the range [0, 65534], and its default value is 1. + make_clamped_uint_setter!(SetRowSpan, "rowspan", 0, 65534, 1); // https://html.spec.whatwg.org/multipage/#dom-tdth-bgcolor make_getter!(BgColor, "bgcolor"); @@ -174,23 +178,26 @@ impl VirtualMethods for HTMLTableCellElement { match *local_name { local_name!("colspan") => { let mut attr = AttrValue::from_u32(value.into(), DEFAULT_COLSPAN); - if let AttrValue::UInt(_, ref mut val) = attr { - if *val == 0 { - *val = 1; - } + if let AttrValue::UInt(_, ref mut value) = attr { + // From <https://html.spec.whatwg.org/multipage/#dom-tdth-colspan>: + // > The colSpan IDL attribute must reflect the colspan content attribute. It is clamped to + // > the range [1, 1000], and its default value is 1. + *value = (*value).clamp(1, 1000); } attr }, local_name!("rowspan") => { let mut attr = AttrValue::from_u32(value.into(), DEFAULT_ROWSPAN); - if let AttrValue::UInt(_, ref mut val) = attr { - if *val == 0 { - let node = self.upcast::<Node>(); - let doc = node.owner_doc(); - // rowspan = 0 is not supported in quirks mode - if doc.quirks_mode() != QuirksMode::NoQuirks { - *val = 1; - } + if let AttrValue::UInt(_, ref mut value) = attr { + // From <https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan>: + // > The rowSpan IDL attribute must reflect the rowspan content attribute. It is clamped to + // > the range [0, 65534], and its default value is 1. + // Note that rowspan = 0 is not supported in quirks mode. + let document = self.upcast::<Node>().owner_doc(); + if document.quirks_mode() != QuirksMode::NoQuirks { + *value = (*value).clamp(1, 65534); + } else { + *value = (*value).clamp(0, 65534); } } attr diff --git a/components/script/dom/htmltablecolelement.rs b/components/script/dom/htmltablecolelement.rs index c7ad4afd944..9e8eecf1147 100644 --- a/components/script/dom/htmltablecolelement.rs +++ b/components/script/dom/htmltablecolelement.rs @@ -20,8 +20,6 @@ use crate::dom::node::Node; use crate::dom::virtualmethods::VirtualMethods; use crate::script_runtime::CanGc; -const DEFAULT_SPAN: u32 = 1; - #[dom_struct] pub(crate) struct HTMLTableColElement { htmlelement: HTMLElement, @@ -62,9 +60,11 @@ impl HTMLTableColElement { impl HTMLTableColElementMethods<crate::DomTypeHolder> for HTMLTableColElement { // <https://html.spec.whatwg.org/multipage/#attr-col-span> - make_uint_getter!(Span, "span", DEFAULT_SPAN); + make_uint_getter!(Span, "span", 1); // <https://html.spec.whatwg.org/multipage/#attr-col-span> - make_uint_setter!(SetSpan, "span", DEFAULT_SPAN); + // > The span IDL attribute must reflect the content attribute of the same name. It is clamped + // > to the range [1, 1000], and its default value is 1. + make_clamped_uint_setter!(SetSpan, "span", 1, 1000, 1); } pub(crate) trait HTMLTableColElementLayoutHelpers<'dom> { @@ -96,11 +96,12 @@ impl VirtualMethods for HTMLTableColElement { fn parse_plain_attribute(&self, local_name: &LocalName, value: DOMString) -> AttrValue { match *local_name { local_name!("span") => { - let mut attr = AttrValue::from_u32(value.into(), DEFAULT_SPAN); + let mut attr = AttrValue::from_u32(value.into(), 1); if let AttrValue::UInt(_, ref mut val) = attr { - if *val == 0 { - *val = 1; - } + // From <https://html.spec.whatwg.org/multipage/#attr-col-span>: + // > The span IDL attribute must reflect the content attribute of the same name. + // > It is clamped to the range [1, 1000], and its default value is 1. + *val = (*val).clamp(1, 1000); } attr }, diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index c2f5ba37c21..997341984c6 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -318,6 +318,26 @@ macro_rules! make_uint_setter( ); #[macro_export] +macro_rules! make_clamped_uint_setter( + ($attr:ident, $htmlname:tt, $min:expr, $max:expr, $default:expr) => ( + fn $attr(&self, value: u32) { + use $crate::dom::bindings::inheritance::Castable; + use $crate::dom::element::Element; + use $crate::dom::values::UNSIGNED_LONG_MAX; + use $crate::script_runtime::CanGc; + let value = if value > UNSIGNED_LONG_MAX { + $default + } else { + value.clamp($min, $max) + }; + + let element = self.upcast::<Element>(); + element.set_uint_attribute(&html5ever::local_name!($htmlname), value, CanGc::note()) + } + ); +); + +#[macro_export] macro_rules! make_limited_uint_setter( ($attr:ident, $htmlname:tt, $default:expr) => ( fn $attr(&self, value: u32) -> $crate::dom::bindings::error::ErrorResult { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 1117eff6d3c..e9d36a01426 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -110,7 +110,7 @@ use crate::dom::pointerevent::{PointerEvent, PointerId}; use crate::dom::processinginstruction::ProcessingInstruction; use crate::dom::range::WeakRangeVec; use crate::dom::raredata::NodeRareData; -use crate::dom::servoparser::serialize_html_fragment; +use crate::dom::servoparser::{ServoParser, serialize_html_fragment}; use crate::dom::shadowroot::{IsUserAgentWidget, LayoutShadowRootHelpers, ShadowRoot}; use crate::dom::stylesheetlist::StyleSheetListOwner; use crate::dom::svgsvgelement::{LayoutSVGSVGElementHelpers, SVGSVGElement}; @@ -316,6 +316,34 @@ impl Node { } } + /// Implements the "unsafely set HTML" algorithm as specified in: + /// <https://html.spec.whatwg.org/multipage/#concept-unsafely-set-html> + pub fn unsafely_set_html( + target: &Node, + context_element: &Element, + html: DOMString, + can_gc: CanGc, + ) { + // Step 1. Let newChildren be the result of the HTML fragment parsing algorithm. + let new_children = ServoParser::parse_html_fragment(context_element, html, true, can_gc); + + // Step 2. Let fragment be a new DocumentFragment whose node document is contextElement's node document. + + let context_document = context_element.owner_document(); + let fragment = DocumentFragment::new(&context_document, can_gc); + + // Step 3. For each node in newChildren, append node to fragment. + for child in new_children { + fragment + .upcast::<Node>() + .AppendChild(&child, can_gc) + .unwrap(); + } + + // Step 4. Replace all with fragment within target. + Node::replace_all(Some(fragment.upcast()), target, can_gc); + } + pub(crate) fn clean_up_style_and_layout_data(&self) { self.owner_doc().cancel_animations_for_node(self); self.style_data.borrow_mut().take(); @@ -1283,6 +1311,21 @@ impl Node { is_shadow_host, shadow_root_mode, display, + doctype_name: self + .downcast::<DocumentType>() + .map(DocumentType::name) + .cloned() + .map(String::from), + doctype_public_identifier: self + .downcast::<DocumentType>() + .map(DocumentType::public_id) + .cloned() + .map(String::from), + doctype_system_identifier: self + .downcast::<DocumentType>() + .map(DocumentType::system_id) + .cloned() + .map(String::from), } } diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs index aabe5955e12..9947d35f4e0 100644 --- a/components/script/dom/offscreencanvas.rs +++ b/components/script/dom/offscreencanvas.rs @@ -9,9 +9,10 @@ use euclid::default::Size2D; use js::rust::{HandleObject, HandleValue}; use snapshot::Snapshot; +use crate::canvas_context::{CanvasContext, OffscreenRenderingContext}; use crate::dom::bindings::cell::{DomRefCell, Ref, ref_filter_map}; use crate::dom::bindings::codegen::Bindings::OffscreenCanvasBinding::{ - OffscreenCanvasMethods, OffscreenRenderingContext, + OffscreenCanvasMethods, OffscreenRenderingContext as RootedOffscreenRenderingContext, }; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto}; @@ -23,20 +24,12 @@ use crate::dom::htmlcanvaselement::HTMLCanvasElement; use crate::dom::offscreencanvasrenderingcontext2d::OffscreenCanvasRenderingContext2D; use crate::script_runtime::{CanGc, JSContext}; -#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] -#[derive(Clone, JSTraceable, MallocSizeOf)] -pub(crate) enum OffscreenCanvasContext { - OffscreenContext2d(Dom<OffscreenCanvasRenderingContext2D>), - //WebGL(Dom<WebGLRenderingContext>), - //WebGL2(Dom<WebGL2RenderingContext>), -} - #[dom_struct] pub(crate) struct OffscreenCanvas { eventtarget: EventTarget, width: Cell<u64>, height: Cell<u64>, - context: DomRefCell<Option<OffscreenCanvasContext>>, + context: DomRefCell<Option<OffscreenRenderingContext>>, placeholder: Option<Dom<HTMLCanvasElement>>, } @@ -77,20 +70,18 @@ impl OffscreenCanvas { pub(crate) fn origin_is_clean(&self) -> bool { match *self.context.borrow() { - Some(OffscreenCanvasContext::OffscreenContext2d(ref context)) => { - context.origin_is_clean() - }, + Some(ref context) => context.origin_is_clean(), _ => true, } } - pub(crate) fn context(&self) -> Option<Ref<OffscreenCanvasContext>> { + pub(crate) fn context(&self) -> Option<Ref<OffscreenRenderingContext>> { ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) } pub(crate) fn get_image_data(&self) -> Option<Snapshot> { match self.context.borrow().as_ref() { - Some(OffscreenCanvasContext::OffscreenContext2d(context)) => context.get_image_data(), + Some(context) => context.get_image_data(), None => { let size = self.get_size(); if size.width == 0 || size.height == 0 { @@ -108,13 +99,13 @@ impl OffscreenCanvas { ) -> Option<DomRoot<OffscreenCanvasRenderingContext2D>> { if let Some(ctx) = self.context() { return match *ctx { - OffscreenCanvasContext::OffscreenContext2d(ref ctx) => Some(DomRoot::from_ref(ctx)), + OffscreenRenderingContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)), }; } let context = OffscreenCanvasRenderingContext2D::new(&self.global(), self, can_gc); - *self.context.borrow_mut() = Some(OffscreenCanvasContext::OffscreenContext2d( - Dom::from_ref(&*context), - )); + *self.context.borrow_mut() = Some(OffscreenRenderingContext::Context2d(Dom::from_ref( + &*context, + ))); Some(context) } @@ -125,19 +116,6 @@ impl OffscreenCanvas { pub(crate) fn placeholder(&self) -> Option<&HTMLCanvasElement> { self.placeholder.as_deref() } - - pub(crate) fn resize(&self, size: Size2D<u64>) { - self.width.set(size.width); - self.height.set(size.height); - - if let Some(canvas_context) = self.context() { - match &*canvas_context { - OffscreenCanvasContext::OffscreenContext2d(rendering_context) => { - rendering_context.set_canvas_bitmap_dimensions(self.get_size()); - }, - } - } - } } impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas { @@ -160,11 +138,11 @@ impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas { id: DOMString, _options: HandleValue, can_gc: CanGc, - ) -> Fallible<Option<OffscreenRenderingContext>> { + ) -> Fallible<Option<RootedOffscreenRenderingContext>> { match &*id { "2d" => Ok(self .get_or_init_2d_context(can_gc) - .map(OffscreenRenderingContext::OffscreenCanvasRenderingContext2D)), + .map(RootedOffscreenRenderingContext::OffscreenCanvasRenderingContext2D)), /*"webgl" | "experimental-webgl" => self .get_or_init_webgl_context(cx, options) .map(OffscreenRenderingContext::WebGLRenderingContext), @@ -187,11 +165,7 @@ impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas { self.width.set(value); if let Some(canvas_context) = self.context() { - match &*canvas_context { - OffscreenCanvasContext::OffscreenContext2d(rendering_context) => { - rendering_context.set_canvas_bitmap_dimensions(self.get_size()); - }, - } + canvas_context.resize(); } if let Some(canvas) = &self.placeholder { @@ -209,11 +183,7 @@ impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas { self.height.set(value); if let Some(canvas_context) = self.context() { - match &*canvas_context { - OffscreenCanvasContext::OffscreenContext2d(rendering_context) => { - rendering_context.set_canvas_bitmap_dimensions(self.get_size()); - }, - } + canvas_context.resize(); } if let Some(canvas) = &self.placeholder { diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs index b2d0f3201ca..d7ca0e9dc4d 100644 --- a/components/script/dom/offscreencanvasrenderingcontext2d.rs +++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs @@ -3,11 +3,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::GenericBindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2D_Binding::CanvasRenderingContext2DMethods; -use crate::canvas_context::CanvasContext as _; +use crate::canvas_context::CanvasContext; use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas; use canvas_traits::canvas::Canvas2dMsg; use dom_struct::dom_struct; -use euclid::default::Size2D; use snapshot::Snapshot; use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{ @@ -64,21 +63,33 @@ impl OffscreenCanvasRenderingContext2D { reflect_dom_object(boxed, global, can_gc) } - pub(crate) fn set_canvas_bitmap_dimensions(&self, size: Size2D<u64>) { - self.context.set_canvas_bitmap_dimensions(size.cast()); - } - pub(crate) fn send_canvas_2d_msg(&self, msg: Canvas2dMsg) { self.context.send_canvas_2d_msg(msg) } +} - pub(crate) fn origin_is_clean(&self) -> bool { - self.context.origin_is_clean() +impl CanvasContext for OffscreenCanvasRenderingContext2D { + type ID = <CanvasRenderingContext2D as CanvasContext>::ID; + + fn context_id(&self) -> Self::ID { + self.context.context_id() + } + + fn canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas { + self.context.canvas() + } + + fn resize(&self) { + self.context.resize() } - pub(crate) fn get_image_data(&self) -> Option<Snapshot> { + fn get_image_data(&self) -> Option<Snapshot> { self.context.get_image_data() } + + fn origin_is_clean(&self) -> bool { + self.context.origin_is_clean() + } } impl OffscreenCanvasRenderingContext2DMethods<crate::DomTypeHolder> diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 72b074ed6f4..14d9c24b10e 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -453,6 +453,15 @@ impl ShadowRootMethods<crate::DomTypeHolder> for ShadowRoot { self.slot_assignment_mode } + /// <https://html.spec.whatwg.org/multipage/#dom-shadowroot-sethtmlunsafe> + fn SetHTMLUnsafe(&self, html: DOMString, can_gc: CanGc) { + // Step 2. Unsafely set HTMl given this, this's shadow host, and complaintHTML + let target = self.upcast::<Node>(); + let context_element = self.Host(); + + Node::unsafely_set_html(target, &context_element, html, can_gc); + } + // https://dom.spec.whatwg.org/#dom-shadowroot-onslotchange event_handler!(onslotchange, GetOnslotchange, SetOnslotchange); } diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 416454d8719..5e538b53b5f 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -22,10 +22,10 @@ use js::jsval::{BooleanValue, DoubleValue, Int32Value, NullValue, ObjectValue, U use js::rust::{CustomAutoRooterGuard, HandleObject, MutableHandleValue}; use js::typedarray::{ArrayBufferView, CreateWith, Float32, Int32Array, Uint32, Uint32Array}; use script_bindings::interfaces::WebGL2RenderingContextHelpers; -use script_layout_interface::HTMLCanvasDataSource; use servo_config::pref; use snapshot::Snapshot; use url::Host; +use webrender_api::ImageKey; use crate::canvas_context::CanvasContext; use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::{ @@ -4702,7 +4702,7 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, WebGL2RenderingContext> { #[allow(unsafe_code)] - fn canvas_data_source(self) -> HTMLCanvasDataSource { + fn canvas_data_source(self) -> Option<ImageKey> { let this = self.unsafe_get(); unsafe { (*this.base.to_layout().unsafe_get()).layout_handle() } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 9996a3cf504..98170f9655b 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -31,7 +31,6 @@ use js::typedarray::{ }; use net_traits::image_cache::ImageResponse; use pixels::{self, PixelFormat}; -use script_layout_interface::HTMLCanvasDataSource; use serde::{Deserialize, Serialize}; use servo_config::pref; use snapshot::Snapshot; @@ -875,9 +874,8 @@ impl WebGLRenderingContext { receiver.recv().unwrap() } - pub(crate) fn layout_handle(&self) -> HTMLCanvasDataSource { - let image_key = self.webrender_image; - HTMLCanvasDataSource::WebGL(image_key) + pub(crate) fn layout_handle(&self) -> Option<ImageKey> { + Some(self.webrender_image) } // https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/ @@ -4829,7 +4827,7 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex } impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, WebGLRenderingContext> { - fn canvas_data_source(self) -> HTMLCanvasDataSource { + fn canvas_data_source(self) -> Option<ImageKey> { (*self.unsafe_get()).layout_handle() } } diff --git a/components/script/dom/webgpu/gpucanvascontext.rs b/components/script/dom/webgpu/gpucanvascontext.rs index c81f96f651f..359b1b14003 100644 --- a/components/script/dom/webgpu/gpucanvascontext.rs +++ b/components/script/dom/webgpu/gpucanvascontext.rs @@ -8,7 +8,6 @@ use std::cell::RefCell; use arrayvec::ArrayVec; use dom_struct::dom_struct; use ipc_channel::ipc::{self}; -use script_layout_interface::HTMLCanvasDataSource; use snapshot::Snapshot; use webgpu_traits::{ ContextConfiguration, PRESENTATION_BUFFER_COUNT, WebGPU, WebGPUContextId, WebGPURequest, @@ -227,11 +226,11 @@ impl GPUCanvasContext { // Internal helper methods impl GPUCanvasContext { - fn layout_handle(&self) -> HTMLCanvasDataSource { + fn layout_handle(&self) -> Option<ImageKey> { if self.drawing_buffer.borrow().cleared { - HTMLCanvasDataSource::Empty + None } else { - HTMLCanvasDataSource::WebGPU(self.webrender_image) + Some(self.webrender_image) } } @@ -301,7 +300,7 @@ impl CanvasContext for GPUCanvasContext { } impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, GPUCanvasContext> { - fn canvas_data_source(self) -> HTMLCanvasDataSource { + fn canvas_data_source(self) -> Option<ImageKey> { (*self.unsafe_get()).layout_handle() } } diff --git a/components/script/script_module.rs b/components/script/script_module.rs index c7697adeea6..0aa35a2eda8 100644 --- a/components/script/script_module.rs +++ b/components/script/script_module.rs @@ -1369,7 +1369,7 @@ pub(crate) unsafe extern "C" fn host_import_module_dynamically( true } -#[derive(Clone, JSTraceable, MallocSizeOf)] +#[derive(Clone, Debug, JSTraceable, MallocSizeOf)] /// <https://html.spec.whatwg.org/multipage/#script-fetch-options> pub(crate) struct ScriptFetchOptions { #[no_trace] @@ -1763,7 +1763,8 @@ fn fetch_single_module_script( .mode(mode) .insecure_requests_policy(global.insecure_requests_policy()) .has_trustworthy_ancestor_origin(global.has_trustworthy_ancestor_origin()) - .policy_container(global.policy_container().to_owned()); + .policy_container(global.policy_container().to_owned()) + .cryptographic_nonce_metadata(options.cryptographic_nonce.clone()); let context = Arc::new(Mutex::new(ModuleContext { owner, |