aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/script/dom/cssstyledeclaration.rs5
-rw-r--r--components/script/dom/element.rs4
-rw-r--r--components/script/dom/htmllinkelement.rs4
-rw-r--r--components/script/dom/htmlstyleelement.rs4
-rw-r--r--components/style/Cargo.toml3
-rw-r--r--components/style/lib.rs2
-rw-r--r--components/style/parser.rs38
-rw-r--r--components/style/properties/helpers.mako.rs2
-rw-r--r--components/style/properties/longhand/box.mako.rs75
-rw-r--r--components/style/properties/properties.mako.rs27
-rw-r--r--components/style/selector_matching.rs10
-rw-r--r--components/style/stylesheets.rs19
-rw-r--r--components/style/values.rs10
13 files changed, 170 insertions, 33 deletions
diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs
index 6d537c40ea5..df9251f3888 100644
--- a/components/script/dom/cssstyledeclaration.rs
+++ b/components/script/dom/cssstyledeclaration.rs
@@ -16,6 +16,7 @@ use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::cell::Ref;
use string_cache::Atom;
+use style::parser::ParserContextExtraData;
use style::properties::{PropertyDeclaration, Shorthand};
use style::properties::{is_supported_property, parse_one_declaration};
use style::selector_impl::PseudoElement;
@@ -240,7 +241,9 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// Step 6
let window = window_from_node(&*self.owner);
- let declarations = parse_one_declaration(&property, &value, &window.get_url(), window.css_error_reporter());
+ let declarations =
+ parse_one_declaration(&property, &value, &window.get_url(), window.css_error_reporter(),
+ ParserContextExtraData::default());
// Step 7
let declarations = if let Ok(declarations) = declarations {
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index ec33deb1608..f5832089202 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -86,6 +86,7 @@ use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace, QualName};
use style::element_state::*;
+use style::parser::ParserContextExtraData;
use style::properties::DeclaredValue;
use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
@@ -1977,7 +1978,8 @@ impl VirtualMethods for Element {
*self.style_attribute.borrow_mut() =
mutation.new_value(attr).map(|value| {
let win = window_from_node(self);
- parse_style_attribute(&value, &doc.base_url(), win.css_error_reporter())
+ parse_style_attribute(&value, &doc.base_url(), win.css_error_reporter(),
+ ParserContextExtraData::default())
});
if node.is_in_doc() {
node.dirty(NodeDamage::NodeStyleDamaged);
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index 18ff43c000b..88de9756267 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -38,6 +38,7 @@ use std::mem;
use std::sync::{Arc, Mutex};
use string_cache::Atom;
use style::media_queries::{MediaQueryList, parse_media_query_list};
+use style::parser::ParserContextExtraData;
use style::servo::Stylesheet;
use style::stylesheets::Origin;
use url::Url;
@@ -307,7 +308,8 @@ impl AsyncResponseListener for StylesheetContext {
let mut sheet = Stylesheet::from_bytes(&data, final_url, protocol_encoding_label,
Some(environment_encoding), Origin::Author,
- win.css_error_reporter());
+ win.css_error_reporter(),
+ ParserContextExtraData::default());
let media = self.media.take().unwrap();
sheet.set_media(Some(media));
let sheet = Arc::new(sheet);
diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs
index 8d4a05eb9b7..62395b682d1 100644
--- a/components/script/dom/htmlstyleelement.rs
+++ b/components/script/dom/htmlstyleelement.rs
@@ -18,6 +18,7 @@ use layout_interface::{LayoutChan, Msg};
use std::sync::Arc;
use string_cache::Atom;
use style::media_queries::parse_media_query_list;
+use style::parser::ParserContextExtraData;
use style::servo::Stylesheet;
use style::stylesheets::Origin;
@@ -60,7 +61,8 @@ impl HTMLStyleElement {
};
let data = node.GetTextContent().expect("Element.textContent must be a string");
- let mut sheet = Stylesheet::from_str(&data, url, Origin::Author, win.css_error_reporter());
+ let mut sheet = Stylesheet::from_str(&data, url, Origin::Author, win.css_error_reporter(),
+ ParserContextExtraData::default());
let mut css_parser = CssParser::new(&mq_str);
let media = parse_media_query_list(&mut css_parser);
sheet.set_media(Some(media));
diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml
index 5198dc05b14..566506e987e 100644
--- a/components/style/Cargo.toml
+++ b/components/style/Cargo.toml
@@ -11,7 +11,7 @@ name = "style"
path = "lib.rs"
[features]
-gecko = []
+gecko = ["gecko_bindings"]
[dependencies]
app_units = {version = "0.2.3", features = ["plugins"]}
@@ -20,6 +20,7 @@ cssparser = {version = "0.5.5", features = ["heap_size", "serde-serialization"]}
encoding = "0.2"
euclid = {version = "0.6.4", features = ["plugins"]}
fnv = "1.0"
+gecko_bindings = {path = "../../ports/geckolib/gecko_bindings", optional = true}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
lazy_static = "0.2"
diff --git a/components/style/lib.rs b/components/style/lib.rs
index 00d5d079066..4ec45e45e04 100644
--- a/components/style/lib.rs
+++ b/components/style/lib.rs
@@ -28,6 +28,8 @@ extern crate cssparser;
extern crate encoding;
extern crate euclid;
extern crate fnv;
+#[cfg(feature = "gecko")]
+extern crate gecko_bindings;
extern crate heapsize;
#[allow(unused_extern_crates)]
#[macro_use]
diff --git a/components/style/parser.rs b/components/style/parser.rs
index b044367e8dd..eadb778db55 100644
--- a/components/style/parser.rs
+++ b/components/style/parser.rs
@@ -5,20 +5,47 @@
use cssparser::{Parser, SourcePosition};
use error_reporting::ParseErrorReporter;
+#[cfg(feature = "gecko")]
+use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
use selectors::parser::ParserContext as SelectorParserContext;
use stylesheets::Origin;
use url::Url;
+#[cfg(not(feature = "gecko"))]
+pub struct ParserContextExtraData;
+
+#[cfg(feature = "gecko")]
+pub struct ParserContextExtraData {
+ pub base: Option<GeckoArcURI>,
+ pub referrer: Option<GeckoArcURI>,
+ pub principal: Option<GeckoArcPrincipal>,
+}
+
+impl ParserContextExtraData {
+ #[cfg(not(feature = "gecko"))]
+ pub fn default() -> ParserContextExtraData {
+ ParserContextExtraData
+ }
+
+ #[cfg(feature = "gecko")]
+ pub fn default() -> ParserContextExtraData {
+ ParserContextExtraData { base: None, referrer: None, principal: None }
+ }
+}
+
pub struct ParserContext<'a> {
pub stylesheet_origin: Origin,
pub base_url: &'a Url,
pub selector_context: SelectorParserContext,
pub error_reporter: Box<ParseErrorReporter + Send>,
+ pub extra_data: ParserContextExtraData,
}
impl<'a> ParserContext<'a> {
- pub fn new(stylesheet_origin: Origin, base_url: &'a Url, error_reporter: Box<ParseErrorReporter + Send>)
- -> ParserContext<'a> {
+ pub fn new_with_extra_data(stylesheet_origin: Origin, base_url: &'a Url,
+ error_reporter: Box<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData)
+ -> ParserContext<'a> {
let mut selector_context = SelectorParserContext::new();
selector_context.in_user_agent_stylesheet = stylesheet_origin == Origin::UserAgent;
ParserContext {
@@ -26,8 +53,15 @@ impl<'a> ParserContext<'a> {
base_url: base_url,
selector_context: selector_context,
error_reporter: error_reporter,
+ extra_data: extra_data,
}
}
+
+ pub fn new(stylesheet_origin: Origin, base_url: &'a Url, error_reporter: Box<ParseErrorReporter + Send>)
+ -> ParserContext<'a> {
+ let extra_data = ParserContextExtraData::default();
+ ParserContext::new_with_extra_data(stylesheet_origin, base_url, error_reporter, extra_data)
+ }
}
diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs
index af052179d2c..86961c89192 100644
--- a/components/style/properties/helpers.mako.rs
+++ b/components/style/properties/helpers.mako.rs
@@ -43,7 +43,7 @@
#![allow(unused_imports)]
% if not property.derived_from:
use cssparser::Parser;
- use parser::ParserContext;
+ use parser::{ParserContext, ParserContextExtraData};
use properties::{CSSWideKeyword, DeclaredValue, Shorthand};
% endif
use error_reporting::ParseErrorReporter;
diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs
index 6fd36b71a4d..f80a42c88d2 100644
--- a/components/style/properties/longhand/box.mako.rs
+++ b/components/style/properties/longhand/box.mako.rs
@@ -851,3 +851,78 @@ ${helpers.single_keyword("-moz-appearance",
gecko_ffi_name="mAppearance",
gecko_constant_prefix="NS_THEME",
products="gecko")}
+
+// Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding
+<%helpers:longhand name="-moz-binding" products="gecko">
+ use cssparser::{CssStringWriter, ToCss};
+ use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
+ use std::fmt::{self, Write};
+ use url::Url;
+ use values::computed::ComputedValueAsSpecified;
+
+ #[derive(PartialEq, Clone, Debug, HeapSizeOf)]
+ pub struct UrlExtraData {
+ pub base: GeckoArcURI,
+ pub referrer: GeckoArcURI,
+ pub principal: GeckoArcPrincipal,
+ }
+
+ #[derive(PartialEq, Clone, Debug, HeapSizeOf)]
+ pub enum SpecifiedValue {
+ Url(Url, UrlExtraData),
+ None,
+ }
+
+ impl ComputedValueAsSpecified for SpecifiedValue {}
+
+ impl ToCss for SpecifiedValue {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ use values::LocalToCss;
+ match *self {
+ SpecifiedValue::Url(ref url, _) => {
+ url.to_css(dest)
+ }
+ SpecifiedValue::None => {
+ try!(dest.write_str("none"));
+ Ok(())
+ }
+ }
+ }
+ }
+
+ pub mod computed_value {
+ pub type T = super::SpecifiedValue;
+ }
+
+ #[inline] pub fn get_initial_value() -> SpecifiedValue {
+ SpecifiedValue::None
+ }
+
+ pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
+ if input.try(|input| input.expect_ident_matching("none")).is_ok() {
+ return Ok(SpecifiedValue::None);
+ }
+
+ let url = context.parse_url(&*try!(input.expect_url()));
+ match context.extra_data {
+ ParserContextExtraData {
+ base: Some(ref base),
+ referrer: Some(ref referrer),
+ principal: Some(ref principal),
+ } => {
+ let extra_data = UrlExtraData {
+ base: base.clone(),
+ referrer: referrer.clone(),
+ principal: principal.clone(),
+ };
+ Ok(SpecifiedValue::Url(url, extra_data))
+ },
+ _ => {
+ // FIXME(heycam) should ensure we always have a principal, etc., when parsing
+ // style attributes and re-parsing due to CSS Variables.
+ println!("stylo: skipping -moz-binding declaration without ParserContextExtraData");
+ Err(())
+ },
+ }
+ }
+</%helpers:longhand>
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index dc15f7339d0..ec6fe6562e0 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -29,7 +29,7 @@ use euclid::size::Size2D;
use string_cache::Atom;
use computed_values;
use logical_geometry::{LogicalMargin, PhysicalSide, WritingMode};
-use parser::{ParserContext, log_css_error};
+use parser::{ParserContext, ParserContextExtraData, log_css_error};
use selectors::matching::DeclarationBlock;
use stylesheets::Origin;
use values::AuExtensionMethods;
@@ -185,13 +185,18 @@ mod property_bit_field {
if let DeclaredValue::WithVariables {
ref css, first_token_type, ref base_url, from_shorthand
} = *value {
+ // FIXME(heycam): A ParserContextExtraData should be built from data
+ // stored in the WithVariables, in case variable expansion results in
+ // a url() value.
+ let extra_data = ParserContextExtraData::default();
substitute_variables_${property.ident}_slow(css,
first_token_type,
base_url,
from_shorthand,
custom_properties,
f,
- error_reporter);
+ error_reporter,
+ extra_data);
} else {
f(value);
}
@@ -206,7 +211,8 @@ mod property_bit_field {
from_shorthand: Option<Shorthand>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
- error_reporter: &mut StdBox<ParseErrorReporter + Send>)
+ error_reporter: &mut StdBox<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData)
where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) {
f(&
::custom_properties::substitute(css, first_token_type, custom_properties)
@@ -215,8 +221,9 @@ mod property_bit_field {
//
// FIXME(pcwalton): Cloning the error reporter is slow! But so are custom
// properties, so whatever...
- let context = ParserContext::new(
- ::stylesheets::Origin::Author, base_url, (*error_reporter).clone());
+ let context = ParserContext::new_with_extra_data(
+ ::stylesheets::Origin::Author, base_url, (*error_reporter).clone(),
+ extra_data);
Parser::new(&css).parse_entirely(|input| {
match from_shorthand {
None => {
@@ -256,15 +263,17 @@ pub struct PropertyDeclarationBlock {
pub normal: Arc<Vec<PropertyDeclaration>>,
}
-pub fn parse_style_attribute(input: &str, base_url: &Url, error_reporter: StdBox<ParseErrorReporter + Send>)
+pub fn parse_style_attribute(input: &str, base_url: &Url, error_reporter: StdBox<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData)
-> PropertyDeclarationBlock {
- let context = ParserContext::new(Origin::Author, base_url, error_reporter);
+ let context = ParserContext::new_with_extra_data(Origin::Author, base_url, error_reporter, extra_data);
parse_property_declaration_list(&context, &mut Parser::new(input))
}
-pub fn parse_one_declaration(name: &str, input: &str, base_url: &Url, error_reporter: StdBox<ParseErrorReporter + Send>)
+pub fn parse_one_declaration(name: &str, input: &str, base_url: &Url, error_reporter: StdBox<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData)
-> Result<Vec<PropertyDeclaration>, ()> {
- let context = ParserContext::new(Origin::Author, base_url, error_reporter);
+ let context = ParserContext::new_with_extra_data(Origin::Author, base_url, error_reporter, extra_data);
let mut results = vec![];
match PropertyDeclaration::parse(name, &context, &mut Parser::new(input), &mut results) {
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => Ok(results),
diff --git a/components/style/selector_matching.rs b/components/style/selector_matching.rs
index c1989348f50..017a7443624 100644
--- a/components/style/selector_matching.rs
+++ b/components/style/selector_matching.rs
@@ -9,6 +9,7 @@ use dom::PresentationalHintsSynthetizer;
use element_state::*;
use error_reporting::StdoutErrorReporter;
use media_queries::{Device, MediaType};
+use parser::ParserContextExtraData;
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock};
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
use selector_impl::{SelectorImplExt, ServoSelectorImpl};
@@ -46,7 +47,8 @@ lazy_static! {
None,
None,
Origin::UserAgent,
- box StdoutErrorReporter);
+ box StdoutErrorReporter,
+ ParserContextExtraData::default());
stylesheets.push(ua_stylesheet);
}
Err(..) => {
@@ -57,7 +59,8 @@ lazy_static! {
}
for &(ref contents, ref url) in &opts::get().user_stylesheets {
stylesheets.push(Stylesheet::from_bytes(
- &contents, url.clone(), None, None, Origin::User, box StdoutErrorReporter));
+ &contents, url.clone(), None, None, Origin::User, box StdoutErrorReporter,
+ ParserContextExtraData::default()));
}
stylesheets
};
@@ -73,7 +76,8 @@ lazy_static! {
None,
None,
Origin::UserAgent,
- box StdoutErrorReporter)
+ box StdoutErrorReporter,
+ ParserContextExtraData::default())
},
Err(..) => {
error!("Stylist failed to load 'quirks-mode.css'!");
diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs
index 7a978263b2b..4de57e81d40 100644
--- a/components/style/stylesheets.rs
+++ b/components/style/stylesheets.rs
@@ -8,7 +8,7 @@ use encoding::EncodingRef;
use error_reporting::ParseErrorReporter;
use font_face::{FontFaceRule, parse_font_face_block};
use media_queries::{Device, MediaQueryList, parse_media_query_list};
-use parser::{ParserContext, log_css_error};
+use parser::{ParserContext, ParserContextExtraData, log_css_error};
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
use selectors::parser::{Selector, SelectorImpl, parse_selector_list};
use smallvec::SmallVec;
@@ -83,32 +83,37 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
input: I, base_url: Url, protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>, origin: Origin,
- error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet<Impl> {
+ error_reporter: Box<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData) -> Stylesheet<Impl> {
let mut bytes = vec![];
// TODO: incremental decoding and tokenization/parsing
for chunk in input {
bytes.extend_from_slice(&chunk)
}
Stylesheet::from_bytes(&bytes, base_url, protocol_encoding_label,
- environment_encoding, origin, error_reporter)
+ environment_encoding, origin, error_reporter,
+ extra_data)
}
pub fn from_bytes(bytes: &[u8],
base_url: Url,
protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>,
- origin: Origin, error_reporter: Box<ParseErrorReporter + Send>)
+ origin: Origin, error_reporter: Box<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData)
-> Stylesheet<Impl> {
// TODO: bytes.as_slice could be bytes.container_as_bytes()
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
- Stylesheet::from_str(&string, base_url, origin, error_reporter)
+ Stylesheet::from_str(&string, base_url, origin, error_reporter, extra_data)
}
pub fn from_str(css: &str, base_url: Url, origin: Origin,
- error_reporter: Box<ParseErrorReporter + Send>) -> Stylesheet<Impl> {
+ error_reporter: Box<ParseErrorReporter + Send>,
+ extra_data: ParserContextExtraData) -> Stylesheet<Impl> {
let rule_parser = TopLevelRuleParser {
- context: ParserContext::new(origin, &base_url, error_reporter.clone()),
+ context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter.clone(),
+ extra_data),
state: Cell::new(State::Start),
_impl: PhantomData,
};
diff --git a/components/style/values.rs b/components/style/values.rs
index 2f295bd8775..9492a028cfc 100644
--- a/components/style/values.rs
+++ b/components/style/values.rs
@@ -90,13 +90,13 @@ pub const FONT_MEDIUM_PX: i32 = 16;
pub mod specified {
use app_units::Au;
- use cssparser::{self, CssStringWriter, Parser, ToCss, Token};
+ use cssparser::{self, Parser, ToCss, Token};
use euclid::size::Size2D;
use parser::ParserContext;
use std::ascii::AsciiExt;
use std::cmp;
use std::f32::consts::PI;
- use std::fmt::{self, Write};
+ use std::fmt;
use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType;
use super::AuExtensionMethods;
@@ -1224,12 +1224,10 @@ pub mod specified {
impl ToCss for Image {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ use values::LocalToCss;
match *self {
Image::Url(ref url) => {
- try!(dest.write_str("url(\""));
- try!(write!(&mut CssStringWriter::new(dest), "{}", url));
- try!(dest.write_str("\")"));
- Ok(())
+ url.to_css(dest)
}
Image::LinearGradient(ref gradient) => gradient.to_css(dest)
}