Update Node.js library

This commit is contained in:
Wilson Lin 2021-08-07 19:48:07 +10:00
parent cc33290335
commit 60b72e5c3c
3 changed files with 57 additions and 84 deletions

View File

@ -29,9 +29,9 @@ pub extern "system" fn Java_in_wilsonl_minifyhtml_MinifyHtml_minify(
) )
-> jstring { -> jstring {
let source: String = env.get_string(input).unwrap().into(); let source: String = env.get_string(input).unwrap().into();
let mut code = source.into_bytes(); let code = source.into_bytes();
let out_code = minify_html_native(&mut code, &build_cfg(&env, &cfg)); let out_code = minify_html_native(&code, &build_cfg(&env, &cfg));
let out_code_str = from_utf8(&out_code).unwrap(); let out_code_str = from_utf8(&out_code).unwrap();
env.new_string(out_code_str).unwrap().into_inner() env.new_string(out_code_str).unwrap().into_inner()
} }

View File

@ -58,17 +58,6 @@ void js_copy_min_buf_finalizer(napi_env env, void* _finalize_data, void* finaliz
free(finalize_hint); free(finalize_hint);
} }
static inline void throw_js_ffi_error(napi_env env, ffi_error const* min_err) {
napi_value js_min_err_msg;
assert_ok(napi_create_string_utf8(env, (char const*) min_err->message, min_err->message_len, &js_min_err_msg));
napi_value js_min_err;
assert_ok(napi_create_error(env, NULL, js_min_err_msg, &js_min_err));
napi_value js_min_err_pos;
assert_ok(napi_create_int64(env, min_err->position, &js_min_err_pos));
assert_ok(napi_set_named_property(env, js_min_err, "position", js_min_err_pos));
assert_ok(napi_throw(env, js_min_err));
}
napi_value node_method_create_configuration(napi_env env, napi_callback_info info) { napi_value node_method_create_configuration(napi_env env, napi_callback_info info) {
napi_value undefined = get_undefined(env); napi_value undefined = get_undefined(env);
@ -84,23 +73,32 @@ napi_value node_method_create_configuration(napi_env env, napi_callback_info inf
} }
napi_value obj_arg = argv[0]; napi_value obj_arg = argv[0];
// Get `minifyJs` property. #define GET_CFG_PROP(prop) \
bool minify_js = false; bool prop = false; \
napi_value minify_js_value; napi_value prop##_value; \
if (napi_get_named_property(env, obj_arg, "minifyJs", &minify_js_value) == napi_ok) { if (napi_get_named_property(env, obj_arg, #prop, &prop##_value) == napi_ok) { \
// It's OK if this fails. /* It's OK if this fails. */ napi_get_value_bool(env, prop##_value, &prop); \
napi_get_value_bool(env, minify_js_value, &minify_js);
} }
// Get `minifyCss` property. GET_CFG_PROP(keep_closing_tags);
bool minify_css = false; GET_CFG_PROP(keep_comments);
napi_value minify_css_value; GET_CFG_PROP(keep_html_and_head_opening_tags);
if (napi_get_named_property(env, obj_arg, "minifyCss", &minify_css_value) == napi_ok) { GET_CFG_PROP(keep_spaces_between_attributes);
// It's OK if this fails. GET_CFG_PROP(minify_css);
napi_get_value_bool(env, minify_css_value, &minify_css); GET_CFG_PROP(minify_js);
} GET_CFG_PROP(remove_bangs);
GET_CFG_PROP(remove_processing_instructions);
Cfg const* cfg = ffi_create_cfg(minify_js, minify_css); Cfg const* cfg = ffi_create_cfg(
keep_closing_tags,
keep_comments,
keep_html_and_head_opening_tags,
keep_spaces_between_attributes,
minify_css,
minify_js,
remove_bangs,
remove_processing_instructions
);
napi_value js_cfg; napi_value js_cfg;
if (napi_create_external(env, (void*) cfg, js_cfg_finalizer, NULL, &js_cfg) != napi_ok) { if (napi_create_external(env, (void*) cfg, js_cfg_finalizer, NULL, &js_cfg) != napi_ok) {
@ -117,7 +115,6 @@ napi_value node_method_minify_in_place(napi_env env, napi_callback_info info) {
bool buffer_arg_ref_set = false; bool buffer_arg_ref_set = false;
napi_ref buffer_arg_ref; napi_ref buffer_arg_ref;
js_min_buf_metadata* min_buf_meta = NULL; js_min_buf_metadata* min_buf_meta = NULL;
ffi_error const* min_err = NULL;
size_t argc = 2; size_t argc = 2;
napi_value argv[2]; napi_value argv[2];
@ -157,11 +154,7 @@ napi_value node_method_minify_in_place(napi_env env, napi_callback_info info) {
// Run minifier in place. // Run minifier in place.
size_t min_len; size_t min_len;
min_err = ffi_in_place(buffer_data, buffer_len, cfg, &min_len); ffi_in_place(buffer_data, buffer_len, cfg, &min_len);
if (min_err != NULL) {
throw_js_ffi_error(env, min_err);
goto rollback;
}
// Create minified buffer with underlying source memory but minified length. // Create minified buffer with underlying source memory but minified length.
min_buf_meta = assert_malloc(sizeof(js_min_buf_metadata)); min_buf_meta = assert_malloc(sizeof(js_min_buf_metadata));
@ -181,10 +174,6 @@ rollback:
free(min_buf_meta); free(min_buf_meta);
cleanup: cleanup:
if (min_err != NULL) {
ffi_drop_ffi_error(min_err);
}
return min_buf_rv; return min_buf_rv;
} }
@ -193,7 +182,6 @@ napi_value node_method_minify(napi_env env, napi_callback_info info) {
napi_value min_buf_rv = undefined; napi_value min_buf_rv = undefined;
void* src_data_copy = NULL; void* src_data_copy = NULL;
ffi_error const* min_err = NULL;
size_t argc = 2; size_t argc = 2;
napi_value argv[2]; napi_value argv[2];
@ -243,11 +231,7 @@ napi_value node_method_minify(napi_env env, napi_callback_info info) {
// Run minifier in place. // Run minifier in place.
size_t min_len; size_t min_len;
min_err = ffi_in_place(src_data_copy, src_data_len, cfg, &min_len); ffi_in_place(src_data_copy, src_data_len, cfg, &min_len);
if (min_err != NULL) {
throw_js_ffi_error(env, min_err);
goto rollback;
}
// Create minified buffer with copied memory. // Create minified buffer with copied memory.
if (napi_create_external_buffer(env, min_len, src_data_copy, js_copy_min_buf_finalizer, src_data_copy, &min_buf_rv) != napi_ok) { if (napi_create_external_buffer(env, min_len, src_data_copy, js_copy_min_buf_finalizer, src_data_copy, &min_buf_rv) != napi_ok) {
@ -261,10 +245,6 @@ rollback:
free(src_data_copy); free(src_data_copy);
cleanup: cleanup:
if (min_err != NULL) {
ffi_drop_ffi_error(min_err);
}
return min_buf_rv; return min_buf_rv;
} }

View File

@ -1,11 +1,26 @@
use std::{mem, ptr, slice}; use minify_html::{minify, Cfg};
use minify_html::{Cfg, Error, in_place}; use std::slice;
#[no_mangle] #[no_mangle]
pub extern "C" fn ffi_create_cfg(minify_js: bool, minify_css: bool) -> *const Cfg { pub extern "C" fn ffi_create_cfg(
keep_closing_tags: bool,
keep_comments: bool,
keep_html_and_head_opening_tags: bool,
keep_spaces_between_attributes: bool,
minify_css: bool,
minify_js: bool,
remove_bangs: bool,
remove_processing_instructions: bool,
) -> *const Cfg {
Box::into_raw(Box::new(Cfg { Box::into_raw(Box::new(Cfg {
minify_js, keep_closing_tags,
keep_comments,
keep_html_and_head_opening_tags,
keep_spaces_between_attributes,
minify_css, minify_css,
minify_js,
remove_bangs,
remove_processing_instructions,
})) }))
} }
@ -16,40 +31,18 @@ pub extern "C" fn ffi_drop_cfg(cfg: *const Cfg) -> () {
}; };
} }
#[repr(C)]
pub struct ffi_error {
message: *mut u8,
message_len: usize,
position: usize,
}
#[no_mangle] #[no_mangle]
pub extern "C" fn ffi_drop_ffi_error(ffi_error_ptr: *const ffi_error) -> () { pub extern "C" fn ffi_in_place(
unsafe { code: *mut u8,
let ffi_error = Box::from_raw(ffi_error_ptr as *mut ffi_error); code_len: usize,
let _ = String::from_raw_parts(ffi_error.message, ffi_error.message_len, ffi_error.message_len); cfg: *const Cfg,
}; out_min_len: *mut usize,
} ) {
#[no_mangle]
pub extern "C" fn ffi_in_place(code: *mut u8, code_len: usize, cfg: *const Cfg, out_min_len: *mut usize) -> *const ffi_error {
let code_slice = unsafe { slice::from_raw_parts_mut(code, code_len) }; let code_slice = unsafe { slice::from_raw_parts_mut(code, code_len) };
match in_place(code_slice, unsafe { &*cfg }) { let min_code = minify(code_slice, unsafe { &*cfg });
Ok(min_len) => unsafe { let min_len = min_code.len();
*out_min_len = min_len; code_slice[..min_len].copy_from_slice(&min_code);
ptr::null() unsafe {
} *out_min_len = min_len;
Err(Error { error_type, position }) => {
let mut msg = error_type.message();
msg.shrink_to_fit();
let msg_ptr = msg.as_mut_ptr();
let msg_len = msg.len();
mem::forget(msg);
Box::into_raw(Box::new(ffi_error {
message: msg_ptr,
message_len: msg_len,
position,
}))
}
} }
} }