Skip to content

Commit

Permalink
feat: Non-blocking stylesheet resolving
Browse files Browse the repository at this point in the history
  • Loading branch information
Stranger6667 committed Jan 1, 2024
1 parent a52171c commit 568bf17
Show file tree
Hide file tree
Showing 25 changed files with 704 additions and 509 deletions.
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

0 comments on commit 568bf17

Please sign in to comment.