Skip to content

Commit ef14028

Browse files
authored
chore: Replaced the kuchiki crate with our custom-built HTML tree representation (#186)
1 parent 8de09cd commit ef14028

27 files changed

+1624
-96
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## [Unreleased]
44

5+
### Internal
6+
7+
- Replaced the `kuchiki` crate with our custom-built HTML tree representation. [#176](https://github.com/Stranger6667/css-inline/issues/176)
8+
9+
### Performance
10+
11+
- 15-30% average performance improvement due switch from `kuchiki` to a custom-built HTML tree representation.
12+
513
## [0.8.5] - 2022-11-10
614

715
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ This attribute also allows you to skip `link` and `style` tags:
116116

117117
## Standards support & restrictions
118118

119-
`css-inline` is built on top of [kuchiki](https://crates.io/crates/kuchiki) and [cssparser](https://crates.io/crates/cssparser) and relies on their behavior for HTML / CSS parsing and serialization.
119+
`css-inline` is built on top of [cssparser](https://crates.io/crates/cssparser) and relies on its behavior for CSS parsing.
120120
Notably:
121121

122122
- Only HTML 5, XHTML is not supported;

bindings/python/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Performance
6+
7+
- 15-30% average performance improvement due switch from `kuchiki` to a custom-built HTML tree representation.
8+
59
## [0.8.7] - 2023-01-30
610

711
### Added

bindings/python/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ a Rust compiler to build this package from source. The minimum supported Rust ve
3030

3131
## Usage
3232

33-
To inline CSS in a HTML document:
33+
To inline CSS in an HTML document:
3434

3535
```python
3636
import css_inline
@@ -118,7 +118,7 @@ inliner.inline("...")
118118

119119
## Standards support & restrictions
120120

121-
`css-inline` is built on top of [kuchiki](https://crates.io/crates/kuchiki) and [cssparser](https://crates.io/crates/cssparser) and relies on their behavior for HTML / CSS parsing and serialization.
121+
`css-inline` is built on top of [cssparser](https://crates.io/crates/cssparser) and relies on its behavior for CSS parsing.
122122
Notably:
123123

124124
- Only HTML 5, XHTML is not supported;

bindings/python/src/lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ fn parse_url(url: Option<String>) -> PyResult<Option<url::Url>> {
6767
})
6868
}
6969

70-
/// CSSInliner(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)
70+
/// CSSInliner(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, preallocate_node_capacity=0)
7171
///
7272
/// Customizable CSS inliner.
7373
#[pyclass]
7474
#[pyo3(
75-
text_signature = "(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None)"
75+
text_signature = "(inline_style_tags=True, remove_style_tags=False, base_url=None, load_remote_stylesheets=True, extra_css=None, preallocate_node_capacity=0)"
7676
)]
7777
struct CSSInliner {
7878
inner: rust_inline::CSSInliner<'static>,
@@ -87,13 +87,16 @@ impl CSSInliner {
8787
base_url: Option<String>,
8888
load_remote_stylesheets: Option<bool>,
8989
extra_css: Option<String>,
90+
preallocate_node_capacity: Option<usize>,
9091
) -> PyResult<Self> {
9192
let options = rust_inline::InlineOptions {
9293
inline_style_tags: inline_style_tags.unwrap_or(true),
9394
remove_style_tags: remove_style_tags.unwrap_or(false),
9495
base_url: parse_url(base_url)?,
9596
load_remote_stylesheets: load_remote_stylesheets.unwrap_or(true),
9697
extra_css: extra_css.map(Cow::Owned),
98+
preallocate_node_capacity: preallocate_node_capacity
99+
.unwrap_or(rust_inline::DEFAULT_HTML_TREE_CAPACITY),
97100
};
98101
Ok(CSSInliner {
99102
inner: rust_inline::CSSInliner::new(options),
@@ -131,13 +134,16 @@ fn inline(
131134
base_url: Option<String>,
132135
load_remote_stylesheets: Option<bool>,
133136
extra_css: Option<&str>,
137+
preallocate_node_capacity: Option<usize>,
134138
) -> PyResult<String> {
135139
let options = rust_inline::InlineOptions {
136140
inline_style_tags: inline_style_tags.unwrap_or(true),
137141
remove_style_tags: remove_style_tags.unwrap_or(false),
138142
base_url: parse_url(base_url)?,
139143
load_remote_stylesheets: load_remote_stylesheets.unwrap_or(true),
140144
extra_css: extra_css.map(Cow::Borrowed),
145+
preallocate_node_capacity: preallocate_node_capacity
146+
.unwrap_or(rust_inline::DEFAULT_HTML_TREE_CAPACITY),
141147
};
142148
let inliner = rust_inline::CSSInliner::new(options);
143149
Ok(inliner.inline(html).map_err(InlineErrorWrapper)?)
@@ -157,13 +163,16 @@ fn inline_many(
157163
base_url: Option<String>,
158164
load_remote_stylesheets: Option<bool>,
159165
extra_css: Option<&str>,
166+
preallocate_node_capacity: Option<usize>,
160167
) -> PyResult<Vec<String>> {
161168
let options = rust_inline::InlineOptions {
162169
inline_style_tags: inline_style_tags.unwrap_or(true),
163170
remove_style_tags: remove_style_tags.unwrap_or(false),
164171
base_url: parse_url(base_url)?,
165172
load_remote_stylesheets: load_remote_stylesheets.unwrap_or(true),
166173
extra_css: extra_css.map(Cow::Borrowed),
174+
preallocate_node_capacity: preallocate_node_capacity
175+
.unwrap_or(rust_inline::DEFAULT_HTML_TREE_CAPACITY),
167176
};
168177
let inliner = rust_inline::CSSInliner::new(options);
169178
inline_many_impl(&inliner, htmls)

bindings/wasm/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Performance
6+
7+
- 15-30% average performance improvement due switch from `kuchiki` to a custom-built HTML tree representation.
8+
59
## [0.8.4] - 2022-11-10
610

711
### Added

bindings/wasm/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ This attribute also allows you to skip `link` and `style` tags:
7474

7575
## Standards support & restrictions
7676

77-
`css-inline` is built on top of [kuchiki](https://crates.io/crates/kuchiki) and [cssparser](https://crates.io/crates/cssparser) and relies on their behavior for HTML / CSS parsing and serialization.
77+
`css-inline` is built on top of [cssparser](https://crates.io/crates/cssparser) and relies on its behavior for CSS parsing.
7878
Notably:
7979

8080
- Only HTML 5, XHTML is not supported;

bindings/wasm/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct Options {
6767
base_url: Option<String>,
6868
load_remote_stylesheets: bool,
6969
extra_css: Option<String>,
70+
preallocate_node_capacity: Option<usize>,
7071
}
7172

7273
impl Default for Options {
@@ -77,6 +78,7 @@ impl Default for Options {
7778
base_url: None,
7879
load_remote_stylesheets: true,
7980
extra_css: None,
81+
preallocate_node_capacity: None,
8082
}
8183
}
8284
}
@@ -99,6 +101,9 @@ impl TryFrom<Options> for rust_inline::InlineOptions<'_> {
99101
base_url: parse_url(value.base_url)?,
100102
load_remote_stylesheets: value.load_remote_stylesheets,
101103
extra_css: value.extra_css.map(Cow::Owned),
104+
preallocate_node_capacity: value
105+
.preallocate_node_capacity
106+
.unwrap_or(rust_inline::DEFAULT_HTML_TREE_CAPACITY),
102107
})
103108
}
104109
}
@@ -123,6 +128,7 @@ interface InlineOptions {
123128
base_url?: string,
124129
load_remote_stylesheets?: boolean,
125130
extra_css?: string,
131+
preallocate_node_capacity?: number,
126132
}
127133
128134
export function inline(html: string, options?: InlineOptions): string;

css-inline/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,19 @@ file = []
2323

2424
[dependencies]
2525
cssparser = "0.29"
26-
kuchiki = "0.8"
26+
html5ever = "0.26.0"
2727
memchr = "2.4"
2828
attohttpc = { version = "0", default-features = false, features = ["compress", "tls-rustls"], optional = true }
2929
url = "2"
3030
smallvec = "1"
3131
indexmap = "1.8.1"
3232
pico-args = { version = "0.3", optional = true }
3333
rayon = { version = "1.5", optional = true }
34+
selectors = "0.24.0"
3435

3536
[dev-dependencies]
3637
assert_cmd = "2.0.6"
37-
criterion = ">= 0.1"
38+
criterion = { version = "0.5.1", features = [], default-features = false }
3839

3940
[[bench]]
4041
name = "inliner"

css-inline/rustfmt.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
imports_granularity = "Crate"
2+
edition = "2021"

0 commit comments

Comments
 (0)