stylo: Fix StyleSheetInner/Stylesheet mapping

The key of this patch is the split between Stylesheet and StylesheetContents.

Gecko will use StylesheetContents, which maps to a ServoStyleSheetInner.
This commit is contained in:
Emilio Cobos Álvarez 2017-06-28 12:12:14 -07:00
parent fd65ac8924
commit 1263075776
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
38 changed files with 3818 additions and 2931 deletions

View file

@ -101,6 +101,7 @@ use std::marker::PhantomData;
use std::mem as std_mem; use std::mem as std_mem;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::process; use std::process;
use std::slice;
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Mutex, MutexGuard};
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender, channel};
@ -117,7 +118,7 @@ use style::selector_parser::SnapshotMap;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW}; use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards}; use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
use style::stylearc::Arc as StyleArc; use style::stylearc::Arc as StyleArc;
use style::stylesheets::{Origin, Stylesheet, UserAgentStylesheets}; use style::stylesheets::{Origin, Stylesheet, StylesheetInDocument, UserAgentStylesheets};
use style::stylist::{ExtraStyleData, Stylist}; use style::stylist::{ExtraStyleData, Stylist};
use style::thread_state; use style::thread_state;
use style::timer::Timer; use style::timer::Timer;
@ -417,6 +418,17 @@ fn add_font_face_rules(stylesheet: &Stylesheet,
} }
} }
#[derive(Clone)]
struct StylesheetIterator<'a>(slice::Iter<'a, StyleArc<Stylesheet>>);
impl<'a> Iterator for StylesheetIterator<'a> {
type Item = &'a Stylesheet;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|s| &**s)
}
}
impl LayoutThread { impl LayoutThread {
/// Creates a new `LayoutThread` structure. /// Creates a new `LayoutThread` structure.
fn new(id: PipelineId, fn new(id: PipelineId,
@ -1146,7 +1158,7 @@ impl LayoutThread {
marker: PhantomData, marker: PhantomData,
}; };
let needs_dirtying = self.stylist.update( let needs_dirtying = self.stylist.update(
data.document_stylesheets.iter(), StylesheetIterator(data.document_stylesheets.iter()),
&guards, &guards,
Some(ua_stylesheets), Some(ua_stylesheets),
data.stylesheets_changed, data.stylesheets_changed,

View file

@ -82,7 +82,13 @@ impl CSSKeyframesRuleMethods for CSSKeyframesRule {
// https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-appendrule // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-appendrule
fn AppendRule(&self, rule: DOMString) { fn AppendRule(&self, rule: DOMString) {
let rule = Keyframe::parse(&rule, self.cssrule.parent_stylesheet().style_stylesheet()); let style_stylesheet = self.cssrule.parent_stylesheet().style_stylesheet();
let rule = Keyframe::parse(
&rule,
&style_stylesheet.contents,
&style_stylesheet.shared_lock
);
if let Ok(rule) = rule { if let Ok(rule) = rule {
let mut guard = self.cssrule.shared_lock().write(); let mut guard = self.cssrule.shared_lock().write();
self.keyframesrule.write_with(&mut guard).keyframes.push(rule); self.keyframesrule.write_with(&mut guard).keyframes.push(rule);

View file

@ -93,7 +93,7 @@ impl CSSRuleList {
let new_rule = let new_rule =
css_rules.insert_rule(&parent_stylesheet.shared_lock, css_rules.insert_rule(&parent_stylesheet.shared_lock,
rule, rule,
parent_stylesheet, &parent_stylesheet.contents,
index, index,
nested, nested,
None)?; None)?;

View file

@ -146,7 +146,7 @@ impl CSSStyleOwner {
match *self { match *self {
CSSStyleOwner::Element(ref el) => window_from_node(&**el).Document().base_url(), CSSStyleOwner::Element(ref el) => window_from_node(&**el).Document().base_url(),
CSSStyleOwner::CSSRule(ref rule, _) => { CSSStyleOwner::CSSRule(ref rule, _) => {
(*rule.parent_stylesheet().style_stylesheet().url_data.read()).clone() (*rule.parent_stylesheet().style_stylesheet().contents.url_data.read()).clone()
} }
} }
} }

View file

@ -57,10 +57,14 @@ impl CSSStyleSheet {
} }
fn rulelist(&self) -> Root<CSSRuleList> { fn rulelist(&self) -> Root<CSSRuleList> {
self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), self.rulelist.or_init(|| {
self, let rules = self.style_stylesheet.contents.rules.clone();
RulesSource::Rules(self.style_stylesheet CSSRuleList::new(
.rules.clone()))) self.global().as_window(),
self,
RulesSource::Rules(rules)
)
})
} }
pub fn disabled(&self) -> bool { pub fn disabled(&self) -> bool {

View file

@ -27,7 +27,7 @@ use style::attr::AttrValue;
use style::media_queries::MediaList; use style::media_queries::MediaList;
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
use style::stylearc::Arc; use style::stylearc::Arc;
use style::stylesheets::{Stylesheet, CssRule, CssRules, Origin, ViewportRule}; use style::stylesheets::{Stylesheet, StylesheetContents, CssRule, CssRules, Origin, ViewportRule};
#[dom_struct] #[dom_struct]
pub struct HTMLMetaElement { pub struct HTMLMetaElement {
@ -103,17 +103,20 @@ impl HTMLMetaElement {
let shared_lock = document.style_shared_lock(); let shared_lock = document.style_shared_lock();
let rule = CssRule::Viewport(Arc::new(shared_lock.wrap(translated_rule))); let rule = CssRule::Viewport(Arc::new(shared_lock.wrap(translated_rule)));
*self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet { *self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
rules: CssRules::new(vec![rule], shared_lock), contents: StylesheetContents {
origin: Origin::Author, rules: CssRules::new(vec![rule], shared_lock),
shared_lock: shared_lock.clone(), origin: Origin::Author,
url_data: RwLock::new(window_from_node(self).get_url()), namespaces: Default::default(),
namespaces: Default::default(), quirks_mode: document.quirks_mode(),
url_data: RwLock::new(window_from_node(self).get_url()),
// Viewport constraints are always recomputed on
// resize; they don't need to force all styles to be
// recomputed.
dirty_on_viewport_size_change: AtomicBool::new(false),
},
media: Arc::new(shared_lock.wrap(MediaList::empty())), media: Arc::new(shared_lock.wrap(MediaList::empty())),
// Viewport constraints are always recomputed on resize; they don't need to shared_lock: shared_lock.clone(),
// force all styles to be recomputed.
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false), disabled: AtomicBool::new(false),
quirks_mode: document.quirks_mode(),
})); }));
let doc = document_from_node(self); let doc = document_from_node(self);
doc.invalidate_stylesheets(); doc.invalidate_stylesheets();

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::SourceLocation;
use document_loader::LoadType; use document_loader::LoadType;
use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::Castable;
use dom::bindings::refcounted::Trusted; use dom::bindings::refcounted::Trusted;
@ -22,14 +23,19 @@ use ipc_channel::router::ROUTER;
use net_traits::{FetchResponseListener, FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy}; use net_traits::{FetchResponseListener, FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy};
use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType}; use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
use network_listener::{NetworkListener, PreInvoke}; use network_listener::{NetworkListener, PreInvoke};
use parking_lot::RwLock;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::mem; use std::mem;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::atomic::AtomicBool;
use style::media_queries::MediaList; use style::media_queries::MediaList;
use style::shared_lock::Locked as StyleLocked; use style::parser::ParserContext;
use style::shared_lock::{Locked, SharedRwLock};
use style::stylearc::Arc; use style::stylearc::Arc;
use style::stylesheets::{ImportRule, Stylesheet, Origin}; use style::stylesheets::{CssRules, ImportRule, Namespaces, Stylesheet, StylesheetContents, Origin};
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::stylesheets::import_rule::ImportSheet;
use style::values::specified::url::SpecifiedUrl;
pub trait StylesheetOwner { pub trait StylesheetOwner {
/// Returns whether this element was inserted by the parser (i.e., it should /// Returns whether this element was inserted by the parser (i.e., it should
@ -268,20 +274,43 @@ impl<'a> StylesheetLoader<'a> {
} }
impl<'a> StyleStylesheetLoader for StylesheetLoader<'a> { impl<'a> StyleStylesheetLoader for StylesheetLoader<'a> {
/// Request a stylesheet after parsing a given `@import` rule, and return
/// the constructed `@import` rule.
fn request_stylesheet( fn request_stylesheet(
&self, &self,
media: Arc<StyleLocked<MediaList>>, url: SpecifiedUrl,
make_import: &mut FnMut(Arc<StyleLocked<MediaList>>) -> ImportRule, source_location: SourceLocation,
make_arc: &mut FnMut(ImportRule) -> Arc<StyleLocked<ImportRule>>, context: &ParserContext,
) -> Arc<StyleLocked<ImportRule>> { lock: &SharedRwLock,
let import = make_import(media); media: Arc<Locked<MediaList>>,
let url = import.url.url().expect("Invalid urls shouldn't enter the loader").clone(); ) -> Arc<Locked<ImportRule>> {
let sheet = Arc::new(Stylesheet {
contents: StylesheetContents {
rules: CssRules::new(Vec::new(), lock),
origin: context.stylesheet_origin,
url_data: RwLock::new(context.url_data.clone()),
dirty_on_viewport_size_change: AtomicBool::new(false),
quirks_mode: context.quirks_mode,
namespaces: RwLock::new(Namespaces::default()),
},
media: media,
shared_lock: lock.clone(),
disabled: AtomicBool::new(false),
});
let stylesheet = ImportSheet(sheet.clone());
let import = ImportRule { url, source_location, stylesheet };
let url = match import.url.url().cloned() {
Some(url) => url,
None => return Arc::new(lock.wrap(import)),
};
// TODO (mrnayak) : Whether we should use the original loader's CORS // TODO (mrnayak) : Whether we should use the original loader's CORS
// setting? Fix this when spec has more details. // setting? Fix this when spec has more details.
let source = StylesheetContextSource::Import(import.stylesheet.clone()); let source = StylesheetContextSource::Import(sheet.clone());
self.load(source, url, None, "".to_owned()); self.load(source, url, None, "".to_owned());
make_arc(import) Arc::new(lock.wrap(import))
} }
} }

View file

@ -8,14 +8,13 @@
#![allow(non_snake_case, missing_docs)] #![allow(non_snake_case, missing_docs)]
use gecko_bindings::bindings::{RawServoImportRule, RawServoSupportsRule};
use gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframesRule}; use gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframesRule};
use gecko_bindings::bindings::{RawServoMediaList, RawServoMediaRule};
use gecko_bindings::bindings::{RawServoNamespaceRule, RawServoPageRule}; use gecko_bindings::bindings::{RawServoNamespaceRule, RawServoPageRule};
use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule}; use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule, RawServoMediaRule};
use gecko_bindings::bindings::{RawServoStyleSheet, RawServoImportRule, RawServoSupportsRule};
use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules}; use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
use gecko_bindings::structs::{RawServoDeclarationBlock, RawServoStyleRule}; use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock, RawServoStyleRule, RawServoMediaList};
use gecko_bindings::structs::RawServoAnimationValue; use gecko_bindings::structs::RawServoStyleSheetContents;
use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
use media_queries::MediaList; use media_queries::MediaList;
use properties::{ComputedValues, PropertyDeclarationBlock}; use properties::{ComputedValues, PropertyDeclarationBlock};
@ -23,7 +22,7 @@ use properties::animated_properties::AnimationValue;
use rule_tree::StrongRuleNode; use rule_tree::StrongRuleNode;
use shared_lock::Locked; use shared_lock::Locked;
use std::{mem, ptr}; use std::{mem, ptr};
use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule, KeyframesRule, MediaRule}; use stylesheets::{CssRules, StylesheetContents, StyleRule, ImportRule, KeyframesRule, MediaRule};
use stylesheets::{NamespaceRule, PageRule, SupportsRule, DocumentRule}; use stylesheets::{NamespaceRule, PageRule, SupportsRule, DocumentRule};
use stylesheets::keyframes_rule::Keyframe; use stylesheets::keyframes_rule::Keyframe;
@ -49,8 +48,8 @@ macro_rules! impl_arc_ffi {
impl_arc_ffi!(Locked<CssRules> => ServoCssRules impl_arc_ffi!(Locked<CssRules> => ServoCssRules
[Servo_CssRules_AddRef, Servo_CssRules_Release]); [Servo_CssRules_AddRef, Servo_CssRules_Release]);
impl_arc_ffi!(Stylesheet => RawServoStyleSheet impl_arc_ffi!(StylesheetContents => RawServoStyleSheetContents
[Servo_StyleSheet_AddRef, Servo_StyleSheet_Release]); [Servo_StyleSheetContents_AddRef, Servo_StyleSheetContents_Release]);
impl_arc_ffi!(ComputedValues => ServoComputedValues impl_arc_ffi!(ComputedValues => ServoComputedValues
[Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]); [Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]);

View file

@ -9,18 +9,108 @@ use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use dom::TElement; use dom::TElement;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use gecko::rules::{CounterStyleRule, FontFaceRule}; use gecko::rules::{CounterStyleRule, FontFaceRule};
use gecko_bindings::bindings::RawServoStyleSet; use gecko_bindings::bindings::{self, RawServoStyleSet};
use gecko_bindings::structs::{ServoStyleSheet, StyleSheetInfo, ServoStyleSheetInner};
use gecko_bindings::structs::RawGeckoPresContextOwned; use gecko_bindings::structs::RawGeckoPresContextOwned;
use gecko_bindings::structs::nsIDocument; use gecko_bindings::structs::nsIDocument;
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI};
use media_queries::Device; use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use media_queries::{Device, MediaList};
use properties::ComputedValues; use properties::ComputedValues;
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard}; use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use stylearc::Arc; use stylearc::Arc;
use stylesheet_set::StylesheetSet; use stylesheet_set::StylesheetSet;
use stylesheets::Origin; use stylesheets::{Origin, StylesheetContents, StylesheetInDocument};
use stylist::{ExtraStyleData, Stylist}; use stylist::{ExtraStyleData, Stylist};
/// Little wrapper to a Gecko style sheet.
#[derive(PartialEq, Eq, Debug)]
pub struct GeckoStyleSheet(*const ServoStyleSheet);
impl ToMediaListKey for ::gecko::data::GeckoStyleSheet {
fn to_media_list_key(&self) -> MediaListKey {
use std::mem;
unsafe {
MediaListKey::from_raw(mem::transmute(self.0))
}
}
}
impl GeckoStyleSheet {
/// Create a `GeckoStyleSheet` from a raw `ServoStyleSheet` pointer.
#[inline]
pub unsafe fn new(s: *const ServoStyleSheet) -> Self {
debug_assert!(!s.is_null());
bindings::Gecko_StyleSheet_AddRef(s);
Self::from_addrefed(s)
}
/// Create a `GeckoStyleSheet` from a raw `ServoStyleSheet` pointer that
/// already holds a strong reference.
#[inline]
pub unsafe fn from_addrefed(s: *const ServoStyleSheet) -> Self {
debug_assert!(!s.is_null());
GeckoStyleSheet(s)
}
/// Get the raw `ServoStyleSheet` that we're wrapping.
pub fn raw(&self) -> &ServoStyleSheet {
unsafe { &*self.0 }
}
fn inner(&self) -> &ServoStyleSheetInner {
unsafe {
&*(self.raw()._base.mInner as *const StyleSheetInfo as *const ServoStyleSheetInner)
}
}
}
impl Drop for GeckoStyleSheet {
fn drop(&mut self) {
unsafe { bindings::Gecko_StyleSheet_Release(self.0) };
}
}
impl Clone for GeckoStyleSheet {
fn clone(&self) -> Self {
unsafe { bindings::Gecko_StyleSheet_AddRef(self.0) };
GeckoStyleSheet(self.0)
}
}
impl StylesheetInDocument for GeckoStyleSheet {
fn contents(&self, _: &SharedRwLockReadGuard) -> &StylesheetContents {
debug_assert!(!self.inner().mContents.mRawPtr.is_null());
unsafe {
let contents =
(&**StylesheetContents::as_arc(&&*self.inner().mContents.mRawPtr)) as *const _;
&*contents
}
}
fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList> {
use gecko_bindings::structs::ServoMediaList;
use std::mem;
unsafe {
let servo_media_list =
self.raw()._base.mMedia.mRawPtr as *const ServoMediaList;
if servo_media_list.is_null() {
return None;
}
let raw_list = &*(*servo_media_list).mRawList.mRawPtr;
let list = Locked::<MediaList>::as_arc(mem::transmute(&raw_list));
Some(list.read_with(guard))
}
}
// All the stylesheets Servo knows about are enabled, because that state is
// handled externally by Gecko.
fn enabled(&self) -> bool {
true
}
}
/// The container for data that a Servo-backed Gecko document needs to style /// The container for data that a Servo-backed Gecko document needs to style
/// itself. /// itself.
pub struct PerDocumentStyleDataImpl { pub struct PerDocumentStyleDataImpl {
@ -28,7 +118,7 @@ pub struct PerDocumentStyleDataImpl {
pub stylist: Stylist, pub stylist: Stylist,
/// List of stylesheets, mirrored from Gecko. /// List of stylesheets, mirrored from Gecko.
pub stylesheets: StylesheetSet, pub stylesheets: StylesheetSet<GeckoStyleSheet>,
/// List of effective font face rules. /// List of effective font face rules.
pub font_faces: Vec<(Arc<Locked<FontFaceRule>>, Origin)>, pub font_faces: Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
@ -87,12 +177,14 @@ impl PerDocumentStyleDataImpl {
let author_style_disabled = self.stylesheets.author_style_disabled(); let author_style_disabled = self.stylesheets.author_style_disabled();
self.stylist.clear(); self.stylist.clear();
let iter = self.stylesheets.flush(document_element); let iter = self.stylesheets.flush(document_element);
self.stylist.rebuild(iter, self.stylist.rebuild(
&StylesheetGuards::same(guard), iter,
/* ua_sheets = */ None, &StylesheetGuards::same(guard),
/* stylesheets_changed = */ true, /* ua_sheets = */ None,
author_style_disabled, /* stylesheets_changed = */ true,
&mut extra_data); author_style_disabled,
&mut extra_data
);
} }
/// Get the default computed values for this document. /// Get the default computed values for this document.

View file

@ -4334,6 +4334,8 @@ cfg_if! {
pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom; pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms18overlay_scrollbarsE"] #[link_name = "_ZN9nsGkAtoms18overlay_scrollbarsE"]
pub static nsGkAtoms_overlay_scrollbars: *mut nsIAtom; pub static nsGkAtoms_overlay_scrollbars: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms28windows_accent_color_appliesE"]
pub static nsGkAtoms_windows_accent_color_applies: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms21windows_default_themeE"] #[link_name = "_ZN9nsGkAtoms21windows_default_themeE"]
pub static nsGkAtoms_windows_default_theme: *mut nsIAtom; pub static nsGkAtoms_windows_default_theme: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms18mac_graphite_themeE"] #[link_name = "_ZN9nsGkAtoms18mac_graphite_themeE"]
@ -4384,6 +4386,8 @@ cfg_if! {
pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom; pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms23_moz_overlay_scrollbarsE"] #[link_name = "_ZN9nsGkAtoms23_moz_overlay_scrollbarsE"]
pub static nsGkAtoms__moz_overlay_scrollbars: *mut nsIAtom; pub static nsGkAtoms__moz_overlay_scrollbars: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms33_moz_windows_accent_color_appliesE"]
pub static nsGkAtoms__moz_windows_accent_color_applies: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms26_moz_windows_default_themeE"] #[link_name = "_ZN9nsGkAtoms26_moz_windows_default_themeE"]
pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom; pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom;
#[link_name = "_ZN9nsGkAtoms23_moz_mac_graphite_themeE"] #[link_name = "_ZN9nsGkAtoms23_moz_mac_graphite_themeE"]
@ -9455,6 +9459,8 @@ cfg_if! {
pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom; pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom;
#[link_name = "?overlay_scrollbars@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?overlay_scrollbars@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_overlay_scrollbars: *mut nsIAtom; pub static nsGkAtoms_overlay_scrollbars: *mut nsIAtom;
#[link_name = "?windows_accent_color_applies@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_windows_accent_color_applies: *mut nsIAtom;
#[link_name = "?windows_default_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?windows_default_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms_windows_default_theme: *mut nsIAtom; pub static nsGkAtoms_windows_default_theme: *mut nsIAtom;
#[link_name = "?mac_graphite_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?mac_graphite_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -9505,6 +9511,8 @@ cfg_if! {
pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom; pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom;
#[link_name = "?_moz_overlay_scrollbars@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?_moz_overlay_scrollbars@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms__moz_overlay_scrollbars: *mut nsIAtom; pub static nsGkAtoms__moz_overlay_scrollbars: *mut nsIAtom;
#[link_name = "?_moz_windows_accent_color_applies@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms__moz_windows_accent_color_applies: *mut nsIAtom;
#[link_name = "?_moz_windows_default_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?_moz_windows_default_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"]
pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom; pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom;
#[link_name = "?_moz_mac_graphite_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"] #[link_name = "?_moz_mac_graphite_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"]
@ -14576,6 +14584,8 @@ cfg_if! {
pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom; pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom;
#[link_name = "\x01?overlay_scrollbars@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?overlay_scrollbars@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_overlay_scrollbars: *mut nsIAtom; pub static nsGkAtoms_overlay_scrollbars: *mut nsIAtom;
#[link_name = "\x01?windows_accent_color_applies@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_windows_accent_color_applies: *mut nsIAtom;
#[link_name = "\x01?windows_default_theme@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?windows_default_theme@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms_windows_default_theme: *mut nsIAtom; pub static nsGkAtoms_windows_default_theme: *mut nsIAtom;
#[link_name = "\x01?mac_graphite_theme@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?mac_graphite_theme@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -14626,6 +14636,8 @@ cfg_if! {
pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom; pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom;
#[link_name = "\x01?_moz_overlay_scrollbars@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?_moz_overlay_scrollbars@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms__moz_overlay_scrollbars: *mut nsIAtom; pub static nsGkAtoms__moz_overlay_scrollbars: *mut nsIAtom;
#[link_name = "\x01?_moz_windows_accent_color_applies@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms__moz_windows_accent_color_applies: *mut nsIAtom;
#[link_name = "\x01?_moz_windows_default_theme@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?_moz_windows_default_theme@nsGkAtoms@@2PAVnsIAtom@@A"]
pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom; pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom;
#[link_name = "\x01?_moz_mac_graphite_theme@nsGkAtoms@@2PAVnsIAtom@@A"] #[link_name = "\x01?_moz_mac_graphite_theme@nsGkAtoms@@2PAVnsIAtom@@A"]
@ -19700,6 +19712,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_scrollbar_thumb_proportional as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_scrollbar_thumb_proportional as *mut _) } };
("overlay-scrollbars") => ("overlay-scrollbars") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_overlay_scrollbars as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_overlay_scrollbars as *mut _) } };
("windows-accent-color-applies") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_windows_accent_color_applies as *mut _) } };
("windows-default-theme") => ("windows-default-theme") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_windows_default_theme as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_windows_default_theme as *mut _) } };
("mac-graphite-theme") => ("mac-graphite-theme") =>
@ -19750,6 +19764,8 @@ macro_rules! atom {
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms__moz_scrollbar_thumb_proportional as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms__moz_scrollbar_thumb_proportional as *mut _) } };
("-moz-overlay-scrollbars") => ("-moz-overlay-scrollbars") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms__moz_overlay_scrollbars as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms__moz_overlay_scrollbars as *mut _) } };
("-moz-windows-accent-color-applies") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms__moz_windows_accent_color_applies as *mut _) } };
("-moz-windows-default-theme") => ("-moz-windows-default-theme") =>
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms__moz_windows_default_theme as *mut _) } }; { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms__moz_windows_default_theme as *mut _) } };
("-moz-mac-graphite-theme") => ("-moz-mac-graphite-theme") =>

View file

@ -24,6 +24,8 @@ use gecko_bindings::structs::RawGeckoFontFaceRuleList;
use gecko_bindings::structs::RawGeckoNode; use gecko_bindings::structs::RawGeckoNode;
use gecko_bindings::structs::RawServoAnimationValue; use gecko_bindings::structs::RawServoAnimationValue;
use gecko_bindings::structs::RawGeckoServoAnimationValueList; use gecko_bindings::structs::RawGeckoServoAnimationValueList;
use gecko_bindings::structs::RawServoMediaList;
use gecko_bindings::structs::RawServoStyleSheetContents;
use gecko_bindings::structs::RawServoDeclarationBlock; use gecko_bindings::structs::RawServoDeclarationBlock;
use gecko_bindings::structs::RawServoStyleRule; use gecko_bindings::structs::RawServoStyleRule;
use gecko_bindings::structs::RawGeckoPresContext; use gecko_bindings::structs::RawGeckoPresContext;
@ -305,11 +307,9 @@ pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
pub type ServoCssRulesBorrowedOrNull<'a> = Option<&'a ServoCssRules>; pub type ServoCssRulesBorrowedOrNull<'a> = Option<&'a ServoCssRules>;
enum ServoCssRulesVoid { } enum ServoCssRulesVoid { }
pub struct ServoCssRules(ServoCssRulesVoid); pub struct ServoCssRules(ServoCssRulesVoid);
pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>; pub type RawServoStyleSheetContentsStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheetContents>;
pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet; pub type RawServoStyleSheetContentsBorrowed<'a> = &'a RawServoStyleSheetContents;
pub type RawServoStyleSheetBorrowedOrNull<'a> = Option<&'a RawServoStyleSheet>; pub type RawServoStyleSheetContentsBorrowedOrNull<'a> = Option<&'a RawServoStyleSheetContents>;
enum RawServoStyleSheetVoid { }
pub struct RawServoStyleSheet(RawServoStyleSheetVoid);
pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>; pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>;
pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues; pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;
pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>; pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;
@ -342,8 +342,6 @@ pub struct RawServoKeyframesRule(RawServoKeyframesRuleVoid);
pub type RawServoMediaListStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaList>; pub type RawServoMediaListStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaList>;
pub type RawServoMediaListBorrowed<'a> = &'a RawServoMediaList; pub type RawServoMediaListBorrowed<'a> = &'a RawServoMediaList;
pub type RawServoMediaListBorrowedOrNull<'a> = Option<&'a RawServoMediaList>; pub type RawServoMediaListBorrowedOrNull<'a> = Option<&'a RawServoMediaList>;
enum RawServoMediaListVoid { }
pub struct RawServoMediaList(RawServoMediaListVoid);
pub type RawServoMediaRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaRule>; pub type RawServoMediaRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaRule>;
pub type RawServoMediaRuleBorrowed<'a> = &'a RawServoMediaRule; pub type RawServoMediaRuleBorrowed<'a> = &'a RawServoMediaRule;
pub type RawServoMediaRuleBorrowedOrNull<'a> = Option<&'a RawServoMediaRule>; pub type RawServoMediaRuleBorrowedOrNull<'a> = Option<&'a RawServoMediaRule>;
@ -390,10 +388,12 @@ extern "C" {
pub fn Servo_CssRules_Release(ptr: ServoCssRulesBorrowed); pub fn Servo_CssRules_Release(ptr: ServoCssRulesBorrowed);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_AddRef(ptr: RawServoStyleSheetBorrowed); pub fn Servo_StyleSheetContents_AddRef(ptr:
RawServoStyleSheetContentsBorrowed);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_Release(ptr: RawServoStyleSheetBorrowed); pub fn Servo_StyleSheetContents_Release(ptr:
RawServoStyleSheetContentsBorrowed);
} }
extern "C" { extern "C" {
pub fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed); pub fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed);
@ -544,10 +544,10 @@ extern "C" {
parent: *mut ServoStyleSheet, parent: *mut ServoStyleSheet,
reusable_sheets: reusable_sheets:
*mut LoaderReusableStyleSheets, *mut LoaderReusableStyleSheets,
child_sheet: RawServoStyleSheetBorrowed,
base_url_data: *mut RawGeckoURLExtraData, base_url_data: *mut RawGeckoURLExtraData,
url_bytes: *const u8, url_length: u32, url_bytes: *const u8, url_length: u32,
media_list: RawServoMediaListStrong); media_list: RawServoMediaListStrong)
-> *mut ServoStyleSheet;
} }
extern "C" { extern "C" {
pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u64; pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u64;
@ -1416,6 +1416,17 @@ extern "C" {
RawGeckoPresContextBorrowed) RawGeckoPresContextBorrowed)
-> i32; -> i32;
} }
extern "C" {
pub fn Gecko_StyleSheet_Clone(aSheet: *const ServoStyleSheet,
aNewParentSheet: *const ServoStyleSheet)
-> *mut ServoStyleSheet;
}
extern "C" {
pub fn Gecko_StyleSheet_AddRef(aSheet: *const ServoStyleSheet);
}
extern "C" {
pub fn Gecko_StyleSheet_Release(aSheet: *const ServoStyleSheet);
}
extern "C" { extern "C" {
pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature; pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature;
} }
@ -1813,53 +1824,41 @@ extern "C" {
extern "C" { extern "C" {
pub fn Servo_Element_ClearData(node: RawGeckoElementBorrowed); pub fn Servo_Element_ClearData(node: RawGeckoElementBorrowed);
} }
extern "C" {
pub fn Servo_StyleSheet_Empty(parsing_mode: SheetParsingMode)
-> RawServoStyleSheetStrong;
}
extern "C" { extern "C" {
pub fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader, pub fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
gecko_stylesheet: gecko_stylesheet:
*mut ServoStyleSheet, *mut ServoStyleSheet,
data: *const nsACString, data: *const nsACString,
parsing_mode: SheetParsingMode, parsing_mode: SheetParsingMode,
media_list:
*const RawServoMediaList,
extra_data: extra_data:
*mut RawGeckoURLExtraData, *mut RawGeckoURLExtraData,
line_number_offset: u32, line_number_offset: u32,
quirks_mode: nsCompatibility) quirks_mode: nsCompatibility)
-> RawServoStyleSheetStrong; -> RawServoStyleSheetContentsStrong;
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_ClearAndUpdate(stylesheet: pub fn Servo_StyleSheet_Empty(parsing_mode: SheetParsingMode)
RawServoStyleSheetBorrowed, -> RawServoStyleSheetContentsStrong;
loader: *mut Loader,
gecko_stylesheet:
*mut ServoStyleSheet,
data: *const nsACString,
extra_data:
*mut RawGeckoURLExtraData,
line_number_offset: u32,
reusable_sheets:
*mut LoaderReusableStyleSheets);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed) pub fn Servo_StyleSheet_HasRules(sheet:
RawServoStyleSheetContentsBorrowed)
-> bool; -> bool;
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) pub fn Servo_StyleSheet_GetRules(sheet:
RawServoStyleSheetContentsBorrowed)
-> ServoCssRulesStrong; -> ServoCssRulesStrong;
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_Clone(sheet: RawServoStyleSheetBorrowed) pub fn Servo_StyleSheet_Clone(sheet: RawServoStyleSheetContentsBorrowed,
-> RawServoStyleSheetStrong; reference_sheet: *const ServoStyleSheet)
-> RawServoStyleSheetContentsStrong;
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_SizeOfIncludingThis(malloc_size_of: MallocSizeOf, pub fn Servo_StyleSheet_SizeOfIncludingThis(malloc_size_of: MallocSizeOf,
sheet: sheet:
RawServoStyleSheetBorrowed) RawServoStyleSheetContentsBorrowed)
-> usize; -> usize;
} }
extern "C" { extern "C" {
@ -1882,30 +1881,26 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowed, pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowed,
sheet: RawServoStyleSheetBorrowed, gecko_sheet:
unique_id: u64); *const ServoStyleSheet);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowed, pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowed,
sheet: RawServoStyleSheetBorrowed, gecko_sheet:
unique_id: u64); *const ServoStyleSheet);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowed, pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowed,
unique_id: u64); gecko_sheet:
*const ServoStyleSheet);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSet_InsertStyleSheetBefore(set: pub fn Servo_StyleSet_InsertStyleSheetBefore(set:
RawServoStyleSetBorrowed, RawServoStyleSetBorrowed,
sheet: gecko_sheet:
RawServoStyleSheetBorrowed, *const ServoStyleSheet,
unique_id: u64, before:
before_unique_id: u64); *const ServoStyleSheet);
}
extern "C" {
pub fn Servo_StyleSet_UpdateStyleSheet(set: RawServoStyleSetBorrowed,
sheet: RawServoStyleSheetBorrowed,
unique_id: u64);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSet_FlushStyleSheets(set: RawServoStyleSetBorrowed, pub fn Servo_StyleSet_FlushStyleSheets(set: RawServoStyleSetBorrowed,
@ -1967,7 +1962,8 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
sheet: RawServoStyleSheetBorrowed, sheet:
RawServoStyleSheetContentsBorrowed,
rule: *const nsACString, index: u32, rule: *const nsACString, index: u32,
nested: bool, loader: *mut Loader, nested: bool, loader: *mut Loader,
gecko_stylesheet: *mut ServoStyleSheet, gecko_stylesheet: *mut ServoStyleSheet,
@ -2154,7 +2150,7 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed) pub fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed)
-> *const RawServoStyleSheet; -> *const ServoStyleSheet;
} }
extern "C" { extern "C" {
pub fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed, pub fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed,
@ -2197,7 +2193,8 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_KeyframesRule_AppendRule(rule: RawServoKeyframesRuleBorrowed, pub fn Servo_KeyframesRule_AppendRule(rule: RawServoKeyframesRuleBorrowed,
sheet: RawServoStyleSheetBorrowed, sheet:
RawServoStyleSheetContentsBorrowed,
css: *const nsACString) -> bool; css: *const nsACString) -> bool;
} }
extern "C" { extern "C" {
@ -2264,6 +2261,11 @@ extern "C" {
nsCSSPropertyID) nsCSSPropertyID)
-> RawServoAnimationValueStrong; -> RawServoAnimationValueStrong;
} }
extern "C" {
pub fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(computed_values:
ServoComputedValuesBorrowed)
-> bool;
}
extern "C" { extern "C" {
pub fn Servo_Property_IsAnimatable(property: nsCSSPropertyID) -> bool; pub fn Servo_Property_IsAnimatable(property: nsCSSPropertyID) -> bool;
} }
@ -2679,6 +2681,10 @@ extern "C" {
set: RawServoStyleSetBorrowed) set: RawServoStyleSetBorrowed)
-> ServoComputedValuesStrong; -> ServoComputedValuesStrong;
} }
extern "C" {
pub fn Servo_SetExplicitStyle(element: RawGeckoElementBorrowed,
primary_style: ServoComputedValuesBorrowed);
}
extern "C" { extern "C" {
pub fn Servo_HasAuthorSpecifiedRules(element: RawGeckoElementBorrowed, pub fn Servo_HasAuthorSpecifiedRules(element: RawGeckoElementBorrowed,
rule_type_mask: u32, rule_type_mask: u32,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,13 @@ use stylesheets::{NestedRuleIterationCondition, Stylesheet};
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct MediaListKey(usize); pub struct MediaListKey(usize);
impl MediaListKey {
/// Create a MediaListKey from a raw usize.
pub fn from_raw(k: usize) -> Self {
MediaListKey(k)
}
}
/// A trait to get a given `MediaListKey` for a given item that can hold a /// A trait to get a given `MediaListKey` for a given item that can hold a
/// `MediaList`. /// `MediaList`.
pub trait ToMediaListKey : Sized { pub trait ToMediaListKey : Sized {

View file

@ -15,7 +15,7 @@ use selector_parser::SelectorImpl;
use selectors::attr::CaseSensitivity; use selectors::attr::CaseSensitivity;
use selectors::parser::{Component, Selector}; use selectors::parser::{Component, Selector};
use shared_lock::SharedRwLockReadGuard; use shared_lock::SharedRwLockReadGuard;
use stylesheets::{CssRule, Stylesheet}; use stylesheets::{CssRule, StylesheetInDocument};
use stylist::Stylist; use stylist::Stylist;
/// An invalidation scope represents a kind of subtree that may need to be /// An invalidation scope represents a kind of subtree that may need to be
@ -80,11 +80,14 @@ impl StylesheetInvalidationSet {
/// Analyze the given stylesheet, and collect invalidations from their /// Analyze the given stylesheet, and collect invalidations from their
/// rules, in order to avoid doing a full restyle when we style the document /// rules, in order to avoid doing a full restyle when we style the document
/// next time. /// next time.
pub fn collect_invalidations_for( pub fn collect_invalidations_for<S>(
&mut self, &mut self,
stylist: &Stylist, stylist: &Stylist,
stylesheet: &Stylesheet, stylesheet: &S,
guard: &SharedRwLockReadGuard) guard: &SharedRwLockReadGuard
)
where
S: StylesheetInDocument,
{ {
debug!("StylesheetInvalidationSet::collect_invalidations_for"); debug!("StylesheetInvalidationSet::collect_invalidations_for");
if self.fully_invalid { if self.fully_invalid {
@ -92,7 +95,7 @@ impl StylesheetInvalidationSet {
return; return;
} }
if stylesheet.disabled() || if !stylesheet.enabled() ||
!stylesheet.is_effective_for_device(stylist.device(), guard) { !stylesheet.is_effective_for_device(stylist.device(), guard) {
debug!(" > Stylesheet was not effective"); debug!(" > Stylesheet was not effective");
return; // Nothing to do here. return; // Nothing to do here.

View file

@ -228,6 +228,18 @@ pub trait ToCssWithGuard {
} }
} }
/// Parameters needed for deep clones.
#[cfg(feature = "gecko")]
pub struct DeepCloneParams {
/// The new sheet we're cloning rules into.
pub reference_sheet: *const ::gecko_bindings::structs::ServoStyleSheet,
}
/// Parameters needed for deep clones.
#[cfg(feature = "servo")]
pub struct DeepCloneParams;
/// A trait to do a deep clone of a given CSS type. Gets a lock and a read /// A trait to do a deep clone of a given CSS type. Gets a lock and a read
/// guard, in order to be able to read and clone nested structures. /// guard, in order to be able to read and clone nested structures.
pub trait DeepCloneWithLock : Sized { pub trait DeepCloneWithLock : Sized {
@ -235,7 +247,8 @@ pub trait DeepCloneWithLock : Sized {
fn deep_clone_with_lock( fn deep_clone_with_lock(
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self; ) -> Self;
} }

View file

@ -8,36 +8,46 @@ use dom::TElement;
use invalidation::stylesheets::StylesheetInvalidationSet; use invalidation::stylesheets::StylesheetInvalidationSet;
use shared_lock::SharedRwLockReadGuard; use shared_lock::SharedRwLockReadGuard;
use std::slice; use std::slice;
use stylearc::Arc; use stylesheets::StylesheetInDocument;
use stylesheets::Stylesheet;
use stylist::Stylist; use stylist::Stylist;
/// Entry for a StylesheetSet. We don't bother creating a constructor, because /// Entry for a StylesheetSet. We don't bother creating a constructor, because
/// there's no sensible defaults for the member variables. /// there's no sensible defaults for the member variables.
pub struct StylesheetSetEntry { pub struct StylesheetSetEntry<S>
unique_id: u64, where
sheet: Arc<Stylesheet>, S: StylesheetInDocument + PartialEq + 'static,
{
sheet: S,
} }
/// A iterator over the stylesheets of a list of entries in the StylesheetSet. /// A iterator over the stylesheets of a list of entries in the StylesheetSet.
#[derive(Clone)] #[derive(Clone)]
pub struct StylesheetIterator<'a>(slice::Iter<'a, StylesheetSetEntry>); pub struct StylesheetIterator<'a, S>(slice::Iter<'a, StylesheetSetEntry<S>>)
where
S: StylesheetInDocument + PartialEq + 'static;
impl<'a, S> Iterator for StylesheetIterator<'a, S>
where
S: StylesheetInDocument + PartialEq + 'static,
{
type Item = &'a S;
impl<'a> Iterator for StylesheetIterator<'a> {
type Item = &'a Arc<Stylesheet>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|entry| &entry.sheet) self.0.next().map(|entry| &entry.sheet)
} }
} }
/// The set of stylesheets effective for a given document. /// The set of stylesheets effective for a given document.
pub struct StylesheetSet { pub struct StylesheetSet<S>
where
S: StylesheetInDocument + PartialEq + 'static,
{
/// The actual list of all the stylesheets that apply to the given document, /// The actual list of all the stylesheets that apply to the given document,
/// each stylesheet associated with a unique ID. /// each stylesheet associated with a unique ID.
/// ///
/// This is only a list of top-level stylesheets, and as such it doesn't /// This is only a list of top-level stylesheets, and as such it doesn't
/// include recursive `@import` rules. /// include recursive `@import` rules.
entries: Vec<StylesheetSetEntry>, entries: Vec<StylesheetSetEntry<S>>,
/// Whether the entries list above has changed since the last restyle. /// Whether the entries list above has changed since the last restyle.
dirty: bool, dirty: bool,
@ -49,7 +59,10 @@ pub struct StylesheetSet {
invalidations: StylesheetInvalidationSet, invalidations: StylesheetInvalidationSet,
} }
impl StylesheetSet { impl<S> StylesheetSet<S>
where
S: StylesheetInDocument + PartialEq + 'static,
{
/// Create a new empty StylesheetSet. /// Create a new empty StylesheetSet.
pub fn new() -> Self { pub fn new() -> Self {
StylesheetSet { StylesheetSet {
@ -66,98 +79,72 @@ impl StylesheetSet {
self.author_style_disabled self.author_style_disabled
} }
fn remove_stylesheet_if_present(&mut self, unique_id: u64) { fn remove_stylesheet_if_present(&mut self, sheet: &S) {
self.entries.retain(|x| x.unique_id != unique_id); self.entries.retain(|entry| entry.sheet != *sheet);
} }
/// Appends a new stylesheet to the current set. /// Appends a new stylesheet to the current set.
pub fn append_stylesheet( pub fn append_stylesheet(
&mut self, &mut self,
stylist: &Stylist, stylist: &Stylist,
sheet: &Arc<Stylesheet>, sheet: S,
unique_id: u64, guard: &SharedRwLockReadGuard
guard: &SharedRwLockReadGuard) ) {
{
debug!("StylesheetSet::append_stylesheet"); debug!("StylesheetSet::append_stylesheet");
self.remove_stylesheet_if_present(unique_id); self.remove_stylesheet_if_present(&sheet);
self.entries.push(StylesheetSetEntry {
unique_id: unique_id,
sheet: sheet.clone(),
});
self.dirty = true;
self.invalidations.collect_invalidations_for( self.invalidations.collect_invalidations_for(
stylist, stylist,
sheet, &sheet,
guard) guard
);
self.dirty = true;
self.entries.push(StylesheetSetEntry { sheet });
} }
/// Prepend a new stylesheet to the current set. /// Prepend a new stylesheet to the current set.
pub fn prepend_stylesheet( pub fn prepend_stylesheet(
&mut self, &mut self,
stylist: &Stylist, stylist: &Stylist,
sheet: &Arc<Stylesheet>, sheet: S,
unique_id: u64, guard: &SharedRwLockReadGuard
guard: &SharedRwLockReadGuard) ) {
{
debug!("StylesheetSet::prepend_stylesheet"); debug!("StylesheetSet::prepend_stylesheet");
self.remove_stylesheet_if_present(unique_id); self.remove_stylesheet_if_present(&sheet);
self.entries.insert(0, StylesheetSetEntry {
unique_id: unique_id,
sheet: sheet.clone(),
});
self.dirty = true;
self.invalidations.collect_invalidations_for( self.invalidations.collect_invalidations_for(
stylist, stylist,
sheet, &sheet,
guard) guard
);
self.entries.insert(0, StylesheetSetEntry { sheet });
self.dirty = true;
} }
/// Insert a given stylesheet before another stylesheet in the document. /// Insert a given stylesheet before another stylesheet in the document.
pub fn insert_stylesheet_before( pub fn insert_stylesheet_before(
&mut self, &mut self,
stylist: &Stylist, stylist: &Stylist,
sheet: &Arc<Stylesheet>, sheet: S,
unique_id: u64, before_sheet: S,
before_unique_id: u64,
guard: &SharedRwLockReadGuard) guard: &SharedRwLockReadGuard)
{ {
debug!("StylesheetSet::insert_stylesheet_before"); debug!("StylesheetSet::insert_stylesheet_before");
self.remove_stylesheet_if_present(unique_id); self.remove_stylesheet_if_present(&sheet);
let index = self.entries.iter().position(|x| { let index = self.entries.iter().position(|entry| {
x.unique_id == before_unique_id entry.sheet == before_sheet
}).expect("`before_unique_id` stylesheet not found"); }).expect("`before_sheet` stylesheet not found");
self.entries.insert(index, StylesheetSetEntry {
unique_id: unique_id,
sheet: sheet.clone(),
});
self.dirty = true;
self.invalidations.collect_invalidations_for( self.invalidations.collect_invalidations_for(
stylist, stylist,
sheet, &sheet,
guard) guard
} );
self.entries.insert(index, StylesheetSetEntry { sheet });
/// Update the sheet that matches the unique_id. self.dirty = true;
pub fn update_stylesheet(
&mut self,
sheet: &Arc<Stylesheet>,
unique_id: u64)
{
// Since this function doesn't set self.dirty, or call
// self.invalidations.collect_invalidations_for, it should
// only be called in the case where sheet is a clone of
// the sheet it is updating.
debug!("StylesheetSet::update_stylesheet");
if let Some(entry) = self.entries.iter_mut().find(
|e| e.unique_id == unique_id) {
entry.sheet = sheet.clone();
}
} }
/// Remove a given stylesheet from the set. /// Remove a given stylesheet from the set.
pub fn remove_stylesheet(&mut self, unique_id: u64) { pub fn remove_stylesheet(&mut self, sheet: S) {
debug!("StylesheetSet::remove_stylesheet"); debug!("StylesheetSet::remove_stylesheet");
self.remove_stylesheet_if_present(unique_id); self.remove_stylesheet_if_present(&sheet);
self.dirty = true; self.dirty = true;
// FIXME(emilio): We can do better! // FIXME(emilio): We can do better!
self.invalidations.invalidate_fully(); self.invalidations.invalidate_fully();
@ -181,10 +168,12 @@ impl StylesheetSet {
/// Flush the current set, unmarking it as dirty, and returns an iterator /// Flush the current set, unmarking it as dirty, and returns an iterator
/// over the new stylesheet list. /// over the new stylesheet list.
pub fn flush<E>(&mut self, pub fn flush<E>(
document_element: Option<E>) &mut self,
-> StylesheetIterator document_element: Option<E>
where E: TElement, ) -> StylesheetIterator<S>
where
E: TElement,
{ {
debug!("StylesheetSet::flush"); debug!("StylesheetSet::flush");
debug_assert!(self.dirty); debug_assert!(self.dirty);
@ -196,7 +185,7 @@ impl StylesheetSet {
} }
/// Returns an iterator over the current list of stylesheets. /// Returns an iterator over the current list of stylesheets.
pub fn iter(&self) -> StylesheetIterator { pub fn iter(&self) -> StylesheetIterator<S> {
StylesheetIterator(self.entries.iter()) StylesheetIterator(self.entries.iter())
} }

View file

@ -9,7 +9,7 @@
use cssparser::{Parser, Token, SourceLocation, BasicParseError}; use cssparser::{Parser, Token, SourceLocation, BasicParseError};
use media_queries::Device; use media_queries::Device;
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::{ToCss, ParseError, StyleParseError}; use style_traits::{ToCss, ParseError, StyleParseError};
use stylearc::Arc; use stylearc::Arc;
@ -47,11 +47,12 @@ impl DeepCloneWithLock for DocumentRule {
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self { ) -> Self {
let rules = self.rules.read_with(guard); let rules = self.rules.read_with(guard);
DocumentRule { DocumentRule {
condition: self.condition.clone(), condition: self.condition.clone(),
rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard))), rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard, params))),
source_location: self.source_location.clone(), source_location: self.source_location.clone(),
} }
} }

View file

@ -7,13 +7,72 @@
//! [import]: https://drafts.csswg.org/css-cascade-3/#at-import //! [import]: https://drafts.csswg.org/css-cascade-3/#at-import
use cssparser::SourceLocation; use cssparser::SourceLocation;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use media_queries::MediaList;
use shared_lock::{DeepCloneWithLock, DeepCloneParams, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use stylearc::Arc; use stylesheets::{StylesheetContents, StylesheetInDocument};
use stylesheets::stylesheet::Stylesheet;
use values::specified::url::SpecifiedUrl; use values::specified::url::SpecifiedUrl;
/// A sheet that is held from an import rule.
#[cfg(feature = "gecko")]
#[derive(Debug)]
pub struct ImportSheet(pub ::gecko::data::GeckoStyleSheet);
#[cfg(feature = "gecko")]
impl DeepCloneWithLock for ImportSheet {
fn deep_clone_with_lock(
&self,
_lock: &SharedRwLock,
_guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self {
use gecko::data::GeckoStyleSheet;
use gecko_bindings::bindings;
let clone = unsafe {
bindings::Gecko_StyleSheet_Clone(
self.0.raw() as *const _,
params.reference_sheet
)
};
ImportSheet(unsafe { GeckoStyleSheet::from_addrefed(clone) })
}
}
/// A sheet that is held from an import rule.
#[cfg(feature = "servo")]
#[derive(Debug)]
pub struct ImportSheet(pub ::stylearc::Arc<::stylesheets::Stylesheet>);
impl StylesheetInDocument for ImportSheet {
/// Get the media associated with this stylesheet.
fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList> {
self.0.media(guard)
}
fn contents(&self, guard: &SharedRwLockReadGuard) -> &StylesheetContents {
self.0.contents(guard)
}
fn enabled(&self) -> bool {
self.0.enabled()
}
}
#[cfg(feature = "servo")]
impl DeepCloneWithLock for ImportSheet {
fn deep_clone_with_lock(
&self,
_lock: &SharedRwLock,
_guard: &SharedRwLockReadGuard,
_params: &DeepCloneParams,
) -> Self {
use stylearc::Arc;
ImportSheet(Arc::new((&*self.0).clone()))
}
}
/// The [`@import`][import] at-rule. /// The [`@import`][import] at-rule.
/// ///
/// [import]: https://drafts.csswg.org/css-cascade-3/#at-import /// [import]: https://drafts.csswg.org/css-cascade-3/#at-import
@ -26,18 +85,22 @@ pub struct ImportRule {
/// ///
/// It contains an empty list of rules and namespace set that is updated /// It contains an empty list of rules and namespace set that is updated
/// when it loads. /// when it loads.
pub stylesheet: Arc<Stylesheet>, pub stylesheet: ImportSheet,
/// The line and column of the rule's source code. /// The line and column of the rule's source code.
pub source_location: SourceLocation, pub source_location: SourceLocation,
} }
impl Clone for ImportRule { impl DeepCloneWithLock for ImportRule {
fn clone(&self) -> ImportRule { fn deep_clone_with_lock(
let stylesheet: &Stylesheet = &*self.stylesheet; &self,
lock: &SharedRwLock,
guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self {
ImportRule { ImportRule {
url: self.url.clone(), url: self.url.clone(),
stylesheet: Arc::new(stylesheet.clone()), stylesheet: self.stylesheet.deep_clone_with_lock(lock, guard, params),
source_location: self.source_location.clone(), source_location: self.source_location.clone(),
} }
} }
@ -49,11 +112,15 @@ impl ToCssWithGuard for ImportRule {
{ {
dest.write_str("@import ")?; dest.write_str("@import ")?;
self.url.to_css(dest)?; self.url.to_css(dest)?;
let media = self.stylesheet.media.read_with(guard);
if !media.is_empty() { match self.stylesheet.media(guard) {
dest.write_str(" ")?; Some(media) if !media.is_empty() => {
media.to_css(dest)?; dest.write_str(" ")?;
} media.to_css(dest)?;
}
_ => {},
};
dest.write_str(";") dest.write_str(";")
} }
} }

View file

@ -14,11 +14,11 @@ use properties::LonghandIdSet;
use properties::animated_properties::AnimatableLonghand; use properties::animated_properties::AnimatableLonghand;
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
use shared_lock::{DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError}; use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError};
use stylearc::Arc; use stylearc::Arc;
use stylesheets::{CssRuleType, Stylesheet}; use stylesheets::{CssRuleType, StylesheetContents};
use stylesheets::rule_parser::VendorPrefix; use stylesheets::rule_parser::VendorPrefix;
use values::KeyframesName; use values::KeyframesName;
@ -78,13 +78,17 @@ impl DeepCloneWithLock for KeyframesRule {
fn deep_clone_with_lock( fn deep_clone_with_lock(
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self { ) -> Self {
KeyframesRule { KeyframesRule {
name: self.name.clone(), name: self.name.clone(),
keyframes: self.keyframes.iter() keyframes: self.keyframes.iter()
.map(|ref x| Arc::new(lock.wrap( .map(|x| {
x.read_with(guard).deep_clone_with_lock(lock, guard)))) Arc::new(lock.wrap(
x.read_with(guard).deep_clone_with_lock(lock, guard, params)
))
})
.collect(), .collect(),
vendor_prefix: self.vendor_prefix.clone(), vendor_prefix: self.vendor_prefix.clone(),
source_location: self.source_location.clone(), source_location: self.source_location.clone(),
@ -202,23 +206,26 @@ impl ToCssWithGuard for Keyframe {
impl Keyframe { impl Keyframe {
/// Parse a CSS keyframe. /// Parse a CSS keyframe.
pub fn parse<'i>(css: &'i str, parent_stylesheet: &Stylesheet) pub fn parse<'i>(
-> Result<Arc<Locked<Self>>, ParseError<'i>> { css: &'i str,
let url_data = parent_stylesheet.url_data.read(); parent_stylesheet_contents: &StylesheetContents,
lock: &SharedRwLock,
) -> Result<Arc<Locked<Self>>, ParseError<'i>> {
let url_data = parent_stylesheet_contents.url_data.read();
let error_reporter = NullReporter; let error_reporter = NullReporter;
let context = ParserContext::new(parent_stylesheet.origin, let context = ParserContext::new(parent_stylesheet_contents.origin,
&url_data, &url_data,
&error_reporter, &error_reporter,
Some(CssRuleType::Keyframe), Some(CssRuleType::Keyframe),
PARSING_MODE_DEFAULT, PARSING_MODE_DEFAULT,
parent_stylesheet.quirks_mode); parent_stylesheet_contents.quirks_mode);
let mut input = ParserInput::new(css); let mut input = ParserInput::new(css);
let mut input = Parser::new(&mut input); let mut input = Parser::new(&mut input);
let mut declarations = SourcePropertyDeclaration::new(); let mut declarations = SourcePropertyDeclaration::new();
let mut rule_parser = KeyframeListParser { let mut rule_parser = KeyframeListParser {
context: &context, context: &context,
shared_lock: &parent_stylesheet.shared_lock, shared_lock: &lock,
declarations: &mut declarations, declarations: &mut declarations,
}; };
parse_one_rule(&mut input, &mut rule_parser) parse_one_rule(&mut input, &mut rule_parser)
@ -230,7 +237,8 @@ impl DeepCloneWithLock for Keyframe {
fn deep_clone_with_lock( fn deep_clone_with_lock(
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard guard: &SharedRwLockReadGuard,
_params: &DeepCloneParams,
) -> Keyframe { ) -> Keyframe {
Keyframe { Keyframe {
selector: self.selector.clone(), selector: self.selector.clone(),

View file

@ -5,39 +5,25 @@
//! The stylesheet loader is the abstraction used to trigger network requests //! The stylesheet loader is the abstraction used to trigger network requests
//! for `@import` rules. //! for `@import` rules.
use cssparser::SourceLocation;
use media_queries::MediaList; use media_queries::MediaList;
use shared_lock::Locked; use parser::ParserContext;
use shared_lock::{Locked, SharedRwLock};
use stylearc::Arc; use stylearc::Arc;
use stylesheets::ImportRule; use stylesheets::import_rule::ImportRule;
use values::specified::url::SpecifiedUrl;
/// The stylesheet loader is the abstraction used to trigger network requests /// The stylesheet loader is the abstraction used to trigger network requests
/// for `@import` rules. /// for `@import` rules.
pub trait StylesheetLoader { pub trait StylesheetLoader {
/// Request a stylesheet after parsing a given `@import` rule. /// Request a stylesheet after parsing a given `@import` rule, and return
/// /// the constructed `@import` rule.
/// The called code is responsible to update the `stylesheet` rules field
/// when the sheet is done loading.
///
/// The convoluted signature allows impls to look at MediaList and
/// ImportRule before theyre locked, while keeping the trait object-safe.
fn request_stylesheet( fn request_stylesheet(
&self, &self,
url: SpecifiedUrl,
location: SourceLocation,
context: &ParserContext,
lock: &SharedRwLock,
media: Arc<Locked<MediaList>>, media: Arc<Locked<MediaList>>,
make_import: &mut FnMut(Arc<Locked<MediaList>>) -> ImportRule,
make_arc: &mut FnMut(ImportRule) -> Arc<Locked<ImportRule>>,
) -> Arc<Locked<ImportRule>>; ) -> Arc<Locked<ImportRule>>;
} }
/// A dummy loader that just creates the import rule with the empty stylesheet.
pub struct NoOpLoader;
impl StylesheetLoader for NoOpLoader {
fn request_stylesheet(
&self,
media: Arc<Locked<MediaList>>,
make_import: &mut FnMut(Arc<Locked<MediaList>>) -> ImportRule,
make_arc: &mut FnMut(ImportRule) -> Arc<Locked<ImportRule>>,
) -> Arc<Locked<ImportRule>> {
make_arc(make_import(media))
}
}

View file

@ -8,7 +8,7 @@
use cssparser::SourceLocation; use cssparser::SourceLocation;
use media_queries::MediaList; use media_queries::MediaList;
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use stylearc::Arc; use stylearc::Arc;
@ -47,13 +47,14 @@ impl DeepCloneWithLock for MediaRule {
fn deep_clone_with_lock( fn deep_clone_with_lock(
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self { ) -> Self {
let media_queries = self.media_queries.read_with(guard); let media_queries = self.media_queries.read_with(guard);
let rules = self.rules.read_with(guard); let rules = self.rules.read_with(guard);
MediaRule { MediaRule {
media_queries: Arc::new(lock.wrap(media_queries.clone())), media_queries: Arc::new(lock.wrap(media_queries.clone())),
rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard))), rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard, params))),
source_location: self.source_location.clone(), source_location: self.source_location.clone(),
} }
} }

View file

@ -7,7 +7,7 @@
mod counter_style_rule; mod counter_style_rule;
mod document_rule; mod document_rule;
mod font_face_rule; mod font_face_rule;
mod import_rule; pub mod import_rule;
pub mod keyframes_rule; pub mod keyframes_rule;
mod loader; mod loader;
mod media_rule; mod media_rule;
@ -25,7 +25,7 @@ pub mod viewport_rule;
use cssparser::{parse_one_rule, Parser, ParserInput}; use cssparser::{parse_one_rule, Parser, ParserInput};
use error_reporting::NullReporter; use error_reporting::NullReporter;
use parser::ParserContext; use parser::ParserContext;
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::PARSING_MODE_DEFAULT; use style_traits::PARSING_MODE_DEFAULT;
use stylearc::Arc; use stylearc::Arc;
@ -43,7 +43,7 @@ pub use self::page_rule::PageRule;
pub use self::rule_parser::{State, TopLevelRuleParser}; pub use self::rule_parser::{State, TopLevelRuleParser};
pub use self::rule_list::{CssRules, CssRulesHelpers}; pub use self::rule_list::{CssRules, CssRulesHelpers};
pub use self::rules_iterator::{AllRules, EffectiveRules, NestedRuleIterationCondition, RulesIterator}; pub use self::rules_iterator::{AllRules, EffectiveRules, NestedRuleIterationCondition, RulesIterator};
pub use self::stylesheet::{Namespaces, Stylesheet, UserAgentStylesheets}; pub use self::stylesheet::{Namespaces, Stylesheet, StylesheetContents, StylesheetInDocument, UserAgentStylesheets};
pub use self::style_rule::StyleRule; pub use self::style_rule::StyleRule;
pub use self::supports_rule::SupportsRule; pub use self::supports_rule::SupportsRule;
pub use self::viewport_rule::ViewportRule; pub use self::viewport_rule::ViewportRule;
@ -221,32 +221,33 @@ impl CssRule {
/// Input state is None for a nested rule /// Input state is None for a nested rule
pub fn parse( pub fn parse(
css: &str, css: &str,
parent_stylesheet: &Stylesheet, parent_stylesheet_contents: &StylesheetContents,
shared_lock: &SharedRwLock,
state: Option<State>, state: Option<State>,
loader: Option<&StylesheetLoader> loader: Option<&StylesheetLoader>
) -> Result<(Self, State), SingleRuleParseError> { ) -> Result<(Self, State), SingleRuleParseError> {
let url_data = parent_stylesheet.url_data.read(); let url_data = parent_stylesheet_contents.url_data.read();
let error_reporter = NullReporter; let error_reporter = NullReporter;
let context = ParserContext::new( let context = ParserContext::new(
parent_stylesheet.origin, parent_stylesheet_contents.origin,
&url_data, &url_data,
&error_reporter, &error_reporter,
None, None,
PARSING_MODE_DEFAULT, PARSING_MODE_DEFAULT,
parent_stylesheet.quirks_mode parent_stylesheet_contents.quirks_mode,
); );
let mut input = ParserInput::new(css); let mut input = ParserInput::new(css);
let mut input = Parser::new(&mut input); let mut input = Parser::new(&mut input);
let mut guard = parent_stylesheet.namespaces.write(); let mut guard = parent_stylesheet_contents.namespaces.write();
// nested rules are in the body state // nested rules are in the body state
let state = state.unwrap_or(State::Body); let state = state.unwrap_or(State::Body);
let mut rule_parser = TopLevelRuleParser { let mut rule_parser = TopLevelRuleParser {
stylesheet_origin: parent_stylesheet.origin, stylesheet_origin: parent_stylesheet_contents.origin,
context: context, context: context,
shared_lock: &parent_stylesheet.shared_lock, shared_lock: &shared_lock,
loader: loader, loader: loader,
state: state, state: state,
namespaces: Some(&mut *guard), namespaces: Some(&mut *guard),
@ -270,6 +271,7 @@ impl DeepCloneWithLock for CssRule {
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> CssRule { ) -> CssRule {
match *self { match *self {
CssRule::Namespace(ref arc) => { CssRule::Namespace(ref arc) => {
@ -277,18 +279,19 @@ impl DeepCloneWithLock for CssRule {
CssRule::Namespace(Arc::new(lock.wrap(rule.clone()))) CssRule::Namespace(Arc::new(lock.wrap(rule.clone())))
}, },
CssRule::Import(ref arc) => { CssRule::Import(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard)
CssRule::Import(Arc::new(lock.wrap(rule.clone()))) .deep_clone_with_lock(lock, guard, params);
CssRule::Import(Arc::new(lock.wrap(rule)))
}, },
CssRule::Style(ref arc) => { CssRule::Style(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard);
CssRule::Style(Arc::new( CssRule::Style(Arc::new(
lock.wrap(rule.deep_clone_with_lock(lock, guard)))) lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
}, },
CssRule::Media(ref arc) => { CssRule::Media(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard);
CssRule::Media(Arc::new( CssRule::Media(Arc::new(
lock.wrap(rule.deep_clone_with_lock(lock, guard)))) lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
}, },
CssRule::FontFace(ref arc) => { CssRule::FontFace(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard);
@ -307,22 +310,22 @@ impl DeepCloneWithLock for CssRule {
CssRule::Keyframes(ref arc) => { CssRule::Keyframes(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard);
CssRule::Keyframes(Arc::new( CssRule::Keyframes(Arc::new(
lock.wrap(rule.deep_clone_with_lock(lock, guard)))) lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
}, },
CssRule::Supports(ref arc) => { CssRule::Supports(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard);
CssRule::Supports(Arc::new( CssRule::Supports(Arc::new(
lock.wrap(rule.deep_clone_with_lock(lock, guard)))) lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
}, },
CssRule::Page(ref arc) => { CssRule::Page(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard);
CssRule::Page(Arc::new( CssRule::Page(Arc::new(
lock.wrap(rule.deep_clone_with_lock(lock, guard)))) lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
}, },
CssRule::Document(ref arc) => { CssRule::Document(ref arc) => {
let rule = arc.read_with(guard); let rule = arc.read_with(guard);
CssRule::Document(Arc::new( CssRule::Document(Arc::new(
lock.wrap(rule.deep_clone_with_lock(lock, guard)))) lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
}, },
} }
} }

View file

@ -8,7 +8,7 @@
use cssparser::SourceLocation; use cssparser::SourceLocation;
use properties::PropertyDeclarationBlock; use properties::PropertyDeclarationBlock;
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use stylearc::Arc; use stylearc::Arc;
@ -51,6 +51,7 @@ impl DeepCloneWithLock for PageRule {
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
_params: &DeepCloneParams,
) -> Self { ) -> Self {
PageRule { PageRule {
block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())), block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())),

View file

@ -4,13 +4,13 @@
//! A list of CSS rules. //! A list of CSS rules.
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
use stylearc::Arc; use stylearc::Arc;
use stylesheets::{CssRule, RulesMutateError}; use stylesheets::{CssRule, RulesMutateError};
use stylesheets::loader::StylesheetLoader; use stylesheets::loader::StylesheetLoader;
use stylesheets::memory::{MallocSizeOfFn, MallocSizeOfWithGuard}; use stylesheets::memory::{MallocSizeOfFn, MallocSizeOfWithGuard};
use stylesheets::rule_parser::State; use stylesheets::rule_parser::State;
use stylesheets::stylesheet::Stylesheet; use stylesheets::stylesheet::StylesheetContents;
/// A list of CSS rules. /// A list of CSS rules.
#[derive(Debug)] #[derive(Debug)]
@ -27,11 +27,12 @@ impl DeepCloneWithLock for CssRules {
fn deep_clone_with_lock( fn deep_clone_with_lock(
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self { ) -> Self {
CssRules( CssRules(self.0.iter().map(|x| {
self.0.iter().map(|ref x| x.deep_clone_with_lock(lock, guard)).collect() x.deep_clone_with_lock(lock, guard, params)
) }).collect())
} }
} }
@ -101,7 +102,7 @@ pub trait CssRulesHelpers {
fn insert_rule(&self, fn insert_rule(&self,
lock: &SharedRwLock, lock: &SharedRwLock,
rule: &str, rule: &str,
parent_stylesheet: &Stylesheet, parent_stylesheet_contents: &StylesheetContents,
index: usize, index: usize,
nested: bool, nested: bool,
loader: Option<&StylesheetLoader>) loader: Option<&StylesheetLoader>)
@ -112,7 +113,7 @@ impl CssRulesHelpers for Arc<Locked<CssRules>> {
fn insert_rule(&self, fn insert_rule(&self,
lock: &SharedRwLock, lock: &SharedRwLock,
rule: &str, rule: &str,
parent_stylesheet: &Stylesheet, parent_stylesheet_contents: &StylesheetContents,
index: usize, index: usize,
nested: bool, nested: bool,
loader: Option<&StylesheetLoader>) loader: Option<&StylesheetLoader>)
@ -139,7 +140,13 @@ impl CssRulesHelpers for Arc<Locked<CssRules>> {
// Step 3, 4 // Step 3, 4
// XXXManishearth should we also store the namespace map? // XXXManishearth should we also store the namespace map?
let (new_rule, new_state) = let (new_rule, new_state) =
CssRule::parse(&rule, parent_stylesheet, state, loader)?; CssRule::parse(
&rule,
parent_stylesheet_contents,
lock,
state,
loader
)?;
{ {
let mut write_guard = lock.write(); let mut write_guard = lock.write();

View file

@ -11,7 +11,6 @@ use cssparser::{CompactCowStr, SourceLocation};
use error_reporting::ContextualParseError; use error_reporting::ContextualParseError;
use font_face::parse_font_face_block; use font_face::parse_font_face_block;
use media_queries::{parse_media_query_list, MediaList}; use media_queries::{parse_media_query_list, MediaList};
use parking_lot::RwLock;
use parser::{Parse, ParserContext, log_css_error}; use parser::{Parse, ParserContext, log_css_error};
use properties::parse_property_declaration_list; use properties::parse_property_declaration_list;
use selector_parser::{SelectorImpl, SelectorParser}; use selector_parser::{SelectorImpl, SelectorParser};
@ -19,17 +18,15 @@ use selectors::SelectorList;
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
use shared_lock::{Locked, SharedRwLock}; use shared_lock::{Locked, SharedRwLock};
use std::borrow::Cow; use std::borrow::Cow;
use std::sync::atomic::AtomicBool;
use str::starts_with_ignore_ascii_case; use str::starts_with_ignore_ascii_case;
use style_traits::{StyleParseError, ParseError}; use style_traits::{StyleParseError, ParseError};
use stylearc::Arc; use stylearc::Arc;
use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader}; use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader};
use stylesheets::{DocumentRule, ImportRule, KeyframesRule, MediaRule, NamespaceRule, PageRule}; use stylesheets::{DocumentRule, KeyframesRule, MediaRule, NamespaceRule, PageRule};
use stylesheets::{StyleRule, SupportsRule, ViewportRule}; use stylesheets::{StyleRule, SupportsRule, ViewportRule};
use stylesheets::document_rule::DocumentCondition; use stylesheets::document_rule::DocumentCondition;
use stylesheets::keyframes_rule::parse_keyframe_list; use stylesheets::keyframes_rule::parse_keyframe_list;
use stylesheets::loader::NoOpLoader; use stylesheets::stylesheet::Namespaces;
use stylesheets::stylesheet::{Namespaces, Stylesheet};
use stylesheets::supports_rule::SupportsCondition; use stylesheets::supports_rule::SupportsCondition;
use stylesheets::viewport_rule; use stylesheets::viewport_rule;
use values::CustomIdent; use values::CustomIdent;
@ -165,35 +162,18 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
let media = parse_media_query_list(&self.context, input); let media = parse_media_query_list(&self.context, input);
let media = Arc::new(self.shared_lock.wrap(media)); let media = Arc::new(self.shared_lock.wrap(media));
let noop_loader = NoOpLoader; let loader =
let loader = if !specified_url.is_invalid() { self.loader.expect("Expected a stylesheet loader for @import");
self.loader.expect("Expected a stylesheet loader for @import")
} else {
&noop_loader
};
let mut specified_url = Some(specified_url); let import_rule = loader.request_stylesheet(
let arc = loader.request_stylesheet(media, &mut |media| { specified_url,
ImportRule { location,
url: specified_url.take().unwrap(), &self.context,
stylesheet: Arc::new(Stylesheet { &self.shared_lock,
rules: CssRules::new(Vec::new(), self.shared_lock), media,
media: media, );
shared_lock: self.shared_lock.clone(),
origin: self.context.stylesheet_origin,
url_data: RwLock::new(self.context.url_data.clone()),
namespaces: RwLock::new(Namespaces::default()),
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),
quirks_mode: self.context.quirks_mode,
}),
source_location: location,
}
}, &mut |import_rule| {
Arc::new(self.shared_lock.wrap(import_rule))
});
return Ok(AtRuleType::WithoutBlock(CssRule::Import(arc))) return Ok(AtRuleType::WithoutBlock(CssRule::Import(import_rule)))
}, },
"namespace" => { "namespace" => {
if self.state > State::Namespaces { if self.state > State::Namespaces {

View file

@ -10,6 +10,7 @@ use shared_lock::SharedRwLockReadGuard;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::slice; use std::slice;
use stylesheets::{CssRule, CssRules, DocumentRule, ImportRule, MediaRule, SupportsRule}; use stylesheets::{CssRule, CssRules, DocumentRule, ImportRule, MediaRule, SupportsRule};
use stylesheets::StylesheetInDocument;
/// An iterator over a list of rules. /// An iterator over a list of rules.
pub struct RulesIterator<'a, 'b, C> pub struct RulesIterator<'a, 'b, C>
@ -96,7 +97,9 @@ impl<'a, 'b, C> Iterator for RulesIterator<'a, 'b, C>
import_rule) { import_rule) {
continue; continue;
} }
import_rule.stylesheet.rules.read_with(self.guard).0.iter() import_rule
.stylesheet.contents(self.guard).rules
.read_with(self.guard).0.iter()
} }
CssRule::Document(ref doc_rule) => { CssRule::Document(ref doc_rule) => {
let doc_rule = doc_rule.read_with(self.guard); let doc_rule = doc_rule.read_with(self.guard);
@ -182,11 +185,11 @@ impl NestedRuleIterationCondition for EffectiveRules {
fn process_import( fn process_import(
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
device: &Device, device: &Device,
quirks_mode: QuirksMode, _quirks_mode: QuirksMode,
rule: &ImportRule) rule: &ImportRule)
-> bool -> bool
{ {
rule.stylesheet.media.read_with(guard).evaluate(device, quirks_mode) rule.stylesheet.is_effective_for_device(device, guard)
} }
fn process_media( fn process_media(

View file

@ -8,7 +8,7 @@ use cssparser::SourceLocation;
use properties::PropertyDeclarationBlock; use properties::PropertyDeclarationBlock;
use selector_parser::SelectorImpl; use selector_parser::SelectorImpl;
use selectors::SelectorList; use selectors::SelectorList;
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use stylearc::Arc; use stylearc::Arc;
@ -31,6 +31,7 @@ impl DeepCloneWithLock for StyleRule {
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
_params: &DeepCloneParams,
) -> StyleRule { ) -> StyleRule {
StyleRule { StyleRule {
selectors: self.selectors.clone(), selectors: self.selectors.clone(),

View file

@ -10,7 +10,7 @@ use fnv::FnvHashMap;
use media_queries::{MediaList, Device}; use media_queries::{MediaList, Device};
use parking_lot::RwLock; use parking_lot::RwLock;
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
use std::mem; use std::mem;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use style_traits::PARSING_MODE_DEFAULT; use style_traits::PARSING_MODE_DEFAULT;
@ -42,28 +42,232 @@ pub struct Namespaces {
pub prefixes: FnvHashMap<Prefix, (Namespace, NamespaceId)>, pub prefixes: FnvHashMap<Prefix, (Namespace, NamespaceId)>,
} }
/// The structure servo uses to represent a stylesheet. /// The contents of a given stylesheet. This effectively maps to a
/// StyleSheetInner in Gecko.
#[derive(Debug)] #[derive(Debug)]
pub struct Stylesheet { pub struct StylesheetContents {
/// List of rules in the order they were found (important for /// List of rules in the order they were found (important for
/// cascading order) /// cascading order)
pub rules: Arc<Locked<CssRules>>, pub rules: Arc<Locked<CssRules>>,
/// List of media associated with the Stylesheet.
pub media: Arc<Locked<MediaList>>,
/// The origin of this stylesheet. /// The origin of this stylesheet.
pub origin: Origin, pub origin: Origin,
/// The url data this stylesheet should use. /// The url data this stylesheet should use.
pub url_data: RwLock<UrlExtraData>, pub url_data: RwLock<UrlExtraData>,
/// The lock used for objects inside this stylesheet
pub shared_lock: SharedRwLock,
/// The namespaces that apply to this stylesheet. /// The namespaces that apply to this stylesheet.
pub namespaces: RwLock<Namespaces>, pub namespaces: RwLock<Namespaces>,
/// Whether this stylesheet would be dirty when the viewport size changes.
pub dirty_on_viewport_size_change: AtomicBool,
/// Whether this stylesheet should be disabled.
pub disabled: AtomicBool,
/// The quirks mode of this stylesheet. /// The quirks mode of this stylesheet.
pub quirks_mode: QuirksMode, pub quirks_mode: QuirksMode,
/// Whether this stylesheet would be dirty when the viewport size changes.
pub dirty_on_viewport_size_change: AtomicBool,
}
impl StylesheetContents {
/// Parse a given CSS string, with a given url-data, origin, and
/// quirks mode.
pub fn from_str(
css: &str,
url_data: UrlExtraData,
origin: Origin,
shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
quirks_mode: QuirksMode,
line_number_offset: u64
) -> Self {
let namespaces = RwLock::new(Namespaces::default());
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css,
&url_data,
origin,
&mut *namespaces.write(),
&shared_lock,
stylesheet_loader,
error_reporter,
quirks_mode,
line_number_offset,
);
Self {
rules: CssRules::new(rules, &shared_lock),
origin: origin,
url_data: RwLock::new(url_data),
namespaces: namespaces,
dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change),
quirks_mode: quirks_mode,
}
}
/// Return an iterator using the condition `C`.
#[inline]
pub fn iter_rules<'a, 'b, C>(
&'a self,
device: &'a Device,
guard: &'a SharedRwLockReadGuard<'b>
) -> RulesIterator<'a, 'b, C>
where
C: NestedRuleIterationCondition,
{
RulesIterator::new(
device,
self.quirks_mode,
guard,
&self.rules.read_with(guard)
)
}
}
impl DeepCloneWithLock for StylesheetContents {
fn deep_clone_with_lock(
&self,
lock: &SharedRwLock,
guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self {
// Make a deep clone of the rules, using the new lock.
let rules =
self.rules.read_with(guard)
.deep_clone_with_lock(lock, guard, params);
let dirty_on_viewport_size_change =
AtomicBool::new(self.dirty_on_viewport_size_change.load(Ordering::Relaxed));
Self {
rules: Arc::new(lock.wrap(rules)),
dirty_on_viewport_size_change,
quirks_mode: self.quirks_mode,
origin: self.origin,
url_data: RwLock::new((*self.url_data.read()).clone()),
namespaces: RwLock::new((*self.namespaces.read()).clone()),
}
}
}
impl MallocSizeOfWithGuard for StylesheetContents {
fn malloc_size_of_children(
&self,
guard: &SharedRwLockReadGuard,
malloc_size_of: MallocSizeOfFn
) -> usize {
// Measurement of other fields may be added later.
self.rules.read_with(guard).malloc_size_of_children(guard, malloc_size_of)
}
}
/// The structure servo uses to represent a stylesheet.
#[derive(Debug)]
pub struct Stylesheet {
/// The contents of this stylesheet.
pub contents: StylesheetContents,
/// The lock used for objects inside this stylesheet
pub shared_lock: SharedRwLock,
/// List of media associated with the Stylesheet.
pub media: Arc<Locked<MediaList>>,
/// Whether this stylesheet should be disabled.
pub disabled: AtomicBool,
}
macro_rules! rule_filter {
($( $method: ident($variant:ident => $rule_type: ident), )+) => {
$(
#[allow(missing_docs)]
fn $method<F>(&self, device: &Device, guard: &SharedRwLockReadGuard, mut f: F)
where F: FnMut(&::stylesheets::$rule_type),
{
use stylesheets::CssRule;
for rule in self.effective_rules(device, guard) {
if let CssRule::$variant(ref lock) = *rule {
let rule = lock.read_with(guard);
f(&rule)
}
}
}
)+
}
}
/// A trait to represent a given stylesheet in a document.
pub trait StylesheetInDocument {
/// Get the contents of this stylesheet.
fn contents(&self, guard: &SharedRwLockReadGuard) -> &StylesheetContents;
/// Get the stylesheet origin.
fn origin(&self, guard: &SharedRwLockReadGuard) -> Origin {
self.contents(guard).origin
}
/// Get the stylesheet quirks mode.
fn quirks_mode(&self, guard: &SharedRwLockReadGuard) -> QuirksMode {
self.contents(guard).quirks_mode
}
/// Get the media associated with this stylesheet.
fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList>;
/// Returns whether the style-sheet applies for the current device.
fn is_effective_for_device(
&self,
device: &Device,
guard: &SharedRwLockReadGuard
) -> bool {
match self.media(guard) {
Some(medialist) => medialist.evaluate(device, self.quirks_mode(guard)),
None => true,
}
}
/// Get whether this stylesheet is enabled.
fn enabled(&self) -> bool;
/// Return an iterator using the condition `C`.
#[inline]
fn iter_rules<'a, 'b, C>(
&'a self,
device: &'a Device,
guard: &'a SharedRwLockReadGuard<'b>
) -> RulesIterator<'a, 'b, C>
where
C: NestedRuleIterationCondition,
{
self.contents(guard).iter_rules(device, guard)
}
/// Return an iterator over the effective rules within the style-sheet, as
/// according to the supplied `Device`.
#[inline]
fn effective_rules<'a, 'b>(
&'a self,
device: &'a Device,
guard: &'a SharedRwLockReadGuard<'b>
) -> EffectiveRulesIterator<'a, 'b> {
self.iter_rules::<'a, 'b, EffectiveRules>(device, guard)
}
rule_filter! {
effective_style_rules(Style => StyleRule),
effective_media_rules(Media => MediaRule),
effective_font_face_rules(FontFace => FontFaceRule),
effective_counter_style_rules(CounterStyle => CounterStyleRule),
effective_viewport_rules(Viewport => ViewportRule),
effective_keyframes_rules(Keyframes => KeyframesRule),
effective_supports_rules(Supports => SupportsRule),
effective_page_rules(Page => PageRule),
effective_document_rules(Document => DocumentRule),
}
}
impl StylesheetInDocument for Stylesheet {
fn contents(&self, _: &SharedRwLockReadGuard) -> &StylesheetContents {
&self.contents
}
fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList> {
Some(self.media.read_with(guard))
}
fn enabled(&self) -> bool {
!self.disabled()
}
} }
impl Stylesheet { impl Stylesheet {
@ -79,23 +283,26 @@ impl Stylesheet {
Stylesheet::parse_rules( Stylesheet::parse_rules(
css, css,
&url_data, &url_data,
existing.origin, existing.contents.origin,
&mut *namespaces.write(), &mut *namespaces.write(),
&existing.shared_lock, &existing.shared_lock,
stylesheet_loader, stylesheet_loader,
error_reporter, error_reporter,
existing.quirks_mode, existing.contents.quirks_mode,
line_number_offset line_number_offset
); );
*existing.url_data.write() = url_data; *existing.contents.url_data.write() = url_data;
mem::swap(&mut *existing.namespaces.write(), &mut *namespaces.write()); mem::swap(
existing.dirty_on_viewport_size_change &mut *existing.contents.namespaces.write(),
&mut *namespaces.write()
);
existing.contents.dirty_on_viewport_size_change
.store(dirty_on_viewport_size_change, Ordering::Release); .store(dirty_on_viewport_size_change, Ordering::Release);
// Acquire the lock *after* parsing, to minimize the exclusive section. // Acquire the lock *after* parsing, to minimize the exclusive section.
let mut guard = existing.shared_lock.write(); let mut guard = existing.shared_lock.write();
*existing.rules.write_with(&mut guard) = CssRules(rules); *existing.contents.rules.write_with(&mut guard) = CssRules(rules);
} }
fn parse_rules( fn parse_rules(
@ -169,35 +376,28 @@ impl Stylesheet {
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
line_number_offset: u64) line_number_offset: u64)
-> Stylesheet { -> Stylesheet {
let namespaces = RwLock::new(Namespaces::default()); let contents = StylesheetContents::from_str(
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css, css,
&url_data, url_data,
origin, origin,
&mut *namespaces.write(),
&shared_lock, &shared_lock,
stylesheet_loader, stylesheet_loader,
error_reporter, error_reporter,
quirks_mode, quirks_mode,
line_number_offset, line_number_offset
); );
Stylesheet { Stylesheet {
origin: origin, contents,
url_data: RwLock::new(url_data), shared_lock,
namespaces: namespaces, media,
rules: CssRules::new(rules, &shared_lock),
media: media,
shared_lock: shared_lock,
dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change),
disabled: AtomicBool::new(false), disabled: AtomicBool::new(false),
quirks_mode: quirks_mode,
} }
} }
/// Whether this stylesheet can be dirty on viewport size change. /// Whether this stylesheet can be dirty on viewport size change.
pub fn dirty_on_viewport_size_change(&self) -> bool { pub fn dirty_on_viewport_size_change(&self) -> bool {
self.dirty_on_viewport_size_change.load(Ordering::SeqCst) self.contents.dirty_on_viewport_size_change.load(Ordering::SeqCst)
} }
/// When CSSOM inserts a rule or declaration into this stylesheet, it needs to call this method /// When CSSOM inserts a rule or declaration into this stylesheet, it needs to call this method
@ -212,43 +412,10 @@ impl Stylesheet {
/// Instead, we conservatively assume there might be some. /// Instead, we conservatively assume there might be some.
/// Restyling will some some more work than necessary, but give correct results. /// Restyling will some some more work than necessary, but give correct results.
pub fn inserted_has_viewport_percentages(&self, has_viewport_percentages: bool) { pub fn inserted_has_viewport_percentages(&self, has_viewport_percentages: bool) {
self.dirty_on_viewport_size_change.fetch_or(has_viewport_percentages, Ordering::SeqCst); self.contents.dirty_on_viewport_size_change.fetch_or(
} has_viewport_percentages,
Ordering::SeqCst
/// Returns whether the style-sheet applies for the current device depending );
/// on the associated MediaList.
///
/// Always true if no associated MediaList exists.
pub fn is_effective_for_device(&self, device: &Device, guard: &SharedRwLockReadGuard) -> bool {
self.media.read_with(guard).evaluate(device, self.quirks_mode)
}
/// Return an iterator over the effective rules within the style-sheet, as
/// according to the supplied `Device`.
#[inline]
pub fn effective_rules<'a, 'b>(
&'a self,
device: &'a Device,
guard: &'a SharedRwLockReadGuard<'b>)
-> EffectiveRulesIterator<'a, 'b>
{
self.iter_rules::<'a, 'b, EffectiveRules>(device, guard)
}
/// Return an iterator using the condition `C`.
#[inline]
pub fn iter_rules<'a, 'b, C>(
&'a self,
device: &'a Device,
guard: &'a SharedRwLockReadGuard<'b>)
-> RulesIterator<'a, 'b, C>
where C: NestedRuleIterationCondition,
{
RulesIterator::new(
device,
self.quirks_mode,
guard,
&self.rules.read_with(guard))
} }
/// Returns whether the stylesheet has been explicitly disabled through the /// Returns whether the stylesheet has been explicitly disabled through the
@ -269,76 +436,28 @@ impl Stylesheet {
} }
} }
#[cfg(feature = "servo")]
impl Clone for Stylesheet { impl Clone for Stylesheet {
fn clone(&self) -> Stylesheet { fn clone(&self) -> Self {
// Create a new lock for our clone. // Create a new lock for our clone.
let lock = self.shared_lock.clone(); let lock = self.shared_lock.clone();
let guard = self.shared_lock.read(); let guard = self.shared_lock.read();
// Make a deep clone of the rules, using the new lock.
let rules = self.rules.read_with(&guard);
let cloned_rules = rules.deep_clone_with_lock(&lock, &guard);
// Make a deep clone of the media, using the new lock. // Make a deep clone of the media, using the new lock.
let media = self.media.read_with(&guard); let media = self.media.read_with(&guard).clone();
let cloned_media = media.clone(); let media = Arc::new(lock.wrap(media));
let contents = self.contents.deep_clone_with_lock(
&lock,
&guard,
&DeepCloneParams
);
Stylesheet { Stylesheet {
rules: Arc::new(lock.wrap(cloned_rules)), contents,
media: Arc::new(lock.wrap(cloned_media)), media: media,
origin: self.origin,
url_data: RwLock::new((*self.url_data.read()).clone()),
shared_lock: lock, shared_lock: lock,
namespaces: RwLock::new((*self.namespaces.read()).clone()),
dirty_on_viewport_size_change: AtomicBool::new(
self.dirty_on_viewport_size_change.load(Ordering::SeqCst)),
disabled: AtomicBool::new(self.disabled.load(Ordering::SeqCst)), disabled: AtomicBool::new(self.disabled.load(Ordering::SeqCst)),
quirks_mode: self.quirks_mode,
} }
} }
} }
impl MallocSizeOfWithGuard for Stylesheet {
fn malloc_size_of_children(
&self,
guard: &SharedRwLockReadGuard,
malloc_size_of: MallocSizeOfFn
) -> usize {
// Measurement of other fields may be added later.
self.rules.read_with(guard).malloc_size_of_children(guard, malloc_size_of)
}
}
macro_rules! rule_filter {
($( $method: ident($variant:ident => $rule_type: ident), )+) => {
impl Stylesheet {
$(
#[allow(missing_docs)]
pub fn $method<F>(&self, device: &Device, guard: &SharedRwLockReadGuard, mut f: F)
where F: FnMut(&::stylesheets::$rule_type),
{
use stylesheets::CssRule;
for rule in self.effective_rules(device, guard) {
if let CssRule::$variant(ref lock) = *rule {
let rule = lock.read_with(guard);
f(&rule)
}
}
}
)+
}
}
}
rule_filter! {
effective_style_rules(Style => StyleRule),
effective_media_rules(Media => MediaRule),
effective_font_face_rules(FontFace => FontFaceRule),
effective_counter_style_rules(CounterStyle => CounterStyleRule),
effective_viewport_rules(Viewport => ViewportRule),
effective_keyframes_rules(Keyframes => KeyframesRule),
effective_supports_rules(Supports => SupportsRule),
effective_page_rules(Page => PageRule),
effective_document_rules(Document => DocumentRule),
}

View file

@ -9,7 +9,7 @@ use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token};
use parser::ParserContext; use parser::ParserContext;
use properties::{PropertyId, PropertyDeclaration, SourcePropertyDeclaration}; use properties::{PropertyId, PropertyDeclaration, SourcePropertyDeclaration};
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::{ToCss, ParseError, StyleParseError}; use style_traits::{ToCss, ParseError, StyleParseError};
use stylearc::Arc; use stylearc::Arc;
@ -48,12 +48,13 @@ impl DeepCloneWithLock for SupportsRule {
fn deep_clone_with_lock( fn deep_clone_with_lock(
&self, &self,
lock: &SharedRwLock, lock: &SharedRwLock,
guard: &SharedRwLockReadGuard guard: &SharedRwLockReadGuard,
params: &DeepCloneParams,
) -> Self { ) -> Self {
let rules = self.rules.read_with(guard); let rules = self.rules.read_with(guard);
SupportsRule { SupportsRule {
condition: self.condition.clone(), condition: self.condition.clone(),
rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard))), rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard, params))),
enabled: self.enabled, enabled: self.enabled,
source_location: self.source_location.clone(), source_location: self.source_location.clone(),
} }

View file

@ -26,8 +26,7 @@ use std::iter::Enumerate;
use std::str::Chars; use std::str::Chars;
use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseError}; use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseError};
use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom}; use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
use stylearc::Arc; use stylesheets::{StylesheetInDocument, Origin};
use stylesheets::{Stylesheet, Origin};
use values::computed::{Context, ToComputedValue}; use values::computed::{Context, ToComputedValue};
use values::specified::{NoCalcLength, LengthOrPercentageOrAuto, ViewportPercentageLength}; use values::specified::{NoCalcLength, LengthOrPercentageOrAuto, ViewportPercentageLength};
@ -563,11 +562,14 @@ impl Cascade {
} }
} }
pub fn from_stylesheets<'a, I>(stylesheets: I, pub fn from_stylesheets<'a, I, S>(
guard: &SharedRwLockReadGuard, stylesheets: I,
device: &Device) guard: &SharedRwLockReadGuard,
-> Self device: &Device
where I: Iterator<Item = &'a Arc<Stylesheet>>, ) -> Self
where
I: Iterator<Item = &'a S>,
S: StylesheetInDocument + 'static,
{ {
let mut cascade = Self::new(); let mut cascade = Self::new();
for stylesheet in stylesheets { for stylesheet in stylesheets {

View file

@ -15,7 +15,7 @@ use font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use gecko_bindings::structs::{nsIAtom, StyleRuleInclusion}; use gecko_bindings::structs::{nsIAtom, StyleRuleInclusion};
use invalidation::element::invalidation_map::InvalidationMap; use invalidation::element::invalidation_map::InvalidationMap;
use invalidation::media_queries::EffectiveMediaQueryResults; use invalidation::media_queries::{EffectiveMediaQueryResults, ToMediaListKey};
use matching::CascadeVisitedMode; use matching::CascadeVisitedMode;
use media_queries::Device; use media_queries::Device;
use properties::{self, CascadeFlags, ComputedValues}; use properties::{self, CascadeFlags, ComputedValues};
@ -43,7 +43,7 @@ use stylearc::Arc;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use stylesheets::{CounterStyleRule, FontFaceRule}; use stylesheets::{CounterStyleRule, FontFaceRule};
use stylesheets::{CssRule, StyleRule}; use stylesheets::{CssRule, StyleRule};
use stylesheets::{Stylesheet, Origin, UserAgentStylesheets}; use stylesheets::{StylesheetInDocument, Origin, UserAgentStylesheets};
use stylesheets::keyframes_rule::KeyframesAnimation; use stylesheets::keyframes_rule::KeyframesAnimation;
use stylesheets::viewport_rule::{self, MaybeNew, ViewportRule}; use stylesheets::viewport_rule::{self, MaybeNew, ViewportRule};
use thread_state; use thread_state;
@ -342,14 +342,18 @@ impl Stylist {
/// This method resets all the style data each time the stylesheets change /// This method resets all the style data each time the stylesheets change
/// (which is indicated by the `stylesheets_changed` parameter), or the /// (which is indicated by the `stylesheets_changed` parameter), or the
/// device is dirty, which means we need to re-evaluate media queries. /// device is dirty, which means we need to re-evaluate media queries.
pub fn rebuild<'a, 'b, I>(&mut self, pub fn rebuild<'a, 'b, I, S>(
doc_stylesheets: I, &mut self,
guards: &StylesheetGuards, doc_stylesheets: I,
ua_stylesheets: Option<&UserAgentStylesheets>, guards: &StylesheetGuards,
stylesheets_changed: bool, ua_stylesheets: Option<&UserAgentStylesheets>,
author_style_disabled: bool, stylesheets_changed: bool,
extra_data: &mut ExtraStyleData<'a>) -> bool author_style_disabled: bool,
where I: Iterator<Item = &'b Arc<Stylesheet>> + Clone, extra_data: &mut ExtraStyleData<'a>
) -> bool
where
I: Iterator<Item = &'b S> + Clone,
S: StylesheetInDocument + ToMediaListKey + 'static,
{ {
debug_assert!(!self.is_cleared || self.is_device_dirty); debug_assert!(!self.is_cleared || self.is_device_dirty);
@ -398,7 +402,7 @@ impl Stylist {
if let Some(ua_stylesheets) = ua_stylesheets { if let Some(ua_stylesheets) = ua_stylesheets {
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets { for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
self.add_stylesheet(&stylesheet, guards.ua_or_user, extra_data); self.add_stylesheet(stylesheet, guards.ua_or_user, extra_data);
} }
if self.quirks_mode != QuirksMode::NoQuirks { if self.quirks_mode != QuirksMode::NoQuirks {
@ -409,10 +413,10 @@ impl Stylist {
// Only use author stylesheets if author styles are enabled. // Only use author stylesheets if author styles are enabled.
let sheets_to_add = doc_stylesheets.filter(|s| { let sheets_to_add = doc_stylesheets.filter(|s| {
!author_style_disabled || s.origin != Origin::Author !author_style_disabled || s.origin(guards.author) != Origin::Author
}); });
for ref stylesheet in sheets_to_add { for stylesheet in sheets_to_add {
self.add_stylesheet(stylesheet, guards.author, extra_data); self.add_stylesheet(stylesheet, guards.author, extra_data);
} }
@ -429,14 +433,18 @@ impl Stylist {
/// clear the stylist and then rebuild it. Chances are, you want to use /// clear the stylist and then rebuild it. Chances are, you want to use
/// either clear() or rebuild(), with the latter done lazily, instead. /// either clear() or rebuild(), with the latter done lazily, instead.
pub fn update<'a, 'b, I>(&mut self, pub fn update<'a, 'b, I, S>(
doc_stylesheets: I, &mut self,
guards: &StylesheetGuards, doc_stylesheets: I,
ua_stylesheets: Option<&UserAgentStylesheets>, guards: &StylesheetGuards,
stylesheets_changed: bool, ua_stylesheets: Option<&UserAgentStylesheets>,
author_style_disabled: bool, stylesheets_changed: bool,
extra_data: &mut ExtraStyleData<'a>) -> bool author_style_disabled: bool,
where I: Iterator<Item = &'b Arc<Stylesheet>> + Clone, extra_data: &mut ExtraStyleData<'a>
) -> bool
where
I: Iterator<Item = &'b S> + Clone,
S: StylesheetInDocument + ToMediaListKey + 'static,
{ {
debug_assert!(!self.is_cleared || self.is_device_dirty); debug_assert!(!self.is_cleared || self.is_device_dirty);
@ -450,16 +458,23 @@ impl Stylist {
author_style_disabled, extra_data) author_style_disabled, extra_data)
} }
fn add_stylesheet<'a>(&mut self, fn add_stylesheet<'a, S>(
stylesheet: &Stylesheet, &mut self,
guard: &SharedRwLockReadGuard, stylesheet: &S,
_extra_data: &mut ExtraStyleData<'a>) { guard: &SharedRwLockReadGuard,
if stylesheet.disabled() || !stylesheet.is_effective_for_device(&self.device, guard) { _extra_data: &mut ExtraStyleData<'a>
)
where
S: StylesheetInDocument + ToMediaListKey + 'static,
{
if !stylesheet.enabled() ||
!stylesheet.is_effective_for_device(&self.device, guard) {
return; return;
} }
self.effective_media_query_results.saw_effective(stylesheet); self.effective_media_query_results.saw_effective(stylesheet);
let origin = stylesheet.origin(guard);
for rule in stylesheet.effective_rules(&self.device, guard) { for rule in stylesheet.effective_rules(&self.device, guard) {
match *rule { match *rule {
CssRule::Style(ref locked) => { CssRule::Style(ref locked) => {
@ -472,9 +487,9 @@ impl Stylist {
self.pseudos_map self.pseudos_map
.entry(pseudo.canonical()) .entry(pseudo.canonical())
.or_insert_with(PerPseudoElementSelectorMap::new) .or_insert_with(PerPseudoElementSelectorMap::new)
.borrow_for_origin(&stylesheet.origin) .borrow_for_origin(&origin)
} else { } else {
self.element_map.borrow_for_origin(&stylesheet.origin) self.element_map.borrow_for_origin(&origin)
}; };
map.insert( map.insert(
@ -529,7 +544,7 @@ impl Stylist {
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
CssRule::FontFace(ref rule) => { CssRule::FontFace(ref rule) => {
_extra_data.add_font_face(&rule, stylesheet.origin); _extra_data.add_font_face(&rule, origin);
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
CssRule::CounterStyle(ref rule) => { CssRule::CounterStyle(ref rule) => {
@ -909,9 +924,13 @@ impl Stylist {
pub fn set_device(&mut self, pub fn set_device(&mut self,
mut device: Device, mut device: Device,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
stylesheets: &[Arc<Stylesheet>]) { stylesheets: &[Arc<::stylesheets::Stylesheet>]) {
let cascaded_rule = ViewportRule { let cascaded_rule = ViewportRule {
declarations: viewport_rule::Cascade::from_stylesheets(stylesheets.iter(), guard, &device).finish(), declarations: viewport_rule::Cascade::from_stylesheets(
stylesheets.iter().map(|s| &**s),
guard,
&device
).finish(),
}; };
self.viewport_constraints = self.viewport_constraints =
@ -923,7 +942,7 @@ impl Stylist {
self.device = device; self.device = device;
let features_changed = self.media_features_change_changed_style( let features_changed = self.media_features_change_changed_style(
stylesheets.iter(), stylesheets.iter().map(|s| &**s),
guard guard
); );
self.is_device_dirty |= features_changed; self.is_device_dirty |= features_changed;
@ -931,12 +950,14 @@ impl Stylist {
/// Returns whether, given a media feature change, any previously-applicable /// Returns whether, given a media feature change, any previously-applicable
/// style has become non-applicable, or vice-versa. /// style has become non-applicable, or vice-versa.
pub fn media_features_change_changed_style<'a, I>( pub fn media_features_change_changed_style<'a, I, S>(
&self, &self,
stylesheets: I, stylesheets: I,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
) -> bool ) -> bool
where I: Iterator<Item = &'a Arc<Stylesheet>> where
I: Iterator<Item = &'a S>,
S: StylesheetInDocument + ToMediaListKey + 'static,
{ {
use invalidation::media_queries::PotentiallyEffectiveMediaRules; use invalidation::media_queries::PotentiallyEffectiveMediaRules;
@ -944,11 +965,10 @@ impl Stylist {
for stylesheet in stylesheets { for stylesheet in stylesheets {
let effective_now = let effective_now =
stylesheet.media.read_with(guard) stylesheet.is_effective_for_device(&self.device, guard);
.evaluate(&self.device, self.quirks_mode);
let effective_then = let effective_then =
self.effective_media_query_results.was_effective(&**stylesheet); self.effective_media_query_results.was_effective(stylesheet);
if effective_now != effective_then { if effective_now != effective_then {
debug!(" > Stylesheet changed -> {}, {}", debug!(" > Stylesheet changed -> {}, {}",
@ -982,9 +1002,9 @@ impl Stylist {
} }
CssRule::Import(ref lock) => { CssRule::Import(ref lock) => {
let import_rule = lock.read_with(guard); let import_rule = lock.read_with(guard);
let mq = import_rule.stylesheet.media.read_with(guard);
let effective_now = let effective_now =
mq.evaluate(&self.device, self.quirks_mode); import_rule.stylesheet
.is_effective_for_device(&self.device, guard);
let effective_then = let effective_then =
self.effective_media_query_results.was_effective(import_rule); self.effective_media_query_results.was_effective(import_rule);
if effective_now != effective_then { if effective_now != effective_then {

View file

@ -18,7 +18,7 @@ use style::dom::{ShowSubtreeData, TElement, TNode};
use style::element_state::ElementState; use style::element_state::ElementState;
use style::error_reporting::RustLogReporter; use style::error_reporting::RustLogReporter;
use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product}; use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product};
use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl}; use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl};
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL}; use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL};
use style::gecko::restyle_damage::GeckoRestyleDamage; use style::gecko::restyle_damage::GeckoRestyleDamage;
use style::gecko::selector_parser::PseudoElement; use style::gecko::selector_parser::PseudoElement;
@ -32,13 +32,13 @@ use style::gecko_bindings::bindings::{RawServoDocumentRule, RawServoDocumentRule
use style::gecko_bindings::bindings::{RawServoImportRule, RawServoImportRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoImportRule, RawServoImportRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong}; use style::gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong};
use style::gecko_bindings::bindings::{RawServoKeyframesRule, RawServoKeyframesRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoKeyframesRule, RawServoKeyframesRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoMediaList, RawServoMediaListBorrowed, RawServoMediaListStrong}; use style::gecko_bindings::bindings::{RawServoMediaListBorrowed, RawServoMediaListStrong};
use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned}; use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use style::gecko_bindings::bindings::{RawServoStyleSheetContentsBorrowed, ServoComputedValuesBorrowed};
use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; use style::gecko_bindings::bindings::{RawServoStyleSheetContentsStrong, ServoComputedValuesStrong};
use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed};
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong}; use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut}; use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut};
@ -59,14 +59,12 @@ use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut; use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowedMut;
use style::gecko_bindings::bindings::RawServoAnimationValueStrong; use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed; use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed;
use style::gecko_bindings::bindings::RawServoStyleSheet;
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull; use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t; use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
use style::gecko_bindings::bindings::nsTimingFunctionBorrowed; use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut; use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
use style::gecko_bindings::structs; use style::gecko_bindings::structs;
use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation}; use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation, Loader};
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet}; use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID}; use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule}; use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule};
@ -105,7 +103,8 @@ use style::style_adjuster::StyleAdjuster;
use style::stylearc::Arc; use style::stylearc::Arc;
use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, DocumentRule}; use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, DocumentRule};
use style::stylesheets::{ImportRule, KeyframesRule, MallocSizeOfWithGuard, MediaRule}; use style::stylesheets::{ImportRule, KeyframesRule, MallocSizeOfWithGuard, MediaRule};
use style::stylesheets::{NamespaceRule, Origin, PageRule, Stylesheet, StyleRule, SupportsRule}; use style::stylesheets::{NamespaceRule, Origin, PageRule, StyleRule, SupportsRule};
use style::stylesheets::StylesheetContents;
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue}; use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
use style::stylesheets::supports_rule::parse_condition_or_declaration; use style::stylesheets::supports_rule::parse_condition_or_declaration;
@ -739,7 +738,7 @@ pub extern "C" fn Servo_Element_ClearData(element: RawGeckoElementBorrowed) {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyleSheetStrong { pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyleSheetContentsStrong {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let origin = match mode { let origin = match mode {
SheetParsingMode::eAuthorSheetFeatures => Origin::Author, SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
@ -747,24 +746,31 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent, SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent, SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent,
}; };
let shared_lock = global_style_data.shared_lock.clone(); let shared_lock = &global_style_data.shared_lock;
Arc::new(Stylesheet::from_str( Arc::new(
"", unsafe { dummy_url_data() }.clone(), origin, StylesheetContents::from_str(
Arc::new(shared_lock.wrap(MediaList::empty())), "",
shared_lock, None, &RustLogReporter, QuirksMode::NoQuirks, 0u64) unsafe { dummy_url_data() }.clone(),
origin,
shared_lock,
/* loader = */ None,
&RustLogReporter,
QuirksMode::NoQuirks,
0
)
).into_strong() ).into_strong()
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader, pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
stylesheet: *mut ServoStyleSheet, loader: *mut Loader,
data: *const nsACString, stylesheet: *mut ServoStyleSheet,
mode: SheetParsingMode, data: *const nsACString,
media_list: *const RawServoMediaList, mode: SheetParsingMode,
extra_data: *mut URLExtraData, extra_data: *mut URLExtraData,
line_number_offset: u32, line_number_offset: u32,
quirks_mode: nsCompatibility) quirks_mode: nsCompatibility
-> RawServoStyleSheetStrong { ) -> RawServoStyleSheetContentsStrong {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() }; let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
@ -788,63 +794,28 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
Some(ref s) => Some(s), Some(ref s) => Some(s),
}; };
let shared_lock = global_style_data.shared_lock.clone();
let media = if media_list.is_null() {
Arc::new(shared_lock.wrap(MediaList::empty()))
} else {
Locked::<MediaList>::as_arc(unsafe { &&*media_list }).clone()
};
Arc::new(Stylesheet::from_str( Arc::new(StylesheetContents::from_str(
input, url_data.clone(), origin, media, input, url_data.clone(), origin,
shared_lock, loader, &RustLogReporter, &global_style_data.shared_lock, loader, &RustLogReporter,
quirks_mode.into(), line_number_offset as u64) quirks_mode.into(), line_number_offset as u64)
).into_strong() ).into_strong()
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheetBorrowed, pub extern "C" fn Servo_StyleSet_AppendStyleSheet(
loader: *mut Loader, raw_data: RawServoStyleSetBorrowed,
gecko_stylesheet: *mut ServoStyleSheet, sheet: *const ServoStyleSheet,
data: *const nsACString, ) {
extra_data: *mut URLExtraData,
line_number_offset: u32,
reusable_sheets: *mut LoaderReusableStyleSheets)
{
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
let loader = if loader.is_null() {
None
} else {
Some(StylesheetLoader::new(loader, gecko_stylesheet, reusable_sheets))
};
// FIXME(emilio): loader.as_ref() doesn't typecheck for some reason?
let loader: Option<&StyleStylesheetLoader> = match loader {
None => None,
Some(ref s) => Some(s),
};
let sheet = Stylesheet::as_arc(&stylesheet);
Stylesheet::update_from_str(&sheet, input, url_data.clone(), loader,
&RustLogReporter, line_number_offset as u64);
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(raw_data: RawServoStyleSetBorrowed,
raw_sheet: RawServoStyleSheetBorrowed,
unique_id: u64) {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let mut data = &mut *data; let mut data = &mut *data;
let sheet = HasArcFFI::as_arc(&raw_sheet);
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
data.stylesheets.append_stylesheet( data.stylesheets.append_stylesheet(
&data.stylist, &data.stylist,
sheet, unsafe { GeckoStyleSheet::new(sheet) },
unique_id, &guard
&guard); );
data.clear_stylist(); data.clear_stylist();
} }
@ -875,65 +846,55 @@ pub extern "C" fn Servo_StyleSet_MediumFeaturesChanged(
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowed, pub extern "C" fn Servo_StyleSet_PrependStyleSheet(
raw_sheet: RawServoStyleSheetBorrowed, raw_data: RawServoStyleSetBorrowed,
unique_id: u64) { sheet: *const ServoStyleSheet,
) {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let mut data = &mut *data; let mut data = &mut *data;
let sheet = HasArcFFI::as_arc(&raw_sheet);
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
data.stylesheets.prepend_stylesheet( data.stylesheets.prepend_stylesheet(
&data.stylist, &data.stylist,
sheet, unsafe { GeckoStyleSheet::new(sheet) },
unique_id, &guard,
&guard); );
data.clear_stylist(); data.clear_stylist();
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowed, pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(
raw_sheet: RawServoStyleSheetBorrowed, raw_data: RawServoStyleSetBorrowed,
unique_id: u64, sheet: *const ServoStyleSheet,
before_unique_id: u64) { before_sheet: *const ServoStyleSheet
) {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let mut data = &mut *data; let mut data = &mut *data;
let sheet = HasArcFFI::as_arc(&raw_sheet);
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
data.stylesheets.insert_stylesheet_before( data.stylesheets.insert_stylesheet_before(
&data.stylist, &data.stylist,
sheet, unsafe { GeckoStyleSheet::new(sheet) },
unique_id, unsafe { GeckoStyleSheet::new(before_sheet) },
before_unique_id,
&guard); &guard);
data.clear_stylist(); data.clear_stylist();
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSet_UpdateStyleSheet(raw_data: RawServoStyleSetBorrowed, pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(
raw_sheet: RawServoStyleSheetBorrowed, raw_data: RawServoStyleSetBorrowed,
unique_id: u64) { sheet: *const ServoStyleSheet
) {
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let sheet = HasArcFFI::as_arc(&raw_sheet); data.stylesheets.remove_stylesheet(unsafe { GeckoStyleSheet::new(sheet) });
data.stylesheets.update_stylesheet(
sheet,
unique_id);
}
#[no_mangle]
pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorrowed,
unique_id: u64) {
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
data.stylesheets.remove_stylesheet(unique_id);
data.clear_stylist(); data.clear_stylist();
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSet_FlushStyleSheets( pub extern "C" fn Servo_StyleSet_FlushStyleSheets(
raw_data: RawServoStyleSetBorrowed, raw_data: RawServoStyleSetBorrowed,
doc_element: RawGeckoElementBorrowedOrNull) doc_element: RawGeckoElementBorrowedOrNull,
{ ) {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
@ -944,8 +905,8 @@ pub extern "C" fn Servo_StyleSet_FlushStyleSheets(
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged( pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged(
raw_data: RawServoStyleSetBorrowed, raw_data: RawServoStyleSetBorrowed,
author_style_disabled: bool) author_style_disabled: bool,
{ ) {
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
data.stylesheets.force_dirty(); data.stylesheets.force_dirty();
data.stylesheets.set_author_style_disabled(author_style_disabled); data.stylesheets.set_author_style_disabled(author_style_disabled);
@ -953,30 +914,50 @@ pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged(
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool { pub extern "C" fn Servo_StyleSheet_HasRules(
raw_contents: RawServoStyleSheetContentsBorrowed
) -> bool {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
!Stylesheet::as_arc(&raw_sheet).rules.read_with(&guard).0.is_empty() !StylesheetContents::as_arc(&raw_contents)
.rules.read_with(&guard).0.is_empty()
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -> ServoCssRulesStrong { pub extern "C" fn Servo_StyleSheet_GetRules(
Stylesheet::as_arc(&sheet).rules.clone().into_strong() sheet: RawServoStyleSheetContentsBorrowed
) -> ServoCssRulesStrong {
StylesheetContents::as_arc(&sheet).rules.clone().into_strong()
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_Clone(raw_sheet: RawServoStyleSheetBorrowed) -> RawServoStyleSheetStrong { pub extern "C" fn Servo_StyleSheet_Clone(
let sheet: &Arc<Stylesheet> = HasArcFFI::as_arc(&raw_sheet); raw_sheet: RawServoStyleSheetContentsBorrowed,
Arc::new(sheet.as_ref().clone()).into_strong() reference_sheet: *const ServoStyleSheet,
) -> RawServoStyleSheetContentsStrong {
use style::shared_lock::{DeepCloneParams, DeepCloneWithLock};
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let contents = StylesheetContents::as_arc(&raw_sheet);
let params = DeepCloneParams { reference_sheet };
Arc::new(contents.deep_clone_with_lock(
&global_style_data.shared_lock,
&guard,
&params,
)).into_strong()
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_SizeOfIncludingThis(malloc_size_of: MallocSizeOf, pub extern "C" fn Servo_StyleSheet_SizeOfIncludingThis(
sheet: RawServoStyleSheetBorrowed) -> usize { malloc_size_of: MallocSizeOf,
sheet: RawServoStyleSheetContentsBorrowed
) -> usize {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
let malloc_size_of = malloc_size_of.unwrap(); let malloc_size_of = malloc_size_of.unwrap();
Stylesheet::as_arc(&sheet).malloc_size_of_children(&guard, malloc_size_of) StylesheetContents::as_arc(&sheet)
.malloc_size_of_children(&guard, malloc_size_of)
} }
fn read_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R fn read_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R
@ -1008,15 +989,16 @@ pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, pub extern "C" fn Servo_CssRules_InsertRule(
sheet: RawServoStyleSheetBorrowed, rules: ServoCssRulesBorrowed,
rule: *const nsACString, contents: RawServoStyleSheetContentsBorrowed,
index: u32, rule: *const nsACString,
nested: bool, index: u32,
loader: *mut Loader, nested: bool,
gecko_stylesheet: *mut ServoStyleSheet, loader: *mut Loader,
rule_type: *mut u16) -> nsresult { gecko_stylesheet: *mut ServoStyleSheet,
let sheet = Stylesheet::as_arc(&sheet); rule_type: *mut u16,
) -> nsresult {
let loader = if loader.is_null() { let loader = if loader.is_null() {
None None
} else { } else {
@ -1026,12 +1008,17 @@ pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
let rule = unsafe { rule.as_ref().unwrap().as_str_unchecked() }; let rule = unsafe { rule.as_ref().unwrap().as_str_unchecked() };
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
match Locked::<CssRules>::as_arc(&rules).insert_rule(&global_style_data.shared_lock, let contents = StylesheetContents::as_arc(&contents);
rule, let result = Locked::<CssRules>::as_arc(&rules).insert_rule(
sheet, &global_style_data.shared_lock,
index as usize, rule,
nested, contents,
loader) { index as usize,
nested,
loader
);
match result {
Ok(new_rule) => { Ok(new_rule) => {
*unsafe { rule_type.as_mut().unwrap() } = new_rule.rule_type() as u16; *unsafe { rule_type.as_mut().unwrap() } = new_rule.rule_type() as u16;
nsresult::NS_OK nsresult::NS_OK
@ -1041,7 +1028,10 @@ pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: u32) -> nsresult { pub extern "C" fn Servo_CssRules_DeleteRule(
rules: ServoCssRulesBorrowed,
index: u32
) -> nsresult {
write_locked_arc(rules, |rules: &mut CssRules| { write_locked_arc(rules, |rules: &mut CssRules| {
match rules.remove_rule(index as usize) { match rules.remove_rule(index as usize) {
Ok(_) => nsresult::NS_OK, Ok(_) => nsresult::NS_OK,
@ -1085,7 +1075,13 @@ macro_rules! impl_basic_rule_funcs {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard); let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
match rules.0[index as usize] { let index = index as usize;
if index >= rules.0.len() {
return Strong::null();
}
match rules.0[index] {
CssRule::$name(ref rule) => { CssRule::$name(ref rule) => {
let location = rule.read_with(&guard).source_location; let location = rule.read_with(&guard).source_location;
*unsafe { line.as_mut().unwrap() } = location.line as u32; *unsafe { line.as_mut().unwrap() } = location.line as u32;
@ -1093,8 +1089,7 @@ macro_rules! impl_basic_rule_funcs {
rule.clone().into_strong() rule.clone().into_strong()
}, },
_ => { _ => {
unreachable!(concat!(stringify!($getter), "should only be called ", Strong::null()
"on a ", stringify!($name), " rule"));
} }
} }
} }
@ -1244,9 +1239,11 @@ pub extern "C" fn Servo_StyleRule_GetSelectorCount(rule: RawServoStyleRuleBorrow
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleRule_GetSpecificityAtIndex(rule: RawServoStyleRuleBorrowed, pub extern "C" fn Servo_StyleRule_GetSpecificityAtIndex(
index: u32, rule: RawServoStyleRuleBorrowed,
specificity: *mut u64) { index: u32,
specificity: *mut u64
) {
read_locked_arc(rule, |rule: &StyleRule| { read_locked_arc(rule, |rule: &StyleRule| {
let mut specificity = unsafe { specificity.as_mut().unwrap() }; let mut specificity = unsafe { specificity.as_mut().unwrap() };
let index = index as usize; let index = index as usize;
@ -1266,14 +1263,19 @@ pub extern "C" fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, res
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed) -> *const RawServoStyleSheet { pub extern "C" fn Servo_ImportRule_GetSheet(
rule: RawServoImportRuleBorrowed
) -> *const ServoStyleSheet {
read_locked_arc(rule, |rule: &ImportRule| { read_locked_arc(rule, |rule: &ImportRule| {
rule.stylesheet.as_borrowed_opt().unwrap() as *const _ rule.stylesheet.0.raw() as *const ServoStyleSheet
}) })
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed, result: *mut nsAString) { pub extern "C" fn Servo_Keyframe_GetKeyText(
keyframe: RawServoKeyframeBorrowed,
result: *mut nsAString
) {
read_locked_arc(keyframe, |keyframe: &Keyframe| { read_locked_arc(keyframe, |keyframe: &Keyframe| {
keyframe.selector.to_css(unsafe { result.as_mut().unwrap() }).unwrap() keyframe.selector.to_css(unsafe { result.as_mut().unwrap() }).unwrap()
}) })
@ -1344,18 +1346,22 @@ pub extern "C" fn Servo_KeyframesRule_FindRule(rule: RawServoKeyframesRuleBorrow
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_KeyframesRule_AppendRule(rule: RawServoKeyframesRuleBorrowed, pub extern "C" fn Servo_KeyframesRule_AppendRule(
sheet: RawServoStyleSheetBorrowed, rule: RawServoKeyframesRuleBorrowed,
css: *const nsACString) -> bool { contents: RawServoStyleSheetContentsBorrowed,
css: *const nsACString
) -> bool {
let css = unsafe { css.as_ref().unwrap().as_str_unchecked() }; let css = unsafe { css.as_ref().unwrap().as_str_unchecked() };
let sheet = Stylesheet::as_arc(&sheet); let contents = StylesheetContents::as_arc(&contents);
if let Ok(keyframe) = Keyframe::parse(css, sheet) { let global_style_data = &*GLOBAL_STYLE_DATA;
write_locked_arc(rule, |rule: &mut KeyframesRule| { match Keyframe::parse(css, &contents, &global_style_data.shared_lock) {
rule.keyframes.push(keyframe); Ok(keyframe) => {
}); write_locked_arc(rule, |rule: &mut KeyframesRule| {
true rule.keyframes.push(keyframe);
} else { });
false true
}
Err(..) => false,
} }
} }
@ -1607,10 +1613,10 @@ fn get_pseudo_style(
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_ComputedValues_Inherit( pub extern "C" fn Servo_ComputedValues_Inherit(
raw_data: RawServoStyleSetBorrowed, raw_data: RawServoStyleSetBorrowed,
parent_style: ServoComputedValuesBorrowedOrNull, parent_style: ServoComputedValuesBorrowedOrNull,
target: structs::InheritTarget) target: structs::InheritTarget
-> ServoComputedValuesStrong { ) -> ServoComputedValuesStrong {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let maybe_arc = ComputedValues::arc_from_borrowed(&parent_style); let maybe_arc = ComputedValues::arc_from_borrowed(&parent_style);
@ -3149,11 +3155,11 @@ pub extern "C" fn Servo_StyleSet_GetCounterStyleRule(raw_data: RawServoStyleSetB
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(raw_data: RawServoStyleSetBorrowed, pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(
parent_style_or_null: ServoComputedValuesBorrowedOrNull, raw_data: RawServoStyleSetBorrowed,
declarations: RawServoDeclarationBlockBorrowed) parent_style_or_null: ServoComputedValuesBorrowedOrNull,
-> ServoComputedValuesStrong declarations: RawServoDeclarationBlockBorrowed
{ ) -> ServoComputedValuesStrong {
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();

View file

@ -2,13 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::SourceLocation;
use style::gecko::data::GeckoStyleSheet;
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet; use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
use style::gecko_bindings::structs::{Loader, ServoStyleSheet, LoaderReusableStyleSheets}; use style::gecko_bindings::structs::{Loader, ServoStyleSheet, LoaderReusableStyleSheets};
use style::gecko_bindings::sugar::ownership::{HasArcFFI, FFIArcHelpers}; use style::gecko_bindings::sugar::ownership::FFIArcHelpers;
use style::media_queries::MediaList; use style::media_queries::MediaList;
use style::shared_lock::Locked; use style::parser::ParserContext;
use style::shared_lock::{Locked, SharedRwLock};
use style::stylearc::Arc; use style::stylearc::Arc;
use style::stylesheets::{ImportRule, Stylesheet, StylesheetLoader as StyleStylesheetLoader}; use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader};
use style::stylesheets::import_rule::ImportSheet;
use style::values::specified::url::SpecifiedUrl;
pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet, *mut LoaderReusableStyleSheets); pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet, *mut LoaderReusableStyleSheets);
@ -23,29 +28,34 @@ impl StylesheetLoader {
impl StyleStylesheetLoader for StylesheetLoader { impl StyleStylesheetLoader for StylesheetLoader {
fn request_stylesheet( fn request_stylesheet(
&self, &self,
url: SpecifiedUrl,
source_location: SourceLocation,
_context: &ParserContext,
lock: &SharedRwLock,
media: Arc<Locked<MediaList>>, media: Arc<Locked<MediaList>>,
make_import: &mut FnMut(Arc<Locked<MediaList>>) -> ImportRule,
make_arc: &mut FnMut(ImportRule) -> Arc<Locked<ImportRule>>,
) -> Arc<Locked<ImportRule>> { ) -> Arc<Locked<ImportRule>> {
let import = make_import(media.clone());
// After we get this raw pointer ImportRule will be moved into a lock and Arc // After we get this raw pointer ImportRule will be moved into a lock and Arc
// and so the Arc<Url> pointer inside will also move, // and so the Arc<Url> pointer inside will also move,
// but the Url it points to or the allocating backing the String inside that Url wont, // but the Url it points to or the allocating backing the String inside that Url wont,
// so this raw pointer will still be valid. // so this raw pointer will still be valid.
let (spec_bytes, spec_len): (*const u8, usize) = import.url.as_slice_components();
let base_url_data = import.url.extra_data.get(); let child_sheet = unsafe {
unsafe { let (spec_bytes, spec_len) = url.as_slice_components();
let base_url_data = url.extra_data.get();
Gecko_LoadStyleSheet(self.0, Gecko_LoadStyleSheet(self.0,
self.1, self.1,
self.2, self.2,
Stylesheet::arc_as_borrowed(&import.stylesheet),
base_url_data, base_url_data,
spec_bytes, spec_bytes,
spec_len as u32, spec_len as u32,
media.into_strong()) media.into_strong())
} };
make_arc(import)
debug_assert!(!child_sheet.is_null(),
"Import rules should always have a strong sheet");
let stylesheet = unsafe {
ImportSheet(GeckoStyleSheet::from_addrefed(child_sheet))
};
Arc::new(lock.wrap(ImportRule { url, source_location, stylesheet }))
} }
} }

View file

@ -13,7 +13,7 @@ use style::media_queries::*;
use style::servo::media_queries::*; use style::servo::media_queries::*;
use style::shared_lock::SharedRwLock; use style::shared_lock::SharedRwLock;
use style::stylearc::Arc; use style::stylearc::Arc;
use style::stylesheets::{AllRules, Stylesheet, Origin, CssRule}; use style::stylesheets::{AllRules, Stylesheet, StylesheetInDocument, Origin, CssRule};
use style::values::specified; use style::values::specified;
use style_traits::ToCss; use style_traits::ToCss;

View file

@ -62,7 +62,7 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> {
QuirksMode::NoQuirks, QuirksMode::NoQuirks,
0u64); 0u64);
let guard = s.shared_lock.read(); let guard = s.shared_lock.read();
let rules = s.rules.read_with(&guard); let rules = s.contents.rules.read_with(&guard);
rules.0.iter().filter_map(|rule| { rules.0.iter().filter_map(|rule| {
match *rule { match *rule {
CssRule::Style(ref style_rule) => Some(style_rule), CssRule::Style(ref style_rule) => Some(style_rule),

View file

@ -23,7 +23,7 @@ use style::properties::longhands::animation_play_state;
use style::shared_lock::SharedRwLock; use style::shared_lock::SharedRwLock;
use style::stylearc::Arc; use style::stylearc::Arc;
use style::stylesheets::{Origin, Namespaces}; use style::stylesheets::{Origin, Namespaces};
use style::stylesheets::{Stylesheet, NamespaceRule, CssRule, CssRules, StyleRule, KeyframesRule}; use style::stylesheets::{Stylesheet, StylesheetContents, NamespaceRule, CssRule, CssRules, StyleRule, KeyframesRule};
use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframePercentage}; use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframePercentage};
use style::values::{KeyframesName, CustomIdent}; use style::values::{KeyframesName, CustomIdent};
use style::values::specified::{LengthOrPercentageOrAuto, Percentage, PositionComponent}; use style::values::specified::{LengthOrPercentageOrAuto, Percentage, PositionComponent};
@ -72,176 +72,178 @@ fn test_parse_stylesheet() {
let mut namespaces = Namespaces::default(); let mut namespaces = Namespaces::default();
namespaces.default = Some((ns!(html), ())); namespaces.default = Some((ns!(html), ()));
let expected = Stylesheet { let expected = Stylesheet {
origin: Origin::UserAgent, contents: StylesheetContents {
media: Arc::new(stylesheet.shared_lock.wrap(MediaList::empty())), origin: Origin::UserAgent,
shared_lock: stylesheet.shared_lock.clone(), namespaces: RwLock::new(namespaces),
namespaces: RwLock::new(namespaces), url_data: RwLock::new(url),
url_data: RwLock::new(url), dirty_on_viewport_size_change: AtomicBool::new(false),
dirty_on_viewport_size_change: AtomicBool::new(false), quirks_mode: QuirksMode::NoQuirks,
disabled: AtomicBool::new(false), rules: CssRules::new(vec![
quirks_mode: QuirksMode::NoQuirks, CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule {
rules: CssRules::new(vec![ prefix: None,
CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule { url: NsAtom::from("http://www.w3.org/1999/xhtml"),
prefix: None, source_location: SourceLocation {
url: NsAtom::from("http://www.w3.org/1999/xhtml"), line: 1,
source_location: SourceLocation { column: 19,
line: 1, },
column: 19, }))),
}, CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
}))), selectors: SelectorList::from_vec(vec!(
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { Selector::from_vec(vec!(
selectors: SelectorList::from_vec(vec!(
Selector::from_vec(vec!(
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
Component::LocalName(LocalName {
name: local_name!("input"),
lower_name: local_name!("input"),
}),
Component::AttributeInNoNamespace {
local_name: local_name!("type"),
local_name_lower: local_name!("type"),
operator: AttrSelectorOperator::Equal,
value: "hidden".to_owned(),
case_sensitivity: ParsedCaseSensitivity::AsciiCaseInsensitive,
never_matches: false,
}
), (0 << 20) + (1 << 10) + (1 << 0))
)),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::none),
Importance::Important),
(PropertyDeclaration::Custom(Atom::from("a"),
DeclaredValueOwned::CSSWideKeyword(CSSWideKeyword::Inherit)),
Importance::Important),
]))),
source_location: SourceLocation {
line: 3,
column: 9,
},
}))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList::from_vec(vec!(
Selector::from_vec(vec!(
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")), Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
Component::LocalName(LocalName { Component::LocalName(LocalName {
name: local_name!("html"), name: local_name!("input"),
lower_name: local_name!("html"), lower_name: local_name!("input"),
}), }),
), (0 << 20) + (0 << 10) + (1 << 0)), Component::AttributeInNoNamespace {
Selector::from_vec(vec!( local_name: local_name!("type"),
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")), local_name_lower: local_name!("type"),
Component::LocalName(LocalName { operator: AttrSelectorOperator::Equal,
name: local_name!("body"), value: "hidden".to_owned(),
lower_name: local_name!("body"), case_sensitivity: ParsedCaseSensitivity::AsciiCaseInsensitive,
}) never_matches: false,
), (0 << 20) + (0 << 10) + (1 << 0) }
), ), (0 << 20) + (1 << 10) + (1 << 0))
)), )),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::block), (PropertyDeclaration::Display(longhands::display::SpecifiedValue::none),
Importance::Normal), Importance::Important),
]))), (PropertyDeclaration::Custom(Atom::from("a"),
source_location: SourceLocation { DeclaredValueOwned::CSSWideKeyword(CSSWideKeyword::Inherit)),
line: 11, Importance::Important),
column: 9, ]))),
}, source_location: SourceLocation {
}))), line: 3,
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { column: 9,
selectors: SelectorList::from_vec(vec!( },
Selector::from_vec(vec!( }))),
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")), CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
Component::ID(Atom::from("d1")), selectors: SelectorList::from_vec(vec!(
Component::Combinator(Combinator::Child), Selector::from_vec(vec!(
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")), Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
Component::Class(Atom::from("ok")) Component::LocalName(LocalName {
), (1 << 20) + (1 << 10) + (0 << 0)) name: local_name!("html"),
)), lower_name: local_name!("html"),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ }),
(PropertyDeclaration::BackgroundColor( ), (0 << 20) + (0 << 10) + (1 << 0)),
longhands::background_color::SpecifiedValue::Numeric { Selector::from_vec(vec!(
authored: Some("blue".to_owned().into_boxed_str()), Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
parsed: cssparser::RGBA::new(0, 0, 255, 255), Component::LocalName(LocalName {
} name: local_name!("body"),
), lower_name: local_name!("body"),
Importance::Normal), })
(PropertyDeclaration::BackgroundPositionX( ), (0 << 20) + (0 << 10) + (1 << 0)
longhands::background_position_x::SpecifiedValue( ),
vec![PositionComponent::zero()])), )),
Importance::Normal), block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::BackgroundPositionY( (PropertyDeclaration::Display(longhands::display::SpecifiedValue::block),
longhands::background_position_y::SpecifiedValue( Importance::Normal),
vec![PositionComponent::zero()])), ]))),
Importance::Normal), source_location: SourceLocation {
(PropertyDeclaration::BackgroundRepeat( line: 11,
longhands::background_repeat::SpecifiedValue( column: 9,
vec![longhands::background_repeat::single_value },
::get_initial_specified_value()])), }))),
Importance::Normal), CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
(PropertyDeclaration::BackgroundAttachment( selectors: SelectorList::from_vec(vec!(
longhands::background_attachment::SpecifiedValue( Selector::from_vec(vec!(
vec![longhands::background_attachment::single_value Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
::get_initial_specified_value()])), Component::ID(Atom::from("d1")),
Importance::Normal), Component::Combinator(Combinator::Child),
(PropertyDeclaration::BackgroundImage( Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
longhands::background_image::SpecifiedValue( Component::Class(Atom::from("ok"))
vec![longhands::background_image::single_value ), (1 << 20) + (1 << 10) + (0 << 0))
::get_initial_specified_value()])), )),
Importance::Normal), block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::BackgroundSize( (PropertyDeclaration::BackgroundColor(
longhands::background_size::SpecifiedValue( longhands::background_color::SpecifiedValue::Numeric {
vec![longhands::background_size::single_value authored: Some("blue".to_owned().into_boxed_str()),
::get_initial_specified_value()])), parsed: cssparser::RGBA::new(0, 0, 255, 255),
Importance::Normal), }
(PropertyDeclaration::BackgroundOrigin( ),
longhands::background_origin::SpecifiedValue( Importance::Normal),
vec![longhands::background_origin::single_value (PropertyDeclaration::BackgroundPositionX(
::get_initial_specified_value()])), longhands::background_position_x::SpecifiedValue(
Importance::Normal), vec![PositionComponent::zero()])),
(PropertyDeclaration::BackgroundClip( Importance::Normal),
longhands::background_clip::SpecifiedValue( (PropertyDeclaration::BackgroundPositionY(
vec![longhands::background_clip::single_value longhands::background_position_y::SpecifiedValue(
::get_initial_specified_value()])), vec![PositionComponent::zero()])),
Importance::Normal), Importance::Normal),
]))), (PropertyDeclaration::BackgroundRepeat(
source_location: SourceLocation { longhands::background_repeat::SpecifiedValue(
line: 15, vec![longhands::background_repeat::single_value
column: 9, ::get_initial_specified_value()])),
}, Importance::Normal),
}))), (PropertyDeclaration::BackgroundAttachment(
CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule { longhands::background_attachment::SpecifiedValue(
name: KeyframesName::Ident(CustomIdent("foo".into())), vec![longhands::background_attachment::single_value
keyframes: vec![ ::get_initial_specified_value()])),
Arc::new(stylesheet.shared_lock.wrap(Keyframe { Importance::Normal),
selector: KeyframeSelector::new_for_unit_testing( (PropertyDeclaration::BackgroundImage(
vec![KeyframePercentage::new(0.)]), longhands::background_image::SpecifiedValue(
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ vec![longhands::background_image::single_value
(PropertyDeclaration::Width( ::get_initial_specified_value()])),
LengthOrPercentageOrAuto::Percentage(Percentage(0.))), Importance::Normal),
Importance::Normal), (PropertyDeclaration::BackgroundSize(
]))) longhands::background_size::SpecifiedValue(
})), vec![longhands::background_size::single_value
Arc::new(stylesheet.shared_lock.wrap(Keyframe { ::get_initial_specified_value()])),
selector: KeyframeSelector::new_for_unit_testing( Importance::Normal),
vec![KeyframePercentage::new(1.)]), (PropertyDeclaration::BackgroundOrigin(
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ longhands::background_origin::SpecifiedValue(
(PropertyDeclaration::Width( vec![longhands::background_origin::single_value
LengthOrPercentageOrAuto::Percentage(Percentage(1.))), ::get_initial_specified_value()])),
Importance::Normal), Importance::Normal),
(PropertyDeclaration::AnimationPlayState( (PropertyDeclaration::BackgroundClip(
animation_play_state::SpecifiedValue( longhands::background_clip::SpecifiedValue(
vec![animation_play_state::SingleSpecifiedValue::running])), vec![longhands::background_clip::single_value
Importance::Normal), ::get_initial_specified_value()])),
]))), Importance::Normal),
})), ]))),
], source_location: SourceLocation {
vendor_prefix: None, line: 15,
source_location: SourceLocation { column: 9,
line: 16, },
column: 19, }))),
}, CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule {
}))) name: KeyframesName::Ident(CustomIdent("foo".into())),
keyframes: vec![
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(
vec![KeyframePercentage::new(0.)]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::Width(
LengthOrPercentageOrAuto::Percentage(Percentage(0.))),
Importance::Normal),
])))
})),
Arc::new(stylesheet.shared_lock.wrap(Keyframe {
selector: KeyframeSelector::new_for_unit_testing(
vec![KeyframePercentage::new(1.)]),
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
(PropertyDeclaration::Width(
LengthOrPercentageOrAuto::Percentage(Percentage(1.))),
Importance::Normal),
(PropertyDeclaration::AnimationPlayState(
animation_play_state::SpecifiedValue(
vec![animation_play_state::SingleSpecifiedValue::running])),
Importance::Normal),
]))),
})),
],
vendor_prefix: None,
source_location: SourceLocation {
line: 16,
column: 19,
},
})))
], &stylesheet.shared_lock), ], &stylesheet.shared_lock),
},
media: Arc::new(stylesheet.shared_lock.wrap(MediaList::empty())),
shared_lock: stylesheet.shared_lock.clone(),
disabled: AtomicBool::new(false),
}; };
assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected)); assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));

View file

@ -12,7 +12,7 @@ use style::media_queries::{Device, MediaList, MediaType};
use style::parser::{Parse, ParserContext}; use style::parser::{Parse, ParserContext};
use style::shared_lock::SharedRwLock; use style::shared_lock::SharedRwLock;
use style::stylearc::Arc; use style::stylearc::Arc;
use style::stylesheets::{CssRuleType, Stylesheet, Origin}; use style::stylesheets::{CssRuleType, Stylesheet, StylesheetInDocument, Origin};
use style::stylesheets::viewport_rule::*; use style::stylesheets::viewport_rule::*;
use style::values::specified::LengthOrPercentageOrAuto::{self, Auto}; use style::values::specified::LengthOrPercentageOrAuto::{self, Auto};
use style::values::specified::NoCalcLength::{self, ViewportPercentage}; use style::values::specified::NoCalcLength::{self, ViewportPercentage};
@ -269,7 +269,11 @@ fn multiple_stylesheets_cascading() {
Author, error_reporter, shared_lock.clone()) Author, error_reporter, shared_lock.clone())
]; ];
let declarations = Cascade::from_stylesheets(stylesheets.iter(), &shared_lock.read(), &device).finish(); let declarations = Cascade::from_stylesheets(
stylesheets.iter().map(|s| &**s),
&shared_lock.read(),
&device,
).finish();
assert_decl_len!(declarations == 3); assert_decl_len!(declarations == 3);
assert_decl_eq!(&declarations[0], UserAgent, Zoom: Zoom::Number(1.)); assert_decl_eq!(&declarations[0], UserAgent, Zoom: Zoom::Number(1.));
assert_decl_eq!(&declarations[1], User, MinHeight: viewport_length!(200., px)); assert_decl_eq!(&declarations[1], User, MinHeight: viewport_length!(200., px));
@ -283,7 +287,11 @@ fn multiple_stylesheets_cascading() {
stylesheet!("@viewport { min-width: 300px !important; min-height: 300px !important; zoom: 3 !important; }", stylesheet!("@viewport { min-width: 300px !important; min-height: 300px !important; zoom: 3 !important; }",
Author, error_reporter, shared_lock.clone()) Author, error_reporter, shared_lock.clone())
]; ];
let declarations = Cascade::from_stylesheets(stylesheets.iter(), &shared_lock.read(), &device).finish(); let declarations = Cascade::from_stylesheets(
stylesheets.iter().map(|s| &**s),
&shared_lock.read(),
&device,
).finish();
assert_decl_len!(declarations == 3); assert_decl_len!(declarations == 3);
assert_decl_eq!(&declarations[0], UserAgent, MinWidth: viewport_length!(100., px), !important); assert_decl_eq!(&declarations[0], UserAgent, MinWidth: viewport_length!(100., px), !important);
assert_decl_eq!(&declarations[1], User, MinHeight: viewport_length!(200., px), !important); assert_decl_eq!(&declarations[1], User, MinHeight: viewport_length!(200., px), !important);