mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Bug 1331213: Bootstrap a Gecko-side Device, and track it's dirtiness manually in the per-doc data. r=heycam
The setup is quite different to Servo-land, so add a comment about the different setup. Also, check viewport rules when flushing stylesheets. I believe that the previous behavior is plain wrong, though I haven't taken the time to come up with a test case. In any case, it doesn't hurt any of both back-ends. MozReview-Commit-ID: 46gtTkesOsr Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
parent
5d6ac65e04
commit
5b5243b8af
11 changed files with 685 additions and 83 deletions
|
@ -497,6 +497,7 @@ mod bindings {
|
|||
"RawGeckoAnimationValueList",
|
||||
"RawServoAnimationValue",
|
||||
"RawGeckoPresContext",
|
||||
"RawGeckoPresContextOwned",
|
||||
"ThreadSafeURIHolder",
|
||||
"ThreadSafePrincipalHolder",
|
||||
"CSSPseudoClassType",
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
use animation::Animation;
|
||||
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
||||
use dom::OpaqueNode;
|
||||
use euclid::size::TypedSize2D;
|
||||
use gecko_bindings::bindings::RawGeckoPresContextBorrowed;
|
||||
use gecko_bindings::bindings::RawServoStyleSet;
|
||||
use gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
|
||||
use media_queries::{Device, MediaType};
|
||||
use media_queries::Device;
|
||||
use num_cpus;
|
||||
use parking_lot::RwLock;
|
||||
use properties::ComputedValues;
|
||||
|
@ -21,7 +20,6 @@ use std::collections::HashMap;
|
|||
use std::env;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||
use style_traits::ViewportPx;
|
||||
use stylesheets::Stylesheet;
|
||||
use stylist::Stylist;
|
||||
|
||||
|
@ -37,6 +35,9 @@ pub struct PerDocumentStyleDataImpl {
|
|||
/// Whether the stylesheets list above has changed since the last restyle.
|
||||
pub stylesheets_changed: bool,
|
||||
|
||||
/// Whether the device has changed since the last restyle.
|
||||
pub device_changed: bool,
|
||||
|
||||
// FIXME(bholley): Hook these up to something.
|
||||
/// Unused. Will go away when we actually implement transitions and
|
||||
/// animations properly.
|
||||
|
@ -57,9 +58,6 @@ pub struct PerDocumentStyleDataImpl {
|
|||
|
||||
/// The number of threads of the work queue.
|
||||
pub num_threads: usize,
|
||||
|
||||
/// Default computed values for this document.
|
||||
pub default_computed_values: Arc<ComputedValues>
|
||||
}
|
||||
|
||||
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
|
||||
|
@ -78,15 +76,8 @@ lazy_static! {
|
|||
|
||||
impl PerDocumentStyleData {
|
||||
/// Create a dummy `PerDocumentStyleData`.
|
||||
pub fn new(pres_context: RawGeckoPresContextBorrowed) -> Self {
|
||||
// FIXME(bholley): Real window size.
|
||||
let window_size: TypedSize2D<f32, ViewportPx> = TypedSize2D::new(800.0, 600.0);
|
||||
let default_computed_values = ComputedValues::default_values(pres_context);
|
||||
|
||||
// FIXME(bz): We're going to need to either update the computed values
|
||||
// in the Stylist's Device or give the Stylist a new Device when our
|
||||
// default_computed_values changes.
|
||||
let device = Device::new(MediaType::Screen, window_size, &default_computed_values);
|
||||
pub fn new(pres_context: RawGeckoPresContextOwned) -> Self {
|
||||
let device = Device::new(pres_context);
|
||||
|
||||
let (new_anims_sender, new_anims_receiver) = channel();
|
||||
|
||||
|
@ -94,6 +85,7 @@ impl PerDocumentStyleData {
|
|||
stylist: Arc::new(Stylist::new(device)),
|
||||
stylesheets: vec![],
|
||||
stylesheets_changed: true,
|
||||
device_changed: true,
|
||||
new_animations_sender: new_anims_sender,
|
||||
new_animations_receiver: new_anims_receiver,
|
||||
running_animations: Arc::new(RwLock::new(HashMap::new())),
|
||||
|
@ -106,7 +98,6 @@ impl PerDocumentStyleData {
|
|||
rayon::ThreadPool::new(configuration).ok()
|
||||
},
|
||||
num_threads: *NUM_THREADS,
|
||||
default_computed_values: default_computed_values,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -124,15 +115,30 @@ impl PerDocumentStyleData {
|
|||
impl PerDocumentStyleDataImpl {
|
||||
/// Recreate the style data if the stylesheets have changed.
|
||||
pub fn flush_stylesheets(&mut self) {
|
||||
// The stylist wants to be flushed if either the stylesheets change or the
|
||||
// device dimensions change. When we add support for media queries, we'll
|
||||
// need to detect the latter case and trigger a flush as well.
|
||||
let mut stylist = if self.device_changed || self.stylesheets_changed {
|
||||
Some(Arc::get_mut(&mut self.stylist).unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if self.device_changed {
|
||||
Arc::get_mut(&mut stylist.as_mut().unwrap().device).unwrap().reset();
|
||||
self.device_changed = false;
|
||||
// Force a stylesheet flush if the device has changed.
|
||||
self.stylesheets_changed = true;
|
||||
}
|
||||
|
||||
if self.stylesheets_changed {
|
||||
let _ = Arc::get_mut(&mut self.stylist).unwrap()
|
||||
.update(&self.stylesheets, None, true);
|
||||
let _ = stylist.unwrap().update(&self.stylesheets, None, true);
|
||||
self.stylesheets_changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the default computed values for this document.
|
||||
pub fn default_computed_values(&self) -> &Arc<ComputedValues> {
|
||||
debug_assert!(!self.device_changed, "A device flush was pending");
|
||||
self.stylist.device.default_values_arc()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl HasFFI for PerDocumentStyleData {
|
||||
|
|
359
components/style/gecko/media_queries.rs
Normal file
359
components/style/gecko/media_queries.rs
Normal file
|
@ -0,0 +1,359 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
//! Gecko's media-query device and expression representation.
|
||||
|
||||
use app_units::Au;
|
||||
use cssparser::{Parser, Token};
|
||||
use euclid::Size2D;
|
||||
use gecko_bindings::bindings;
|
||||
use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature};
|
||||
use gecko_bindings::structs::{nsMediaFeature_ValueType, nsMediaFeature_RangeType, nsMediaFeature_RequirementFlags};
|
||||
use gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use media_queries::MediaType;
|
||||
use properties::ComputedValues;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use string_cache::Atom;
|
||||
use style_traits::ToCss;
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use values::{CSSFloat, specified};
|
||||
|
||||
/// The `Device` in Gecko wraps a pres context, has a default values computed,
|
||||
/// and contains all the viewport rule state.
|
||||
pub struct Device {
|
||||
/// NB: The pres context lifetime is tied to the styleset, who owns the
|
||||
/// stylist, and thus the `Device`, so having a raw pres context pointer
|
||||
/// here is fine.
|
||||
pres_context: RawGeckoPresContextOwned,
|
||||
default_values: Arc<ComputedValues>,
|
||||
viewport_override: Option<ViewportConstraints>,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
/// Trivially constructs a new `Device`.
|
||||
pub fn new(pres_context: RawGeckoPresContextOwned) -> Self {
|
||||
assert!(!pres_context.is_null());
|
||||
Device {
|
||||
pres_context: pres_context,
|
||||
default_values: ComputedValues::default_values(unsafe { &*pres_context }),
|
||||
viewport_override: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Tells the device that a new viewport rule has been found, and stores the
|
||||
/// relevant viewport constraints.
|
||||
pub fn account_for_viewport_rule(&mut self,
|
||||
constraints: &ViewportConstraints) {
|
||||
self.viewport_override = Some(constraints.clone());
|
||||
}
|
||||
|
||||
/// Returns the default computed values as a reference, in order to match
|
||||
/// Servo.
|
||||
pub fn default_values(&self) -> &ComputedValues {
|
||||
&*self.default_values
|
||||
}
|
||||
|
||||
/// Returns the default computed values as an `Arc`, in order to avoid
|
||||
/// clones.
|
||||
pub fn default_values_arc(&self) -> &Arc<ComputedValues> {
|
||||
&self.default_values
|
||||
}
|
||||
|
||||
/// Recreates all the temporary state that the `Device` stores.
|
||||
///
|
||||
/// This includes the viewport override from `@viewport` rules, and also the
|
||||
/// default computed values.
|
||||
pub fn reset(&mut self) {
|
||||
// NB: A following stylesheet flush will populate this if appropriate.
|
||||
self.viewport_override = None;
|
||||
self.default_values = ComputedValues::default_values(unsafe { &*self.pres_context });
|
||||
}
|
||||
|
||||
/// Returns the current media type of the device.
|
||||
pub fn media_type(&self) -> MediaType {
|
||||
// TODO
|
||||
MediaType::Screen
|
||||
}
|
||||
|
||||
/// Returns the current viewport size in app units.
|
||||
pub fn au_viewport_size(&self) -> Size2D<Au> {
|
||||
self.viewport_override.as_ref().map(|v| {
|
||||
Size2D::new(Au::from_f32_px(v.size.width),
|
||||
Au::from_f32_px(v.size.height))
|
||||
}).unwrap_or_else(|| {
|
||||
// TODO(emilio): Grab from pres context.
|
||||
Size2D::new(Au::from_f32_px(1024.0),
|
||||
Au::from_f32_px(768.0))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for Device {}
|
||||
unsafe impl Send for Device {}
|
||||
|
||||
/// A expression for gecko contains a reference to the media feature, the value
|
||||
/// the media query contained, and the range to evaluate.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Expression {
|
||||
feature: &'static nsMediaFeature,
|
||||
value: MediaExpressionValue,
|
||||
range: nsMediaExpression_Range
|
||||
}
|
||||
|
||||
impl ToCss for Expression {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
dest.write_str("(")?;
|
||||
match self.range {
|
||||
nsMediaExpression_Range::eMin => dest.write_str("min-")?,
|
||||
nsMediaExpression_Range::eMax => dest.write_str("max-")?,
|
||||
nsMediaExpression_Range::eEqual => {},
|
||||
}
|
||||
// NB: CSSStringWriter not needed, features are under control.
|
||||
write!(dest, "{}", Atom::from(unsafe { *self.feature.mName }))?;
|
||||
dest.write_str(": ")?;
|
||||
|
||||
self.value.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
}
|
||||
}
|
||||
|
||||
/// A resolution.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Resolution {
|
||||
/// Dots per inch.
|
||||
Dpi(CSSFloat),
|
||||
/// Dots per pixel.
|
||||
Dppx(CSSFloat),
|
||||
/// Dots per centimeter.
|
||||
Dpcm(CSSFloat),
|
||||
}
|
||||
|
||||
impl Resolution {
|
||||
fn parse(input: &mut Parser) -> Result<Self, ()> {
|
||||
let (value, unit) = match try!(input.next()) {
|
||||
Token::Dimension(value, unit) => {
|
||||
(value.value, unit)
|
||||
},
|
||||
_ => return Err(()),
|
||||
};
|
||||
|
||||
Ok(match_ignore_ascii_case! { unit,
|
||||
"dpi" => Resolution::Dpi(value),
|
||||
"dppx" => Resolution::Dppx(value),
|
||||
"dpcm" => Resolution::Dpcm(value),
|
||||
_ => return Err(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for Resolution {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
Resolution::Dpi(v) => write!(dest, "{}dpi", v),
|
||||
Resolution::Dppx(v) => write!(dest, "{}dppx", v),
|
||||
Resolution::Dpcm(v) => write!(dest, "{}dpcm", v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A value found or expected in a media expression.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MediaExpressionValue {
|
||||
/// A length.
|
||||
Length(specified::Length),
|
||||
/// A (non-negative) integer.
|
||||
Integer(u32),
|
||||
/// A floating point value.
|
||||
Float(CSSFloat),
|
||||
/// A boolean value, specified as an integer (i.e., either 0 or 1).
|
||||
BoolInteger(bool),
|
||||
/// Two integers separated by '/', with optional whitespace on either side
|
||||
/// of the '/'.
|
||||
IntRatio(u32, u32),
|
||||
/// A resolution.
|
||||
Resolution(Resolution),
|
||||
/// An enumerated index into the variant keyword table.
|
||||
Enumerated(u32),
|
||||
/// An identifier.
|
||||
Ident(Atom),
|
||||
}
|
||||
|
||||
impl ToCss for MediaExpressionValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
MediaExpressionValue::Length(ref l) => l.to_css(dest),
|
||||
MediaExpressionValue::Integer(v) => write!(dest, "{}", v),
|
||||
MediaExpressionValue::Float(v) => write!(dest, "{}", v),
|
||||
MediaExpressionValue::BoolInteger(v) => {
|
||||
dest.write_str(if v { "1" } else { "0" })
|
||||
},
|
||||
MediaExpressionValue::IntRatio(a, b) => {
|
||||
write!(dest, "{}/{}", a, b)
|
||||
},
|
||||
MediaExpressionValue::Resolution(ref r) => r.to_css(dest),
|
||||
MediaExpressionValue::Enumerated(..) |
|
||||
MediaExpressionValue::Ident(..) => {
|
||||
// TODO(emilio)
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn starts_with_ignore_ascii_case(string: &str, prefix: &str) -> bool {
|
||||
string.len() > prefix.len() &&
|
||||
string[0..prefix.len()].eq_ignore_ascii_case(prefix)
|
||||
}
|
||||
|
||||
#[allow(warnings)]
|
||||
fn find_feature<F>(mut f: F) -> Option<&'static nsMediaFeature>
|
||||
where F: FnMut(&'static nsMediaFeature) -> bool,
|
||||
{
|
||||
// FIXME(emilio): With build-time bindgen, we would be able to use
|
||||
// structs::nsMediaFeatures_features. That would unfortunately break MSVC
|
||||
// builds, or require one bindings file per platform.
|
||||
//
|
||||
// I'm not into any of those, so meanwhile let's use a FFI function.
|
||||
unsafe {
|
||||
let mut features = bindings::Gecko_GetMediaFeatures();
|
||||
while !(*features).mName.is_null() {
|
||||
if f(&*features) {
|
||||
return Some(&*features);
|
||||
}
|
||||
features = features.offset(1);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
impl Expression {
|
||||
/// Trivially construct a new expression.
|
||||
fn new(feature: &'static nsMediaFeature,
|
||||
value: MediaExpressionValue,
|
||||
range: nsMediaExpression_Range) -> Self {
|
||||
Expression {
|
||||
feature: feature,
|
||||
value: value,
|
||||
range: range,
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a media expression of the form:
|
||||
///
|
||||
/// ```
|
||||
/// (media-feature: media-value)
|
||||
/// ```
|
||||
#[allow(warnings)]
|
||||
pub fn parse(input: &mut Parser) -> Result<Self, ()> {
|
||||
try!(input.expect_parenthesis_block());
|
||||
input.parse_nested_block(|input| {
|
||||
let ident = try!(input.expect_ident());
|
||||
try!(input.expect_colon());
|
||||
|
||||
let mut flags = 0;
|
||||
let mut feature_name = &*ident;
|
||||
|
||||
// TODO(emilio): this is under a pref in Gecko.
|
||||
if starts_with_ignore_ascii_case(feature_name, "-webkit-") {
|
||||
feature_name = &feature_name[8..];
|
||||
flags |= nsMediaFeature_RequirementFlags::eHasWebkitPrefix as u8;
|
||||
}
|
||||
|
||||
let range = if starts_with_ignore_ascii_case(feature_name, "min-") {
|
||||
feature_name = &feature_name[4..];
|
||||
nsMediaExpression_Range::eMin
|
||||
} else if starts_with_ignore_ascii_case(feature_name, "max-") {
|
||||
feature_name = &feature_name[4..];
|
||||
nsMediaExpression_Range::eMax
|
||||
} else {
|
||||
nsMediaExpression_Range::eEqual
|
||||
};
|
||||
|
||||
let atom = Atom::from(feature_name);
|
||||
let feature =
|
||||
match find_feature(|f| atom.as_ptr() == unsafe { *f.mName }) {
|
||||
Some(f) => f,
|
||||
None => return Err(()),
|
||||
};
|
||||
|
||||
if (feature.mReqFlags & !flags) != 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
if range != nsMediaExpression_Range::eEqual &&
|
||||
feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let value = match feature.mValueType {
|
||||
nsMediaFeature_ValueType::eLength => {
|
||||
MediaExpressionValue::Length(
|
||||
specified::Length::parse_non_negative(input)?)
|
||||
},
|
||||
nsMediaFeature_ValueType::eInteger => {
|
||||
let i = input.expect_integer()?;
|
||||
if i < 0 {
|
||||
return Err(())
|
||||
}
|
||||
MediaExpressionValue::Integer(i as u32)
|
||||
}
|
||||
nsMediaFeature_ValueType::eBoolInteger => {
|
||||
let i = input.expect_integer()?;
|
||||
if i < 0 || i > 1 {
|
||||
return Err(())
|
||||
}
|
||||
MediaExpressionValue::BoolInteger(i == 1)
|
||||
}
|
||||
nsMediaFeature_ValueType::eFloat => {
|
||||
MediaExpressionValue::Float(input.expect_number()?)
|
||||
}
|
||||
nsMediaFeature_ValueType::eIntRatio => {
|
||||
let a = input.expect_integer()?;
|
||||
if a <= 0 {
|
||||
return Err(())
|
||||
}
|
||||
|
||||
input.expect_delim('/')?;
|
||||
|
||||
let b = input.expect_integer()?;
|
||||
if b <= 0 {
|
||||
return Err(())
|
||||
}
|
||||
MediaExpressionValue::IntRatio(a as u32, b as u32)
|
||||
}
|
||||
nsMediaFeature_ValueType::eResolution => {
|
||||
MediaExpressionValue::Resolution(Resolution::parse(input)?)
|
||||
}
|
||||
nsMediaFeature_ValueType::eEnumerated => {
|
||||
let index = unsafe {
|
||||
let _table = feature.mData.mKeywordTable.as_ref();
|
||||
0
|
||||
};
|
||||
MediaExpressionValue::Enumerated(index)
|
||||
}
|
||||
nsMediaFeature_ValueType::eIdent => {
|
||||
MediaExpressionValue::Ident(input.expect_ident()?.into())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Expression::new(feature, value, range))
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns whether this media query evaluates to true for the given
|
||||
/// device.
|
||||
pub fn matches(&self, _device: &Device) -> bool {
|
||||
// TODO
|
||||
false
|
||||
}
|
||||
}
|
|
@ -6,12 +6,7 @@
|
|||
|
||||
pub mod conversions;
|
||||
pub mod data;
|
||||
|
||||
// TODO(emilio): Implement Gecko media query parsing and evaluation using
|
||||
// nsMediaFeatures.
|
||||
#[path = "../servo/media_queries.rs"]
|
||||
pub mod media_queries;
|
||||
|
||||
pub mod restyle_damage;
|
||||
pub mod selector_parser;
|
||||
pub mod snapshot;
|
||||
|
|
|
@ -9,6 +9,7 @@ use gecko_bindings::structs::RawGeckoNode;
|
|||
use gecko_bindings::structs::RawGeckoAnimationValueList;
|
||||
use gecko_bindings::structs::RawServoAnimationValue;
|
||||
use gecko_bindings::structs::RawGeckoPresContext;
|
||||
use gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use gecko_bindings::structs::ThreadSafeURIHolder;
|
||||
use gecko_bindings::structs::ThreadSafePrincipalHolder;
|
||||
use gecko_bindings::structs::CSSPseudoClassType;
|
||||
|
@ -1118,14 +1119,11 @@ extern "C" {
|
|||
-> ServoCssRulesStrong;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextBorrowed)
|
||||
pub fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextOwned)
|
||||
-> RawServoStyleSetOwned;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_RecomputeDefaultStyles(set:
|
||||
RawServoStyleSetBorrowed,
|
||||
pres_context:
|
||||
RawGeckoPresContextBorrowed);
|
||||
pub fn Servo_StyleSet_RebuildData(set: RawServoStyleSetBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowed,
|
||||
|
|
|
@ -2957,7 +2957,7 @@ pub mod root {
|
|||
* The FramePropertyTable is optimized for storing 0 or 1 properties on
|
||||
* a given frame. Storing very large numbers of properties on a single
|
||||
* frame will not be efficient.
|
||||
*
|
||||
*
|
||||
* Property values are passed as void* but do not actually have to be
|
||||
* valid pointers. You can use NS_INT32_TO_PTR/NS_PTR_TO_INT32 to
|
||||
* store int32_t values. Null/zero values can be stored and retrieved.
|
||||
|
@ -12149,9 +12149,11 @@ pub mod root {
|
|||
pub type RawGeckoElementBorrowedOrNull = *const root::RawGeckoElement;
|
||||
pub type RawGeckoDocumentBorrowed = *const root::RawGeckoDocument;
|
||||
pub type RawGeckoDocumentBorrowedOrNull = *const root::RawGeckoDocument;
|
||||
pub type RawGeckoPresContextOwned = *mut [u64; 162usize];
|
||||
pub type RawGeckoPresContextBorrowed = *const [u64; 162usize];
|
||||
pub type RawGeckoAnimationValueListBorrowedMut =
|
||||
*mut root::RawGeckoAnimationValueList;
|
||||
pub type RawGeckoPresContextBorrowedMut = *mut [u64; 162usize];
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsCSSTokenSerializationType {
|
||||
|
@ -13600,6 +13602,125 @@ pub mod root {
|
|||
pub type ThreadSafePrincipalHolder =
|
||||
root::nsMainThreadPtrHolder<root::nsIPrincipal>;
|
||||
pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
pub struct nsMediaFeature {
|
||||
pub mName: *mut *mut root::nsIAtom,
|
||||
pub mRangeType: root::nsMediaFeature_RangeType,
|
||||
pub mValueType: root::nsMediaFeature_ValueType,
|
||||
pub mReqFlags: u8,
|
||||
pub mData: root::nsMediaFeature__bindgen_ty_1,
|
||||
pub mGetter: root::nsMediaFeatureValueGetter,
|
||||
}
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaFeature_RangeType {
|
||||
eMinMaxAllowed = 0,
|
||||
eMinMaxNotAllowed = 1,
|
||||
}
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaFeature_ValueType {
|
||||
eLength = 0,
|
||||
eInteger = 1,
|
||||
eFloat = 2,
|
||||
eBoolInteger = 3,
|
||||
eIntRatio = 4,
|
||||
eResolution = 5,
|
||||
eEnumerated = 6,
|
||||
eIdent = 7,
|
||||
}
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaFeature_RequirementFlags {
|
||||
eNoRequirements = 0,
|
||||
eHasWebkitPrefix = 1,
|
||||
eWebkitDevicePixelRatioPrefEnabled = 2,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
pub struct nsMediaFeature__bindgen_ty_1 {
|
||||
pub mInitializer_: root::__BindgenUnionField<*const ::std::os::raw::c_void>,
|
||||
pub mKeywordTable: root::__BindgenUnionField<*const root::nsCSSProps_KTableEntry>,
|
||||
pub mMetric: root::__BindgenUnionField<*const *const root::nsIAtom>,
|
||||
pub bindgen_union_field: u64,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaFeature__bindgen_ty_1() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaFeature__bindgen_ty_1>() ,
|
||||
8usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaFeature__bindgen_ty_1>() ,
|
||||
8usize);
|
||||
}
|
||||
impl Clone for nsMediaFeature__bindgen_ty_1 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaFeature() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaFeature>() , 40usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaFeature>() , 8usize);
|
||||
}
|
||||
impl Clone for nsMediaFeature {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
pub type ThreadSafePrincipalHolder =
|
||||
root::nsMainThreadPtrHolder<root::nsIPrincipal>;
|
||||
pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>;
|
||||
pub type nsMediaFeatureValueGetter =
|
||||
::std::option::Option<unsafe extern "C" fn(aPresContext:
|
||||
*mut root::nsPresContext,
|
||||
aFeature:
|
||||
*const root::nsMediaFeature,
|
||||
aResult:
|
||||
*mut root::nsCSSValue)
|
||||
-> root::nsresult>;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
pub struct nsMediaFeatures {
|
||||
pub _address: u8,
|
||||
}
|
||||
extern "C" {
|
||||
#[link_name = "_ZN15nsMediaFeatures8featuresE"]
|
||||
pub static mut nsMediaFeatures_features: *const root::nsMediaFeature;
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaFeatures() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaFeatures>() , 1usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaFeatures>() , 1usize);
|
||||
}
|
||||
impl Clone for nsMediaFeatures {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct nsMediaExpression {
|
||||
pub mFeature: *const root::nsMediaFeature,
|
||||
pub mRange: root::nsMediaExpression_Range,
|
||||
pub mValue: root::nsCSSValue,
|
||||
}
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaExpression_Range { eMin = 0, eMax = 1, eEqual = 2, }
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaExpression() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaExpression>() , 32usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaExpression>() , 8usize);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct nsMediaQuery {
|
||||
pub mNegated: bool,
|
||||
pub mHasOnly: bool,
|
||||
pub mTypeOmitted: bool,
|
||||
pub mHadUnknownExpression: bool,
|
||||
pub mMediaType: root::nsCOMPtr<root::nsIAtom>,
|
||||
pub mExpressions: root::nsTArray<root::nsMediaExpression>,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaQuery() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaQuery>() , 24usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaQuery>() , 8usize);
|
||||
}
|
||||
#[test]
|
||||
fn __bindgen_test_layout_template_11() {
|
||||
assert_eq!(::std::mem::size_of::<root::JS::TenuredHeap<*mut root::JSObject>>()
|
||||
|
|
|
@ -2944,7 +2944,7 @@ pub mod root {
|
|||
* The FramePropertyTable is optimized for storing 0 or 1 properties on
|
||||
* a given frame. Storing very large numbers of properties on a single
|
||||
* frame will not be efficient.
|
||||
*
|
||||
*
|
||||
* Property values are passed as void* but do not actually have to be
|
||||
* valid pointers. You can use NS_INT32_TO_PTR/NS_PTR_TO_INT32 to
|
||||
* store int32_t values. Null/zero values can be stored and retrieved.
|
||||
|
@ -12076,9 +12076,11 @@ pub mod root {
|
|||
pub type RawGeckoElementBorrowedOrNull = *const root::RawGeckoElement;
|
||||
pub type RawGeckoDocumentBorrowed = *const root::RawGeckoDocument;
|
||||
pub type RawGeckoDocumentBorrowedOrNull = *const root::RawGeckoDocument;
|
||||
pub type RawGeckoPresContextOwned = *mut [u64; 158usize];
|
||||
pub type RawGeckoPresContextBorrowed = *const [u64; 158usize];
|
||||
pub type RawGeckoAnimationValueListBorrowedMut =
|
||||
*mut root::RawGeckoAnimationValueList;
|
||||
pub type RawGeckoPresContextBorrowedMut = *mut [u64; 158usize];
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsCSSTokenSerializationType {
|
||||
|
@ -13524,9 +13526,125 @@ pub mod root {
|
|||
pub struct nsTArray<T> {
|
||||
pub mBuffer: *mut T,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
pub struct nsMediaFeature {
|
||||
pub mName: *mut *mut root::nsIAtom,
|
||||
pub mRangeType: root::nsMediaFeature_RangeType,
|
||||
pub mValueType: root::nsMediaFeature_ValueType,
|
||||
pub mReqFlags: u8,
|
||||
pub mData: root::nsMediaFeature__bindgen_ty_1,
|
||||
pub mGetter: root::nsMediaFeatureValueGetter,
|
||||
}
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaFeature_RangeType {
|
||||
eMinMaxAllowed = 0,
|
||||
eMinMaxNotAllowed = 1,
|
||||
}
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaFeature_ValueType {
|
||||
eLength = 0,
|
||||
eInteger = 1,
|
||||
eFloat = 2,
|
||||
eBoolInteger = 3,
|
||||
eIntRatio = 4,
|
||||
eResolution = 5,
|
||||
eEnumerated = 6,
|
||||
eIdent = 7,
|
||||
}
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaFeature_RequirementFlags {
|
||||
eNoRequirements = 0,
|
||||
eHasWebkitPrefix = 1,
|
||||
eWebkitDevicePixelRatioPrefEnabled = 2,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
pub struct nsMediaFeature__bindgen_ty_1 {
|
||||
pub mInitializer_: root::__BindgenUnionField<*const ::std::os::raw::c_void>,
|
||||
pub mKeywordTable: root::__BindgenUnionField<*const root::nsCSSProps_KTableEntry>,
|
||||
pub mMetric: root::__BindgenUnionField<*const *const root::nsIAtom>,
|
||||
pub bindgen_union_field: u64,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaFeature__bindgen_ty_1() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaFeature__bindgen_ty_1>() ,
|
||||
8usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaFeature__bindgen_ty_1>() ,
|
||||
8usize);
|
||||
}
|
||||
impl Clone for nsMediaFeature__bindgen_ty_1 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaFeature() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaFeature>() , 40usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaFeature>() , 8usize);
|
||||
}
|
||||
impl Clone for nsMediaFeature {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
pub type ThreadSafePrincipalHolder =
|
||||
root::nsMainThreadPtrHolder<root::nsIPrincipal>;
|
||||
pub type ThreadSafeURIHolder = root::nsMainThreadPtrHolder<root::nsIURI>;
|
||||
pub type nsMediaFeatureValueGetter =
|
||||
::std::option::Option<unsafe extern "C" fn(aPresContext:
|
||||
*mut root::nsPresContext,
|
||||
aFeature:
|
||||
*const root::nsMediaFeature,
|
||||
aResult:
|
||||
*mut root::nsCSSValue)
|
||||
-> root::nsresult>;
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
pub struct nsMediaFeatures {
|
||||
pub _address: u8,
|
||||
}
|
||||
extern "C" {
|
||||
#[link_name = "_ZN15nsMediaFeatures8featuresE"]
|
||||
pub static mut nsMediaFeatures_features: *const root::nsMediaFeature;
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaFeatures() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaFeatures>() , 1usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaFeatures>() , 1usize);
|
||||
}
|
||||
impl Clone for nsMediaFeatures {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct nsMediaExpression {
|
||||
pub mFeature: *const root::nsMediaFeature,
|
||||
pub mRange: root::nsMediaExpression_Range,
|
||||
pub mValue: root::nsCSSValue,
|
||||
}
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum nsMediaExpression_Range { eMin = 0, eMax = 1, eEqual = 2, }
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaExpression() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaExpression>() , 32usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaExpression>() , 8usize);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct nsMediaQuery {
|
||||
pub mNegated: bool,
|
||||
pub mHasOnly: bool,
|
||||
pub mTypeOmitted: bool,
|
||||
pub mHadUnknownExpression: bool,
|
||||
pub mMediaType: root::nsCOMPtr<root::nsIAtom>,
|
||||
pub mExpressions: root::nsTArray<root::nsMediaExpression>,
|
||||
}
|
||||
#[test]
|
||||
fn bindgen_test_layout_nsMediaQuery() {
|
||||
assert_eq!(::std::mem::size_of::<nsMediaQuery>() , 24usize);
|
||||
assert_eq!(::std::mem::align_of::<nsMediaQuery>() , 8usize);
|
||||
}
|
||||
#[test]
|
||||
fn __bindgen_test_layout_template_11() {
|
||||
assert_eq!(::std::mem::size_of::<root::JS::TenuredHeap<*mut root::JSObject>>()
|
||||
|
|
|
@ -19,7 +19,7 @@ pub use servo::media_queries::{Device, Expression};
|
|||
pub use gecko::media_queries::{Device, Expression};
|
||||
|
||||
/// A type that encapsulates a media query list.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct MediaList {
|
||||
/// The list of media queries.
|
||||
|
@ -66,7 +66,7 @@ impl ToCss for Qualifier {
|
|||
/// A [media query][mq].
|
||||
///
|
||||
/// [mq]: https://drafts.csswg.org/mediaqueries/
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct MediaQuery {
|
||||
/// The qualifier for this query.
|
||||
|
|
|
@ -10,8 +10,6 @@ use euclid::{Size2D, TypedSize2D};
|
|||
use media_queries::MediaType;
|
||||
use properties::ComputedValues;
|
||||
use std::fmt;
|
||||
#[cfg(feature = "gecko")]
|
||||
use std::sync::Arc;
|
||||
use style_traits::{ToCss, ViewportPx};
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use values::computed::{self, ToComputedValue};
|
||||
|
@ -21,24 +19,16 @@ use values::specified;
|
|||
/// is displayed in.
|
||||
///
|
||||
/// This is the struct against which media queries are evaluated.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Debug, HeapSizeOf)]
|
||||
pub struct Device {
|
||||
/// The current media type used by de device.
|
||||
media_type: MediaType,
|
||||
/// The current viewport size, in viewport pixels.
|
||||
viewport_size: TypedSize2D<f32, ViewportPx>,
|
||||
/// A set of default computed values for this document.
|
||||
///
|
||||
/// This allows handling zoom correctly, among other things. Gecko-only for
|
||||
/// now, see #14773.
|
||||
#[cfg(feature = "gecko")]
|
||||
default_values: Arc<ComputedValues>,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
/// Trivially construct a new `Device`.
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn new(media_type: MediaType,
|
||||
viewport_size: TypedSize2D<f32, ViewportPx>)
|
||||
-> Device {
|
||||
|
@ -48,30 +38,11 @@ impl Device {
|
|||
}
|
||||
}
|
||||
|
||||
/// Trivially construct a new `Device`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn new(media_type:
|
||||
MediaType, viewport_size: TypedSize2D<f32, ViewportPx>,
|
||||
default_values: &Arc<ComputedValues>) -> Device {
|
||||
Device {
|
||||
media_type: media_type,
|
||||
viewport_size: viewport_size,
|
||||
default_values: default_values.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the default computed values for this device.
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn default_values(&self) -> &ComputedValues {
|
||||
ComputedValues::initial_values()
|
||||
}
|
||||
|
||||
/// Return the default computed values for this device.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn default_values(&self) -> &ComputedValues {
|
||||
&*self.default_values
|
||||
}
|
||||
|
||||
/// Returns the viewport size of the current device in app units, needed,
|
||||
/// among other things, to resolve viewport units.
|
||||
#[inline]
|
||||
|
|
|
@ -49,6 +49,20 @@ pub use ::fnv::FnvHashMap;
|
|||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct Stylist {
|
||||
/// Device that the stylist is currently evaluating against.
|
||||
///
|
||||
/// This field deserves a bigger comment due to the different use that Gecko
|
||||
/// and Servo give to it (that we should eventually unify).
|
||||
///
|
||||
/// With Gecko, the device is never changed. Gecko manually tracks whether
|
||||
/// the device data should be reconstructed, and "resets" the state of the
|
||||
/// device.
|
||||
///
|
||||
/// On Servo, on the other hand, the device is a really cheap representation
|
||||
/// that is recreated each time some constraint changes and calling
|
||||
/// `set_device`.
|
||||
///
|
||||
/// In both cases, the device is actually _owned_ by the Stylist, and it's
|
||||
/// only an `Arc` so we can implement `add_stylesheet` more idiomatically.
|
||||
pub device: Arc<Device>,
|
||||
|
||||
/// Viewport constraints based on the current device.
|
||||
|
@ -146,6 +160,18 @@ impl Stylist {
|
|||
return false;
|
||||
}
|
||||
|
||||
let cascaded_rule = ViewportRule {
|
||||
declarations: viewport::Cascade::from_stylesheets(doc_stylesheets, &self.device).finish(),
|
||||
};
|
||||
|
||||
self.viewport_constraints =
|
||||
ViewportConstraints::maybe_new(&self.device, &cascaded_rule);
|
||||
|
||||
if let Some(ref constraints) = self.viewport_constraints {
|
||||
Arc::get_mut(&mut self.device).unwrap()
|
||||
.account_for_viewport_rule(constraints);
|
||||
}
|
||||
|
||||
self.element_map = PerPseudoElementSelectorMap::new();
|
||||
self.pseudos_map = Default::default();
|
||||
self.animations = Default::default();
|
||||
|
@ -394,6 +420,13 @@ impl Stylist {
|
|||
///
|
||||
/// Probably worth to make the stylist own a single `Device`, and have a
|
||||
/// `update_device` function?
|
||||
///
|
||||
/// feature = "servo" because gecko only has one device, and manually tracks
|
||||
/// when the device is dirty.
|
||||
///
|
||||
/// FIXME(emilio): The semantics of the device for Servo and Gecko are
|
||||
/// different enough we may want to unify them.
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet>]) {
|
||||
let cascaded_rule = ViewportRule {
|
||||
declarations: viewport::Cascade::from_stylesheets(stylesheets, &device).finish(),
|
||||
|
|
|
@ -37,12 +37,12 @@ use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong
|
|||
use style::gecko_bindings::bindings::{nsACString, nsAString};
|
||||
use style::gecko_bindings::bindings::RawGeckoAnimationValueListBorrowedMut;
|
||||
use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
|
||||
use style::gecko_bindings::bindings::RawGeckoPresContextBorrowed;
|
||||
use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
|
||||
use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
|
||||
use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
|
||||
use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
|
||||
use style::gecko_bindings::structs;
|
||||
use style::gecko_bindings::structs::{RawGeckoPresContextOwned, RawGeckoPresContextBorrowed};
|
||||
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
|
||||
use style::gecko_bindings::structs::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
|
||||
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint};
|
||||
|
@ -111,7 +111,7 @@ fn create_shared_context(per_doc_data: &PerDocumentStyleDataImpl) -> SharedStyle
|
|||
timer: Timer::new(),
|
||||
// FIXME Find the real QuirksMode information for this document
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
default_computed_values: per_doc_data.default_computed_values.clone(),
|
||||
default_computed_values: per_doc_data.default_computed_values().clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ pub extern "C" fn Servo_RestyleWithAddedDeclaration(raw_data: RawServoStyleSetBo
|
|||
/* is_root_element = */ false,
|
||||
declarations,
|
||||
previous_style,
|
||||
&data.default_computed_values,
|
||||
data.default_computed_values(),
|
||||
None,
|
||||
Box::new(StdoutErrorReporter),
|
||||
None,
|
||||
|
@ -597,7 +597,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
|||
|
||||
let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
|
||||
data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent,
|
||||
&data.default_computed_values, false)
|
||||
data.default_computed_values(), false)
|
||||
.values
|
||||
.into_strong()
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
|
|||
return if is_probe {
|
||||
Strong::null()
|
||||
} else {
|
||||
doc_data.borrow().default_computed_values.clone().into_strong()
|
||||
doc_data.borrow().default_computed_values().clone().into_strong()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -640,7 +640,7 @@ fn get_pseudo_style(element: GeckoElement, pseudo_tag: *mut nsIAtom,
|
|||
PseudoElementCascadeType::Lazy => {
|
||||
let d = doc_data.borrow_mut();
|
||||
let base = &styles.primary.values;
|
||||
d.stylist.lazily_compute_pseudo_element_style(&element, &pseudo, base, &d.default_computed_values)
|
||||
d.stylist.lazily_compute_pseudo_element_style(&element, &pseudo, base, &d.default_computed_values())
|
||||
.map(|s| s.values.clone())
|
||||
},
|
||||
}
|
||||
|
@ -654,37 +654,37 @@ pub extern "C" fn Servo_ComputedValues_Inherit(
|
|||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||
let maybe_arc = ComputedValues::arc_from_borrowed(&parent_style);
|
||||
let style = if let Some(reference) = maybe_arc.as_ref() {
|
||||
ComputedValues::inherit_from(reference, &data.default_computed_values)
|
||||
ComputedValues::inherit_from(reference, &data.default_computed_values())
|
||||
} else {
|
||||
data.default_computed_values.clone()
|
||||
data.default_computed_values().clone()
|
||||
};
|
||||
style.into_strong()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed) -> () {
|
||||
pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed) {
|
||||
unsafe { ComputedValues::addref(ptr) };
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) -> () {
|
||||
pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) {
|
||||
unsafe { ComputedValues::release(ptr) };
|
||||
}
|
||||
|
||||
/// See the comment in `Device` to see why it's ok to pass an owned reference to
|
||||
/// the pres context (hint: the context outlives the StyleSet, that holds the
|
||||
/// device alive).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextBorrowed)
|
||||
pub extern "C" fn Servo_StyleSet_Init(pres_context: RawGeckoPresContextOwned)
|
||||
-> RawServoStyleSetOwned {
|
||||
let data = Box::new(PerDocumentStyleData::new(pres_context));
|
||||
data.into_ffi()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_RecomputeDefaultStyles(
|
||||
raw_data: RawServoStyleSetBorrowed,
|
||||
pres_context: RawGeckoPresContextBorrowed) {
|
||||
pub extern "C" fn Servo_StyleSet_RebuildData(raw_data: RawServoStyleSetBorrowed) {
|
||||
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
|
||||
data.default_computed_values = ComputedValues::default_values(pres_context);
|
||||
// FIXME(bz): We need to update our Stylist's Device's computed values, but how?
|
||||
data.device_changed = true;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -1034,7 +1034,7 @@ pub extern "C" fn Servo_ResolveStyle(element: RawGeckoElementBorrowed,
|
|||
if !data.has_current_styles() {
|
||||
error!("Resolving style on unstyled element with lazy computation forbidden.");
|
||||
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||
return per_doc_data.default_computed_values.clone().into_strong();
|
||||
return per_doc_data.default_computed_values().clone().into_strong();
|
||||
}
|
||||
|
||||
data.styles().primary.values.clone().into_strong()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue