selma 0.4.4 → 0.4.5

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.
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