mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
Unminify JS and dump it to a file before executing it
This commit is contained in:
parent
c8cd70f333
commit
3ad473755c
4 changed files with 86 additions and 2 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -27,3 +27,5 @@ Servo.app
|
||||||
|
|
||||||
# VSCode
|
# VSCode
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
/unminified-js
|
||||||
|
|
|
@ -228,6 +228,9 @@ pub struct Opts {
|
||||||
|
|
||||||
/// Path to SSL certificates.
|
/// Path to SSL certificates.
|
||||||
pub certificate_path: Option<String>,
|
pub certificate_path: Option<String>,
|
||||||
|
|
||||||
|
/// Unminify Javascript.
|
||||||
|
pub unminify_js: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_usage(app: &str, opts: &Options) {
|
fn print_usage(app: &str, opts: &Options) {
|
||||||
|
@ -559,6 +562,7 @@ pub fn default_opts() -> Opts {
|
||||||
precache_shaders: false,
|
precache_shaders: false,
|
||||||
signpost: false,
|
signpost: false,
|
||||||
certificate_path: None,
|
certificate_path: None,
|
||||||
|
unminify_js: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,6 +623,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
||||||
opts.optopt("", "config-dir",
|
opts.optopt("", "config-dir",
|
||||||
"config directory following xdg spec on linux platform", "");
|
"config directory following xdg spec on linux platform", "");
|
||||||
opts.optflag("v", "version", "Display servo version information");
|
opts.optflag("v", "version", "Display servo version information");
|
||||||
|
opts.optflag("", "unminify-js", "Unminify Javascript");
|
||||||
|
|
||||||
let opt_match = match opts.parse(args) {
|
let opt_match = match opts.parse(args) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
|
@ -862,6 +867,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
||||||
precache_shaders: debug_options.precache_shaders,
|
precache_shaders: debug_options.precache_shaders,
|
||||||
signpost: debug_options.signpost,
|
signpost: debug_options.signpost,
|
||||||
certificate_path: opt_match.opt_str("certificate-path"),
|
certificate_path: opt_match.opt_str("certificate-path"),
|
||||||
|
unminify_js: opt_match.opt_present("unminify-js"),
|
||||||
};
|
};
|
||||||
|
|
||||||
set_defaults(opts);
|
set_defaults(opts);
|
||||||
|
|
|
@ -34,11 +34,17 @@ use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError};
|
||||||
use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
|
use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
|
||||||
use network_listener::{NetworkListener, PreInvoke};
|
use network_listener::{NetworkListener, PreInvoke};
|
||||||
use servo_atoms::Atom;
|
use servo_atoms::Atom;
|
||||||
|
use servo_config::opts;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
|
use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct HTMLScriptElement {
|
pub struct HTMLScriptElement {
|
||||||
|
@ -450,6 +456,46 @@ impl HTMLScriptElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unminify_js(&self, script: &mut ClassicScript) {
|
||||||
|
if !opts::get().unminify_js {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let process = Command::new("js-beautify")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect("Failed to execute js-beautify");
|
||||||
|
|
||||||
|
let mut script_content = String::from(script.text.clone());
|
||||||
|
let _ = process.stdin.unwrap().write_all(script_content.as_bytes());
|
||||||
|
script_content.clear();
|
||||||
|
let _ = process.stdout.unwrap().read_to_string(&mut script_content);
|
||||||
|
|
||||||
|
script.text = DOMString::from(script_content);
|
||||||
|
|
||||||
|
let unminified_js_dir = PathBuf::from(window_from_node(self).unminified_js_dir().unwrap());
|
||||||
|
let path = if script.external {
|
||||||
|
// External script.
|
||||||
|
debug!("unminifying script {:?}", script.url);
|
||||||
|
let url = script.url.clone().into_string();
|
||||||
|
let path_parts = url.split("/").collect::<Vec<&str>>();
|
||||||
|
match path_parts.last() {
|
||||||
|
Some(script_name) => unminified_js_dir.join(script_name),
|
||||||
|
None => unminified_js_dir.join(Uuid::new_v4().to_string()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Inline script.
|
||||||
|
debug!("unminifying inline script for {:?}", script.url);
|
||||||
|
unminified_js_dir.join(Uuid::new_v4().to_string())
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("unminified script will be stored in {:?}", path);
|
||||||
|
if let Ok(mut file) = File::create(&path) {
|
||||||
|
file.write_all(script.text.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// https://html.spec.whatwg.org/multipage/#execute-the-script-block
|
/// https://html.spec.whatwg.org/multipage/#execute-the-script-block
|
||||||
pub fn execute(&self, result: Result<ClassicScript, NetworkError>) {
|
pub fn execute(&self, result: Result<ClassicScript, NetworkError>) {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
|
@ -458,7 +504,7 @@ impl HTMLScriptElement {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let script = match result {
|
let mut script = match result {
|
||||||
// Step 2.
|
// Step 2.
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("error loading script {:?}", e);
|
warn!("error loading script {:?}", e);
|
||||||
|
@ -469,6 +515,8 @@ impl HTMLScriptElement {
|
||||||
Ok(script) => script,
|
Ok(script) => script,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.unminify_js(&mut script);
|
||||||
|
|
||||||
// Step 3.
|
// Step 3.
|
||||||
let neutralized_doc = if script.external {
|
let neutralized_doc = if script.external {
|
||||||
debug!("loading external script, url = {}", script.url);
|
debug!("loading external script, url = {}", script.url);
|
||||||
|
|
|
@ -86,13 +86,15 @@ use servo_atoms::Atom;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_config::prefs::PREFS;
|
use servo_config::prefs::PREFS;
|
||||||
use servo_geometry::{f32_rect_to_au_rect, max_rect};
|
use servo_geometry::{f32_rect_to_au_rect, max_rect};
|
||||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
use servo_url::{Host, ImmutableOrigin, ServoUrl};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
use std::io::{Write, stderr, stdout};
|
use std::io::{Write, stderr, stdout};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -265,6 +267,10 @@ pub struct Window {
|
||||||
/// to ensure that the element can be marked dirty when the image data becomes
|
/// to ensure that the element can be marked dirty when the image data becomes
|
||||||
/// available at some point in the future.
|
/// available at some point in the future.
|
||||||
pending_layout_images: DOMRefCell<HashMap<PendingImageId, Vec<JS<Node>>>>,
|
pending_layout_images: DOMRefCell<HashMap<PendingImageId, Vec<JS<Node>>>>,
|
||||||
|
|
||||||
|
/// Directory to store unminified scripts for this window if unminify-js
|
||||||
|
/// opt is enabled.
|
||||||
|
unminified_js_dir: DOMRefCell<Option<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -1484,6 +1490,23 @@ 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 !opts::get().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),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -1691,6 +1714,10 @@ impl Window {
|
||||||
self.upcast::<GlobalScope>().slow_down_timers();
|
self.upcast::<GlobalScope>().slow_down_timers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unminified_js_dir(&self) -> Option<String> {
|
||||||
|
self.unminified_js_dir.borrow().clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -1785,6 +1812,7 @@ impl Window {
|
||||||
webvr_thread: webvr_thread,
|
webvr_thread: webvr_thread,
|
||||||
permission_state_invocation_results: DOMRefCell::new(HashMap::new()),
|
permission_state_invocation_results: DOMRefCell::new(HashMap::new()),
|
||||||
pending_layout_images: DOMRefCell::new(HashMap::new()),
|
pending_layout_images: DOMRefCell::new(HashMap::new()),
|
||||||
|
unminified_js_dir: DOMRefCell::new(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue