Files
ladybird/Libraries/LibWeb/NotificationsAPI/Notification.h
Shannon Booth 5adfd1c43a LibWeb/Bindings: Generate struct definitions from IDL dictionaries
Previously we were inconsistent by generating code for enum definitions
but not generating code for dictionaries. With future changes to the
IDL generator to expose helpers to convert to and from IDL values
this produced circular depdendencies. To solve this problem, also
generate the dictionary definitions in bindings headers.
2026-05-09 10:49:49 +02:00

123 lines
4.9 KiB
C++

/*
* Copyright (c) 2025, Niccolo Antonelli-Dziri <niccolo.antonelli-dziri@protonmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/Vector.h>
#include <LibJS/Runtime/Realm.h>
#include <LibJS/Runtime/Value.h>
#include <LibWeb/Bindings/Notification.h>
#include <LibWeb/DOM/EventTarget.h>
#include <LibWeb/HTML/StructuredSerialize.h>
#include <LibWeb/HighResolutionTime/EpochTimeStamp.h>
namespace Web::NotificationsAPI {
struct NotificationAction {
String action;
String title;
Optional<String> navigate;
Optional<String> icon;
};
// https://notifications.spec.whatwg.org/#concept-notification
// This is the notification described as "notification" in the spec. Do not confuse it with "notification" as in the IDL which is just the JS wrapper.
// "A notification is an abstract representation of something that happened, such as the delivery of a message."
struct ConceptNotification {
// FIXME: A notification has an associated service worker registration (null or a service worker registration). It is initially null.
String title;
Bindings::NotificationDirection direction;
String language;
String body;
Optional<URL::URL> navigation_url;
String tag;
HTML::SerializationRecord data;
HighResolutionTime::EpochTimeStamp timestamp;
URL::Origin origin = URL::Origin({}); // FIXME: Is this a hack ? There is no default constructor to URL::Origin and the value for `origin` is set in `create-a-notification-with-a-settings-object`
bool renotify_preference;
Optional<bool> silent_preference;
bool require_interaction_preference;
Optional<URL::URL> image_url;
Optional<URL::URL> icon_url;
Optional<URL::URL> badge_url;
// FIXME: add the resources from m_image_url, m_icon_url and m_badge_url
// FIXME: A notification has an associated vibration pattern (a list). It is initially « ».
// https://notifications.spec.whatwg.org/#action
struct Action {
String name;
String title;
Optional<URL::URL> navigation_url;
Optional<URL::URL> icon_url;
// FIXME: icon resource
};
Vector<Action> actions;
};
// https://notifications.spec.whatwg.org/#notifications
class WEB_API Notification final : public DOM::EventTarget {
WEB_PLATFORM_OBJECT(Notification, DOM::EventTarget);
GC_DECLARE_ALLOCATOR(Notification);
public:
[[nodiscard]] static WebIDL::ExceptionOr<GC::Ref<Notification>> construct_impl(
JS::Realm& realm,
String const& title,
Bindings::NotificationOptions const& options);
// https://notifications.spec.whatwg.org/#create-a-notification-with-a-settings-object
static WebIDL::ExceptionOr<ConceptNotification> create_a_notification_with_a_settings_object(
JS::Realm& realm,
String const& title,
Bindings::NotificationOptions const& options,
GC::Ref<HTML::EnvironmentSettingsObject> settings);
// https://notifications.spec.whatwg.org/#create-a-notification
static WebIDL::ExceptionOr<ConceptNotification> create_a_notification(
JS::Realm& realm,
String const& title,
Bindings::NotificationOptions const& options,
URL::Origin origin,
URL::URL base_url,
HighResolutionTime::EpochTimeStamp fallback_timestamp);
static unsigned long max_actions(JS::VM&)
{
// FIXME: Change the number of max_actions supported when actions will actually be supported
// It seems like Chrome is 2, Firefox is undefined, Safari is undefined
return 0;
}
String const& title() const { return m_notification.title; }
Bindings::NotificationDirection dir() const { return m_notification.direction; }
String const& lang() const { return m_notification.language; }
String const& body() const { return m_notification.body; }
String navigate() const { return m_notification.navigation_url.has_value() ? m_notification.navigation_url->serialize() : ""_string; }
String const& tag() const { return m_notification.tag; }
String image() const { return m_notification.image_url.has_value() ? m_notification.image_url->serialize() : ""_string; }
String icon() const { return m_notification.icon_url.has_value() ? m_notification.icon_url->serialize() : ""_string; }
String badge() const { return m_notification.badge_url.has_value() ? m_notification.badge_url->serialize() : ""_string; }
HighResolutionTime::EpochTimeStamp timestamp() const { return m_notification.timestamp; }
bool renotify() const { return m_notification.renotify_preference; }
Optional<bool> silent() const { return m_notification.silent_preference; }
bool require_interaction() const { return m_notification.require_interaction_preference; }
Vector<NotificationAction> actions() const;
JS::Value data() const;
private:
Notification(JS::Realm&);
virtual void initialize(JS::Realm&) override;
ConceptNotification m_notification;
};
}