diff --git a/CHANGELOG.md b/CHANGELOG.md
index 350f5178..064a9c78 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+### Added
+
+- `keep_at_rules` option [#265](https://github.com/Stranger6667/css-inline/issues/265)
+
## [0.16.0] - 2025-07-16
### Added
diff --git a/README.md b/README.md
index 309768dc..a37eafff 100644
--- a/README.md
+++ b/README.md
@@ -126,6 +126,7 @@ fn main() -> css_inline::Result<()> {
- `inline_style_tags`. Specifies whether to inline CSS from "style" tags. Default: `true`
- `keep_style_tags`. Specifies whether to keep "style" tags after inlining. Default: `false`
- `keep_link_tags`. Specifies whether to keep "link" tags after inlining. Default: `false`
+- `keep_at_rules`. Specifies whether to keep "at-rules" (starting with `@`) after inlining. Default: `false`
- `base_url`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `None`
- `load_remote_stylesheets`. Specifies whether remote stylesheets should be loaded. Default: `true`
- `cache`. Specifies cache for external stylesheets. Default: `None`
@@ -157,7 +158,8 @@ The `data-css-inline="ignore"` attribute also allows you to skip `link` and `sty
```
Alternatively, you may keep `style` from being removed by using the `data-css-inline="keep"` attribute.
-This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags:
+This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
```html
@@ -169,7 +171,20 @@ This is useful if you want to keep `@media` queries for responsive emails in sep
```
-Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
+Another possibility is to set `keep_at_rules` option to `true`. At-rules cannot be inlined into HTML therefore they
+get removed by default. This is useful if you want to keep at-rules, e.g. `@media` queries for responsive emails in
+separate `style` tags but inline any styles which can be inlined.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is explicitly set to `false`.
+
+```html
+
+
+
+
+
+ Big Text
+
+```
If you'd like to load stylesheets from your filesystem, use the `file://` scheme:
diff --git a/bindings/c/CHANGELOG.md b/bindings/c/CHANGELOG.md
index 8f6095bf..ce2e730d 100644
--- a/bindings/c/CHANGELOG.md
+++ b/bindings/c/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+### Added
+
+- `keep_at_rules` option [#265](https://github.com/Stranger6667/css-inline/issues/265)
+
## [0.16.0] - 2025-07-16
### Changed
diff --git a/bindings/c/README.md b/bindings/c/README.md
index 8af5497d..924deb35 100644
--- a/bindings/c/README.md
+++ b/bindings/c/README.md
@@ -153,6 +153,7 @@ Possible configurations:
- `inline_style_tags`. Specifies whether to inline CSS from "style" tags. Default: `true`
- `keep_style_tags`. Specifies whether to keep "style" tags after inlining. Default: `false`
- `keep_link_tags`. Specifies whether to keep "link" tags after inlining. Default: `false`
+- `keep_at_rules`. Specifies whether to keep "at-rules" (starting with `@`) after inlining. Default: `false`
- `base_url`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `NULL`
- `load_remote_stylesheets`. Specifies whether remote stylesheets should be loaded. Default: `true`
- `cache`. Specifies caching options for external stylesheets. Default: `NULL`
@@ -186,7 +187,8 @@ The `data-css-inline="ignore"` attribute also allows you to skip `link` and `sty
```
Alternatively, you may keep `style` from being removed by using the `data-css-inline="keep"` attribute.
-This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags:
+This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
```html
@@ -198,7 +200,20 @@ This is useful if you want to keep `@media` queries for responsive emails in sep
```
-Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
+Another possibility is to set `keep_at_rules` option to `true`. At-rules cannot be inlined into HTML therefore they
+get removed by default. This is useful if you want to keep at-rules, e.g. `@media` queries for responsive emails in
+separate `style` tags but inline any styles which can be inlined.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is explicitly set to `false`.
+
+```html
+
+
+
+
+
+ Big Text
+
+```
You can also cache external stylesheets to avoid excessive network requests:
diff --git a/bindings/c/src/lib.rs b/bindings/c/src/lib.rs
index e13622df..7f48a1dc 100644
--- a/bindings/c/src/lib.rs
+++ b/bindings/c/src/lib.rs
@@ -82,6 +82,8 @@ pub struct CssInlinerOptions {
pub keep_style_tags: bool,
/// Keep "link" tags after inlining.
pub keep_link_tags: bool,
+ /// Keep "at-rules" after inlining.
+ pub keep_at_rules: bool,
/// Whether remote stylesheets should be loaded or not.
pub load_remote_stylesheets: bool,
/// Cache for external stylesheets.
@@ -183,6 +185,7 @@ pub extern "C" fn css_inliner_default_options() -> CssInlinerOptions {
inline_style_tags: true,
keep_style_tags: false,
keep_link_tags: false,
+ keep_at_rules: false,
base_url: ptr::null(),
load_remote_stylesheets: true,
cache: std::ptr::null(),
@@ -225,6 +228,7 @@ impl TryFrom<&CssInlinerOptions> for InlineOptions<'_> {
inline_style_tags: value.inline_style_tags,
keep_style_tags: value.keep_style_tags,
keep_link_tags: value.keep_link_tags,
+ keep_at_rules: value.keep_at_rules,
base_url: match base_url {
Some(url) => Some(Url::parse(url).map_err(|_| InlineOptionsError::InvalidUrl)?),
None => None,
diff --git a/bindings/java/CHANGELOG.md b/bindings/java/CHANGELOG.md
index db1828e5..c264a7fc 100644
--- a/bindings/java/CHANGELOG.md
+++ b/bindings/java/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+### Added
+
+- `keep_at_rules` option [#265](https://github.com/Stranger6667/css-inline/issues/265)
+
## [0.16.0] - 2025-07-16
### Changed
diff --git a/bindings/java/README.md b/bindings/java/README.md
index bebece4f..a0accd70 100644
--- a/bindings/java/README.md
+++ b/bindings/java/README.md
@@ -146,6 +146,7 @@ public class ConfigExample {
- **`setInlineStyleTags(boolean)`** - Inline CSS from `
+
+
+ Big Text
+
+```
## Performance
diff --git a/bindings/java/src/main/java/org/cssinline/CssInlineConfig.java b/bindings/java/src/main/java/org/cssinline/CssInlineConfig.java
index 557e2b15..043da02a 100644
--- a/bindings/java/src/main/java/org/cssinline/CssInlineConfig.java
+++ b/bindings/java/src/main/java/org/cssinline/CssInlineConfig.java
@@ -11,6 +11,9 @@ public class CssInlineConfig {
/** Keep "link" tags after inlining. */
public final boolean keepLinkTags;
+ /** Keep "at-rules" after inlining. */
+ public final boolean keepAtRules;
+
/** Whether remote stylesheets should be loaded or not. */
public final boolean loadRemoteStylesheets;
@@ -27,11 +30,12 @@ public class CssInlineConfig {
public final int preallocateNodeCapacity;
private CssInlineConfig(boolean inlineStyleTags, boolean keepStyleTags, boolean keepLinkTags,
- boolean loadRemoteStylesheets, String baseUrl, String extraCss, int cacheSize,
+ boolean keepAtRules, boolean loadRemoteStylesheets, String baseUrl, String extraCss, int cacheSize,
int preallocateNodeCapacity) {
this.inlineStyleTags = inlineStyleTags;
this.keepStyleTags = keepStyleTags;
this.keepLinkTags = keepLinkTags;
+ this.keepAtRules = keepAtRules;
this.loadRemoteStylesheets = loadRemoteStylesheets;
this.baseUrl = baseUrl;
this.extraCss = extraCss;
@@ -46,6 +50,7 @@ public static class Builder {
private boolean inlineStyleTags = true;
private boolean keepStyleTags = false;
private boolean keepLinkTags = false;
+ private boolean keepAtRules = false;
private boolean loadRemoteStylesheets = true;
private String baseUrl = null;
private String extraCss = null;
@@ -94,6 +99,17 @@ public Builder setKeepLinkTags(boolean b) {
return this;
}
+ /**
+ * Keep "at-rules" after inlining.
+ *
+ * @param b true to preserve at-rules, false to remove them
+ * @return this builder instance for method chaining
+ */
+ public Builder setKeepAtRules(boolean b) {
+ this.keepAtRules = b;
+ return this;
+ }
+
/**
* Whether remote stylesheets should be loaded or not.
*
@@ -168,7 +184,7 @@ public Builder setPreallocateNodeCapacity(int cap) {
* @return a new immutable configuration instance
*/
public CssInlineConfig build() {
- return new CssInlineConfig(inlineStyleTags, keepStyleTags, keepLinkTags, loadRemoteStylesheets, baseUrl,
+ return new CssInlineConfig(inlineStyleTags, keepStyleTags, keepLinkTags, keepAtRules, loadRemoteStylesheets, baseUrl,
extraCss, cacheSize, preallocateNodeCapacity);
}
}
diff --git a/bindings/java/src/main/rust/lib.rs b/bindings/java/src/main/rust/lib.rs
index 3a1b3615..6be63a69 100644
--- a/bindings/java/src/main/rust/lib.rs
+++ b/bindings/java/src/main/rust/lib.rs
@@ -74,6 +74,7 @@ fn build_inliner(
let inline_style_tags = env.get_bool_field(&cfg, "inlineStyleTags")?;
let keep_style_tags = env.get_bool_field(&cfg, "keepStyleTags")?;
let keep_link_tags = env.get_bool_field(&cfg, "keepLinkTags")?;
+ let keep_at_rules = env.get_bool_field(&cfg, "keepAtRules")?;
let load_remote_stylesheets = env.get_bool_field(&cfg, "loadRemoteStylesheets")?;
let cache_size = env.get_int_field(&cfg, "cacheSize")?;
let preallocate_node_capacity = env.get_int_field(&cfg, "preallocateNodeCapacity")?;
@@ -84,6 +85,7 @@ fn build_inliner(
.inline_style_tags(inline_style_tags)
.keep_style_tags(keep_style_tags)
.keep_link_tags(keep_link_tags)
+ .keep_at_rules(keep_at_rules)
.load_remote_stylesheets(load_remote_stylesheets)
.extra_css(extra_css.map(Cow::Owned))
.preallocate_node_capacity(preallocate_node_capacity as usize);
diff --git a/bindings/javascript/CHANGELOG.md b/bindings/javascript/CHANGELOG.md
index e001fef2..14b5da33 100644
--- a/bindings/javascript/CHANGELOG.md
+++ b/bindings/javascript/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+### Added
+
+- `keep_at_rules` option [#265](https://github.com/Stranger6667/css-inline/issues/265)
+
## [0.16.0] - 2025-07-16
### Changed
diff --git a/bindings/javascript/README.md b/bindings/javascript/README.md
index b7501b01..23aeccd6 100644
--- a/bindings/javascript/README.md
+++ b/bindings/javascript/README.md
@@ -116,6 +116,7 @@ var inlined = inlineFragment(
- `inlineStyleTags`. Specifies whether to inline CSS from "style" tags. Default: `true`
- `keepStyleTags`. Specifies whether to keep "style" tags after inlining. Default: `false`
- `keepLinkTags`. Specifies whether to keep "link" tags after inlining. Default: `false`
+- `keep_at_rules`. Specifies whether to keep "at-rules" (starting with `@`) after inlining. Default: `false`
- `baseUrl`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `null`
- `loadRemoteStylesheets`. Specifies whether remote stylesheets should be loaded. Default: `true`
- `cache`. Specifies caching options for external stylesheets (for example, `{size: 5}`). Default: `null`
@@ -148,7 +149,8 @@ The `data-css-inline="ignore"` attribute also allows you to skip `link` and `sty
```
Alternatively, you may keep `style` from being removed by using the `data-css-inline="keep"` attribute.
-This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags:
+This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
```html
@@ -160,7 +162,20 @@ This is useful if you want to keep `@media` queries for responsive emails in sep
```
-Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
+Another possibility is to set `keep_at_rules` option to `true`. At-rules cannot be inlined into HTML therefore they
+get removed by default. This is useful if you want to keep at-rules, e.g. `@media` queries for responsive emails in
+separate `style` tags but inline any styles which can be inlined.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is explicitly set to `false`.
+
+```html
+
+
+
+
+
+ Big Text
+
+```
You can also cache external stylesheets to avoid excessive network requests:
diff --git a/bindings/javascript/src/lib.rs b/bindings/javascript/src/lib.rs
index 8c1b03e2..abea8da2 100644
--- a/bindings/javascript/src/lib.rs
+++ b/bindings/javascript/src/lib.rs
@@ -74,6 +74,7 @@ const INLINE: &'static str = r#"export interface InlineOptions {
inlineStyleTags?: boolean,
keepStyleTags?: boolean,
keepLinkTags?: boolean,
+ keepAtRules?: boolean,
baseUrl?: string,
loadRemoteStylesheets?: boolean,
extraCss?: string,
diff --git a/bindings/javascript/src/options.rs b/bindings/javascript/src/options.rs
index c3c7f064..37cd60c7 100644
--- a/bindings/javascript/src/options.rs
+++ b/bindings/javascript/src/options.rs
@@ -40,6 +40,8 @@ pub struct Options {
pub keep_style_tags: Option,
/// Keep "link" tags after inlining.
pub keep_link_tags: Option,
+ /// Keep "at-rules" after inlining.
+ pub keep_at_rules: Option,
/// Used for loading external stylesheets via relative URLs.
pub base_url: Option,
/// Whether remote stylesheets should be loaded or not.
@@ -62,6 +64,7 @@ impl TryFrom for css_inline::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),
+ keep_at_rules: value.keep_at_rules.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),
diff --git a/bindings/javascript/wasm/index.d.ts b/bindings/javascript/wasm/index.d.ts
index ba0b3540..82705066 100644
--- a/bindings/javascript/wasm/index.d.ts
+++ b/bindings/javascript/wasm/index.d.ts
@@ -1,4 +1,4 @@
-// Generated by dts-bundle-generator v9.1.0
+// Generated by dts-bundle-generator v9.5.1
/* tslint:disable */
/* eslint-disable */
@@ -6,6 +6,7 @@ export interface InlineOptions {
inlineStyleTags?: boolean;
keepStyleTags?: boolean;
keepLinkTags?: boolean;
+ keepAtRules?: boolean;
baseUrl?: string;
loadRemoteStylesheets?: boolean;
extraCss?: string;
diff --git a/bindings/javascript/wasm/index.js b/bindings/javascript/wasm/index.js
index e6861221..256e609c 100644
--- a/bindings/javascript/wasm/index.js
+++ b/bindings/javascript/wasm/index.js
@@ -120,8 +120,7 @@ function passStringToWasm0(arg, malloc, realloc) {
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
- if (code > 127)
- break;
+ if (code > 127) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
@@ -373,8 +372,7 @@ function __wbg_finalize_init(instance, module2) {
return wasm;
}
async function __wbg_init(module_or_path) {
- if (wasm !== void 0)
- return wasm;
+ if (wasm !== void 0) return wasm;
if (typeof module_or_path !== "undefined") {
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
({ module_or_path } = module_or_path);
diff --git a/bindings/javascript/wasm/index.mjs b/bindings/javascript/wasm/index.mjs
index 7c1ac156..0bdc2625 100644
--- a/bindings/javascript/wasm/index.mjs
+++ b/bindings/javascript/wasm/index.mjs
@@ -91,8 +91,7 @@ function passStringToWasm0(arg, malloc, realloc) {
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
- if (code > 127)
- break;
+ if (code > 127) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
@@ -344,8 +343,7 @@ function __wbg_finalize_init(instance, module) {
return wasm;
}
async function __wbg_init(module_or_path) {
- if (wasm !== void 0)
- return wasm;
+ if (wasm !== void 0) return wasm;
if (typeof module_or_path !== "undefined") {
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
({ module_or_path } = module_or_path);
diff --git a/bindings/javascript/wasm/index_bg.wasm b/bindings/javascript/wasm/index_bg.wasm
index 8d6a0b64..4a37decf 100644
Binary files a/bindings/javascript/wasm/index_bg.wasm and b/bindings/javascript/wasm/index_bg.wasm differ
diff --git a/bindings/python/CHANGELOG.md b/bindings/python/CHANGELOG.md
index 9fa53fb9..cda8ec37 100644
--- a/bindings/python/CHANGELOG.md
+++ b/bindings/python/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+### Added
+
+- `keep_at_rules` option [#265](https://github.com/Stranger6667/css-inline/issues/265)
+
## [0.16.0] - 2025-07-16
### Changed
diff --git a/bindings/python/README.md b/bindings/python/README.md
index 4761e49f..2e8d7803 100644
--- a/bindings/python/README.md
+++ b/bindings/python/README.md
@@ -148,6 +148,7 @@ inliner.inline("...")
- `inline_style_tags`. Specifies whether to inline CSS from "style" tags. Default: `True`
- `keep_style_tags`. Specifies whether to keep "style" tags after inlining. Default: `False`
- `keep_link_tags`. Specifies whether to keep "link" tags after inlining. Default: `False`
+- `keep_at_rules`. Specifies whether to keep "at-rules" (starting with `@`) after inlining. Default: `False`
- `base_url`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `None`
- `load_remote_stylesheets`. Specifies whether remote stylesheets should be loaded. Default: `True`
- `cache`. Specifies caching options for external stylesheets (for example, `StylesheetCache(size=5)`). Default: `None`
@@ -179,7 +180,8 @@ The `data-css-inline="ignore"` attribute also allows you to skip `link` and `sty
```
Alternatively, you may keep `style` from being removed by using the `data-css-inline="keep"` attribute.
-This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags:
+This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
```html
@@ -191,7 +193,20 @@ This is useful if you want to keep `@media` queries for responsive emails in sep
```
-Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
+Another possibility is to set `keep_at_rules` option to `true`. At-rules cannot be inlined into HTML therefore they
+get removed by default. This is useful if you want to keep at-rules, e.g. `@media` queries for responsive emails in
+separate `style` tags but inline any styles which can be inlined.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is explicitly set to `false`.
+
+```html
+
+
+
+
+
+ Big Text
+
+```
If you'd like to load stylesheets from your filesystem, use the `file://` scheme:
diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs
index 6f09b4e2..f958411d 100644
--- a/bindings/python/src/lib.rs
+++ b/bindings/python/src/lib.rs
@@ -99,7 +99,7 @@ impl StylesheetCache {
}
}
-/// CSSInliner(inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
+/// CSSInliner(inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, keep_at_rules=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
///
/// Customizable CSS inliner.
#[pyclass]
@@ -108,11 +108,12 @@ struct CSSInliner {
}
macro_rules! inliner {
- ($inline_style_tags:expr, $keep_style_tags:expr, $keep_link_tags:expr, $base_url:expr, $load_remote_stylesheets:expr, $cache:expr, $extra_css:expr, $preallocate_node_capacity:expr) => {{
+ ($inline_style_tags:expr, $keep_style_tags:expr, $keep_link_tags:expr, $keep_at_rules:expr, $base_url:expr, $load_remote_stylesheets:expr, $cache:expr, $extra_css:expr, $preallocate_node_capacity:expr) => {{
let options = rust_inline::InlineOptions {
inline_style_tags: $inline_style_tags.unwrap_or(true),
keep_style_tags: $keep_style_tags.unwrap_or(false),
keep_link_tags: $keep_link_tags.unwrap_or(false),
+ keep_at_rules: $keep_at_rules.unwrap_or(false),
base_url: $crate::parse_url($base_url)?,
load_remote_stylesheets: $load_remote_stylesheets.unwrap_or(true),
cache: {
@@ -136,13 +137,14 @@ macro_rules! inliner {
impl CSSInliner {
#[new]
#[pyo3(
- signature = (inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
+ signature = (inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, keep_at_rules=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
)]
#[allow(clippy::too_many_arguments)]
fn new(
inline_style_tags: Option,
keep_style_tags: Option,
keep_link_tags: Option,
+ keep_at_rules: Option,
base_url: Option,
load_remote_stylesheets: Option,
cache: Option,
@@ -153,6 +155,7 @@ impl CSSInliner {
inline_style_tags,
keep_style_tags,
keep_link_tags,
+ keep_at_rules,
base_url,
load_remote_stylesheets,
cache,
@@ -202,12 +205,12 @@ impl CSSInliner {
}
}
-/// inline(html, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
+/// inline(html, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, keep_at_rules=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
///
/// Inline CSS in the given HTML document
#[pyfunction]
#[pyo3(
- signature = (html, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
+ signature = (html, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, keep_at_rules=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
)]
#[allow(clippy::too_many_arguments)]
fn inline(
@@ -215,6 +218,7 @@ fn inline(
inline_style_tags: Option,
keep_style_tags: Option,
keep_link_tags: Option,
+ keep_at_rules: Option,
base_url: Option,
load_remote_stylesheets: Option,
cache: Option,
@@ -225,6 +229,7 @@ fn inline(
inline_style_tags,
keep_style_tags,
keep_link_tags,
+ keep_at_rules,
base_url,
load_remote_stylesheets,
cache,
@@ -234,12 +239,12 @@ fn inline(
Ok(inliner.inline(html).map_err(InlineErrorWrapper)?)
}
-/// inline_fragment(html, css, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
+/// inline_fragment(html, css, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, keep_at_rules=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
///
/// Inline CSS in the given HTML fragment
#[pyfunction]
#[pyo3(
- signature = (html, css, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
+ signature = (html, css, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, keep_at_rules=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
)]
#[allow(clippy::too_many_arguments)]
fn inline_fragment(
@@ -248,6 +253,7 @@ fn inline_fragment(
inline_style_tags: Option,
keep_style_tags: Option,
keep_link_tags: Option,
+ keep_at_rules: Option,
base_url: Option,
load_remote_stylesheets: Option,
cache: Option,
@@ -258,6 +264,7 @@ fn inline_fragment(
inline_style_tags,
keep_style_tags,
keep_link_tags,
+ keep_at_rules,
base_url,
load_remote_stylesheets,
cache,
@@ -269,12 +276,12 @@ fn inline_fragment(
.map_err(InlineErrorWrapper)?)
}
-/// inline_many(htmls, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
+/// inline_many(htmls, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, keep_at_rules=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
///
/// Inline CSS in multiple HTML documents
#[pyfunction]
#[pyo3(
- signature = (htmls, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
+ signature = (htmls, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, keep_at_rules=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
)]
#[allow(clippy::too_many_arguments)]
fn inline_many(
@@ -282,6 +289,7 @@ fn inline_many(
inline_style_tags: Option,
keep_style_tags: Option,
keep_link_tags: Option,
+ keep_at_rules: Option,
base_url: Option,
load_remote_stylesheets: Option,
cache: Option,
@@ -292,6 +300,7 @@ fn inline_many(
inline_style_tags,
keep_style_tags,
keep_link_tags,
+ keep_at_rules,
base_url,
load_remote_stylesheets,
cache,
@@ -314,12 +323,12 @@ fn inline_many_impl(
Ok(output.map_err(InlineErrorWrapper)?)
}
-/// inline_many_fragments(htmls, css, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
+/// inline_many_fragments(htmls, css, inline_style_tags=True, keep_style_tags=False, keep_link_tags=False, keep_at_rules=False, base_url=None, load_remote_stylesheets=True, cache=None, extra_css=None, preallocate_node_capacity=32)
///
/// Inline CSS in multiple HTML fragments
#[pyfunction]
#[pyo3(
- signature = (htmls, css, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
+ signature = (htmls, css, inline_style_tags=true, keep_style_tags=false, keep_link_tags=false, keep_at_rules=false, base_url=None, load_remote_stylesheets=true, cache=None, extra_css=None, preallocate_node_capacity=32)
)]
#[allow(clippy::too_many_arguments)]
fn inline_many_fragments(
@@ -328,6 +337,7 @@ fn inline_many_fragments(
inline_style_tags: Option,
keep_style_tags: Option,
keep_link_tags: Option,
+ keep_at_rules: Option,
base_url: Option,
load_remote_stylesheets: Option,
cache: Option,
@@ -338,6 +348,7 @@ fn inline_many_fragments(
inline_style_tags,
keep_style_tags,
keep_link_tags,
+ keep_at_rules,
base_url,
load_remote_stylesheets,
cache,
diff --git a/bindings/ruby/CHANGELOG.md b/bindings/ruby/CHANGELOG.md
index eb2de8ad..c1a694ed 100644
--- a/bindings/ruby/CHANGELOG.md
+++ b/bindings/ruby/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+### Added
+
+- `keep_at_rules` option [#265](https://github.com/Stranger6667/css-inline/issues/265)
+
## [0.16.0] - 2025-07-16
### Changed
diff --git a/bindings/ruby/Cargo.lock b/bindings/ruby/Cargo.lock
index 359b62ae..19f9224a 100644
--- a/bindings/ruby/Cargo.lock
+++ b/bindings/ruby/Cargo.lock
@@ -105,9 +105,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
-version = "1.2.29"
+version = "1.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
+checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
dependencies = [
"shlex",
]
@@ -172,17 +172,6 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "css-inline"
version = "0.16.0"
-dependencies = [
- "css-inline 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "magnus",
- "rayon",
-]
-
-[[package]]
-name = "css-inline"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "029829f1a34f85c62c0e5e376c3aa5195308fb5f6c04ec1480188e578574bc4b"
dependencies = [
"cssparser",
"html5ever",
@@ -196,6 +185,15 @@ dependencies = [
"url",
]
+[[package]]
+name = "css-inline-ruby"
+version = "0.16.0"
+dependencies = [
+ "css-inline",
+ "magnus",
+ "rayon",
+]
+
[[package]]
name = "cssparser"
version = "0.35.0"
@@ -506,9 +504,9 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
+checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
dependencies = [
"base64",
"bytes",
@@ -522,7 +520,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
- "socket2",
+ "socket2 0.6.0",
"tokio",
"tower-service",
"tracing",
@@ -647,9 +645,9 @@ dependencies = [
[[package]]
name = "io-uring"
-version = "0.7.8"
+version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
+checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
dependencies = [
"bitflags",
"cfg-if",
@@ -1015,7 +1013,7 @@ dependencies = [
"quinn-udp",
"rustc-hash 2.1.1",
"rustls",
- "socket2",
+ "socket2 0.5.10",
"thiserror",
"tokio",
"tracing",
@@ -1031,7 +1029,7 @@ dependencies = [
"bytes",
"getrandom 0.3.3",
"lru-slab",
- "rand 0.9.1",
+ "rand 0.9.2",
"ring",
"rustc-hash 2.1.1",
"rustls",
@@ -1052,7 +1050,7 @@ dependencies = [
"cfg_aliases",
"libc",
"once_cell",
- "socket2",
+ "socket2 0.5.10",
"tracing",
"windows-sys 0.59.0",
]
@@ -1083,9 +1081,9 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.9.1"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
+checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha",
"rand_core 0.9.3",
@@ -1168,9 +1166,9 @@ checksum = "a35802679f07360454b418a5d1735c89716bde01d35b1560fc953c1415a0b3bb"
[[package]]
name = "redox_syscall"
-version = "0.5.13"
+version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
+checksum = "7e8af0dde094006011e6a740d4879319439489813bd0bcdc7d821beaeeff48ec"
dependencies = [
"bitflags",
]
@@ -1376,9 +1374,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.140"
+version = "1.0.141"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
+checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
dependencies = [
"itoa",
"memchr",
@@ -1447,6 +1445,16 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "socket2"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
+dependencies = [
+ "libc",
+ "windows-sys 0.59.0",
+]
+
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@@ -1584,7 +1592,7 @@ dependencies = [
"mio",
"pin-project-lite",
"slab",
- "socket2",
+ "socket2 0.5.10",
"windows-sys 0.52.0",
]
@@ -1832,9 +1840,9 @@ dependencies = [
[[package]]
name = "webpki-roots"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502"
+checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2"
dependencies = [
"rustls-pki-types",
]
diff --git a/bindings/ruby/README.md b/bindings/ruby/README.md
index de053476..2aa9b690 100644
--- a/bindings/ruby/README.md
+++ b/bindings/ruby/README.md
@@ -135,6 +135,7 @@ inliner.inline("...")
- `inline_style_tags`. Specifies whether to inline CSS from "style" tags. Default: `true`
- `keep_style_tags`. Specifies whether to keep "style" tags after inlining. Default: `false`
- `keep_link_tags`. Specifies whether to keep "link" tags after inlining. Default: `false`
+- `keep_at_rules`. Specifies whether to keep "at-rules" (starting with `@`) after inlining. Default: `false`
- `base_url`. The base URL used to resolve relative URLs. If you'd like to load stylesheets from your filesystem, use the `file://` scheme. Default: `nil`
- `load_remote_stylesheets`. Specifies whether remote stylesheets should be loaded. Default: `true`
- `cache`. Specifies caching options for external stylesheets (for example, `StylesheetCache(size: 5)`). Default: `nil`
@@ -166,7 +167,8 @@ The `data-css-inline="ignore"` attribute also allows you to skip `link` and `sty
```
Alternatively, you may keep `style` from being removed by using the `data-css-inline="keep"` attribute.
-This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags:
+This is useful if you want to keep `@media` queries for responsive emails in separate `style` tags.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
```html
@@ -178,7 +180,20 @@ This is useful if you want to keep `@media` queries for responsive emails in sep
```
-Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is set to `false`.
+Another possibility is to set `keep_at_rules` option to `true`. At-rules cannot be inlined into HTML therefore they
+get removed by default. This is useful if you want to keep at-rules, e.g. `@media` queries for responsive emails in
+separate `style` tags but inline any styles which can be inlined.
+Such tags will be kept in the resulting HTML even if the `keep_style_tags` option is explicitly set to `false`.
+
+```html
+
+
+
+
+
+ Big Text
+
+```
If you'd like to load stylesheets from your filesystem, use the `file://` scheme:
diff --git a/bindings/ruby/ext/css_inline/Cargo.lock b/bindings/ruby/ext/css_inline/Cargo.lock
index 359b62ae..19f9224a 100644
--- a/bindings/ruby/ext/css_inline/Cargo.lock
+++ b/bindings/ruby/ext/css_inline/Cargo.lock
@@ -105,9 +105,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
-version = "1.2.29"
+version = "1.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
+checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
dependencies = [
"shlex",
]
@@ -172,17 +172,6 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "css-inline"
version = "0.16.0"
-dependencies = [
- "css-inline 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "magnus",
- "rayon",
-]
-
-[[package]]
-name = "css-inline"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "029829f1a34f85c62c0e5e376c3aa5195308fb5f6c04ec1480188e578574bc4b"
dependencies = [
"cssparser",
"html5ever",
@@ -196,6 +185,15 @@ dependencies = [
"url",
]
+[[package]]
+name = "css-inline-ruby"
+version = "0.16.0"
+dependencies = [
+ "css-inline",
+ "magnus",
+ "rayon",
+]
+
[[package]]
name = "cssparser"
version = "0.35.0"
@@ -506,9 +504,9 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
+checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
dependencies = [
"base64",
"bytes",
@@ -522,7 +520,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
- "socket2",
+ "socket2 0.6.0",
"tokio",
"tower-service",
"tracing",
@@ -647,9 +645,9 @@ dependencies = [
[[package]]
name = "io-uring"
-version = "0.7.8"
+version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
+checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
dependencies = [
"bitflags",
"cfg-if",
@@ -1015,7 +1013,7 @@ dependencies = [
"quinn-udp",
"rustc-hash 2.1.1",
"rustls",
- "socket2",
+ "socket2 0.5.10",
"thiserror",
"tokio",
"tracing",
@@ -1031,7 +1029,7 @@ dependencies = [
"bytes",
"getrandom 0.3.3",
"lru-slab",
- "rand 0.9.1",
+ "rand 0.9.2",
"ring",
"rustc-hash 2.1.1",
"rustls",
@@ -1052,7 +1050,7 @@ dependencies = [
"cfg_aliases",
"libc",
"once_cell",
- "socket2",
+ "socket2 0.5.10",
"tracing",
"windows-sys 0.59.0",
]
@@ -1083,9 +1081,9 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.9.1"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
+checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha",
"rand_core 0.9.3",
@@ -1168,9 +1166,9 @@ checksum = "a35802679f07360454b418a5d1735c89716bde01d35b1560fc953c1415a0b3bb"
[[package]]
name = "redox_syscall"
-version = "0.5.13"
+version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
+checksum = "7e8af0dde094006011e6a740d4879319439489813bd0bcdc7d821beaeeff48ec"
dependencies = [
"bitflags",
]
@@ -1376,9 +1374,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.140"
+version = "1.0.141"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
+checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
dependencies = [
"itoa",
"memchr",
@@ -1447,6 +1445,16 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "socket2"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
+dependencies = [
+ "libc",
+ "windows-sys 0.59.0",
+]
+
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@@ -1584,7 +1592,7 @@ dependencies = [
"mio",
"pin-project-lite",
"slab",
- "socket2",
+ "socket2 0.5.10",
"windows-sys 0.52.0",
]
@@ -1832,9 +1840,9 @@ dependencies = [
[[package]]
name = "webpki-roots"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502"
+checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2"
dependencies = [
"rustls-pki-types",
]
diff --git a/bindings/ruby/ext/css_inline/Cargo.toml b/bindings/ruby/ext/css_inline/Cargo.toml
index 31615d49..e98b7e9e 100644
--- a/bindings/ruby/ext/css_inline/Cargo.toml
+++ b/bindings/ruby/ext/css_inline/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "css-inline"
+name = "css-inline-ruby"
version = "0.16.0"
authors = ["Dmitry Dygalo "]
edition = "2021"
@@ -20,6 +20,7 @@ magnus = "0.7"
rayon = "1"
[dependencies.css-inline]
-version = "0.16"
+path = "../../../../css-inline"
+version = "*"
default-features = false
features = ["http", "file", "stylesheet-cache"]
diff --git a/bindings/ruby/ext/css_inline/src/lib.rs b/bindings/ruby/ext/css_inline/src/lib.rs
index 9fa506cb..734cf2f1 100644
--- a/bindings/ruby/ext/css_inline/src/lib.rs
+++ b/bindings/ruby/ext/css_inline/src/lib.rs
@@ -52,6 +52,7 @@ fn parse_options(
Option,
Option,
Option,
+ Option,
Option,
Option,
Option>,
@@ -66,6 +67,7 @@ fn parse_options(
"inline_style_tags",
"keep_style_tags",
"keep_link_tags",
+ "keep_at_rules",
"base_url",
"load_remote_stylesheets",
"cache",
@@ -78,13 +80,14 @@ fn parse_options(
inline_style_tags: kwargs.0.unwrap_or(true),
keep_style_tags: kwargs.1.unwrap_or(false),
keep_link_tags: kwargs.2.unwrap_or(false),
- base_url: parse_url(kwargs.3)?,
- load_remote_stylesheets: kwargs.4.unwrap_or(true),
+ keep_at_rules: kwargs.3.unwrap_or(false),
+ base_url: parse_url(kwargs.4)?,
+ load_remote_stylesheets: kwargs.5.unwrap_or(true),
cache: kwargs
- .5
+ .6
.map(|cache| Mutex::new(rust_inline::StylesheetCache::new(cache.size))),
- extra_css: kwargs.6.map(Cow::Owned),
- preallocate_node_capacity: kwargs.7.unwrap_or(32),
+ extra_css: kwargs.7.map(Cow::Owned),
+ preallocate_node_capacity: kwargs.8.unwrap_or(32),
resolver: Arc::new(rust_inline::DefaultStylesheetResolver),
})
}
diff --git a/bindings/ruby/lib/css_inline.rb b/bindings/ruby/lib/css_inline.rb
deleted file mode 100644
index 8d5fc2ee..00000000
--- a/bindings/ruby/lib/css_inline.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-begin
- require "css_inline/#{RUBY_VERSION.to_f}/css_inline"
-rescue LoadError
- require "css_inline/css_inline"
-end
diff --git a/css-inline/src/html/document.rs b/css-inline/src/html/document.rs
index 482afc6d..717b9595 100644
--- a/css-inline/src/html/document.rs
+++ b/css-inline/src/html/document.rs
@@ -288,9 +288,18 @@ impl Document {
styles: DocumentStyleMap<'_>,
keep_style_tags: bool,
keep_link_tags: bool,
+ at_rules: Option<&String>,
mode: InliningMode,
) -> Result<(), InlineError> {
- serialize_to(self, writer, styles, keep_style_tags, keep_link_tags, mode)
+ serialize_to(
+ self,
+ writer,
+ styles,
+ keep_style_tags,
+ keep_link_tags,
+ at_rules,
+ mode,
+ )
}
/// Filter this node iterator to elements matching the given selectors.
@@ -341,6 +350,7 @@ mod tests {
IndexMap::default(),
false,
false,
+ None,
InliningMode::Document,
)
.expect("Failed to serialize");
diff --git a/css-inline/src/html/serializer.rs b/css-inline/src/html/serializer.rs
index f5997c2d..3d7b1fba 100644
--- a/css-inline/src/html/serializer.rs
+++ b/css-inline/src/html/serializer.rs
@@ -15,6 +15,7 @@ pub(crate) fn serialize_to(
styles: DocumentStyleMap<'_>,
keep_style_tags: bool,
keep_link_tags: bool,
+ at_rules: Option<&String>,
mode: InliningMode,
) -> Result<(), InlineError> {
let sink = Sink::new(
@@ -22,6 +23,7 @@ pub(crate) fn serialize_to(
NodeId::document_id(),
keep_style_tags,
keep_link_tags,
+ at_rules,
mode,
);
let mut ser = HtmlSerializer::new(writer, styles);
@@ -34,6 +36,7 @@ struct Sink<'a> {
node: NodeId,
keep_style_tags: bool,
keep_link_tags: bool,
+ at_rules: Option<&'a String>,
inlining_mode: InliningMode,
}
@@ -43,6 +46,7 @@ impl<'a> Sink<'a> {
node: NodeId,
keep_style_tags: bool,
keep_link_tags: bool,
+ at_rules: Option<&'a String>,
inlining_mode: InliningMode,
) -> Sink<'a> {
Sink {
@@ -50,6 +54,7 @@ impl<'a> Sink<'a> {
node,
keep_style_tags,
keep_link_tags,
+ at_rules,
inlining_mode,
}
}
@@ -60,6 +65,7 @@ impl<'a> Sink<'a> {
node,
self.keep_style_tags,
self.keep_link_tags,
+ self.at_rules,
self.inlining_mode,
)
}
@@ -114,6 +120,14 @@ impl<'a> Sink<'a> {
serializer.start_elem(&element.name, &element.attributes, style_node_id)?;
+ if element.name.local == local_name!("head") {
+ if let Some(at_rules) = &self.at_rules {
+ if !at_rules.is_empty() {
+ serializer.write_at_rules_style(at_rules)?;
+ }
+ }
+ }
+
self.serialize_children(serializer)?;
serializer.end_elem(&element.name)?;
@@ -363,6 +377,13 @@ impl<'a, W: Write> HtmlSerializer<'a, W> {
Ok(())
}
+ fn write_at_rules_style(&mut self, at_rules: &str) -> Result<(), InlineError> {
+ self.writer.write_all(b"")?;
+ Ok(())
+ }
+
fn write_comment(&mut self, text: &str) -> Result<(), InlineError> {
self.writer.write_all(b"