Auto merge of #21724 - emilio:gecko-sync, r=emilio

style: Sync changes from mozilla-central

See each individual commit for details.

<!-- 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/21724)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-09-15 13:19:54 -04:00 committed by GitHub
commit 6c2f41bd0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 239 additions and 68 deletions

View file

@ -15,6 +15,7 @@ servo = [
"mozjs",
"serde",
"serde_bytes",
"servo_channel",
"string_cache",
"time",
"url",
@ -34,7 +35,7 @@ selectors = { path = "../selectors" }
serde = { version = "1.0.27", optional = true }
serde_bytes = { version = "0.10", optional = true }
servo_arc = { path = "../servo_arc" }
servo_channel = {path = "../channel"}
servo_channel = { path = "../channel", optional = true }
smallbitvec = "2.1.0"
smallvec = "0.6"
string_cache = { version = "0.7", optional = true }

View file

@ -59,6 +59,7 @@ extern crate serde;
#[cfg(feature = "servo")]
extern crate serde_bytes;
extern crate servo_arc;
#[cfg(feature = "servo")]
extern crate servo_channel;
extern crate smallbitvec;
extern crate smallvec;
@ -1024,6 +1025,7 @@ where
// Placeholder for unique case where internals of Sender cannot be measured.
// malloc size of is 0 macro complains about type supplied!
#[cfg(feature = "servo")]
impl<T> MallocSizeOf for servo_channel::Sender<T> {
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
0

View file

@ -4,6 +4,10 @@
//! CSS transitions and animations.
// NOTE(emilio): This code isn't really executed in Gecko, but we don't want to
// compile it out so that people remember it exists, thus the cfg'd Sender
// import.
use Atom;
use bezier::Bezier;
use context::SharedStyleContext;
@ -15,8 +19,11 @@ use properties::longhands::animation_direction::computed_value::single_value::T
use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState;
use rule_tree::CascadeLevel;
use servo_arc::Arc;
#[cfg(feature = "servo")]
use servo_channel::Sender;
use std::fmt;
#[cfg(feature = "gecko")]
use std::sync::mpsc::Sender;
use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue};
use timer::Timer;
use values::computed::Time;
@ -25,6 +32,7 @@ use values::computed::transform::TimingFunction;
use values::generics::box_::AnimationIterationCount;
use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
/// This structure represents a keyframes animation current iteration state.
///
/// If the iteration count is infinite, there's no other state, otherwise we

View file

@ -8,6 +8,7 @@ use Atom;
use app_units::Au;
use euclid::Size2D;
use gecko_bindings::bindings;
use gecko_bindings::structs;
use media_queries::Device;
use media_queries::media_feature::{AllowsRanges, ParsingRequirements};
use media_queries::media_feature::{MediaFeatureDescription, Evaluator};
@ -300,6 +301,94 @@ fn eval_prefers_reduced_motion(device: &Device, query_value: Option<PrefersReduc
}
}
/// https://drafts.csswg.org/mediaqueries-4/#mf-interaction
bitflags! {
struct PointerCapabilities: u8 {
const COARSE = structs::PointerCapabilities_Coarse;
const FINE = structs::PointerCapabilities_Fine;
const HOVER = structs::PointerCapabilities_Hover;
}
}
fn primary_pointer_capabilities(device: &Device) -> PointerCapabilities {
PointerCapabilities::from_bits_truncate(
unsafe { bindings::Gecko_MediaFeatures_PrimaryPointerCapabilities(device.document()) }
)
}
fn all_pointer_capabilities(device: &Device) -> PointerCapabilities {
PointerCapabilities::from_bits_truncate(
unsafe { bindings::Gecko_MediaFeatures_AllPointerCapabilities(device.document()) }
)
}
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
#[repr(u8)]
enum Pointer {
None,
Coarse,
Fine,
}
fn eval_pointer_capabilities(
query_value: Option<Pointer>,
pointer_capabilities: PointerCapabilities,
) -> bool {
let query_value = match query_value {
Some(v) => v,
None => return !pointer_capabilities.is_empty(),
};
match query_value {
Pointer::None => pointer_capabilities.is_empty(),
Pointer::Coarse => pointer_capabilities.intersects(PointerCapabilities::COARSE),
Pointer::Fine => pointer_capabilities.intersects(PointerCapabilities::FINE),
}
}
/// https://drafts.csswg.org/mediaqueries-4/#pointer
fn eval_pointer(device: &Device, query_value: Option<Pointer>) -> bool {
eval_pointer_capabilities(query_value, primary_pointer_capabilities(device))
}
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-pointer
fn eval_any_pointer(device: &Device, query_value: Option<Pointer>) -> bool {
eval_pointer_capabilities(query_value, all_pointer_capabilities(device))
}
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)]
#[repr(u8)]
enum Hover {
None,
Hover,
}
fn eval_hover_capabilities(
query_value: Option<Hover>,
pointer_capabilities: PointerCapabilities,
) -> bool {
let can_hover = pointer_capabilities.intersects(PointerCapabilities::HOVER);
let query_value = match query_value {
Some(v) => v,
None => return can_hover,
};
match query_value {
Hover::None => !can_hover,
Hover::Hover => can_hover,
}
}
/// https://drafts.csswg.org/mediaqueries-4/#hover
fn eval_hover(device: &Device, query_value: Option<Hover>) -> bool {
eval_hover_capabilities(query_value, primary_pointer_capabilities(device))
}
/// https://drafts.csswg.org/mediaqueries-4/#descdef-media-any-hover
fn eval_any_hover(device: &Device, query_value: Option<Hover>) -> bool {
eval_hover_capabilities(query_value, all_pointer_capabilities(device))
}
fn eval_moz_is_glyph(
device: &Device,
query_value: Option<bool>,
@ -390,7 +479,7 @@ lazy_static! {
/// to support new types in these entries and (2) ensuring that either
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
/// would be returned by the evaluator function could change.
pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 43] = [
pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 47] = [
feature!(
atom!("width"),
AllowsRanges::Yes,
@ -509,6 +598,30 @@ lazy_static! {
keyword_evaluator!(eval_prefers_reduced_motion, PrefersReducedMotion),
ParsingRequirements::empty(),
),
feature!(
atom!("pointer"),
AllowsRanges::No,
keyword_evaluator!(eval_pointer, Pointer),
ParsingRequirements::empty(),
),
feature!(
atom!("any-pointer"),
AllowsRanges::No,
keyword_evaluator!(eval_any_pointer, Pointer),
ParsingRequirements::empty(),
),
feature!(
atom!("hover"),
AllowsRanges::No,
keyword_evaluator!(eval_hover, Hover),
ParsingRequirements::empty(),
),
feature!(
atom!("any-hover"),
AllowsRanges::No,
keyword_evaluator!(eval_any_hover, Hover),
ParsingRequirements::empty(),
),
// Internal -moz-is-glyph media feature: applies only inside SVG glyphs.
// Internal because it is really only useful in the user agent anyway

View file

@ -234,10 +234,13 @@ impl Device {
}
/// Applies text zoom to a font-size or line-height value (see nsStyleFont::ZoomText).
#[inline]
pub fn zoom_text(&self, size: Au) -> Au {
size.scale_by(self.pres_context().mEffectiveTextZoom)
}
/// Un-apply text zoom (see nsStyleFont::UnzoomText).
/// Un-apply text zoom.
#[inline]
pub fn unzoom_text(&self, size: Au) -> Au {
size.scale_by(1. / self.pres_context().mEffectiveTextZoom)
}

View file

@ -9,6 +9,7 @@ use gecko_bindings::bindings;
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::structs::mozilla::css::URLValueData;
use gecko_bindings::structs::root::{RustString, nsStyleImageRequest};
use gecko_bindings::structs::root::mozilla::CORSMode;
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
use gecko_bindings::sugar::refptr::RefPtr;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
@ -186,15 +187,34 @@ impl SpecifiedImageUrl {
Self::from_css_url(CssUrl::parse_from_string(url, context))
}
fn from_css_url(url: CssUrl) -> Self {
fn from_css_url_with_cors(url: CssUrl, cors: CORSMode) -> Self {
let image_value = unsafe {
let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi());
let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi(), cors);
// We do not expect Gecko_ImageValue_Create returns null.
debug_assert!(!ptr.is_null());
RefPtr::from_addrefed(ptr)
};
Self { url, image_value }
}
fn from_css_url(url: CssUrl) -> Self {
use gecko_bindings::structs::root::mozilla::CORSMode_CORS_NONE;
Self::from_css_url_with_cors(url, CORSMode_CORS_NONE)
}
fn from_css_url_with_cors_anonymous(url: CssUrl) -> Self {
use gecko_bindings::structs::root::mozilla::CORSMode_CORS_ANONYMOUS;
Self::from_css_url_with_cors(url, CORSMode_CORS_ANONYMOUS)
}
/// Provides an alternate method for parsing that associates the URL
/// with anonymous CORS headers.
pub fn parse_with_cors_anonymous<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
CssUrl::parse(context, input).map(Self::from_css_url_with_cors_anonymous)
}
}
impl Parse for SpecifiedImageUrl {

View file

@ -2403,7 +2403,8 @@ fn static_assert() {
/// Calculates the constrained and unconstrained font sizes to be inherited
/// from the parent.
///
/// See ComputeScriptLevelSize in Gecko's nsRuleNode.cpp
/// This is a port of Gecko's old ComputeScriptLevelSize function:
/// https://dxr.mozilla.org/mozilla-central/rev/35fbf14b9/layout/style/nsRuleNode.cpp#3197-3254
///
/// scriptlevel is a property that affects how font-size is inherited. If scriptlevel is
/// +1, for example, it will inherit as the script size multiplier times
@ -2511,17 +2512,18 @@ fn static_assert() {
= self.calculate_script_level_size(parent, device);
if adjusted_size.0 != parent.gecko.mSize ||
adjusted_unconstrained_size.0 != parent.gecko.mScriptUnconstrainedSize {
// This is incorrect. When there is both a keyword size being inherited
// and a scriptlevel change, we must handle the keyword size the same
// way we handle em units. This complicates things because we now have
// to keep track of the adjusted and unadjusted ratios in the kw font size.
// This only affects the use case of a generic font being used in MathML.
// FIXME(Manishearth): This is incorrect. When there is both a
// keyword size being inherited and a scriptlevel change, we must
// handle the keyword size the same way we handle em units. This
// complicates things because we now have to keep track of the
// adjusted and unadjusted ratios in the kw font size. This only
// affects the use case of a generic font being used in MathML.
//
// If we were to fix this I would prefer doing it by removing the
// ruletree walk on the Gecko side in nsRuleNode::SetGenericFont
// and instead using extra bookkeeping in the mSize and mScriptUnconstrainedSize
// values, and reusing those instead of font_size_keyword.
// If we were to fix this I would prefer doing it not doing
// something like the ruletree walk that Gecko used to do in
// nsRuleNode::SetGenericFont and instead using extra bookkeeping in
// the mSize and mScriptUnconstrainedSize values, and reusing those
// instead of font_size_keyword.
// In the case that MathML has given us an adjusted size, apply it.
// Keep track of the unconstrained adjusted size.

View file

@ -1200,9 +1200,6 @@ impl StrongRuleNode {
}
}
/// Implementation of `nsRuleNode::HasAuthorSpecifiedRules` for Servo rule
/// nodes.
///
/// Returns true if any properties specified by `rule_type_mask` was set by
/// an author rule.
#[cfg(feature = "gecko")]

View file

@ -98,6 +98,18 @@ impl CssUrl {
resolved: ServoUrl::parse(url).ok(),
}
}
/// Parses a URL request and records that the corresponding request needs to
/// be CORS-enabled.
///
/// This is only for shape images and masks in Gecko, thus unimplemented for
/// now so somebody notices when trying to do so.
pub fn parse_with_cors_anonymous<'i, 't>(
_context: &ParserContext,
_input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
unimplemented!("Need to record somewhere that the request needs to be CORS-enabled")
}
}
impl Parse for CssUrl {

View file

@ -11,7 +11,6 @@ use values::computed::{Angle, Number};
use values::computed::length::Length;
#[cfg(feature = "gecko")]
use values::computed::url::ComputedUrl;
use values::distance::{ComputeSquaredDistance, SquaredDistance};
use values::generics::effects::BoxShadow as GenericBoxShadow;
use values::generics::effects::Filter as GenericFilter;
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
@ -29,14 +28,3 @@ pub type Filter = GenericFilter<Angle, Number, Length, Impossible, Impossible>;
/// An animated value for the `drop-shadow()` filter.
pub type SimpleShadow = GenericSimpleShadow<Color, Length, Length>;
impl ComputeSquaredDistance for BoxShadow {
#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
if self.inset != other.inset {
return Err(());
}
Ok(self.base.compute_squared_distance(&other.base)? +
self.spread.compute_squared_distance(&other.spread)?)
}
}

View file

@ -8,6 +8,7 @@
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Debug,
MallocSizeOf,
PartialEq,

View file

@ -13,7 +13,6 @@ use std::fmt::{self, Write};
use std::io::Cursor;
use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
use values::distance::{ComputeSquaredDistance, SquaredDistance};
/// https://drafts.csswg.org/css-fonts-4/#feature-tag-value
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)]
@ -47,7 +46,16 @@ where
///
/// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def
#[derive(
Animate, Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss,
Animate,
Clone,
ComputeSquaredDistance,
Debug,
Eq,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
)]
pub struct VariationValue<Number> {
/// A four-character tag, packed into a u32 (one byte per character).
@ -57,19 +65,6 @@ pub struct VariationValue<Number> {
pub value: Number,
}
impl<Number> ComputeSquaredDistance for VariationValue<Number>
where
Number: ComputeSquaredDistance,
{
#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
if self.tag != other.tag {
return Err(());
}
self.value.compute_squared_distance(&other.value)
}
}
/// A value both for font-variation-settings and font-feature-settings.
#[css(comma)]
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)]

