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;
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;
23use crate::script_runtime::CanGc;
24
25#[dom_struct]
26pub(crate) struct IDBVersionChangeEvent {
27    event: Event,
28    old_version: u64,
29    new_version: Option<u64>,
30}
31
32impl IDBVersionChangeEvent {
33    pub fn new_inherited(old_version: u64, new_version: Option<u64>) -> IDBVersionChangeEvent {
34        IDBVersionChangeEvent {
35            event: Event::new_inherited(),
36            old_version,
37            new_version,
38        }
39    }
40
41    pub fn new(
42        global: &GlobalScope,
43        type_: Atom,
44        bubbles: EventBubbles,
45        cancelable: EventCancelable,
46        old_version: u64,
47        new_version: Option<u64>,
48        can_gc: CanGc,
49    ) -> DomRoot<IDBVersionChangeEvent> {
50        Self::new_with_proto(
51            global,
52            None,
53            type_,
54            bool::from(bubbles),
55            bool::from(cancelable),
56            old_version,
57            new_version,
58            can_gc,
59        )
60    }
61
62    #[expect(clippy::too_many_arguments)]
63    fn new_with_proto(
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        can_gc: CanGc,
72    ) -> DomRoot<Self> {
73        let ev = reflect_dom_object_with_proto(
74            Box::new(IDBVersionChangeEvent::new_inherited(
75                old_version,
76                new_version,
77            )),
78            global,
79            proto,
80            can_gc,
81        );
82        {
83            let event = ev.upcast::<Event>();
84            event.init_event(type_, bubbles, cancelable);
85        }
86        ev
87    }
88
89    /// <https://w3c.github.io/IndexedDB/#fire-a-version-change-event>
90    pub(crate) fn fire_version_change_event(
91        cx: &mut JSContext,
92        global: &GlobalScope,
93        target: &EventTarget,
94        event_type: Atom,
95        old_version: u64,
96        new_version: Option<u64>,
97    ) -> bool {
98        // Step 1: Let event be the result of creating an event using IDBVersionChangeEvent.
99        // Step 2: Set event’s type attribute to e.
100        // Step 3: Set event’s bubbles and cancelable attributes to false.
101        // Step 4: Set event’s oldVersion attribute to oldVersion.
102        // Step 5: Set event’s newVersion attribute to newVersion.
103        let event = IDBVersionChangeEvent::new(
104            global,
105            event_type,
106            EventBubbles::DoesNotBubble,
107            EventCancelable::NotCancelable,
108            old_version,
109            new_version,
110            CanGc::from_cx(cx),
111        );
112
113        // Step 6: Let legacyOutputDidListenersThrowFlag be false.
114        let legacy_output_did_listeners_throw = Cell::new(false);
115        // Step 7: Dispatch event at target with legacyOutputDidListenersThrowFlag.
116        let _ = event
117            .upcast::<Event>()
118            .fire_with_legacy_output_did_listeners_throw(
119                cx,
120                target,
121                &legacy_output_did_listeners_throw,
122            );
123        // Step 8: Return legacyOutputDidListenersThrowFlag.
124        legacy_output_did_listeners_throw.get()
125    }
126}
127
128impl IDBVersionChangeEventMethods<crate::DomTypeHolder> for IDBVersionChangeEvent {
129    /// <https://w3c.github.io/IndexedDB/#dom-idbversionchangeevent-idbversionchangeevent>
130    fn Constructor(
131        global: &GlobalScope,
132        proto: Option<HandleObject>,
133        can_gc: CanGc,
134        type_: DOMString,
135        init: &IDBVersionChangeEventInit,
136    ) -> DomRoot<Self> {
137        Self::new_with_proto(
138            global,
139            proto,
140            Atom::from(type_),
141            init.parent.bubbles,
142            init.parent.cancelable,
143            init.oldVersion,
144            init.newVersion,
145            can_gc,
146        )
147    }
148
149    /// <https://www.w3.org/TR/IndexedDB-3/#dom-idbversionchangeevent-oldversion>
150    fn OldVersion(&self) -> u64 {
151        self.old_version
152    }
153
154    /// <https://www.w3.org/TR/IndexedDB-3/#dom-idbversionchangeevent-newversion>
155    fn GetNewVersion(&self) -> Option<u64> {
156        self.new_version
157    }
158
159    /// <https://dom.spec.whatwg.org/#dom-event-istrusted>
160    fn IsTrusted(&self) -> bool {
161        self.event.IsTrusted()
162    }
163}