Auto merge of #16241 - upsuper:bug1352763-bug1352025, r=Manishearth,emilio

Stop passing url as string into Servo side

This is the Servo side changes of [bug 1352763](https://bugzilla.mozilla.org/show_bug.cgi?id=1352763) and [bug 1352025](https://bugzilla.mozilla.org/show_bug.cgi?id=1352025) which have been reviewed on Bugzilla.
This commit is contained in:
bors-servo 2017-04-03 07:05:42 -05:00 committed by GitHub
commit 679b418937
32 changed files with 269 additions and 308 deletions

View file

@ -9,12 +9,10 @@ extern crate encoding;
use cssparser::{stylesheet_encoding, EncodingSupport};
use error_reporting::ParseErrorReporter;
use media_queries::MediaList;
use parser::ParserContextExtraData;
use self::encoding::{EncodingRef, DecoderTrap};
use servo_url::ServoUrl;
use shared_lock::SharedRwLock;
use std::str;
use stylesheets::{Stylesheet, StylesheetLoader, Origin};
use stylesheets::{Stylesheet, StylesheetLoader, Origin, UrlExtraData};
struct RustEncoding;
@ -50,26 +48,24 @@ impl Stylesheet {
/// Takes care of decoding the network bytes and forwards the resulting
/// string to `Stylesheet::from_str`.
pub fn from_bytes(bytes: &[u8],
base_url: ServoUrl,
url_data: UrlExtraData,
protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>,
origin: Origin,
media: MediaList,
shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData)
error_reporter: &ParseErrorReporter)
-> Stylesheet {
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
Stylesheet::from_str(&string,
base_url,
url_data,
origin,
media,
shared_lock,
stylesheet_loader,
error_reporter,
extra_data)
error_reporter)
}
/// Updates an empty stylesheet with a set of bytes that reached over the
@ -78,15 +74,15 @@ impl Stylesheet {
bytes: &[u8],
protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>,
url_data: &UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData) {
error_reporter: &ParseErrorReporter) {
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
Self::update_from_str(existing,
&string,
url_data,
stylesheet_loader,
error_reporter,
extra_data)
error_reporter)
}
}

View file

@ -8,7 +8,7 @@
use cssparser::{Parser, SourcePosition};
use log;
use servo_url::ServoUrl;
use stylesheets::UrlExtraData;
/// A generic trait for an error reporter.
pub trait ParseErrorReporter : Sync + Send {
@ -20,7 +20,7 @@ pub trait ParseErrorReporter : Sync + Send {
input: &mut Parser,
position: SourcePosition,
message: &str,
url: &ServoUrl);
url: &UrlExtraData);
}
/// An error reporter that reports the errors to the `info` log channel.
@ -32,7 +32,7 @@ impl ParseErrorReporter for StdoutErrorReporter {
input: &mut Parser,
position: SourcePosition,
message: &str,
url: &ServoUrl) {
url: &UrlExtraData) {
if log_enabled!(log::LogLevel::Info) {
let location = input.source_location(position);
info!("Url:\t{}\n{}:{} {}", url.as_str(), location.line, location.column, message)

View file

@ -34,18 +34,9 @@ impl SpecifiedUrl {
pub fn parse_from_string<'a>(url: Cow<'a, str>,
context: &ParserContext)
-> Result<Self, ()> {
let extra = &context.extra_data;
if extra.data.is_none() {
// FIXME(heycam) should ensure we always have a principal, etc.,
// when parsing style attributes and re-parsing due to CSS
// Variables.
warn!("stylo: skipping declaration without ParserContextExtraData");
return Err(())
}
Ok(SpecifiedUrl {
serialization: Arc::new(url.into_owned()),
extra_data: extra.data.as_ref().unwrap().clone(),
extra_data: context.url_data.clone(),
})
}

View file

@ -50,7 +50,6 @@ use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
use gecko_bindings::sugar::ownership::HasArcFFI;
use parking_lot::RwLock;
use parser::ParserContextExtraData;
use properties::{ComputedValues, parse_style_attribute};
use properties::PropertyDeclarationBlock;
use properties::animated_properties::AnimationValueMap;
@ -59,13 +58,13 @@ use selector_parser::{ElementExt, Snapshot};
use selectors::Element;
use selectors::matching::{ElementSelectorFlags, StyleRelations};
use selectors::parser::{AttrSelector, NamespaceConstraint};
use servo_url::ServoUrl;
use shared_lock::Locked;
use sink::Push;
use std::fmt;
use std::ptr;
use std::sync::Arc;
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use stylesheets::UrlExtraData;
use stylist::ApplicableDeclarationBlock;
/// A simple wrapper over a non-null Gecko node (`nsINode`) pointer.
@ -315,9 +314,8 @@ impl<'le> fmt::Debug for GeckoElement<'le> {
impl<'le> GeckoElement<'le> {
/// Parse the style attribute of an element.
pub fn parse_style_attribute(value: &str,
base_url: &ServoUrl,
extra_data: ParserContextExtraData) -> PropertyDeclarationBlock {
parse_style_attribute(value, base_url, &StdoutErrorReporter, extra_data)
url_data: &UrlExtraData) -> PropertyDeclarationBlock {
parse_style_attribute(value, url_data, &StdoutErrorReporter)
}
fn flags(&self) -> u32 {
@ -389,15 +387,6 @@ impl<'le> GeckoElement<'le> {
}
}
lazy_static! {
/// A dummy base url in order to get it where we don't have any available.
///
/// We need to get rid of this sooner than later.
pub static ref DUMMY_BASE_URL: ServoUrl = {
ServoUrl::parse("http://www.example.org").unwrap()
};
}
/// Converts flags from the layout used by rust-selectors to the layout used
/// by Gecko. We could align these and then do this without conditionals, but
/// it's probably not worth the trouble.

View file

@ -428,11 +428,14 @@ extern "C" {
extern "C" {
pub fn Gecko_LoadStyleSheet(loader: *mut Loader,
parent: *mut ServoStyleSheet,
import_rule: RawServoImportRuleBorrowed,
child_sheet: RawServoStyleSheetBorrowed,
base_url_data: *mut RawGeckoURLExtraData,
url_bytes: *const u8, url_length: u32,
media_bytes: *const u8, media_length: u32);
}
extern "C" {
pub fn Gecko_URLExtraData_CreateDummy() -> *mut RawGeckoURLExtraData;
}
extern "C" {
pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed)
-> StyleChildrenIteratorOwnedOrNull;
@ -1377,7 +1380,6 @@ extern "C" {
*mut ServoStyleSheet,
data: *const nsACString,
parsing_mode: SheetParsingMode,
base_url: *const nsACString,
extra_data:
*mut RawGeckoURLExtraData)
-> RawServoStyleSheetStrong;
@ -1466,8 +1468,9 @@ extern "C" {
pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
sheet: RawServoStyleSheetBorrowed,
rule: *const nsACString, index: u32,
nested: bool, rule_type: *mut u16)
-> nsresult;
nested: bool, loader: *mut Loader,
gecko_stylesheet: *mut ServoStyleSheet,
rule_type: *mut u16) -> nsresult;
}
extern "C" {
pub fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: u32)
@ -1549,13 +1552,11 @@ extern "C" {
extern "C" {
pub fn Servo_ParseProperty(property: *const nsACString,
value: *const nsACString,
base: *const nsACString,
data: *mut RawGeckoURLExtraData)
-> RawServoDeclarationBlockStrong;
}
extern "C" {
pub fn Servo_ParseEasing(easing: *const nsAString,
base: *const nsACString,
data: *mut RawGeckoURLExtraData,
output: nsTimingFunctionBorrowedMut) -> bool;
}
@ -1610,7 +1611,6 @@ extern "C" {
}
extern "C" {
pub fn Servo_ParseStyleAttribute(data: *const nsACString,
base: *const nsACString,
extra_data: *mut RawGeckoURLExtraData)
-> RawServoDeclarationBlockStrong;
}
@ -1678,7 +1678,6 @@ extern "C" {
property: *const nsACString,
value: *const nsACString,
is_important: bool,
base: *const nsACString,
data: *mut RawGeckoURLExtraData)
-> bool;
}
@ -1688,7 +1687,6 @@ extern "C" {
property: nsCSSPropertyID,
value: *const nsACString,
is_important: bool,
base: *const nsACString,
data:
*mut RawGeckoURLExtraData)
-> bool;

View file

@ -5626,7 +5626,8 @@ pub mod root {
#[derive(Debug)]
pub struct StyleSheet {
pub _base: root::nsIDOMCSSStyleSheet,
pub _base_1: root::nsWrapperCache,
pub _base_1: root::nsICSSLoaderObserver,
pub _base_2: root::nsWrapperCache,
pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
pub _mOwningThread: root::nsAutoOwningThread,
pub mParent: *mut root::mozilla::StyleSheet,
@ -5709,7 +5710,7 @@ pub mod root {
}
#[test]
fn bindgen_test_layout_StyleSheet() {
assert_eq!(::std::mem::size_of::<StyleSheet>() , 128usize , concat
assert_eq!(::std::mem::size_of::<StyleSheet>() , 136usize , concat
! ( "Size of: " , stringify ! ( StyleSheet ) ));
assert_eq! (::std::mem::align_of::<StyleSheet>() , 8usize , concat
! ( "Alignment of " , stringify ! ( StyleSheet ) ));
@ -14743,6 +14744,30 @@ pub mod root {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsICSSLoaderObserver {
pub _base: root::nsISupports,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct nsICSSLoaderObserver_COMTypeInfo<T, U> {
pub _address: u8,
pub _phantom_0: ::std::marker::PhantomData<T>,
pub _phantom_1: ::std::marker::PhantomData<U>,
}
#[test]
fn bindgen_test_layout_nsICSSLoaderObserver() {
assert_eq!(::std::mem::size_of::<nsICSSLoaderObserver>() , 8usize ,
concat ! (
"Size of: " , stringify ! ( nsICSSLoaderObserver ) ));
assert_eq! (::std::mem::align_of::<nsICSSLoaderObserver>() , 8usize ,
concat ! (
"Alignment of " , stringify ! ( nsICSSLoaderObserver ) ));
}
impl Clone for nsICSSLoaderObserver {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug)]
pub struct nsAttrValue {
pub mBits: usize,

View file

@ -5535,7 +5535,8 @@ pub mod root {
#[derive(Debug)]
pub struct StyleSheet {
pub _base: root::nsIDOMCSSStyleSheet,
pub _base_1: root::nsWrapperCache,
pub _base_1: root::nsICSSLoaderObserver,
pub _base_2: root::nsWrapperCache,
pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
pub mParent: *mut root::mozilla::StyleSheet,
pub mTitle: ::nsstring::nsStringRepr,
@ -5617,7 +5618,7 @@ pub mod root {
}
#[test]
fn bindgen_test_layout_StyleSheet() {
assert_eq!(::std::mem::size_of::<StyleSheet>() , 120usize , concat
assert_eq!(::std::mem::size_of::<StyleSheet>() , 128usize , concat
! ( "Size of: " , stringify ! ( StyleSheet ) ));
assert_eq! (::std::mem::align_of::<StyleSheet>() , 8usize , concat
! ( "Alignment of " , stringify ! ( StyleSheet ) ));
@ -14233,6 +14234,30 @@ pub mod root {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsICSSLoaderObserver {
pub _base: root::nsISupports,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct nsICSSLoaderObserver_COMTypeInfo<T, U> {
pub _address: u8,
pub _phantom_0: ::std::marker::PhantomData<T>,
pub _phantom_1: ::std::marker::PhantomData<U>,
}
#[test]
fn bindgen_test_layout_nsICSSLoaderObserver() {
assert_eq!(::std::mem::size_of::<nsICSSLoaderObserver>() , 8usize ,
concat ! (
"Size of: " , stringify ! ( nsICSSLoaderObserver ) ));
assert_eq! (::std::mem::align_of::<nsICSSLoaderObserver>() , 8usize ,
concat ! (
"Alignment of " , stringify ! ( nsICSSLoaderObserver ) ));
}
impl Clone for nsICSSLoaderObserver {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug)]
pub struct nsAttrValue {
pub mBits: usize,

View file

@ -71,6 +71,15 @@ impl<T: RefCounted> RefPtr<T> {
ret
}
/// Create a reference to RefPtr from a reference to pointer.
///
/// The pointer must be valid and non null.
///
/// This method doesn't touch refcount.
pub unsafe fn from_ptr_ref(ptr: &*mut T) -> &Self {
mem::transmute(ptr)
}
/// Produces an FFI-compatible RefPtr that can be stored in style structs.
///
/// structs::RefPtr does not have a destructor, so this may leak

View file

@ -8,7 +8,7 @@
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule};
use parser::{ParserContext, ParserContextExtraData, log_css_error};
use parser::{ParserContext, log_css_error};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId};
use properties::{PropertyDeclarationId, LonghandId, ParsedDeclaration};
use properties::LonghandIdSet;
@ -123,15 +123,12 @@ impl ToCssWithGuard for Keyframe {
impl Keyframe {
/// Parse a CSS keyframe.
pub fn parse(css: &str,
parent_stylesheet: &Stylesheet,
extra_data: ParserContextExtraData)
pub fn parse(css: &str, parent_stylesheet: &Stylesheet)
-> Result<Arc<Locked<Self>>, ()> {
let error_reporter = MemoryHoleReporter;
let context = ParserContext::new_with_extra_data(parent_stylesheet.origin,
&parent_stylesheet.base_url,
&error_reporter,
extra_data);
let context = ParserContext::new(parent_stylesheet.origin,
&parent_stylesheet.url_data,
&error_reporter);
let mut input = Parser::new(css);
let mut rule_parser = KeyframeListParser {

View file

@ -8,92 +8,38 @@
use cssparser::{Parser, SourcePosition, UnicodeRange};
use error_reporting::ParseErrorReporter;
#[cfg(feature = "gecko")]
use gecko_bindings::structs::URLExtraData;
#[cfg(feature = "gecko")]
use gecko_bindings::sugar::refptr::RefPtr;
use servo_url::ServoUrl;
use style_traits::OneOrMoreCommaSeparated;
use stylesheets::Origin;
use stylesheets::{Origin, UrlExtraData};
/// Extra data that the style backend may need to parse stylesheets.
#[cfg(not(feature = "gecko"))]
pub struct ParserContextExtraData;
/// Extra data that the style backend may need to parse stylesheets.
#[cfg(feature = "gecko")]
pub struct ParserContextExtraData {
/// The URL extra data.
pub data: Option<RefPtr<URLExtraData>>,
}
#[cfg(not(feature = "gecko"))]
impl Default for ParserContextExtraData {
fn default() -> Self {
ParserContextExtraData
}
}
#[cfg(feature = "gecko")]
impl Default for ParserContextExtraData {
fn default() -> Self {
ParserContextExtraData { data: None }
}
}
#[cfg(feature = "gecko")]
impl ParserContextExtraData {
/// Construct from a GeckoParserExtraData
///
/// GeckoParserExtraData must live longer than this call
pub unsafe fn new(data: *mut URLExtraData) -> Self {
ParserContextExtraData {
data: Some(RefPtr::new(data)),
}
}
}
/// The data that the parser needs from outside in order to parse a stylesheet.
pub struct ParserContext<'a> {
/// The `Origin` of the stylesheet, whether it's a user, author or
/// user-agent stylesheet.
pub stylesheet_origin: Origin,
/// The base url we're parsing this stylesheet as.
pub base_url: &'a ServoUrl,
/// The extra data we need for resolving url values.
pub url_data: &'a UrlExtraData,
/// An error reporter to report syntax errors.
pub error_reporter: &'a ParseErrorReporter,
/// Implementation-dependent extra data.
pub extra_data: ParserContextExtraData,
}
impl<'a> ParserContext<'a> {
/// Create a `ParserContext` with extra data.
pub fn new_with_extra_data(stylesheet_origin: Origin,
base_url: &'a ServoUrl,
error_reporter: &'a ParseErrorReporter,
extra_data: ParserContextExtraData)
-> ParserContext<'a> {
/// Create a parser context.
pub fn new(stylesheet_origin: Origin,
url_data: &'a UrlExtraData,
error_reporter: &'a ParseErrorReporter)
-> ParserContext<'a> {
ParserContext {
stylesheet_origin: stylesheet_origin,
base_url: base_url,
url_data: url_data,
error_reporter: error_reporter,
extra_data: extra_data,
}
}
/// Create a parser context with the default extra data.
pub fn new(stylesheet_origin: Origin,
base_url: &'a ServoUrl,
error_reporter: &'a ParseErrorReporter)
-> ParserContext<'a> {
let extra_data = ParserContextExtraData::default();
Self::new_with_extra_data(stylesheet_origin, base_url, error_reporter, extra_data)
}
/// Create a parser context for on-the-fly parsing in CSSOM
pub fn new_for_cssom(base_url: &'a ServoUrl,
pub fn new_for_cssom(url_data: &'a UrlExtraData,
error_reporter: &'a ParseErrorReporter)
-> ParserContext<'a> {
Self::new(Origin::User, base_url, error_reporter)
Self::new(Origin::User, url_data, error_reporter)
}
}
@ -104,8 +50,8 @@ pub fn log_css_error(input: &mut Parser,
position: SourcePosition,
message: &str,
parsercontext: &ParserContext) {
let servo_url = parsercontext.base_url;
parsercontext.error_reporter.report_error(input, position, message, servo_url);
let url_data = parsercontext.url_data;
parsercontext.error_reporter.report_error(input, position, message, url_data);
}
// XXXManishearth Replace all specified value parse impls with impls of this

View file

@ -9,11 +9,10 @@
use cssparser::{DeclarationListParser, parse_important};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
use error_reporting::ParseErrorReporter;
use parser::{ParserContext, ParserContextExtraData, log_css_error};
use servo_url::ServoUrl;
use parser::{ParserContext, log_css_error};
use std::fmt;
use style_traits::ToCss;
use stylesheets::Origin;
use stylesheets::{Origin, UrlExtraData};
use super::*;
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
@ -610,14 +609,10 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W,
/// A helper to parse the style attribute of an element, in order for this to be
/// shared between Servo and Gecko.
pub fn parse_style_attribute(input: &str,
base_url: &ServoUrl,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData)
url_data: &UrlExtraData,
error_reporter: &ParseErrorReporter)
-> PropertyDeclarationBlock {
let context = ParserContext::new_with_extra_data(Origin::Author,
base_url,
error_reporter,
extra_data);
let context = ParserContext::new(Origin::Author, url_data, error_reporter);
parse_property_declaration_list(&context, &mut Parser::new(input))
}
@ -628,14 +623,10 @@ pub fn parse_style_attribute(input: &str,
/// this does not attempt to parse !important at all
pub fn parse_one_declaration(id: PropertyId,
input: &str,
base_url: &ServoUrl,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData)
url_data: &UrlExtraData,
error_reporter: &ParseErrorReporter)
-> Result<ParsedDeclaration, ()> {
let context = ParserContext::new_with_extra_data(Origin::Author,
base_url,
error_reporter,
extra_data);
let context = ParserContext::new(Origin::Author, url_data, error_reporter);
Parser::new(input).parse_entirely(|parser| {
ParsedDeclaration::parse(id, &context, parser, false)
.map_err(|_| ())

View file

@ -71,7 +71,7 @@
pub mod single_value {
use cssparser::Parser;
use parser::{Parse, ParserContext, ParserContextExtraData};
use parser::{Parse, ParserContext};
use properties::ShorthandId;
use values::computed::{Context, ToComputedValue};
use values::{computed, specified};
@ -211,7 +211,7 @@
#![allow(unused_imports)]
% if not property.derived_from:
use cssparser::Parser;
use parser::{Parse, ParserContext, ParserContextExtraData};
use parser::{Parse, ParserContext};
use properties::{UnparsedValue, ShorthandId};
% endif
use values::{Auto, Either, None_, Normal};
@ -368,7 +368,7 @@
Arc::new(UnparsedValue {
css: css.into_owned(),
first_token_type: first_token_type,
base_url: context.base_url.clone(),
url_data: context.url_data.clone(),
from_shorthand: None,
})))
}
@ -594,7 +594,7 @@
Ok(ParsedDeclaration::${shorthand.camel_case}WithVariables(Arc::new(UnparsedValue {
css: css.into_owned(),
first_token_type: first_token_type,
base_url: context.base_url.clone(),
url_data: context.url_data.clone(),
from_shorthand: Some(ShorthandId::${shorthand.camel_case}),
})))
} else {

View file

@ -27,13 +27,12 @@ use font_metrics::FontMetricsProvider;
#[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
use logical_geometry::WritingMode;
use media_queries::Device;
use parser::{Parse, ParserContext, ParserContextExtraData};
use parser::{Parse, ParserContext};
use properties::animated_properties::TransitionProperty;
#[cfg(feature = "servo")] use servo_config::prefs::PREFS;
use servo_url::ServoUrl;
use shared_lock::StylesheetGuards;
use style_traits::ToCss;
use stylesheets::Origin;
use stylesheets::{Origin, UrlExtraData};
#[cfg(feature = "servo")] use values::Either;
use values::{HasViewportPercentage, computed};
use cascade_info::CascadeInfo;
@ -296,18 +295,13 @@ impl PropertyDeclarationIdSet {
% endif
{
if let DeclaredValue::WithVariables(ref with_variables) = *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(&with_variables.css,
with_variables.first_token_type,
&with_variables.base_url,
&with_variables.url_data,
with_variables.from_shorthand,
custom_properties,
f,
error_reporter,
extra_data);
error_reporter);
} else {
f(value);
}
@ -318,12 +312,11 @@ impl PropertyDeclarationIdSet {
fn substitute_variables_${property.ident}_slow<F>(
css: &String,
first_token_type: TokenSerializationType,
base_url: &ServoUrl,
url_data: &UrlExtraData,
from_shorthand: Option<ShorthandId>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData)
error_reporter: &ParseErrorReporter)
% if property.boxed:
where F: FnOnce(&DeclaredValue<Box<longhands::${property.ident}::SpecifiedValue>>)
% else:
@ -337,9 +330,7 @@ impl PropertyDeclarationIdSet {
//
// FIXME(pcwalton): Cloning the error reporter is slow! But so are custom
// properties, so whatever...
let context = ParserContext::new_with_extra_data(
::stylesheets::Origin::Author, base_url, error_reporter,
extra_data);
let context = ParserContext::new(Origin::Author, url_data, error_reporter);
Parser::new(&css).parse_entirely(|input| {
match from_shorthand {
None => {
@ -652,8 +643,8 @@ pub struct UnparsedValue {
css: String,
/// The first token type for this serialization.
first_token_type: TokenSerializationType,
/// The base url.
base_url: ServoUrl,
/// The url data for resolving url values.
url_data: UrlExtraData,
/// The shorthand this came from.
from_shorthand: Option<ShorthandId>,
}

View file

@ -42,7 +42,7 @@ impl SpecifiedUrl {
context: &ParserContext)
-> Result<Self, ()> {
let serialization = Arc::new(url.into_owned());
let resolved = context.base_url.join(&serialization).ok();
let resolved = context.url_data.join(&serialization).ok();
Ok(SpecifiedUrl {
original: Some(serialization),
resolved: resolved,

View file

@ -16,14 +16,19 @@ use font_face::FontFaceRuleData;
use font_face::parse_font_face_block;
#[cfg(feature = "gecko")]
pub use gecko::rules::FontFaceRule;
#[cfg(feature = "gecko")]
use gecko_bindings::structs::URLExtraData;
#[cfg(feature = "gecko")]
use gecko_bindings::sugar::refptr::RefPtr;
use keyframes::{Keyframe, parse_keyframe_list};
use media_queries::{Device, MediaList, parse_media_query_list};
use parking_lot::RwLock;
use parser::{ParserContext, ParserContextExtraData, log_css_error};
use parser::{ParserContext, log_css_error};
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
use selector_parser::{SelectorImpl, SelectorParser};
use selectors::parser::SelectorList;
use servo_config::prefs::PREFS;
#[cfg(not(feature = "gecko"))]
use servo_url::ServoUrl;
use shared_lock::{SharedRwLock, Locked, ToCssWithGuard, SharedRwLockReadGuard};
use std::cell::Cell;
@ -37,6 +42,30 @@ use values::specified::url::SpecifiedUrl;
use viewport::ViewportRule;
/// Extra data that the backend may need to resolve url values.
#[cfg(not(feature = "gecko"))]
pub type UrlExtraData = ServoUrl;
/// Extra data that the backend may need to resolve url values.
#[cfg(feature = "gecko")]
pub type UrlExtraData = RefPtr<URLExtraData>;
#[cfg(feature = "gecko")]
impl UrlExtraData {
/// Returns a string for the url.
///
/// Unimplemented currently.
pub fn as_str(&self) -> &str {
// TODO
"(stylo: not supported)"
}
}
// XXX We probably need to figure out whether we should mark Eq here.
// It is currently marked so because properties::UnparsedValue wants Eq.
#[cfg(feature = "gecko")]
impl Eq for UrlExtraData {}
/// Each style rule has an origin, which determines where it enters the cascade.
///
/// http://dev.w3.org/csswg/css-cascade/#cascading-origins
@ -106,7 +135,12 @@ impl CssRules {
}
/// https://drafts.csswg.org/cssom/#insert-a-css-rule
pub fn insert_rule(&mut self, rule: &str, parent_stylesheet: &Stylesheet, index: usize, nested: bool)
pub fn insert_rule(&mut self,
rule: &str,
parent_stylesheet: &Stylesheet,
index: usize,
nested: bool,
loader: Option<&StylesheetLoader>)
-> Result<CssRule, RulesMutateError> {
// Step 1, 2
if index > self.0.len() {
@ -125,8 +159,7 @@ impl CssRules {
// Step 3, 4
// XXXManishearth should we also store the namespace map?
let (new_rule, new_state) =
try!(CssRule::parse(&rule, parent_stylesheet,
ParserContextExtraData::default(), state));
try!(CssRule::parse(&rule, parent_stylesheet, state, loader));
// Step 5
// Computes the maximum allowed parser state at a given index.
@ -183,8 +216,8 @@ pub struct Stylesheet {
pub media: Arc<Locked<MediaList>>,
/// The origin of this stylesheet.
pub origin: Origin,
/// The base url this stylesheet should use.
pub base_url: ServoUrl,
/// The url data this stylesheet should use.
pub url_data: UrlExtraData,
/// The lock used for objects inside this stylesheet
pub shared_lock: SharedRwLock,
/// The namespaces that apply to this stylesheet.
@ -259,7 +292,7 @@ impl ParseErrorReporter for MemoryHoleReporter {
_: &mut Parser,
_: SourcePosition,
_: &str,
_: &ServoUrl) {
_: &UrlExtraData) {
// do nothing
}
}
@ -342,15 +375,14 @@ impl CssRule {
#[allow(missing_docs)]
pub fn parse(css: &str,
parent_stylesheet: &Stylesheet,
extra_data: ParserContextExtraData,
state: Option<State>)
state: Option<State>,
loader: Option<&StylesheetLoader>)
-> Result<(Self, State), SingleRuleParseError> {
let error_reporter = MemoryHoleReporter;
let mut namespaces = parent_stylesheet.namespaces.write();
let context = ParserContext::new_with_extra_data(parent_stylesheet.origin,
&parent_stylesheet.base_url,
&error_reporter,
extra_data);
let context = ParserContext::new(parent_stylesheet.origin,
&parent_stylesheet.url_data,
&error_reporter);
let mut input = Parser::new(css);
// nested rules are in the body state
@ -359,7 +391,7 @@ impl CssRule {
stylesheet_origin: parent_stylesheet.origin,
context: context,
shared_lock: &parent_stylesheet.shared_lock,
loader: None,
loader: loader,
state: Cell::new(state),
namespaces: &mut namespaces,
};
@ -563,13 +595,15 @@ impl Stylesheet {
/// Updates an empty stylesheet from a given string of text.
pub fn update_from_str(existing: &Stylesheet,
css: &str,
url_data: &UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData) {
error_reporter: &ParseErrorReporter) {
let mut namespaces = Namespaces::default();
// FIXME: we really should update existing.url_data with the given url_data,
// otherwise newly inserted rule may not have the right base url.
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css, &existing.base_url, existing.origin, &mut namespaces, &existing.shared_lock,
stylesheet_loader, error_reporter, extra_data,
css, url_data, existing.origin, &mut namespaces,
&existing.shared_lock, stylesheet_loader, error_reporter,
);
*existing.namespaces.write() = namespaces;
@ -582,13 +616,12 @@ impl Stylesheet {
}
fn parse_rules(css: &str,
base_url: &ServoUrl,
url_data: &UrlExtraData,
origin: Origin,
namespaces: &mut Namespaces,
shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData)
error_reporter: &ParseErrorReporter)
-> (Vec<CssRule>, bool) {
let mut rules = Vec::new();
let mut input = Parser::new(css);
@ -597,10 +630,7 @@ impl Stylesheet {
namespaces: namespaces,
shared_lock: shared_lock,
loader: stylesheet_loader,
context: ParserContext::new_with_extra_data(origin,
base_url,
error_reporter,
extra_data),
context: ParserContext::new(origin, url_data, error_reporter),
state: Cell::new(State::Start),
};
@ -629,21 +659,20 @@ impl Stylesheet {
/// Effectively creates a new stylesheet and forwards the hard work to
/// `Stylesheet::update_from_str`.
pub fn from_str(css: &str,
base_url: ServoUrl,
url_data: UrlExtraData,
origin: Origin,
media: MediaList,
shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData) -> Stylesheet {
error_reporter: &ParseErrorReporter) -> Stylesheet {
let mut namespaces = Namespaces::default();
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css, &base_url, origin, &mut namespaces, &shared_lock,
stylesheet_loader, error_reporter, extra_data,
css, &url_data, origin, &mut namespaces,
&shared_lock, stylesheet_loader, error_reporter,
);
Stylesheet {
origin: origin,
base_url: base_url,
url_data: url_data,
namespaces: RwLock::new(namespaces),
rules: CssRules::new(rules, &shared_lock),
media: Arc::new(shared_lock.wrap(media)),
@ -862,7 +891,7 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
media: Arc::new(self.shared_lock.wrap(media)),
shared_lock: self.shared_lock.clone(),
origin: self.context.stylesheet_origin,
base_url: self.context.base_url.clone(),
url_data: self.context.url_data.clone(),
namespaces: RwLock::new(Namespaces::default()),
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),