mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Support persisting unminified external stylesheets (#33919)
* Support local tweaking of external stylesheets Signed-off-by: Taym <haddadi.taym@gmail.com> * Remove duplicated code between unminify_css and unminify_js Signed-off-by: Taym <haddadi.taym@gmail.com> * Add License Signed-off-by: Taym <haddadi.taym@gmail.com> * Use js-beautify instead of npx Signed-off-by: Taym <haddadi.taym@gmail.com> * Fix clippy warning Signed-off-by: Taym <haddadi.taym@gmail.com> --------- Signed-off-by: Taym <haddadi.taym@gmail.com>
This commit is contained in:
parent
bac1101163
commit
ee68dc2589
8 changed files with 206 additions and 77 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -57,6 +57,7 @@ Session.vim
|
||||||
Sessionx.vim
|
Sessionx.vim
|
||||||
|
|
||||||
/unminified-js
|
/unminified-js
|
||||||
|
/unminified-css
|
||||||
|
|
||||||
# Layout debugger trace files
|
# Layout debugger trace files
|
||||||
layout_trace*
|
layout_trace*
|
||||||
|
|
|
@ -126,6 +126,9 @@ pub struct Opts {
|
||||||
/// Directory path that was created with "unminify-js"
|
/// Directory path that was created with "unminify-js"
|
||||||
pub local_script_source: Option<String>,
|
pub local_script_source: Option<String>,
|
||||||
|
|
||||||
|
/// Unminify Css.
|
||||||
|
pub unminify_css: bool,
|
||||||
|
|
||||||
/// Print Progressive Web Metrics to console.
|
/// Print Progressive Web Metrics to console.
|
||||||
pub print_pwm: bool,
|
pub print_pwm: bool,
|
||||||
}
|
}
|
||||||
|
@ -421,6 +424,7 @@ pub fn default_opts() -> Opts {
|
||||||
ignore_certificate_errors: false,
|
ignore_certificate_errors: false,
|
||||||
unminify_js: false,
|
unminify_js: false,
|
||||||
local_script_source: None,
|
local_script_source: None,
|
||||||
|
unminify_css: false,
|
||||||
print_pwm: false,
|
print_pwm: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,6 +564,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
|
||||||
"Directory root with unminified scripts",
|
"Directory root with unminified scripts",
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
|
opts.optflag("", "unminify-css", "Unminify Css");
|
||||||
|
|
||||||
let opt_match = match opts.parse(args) {
|
let opt_match = match opts.parse(args) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
|
@ -761,6 +766,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
|
||||||
ignore_certificate_errors: opt_match.opt_present("ignore-certificate-errors"),
|
ignore_certificate_errors: opt_match.opt_present("ignore-certificate-errors"),
|
||||||
unminify_js: opt_match.opt_present("unminify-js"),
|
unminify_js: opt_match.opt_present("unminify-js"),
|
||||||
local_script_source: opt_match.opt_str("local-script-source"),
|
local_script_source: opt_match.opt_str("local-script-source"),
|
||||||
|
unminify_css: opt_match.opt_present("unminify-css"),
|
||||||
print_pwm: opt_match.opt_present("print-pwm"),
|
print_pwm: opt_match.opt_present("print-pwm"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,9 @@ use crate::script_runtime::CanGc;
|
||||||
use crate::task::TaskCanceller;
|
use crate::task::TaskCanceller;
|
||||||
use crate::task_source::dom_manipulation::DOMManipulationTaskSource;
|
use crate::task_source::dom_manipulation::DOMManipulationTaskSource;
|
||||||
use crate::task_source::{TaskSource, TaskSourceName};
|
use crate::task_source::{TaskSource, TaskSourceName};
|
||||||
|
use crate::unminify::{
|
||||||
|
create_output_file, create_temp_files, execute_js_beautify, BeautifyFileType,
|
||||||
|
};
|
||||||
|
|
||||||
// TODO Implement offthread compilation in mozjs
|
// TODO Implement offthread compilation in mozjs
|
||||||
/*pub struct OffThreadCompilationContext {
|
/*pub struct OffThreadCompilationContext {
|
||||||
|
@ -853,17 +856,11 @@ impl HTMLScriptElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unminify_js(&self, script: &mut ScriptOrigin) {
|
fn unminify_js(&self, script: &mut ScriptOrigin) {
|
||||||
if !self.parser_document.window().unminify_js() {
|
if self.parser_document.window().unminified_js_dir().is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the minified code to a temporary file and pass its path as an argument
|
if let Some((mut input, mut output)) = create_temp_files() {
|
||||||
// to js-beautify to read from. Meanwhile, redirect the process' stdout into
|
|
||||||
// another temporary file and read that into a string. This avoids some hangs
|
|
||||||
// observed on macOS when using direct input/output pipes with very large
|
|
||||||
// unminified content.
|
|
||||||
let (input, output) = (tempfile::NamedTempFile::new(), tempfile::tempfile());
|
|
||||||
if let (Ok(mut input), Ok(mut output)) = (input, output) {
|
|
||||||
match &script.code {
|
match &script.code {
|
||||||
SourceCode::Text(text) => {
|
SourceCode::Text(text) => {
|
||||||
input.write_all(text.as_bytes()).unwrap();
|
input.write_all(text.as_bytes()).unwrap();
|
||||||
|
@ -874,66 +871,24 @@ impl HTMLScriptElement {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
match Command::new("js-beautify")
|
|
||||||
.arg(input.path())
|
if execute_js_beautify(
|
||||||
.stdout(output.try_clone().unwrap())
|
input.path(),
|
||||||
.status()
|
output.try_clone().unwrap(),
|
||||||
{
|
BeautifyFileType::Js,
|
||||||
Ok(status) if status.success() => {
|
) {
|
||||||
let mut script_content = String::new();
|
let mut script_content = String::new();
|
||||||
output.seek(std::io::SeekFrom::Start(0)).unwrap();
|
output.seek(std::io::SeekFrom::Start(0)).unwrap();
|
||||||
output.read_to_string(&mut script_content).unwrap();
|
output.read_to_string(&mut script_content).unwrap();
|
||||||
script.code = SourceCode::Text(Rc::new(DOMString::from(script_content)));
|
script.code = SourceCode::Text(Rc::new(DOMString::from(script_content)));
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
warn!("Failed to execute js-beautify. Will store unmodified script");
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
warn!("Error creating input and output files for unminify");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = match window_from_node(self).unminified_js_dir() {
|
match create_output_file(
|
||||||
Some(unminified_js_dir) => PathBuf::from(unminified_js_dir),
|
window_from_node(self).unminified_js_dir(),
|
||||||
None => {
|
&script.url,
|
||||||
warn!("Unminified script directory not found");
|
Some(script.external),
|
||||||
return;
|
) {
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let (base, has_name) = match script.url.as_str().ends_with('/') {
|
|
||||||
true => (
|
|
||||||
path.join(&script.url[url::Position::BeforeHost..])
|
|
||||||
.as_path()
|
|
||||||
.to_owned(),
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
false => (
|
|
||||||
path.join(&script.url[url::Position::BeforeHost..])
|
|
||||||
.parent()
|
|
||||||
.unwrap()
|
|
||||||
.to_owned(),
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
match create_dir_all(base.clone()) {
|
|
||||||
Ok(()) => debug!("Created base dir: {:?}", base),
|
|
||||||
Err(e) => {
|
|
||||||
debug!("Failed to create base dir: {:?}, {:?}", base, e);
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
let path = if script.external && has_name {
|
|
||||||
// External script.
|
|
||||||
path.join(&script.url[url::Position::BeforeHost..])
|
|
||||||
} else {
|
|
||||||
// Inline script or url ends with '/'
|
|
||||||
base.join(Uuid::new_v4().to_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("script will be stored in {:?}", path);
|
|
||||||
|
|
||||||
match File::create(&path) {
|
|
||||||
Ok(mut file) => match &script.code {
|
Ok(mut file) => match &script.code {
|
||||||
SourceCode::Text(text) => file.write_all(text.as_bytes()).unwrap(),
|
SourceCode::Text(text) => file.write_all(text.as_bytes()).unwrap(),
|
||||||
SourceCode::Compiled(compiled_source_code) => {
|
SourceCode::Compiled(compiled_source_code) => {
|
||||||
|
|
|
@ -297,6 +297,10 @@ pub struct Window {
|
||||||
/// opt is enabled.
|
/// opt is enabled.
|
||||||
unminified_js_dir: DomRefCell<Option<String>>,
|
unminified_js_dir: DomRefCell<Option<String>>,
|
||||||
|
|
||||||
|
/// Directory to store unminified css for this window if unminify-css
|
||||||
|
/// opt is enabled.
|
||||||
|
unminified_css_dir: DomRefCell<Option<String>>,
|
||||||
|
|
||||||
/// Directory with stored unminified scripts
|
/// Directory with stored unminified scripts
|
||||||
local_script_source: Option<String>,
|
local_script_source: Option<String>,
|
||||||
|
|
||||||
|
@ -330,6 +334,9 @@ pub struct Window {
|
||||||
/// Unminify Javascript.
|
/// Unminify Javascript.
|
||||||
unminify_js: bool,
|
unminify_js: bool,
|
||||||
|
|
||||||
|
/// Unminify Css.
|
||||||
|
unminify_css: bool,
|
||||||
|
|
||||||
/// Where to load userscripts from, if any. An empty string will load from
|
/// Where to load userscripts from, if any. An empty string will load from
|
||||||
/// the resources/user-agent-js directory, and if the option isn't passed userscripts
|
/// the resources/user-agent-js directory, and if the option isn't passed userscripts
|
||||||
/// won't be loaded.
|
/// won't be loaded.
|
||||||
|
@ -538,10 +545,6 @@ impl Window {
|
||||||
self.replace_surrogates
|
self.replace_surrogates
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unminify_js(&self) -> bool {
|
|
||||||
self.unminify_js
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_player_context(&self) -> WindowGLContext {
|
pub fn get_player_context(&self) -> WindowGLContext {
|
||||||
self.player_context.clone()
|
self.player_context.clone()
|
||||||
}
|
}
|
||||||
|
@ -2248,13 +2251,14 @@ impl Window {
|
||||||
assert!(self.document.get().is_none());
|
assert!(self.document.get().is_none());
|
||||||
assert!(document.window() == self);
|
assert!(document.window() == self);
|
||||||
self.document.set(Some(document));
|
self.document.set(Some(document));
|
||||||
if !self.unminify_js {
|
|
||||||
return;
|
set_unminified_path(self.unminify_js, &self.unminified_js_dir, "unminified-js");
|
||||||
}
|
|
||||||
// Set a path for the document host to store unminified scripts.
|
set_unminified_path(
|
||||||
let mut path = env::current_dir().unwrap();
|
self.unminify_css,
|
||||||
path.push("unminified-js");
|
&self.unminified_css_dir,
|
||||||
*self.unminified_js_dir.borrow_mut() = Some(path.into_os_string().into_string().unwrap());
|
"unminified-css",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commence a new URL load which will either replace this window or scroll to a fragment.
|
/// Commence a new URL load which will either replace this window or scroll to a fragment.
|
||||||
|
@ -2521,6 +2525,10 @@ impl Window {
|
||||||
self.unminified_js_dir.borrow().clone()
|
self.unminified_js_dir.borrow().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unminified_css_dir(&self) -> Option<String> {
|
||||||
|
self.unminified_css_dir.borrow().clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn local_script_source(&self) -> &Option<String> {
|
pub fn local_script_source(&self) -> &Option<String> {
|
||||||
&self.local_script_source
|
&self.local_script_source
|
||||||
}
|
}
|
||||||
|
@ -2585,6 +2593,7 @@ impl Window {
|
||||||
relayout_event: bool,
|
relayout_event: bool,
|
||||||
prepare_for_screenshot: bool,
|
prepare_for_screenshot: bool,
|
||||||
unminify_js: bool,
|
unminify_js: bool,
|
||||||
|
unminify_css: bool,
|
||||||
local_script_source: Option<String>,
|
local_script_source: Option<String>,
|
||||||
userscripts_path: Option<String>,
|
userscripts_path: Option<String>,
|
||||||
is_headless: bool,
|
is_headless: bool,
|
||||||
|
@ -2661,6 +2670,7 @@ impl Window {
|
||||||
webxr_registry,
|
webxr_registry,
|
||||||
pending_layout_images: Default::default(),
|
pending_layout_images: Default::default(),
|
||||||
unminified_js_dir: Default::default(),
|
unminified_js_dir: Default::default(),
|
||||||
|
unminified_css_dir: Default::default(),
|
||||||
local_script_source,
|
local_script_source,
|
||||||
test_worklet: Default::default(),
|
test_worklet: Default::default(),
|
||||||
paint_worklet: Default::default(),
|
paint_worklet: Default::default(),
|
||||||
|
@ -2671,6 +2681,7 @@ impl Window {
|
||||||
relayout_event,
|
relayout_event,
|
||||||
prepare_for_screenshot,
|
prepare_for_screenshot,
|
||||||
unminify_js,
|
unminify_js,
|
||||||
|
unminify_css,
|
||||||
userscripts_path,
|
userscripts_path,
|
||||||
replace_surrogates,
|
replace_surrogates,
|
||||||
player_context,
|
player_context,
|
||||||
|
@ -2902,3 +2913,12 @@ fn is_named_element_with_name_attribute(elem: &Element) -> bool {
|
||||||
fn is_named_element_with_id_attribute(elem: &Element) -> bool {
|
fn is_named_element_with_id_attribute(elem: &Element) -> bool {
|
||||||
elem.is_html_element()
|
elem.is_html_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_unminified_path(option: bool, dir_ref: &DomRefCell<Option<String>>, folder_name: &str) {
|
||||||
|
if option {
|
||||||
|
// Set a path for the document host to store unminified files.
|
||||||
|
let mut path = env::current_dir().unwrap();
|
||||||
|
path.push(folder_name);
|
||||||
|
*dir_ref.borrow_mut() = Some(path.into_os_string().into_string().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -94,6 +94,8 @@ mod webdriver_handlers;
|
||||||
#[warn(deprecated)]
|
#[warn(deprecated)]
|
||||||
mod window_named_properties;
|
mod window_named_properties;
|
||||||
|
|
||||||
|
mod unminify;
|
||||||
|
|
||||||
mod links;
|
mod links;
|
||||||
|
|
||||||
pub use init::init;
|
pub use init::init;
|
||||||
|
|
|
@ -707,6 +707,9 @@ pub struct ScriptThread {
|
||||||
/// Directory with stored unminified scripts
|
/// Directory with stored unminified scripts
|
||||||
local_script_source: Option<String>,
|
local_script_source: Option<String>,
|
||||||
|
|
||||||
|
/// Unminify Css.
|
||||||
|
unminify_css: bool,
|
||||||
|
|
||||||
/// Where to load userscripts from, if any. An empty string will load from
|
/// Where to load userscripts from, if any. An empty string will load from
|
||||||
/// the resources/user-agent-js directory, and if the option isn't passed userscripts
|
/// the resources/user-agent-js directory, and if the option isn't passed userscripts
|
||||||
/// won't be loaded
|
/// won't be loaded
|
||||||
|
@ -1343,6 +1346,7 @@ impl ScriptThread {
|
||||||
prepare_for_screenshot,
|
prepare_for_screenshot,
|
||||||
unminify_js: opts.unminify_js,
|
unminify_js: opts.unminify_js,
|
||||||
local_script_source: opts.local_script_source.clone(),
|
local_script_source: opts.local_script_source.clone(),
|
||||||
|
unminify_css: opts.unminify_css,
|
||||||
|
|
||||||
userscripts_path: opts.userscripts.clone(),
|
userscripts_path: opts.userscripts.clone(),
|
||||||
headless: opts.headless,
|
headless: opts.headless,
|
||||||
|
@ -3672,6 +3676,7 @@ impl ScriptThread {
|
||||||
self.relayout_event,
|
self.relayout_event,
|
||||||
self.prepare_for_screenshot,
|
self.prepare_for_screenshot,
|
||||||
self.unminify_js,
|
self.unminify_js,
|
||||||
|
self.unminify_css,
|
||||||
self.local_script_source.clone(),
|
self.local_script_source.clone(),
|
||||||
self.userscripts_path.clone(),
|
self.userscripts_path.clone(),
|
||||||
self.headless,
|
self.headless,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::io::{Read, Seek, Write};
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
use base::id::PipelineId;
|
use base::id::PipelineId;
|
||||||
|
@ -42,6 +43,9 @@ use crate::dom::shadowroot::ShadowRoot;
|
||||||
use crate::fetch::create_a_potential_cors_request;
|
use crate::fetch::create_a_potential_cors_request;
|
||||||
use crate::network_listener::{self, PreInvoke, ResourceTimingListener};
|
use crate::network_listener::{self, PreInvoke, ResourceTimingListener};
|
||||||
use crate::script_runtime::CanGc;
|
use crate::script_runtime::CanGc;
|
||||||
|
use crate::unminify::{
|
||||||
|
create_output_file, create_temp_files, execute_js_beautify, BeautifyFileType,
|
||||||
|
};
|
||||||
|
|
||||||
pub trait StylesheetOwner {
|
pub trait StylesheetOwner {
|
||||||
/// Returns whether this element was inserted by the parser (i.e., it should
|
/// Returns whether this element was inserted by the parser (i.e., it should
|
||||||
|
@ -88,6 +92,41 @@ pub struct StylesheetContext {
|
||||||
resource_timing: ResourceFetchTiming,
|
resource_timing: ResourceFetchTiming,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StylesheetContext {
|
||||||
|
fn unminify_css(&self, data: Vec<u8>, file_url: ServoUrl) -> Vec<u8> {
|
||||||
|
if self.document.root().window().unminified_css_dir().is_none() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut style_content = data;
|
||||||
|
|
||||||
|
if let Some((input, mut output)) = create_temp_files() {
|
||||||
|
if execute_js_beautify(
|
||||||
|
input.path(),
|
||||||
|
output.try_clone().unwrap(),
|
||||||
|
BeautifyFileType::Css,
|
||||||
|
) {
|
||||||
|
output.seek(std::io::SeekFrom::Start(0)).unwrap();
|
||||||
|
output.read_to_end(&mut style_content).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match create_output_file(
|
||||||
|
self.document.root().window().unminified_css_dir(),
|
||||||
|
&file_url,
|
||||||
|
None,
|
||||||
|
) {
|
||||||
|
Ok(mut file) => {
|
||||||
|
file.write_all(&style_content).unwrap();
|
||||||
|
},
|
||||||
|
Err(why) => {
|
||||||
|
log::warn!("Could not store script {:?}", why);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
style_content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PreInvoke for StylesheetContext {}
|
impl PreInvoke for StylesheetContext {}
|
||||||
|
|
||||||
impl FetchResponseListener for StylesheetContext {
|
impl FetchResponseListener for StylesheetContext {
|
||||||
|
@ -134,7 +173,8 @@ impl FetchResponseListener for StylesheetContext {
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = if is_css {
|
let data = if is_css {
|
||||||
std::mem::take(&mut self.data)
|
let data = std::mem::take(&mut self.data);
|
||||||
|
self.unminify_css(data, metadata.final_url.clone())
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
100
components/script/unminify.rs
Normal file
100
components/script/unminify.rs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::fs::{create_dir_all, File};
|
||||||
|
use std::io::{Error, ErrorKind};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
pub fn create_temp_files() -> Option<(NamedTempFile, File)> {
|
||||||
|
// Write the minified code to a temporary file and pass its path as an argument
|
||||||
|
// to js-beautify to read from. Meanwhile, redirect the process' stdout into
|
||||||
|
// another temporary file and read that into a string. This avoids some hangs
|
||||||
|
// observed on macOS when using direct input/output pipes with very large
|
||||||
|
// unminified content.
|
||||||
|
let (input, output) = (NamedTempFile::new(), tempfile::tempfile());
|
||||||
|
if let (Ok(input), Ok(output)) = (input, output) {
|
||||||
|
Some((input, output))
|
||||||
|
} else {
|
||||||
|
log::warn!("Error creating input and output temp files");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum BeautifyFileType {
|
||||||
|
Css,
|
||||||
|
Js,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute_js_beautify(input: &Path, output: File, file_type: BeautifyFileType) -> bool {
|
||||||
|
let mut cmd = Command::new("js-beautify");
|
||||||
|
match file_type {
|
||||||
|
BeautifyFileType::Js => (),
|
||||||
|
BeautifyFileType::Css => {
|
||||||
|
cmd.arg("--type").arg("css");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
match cmd.arg(input).stdout(output).status() {
|
||||||
|
Ok(status) => status.success(),
|
||||||
|
_ => {
|
||||||
|
log::warn!(
|
||||||
|
"Failed to execute js-beautify --type {:?}, Will store unmodified script",
|
||||||
|
file_type
|
||||||
|
);
|
||||||
|
false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_output_file(
|
||||||
|
unminified_dir: Option<String>,
|
||||||
|
url: &ServoUrl,
|
||||||
|
external: Option<bool>,
|
||||||
|
) -> Result<File, Error> {
|
||||||
|
let path = match unminified_dir {
|
||||||
|
Some(unminified_dir) => PathBuf::from(unminified_dir),
|
||||||
|
None => {
|
||||||
|
warn!("Unminified file directory not found");
|
||||||
|
return Err(Error::new(
|
||||||
|
ErrorKind::NotFound,
|
||||||
|
"Unminified file directory not found",
|
||||||
|
));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let (base, has_name) = match url.as_str().ends_with('/') {
|
||||||
|
true => (
|
||||||
|
path.join(&url[url::Position::BeforeHost..])
|
||||||
|
.as_path()
|
||||||
|
.to_owned(),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false => (
|
||||||
|
path.join(&url[url::Position::BeforeHost..])
|
||||||
|
.parent()
|
||||||
|
.unwrap()
|
||||||
|
.to_owned(),
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
create_dir_all(&base)?;
|
||||||
|
|
||||||
|
let path = if external.unwrap_or(true) && has_name {
|
||||||
|
// External.
|
||||||
|
path.join(&url[url::Position::BeforeHost..])
|
||||||
|
} else {
|
||||||
|
// Inline file or url ends with '/'
|
||||||
|
base.join(Uuid::new_v4().to_string())
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("Unminified files will be stored in {:?}", path);
|
||||||
|
|
||||||
|
File::create(path)
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue