Auto merge of #16609 - nox:quirks, r=Manishearth,emilio

Implement unitless length quirk

The Gecko side doesn't propagate its quirks mode yet.

<!-- 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/16609)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-04-27 22:32:24 -05:00 committed by GitHub
commit d8bcc0db1a
70 changed files with 2321 additions and 194 deletions

View file

@ -140,7 +140,7 @@ class Longhand(object):
need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False,
allowed_in_keyframe_block=True, complex_color=False, cast_type='u8',
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False,
flags=None, allowed_in_page_rule=False):
flags=None, allowed_in_page_rule=False, allow_quirks=False):
self.name = name
if not spec:
raise TypeError("Spec should be specified for %s" % name)
@ -166,6 +166,7 @@ class Longhand(object):
self.boxed = arg_to_bool(boxed)
self.flags = flags.split() if flags else []
self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule)
self.allow_quirks = allow_quirks
# https://drafts.csswg.org/css-animations/#keyframes
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property

View file

@ -6,6 +6,7 @@
#![deny(missing_docs)]
use context::QuirksMode;
use cssparser::{DeclarationListParser, parse_important};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
use error_reporting::ParseErrorReporter;
@ -641,13 +642,15 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W,
/// shared between Servo and Gecko.
pub fn parse_style_attribute(input: &str,
url_data: &UrlExtraData,
error_reporter: &ParseErrorReporter)
error_reporter: &ParseErrorReporter,
quirks_mode: QuirksMode)
-> PropertyDeclarationBlock {
let context = ParserContext::new(Origin::Author,
url_data,
error_reporter,
Some(CssRuleType::Style),
LengthParsingMode::Default);
LengthParsingMode::Default,
quirks_mode);
parse_property_declaration_list(&context, &mut Parser::new(input))
}
@ -660,13 +663,15 @@ pub fn parse_one_declaration(id: PropertyId,
input: &str,
url_data: &UrlExtraData,
error_reporter: &ParseErrorReporter,
length_parsing_mode: LengthParsingMode)
length_parsing_mode: LengthParsingMode,
quirks_mode: QuirksMode)
-> Result<ParsedDeclaration, ()> {
let context = ParserContext::new(Origin::Author,
url_data,
error_reporter,
Some(CssRuleType::Style),
length_parsing_mode);
length_parsing_mode,
quirks_mode);
Parser::new(input).parse_entirely(|parser| {
ParsedDeclaration::parse(id, &context, parser)
.map_err(|_| ())

View file

@ -8,11 +8,13 @@
%>
<%def name="predefined_type(name, type, initial_value, parse_method='parse',
needs_context=True, vector=False, computed_type=None, initial_specified_value=None, **kwargs)">
needs_context=True, vector=False, computed_type=None, initial_specified_value=None,
allow_quirks=False, **kwargs)">
<%def name="predefined_type_inner(name, type, initial_value, parse_method)">
#[allow(unused_imports)]
use app_units::Au;
use cssparser::{Color as CSSParserColor, RGBA};
use values::specified::AllowQuirks;
pub use values::specified::${type} as SpecifiedValue;
pub mod computed_value {
% if computed_type:
@ -30,7 +32,9 @@
pub fn parse(context: &ParserContext,
input: &mut Parser)
-> Result<SpecifiedValue, ()> {
% if needs_context:
% if allow_quirks:
specified::${type}::${parse_method}_quirky(context, input, AllowQuirks::Yes)
% elif needs_context:
specified::${type}::${parse_method}(context, input)
% else:
specified::${type}::${parse_method}(input)
@ -277,6 +281,7 @@
% if not property.derived_from:
{
let custom_props = context.style().custom_properties();
let quirks_mode = context.quirks_mode;
::properties::substitute_variables_${property.ident}(
&declared_value, &custom_props,
|value| {
@ -349,7 +354,7 @@
}
}
}
}, error_reporter);
}, error_reporter, quirks_mode);
}
% if property.custom_cascade:
@ -370,7 +375,11 @@
parse(context, input).map(|result| Box::new(result))
% else:
-> Result<SpecifiedValue, ()> {
parse(context, input)
% if property.allow_quirks:
parse_quirky(context, input, specified::AllowQuirks::Yes)
% else:
parse(context, input)
% endif
% endif
}
pub fn parse_declared(context: &ParserContext, input: &mut Parser)
@ -800,7 +809,8 @@
% endif
</%def>
<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function, needs_context=True, **kwargs)">
<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function,
needs_context=True, allow_quirks=False, **kwargs)">
<% sub_properties=' '.join(sub_property_pattern % side for side in ['top', 'right', 'bottom', 'left']) %>
<%call expr="self.shorthand(name, sub_properties=sub_properties, **kwargs)">
#[allow(unused_imports)]
@ -810,7 +820,9 @@
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let (top, right, bottom, left) =
% if needs_context:
% if allow_quirks:
try!(parse_four_sides(input, |i| ${parser_function}_quirky(context, i, specified::AllowQuirks::Yes)));
% elif needs_context:
try!(parse_four_sides(input, |i| ${parser_function}(context, i)));
% else:
try!(parse_four_sides(input, ${parser_function}));

View file

@ -515,6 +515,7 @@ impl AnimationValue {
% if prop.animatable:
LonghandId::${prop.camel_case} => {
let mut result = None;
let quirks_mode = context.quirks_mode;
::properties::substitute_variables_${prop.ident}_slow(
&variables.css,
variables.first_token_type,
@ -533,7 +534,8 @@ impl AnimationValue {
};
result = AnimationValue::from_declaration(&declaration, context, initial);
},
&reporter);
&reporter,
quirks_mode);
result
},
% else:

View file

@ -33,7 +33,9 @@
computed_type="::app_units::Au",
alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-width"),
spec=maybe_logical_spec(side, "width"),
animation_value_type="ComputedValue", logical=side[1])}
animation_value_type="ComputedValue",
logical=side[1],
allow_quirks=not side[1])}
% endfor
${helpers.gecko_keyword_conversion(Keyword('border-style',

View file

@ -264,6 +264,7 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
use values::specified::AllowQuirks;
<% vertical_align = data.longhands_by_name["vertical-align"] %>
<% vertical_align.keyword = Keyword("vertical-align",
@ -306,7 +307,7 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
/// baseline | sub | super | top | text-top | middle | bottom | text-bottom
/// | <percentage> | <length>
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
input.try(|i| specified::LengthOrPercentage::parse(context, i))
input.try(|i| specified::LengthOrPercentage::parse_quirky(context, i, AllowQuirks::Yes))
.map(SpecifiedValue::LengthOrPercentage)
.or_else(|_| {
match_ignore_ascii_case! { &try!(input.expect_ident()),

View file

@ -550,14 +550,14 @@ ${helpers.single_keyword_system("font-variant-caps",
</%helpers:longhand>
<%helpers:longhand name="font-size" need_clone="True" animation_value_type="ComputedValue"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size">
allow_quirks="True" spec="https://drafts.csswg.org/css-fonts/#propdef-font-size">
use app_units::Au;
use properties::longhands::system_font::SystemFont;
use properties::style_structs::Font;
use std::fmt;
use style_traits::ToCss;
use values::{FONT_MEDIUM_PX, HasViewportPercentage};
use values::specified::{FontRelativeLength, LengthOrPercentage, Length};
use values::specified::{AllowQuirks, FontRelativeLength, LengthOrPercentage, Length};
use values::specified::{NoCalcLength, Percentage};
use values::specified::length::FontBaseSize;
@ -843,9 +843,19 @@ ${helpers.single_keyword_system("font-variant-caps",
))
}
}
/// <length> | <percentage> | <absolute-size> | <relative-size>
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
if let Ok(lop) = input.try(|i| specified::LengthOrPercentage::parse_non_negative(context, i)) {
parse_quirky(context, input, AllowQuirks::No)
}
/// Parses a font-size, with quirks.
pub fn parse_quirky(context: &ParserContext,
input: &mut Parser,
allow_quirks: AllowQuirks)
-> Result<SpecifiedValue, ()> {
use self::specified::LengthOrPercentage;
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative_quirky(context, i, allow_quirks)) {
return Ok(SpecifiedValue::Length(lop))
}

View file

@ -26,6 +26,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
use values::specified::{AllowQuirks, Length};
pub mod computed_value {
use app_units::Au;
@ -73,8 +74,8 @@ ${helpers.single_keyword("caption-side", "top bottom",
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue {
pub horizontal: specified::Length,
pub vertical: Option<specified::Length>,
pub horizontal: Length,
pub vertical: Option<Length>,
}
#[inline]
@ -130,11 +131,11 @@ ${helpers.single_keyword("caption-side", "top bottom",
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
let mut first = None;
let mut second = None;
match specified::Length::parse_non_negative(context, input) {
match Length::parse_non_negative_quirky(context, input, AllowQuirks::Yes) {
Err(()) => (),
Ok(length) => {
first = Some(length);
if let Ok(len) = input.try(|input| specified::Length::parse_non_negative(context, input)) {
if let Ok(len) = input.try(|i| Length::parse_non_negative_quirky(context, i, AllowQuirks::Yes)) {
second = Some(len);
}
}

View file

@ -184,7 +184,8 @@ ${helpers.predefined_type("text-indent",
"LengthOrPercentage",
"computed::LengthOrPercentage::Length(Au(0))",
animation_value_type="ComputedValue",
spec="https://drafts.csswg.org/css-text/#propdef-text-indent")}
spec="https://drafts.csswg.org/css-text/#propdef-text-indent",
allow_quirks=True)}
// Also known as "word-wrap" (which is more popular because of IE), but this is the preferred
// name per CSS-TEXT 6.2.
@ -411,6 +412,7 @@ ${helpers.single_keyword("text-align-last",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
use values::specified::AllowQuirks;
impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
@ -487,7 +489,7 @@ ${helpers.single_keyword("text-align-last",
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
Ok(SpecifiedValue::Normal)
} else {
specified::Length::parse(context, input).map(SpecifiedValue::Specified)
specified::Length::parse_quirky(context, input, AllowQuirks::Yes).map(SpecifiedValue::Specified)
}
}
</%helpers:longhand>
@ -497,6 +499,7 @@ ${helpers.single_keyword("text-align-last",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
use values::specified::AllowQuirks;
impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
@ -572,7 +575,7 @@ ${helpers.single_keyword("text-align-last",
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
Ok(SpecifiedValue::Normal)
} else {
specified::LengthOrPercentage::parse(context, input)
specified::LengthOrPercentage::parse_quirky(context, input, AllowQuirks::Yes)
.map(SpecifiedValue::Specified)
}
}

View file

@ -15,6 +15,7 @@
${helpers.predefined_type("margin-%s" % side[0], "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Length(Au(0))",
alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"),
allow_quirks=not side[1],
animation_value_type="ComputedValue", logical = side[1], spec = spec,
allowed_in_page_rule=True)}
% endfor

View file

@ -18,5 +18,6 @@
alias=maybe_moz_logical_alias(product, side, "-moz-padding-%s"),
animation_value_type="ComputedValue",
logical = side[1],
spec = spec)}
spec = spec,
allow_quirks=not side[1])}
% endfor

View file

@ -13,7 +13,8 @@
${helpers.predefined_type(side, "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Auto",
spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
animation_value_type="ComputedValue")}
animation_value_type="ComputedValue",
allow_quirks=True)}
% endfor
// offset-* logical properties, map to "top" / "left" / "bottom" / "right"
% for side in LOGICAL_SIDES:
@ -157,6 +158,7 @@ ${helpers.predefined_type("flex-basis",
"computed::LengthOrPercentageOrAuto::Auto",
"parse_non_negative",
spec=spec % size,
allow_quirks=not logical,
animation_value_type="ComputedValue", logical = logical)}
% if product == "gecko":
% for min_max in ["min", "max"]:
@ -177,7 +179,7 @@ ${helpers.predefined_type("flex-basis",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
use values::specified::${MinMax}Length;
use values::specified::{AllowQuirks, ${MinMax}Length};
impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
@ -199,7 +201,11 @@ ${helpers.predefined_type("flex-basis",
${MinMax}Length::${initial}
}
fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
% if logical:
let ret = ${MinMax}Length::parse(context, input);
% else:
let ret = ${MinMax}Length::parse_quirky(context, input, AllowQuirks::Yes);
% endif
// Keyword values don't make sense in the block direction; don't parse them
% if "block" in size:
if let Ok(${MinMax}Length::ExtremumLength(..)) = ret {
@ -254,13 +260,17 @@ ${helpers.predefined_type("flex-basis",
"computed::LengthOrPercentage::Length(Au(0))",
"parse_non_negative",
spec=spec % ("min-%s" % size),
animation_value_type="ComputedValue", logical = logical)}
animation_value_type="ComputedValue",
logical=logical,
allow_quirks=not logical)}
${helpers.predefined_type("max-%s" % size,
"LengthOrPercentageOrNone",
"computed::LengthOrPercentageOrNone::None",
"parse_non_negative",
spec=spec % ("min-%s" % size),
animation_value_type="ComputedValue", logical = logical)}
animation_value_type="ComputedValue",
logical=logical,
allow_quirks=not logical)}
% endif
% endfor

View file

@ -21,6 +21,7 @@ use cssparser::{Parser, TokenSerializationType};
use error_reporting::ParseErrorReporter;
#[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
use computed_values;
use context::QuirksMode;
use font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")] use gecko_bindings::bindings;
#[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID};
@ -328,7 +329,8 @@ impl PropertyDeclarationIdSet {
% endif
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
error_reporter: &ParseErrorReporter)
error_reporter: &ParseErrorReporter,
quirks_mode: QuirksMode)
% if property.boxed:
where F: FnOnce(&DeclaredValue<Box<longhands::${property.ident}::SpecifiedValue>>)
% else:
@ -342,7 +344,8 @@ impl PropertyDeclarationIdSet {
with_variables.from_shorthand,
custom_properties,
f,
error_reporter);
error_reporter,
quirks_mode);
} else {
f(value);
}
@ -357,7 +360,8 @@ impl PropertyDeclarationIdSet {
from_shorthand: Option<ShorthandId>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
error_reporter: &ParseErrorReporter)
error_reporter: &ParseErrorReporter,
quirks_mode: QuirksMode)
% if property.boxed:
where F: FnOnce(&DeclaredValue<Box<longhands::${property.ident}::SpecifiedValue>>)
% else:
@ -375,7 +379,8 @@ impl PropertyDeclarationIdSet {
url_data,
error_reporter,
None,
LengthParsingMode::Default);
LengthParsingMode::Default,
quirks_mode);
Parser::new(&css).parse_entirely(|input| {
match from_shorthand {
None => {
@ -2116,7 +2121,8 @@ pub fn cascade(device: &Device,
cascade_info: Option<<&mut CascadeInfo>,
error_reporter: &ParseErrorReporter,
font_metrics_provider: &FontMetricsProvider,
flags: CascadeFlags)
flags: CascadeFlags,
quirks_mode: QuirksMode)
-> ComputedValues {
debug_assert_eq!(parent_style.is_some(), layout_parent_style.is_some());
let (is_root_element, inherited_style, layout_parent_style) = match parent_style {
@ -2162,7 +2168,8 @@ pub fn cascade(device: &Device,
cascade_info,
error_reporter,
font_metrics_provider,
flags)
flags,
quirks_mode)
}
/// NOTE: This function expects the declaration with more priority to appear
@ -2177,7 +2184,8 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
mut cascade_info: Option<<&mut CascadeInfo>,
error_reporter: &ParseErrorReporter,
font_metrics_provider: &FontMetricsProvider,
flags: CascadeFlags)
flags: CascadeFlags,
quirks_mode: QuirksMode)
-> ComputedValues
where F: Fn() -> I,
I: Iterator<Item = &'a PropertyDeclaration>,
@ -2230,6 +2238,7 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
style: starting_style,
font_metrics_provider: font_metrics_provider,
in_media_query: false,
quirks_mode: quirks_mode,
};
// Set computed values, overwriting earlier declarations for the same

View file

@ -194,8 +194,8 @@
sub_properties="background-position-x background-position-y"
spec="https://drafts.csswg.org/css-backgrounds-4/#the-background-position">
use properties::longhands::{background_position_x,background_position_y};
use values::specified::AllowQuirks;
use values::specified::position::Position;
use parser::Parse;
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let mut position_x = background_position_x::SpecifiedValue(Vec::new());
@ -204,7 +204,7 @@
try!(input.parse_comma_separated(|input| {
loop {
if let Ok(value) = input.try(|input| Position::parse(context, input)) {
if let Ok(value) = input.try(|input| Position::parse_quirky(context, input, AllowQuirks::Yes)) {
position_x.0.push(value.horizontal);
position_y.0.push(value.vertical);
any = true;

View file

@ -17,11 +17,12 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style",
for side in PHYSICAL_SIDES)}"
spec="https://drafts.csswg.org/css-backgrounds/#border-width">
use super::parse_four_sides;
use parser::Parse;
use values::specified;
use values::specified::{AllowQuirks, BorderWidth};
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let (top, right, bottom, left) = try!(parse_four_sides(input, |i| specified::BorderWidth::parse(context, i)));
let (top, right, bottom, left) = try!(parse_four_sides(input, |i| {
BorderWidth::parse_quirky(context, i, AllowQuirks::Yes)
}));
Ok(Longhands {
% for side in PHYSICAL_SIDES:
${to_rust_ident('border-%s-width' % side)}: ${side},

View file

@ -6,4 +6,5 @@
${helpers.four_sides_shorthand("margin", "margin-%s", "specified::LengthOrPercentageOrAuto::parse",
spec="https://drafts.csswg.org/css-box/#propdef-margin",
allowed_in_page_rule=True)}
allowed_in_page_rule=True,
allow_quirks=True)}

View file

@ -5,4 +5,5 @@
<%namespace name="helpers" file="/helpers.mako.rs" />
${helpers.four_sides_shorthand("padding", "padding-%s", "specified::LengthOrPercentage::parse",
spec="https://drafts.csswg.org/css-box-3/#propdef-padding")}
spec="https://drafts.csswg.org/css-box-3/#propdef-padding",
allow_quirks=True)}