Skip to main content

leptos_tiptap/
js_tiptap.rs

1use cfg_if::cfg_if;
2use wasm_bindgen::{prelude::Closure, JsValue};
3
4use crate::TiptapHeadingLevel;
5
6#[cfg(not(feature = "ssr"))]
7mod js {
8    use wasm_bindgen::prelude::*;
9
10    #[wasm_bindgen(raw_module = "/js/tiptap.js")]
11    extern "C" {
12        pub fn create(
13            id: String,
14            content: String,
15            editable: bool,
16            onChange: &Closure<dyn Fn(String)>,
17            onSelection: &Closure<dyn Fn(JsValue)>,
18        );
19        pub fn destroy(id: String);
20        pub fn isEditable(id: String) -> bool;
21        pub fn setEditable(id: String, editable: bool);
22        pub fn getHTML(id: String) -> JsValue;
23        pub fn toggleHeading(id: String, level: i32) -> JsValue;
24        pub fn setParagraph(id: String) -> JsValue;
25        pub fn toggleBold(id: String) -> JsValue;
26        pub fn toggleItalic(id: String) -> JsValue;
27        pub fn toggleStrike(id: String) -> JsValue;
28        pub fn toggleBlockquote(id: String) -> JsValue;
29        pub fn toggleHighlight(id: String) -> JsValue;
30        pub fn toggleBulletList(id: String) -> JsValue;
31        pub fn toggleOrderedList(id: String) -> JsValue;
32        pub fn setTextAlignLeft(id: String) -> JsValue;
33        pub fn setTextAlignCenter(id: String) -> JsValue;
34        pub fn setTextAlignRight(id: String) -> JsValue;
35        pub fn setTextAlignJustify(id: String) -> JsValue;
36        pub fn setImage(id: String, src: String, alt: String, title: String) -> JsValue;
37        pub fn setLink(id: String, href: String, target: String, rel: String) -> JsValue;
38        pub fn toggleLink(id: String, href: String, target: String, rel: String) -> JsValue;
39        pub fn unsetLink(id: String) -> JsValue;
40        pub fn setYoutubeVideo(
41            id: String,
42            src: String,
43            start: String,
44            width: String,
45            height: String,
46        ) -> JsValue;
47        pub fn getEditorState(id: String) -> JsValue;
48        pub fn getSelectionState(id: String) -> JsValue;
49    }
50}
51
52// TODO: Decide what to do with currently unused functionality.
53
54pub fn create(
55    id: String,
56    content: String,
57    editable: bool,
58    on_change: &Closure<dyn Fn(String)>,
59    on_selection: &Closure<dyn Fn(JsValue)>,
60) {
61    cfg_if! {if #[cfg(not(feature = "ssr"))] {
62        js::create(id, content, editable, on_change, on_selection);
63    } else {
64        let _id = id;
65        let _content = content;
66        let _editable = editable;
67        let _on_change = on_change;
68        let _on_selection = on_selection;
69    }}
70}
71
72pub fn destroy(id: String) {
73    cfg_if! {if #[cfg(not(feature = "ssr"))] {
74        js::destroy(id);
75    } else {
76        let _id = id;
77    }}
78}
79
80// pub fn is_editable(id: String) -> bool {
81//     js::isEditable(id)
82// }
83
84pub fn set_editable(id: String, editable: bool) {
85    cfg_if! {if #[cfg(not(feature = "ssr"))] {
86        js::setEditable(id, editable);
87    } else {
88        let _id = id;
89        let _editable = editable;
90    }}
91}
92
93// pub fn get_html(id: String) -> String {
94//     let value = js::getHTML(id);
95//     match value.as_string() {
96//         Some(string) => string,
97//         None => {
98//             error!(
99//                 "JS function getHTML returned {:?}, which was not of the expected type: String",
100//                 value
101//             );
102//             "error".to_owned()
103//         }
104//     }
105// }
106
107pub fn toggle_heading(id: String, level: TiptapHeadingLevel) {
108    cfg_if! {if #[cfg(not(feature = "ssr"))] {
109        js::toggleHeading(id, level.into());
110    } else {
111        let _id = id;
112        let _level = level;
113    }}
114}
115
116pub fn set_paragraph(id: String) {
117    cfg_if! {if #[cfg(not(feature = "ssr"))] {
118        js::setParagraph(id);
119    } else {
120        let _id = id;
121    }}
122}
123
124pub fn toggle_bold(id: String) {
125    cfg_if! {if #[cfg(not(feature = "ssr"))] {
126        js::toggleBold(id);
127    } else {
128        let _id = id;
129    }}
130}
131
132pub fn toggle_italic(id: String) {
133    cfg_if! {if #[cfg(not(feature = "ssr"))] {
134        js::toggleItalic(id);
135    } else {
136        let _id = id;
137    }}
138}
139
140pub fn toggle_strike(id: String) {
141    cfg_if! {if #[cfg(not(feature = "ssr"))] {
142        js::toggleStrike(id);
143    } else {
144        let _id = id;
145    }}
146}
147
148pub fn toggle_blockquote(id: String) {
149    cfg_if! {if #[cfg(not(feature = "ssr"))] {
150        js::toggleBlockquote(id);
151    } else {
152        let _id = id;
153    }}
154}
155
156pub fn toggle_highlight(id: String) {
157    cfg_if! {if #[cfg(not(feature = "ssr"))] {
158        js::toggleHighlight(id);
159    } else {
160        let _id = id;
161    }}
162}
163
164pub fn toggle_bullet_list(id: String) {
165    cfg_if! {if #[cfg(not(feature = "ssr"))] {
166        js::toggleBulletList(id);
167    } else {
168        let _id = id;
169    }}
170}
171
172pub fn toggle_ordered_list(id: String) {
173    cfg_if! {if #[cfg(not(feature = "ssr"))] {
174        js::toggleOrderedList(id);
175    } else {
176        let _id = id;
177    }}
178}
179
180pub fn set_text_align_left(id: String) {
181    cfg_if! {if #[cfg(not(feature = "ssr"))] {
182        js::setTextAlignLeft(id);
183    } else {
184        let _id = id;
185    }}
186}
187
188pub fn set_text_align_center(id: String) {
189    cfg_if! {if #[cfg(not(feature = "ssr"))] {
190        js::setTextAlignCenter(id);
191    } else {
192        let _id = id;
193    }}
194}
195
196pub fn set_text_align_right(id: String) {
197    cfg_if! {if #[cfg(not(feature = "ssr"))] {
198        js::setTextAlignRight(id);
199    } else {
200        let _id = id;
201    }}
202}
203
204pub fn set_text_align_justify(id: String) {
205    cfg_if! {if #[cfg(not(feature = "ssr"))] {
206        js::setTextAlignJustify(id);
207    } else {
208        let _id = id;
209    }}
210}
211
212pub fn set_image(id: String, src: String, alt: String, title: String) {
213    cfg_if! {if #[cfg(not(feature = "ssr"))] {
214        js::setImage(id, src, alt, title);
215    } else {
216        let _id = id;
217        let _src = src;
218        let _alt = alt;
219        let _title = title;
220    }}
221}
222
223pub fn set_link(id: String, href: String, target: String, rel: String) {
224    cfg_if! {if #[cfg(not(feature = "ssr"))] {
225        js::setLink(id, href, target, rel);
226    } else {
227        let _id = id;
228        let _href = href;
229        let _target = target;
230        let _rel = rel;
231    }}
232}
233
234pub fn toggle_link(id: String, href: String, target: String, rel: String) {
235    cfg_if! {if #[cfg(not(feature = "ssr"))] {
236        js::toggleLink(id, href, target, rel);
237    } else {
238        let _id = id;
239        let _href = href;
240        let _target = target;
241        let _rel = rel;
242    }}
243}
244
245pub fn unset_link(id: String) {
246    cfg_if! {if #[cfg(not(feature = "ssr"))] {
247        js::unsetLink(id);
248    } else {
249        let _id = id;
250    }}
251}
252
253pub fn set_youtube_video(id: String, src: String, start: String, width: String, height: String) {
254    cfg_if! {if #[cfg(not(feature = "ssr"))] {
255        js::setYoutubeVideo(id, src, start, width, height);
256    } else {
257        let _id = id;
258        let _src = src;
259        let _start = start;
260        let _width = width;
261        let _height = height;
262    }}
263}
264
265// pub fn get_editor_state(id: String) -> Result<TiptapEditorState, serde_wasm_bindgen::Error> {
266//     serde_wasm_bindgen::from_value(js::getEditorState(id))
267// }
268
269// pub fn get_selection_state(id: String) -> Result<TiptapSelectionState, serde_wasm_bindgen::Error> {
270//     serde_wasm_bindgen::from_value(js::getSelectionState(id))
271// }