diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 1fc969f163a..76892fbe9e8 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -3009,6 +3009,22 @@ impl GlobalScope { return p; } + // The promise with image bitmap should be fulfilled on the the bitmap task source. + let fullfill_promise_on_bitmap_task_source = + |promise: &Rc, image_bitmap: &ImageBitmap| { + let trusted_promise = TrustedPromise::new(promise.clone()); + let trusted_image_bitmap = Trusted::new(image_bitmap); + + self.task_manager() + .bitmap_task_source() + .queue(task!(resolve_promise: move || { + let promise = trusted_promise.root(); + let image_bitmap = trusted_image_bitmap.root(); + + promise.resolve_native(&image_bitmap, CanGc::note()); + })); + }; + // Step 3. Check the usability of the image argument. If this throws an exception or returns bad, // then return a promise rejected with an "InvalidStateError" DOMException. // Step 6. Switch on image: @@ -3065,7 +3081,9 @@ impl GlobalScope { // of imageBitmap's bitmap to false. image_bitmap.set_origin_clean(image.same_origin(GlobalScope::entry().origin())); - p.resolve_native(&image_bitmap, can_gc); + // Step 6.5. Queue a global task, using the bitmap task source, + // to resolve promise with imageBitmap. + fullfill_promise_on_bitmap_task_source(&p, &image_bitmap); }, ImageBitmapSource::HTMLVideoElement(ref video) => { // @@ -3103,7 +3121,9 @@ impl GlobalScope { // of imageBitmap's bitmap to false. image_bitmap.set_origin_clean(video.origin_is_clean()); - p.resolve_native(&image_bitmap, can_gc); + // Step 6.4. Queue a global task, using the bitmap task source, + // to resolve promise with imageBitmap. + fullfill_promise_on_bitmap_task_source(&p, &image_bitmap); }, ImageBitmapSource::HTMLCanvasElement(ref canvas) => { // @@ -3132,7 +3152,9 @@ impl GlobalScope { // as the origin-clean flag of image's bitmap. image_bitmap.set_origin_clean(canvas.origin_is_clean()); - p.resolve_native(&image_bitmap, can_gc); + // Step 6.3. Queue a global task, using the bitmap task source, + // to resolve promise with imageBitmap. + fullfill_promise_on_bitmap_task_source(&p, &image_bitmap); }, ImageBitmapSource::ImageBitmap(ref bitmap) => { // @@ -3161,7 +3183,9 @@ impl GlobalScope { // as the origin-clean flag of image's bitmap. image_bitmap.set_origin_clean(bitmap.origin_is_clean()); - p.resolve_native(&image_bitmap, can_gc); + // Step 6.3. Queue a global task, using the bitmap task source, + // to resolve promise with imageBitmap. + fullfill_promise_on_bitmap_task_source(&p, &image_bitmap); }, ImageBitmapSource::OffscreenCanvas(ref canvas) => { // @@ -3190,7 +3214,9 @@ impl GlobalScope { // as the origin-clean flag of image's bitmap. image_bitmap.set_origin_clean(canvas.origin_is_clean()); - p.resolve_native(&image_bitmap, can_gc); + // Step 6.3. Queue a global task, using the bitmap task source, + // to resolve promise with imageBitmap. + fullfill_promise_on_bitmap_task_source(&p, &image_bitmap); }, ImageBitmapSource::Blob(_) => { // TODO: implement support of Blob object as ImageBitmapSource @@ -3227,7 +3253,9 @@ impl GlobalScope { let image_bitmap = ImageBitmap::new(self, bitmap_data, can_gc); - p.resolve_native(&image_bitmap, can_gc); + // Step 6.4. Queue a global task, using the bitmap task source, + // to resolve promise with imageBitmap. + fullfill_promise_on_bitmap_task_source(&p, &image_bitmap); }, ImageBitmapSource::CSSStyleValue(_) => { // TODO: CSSStyleValue is not part of ImageBitmapSource diff --git a/components/script/task_manager.rs b/components/script/task_manager.rs index 768d78bcb24..34798bc7f6a 100644 --- a/components/script/task_manager.rs +++ b/components/script/task_manager.rs @@ -132,6 +132,7 @@ impl TaskManager { .cancel_pending_tasks_for_source(task_source_name); } + task_source_functions!(self, bitmap_task_source, Bitmap); task_source_functions!(self, canvas_blob_task_source, Canvas); task_source_functions!(self, clipboard_task_source, Clipboard); task_source_functions!(self, dom_manipulation_task_source, DOMManipulation); diff --git a/components/script/task_source.rs b/components/script/task_source.rs index 2aaa15609f1..031bd9db2de 100644 --- a/components/script/task_source.rs +++ b/components/script/task_source.rs @@ -22,6 +22,8 @@ use crate::task_manager::TaskManager; /// doesn't implement TaskSource. #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, MallocSizeOf, PartialEq, VariantArray)] pub(crate) enum TaskSourceName { + /// + Bitmap, Canvas, Clipboard, DOMManipulation, @@ -48,6 +50,7 @@ pub(crate) enum TaskSourceName { impl From for ScriptThreadEventCategory { fn from(value: TaskSourceName) -> Self { match value { + TaskSourceName::Bitmap => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::Canvas => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::Clipboard => ScriptThreadEventCategory::ScriptEvent, TaskSourceName::DOMManipulation => ScriptThreadEventCategory::ScriptEvent, diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-resolves-in-task.any.js.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-resolves-in-task.any.js.ini index b01db0541f9..d414b0aa93f 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-resolves-in-task.any.js.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-resolves-in-task.any.js.ini @@ -1,16 +1,10 @@ [createImageBitmap-resolves-in-task.any.html] - [createImageBitmap with an HTMLCanvasElement source should resolve async] - expected: FAIL - [createImageBitmap with an HTMLVideoElement source should resolve async] expected: FAIL [createImageBitmap with an HTMLVideoElement from a data URL source should resolve async] expected: FAIL - [createImageBitmap with a bitmap HTMLImageElement source should resolve async] - expected: FAIL - [createImageBitmap with a vector HTMLImageElement source should resolve async] expected: FAIL @@ -32,28 +26,10 @@ [createImageBitmap with a vector SVGImageElement source should resolve async] expected: FAIL - [createImageBitmap with an OffscreenCanvas source should resolve async] - expected: FAIL - - [createImageBitmap with an ImageData source should resolve async] - expected: FAIL - - [createImageBitmap with an ImageBitmap source should resolve async] - expected: FAIL - [createImageBitmap with a Blob source should resolve async] expected: FAIL [createImageBitmap-resolves-in-task.any.worker.html] - [createImageBitmap with an OffscreenCanvas source should resolve async] - expected: FAIL - - [createImageBitmap with an ImageData source should resolve async] - expected: FAIL - - [createImageBitmap with an ImageBitmap source should resolve async] - expected: FAIL - [createImageBitmap with a Blob source should resolve async] expected: FAIL