mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
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:
parent
fd65ac8924
commit
1263075776
38 changed files with 3818 additions and 2931 deletions
|
@ -101,6 +101,7 @@ use std::marker::PhantomData;
|
|||
use std::mem as std_mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::process;
|
||||
use std::slice;
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
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::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
|
||||
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::thread_state;
|
||||
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 {
|
||||
/// Creates a new `LayoutThread` structure.
|
||||
fn new(id: PipelineId,
|
||||
|
@ -1146,7 +1158,7 @@ impl LayoutThread {
|
|||
marker: PhantomData,
|
||||
};
|
||||
let needs_dirtying = self.stylist.update(
|
||||
data.document_stylesheets.iter(),
|
||||
StylesheetIterator(data.document_stylesheets.iter()),
|
||||
&guards,
|
||||
Some(ua_stylesheets),
|
||||
data.stylesheets_changed,
|
||||
|
|
|
@ -82,7 +82,13 @@ impl CSSKeyframesRuleMethods for CSSKeyframesRule {
|
|||
|
||||
// https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-appendrule
|
||||
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 {
|
||||
let mut guard = self.cssrule.shared_lock().write();
|
||||
self.keyframesrule.write_with(&mut guard).keyframes.push(rule);
|
||||
|
|
|
@ -93,7 +93,7 @@ impl CSSRuleList {
|
|||
let new_rule =
|
||||
css_rules.insert_rule(&parent_stylesheet.shared_lock,
|
||||
rule,
|
||||
parent_stylesheet,
|
||||
&parent_stylesheet.contents,
|
||||
index,
|
||||
nested,
|
||||
None)?;
|
||||
|
|
|
@ -146,7 +146,7 @@ impl CSSStyleOwner {
|
|||
match *self {
|
||||
CSSStyleOwner::Element(ref el) => window_from_node(&**el).Document().base_url(),
|
||||
CSSStyleOwner::CSSRule(ref rule, _) => {
|
||||
(*rule.parent_stylesheet().style_stylesheet().url_data.read()).clone()
|
||||
(*rule.parent_stylesheet().style_stylesheet().contents.url_data.read()).clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,10 +57,14 @@ impl CSSStyleSheet {
|
|||
}
|
||||
|
||||
fn rulelist(&self) -> Root<CSSRuleList> {
|
||||
self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(),
|
||||
self,
|
||||
RulesSource::Rules(self.style_stylesheet
|
||||
.rules.clone())))
|
||||
self.rulelist.or_init(|| {
|
||||
let rules = self.style_stylesheet.contents.rules.clone();
|
||||
CSSRuleList::new(
|
||||
self.global().as_window(),
|
||||
self,
|
||||
RulesSource::Rules(rules)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn disabled(&self) -> bool {
|
||||
|
|
|
@ -27,7 +27,7 @@ use style::attr::AttrValue;
|
|||
use style::media_queries::MediaList;
|
||||
use style::str::HTML_SPACE_CHARACTERS;
|
||||
use style::stylearc::Arc;
|
||||
use style::stylesheets::{Stylesheet, CssRule, CssRules, Origin, ViewportRule};
|
||||
use style::stylesheets::{Stylesheet, StylesheetContents, CssRule, CssRules, Origin, ViewportRule};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct HTMLMetaElement {
|
||||
|
@ -103,17 +103,20 @@ impl HTMLMetaElement {
|
|||
let shared_lock = document.style_shared_lock();
|
||||
let rule = CssRule::Viewport(Arc::new(shared_lock.wrap(translated_rule)));
|
||||
*self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
|
||||
rules: CssRules::new(vec![rule], shared_lock),
|
||||
origin: Origin::Author,
|
||||
shared_lock: shared_lock.clone(),
|
||||
url_data: RwLock::new(window_from_node(self).get_url()),
|
||||
namespaces: Default::default(),
|
||||
contents: StylesheetContents {
|
||||
rules: CssRules::new(vec![rule], shared_lock),
|
||||
origin: Origin::Author,
|
||||
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())),
|
||||
// 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),
|
||||
shared_lock: shared_lock.clone(),
|
||||
disabled: AtomicBool::new(false),
|
||||
quirks_mode: document.quirks_mode(),
|
||||
}));
|
||||
let doc = document_from_node(self);
|
||||
doc.invalidate_stylesheets();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
use cssparser::SourceLocation;
|
||||
use document_loader::LoadType;
|
||||
use dom::bindings::inheritance::Castable;
|
||||
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::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType};
|
||||
use network_listener::{NetworkListener, PreInvoke};
|
||||
use parking_lot::RwLock;
|
||||
use servo_url::ServoUrl;
|
||||
use std::mem;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
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::stylesheets::{ImportRule, Stylesheet, Origin};
|
||||
use style::stylesheets::{CssRules, ImportRule, Namespaces, Stylesheet, StylesheetContents, Origin};
|
||||
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
|
||||
use style::stylesheets::import_rule::ImportSheet;
|
||||
use style::values::specified::url::SpecifiedUrl;
|
||||
|
||||
pub trait StylesheetOwner {
|
||||
/// 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> {
|
||||
/// Request a stylesheet after parsing a given `@import` rule, and return
|
||||
/// the constructed `@import` rule.
|
||||
fn request_stylesheet(
|
||||
&self,
|
||||
media: Arc<StyleLocked<MediaList>>,
|
||||
make_import: &mut FnMut(Arc<StyleLocked<MediaList>>) -> ImportRule,
|
||||
make_arc: &mut FnMut(ImportRule) -> Arc<StyleLocked<ImportRule>>,
|
||||
) -> Arc<StyleLocked<ImportRule>> {
|
||||
let import = make_import(media);
|
||||
let url = import.url.url().expect("Invalid urls shouldn't enter the loader").clone();
|
||||
url: SpecifiedUrl,
|
||||
source_location: SourceLocation,
|
||||
context: &ParserContext,
|
||||
lock: &SharedRwLock,
|
||||
media: Arc<Locked<MediaList>>,
|
||||
) -> 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
|
||||
// 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());
|
||||
|
||||
make_arc(import)
|
||||
Arc::new(lock.wrap(import))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,13 @@
|
|||
|
||||
#![allow(non_snake_case, missing_docs)]
|
||||
|
||||
use gecko_bindings::bindings::{RawServoImportRule, RawServoSupportsRule};
|
||||
use gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframesRule};
|
||||
use gecko_bindings::bindings::{RawServoMediaList, RawServoMediaRule};
|
||||
use gecko_bindings::bindings::{RawServoNamespaceRule, RawServoPageRule};
|
||||
use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule};
|
||||
use gecko_bindings::bindings::{RawServoStyleSheet, RawServoImportRule, RawServoSupportsRule};
|
||||
use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule, RawServoMediaRule};
|
||||
use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
|
||||
use gecko_bindings::structs::{RawServoDeclarationBlock, RawServoStyleRule};
|
||||
use gecko_bindings::structs::RawServoAnimationValue;
|
||||
use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock, RawServoStyleRule, RawServoMediaList};
|
||||
use gecko_bindings::structs::RawServoStyleSheetContents;
|
||||
use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
|
||||
use media_queries::MediaList;
|
||||
use properties::{ComputedValues, PropertyDeclarationBlock};
|
||||
|
@ -23,7 +22,7 @@ use properties::animated_properties::AnimationValue;
|
|||
use rule_tree::StrongRuleNode;
|
||||
use shared_lock::Locked;
|
||||
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::keyframes_rule::Keyframe;
|
||||
|
||||
|
@ -49,8 +48,8 @@ macro_rules! impl_arc_ffi {
|
|||
impl_arc_ffi!(Locked<CssRules> => ServoCssRules
|
||||
[Servo_CssRules_AddRef, Servo_CssRules_Release]);
|
||||
|
||||
impl_arc_ffi!(Stylesheet => RawServoStyleSheet
|
||||
[Servo_StyleSheet_AddRef, Servo_StyleSheet_Release]);
|
||||
impl_arc_ffi!(StylesheetContents => RawServoStyleSheetContents
|
||||
[Servo_StyleSheetContents_AddRef, Servo_StyleSheetContents_Release]);
|
||||
|
||||
impl_arc_ffi!(ComputedValues => ServoComputedValues
|
||||
[Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]);
|
||||
|
|
|
@ -9,18 +9,108 @@ use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
|||
use dom::TElement;
|
||||
use fnv::FnvHashMap;
|
||||
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::nsIDocument;
|
||||
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
|
||||
use media_queries::Device;
|
||||
use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI};
|
||||
use invalidation::media_queries::{MediaListKey, ToMediaListKey};
|
||||
use media_queries::{Device, MediaList};
|
||||
use properties::ComputedValues;
|
||||
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
|
||||
use stylearc::Arc;
|
||||
use stylesheet_set::StylesheetSet;
|
||||
use stylesheets::Origin;
|
||||
use stylesheets::{Origin, StylesheetContents, StylesheetInDocument};
|
||||
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
|
||||
/// itself.
|
||||
pub struct PerDocumentStyleDataImpl {
|
||||
|
@ -28,7 +118,7 @@ pub struct PerDocumentStyleDataImpl {
|
|||
pub stylist: Stylist,
|
||||
|
||||
/// List of stylesheets, mirrored from Gecko.
|
||||
pub stylesheets: StylesheetSet,
|
||||
pub stylesheets: StylesheetSet<GeckoStyleSheet>,
|
||||
|
||||
/// List of effective font face rules.
|
||||
pub font_faces: Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
|
||||
|
@ -87,12 +177,14 @@ impl PerDocumentStyleDataImpl {
|
|||
let author_style_disabled = self.stylesheets.author_style_disabled();
|
||||
self.stylist.clear();
|
||||
let iter = self.stylesheets.flush(document_element);
|
||||
self.stylist.rebuild(iter,
|
||||
&StylesheetGuards::same(guard),
|
||||
/* ua_sheets = */ None,
|
||||
/* stylesheets_changed = */ true,
|
||||
author_style_disabled,
|
||||
&mut extra_data);
|
||||
self.stylist.rebuild(
|
||||
iter,
|
||||
&StylesheetGuards::same(guard),
|
||||
/* ua_sheets = */ None,
|
||||
/* stylesheets_changed = */ true,
|
||||
author_style_disabled,
|
||||
&mut extra_data
|
||||
);
|
||||
}
|
||||
|
||||
/// Get the default computed values for this document.
|
||||
|
|
|
@ -4334,6 +4334,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms18overlay_scrollbarsE"]
|
||||
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"]
|
||||
pub static nsGkAtoms_windows_default_theme: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms18mac_graphite_themeE"]
|
||||
|
@ -4384,6 +4386,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms23_moz_overlay_scrollbarsE"]
|
||||
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"]
|
||||
pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms23_moz_mac_graphite_themeE"]
|
||||
|
@ -9455,6 +9459,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom;
|
||||
#[link_name = "?overlay_scrollbars@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
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"]
|
||||
pub static nsGkAtoms_windows_default_theme: *mut nsIAtom;
|
||||
#[link_name = "?mac_graphite_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
|
@ -9505,6 +9511,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom;
|
||||
#[link_name = "?_moz_overlay_scrollbars@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
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"]
|
||||
pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom;
|
||||
#[link_name = "?_moz_mac_graphite_theme@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
|
@ -14576,6 +14584,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms_scrollbar_thumb_proportional: *mut nsIAtom;
|
||||
#[link_name = "\x01?overlay_scrollbars@nsGkAtoms@@2PAVnsIAtom@@A"]
|
||||
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"]
|
||||
pub static nsGkAtoms_windows_default_theme: *mut nsIAtom;
|
||||
#[link_name = "\x01?mac_graphite_theme@nsGkAtoms@@2PAVnsIAtom@@A"]
|
||||
|
@ -14626,6 +14636,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms__moz_scrollbar_thumb_proportional: *mut nsIAtom;
|
||||
#[link_name = "\x01?_moz_overlay_scrollbars@nsGkAtoms@@2PAVnsIAtom@@A"]
|
||||
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"]
|
||||
pub static nsGkAtoms__moz_windows_default_theme: *mut nsIAtom;
|
||||
#[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 _) } };
|
||||
("overlay-scrollbars") =>
|
||||
{ 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") =>
|
||||
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_windows_default_theme as *mut _) } };
|
||||
("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 _) } };
|
||||
("-moz-overlay-scrollbars") =>
|
||||
{ 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") =>
|
||||
{ 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") =>
|
||||
|
|
|
@ -24,6 +24,8 @@ use gecko_bindings::structs::RawGeckoFontFaceRuleList;
|
|||
use gecko_bindings::structs::RawGeckoNode;
|
||||
use gecko_bindings::structs::RawServoAnimationValue;
|
||||
use gecko_bindings::structs::RawGeckoServoAnimationValueList;
|
||||
use gecko_bindings::structs::RawServoMediaList;
|
||||
use gecko_bindings::structs::RawServoStyleSheetContents;
|
||||
use gecko_bindings::structs::RawServoDeclarationBlock;
|
||||
use gecko_bindings::structs::RawServoStyleRule;
|
||||
use gecko_bindings::structs::RawGeckoPresContext;
|
||||
|
@ -305,11 +307,9 @@ pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
|
|||
pub type ServoCssRulesBorrowedOrNull<'a> = Option<&'a ServoCssRules>;
|
||||
enum ServoCssRulesVoid { }
|
||||
pub struct ServoCssRules(ServoCssRulesVoid);
|
||||
pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>;
|
||||
pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet;
|
||||
pub type RawServoStyleSheetBorrowedOrNull<'a> = Option<&'a RawServoStyleSheet>;
|
||||
enum RawServoStyleSheetVoid { }
|
||||
pub struct RawServoStyleSheet(RawServoStyleSheetVoid);
|
||||
pub type RawServoStyleSheetContentsStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheetContents>;
|
||||
pub type RawServoStyleSheetContentsBorrowed<'a> = &'a RawServoStyleSheetContents;
|
||||
pub type RawServoStyleSheetContentsBorrowedOrNull<'a> = Option<&'a RawServoStyleSheetContents>;
|
||||
pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>;
|
||||
pub type ServoComputedValuesBorrowed<'a> = &'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 RawServoMediaListBorrowed<'a> = &'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 RawServoMediaRuleBorrowed<'a> = &'a RawServoMediaRule;
|
||||
pub type RawServoMediaRuleBorrowedOrNull<'a> = Option<&'a RawServoMediaRule>;
|
||||
|
@ -390,10 +388,12 @@ extern "C" {
|
|||
pub fn Servo_CssRules_Release(ptr: ServoCssRulesBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_AddRef(ptr: RawServoStyleSheetBorrowed);
|
||||
pub fn Servo_StyleSheetContents_AddRef(ptr:
|
||||
RawServoStyleSheetContentsBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_Release(ptr: RawServoStyleSheetBorrowed);
|
||||
pub fn Servo_StyleSheetContents_Release(ptr:
|
||||
RawServoStyleSheetContentsBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed);
|
||||
|
@ -544,10 +544,10 @@ extern "C" {
|
|||
parent: *mut ServoStyleSheet,
|
||||
reusable_sheets:
|
||||
*mut LoaderReusableStyleSheets,
|
||||
child_sheet: RawServoStyleSheetBorrowed,
|
||||
base_url_data: *mut RawGeckoURLExtraData,
|
||||
url_bytes: *const u8, url_length: u32,
|
||||
media_list: RawServoMediaListStrong);
|
||||
media_list: RawServoMediaListStrong)
|
||||
-> *mut ServoStyleSheet;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u64;
|
||||
|
@ -1416,6 +1416,17 @@ extern "C" {
|
|||
RawGeckoPresContextBorrowed)
|
||||
-> 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" {
|
||||
pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature;
|
||||
}
|
||||
|
@ -1813,53 +1824,41 @@ extern "C" {
|
|||
extern "C" {
|
||||
pub fn Servo_Element_ClearData(node: RawGeckoElementBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_Empty(parsing_mode: SheetParsingMode)
|
||||
-> RawServoStyleSheetStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
|
||||
gecko_stylesheet:
|
||||
*mut ServoStyleSheet,
|
||||
data: *const nsACString,
|
||||
parsing_mode: SheetParsingMode,
|
||||
media_list:
|
||||
*const RawServoMediaList,
|
||||
extra_data:
|
||||
*mut RawGeckoURLExtraData,
|
||||
line_number_offset: u32,
|
||||
quirks_mode: nsCompatibility)
|
||||
-> RawServoStyleSheetStrong;
|
||||
-> RawServoStyleSheetContentsStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_ClearAndUpdate(stylesheet:
|
||||
RawServoStyleSheetBorrowed,
|
||||
loader: *mut Loader,
|
||||
gecko_stylesheet:
|
||||
*mut ServoStyleSheet,
|
||||
data: *const nsACString,
|
||||
extra_data:
|
||||
*mut RawGeckoURLExtraData,
|
||||
line_number_offset: u32,
|
||||
reusable_sheets:
|
||||
*mut LoaderReusableStyleSheets);
|
||||
pub fn Servo_StyleSheet_Empty(parsing_mode: SheetParsingMode)
|
||||
-> RawServoStyleSheetContentsStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
|
||||
pub fn Servo_StyleSheet_HasRules(sheet:
|
||||
RawServoStyleSheetContentsBorrowed)
|
||||
-> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed)
|
||||
pub fn Servo_StyleSheet_GetRules(sheet:
|
||||
RawServoStyleSheetContentsBorrowed)
|
||||
-> ServoCssRulesStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_Clone(sheet: RawServoStyleSheetBorrowed)
|
||||
-> RawServoStyleSheetStrong;
|
||||
pub fn Servo_StyleSheet_Clone(sheet: RawServoStyleSheetContentsBorrowed,
|
||||
reference_sheet: *const ServoStyleSheet)
|
||||
-> RawServoStyleSheetContentsStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_SizeOfIncludingThis(malloc_size_of: MallocSizeOf,
|
||||
sheet:
|
||||
RawServoStyleSheetBorrowed)
|
||||
RawServoStyleSheetContentsBorrowed)
|
||||
-> usize;
|
||||
}
|
||||
extern "C" {
|
||||
|
@ -1882,30 +1881,26 @@ extern "C" {
|
|||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowed,
|
||||
sheet: RawServoStyleSheetBorrowed,
|
||||
unique_id: u64);
|
||||
gecko_sheet:
|
||||
*const ServoStyleSheet);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowed,
|
||||
sheet: RawServoStyleSheetBorrowed,
|
||||
unique_id: u64);
|
||||
gecko_sheet:
|
||||
*const ServoStyleSheet);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_RemoveStyleSheet(set: RawServoStyleSetBorrowed,
|
||||
unique_id: u64);
|
||||
gecko_sheet:
|
||||
*const ServoStyleSheet);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_InsertStyleSheetBefore(set:
|
||||
RawServoStyleSetBorrowed,
|
||||
sheet:
|
||||
RawServoStyleSheetBorrowed,
|
||||
unique_id: u64,
|
||||
before_unique_id: u64);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_UpdateStyleSheet(set: RawServoStyleSetBorrowed,
|
||||
sheet: RawServoStyleSheetBorrowed,
|
||||
unique_id: u64);
|
||||
gecko_sheet:
|
||||
*const ServoStyleSheet,
|
||||
before:
|
||||
*const ServoStyleSheet);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_FlushStyleSheets(set: RawServoStyleSetBorrowed,
|
||||
|
@ -1967,7 +1962,8 @@ extern "C" {
|
|||
}
|
||||
extern "C" {
|
||||
pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
|
||||
sheet: RawServoStyleSheetBorrowed,
|
||||
sheet:
|
||||
RawServoStyleSheetContentsBorrowed,
|
||||
rule: *const nsACString, index: u32,
|
||||
nested: bool, loader: *mut Loader,
|
||||
gecko_stylesheet: *mut ServoStyleSheet,
|
||||
|
@ -2154,7 +2150,7 @@ extern "C" {
|
|||
}
|
||||
extern "C" {
|
||||
pub fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed)
|
||||
-> *const RawServoStyleSheet;
|
||||
-> *const ServoStyleSheet;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed,
|
||||
|
@ -2197,7 +2193,8 @@ extern "C" {
|
|||
}
|
||||
extern "C" {
|
||||
pub fn Servo_KeyframesRule_AppendRule(rule: RawServoKeyframesRuleBorrowed,
|
||||
sheet: RawServoStyleSheetBorrowed,
|
||||
sheet:
|
||||
RawServoStyleSheetContentsBorrowed,
|
||||
css: *const nsACString) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
|
@ -2264,6 +2261,11 @@ extern "C" {
|
|||
nsCSSPropertyID)
|
||||
-> RawServoAnimationValueStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(computed_values:
|
||||
ServoComputedValuesBorrowed)
|
||||
-> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_Property_IsAnimatable(property: nsCSSPropertyID) -> bool;
|
||||
}
|
||||
|
@ -2679,6 +2681,10 @@ extern "C" {
|
|||
set: RawServoStyleSetBorrowed)
|
||||
-> ServoComputedValuesStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_SetExplicitStyle(element: RawGeckoElementBorrowed,
|
||||
primary_style: ServoComputedValuesBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_HasAuthorSpecifiedRules(element: RawGeckoElementBorrowed,
|
||||
rule_type_mask: u32,
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -27,6 +27,13 @@ use stylesheets::{NestedRuleIterationCondition, Stylesheet};
|
|||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
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
|
||||
/// `MediaList`.
|
||||
pub trait ToMediaListKey : Sized {
|
||||
|
|
|
@ -15,7 +15,7 @@ use selector_parser::SelectorImpl;
|
|||
use selectors::attr::CaseSensitivity;
|
||||
use selectors::parser::{Component, Selector};
|
||||
use shared_lock::SharedRwLockReadGuard;
|
||||
use stylesheets::{CssRule, Stylesheet};
|
||||
use stylesheets::{CssRule, StylesheetInDocument};
|
||||
use stylist::Stylist;
|
||||
|
||||
/// 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
|
||||
/// rules, in order to avoid doing a full restyle when we style the document
|
||||
/// next time.
|
||||
pub fn collect_invalidations_for(
|
||||
pub fn collect_invalidations_for<S>(
|
||||
&mut self,
|
||||
stylist: &Stylist,
|
||||
stylesheet: &Stylesheet,
|
||||
guard: &SharedRwLockReadGuard)
|
||||
stylesheet: &S,
|
||||
guard: &SharedRwLockReadGuard
|
||||
)
|
||||
where
|
||||
S: StylesheetInDocument,
|
||||
{
|
||||
debug!("StylesheetInvalidationSet::collect_invalidations_for");
|
||||
if self.fully_invalid {
|
||||
|
@ -92,7 +95,7 @@ impl StylesheetInvalidationSet {
|
|||
return;
|
||||
}
|
||||
|
||||
if stylesheet.disabled() ||
|
||||
if !stylesheet.enabled() ||
|
||||
!stylesheet.is_effective_for_device(stylist.device(), guard) {
|
||||
debug!(" > Stylesheet was not effective");
|
||||
return; // Nothing to do here.
|
||||
|
|
|
@ -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
|
||||
/// guard, in order to be able to read and clone nested structures.
|
||||
pub trait DeepCloneWithLock : Sized {
|
||||
|
@ -235,7 +247,8 @@ pub trait DeepCloneWithLock : Sized {
|
|||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,36 +8,46 @@ use dom::TElement;
|
|||
use invalidation::stylesheets::StylesheetInvalidationSet;
|
||||
use shared_lock::SharedRwLockReadGuard;
|
||||
use std::slice;
|
||||
use stylearc::Arc;
|
||||
use stylesheets::Stylesheet;
|
||||
use stylesheets::StylesheetInDocument;
|
||||
use stylist::Stylist;
|
||||
|
||||
/// Entry for a StylesheetSet. We don't bother creating a constructor, because
|
||||
/// there's no sensible defaults for the member variables.
|
||||
pub struct StylesheetSetEntry {
|
||||
unique_id: u64,
|
||||
sheet: Arc<Stylesheet>,
|
||||
pub struct StylesheetSetEntry<S>
|
||||
where
|
||||
S: StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
sheet: S,
|
||||
}
|
||||
|
||||
/// A iterator over the stylesheets of a list of entries in the StylesheetSet.
|
||||
#[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> {
|
||||
self.0.next().map(|entry| &entry.sheet)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,
|
||||
/// each stylesheet associated with a unique ID.
|
||||
///
|
||||
/// This is only a list of top-level stylesheets, and as such it doesn't
|
||||
/// include recursive `@import` rules.
|
||||
entries: Vec<StylesheetSetEntry>,
|
||||
entries: Vec<StylesheetSetEntry<S>>,
|
||||
|
||||
/// Whether the entries list above has changed since the last restyle.
|
||||
dirty: bool,
|
||||
|
@ -49,7 +59,10 @@ pub struct StylesheetSet {
|
|||
invalidations: StylesheetInvalidationSet,
|
||||
}
|
||||
|
||||
impl StylesheetSet {
|
||||
impl<S> StylesheetSet<S>
|
||||
where
|
||||
S: StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
/// Create a new empty StylesheetSet.
|
||||
pub fn new() -> Self {
|
||||
StylesheetSet {
|
||||
|
@ -66,98 +79,72 @@ impl StylesheetSet {
|
|||
self.author_style_disabled
|
||||
}
|
||||
|
||||
fn remove_stylesheet_if_present(&mut self, unique_id: u64) {
|
||||
self.entries.retain(|x| x.unique_id != unique_id);
|
||||
fn remove_stylesheet_if_present(&mut self, sheet: &S) {
|
||||
self.entries.retain(|entry| entry.sheet != *sheet);
|
||||
}
|
||||
|
||||
/// Appends a new stylesheet to the current set.
|
||||
pub fn append_stylesheet(
|
||||
&mut self,
|
||||
stylist: &Stylist,
|
||||
sheet: &Arc<Stylesheet>,
|
||||
unique_id: u64,
|
||||
guard: &SharedRwLockReadGuard)
|
||||
{
|
||||
sheet: S,
|
||||
guard: &SharedRwLockReadGuard
|
||||
) {
|
||||
debug!("StylesheetSet::append_stylesheet");
|
||||
self.remove_stylesheet_if_present(unique_id);
|
||||
self.entries.push(StylesheetSetEntry {
|
||||
unique_id: unique_id,
|
||||
sheet: sheet.clone(),
|
||||
});
|
||||
self.dirty = true;
|
||||
self.remove_stylesheet_if_present(&sheet);
|
||||
self.invalidations.collect_invalidations_for(
|
||||
stylist,
|
||||
sheet,
|
||||
guard)
|
||||
&sheet,
|
||||
guard
|
||||
);
|
||||
self.dirty = true;
|
||||
self.entries.push(StylesheetSetEntry { sheet });
|
||||
}
|
||||
|
||||
/// Prepend a new stylesheet to the current set.
|
||||
pub fn prepend_stylesheet(
|
||||
&mut self,
|
||||
stylist: &Stylist,
|
||||
sheet: &Arc<Stylesheet>,
|
||||
unique_id: u64,
|
||||
guard: &SharedRwLockReadGuard)
|
||||
{
|
||||
sheet: S,
|
||||
guard: &SharedRwLockReadGuard
|
||||
) {
|
||||
debug!("StylesheetSet::prepend_stylesheet");
|
||||
self.remove_stylesheet_if_present(unique_id);
|
||||
self.entries.insert(0, StylesheetSetEntry {
|
||||
unique_id: unique_id,
|
||||
sheet: sheet.clone(),
|
||||
});
|
||||
self.dirty = true;
|
||||
self.remove_stylesheet_if_present(&sheet);
|
||||
self.invalidations.collect_invalidations_for(
|
||||
stylist,
|
||||
sheet,
|
||||
guard)
|
||||
&sheet,
|
||||
guard
|
||||
);
|
||||
self.entries.insert(0, StylesheetSetEntry { sheet });
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
/// Insert a given stylesheet before another stylesheet in the document.
|
||||
pub fn insert_stylesheet_before(
|
||||
&mut self,
|
||||
stylist: &Stylist,
|
||||
sheet: &Arc<Stylesheet>,
|
||||
unique_id: u64,
|
||||
before_unique_id: u64,
|
||||
sheet: S,
|
||||
before_sheet: S,
|
||||
guard: &SharedRwLockReadGuard)
|
||||
{
|
||||
debug!("StylesheetSet::insert_stylesheet_before");
|
||||
self.remove_stylesheet_if_present(unique_id);
|
||||
let index = self.entries.iter().position(|x| {
|
||||
x.unique_id == before_unique_id
|
||||
}).expect("`before_unique_id` stylesheet not found");
|
||||
self.entries.insert(index, StylesheetSetEntry {
|
||||
unique_id: unique_id,
|
||||
sheet: sheet.clone(),
|
||||
});
|
||||
self.dirty = true;
|
||||
self.remove_stylesheet_if_present(&sheet);
|
||||
let index = self.entries.iter().position(|entry| {
|
||||
entry.sheet == before_sheet
|
||||
}).expect("`before_sheet` stylesheet not found");
|
||||
self.invalidations.collect_invalidations_for(
|
||||
stylist,
|
||||
sheet,
|
||||
guard)
|
||||
}
|
||||
|
||||
/// Update the sheet that matches the unique_id.
|
||||
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();
|
||||
}
|
||||
&sheet,
|
||||
guard
|
||||
);
|
||||
self.entries.insert(index, StylesheetSetEntry { sheet });
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
/// 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");
|
||||
self.remove_stylesheet_if_present(unique_id);
|
||||
self.remove_stylesheet_if_present(&sheet);
|
||||
self.dirty = true;
|
||||
// FIXME(emilio): We can do better!
|
||||
self.invalidations.invalidate_fully();
|
||||
|
@ -181,10 +168,12 @@ impl StylesheetSet {
|
|||
|
||||
/// Flush the current set, unmarking it as dirty, and returns an iterator
|
||||
/// over the new stylesheet list.
|
||||
pub fn flush<E>(&mut self,
|
||||
document_element: Option<E>)
|
||||
-> StylesheetIterator
|
||||
where E: TElement,
|
||||
pub fn flush<E>(
|
||||
&mut self,
|
||||
document_element: Option<E>
|
||||
) -> StylesheetIterator<S>
|
||||
where
|
||||
E: TElement,
|
||||
{
|
||||
debug!("StylesheetSet::flush");
|
||||
debug_assert!(self.dirty);
|
||||
|
@ -196,7 +185,7 @@ impl StylesheetSet {
|
|||
}
|
||||
|
||||
/// Returns an iterator over the current list of stylesheets.
|
||||
pub fn iter(&self) -> StylesheetIterator {
|
||||
pub fn iter(&self) -> StylesheetIterator<S> {
|
||||
StylesheetIterator(self.entries.iter())
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
use cssparser::{Parser, Token, SourceLocation, BasicParseError};
|
||||
use media_queries::Device;
|
||||
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 style_traits::{ToCss, ParseError, StyleParseError};
|
||||
use stylearc::Arc;
|
||||
|
@ -47,11 +47,12 @@ impl DeepCloneWithLock for DocumentRule {
|
|||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
let rules = self.rules.read_with(guard);
|
||||
DocumentRule {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,72 @@
|
|||
//! [import]: https://drafts.csswg.org/css-cascade-3/#at-import
|
||||
|
||||
use cssparser::SourceLocation;
|
||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use media_queries::MediaList;
|
||||
use shared_lock::{DeepCloneWithLock, DeepCloneParams, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use stylearc::Arc;
|
||||
use stylesheets::stylesheet::Stylesheet;
|
||||
use stylesheets::{StylesheetContents, StylesheetInDocument};
|
||||
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.
|
||||
///
|
||||
/// [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
|
||||
/// when it loads.
|
||||
pub stylesheet: Arc<Stylesheet>,
|
||||
pub stylesheet: ImportSheet,
|
||||
|
||||
/// The line and column of the rule's source code.
|
||||
pub source_location: SourceLocation,
|
||||
}
|
||||
|
||||
impl Clone for ImportRule {
|
||||
fn clone(&self) -> ImportRule {
|
||||
let stylesheet: &Stylesheet = &*self.stylesheet;
|
||||
impl DeepCloneWithLock for ImportRule {
|
||||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
ImportRule {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
@ -49,11 +112,15 @@ impl ToCssWithGuard for ImportRule {
|
|||
{
|
||||
dest.write_str("@import ")?;
|
||||
self.url.to_css(dest)?;
|
||||
let media = self.stylesheet.media.read_with(guard);
|
||||
if !media.is_empty() {
|
||||
dest.write_str(" ")?;
|
||||
media.to_css(dest)?;
|
||||
}
|
||||
|
||||
match self.stylesheet.media(guard) {
|
||||
Some(media) if !media.is_empty() => {
|
||||
dest.write_str(" ")?;
|
||||
media.to_css(dest)?;
|
||||
}
|
||||
_ => {},
|
||||
};
|
||||
|
||||
dest.write_str(";")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ use properties::LonghandIdSet;
|
|||
use properties::animated_properties::AnimatableLonghand;
|
||||
use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction;
|
||||
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 style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError};
|
||||
use stylearc::Arc;
|
||||
use stylesheets::{CssRuleType, Stylesheet};
|
||||
use stylesheets::{CssRuleType, StylesheetContents};
|
||||
use stylesheets::rule_parser::VendorPrefix;
|
||||
use values::KeyframesName;
|
||||
|
||||
|
@ -78,13 +78,17 @@ impl DeepCloneWithLock for KeyframesRule {
|
|||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
KeyframesRule {
|
||||
name: self.name.clone(),
|
||||
keyframes: self.keyframes.iter()
|
||||
.map(|ref x| Arc::new(lock.wrap(
|
||||
x.read_with(guard).deep_clone_with_lock(lock, guard))))
|
||||
.map(|x| {
|
||||
Arc::new(lock.wrap(
|
||||
x.read_with(guard).deep_clone_with_lock(lock, guard, params)
|
||||
))
|
||||
})
|
||||
.collect(),
|
||||
vendor_prefix: self.vendor_prefix.clone(),
|
||||
source_location: self.source_location.clone(),
|
||||
|
@ -202,23 +206,26 @@ impl ToCssWithGuard for Keyframe {
|
|||
|
||||
impl Keyframe {
|
||||
/// Parse a CSS keyframe.
|
||||
pub fn parse<'i>(css: &'i str, parent_stylesheet: &Stylesheet)
|
||||
-> Result<Arc<Locked<Self>>, ParseError<'i>> {
|
||||
let url_data = parent_stylesheet.url_data.read();
|
||||
pub fn parse<'i>(
|
||||
css: &'i str,
|
||||
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 context = ParserContext::new(parent_stylesheet.origin,
|
||||
let context = ParserContext::new(parent_stylesheet_contents.origin,
|
||||
&url_data,
|
||||
&error_reporter,
|
||||
Some(CssRuleType::Keyframe),
|
||||
PARSING_MODE_DEFAULT,
|
||||
parent_stylesheet.quirks_mode);
|
||||
parent_stylesheet_contents.quirks_mode);
|
||||
let mut input = ParserInput::new(css);
|
||||
let mut input = Parser::new(&mut input);
|
||||
|
||||
let mut declarations = SourcePropertyDeclaration::new();
|
||||
let mut rule_parser = KeyframeListParser {
|
||||
context: &context,
|
||||
shared_lock: &parent_stylesheet.shared_lock,
|
||||
shared_lock: &lock,
|
||||
declarations: &mut declarations,
|
||||
};
|
||||
parse_one_rule(&mut input, &mut rule_parser)
|
||||
|
@ -230,7 +237,8 @@ impl DeepCloneWithLock for Keyframe {
|
|||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard
|
||||
guard: &SharedRwLockReadGuard,
|
||||
_params: &DeepCloneParams,
|
||||
) -> Keyframe {
|
||||
Keyframe {
|
||||
selector: self.selector.clone(),
|
||||
|
|
|
@ -5,39 +5,25 @@
|
|||
//! The stylesheet loader is the abstraction used to trigger network requests
|
||||
//! for `@import` rules.
|
||||
|
||||
use cssparser::SourceLocation;
|
||||
use media_queries::MediaList;
|
||||
use shared_lock::Locked;
|
||||
use parser::ParserContext;
|
||||
use shared_lock::{Locked, SharedRwLock};
|
||||
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
|
||||
/// for `@import` rules.
|
||||
pub trait StylesheetLoader {
|
||||
/// Request a stylesheet after parsing a given `@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 they’re locked, while keeping the trait object-safe.
|
||||
/// Request a stylesheet after parsing a given `@import` rule, and return
|
||||
/// the constructed `@import` rule.
|
||||
fn request_stylesheet(
|
||||
&self,
|
||||
url: SpecifiedUrl,
|
||||
location: SourceLocation,
|
||||
context: &ParserContext,
|
||||
lock: &SharedRwLock,
|
||||
media: Arc<Locked<MediaList>>,
|
||||
make_import: &mut FnMut(Arc<Locked<MediaList>>) -> ImportRule,
|
||||
make_arc: &mut FnMut(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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use cssparser::SourceLocation;
|
||||
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 style_traits::ToCss;
|
||||
use stylearc::Arc;
|
||||
|
@ -47,13 +47,14 @@ impl DeepCloneWithLock for MediaRule {
|
|||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
let media_queries = self.media_queries.read_with(guard);
|
||||
let rules = self.rules.read_with(guard);
|
||||
MediaRule {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
mod counter_style_rule;
|
||||
mod document_rule;
|
||||
mod font_face_rule;
|
||||
mod import_rule;
|
||||
pub mod import_rule;
|
||||
pub mod keyframes_rule;
|
||||
mod loader;
|
||||
mod media_rule;
|
||||
|
@ -25,7 +25,7 @@ pub mod viewport_rule;
|
|||
use cssparser::{parse_one_rule, Parser, ParserInput};
|
||||
use error_reporting::NullReporter;
|
||||
use parser::ParserContext;
|
||||
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::fmt;
|
||||
use style_traits::PARSING_MODE_DEFAULT;
|
||||
use stylearc::Arc;
|
||||
|
@ -43,7 +43,7 @@ pub use self::page_rule::PageRule;
|
|||
pub use self::rule_parser::{State, TopLevelRuleParser};
|
||||
pub use self::rule_list::{CssRules, CssRulesHelpers};
|
||||
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::supports_rule::SupportsRule;
|
||||
pub use self::viewport_rule::ViewportRule;
|
||||
|
@ -221,32 +221,33 @@ impl CssRule {
|
|||
/// Input state is None for a nested rule
|
||||
pub fn parse(
|
||||
css: &str,
|
||||
parent_stylesheet: &Stylesheet,
|
||||
parent_stylesheet_contents: &StylesheetContents,
|
||||
shared_lock: &SharedRwLock,
|
||||
state: Option<State>,
|
||||
loader: Option<&StylesheetLoader>
|
||||
) -> 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 context = ParserContext::new(
|
||||
parent_stylesheet.origin,
|
||||
parent_stylesheet_contents.origin,
|
||||
&url_data,
|
||||
&error_reporter,
|
||||
None,
|
||||
PARSING_MODE_DEFAULT,
|
||||
parent_stylesheet.quirks_mode
|
||||
parent_stylesheet_contents.quirks_mode,
|
||||
);
|
||||
|
||||
let mut input = ParserInput::new(css);
|
||||
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
|
||||
let state = state.unwrap_or(State::Body);
|
||||
let mut rule_parser = TopLevelRuleParser {
|
||||
stylesheet_origin: parent_stylesheet.origin,
|
||||
stylesheet_origin: parent_stylesheet_contents.origin,
|
||||
context: context,
|
||||
shared_lock: &parent_stylesheet.shared_lock,
|
||||
shared_lock: &shared_lock,
|
||||
loader: loader,
|
||||
state: state,
|
||||
namespaces: Some(&mut *guard),
|
||||
|
@ -270,6 +271,7 @@ impl DeepCloneWithLock for CssRule {
|
|||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> CssRule {
|
||||
match *self {
|
||||
CssRule::Namespace(ref arc) => {
|
||||
|
@ -277,18 +279,19 @@ impl DeepCloneWithLock for CssRule {
|
|||
CssRule::Namespace(Arc::new(lock.wrap(rule.clone())))
|
||||
},
|
||||
CssRule::Import(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Import(Arc::new(lock.wrap(rule.clone())))
|
||||
let rule = arc.read_with(guard)
|
||||
.deep_clone_with_lock(lock, guard, params);
|
||||
CssRule::Import(Arc::new(lock.wrap(rule)))
|
||||
},
|
||||
CssRule::Style(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
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) => {
|
||||
let rule = arc.read_with(guard);
|
||||
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) => {
|
||||
let rule = arc.read_with(guard);
|
||||
|
@ -307,22 +310,22 @@ impl DeepCloneWithLock for CssRule {
|
|||
CssRule::Keyframes(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
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) => {
|
||||
let rule = arc.read_with(guard);
|
||||
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) => {
|
||||
let rule = arc.read_with(guard);
|
||||
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) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Document(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard))))
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use cssparser::SourceLocation;
|
||||
use properties::PropertyDeclarationBlock;
|
||||
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use stylearc::Arc;
|
||||
|
@ -51,6 +51,7 @@ impl DeepCloneWithLock for PageRule {
|
|||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
_params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
PageRule {
|
||||
block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())),
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
//! A list of CSS rules.
|
||||
|
||||
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
|
||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
|
||||
use stylearc::Arc;
|
||||
use stylesheets::{CssRule, RulesMutateError};
|
||||
use stylesheets::loader::StylesheetLoader;
|
||||
use stylesheets::memory::{MallocSizeOfFn, MallocSizeOfWithGuard};
|
||||
use stylesheets::rule_parser::State;
|
||||
use stylesheets::stylesheet::Stylesheet;
|
||||
use stylesheets::stylesheet::StylesheetContents;
|
||||
|
||||
/// A list of CSS rules.
|
||||
#[derive(Debug)]
|
||||
|
@ -27,11 +27,12 @@ impl DeepCloneWithLock for CssRules {
|
|||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
CssRules(
|
||||
self.0.iter().map(|ref x| x.deep_clone_with_lock(lock, guard)).collect()
|
||||
)
|
||||
CssRules(self.0.iter().map(|x| {
|
||||
x.deep_clone_with_lock(lock, guard, params)
|
||||
}).collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +102,7 @@ pub trait CssRulesHelpers {
|
|||
fn insert_rule(&self,
|
||||
lock: &SharedRwLock,
|
||||
rule: &str,
|
||||
parent_stylesheet: &Stylesheet,
|
||||
parent_stylesheet_contents: &StylesheetContents,
|
||||
index: usize,
|
||||
nested: bool,
|
||||
loader: Option<&StylesheetLoader>)
|
||||
|
@ -112,7 +113,7 @@ impl CssRulesHelpers for Arc<Locked<CssRules>> {
|
|||
fn insert_rule(&self,
|
||||
lock: &SharedRwLock,
|
||||
rule: &str,
|
||||
parent_stylesheet: &Stylesheet,
|
||||
parent_stylesheet_contents: &StylesheetContents,
|
||||
index: usize,
|
||||
nested: bool,
|
||||
loader: Option<&StylesheetLoader>)
|
||||
|
@ -139,7 +140,13 @@ impl CssRulesHelpers for Arc<Locked<CssRules>> {
|
|||
// Step 3, 4
|
||||
// XXXManishearth should we also store the namespace map?
|
||||
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();
|
||||
|
|
|
@ -11,7 +11,6 @@ use cssparser::{CompactCowStr, SourceLocation};
|
|||
use error_reporting::ContextualParseError;
|
||||
use font_face::parse_font_face_block;
|
||||
use media_queries::{parse_media_query_list, MediaList};
|
||||
use parking_lot::RwLock;
|
||||
use parser::{Parse, ParserContext, log_css_error};
|
||||
use properties::parse_property_declaration_list;
|
||||
use selector_parser::{SelectorImpl, SelectorParser};
|
||||
|
@ -19,17 +18,15 @@ use selectors::SelectorList;
|
|||
use selectors::parser::SelectorParseError;
|
||||
use shared_lock::{Locked, SharedRwLock};
|
||||
use std::borrow::Cow;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use str::starts_with_ignore_ascii_case;
|
||||
use style_traits::{StyleParseError, ParseError};
|
||||
use stylearc::Arc;
|
||||
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::document_rule::DocumentCondition;
|
||||
use stylesheets::keyframes_rule::parse_keyframe_list;
|
||||
use stylesheets::loader::NoOpLoader;
|
||||
use stylesheets::stylesheet::{Namespaces, Stylesheet};
|
||||
use stylesheets::stylesheet::Namespaces;
|
||||
use stylesheets::supports_rule::SupportsCondition;
|
||||
use stylesheets::viewport_rule;
|
||||
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 = Arc::new(self.shared_lock.wrap(media));
|
||||
|
||||
let noop_loader = NoOpLoader;
|
||||
let loader = if !specified_url.is_invalid() {
|
||||
self.loader.expect("Expected a stylesheet loader for @import")
|
||||
} else {
|
||||
&noop_loader
|
||||
};
|
||||
let loader =
|
||||
self.loader.expect("Expected a stylesheet loader for @import");
|
||||
|
||||
let mut specified_url = Some(specified_url);
|
||||
let arc = loader.request_stylesheet(media, &mut |media| {
|
||||
ImportRule {
|
||||
url: specified_url.take().unwrap(),
|
||||
stylesheet: Arc::new(Stylesheet {
|
||||
rules: CssRules::new(Vec::new(), self.shared_lock),
|
||||
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))
|
||||
});
|
||||
let import_rule = loader.request_stylesheet(
|
||||
specified_url,
|
||||
location,
|
||||
&self.context,
|
||||
&self.shared_lock,
|
||||
media,
|
||||
);
|
||||
|
||||
return Ok(AtRuleType::WithoutBlock(CssRule::Import(arc)))
|
||||
return Ok(AtRuleType::WithoutBlock(CssRule::Import(import_rule)))
|
||||
},
|
||||
"namespace" => {
|
||||
if self.state > State::Namespaces {
|
||||
|
|
|
@ -10,6 +10,7 @@ use shared_lock::SharedRwLockReadGuard;
|
|||
use smallvec::SmallVec;
|
||||
use std::slice;
|
||||
use stylesheets::{CssRule, CssRules, DocumentRule, ImportRule, MediaRule, SupportsRule};
|
||||
use stylesheets::StylesheetInDocument;
|
||||
|
||||
/// An iterator over a list of rules.
|
||||
pub struct RulesIterator<'a, 'b, C>
|
||||
|
@ -96,7 +97,9 @@ impl<'a, 'b, C> Iterator for RulesIterator<'a, 'b, C>
|
|||
import_rule) {
|
||||
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) => {
|
||||
let doc_rule = doc_rule.read_with(self.guard);
|
||||
|
@ -182,11 +185,11 @@ impl NestedRuleIterationCondition for EffectiveRules {
|
|||
fn process_import(
|
||||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
_quirks_mode: QuirksMode,
|
||||
rule: &ImportRule)
|
||||
-> bool
|
||||
{
|
||||
rule.stylesheet.media.read_with(guard).evaluate(device, quirks_mode)
|
||||
rule.stylesheet.is_effective_for_device(device, guard)
|
||||
}
|
||||
|
||||
fn process_media(
|
||||
|
|
|
@ -8,7 +8,7 @@ use cssparser::SourceLocation;
|
|||
use properties::PropertyDeclarationBlock;
|
||||
use selector_parser::SelectorImpl;
|
||||
use selectors::SelectorList;
|
||||
use shared_lock::{DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use stylearc::Arc;
|
||||
|
@ -31,6 +31,7 @@ impl DeepCloneWithLock for StyleRule {
|
|||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
_params: &DeepCloneParams,
|
||||
) -> StyleRule {
|
||||
StyleRule {
|
||||
selectors: self.selectors.clone(),
|
||||
|
|
|
@ -10,7 +10,7 @@ use fnv::FnvHashMap;
|
|||
use media_queries::{MediaList, Device};
|
||||
use parking_lot::RwLock;
|
||||
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::sync::atomic::{AtomicBool, Ordering};
|
||||
use style_traits::PARSING_MODE_DEFAULT;
|
||||
|
@ -42,28 +42,232 @@ pub struct Namespaces {
|
|||
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)]
|
||||
pub struct Stylesheet {
|
||||
pub struct StylesheetContents {
|
||||
/// List of rules in the order they were found (important for
|
||||
/// cascading order)
|
||||
pub rules: Arc<Locked<CssRules>>,
|
||||
/// List of media associated with the Stylesheet.
|
||||
pub media: Arc<Locked<MediaList>>,
|
||||
/// The origin of this stylesheet.
|
||||
pub origin: Origin,
|
||||
/// The url data this stylesheet should use.
|
||||
pub url_data: RwLock<UrlExtraData>,
|
||||
/// The lock used for objects inside this stylesheet
|
||||
pub shared_lock: SharedRwLock,
|
||||
/// The namespaces that apply to this stylesheet.
|
||||
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.
|
||||
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 {
|
||||
|
@ -79,23 +283,26 @@ impl Stylesheet {
|
|||
Stylesheet::parse_rules(
|
||||
css,
|
||||
&url_data,
|
||||
existing.origin,
|
||||
existing.contents.origin,
|
||||
&mut *namespaces.write(),
|
||||
&existing.shared_lock,
|
||||
stylesheet_loader,
|
||||
error_reporter,
|
||||
existing.quirks_mode,
|
||||
existing.contents.quirks_mode,
|
||||
line_number_offset
|
||||
);
|
||||
|
||||
*existing.url_data.write() = url_data;
|
||||
mem::swap(&mut *existing.namespaces.write(), &mut *namespaces.write());
|
||||
existing.dirty_on_viewport_size_change
|
||||
*existing.contents.url_data.write() = url_data;
|
||||
mem::swap(
|
||||
&mut *existing.contents.namespaces.write(),
|
||||
&mut *namespaces.write()
|
||||
);
|
||||
existing.contents.dirty_on_viewport_size_change
|
||||
.store(dirty_on_viewport_size_change, Ordering::Release);
|
||||
|
||||
// Acquire the lock *after* parsing, to minimize the exclusive section.
|
||||
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(
|
||||
|
@ -169,35 +376,28 @@ impl Stylesheet {
|
|||
quirks_mode: QuirksMode,
|
||||
line_number_offset: u64)
|
||||
-> Stylesheet {
|
||||
let namespaces = RwLock::new(Namespaces::default());
|
||||
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
|
||||
let contents = StylesheetContents::from_str(
|
||||
css,
|
||||
&url_data,
|
||||
url_data,
|
||||
origin,
|
||||
&mut *namespaces.write(),
|
||||
&shared_lock,
|
||||
stylesheet_loader,
|
||||
error_reporter,
|
||||
quirks_mode,
|
||||
line_number_offset,
|
||||
line_number_offset
|
||||
);
|
||||
|
||||
Stylesheet {
|
||||
origin: origin,
|
||||
url_data: RwLock::new(url_data),
|
||||
namespaces: namespaces,
|
||||
rules: CssRules::new(rules, &shared_lock),
|
||||
media: media,
|
||||
shared_lock: shared_lock,
|
||||
dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change),
|
||||
contents,
|
||||
shared_lock,
|
||||
media,
|
||||
disabled: AtomicBool::new(false),
|
||||
quirks_mode: quirks_mode,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether this stylesheet can be dirty on viewport size change.
|
||||
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
|
||||
|
@ -212,43 +412,10 @@ impl Stylesheet {
|
|||
/// Instead, we conservatively assume there might be some.
|
||||
/// Restyling will some some more work than necessary, but give correct results.
|
||||
pub fn inserted_has_viewport_percentages(&self, has_viewport_percentages: bool) {
|
||||
self.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))
|
||||
self.contents.dirty_on_viewport_size_change.fetch_or(
|
||||
has_viewport_percentages,
|
||||
Ordering::SeqCst
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns whether the stylesheet has been explicitly disabled through the
|
||||
|
@ -269,76 +436,28 @@ impl Stylesheet {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
impl Clone for Stylesheet {
|
||||
fn clone(&self) -> Stylesheet {
|
||||
fn clone(&self) -> Self {
|
||||
// Create a new lock for our clone.
|
||||
let lock = self.shared_lock.clone();
|
||||
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.
|
||||
let media = self.media.read_with(&guard);
|
||||
let cloned_media = media.clone();
|
||||
let media = self.media.read_with(&guard).clone();
|
||||
let media = Arc::new(lock.wrap(media));
|
||||
let contents = self.contents.deep_clone_with_lock(
|
||||
&lock,
|
||||
&guard,
|
||||
&DeepCloneParams
|
||||
);
|
||||
|
||||
Stylesheet {
|
||||
rules: Arc::new(lock.wrap(cloned_rules)),
|
||||
media: Arc::new(lock.wrap(cloned_media)),
|
||||
origin: self.origin,
|
||||
url_data: RwLock::new((*self.url_data.read()).clone()),
|
||||
contents,
|
||||
media: media,
|
||||
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)),
|
||||
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),
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token};
|
|||
use parser::ParserContext;
|
||||
use properties::{PropertyId, PropertyDeclaration, SourcePropertyDeclaration};
|
||||
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 style_traits::{ToCss, ParseError, StyleParseError};
|
||||
use stylearc::Arc;
|
||||
|
@ -48,12 +48,13 @@ impl DeepCloneWithLock for SupportsRule {
|
|||
fn deep_clone_with_lock(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
guard: &SharedRwLockReadGuard
|
||||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
let rules = self.rules.read_with(guard);
|
||||
SupportsRule {
|
||||
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,
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@ use std::iter::Enumerate;
|
|||
use std::str::Chars;
|
||||
use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseError};
|
||||
use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
|
||||
use stylearc::Arc;
|
||||
use stylesheets::{Stylesheet, Origin};
|
||||
use stylesheets::{StylesheetInDocument, Origin};
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::specified::{NoCalcLength, LengthOrPercentageOrAuto, ViewportPercentageLength};
|
||||
|
||||
|
@ -563,11 +562,14 @@ impl Cascade {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_stylesheets<'a, I>(stylesheets: I,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device)
|
||||
-> Self
|
||||
where I: Iterator<Item = &'a Arc<Stylesheet>>,
|
||||
pub fn from_stylesheets<'a, I, S>(
|
||||
stylesheets: I,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device
|
||||
) -> Self
|
||||
where
|
||||
I: Iterator<Item = &'a S>,
|
||||
S: StylesheetInDocument + 'static,
|
||||
{
|
||||
let mut cascade = Self::new();
|
||||
for stylesheet in stylesheets {
|
||||
|
|
|
@ -15,7 +15,7 @@ use font_metrics::FontMetricsProvider;
|
|||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::structs::{nsIAtom, StyleRuleInclusion};
|
||||
use invalidation::element::invalidation_map::InvalidationMap;
|
||||
use invalidation::media_queries::EffectiveMediaQueryResults;
|
||||
use invalidation::media_queries::{EffectiveMediaQueryResults, ToMediaListKey};
|
||||
use matching::CascadeVisitedMode;
|
||||
use media_queries::Device;
|
||||
use properties::{self, CascadeFlags, ComputedValues};
|
||||
|
@ -43,7 +43,7 @@ use stylearc::Arc;
|
|||
#[cfg(feature = "gecko")]
|
||||
use stylesheets::{CounterStyleRule, FontFaceRule};
|
||||
use stylesheets::{CssRule, StyleRule};
|
||||
use stylesheets::{Stylesheet, Origin, UserAgentStylesheets};
|
||||
use stylesheets::{StylesheetInDocument, Origin, UserAgentStylesheets};
|
||||
use stylesheets::keyframes_rule::KeyframesAnimation;
|
||||
use stylesheets::viewport_rule::{self, MaybeNew, ViewportRule};
|
||||
use thread_state;
|
||||
|
@ -342,14 +342,18 @@ impl Stylist {
|
|||
/// This method resets all the style data each time the stylesheets change
|
||||
/// (which is indicated by the `stylesheets_changed` parameter), or the
|
||||
/// device is dirty, which means we need to re-evaluate media queries.
|
||||
pub fn rebuild<'a, 'b, I>(&mut self,
|
||||
doc_stylesheets: I,
|
||||
guards: &StylesheetGuards,
|
||||
ua_stylesheets: Option<&UserAgentStylesheets>,
|
||||
stylesheets_changed: bool,
|
||||
author_style_disabled: bool,
|
||||
extra_data: &mut ExtraStyleData<'a>) -> bool
|
||||
where I: Iterator<Item = &'b Arc<Stylesheet>> + Clone,
|
||||
pub fn rebuild<'a, 'b, I, S>(
|
||||
&mut self,
|
||||
doc_stylesheets: I,
|
||||
guards: &StylesheetGuards,
|
||||
ua_stylesheets: Option<&UserAgentStylesheets>,
|
||||
stylesheets_changed: bool,
|
||||
author_style_disabled: bool,
|
||||
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);
|
||||
|
||||
|
@ -398,7 +402,7 @@ impl Stylist {
|
|||
|
||||
if let Some(ua_stylesheets) = ua_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 {
|
||||
|
@ -409,10 +413,10 @@ impl Stylist {
|
|||
|
||||
// Only use author stylesheets if author styles are enabled.
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -429,14 +433,18 @@ impl Stylist {
|
|||
|
||||
/// clear the stylist and then rebuild it. Chances are, you want to use
|
||||
/// either clear() or rebuild(), with the latter done lazily, instead.
|
||||
pub fn update<'a, 'b, I>(&mut self,
|
||||
doc_stylesheets: I,
|
||||
guards: &StylesheetGuards,
|
||||
ua_stylesheets: Option<&UserAgentStylesheets>,
|
||||
stylesheets_changed: bool,
|
||||
author_style_disabled: bool,
|
||||
extra_data: &mut ExtraStyleData<'a>) -> bool
|
||||
where I: Iterator<Item = &'b Arc<Stylesheet>> + Clone,
|
||||
pub fn update<'a, 'b, I, S>(
|
||||
&mut self,
|
||||
doc_stylesheets: I,
|
||||
guards: &StylesheetGuards,
|
||||
ua_stylesheets: Option<&UserAgentStylesheets>,
|
||||
stylesheets_changed: bool,
|
||||
author_style_disabled: bool,
|
||||
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);
|
||||
|
||||
|
@ -450,16 +458,23 @@ impl Stylist {
|
|||
author_style_disabled, extra_data)
|
||||
}
|
||||
|
||||
fn add_stylesheet<'a>(&mut self,
|
||||
stylesheet: &Stylesheet,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
_extra_data: &mut ExtraStyleData<'a>) {
|
||||
if stylesheet.disabled() || !stylesheet.is_effective_for_device(&self.device, guard) {
|
||||
fn add_stylesheet<'a, S>(
|
||||
&mut self,
|
||||
stylesheet: &S,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
_extra_data: &mut ExtraStyleData<'a>
|
||||
)
|
||||
where
|
||||
S: StylesheetInDocument + ToMediaListKey + 'static,
|
||||
{
|
||||
if !stylesheet.enabled() ||
|
||||
!stylesheet.is_effective_for_device(&self.device, guard) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.effective_media_query_results.saw_effective(stylesheet);
|
||||
|
||||
let origin = stylesheet.origin(guard);
|
||||
for rule in stylesheet.effective_rules(&self.device, guard) {
|
||||
match *rule {
|
||||
CssRule::Style(ref locked) => {
|
||||
|
@ -472,9 +487,9 @@ impl Stylist {
|
|||
self.pseudos_map
|
||||
.entry(pseudo.canonical())
|
||||
.or_insert_with(PerPseudoElementSelectorMap::new)
|
||||
.borrow_for_origin(&stylesheet.origin)
|
||||
.borrow_for_origin(&origin)
|
||||
} else {
|
||||
self.element_map.borrow_for_origin(&stylesheet.origin)
|
||||
self.element_map.borrow_for_origin(&origin)
|
||||
};
|
||||
|
||||
map.insert(
|
||||
|
@ -529,7 +544,7 @@ impl Stylist {
|
|||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
CssRule::FontFace(ref rule) => {
|
||||
_extra_data.add_font_face(&rule, stylesheet.origin);
|
||||
_extra_data.add_font_face(&rule, origin);
|
||||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
CssRule::CounterStyle(ref rule) => {
|
||||
|
@ -909,9 +924,13 @@ impl Stylist {
|
|||
pub fn set_device(&mut self,
|
||||
mut device: Device,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
stylesheets: &[Arc<Stylesheet>]) {
|
||||
stylesheets: &[Arc<::stylesheets::Stylesheet>]) {
|
||||
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 =
|
||||
|
@ -923,7 +942,7 @@ impl Stylist {
|
|||
|
||||
self.device = device;
|
||||
let features_changed = self.media_features_change_changed_style(
|
||||
stylesheets.iter(),
|
||||
stylesheets.iter().map(|s| &**s),
|
||||
guard
|
||||
);
|
||||
self.is_device_dirty |= features_changed;
|
||||
|
@ -931,12 +950,14 @@ impl Stylist {
|
|||
|
||||
/// Returns whether, given a media feature change, any previously-applicable
|
||||
/// 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,
|
||||
stylesheets: I,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
) -> bool
|
||||
where I: Iterator<Item = &'a Arc<Stylesheet>>
|
||||
where
|
||||
I: Iterator<Item = &'a S>,
|
||||
S: StylesheetInDocument + ToMediaListKey + 'static,
|
||||
{
|
||||
use invalidation::media_queries::PotentiallyEffectiveMediaRules;
|
||||
|
||||
|
@ -944,11 +965,10 @@ impl Stylist {
|
|||
|
||||
for stylesheet in stylesheets {
|
||||
let effective_now =
|
||||
stylesheet.media.read_with(guard)
|
||||
.evaluate(&self.device, self.quirks_mode);
|
||||
stylesheet.is_effective_for_device(&self.device, guard);
|
||||
|
||||
let effective_then =
|
||||
self.effective_media_query_results.was_effective(&**stylesheet);
|
||||
self.effective_media_query_results.was_effective(stylesheet);
|
||||
|
||||
if effective_now != effective_then {
|
||||
debug!(" > Stylesheet changed -> {}, {}",
|
||||
|
@ -982,9 +1002,9 @@ impl Stylist {
|
|||
}
|
||||
CssRule::Import(ref lock) => {
|
||||
let import_rule = lock.read_with(guard);
|
||||
let mq = import_rule.stylesheet.media.read_with(guard);
|
||||
let effective_now =
|
||||
mq.evaluate(&self.device, self.quirks_mode);
|
||||
import_rule.stylesheet
|
||||
.is_effective_for_device(&self.device, guard);
|
||||
let effective_then =
|
||||
self.effective_media_query_results.was_effective(import_rule);
|
||||
if effective_now != effective_then {
|
||||
|
|
|
@ -18,7 +18,7 @@ use style::dom::{ShowSubtreeData, TElement, TNode};
|
|||
use style::element_state::ElementState;
|
||||
use style::error_reporting::RustLogReporter;
|
||||
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::restyle_damage::GeckoRestyleDamage;
|
||||
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::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong};
|
||||
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::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
|
||||
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
|
||||
use style::gecko_bindings::bindings::{RawServoStyleSheetContentsBorrowed, ServoComputedValuesBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoStyleSheetContentsStrong, ServoComputedValuesStrong};
|
||||
use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed};
|
||||
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
|
||||
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::RawServoAnimationValueStrong;
|
||||
use style::gecko_bindings::bindings::RawServoStyleRuleBorrowed;
|
||||
use style::gecko_bindings::bindings::RawServoStyleSheet;
|
||||
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
|
||||
use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
|
||||
use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
|
||||
use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
|
||||
use style::gecko_bindings::structs;
|
||||
use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation};
|
||||
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
|
||||
use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation, Loader};
|
||||
use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
|
||||
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
|
||||
use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule};
|
||||
|
@ -105,7 +103,8 @@ use style::style_adjuster::StyleAdjuster;
|
|||
use style::stylearc::Arc;
|
||||
use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, DocumentRule};
|
||||
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::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
|
||||
use style::stylesheets::supports_rule::parse_condition_or_declaration;
|
||||
|
@ -739,7 +738,7 @@ pub extern "C" fn Servo_Element_ClearData(element: RawGeckoElementBorrowed) {
|
|||
}
|
||||
|
||||
#[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 origin = match mode {
|
||||
SheetParsingMode::eAuthorSheetFeatures => Origin::Author,
|
||||
|
@ -747,24 +746,31 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl
|
|||
SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent,
|
||||
SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent,
|
||||
};
|
||||
let shared_lock = global_style_data.shared_lock.clone();
|
||||
Arc::new(Stylesheet::from_str(
|
||||
"", unsafe { dummy_url_data() }.clone(), origin,
|
||||
Arc::new(shared_lock.wrap(MediaList::empty())),
|
||||
shared_lock, None, &RustLogReporter, QuirksMode::NoQuirks, 0u64)
|
||||
let shared_lock = &global_style_data.shared_lock;
|
||||
Arc::new(
|
||||
StylesheetContents::from_str(
|
||||
"",
|
||||
unsafe { dummy_url_data() }.clone(),
|
||||
origin,
|
||||
shared_lock,
|
||||
/* loader = */ None,
|
||||
&RustLogReporter,
|
||||
QuirksMode::NoQuirks,
|
||||
0
|
||||
)
|
||||
).into_strong()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
|
||||
stylesheet: *mut ServoStyleSheet,
|
||||
data: *const nsACString,
|
||||
mode: SheetParsingMode,
|
||||
media_list: *const RawServoMediaList,
|
||||
extra_data: *mut URLExtraData,
|
||||
line_number_offset: u32,
|
||||
quirks_mode: nsCompatibility)
|
||||
-> RawServoStyleSheetStrong {
|
||||
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
|
||||
loader: *mut Loader,
|
||||
stylesheet: *mut ServoStyleSheet,
|
||||
data: *const nsACString,
|
||||
mode: SheetParsingMode,
|
||||
extra_data: *mut URLExtraData,
|
||||
line_number_offset: u32,
|
||||
quirks_mode: nsCompatibility
|
||||
) -> RawServoStyleSheetContentsStrong {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
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),
|
||||
};
|
||||
|
||||
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(
|
||||
input, url_data.clone(), origin, media,
|
||||
shared_lock, loader, &RustLogReporter,
|
||||
Arc::new(StylesheetContents::from_str(
|
||||
input, url_data.clone(), origin,
|
||||
&global_style_data.shared_lock, loader, &RustLogReporter,
|
||||
quirks_mode.into(), line_number_offset as u64)
|
||||
).into_strong()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheetBorrowed,
|
||||
loader: *mut Loader,
|
||||
gecko_stylesheet: *mut 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) {
|
||||
pub extern "C" fn Servo_StyleSet_AppendStyleSheet(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
sheet: *const ServoStyleSheet,
|
||||
) {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
let mut data = &mut *data;
|
||||
let sheet = HasArcFFI::as_arc(&raw_sheet);
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
data.stylesheets.append_stylesheet(
|
||||
&data.stylist,
|
||||
sheet,
|
||||
unique_id,
|
||||
&guard);
|
||||
unsafe { GeckoStyleSheet::new(sheet) },
|
||||
&guard
|
||||
);
|
||||
data.clear_stylist();
|
||||
}
|
||||
|
||||
|
@ -875,65 +846,55 @@ pub extern "C" fn Servo_StyleSet_MediumFeaturesChanged(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_PrependStyleSheet(raw_data: RawServoStyleSetBorrowed,
|
||||
raw_sheet: RawServoStyleSheetBorrowed,
|
||||
unique_id: u64) {
|
||||
pub extern "C" fn Servo_StyleSet_PrependStyleSheet(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
sheet: *const ServoStyleSheet,
|
||||
) {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
let mut data = &mut *data;
|
||||
let sheet = HasArcFFI::as_arc(&raw_sheet);
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
data.stylesheets.prepend_stylesheet(
|
||||
&data.stylist,
|
||||
sheet,
|
||||
unique_id,
|
||||
&guard);
|
||||
unsafe { GeckoStyleSheet::new(sheet) },
|
||||
&guard,
|
||||
);
|
||||
data.clear_stylist();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(raw_data: RawServoStyleSetBorrowed,
|
||||
raw_sheet: RawServoStyleSheetBorrowed,
|
||||
unique_id: u64,
|
||||
before_unique_id: u64) {
|
||||
pub extern "C" fn Servo_StyleSet_InsertStyleSheetBefore(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
sheet: *const ServoStyleSheet,
|
||||
before_sheet: *const ServoStyleSheet
|
||||
) {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
let mut data = &mut *data;
|
||||
let sheet = HasArcFFI::as_arc(&raw_sheet);
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
data.stylesheets.insert_stylesheet_before(
|
||||
&data.stylist,
|
||||
sheet,
|
||||
unique_id,
|
||||
before_unique_id,
|
||||
unsafe { GeckoStyleSheet::new(sheet) },
|
||||
unsafe { GeckoStyleSheet::new(before_sheet) },
|
||||
&guard);
|
||||
data.clear_stylist();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_UpdateStyleSheet(raw_data: RawServoStyleSetBorrowed,
|
||||
raw_sheet: RawServoStyleSheetBorrowed,
|
||||
unique_id: u64) {
|
||||
pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
sheet: *const ServoStyleSheet
|
||||
) {
|
||||
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
let sheet = HasArcFFI::as_arc(&raw_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.stylesheets.remove_stylesheet(unsafe { GeckoStyleSheet::new(sheet) });
|
||||
data.clear_stylist();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_FlushStyleSheets(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
doc_element: RawGeckoElementBorrowedOrNull)
|
||||
{
|
||||
doc_element: RawGeckoElementBorrowedOrNull,
|
||||
) {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
|
@ -944,8 +905,8 @@ pub extern "C" fn Servo_StyleSet_FlushStyleSheets(
|
|||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
author_style_disabled: bool)
|
||||
{
|
||||
author_style_disabled: bool,
|
||||
) {
|
||||
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
data.stylesheets.force_dirty();
|
||||
data.stylesheets.set_author_style_disabled(author_style_disabled);
|
||||
|
@ -953,30 +914,50 @@ pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged(
|
|||
}
|
||||
|
||||
#[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 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]
|
||||
pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -> ServoCssRulesStrong {
|
||||
Stylesheet::as_arc(&sheet).rules.clone().into_strong()
|
||||
pub extern "C" fn Servo_StyleSheet_GetRules(
|
||||
sheet: RawServoStyleSheetContentsBorrowed
|
||||
) -> ServoCssRulesStrong {
|
||||
StylesheetContents::as_arc(&sheet).rules.clone().into_strong()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSheet_Clone(raw_sheet: RawServoStyleSheetBorrowed) -> RawServoStyleSheetStrong {
|
||||
let sheet: &Arc<Stylesheet> = HasArcFFI::as_arc(&raw_sheet);
|
||||
Arc::new(sheet.as_ref().clone()).into_strong()
|
||||
pub extern "C" fn Servo_StyleSheet_Clone(
|
||||
raw_sheet: RawServoStyleSheetContentsBorrowed,
|
||||
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,
|
||||
¶ms,
|
||||
)).into_strong()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSheet_SizeOfIncludingThis(malloc_size_of: MallocSizeOf,
|
||||
sheet: RawServoStyleSheetBorrowed) -> usize {
|
||||
pub extern "C" fn Servo_StyleSheet_SizeOfIncludingThis(
|
||||
malloc_size_of: MallocSizeOf,
|
||||
sheet: RawServoStyleSheetContentsBorrowed
|
||||
) -> usize {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
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
|
||||
|
@ -1008,15 +989,16 @@ pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
|
||||
sheet: RawServoStyleSheetBorrowed,
|
||||
rule: *const nsACString,
|
||||
index: u32,
|
||||
nested: bool,
|
||||
loader: *mut Loader,
|
||||
gecko_stylesheet: *mut ServoStyleSheet,
|
||||
rule_type: *mut u16) -> nsresult {
|
||||
let sheet = Stylesheet::as_arc(&sheet);
|
||||
pub extern "C" fn Servo_CssRules_InsertRule(
|
||||
rules: ServoCssRulesBorrowed,
|
||||
contents: RawServoStyleSheetContentsBorrowed,
|
||||
rule: *const nsACString,
|
||||
index: u32,
|
||||
nested: bool,
|
||||
loader: *mut Loader,
|
||||
gecko_stylesheet: *mut ServoStyleSheet,
|
||||
rule_type: *mut u16,
|
||||
) -> nsresult {
|
||||
let loader = if loader.is_null() {
|
||||
None
|
||||
} 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 global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
match Locked::<CssRules>::as_arc(&rules).insert_rule(&global_style_data.shared_lock,
|
||||
rule,
|
||||
sheet,
|
||||
index as usize,
|
||||
nested,
|
||||
loader) {
|
||||
let contents = StylesheetContents::as_arc(&contents);
|
||||
let result = Locked::<CssRules>::as_arc(&rules).insert_rule(
|
||||
&global_style_data.shared_lock,
|
||||
rule,
|
||||
contents,
|
||||
index as usize,
|
||||
nested,
|
||||
loader
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(new_rule) => {
|
||||
*unsafe { rule_type.as_mut().unwrap() } = new_rule.rule_type() as u16;
|
||||
nsresult::NS_OK
|
||||
|
@ -1041,7 +1028,10 @@ pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
|
|||
}
|
||||
|
||||
#[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| {
|
||||
match rules.remove_rule(index as usize) {
|
||||
Ok(_) => nsresult::NS_OK,
|
||||
|
@ -1085,7 +1075,13 @@ macro_rules! impl_basic_rule_funcs {
|
|||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
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) => {
|
||||
let location = rule.read_with(&guard).source_location;
|
||||
*unsafe { line.as_mut().unwrap() } = location.line as u32;
|
||||
|
@ -1093,8 +1089,7 @@ macro_rules! impl_basic_rule_funcs {
|
|||
rule.clone().into_strong()
|
||||
},
|
||||
_ => {
|
||||
unreachable!(concat!(stringify!($getter), "should only be called ",
|
||||
"on a ", stringify!($name), " rule"));
|
||||
Strong::null()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1244,9 +1239,11 @@ pub extern "C" fn Servo_StyleRule_GetSelectorCount(rule: RawServoStyleRuleBorrow
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleRule_GetSpecificityAtIndex(rule: RawServoStyleRuleBorrowed,
|
||||
index: u32,
|
||||
specificity: *mut u64) {
|
||||
pub extern "C" fn Servo_StyleRule_GetSpecificityAtIndex(
|
||||
rule: RawServoStyleRuleBorrowed,
|
||||
index: u32,
|
||||
specificity: *mut u64
|
||||
) {
|
||||
read_locked_arc(rule, |rule: &StyleRule| {
|
||||
let mut specificity = unsafe { specificity.as_mut().unwrap() };
|
||||
let index = index as usize;
|
||||
|
@ -1266,14 +1263,19 @@ pub extern "C" fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, res
|
|||
}
|
||||
|
||||
#[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| {
|
||||
rule.stylesheet.as_borrowed_opt().unwrap() as *const _
|
||||
rule.stylesheet.0.raw() as *const ServoStyleSheet
|
||||
})
|
||||
}
|
||||
|
||||
#[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| {
|
||||
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]
|
||||
pub extern "C" fn Servo_KeyframesRule_AppendRule(rule: RawServoKeyframesRuleBorrowed,
|
||||
sheet: RawServoStyleSheetBorrowed,
|
||||
css: *const nsACString) -> bool {
|
||||
pub extern "C" fn Servo_KeyframesRule_AppendRule(
|
||||
rule: RawServoKeyframesRuleBorrowed,
|
||||
contents: RawServoStyleSheetContentsBorrowed,
|
||||
css: *const nsACString
|
||||
) -> bool {
|
||||
let css = unsafe { css.as_ref().unwrap().as_str_unchecked() };
|
||||
let sheet = Stylesheet::as_arc(&sheet);
|
||||
if let Ok(keyframe) = Keyframe::parse(css, sheet) {
|
||||
write_locked_arc(rule, |rule: &mut KeyframesRule| {
|
||||
rule.keyframes.push(keyframe);
|
||||
});
|
||||
true
|
||||
} else {
|
||||
false
|
||||
let contents = StylesheetContents::as_arc(&contents);
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
match Keyframe::parse(css, &contents, &global_style_data.shared_lock) {
|
||||
Ok(keyframe) => {
|
||||
write_locked_arc(rule, |rule: &mut KeyframesRule| {
|
||||
rule.keyframes.push(keyframe);
|
||||
});
|
||||
true
|
||||
}
|
||||
Err(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1607,10 +1613,10 @@ fn get_pseudo_style(
|
|||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ComputedValues_Inherit(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
parent_style: ServoComputedValuesBorrowedOrNull,
|
||||
target: structs::InheritTarget)
|
||||
-> ServoComputedValuesStrong {
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
parent_style: ServoComputedValuesBorrowedOrNull,
|
||||
target: structs::InheritTarget
|
||||
) -> ServoComputedValuesStrong {
|
||||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||
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]
|
||||
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(raw_data: RawServoStyleSetBorrowed,
|
||||
parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
||||
declarations: RawServoDeclarationBlockBorrowed)
|
||||
-> ServoComputedValuesStrong
|
||||
{
|
||||
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
||||
declarations: RawServoDeclarationBlockBorrowed
|
||||
) -> ServoComputedValuesStrong {
|
||||
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
|
|
|
@ -2,13 +2,18 @@
|
|||
* 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/. */
|
||||
|
||||
use cssparser::SourceLocation;
|
||||
use style::gecko::data::GeckoStyleSheet;
|
||||
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
|
||||
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::shared_lock::Locked;
|
||||
use style::parser::ParserContext;
|
||||
use style::shared_lock::{Locked, SharedRwLock};
|
||||
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);
|
||||
|
||||
|
@ -23,29 +28,34 @@ impl StylesheetLoader {
|
|||
impl StyleStylesheetLoader for StylesheetLoader {
|
||||
fn request_stylesheet(
|
||||
&self,
|
||||
url: SpecifiedUrl,
|
||||
source_location: SourceLocation,
|
||||
_context: &ParserContext,
|
||||
lock: &SharedRwLock,
|
||||
media: Arc<Locked<MediaList>>,
|
||||
make_import: &mut FnMut(Arc<Locked<MediaList>>) -> ImportRule,
|
||||
make_arc: &mut FnMut(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
|
||||
// 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 won’t,
|
||||
// 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();
|
||||
unsafe {
|
||||
let child_sheet = unsafe {
|
||||
let (spec_bytes, spec_len) = url.as_slice_components();
|
||||
let base_url_data = url.extra_data.get();
|
||||
Gecko_LoadStyleSheet(self.0,
|
||||
self.1,
|
||||
self.2,
|
||||
Stylesheet::arc_as_borrowed(&import.stylesheet),
|
||||
base_url_data,
|
||||
spec_bytes,
|
||||
spec_len as u32,
|
||||
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 }))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use style::media_queries::*;
|
|||
use style::servo::media_queries::*;
|
||||
use style::shared_lock::SharedRwLock;
|
||||
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_traits::ToCss;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> {
|
|||
QuirksMode::NoQuirks,
|
||||
0u64);
|
||||
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| {
|
||||
match *rule {
|
||||
CssRule::Style(ref style_rule) => Some(style_rule),
|
||||
|
|
|
@ -23,7 +23,7 @@ use style::properties::longhands::animation_play_state;
|
|||
use style::shared_lock::SharedRwLock;
|
||||
use style::stylearc::Arc;
|
||||
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::values::{KeyframesName, CustomIdent};
|
||||
use style::values::specified::{LengthOrPercentageOrAuto, Percentage, PositionComponent};
|
||||
|
@ -72,176 +72,178 @@ fn test_parse_stylesheet() {
|
|||
let mut namespaces = Namespaces::default();
|
||||
namespaces.default = Some((ns!(html), ()));
|
||||
let expected = Stylesheet {
|
||||
origin: Origin::UserAgent,
|
||||
media: Arc::new(stylesheet.shared_lock.wrap(MediaList::empty())),
|
||||
shared_lock: stylesheet.shared_lock.clone(),
|
||||
namespaces: RwLock::new(namespaces),
|
||||
url_data: RwLock::new(url),
|
||||
dirty_on_viewport_size_change: AtomicBool::new(false),
|
||||
disabled: AtomicBool::new(false),
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
rules: CssRules::new(vec![
|
||||
CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule {
|
||||
prefix: None,
|
||||
url: NsAtom::from("http://www.w3.org/1999/xhtml"),
|
||||
source_location: SourceLocation {
|
||||
line: 1,
|
||||
column: 19,
|
||||
},
|
||||
}))),
|
||||
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::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!(
|
||||
contents: StylesheetContents {
|
||||
origin: Origin::UserAgent,
|
||||
namespaces: RwLock::new(namespaces),
|
||||
url_data: RwLock::new(url),
|
||||
dirty_on_viewport_size_change: AtomicBool::new(false),
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
rules: CssRules::new(vec![
|
||||
CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule {
|
||||
prefix: None,
|
||||
url: NsAtom::from("http://www.w3.org/1999/xhtml"),
|
||||
source_location: SourceLocation {
|
||||
line: 1,
|
||||
column: 19,
|
||||
},
|
||||
}))),
|
||||
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::LocalName(LocalName {
|
||||
name: local_name!("html"),
|
||||
lower_name: local_name!("html"),
|
||||
name: local_name!("input"),
|
||||
lower_name: local_name!("input"),
|
||||
}),
|
||||
), (0 << 20) + (0 << 10) + (1 << 0)),
|
||||
Selector::from_vec(vec!(
|
||||
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
|
||||
Component::LocalName(LocalName {
|
||||
name: local_name!("body"),
|
||||
lower_name: local_name!("body"),
|
||||
})
|
||||
), (0 << 20) + (0 << 10) + (1 << 0)
|
||||
),
|
||||
)),
|
||||
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::block),
|
||||
Importance::Normal),
|
||||
]))),
|
||||
source_location: SourceLocation {
|
||||
line: 11,
|
||||
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::ID(Atom::from("d1")),
|
||||
Component::Combinator(Combinator::Child),
|
||||
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
|
||||
Component::Class(Atom::from("ok"))
|
||||
), (1 << 20) + (1 << 10) + (0 << 0))
|
||||
)),
|
||||
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||
(PropertyDeclaration::BackgroundColor(
|
||||
longhands::background_color::SpecifiedValue::Numeric {
|
||||
authored: Some("blue".to_owned().into_boxed_str()),
|
||||
parsed: cssparser::RGBA::new(0, 0, 255, 255),
|
||||
}
|
||||
),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundPositionX(
|
||||
longhands::background_position_x::SpecifiedValue(
|
||||
vec![PositionComponent::zero()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundPositionY(
|
||||
longhands::background_position_y::SpecifiedValue(
|
||||
vec![PositionComponent::zero()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundRepeat(
|
||||
longhands::background_repeat::SpecifiedValue(
|
||||
vec![longhands::background_repeat::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundAttachment(
|
||||
longhands::background_attachment::SpecifiedValue(
|
||||
vec![longhands::background_attachment::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundImage(
|
||||
longhands::background_image::SpecifiedValue(
|
||||
vec![longhands::background_image::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundSize(
|
||||
longhands::background_size::SpecifiedValue(
|
||||
vec![longhands::background_size::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundOrigin(
|
||||
longhands::background_origin::SpecifiedValue(
|
||||
vec![longhands::background_origin::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundClip(
|
||||
longhands::background_clip::SpecifiedValue(
|
||||
vec![longhands::background_clip::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
]))),
|
||||
source_location: SourceLocation {
|
||||
line: 15,
|
||||
column: 9,
|
||||
},
|
||||
}))),
|
||||
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,
|
||||
},
|
||||
})))
|
||||
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::LocalName(LocalName {
|
||||
name: local_name!("html"),
|
||||
lower_name: local_name!("html"),
|
||||
}),
|
||||
), (0 << 20) + (0 << 10) + (1 << 0)),
|
||||
Selector::from_vec(vec!(
|
||||
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
|
||||
Component::LocalName(LocalName {
|
||||
name: local_name!("body"),
|
||||
lower_name: local_name!("body"),
|
||||
})
|
||||
), (0 << 20) + (0 << 10) + (1 << 0)
|
||||
),
|
||||
)),
|
||||
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::block),
|
||||
Importance::Normal),
|
||||
]))),
|
||||
source_location: SourceLocation {
|
||||
line: 11,
|
||||
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::ID(Atom::from("d1")),
|
||||
Component::Combinator(Combinator::Child),
|
||||
Component::DefaultNamespace(NsAtom::from("http://www.w3.org/1999/xhtml")),
|
||||
Component::Class(Atom::from("ok"))
|
||||
), (1 << 20) + (1 << 10) + (0 << 0))
|
||||
)),
|
||||
block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![
|
||||
(PropertyDeclaration::BackgroundColor(
|
||||
longhands::background_color::SpecifiedValue::Numeric {
|
||||
authored: Some("blue".to_owned().into_boxed_str()),
|
||||
parsed: cssparser::RGBA::new(0, 0, 255, 255),
|
||||
}
|
||||
),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundPositionX(
|
||||
longhands::background_position_x::SpecifiedValue(
|
||||
vec![PositionComponent::zero()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundPositionY(
|
||||
longhands::background_position_y::SpecifiedValue(
|
||||
vec![PositionComponent::zero()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundRepeat(
|
||||
longhands::background_repeat::SpecifiedValue(
|
||||
vec![longhands::background_repeat::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundAttachment(
|
||||
longhands::background_attachment::SpecifiedValue(
|
||||
vec![longhands::background_attachment::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundImage(
|
||||
longhands::background_image::SpecifiedValue(
|
||||
vec![longhands::background_image::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundSize(
|
||||
longhands::background_size::SpecifiedValue(
|
||||
vec![longhands::background_size::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundOrigin(
|
||||
longhands::background_origin::SpecifiedValue(
|
||||
vec![longhands::background_origin::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
(PropertyDeclaration::BackgroundClip(
|
||||
longhands::background_clip::SpecifiedValue(
|
||||
vec![longhands::background_clip::single_value
|
||||
::get_initial_specified_value()])),
|
||||
Importance::Normal),
|
||||
]))),
|
||||
source_location: SourceLocation {
|
||||
line: 15,
|
||||
column: 9,
|
||||
},
|
||||
}))),
|
||||
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));
|
||||
|
|
|
@ -12,7 +12,7 @@ use style::media_queries::{Device, MediaList, MediaType};
|
|||
use style::parser::{Parse, ParserContext};
|
||||
use style::shared_lock::SharedRwLock;
|
||||
use style::stylearc::Arc;
|
||||
use style::stylesheets::{CssRuleType, Stylesheet, Origin};
|
||||
use style::stylesheets::{CssRuleType, Stylesheet, StylesheetInDocument, Origin};
|
||||
use style::stylesheets::viewport_rule::*;
|
||||
use style::values::specified::LengthOrPercentageOrAuto::{self, Auto};
|
||||
use style::values::specified::NoCalcLength::{self, ViewportPercentage};
|
||||
|
@ -269,7 +269,11 @@ fn multiple_stylesheets_cascading() {
|
|||
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_eq!(&declarations[0], UserAgent, Zoom: Zoom::Number(1.));
|
||||
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; }",
|
||||
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_eq!(&declarations[0], UserAgent, MinWidth: viewport_length!(100., px), !important);
|
||||
assert_decl_eq!(&declarations[1], User, MinHeight: viewport_length!(200., px), !important);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue