diff options
author | CYBAI <cyb.ai.815@gmail.com> | 2018-11-04 14:35:17 +0800 |
---|---|---|
committer | CYBAI <cyb.ai.815@gmail.com> | 2018-11-13 22:29:45 +0800 |
commit | 23a4d646ce779b0e13ea0441bfad081fcaf97928 (patch) | |
tree | c7cb195a3232d68207d62e1b92d34a829c29f7b2 /components/script/script_runtime.rs | |
parent | b1a2b6b5bfe72440059834c67dc28ad422b89a82 (diff) | |
download | servo-23a4d646ce779b0e13ea0441bfad081fcaf97928.tar.gz servo-23a4d646ce779b0e13ea0441bfad081fcaf97928.zip |
Introduce rejectionhandled event
Diffstat (limited to 'components/script/script_runtime.rs')
-rw-r--r-- | components/script/script_runtime.rs | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index f0cdd8ccad0..8cda22d6288 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -41,6 +41,7 @@ use js::jsapi::{SetBuildIdOp, SetEnqueuePromiseJobCallback, SetPromiseRejectionT use js::panic::wrap_panic; use js::rust::wrappers::{GetPromiseIsHandled, GetPromiseResult}; use js::rust::Handle; +use js::rust::IntoHandle; use js::rust::Runtime as RustRuntime; use malloc_size_of::MallocSizeOfOps; use msg::constellation_msg::PipelineId; @@ -152,7 +153,7 @@ unsafe extern "C" fn enqueue_job( ) } -#[allow(unsafe_code)] +#[allow(unsafe_code, unrooted_must_root)] /// https://html.spec.whatwg.org/multipage/#the-hostpromiserejectiontracker-implementation unsafe extern "C" fn promise_rejection_tracker( cx: *mut JSContext, @@ -190,14 +191,38 @@ unsafe extern "C" fn promise_rejection_tracker( .borrow() .contains(&Heap::boxed(promise.get())) { - global.add_consumed_rejection(promise); return; } // Step 5-3. global.remove_consumed_rejection(promise); - // TODO: Step 5-4 - Queue a task to fire `rejectionhandled` event + let target = Trusted::new(global.upcast::<EventTarget>()); + let promise = Promise::new_with_js_promise(Handle::from_raw(promise), cx); + let trusted_promise = TrustedPromise::new(promise.clone()); + + // Step 5-4. + global.dom_manipulation_task_source().queue( + task!(rejection_handled_event: move || { + let target = target.root(); + let cx = target.global().get_cx(); + let root_promise = trusted_promise.root(); + + rooted!(in(cx) let reason = GetPromiseResult(root_promise.reflector().get_jsobject())); + + let event = PromiseRejectionEvent::new( + &target.global(), + atom!("rejectionhandled"), + EventBubbles::DoesNotBubble, + EventCancelable::Cancelable, + root_promise, + reason.handle() + ); + + event.upcast::<Event>().fire(&target); + }), + global.upcast(), + ).unwrap(); }, }; }), @@ -254,7 +279,7 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) { atom!("unhandledrejection"), EventBubbles::DoesNotBubble, EventCancelable::Cancelable, - promise, + promise.clone(), reason.handle() ); @@ -265,19 +290,15 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) { // TODO: The promise rejection is not handled; we need to add it back to the list. } - // TODO: Step 4-4 - If [[PromiseIsHandled]] is false, add promise to consumed_rejections + // Step 4-4. + if !promise_is_handled { + target.global().add_consumed_rejection(promise.reflector().get_jsobject().into_handle()); + } } }), global.upcast(), ).unwrap(); } - - if global.get_consumed_rejections().borrow().len() > 0 { - // FIXME(cybai): Implement `rejectionhandled` event instead of clearing the whole - // consumed rejections - // https://html.spec.whatwg.org/multipage/#the-hostpromiserejectiontracker-implementation - global.get_consumed_rejections().borrow_mut().clear(); - } } } |