diff --git a/src/lib.rs b/src/lib.rs index 384aee4f..6e424a3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,7 +93,7 @@ make_dispatch! { #[cfg(target_os = "macos")] CG((), cg::CGImpl), #[cfg(target_arch = "wasm32")] - Web((), web::WebImpl), + Web(web::WebDisplayImpl, web::WebImpl), #[cfg(target_os = "redox")] Orbital((), orbital::OrbitalImpl), } @@ -134,7 +134,7 @@ impl Context { #[cfg(target_os = "macos")] RawDisplayHandle::AppKit(_) => ContextDispatch::CG(()), #[cfg(target_arch = "wasm32")] - RawDisplayHandle::Web(_) => ContextDispatch::Web(()), + RawDisplayHandle::Web(_) => ContextDispatch::Web(web::WebDisplayImpl::new()?), #[cfg(target_os = "redox")] RawDisplayHandle::Orbital(_) => ContextDispatch::Orbital(()), unimplemented_display_handle => { @@ -212,8 +212,8 @@ impl Surface { SurfaceDispatch::CG(unsafe { cg::CGImpl::new(appkit_handle)? }) } #[cfg(target_arch = "wasm32")] - (ContextDispatch::Web(()), RawWindowHandle::Web(web_handle)) => { - SurfaceDispatch::Web(web::WebImpl::new(web_handle)?) + (ContextDispatch::Web(context), RawWindowHandle::Web(web_handle)) => { + SurfaceDispatch::Web(web::WebImpl::new(context, web_handle)?) } #[cfg(target_os = "redox")] (ContextDispatch::Orbital(()), RawWindowHandle::Orbital(orbital_handle)) => { diff --git a/src/web.rs b/src/web.rs index 28667873..f0e9f3d9 100644 --- a/src/web.rs +++ b/src/web.rs @@ -7,14 +7,16 @@ use web_sys::ImageData; use crate::SoftBufferError; -pub struct WebImpl { - canvas: HtmlCanvasElement, - ctx: CanvasRenderingContext2d, +/// Display implementation for the web platform. +/// +/// This just caches the document to prevent having to query it every time. +pub struct WebDisplayImpl { + document: web_sys::Document, } -impl WebImpl { - pub fn new(handle: WebWindowHandle) -> Result { - let canvas: HtmlCanvasElement = web_sys::window() +impl WebDisplayImpl { + pub(super) fn new() -> Result { + let document = web_sys::window() .ok_or_else(|| { SoftBufferError::PlatformError( Some("`window` is not present in this runtime".into()), @@ -27,7 +29,21 @@ impl WebImpl { Some("`document` is not present in this runtime".into()), None, ) - })? + })?; + + Ok(Self { document }) + } +} + +pub struct WebImpl { + canvas: HtmlCanvasElement, + ctx: CanvasRenderingContext2d, +} + +impl WebImpl { + pub fn new(display: &WebDisplayImpl, handle: WebWindowHandle) -> Result { + let canvas: HtmlCanvasElement = display + .document .query_selector(&format!("canvas[data-raw-handle=\"{}\"]", handle.id)) // `querySelector` only throws an error if the selector is invalid. .unwrap()