css_inline 0.17.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 +277 -362
- data/README.md +14 -0
- data/ext/css_inline/Cargo.lock +277 -362
- data/ext/css_inline/Cargo.toml +5 -5
- data/ext/css_inline/src/lib.rs +77 -55
- 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,52 +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<bool>,
|
|
56
|
-
Option<String>,
|
|
57
|
-
Option<bool>,
|
|
58
|
-
Option<Obj<StylesheetCache>>,
|
|
59
|
-
Option<String>,
|
|
60
|
-
Option<usize>,
|
|
61
|
-
),
|
|
62
|
-
(),
|
|
63
|
-
>(
|
|
64
|
-
args.keywords,
|
|
65
|
-
&[],
|
|
66
|
-
&[
|
|
67
|
-
"inline_style_tags",
|
|
68
|
-
"keep_style_tags",
|
|
69
|
-
"keep_link_tags",
|
|
70
|
-
"keep_at_rules",
|
|
71
|
-
"base_url",
|
|
72
|
-
"load_remote_stylesheets",
|
|
73
|
-
"cache",
|
|
74
|
-
"extra_css",
|
|
75
|
-
"preallocate_node_capacity",
|
|
76
|
-
],
|
|
77
|
-
)?;
|
|
78
|
-
let kwargs = kwargs.optional;
|
|
97
|
+
let kwargs: Options = Options::try_convert(args.keywords.as_value())?;
|
|
79
98
|
Ok(rust_inline::InlineOptions {
|
|
80
|
-
inline_style_tags: kwargs.
|
|
81
|
-
keep_style_tags: kwargs.
|
|
82
|
-
keep_link_tags: kwargs.
|
|
83
|
-
keep_at_rules: kwargs.
|
|
84
|
-
|
|
85
|
-
|
|
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),
|
|
86
106
|
cache: kwargs
|
|
87
|
-
.
|
|
107
|
+
.cache
|
|
88
108
|
.map(|cache| Mutex::new(rust_inline::StylesheetCache::new(cache.size))),
|
|
89
|
-
extra_css: kwargs.
|
|
90
|
-
preallocate_node_capacity: kwargs.
|
|
109
|
+
extra_css: kwargs.extra_css.map(Cow::Owned),
|
|
110
|
+
preallocate_node_capacity: kwargs.preallocate_node_capacity.unwrap_or(32),
|
|
91
111
|
resolver: Arc::new(rust_inline::DefaultStylesheetResolver),
|
|
92
112
|
})
|
|
93
113
|
}
|
|
@@ -101,8 +121,9 @@ struct StylesheetCache {
|
|
|
101
121
|
impl StylesheetCache {
|
|
102
122
|
fn new(args: &[Value]) -> RubyResult<StylesheetCache> {
|
|
103
123
|
fn error() -> magnus::Error {
|
|
124
|
+
let ruby = Ruby::get().expect("Always called from a Ruby thread");
|
|
104
125
|
magnus::Error::new(
|
|
105
|
-
|
|
126
|
+
ruby.exception_arg_error(),
|
|
106
127
|
"Cache size must be an integer greater than zero",
|
|
107
128
|
)
|
|
108
129
|
}
|
|
@@ -124,19 +145,19 @@ struct InlineErrorWrapper(rust_inline::InlineError);
|
|
|
124
145
|
|
|
125
146
|
impl From<InlineErrorWrapper> for magnus::Error {
|
|
126
147
|
fn from(error: InlineErrorWrapper) -> Self {
|
|
148
|
+
let ruby = Ruby::get().expect("Always called from a Ruby thread");
|
|
127
149
|
match error.0 {
|
|
128
150
|
rust_inline::InlineError::IO(error) => {
|
|
129
|
-
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}"))
|
|
130
155
|
}
|
|
131
|
-
rust_inline::InlineError::Network { error, location } => magnus::Error::new(
|
|
132
|
-
magnus::exception::arg_error(),
|
|
133
|
-
format!("{error}: {location}"),
|
|
134
|
-
),
|
|
135
156
|
rust_inline::InlineError::ParseError(message) => {
|
|
136
|
-
magnus::Error::new(
|
|
157
|
+
magnus::Error::new(ruby.exception_arg_error(), message.to_string())
|
|
137
158
|
}
|
|
138
159
|
rust_inline::InlineError::MissingStyleSheet { .. } => {
|
|
139
|
-
magnus::Error::new(
|
|
160
|
+
magnus::Error::new(ruby.exception_arg_error(), error.0.to_string())
|
|
140
161
|
}
|
|
141
162
|
}
|
|
142
163
|
}
|
|
@@ -149,8 +170,9 @@ struct UrlError {
|
|
|
149
170
|
|
|
150
171
|
impl From<UrlError> for magnus::Error {
|
|
151
172
|
fn from(error: UrlError) -> magnus::Error {
|
|
173
|
+
let ruby = Ruby::get().expect("Always called from a Ruby thread");
|
|
152
174
|
magnus::Error::new(
|
|
153
|
-
|
|
175
|
+
ruby.exception_arg_error(),
|
|
154
176
|
format!("{}: {}", error.error, error.url),
|
|
155
177
|
)
|
|
156
178
|
}
|
|
@@ -256,8 +278,8 @@ fn inline_many_fragments_impl(
|
|
|
256
278
|
}
|
|
257
279
|
|
|
258
280
|
#[magnus::init(name = "css_inline")]
|
|
259
|
-
fn init() -> RubyResult<()> {
|
|
260
|
-
let module = define_module("CSSInline")?;
|
|
281
|
+
fn init(ruby: &Ruby) -> RubyResult<()> {
|
|
282
|
+
let module = ruby.define_module("CSSInline")?;
|
|
261
283
|
|
|
262
284
|
module.define_module_function("inline", function!(inline, -1))?;
|
|
263
285
|
module.define_module_function("inline_fragment", function!(inline_fragment, -1))?;
|
|
@@ -267,7 +289,7 @@ fn init() -> RubyResult<()> {
|
|
|
267
289
|
function!(inline_many_fragments, -1),
|
|
268
290
|
)?;
|
|
269
291
|
|
|
270
|
-
let class = module.define_class("CSSInliner",
|
|
292
|
+
let class = module.define_class("CSSInliner", ruby.class_object())?;
|
|
271
293
|
class.define_singleton_method("new", function!(CSSInliner::new, -1))?;
|
|
272
294
|
class.define_method("inline", method!(CSSInliner::inline, 1))?;
|
|
273
295
|
class.define_method("inline_fragment", method!(CSSInliner::inline_fragment, 2))?;
|
|
@@ -277,7 +299,7 @@ fn init() -> RubyResult<()> {
|
|
|
277
299
|
method!(CSSInliner::inline_many_fragments, 2),
|
|
278
300
|
)?;
|
|
279
301
|
|
|
280
|
-
let class = module.define_class("StylesheetCache",
|
|
302
|
+
let class = module.define_class("StylesheetCache", ruby.class_object())?;
|
|
281
303
|
class.define_singleton_method("new", function!(StylesheetCache::new, -1))?;
|
|
282
304
|
Ok(())
|
|
283
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
|