-
-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathoptions.rs
More file actions
98 lines (93 loc) · 3.97 KB
/
options.rs
File metadata and controls
98 lines (93 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::errors::{JsError, UrlError};
#[cfg(not(target_arch = "wasm32"))]
use napi_derive::napi;
use std::{borrow::Cow, sync::Arc};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::JsValue;
fn parse_url(url: Option<String>) -> std::result::Result<Option<css_inline::Url>, JsError> {
Ok(if let Some(url) = url {
Some(css_inline::Url::parse(url.as_str()).map_err(|error| UrlError { error, url })?)
} else {
None
})
}
#[cfg_attr(
target_arch = "wasm32",
derive(serde::Deserialize),
serde(default, rename_all = "camelCase", deny_unknown_fields)
)]
#[cfg_attr(not(target_arch = "wasm32"), napi(object))]
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Default)]
pub struct Options {
/// Whether to inline CSS from "style" tags.
///
/// Sometimes HTML may include a lot of boilerplate styles, that are not applicable in every
/// scenario, and it is useful to ignore them and use `extra_css` instead.
pub inline_style_tags: Option<bool>,
/// Keep "style" tags after inlining.
pub keep_style_tags: Option<bool>,
/// Keep "link" tags after inlining.
pub keep_link_tags: Option<bool>,
/// Used for loading external stylesheets via relative URLs.
pub base_url: Option<String>,
/// Whether remote stylesheets should be loaded or not.
pub load_remote_stylesheets: Option<bool>,
/// Additional CSS to inline.
pub extra_css: Option<String>,
/// Pre-allocate capacity for HTML nodes during parsing.
/// It can improve performance when you have an estimate of the number of nodes in your HTML document.
pub preallocate_node_capacity: Option<u32>,
}
impl TryFrom<Options> for css_inline::blocking::InlineOptions<'_> {
type Error = JsError;
fn try_from(value: Options) -> std::result::Result<Self, Self::Error> {
Ok(css_inline::blocking::InlineOptions {
inline_style_tags: value.inline_style_tags.unwrap_or(true),
keep_style_tags: value.keep_style_tags.unwrap_or(false),
keep_link_tags: value.keep_link_tags.unwrap_or(false),
base_url: parse_url(value.base_url)?,
load_remote_stylesheets: value.load_remote_stylesheets.unwrap_or(true),
extra_css: value.extra_css.map(Cow::Owned),
preallocate_node_capacity: if let Some(capacity) = value.preallocate_node_capacity {
usize::try_from(capacity).map_err(|_| {
let reason = "Invalid capacity".to_string();
#[cfg(target_arch = "wasm32")]
{
JsValue::from_str(reason.as_str())
}
#[cfg(not(target_arch = "wasm32"))]
{
napi::Error::from_reason(reason)
}
})?
} else {
32
},
resolver: {
#[cfg(target_arch = "wasm32")]
{
#[derive(Debug, Default)]
pub struct UnsupportedResolver;
impl css_inline::StylesheetResolver for UnsupportedResolver {
fn retrieve_blocking(&self, location: &str) -> css_inline::Result<String> {
let message = if location.starts_with("https")
| location.starts_with("http")
{
format!("Loading remote stylesheets is not supported on WASM: {location}")
} else {
format!("Loading local files is not supported on WASM: {location}")
};
Err(self.unsupported(&message))
}
}
Arc::new(UnsupportedResolver)
}
#[cfg(not(target_arch = "wasm32"))]
{
Arc::new(css_inline::DefaultStylesheetResolver)
}
},
})
}
}