зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #17028 - Stylo: Deep clone ServoStyleSheets (from bradwerth:innerClone); r=heycam
MozReview-Commit-ID: 6hYIcOa86Y <!-- Please describe your changes on the following line: --> https://bugzilla.mozilla.org/show_bug.cgi?id=1339629 https://reviewboard.mozilla.org/r/135314/ --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./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: --> - [X] 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. --> Source-Repo: https://github.com/servo/servo Source-Revision: 0d6b0da3544359343b191354ecc258e42394c5dd --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 2b2d7c20dc3452c9d77414572c636d9cd6d4d79d
This commit is contained in:
Родитель
30a91cb819
Коммит
1b41d0dc5a
|
@ -142,7 +142,7 @@ macro_rules! counter_style_descriptors {
|
|||
$( #[$doc: meta] $name: tt $ident: ident / $gecko_ident: ident: $ty: ty = $initial: tt )+
|
||||
) => {
|
||||
/// An @counter-style rule
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CounterStyleRuleData {
|
||||
name: CustomIdent,
|
||||
$(
|
||||
|
|
|
@ -20,7 +20,7 @@ use style_traits::ToCss;
|
|||
use values::specified::url::SpecifiedUrl;
|
||||
|
||||
/// A URL matching function for a `@document` rule's condition.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UrlMatchingFunction {
|
||||
/// Exact URL matching function. It evaluates to true whenever the
|
||||
/// URL of the document being styled is exactly the URL given.
|
||||
|
@ -141,7 +141,7 @@ impl ToCss for UrlMatchingFunction {
|
|||
/// The `@document` rule's condition is written as a comma-separated list of
|
||||
/// URL matching functions, and the condition evaluates to true whenever any
|
||||
/// one of those functions evaluates to true.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DocumentCondition(Vec<UrlMatchingFunction>);
|
||||
|
||||
impl DocumentCondition {
|
||||
|
|
|
@ -194,7 +194,7 @@ macro_rules! font_face_descriptors_common {
|
|||
/// Data inside a `@font-face` rule.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-fonts/#font-face-rule
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct FontFaceRuleData {
|
||||
$(
|
||||
#[$doc]
|
||||
|
|
|
@ -1736,6 +1736,10 @@ extern "C" {
|
|||
pub fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed)
|
||||
-> ServoCssRulesStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSheet_Clone(sheet: RawServoStyleSheetBorrowed)
|
||||
-> RawServoStyleSheetStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextOwned)
|
||||
-> RawServoStyleSetOwned;
|
||||
|
|
|
@ -71,7 +71,7 @@ impl KeyframePercentage {
|
|||
|
||||
/// A keyframes selector is a list of percentages or from/to symbols, which are
|
||||
/// converted at parse time to percentages.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct KeyframeSelector(Vec<KeyframePercentage>);
|
||||
|
||||
impl ToCss for KeyframeSelector {
|
||||
|
@ -150,6 +150,16 @@ impl Keyframe {
|
|||
};
|
||||
parse_one_rule(&mut input, &mut rule_parser)
|
||||
}
|
||||
|
||||
/// Deep clones this Keyframe.
|
||||
pub fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> Keyframe {
|
||||
let guard = lock.read();
|
||||
Keyframe {
|
||||
selector: self.selector.clone(),
|
||||
block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A keyframes step value. This can be a synthetised keyframes animation, that
|
||||
|
|
|
@ -37,6 +37,7 @@ use servo_config::prefs::PREFS;
|
|||
#[cfg(not(feature = "gecko"))]
|
||||
use servo_url::ServoUrl;
|
||||
use shared_lock::{SharedRwLock, Locked, ToCssWithGuard, SharedRwLockReadGuard};
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
@ -91,7 +92,7 @@ pub enum Origin {
|
|||
}
|
||||
|
||||
/// A set of namespaces applying to a given stylesheet.
|
||||
#[derive(Default, Debug)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct Namespaces {
|
||||
pub default: Option<Namespace>,
|
||||
|
@ -107,6 +108,15 @@ impl CssRules {
|
|||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
/// Creates a deep clone where each CssRule has also been cloned with
|
||||
/// the provided lock.
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> CssRules {
|
||||
CssRules(
|
||||
self.0.iter().map(|ref x| x.deep_clone_with_lock(lock)).collect()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
|
@ -469,6 +479,64 @@ impl CssRule {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Deep clones this CssRule.
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> CssRule {
|
||||
let guard = lock.read();
|
||||
match *self {
|
||||
CssRule::Namespace(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
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())))
|
||||
},
|
||||
CssRule::Style(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::Style(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock))))
|
||||
},
|
||||
CssRule::Media(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::Media(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock))))
|
||||
},
|
||||
CssRule::FontFace(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::FontFace(Arc::new(lock.wrap(rule.clone())))
|
||||
},
|
||||
CssRule::CounterStyle(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::CounterStyle(Arc::new(lock.wrap(rule.clone())))
|
||||
},
|
||||
CssRule::Viewport(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::Viewport(Arc::new(lock.wrap(rule.clone())))
|
||||
},
|
||||
CssRule::Keyframes(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::Keyframes(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock))))
|
||||
},
|
||||
CssRule::Supports(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::Supports(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock))))
|
||||
},
|
||||
CssRule::Page(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::Page(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock))))
|
||||
},
|
||||
CssRule::Document(ref arc) => {
|
||||
let rule = arc.read_with(&guard);
|
||||
CssRule::Document(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock))))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCssWithGuard for CssRule {
|
||||
|
@ -500,7 +568,7 @@ fn get_location_with_offset(location: SourceLocation, offset: u64)
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct NamespaceRule {
|
||||
/// `None` for the default Namespace
|
||||
|
@ -540,6 +608,16 @@ pub struct ImportRule {
|
|||
pub stylesheet: Arc<Stylesheet>,
|
||||
}
|
||||
|
||||
impl Clone for ImportRule {
|
||||
fn clone(&self) -> ImportRule {
|
||||
let stylesheet: &Stylesheet = self.stylesheet.borrow();
|
||||
ImportRule {
|
||||
url: self.url.clone(),
|
||||
stylesheet: Arc::new(stylesheet.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCssWithGuard for ImportRule {
|
||||
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write {
|
||||
|
@ -604,6 +682,23 @@ impl KeyframesRule {
|
|||
}
|
||||
}
|
||||
|
||||
impl KeyframesRule {
|
||||
/// Deep clones this KeyframesRule.
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> KeyframesRule {
|
||||
let guard = lock.read();
|
||||
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))))
|
||||
.collect(),
|
||||
vendor_prefix: self.vendor_prefix.clone(),
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug)]
|
||||
pub struct MediaRule {
|
||||
|
@ -628,6 +723,21 @@ impl ToCssWithGuard for MediaRule {
|
|||
}
|
||||
}
|
||||
|
||||
impl MediaRule {
|
||||
/// Deep clones this MediaRule.
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> MediaRule {
|
||||
let guard = lock.read();
|
||||
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))),
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
/// An @supports rule
|
||||
|
@ -656,6 +766,20 @@ impl ToCssWithGuard for SupportsRule {
|
|||
}
|
||||
}
|
||||
|
||||
impl SupportsRule {
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> SupportsRule {
|
||||
let guard = lock.read();
|
||||
let rules = self.rules.read_with(&guard);
|
||||
SupportsRule {
|
||||
condition: self.condition.clone(),
|
||||
rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock))),
|
||||
enabled: self.enabled,
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`@page`][page] rule. This implements only a limited subset of the CSS 2.2 syntax. In this
|
||||
/// subset, [page selectors][page-selectors] are not implemented.
|
||||
///
|
||||
|
@ -682,6 +806,17 @@ impl ToCssWithGuard for PageRule {
|
|||
}
|
||||
}
|
||||
|
||||
impl PageRule {
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> PageRule {
|
||||
let guard = lock.read();
|
||||
PageRule {
|
||||
block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())),
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug)]
|
||||
pub struct StyleRule {
|
||||
|
@ -711,6 +846,19 @@ impl ToCssWithGuard for StyleRule {
|
|||
}
|
||||
}
|
||||
|
||||
impl StyleRule {
|
||||
/// Deep clones this StyleRule.
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> StyleRule {
|
||||
let guard = lock.read();
|
||||
StyleRule {
|
||||
selectors: self.selectors.clone(),
|
||||
block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())),
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A @font-face rule
|
||||
#[cfg(feature = "servo")]
|
||||
pub type FontFaceRule = FontFaceRuleData;
|
||||
|
@ -744,6 +892,20 @@ impl ToCssWithGuard for DocumentRule {
|
|||
}
|
||||
}
|
||||
|
||||
impl DocumentRule {
|
||||
/// Deep clones this DocumentRule.
|
||||
fn deep_clone_with_lock(&self,
|
||||
lock: &SharedRwLock) -> DocumentRule {
|
||||
let guard = lock.read();
|
||||
let rules = self.rules.read_with(&guard);
|
||||
DocumentRule {
|
||||
condition: self.condition.clone(),
|
||||
rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock))),
|
||||
source_location: self.source_location.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Stylesheet {
|
||||
/// Updates an empty stylesheet from a given string of text.
|
||||
pub fn update_from_str(existing: &Stylesheet,
|
||||
|
@ -901,6 +1063,35 @@ impl Stylesheet {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for Stylesheet {
|
||||
fn clone(&self) -> Stylesheet {
|
||||
// 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);
|
||||
|
||||
// Make a deep clone of the media, using the new lock.
|
||||
let media = self.media.read_with(&guard);
|
||||
let cloned_media = media.clone();
|
||||
|
||||
Stylesheet {
|
||||
rules: Arc::new(lock.wrap(cloned_rules)),
|
||||
media: Arc::new(lock.wrap(cloned_media)),
|
||||
origin: self.origin,
|
||||
url_data: self.url_data.clone(),
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn effective_rules<F>(rules: &[CssRule],
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::fmt;
|
|||
use style_traits::ToCss;
|
||||
use stylesheets::CssRuleType;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
/// An @supports condition
|
||||
///
|
||||
/// https://drafts.csswg.org/css-conditional-3/#at-supports
|
||||
|
@ -162,7 +162,7 @@ impl ToCss for SupportsCondition {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
/// A possibly-invalid property declaration
|
||||
pub struct Declaration {
|
||||
/// The property name
|
||||
|
|
|
@ -309,7 +309,7 @@ impl<'a, 'b> DeclarationParser for ViewportRuleParser<'a, 'b> {
|
|||
}
|
||||
|
||||
/// A `@viewport` rule.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct ViewportRule {
|
||||
/// The declarations contained in this @viewport rule.
|
||||
|
|
|
@ -792,6 +792,12 @@ pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -
|
|||
Stylesheet::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()
|
||||
}
|
||||
|
||||
fn read_locked_arc<T, R, F>(raw: &<Locked<T> as HasFFI>::FFIType, func: F) -> R
|
||||
where Locked<T>: HasArcFFI, F: FnOnce(&T) -> R
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче