aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-08-11 00:40:18 -0500
committerGitHub <noreply@github.com>2017-08-11 00:40:18 -0500
commit56f5fc41fae732ba28f63acec6755559da31d47f (patch)
treeaeddcdc450a00ca94b6903232004a81f0be734cb /components
parentc811a1aa7745c848870af226e249e14baaa4ccc3 (diff)
parent57622004ce9074447dd38e269780c44f0c8d46d8 (diff)
downloadservo-56f5fc41fae732ba28f63acec6755559da31d47f.tar.gz
servo-56f5fc41fae732ba28f63acec6755559da31d47f.zip
Auto merge of #18037 - heycam:split-cascade-font-counter, r=emilio
style: Split collected @font-face / @counter-style rules per origin. <!-- Please describe your changes on the following line: --> More refactoring in preparation for rebuilding sheets only from the origin that changed. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18037) <!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r--components/layout_thread/lib.rs5
-rw-r--r--components/style/gecko/data.rs22
-rw-r--r--components/style/stylist.rs117
3 files changed, 100 insertions, 44 deletions
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index 26d1ef7bb41..9635e0b081d 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -114,7 +114,6 @@ use servo_url::ServoUrl;
use std::borrow::ToOwned;
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
-use std::marker::PhantomData;
use std::mem as std_mem;
use std::ops::{Deref, DerefMut};
use std::process;
@@ -1207,9 +1206,7 @@ impl LayoutThread {
author: &author_guard,
ua_or_user: &ua_or_user_guard,
};
- let mut extra_data = ExtraStyleData {
- marker: PhantomData,
- };
+ let mut extra_data = ExtraStyleData;
let needs_dirtying = self.stylist.update(
StylesheetIterator(data.document_stylesheets.iter()),
&guards,
diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs
index 193ee928670..54dab9fe283 100644
--- a/components/style/gecko/data.rs
+++ b/components/style/gecko/data.rs
@@ -4,10 +4,8 @@
//! Data needed to style a Gecko document.
-use Atom;
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use dom::TElement;
-use gecko::rules::{CounterStyleRule, FontFaceRule};
use gecko_bindings::bindings::{self, RawServoStyleSet};
use gecko_bindings::structs::{ServoStyleSheet, StyleSheetInfo, ServoStyleSheetInner};
use gecko_bindings::structs::RawGeckoPresContextOwned;
@@ -16,11 +14,10 @@ use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFF
use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use media_queries::{Device, MediaList};
use properties::ComputedValues;
-use selector_map::PrecomputedHashMap;
use servo_arc::Arc;
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use stylesheet_set::StylesheetSet;
-use stylesheets::{Origin, StylesheetContents, StylesheetInDocument};
+use stylesheets::{StylesheetContents, StylesheetInDocument};
use stylist::{ExtraStyleData, Stylist};
/// Little wrapper to a Gecko style sheet.
@@ -120,11 +117,8 @@ pub struct PerDocumentStyleDataImpl {
/// List of stylesheets, mirrored from Gecko.
pub stylesheets: StylesheetSet<GeckoStyleSheet>,
- /// List of effective font face rules.
- pub font_faces: Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
-
- /// Map for effective counter style rules.
- pub counter_styles: PrecomputedHashMap<Atom, Arc<Locked<CounterStyleRule>>>,
+ /// List of effective @font-face and @counter-style rules.
+ pub extra_style_data: ExtraStyleData,
}
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
@@ -142,8 +136,7 @@ impl PerDocumentStyleData {
PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl {
stylist: Stylist::new(device, quirks_mode.into()),
stylesheets: StylesheetSet::new(),
- font_faces: vec![],
- counter_styles: PrecomputedHashMap::default(),
+ extra_style_data: Default::default(),
}))
}
@@ -169,11 +162,6 @@ impl PerDocumentStyleDataImpl {
return;
}
- let mut extra_data = ExtraStyleData {
- font_faces: &mut self.font_faces,
- counter_styles: &mut self.counter_styles,
- };
-
let author_style_disabled = self.stylesheets.author_style_disabled();
self.stylist.clear();
let iter = self.stylesheets.flush(document_element);
@@ -183,7 +171,7 @@ impl PerDocumentStyleDataImpl {
/* ua_sheets = */ None,
/* stylesheets_changed = */ true,
author_style_disabled,
- &mut extra_data
+ &mut self.extra_style_data,
);
}
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index 3000cd29e27..f3d79277a80 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -36,8 +36,6 @@ use servo_arc::{Arc, ArcBorrow};
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
use smallvec::VecLike;
use std::fmt::Debug;
-#[cfg(feature = "servo")]
-use std::marker::PhantomData;
use style_traits::viewport::ViewportConstraints;
#[cfg(feature = "gecko")]
use stylesheets::{CounterStyleRule, FontFaceRule};
@@ -112,27 +110,71 @@ pub struct Stylist {
num_rebuilds: usize,
}
-/// This struct holds data which user of Stylist may want to extract
+/// This struct holds data which users of Stylist may want to extract
+/// from stylesheets which can be done at the same time as updating.
+#[cfg(feature = "gecko")]
+#[derive(Default)]
+pub struct ExtraStyleData {
+ /// Extra data from user agent stylesheets
+ user_agent: PerOriginExtraStyleData,
+ /// Extra data from author stylesheets
+ author: PerOriginExtraStyleData,
+ /// Extra data from user stylesheets
+ user: PerOriginExtraStyleData,
+}
+
+/// This struct holds data which users of Stylist may want to extract
/// from stylesheets which can be done at the same time as updating.
#[cfg(feature = "gecko")]
-pub struct ExtraStyleData<'a> {
+#[derive(Default)]
+pub struct PerOriginExtraStyleData {
/// A list of effective font-face rules and their origin.
- pub font_faces: &'a mut Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
+ pub font_faces: Vec<Arc<Locked<FontFaceRule>>>,
/// A map of effective counter-style rules.
- pub counter_styles: &'a mut PrecomputedHashMap<Atom, Arc<Locked<CounterStyleRule>>>,
+ pub counter_styles: PrecomputedHashMap<Atom, Arc<Locked<CounterStyleRule>>>,
}
#[cfg(feature = "gecko")]
-impl<'a> ExtraStyleData<'a> {
+impl ExtraStyleData {
/// Clear the internal data.
+ pub fn clear(&mut self) {
+ self.user_agent.clear();
+ self.author.clear();
+ self.user.clear();
+ }
+
+ /// Returns a reference to the per-origin extra style data for
+ /// the specified origin.
+ #[inline]
+ pub fn borrow_mut_for_origin(&mut self, origin: &Origin) -> &mut PerOriginExtraStyleData {
+ match *origin {
+ Origin::UserAgent => &mut self.user_agent,
+ Origin::Author => &mut self.author,
+ Origin::User => &mut self.user,
+ }
+ }
+
+ /// Iterates over the per-origin extra style data, from highest level (user)
+ /// to lowest (user agent).
+ pub fn iter_origins(&self) -> ExtraStyleDataIter {
+ ExtraStyleDataIter {
+ extra_style_data: &self,
+ cur: 0,
+ }
+ }
+}
+
+#[cfg(feature = "gecko")]
+impl PerOriginExtraStyleData {
+ /// Clears the stored @font-face and @counter-style rules.
fn clear(&mut self) {
self.font_faces.clear();
self.counter_styles.clear();
}
/// Add the given @font-face rule.
- fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>, origin: Origin) {
- self.font_faces.push((rule.clone(), origin));
+ fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>) {
+ self.font_faces.push(rule.clone());
}
/// Add the given @counter-style rule.
@@ -145,12 +187,10 @@ impl<'a> ExtraStyleData<'a> {
#[allow(missing_docs)]
#[cfg(feature = "servo")]
-pub struct ExtraStyleData<'a> {
- pub marker: PhantomData<&'a usize>,
-}
+pub struct ExtraStyleData;
#[cfg(feature = "servo")]
-impl<'a> ExtraStyleData<'a> {
+impl ExtraStyleData {
fn clear(&mut self) {}
}
@@ -277,17 +317,17 @@ 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, S>(
+ pub fn rebuild<'a, 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>
+ extra_data: &mut ExtraStyleData
) -> bool
where
- I: Iterator<Item = &'b S> + Clone,
+ I: Iterator<Item = &'a S> + Clone,
S: StylesheetInDocument + ToMediaListKey + 'static,
{
debug_assert!(!self.is_cleared || self.is_device_dirty);
@@ -357,17 +397,17 @@ 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, S>(
+ pub fn update<'a, 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>
+ extra_data: &mut ExtraStyleData
) -> bool
where
- I: Iterator<Item = &'b S> + Clone,
+ I: Iterator<Item = &'a S> + Clone,
S: StylesheetInDocument + ToMediaListKey + 'static,
{
debug_assert!(!self.is_cleared || self.is_device_dirty);
@@ -382,11 +422,11 @@ impl Stylist {
author_style_disabled, extra_data)
}
- fn add_stylesheet<'a, S>(
+ fn add_stylesheet<S>(
&mut self,
stylesheet: &S,
guard: &SharedRwLockReadGuard,
- _extra_data: &mut ExtraStyleData<'a>
+ _extra_data: &mut ExtraStyleData
)
where
S: StylesheetInDocument + ToMediaListKey + 'static,
@@ -506,11 +546,15 @@ impl Stylist {
}
#[cfg(feature = "gecko")]
CssRule::FontFace(ref rule) => {
- _extra_data.add_font_face(&rule, origin);
+ _extra_data
+ .borrow_mut_for_origin(&origin)
+ .add_font_face(&rule);
}
#[cfg(feature = "gecko")]
CssRule::CounterStyle(ref rule) => {
- _extra_data.add_counter_style(guard, &rule);
+ _extra_data
+ .borrow_mut_for_origin(&origin)
+ .add_counter_style(guard, &rule);
}
// We don't care about any other rule.
_ => {}
@@ -1628,6 +1672,33 @@ impl<'a> Iterator for CascadeDataIter<'a> {
}
}
+/// Iterator over `PerOriginExtraStyleData`, from highest level (user) to lowest
+/// (user agent).
+///
+/// We rely on this specific order for correctly looking up the @font-face
+/// and @counter-style rules.
+#[cfg(feature = "gecko")]
+pub struct ExtraStyleDataIter<'a> {
+ extra_style_data: &'a ExtraStyleData,
+ cur: usize,
+}
+
+#[cfg(feature = "gecko")]
+impl<'a> Iterator for ExtraStyleDataIter<'a> {
+ type Item = (&'a PerOriginExtraStyleData, Origin);
+
+ fn next(&mut self) -> Option<(&'a PerOriginExtraStyleData, Origin)> {
+ let result = match self.cur {
+ 0 => (&self.extra_style_data.user, Origin::User),
+ 1 => (&self.extra_style_data.author, Origin::Author),
+ 2 => (&self.extra_style_data.user_agent, Origin::UserAgent),
+ _ => return None,
+ };
+ self.cur += 1;
+ Some(result)
+ }
+}
+
/// Data resulting from performing the CSS cascade that is specific to a given
/// origin.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]