Skip to main content

script/dom/indexeddb/
idbversionchangeevent.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::cell::Cell;
6
7use dom_struct::dom_struct;
8use js::context::JSContext;
9use script_bindings::reflector::reflect_dom_object_with_proto_and_cx;
10use stylo_atoms::Atom;
11
12use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
13use crate::dom::bindings::codegen::Bindings::IDBVersionChangeEventBinding::{
14    IDBVersionChangeEventInit, IDBVersionChangeEventMethods,
15};
16use crate::dom::bindings::import::module::HandleObject;
17use crate::dom::bindings::inheritance::Castable;
18use crate::dom::bindings::root::DomRoot;
19use crate::dom::bindings::str::DOMString;
20use crate::dom::event::{Event, EventBubbles, EventCancelable};
21use crate::dom::eventtarget::EventTarget;
22use crate::dom::globalscope::GlobalScope;
23
24#[dom_struct]
25pub(crate) struct IDBVersionChangeEvent {
26    event: Event,
27    old_version: u64,
28    new_version: Option<u64>,
29}
30
31impl IDBVersionChangeEvent {
32    pub fn new_inherited(old_version: u64, new_version: Option<u64>) -> IDBVersionChangeEvent {
33        IDBVersionChangeEvent {
34            event: Event::new_inherited(),
35            old_version,
36            new_version,
37        }
38    }
39
40    pub fn new(
41        cx: &mut JSContext,
42        global: &GlobalScope,
43        type_: Atom,
44        bubbles: EventBubbles,
45        cancelable: EventCancelable,
46        old_version: u64,
47        new_version: Option<u64>,
48    ) -> DomRoot<IDBVersionChangeEvent> {
49        Self::new_with_proto(
50            cx,
51            global,
52            None,
53            type_,
54            bool::from(bubbles),
55            bool::from(cancelable),
56            old_version,
57            new_version,
58        )
59    }
60
61    #[expect(clippy::too_many_arguments)]
62    fn new_with_proto(
63        cx: &mut JSContext,
64        global: &GlobalScope,
65        proto: Option<HandleObject>,
66        type_: Atom,
67        bubbles: bool,
68        cancelable: bool,
69        old_version: u64,
70        new_version: Option<u64>,
71    ) -> DomRoot<Self> {
72        let ev = reflect_dom_object_with_proto_and_cx(
73            Box::new(IDBVersionChangeEvent::new_inherited(
74                old_version,
75                new_version,
76            )),
77            global,
78            proto,
79            cx,
80        );
81        {
82            let event = ev.upcast::<Event>();
83            event.init_event(type_, bubbles, cancelable);
84        }
85        ev
86    }
87
88    /// <https://w3c.github.io/IndexedDB/#fire-a-version-change-event>
89    pub(crate) fn fire_version_change_event(
90        cx: &mut JSContext,
91        global: &GlobalScope,
92        target: &EventTarget,
93        event_type: Atom,
94        old_version: u64,
95        new_version: Option<u64>,
96    ) -> bool {
97        // Step 1: Let event be the result of creating an event using IDBVersionChangeEvent.
98        // Step 2: Set event’s type attribute to e.
99        // Step 3: Set event’s bubbles and cancelable attributes to false.
100        // Step 4: Set event’s oldVersion attribute to oldVersion.
101        // Step 5: Set event’s newVersion attribute to newVersion.
102        let event = IDBVersionChangeEvent::new(
103            cx,
104            global,
105            event_type,
106            EventBubbles::DoesNotBubble,
107            EventCancelable::NotCancelable,
108            old_version,
109            new_version,
110        );
111
112        // Step 6: Let legacyOutputDidListenersThrowFlag be false.
113        let legacy_output_did_listeners_throw = Cell::new(false);
114        // Step 7: Dispatch event at target with legacyOutputDidListenersThrowFlag.
115        let _ = event
116            .upcast::<Event>()
117            .fire_with_legacy_output_did_listeners_throw(
118                cx,
119                target,
120                &legacy_output_did_listeners_throw,
121            );
122        // Step 8: Return legacyOutputDidListenersThrowFlag.
123        legacy_output_did_listeners_throw.get()
124    }
125}
126
127impl IDBVersionChangeEventMethods<crate::DomTypeHolder> for IDBVersionChangeEvent {
128    /// <https://w3c.github.io/IndexedDB/#dom-idbversionchangeevent-idbversionchangeevent>
129    fn Constructor(
130        cx: &mut JSContext,
131        global: &GlobalScope,
132        proto: Option<HandleObject>,
133        type_: DOMString,
134        init: &IDBVersionChangeEventInit,
135    ) -> DomRoot<Self> {
136        Self::new_with_proto(
137            cx,
138            global,
139            proto,
140            Atom::from(type_),
141            init.parent.bubbles,
142            init.parent.cancelable,
143            init.oldVersion,
144            init.newVersion,
145        )
146    }
147
148    /// <https://www.w3.org/TR/IndexedDB-3/#dom-idbversionchangeevent-oldversion>
149    fn OldVersion(&self) -> u64 {
150        self.old_version
151    }
152
153    /// <https://www.w3.org/TR/IndexedDB-3/#dom-idbversionchangeevent-newversion>
154    fn GetNewVersion(&self) -> Option<u64> {
155        self.new_version
156    }
157
158    /// <https://dom.spec.whatwg.org/#dom-event-istrusted>
159    fn IsTrusted(&self) -> bool {
160        self.event.IsTrusted()
161    }
162}