View file

@ -71,7 +71,12 @@ impl Parse for ClippingShape {
return Ok(ShapeSource::Path(p));
}
}
Self::parse_internal(context, input)
if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) {
return Ok(ShapeSource::ImageOrUrl(url));
}
Self::parse_common(context, input)
}
}
@ -81,17 +86,20 @@ impl Parse for FloatAreaShape {
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_internal(context, input)
if let Ok(image) = input.try(|i| Image::parse_with_cors_anonymous(context, i)) {
return Ok(ShapeSource::ImageOrUrl(image));
}
Self::parse_common(context, input)
}
}
impl<ReferenceBox, ImageOrUrl> ShapeSource<BasicShape, ReferenceBox, ImageOrUrl>
where
ReferenceBox: Parse,
ImageOrUrl: Parse,
{
/// The internal parser for ShapeSource.
fn parse_internal<'i, 't>(
fn parse_common<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
@ -99,10 +107,6 @@ where
return Ok(ShapeSource::None);
}
if let Ok(image_or_url) = input.try(|i| ImageOrUrl::parse(context, i)) {
return Ok(ShapeSource::ImageOrUrl(image_or_url));
}
fn parse_component<U: Parse>(
context: &ParserContext,
input: &mut Parser,

View file

@ -746,7 +746,12 @@ impl ToComputedValue for KeywordSize {
fn to_computed_value(&self, cx: &Context) -> NonNegativeLength {
use context::QuirksMode;
use values::specified::length::au_to_int_px;
// Data from nsRuleNode.cpp in Gecko
// The tables in this function are originally from
// nsRuleNode::CalcFontPointSize in Gecko:
//
// https://dxr.mozilla.org/mozilla-central/rev/35fbf14b9/layout/style/nsRuleNode.cpp#3262-3336
// Mapping from base size and HTML size to pixels
// The first index is (base_size - 9), the second is the
// HTML size. "0" is CSS keyword xx-small, not HTML size 0,
@ -765,9 +770,6 @@ impl ToComputedValue for KeywordSize {
[9, 10, 13, 16, 18, 24, 32, 48],
];
// Data from nsRuleNode.cpp in Gecko
// (https://dxr.mozilla.org/mozilla-central/rev/35fbf14b9/layout/style/nsRuleNode.cpp#3303)
//
// This table gives us compatibility with WinNav4 for the default fonts only.
// In WinNav4, the default fonts were:
//

View file

@ -166,6 +166,21 @@ impl Image {
ref t => Err(location.new_unexpected_token_error(t.clone())),
})
}
/// Provides an alternate method for parsing that associates the URL with
/// anonymous CORS headers.
///
/// FIXME(emilio): It'd be nicer for this to pass a `CorsMode` parameter to
/// a shared function instead.
pub fn parse_with_cors_anonymous<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Image, ParseError<'i>> {
if let Ok(url) = input.try(|input| SpecifiedImageUrl::parse_with_cors_anonymous(context, input)) {
return Ok(generic::Image::Url(url));
}
Self::parse(context, input)
}
}
impl Parse for Gradient {

View file

@ -538,13 +538,6 @@ impl ToCss for ArcFlag {
}
}
impl ComputeSquaredDistance for ArcFlag {
#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
(self.0 as i32).compute_squared_distance(&(other.0 as i32))
}
}
/// SVG Path parser.
struct PathParser<'a> {
chars: Peekable<Cloned<slice::Iter<'a, u8>>>,

View file

@ -2,7 +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 animate::{AnimationInputAttrs, AnimationVariantAttrs};
use animate::{AnimationInputAttrs, AnimationVariantAttrs, AnimationFieldAttrs};
use cg;
use quote::Tokens;
use syn::{DeriveInput, Path};
@ -47,8 +47,23 @@ pub fn derive(mut input: DeriveInput) -> Tokens {
parse_quote!(#ty: ::values::distance::ComputeSquaredDistance),
);
}
quote! {
::values::distance::ComputeSquaredDistance::compute_squared_distance(#this, #other)?
let animation_field_attrs =
cg::parse_field_attrs::<AnimationFieldAttrs>(&this.ast());
if animation_field_attrs.constant {
quote! {
{
if #this != #other {
return Err(());
}
::values::distance::SquaredDistance::from_sqrt(0.)
}
}
} else {
quote! {
::values::distance::ComputeSquaredDistance::compute_squared_distance(#this, #other)?
}
}
}), quote!(+));
sum