aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-04-12 11:11:23 -0500
committerGitHub <noreply@github.com>2017-04-12 11:11:23 -0500
commitbc9d7863b6763e59f7efed3d5c9870b19bafb195 (patch)
treef6ad68446155b4d27d88a9429e9ee73eda1de04c /components/script/dom
parent0912bd06d7c5f5560de43a47b2f15002f334a533 (diff)
parent11f227b4fff8e832f1bd140ee7db70d10475aea0 (diff)
downloadservo-bc9d7863b6763e59f7efed3d5c9870b19bafb195.tar.gz
servo-bc9d7863b6763e59f7efed3d5c9870b19bafb195.zip
Auto merge of #16348 - ferjm:issue-14824-unminify-js, r=jdm
Unminify JS and dump it to a file before executing it - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14824 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16348) <!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/htmlscriptelement.rs53
-rw-r--r--components/script/dom/window.rs30
2 files changed, 81 insertions, 2 deletions
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index f13c0224b1a..d6679c5168c 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -34,11 +34,17 @@ use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError};
use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
use network_listener::{NetworkListener, PreInvoke};
use servo_atoms::Atom;
+use servo_config::opts;
use servo_url::ServoUrl;
use std::ascii::AsciiExt;
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 style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
+use uuid::Uuid;
#[dom_struct]
pub struct HTMLScriptElement {
@@ -450,6 +456,49 @@ impl HTMLScriptElement {
}
}
+ fn unminify_js(&self, script: &mut ClassicScript) {
+ if !opts::get().unminify_js {
+ return;
+ }
+
+ match Command::new("js-beautify")
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .spawn() {
+ Err(_) => {
+ warn!("Failed to execute js-beautify. Will store unmodified script");
+ },
+ Ok(process) => {
+ 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 path = PathBuf::from(window_from_node(self).unminified_js_dir().unwrap());
+ let path = if script.external {
+ // 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()),
+ }
+ } else {
+ // Inline script.
+ path.join(Uuid::new_v4().to_string())
+ };
+
+ debug!("script will be stored in {:?}", path);
+
+ match File::create(&path) {
+ Ok(mut file) => file.write_all(script.text.as_bytes()).unwrap(),
+ Err(why) => warn!("Could not store script {:?}", why),
+ }
+ }
+
/// https://html.spec.whatwg.org/multipage/#execute-the-script-block
pub fn execute(&self, result: Result<ClassicScript, NetworkError>) {
// Step 1.
@@ -458,7 +507,7 @@ impl HTMLScriptElement {
return;
}
- let script = match result {
+ let mut script = match result {
// Step 2.
Err(e) => {
warn!("error loading script {:?}", e);
@@ -469,6 +518,8 @@ impl HTMLScriptElement {
Ok(script) => script,
};
+ self.unminify_js(&mut script);
+
// Step 3.
let neutralized_doc = if script.external {
debug!("loading external script, url = {}", script.url);
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 94cebd6975f..ac39049b8dd 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -86,13 +86,15 @@ use servo_atoms::Atom;
use servo_config::opts;
use servo_config::prefs::PREFS;
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::borrow::ToOwned;
use std::cell::Cell;
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry;
use std::default::Default;
+use std::env;
+use std::fs;
use std::io::{Write, stderr, stdout};
use std::mem;
use std::rc::Rc;
@@ -267,6 +269,10 @@ pub struct Window {
/// to ensure that the element can be marked dirty when the image data becomes
/// available at some point in the future.
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 {
@@ -1488,6 +1494,23 @@ impl Window {
assert!(self.document.get().is_none());
assert!(document.window() == self);
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.
@@ -1695,6 +1718,10 @@ impl Window {
self.upcast::<GlobalScope>().slow_down_timers();
}
}
+
+ pub fn unminified_js_dir(&self) -> Option<String> {
+ self.unminified_js_dir.borrow().clone()
+ }
}
impl Window {
@@ -1789,6 +1816,7 @@ impl Window {
webvr_thread: webvr_thread,
permission_state_invocation_results: DOMRefCell::new(HashMap::new()),
pending_layout_images: DOMRefCell::new(HashMap::new()),
+ unminified_js_dir: DOMRefCell::new(None),
};
unsafe {