aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/notification.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/notification.rs')
-rw-r--r--components/script/dom/notification.rs98
1 files changed, 80 insertions, 18 deletions
diff --git a/components/script/dom/notification.rs b/components/script/dom/notification.rs
index 197a79e9bfb..0cdf0a74d69 100644
--- a/components/script/dom/notification.rs
+++ b/components/script/dom/notification.rs
@@ -9,6 +9,10 @@ use std::time::{SystemTime, UNIX_EPOCH};
use content_security_policy::Destination;
use dom_struct::dom_struct;
+use embedder_traits::{
+ EmbedderMsg, Notification as EmbedderNotification,
+ NotificationAction as EmbedderNotificationAction,
+};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use js::jsapi::Heap;
@@ -253,23 +257,39 @@ impl Notification {
/// <https://notifications.spec.whatwg.org/#notification-show-steps>
fn show(&self) {
- // TODO: step 3: set shown to false
+ // step 3: set shown to false
+ let shown = false;
+
// TODO: step 4: Let oldNotification be the notification in the list of notifications
// whose tag is not the empty string and is notification’s tag,
// and whose origin is same origin with notification’s origin,
// if any, and null otherwise.
+
// TODO: step 5: If oldNotification is non-null, then:
- // TODO: step 6: If shown is false, then:
- // TODO: step 6.1: Append notification to the list of notifications.
- // TODO: step 6.2: Display notification on the device
- // TODO: Add EmbedderMsg::ShowNotification(...) event
+ // TODO: step 5.1: Handle close events with oldNotification.
+ // TODO: step 5.2: If the notification platform supports replacement, then:
+ // TODO: step 5.2.1: Replace oldNotification with notification, in the list of notifications.
+ // TODO: step 5.2.2: Set shown to true.
+ // TODO: step 5.3: Otherwise, remove oldNotification from the list of notifications.
+
+ // step 6: If shown is false, then:
+ if !shown {
+ // TODO: step 6.1: Append notification to the list of notifications.
+ // step 6.2: Display notification on the device
+ self.global()
+ .send_to_embedder(EmbedderMsg::ShowNotification(
+ self.global().webview_id(),
+ self.to_embedder_notification(),
+ ));
+ }
+
// TODO: step 7: If shown is false or oldNotification is non-null,
// and notification’s renotify preference is true,
// then run the alert steps for notification.
// step 8: If notification is a non-persistent notification,
- // then queue a task to fire an event named show on
- // the Notification object representing notification.
+ // then queue a task to fire an event named show on
+ // the Notification object representing notification.
if self.serviceworker_registration.is_none() {
self.global()
.task_manager()
@@ -277,6 +297,46 @@ impl Notification {
.queue_simple_event(self.upcast(), atom!("show"));
}
}
+
+ /// Create an [`embedder_traits::Notification`].
+ fn to_embedder_notification(&self) -> EmbedderNotification {
+ EmbedderNotification {
+ title: self.title.to_string(),
+ body: self.body.to_string(),
+ tag: self.tag.to_string(),
+ language: self.lang.to_string(),
+ require_interaction: self.require_interaction,
+ silent: self.silent,
+ icon_url: self
+ .icon
+ .as_ref()
+ .and_then(|icon| ServoUrl::parse(icon).ok()),
+ badge_url: self
+ .badge
+ .as_ref()
+ .and_then(|badge| ServoUrl::parse(badge).ok()),
+ image_url: self
+ .image
+ .as_ref()
+ .and_then(|image| ServoUrl::parse(image).ok()),
+ actions: self
+ .actions
+ .iter()
+ .map(|action| EmbedderNotificationAction {
+ name: action.name.to_string(),
+ title: action.title.to_string(),
+ icon_url: action
+ .icon_url
+ .as_ref()
+ .and_then(|icon| ServoUrl::parse(icon).ok()),
+ icon_resource: action.icon_resource.borrow().clone(),
+ })
+ .collect(),
+ icon_resource: self.icon_resource.borrow().clone(),
+ badge_resource: self.badge_resource.borrow().clone(),
+ image_resource: self.image_resource.borrow().clone(),
+ }
+ }
}
impl NotificationMethods<crate::DomTypeHolder> for Notification {
@@ -316,12 +376,12 @@ impl NotificationMethods<crate::DomTypeHolder> for Notification {
.dom_manipulation_task_source()
.queue_simple_event(notification.upcast(), atom!("error"));
// TODO: abort steps
+ } else {
+ // step 5.2: Run the notification show steps for notification
+ // <https://notifications.spec.whatwg.org/#notification-show-steps>
+ // step 1: Run the fetch steps for notification.
+ notification.fetch_resources_and_show_when_ready();
}
- // TODO: step 5.2: Run the notification show steps for notification
- // <https://notifications.spec.whatwg.org/#notification-show-steps>
- // step 1: Run the fetch steps for notification.
- // following steps are processed in show_steps after all resources are fetched
- notification.fetch_resources_and_show_when_ready();
Ok(notification)
}
@@ -478,10 +538,12 @@ impl NotificationMethods<crate::DomTypeHolder> for Notification {
// If notification is a non-persistent notification
// then queue a task to fire an event named close on the Notification object representing notification.
- self.global()
- .task_manager()
- .dom_manipulation_task_source()
- .queue_simple_event(self.upcast(), atom!("close"));
+ if self.serviceworker_registration.is_none() {
+ self.global()
+ .task_manager()
+ .dom_manipulation_task_source()
+ .queue_simple_event(self.upcast(), atom!("close"));
+ }
}
}
@@ -754,7 +816,7 @@ impl Notification {
None,
url.clone(),
Destination::Image,
- None, // TODO: check CORS
+ None, // TODO: check which CORS should be used
None,
global.get_referrer(),
global.insecure_requests_policy(),
@@ -809,7 +871,7 @@ impl Notification {
let cache_result = global.image_cache().get_cached_image_status(
request.url.clone(),
global.origin().immutable().clone(),
- None, // TODO: check CORS
+ None, // TODO: check which CORS should be used
UsePlaceholder::No,
);
match cache_result {