css_inline 0.16.0 → 0.18.0
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 +4 -4
- data/Cargo.lock +276 -351
- data/README.md +31 -2
- data/ext/css_inline/Cargo.lock +276 -351
- data/ext/css_inline/Cargo.toml +5 -5
- data/ext/css_inline/src/lib.rs +77 -52
- metadata +3 -3
data/ext/css_inline/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
|
-
name = "css-inline"
|
|
3
|
-
version = "0.
|
|
2
|
+
name = "css-inline-ruby"
|
|
3
|
+
version = "0.18.0"
|
|
4
4
|
authors = ["Dmitry Dygalo <dmitry@dygalo.dev>"]
|
|
5
5
|
edition = "2021"
|
|
6
6
|
readme = "README.rdoc"
|
|
@@ -9,17 +9,17 @@ repository = "https://github.com/Stranger6667/css-inline"
|
|
|
9
9
|
keywords = ["css", "html", "email", "stylesheet", "inlining"]
|
|
10
10
|
categories = ["web-programming"]
|
|
11
11
|
license = "MIT"
|
|
12
|
-
rust-version = "1.
|
|
12
|
+
rust-version = "1.83"
|
|
13
13
|
|
|
14
14
|
[lib]
|
|
15
15
|
name = "css_inline"
|
|
16
16
|
crate-type = ["cdylib"]
|
|
17
17
|
|
|
18
18
|
[dependencies]
|
|
19
|
-
magnus = "0.
|
|
19
|
+
magnus = "0.8"
|
|
20
20
|
rayon = "1"
|
|
21
21
|
|
|
22
22
|
[dependencies.css-inline]
|
|
23
|
-
version = "0.
|
|
23
|
+
version = "0.18.0"
|
|
24
24
|
default-features = false
|
|
25
25
|
features = ["http", "file", "stylesheet-cache"]
|
data/ext/css_inline/src/lib.rs
CHANGED
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
)]
|
|
28
28
|
use css_inline as rust_inline;
|
|
29
29
|
use magnus::{
|
|
30
|
-
|
|
30
|
+
function, method,
|
|
31
31
|
prelude::*,
|
|
32
32
|
scan_args::{get_kwargs, scan_args, Args},
|
|
33
33
|
typed_data::Obj,
|
|
34
|
-
DataTypeFunctions, RHash, TypedData, Value,
|
|
34
|
+
DataTypeFunctions, RHash, Ruby, TryConvert, TypedData, Value,
|
|
35
35
|
};
|
|
36
36
|
use rayon::prelude::*;
|
|
37
37
|
use std::{
|
|
@@ -42,49 +42,72 @@ use std::{
|
|
|
42
42
|
|
|
43
43
|
type RubyResult<T> = Result<T, magnus::Error>;
|
|
44
44
|
|
|
45
|
+
#[allow(clippy::struct_excessive_bools)]
|
|
46
|
+
struct Options {
|
|
47
|
+
/// Whether to inline CSS from "style" tags.
|
|
48
|
+
///
|
|
49
|
+
/// Sometimes HTML may include a lot of boilerplate styles, that are not applicable in every
|
|
50
|
+
/// scenario, and it is useful to ignore them and use `extra_css` instead.
|
|
51
|
+
inline_style_tags: Option<bool>,
|
|
52
|
+
/// Keep "style" tags after inlining.
|
|
53
|
+
keep_style_tags: Option<bool>,
|
|
54
|
+
/// Keep "link" tags after inlining.
|
|
55
|
+
keep_link_tags: Option<bool>,
|
|
56
|
+
/// Keep "at-rules" after inlining.
|
|
57
|
+
keep_at_rules: Option<bool>,
|
|
58
|
+
/// Remove trailing semicolons and spaces between properties and values.
|
|
59
|
+
minify_css: Option<bool>,
|
|
60
|
+
/// Used for loading external stylesheets via relative URLs.
|
|
61
|
+
base_url: Option<String>,
|
|
62
|
+
/// Whether remote stylesheets should be loaded or not.
|
|
63
|
+
load_remote_stylesheets: Option<bool>,
|
|
64
|
+
/// An LRU Cache for external stylesheets.
|
|
65
|
+
cache: Option<Obj<StylesheetCache>>,
|
|
66
|
+
/// Additional CSS to inline.
|
|
67
|
+
extra_css: Option<String>,
|
|
68
|
+
/// Pre-allocate capacity for HTML nodes during parsing.
|
|
69
|
+
/// It can improve performance when you have an estimate of the number of nodes in your HTML document.
|
|
70
|
+
preallocate_node_capacity: Option<usize>,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
impl TryConvert for Options {
|
|
74
|
+
fn try_convert(v: Value) -> Result<Self, magnus::Error> {
|
|
75
|
+
let h = RHash::try_convert(v)?;
|
|
76
|
+
let ruby = Ruby::get_with(v);
|
|
77
|
+
Ok(Self {
|
|
78
|
+
inline_style_tags: h.aref::<_, Option<bool>>(ruby.to_symbol("inline_style_tags"))?,
|
|
79
|
+
keep_style_tags: h.aref::<_, Option<bool>>(ruby.to_symbol("keep_style_tags"))?,
|
|
80
|
+
keep_link_tags: h.aref::<_, Option<bool>>(ruby.to_symbol("keep_link_tags"))?,
|
|
81
|
+
keep_at_rules: h.aref::<_, Option<bool>>(ruby.to_symbol("keep_at_rules"))?,
|
|
82
|
+
minify_css: h.aref::<_, Option<bool>>(ruby.to_symbol("minify_css"))?,
|
|
83
|
+
base_url: h.aref::<_, Option<String>>(ruby.to_symbol("base_url"))?,
|
|
84
|
+
load_remote_stylesheets: h
|
|
85
|
+
.aref::<_, Option<bool>>(ruby.to_symbol("load_remote_stylesheets"))?,
|
|
86
|
+
cache: h.aref::<_, Option<Obj<StylesheetCache>>>(ruby.to_symbol("cache"))?,
|
|
87
|
+
extra_css: h.aref::<_, Option<String>>(ruby.to_symbol("extra_css"))?,
|
|
88
|
+
preallocate_node_capacity: h
|
|
89
|
+
.aref::<_, Option<usize>>(ruby.to_symbol("preallocate_node_capacity"))?,
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
45
94
|
fn parse_options<Req>(
|
|
46
95
|
args: &Args<Req, (), (), (), RHash, ()>,
|
|
47
96
|
) -> RubyResult<rust_inline::InlineOptions<'static>> {
|
|
48
|
-
let kwargs =
|
|
49
|
-
_,
|
|
50
|
-
(),
|
|
51
|
-
(
|
|
52
|
-
Option<bool>,
|
|
53
|
-
Option<bool>,
|
|
54
|
-
Option<bool>,
|
|
55
|
-
Option<String>,
|
|
56
|
-
Option<bool>,
|
|
57
|
-
Option<Obj<StylesheetCache>>,
|
|
58
|
-
Option<String>,
|
|
59
|
-
Option<usize>,
|
|
60
|
-
),
|
|
61
|
-
(),
|
|
62
|
-
>(
|
|
63
|
-
args.keywords,
|
|
64
|
-
&[],
|
|
65
|
-
&[
|
|
66
|
-
"inline_style_tags",
|
|
67
|
-
"keep_style_tags",
|
|
68
|
-
"keep_link_tags",
|
|
69
|
-
"base_url",
|
|
70
|
-
"load_remote_stylesheets",
|
|
71
|
-
"cache",
|
|
72
|
-
"extra_css",
|
|
73
|
-
"preallocate_node_capacity",
|
|
74
|
-
],
|
|
75
|
-
)?;
|
|
76
|
-
let kwargs = kwargs.optional;
|
|
97
|
+
let kwargs: Options = Options::try_convert(args.keywords.as_value())?;
|
|
77
98
|
Ok(rust_inline::InlineOptions {
|
|
78
|
-
inline_style_tags: kwargs.
|
|
79
|
-
keep_style_tags: kwargs.
|
|
80
|
-
keep_link_tags: kwargs.
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
inline_style_tags: kwargs.inline_style_tags.unwrap_or(true),
|
|
100
|
+
keep_style_tags: kwargs.keep_style_tags.unwrap_or(false),
|
|
101
|
+
keep_link_tags: kwargs.keep_link_tags.unwrap_or(false),
|
|
102
|
+
keep_at_rules: kwargs.keep_at_rules.unwrap_or(false),
|
|
103
|
+
minify_css: kwargs.minify_css.unwrap_or(false),
|
|
104
|
+
base_url: parse_url(kwargs.base_url)?,
|
|
105
|
+
load_remote_stylesheets: kwargs.load_remote_stylesheets.unwrap_or(true),
|
|
83
106
|
cache: kwargs
|
|
84
|
-
.
|
|
107
|
+
.cache
|
|
85
108
|
.map(|cache| Mutex::new(rust_inline::StylesheetCache::new(cache.size))),
|
|
86
|
-
extra_css: kwargs.
|
|
87
|
-
preallocate_node_capacity: kwargs.
|
|
109
|
+
extra_css: kwargs.extra_css.map(Cow::Owned),
|
|
110
|
+
preallocate_node_capacity: kwargs.preallocate_node_capacity.unwrap_or(32),
|
|
88
111
|
resolver: Arc::new(rust_inline::DefaultStylesheetResolver),
|
|
89
112
|
})
|
|
90
113
|
}
|
|
@@ -98,8 +121,9 @@ struct StylesheetCache {
|
|
|
98
121
|
impl StylesheetCache {
|
|
99
122
|
fn new(args: &[Value]) -> RubyResult<StylesheetCache> {
|
|
100
123
|
fn error() -> magnus::Error {
|
|
124
|
+
let ruby = Ruby::get().expect("Always called from a Ruby thread");
|
|
101
125
|
magnus::Error::new(
|
|
102
|
-
|
|
126
|
+
ruby.exception_arg_error(),
|
|
103
127
|
"Cache size must be an integer greater than zero",
|
|
104
128
|
)
|
|
105
129
|
}
|
|
@@ -121,19 +145,19 @@ struct InlineErrorWrapper(rust_inline::InlineError);
|
|
|
121
145
|
|
|
122
146
|
impl From<InlineErrorWrapper> for magnus::Error {
|
|
123
147
|
fn from(error: InlineErrorWrapper) -> Self {
|
|
148
|
+
let ruby = Ruby::get().expect("Always called from a Ruby thread");
|
|
124
149
|
match error.0 {
|
|
125
150
|
rust_inline::InlineError::IO(error) => {
|
|
126
|
-
magnus::Error::new(
|
|
151
|
+
magnus::Error::new(ruby.exception_arg_error(), error.to_string())
|
|
152
|
+
}
|
|
153
|
+
rust_inline::InlineError::Network { error, location } => {
|
|
154
|
+
magnus::Error::new(ruby.exception_arg_error(), format!("{error}: {location}"))
|
|
127
155
|
}
|
|
128
|
-
rust_inline::InlineError::Network { error, location } => magnus::Error::new(
|
|
129
|
-
magnus::exception::arg_error(),
|
|
130
|
-
format!("{error}: {location}"),
|
|
131
|
-
),
|
|
132
156
|
rust_inline::InlineError::ParseError(message) => {
|
|
133
|
-
magnus::Error::new(
|
|
157
|
+
magnus::Error::new(ruby.exception_arg_error(), message.to_string())
|
|
134
158
|
}
|
|
135
159
|
rust_inline::InlineError::MissingStyleSheet { .. } => {
|
|
136
|
-
magnus::Error::new(
|
|
160
|
+
magnus::Error::new(ruby.exception_arg_error(), error.0.to_string())
|
|
137
161
|
}
|
|
138
162
|
}
|
|
139
163
|
}
|
|
@@ -146,8 +170,9 @@ struct UrlError {
|
|
|
146
170
|
|
|
147
171
|
impl From<UrlError> for magnus::Error {
|
|
148
172
|
fn from(error: UrlError) -> magnus::Error {
|
|
173
|
+
let ruby = Ruby::get().expect("Always called from a Ruby thread");
|
|
149
174
|
magnus::Error::new(
|
|
150
|
-
|
|
175
|
+
ruby.exception_arg_error(),
|
|
151
176
|
format!("{}: {}", error.error, error.url),
|
|
152
177
|
)
|
|
153
178
|
}
|
|
@@ -253,8 +278,8 @@ fn inline_many_fragments_impl(
|
|
|
253
278
|
}
|
|
254
279
|
|
|
255
280
|
#[magnus::init(name = "css_inline")]
|
|
256
|
-
fn init() -> RubyResult<()> {
|
|
257
|
-
let module = define_module("CSSInline")?;
|
|
281
|
+
fn init(ruby: &Ruby) -> RubyResult<()> {
|
|
282
|
+
let module = ruby.define_module("CSSInline")?;
|
|
258
283
|
|
|
259
284
|
module.define_module_function("inline", function!(inline, -1))?;
|
|
260
285
|
module.define_module_function("inline_fragment", function!(inline_fragment, -1))?;
|
|
@@ -264,7 +289,7 @@ fn init() -> RubyResult<()> {
|
|
|
264
289
|
function!(inline_many_fragments, -1),
|
|
265
290
|
)?;
|
|
266
291
|
|
|
267
|
-
let class = module.define_class("CSSInliner",
|
|
292
|
+
let class = module.define_class("CSSInliner", ruby.class_object())?;
|
|
268
293
|
class.define_singleton_method("new", function!(CSSInliner::new, -1))?;
|
|
269
294
|
class.define_method("inline", method!(CSSInliner::inline, 1))?;
|
|
270
295
|
class.define_method("inline_fragment", method!(CSSInliner::inline_fragment, 2))?;
|
|
@@ -274,7 +299,7 @@ fn init() -> RubyResult<()> {
|
|
|
274
299
|
method!(CSSInliner::inline_many_fragments, 2),
|
|
275
300
|
)?;
|
|
276
301
|
|
|
277
|
-
let class = module.define_class("StylesheetCache",
|
|
302
|
+
let class = module.define_class("StylesheetCache", ruby.class_object())?;
|
|
278
303
|
class.define_singleton_method("new", function!(StylesheetCache::new, -1))?;
|
|
279
304
|
Ok(())
|
|
280
305
|
}
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: css_inline
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Dygalo
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
141
141
|
- !ruby/object:Gem::Version
|
|
142
142
|
version: 3.3.26
|
|
143
143
|
requirements:
|
|
144
|
-
- Rust >= 1.
|
|
144
|
+
- Rust >= 1.83
|
|
145
145
|
rubygems_version: 3.4.19
|
|
146
146
|
signing_key:
|
|
147
147
|
specification_version: 4
|