reading unminified scripts from disk

This commit is contained in:
skrzyp1 2020-06-02 19:32:52 +02:00
parent 6a1cb940bf
commit ee6906443f
6 changed files with 91 additions and 31 deletions

View file

@ -210,6 +210,9 @@ pub struct Opts {
/// Unminify Javascript.
pub unminify_js: bool,
/// Directory path that was created with "unminify-js"
pub local_script_source: Option<String>,
/// Print Progressive Web Metrics to console.
pub print_pwm: bool,
}
@ -522,6 +525,7 @@ pub fn default_opts() -> Opts {
signpost: false,
certificate_path: None,
unminify_js: false,
local_script_source: None,
print_pwm: false,
}
}
@ -676,6 +680,12 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
opts.optopt("", "profiler-db-name", "Profiler database name", "");
opts.optflag("", "print-pwm", "Print Progressive Web Metrics");
opts.optopt("", "vslogger-level", "Visual Studio logger level", "Warn");
opts.optopt(
"",
"local-script-source",
"Directory root with unminified scripts",
"",
);
let opt_match = match opts.parse(args) {
Ok(m) => m,
@ -923,6 +933,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR
signpost: debug_options.signpost,
certificate_path: opt_match.opt_str("certificate-path"),
unminify_js: opt_match.opt_present("unminify-js"),
local_script_source: opt_match.opt_str("local-script-source"),
print_pwm: opt_match.opt_present("print-pwm"),
};

View file

@ -584,6 +584,7 @@ impl UnprivilegedPipelineContent {
self.opts.exit_after_load ||
self.opts.webdriver_port.is_some(),
self.opts.unminify_js,
self.opts.local_script_source,
self.opts.userscripts,
self.opts.headless,
self.opts.replace_surrogates,

View file

@ -45,7 +45,7 @@ use servo_atoms::Atom;
use servo_url::ImmutableOrigin;
use servo_url::ServoUrl;
use std::cell::Cell;
use std::fs::File;
use std::fs::{create_dir_all, read_to_string, File};
use std::io::{Read, Seek, Write};
use std::path::PathBuf;
use std::process::Command;
@ -698,17 +698,34 @@ impl HTMLScriptElement {
return;
},
}
let path = if script.external {
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.
let path_parts = script.url.path_segments().unwrap();
match path_parts.last() {
Some(script_name) => path.join(script_name),
None => path.join(Uuid::new_v4().to_string()),
}
path.join(&script.url[url::Position::BeforeHost..])
} else {
// Inline script.
path.join(Uuid::new_v4().to_string())
// Inline script or url ends with '/'
base.join(Uuid::new_v4().to_string())
};
debug!("script will be stored in {:?}", path);
@ -719,6 +736,34 @@ impl HTMLScriptElement {
}
}
fn substitute_with_local_script(&self, script: &mut ScriptOrigin) {
if self
.parser_document
.window()
.local_script_source()
.is_none() ||
!script.external
{
return;
}
let mut path = PathBuf::from(
self.parser_document
.window()
.local_script_source()
.clone()
.unwrap(),
);
path = path.join(&script.url[url::Position::BeforeHost..]);
debug!("Attempting to read script stored at: {:?}", path);
match read_to_string(path.clone()) {
Ok(local_script) => {
debug!("Found script stored at: {:?}", path);
script.text = DOMString::from(local_script);
},
Err(why) => warn!("Could not restore script from file {:?}", why),
}
}
/// <https://html.spec.whatwg.org/multipage/#execute-the-script-block>
pub fn execute(&self, result: ScriptResult) {
// Step 1.
@ -740,6 +785,7 @@ impl HTMLScriptElement {
if script.type_ == ScriptType::Classic {
self.unminify_js(&mut script);
self.substitute_with_local_script(&mut script);
}
// Step 3.

View file

@ -119,7 +119,7 @@ use script_traits::{
use script_traits::{TimerSchedulerMsg, WebrenderIpcSender, WindowSizeData, WindowSizeType};
use selectors::attr::CaseSensitivity;
use servo_geometry::{f32_rect_to_au_rect, MaxRect};
use servo_url::{Host, ImmutableOrigin, MutableOrigin, ServoUrl};
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
use std::borrow::Cow;
use std::borrow::ToOwned;
use std::cell::Cell;
@ -127,7 +127,6 @@ use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::env;
use std::fs;
use std::io::{stderr, stdout, Write};
use std::mem;
use std::rc::Rc;
@ -287,6 +286,9 @@ pub struct Window {
/// opt is enabled.
unminified_js_dir: DomRefCell<Option<String>>,
/// Directory with stored unminified scripts
local_script_source: Option<String>,
/// Worklets
test_worklet: MutNullableDom<Worklet>,
/// <https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet>
@ -1977,25 +1979,10 @@ impl Window {
if !self.unminify_js {
return;
}
// Create a folder for the document host to store unminified scripts.
if let Some(&Host::Domain(ref host)) = document.url().origin().host() {
let mut path = env::current_dir().unwrap();
path.push("unminified-js");
path.push(host);
let _ = fs::remove_dir_all(&path);
match fs::create_dir_all(&path) {
Ok(_) => {
*self.unminified_js_dir.borrow_mut() =
Some(path.into_os_string().into_string().unwrap());
debug!(
"Created folder for {:?} unminified scripts {:?}",
host,
self.unminified_js_dir.borrow()
);
},
Err(_) => warn!("Could not create unminified dir for {:?}", host),
}
}
// Set a path for the document host to store unminified scripts.
let mut path = env::current_dir().unwrap();
path.push("unminified-js");
*self.unminified_js_dir.borrow_mut() = Some(path.into_os_string().into_string().unwrap());
}
/// Commence a new URL load which will either replace this window or scroll to a fragment.
@ -2271,6 +2258,10 @@ impl Window {
self.unminified_js_dir.borrow().clone()
}
pub fn local_script_source(&self) -> &Option<String> {
&self.local_script_source
}
pub fn set_navigation_start(&self) {
let current_time = time::get_time();
let now = (current_time.sec * 1000 + current_time.nsec as i64 / 1000000) as u64;
@ -2334,6 +2325,7 @@ impl Window {
relayout_event: bool,
prepare_for_screenshot: bool,
unminify_js: bool,
local_script_source: Option<String>,
userscripts_path: Option<String>,
is_headless: bool,
replace_surrogates: bool,
@ -2408,6 +2400,7 @@ impl Window {
webxr_registry,
pending_layout_images: Default::default(),
unminified_js_dir: Default::default(),
local_script_source,
test_worklet: Default::default(),
paint_worklet: Default::default(),
webrender_document,

View file

@ -649,6 +649,9 @@ pub struct ScriptThread {
/// Unminify Javascript.
unminify_js: bool,
/// Directory with stored unminified scripts
local_script_source: Option<String>,
/// 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
/// won't be loaded
@ -723,6 +726,7 @@ impl ScriptThreadFactory for ScriptThread {
relayout_event: bool,
prepare_for_screenshot: bool,
unminify_js: bool,
local_script_source: Option<String>,
userscripts_path: Option<String>,
headless: bool,
replace_surrogates: bool,
@ -758,6 +762,7 @@ impl ScriptThreadFactory for ScriptThread {
relayout_event,
prepare_for_screenshot,
unminify_js,
local_script_source,
userscripts_path,
headless,
replace_surrogates,
@ -1209,6 +1214,7 @@ impl ScriptThread {
relayout_event: bool,
prepare_for_screenshot: bool,
unminify_js: bool,
local_script_source: Option<String>,
userscripts_path: Option<String>,
headless: bool,
replace_surrogates: bool,
@ -1322,6 +1328,7 @@ impl ScriptThread {
relayout_event,
prepare_for_screenshot,
unminify_js,
local_script_source,
userscripts_path,
headless,
@ -3161,6 +3168,7 @@ impl ScriptThread {
self.relayout_event,
self.prepare_for_screenshot,
self.unminify_js,
self.local_script_source.clone(),
self.userscripts_path.clone(),
self.headless,
self.replace_surrogates,

View file

@ -697,6 +697,7 @@ pub trait ScriptThreadFactory {
relayout_event: bool,
prepare_for_screenshot: bool,
unminify_js: bool,
local_script_source: Option<String>,
userscripts_path: Option<String>,
headless: bool,
replace_surrogates: bool,