Split CssUrl from SpecifiedUrl for non-value URLs.

This commit is contained in:
Xidorn Quan 2018-03-08 21:31:09 +11:00
parent 0090fbb3c8
commit fa5d76c395
10 changed files with 86 additions and 47 deletions

View file

@ -34,7 +34,7 @@ use style::shared_lock::{Locked, SharedRwLock};
use style::stylesheets::{CssRules, ImportRule, Namespaces, Stylesheet, StylesheetContents, Origin};
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::stylesheets::import_rule::ImportSheet;
use style::values::specified::url::SpecifiedUrl;
use style::values::CssUrl;
pub trait StylesheetOwner {
/// Returns whether this element was inserted by the parser (i.e., it should
@ -276,7 +276,7 @@ impl<'a> StyleStylesheetLoader for StylesheetLoader<'a> {
/// the constructed `@import` rule.
fn request_stylesheet(
&self,
url: SpecifiedUrl,
url: CssUrl,
source_location: SourceLocation,
context: &ParserContext,
lock: &SharedRwLock,

View file

@ -17,10 +17,10 @@ use servo_arc::{Arc, RawOffsetArc};
use std::mem;
use style_traits::ParseError;
/// A specified url() value for gecko. Gecko does not eagerly resolve SpecifiedUrls.
/// A CSS url() value for gecko.
#[css(function = "url")]
#[derive(Clone, Debug, PartialEq, ToCss)]
pub struct SpecifiedUrl {
pub struct CssUrl {
/// The URL in unresolved string form.
///
/// Refcounted since cloning this should be cheap and data: uris can be
@ -31,9 +31,8 @@ pub struct SpecifiedUrl {
#[css(skip)]
pub extra_data: RefPtr<URLExtraData>,
}
trivial_to_computed_value!(SpecifiedUrl);
impl SpecifiedUrl {
impl CssUrl {
/// Try to parse a URL from a string value that is a valid CSS token for a
/// URL.
///
@ -41,7 +40,7 @@ impl SpecifiedUrl {
pub fn parse_from_string<'a>(url: String,
context: &ParserContext)
-> Result<Self, ParseError<'a>> {
Ok(SpecifiedUrl {
Ok(CssUrl {
serialization: Arc::new(url),
extra_data: context.url_data.clone(),
})
@ -55,9 +54,8 @@ impl SpecifiedUrl {
}
/// Convert from URLValueData to SpecifiedUrl.
pub unsafe fn from_url_value_data(url: &URLValueData)
-> Result<SpecifiedUrl, ()> {
Ok(SpecifiedUrl {
unsafe fn from_url_value_data(url: &URLValueData) -> Result<Self, ()> {
Ok(CssUrl {
serialization: if url.mUsingRustString {
let arc_type = url.mStrings.mRustString.as_ref()
as *const _ as
@ -102,16 +100,16 @@ impl SpecifiedUrl {
}
}
impl Parse for SpecifiedUrl {
impl Parse for CssUrl {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let url = input.expect_url()?;
Self::parse_from_string(url.as_ref().to_owned(), context)
}
}
impl Eq for SpecifiedUrl {}
impl Eq for CssUrl {}
impl MallocSizeOf for SpecifiedUrl {
impl MallocSizeOf for CssUrl {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
// XXX: measure `serialization` once bug 1397971 lands
@ -122,13 +120,47 @@ impl MallocSizeOf for SpecifiedUrl {
}
}
/// A specified url() value for general usage.
#[derive(Clone, Debug, PartialEq, Eq, MallocSizeOf, ToCss)]
pub struct SpecifiedUrl {
/// The specified url value.
pub url: CssUrl,
}
trivial_to_computed_value!(SpecifiedUrl);
impl SpecifiedUrl {
fn from_css_url(url: CssUrl) -> Self {
SpecifiedUrl { url }
}
/// Convert from URLValueData to SpecifiedUrl.
pub unsafe fn from_url_value_data(url: &URLValueData) -> Result<Self, ()> {
CssUrl::from_url_value_data(url).map(Self::from_css_url)
}
/// Create a bundled URI suitable for sending to Gecko
/// to be constructed into a css::URLValue.
///
/// XXX This is added temporially. It would be removed once we store
/// URLValue in SpecifiedUrl directly.
pub fn for_ffi(&self) -> ServoBundledURI {
self.url.for_ffi()
}
}
impl Parse for SpecifiedUrl {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
CssUrl::parse(context, input).map(Self::from_css_url)
}
}
/// A specified url() value for image.
///
/// This exists so that we can construct `ImageValue` and reuse it.
#[derive(Clone, Debug, ToCss)]
pub struct SpecifiedImageUrl {
/// The specified url value.
pub url: SpecifiedUrl,
pub url: CssUrl,
/// Gecko's ImageValue so that we can reuse it while rematching a
/// property with this specified value.
#[css(skip)]
@ -137,7 +169,7 @@ pub struct SpecifiedImageUrl {
trivial_to_computed_value!(SpecifiedImageUrl);
impl SpecifiedImageUrl {
fn from_specified_url(url: SpecifiedUrl) -> Self {
fn from_css_url(url: CssUrl) -> Self {
let image_value = unsafe {
let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi());
// We do not expect Gecko_ImageValue_Create returns null.
@ -152,12 +184,12 @@ impl SpecifiedImageUrl {
url: String,
context: &ParserContext
) -> Result<Self, ParseError<'a>> {
SpecifiedUrl::parse_from_string(url, context).map(Self::from_specified_url)
CssUrl::parse_from_string(url, context).map(Self::from_css_url)
}
/// Convert from URLValueData to SpecifiedUrl.
pub unsafe fn from_url_value_data(url: &URLValueData) -> Result<Self, ()> {
SpecifiedUrl::from_url_value_data(url).map(Self::from_specified_url)
CssUrl::from_url_value_data(url).map(Self::from_css_url)
}
/// Convert from nsStyleImageRequest to SpecifiedUrl.
@ -174,7 +206,7 @@ impl SpecifiedImageUrl {
impl Parse for SpecifiedImageUrl {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
SpecifiedUrl::parse(context, input).map(Self::from_specified_url)
CssUrl::parse(context, input).map(Self::from_css_url)
}
}

View file

@ -15,7 +15,7 @@ use std::sync::Arc;
use style_traits::{CssWriter, ParseError, ToCss};
use values::computed::{Context, ToComputedValue};
/// A specified url() value for servo.
/// A CSS url() value for servo.
///
/// Servo eagerly resolves SpecifiedUrls, which it can then take advantage of
/// when computing values. In contrast, Gecko uses a different URL backend, so
@ -24,7 +24,7 @@ use values::computed::{Context, ToComputedValue};
/// However, this approach is still not necessarily optimal: See
/// <https://bugzilla.mozilla.org/show_bug.cgi?id=1347435#c6>
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct SpecifiedUrl {
pub struct CssUrl {
/// The original URI. This might be optional since we may insert computed
/// values of images into the cascade directly, and we don't bother to
/// convert their serialization.
@ -38,7 +38,7 @@ pub struct SpecifiedUrl {
resolved: Option<ServoUrl>,
}
impl SpecifiedUrl {
impl CssUrl {
/// Try to parse a URL from a string value that is a valid CSS token for a
/// URL. Never fails - the API is only fallible to be compatible with the
/// gecko version.
@ -47,7 +47,7 @@ impl SpecifiedUrl {
-> Result<Self, ParseError<'a>> {
let serialization = Arc::new(url);
let resolved = context.url_data.join(&serialization).ok();
Ok(SpecifiedUrl {
Ok(CssUrl {
original: Some(serialization),
resolved: resolved,
})
@ -88,7 +88,7 @@ impl SpecifiedUrl {
/// Creates an already specified url value from an already resolved URL
/// for insertion in the cascade.
pub fn for_cascade(url: ServoUrl) -> Self {
SpecifiedUrl {
CssUrl {
original: None,
resolved: Some(url),
}
@ -96,21 +96,21 @@ impl SpecifiedUrl {
/// Gets a new url from a string for unit tests.
pub fn new_for_testing(url: &str) -> Self {
SpecifiedUrl {
CssUrl {
original: Some(Arc::new(url.into())),
resolved: ServoUrl::parse(url).ok(),
}
}
}
impl Parse for SpecifiedUrl {
impl Parse for CssUrl {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
let url = input.expect_url()?;
Self::parse_from_string(url.as_ref().to_owned(), context)
}
}
impl PartialEq for SpecifiedUrl {
impl PartialEq for CssUrl {
fn eq(&self, other: &Self) -> bool {
// TODO(emilio): maybe we care about equality of the specified values if
// present? Seems not.
@ -118,9 +118,9 @@ impl PartialEq for SpecifiedUrl {
}
}
impl Eq for SpecifiedUrl {}
impl Eq for CssUrl {}
impl ToCss for SpecifiedUrl {
impl ToCss for CssUrl {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
@ -142,6 +142,9 @@ impl ToCss for SpecifiedUrl {
}
}
/// A specified url() value for servo.
pub type SpecifiedUrl = CssUrl;
impl ToComputedValue for SpecifiedUrl {
type ComputedValue = ComputedUrl;
@ -174,7 +177,7 @@ impl ToComputedValue for SpecifiedUrl {
}
/// A specified image url() value for servo.
pub type SpecifiedImageUrl = SpecifiedUrl;
pub type SpecifiedImageUrl = CssUrl;
/// The computed value of a CSS `url()`, resolved relative to the stylesheet URL.
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]

View file

@ -17,7 +17,7 @@ use std::fmt::{self, Write};
use str::CssStringWriter;
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use stylesheets::CssRules;
use values::specified::url::SpecifiedUrl;
use values::CssUrl;
#[derive(Debug)]
/// A @-moz-document rule
@ -75,7 +75,7 @@ impl DeepCloneWithLock for DocumentRule {
pub enum UrlMatchingFunction {
/// Exact URL matching function. It evaluates to true whenever the
/// URL of the document being styled is exactly the URL given.
Url(SpecifiedUrl),
Url(CssUrl),
/// URL prefix matching function. It evaluates to true whenever the
/// URL of the document being styled has the argument to the
/// function as an initial substring (which is true when the two
@ -130,7 +130,7 @@ impl UrlMatchingFunction {
input.parse_nested_block(|input| {
Ok(UrlMatchingFunction::Regexp(input.expect_string()?.as_ref().to_owned()))
})
} else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) {
} else if let Ok(url) = input.try(|input| CssUrl::parse(context, input)) {
Ok(UrlMatchingFunction::Url(url))
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))

View file

@ -13,7 +13,7 @@ use std::fmt::{self, Write};
use str::CssStringWriter;
use style_traits::{CssWriter, ToCss};
use stylesheets::{StylesheetContents, StylesheetInDocument};
use values::specified::url::SpecifiedUrl;
use values::CssUrl;
/// A sheet that is held from an import rule.
#[cfg(feature = "gecko")]
@ -80,7 +80,7 @@ impl DeepCloneWithLock for ImportSheet {
#[derive(Debug)]
pub struct ImportRule {
/// The `<url>` this `@import` rule is loading.
pub url: SpecifiedUrl,
pub url: CssUrl,
/// The stylesheet is always present.
///

View file

@ -11,7 +11,7 @@ use parser::ParserContext;
use servo_arc::Arc;
use shared_lock::{Locked, SharedRwLock};
use stylesheets::import_rule::ImportRule;
use values::specified::url::SpecifiedUrl;
use values::CssUrl;
/// The stylesheet loader is the abstraction used to trigger network requests
/// for `@import` rules.
@ -20,7 +20,7 @@ pub trait StylesheetLoader {
/// the constructed `@import` rule.
fn request_stylesheet(
&self,
url: SpecifiedUrl,
url: CssUrl,
location: SourceLocation,
context: &ParserContext,
lock: &SharedRwLock,

View file

@ -28,10 +28,8 @@ use stylesheets::keyframes_rule::parse_keyframe_list;
use stylesheets::stylesheet::Namespaces;
use stylesheets::supports_rule::SupportsCondition;
use stylesheets::viewport_rule;
use values::CustomIdent;
use values::KeyframesName;
use values::{CssUrl, CustomIdent, KeyframesName};
use values::computed::font::FamilyName;
use values::specified::url::SpecifiedUrl;
/// The parser for the top-level rules in a stylesheet.
pub struct TopLevelRuleParser<'a, R: 'a> {
@ -134,7 +132,7 @@ pub enum AtRuleBlockPrelude {
/// A rule prelude for at-rule without block.
pub enum AtRuleNonBlockPrelude {
/// A @import rule prelude.
Import(SpecifiedUrl, Arc<Locked<MediaList>>, SourceLocation),
Import(CssUrl, Arc<Locked<MediaList>>, SourceLocation),
/// A @namespace rule prelude.
Namespace(Option<Prefix>, Namespace, SourceLocation),
}
@ -174,13 +172,13 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
}
let url_string = input.expect_url_or_string()?.as_ref().to_owned();
let specified_url = SpecifiedUrl::parse_from_string(url_string, &self.context)?;
let url = CssUrl::parse_from_string(url_string, &self.context)?;
let media = parse_media_query_list(&self.context, input,
self.error_context.error_reporter);
let media = Arc::new(self.shared_lock.wrap(media));
let prelude = AtRuleNonBlockPrelude::Import(specified_url, media, location);
let prelude = AtRuleNonBlockPrelude::Import(url, media, location);
return Ok(AtRuleType::WithoutBlock(prelude));
},
"namespace" => {
@ -228,12 +226,12 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
#[inline]
fn rule_without_block(&mut self, prelude: AtRuleNonBlockPrelude) -> CssRule {
match prelude {
AtRuleNonBlockPrelude::Import(specified_url, media, location) => {
AtRuleNonBlockPrelude::Import(url, media, location) => {
let loader =
self.loader.expect("Expected a stylesheet loader for @import");
let import_rule = loader.request_stylesheet(
specified_url,
url,
location,
&self.context,
&self.shared_lock,

View file

@ -17,6 +17,11 @@ use std::hash;
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use values::distance::{ComputeSquaredDistance, SquaredDistance};
#[cfg(feature = "servo")]
pub use servo::url::CssUrl;
#[cfg(feature = "gecko")]
pub use gecko::url::CssUrl;
pub mod animated;
pub mod computed;
pub mod distance;

View file

@ -152,7 +152,8 @@ impl Image {
/// for insertion in the cascade.
#[cfg(feature = "servo")]
pub fn for_cascade(url: ServoUrl) -> Self {
GenericImage::Url(SpecifiedUrl::for_cascade(url))
use values::CssUrl;
GenericImage::Url(CssUrl::for_cascade(url))
}
/// Parses a `-moz-element(# <element-id>)`.

View file

@ -13,7 +13,7 @@ use style::parser::ParserContext;
use style::shared_lock::{Locked, SharedRwLock};
use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader};
use style::stylesheets::import_rule::ImportSheet;
use style::values::specified::url::SpecifiedUrl;
use style::values::CssUrl;
pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet, *mut SheetLoadData, *mut LoaderReusableStyleSheets);
@ -29,7 +29,7 @@ impl StylesheetLoader {
impl StyleStylesheetLoader for StylesheetLoader {
fn request_stylesheet(
&self,
url: SpecifiedUrl,
url: CssUrl,
source_location: SourceLocation,
_context: &ParserContext,
lock: &SharedRwLock,