selma 0.4.15 → 0.5.1

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.
data/ext/selma/Cargo.toml CHANGED
@@ -12,7 +12,7 @@ magnus = { version = "0.8", features = ["rb-sys"] }
12
12
  rb-sys = { version = "*", default-features = false, features = [
13
13
  "stable-api-compiled-fallback",
14
14
  ] }
15
- lol_html = "2.7"
15
+ lol_html = "3.0"
16
16
 
17
17
  [lib]
18
18
  name = "selma"
@@ -2,7 +2,7 @@ use std::cell::RefCell;
2
2
 
3
3
  use crate::native_ref_wrap::NativeRefWrap;
4
4
  use lol_html::html_content::Element;
5
- use magnus::{exception, method, Error, Module, RArray, RClass, RHash, RString, Value};
5
+ use magnus::{method, Error, Module, RArray, RClass, RHash, Ruby, Value};
6
6
 
7
7
  struct HTMLElement {
8
8
  element: NativeRefWrap<Element<'static, 'static>>,
@@ -29,7 +29,7 @@ impl SelmaHTMLElement {
29
29
  match binding.element.get() {
30
30
  Ok(e) => Ok(e.tag_name().to_string()),
31
31
  Err(_) => Err(Error::new(
32
- exception::runtime_error(),
32
+ Ruby::get().unwrap().exception_runtime_error(),
33
33
  "`tag_name` is not available",
34
34
  )),
35
35
  }
@@ -37,15 +37,19 @@ impl SelmaHTMLElement {
37
37
 
38
38
  fn set_tag_name(&self, name: String) -> Result<(), Error> {
39
39
  let mut binding = self.0.borrow_mut();
40
+ let ruby = Ruby::get().unwrap();
40
41
 
41
42
  if let Ok(element) = binding.element.get_mut() {
42
43
  match element.set_tag_name(&name) {
43
44
  Ok(_) => Ok(()),
44
- Err(err) => Err(Error::new(exception::runtime_error(), format!("{err:?}"))),
45
+ Err(err) => Err(Error::new(
46
+ ruby.exception_runtime_error(),
47
+ format!("{err:?}"),
48
+ )),
45
49
  }
46
50
  } else {
47
51
  Err(Error::new(
48
- exception::runtime_error(),
52
+ ruby.exception_runtime_error(),
49
53
  "`set_tag_name` is not available",
50
54
  ))
51
55
  }
@@ -58,7 +62,7 @@ impl SelmaHTMLElement {
58
62
  Ok(e.is_self_closing())
59
63
  } else {
60
64
  Err(Error::new(
61
- exception::runtime_error(),
65
+ Ruby::get().unwrap().exception_runtime_error(),
62
66
  "`is_self_closing` is not available",
63
67
  ))
64
68
  }
@@ -71,7 +75,7 @@ impl SelmaHTMLElement {
71
75
  Ok(e.has_attribute(&attr))
72
76
  } else {
73
77
  Err(Error::new(
74
- exception::runtime_error(),
78
+ Ruby::get().unwrap().exception_runtime_error(),
75
79
  "`is_self_closing` is not available",
76
80
  ))
77
81
  }
@@ -85,17 +89,18 @@ impl SelmaHTMLElement {
85
89
 
86
90
  fn set_attribute(&self, attr: String, value: String) -> Result<String, Error> {
87
91
  let mut binding = self.0.borrow_mut();
92
+ let ruby = Ruby::get().unwrap();
88
93
  if let Ok(element) = binding.element.get_mut() {
89
94
  match element.set_attribute(&attr, &value) {
90
95
  Ok(_) => Ok(value),
91
96
  Err(err) => Err(Error::new(
92
- exception::runtime_error(),
97
+ ruby.exception_runtime_error(),
93
98
  format!("AttributeNameError: {err:?}"),
94
99
  )),
95
100
  }
96
101
  } else {
97
102
  Err(Error::new(
98
- exception::runtime_error(),
103
+ ruby.exception_runtime_error(),
99
104
  "`tag_name` is not available",
100
105
  ))
101
106
  }
@@ -109,9 +114,51 @@ impl SelmaHTMLElement {
109
114
  }
110
115
  }
111
116
 
117
+ fn get_attribute_source_location(&self, attr: String) -> Result<Option<RHash>, Error> {
118
+ let binding = self.0.borrow();
119
+ let ruby = Ruby::get().unwrap();
120
+
121
+ let Ok(e) = binding.element.get() else {
122
+ return Ok(None);
123
+ };
124
+
125
+ let lowered = attr.to_lowercase();
126
+ let attrs = e.attributes();
127
+ let Some(attribute) = attrs.iter().find(|a| a.name() == lowered) else {
128
+ return Ok(None);
129
+ };
130
+
131
+ let Some(name_loc) = attribute.name_source_location() else {
132
+ return Ok(None);
133
+ };
134
+
135
+ let hash = ruby.hash_new();
136
+ let name_range = name_loc.bytes();
137
+ hash.aset(
138
+ ruby.to_symbol("name"),
139
+ ruby.range_new(name_range.start, name_range.end, true)?,
140
+ )?;
141
+
142
+ match attribute.value_source_location() {
143
+ Some(loc) => {
144
+ let r = loc.bytes();
145
+ hash.aset(
146
+ ruby.to_symbol("value"),
147
+ ruby.range_new(r.start, r.end, true)?,
148
+ )?;
149
+ }
150
+ None => {
151
+ hash.aset(ruby.to_symbol("value"), ruby.qnil())?;
152
+ }
153
+ }
154
+
155
+ Ok(Some(hash))
156
+ }
157
+
112
158
  fn get_attributes(&self) -> Result<RHash, Error> {
113
159
  let binding = self.0.borrow();
114
- let hash = RHash::new();
160
+ let ruby = Ruby::get().unwrap();
161
+ let hash = ruby.hash_new();
115
162
 
116
163
  if let Ok(e) = binding.element.get() {
117
164
  e.attributes()
@@ -121,7 +168,7 @@ impl SelmaHTMLElement {
121
168
  Err(err) => panic!(
122
169
  "{:?}",
123
170
  Error::new(
124
- exception::runtime_error(),
171
+ ruby.exception_runtime_error(),
125
172
  format!("AttributeNameError: {err:?}"),
126
173
  )
127
174
  ),
@@ -132,17 +179,18 @@ impl SelmaHTMLElement {
132
179
 
133
180
  fn get_ancestors(&self) -> Result<RArray, Error> {
134
181
  let binding = self.0.borrow();
135
- let array = RArray::new();
182
+ let ruby = Ruby::get().unwrap();
183
+ let array = ruby.ary_new();
136
184
 
137
185
  binding
138
186
  .ancestors
139
187
  .iter()
140
- .for_each(|ancestor| match array.push(RString::new(ancestor)) {
188
+ .for_each(|ancestor| match array.push(ruby.str_new(ancestor)) {
141
189
  Ok(_) => {}
142
190
  Err(err) => {
143
191
  panic!(
144
192
  "{:?}",
145
- Error::new(exception::runtime_error(), format!("{err:?}"))
193
+ Error::new(ruby.exception_runtime_error(), format!("{err:?}"))
146
194
  )
147
195
  }
148
196
  });
@@ -244,7 +292,7 @@ impl SelmaHTMLElement {
244
292
  match binding.element.get() {
245
293
  Ok(e) => Ok(e.removed()),
246
294
  Err(_) => Err(Error::new(
247
- exception::runtime_error(),
295
+ Ruby::get().unwrap().exception_runtime_error(),
248
296
  "`is_removed` is not available",
249
297
  )),
250
298
  }
@@ -252,8 +300,9 @@ impl SelmaHTMLElement {
252
300
  }
253
301
 
254
302
  pub fn init(c_html: RClass) -> Result<(), Error> {
303
+ let ruby = Ruby::get().unwrap();
255
304
  let c_element = c_html
256
- .define_class("Element", magnus::class::object())
305
+ .define_class("Element", ruby.class_object())
257
306
  .expect("cannot define class Selma::HTML::Element");
258
307
 
259
308
  c_element.define_method("tag_name", method!(SelmaHTMLElement::tag_name, 0))?;
@@ -273,6 +322,10 @@ pub fn init(c_html: RClass) -> Result<(), Error> {
273
322
  method!(SelmaHTMLElement::has_attribute, 1),
274
323
  )?;
275
324
  c_element.define_method("attributes", method!(SelmaHTMLElement::get_attributes, 0))?;
325
+ c_element.define_method(
326
+ "attribute_source_location",
327
+ method!(SelmaHTMLElement::get_attribute_source_location, 1),
328
+ )?;
276
329
  c_element.define_method("ancestors", method!(SelmaHTMLElement::get_ancestors, 0))?;
277
330
 
278
331
  c_element.define_method("before", method!(SelmaHTMLElement::before, -1))?;
@@ -2,7 +2,7 @@ use std::cell::RefCell;
2
2
 
3
3
  use crate::native_ref_wrap::NativeRefWrap;
4
4
  use lol_html::html_content::EndTag;
5
- use magnus::{method, Error, Module, RClass};
5
+ use magnus::{method, Error, Module, RClass, Ruby};
6
6
 
7
7
  struct HTMLEndTag {
8
8
  end_tag: NativeRefWrap<EndTag<'static>>,
@@ -25,8 +25,9 @@ impl SelmaHTMLEndTag {
25
25
  }
26
26
 
27
27
  pub fn init(c_html: RClass) -> Result<(), Error> {
28
+ let ruby = Ruby::get().unwrap();
28
29
  let c_end_tag = c_html
29
- .define_class("EndTag", magnus::class::object())
30
+ .define_class("EndTag", ruby.class_object())
30
31
  .expect("cannot define class Selma::HTML::EndTag");
31
32
 
32
33
  c_end_tag.define_method("tag_name", method!(SelmaHTMLEndTag::tag_name, 0))?;
@@ -2,7 +2,7 @@ use std::cell::RefCell;
2
2
 
3
3
  use crate::native_ref_wrap::NativeRefWrap;
4
4
  use lol_html::html_content::{TextChunk, TextType};
5
- use magnus::{exception, method, Error, Module, RClass, Symbol, Value};
5
+ use magnus::{method, Error, Module, RClass, Ruby, Symbol, Value};
6
6
 
7
7
  struct HTMLTextChunk {
8
8
  text_chunk: NativeRefWrap<TextChunk<'static>>,
@@ -49,7 +49,7 @@ impl SelmaHTMLTextChunk {
49
49
  Ok(tc.as_str().to_string())
50
50
  } else {
51
51
  Err(Error::new(
52
- exception::runtime_error(),
52
+ Ruby::get().unwrap().exception_runtime_error(),
53
53
  "`to_s` is not available",
54
54
  ))
55
55
  }
@@ -57,19 +57,20 @@ impl SelmaHTMLTextChunk {
57
57
 
58
58
  fn text_type(&self) -> Result<Symbol, Error> {
59
59
  let binding = self.0.borrow();
60
+ let ruby = Ruby::get().unwrap();
60
61
 
61
62
  if let Ok(tc) = binding.text_chunk.get() {
62
63
  match tc.text_type() {
63
- TextType::Data => Ok(Symbol::new("data")),
64
- TextType::PlainText => Ok(Symbol::new("plain_text")),
65
- TextType::RawText => Ok(Symbol::new("raw_text")),
66
- TextType::ScriptData => Ok(Symbol::new("script")),
67
- TextType::RCData => Ok(Symbol::new("rc_data")),
68
- TextType::CDataSection => Ok(Symbol::new("cdata_section")),
64
+ TextType::Data => Ok(ruby.to_symbol("data")),
65
+ TextType::PlainText => Ok(ruby.to_symbol("plain_text")),
66
+ TextType::RawText => Ok(ruby.to_symbol("raw_text")),
67
+ TextType::ScriptData => Ok(ruby.to_symbol("script")),
68
+ TextType::RCData => Ok(ruby.to_symbol("rc_data")),
69
+ TextType::CDataSection => Ok(ruby.to_symbol("cdata_section")),
69
70
  }
70
71
  } else {
71
72
  Err(Error::new(
72
- exception::runtime_error(),
73
+ ruby.exception_runtime_error(),
73
74
  "`text_type` is not available",
74
75
  ))
75
76
  }
@@ -81,7 +82,7 @@ impl SelmaHTMLTextChunk {
81
82
  match binding.text_chunk.get() {
82
83
  Ok(tc) => Ok(tc.removed()),
83
84
  Err(_) => Err(Error::new(
84
- exception::runtime_error(),
85
+ Ruby::get().unwrap().exception_runtime_error(),
85
86
  "`is_removed` is not available",
86
87
  )),
87
88
  }
@@ -140,8 +141,9 @@ impl SelmaHTMLTextChunk {
140
141
  }
141
142
 
142
143
  pub fn init(c_html: RClass) -> Result<(), Error> {
144
+ let ruby = Ruby::get().unwrap();
143
145
  let c_text_chunk = c_html
144
- .define_class("TextChunk", magnus::class::object())
146
+ .define_class("TextChunk", ruby.class_object())
145
147
  .expect("cannot define class Selma::HTML::TextChunk");
146
148
 
147
149
  c_text_chunk.define_method("to_s", method!(SelmaHTMLTextChunk::to_s, 0))?;
@@ -1,12 +1,9 @@
1
- use magnus::{Error, Module, RModule};
2
-
3
- #[derive(Clone, Debug)]
4
- #[magnus::wrap(class = "Selma::HTML")]
5
- pub(crate) struct SelmaHTML {}
1
+ use magnus::{Error, Module, RModule, Ruby};
6
2
 
7
3
  pub fn init(m_selma: RModule) -> Result<(), Error> {
4
+ let ruby = Ruby::get().unwrap();
8
5
  let c_html = m_selma
9
- .define_class("HTML", magnus::class::object())
6
+ .define_class("HTML", ruby.class_object())
10
7
  .expect("cannot define class Selma::HTML");
11
8
 
12
9
  element::init(c_html).expect("cannot define Selma::HTML::Element class");
data/ext/selma/src/lib.rs CHANGED
@@ -1,7 +1,7 @@
1
1
  extern crate core;
2
2
 
3
3
  use lol_html::html_content::ContentType;
4
- use magnus::{define_module, exception, scan_args, Error, Symbol, Value};
4
+ use magnus::{scan_args, Error, Ruby, Symbol, Value};
5
5
 
6
6
  pub mod html;
7
7
  pub mod native_ref_wrap;
@@ -27,8 +27,9 @@ fn scan_text_args(args: &[Value]) -> Result<(String, ContentType), magnus::Error
27
27
  } else if as_sym_str == "html" {
28
28
  ContentType::Html
29
29
  } else {
30
+ let ruby = Ruby::get().unwrap();
30
31
  return Err(Error::new(
31
- exception::runtime_error(),
32
+ ruby.exception_runtime_error(),
32
33
  format!("unknown symbol `{as_sym_str:?}`"),
33
34
  ));
34
35
  };
@@ -37,8 +38,10 @@ fn scan_text_args(args: &[Value]) -> Result<(String, ContentType), magnus::Error
37
38
  }
38
39
 
39
40
  #[magnus::init]
40
- fn init() -> Result<(), Error> {
41
- let m_selma = define_module("Selma").expect("cannot define ::Selma module");
41
+ fn init(ruby: &Ruby) -> Result<(), Error> {
42
+ let m_selma = ruby
43
+ .define_module("Selma")
44
+ .expect("cannot define ::Selma module");
42
45
 
43
46
  sanitizer::init(m_selma).expect("cannot define Selma::Sanitizer class");
44
47
  rewriter::init(m_selma).expect("cannot define Selma::Rewriter class");
@@ -39,7 +39,7 @@ pub struct NativeRefWrap<R> {
39
39
  }
40
40
 
41
41
  impl<R> NativeRefWrap<R> {
42
- pub fn wrap<I>(inner: &mut I) -> (Self, Anchor) {
42
+ pub fn wrap<I>(inner: &mut I) -> (Self, Anchor<'_>) {
43
43
  let wrap = NativeRefWrap {
44
44
  inner_ptr: inner as *mut I as *mut R,
45
45
  poisoned: Arc::new(Mutex::new(false)),