Auto merge of #21578 - kingdido999:master, r=jdm

Format components config #21373

<!-- Please describe your changes on the following line: -->

```bash
rustfmt $(find components/config/ -type f -name "*.rs")
```

<!-- 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/21578)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-09-01 22:05:40 -04:00 committed by GitHub
commit b211e45bb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 444 additions and 225 deletions

View file

@ -8,7 +8,12 @@
use std::path::PathBuf;
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
#[cfg(all(
unix,
not(target_os = "macos"),
not(target_os = "ios"),
not(target_os = "android")
))]
pub fn default_config_dir() -> Option<PathBuf> {
let mut config_dir = ::dirs::config_dir().unwrap();
config_dir.push("servo");

View file

@ -9,17 +9,21 @@ extern crate dirs;
extern crate embedder_traits;
extern crate euclid;
extern crate getopts;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate num_cpus;
extern crate rustc_serialize;
#[macro_use] extern crate serde;
#[macro_use]
extern crate serde;
extern crate servo_geometry;
extern crate servo_url;
extern crate url;
pub mod basedir;
#[allow(unsafe_code)] pub mod opts;
#[allow(unsafe_code)]
pub mod opts;
pub mod prefs;
pub fn servo_version() -> String {

View file

@ -22,7 +22,6 @@ use std::process;
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
use url::{self, Url};
/// Global flags for Servo, currently set on the command line.
#[derive(Clone, Deserialize, Serialize)]
pub struct Opts {
@ -230,11 +229,13 @@ pub struct Opts {
}
fn print_usage(app: &str, opts: &Options) {
let message = format!("Usage: {} [ options ... ] [URL]\n\twhere options include", app);
let message = format!(
"Usage: {} [ options ... ] [URL]\n\twhere options include",
app
);
println!("{}", opts.usage(&message));
}
/// Debug options for Servo, currently set on the command line with -Z
#[derive(Default)]
pub struct DebugOptions {
@ -333,7 +334,6 @@ pub struct DebugOptions {
pub signpost: bool,
}
impl DebugOptions {
pub fn extend(&mut self, debug_string: String) -> Result<(), String> {
for option in debug_string.split(',') {
@ -371,50 +371,103 @@ impl DebugOptions {
"" => {},
_ => return Err(String::from(option)),
};
};
}
Ok(())
}
}
fn print_debug_usage(app: &str) -> ! {
fn print_option(name: &str, description: &str) {
println!("\t{:<35} {}", name, description);
}
println!("Usage: {} debug option,[options,...]\n\twhere options include\n\nOptions:", app);
println!(
"Usage: {} debug option,[options,...]\n\twhere options include\n\nOptions:",
app
);
print_option("bubble-widths", "Bubble intrinsic widths separately like other engines.");
print_option(
"bubble-widths",
"Bubble intrinsic widths separately like other engines.",
);
print_option("disable-text-aa", "Disable antialiasing of rendered text.");
print_option("disable-canvas-aa", "Disable antialiasing on the HTML canvas element.");
print_option("dump-style-tree", "Print the DOM with computed styles after each restyle.");
print_option(
"disable-canvas-aa",
"Disable antialiasing on the HTML canvas element.",
);
print_option(
"dump-style-tree",
"Print the DOM with computed styles after each restyle.",
);
print_option("dump-flow-tree", "Print the flow tree after each layout.");
print_option("dump-display-list", "Print the display list after each layout.");
print_option("dump-display-list-json", "Print the display list in JSON form.");
print_option("relayout-event", "Print notifications when there is a relayout.");
print_option("profile-script-events", "Enable profiling of script-related events.");
print_option("profile-heartbeats", "Enable heartbeats for all thread categories.");
print_option("show-fragment-borders", "Paint borders along fragment boundaries.");
print_option("show-parallel-layout", "Mark which thread laid each flow out with colors.");
print_option("trace-layout", "Write layout trace to an external file for debugging.");
print_option("disable-share-style-cache",
"Disable the style sharing cache.");
print_option("parallel-display-list-building", "Build display lists in parallel.");
print_option("convert-mouse-to-touch", "Send touch events instead of mouse events");
print_option("replace-surrogates", "Replace unpaires surrogates in DOM strings with U+FFFD. \
See https://github.com/servo/servo/issues/6564");
print_option(
"dump-display-list",
"Print the display list after each layout.",
);
print_option(
"dump-display-list-json",
"Print the display list in JSON form.",
);
print_option(
"relayout-event",
"Print notifications when there is a relayout.",
);
print_option(
"profile-script-events",
"Enable profiling of script-related events.",
);
print_option(
"profile-heartbeats",
"Enable heartbeats for all thread categories.",
);
print_option(
"show-fragment-borders",
"Paint borders along fragment boundaries.",
);
print_option(
"show-parallel-layout",
"Mark which thread laid each flow out with colors.",
);
print_option(
"trace-layout",
"Write layout trace to an external file for debugging.",
);
print_option(
"disable-share-style-cache",
"Disable the style sharing cache.",
);
print_option(
"parallel-display-list-building",
"Build display lists in parallel.",
);
print_option(
"convert-mouse-to-touch",
"Send touch events instead of mouse events",
);
print_option(
"replace-surrogates",
"Replace unpaires surrogates in DOM strings with U+FFFD. \
See https://github.com/servo/servo/issues/6564",
);
print_option("gc-profile", "Log GC passes and their durations.");
print_option("load-webfonts-synchronously",
"Load web fonts synchronously to avoid non-deterministic network-driven reflows");
print_option("disable-vsync",
"Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate");
print_option(
"load-webfonts-synchronously",
"Load web fonts synchronously to avoid non-deterministic network-driven reflows",
);
print_option(
"disable-vsync",
"Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate",
);
print_option("wr-stats", "Show WebRender profiler on screen.");
print_option("msaa", "Use multisample antialiasing in WebRender.");
print_option("full-backtraces", "Print full backtraces for all errors");
print_option("wr-debug", "Display webrender tile borders.");
print_option("wr-no-batch", "Disable webrender instanced batching.");
print_option("precache-shaders", "Compile all shaders during init.");
print_option("signpost", "Emit native OS signposts for profile events (currently macOS only)");
print_option(
"signpost",
"Emit native OS signposts for profile events (currently macOS only)",
);
println!("");
@ -445,7 +498,7 @@ enum UserAgent {
Desktop,
Android,
#[allow(non_camel_case_types)]
iOS
iOS,
}
fn default_user_agent_string(agent: UserAgent) -> &'static str {
@ -468,17 +521,12 @@ fn default_user_agent_string(agent: UserAgent) -> &'static str {
const DESKTOP_UA_STRING: &'static str =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:55.0) Servo/1.0 Firefox/55.0";
match agent {
UserAgent::Desktop => {
DESKTOP_UA_STRING
}
UserAgent::Android => {
"Mozilla/5.0 (Android; Mobile; rv:55.0) Servo/1.0 Firefox/55.0"
}
UserAgent::Desktop => DESKTOP_UA_STRING,
UserAgent::Android => "Mozilla/5.0 (Android; Mobile; rv:55.0) Servo/1.0 Firefox/55.0",
UserAgent::iOS => {
"Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X; rv:55.0) Servo/1.0 Firefox/55.0"
}
},
}
}
@ -564,54 +612,146 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
opts.optopt("o", "output", "Output file", "output.png");
opts.optopt("s", "size", "Size of tiles", "512");
opts.optopt("", "device-pixel-ratio", "Device pixels per px", "");
opts.optflagopt("p", "profile", "Time profiler flag and either a TSV output filename \
OR an interval for output to Stdout (blank for Stdout with interval of 5s)", "10 \
OR time.tsv");
opts.optflagopt("", "profiler-trace-path",
"Path to dump a self-contained HTML timeline of profiler traces",
"");
opts.optflagopt("m", "memory-profile", "Memory profiler flag and output interval", "10");
opts.optflagopt(
"p",
"profile",
"Time profiler flag and either a TSV output filename \
OR an interval for output to Stdout (blank for Stdout with interval of 5s)",
"10 \
OR time.tsv",
);
opts.optflagopt(
"",
"profiler-trace-path",
"Path to dump a self-contained HTML timeline of profiler traces",
"",
);
opts.optflagopt(
"m",
"memory-profile",
"Memory profiler flag and output interval",
"10",
);
opts.optflag("x", "exit", "Exit after load flag");
opts.optopt("y", "layout-threads", "Number of threads to use for layout", "1");
opts.optflag("i", "nonincremental-layout", "Enable to turn off incremental layout.");
opts.optflagopt("", "userscripts",
"Uses userscripts in resources/user-agent-js, or a specified full path", "");
opts.optmulti("", "user-stylesheet",
"A user stylesheet to be added to every document", "file.css");
opts.optopt("", "shaders",
"Shaders will be loaded from the specified directory instead of using the builtin ones.", "");
opts.optopt(
"y",
"layout-threads",
"Number of threads to use for layout",
"1",
);
opts.optflag(
"i",
"nonincremental-layout",
"Enable to turn off incremental layout.",
);
opts.optflagopt(
"",
"userscripts",
"Uses userscripts in resources/user-agent-js, or a specified full path",
"",
);
opts.optmulti(
"",
"user-stylesheet",
"A user stylesheet to be added to every document",
"file.css",
);
opts.optopt(
"",
"shaders",
"Shaders will be loaded from the specified directory instead of using the builtin ones.",
"",
);
opts.optflag("z", "headless", "Headless mode");
opts.optflag("f", "hard-fail", "Exit on thread failure instead of displaying about:failure");
opts.optflag("F", "soft-fail", "Display about:failure on thread failure instead of exiting");
opts.optflagopt("", "remote-debugging-port", "Start remote debugger server on port", "2794");
opts.optflagopt("", "devtools", "Start remote devtools server on port", "6000");
opts.optflagopt("", "webdriver", "Start remote WebDriver server on port", "7000");
opts.optflag(
"f",
"hard-fail",
"Exit on thread failure instead of displaying about:failure",
);
opts.optflag(
"F",
"soft-fail",
"Display about:failure on thread failure instead of exiting",
);
opts.optflagopt(
"",
"remote-debugging-port",
"Start remote debugger server on port",
"2794",
);
opts.optflagopt(
"",
"devtools",
"Start remote devtools server on port",
"6000",
);
opts.optflagopt(
"",
"webdriver",
"Start remote WebDriver server on port",
"7000",
);
opts.optopt("", "resolution", "Set window resolution.", "1024x740");
opts.optopt("u",
"user-agent",
"Set custom user agent string (or ios / android / desktop for platform default)",
"NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)");
opts.optopt(
"u",
"user-agent",
"Set custom user agent string (or ios / android / desktop for platform default)",
"NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)",
);
opts.optflag("M", "multiprocess", "Run in multiprocess mode");
opts.optflag("S", "sandbox", "Run in a sandbox if multiprocess");
opts.optopt("",
"random-pipeline-closure-probability",
"Probability of randomly closing a pipeline (for testing constellation hardening).",
"0.0");
opts.optopt("", "random-pipeline-closure-seed", "A fixed seed for repeatbility of random pipeline closure.", "");
opts.optmulti("Z", "debug",
"A comma-separated string of debug options. Pass help to show available options.", "");
opts.optopt(
"",
"random-pipeline-closure-probability",
"Probability of randomly closing a pipeline (for testing constellation hardening).",
"0.0",
);
opts.optopt(
"",
"random-pipeline-closure-seed",
"A fixed seed for repeatbility of random pipeline closure.",
"",
);
opts.optmulti(
"Z",
"debug",
"A comma-separated string of debug options. Pass help to show available options.",
"",
);
opts.optflag("h", "help", "Print this message");
opts.optopt("", "resources-path", "Path to find static resources", "/home/servo/resources");
opts.optopt("", "certificate-path", "Path to find SSL certificates", "/home/servo/resources/certs");
opts.optopt("", "content-process" , "Run as a content process and connect to the given pipe",
"servo-ipc-channel.abcdefg");
opts.optmulti("", "pref",
"A preference to set to enable", "dom.bluetooth.enabled");
opts.optopt(
"",
"resources-path",
"Path to find static resources",
"/home/servo/resources",
);
opts.optopt(
"",
"certificate-path",
"Path to find SSL certificates",
"/home/servo/resources/certs",
);
opts.optopt(
"",
"content-process",
"Run as a content process and connect to the given pipe",
"servo-ipc-channel.abcdefg",
);
opts.optmulti(
"",
"pref",
"A preference to set to enable",
"dom.bluetooth.enabled",
);
opts.optflag("b", "no-native-titlebar", "Do not use native titlebar");
opts.optflag("w", "webrender", "Use webrender backend");
opts.optopt("G", "graphics", "Select graphics backend (gl or es2)", "gl");
opts.optopt("", "config-dir",
"config directory following xdg spec on linux platform", "");
opts.optopt(
"",
"config-dir",
"config directory following xdg spec on linux platform",
"",
);
opts.optflag("v", "version", "Display servo version information");
opts.optflag("", "unminify-js", "Unminify Javascript");
opts.optopt("", "profiler-db-user", "Profiler database user", "");
@ -654,44 +794,50 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
} else {
None
};
let is_running_problem_test =
url_opt
.as_ref()
.map_or(false, |url|
url.starts_with("http://web-platform.test:8000/2dcontext/drawing-images-to-the-canvas/") ||
url.starts_with("http://web-platform.test:8000/_mozilla/mozilla/canvas/") ||
url.starts_with("http://web-platform.test:8000/_mozilla/css/canvas_over_area.html"));
let is_running_problem_test = url_opt.as_ref().map_or(false, |url| {
url.starts_with("http://web-platform.test:8000/2dcontext/drawing-images-to-the-canvas/") ||
url.starts_with("http://web-platform.test:8000/_mozilla/mozilla/canvas/") ||
url.starts_with("http://web-platform.test:8000/_mozilla/css/canvas_over_area.html")
});
let url_opt = url_opt.and_then(|url_string| parse_url_or_filename(&cwd, url_string)
.or_else(|error| {
warn!("URL parsing failed ({:?}).", error);
Err(error)
}).ok());
let url_opt = url_opt.and_then(|url_string| {
parse_url_or_filename(&cwd, url_string)
.or_else(|error| {
warn!("URL parsing failed ({:?}).", error);
Err(error)
}).ok()
});
let tile_size: usize = match opt_match.opt_str("s") {
Some(tile_size_str) => tile_size_str.parse()
Some(tile_size_str) => tile_size_str
.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: -s ({})", err))),
None => 512,
};
let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str|
dppx_str.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: --device-pixel-ratio ({})", err)))
);
let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str| {
dppx_str.parse().unwrap_or_else(|err| {
args_fail(&format!(
"Error parsing option: --device-pixel-ratio ({})",
err
))
})
});
// If only the flag is present, default to a 5 second period for both profilers
let time_profiling = if opt_match.opt_present("p") {
match opt_match.opt_str("p") {
Some(argument) => match argument.parse::<f64>() {
Ok(interval) => Some(OutputOptions::Stdout(interval)) ,
Err(_) => {
match ServoUrl::parse(&argument) {
Ok(url) => Some(OutputOptions::DB(url, opt_match.opt_str("profiler-db-name"),
opt_match.opt_str("profiler-db-user"),
opt_match.opt_str("profiler-db-pass"))),
Err(_) => Some(OutputOptions::FileName(argument)),
}
}
Ok(interval) => Some(OutputOptions::Stdout(interval)),
Err(_) => match ServoUrl::parse(&argument) {
Ok(url) => Some(OutputOptions::DB(
url,
opt_match.opt_str("profiler-db-name"),
opt_match.opt_str("profiler-db-user"),
opt_match.opt_str("profiler-db-pass"),
)),
Err(_) => Some(OutputOptions::FileName(argument)),
},
},
None => Some(OutputOptions::Stdout(5.0 as f64)),
}
@ -704,34 +850,50 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
let mut path = PathBuf::from(time_profiler_trace_path);
path.pop();
if let Err(why) = fs::create_dir_all(&path) {
error!("Couldn't create/open {:?}: {:?}",
Path::new(time_profiler_trace_path).to_string_lossy(), why);
error!(
"Couldn't create/open {:?}: {:?}",
Path::new(time_profiler_trace_path).to_string_lossy(),
why
);
}
}
let mem_profiler_period = opt_match.opt_default("m", "5").map(|period| {
period.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: -m ({})", err)))
period
.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: -m ({})", err)))
});
let mut layout_threads: Option<usize> = opt_match.opt_str("y")
.map(|layout_threads_str| {
layout_threads_str.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: -y ({})", err)))
});
let mut layout_threads: Option<usize> = opt_match.opt_str("y").map(|layout_threads_str| {
layout_threads_str
.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: -y ({})", err)))
});
let nonincremental_layout = opt_match.opt_present("i");
let random_pipeline_closure_probability = opt_match.opt_str("random-pipeline-closure-probability").map(|prob|
prob.parse().unwrap_or_else(|err| {
args_fail(&format!("Error parsing option: --random-pipeline-closure-probability ({})", err))
})
);
let random_pipeline_closure_probability = opt_match
.opt_str("random-pipeline-closure-probability")
.map(|prob| {
prob.parse().unwrap_or_else(|err| {
args_fail(&format!(
"Error parsing option: --random-pipeline-closure-probability ({})",
err
))
})
});
let random_pipeline_closure_seed = opt_match.opt_str("random-pipeline-closure-seed").map(|seed|
seed.parse().unwrap_or_else(|err| {
args_fail(&format!("Error parsing option: --random-pipeline-closure-seed ({})", err))
})
);
let random_pipeline_closure_seed =
opt_match
.opt_str("random-pipeline-closure-seed")
.map(|seed| {
seed.parse().unwrap_or_else(|err| {
args_fail(&format!(
"Error parsing option: --random-pipeline-closure-seed ({})",
err
))
})
});
let mut bubble_inline_sizes_separately = debug_options.bubble_widths;
if debug_options.trace_layout {
@ -739,29 +901,40 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
bubble_inline_sizes_separately = true;
}
let debugger_port = opt_match.opt_default("remote-debugging-port", "2794").map(|port| {
port.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: --remote-debugging-port ({})", err)))
});
let debugger_port = opt_match
.opt_default("remote-debugging-port", "2794")
.map(|port| {
port.parse().unwrap_or_else(|err| {
args_fail(&format!(
"Error parsing option: --remote-debugging-port ({})",
err
))
})
});
let devtools_port = opt_match.opt_default("devtools", "6000").map(|port| {
port.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: --devtools ({})", err)))
port.parse()
.unwrap_or_else(|err| args_fail(&format!("Error parsing option: --devtools ({})", err)))
});
let webdriver_port = opt_match.opt_default("webdriver", "7000").map(|port| {
port.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: --webdriver ({})", err)))
port.parse().unwrap_or_else(|err| {
args_fail(&format!("Error parsing option: --webdriver ({})", err))
})
});
let initial_window_size = match opt_match.opt_str("resolution") {
Some(res_string) => {
let res: Vec<u32> = res_string.split('x').map(|r| {
r.parse().unwrap_or_else(|err| args_fail(&format!("Error parsing option: --resolution ({})", err)))
}).collect();
let res: Vec<u32> = res_string
.split('x')
.map(|r| {
r.parse().unwrap_or_else(|err| {
args_fail(&format!("Error parsing option: --resolution ({})", err))
})
}).collect();
TypedSize2D::new(res[0], res[1])
}
None => {
TypedSize2D::new(1024, 740)
}
},
None => TypedSize2D::new(1024, 740),
};
if opt_match.opt_present("M") {
@ -776,20 +949,24 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
None => default_user_agent_string(DEFAULT_USER_AGENT).into(),
};
let user_stylesheets = opt_match.opt_strs("user-stylesheet").iter().map(|filename| {
let path = cwd.join(filename);
let url = ServoUrl::from_url(Url::from_file_path(&path).unwrap());
let mut contents = Vec::new();
File::open(path)
.unwrap_or_else(|err| args_fail(&format!("Couldn't open {}: {}", filename, err)))
.read_to_end(&mut contents)
.unwrap_or_else(|err| args_fail(&format!("Couldn't read {}: {}", filename, err)));
(contents, url)
}).collect();
let user_stylesheets = opt_match
.opt_strs("user-stylesheet")
.iter()
.map(|filename| {
let path = cwd.join(filename);
let url = ServoUrl::from_url(Url::from_file_path(&path).unwrap());
let mut contents = Vec::new();
File::open(path)
.unwrap_or_else(|err| args_fail(&format!("Couldn't open {}: {}", filename, err)))
.read_to_end(&mut contents)
.unwrap_or_else(|err| args_fail(&format!("Couldn't read {}: {}", filename, err)));
(contents, url)
}).collect();
let do_not_use_native_titlebar =
opt_match.opt_present("b") ||
!PREFS.get("shell.native-titlebar.enabled").as_boolean().unwrap();
let do_not_use_native_titlebar = opt_match.opt_present("b") || !PREFS
.get("shell.native-titlebar.enabled")
.as_boolean()
.unwrap();
let is_printing_version = opt_match.opt_present("v") || opt_match.opt_present("version");
@ -870,7 +1047,10 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
if let Some(layout_threads) = layout_threads {
PREFS.set("layout.threads", PrefValue::Number(layout_threads as f64));
} else if let Some(layout_threads) = PREFS.get("layout.threads").as_string() {
PREFS.set("layout.threads", PrefValue::Number(layout_threads.parse::<f64>().unwrap()));
PREFS.set(
"layout.threads",
PrefValue::Number(layout_threads.parse::<f64>().unwrap()),
);
} else if *PREFS.get("layout.threads") == PrefValue::Missing {
let layout_threads = cmp::max(num_cpus::get() * 3 / 4, 1);
PREFS.set("layout.threads", PrefValue::Number(layout_threads as f64));
@ -926,8 +1106,8 @@ pub fn parse_pref_from_command_line(pref: &str) {
Some(&"true") | None => PREFS.set(pref_name, PrefValue::Boolean(true)),
Some(value) => match value.parse::<f64>() {
Ok(v) => PREFS.set(pref_name, PrefValue::Number(v)),
Err(_) => PREFS.set(pref_name, PrefValue::String(value.to_string()))
}
Err(_) => PREFS.set(pref_name, PrefValue::String(value.to_string())),
},
};
}
@ -941,7 +1121,7 @@ pub fn parse_url_or_filename(cwd: &Path, input: &str) -> Result<ServoUrl, ()> {
Ok(url) => Ok(url),
Err(url::ParseError::RelativeUrlWithoutBase) => {
Url::from_file_path(&*cwd.join(input)).map(ServoUrl::from_url)
}
},
Err(_) => Err(()),
}
}

View file

@ -30,7 +30,7 @@ pub enum PrefValue {
Boolean(bool),
String(String),
Number(f64),
Missing
Missing,
}
impl PrefValue {
@ -41,26 +41,22 @@ impl PrefValue {
Json::F64(x) => PrefValue::Number(x),
Json::I64(x) => PrefValue::Number(x as f64),
Json::U64(x) => PrefValue::Number(x as f64),
_ => return Err(())
_ => return Err(()),
};
Ok(value)
}
pub fn as_boolean(&self) -> Option<bool> {
match *self {
PrefValue::Boolean(value) => {
Some(value)
},
_ => None
PrefValue::Boolean(value) => Some(value),
_ => None,
}
}
pub fn as_string(&self) -> Option<&str> {
match *self {
PrefValue::String(ref value) => {
Some(&value)
},
_ => None
PrefValue::String(ref value) => Some(&value),
_ => None,
}
}
@ -82,16 +78,10 @@ impl PrefValue {
impl ToJson for PrefValue {
fn to_json(&self) -> Json {
match *self {
PrefValue::Boolean(x) => {
Json::Boolean(x)
},
PrefValue::String(ref x) => {
Json::String(x.clone())
},
PrefValue::Number(x) => {
Json::F64(x)
},
PrefValue::Missing => Json::Null
PrefValue::Boolean(x) => Json::Boolean(x),
PrefValue::String(ref x) => Json::String(x.clone()),
PrefValue::Number(x) => Json::F64(x),
PrefValue::Missing => Json::Null,
}
}
}
@ -99,10 +89,9 @@ impl ToJson for PrefValue {
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Pref {
NoDefault(Arc<PrefValue>),
WithDefault(Arc<PrefValue>, Option<Arc<PrefValue>>)
WithDefault(Arc<PrefValue>, Option<Arc<PrefValue>>),
}
impl Pref {
pub fn new(value: PrefValue) -> Pref {
Pref::NoDefault(Arc::new(value))
@ -120,12 +109,10 @@ impl Pref {
pub fn value(&self) -> &Arc<PrefValue> {
match *self {
Pref::NoDefault(ref x) => x,
Pref::WithDefault(ref default, ref override_value) => {
match *override_value {
Some(ref x) => x,
None => default
}
}
Pref::WithDefault(ref default, ref override_value) => match *override_value {
Some(ref x) => x,
None => default,
},
}
}
@ -133,12 +120,8 @@ impl Pref {
// TODO - this should error if we try to override a pref of one type
// with a value of a different type
match *self {
Pref::NoDefault(ref mut pref_value) => {
*pref_value = Arc::new(value)
},
Pref::WithDefault(_, ref mut override_value) => {
*override_value = Some(Arc::new(value))
}
Pref::NoDefault(ref mut pref_value) => *pref_value = Arc::new(value),
Pref::WithDefault(_, ref mut override_value) => *override_value = Some(Arc::new(value)),
}
}
}
@ -151,8 +134,10 @@ impl ToJson for Pref {
pub fn default_prefs() -> Preferences {
let prefs = Preferences(Arc::new(RwLock::new(HashMap::new())));
prefs.set("layout.threads", PrefValue::Number(
max(num_cpus::get() * 3 / 4, 1) as f64));
prefs.set(
"layout.threads",
PrefValue::Number(max(num_cpus::get() * 3 / 4, 1) as f64),
);
prefs
}
@ -169,7 +154,10 @@ pub fn read_prefs(txt: &str) -> Result<HashMap<String, Pref>, ()> {
Ok(x) => {
prefs.insert(name, x);
},
Err(_) => println!("Ignoring non-boolean/string/i64 preference value for {:?}", name),
Err(_) => println!(
"Ignoring non-boolean/string/i64 preference value for {:?}",
name
),
}
}
}
@ -181,14 +169,14 @@ pub fn add_user_prefs() {
Some(ref config_path) => {
let mut path = PathBuf::from(config_path);
init_user_prefs(&mut path);
}
},
None => {
if let Some(mut path) = default_config_dir() {
if path.join("prefs.json").exists() {
init_user_prefs(&mut path);
}
}
}
},
}
}
@ -201,8 +189,10 @@ fn init_user_prefs(path: &mut PathBuf) {
PREFS.extend(prefs);
}
} else {
writeln!(&mut stderr(), "Error opening prefs.json from config directory")
.expect("failed printing to stderr");
writeln!(
&mut stderr(),
"Error opening prefs.json from config directory"
).expect("failed printing to stderr");
}
}
@ -210,7 +200,11 @@ pub struct Preferences(Arc<RwLock<HashMap<String, Pref>>>);
impl Preferences {
pub fn get(&self, name: &str) -> Arc<PrefValue> {
self.0.read().unwrap().get(name).map_or(Arc::new(PrefValue::Missing), |x| x.value().clone())
self.0
.read()
.unwrap()
.get(name)
.map_or(Arc::new(PrefValue::Missing), |x| x.value().clone())
}
pub fn cloned(&self) -> HashMap<String, Pref> {
@ -244,7 +238,12 @@ impl Preferences {
pub fn reset_all(&self) {
let names = {
self.0.read().unwrap().keys().cloned().collect::<Vec<String>>()
self.0
.read()
.unwrap()
.keys()
.cloned()
.collect::<Vec<String>>()
};
for name in names.iter() {
self.reset(name);
@ -260,7 +259,9 @@ impl Preferences {
}
pub fn is_dom_to_texture_enabled(&self) -> bool {
self.get("dom.webgl.dom_to_texture.enabled").as_boolean().unwrap_or(false)
self.get("dom.webgl.dom_to_texture.enabled")
.as_boolean()
.unwrap_or(false)
}
pub fn is_webgl2_enabled(&self) -> bool {

View file

@ -24,7 +24,10 @@ fn test_argument_parsing() {
let url = parse_url_or_filename(fake_cwd, "file:///foo/bar.html").unwrap();
assert_eq!(url.scheme(), "file");
assert_eq!(url.path_segments().unwrap().collect::<Vec<_>>(), ["foo", "bar.html"]);
assert_eq!(
url.path_segments().unwrap().collect::<Vec<_>>(),
["foo", "bar.html"]
);
}
#[test]
@ -34,7 +37,10 @@ fn test_file_path_parsing() {
let url = parse_url_or_filename(fake_cwd, "bar.html").unwrap();
assert_eq!(url.scheme(), "file");
assert_eq!(url.path_segments().unwrap().collect::<Vec<_>>(), ["fake", "cwd", "bar.html"]);
assert_eq!(
url.path_segments().unwrap().collect::<Vec<_>>(),
["fake", "cwd", "bar.html"]
);
}
#[test]
@ -44,7 +50,10 @@ fn test_file_path_parsing() {
let url = parse_url_or_filename(fake_cwd, "bar.html").unwrap();
assert_eq!(url.scheme(), "file");
assert_eq!(url.path_segments().unwrap().collect::<Vec<_>>(), ["C:", "fake", "cwd", "bar.html"]);
assert_eq!(
url.path_segments().unwrap().collect::<Vec<_>>(),
["C:", "fake", "cwd", "bar.html"]
);
}
#[test]
@ -57,16 +66,24 @@ fn test_argument_parsing_special() {
let url = parse_url_or_filename(fake_cwd, "file:///foo/bar?baz#buzz.html").unwrap();
assert_eq!(&*url.to_file_path().unwrap(), Path::new("/foo/bar"));
assert_eq!(url.scheme(), "file");
assert_eq!(url.path_segments().unwrap().collect::<Vec<_>>(), ["foo", "bar"]);
assert_eq!(
url.path_segments().unwrap().collect::<Vec<_>>(),
["foo", "bar"]
);
assert_eq!(url.query(), Some("baz"));
assert_eq!(url.fragment(), Some("buzz.html"));
// but not in file names.
let url = parse_url_or_filename(fake_cwd, "./bar?baz#buzz.html").unwrap();
assert_eq!(&*url.to_file_path().unwrap(), Path::new("/fake/cwd/bar?baz#buzz.html"));
assert_eq!(
&*url.to_file_path().unwrap(),
Path::new("/fake/cwd/bar?baz#buzz.html")
);
assert_eq!(url.scheme(), "file");
assert_eq!(url.path_segments().unwrap().collect::<Vec<_>>(),
["fake", "cwd", "bar%3Fbaz%23buzz.html"]);
assert_eq!(
url.path_segments().unwrap().collect::<Vec<_>>(),
["fake", "cwd", "bar%3Fbaz%23buzz.html"]
);
assert_eq!(url.query(), None);
assert_eq!(url.fragment(), None);
}

View file

@ -12,10 +12,10 @@ use std::io::{Read, Write};
#[test]
fn test_create_pref() {
let json_str = "{\
\"layout.writing-mode.enabled\": true,\
\"network.mime.sniff\": false,\
\"shell.homepage\": \"https://servo.org\"\
}";
\"layout.writing-mode.enabled\": true,\
\"network.mime.sniff\": false,\
\"shell.homepage\": \"https://servo.org\"\
}";
let prefs = read_prefs(json_str);
assert!(prefs.is_ok());
@ -27,40 +27,52 @@ fn test_create_pref() {
#[test]
fn test_get_set_reset_extend() {
let json_str = "{\
\"layout.writing-mode.enabled\": true,\
\"extra.stuff\": false,\
\"shell.homepage\": \"https://google.com\"\
}";
\"layout.writing-mode.enabled\": true,\
\"extra.stuff\": false,\
\"shell.homepage\": \"https://google.com\"\
}";
assert_eq!(*PREFS.get("test"), PrefValue::Missing);
PREFS.set("test", PrefValue::String("hi".to_owned()));
assert_eq!(*PREFS.get("test"), PrefValue::String("hi".to_owned()));
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://servo.org".to_owned()));
assert_eq!(
*PREFS.get("shell.homepage"),
PrefValue::String("https://servo.org".to_owned())
);
PREFS.set("shell.homepage", PrefValue::Boolean(true));
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::Boolean(true));
PREFS.reset("shell.homepage");
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://servo.org".to_owned()));
assert_eq!(
*PREFS.get("shell.homepage"),
PrefValue::String("https://servo.org".to_owned())
);
let extension = read_prefs(json_str).unwrap();
PREFS.extend(extension);
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://google.com".to_owned()));
assert_eq!(*PREFS.get("layout.writing-mode.enabled"), PrefValue::Boolean(true));
assert_eq!(
*PREFS.get("shell.homepage"),
PrefValue::String("https://google.com".to_owned())
);
assert_eq!(
*PREFS.get("layout.writing-mode.enabled"),
PrefValue::Boolean(true)
);
assert_eq!(*PREFS.get("extra.stuff"), PrefValue::Boolean(false));
}
#[cfg(not(target_os = "android"))]
#[test]
fn test_default_config_dir_create_read_write() {
let json_str = "{\
\"layout.writing-mode.enabled\": true,\
\"extra.stuff\": false,\
\"shell.homepage\": \"https://google.com\"\
}";
let json_str = "{\
\"layout.writing-mode.enabled\": true,\
\"extra.stuff\": false,\
\"shell.homepage\": \"https://google.com\"\
}";
let mut expected_json = String::new();
let config_path = basedir::default_config_dir().unwrap();
if !config_path.exists() {
fs::create_dir_all(&config_path).unwrap();
fs::create_dir_all(&config_path).unwrap();
}
let json_path = config_path.join("test_config.json");