Skip to content

Commit d816bc9

Browse files
committed
implement onMove
1 parent 5a09997 commit d816bc9

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ exclude = ["shell.nix", "nix/*"]
1212
[dependencies]
1313
js-sys = "0.3.60"
1414
wasm-bindgen = "0.2.83"
15-
web-sys = { version = "0.3.60", features = ["Element", "HtmlElement"] }
15+
web-sys = { version = "0.3.60", features = ["DomRect", "Element", "HtmlElement"] }

src/lib.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,57 @@ impl Event {
8888
}
8989
}
9090

91+
/// An event raised by one of the Sortable callbacks. See [the official documentation](https://github.com/SortableJS/Sortable/#move-event-object) for details about the fields.
92+
///
93+
/// `raw_event` contains the raw JS event, should additional non-documented
94+
/// fields be needed.
95+
#[derive(Clone, Debug)]
96+
pub struct MoveEvent {
97+
pub raw_event: js_sys::Object,
98+
pub to: web_sys::HtmlElement,
99+
pub from: web_sys::HtmlElement,
100+
pub dragged: web_sys::HtmlElement,
101+
// TODO: cast fails? pub dragged_rect: web_sys::DomRect,
102+
pub related: web_sys::HtmlElement,
103+
// TODO: cast fails? pub related_rect: web_sys::DomRect,
104+
pub will_insert_after: bool,
105+
}
106+
107+
impl MoveEvent {
108+
fn from_raw_event(raw_event: js_sys::Object) -> MoveEvent {
109+
macro_rules! get {
110+
($field:expr) => {
111+
js_sys::Reflect::get(&raw_event, &JsValue::from_str($field))
112+
.expect("failed retrieving field from raw event")
113+
.dyn_into()
114+
.expect("failed casting field of raw event to proper type")
115+
};
116+
}
117+
let will_insert_after =
118+
js_sys::Reflect::get(&raw_event, &JsValue::from_str("willInsertAfter"))
119+
.expect("failed retrieving field from raw event")
120+
.as_bool()
121+
.expect("willInsertAfter was not a boolean");
122+
MoveEvent {
123+
to: get!("to"),
124+
from: get!("from"),
125+
dragged: get!("dragged"),
126+
// dragged_rect: get!("draggedRect"),
127+
related: get!("related"),
128+
// related_rect: get!("relatedRect"),
129+
will_insert_after,
130+
raw_event,
131+
}
132+
}
133+
}
134+
135+
pub enum MoveResponse {
136+
Cancel,
137+
InsertBefore,
138+
InsertAfter,
139+
InsertDefault,
140+
}
141+
91142
#[repr(usize)]
92143
enum CallbackId {
93144
Choose,
@@ -109,6 +160,7 @@ enum CallbackId {
109160
pub struct Options {
110161
options: js_sys::Object,
111162
callbacks: [Option<Rc<Closure<dyn FnMut(js_sys::Object)>>>; CallbackId::_Total as usize],
163+
on_move_cb: Option<Rc<Closure<dyn FnMut(js_sys::Object, js_sys::Object) -> JsValue>>>,
112164
}
113165

114166
macro_rules! option {
@@ -148,6 +200,7 @@ impl Options {
148200
Options {
149201
options: js_sys::Object::new(),
150202
callbacks: std::array::from_fn(|_| None),
203+
on_move_cb: None,
151204
}
152205
}
153206

@@ -208,7 +261,24 @@ impl Options {
208261
callback!(on_clone, "onClone", Clone);
209262
callback!(on_change, "onChange", Change);
210263

211-
// TODO: onMove
264+
pub fn on_move(
265+
&mut self,
266+
mut cb: impl 'static + FnMut(MoveEvent, js_sys::Object) -> MoveResponse,
267+
) -> &Options {
268+
let cb = Closure::new(move |evt: js_sys::Object, original_evt: js_sys::Object| {
269+
match cb(MoveEvent::from_raw_event(evt), original_evt) {
270+
MoveResponse::Cancel => JsValue::FALSE,
271+
MoveResponse::InsertBefore => JsValue::from_f64(-1.),
272+
MoveResponse::InsertAfter => JsValue::from_f64(1.),
273+
MoveResponse::InsertDefault => JsValue::TRUE,
274+
}
275+
});
276+
let res = js_sys::Reflect::set(&self.options, &JsValue::from_str("onMove"), cb.as_ref())
277+
.expect("setting callback on object failed");
278+
assert!(res, "failed setting callback on object");
279+
self.on_move_cb = Some(Rc::new(cb));
280+
self
281+
}
212282

213283
// RevertOnSpill / RemoveOnSpill plugins
214284
option!(revert_on_spill, "revertOnSpill", bool, from_bool);
@@ -237,6 +307,7 @@ impl Options {
237307
raw_object,
238308
sortable,
239309
_callbacks: self.callbacks.clone(),
310+
_on_move_cb: self.on_move_cb.clone(),
240311
}
241312
}
242313
}
@@ -256,6 +327,7 @@ pub struct Sortable {
256327

257328
/// Keep the callbacks alive
258329
_callbacks: [Option<Rc<Closure<dyn FnMut(js_sys::Object)>>>; CallbackId::_Total as usize],
330+
_on_move_cb: Option<Rc<Closure<dyn FnMut(js_sys::Object, js_sys::Object) -> JsValue>>>,
259331
}
260332

261333
impl Drop for Sortable {

0 commit comments

Comments
 (0)