Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Non-blocking stylesheet resolving #320

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Added

- A way to customize resolving remote stylesheets.
- Non-blocking stylesheet resolving by default.

### Changed

Expand Down
42 changes: 36 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,21 @@ const HTML: &str = r#"<html>
</body>
</html>"#;

#[tokio::main]
async fn main() -> css_inline::Result<()> {
let inlined = css_inline::inline(HTML).await?;
// Do something with inlined HTML, e.g. send an email
Ok(())
}
```

There is also a "blocking" API for inlining:

```rust
const HTML: &str = "...";

fn main() -> css_inline::Result<()> {
let inlined = css_inline::inline(HTML)?;
let inlined = css_inline::blocking::inline(HTML)?;
// Do something with inlined HTML, e.g. send an email
Ok(())
}
Expand All @@ -84,11 +97,12 @@ fn main() -> css_inline::Result<()> {
```rust
const HTML: &str = "...";

fn main() -> css_inline::Result<()> {
#[tokio::main]
async fn main() -> css_inline::Result<()> {
let inliner = css_inline::CSSInliner::options()
.load_remote_stylesheets(false)
.build();
let inlined = inliner.inline(HTML)?;
let inlined = inliner.inline(HTML).await?;
// Do something with inlined HTML, e.g. send an email
Ok(())
}
Expand Down Expand Up @@ -131,12 +145,28 @@ If you'd like to load stylesheets from your filesystem, use the `file://` scheme
```rust
const HTML: &str = "...";

fn main() -> css_inline::Result<()> {
#[tokio::main]
async fn main() -> css_inline::Result<()> {
let base_url = css_inline::Url::parse("file://styles/email/").expect("Invalid URL");
let inliner = css_inline::CSSInliner::options()
.base_url(Some(base_url))
.build();
let inlined = inliner.inline(HTML);
let inlined = inliner.inline(HTML).await?;
// Do something with inlined HTML, e.g. send an email
Ok(())
}
```

The blocking version is available as well:

```rust
const HTML: &str = "...";

fn main() -> css_inline::Result<()> {
let inliner = css_inline::blocking::CSSInliner::options()
.load_remote_stylesheets(false)
.build();
let inlined = inliner.inline(HTML)?;
// Do something with inlined HTML, e.g. send an email
Ok(())
}
Expand All @@ -149,7 +179,7 @@ For resolving remote stylesheets it is possible to implement a custom resolver:
pub struct CustomStylesheetResolver;

impl css_inline::StylesheetResolver for CustomStylesheetResolver {
fn retrieve(&self, location: &str) -> css_inline::Result<String> {
fn retrieve_blocking(&self, location: &str) -> css_inline::Result<String> {
Err(self.unsupported("External stylesheets are not supported"))
}
}
Expand Down
2 changes: 1 addition & 1 deletion bindings/c/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ cbindgen = "0.26"
path = "../../css-inline"
version = "*"
default-features = false
features = ["http", "file"]
features = ["http-blocking", "file"]
5 changes: 4 additions & 1 deletion bindings/c/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use css_inline::{CSSInliner, DefaultStylesheetResolver, InlineError, InlineOptions, Url};
use css_inline::{
blocking::{CSSInliner, InlineOptions},
DefaultStylesheetResolver, InlineError, Url,
};
use libc::{c_char, size_t};
use std::{borrow::Cow, cmp, ffi::CStr, io::Write, ptr, sync::Arc};

Expand Down
2 changes: 1 addition & 1 deletion bindings/javascript/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ serde = { version = "1", features = ["derive"], default-features = false }
path = "../../css-inline"
version = "*"
default-features = false
features = ["http", "file"]
features = ["http-blocking", "file"]

[target.'cfg(target_arch = "wasm32")'.dependencies.css-inline]
path = "../../css-inline"
Expand Down
2 changes: 1 addition & 1 deletion bindings/javascript/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ export function inline(html: string, options?: InlineOptions): string;
export function version(): string;"#;

fn inline_inner(html: String, options: Options) -> std::result::Result<String, errors::JsError> {
let inliner = css_inline::CSSInliner::new(options.try_into()?);
let inliner = css_inline::blocking::CSSInliner::new(options.try_into()?);
Ok(inliner.inline(&html).map_err(errors::InlineError)?)
}
6 changes: 3 additions & 3 deletions bindings/javascript/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ pub struct Options {
pub preallocate_node_capacity: Option<u32>,
}

impl TryFrom<Options> for css_inline::InlineOptions<'_> {
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::InlineOptions {
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),
Expand Down Expand Up @@ -75,7 +75,7 @@ impl TryFrom<Options> for css_inline::InlineOptions<'_> {
pub struct UnsupportedResolver;

impl css_inline::StylesheetResolver for UnsupportedResolver {
fn retrieve(&self, location: &str) -> css_inline::Result<String> {
fn retrieve_blocking(&self, location: &str) -> css_inline::Result<String> {
let message = if location.starts_with("https")
| location.starts_with("http")
{
Expand Down
30 changes: 15 additions & 15 deletions bindings/javascript/wasm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ heap.push(void 0, null, true, false);
function getObject(idx) {
return heap[idx];
}
var heap_next = heap.length;
function dropObject(idx) {
if (idx < 132)
return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
var WASM_VECTOR_LEN = 0;
var cachedUint8Memory0 = null;
function getUint8Memory0() {
Expand Down Expand Up @@ -104,7 +116,6 @@ function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
var heap_next = heap.length;
function addHeapObject(obj) {
if (heap_next === heap.length)
heap.push(heap.length + 1);
Expand All @@ -113,17 +124,6 @@ function addHeapObject(obj) {
heap[idx] = obj;
return idx;
}
function dropObject(idx) {
if (idx < 132)
return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
var cachedFloat64Memory0 = null;
function getFloat64Memory0() {
if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) {
Expand Down Expand Up @@ -261,6 +261,9 @@ function __wbg_get_imports() {
const ret = getObject(arg0) === void 0;
return ret;
};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
const obj = getObject(arg1);
const ret = typeof obj === "string" ? obj : void 0;
Expand Down Expand Up @@ -303,9 +306,6 @@ function __wbg_get_imports() {
const ret = +getObject(arg0);
return ret;
};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbg_length_1d25fa9e4ac21ce7 = function(arg0) {
const ret = getObject(arg0).length;
return ret;
Expand Down
4 changes: 2 additions & 2 deletions bindings/javascript/wasm/index.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading