Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle URLs more efficiently in stylo #16092

Merged
merged 2 commits into from Mar 23, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -429,7 +429,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
PropertyDeclaration::BackgroundImage(
background_image::SpecifiedValue(vec![
background_image::single_value::SpecifiedValue(Some(
specified::Image::for_cascade(url.into(), specified::url::UrlExtraData { })
specified::Image::for_cascade(url.into())
))
]))));
}
@@ -353,6 +353,7 @@ mod bindings {
"nsCursorImage",
"nsFont",
"nsIAtom",
"nsIURI",
"nsMainThreadPtrHandle",
"nsMainThreadPtrHolder",
"nsMargin",
@@ -613,6 +614,7 @@ mod bindings {
"nsCursorImage",
"nsFont",
"nsIAtom",
"nsIURI",
"nsMediaFeature",
"nsRestyleHint",
"nsStyleBackground",
@@ -17,5 +17,6 @@ pub mod selector_parser;
pub mod snapshot;
pub mod snapshot_helpers;
pub mod traversal;
pub mod url;
pub mod values;
pub mod wrapper;
@@ -0,0 +1,104 @@
/* 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/. */

//! Common handling for the specified value CSS url() values.

use cssparser::CssStringWriter;
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
use parser::ParserContext;
use std::borrow::Cow;
use std::fmt::{self, Write};
use std::sync::Arc;
use style_traits::ToCss;

/// A specified url() value for gecko. Gecko does not eagerly resolve SpecifiedUrls.
#[derive(Clone, Debug, PartialEq)]
pub struct SpecifiedUrl {
/// The URL in unresolved string form.
///
/// Refcounted since cloning this should be cheap and data: uris can be
/// really large.
serialization: Arc<String>,

/// The base URI.
pub base: GeckoArcURI,
/// The referrer.
pub referrer: GeckoArcURI,
/// The principal that originated this URI.
pub principal: GeckoArcPrincipal,
}

impl SpecifiedUrl {
/// Try to parse a URL from a string value that is a valid CSS token for a
/// URL.
///
/// Returns `Err` in the case that extra_data is incomplete.
pub fn parse_from_string<'a>(url: Cow<'a, str>,
context: &ParserContext)
-> Result<Self, ()> {
let extra = &context.extra_data;
if extra.base.is_none() || extra.referrer.is_none() || extra.principal.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()),
base: extra.base.as_ref().unwrap().clone(),
referrer: extra.referrer.as_ref().unwrap().clone(),
principal: extra.principal.as_ref().unwrap().clone(),
})
}

/// Returns true if the URL is definitely invalid. We don't eagerly resolve
/// URLs in gecko, so we just return false here.
/// use its |resolved| status.
pub fn is_invalid(&self) -> bool {
false
}

/// Returns true if this URL looks like a fragment.
/// See https://drafts.csswg.org/css-values/#local-urls
pub fn is_fragment(&self) -> bool {
self.as_str().chars().next().map_or(false, |c| c == '#')
}

/// Return the resolved url as string, or the empty string if it's invalid.
///
/// FIXME(bholley): This returns the unresolved URL while the servo version
/// returns the resolved URL.
pub fn as_str(&self) -> &str {
&*self.serialization
}

/// Little helper for Gecko's ffi.
pub fn as_slice_components(&self) -> (*const u8, usize) {
(self.serialization.as_str().as_ptr(), self.serialization.as_str().len())
}

/// Create a bundled URI suitable for sending to Gecko
/// to be constructed into a css::URLValue
pub fn for_ffi(&self) -> ServoBundledURI {
let (ptr, len) = self.as_slice_components();
ServoBundledURI {
mURLString: ptr,
mURLStringLength: len as u32,
mBaseURI: self.base.get(),
mReferrer: self.referrer.get(),
mPrincipal: self.principal.get(),
}
}
}

impl ToCss for SpecifiedUrl {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(dest.write_str("url(\""));
try!(CssStringWriter::new(dest).write_str(&*self.serialization));
dest.write_str("\")")
}
}
@@ -40,6 +40,7 @@ use gecko_bindings::structs::nsChangeHint;
use gecko_bindings::structs::nsCursorImage;
use gecko_bindings::structs::nsFont;
use gecko_bindings::structs::nsIAtom;
use gecko_bindings::structs::nsIURI;
use gecko_bindings::structs::nsMediaFeature;
use gecko_bindings::structs::nsRestyleHint;
use gecko_bindings::structs::nsStyleBackground;
@@ -437,8 +438,9 @@ extern "C" {
pub fn Gecko_LoadStyleSheet(loader: *mut Loader,
parent: *mut ServoStyleSheet,
import_rule: RawServoImportRuleBorrowed,
url_bytes: *const u8, url_length: u32,
media_bytes: *const u8, media_length: u32);
base_uri: *mut nsIURI, url_bytes: *const u8,
url_length: u32, media_bytes: *const u8,
media_length: u32);
}
extern "C" {
pub fn Gecko_MaybeCreateStyleChildrenIterator(node: RawGeckoNodeBorrowed)
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.