diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index 2330efe2017..153c0962eeb 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -77,3 +77,4 @@ toggle statechange controllerchange fetch +characteristicvaluechanged diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index afee568d735..0cb9005e282 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -11,12 +11,13 @@ use core::clone::Clone; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothDataFilterInit, BluetoothLEScanFilterInit}; use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothMethods, RequestDeviceOptions}; +use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::UnionTypes::StringOrUnsignedLong; use dom::bindings::error::Error::{self, NotFound, Security, Type}; use dom::bindings::error::Fallible; use dom::bindings::js::{JS, MutHeap, Root}; use dom::bindings::refcounted::{Trusted, TrustedPromise}; -use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::bluetoothadvertisingdata::BluetoothAdvertisingData; use dom::bluetoothdevice::BluetoothDevice; @@ -24,6 +25,7 @@ use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic; use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor; use dom::bluetoothremotegattservice::BluetoothRemoteGATTService; use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID}; +use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::promise::Promise; use ipc_channel::ipc::{self, IpcSender}; @@ -84,7 +86,7 @@ impl BluetoothResponseListener f // https://webbluetoothcg.github.io/web-bluetooth/#bluetooth #[dom_struct] pub struct Bluetooth { - reflector_: Reflector, + eventtarget: EventTarget, device_instance_map: DOMRefCell>>>, service_instance_map: DOMRefCell>>>, characteristic_instance_map: DOMRefCell>>>, @@ -94,7 +96,7 @@ pub struct Bluetooth { impl Bluetooth { pub fn new_inherited() -> Bluetooth { Bluetooth { - reflector_: Reflector::new(), + eventtarget: EventTarget::new_inherited(), device_instance_map: DOMRefCell::new(HashMap::new()), service_instance_map: DOMRefCell::new(HashMap::new()), characteristic_instance_map: DOMRefCell::new(HashMap::new()), @@ -382,6 +384,9 @@ impl BluetoothMethods for Bluetooth { // TODO(#4282): Step 3-5: Reject and resolve promise. return p; } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-onavailabilitychanged + event_handler!(availabilitychanged, GetOnavailabilitychanged, SetOnavailabilitychanged); } impl AsyncBluetoothListener for Bluetooth { diff --git a/components/script/dom/bluetoothdevice.rs b/components/script/dom/bluetoothdevice.rs index 39706befad6..4f66218dfb4 100644 --- a/components/script/dom/bluetoothdevice.rs +++ b/components/script/dom/bluetoothdevice.rs @@ -4,18 +4,20 @@ use dom::bindings::codegen::Bindings::BluetoothDeviceBinding; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; +use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::js::{JS, Root, MutHeap, MutNullableHeap}; -use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::bluetooth::Bluetooth; use dom::bluetoothadvertisingdata::BluetoothAdvertisingData; use dom::bluetoothremotegattserver::BluetoothRemoteGATTServer; +use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice #[dom_struct] pub struct BluetoothDevice { - reflector_: Reflector, + eventtarget: EventTarget, id: DOMString, name: Option, ad_data: MutHeap>, @@ -30,7 +32,7 @@ impl BluetoothDevice { context: &Bluetooth) -> BluetoothDevice { BluetoothDevice { - reflector_: Reflector::new(), + eventtarget: EventTarget::new_inherited(), id: id, name: name, ad_data: MutHeap::new(ad_data), @@ -80,4 +82,7 @@ impl BluetoothDeviceMethods for BluetoothDevice { BluetoothRemoteGATTServer::new(&self.global(), self) }) } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdeviceeventhandlers-ongattserverdisconnected + event_handler!(gattserverdisconnected, GetOngattserverdisconnected, SetOngattserverdisconnected); } diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs index 390878342db..9640ba95d52 100644 --- a/components/script/dom/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetoothremotegattcharacteristic.rs @@ -13,15 +13,18 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding:: BluetoothRemoteGATTCharacteristicMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods; +use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::error::Error::{self, InvalidModification, Network, NotSupported, Security}; +use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutHeap, Root}; -use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString}; use dom::bluetooth::{AsyncBluetoothListener, response_async}; use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties; use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor; use dom::bluetoothremotegattservice::BluetoothRemoteGATTService; use dom::bluetoothuuid::{BluetoothDescriptorUUID, BluetoothUUID}; +use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::promise::Promise; use ipc_channel::ipc::IpcSender; @@ -35,7 +38,7 @@ pub const MAXIMUM_ATTRIBUTE_LENGTH: usize = 512; // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattcharacteristic #[dom_struct] pub struct BluetoothRemoteGATTCharacteristic { - reflector_: Reflector, + eventtarget: EventTarget, service: MutHeap>, uuid: DOMString, properties: MutHeap>, @@ -50,7 +53,7 @@ impl BluetoothRemoteGATTCharacteristic { instance_id: String) -> BluetoothRemoteGATTCharacteristic { BluetoothRemoteGATTCharacteristic { - reflector_: Reflector::new(), + eventtarget: EventTarget::new_inherited(), service: MutHeap::new(service), uuid: uuid, properties: MutHeap::new(properties), @@ -255,6 +258,9 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris sender)).unwrap(); return p; } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-characteristiceventhandlers-oncharacteristicvaluechanged + event_handler!(characteristicvaluechanged, GetOncharacteristicvaluechanged, SetOncharacteristicvaluechanged); } impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { @@ -297,6 +303,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { BluetoothResponse::ReadValue(result) => { let value = ByteString::new(result); *self.value.borrow_mut() = Some(value.clone()); + self.upcast::().fire_bubbling_event(atom!("characteristicvaluechanged")); promise.resolve_native(promise_cx, &value); }, BluetoothResponse::WriteValue(result) => { diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs index 69593e2c390..2f2206eb89a 100644 --- a/components/script/dom/bluetoothremotegattservice.rs +++ b/components/script/dom/bluetoothremotegattservice.rs @@ -8,15 +8,17 @@ use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMet use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods; +use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::error::Error::{self, Network, Security}; use dom::bindings::js::{JS, MutHeap, Root}; -use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::bluetooth::{AsyncBluetoothListener, response_async}; use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties; use dom::bluetoothdevice::BluetoothDevice; use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic; use dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUID, BluetoothUUID}; +use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::promise::Promise; use ipc_channel::ipc::IpcSender; @@ -26,7 +28,7 @@ use std::rc::Rc; // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice #[dom_struct] pub struct BluetoothRemoteGATTService { - reflector_: Reflector, + eventtarget: EventTarget, device: MutHeap>, uuid: DOMString, is_primary: bool, @@ -40,7 +42,7 @@ impl BluetoothRemoteGATTService { instance_id: String) -> BluetoothRemoteGATTService { BluetoothRemoteGATTService { - reflector_: Reflector::new(), + eventtarget: EventTarget::new_inherited(), device: MutHeap::new(device), uuid: uuid, is_primary: is_primary, @@ -217,6 +219,15 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService { sender)).unwrap(); return p; } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onserviceadded + event_handler!(serviceadded, GetOnserviceadded, SetOnserviceadded); + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onservicechanged + event_handler!(servicechanged, GetOnservicechanged, SetOnservicechanged); + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-serviceeventhandlers-onserviceremoved + event_handler!(serviceremoved, GetOnserviceremoved, SetOnserviceremoved); } impl AsyncBluetoothListener for BluetoothRemoteGATTService { diff --git a/components/script/dom/webidls/Bluetooth.webidl b/components/script/dom/webidls/Bluetooth.webidl index b925e0b0b25..de2b95c3fbb 100644 --- a/components/script/dom/webidls/Bluetooth.webidl +++ b/components/script/dom/webidls/Bluetooth.webidl @@ -28,9 +28,10 @@ dictionary RequestDeviceOptions { }; [Pref="dom.bluetooth.enabled"] -interface Bluetooth { +interface Bluetooth : EventTarget { // [SecureContext] // readonly attribute BluetoothDevice? referringDevice; + attribute EventHandler onavailabilitychanged; // [SecureContext] // Promise getAvailability(); // [SecureContext] diff --git a/components/script/dom/webidls/BluetoothDevice.webidl b/components/script/dom/webidls/BluetoothDevice.webidl index 34a77230850..0e7843db109 100644 --- a/components/script/dom/webidls/BluetoothDevice.webidl +++ b/components/script/dom/webidls/BluetoothDevice.webidl @@ -5,7 +5,7 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice [Pref="dom.bluetooth.enabled"] -interface BluetoothDevice { +interface BluetoothDevice : EventTarget { readonly attribute DOMString id; readonly attribute DOMString? name; // TODO: remove this after BluetoothAdvertisingEvent implemented. @@ -17,7 +17,12 @@ interface BluetoothDevice { // readonly attribute boolean watchingAdvertisements; }; +[NoInterfaceObject] +interface BluetoothDeviceEventHandlers { + attribute EventHandler ongattserverdisconnected; +}; + // BluetoothDevice implements EventTarget; -// BluetoothDevice implements BluetoothDeviceEventHandlers; +BluetoothDevice implements BluetoothDeviceEventHandlers; // BluetoothDevice implements CharacteristicEventHandlers; // BluetoothDevice implements ServiceEventHandlers; diff --git a/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl b/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl index d1d937475b4..55d7bf0a43c 100644 --- a/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl +++ b/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl @@ -5,7 +5,7 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattcharacteristic [Pref="dom.bluetooth.enabled"] -interface BluetoothRemoteGATTCharacteristic { +interface BluetoothRemoteGATTCharacteristic : EventTarget { readonly attribute BluetoothRemoteGATTService service; readonly attribute DOMString uuid; readonly attribute BluetoothCharacteristicProperties properties; @@ -21,5 +21,10 @@ interface BluetoothRemoteGATTCharacteristic { Promise stopNotifications(); }; -//BluetootRemoteGATTCharacteristic implements EventTarget; -//BluetootRemoteGATTCharacteristic implements CharacteristicEventHandlers; +[NoInterfaceObject] +interface CharacteristicEventHandlers { + attribute EventHandler oncharacteristicvaluechanged; +}; + +// BluetoothRemoteGATTCharacteristic implements EventTarget; +BluetoothRemoteGATTCharacteristic implements CharacteristicEventHandlers; diff --git a/components/script/dom/webidls/BluetoothRemoteGATTService.webidl b/components/script/dom/webidls/BluetoothRemoteGATTService.webidl index 715c2acbe1e..c39dcc1447a 100644 --- a/components/script/dom/webidls/BluetoothRemoteGATTService.webidl +++ b/components/script/dom/webidls/BluetoothRemoteGATTService.webidl @@ -5,7 +5,7 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice [Pref="dom.bluetooth.enabled"] -interface BluetoothRemoteGATTService { +interface BluetoothRemoteGATTService : EventTarget { readonly attribute BluetoothDevice device; readonly attribute DOMString uuid; readonly attribute boolean isPrimary; @@ -15,3 +15,14 @@ interface BluetoothRemoteGATTService { Promise getIncludedService(BluetoothServiceUUID service); Promise> getIncludedServices(optional BluetoothServiceUUID service); }; + +[NoInterfaceObject] +interface ServiceEventHandlers { + attribute EventHandler onserviceadded; + attribute EventHandler onservicechanged; + attribute EventHandler onserviceremoved; +}; + +// BluetoothRemoteGATTService implements EventTarget; +// BluetoothRemoteGATTService implements CharacteristicEventHandlers; +BluetoothRemoteGATTService implements ServiceEventHandlers; diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 45dfabb2d13..756879c3fdd 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -7268,6 +7268,12 @@ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html" } ], + "mozilla/bluetooth/readValue/characteristic/event-is-fired.html": [ + { + "path": "mozilla/bluetooth/readValue/characteristic/event-is-fired.html", + "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/event-is-fired.html" + } + ], "mozilla/bluetooth/readValue/characteristic/read-succeeds.html": [ { "path": "mozilla/bluetooth/readValue/characteristic/read-succeeds.html", diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/event-is-fired.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/event-is-fired.html new file mode 100644 index 00000000000..291bcf805a6 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/event-is-fired.html @@ -0,0 +1,35 @@ + + + + +