selma 0.0.6-x86_64-linux → 0.1.0-x86_64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,254 +0,0 @@
1
- use crate::native_ref_wrap::NativeRefWrap;
2
- use lol_html::html_content::Element;
3
- use magnus::{exception, method, Error, Module, RArray, RClass, RHash, RString, Value};
4
-
5
- struct HTMLElement {
6
- element: NativeRefWrap<Element<'static, 'static>>,
7
- ancestors: Vec<String>,
8
- }
9
-
10
- #[magnus::wrap(class = "Selma::HTML::Element")]
11
- pub struct SelmaHTMLElement(std::cell::RefCell<HTMLElement>);
12
-
13
- /// SAFETY: This is safe because we only access this data when the GVL is held.
14
- unsafe impl Send for SelmaHTMLElement {}
15
-
16
- impl SelmaHTMLElement {
17
- pub fn new(element: &mut Element, ancestors: &[String]) -> Self {
18
- let (ref_wrap, _anchor) = NativeRefWrap::wrap_mut(element);
19
-
20
- Self(std::cell::RefCell::new(HTMLElement {
21
- element: ref_wrap,
22
- ancestors: ancestors.to_owned(),
23
- }))
24
- }
25
-
26
- fn tag_name(&self) -> Result<String, Error> {
27
- let binding = self.0.borrow();
28
-
29
- if let Ok(e) = binding.element.get() {
30
- Ok(e.tag_name())
31
- } else {
32
- Err(Error::new(
33
- exception::runtime_error(),
34
- "`tag_name` is not available",
35
- ))
36
- }
37
- }
38
-
39
- fn set_tag_name(&self, name: String) -> Result<(), Error> {
40
- let mut binding = self.0.borrow_mut();
41
-
42
- if let Ok(element) = binding.element.get_mut() {
43
- match element.set_tag_name(&name) {
44
- Ok(_) => Ok(()),
45
- Err(err) => Err(Error::new(exception::runtime_error(), format!("{err:?}"))),
46
- }
47
- } else {
48
- Err(Error::new(
49
- exception::runtime_error(),
50
- "`set_tag_name` is not available",
51
- ))
52
- }
53
- }
54
-
55
- fn is_self_closing(&self) -> Result<bool, Error> {
56
- let binding = self.0.borrow();
57
-
58
- if let Ok(e) = binding.element.get() {
59
- Ok(e.is_self_closing())
60
- } else {
61
- Err(Error::new(
62
- exception::runtime_error(),
63
- "`is_self_closing` is not available",
64
- ))
65
- }
66
- }
67
-
68
- fn has_attribute(&self, attr: String) -> Result<bool, Error> {
69
- let binding = self.0.borrow();
70
-
71
- if let Ok(e) = binding.element.get() {
72
- Ok(e.has_attribute(&attr))
73
- } else {
74
- Err(Error::new(
75
- exception::runtime_error(),
76
- "`is_self_closing` is not available",
77
- ))
78
- }
79
- }
80
-
81
- fn get_attribute(&self, attr: String) -> Option<String> {
82
- let binding = self.0.borrow();
83
- let element = binding.element.get();
84
- element.unwrap().get_attribute(&attr)
85
- }
86
-
87
- fn set_attribute(&self, attr: String, value: String) -> Result<String, Error> {
88
- let mut binding = self.0.borrow_mut();
89
- if let Ok(element) = binding.element.get_mut() {
90
- match element.set_attribute(&attr, &value) {
91
- Ok(_) => Ok(value),
92
- Err(err) => Err(Error::new(
93
- exception::runtime_error(),
94
- format!("AttributeNameError: {err:?}"),
95
- )),
96
- }
97
- } else {
98
- Err(Error::new(
99
- exception::runtime_error(),
100
- "`tag_name` is not available",
101
- ))
102
- }
103
- }
104
-
105
- fn remove_attribute(&self, attr: String) {
106
- let mut binding = self.0.borrow_mut();
107
-
108
- if let Ok(e) = binding.element.get_mut() {
109
- e.remove_attribute(&attr)
110
- }
111
- }
112
-
113
- fn get_attributes(&self) -> Result<RHash, Error> {
114
- let binding = self.0.borrow();
115
- let hash = RHash::new();
116
-
117
- if let Ok(e) = binding.element.get() {
118
- e.attributes()
119
- .iter()
120
- .for_each(|attr| match hash.aset(attr.name(), attr.value()) {
121
- Ok(_) => {}
122
- Err(err) => Err(Error::new(
123
- exception::runtime_error(),
124
- format!("AttributeNameError: {err:?}"),
125
- ))
126
- .unwrap(),
127
- });
128
- }
129
- Ok(hash)
130
- }
131
-
132
- fn get_ancestors(&self) -> Result<RArray, Error> {
133
- let binding = self.0.borrow();
134
- let array = RArray::new();
135
-
136
- binding
137
- .ancestors
138
- .iter()
139
- .for_each(|ancestor| match array.push(RString::new(ancestor)) {
140
- Ok(_) => {}
141
- Err(err) => {
142
- Err(Error::new(exception::runtime_error(), format!("{err:?}"))).unwrap()
143
- }
144
- });
145
-
146
- Ok(array)
147
- }
148
-
149
- fn before(&self, args: &[Value]) -> Result<(), Error> {
150
- let mut binding = self.0.borrow_mut();
151
- let element = binding.element.get_mut().unwrap();
152
-
153
- let (text_str, content_type) = match crate::scan_text_args(args) {
154
- Ok((text_str, content_type)) => (text_str, content_type),
155
- Err(err) => return Err(err),
156
- };
157
-
158
- element.before(&text_str, content_type);
159
-
160
- Ok(())
161
- }
162
-
163
- fn after(&self, args: &[Value]) -> Result<(), Error> {
164
- let mut binding = self.0.borrow_mut();
165
- let element = binding.element.get_mut().unwrap();
166
-
167
- let (text_str, content_type) = match crate::scan_text_args(args) {
168
- Ok((text_str, content_type)) => (text_str, content_type),
169
- Err(err) => return Err(err),
170
- };
171
-
172
- element.after(&text_str, content_type);
173
-
174
- Ok(())
175
- }
176
-
177
- fn prepend(&self, args: &[Value]) -> Result<(), Error> {
178
- let mut binding = self.0.borrow_mut();
179
- let element = binding.element.get_mut().unwrap();
180
-
181
- let (text_str, content_type) = match crate::scan_text_args(args) {
182
- Ok((text_str, content_type)) => (text_str, content_type),
183
- Err(err) => return Err(err),
184
- };
185
-
186
- element.prepend(&text_str, content_type);
187
-
188
- Ok(())
189
- }
190
-
191
- fn append(&self, args: &[Value]) -> Result<(), Error> {
192
- let mut binding = self.0.borrow_mut();
193
- let element = binding.element.get_mut().unwrap();
194
-
195
- let (text_str, content_type) = match crate::scan_text_args(args) {
196
- Ok((text_str, content_type)) => (text_str, content_type),
197
- Err(err) => return Err(err),
198
- };
199
-
200
- element.append(&text_str, content_type);
201
-
202
- Ok(())
203
- }
204
-
205
- fn set_inner_content(&self, args: &[Value]) -> Result<(), Error> {
206
- let mut binding = self.0.borrow_mut();
207
- let element = binding.element.get_mut().unwrap();
208
-
209
- let (inner_content, content_type) = match crate::scan_text_args(args) {
210
- Ok((inner_content, content_type)) => (inner_content, content_type),
211
- Err(err) => return Err(err),
212
- };
213
-
214
- element.set_inner_content(&inner_content, content_type);
215
-
216
- Ok(())
217
- }
218
- }
219
-
220
- pub fn init(c_html: RClass) -> Result<(), Error> {
221
- let c_element = c_html
222
- .define_class("Element", Default::default())
223
- .expect("cannot find class Selma::HTML::Element");
224
-
225
- c_element.define_method("tag_name", method!(SelmaHTMLElement::tag_name, 0))?;
226
- c_element.define_method("tag_name=", method!(SelmaHTMLElement::set_tag_name, 1))?;
227
- c_element.define_method(
228
- "self_closing?",
229
- method!(SelmaHTMLElement::is_self_closing, 0),
230
- )?;
231
- c_element.define_method("[]", method!(SelmaHTMLElement::get_attribute, 1))?;
232
- c_element.define_method("[]=", method!(SelmaHTMLElement::set_attribute, 2))?;
233
- c_element.define_method(
234
- "remove_attribute",
235
- method!(SelmaHTMLElement::remove_attribute, 1),
236
- )?;
237
- c_element.define_method(
238
- "has_attribute?",
239
- method!(SelmaHTMLElement::has_attribute, 1),
240
- )?;
241
- c_element.define_method("attributes", method!(SelmaHTMLElement::get_attributes, 0))?;
242
- c_element.define_method("ancestors", method!(SelmaHTMLElement::get_ancestors, 0))?;
243
-
244
- c_element.define_method("before", method!(SelmaHTMLElement::before, -1))?;
245
- c_element.define_method("after", method!(SelmaHTMLElement::after, -1))?;
246
- c_element.define_method("prepend", method!(SelmaHTMLElement::prepend, -1))?;
247
- c_element.define_method("append", method!(SelmaHTMLElement::append, -1))?;
248
- c_element.define_method(
249
- "set_inner_content",
250
- method!(SelmaHTMLElement::set_inner_content, -1),
251
- )?;
252
-
253
- Ok(())
254
- }
@@ -1,35 +0,0 @@
1
- use crate::native_ref_wrap::NativeRefWrap;
2
- use lol_html::html_content::EndTag;
3
- use magnus::{method, Error, Module, RClass};
4
-
5
- struct HTMLEndTag {
6
- end_tag: NativeRefWrap<EndTag<'static>>,
7
- }
8
-
9
- #[magnus::wrap(class = "Selma::HTML::EndTag")]
10
- pub struct SelmaHTMLEndTag(std::cell::RefCell<HTMLEndTag>);
11
-
12
- /// SAFETY: This is safe because we only access this data when the GVL is held.
13
- unsafe impl Send for SelmaHTMLEndTag {}
14
-
15
- impl SelmaHTMLEndTag {
16
- pub fn new(end_tag: &mut EndTag) -> Self {
17
- let (ref_wrap, _anchor) = NativeRefWrap::wrap(end_tag);
18
-
19
- Self(std::cell::RefCell::new(HTMLEndTag { end_tag: ref_wrap }))
20
- }
21
-
22
- fn tag_name(&self) -> String {
23
- self.0.borrow().end_tag.get().unwrap().name()
24
- }
25
- }
26
-
27
- pub fn init(c_html: RClass) -> Result<(), Error> {
28
- let c_end_tag = c_html
29
- .define_class("EndTag", Default::default())
30
- .expect("cannot find class Selma::HTML::EndTag");
31
-
32
- c_end_tag.define_method("tag_name", method!(SelmaHTMLEndTag::tag_name, 0))?;
33
-
34
- Ok(())
35
- }
@@ -1,113 +0,0 @@
1
- use crate::native_ref_wrap::NativeRefWrap;
2
- use lol_html::html_content::{TextChunk, TextType};
3
- use magnus::{exception, method, Error, Module, RClass, Symbol, Value};
4
-
5
- struct HTMLTextChunk {
6
- text_chunk: NativeRefWrap<TextChunk<'static>>,
7
- }
8
-
9
- #[magnus::wrap(class = "Selma::HTML::TextChunk")]
10
- pub struct SelmaHTMLTextChunk(std::cell::RefCell<HTMLTextChunk>);
11
-
12
- /// SAFETY: This is safe because we only access this data when the GVL is held.
13
- unsafe impl Send for SelmaHTMLTextChunk {}
14
-
15
- impl SelmaHTMLTextChunk {
16
- pub fn new(text_chunk: &mut TextChunk) -> Self {
17
- let (ref_wrap, _anchor) = NativeRefWrap::wrap_mut(text_chunk);
18
-
19
- Self(std::cell::RefCell::new(HTMLTextChunk {
20
- text_chunk: ref_wrap,
21
- }))
22
- }
23
-
24
- fn to_s(&self) -> Result<String, Error> {
25
- let binding = self.0.borrow();
26
-
27
- if let Ok(tc) = binding.text_chunk.get() {
28
- Ok(tc.as_str().to_string())
29
- } else {
30
- Err(Error::new(
31
- exception::runtime_error(),
32
- "`to_s` is not available",
33
- ))
34
- }
35
- }
36
-
37
- fn text_type(&self) -> Result<Symbol, Error> {
38
- let binding = self.0.borrow();
39
-
40
- if let Ok(tc) = binding.text_chunk.get() {
41
- match tc.text_type() {
42
- TextType::Data => Ok(Symbol::from("data")),
43
- TextType::PlainText => Ok(Symbol::from("plain_text")),
44
- TextType::RawText => Ok(Symbol::from("raw_text")),
45
- TextType::ScriptData => Ok(Symbol::from("script")),
46
- TextType::RCData => Ok(Symbol::from("rc_data")),
47
- TextType::CDataSection => Ok(Symbol::from("cdata_section")),
48
- }
49
- } else {
50
- Err(Error::new(
51
- exception::runtime_error(),
52
- "`text_type` is not available",
53
- ))
54
- }
55
- }
56
-
57
- fn before(&self, args: &[Value]) -> Result<(), Error> {
58
- let mut binding = self.0.borrow_mut();
59
- let text_chunk = binding.text_chunk.get_mut().unwrap();
60
-
61
- let (text_str, content_type) = match crate::scan_text_args(args) {
62
- Ok((text_str, content_type)) => (text_str, content_type),
63
- Err(err) => return Err(err),
64
- };
65
-
66
- text_chunk.before(&text_str, content_type);
67
-
68
- Ok(())
69
- }
70
-
71
- fn after(&self, args: &[Value]) -> Result<(), Error> {
72
- let mut binding = self.0.borrow_mut();
73
- let text_chunk = binding.text_chunk.get_mut().unwrap();
74
-
75
- let (text_str, content_type) = match crate::scan_text_args(args) {
76
- Ok((text_str, content_type)) => (text_str, content_type),
77
- Err(err) => return Err(err),
78
- };
79
-
80
- text_chunk.after(&text_str, content_type);
81
-
82
- Ok(())
83
- }
84
-
85
- fn replace(&self, args: &[Value]) -> Result<(), Error> {
86
- let mut binding = self.0.borrow_mut();
87
- let text_chunk = binding.text_chunk.get_mut().unwrap();
88
-
89
- let (text_str, content_type) = match crate::scan_text_args(args) {
90
- Ok((text_str, content_type)) => (text_str, content_type),
91
- Err(err) => return Err(err),
92
- };
93
-
94
- text_chunk.replace(&text_str, content_type);
95
-
96
- Ok(())
97
- }
98
- }
99
-
100
- pub fn init(c_html: RClass) -> Result<(), Error> {
101
- let c_text_chunk = c_html
102
- .define_class("TextChunk", Default::default())
103
- .expect("cannot find class Selma::HTML::TextChunk");
104
-
105
- c_text_chunk.define_method("to_s", method!(SelmaHTMLTextChunk::to_s, 0))?;
106
- c_text_chunk.define_method("content", method!(SelmaHTMLTextChunk::to_s, 0))?;
107
- c_text_chunk.define_method("text_type", method!(SelmaHTMLTextChunk::text_type, 0))?;
108
- c_text_chunk.define_method("before", method!(SelmaHTMLTextChunk::before, -1))?;
109
- c_text_chunk.define_method("after", method!(SelmaHTMLTextChunk::after, -1))?;
110
- c_text_chunk.define_method("replace", method!(SelmaHTMLTextChunk::replace, -1))?;
111
-
112
- Ok(())
113
- }
@@ -1,19 +0,0 @@
1
- use magnus::{Error, Module, RModule};
2
-
3
- #[derive(Clone, Debug)]
4
- #[magnus::wrap(class = "Selma::HTML")]
5
- pub(crate) struct SelmaHTML {}
6
-
7
- pub fn init(m_selma: RModule) -> Result<(), Error> {
8
- let c_html = m_selma.define_class("HTML", Default::default()).unwrap();
9
-
10
- element::init(c_html).expect("cannot define Selma::HTML::Element class");
11
- end_tag::init(c_html).expect("cannot define Selma::HTML::EndTag class");
12
- text_chunk::init(c_html).expect("cannot define Selma::HTML::TextChunk class");
13
-
14
- Ok(())
15
- }
16
-
17
- pub mod element;
18
- pub mod end_tag;
19
- pub mod text_chunk;
data/ext/selma/src/lib.rs DELETED
@@ -1,50 +0,0 @@
1
- extern crate core;
2
-
3
- use lol_html::html_content::ContentType;
4
- use magnus::{define_module, exception, scan_args, Error, Symbol, Value};
5
-
6
- pub mod html;
7
- pub mod native_ref_wrap;
8
- pub mod rewriter;
9
- pub mod sanitizer;
10
- pub mod selector;
11
- pub mod tags;
12
- pub mod wrapped_struct;
13
-
14
- #[allow(clippy::let_unit_value)]
15
- fn scan_text_args(args: &[Value]) -> Result<(String, ContentType), magnus::Error> {
16
- let args = scan_args::scan_args(args)?;
17
- let (text,): (String,) = args.required;
18
- let _: () = args.optional;
19
- let _: () = args.splat;
20
- let _: () = args.trailing;
21
- let _: () = args.block;
22
-
23
- let kwargs = scan_args::get_kwargs::<_, (Symbol,), (), ()>(args.keywords, &["as"], &[])?;
24
- let as_sym = kwargs.required.0;
25
- let as_sym_str = as_sym.name().unwrap();
26
- let content_type = if as_sym_str == "text" {
27
- ContentType::Text
28
- } else if as_sym_str == "html" {
29
- ContentType::Html
30
- } else {
31
- return Err(Error::new(
32
- exception::runtime_error(),
33
- format!("unknown symbol `{as_sym_str:?}`"),
34
- ));
35
- };
36
-
37
- Ok((text, content_type))
38
- }
39
-
40
- #[magnus::init]
41
- fn init() -> Result<(), Error> {
42
- let m_selma = define_module("Selma").expect("cannot define ::Selma module");
43
-
44
- sanitizer::init(m_selma).expect("cannot define Selma::Sanitizer class");
45
- rewriter::init(m_selma).expect("cannot define Selma::Rewriter class");
46
- html::init(m_selma).expect("cannot define Selma::HTML class");
47
- selector::init(m_selma).expect("cannot define Selma::Selector class");
48
-
49
- Ok(())
50
- }
@@ -1,79 +0,0 @@
1
- use std::{cell::Cell, marker::PhantomData, rc::Rc};
2
-
3
- // NOTE: My Rust isn't good enough to know what any of this does,
4
- // but it was taken from https://github.com/cloudflare/lol-html/blob/1a1ab2e2bf896f815fe8888ed78ccdf46d7c6b85/js-api/src/lib.rs#LL38
5
-
6
- pub struct Anchor<'r> {
7
- poisoned: Rc<Cell<bool>>,
8
- lifetime: PhantomData<&'r mut ()>,
9
- }
10
-
11
- impl<'r> Anchor<'r> {
12
- pub fn new(poisoned: Rc<Cell<bool>>) -> Self {
13
- Anchor {
14
- poisoned,
15
- lifetime: PhantomData,
16
- }
17
- }
18
- }
19
-
20
- // impl Drop for Anchor<'_> {
21
- // fn drop(&mut self) {
22
- // self.poisoned.replace(true);
23
- // }
24
- // }
25
-
26
- // NOTE: wasm_bindgen doesn't allow structures with lifetimes. To workaround that
27
- // we create a wrapper that erases all the lifetime information from the inner reference
28
- // and provides an anchor object that keeps track of the lifetime in the runtime.
29
- //
30
- // When anchor goes out of scope, wrapper becomes poisoned and any attempt to get inner
31
- // object results in exception.
32
- pub struct NativeRefWrap<R> {
33
- inner_ptr: *mut R,
34
- poisoned: Rc<Cell<bool>>,
35
- }
36
-
37
- impl<R> NativeRefWrap<R> {
38
- pub fn wrap<I>(inner: &I) -> (Self, Anchor) {
39
- let wrap = NativeRefWrap {
40
- inner_ptr: inner as *const I as *mut R,
41
- poisoned: Rc::new(Cell::new(false)),
42
- };
43
-
44
- let anchor = Anchor::new(Rc::clone(&wrap.poisoned));
45
-
46
- (wrap, anchor)
47
- }
48
-
49
- pub fn wrap_mut<I>(inner: &mut I) -> (Self, Anchor) {
50
- let wrap = NativeRefWrap {
51
- inner_ptr: inner as *mut I as *mut R,
52
- poisoned: Rc::new(Cell::new(false)),
53
- };
54
-
55
- let anchor = Anchor::new(Rc::clone(&wrap.poisoned));
56
-
57
- (wrap, anchor)
58
- }
59
-
60
- pub fn get(&self) -> Result<&R, &'static str> {
61
- self.assert_not_poisoned()?;
62
-
63
- Ok(unsafe { self.inner_ptr.as_ref() }.unwrap())
64
- }
65
-
66
- pub fn get_mut(&mut self) -> Result<&mut R, &'static str> {
67
- self.assert_not_poisoned()?;
68
-
69
- Ok(unsafe { self.inner_ptr.as_mut() }.unwrap())
70
- }
71
-
72
- fn assert_not_poisoned(&self) -> Result<(), &'static str> {
73
- if self.poisoned.get() {
74
- Err("The object has been freed and can't be used anymore.")
75
- } else {
76
- Ok(())
77
- }
78
- }
79
- }