/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Common handling for the specified value CSS url() values.
usecrate::gecko_bindings::bindings; usecrate::gecko_bindings::structs; usecrate::parser::{Parse, ParserContext}; usecrate::stylesheets::{CorsMode, UrlExtraData}; usecrate::values::computed::{Context, ToComputedValue}; use cssparser::Parser; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use nsstring::nsCString; use servo_arc::Arc; use std::collections::HashMap; use std::fmt::{self, Write}; use std::mem::ManuallyDrop; use std::sync::RwLock; use style_traits::{CssWriter, ParseError, ToCss}; use to_shmem::{SharedMemoryBuilder, ToShmem};
/// A CSS url() value for gecko. #[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] #[css(function = "url")] #[repr(C)] pubstruct CssUrl(pub Arc<CssUrlData>);
/// Data shared between CssUrls. /// /// cbindgen:derive-eq=false /// cbindgen:derive-neq=false #[derive(Debug, SpecifiedValueInfo, ToCss, ToShmem)] #[repr(C)] pubstruct CssUrlData { /// The URL in unresolved string form.
serialization: crate::OwnedStr,
/// The URL extra data. #[css(skip)] pub extra_data: UrlExtraData,
/// The CORS mode that will be used for the load. #[css(skip)]
cors_mode: CorsMode,
/// Data to trigger a load from Gecko. This is mutable in C++. /// /// TODO(emilio): Maybe we can eagerly resolve URLs and make this immutable? #[css(skip)]
load_data: LoadDataSource,
}
impl CssUrl { /// Parse a URL with a particular CORS mode. pubfn parse_with_cors_mode<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
cors_mode: CorsMode,
) -> Result<Self, ParseError<'i>> { let url = input.expect_url()?;
Ok(Self::parse_from_string(
url.as_ref().to_owned(),
context,
cors_mode,
))
}
/// Parse a URL from a string value that is a valid CSS token for a URL. pubfn parse_from_string(url: String, context: &ParserContext, cors_mode: CorsMode) -> Self {
CssUrl(Arc::new(CssUrlData {
serialization: url.into(),
extra_data: context.url_data.clone(),
cors_mode,
load_data: LoadDataSource::Owned(LoadData::default()),
}))
}
/// 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. pubfn is_invalid(&self) -> bool { false
}
// We ignore `extra_data`, because RefPtr is tricky, and there aren't // many of them in practise (sharing is common).
0
}
}
/// A key type for LOAD_DATA_TABLE. #[derive(Eq, Hash, PartialEq)] struct LoadDataKey(*const LoadDataSource);
unsafeimpl Sync for LoadDataKey {} unsafeimpl Send for LoadDataKey {}
bitflags! { /// Various bits of mutable state that are kept for image loads. #[derive(Debug)] #[repr(C)] pubstruct LoadDataFlags: u8 { /// Whether we tried to resolve the uri at least once. const TRIED_TO_RESOLVE_URI = 1 << 0; /// Whether we tried to resolve the image at least once. const TRIED_TO_RESOLVE_IMAGE = 1 << 1;
}
}
/// This is usable and movable from multiple threads just fine, as long as it's /// not cloned (it is not clonable), and the methods that mutate it run only on /// the main thread (when all the other threads we care about are paused). unsafeimpl Sync for LoadData {} unsafeimpl Send for LoadData {}
/// The load data for a given URL. This is mutable from C++, and shouldn't be /// accessed from rust for anything. #[repr(C)] #[derive(Debug)] pubstruct LoadData { /// A strong reference to the imgRequestProxy, if any, that should be /// released on drop. /// /// These are raw pointers because they are not safe to reference-count off /// the main thread.
resolved_image: *mut structs::imgRequestProxy, /// A strong reference to the resolved URI of this image.
resolved_uri: *mut structs::nsIURI, /// A few flags that are set when resolving the image or such.
flags: LoadDataFlags,
}
impl Drop for LoadData { fn drop(&mutself) { unsafe { bindings::Gecko_LoadData_Drop(self) }
}
}
/// The data for a load, or a lazy-loaded, static member that will be stored in /// LOAD_DATA_TABLE, keyed by the memory location of this object, which is /// always in the heap because it's inside the CssUrlData object. /// /// This type is meant not to be used from C++ so we don't derive helper /// methods. /// /// cbindgen:derive-helper-methods=false #[derive(Debug)] #[repr(u8, C)] pubenum LoadDataSource { /// An owned copy of the load data.
Owned(LoadData), /// A lazily-resolved copy of it.
Lazy,
}
impl LoadDataSource { /// Gets the load data associated with the source. /// /// This relies on the source on being in a stable location if lazy. #[inline] pubunsafefn get(&self) -> *const LoadData { match *self {
LoadDataSource::Owned(ref d) => return d,
LoadDataSource::Lazy => {},
}
let key = LoadDataKey(self);
{ let guard = LOAD_DATA_TABLE.read().unwrap(); iflet Some(r) = guard.get(&key) { return &**r;
}
} letmut guard = LOAD_DATA_TABLE.write().unwrap(); let r = guard.entry(key).or_insert_with(Default::default);
&**r
}
}
/// A specified non-image `url()` value. pubtype SpecifiedUrl = CssUrl;
/// Clears LOAD_DATA_TABLE. Entries in this table, which are for specified URL /// values that come from shared memory style sheets, would otherwise persist /// until the end of the process and be reported as leaks. pubfn shutdown() {
LOAD_DATA_TABLE.write().unwrap().clear();
}
impl ToComputedValue for SpecifiedUrl { type ComputedValue = ComputedUrl;
/// The computed value of a CSS non-image `url()`. /// /// The only difference between specified and computed URLs is the /// serialization. #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] #[repr(C)] pubstruct ComputedUrl(pub SpecifiedUrl);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.