selma 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74ac7348cf564006d365a2d422b4966bbb7f9f2170fc72971945112f75fce9ee
4
- data.tar.gz: ff4872ca7d0a50c8a153947e3682a5cab10f5969c42dc8aa546d11c05efebb40
3
+ metadata.gz: b249e3518d3e0785aca5411ae2b06c1edd45d8034bbc94cc3e38b93fe10ea089
4
+ data.tar.gz: 23a2d098c40860bddc46f1c8cf9d5b96f06adc372997d7eb68a240a7415cab1a
5
5
  SHA512:
6
- metadata.gz: e3c92857028c55138b6d5a95e23f68815448a3cf1324920350eb864971002e4c1033508d61f28aa53df5174b7e14c2875714773249437e6c20e29c478c49956b
7
- data.tar.gz: 0de6e5cbb614e1cd1de5bf2e111a27a646673dc3c046b29048a8e99bce79a45198a30598e46d0b8e977e19faff80ebc110e05b91b39d2f4f662a2fc0f478ce35
6
+ metadata.gz: 0c93fb4e4b203f1d8aaeb992b12130910309525fdfc1a38ac8fed82d6b3e591d1c3c8cbd54f0a1ae4f9d7447389bc6613ed1b4e3cd9ea503d70b1c519ea75d0c
7
+ data.tar.gz: dd6f76b860ed68b353834eaf4f534296a3435703f78125f6845aeb6fdca553b22cbe76c24eec02f905b63a69712562bba16735945700e11ebfd2daf3a2757160
data/Cargo.lock CHANGED
@@ -303,9 +303,9 @@ dependencies = [
303
303
 
304
304
  [[package]]
305
305
  name = "magnus"
306
- version = "0.6.4"
306
+ version = "0.7.1"
307
307
  source = "registry+https://github.com/rust-lang/crates.io-index"
308
- checksum = "b1597ef40aa8c36be098249e82c9a20cf7199278ac1c1a1a995eeead6a184479"
308
+ checksum = "3d87ae53030f3a22e83879e666cb94e58a7bdf31706878a0ba48752994146dab"
309
309
  dependencies = [
310
310
  "magnus-macros",
311
311
  "rb-sys",
@@ -426,9 +426,13 @@ dependencies = [
426
426
 
427
427
  [[package]]
428
428
  name = "ppv-lite86"
429
- version = "0.2.17"
429
+ version = "0.2.19"
430
430
  source = "registry+https://github.com/rust-lang/crates.io-index"
431
- checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
431
+ checksum = "2288c0e17cc8d342c712bb43a257a80ebffce59cdb33d5000d8348f3ec02528b"
432
+ dependencies = [
433
+ "zerocopy",
434
+ "zerocopy-derive",
435
+ ]
432
436
 
433
437
  [[package]]
434
438
  name = "precomputed-hash"
@@ -804,6 +808,7 @@ version = "0.7.35"
804
808
  source = "registry+https://github.com/rust-lang/crates.io-index"
805
809
  checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
806
810
  dependencies = [
811
+ "byteorder",
807
812
  "zerocopy-derive",
808
813
  ]
809
814
 
data/ext/selma/Cargo.toml CHANGED
@@ -8,7 +8,7 @@ publish = false
8
8
  [dependencies]
9
9
  enum-iterator = "2.1"
10
10
  escapist = "0.0.2"
11
- magnus = { version = "0.6", features = ["rb-sys"] }
11
+ magnus = { version = "0.7", features = ["rb-sys"] }
12
12
  rb-sys = { version = "*", default-features = false, features = [
13
13
  "stable-api-compiled-fallback",
14
14
  ] }
@@ -1,3 +1,5 @@
1
+ use std::cell::RefCell;
2
+
1
3
  use crate::native_ref_wrap::NativeRefWrap;
2
4
  use lol_html::html_content::Element;
3
5
  use magnus::{exception, method, Error, Module, RArray, RClass, RHash, RString, Value};
@@ -8,16 +10,14 @@ struct HTMLElement {
8
10
  }
9
11
 
10
12
  #[magnus::wrap(class = "Selma::HTML::Element")]
11
- pub struct SelmaHTMLElement(std::cell::RefCell<HTMLElement>);
13
+ pub struct SelmaHTMLElement(RefCell<HTMLElement>);
12
14
 
13
15
  /// SAFETY: This is safe because we only access this data when the GVL is held.
14
16
  unsafe impl Send for SelmaHTMLElement {}
15
17
 
16
18
  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 {
19
+ pub fn new(ref_wrap: NativeRefWrap<Element<'static, 'static>>, ancestors: &[String]) -> Self {
20
+ Self(RefCell::new(HTMLElement {
21
21
  element: ref_wrap,
22
22
  ancestors: ancestors.to_owned(),
23
23
  }))
@@ -26,13 +26,12 @@ impl SelmaHTMLElement {
26
26
  fn tag_name(&self) -> Result<String, Error> {
27
27
  let binding = self.0.borrow();
28
28
 
29
- if let Ok(e) = binding.element.get() {
30
- Ok(e.tag_name())
31
- } else {
32
- Err(Error::new(
29
+ match binding.element.get() {
30
+ Ok(e) => Ok(e.tag_name().to_string()),
31
+ Err(_) => Err(Error::new(
33
32
  exception::runtime_error(),
34
33
  "`tag_name` is not available",
35
- ))
34
+ )),
36
35
  }
37
36
  }
38
37
 
@@ -229,24 +228,25 @@ impl SelmaHTMLElement {
229
228
  }
230
229
  }
231
230
 
232
- fn remove_and_keep_content(&self) {
233
- let mut binding = self.0.borrow_mut();
234
-
235
- if let Ok(e) = binding.element.get_mut() {
236
- e.remove_and_keep_content()
237
- }
231
+ fn remove_and_keep_content(&self) -> Result<(), Error> {
232
+ self.0
233
+ .borrow_mut()
234
+ .element
235
+ .get_mut()
236
+ .unwrap()
237
+ .remove_and_keep_content();
238
+ Ok(())
238
239
  }
239
240
 
240
241
  fn is_removed(&self) -> Result<bool, Error> {
241
242
  let binding = self.0.borrow();
242
243
 
243
- if let Ok(e) = binding.element.get() {
244
- Ok(e.removed())
245
- } else {
246
- Err(Error::new(
244
+ match binding.element.get() {
245
+ Ok(e) => Ok(e.removed()),
246
+ Err(_) => Err(Error::new(
247
247
  exception::runtime_error(),
248
248
  "`is_removed` is not available",
249
- ))
249
+ )),
250
250
  }
251
251
  }
252
252
  }
@@ -1,3 +1,5 @@
1
+ use std::cell::RefCell;
2
+
1
3
  use crate::native_ref_wrap::NativeRefWrap;
2
4
  use lol_html::html_content::EndTag;
3
5
  use magnus::{method, Error, Module, RClass};
@@ -7,16 +9,14 @@ struct HTMLEndTag {
7
9
  }
8
10
 
9
11
  #[magnus::wrap(class = "Selma::HTML::EndTag")]
10
- pub struct SelmaHTMLEndTag(std::cell::RefCell<HTMLEndTag>);
12
+ pub struct SelmaHTMLEndTag(RefCell<HTMLEndTag>);
11
13
 
12
14
  /// SAFETY: This is safe because we only access this data when the GVL is held.
13
15
  unsafe impl Send for SelmaHTMLEndTag {}
14
16
 
15
17
  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 }))
18
+ pub fn new(ref_wrap: NativeRefWrap<EndTag<'static>>) -> Self {
19
+ Self(RefCell::new(HTMLEndTag { end_tag: ref_wrap }))
20
20
  }
21
21
 
22
22
  fn tag_name(&self) -> String {
@@ -1,3 +1,5 @@
1
+ use std::cell::RefCell;
2
+
1
3
  use crate::native_ref_wrap::NativeRefWrap;
2
4
  use lol_html::html_content::{TextChunk, TextType};
3
5
  use magnus::{exception, method, Error, Module, RClass, Symbol, Value};
@@ -7,16 +9,14 @@ struct HTMLTextChunk {
7
9
  }
8
10
 
9
11
  #[magnus::wrap(class = "Selma::HTML::TextChunk")]
10
- pub struct SelmaHTMLTextChunk(std::cell::RefCell<HTMLTextChunk>);
12
+ pub struct SelmaHTMLTextChunk(RefCell<HTMLTextChunk>);
11
13
 
12
14
  /// SAFETY: This is safe because we only access this data when the GVL is held.
13
15
  unsafe impl Send for SelmaHTMLTextChunk {}
14
16
 
15
17
  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 {
18
+ pub fn new(ref_wrap: NativeRefWrap<TextChunk<'static>>) -> Self {
19
+ Self(RefCell::new(HTMLTextChunk {
20
20
  text_chunk: ref_wrap,
21
21
  }))
22
22
  }
@@ -54,6 +54,18 @@ impl SelmaHTMLTextChunk {
54
54
  }
55
55
  }
56
56
 
57
+ fn is_removed(&self) -> Result<bool, Error> {
58
+ let binding = self.0.borrow();
59
+
60
+ match binding.text_chunk.get() {
61
+ Ok(tc) => Ok(tc.removed()),
62
+ Err(_) => Err(Error::new(
63
+ exception::runtime_error(),
64
+ "`is_removed` is not available",
65
+ )),
66
+ }
67
+ }
68
+
57
69
  fn before(&self, args: &[Value]) -> Result<(), Error> {
58
70
  let mut binding = self.0.borrow_mut();
59
71
  let text_chunk = binding.text_chunk.get_mut().unwrap();
@@ -108,6 +120,7 @@ pub fn init(c_html: RClass) -> Result<(), Error> {
108
120
  c_text_chunk.define_method("before", method!(SelmaHTMLTextChunk::before, -1))?;
109
121
  c_text_chunk.define_method("after", method!(SelmaHTMLTextChunk::after, -1))?;
110
122
  c_text_chunk.define_method("replace", method!(SelmaHTMLTextChunk::replace, -1))?;
123
+ c_text_chunk.define_method("removed?", method!(SelmaHTMLTextChunk::is_removed, 0))?;
111
124
 
112
125
  Ok(())
113
126
  }
@@ -3,7 +3,8 @@ use std::{
3
3
  sync::{Arc, Mutex},
4
4
  };
5
5
 
6
- // NOTE: this was taken from https://github.com/cloudflare/lol-html/blob/1a1ab2e2bf896f815fe8888ed78ccdf46d7c6b85/js-api/src/lib.rs#LL38
6
+ // NOTE: this was inspired from
7
+ // https://github.com/worker-tools/html-rewriter-wasm/blob/92bafdfa34c809c37036f57cb282184cada3bbc9/src/handlers.rs
7
8
 
8
9
  pub struct Anchor<'r> {
9
10
  poisoned: Arc<Mutex<bool>>,
@@ -19,27 +20,28 @@ impl<'r> Anchor<'r> {
19
20
  }
20
21
  }
21
22
 
22
- // impl Drop for Anchor<'_> {
23
- // fn drop(&mut self) {
24
- // *self.poisoned.lock().unwrap() = true;
25
- // }
26
- // }
23
+ impl Drop for Anchor<'_> {
24
+ fn drop(&mut self) {
25
+ *self.poisoned.lock().unwrap() = true;
26
+ }
27
+ }
27
28
 
28
- // NOTE: wasm_bindgen doesn't allow structures with lifetimes. To workaround that
29
- // we create a wrapper that erases all the lifetime information from the inner reference
29
+ // NOTE: So far as I understand it, there's no great wya to work between lol_html's lifetimes and FFI.
30
+ // To work around that, we create a wrapper that erases all the lifetime information from the inner reference
30
31
  // and provides an anchor object that keeps track of the lifetime in the runtime.
31
32
  //
32
33
  // When anchor goes out of scope, wrapper becomes poisoned and any attempt to get inner
33
34
  // object results in exception.
35
+ #[derive(Clone)]
34
36
  pub struct NativeRefWrap<R> {
35
37
  inner_ptr: *mut R,
36
38
  poisoned: Arc<Mutex<bool>>,
37
39
  }
38
40
 
39
41
  impl<R> NativeRefWrap<R> {
40
- pub fn wrap<I>(inner: &I) -> (Self, Anchor) {
42
+ pub fn wrap<I>(inner: &mut I) -> (Self, Anchor) {
41
43
  let wrap = NativeRefWrap {
42
- inner_ptr: inner as *const I as *mut R,
44
+ inner_ptr: inner as *mut I as *mut R,
43
45
  poisoned: Arc::new(Mutex::new(false)),
44
46
  };
45
47
 
@@ -48,15 +50,16 @@ impl<R> NativeRefWrap<R> {
48
50
  (wrap, anchor)
49
51
  }
50
52
 
51
- pub fn wrap_mut<I>(inner: &mut I) -> (Self, Anchor) {
52
- let wrap = NativeRefWrap {
53
- inner_ptr: inner as *mut I as *mut R,
54
- poisoned: Arc::new(Mutex::new(false)),
55
- };
56
-
57
- let anchor = Anchor::new(Arc::clone(&wrap.poisoned));
53
+ fn assert_not_poisoned(&self) -> Result<(), &'static str> {
54
+ if self.is_poisoned() {
55
+ Err("The object has been freed and can't be used anymore.")
56
+ } else {
57
+ Ok(())
58
+ }
59
+ }
58
60
 
59
- (wrap, anchor)
61
+ pub fn is_poisoned(&self) -> bool {
62
+ *self.poisoned.lock().unwrap()
60
63
  }
61
64
 
62
65
  pub fn get(&self) -> Result<&R, &'static str> {
@@ -70,13 +73,4 @@ impl<R> NativeRefWrap<R> {
70
73
 
71
74
  Ok(unsafe { self.inner_ptr.as_mut() }.unwrap())
72
75
  }
73
-
74
- fn assert_not_poisoned(&self) -> Result<(), &'static str> {
75
- let lock = self.poisoned.lock().unwrap();
76
- if *lock {
77
- Err("The object has been freed and can't be used anymore.")
78
- } else {
79
- Ok(())
80
- }
81
- }
82
76
  }
@@ -5,17 +5,19 @@ use lol_html::{
5
5
  Settings,
6
6
  };
7
7
  use magnus::{
8
- exception, function, method,
8
+ exception, function, gc, method,
9
9
  r_hash::ForEach,
10
10
  scan_args,
11
11
  typed_data::Obj,
12
12
  value::{Opaque, ReprValue},
13
- Integer, IntoValue, Module, Object, RArray, RHash, RModule, Ruby, Symbol, Value,
13
+ DataTypeFunctions, Integer, IntoValue, Module, Object, RArray, RHash, RModule, Ruby, Symbol,
14
+ TypedData, Value,
14
15
  };
15
16
 
16
17
  use std::{
17
18
  borrow::Cow,
18
19
  cell::{Ref, RefCell},
20
+ mem,
19
21
  ops::Deref,
20
22
  primitive::str,
21
23
  rc::Rc,
@@ -23,31 +25,15 @@ use std::{
23
25
 
24
26
  use crate::{
25
27
  html::{element::SelmaHTMLElement, end_tag::SelmaHTMLEndTag, text_chunk::SelmaHTMLTextChunk},
28
+ native_ref_wrap::NativeRefWrap,
26
29
  sanitizer::SelmaSanitizer,
27
30
  selector::SelmaSelector,
28
31
  tags::Tag,
29
32
  };
30
33
 
31
- #[derive(Copy, Clone)]
32
- pub struct ObjectValue {
33
- pub inner: Opaque<Value>,
34
- }
35
-
36
- impl IntoValue for ObjectValue {
37
- fn into_value_with(self, _: &Ruby) -> Value {
38
- Ruby::get().unwrap().get_inner(self.inner)
39
- }
40
- }
41
-
42
- impl From<Value> for ObjectValue {
43
- fn from(v: Value) -> Self {
44
- Self { inner: v.into() }
45
- }
46
- }
47
-
48
34
  #[derive(Clone)]
49
35
  pub struct Handler {
50
- rb_handler: ObjectValue,
36
+ rb_handler: Opaque<Value>,
51
37
  rb_selector: Opaque<Obj<SelmaSelector>>,
52
38
  // total_element_handler_calls: usize,
53
39
  // total_elapsed_element_handlers: f64,
@@ -67,9 +53,18 @@ pub struct Rewriter {
67
53
  // total_elapsed: f64,
68
54
  }
69
55
 
70
- #[magnus::wrap(class = "Selma::Rewriter")]
56
+ #[derive(TypedData)]
57
+ #[magnus(class = "Selma::Rewriter", free_immediately, mark)]
71
58
  pub struct SelmaRewriter(std::cell::RefCell<Rewriter>);
72
59
 
60
+ impl DataTypeFunctions for SelmaRewriter {
61
+ fn mark(&self, marker: &gc::Marker) {
62
+ self.0.borrow().handlers.iter().for_each(|handler| {
63
+ marker.mark(handler.rb_handler);
64
+ });
65
+ }
66
+ }
67
+
73
68
  type RewriterValues = (
74
69
  Option<Option<Obj<SelmaSanitizer>>>,
75
70
  Option<RArray>,
@@ -112,9 +107,7 @@ impl SelmaRewriter {
112
107
  Some(rb_handlers) => {
113
108
  let mut handlers: Vec<Handler> = vec![];
114
109
 
115
- for h in rb_handlers.each() {
116
- let rb_handler = h.unwrap();
117
-
110
+ for rb_handler in rb_handlers.into_iter() {
118
111
  // prevents missing #selector from ruining things
119
112
  if !rb_handler.respond_to("selector", true).unwrap() {
120
113
  let classname = unsafe { rb_handler.classname() };
@@ -137,7 +130,7 @@ impl SelmaRewriter {
137
130
  Ok(rb_selector) => rb_selector,
138
131
  };
139
132
  let handler = Handler {
140
- rb_handler: ObjectValue::from(rb_handler),
133
+ rb_handler: Opaque::from(rb_handler),
141
134
  rb_selector: Opaque::from(rb_selector),
142
135
  // total_element_handler_calls: 0,
143
136
  // total_elapsed_element_handlers: 0.0,
@@ -296,6 +289,7 @@ impl SelmaRewriter {
296
289
  if el.removed() {
297
290
  return Ok(());
298
291
  }
292
+ // if it was removed, there are no attributes to sanitize
299
293
  match sanitizer.sanitize_attributes(el) {
300
294
  Ok(_) => Ok(()),
301
295
  Err(err) => Err(err.to_string().into()),
@@ -390,7 +384,7 @@ impl SelmaRewriter {
390
384
  selector.match_element().unwrap(),
391
385
  move |el| {
392
386
  match Self::process_element_handlers(
393
- handler.rb_handler,
387
+ handler,
394
388
  el,
395
389
  &closure_element_stack.borrow(),
396
390
  ) {
@@ -421,7 +415,7 @@ impl SelmaRewriter {
421
415
  }
422
416
  }
423
417
 
424
- match Self::process_text_handlers(handler.rb_handler, text) {
418
+ match Self::process_text_handlers(handler, text) {
425
419
  Ok(_) => Ok(()),
426
420
  Err(err) => Err(err.to_string().into()),
427
421
  }
@@ -493,11 +487,11 @@ impl SelmaRewriter {
493
487
  }
494
488
 
495
489
  fn process_element_handlers(
496
- obj_rb_handler: ObjectValue,
490
+ handler: &Handler,
497
491
  element: &mut Element,
498
492
  ancestors: &[String],
499
493
  ) -> Result<(), magnus::Error> {
500
- let rb_handler = Ruby::get().unwrap().get_inner(obj_rb_handler.inner);
494
+ let rb_handler = handler.rb_handler.into_value();
501
495
 
502
496
  // if `on_end_tag` function is defined, call it
503
497
  if rb_handler.respond_to(Self::SELMA_ON_END_TAG, true).unwrap() {
@@ -506,33 +500,42 @@ impl SelmaRewriter {
506
500
  .end_tag_handlers()
507
501
  .unwrap()
508
502
  .push(Box::new(move |end_tag| {
509
- let rb_end_tag = SelmaHTMLEndTag::new(end_tag);
503
+ let (ref_wrap, anchor) = NativeRefWrap::wrap(end_tag);
504
+
505
+ let rb_end_tag = SelmaHTMLEndTag::new(ref_wrap);
510
506
 
511
- match rb_handler.funcall::<_, _, Value>(Self::SELMA_ON_END_TAG, (rb_end_tag,)) {
507
+ let result =
508
+ rb_handler.funcall::<_, _, Value>(Self::SELMA_ON_END_TAG, (rb_end_tag,));
509
+
510
+ mem::drop(anchor);
511
+
512
+ match result {
512
513
  Ok(_) => Ok(()),
513
514
  Err(err) => Err(err.to_string().into()),
514
515
  }
515
516
  }));
516
517
  }
517
518
 
518
- if element.removed() {
519
- return Ok(());
520
- }
519
+ let (ref_wrap, anchor) = NativeRefWrap::wrap(element);
520
+ let rb_element = SelmaHTMLElement::new(ref_wrap, ancestors);
521
+ let result = rb_handler.funcall::<_, _, Value>(Self::SELMA_HANDLE_ELEMENT, (rb_element,));
521
522
 
522
- let rb_element = SelmaHTMLElement::new(element, ancestors);
523
- let rb_result =
524
- rb_handler.funcall::<_, _, Value>(Self::SELMA_HANDLE_ELEMENT, (rb_element,));
525
- match rb_result {
523
+ mem::drop(anchor);
524
+
525
+ match result {
526
526
  Ok(_) => Ok(()),
527
- Err(err) => Err(err),
527
+ Err(err) => Err(magnus::Error::new(
528
+ exception::runtime_error(),
529
+ format!("{err:?}"),
530
+ )),
528
531
  }
529
532
  }
530
533
 
531
534
  fn process_text_handlers(
532
- obj_rb_handler: ObjectValue,
535
+ handler: &Handler,
533
536
  text_chunk: &mut TextChunk,
534
537
  ) -> Result<(), magnus::Error> {
535
- let rb_handler = Ruby::get().unwrap().get_inner(obj_rb_handler.inner);
538
+ let rb_handler = handler.rb_handler.into_value();
536
539
 
537
540
  // prevents missing `handle_text_chunk` function
538
541
  let content = text_chunk.as_str();
@@ -542,8 +545,15 @@ impl SelmaRewriter {
542
545
  return Ok(());
543
546
  }
544
547
 
545
- let rb_text_chunk = SelmaHTMLTextChunk::new(text_chunk);
546
- match rb_handler.funcall::<_, _, Value>(Self::SELMA_HANDLE_TEXT_CHUNK, (rb_text_chunk,)) {
548
+ let (ref_wrap, anchor) = NativeRefWrap::wrap(text_chunk);
549
+
550
+ let rb_text_chunk = SelmaHTMLTextChunk::new(ref_wrap);
551
+ let result =
552
+ rb_handler.funcall::<_, _, Value>(Self::SELMA_HANDLE_TEXT_CHUNK, (rb_text_chunk,));
553
+
554
+ mem::drop(anchor);
555
+
556
+ match result {
547
557
  Ok(_) => Ok(()),
548
558
  Err(err) => Err(magnus::Error::new(
549
559
  exception::runtime_error(),
@@ -200,8 +200,7 @@ impl SelmaSanitizer {
200
200
 
201
201
  let protocol_sanitizers = &mut element_sanitizer.protocol_sanitizers.borrow_mut();
202
202
 
203
- for opt_allowed_protocol in allow_list.each() {
204
- let allowed_protocol = opt_allowed_protocol.unwrap();
203
+ for allowed_protocol in allow_list.into_iter() {
205
204
  let protocol_list = protocol_sanitizers.get_mut(&attr_name);
206
205
  if allowed_protocol.is_kind_of(class::string()) {
207
206
  match protocol_list {
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Selma
4
+ class HTML
5
+ class Element
6
+ def available?
7
+ !removed?
8
+ end
9
+ end
10
+ end
11
+ end
data/lib/selma/html.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "html/element"
4
+
3
5
  module Selma
4
6
  class HTML
5
7
  end
data/lib/selma/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Selma
4
- VERSION = "0.4.4"
4
+ VERSION = "0.4.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen J. Torikian
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-29 00:00:00.000000000 Z
11
+ date: 2024-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys
@@ -80,6 +80,7 @@ files:
80
80
  - lib/selma/config.rb
81
81
  - lib/selma/extension.rb
82
82
  - lib/selma/html.rb
83
+ - lib/selma/html/element.rb
83
84
  - lib/selma/rewriter.rb
84
85
  - lib/selma/sanitizer.rb
85
86
  - lib/selma/sanitizer/config.rb