Compare commits
10 Commits
1d9a930fb6
...
b77eff39e1
Author | SHA1 | Date |
---|---|---|
Michael Pfaff | b77eff39e1 | |
Wilson Lin | e5307d4c9f | |
Wilson Lin | 93ae6b6b3a | |
Wilson Lin | 1dde21ce12 | |
Wilson Lin | 44160e2ec7 | |
Wilson Lin | 49ab5efe76 | |
Wilson Lin | 6021e02648 | |
Wilson Lin | 2206d991eb | |
Wilson Lin | ad21466d2c | |
Wilson Lin | d4e0887465 |
|
@ -8,7 +8,7 @@ on:
|
|||
|
||||
jobs:
|
||||
bench:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
|
|
|
@ -11,13 +11,13 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11.0, ubuntu-18.04, windows-2019, self-hosted-linux-arm64]
|
||||
os: [macos-11.0, ubuntu-20.04, windows-2019, self-hosted-linux-arm64]
|
||||
include:
|
||||
- os: macos-11.0
|
||||
ARCH: macos-x86_64
|
||||
MIME: application/octet-stream
|
||||
EXT: ''
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
ARCH: linux-x86_64
|
||||
MIME: application/octet-stream
|
||||
EXT: ''
|
||||
|
|
|
@ -8,7 +8,7 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ on:
|
|||
|
||||
jobs:
|
||||
fuzz:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11.0, ubuntu-18.04, windows-2019]
|
||||
os: [macos-11.0, ubuntu-20.04, windows-2019]
|
||||
include:
|
||||
- os: macos-11.0
|
||||
ARCH: macos-x86_64
|
||||
FILE: 'libminify_html_java.dylib'
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
ARCH: linux-x86_64
|
||||
FILE: 'libminify_html_java.so'
|
||||
- os: windows-2019
|
||||
|
@ -47,7 +47,7 @@ jobs:
|
|||
path: ./java/target/rust/release/${{ matrix.FILE }}
|
||||
|
||||
package:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
needs: build
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11.0, ubuntu-18.04, windows-2019, self-hosted-linux-arm64]
|
||||
os: [macos-11.0, ubuntu-20.04, windows-2019, self-hosted-linux-arm64]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
|
@ -55,7 +55,7 @@ jobs:
|
|||
file: ./nodejs/index.node
|
||||
|
||||
package:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
needs: build
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
variant: [main, onepass]
|
||||
os: [macos-11.0, ubuntu-18.04, windows-2019, self-hosted-linux-arm64]
|
||||
os: [macos-11.0, ubuntu-20.04, windows-2019, self-hosted-linux-arm64]
|
||||
python: ['3.8', '3.9', '3.10', '3.11']
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
|
|
@ -11,10 +11,10 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-18.04, macos-11.0]
|
||||
os: [ubuntu-20.04, macos-11.0]
|
||||
ruby: [2.5.7, 2.6.5, 2.7.0]
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
NAME: linux
|
||||
FILE: 'libminify_html_ruby_lib.so'
|
||||
- os: macos-11.0
|
||||
|
@ -85,7 +85,7 @@ jobs:
|
|||
b2 upload-file ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} ./ruby/target/release/${{ matrix.FILE }} minify-html/bin/ruby/${{ steps.version.outputs.VERSION }}/${{ steps.native_file.outputs.NAME }}
|
||||
|
||||
package:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
needs: build
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
|
|
@ -8,7 +8,7 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,6 +1,16 @@
|
|||
# minify-html changelog
|
||||
|
||||
## Pending
|
||||
## 0.11.1
|
||||
|
||||
- Bump GitHub Actions Ubuntu image version.
|
||||
|
||||
## 0.11.0
|
||||
|
||||
- Change the default CSS minifier optimisation level to 1, as higher levels may perform dangerous optimisations.
|
||||
- Allow configuring the CSS minifier optimisation level.
|
||||
- Fix building from source in Node.js postinstall.js script.
|
||||
|
||||
## 0.10.8
|
||||
|
||||
- [Node.js] Fix assertion failure panic on invalid argument type.
|
||||
- Do not consider empty `href` attributes as redundant.
|
||||
|
|
18
README.md
18
README.md
|
@ -23,7 +23,7 @@ View the [changelog](./CHANGELOG.md) to see the latest updates.
|
|||
|
||||
Comparison with [html-minifier](https://github.com/kangax/html-minifier) and [minimize](https://github.com/Swaagie/minimize), run on the top web pages. [See the breakdown here.](./bench)
|
||||
|
||||
<img width="400" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.10.7/core/average-speeds.png"><img width="400" alt="Chart showing compression of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.10.7/core/average-sizes.png">
|
||||
<img width="400" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.11.1/core/average-speeds.png"><img width="400" alt="Chart showing compression of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.11.1/core/average-sizes.png">
|
||||
|
||||
The [onepass](https://github.com/wilsonzlin/minify-html/tree/master/rust/onepass) variant is even more optimised for speed. See its [README](https://github.com/wilsonzlin/minify-html/tree/master/rust/onepass) for more details.
|
||||
|
||||
|
@ -36,10 +36,10 @@ Precompiled binaries are available for Linux, macOS, and Windows.
|
|||
|
||||
### Get
|
||||
|
||||
[Linux x64](https://wilsonl.in/minify-html/bin/0.10.7-linux-x86_64) |
|
||||
[Linux ARM64](https://wilsonl.in/minify-html/bin/0.10.7-linux-arm64) |
|
||||
[macOS x64](https://wilsonl.in/minify-html/bin/0.10.7-macos-x86_64) |
|
||||
[Windows x64](https://wilsonl.in/minify-html/bin/0.10.7-windows-x86_64.exe)
|
||||
[Linux x64](https://wilsonl.in/minify-html/bin/0.11.1-linux-x86_64) |
|
||||
[Linux ARM64](https://wilsonl.in/minify-html/bin/0.11.1-linux-arm64) |
|
||||
[macOS x64](https://wilsonl.in/minify-html/bin/0.11.1-macos-x86_64) |
|
||||
[Windows x64](https://wilsonl.in/minify-html/bin/0.11.1-windows-x86_64.exe)
|
||||
|
||||
### Use
|
||||
|
||||
|
@ -64,7 +64,7 @@ minify-html --keep-closing-tags --minify-css /path/to/**/*.html
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
minify-html = "0.10.7"
|
||||
minify-html = "0.11.1"
|
||||
```
|
||||
|
||||
### Use
|
||||
|
@ -76,14 +76,14 @@ Check out the [docs](https://docs.rs/minify-html) for API and usage examples.
|
|||
<details>
|
||||
<summary><img width="24" src="https://wilsonl.in/minify-html/icon/deno.png"> <strong>Deno</strong></summary>
|
||||
|
||||
- Package: https://wilsonl.in/minify-html/deno/0.10.7/index.js
|
||||
- Package: https://wilsonl.in/minify-html/deno/0.11.1/index.js
|
||||
- Binding: [WASM](https://webassembly.org/)
|
||||
- Platforms: All
|
||||
|
||||
### Use
|
||||
|
||||
```ts
|
||||
import init, {minify} from "https://wilsonl.in/minify-html/deno/0.10.7/index.js";
|
||||
import init, {minify} from "https://wilsonl.in/minify-html/deno/0.11.1/index.js";
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
const decoder = new TextDecoder();
|
||||
|
@ -149,7 +149,7 @@ Add as a Maven dependency:
|
|||
<dependency>
|
||||
<groupId>in.wilsonl.minifyhtml</groupId>
|
||||
<artifactId>minify-html</artifactId>
|
||||
<version>0.10.7</version>
|
||||
<version>0.11.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ For more information on how the inputs are fetched, see [fetch.js](./fetch.js).
|
|||
|
||||
On this [project's README](../README.md), average graphs are shown. Graphs showing per-input results are shown below:
|
||||
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers per input" src="https://wilsonl.in/minify-html/bench/0.10.7/core/speeds.png"><img width="435" alt="Chart showing effectiveness of HTML minifiers per input" src="https://wilsonl.in/minify-html/bench/0.10.7/core/sizes.png">
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers per input" src="https://wilsonl.in/minify-html/bench/0.11.1/core/speeds.png"><img width="435" alt="Chart showing effectiveness of HTML minifiers per input" src="https://wilsonl.in/minify-html/bench/0.11.1/core/sizes.png">
|
||||
|
||||
Results depend on the input, so charts show performance relative to minify-html as a percentage.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
publish = false
|
||||
name = "minify-html-cli"
|
||||
description = "Extremely fast and smart HTML + JS + CSS minifier"
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -31,6 +31,18 @@ struct Cli {
|
|||
#[structopt(long)]
|
||||
minify_css: bool,
|
||||
|
||||
/// Use optimisation level 1 for the CSS minifier.
|
||||
#[structopt(long)]
|
||||
minify_css_level_1: bool,
|
||||
|
||||
/// Use optimisation level 2 for the CSS minifier. May perform some dangerous optimisations.
|
||||
#[structopt(long)]
|
||||
minify_css_level_2: bool,
|
||||
|
||||
/// Use optimisation level 3 for the CSS minifier. May perform many dangerous optimisations.
|
||||
#[structopt(long)]
|
||||
minify_css_level_3: bool,
|
||||
|
||||
#[structopt(long)]
|
||||
/// Do not minify DOCTYPEs. Minified DOCTYPEs may not be spec compliant.
|
||||
do_not_minify_doctype: bool,
|
||||
|
@ -92,6 +104,9 @@ fn main() {
|
|||
keep_html_and_head_opening_tags: args.keep_html_and_head_opening_tags,
|
||||
keep_spaces_between_attributes: args.keep_spaces_between_attributes,
|
||||
minify_css: args.minify_css,
|
||||
minify_css_level_1: args.minify_css_level_1,
|
||||
minify_css_level_2: args.minify_css_level_2,
|
||||
minify_css_level_3: args.minify_css_level_3,
|
||||
minify_js: args.minify_js,
|
||||
remove_bangs: args.remove_bangs,
|
||||
remove_processing_instructions: args.remove_processing_instructions,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
publish = false
|
||||
name = "minify-html-java"
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>in.wilsonl.minifyhtml</groupId>
|
||||
<artifactId>minify-html</artifactId>
|
||||
<version>0.10.7</version>
|
||||
<version>0.11.1</version>
|
||||
|
||||
<name>minify-html</name>
|
||||
<description>Extremely fast and smart HTML + JS + CSS minifier</description>
|
||||
|
|
|
@ -11,6 +11,9 @@ public class Configuration {
|
|||
public final boolean keep_html_and_head_opening_tags;
|
||||
public final boolean keep_spaces_between_attributes;
|
||||
public final boolean minify_css;
|
||||
public final boolean minify_css_level_1;
|
||||
public final boolean minify_css_level_2;
|
||||
public final boolean minify_css_level_3;
|
||||
public final boolean minify_js;
|
||||
public final boolean remove_bangs;
|
||||
public final boolean remove_processing_instructions;
|
||||
|
@ -23,6 +26,9 @@ public class Configuration {
|
|||
boolean keep_html_and_head_opening_tags,
|
||||
boolean keep_spaces_between_attributes,
|
||||
boolean minify_css,
|
||||
boolean minify_css_level_1,
|
||||
boolean minify_css_level_2,
|
||||
boolean minify_css_level_3,
|
||||
boolean minify_js,
|
||||
boolean remove_bangs,
|
||||
boolean remove_processing_instructions
|
||||
|
@ -34,6 +40,9 @@ public class Configuration {
|
|||
this.keep_html_and_head_opening_tags = keep_html_and_head_opening_tags;
|
||||
this.keep_spaces_between_attributes = keep_spaces_between_attributes;
|
||||
this.minify_css = minify_css;
|
||||
this.minify_css_level_1 = minify_css_level_1;
|
||||
this.minify_css_level_2 = minify_css_level_2;
|
||||
this.minify_css_level_3 = minify_css_level_3;
|
||||
this.minify_js = minify_js;
|
||||
this.remove_bangs = remove_bangs;
|
||||
this.remove_processing_instructions = remove_processing_instructions;
|
||||
|
@ -50,6 +59,9 @@ public class Configuration {
|
|||
private boolean keep_html_and_head_opening_tags = false;
|
||||
private boolean keep_spaces_between_attributes = false;
|
||||
private boolean minify_css = false;
|
||||
private boolean minify_css_level_1 = false;
|
||||
private boolean minify_css_level_2 = false;
|
||||
private boolean minify_css_level_3 = false;
|
||||
private boolean minify_js = false;
|
||||
private boolean remove_bangs = false;
|
||||
private boolean remove_processing_instructions = false;
|
||||
|
@ -89,6 +101,21 @@ public class Configuration {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setMinifyCssLevel1(boolean val) {
|
||||
this.minify_css_level_1 = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMinifyCssLevel2(boolean val) {
|
||||
this.minify_css_level_2 = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMinifyCssLevel3(boolean val) {
|
||||
this.minify_css_level_3 = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMinifyJs(boolean val) {
|
||||
this.minify_js = val;
|
||||
return this;
|
||||
|
@ -114,6 +141,9 @@ public class Configuration {
|
|||
this.keep_html_and_head_opening_tags,
|
||||
this.keep_spaces_between_attributes,
|
||||
this.minify_css,
|
||||
this.minify_css_level_1,
|
||||
this.minify_css_level_2,
|
||||
this.minify_css_level_3,
|
||||
this.minify_js,
|
||||
this.remove_bangs,
|
||||
this.remove_processing_instructions
|
||||
|
|
|
@ -37,6 +37,9 @@ fn build_cfg(env: &JNIEnv, obj: &JObject) -> Cfg {
|
|||
.z()
|
||||
.unwrap(),
|
||||
minify_css: env.get_field(*obj, "minify_css", "Z").unwrap().z().unwrap(),
|
||||
minify_css_level_1: env.get_field(*obj, "minify_css_level_1", "Z").unwrap().z().unwrap(),
|
||||
minify_css_level_2: env.get_field(*obj, "minify_css_level_2", "Z").unwrap().z().unwrap(),
|
||||
minify_css_level_3: env.get_field(*obj, "minify_css_level_3", "Z").unwrap().z().unwrap(),
|
||||
minify_js: env.get_field(*obj, "minify_js", "Z").unwrap().z().unwrap(),
|
||||
remove_bangs: env
|
||||
.get_field(*obj, "remove_bangs", "Z")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "minify-html-node"
|
||||
publish = false
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
description = "Node.js bindings for minify-html"
|
||||
authors = ["Wilson Lin <npm@wilsonl.in>"]
|
||||
edition = "2021"
|
||||
|
@ -10,7 +10,7 @@ edition = "2021"
|
|||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
minify-html = "0.10.7"
|
||||
minify-html = "0.11.1"
|
||||
|
||||
[dependencies.neon]
|
||||
version = "0.10"
|
||||
|
|
|
@ -28,6 +28,18 @@ export function minify(
|
|||
* If enabled, CSS in `<style>` tags and `style` attributes will be minified.
|
||||
*/
|
||||
minify_css?: boolean;
|
||||
/**
|
||||
* Use optimisation level 1 for the CSS minifier. This is currently the default, but may change in the future if higher levels become safe.
|
||||
*/
|
||||
minify_css_level_1?: boolean;
|
||||
/**
|
||||
* Use optimisation level 2 for the CSS minifier. This is mostly safe, but may perform some dangerous optimisations.
|
||||
*/
|
||||
minify_css_level_2?: boolean;
|
||||
/**
|
||||
* Use optimisation level 3 for the CSS minifier. This performs many dangerous optimisations, so ensure any input works with this level.
|
||||
*/
|
||||
minify_css_level_3?: boolean;
|
||||
/** Remove all bangs. */
|
||||
remove_bangs?: boolean;
|
||||
/** Remove all processing_instructions. */
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"README.md",
|
||||
"postinstall.js"
|
||||
],
|
||||
"version": "0.10.7",
|
||||
"version": "0.11.1",
|
||||
"types": "index.d.ts",
|
||||
"scripts": {
|
||||
"build": "cargo-cp-artifact --artifact cdylib minify-html-node index.node -- cargo build --message-format=json-render-diagnostics",
|
||||
|
|
|
@ -22,7 +22,11 @@ const fetch = (url) =>
|
|||
new Promise((resolve, reject) => {
|
||||
const stream = https.get(url, (resp) => {
|
||||
if (!resp.statusCode || resp.statusCode < 200 || resp.statusCode > 299) {
|
||||
return reject(new StatusError(resp.statusCode));
|
||||
reject(new StatusError(resp.statusCode));
|
||||
// Destroy stream to allow Node.js to exit.
|
||||
// Destroy after `reject` in case "error" handler is unintentionally triggered.
|
||||
resp.destroy();
|
||||
return;
|
||||
}
|
||||
const parts = [];
|
||||
resp.on("data", (chunk) => parts.push(chunk));
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
use neon::prelude::*;
|
||||
use neon::types::buffer::TypedArray;
|
||||
|
||||
macro_rules! get_bool {
|
||||
($cx:expr, $opt:expr, $name:literal) => {
|
||||
$opt.get_opt::<JsBoolean, _, _>(&mut $cx, $name)?
|
||||
.map(|v| v.value(&mut $cx))
|
||||
.unwrap_or(false)
|
||||
};
|
||||
}
|
||||
|
||||
fn minify(mut cx: FunctionContext) -> JsResult<JsBuffer> {
|
||||
let Ok(src) = cx.try_catch(|cx| cx.argument::<JsBuffer>(0)) else {
|
||||
return cx.throw_type_error("the first argument is not a Buffer");
|
||||
|
@ -9,46 +17,23 @@ fn minify(mut cx: FunctionContext) -> JsResult<JsBuffer> {
|
|||
return cx.throw_type_error("the second argument is not an object");
|
||||
};
|
||||
let cfg = minify_html::Cfg {
|
||||
do_not_minify_doctype: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "do_not_minify_doctype")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
ensure_spec_compliant_unquoted_attribute_values: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "ensure_spec_compliant_unquoted_attribute_values")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_closing_tags: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_closing_tags")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_html_and_head_opening_tags: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_html_and_head_opening_tags")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_spaces_between_attributes: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_spaces_between_attributes")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_comments: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_comments")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
minify_css: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "minify_css")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
minify_js: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "minify_js")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
remove_bangs: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "remove_bangs")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
remove_processing_instructions: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "remove_processing_instructions")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
do_not_minify_doctype: get_bool!(cx, opt, "do_not_minify_doctype"),
|
||||
ensure_spec_compliant_unquoted_attribute_values: get_bool!(
|
||||
cx,
|
||||
opt,
|
||||
"ensure_spec_compliant_unquoted_attribute_values"
|
||||
),
|
||||
keep_closing_tags: get_bool!(cx, opt, "keep_closing_tags"),
|
||||
keep_html_and_head_opening_tags: get_bool!(cx, opt, "keep_html_and_head_opening_tags"),
|
||||
keep_spaces_between_attributes: get_bool!(cx, opt, "keep_spaces_between_attributes"),
|
||||
keep_comments: get_bool!(cx, opt, "keep_comments"),
|
||||
minify_css: get_bool!(cx, opt, "minify_css"),
|
||||
minify_css_level_1: get_bool!(cx, opt, "minify_css_level_1"),
|
||||
minify_css_level_2: get_bool!(cx, opt, "minify_css_level_2"),
|
||||
minify_css_level_3: get_bool!(cx, opt, "minify_css_level_3"),
|
||||
minify_js: get_bool!(cx, opt, "minify_js"),
|
||||
remove_bangs: get_bool!(cx, opt, "remove_bangs"),
|
||||
remove_processing_instructions: get_bool!(cx, opt, "remove_processing_instructions"),
|
||||
};
|
||||
let out = minify_html::minify(src.as_slice(&mut cx), &cfg);
|
||||
Ok(JsBuffer::external(&mut cx, out))
|
||||
|
|
|
@ -6,7 +6,7 @@ license = "MIT"
|
|||
homepage = "https://github.com/wilsonzlin/minify-html"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/wilsonzlin/minify-html.git"
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ use std::string::String;
|
|||
keep_html_and_head_opening_tags = "false",
|
||||
keep_spaces_between_attributes = "false",
|
||||
minify_css = "false",
|
||||
minify_css_level_1 = "false",
|
||||
minify_css_level_2 = "false",
|
||||
minify_css_level_3 = "false",
|
||||
minify_js = "false",
|
||||
remove_bangs = "false",
|
||||
remove_processing_instructions = "false"
|
||||
|
@ -25,6 +28,9 @@ fn minify(
|
|||
keep_html_and_head_opening_tags: bool,
|
||||
keep_spaces_between_attributes: bool,
|
||||
minify_css: bool,
|
||||
minify_css_level_1: bool,
|
||||
minify_css_level_2: bool,
|
||||
minify_css_level_3: bool,
|
||||
minify_js: bool,
|
||||
remove_bangs: bool,
|
||||
remove_processing_instructions: bool,
|
||||
|
@ -40,6 +46,9 @@ fn minify(
|
|||
keep_html_and_head_opening_tags,
|
||||
keep_spaces_between_attributes,
|
||||
minify_css,
|
||||
minify_css_level_1,
|
||||
minify_css_level_2,
|
||||
minify_css_level_3,
|
||||
minify_js,
|
||||
remove_bangs,
|
||||
remove_processing_instructions,
|
||||
|
|
|
@ -6,7 +6,7 @@ license = "MIT"
|
|||
homepage = "https://github.com/wilsonzlin/minify-html"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/wilsonzlin/minify-html.git"
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
publish = false
|
||||
name = "minify-html-ruby"
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ require 'rake'
|
|||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "minify_html"
|
||||
spec.version = "0.10.7"
|
||||
spec.version = "0.11.1"
|
||||
spec.authors = ["Wilson Lin"]
|
||||
spec.email = ["code@wilsonl.in"]
|
||||
spec.license = "MIT"
|
||||
|
|
|
@ -36,6 +36,9 @@ methods! {
|
|||
keep_html_and_head_opening_tags: get_cfg_hash_prop!(cfg_hash, "keep_html_and_head_opening_tags"),
|
||||
keep_spaces_between_attributes: get_cfg_hash_prop!(cfg_hash, "keep_spaces_between_attributes"),
|
||||
minify_css: get_cfg_hash_prop!(cfg_hash, "minify_css"),
|
||||
minify_css_level_1: get_cfg_hash_prop!(cfg_hash, "minify_css_level_1"),
|
||||
minify_css_level_2: get_cfg_hash_prop!(cfg_hash, "minify_css_level_2"),
|
||||
minify_css_level_3: get_cfg_hash_prop!(cfg_hash, "minify_css_level_3"),
|
||||
minify_js: get_cfg_hash_prop!(cfg_hash, "minify_js"),
|
||||
remove_bangs: get_cfg_hash_prop!(cfg_hash, "remove_bangs"),
|
||||
remove_processing_instructions: get_cfg_hash_prop!(cfg_hash, "remove_processing_instructions"),
|
||||
|
|
|
@ -7,7 +7,7 @@ readme = "README.md"
|
|||
keywords = ["html", "compress", "minifier", "js", "css"]
|
||||
categories = ["compression", "command-line-utilities", "development-tools::build-utils", "web-programming"]
|
||||
repository = "https://github.com/wilsonzlin/minify-html.git"
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md"]
|
||||
|
|
|
@ -50,8 +50,8 @@ impl Eq for AttrVal {}
|
|||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub enum RcdataContentType {
|
||||
Textarea,
|
||||
Title,
|
||||
Textarea,
|
||||
Title,
|
||||
}
|
||||
|
||||
// Derive Eq for testing.
|
||||
|
|
|
@ -14,9 +14,15 @@ pub struct Cfg {
|
|||
pub keep_spaces_between_attributes: bool,
|
||||
/// Keep all comments.
|
||||
pub keep_comments: bool,
|
||||
/// If enabled, CSS in `<style>` tags and `style` attributes are minified.
|
||||
/// Minify CSS in `<style>` tags and `style` attributes using [https://github.com/Mnwa/css-minify](css-minify). By default, the optimisation level is 1 as specified by the CSS minifier, but this can be adjusted by the minify_css_level_* settings.
|
||||
pub minify_css: bool,
|
||||
/// If enabled, JavaScript in `<script>` tags are minified using
|
||||
/// Use optimisation level 1 for the CSS minifier. This is currently the default, but may change in the future if higher levels become safe.
|
||||
pub minify_css_level_1: bool,
|
||||
/// Use optimisation level 2 for the CSS minifier. This is mostly safe, but may perform some dangerous optimisations.
|
||||
pub minify_css_level_2: bool,
|
||||
/// Use optimisation level 3 for the CSS minifier. This performs many dangerous optimisations, so ensure any input works with this level.
|
||||
pub minify_css_level_3: bool,
|
||||
/// Minify JavaScript in `<script>` tags using
|
||||
/// [minify-js](https://github.com/wilsonzlin/minify-js).
|
||||
///
|
||||
/// Only `<script>` tags with a valid or no
|
||||
|
|
|
@ -6,7 +6,19 @@ use css_minify::optimizations::{Level, Minifier};
|
|||
|
||||
pub fn minify_css(cfg: &Cfg, out: &mut Vec<u8>, code: &[u8]) {
|
||||
if cfg.minify_css {
|
||||
let result = Minifier::default().minify(unsafe { from_utf8_unchecked(code) }, Level::Three);
|
||||
let result = Minifier::default().minify(
|
||||
unsafe { from_utf8_unchecked(code) },
|
||||
if cfg.minify_css_level_1 {
|
||||
Level::One
|
||||
} else if cfg.minify_css_level_2 {
|
||||
Level::Two
|
||||
} else if cfg.minify_css_level_3 {
|
||||
Level::Three
|
||||
} else {
|
||||
// Default to One, as other levels may perform dangerous optimisations.
|
||||
Level::One
|
||||
},
|
||||
);
|
||||
// TODO Collect error as warning.
|
||||
if let Ok(min) = result {
|
||||
if min.len() < code.len() {
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use crate::{ast::RcdataContentType, tag::{TAG_TEXTAREA_END, TAG_TITLE_END}, entity::encode::encode_entities};
|
||||
use crate::{
|
||||
ast::RcdataContentType,
|
||||
entity::encode::encode_entities,
|
||||
tag::{TAG_TEXTAREA_END, TAG_TITLE_END},
|
||||
};
|
||||
|
||||
pub fn minify_rcdata(out: &mut Vec<u8>, typ: RcdataContentType, text: &[u8]) {
|
||||
// Encode entities, since they're still decoded by the browser.
|
||||
|
@ -6,12 +10,16 @@ pub fn minify_rcdata(out: &mut Vec<u8>, typ: RcdataContentType, text: &[u8]) {
|
|||
|
||||
// Since the text has been decoded, there may be unintentional matches to end tags that we must escape.
|
||||
let html = match typ {
|
||||
RcdataContentType::Textarea => &*TAG_TEXTAREA_END,
|
||||
RcdataContentType::Title => &*TAG_TITLE_END,
|
||||
}.replace_all_bytes(&html, &[match typ {
|
||||
RcdataContentType::Textarea => b"</textarea".as_slice(),
|
||||
RcdataContentType::Title => b"</title".as_slice(),
|
||||
}]);
|
||||
RcdataContentType::Textarea => &*TAG_TEXTAREA_END,
|
||||
RcdataContentType::Title => &*TAG_TITLE_END,
|
||||
}
|
||||
.replace_all_bytes(
|
||||
&html,
|
||||
&[match typ {
|
||||
RcdataContentType::Textarea => b"</textarea".as_slice(),
|
||||
RcdataContentType::Title => b"</title".as_slice(),
|
||||
}],
|
||||
);
|
||||
|
||||
out.extend_from_slice(&html);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ readme = "README.md"
|
|||
keywords = ["html", "compress", "minifier", "js", "css"]
|
||||
categories = ["compression", "command-line-utilities", "development-tools::build-utils", "web-programming"]
|
||||
repository = "https://github.com/wilsonzlin/minify-html.git"
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md"]
|
||||
|
|
|
@ -8,7 +8,7 @@ An HTML minifier that provides the functionality of [minify-html](https://github
|
|||
|
||||
## Performance
|
||||
|
||||
<img width="600" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.10.7/core/average-speeds.png">
|
||||
<img width="600" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.11.1/core/average-speeds.png">
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/// Represents the type of minification error.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ErrorType {
|
||||
ClosingTagMismatch { expected: String, got: String },
|
||||
NotFound(&'static str),
|
||||
|
@ -7,36 +7,41 @@ pub enum ErrorType {
|
|||
UnexpectedClosingTag,
|
||||
}
|
||||
|
||||
impl ErrorType {
|
||||
/// Generates an English message describing the error with any additional context.
|
||||
pub fn message(self) -> String {
|
||||
impl std::fmt::Display for ErrorType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ErrorType::ClosingTagMismatch { expected, got } => {
|
||||
format!(
|
||||
"Closing tag name does not match opening tag (expected \"{}\", got \"{}\").",
|
||||
write!(f,
|
||||
"closing tag name does not match opening tag (expected \"{}\", got \"{}\")",
|
||||
expected, got
|
||||
)
|
||||
}
|
||||
ErrorType::NotFound(exp) => {
|
||||
format!("Expected {}.", exp)
|
||||
write!(f, "expected {}", exp)
|
||||
}
|
||||
ErrorType::UnexpectedEnd => {
|
||||
format!("Unexpected end of source code.")
|
||||
f.write_str("unexpected end of source code")
|
||||
}
|
||||
ErrorType::UnexpectedClosingTag => {
|
||||
format!("Unexpected closing tag.")
|
||||
f.write_str("unexpected closing tag")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Details about a minification failure, including where it occurred and why.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Error {
|
||||
pub error_type: ErrorType,
|
||||
pub position: usize,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "At {}, {}", self.position, self.error_type)
|
||||
}
|
||||
}
|
||||
|
||||
/// User-friendly details about a minification failure, including an English message description of
|
||||
/// the reason, and generated printable contextual representation of the code where the error
|
||||
/// occurred.
|
||||
|
|
|
@ -189,7 +189,7 @@ pub fn copy(code: &[u8], cfg: &Cfg) -> Result<Vec<u8>, Error> {
|
|||
pub fn with_friendly_error(code: &mut [u8], cfg: &Cfg) -> Result<usize, FriendlyError> {
|
||||
in_place(code, cfg).map_err(|err| FriendlyError {
|
||||
position: err.position,
|
||||
message: err.error_type.message(),
|
||||
message: err.error_type.to_string(),
|
||||
code_context: debug_repr(code, err.position as isize, -1),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "index"
|
||||
publish = false
|
||||
version = "0.10.7"
|
||||
version = "0.11.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2021"
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ pub fn minify(code: &[u8], cfg: &JsValue) -> Vec<u8> {
|
|||
keep_spaces_between_attributes: get_prop!(cfg, "keep_spaces_between_attributes"),
|
||||
keep_comments: get_prop!(cfg, "keep_comments"),
|
||||
minify_css: get_prop!(cfg, "minify_css"),
|
||||
minify_css_level_1: get_prop!(cfg, "minify_css_level_1"),
|
||||
minify_css_level_2: get_prop!(cfg, "minify_css_level_2"),
|
||||
minify_css_level_3: get_prop!(cfg, "minify_css_level_3"),
|
||||
minify_js: get_prop!(cfg, "minify_js"),
|
||||
remove_bangs: get_prop!(cfg, "remove_bangs"),
|
||||
remove_processing_instructions: get_prop!(cfg, "remove_processing_instructions"),
|
||||
|
|
Loading…
Reference in New Issue