mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-28 21:26:22 +00:00
LibWeb: Stub WebSerial API
This commit is contained in:
parent
34ec33d71c
commit
1be31c103f
Notes:
github-actions[bot]
2025-08-08 08:24:30 +00:00
Author: https://github.com/EdwinHoksberg
Commit: 1be31c103f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5740
Reviewed-by: https://github.com/gmta ✅
19 changed files with 715 additions and 0 deletions
|
@ -359,6 +359,8 @@ set(SOURCES
|
||||||
Gamepad/Gamepad.cpp
|
Gamepad/Gamepad.cpp
|
||||||
Gamepad/NavigatorGamepad.cpp
|
Gamepad/NavigatorGamepad.cpp
|
||||||
Geolocation/Geolocation.cpp
|
Geolocation/Geolocation.cpp
|
||||||
|
Serial/Serial.cpp
|
||||||
|
Serial/SerialPort.cpp
|
||||||
Geolocation/GeolocationCoordinates.cpp
|
Geolocation/GeolocationCoordinates.cpp
|
||||||
Geolocation/GeolocationPosition.cpp
|
Geolocation/GeolocationPosition.cpp
|
||||||
Geolocation/GeolocationPositionError.cpp
|
Geolocation/GeolocationPositionError.cpp
|
||||||
|
|
|
@ -944,6 +944,20 @@ class Selection;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Web::Serial {
|
||||||
|
|
||||||
|
class Serial;
|
||||||
|
class SerialPort;
|
||||||
|
|
||||||
|
struct SerialPortFilter;
|
||||||
|
struct SerialPortRequestOptions;
|
||||||
|
struct SerialOptions;
|
||||||
|
struct SerialOutputSignals;
|
||||||
|
struct SerialInputSignals;
|
||||||
|
struct SerialPortInfo;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace Web::ServiceWorker {
|
namespace Web::ServiceWorker {
|
||||||
|
|
||||||
class ServiceWorker;
|
class ServiceWorker;
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace Web::HTML::EventNames {
|
||||||
__ENUMERATE_HTML_EVENT(cuechange) \
|
__ENUMERATE_HTML_EVENT(cuechange) \
|
||||||
__ENUMERATE_HTML_EVENT(currententrychange) \
|
__ENUMERATE_HTML_EVENT(currententrychange) \
|
||||||
__ENUMERATE_HTML_EVENT(cut) \
|
__ENUMERATE_HTML_EVENT(cut) \
|
||||||
|
__ENUMERATE_HTML_EVENT(disconnect) \
|
||||||
__ENUMERATE_HTML_EVENT(dispose) \
|
__ENUMERATE_HTML_EVENT(dispose) \
|
||||||
__ENUMERATE_HTML_EVENT(DOMContentLoaded) \
|
__ENUMERATE_HTML_EVENT(DOMContentLoaded) \
|
||||||
__ENUMERATE_HTML_EVENT(drag) \
|
__ENUMERATE_HTML_EVENT(drag) \
|
||||||
|
|
|
@ -69,6 +69,7 @@ void Navigator::visit_edges(Cell::Visitor& visitor)
|
||||||
visitor.visit(m_plugin_array);
|
visitor.visit(m_plugin_array);
|
||||||
visitor.visit(m_clipboard);
|
visitor.visit(m_clipboard);
|
||||||
visitor.visit(m_geolocation);
|
visitor.visit(m_geolocation);
|
||||||
|
visitor.visit(m_serial);
|
||||||
visitor.visit(m_user_activation);
|
visitor.visit(m_user_activation);
|
||||||
visitor.visit(m_service_worker_container);
|
visitor.visit(m_service_worker_container);
|
||||||
visitor.visit(m_media_capabilities);
|
visitor.visit(m_media_capabilities);
|
||||||
|
@ -103,6 +104,13 @@ GC::Ref<Geolocation::Geolocation> Navigator::geolocation()
|
||||||
return *m_geolocation;
|
return *m_geolocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GC::Ref<Serial::Serial> Navigator::serial()
|
||||||
|
{
|
||||||
|
if (!m_serial)
|
||||||
|
m_serial = realm().create<Serial::Serial>(realm());
|
||||||
|
return *m_serial;
|
||||||
|
}
|
||||||
|
|
||||||
GC::Ref<UserActivation> Navigator::user_activation()
|
GC::Ref<UserActivation> Navigator::user_activation()
|
||||||
{
|
{
|
||||||
if (!m_user_activation)
|
if (!m_user_activation)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <LibWeb/HTML/PluginArray.h>
|
#include <LibWeb/HTML/PluginArray.h>
|
||||||
#include <LibWeb/HTML/UserActivation.h>
|
#include <LibWeb/HTML/UserActivation.h>
|
||||||
#include <LibWeb/MediaCapabilitiesAPI/MediaCapabilities.h>
|
#include <LibWeb/MediaCapabilitiesAPI/MediaCapabilities.h>
|
||||||
|
#include <LibWeb/Serial/Serial.h>
|
||||||
#include <LibWeb/StorageAPI/NavigatorStorage.h>
|
#include <LibWeb/StorageAPI/NavigatorStorage.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
@ -56,6 +57,7 @@ public:
|
||||||
[[nodiscard]] GC::Ref<PluginArray> plugins();
|
[[nodiscard]] GC::Ref<PluginArray> plugins();
|
||||||
[[nodiscard]] GC::Ref<Clipboard::Clipboard> clipboard();
|
[[nodiscard]] GC::Ref<Clipboard::Clipboard> clipboard();
|
||||||
[[nodiscard]] GC::Ref<Geolocation::Geolocation> geolocation();
|
[[nodiscard]] GC::Ref<Geolocation::Geolocation> geolocation();
|
||||||
|
[[nodiscard]] GC::Ref<Serial::Serial> serial();
|
||||||
[[nodiscard]] GC::Ref<UserActivation> user_activation();
|
[[nodiscard]] GC::Ref<UserActivation> user_activation();
|
||||||
[[nodiscard]] GC::Ref<CredentialManagement::CredentialsContainer> credentials();
|
[[nodiscard]] GC::Ref<CredentialManagement::CredentialsContainer> credentials();
|
||||||
|
|
||||||
|
@ -89,6 +91,9 @@ private:
|
||||||
// https://w3c.github.io/geolocation/#navigator_interface
|
// https://w3c.github.io/geolocation/#navigator_interface
|
||||||
GC::Ptr<Geolocation::Geolocation> m_geolocation;
|
GC::Ptr<Geolocation::Geolocation> m_geolocation;
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#extensions-to-the-navigator-interface
|
||||||
|
GC::Ptr<Serial::Serial> m_serial;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/interaction.html#dom-navigator-useractivation
|
// https://html.spec.whatwg.org/multipage/interaction.html#dom-navigator-useractivation
|
||||||
GC::Ptr<UserActivation> m_user_activation;
|
GC::Ptr<UserActivation> m_user_activation;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#import <HTML/PluginArray.idl>
|
#import <HTML/PluginArray.idl>
|
||||||
#import <HTML/UserActivation.idl>
|
#import <HTML/UserActivation.idl>
|
||||||
#import <MediaCapabilitiesAPI/MediaCapabilities.idl>
|
#import <MediaCapabilitiesAPI/MediaCapabilities.idl>
|
||||||
|
#import <Serial/Serial.idl>
|
||||||
#import <ServiceWorker/ServiceWorkerContainer.idl>
|
#import <ServiceWorker/ServiceWorkerContainer.idl>
|
||||||
#import <StorageAPI/NavigatorStorage.idl>
|
#import <StorageAPI/NavigatorStorage.idl>
|
||||||
|
|
||||||
|
@ -29,6 +30,9 @@ interface Navigator {
|
||||||
// https://w3c.github.io/pointerevents/#extensions-to-the-navigator-interface
|
// https://w3c.github.io/pointerevents/#extensions-to-the-navigator-interface
|
||||||
readonly attribute long maxTouchPoints;
|
readonly attribute long maxTouchPoints;
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#extensions-to-the-navigator-interface
|
||||||
|
[SameObject] readonly attribute Serial serial;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/interaction.html#useractivation
|
// https://html.spec.whatwg.org/multipage/interaction.html#useractivation
|
||||||
[SameObject] readonly attribute UserActivation userActivation;
|
[SameObject] readonly attribute UserActivation userActivation;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ void WorkerNavigator::visit_edges(Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
visitor.visit(m_media_capabilities);
|
visitor.visit(m_media_capabilities);
|
||||||
|
visitor.visit(m_serial);
|
||||||
visitor.visit(m_service_worker_container);
|
visitor.visit(m_service_worker_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +48,13 @@ GC::Ref<MediaCapabilitiesAPI::MediaCapabilities> WorkerNavigator::media_capabili
|
||||||
return *m_media_capabilities;
|
return *m_media_capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GC::Ref<Serial::Serial> WorkerNavigator::serial()
|
||||||
|
{
|
||||||
|
if (!m_serial)
|
||||||
|
m_serial = realm().create<Serial::Serial>(realm());
|
||||||
|
return *m_serial;
|
||||||
|
}
|
||||||
|
|
||||||
GC::Ref<ServiceWorker::ServiceWorkerContainer> WorkerNavigator::service_worker()
|
GC::Ref<ServiceWorker::ServiceWorkerContainer> WorkerNavigator::service_worker()
|
||||||
{
|
{
|
||||||
if (!m_service_worker_container)
|
if (!m_service_worker_container)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <LibWeb/HTML/NavigatorLanguage.h>
|
#include <LibWeb/HTML/NavigatorLanguage.h>
|
||||||
#include <LibWeb/HTML/NavigatorOnLine.h>
|
#include <LibWeb/HTML/NavigatorOnLine.h>
|
||||||
#include <LibWeb/MediaCapabilitiesAPI/MediaCapabilities.h>
|
#include <LibWeb/MediaCapabilitiesAPI/MediaCapabilities.h>
|
||||||
|
#include <LibWeb/Serial/Serial.h>
|
||||||
#include <LibWeb/ServiceWorker/ServiceWorkerContainer.h>
|
#include <LibWeb/ServiceWorker/ServiceWorkerContainer.h>
|
||||||
#include <LibWeb/StorageAPI/NavigatorStorage.h>
|
#include <LibWeb/StorageAPI/NavigatorStorage.h>
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ public:
|
||||||
|
|
||||||
GC::Ref<MediaCapabilitiesAPI::MediaCapabilities> media_capabilities();
|
GC::Ref<MediaCapabilitiesAPI::MediaCapabilities> media_capabilities();
|
||||||
|
|
||||||
|
[[nodiscard]] GC::Ref<Serial::Serial> serial();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit WorkerNavigator(WorkerGlobalScope&);
|
explicit WorkerNavigator(WorkerGlobalScope&);
|
||||||
|
|
||||||
|
@ -50,6 +53,9 @@ private:
|
||||||
// https://w3c.github.io/media-capabilities/#dom-workernavigator-mediacapabilities
|
// https://w3c.github.io/media-capabilities/#dom-workernavigator-mediacapabilities
|
||||||
GC::Ptr<MediaCapabilitiesAPI::MediaCapabilities> m_media_capabilities;
|
GC::Ptr<MediaCapabilitiesAPI::MediaCapabilities> m_media_capabilities;
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#extensions-to-the-workernavigator-interface
|
||||||
|
GC::Ptr<Serial::Serial> m_serial;
|
||||||
|
|
||||||
GC::Ptr<ServiceWorker::ServiceWorkerContainer> m_service_worker_container;
|
GC::Ptr<ServiceWorker::ServiceWorkerContainer> m_service_worker_container;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#import <HTML/NavigatorLanguage.idl>
|
#import <HTML/NavigatorLanguage.idl>
|
||||||
#import <HTML/NavigatorOnLine.idl>
|
#import <HTML/NavigatorOnLine.idl>
|
||||||
#import <MediaCapabilitiesAPI/MediaCapabilities.idl>
|
#import <MediaCapabilitiesAPI/MediaCapabilities.idl>
|
||||||
|
#import <Serial/Serial.idl>
|
||||||
#import <StorageAPI/NavigatorStorage.idl>
|
#import <StorageAPI/NavigatorStorage.idl>
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/workers.html#workernavigator
|
// https://html.spec.whatwg.org/multipage/workers.html#workernavigator
|
||||||
|
@ -12,6 +13,9 @@ interface WorkerNavigator {
|
||||||
// https://w3c.github.io/media-capabilities/#dom-workernavigator-mediacapabilities
|
// https://w3c.github.io/media-capabilities/#dom-workernavigator-mediacapabilities
|
||||||
[SameObject] readonly attribute MediaCapabilities mediaCapabilities;
|
[SameObject] readonly attribute MediaCapabilities mediaCapabilities;
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#extensions-to-the-workernavigator-interface
|
||||||
|
[SameObject] readonly attribute Serial serial;
|
||||||
|
|
||||||
// https://w3c.github.io/ServiceWorker/#navigator-serviceworker
|
// https://w3c.github.io/ServiceWorker/#navigator-serviceworker
|
||||||
[SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
|
[SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
|
||||||
};
|
};
|
||||||
|
|
123
Libraries/LibWeb/Serial/Serial.cpp
Normal file
123
Libraries/LibWeb/Serial/Serial.cpp
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Edwin Hoksberg <mail@edwinhoksberg.nl>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
#include <LibWeb/Bindings/SerialPrototype.h>
|
||||||
|
#include <LibWeb/HTML/EventNames.h>
|
||||||
|
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||||
|
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||||
|
#include <LibWeb/HTML/Window.h>
|
||||||
|
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||||
|
#include <LibWeb/Serial/Serial.h>
|
||||||
|
#include <LibWeb/Serial/SerialPort.h>
|
||||||
|
#include <LibWeb/WebIDL/Promise.h>
|
||||||
|
|
||||||
|
namespace Web::Serial {
|
||||||
|
|
||||||
|
GC_DEFINE_ALLOCATOR(Serial);
|
||||||
|
|
||||||
|
Serial::Serial(JS::Realm& realm)
|
||||||
|
: DOM::EventTarget(realm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Serial::initialize(JS::Realm& realm)
|
||||||
|
{
|
||||||
|
WEB_SET_PROTOTYPE_FOR_INTERFACE(Serial);
|
||||||
|
Base::initialize(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#requestport-method
|
||||||
|
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> Serial::request_port(SerialPortRequestOptions const)
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// FIXME: 1. Let promise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 2. If this's relevant global object's associated Document is not allowed to use the policy-controlled feature named "serial",
|
||||||
|
// reject promise with a "SecurityError" DOMException and return promise.
|
||||||
|
|
||||||
|
// FIXME: 3. If the relevant global object of this does not have transient activation, reject promise with a "SecurityError" DOMException and return promise.
|
||||||
|
|
||||||
|
// FIXME: 4. If options["filters"] is present, then for each filter in options["filters"] run the following steps:
|
||||||
|
|
||||||
|
// FIXME: 5. Run the following steps in parallel:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Let allPorts be an empty list.
|
||||||
|
|
||||||
|
// FIXME: 2. For each Bluetooth device registered with the system:
|
||||||
|
|
||||||
|
// FIXME: 3. For each available non-Bluetooth serial port:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Let port be a SerialPort representing the port.
|
||||||
|
|
||||||
|
// FIXME: 2. Append port to allPorts.
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: 4. Prompt the user to grant the site access to a serial port by presenting them with a list of ports
|
||||||
|
// in allPorts that match any filter in options["filters"] if present and allPorts otherwise.
|
||||||
|
|
||||||
|
// FIXME: 5. If the user does not choose a port, queue a global task on the relevant global object of this using the
|
||||||
|
// serial port task source to reject promise with a "NotFoundError" DOMException and abort these steps.
|
||||||
|
|
||||||
|
// FIXME: 6. Let port be a SerialPort representing the port chosen by the user.
|
||||||
|
|
||||||
|
// FIXME: 7. Queue a global task on the relevant global object of this using the serial port task source to resolve promise with port.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Return promise.
|
||||||
|
dbgln("FIXME: Unimplemented Serial::request_port()");
|
||||||
|
return WebIDL::create_rejected_promise(realm, WebIDL::UnknownError::create(realm, ""_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#getports-method
|
||||||
|
GC::Ref<WebIDL::Promise> Serial::get_ports()
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// FIXME: 1. Let promise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 2. If this's relevant global object's associated Document is not allowed to use the policy-controlled feature named "serial",
|
||||||
|
// reject promise with a "SecurityError" DOMException and return promise.
|
||||||
|
|
||||||
|
// FIXME: 3. Run the following steps in parallel:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Let availablePorts be the sequence of available serial ports which the user has allowed the site to
|
||||||
|
// access as the result of a previous call to requestPort().
|
||||||
|
|
||||||
|
// FIXME: 2. Let ports be the sequence of the SerialPorts representing the ports in availablePorts.
|
||||||
|
|
||||||
|
// FIXME: 3. Queue a global task on the relevant global object of this using the serial port task source to resolve promise with ports.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return promise.
|
||||||
|
dbgln("FIXME: Unimplemented Serial::get_ports()");
|
||||||
|
return WebIDL::create_rejected_promise(realm, WebIDL::UnknownError::create(realm, ""_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#onconnect-attribute
|
||||||
|
void Serial::set_onconnect(WebIDL::CallbackType* event_handler)
|
||||||
|
{
|
||||||
|
set_event_handler_attribute(HTML::EventNames::connect, event_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::CallbackType* Serial::onconnect()
|
||||||
|
{
|
||||||
|
return event_handler_attribute(HTML::EventNames::connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#ondisconnect-attribute
|
||||||
|
void Serial::set_ondisconnect(WebIDL::CallbackType* event_handler)
|
||||||
|
{
|
||||||
|
set_event_handler_attribute(HTML::EventNames::disconnect, event_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::CallbackType* Serial::ondisconnect()
|
||||||
|
{
|
||||||
|
return event_handler_attribute(HTML::EventNames::disconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
Libraries/LibWeb/Serial/Serial.h
Normal file
52
Libraries/LibWeb/Serial/Serial.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Edwin Hoksberg <mail@edwinhoksberg.nl>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/DOM/EventTarget.h>
|
||||||
|
#include <LibWeb/WebIDL/Types.h>
|
||||||
|
|
||||||
|
namespace Web::Serial {
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialportfilter-dictionary
|
||||||
|
struct SerialPortFilter {
|
||||||
|
Optional<WebIDL::UnsignedShort> usb_vendor_id;
|
||||||
|
Optional<WebIDL::UnsignedShort> usb_product_id;
|
||||||
|
Optional<String> bluetooth_service_class_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialportrequestoptions-dictionary
|
||||||
|
struct SerialPortRequestOptions {
|
||||||
|
Optional<Vector<SerialPortFilter>> filters;
|
||||||
|
Optional<Vector<String>> allowed_bluetooth_service_class_ids;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serial-interface
|
||||||
|
class Serial : public DOM::EventTarget {
|
||||||
|
WEB_PLATFORM_OBJECT(Serial, DOM::EventTarget);
|
||||||
|
GC_DECLARE_ALLOCATOR(Serial);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// https://wicg.github.io/serial/#requestport-method
|
||||||
|
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> request_port(SerialPortRequestOptions = {});
|
||||||
|
// https://wicg.github.io/serial/#getports-method
|
||||||
|
GC::Ref<WebIDL::Promise> get_ports();
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#onconnect-attribute
|
||||||
|
void set_onconnect(WebIDL::CallbackType*);
|
||||||
|
WebIDL::CallbackType* onconnect();
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#ondisconnect-attribute
|
||||||
|
void set_ondisconnect(WebIDL::CallbackType*);
|
||||||
|
WebIDL::CallbackType* ondisconnect();
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Serial(JS::Realm&);
|
||||||
|
|
||||||
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
26
Libraries/LibWeb/Serial/Serial.idl
Normal file
26
Libraries/LibWeb/Serial/Serial.idl
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#import <DOM/EventHandler.idl>
|
||||||
|
#import <Serial/SerialPort.idl>
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serial-interface
|
||||||
|
[Exposed=(DedicatedWorker, Window), SecureContext]
|
||||||
|
interface Serial : EventTarget {
|
||||||
|
attribute EventHandler onconnect;
|
||||||
|
attribute EventHandler ondisconnect;
|
||||||
|
Promise<sequence<SerialPort>> getPorts();
|
||||||
|
[Exposed=Window] Promise<SerialPort> requestPort(optional SerialPortRequestOptions options = {});
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialportfilter-dictionary
|
||||||
|
dictionary SerialPortFilter {
|
||||||
|
unsigned short usbVendorId;
|
||||||
|
unsigned short usbProductId;
|
||||||
|
// FIXME: Should be a BluetoothServiceUUID
|
||||||
|
DOMString bluetoothServiceClassId;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialportrequestoptions-dictionary
|
||||||
|
dictionary SerialPortRequestOptions {
|
||||||
|
sequence<SerialPortFilter> filters;
|
||||||
|
// FIXME: Should be a BluetoothServiceUUID
|
||||||
|
sequence<DOMString> allowedBluetoothServiceClassIds;
|
||||||
|
};
|
258
Libraries/LibWeb/Serial/SerialPort.cpp
Normal file
258
Libraries/LibWeb/Serial/SerialPort.cpp
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Edwin Hoksberg <mail@edwinhoksberg.nl>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
#include <LibWeb/HTML/EventNames.h>
|
||||||
|
#include <LibWeb/Serial/SerialPort.h>
|
||||||
|
#include <LibWeb/WebIDL/Promise.h>
|
||||||
|
|
||||||
|
namespace Web::Serial {
|
||||||
|
|
||||||
|
SerialPort::SerialPort(JS::Realm& realm)
|
||||||
|
: DOM::EventTarget(realm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPort::initialize(JS::Realm& realm)
|
||||||
|
{
|
||||||
|
WEB_SET_PROTOTYPE_FOR_INTERFACE(SerialPort);
|
||||||
|
Base::initialize(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#getinfo-method
|
||||||
|
SerialPortInfo SerialPort::get_info() const
|
||||||
|
{
|
||||||
|
// 1. Let info be an empty ordered map.
|
||||||
|
auto info = SerialPortInfo {};
|
||||||
|
|
||||||
|
// FIXME: 2. If the port is part of a USB device, perform the following steps:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Set info["usbVendorId"] to the vendor ID of the device.
|
||||||
|
|
||||||
|
// FIXME: 2. Set info["usbProductId"] to the product ID of the device.
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: 3. If the port is a service on a Bluetooth device, perform the following steps:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Set info["bluetoothServiceClassId"] to the service class UUID of the Bluetooth service.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return info.
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#open-method
|
||||||
|
GC::Ref<WebIDL::Promise> SerialPort::open(SerialOptions)
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// FIXME: 1. Let promise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 2. If this.[[state]] is not "closed", reject promise with an "InvalidStateError" DOMException and return promise.
|
||||||
|
|
||||||
|
// FIXME: 3. If options["dataBits"] is not 7 or 8, reject promise with TypeError and return promise.
|
||||||
|
|
||||||
|
// FIXME: 4. If options["stopBits"] is not 1 or 2, reject promise with TypeError and return promise.
|
||||||
|
|
||||||
|
// FIXME: 5. If options["bufferSize"] is 0, reject promise with TypeError and return promise.
|
||||||
|
|
||||||
|
// FIXME: 6. Optionally, if options["bufferSize"] is larger than the implementation is able to support, reject promise with a TypeError and return promise.
|
||||||
|
|
||||||
|
// FIXME: 7. Set this.[[state]] to "opening".
|
||||||
|
|
||||||
|
// FIXME: 8. Perform the following steps in parallel.
|
||||||
|
{
|
||||||
|
// FIXME: 1. Invoke the operating system to open the serial port using the connection parameters (or their defaults) specified in options.
|
||||||
|
|
||||||
|
// FIXME: 2. If this fails for any reason, queue a global task on the relevant global object of this using the serial port task source to reject promise with a "NetworkError" DOMException and abort these steps.
|
||||||
|
|
||||||
|
// FIXME: 3. Set this.[[state]] to "opened".
|
||||||
|
|
||||||
|
// FIXME: 4. Set this.[[bufferSize]] to options["bufferSize"].
|
||||||
|
|
||||||
|
// FIXME: 5. Queue a global task on the relevant global object of this using the serial port task source to resolve promise with undefined.
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: 9. Return promise.
|
||||||
|
dbgln("FIXME: Unimplemented SerialPort::open()");
|
||||||
|
return WebIDL::create_rejected_promise(realm, WebIDL::UnknownError::create(realm, ""_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#setsignals-method
|
||||||
|
GC::Ref<WebIDL::Promise> SerialPort::set_signals(SerialOutputSignals)
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// FIXME: 1. Let promise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 2. If this.[[state]] is not "opened", reject promise with an "InvalidStateError" DOMException and return promise.
|
||||||
|
|
||||||
|
// FIXME: 3. If all of the specified members of signals are not present reject promise with TypeError and return promise.
|
||||||
|
|
||||||
|
// FIXME: 4. Perform the following steps in parallel:
|
||||||
|
{
|
||||||
|
// FIXME: 1. If signals["dataTerminalReady"] is present, invoke the operating system to either assert (if true) or
|
||||||
|
// deassert (if false) the "data terminal ready" or "DTR" signal on the serial port.
|
||||||
|
|
||||||
|
// FIXME: 2. If signals["requestToSend"] is present, invoke the operating system to either assert (if true) or
|
||||||
|
// deassert (if false) the "request to send" or "RTS" signal on the serial port.
|
||||||
|
|
||||||
|
// FIXME: 3. If signals["break"] is present, invoke the operating system to either assert (if true) or
|
||||||
|
// deassert (if false) the "break" signal on the serial port.
|
||||||
|
|
||||||
|
// FIXME: 4. If the operating system fails to change the state of any of these signals for any reason, queue a global task
|
||||||
|
// on the relevant global object of this using the serial port task source to reject promise with a "NetworkError" DOMException.
|
||||||
|
|
||||||
|
// FIXME: 5. Queue a global task on the relevant global object of this using the serial port task source to resolve promise with undefined.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Return promise.
|
||||||
|
dbgln("FIXME: Unimplemented SerialPort::set_signals()");
|
||||||
|
return WebIDL::create_rejected_promise(realm, WebIDL::UnknownError::create(realm, ""_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#getsignals-method
|
||||||
|
GC::Ref<WebIDL::Promise> SerialPort::get_signals() const
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// FIXME: 1. Let promise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 2. If this.[[state]] is not "opened", reject promise with an "InvalidStateError" DOMException and return promise.
|
||||||
|
|
||||||
|
// FIXME: 3. Perform the following steps in parallel:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Query the operating system for the status of the control signals that may be asserted by the device connected to the serial port.
|
||||||
|
|
||||||
|
// FIXME: 2. If the operating system fails to determine the status of these signals for any reason, queue a global task on the relevant global object of
|
||||||
|
// this using the serial port task source to reject promise with a "NetworkError" DOMException and abort these steps.
|
||||||
|
|
||||||
|
// FIXME: 3. Let dataCarrierDetect be true if the "data carrier detect" or "DCD" signal has been asserted by the device, and false otherwise.
|
||||||
|
|
||||||
|
// FIXME: 4. Let clearToSend be true if the "clear to send" or "CTS" signal has been asserted by the device, and false otherwise.
|
||||||
|
|
||||||
|
// FIXME: 5. Let ringIndicator be true if the "ring indicator" or "RI" signal has been asserted by the device, and false otherwise.
|
||||||
|
|
||||||
|
// FIXME: 6. Let dataSetReady be true if the "data set ready" or "DSR" signal has been asserted by the device, and false otherwise.
|
||||||
|
|
||||||
|
// FIXME: 7. Let signals be the ordered map «[ "dataCarrierDetect" → dataCarrierDetect, "clearToSend" → clearToSend, "ringIndicator" → ringIndicator, "dataSetReady" → dataSetReady ]».
|
||||||
|
|
||||||
|
// FIXME: 8. Queue a global task on the relevant global object of this using the serial port task source to resolve promise with signals.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Return promise.
|
||||||
|
dbgln("FIXME: Unimplemented SerialPort::get_signals()");
|
||||||
|
return WebIDL::create_rejected_promise(realm, WebIDL::UnknownError::create(realm, ""_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#close-method
|
||||||
|
GC::Ref<WebIDL::Promise> SerialPort::close()
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// FIXME: 1. Let promise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 2. If this.[[state]] is not "opened", reject promise with an "InvalidStateError" DOMException and return promise.
|
||||||
|
|
||||||
|
// FIXME: 3. Let cancelPromise be the result of invoking cancel on this.[[readable]] or a promise resolved with undefined if this.[[readable]] is null.
|
||||||
|
|
||||||
|
// FIXME: 4. Let abortPromise be the result of invoking abort on this.[[writable]] or a promise resolved with undefined if this.[[writable]] is null.
|
||||||
|
|
||||||
|
// FIXME: 5. Let pendingClosePromise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 6. If this.[[readable]] and this.[[writable]] are null, resolve pendingClosePromise with undefined.
|
||||||
|
|
||||||
|
// FIXME: 7. Set this.[[pendingClosePromise]] to pendingClosePromise.
|
||||||
|
|
||||||
|
// FIXME: 8. Let combinedPromise be the result of getting a promise to wait for all with «cancelPromise, abortPromise, pendingClosePromise».
|
||||||
|
|
||||||
|
// FIXME: 9. Set this.[[state]] to "closing".
|
||||||
|
|
||||||
|
// FIXME: 10. React to combinedPromise.
|
||||||
|
{
|
||||||
|
// If combinedPromise was fulfilled, then:
|
||||||
|
// FIXME: 1. Run the following steps in parallel:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Invoke the operating system to close the serial port and release any associated resources.
|
||||||
|
|
||||||
|
// FIXME: 2. Set this.[[state]] to "closed".
|
||||||
|
|
||||||
|
// FIXME: 3. Set this.[[readFatal]] and this.[[writeFatal]] to false.
|
||||||
|
|
||||||
|
// FIXME: 4. Set this.[[pendingClosePromise]] to null.
|
||||||
|
|
||||||
|
// FIXME: 5. Queue a global task on the relevant global object of this using the serial port task source to resolve promise with undefined.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If combinedPromise was rejected with reason r, then:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Set this.[[pendingClosePromise]] to null.
|
||||||
|
|
||||||
|
// FIXME: 2. Queue a global task on the relevant global object of this using the serial port task source to reject promise with r.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. Return promise.
|
||||||
|
dbgln("FIXME: Unimplemented SerialPort::close()");
|
||||||
|
return WebIDL::create_rejected_promise(realm, WebIDL::UnknownError::create(realm, ""_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#forget-method
|
||||||
|
GC::Ref<WebIDL::Promise> SerialPort::forget()
|
||||||
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
// FIXME: 1. Let promise be a new promise.
|
||||||
|
|
||||||
|
// FIXME: 1. If the user agent can't perform this action (e.g. permission was granted by administrator policy), return a promise resolved with undefined.
|
||||||
|
|
||||||
|
// FIXME: 2. Run the following steps in parallel:
|
||||||
|
{
|
||||||
|
// FIXME: 1. Set this.[[state]] to "forgetting".
|
||||||
|
|
||||||
|
// FIXME: 2. Remove this from the sequence of serial ports on the system which the user has allowed the site to access as the result of a previous call to requestPort().
|
||||||
|
|
||||||
|
// FIXME: 3. Set this.[[state]] to "forgotten".
|
||||||
|
|
||||||
|
// FIXME: 4. Queue a global task on the relevant global object of this using the serial port task source to resolve promise with undefined.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Return promise.
|
||||||
|
dbgln("FIXME: Unimplemented SerialPort::forget()");
|
||||||
|
return WebIDL::create_rejected_promise(realm, WebIDL::UnknownError::create(realm, ""_string));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPort::visit_edges(Cell::Visitor& visitor)
|
||||||
|
{
|
||||||
|
Base::visit_edges(visitor);
|
||||||
|
visitor.visit(m_readable);
|
||||||
|
visitor.visit(m_writable);
|
||||||
|
visitor.visit(m_pending_close_promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#onconnect-attribute-0
|
||||||
|
void SerialPort::set_onconnect(WebIDL::CallbackType* event_handler)
|
||||||
|
{
|
||||||
|
set_event_handler_attribute(HTML::EventNames::connect, event_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::CallbackType* SerialPort::onconnect()
|
||||||
|
{
|
||||||
|
return event_handler_attribute(HTML::EventNames::connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#ondisconnect-attribute-0
|
||||||
|
void SerialPort::set_ondisconnect(WebIDL::CallbackType* event_handler)
|
||||||
|
{
|
||||||
|
set_event_handler_attribute(HTML::EventNames::disconnect, event_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::CallbackType* SerialPort::ondisconnect()
|
||||||
|
{
|
||||||
|
return event_handler_attribute(HTML::EventNames::disconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
132
Libraries/LibWeb/Serial/SerialPort.h
Normal file
132
Libraries/LibWeb/Serial/SerialPort.h
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Edwin Hoksberg <mail@edwinhoksberg.nl>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/Bindings/SerialPortPrototype.h>
|
||||||
|
#include <LibWeb/DOM/EventTarget.h>
|
||||||
|
#include <LibWeb/Streams/ReadableStream.h>
|
||||||
|
#include <LibWeb/Streams/WritableStream.h>
|
||||||
|
#include <LibWeb/WebIDL/Types.h>
|
||||||
|
|
||||||
|
namespace Web::Serial {
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialoptions-dictionary
|
||||||
|
struct SerialOptions {
|
||||||
|
Optional<WebIDL::UnsignedLong> baud_rate = {};
|
||||||
|
Optional<WebIDL::Octet> data_bits = 8;
|
||||||
|
Optional<WebIDL::Octet> stop_bits = 1;
|
||||||
|
Optional<Bindings::ParityType> parity = Bindings::ParityType::None;
|
||||||
|
Optional<WebIDL::UnsignedLong> buffer_size = 255;
|
||||||
|
Optional<Bindings::FlowControlType> flow_control = Bindings::FlowControlType::None;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialoutputsignals-dictionary
|
||||||
|
struct SerialOutputSignals {
|
||||||
|
Optional<WebIDL::Boolean> data_terminal_ready;
|
||||||
|
Optional<WebIDL::Boolean> request_to_send;
|
||||||
|
Optional<WebIDL::Boolean> break_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialinputsignals-dictionary
|
||||||
|
struct SerialInputSignals {
|
||||||
|
WebIDL::Boolean data_carrier_detect;
|
||||||
|
WebIDL::Boolean clear_to_send;
|
||||||
|
WebIDL::Boolean ring_indicator;
|
||||||
|
WebIDL::Boolean data_set_ready;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialportinfo-dictionary
|
||||||
|
struct SerialPortInfo {
|
||||||
|
Optional<WebIDL::UnsignedShort> usb_vendor_id;
|
||||||
|
Optional<WebIDL::UnsignedShort> usb_product_id;
|
||||||
|
Optional<String> bluetooth_service_class_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SerialPortState : u8 {
|
||||||
|
Closed,
|
||||||
|
Opening,
|
||||||
|
Opened,
|
||||||
|
Closing,
|
||||||
|
Forgetting,
|
||||||
|
Forgotten,
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialport-interface
|
||||||
|
class SerialPort : public DOM::EventTarget {
|
||||||
|
WEB_PLATFORM_OBJECT(SerialPort, DOM::EventTarget);
|
||||||
|
GC_DECLARE_ALLOCATOR(SerialPort);
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#getinfo-method
|
||||||
|
SerialPortInfo get_info() const;
|
||||||
|
// https://wicg.github.io/serial/#open-method
|
||||||
|
GC::Ref<WebIDL::Promise> open(SerialOptions);
|
||||||
|
// https://wicg.github.io/serial/#setsignals-method
|
||||||
|
GC::Ref<WebIDL::Promise> set_signals(SerialOutputSignals = {});
|
||||||
|
// https://wicg.github.io/serial/#getsignals-method
|
||||||
|
GC::Ref<WebIDL::Promise> get_signals() const;
|
||||||
|
// https://wicg.github.io/serial/#close-method
|
||||||
|
GC::Ref<WebIDL::Promise> close();
|
||||||
|
// https://wicg.github.io/serial/#forget-method
|
||||||
|
GC::Ref<WebIDL::Promise> forget();
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#connected-attribute
|
||||||
|
bool connected() const { return m_connected; }
|
||||||
|
// https://wicg.github.io/serial/#readable-attribute
|
||||||
|
GC::Ref<Streams::ReadableStream> readable() { return *m_readable; }
|
||||||
|
// https://wicg.github.io/serial/#writable-attribute
|
||||||
|
GC::Ref<Streams::WritableStream> writable() { return *m_writable; }
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#onconnect-attribute-0
|
||||||
|
void set_onconnect(WebIDL::CallbackType*);
|
||||||
|
WebIDL::CallbackType* onconnect();
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#ondisconnect-attribute-0
|
||||||
|
void set_ondisconnect(WebIDL::CallbackType*);
|
||||||
|
WebIDL::CallbackType* ondisconnect();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit SerialPort(JS::Realm&);
|
||||||
|
|
||||||
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-state
|
||||||
|
// Tracks the active state of the SerialPort
|
||||||
|
SerialPortState m_state { SerialPortState::Closed };
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-buffersize
|
||||||
|
// The amount of data to buffer for transmit and receive
|
||||||
|
unsigned long m_buffer_size = {};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-connected
|
||||||
|
// A flag indicating the logical connection state of serial port
|
||||||
|
bool m_connected { false };
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-readable
|
||||||
|
// A ReadableStream that receives data from the port
|
||||||
|
GC::Ptr<Streams::ReadableStream> m_readable = {};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-readfatal
|
||||||
|
// A flag indicating that the port has encountered a fatal read error
|
||||||
|
bool m_read_fatal { false };
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-writable
|
||||||
|
// A WritableStream that transmits data to the port
|
||||||
|
GC::Ptr<Streams::WritableStream> m_writable = {};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-writefatal
|
||||||
|
// A flag indicating that the port has encountered a fatal write error
|
||||||
|
bool m_write_fatal { false };
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#dfn-pendingclosepromise
|
||||||
|
// A Promise used to wait for readable and writable to close
|
||||||
|
GC::Ptr<WebIDL::Promise> m_pending_close_promise = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
65
Libraries/LibWeb/Serial/SerialPort.idl
Normal file
65
Libraries/LibWeb/Serial/SerialPort.idl
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
#import <DOM/EventHandler.idl>
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialport-interface
|
||||||
|
[Exposed=(DedicatedWorker,Window), SecureContext]
|
||||||
|
interface SerialPort : EventTarget {
|
||||||
|
attribute EventHandler onconnect;
|
||||||
|
attribute EventHandler ondisconnect;
|
||||||
|
readonly attribute boolean connected;
|
||||||
|
readonly attribute ReadableStream readable;
|
||||||
|
readonly attribute WritableStream writable;
|
||||||
|
|
||||||
|
SerialPortInfo getInfo();
|
||||||
|
|
||||||
|
Promise<undefined> open(SerialOptions options);
|
||||||
|
Promise<undefined> setSignals(optional SerialOutputSignals signals = {});
|
||||||
|
Promise<SerialInputSignals> getSignals();
|
||||||
|
Promise<undefined> close();
|
||||||
|
Promise<undefined> forget();
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialoptions-dictionary
|
||||||
|
dictionary SerialOptions {
|
||||||
|
[EnforceRange] unsigned long baudRate;
|
||||||
|
[EnforceRange] octet dataBits = 8;
|
||||||
|
[EnforceRange] octet stopBits = 1;
|
||||||
|
ParityType parity = "none";
|
||||||
|
[EnforceRange] unsigned long bufferSize = 255;
|
||||||
|
FlowControlType flowControl = "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialoutputsignals-dictionary
|
||||||
|
dictionary SerialOutputSignals {
|
||||||
|
boolean dataTerminalReady;
|
||||||
|
boolean requestToSend;
|
||||||
|
boolean break;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialinputsignals-dictionary
|
||||||
|
dictionary SerialInputSignals {
|
||||||
|
required boolean dataCarrierDetect;
|
||||||
|
required boolean clearToSend;
|
||||||
|
required boolean ringIndicator;
|
||||||
|
required boolean dataSetReady;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#serialportinfo-dictionary
|
||||||
|
dictionary SerialPortInfo {
|
||||||
|
unsigned short usbVendorId;
|
||||||
|
unsigned short usbProductId;
|
||||||
|
// FIXME: Should be a BluetoothServiceUUID
|
||||||
|
DOMString bluetoothServiceClassId;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#paritytype-enum
|
||||||
|
enum ParityType {
|
||||||
|
"none",
|
||||||
|
"even",
|
||||||
|
"odd"
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://wicg.github.io/serial/#flowcontroltype-enum
|
||||||
|
enum FlowControlType {
|
||||||
|
"none",
|
||||||
|
"hardware"
|
||||||
|
};
|
|
@ -306,6 +306,8 @@ libweb_js_bindings(ResizeObserver/ResizeObserver)
|
||||||
libweb_js_bindings(ResizeObserver/ResizeObserverEntry)
|
libweb_js_bindings(ResizeObserver/ResizeObserverEntry)
|
||||||
libweb_js_bindings(ResizeObserver/ResizeObserverSize)
|
libweb_js_bindings(ResizeObserver/ResizeObserverSize)
|
||||||
libweb_js_bindings(ResourceTiming/PerformanceResourceTiming)
|
libweb_js_bindings(ResourceTiming/PerformanceResourceTiming)
|
||||||
|
libweb_js_bindings(Serial/Serial)
|
||||||
|
libweb_js_bindings(Serial/SerialPort)
|
||||||
libweb_js_bindings(ServiceWorker/CacheStorage)
|
libweb_js_bindings(ServiceWorker/CacheStorage)
|
||||||
libweb_js_bindings(ServiceWorker/ServiceWorker)
|
libweb_js_bindings(ServiceWorker/ServiceWorker)
|
||||||
libweb_js_bindings(ServiceWorker/ServiceWorkerContainer)
|
libweb_js_bindings(ServiceWorker/ServiceWorkerContainer)
|
||||||
|
|
|
@ -330,6 +330,7 @@ CppType idl_type_name_to_cpp_type(Type const& type, Interface const& interface)
|
||||||
static ByteString make_input_acceptable_cpp(ByteString const& input)
|
static ByteString make_input_acceptable_cpp(ByteString const& input)
|
||||||
{
|
{
|
||||||
if (input.is_one_of(
|
if (input.is_one_of(
|
||||||
|
"break",
|
||||||
"char",
|
"char",
|
||||||
"class",
|
"class",
|
||||||
"continue",
|
"continue",
|
||||||
|
@ -4841,6 +4842,7 @@ using namespace Web::RequestIdleCallback;
|
||||||
using namespace Web::ResizeObserver;
|
using namespace Web::ResizeObserver;
|
||||||
using namespace Web::ResourceTiming;
|
using namespace Web::ResourceTiming;
|
||||||
using namespace Web::Selection;
|
using namespace Web::Selection;
|
||||||
|
using namespace Web::Serial;
|
||||||
using namespace Web::ServiceWorker;
|
using namespace Web::ServiceWorker;
|
||||||
using namespace Web::StorageAPI;
|
using namespace Web::StorageAPI;
|
||||||
using namespace Web::Streams;
|
using namespace Web::Streams;
|
||||||
|
|
|
@ -37,6 +37,7 @@ static constexpr Array libweb_interface_namespaces = {
|
||||||
"ResizeObserver"sv,
|
"ResizeObserver"sv,
|
||||||
"SVG"sv,
|
"SVG"sv,
|
||||||
"Selection"sv,
|
"Selection"sv,
|
||||||
|
"Serial"sv,
|
||||||
"ServiceWorker"sv,
|
"ServiceWorker"sv,
|
||||||
"Streams"sv,
|
"Streams"sv,
|
||||||
"UIEvents"sv,
|
"UIEvents"sv,
|
||||||
|
|
|
@ -388,6 +388,8 @@ ScreenOrientation
|
||||||
ScriptProcessorNode
|
ScriptProcessorNode
|
||||||
SecurityPolicyViolationEvent
|
SecurityPolicyViolationEvent
|
||||||
Selection
|
Selection
|
||||||
|
Serial
|
||||||
|
SerialPort
|
||||||
ServiceWorker
|
ServiceWorker
|
||||||
ServiceWorkerContainer
|
ServiceWorkerContainer
|
||||||
ServiceWorkerRegistration
|
ServiceWorkerRegistration
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue