mirror of
https://github.com/servo/servo.git
synced 2025-07-16 20:03:39 +01:00
htmlimageelement: Reject decode promises on the current request mutation (#37828)
Follow the HTML specification and reject the pending image decode promises on any current request mutation. https://html.spec.whatwg.org/multipage/#updating-the-image-data (step 18) https://html.spec.whatwg.org/multipage/#dom-img-decode (step 3) Fulfill and reject image decode promises by queueing a global tasks on the DOM manipulation task source. Testing: Improvements in the following tests - html/semantics/embedded-content/the-img-element/decode/* Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
parent
45fb0bac82
commit
4cbadde144
5 changed files with 58 additions and 48 deletions
|
@ -97,6 +97,7 @@ pub(crate) fn throw_dom_exception(
|
|||
Error::NotReadable => DOMErrorName::NotReadableError,
|
||||
Error::Operation => DOMErrorName::OperationError,
|
||||
Error::NotAllowed => DOMErrorName::NotAllowedError,
|
||||
Error::Encoding => DOMErrorName::EncodingError,
|
||||
Error::Type(message) => unsafe {
|
||||
assert!(!JS_IsExceptionPending(*cx));
|
||||
throw_type_error(*cx, &message);
|
||||
|
|
|
@ -43,8 +43,6 @@ use style::values::specified::source_size_list::SourceSizeList;
|
|||
use style_traits::ParsingMode;
|
||||
use url::Url;
|
||||
|
||||
use super::domexception::DOMErrorName;
|
||||
use super::types::DOMException;
|
||||
use crate::document_loader::{LoadBlocker, LoadType};
|
||||
use crate::dom::activation::Activatable;
|
||||
use crate::dom::attr::Attr;
|
||||
|
@ -57,7 +55,7 @@ use crate::dom::bindings::codegen::Bindings::NodeBinding::Node_Binding::NodeMeth
|
|||
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::refcounted::Trusted;
|
||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||
use crate::dom::bindings::reflector::DomGlobal;
|
||||
use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
|
||||
use crate::dom::bindings::str::{DOMString, USVString};
|
||||
|
@ -486,7 +484,7 @@ impl HTMLImageElement {
|
|||
LoadBlocker::terminate(&self.current_request.borrow().blocker, can_gc);
|
||||
// Mark the node dirty
|
||||
self.upcast::<Node>().dirty(NodeDamage::Other);
|
||||
self.resolve_image_decode_promises(can_gc);
|
||||
self.resolve_image_decode_promises();
|
||||
}
|
||||
|
||||
/// Step 24 of <https://html.spec.whatwg.org/multipage/#update-the-image-data>
|
||||
|
@ -597,9 +595,9 @@ impl HTMLImageElement {
|
|||
request.metadata = None;
|
||||
|
||||
if matches!(state, State::Broken) {
|
||||
self.reject_image_decode_promises(can_gc);
|
||||
self.reject_image_decode_promises();
|
||||
} else if matches!(state, State::CompletelyAvailable) {
|
||||
self.resolve_image_decode_promises(can_gc);
|
||||
self.resolve_image_decode_promises();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,6 +892,7 @@ impl HTMLImageElement {
|
|||
// Step 17
|
||||
current_request.current_pixel_density = Some(selected_pixel_density);
|
||||
self.init_image_request(&mut current_request, url, src, can_gc);
|
||||
self.reject_image_decode_promises();
|
||||
},
|
||||
(_, _) => {
|
||||
// step 17
|
||||
|
@ -1186,10 +1185,7 @@ impl HTMLImageElement {
|
|||
if !document.is_fully_active() ||
|
||||
matches!(self.current_request.borrow().state, State::Broken)
|
||||
{
|
||||
promise.reject_native(
|
||||
&DOMException::new(&document.global(), DOMErrorName::EncodingError, can_gc),
|
||||
can_gc,
|
||||
);
|
||||
promise.reject_error(Error::Encoding, can_gc);
|
||||
} else if matches!(
|
||||
self.current_request.borrow().state,
|
||||
State::CompletelyAvailable
|
||||
|
@ -1203,22 +1199,59 @@ impl HTMLImageElement {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_image_decode_promises(&self, can_gc: CanGc) {
|
||||
for promise in self.image_decode_promises.borrow().iter() {
|
||||
promise.resolve_native(&(), can_gc);
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-img-decode>
|
||||
fn resolve_image_decode_promises(&self) {
|
||||
if self.image_decode_promises.borrow().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 3. If the decoding process completes successfully, then queue a
|
||||
// global task on the DOM manipulation task source with global to
|
||||
// resolve promise with undefined.
|
||||
let trusted_image_decode_promises: Vec<TrustedPromise> = self
|
||||
.image_decode_promises
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|promise| TrustedPromise::new(promise.clone()))
|
||||
.collect();
|
||||
|
||||
self.image_decode_promises.borrow_mut().clear();
|
||||
|
||||
self.owner_global()
|
||||
.task_manager()
|
||||
.dom_manipulation_task_source()
|
||||
.queue(task!(fulfill_image_decode_promises: move || {
|
||||
for trusted_promise in trusted_image_decode_promises {
|
||||
trusted_promise.root().resolve_native(&(), CanGc::note());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
fn reject_image_decode_promises(&self, can_gc: CanGc) {
|
||||
let document = self.owner_document();
|
||||
for promise in self.image_decode_promises.borrow().iter() {
|
||||
promise.reject_native(
|
||||
&DOMException::new(&document.global(), DOMErrorName::EncodingError, can_gc),
|
||||
can_gc,
|
||||
);
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-img-decode>
|
||||
fn reject_image_decode_promises(&self) {
|
||||
if self.image_decode_promises.borrow().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 3. Queue a global task on the DOM manipulation task source with
|
||||
// global to reject promise with an "EncodingError" DOMException.
|
||||
let trusted_image_decode_promises: Vec<TrustedPromise> = self
|
||||
.image_decode_promises
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|promise| TrustedPromise::new(promise.clone()))
|
||||
.collect();
|
||||
|
||||
self.image_decode_promises.borrow_mut().clear();
|
||||
|
||||
self.owner_global()
|
||||
.task_manager()
|
||||
.dom_manipulation_task_source()
|
||||
.queue(task!(reject_image_decode_promises: move || {
|
||||
for trusted_promise in trusted_image_decode_promises {
|
||||
trusted_promise.root().reject_error(Error::Encoding, CanGc::note());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/// Step 15 for <https://html.spec.whatwg.org/multipage/#img-environment-changes>
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::codegen::PrototypeList::proto_id_to_name;
|
|||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
|
||||
/// DOM exceptions that can be thrown by a native DOM method.
|
||||
/// <https://webidl.spec.whatwg.org/#dfn-error-names-table>
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
pub enum Error {
|
||||
/// IndexSizeError DOMException
|
||||
|
@ -67,6 +68,8 @@ pub enum Error {
|
|||
Operation,
|
||||
/// NotAllowedError DOMException
|
||||
NotAllowed,
|
||||
/// EncodingError DOMException
|
||||
Encoding,
|
||||
|
||||
/// TypeError JavaScript Error
|
||||
Type(String),
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
[image-decode-path-changes.html]
|
||||
[HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes fail decode; following good png decode succeeds.]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes fail decode; following good svg decode succeeds.]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), src/srcset mutation tests. srcset changes fail decode; following good decode succeeds.]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), src/srcset mutation tests. src changes fail decode.]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), src/srcset mutation tests. srcset changes fail decode.]
|
||||
expected: FAIL
|
|
@ -1,15 +1,3 @@
|
|||
[image-decode-with-quick-attach.html]
|
||||
[HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.: src in empty picture not cached]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.: srcset in empty picture]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.: src in picture with source not cached]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.: src in picture with source cached]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.: srcset in picture with source]
|
||||
[HTMLImageElement.prototype.decode(), attach to DOM before promise resolves.: src in empty picture cached]
|
||||
expected: FAIL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue