aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2015-11-21 21:10:52 +0530
committerbors-servo <lbergstrom+bors@mozilla.com>2015-11-21 21:10:52 +0530
commitea690a2dff64d1cb4eb668473d62f1bbcb19f7c8 (patch)
treecf5804f921ef3b249cc41610b7a99d11663ebfbe /components
parentec3437f4e30547884f9faaf153201fad6ab1173f (diff)
parentf34da4120d475f7fd78a647fc246e5731e7de941 (diff)
downloadservo-ea690a2dff64d1cb4eb668473d62f1bbcb19f7c8.tar.gz
servo-ea690a2dff64d1cb4eb668473d62f1bbcb19f7c8.zip
Auto merge of #8622 - frewsxcv:url-plugin, r=SimonSapin
Implement 'url!(..)' macro https://github.com/servo/rust-url/issues/136 https://github.com/servo/rust-url/pull/137 <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8622) <!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r--components/compositing/constellation.rs2
-rw-r--r--components/plugins/Cargo.toml3
-rw-r--r--components/plugins/lib.rs4
-rw-r--r--components/plugins/url_plugin.rs141
-rw-r--r--components/script/dom/document.rs2
-rw-r--r--components/script/dom/htmliframeelement.rs2
-rw-r--r--components/script/script_task.rs2
-rw-r--r--components/servo/Cargo.lock12
-rw-r--r--components/servo/Cargo.toml3
-rw-r--r--components/style/font_face.rs2
-rw-r--r--components/style/parser.rs2
-rw-r--r--components/style/selector_matching.rs2
-rw-r--r--components/util/opts.rs2
13 files changed, 171 insertions, 8 deletions
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index 2084ace9701..1055aabaa26 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -701,7 +701,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
parent_info,
window_size,
None,
- LoadData::new(Url::parse("about:failure").unwrap()));
+ LoadData::new(url!("about:failure")));
self.push_pending_frame(new_pipeline_id, Some(pipeline_id));
}
diff --git a/components/plugins/Cargo.toml b/components/plugins/Cargo.toml
index 9e317316984..f697fe45cf7 100644
--- a/components/plugins/Cargo.toml
+++ b/components/plugins/Cargo.toml
@@ -16,5 +16,8 @@ git = "https://github.com/Manishearth/rust-clippy"
branch = "servo"
optional = true
+[dependencies.url]
+version = "0.2.36"
+
[features]
default = []
diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs
index bb328c9441a..d52ad866879 100644
--- a/components/plugins/lib.rs
+++ b/components/plugins/lib.rs
@@ -26,6 +26,8 @@ extern crate tenacious;
#[cfg(feature = "clippy")]
extern crate clippy;
+extern crate url;
+
use rustc::plugin::Registry;
use syntax::ext::base::*;
use syntax::feature_gate::AttributeType::Whitelisted;
@@ -41,6 +43,7 @@ pub mod lints;
pub mod reflector;
/// Utilities for writing plugins
pub mod casing;
+mod url_plugin;
pub mod utils;
#[plugin_registrar]
@@ -51,6 +54,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_syntax_extension(intern("derive_HeapSizeOf"), MultiDecorator(box heap_size::expand_heap_size));
reg.register_macro("to_lower", casing::expand_lower);
reg.register_macro("to_upper", casing::expand_upper);
+ reg.register_macro("url", url_plugin::expand_url);
reg.register_late_lint_pass(box lints::transmute_type::TransmutePass);
reg.register_late_lint_pass(box lints::unrooted_must_root::UnrootedPass::new());
reg.register_late_lint_pass(box lints::privatize::PrivatizePass);
diff --git a/components/plugins/url_plugin.rs b/components/plugins/url_plugin.rs
new file mode 100644
index 00000000000..8ae06624c4b
--- /dev/null
+++ b/components/plugins/url_plugin.rs
@@ -0,0 +1,141 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+use std::error::Error;
+use syntax;
+use syntax::ast::{TokenTree, ExprLit, LitStr, Expr};
+use syntax::codemap::Span;
+use syntax::ext::base::{ExtCtxt, MacResult, MacEager, DummyResult};
+use syntax::ext::build::AstBuilder;
+use syntax::fold::Folder;
+use syntax::parse;
+use syntax::parse::token::InternedString;
+use url::{Url, Host, RelativeSchemeData, SchemeData};
+
+pub fn expand_url(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
+ -> Box<MacResult + 'static> {
+ let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_vec());
+ let query_expr = cx.expander().fold_expr(parser.parse_expr());
+
+ // Ensure a str literal was passed to the macro
+ let query = match parse_str_lit(&query_expr) {
+ Some(query) => query,
+ None => {
+ cx.span_err(query_expr.span, "'url!' expected string literal");
+ return DummyResult::any(sp)
+ },
+ };
+
+ // Parse the str literal
+ let Url { scheme, scheme_data, query, fragment } = match Url::parse(&query) {
+ Ok(url) => url,
+ Err(error) => {
+ cx.span_err(query_expr.span, error.description());
+ return DummyResult::any(sp)
+ }
+ };
+
+ let scheme_data_expr = cx.expr_scheme_data(sp, scheme_data);
+ let query_expr = cx.expr_option_string(sp, query);
+ let fragment_expr = cx.expr_option_string(sp, fragment);
+
+ let url_expr = quote_expr!(cx, {
+ ::url::Url {
+ scheme: $scheme.to_owned(),
+ scheme_data: $scheme_data_expr,
+ query: $query_expr,
+ fragment: $fragment_expr,
+ }
+ });
+
+ MacEager::expr(url_expr)
+}
+
+fn parse_str_lit(e: &Expr) -> Option<InternedString> {
+ if let ExprLit(ref lit) = e.node {
+ if let LitStr(ref s, _) = lit.node {
+ return Some(s.clone());
+ }
+ }
+ None
+}
+
+trait ExtCtxtHelpers {
+ fn expr_scheme_data(&self, sp: Span, scheme_data: SchemeData) -> syntax::ptr::P<Expr>;
+ fn expr_option_string(&self, sp: Span, string: Option<String>) -> syntax::ptr::P<Expr>;
+ fn expr_option_u16(&self, sp: Span, unsigned: Option<u16>) -> syntax::ptr::P<Expr>;
+ fn expr_host(&self, sp: Span, host: Host) -> syntax::ptr::P<Expr>;
+ fn expr_slice_u16(&self, sp: Span, unsigned: &[u16]) -> syntax::ptr::P<Expr>;
+ fn expr_vec_string(&self, sp: Span, strings: Vec<String>) -> syntax::ptr::P<Expr>;
+}
+
+impl<'a> ExtCtxtHelpers for ExtCtxt<'a> {
+ fn expr_scheme_data(&self, sp: Span, scheme_data: SchemeData) -> syntax::ptr::P<Expr> {
+ match scheme_data {
+ SchemeData::Relative(
+ RelativeSchemeData { username, password, host, port, default_port, path }) =>
+ {
+ let password_expr = self.expr_option_string(sp, password);
+ let host_expr = self.expr_host(sp, host);
+ let port_expr = self.expr_option_u16(sp, port);
+ let default_port_expr = self.expr_option_u16(sp, default_port);
+ let path_expr = self.expr_vec_string(sp, path);
+
+ quote_expr!(self,
+ ::url::SchemeData::Relative(
+ ::url::RelativeSchemeData {
+ username: $username.to_owned(),
+ password: $password_expr,
+ host: $host_expr,
+ port: $port_expr,
+ default_port: $default_port_expr,
+ path: $path_expr.to_owned(),
+ }
+ ))
+ },
+ SchemeData::NonRelative(ref scheme_data) => {
+ quote_expr!(self, ::url::SchemeData::NonRelative($scheme_data.to_owned()))
+ },
+ }
+ }
+
+ fn expr_option_string(&self, sp: Span, string: Option<String>) -> syntax::ptr::P<Expr> {
+ match string {
+ Some(string) => quote_expr!(self, Some($string.to_owned())),
+ None => self.expr_none(sp),
+ }
+ }
+
+ fn expr_option_u16(&self, sp: Span, unsigned: Option<u16>) -> syntax::ptr::P<Expr> {
+ match unsigned {
+ Some(unsigned) => quote_expr!(self, Some($unsigned)),
+ None => self.expr_none(sp),
+ }
+ }
+
+ fn expr_host(&self, sp: Span, host: Host) -> syntax::ptr::P<Expr> {
+ match host {
+ Host::Domain(domain) => quote_expr!(self, ::url::Host::Domain(String::from($domain))),
+ Host::Ipv6(address) => {
+ let pieces_expr = self.expr_slice_u16(sp, &address.pieces);
+ quote_expr!(self,
+ ::url::Host::Ipv6(
+ ::url::Ipv6Address {
+ pieces: $pieces_expr.to_owned()
+ }
+ ))
+ },
+ }
+ }
+
+ fn expr_slice_u16(&self, sp: Span, unsigned: &[u16]) -> syntax::ptr::P<Expr> {
+ let unsigned = unsigned.iter().map(|p| quote_expr!(self, $p)).collect();
+ self.expr_vec_slice(sp, unsigned)
+ }
+
+ fn expr_vec_string(&self, sp: Span, strings: Vec<String>) -> syntax::ptr::P<Expr> {
+ let strings = strings.iter().map(|p| quote_expr!(self, $p.to_owned())).collect();
+ self.expr_vec(sp, strings)
+ }
+}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 585b93f1912..34a7846b543 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -1388,7 +1388,7 @@ impl Document {
source: DocumentSource,
doc_loader: DocumentLoader)
-> Document {
- let url = url.unwrap_or_else(|| Url::parse("about:blank").unwrap());
+ let url = url.unwrap_or_else(|| url!("about:blank"));
let (ready_state, domcontentloaded_dispatched) = if source == DocumentSource::FromParser {
(DocumentReadyState::Loading, false)
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index b3e62ef434b..7d14dfe916d 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -124,7 +124,7 @@ impl HTMLIFrameElement {
pub fn process_the_iframe_attributes(&self) {
let url = match self.get_url() {
Some(url) => url.clone(),
- None => Url::parse("about:blank").unwrap(),
+ None => url!("about:blank"),
};
self.navigate_child_browsing_context(url);
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index 1f407ab940a..95e1c7f356f 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -1969,7 +1969,7 @@ impl ScriptTask {
};
if load_data.url.scheme == "javascript" {
- load_data.url = Url::parse("about:blank").unwrap();
+ load_data.url = url!("about:blank");
}
resource_task.send(ControlMsg::Load(NetLoadData {
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 92b083fdf50..b95310c217a 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -28,6 +28,7 @@ dependencies = [
"net_traits 0.0.1",
"net_traits_tests 0.0.1",
"offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
+ "plugin_tests 0.0.1",
"profile 0.0.1",
"profile_traits 0.0.1",
"script 0.0.1",
@@ -1223,6 +1224,7 @@ dependencies = [
"msg 0.0.1",
"net 0.0.1",
"net_traits 0.0.1",
+ "plugins 0.0.1",
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -1389,10 +1391,19 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "plugin_tests"
+version = "0.0.1"
+dependencies = [
+ "plugins 0.0.1",
+ "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "plugins"
version = "0.0.1"
dependencies = [
"tenacious 0.0.11 (git+https://github.com/Manishearth/rust-tenacious)",
+ "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1770,6 +1781,7 @@ dependencies = [
"app_units 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plugins 0.0.1",
"selectors 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_plugin 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml
index b17a137a16c..5d2222b8aa1 100644
--- a/components/servo/Cargo.toml
+++ b/components/servo/Cargo.toml
@@ -29,6 +29,9 @@ path = "../../tests/unit/net"
[dev-dependencies.net_traits_tests]
path = "../../tests/unit/net_traits"
+[dev-dependencies.plugin_tests]
+path = "../../tests/unit/plugin"
+
[dev-dependencies.script_tests]
path = "../../tests/unit/script"
diff --git a/components/style/font_face.rs b/components/style/font_face.rs
index ff4f2993d81..52abb82c3cf 100644
--- a/components/style/font_face.rs
+++ b/components/style/font_face.rs
@@ -112,7 +112,7 @@ fn parse_one_src(context: &ParserContext, input: &mut Parser) -> Result<Source,
}
let url = try!(input.expect_url());
let url = UrlParser::new().base_url(context.base_url).parse(&url).unwrap_or_else(
- |_error| Url::parse("about:invalid").unwrap());
+ |_error| url!("about:invalid"));
// Parsing optional format()
let format_hints = if input.try(|input| input.expect_function_matching("format")).is_ok() {
diff --git a/components/style/parser.rs b/components/style/parser.rs
index f189c7c5d93..67f35fa0976 100644
--- a/components/style/parser.rs
+++ b/components/style/parser.rs
@@ -31,7 +31,7 @@ impl<'a> ParserContext<'a> {
impl<'a> ParserContext<'a> {
pub fn parse_url(&self, input: &str) -> Url {
UrlParser::new().base_url(self.base_url).parse(input)
- .unwrap_or_else(|_| Url::parse("about:invalid").unwrap())
+ .unwrap_or_else(|_| url!("about:invalid"))
}
}
diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs
index e8887163b61..f4b2168fc26 100644
--- a/components/style/selector_matching.rs
+++ b/components/style/selector_matching.rs
@@ -61,7 +61,7 @@ lazy_static! {
Ok(res) => {
Stylesheet::from_bytes(
&res,
- Url::parse("chrome:///quirks-mode.css").unwrap(),
+ url!("chrome:///quirks-mode.css"),
None,
None,
Origin::UserAgent)
diff --git a/components/util/opts.rs b/components/util/opts.rs
index 761568de42d..1b74e142408 100644
--- a/components/util/opts.rs
+++ b/components/util/opts.rs
@@ -440,7 +440,7 @@ const DEFAULT_USER_AGENT: UserAgent = UserAgent::Desktop;
pub fn default_opts() -> Opts {
Opts {
is_running_problem_test: false,
- url: Some(Url::parse("about:blank").unwrap()),
+ url: Some(url!("about:blank")),
paint_threads: 1,
gpu_painting: false,
tile_size: 512,