Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CSS3 Calc #7185

Closed
wants to merge 20 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -327,7 +327,12 @@ impl CandidateBSizeIterator {
(LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => {
MaybeAuto::Specified(block_container_block_size.scale_by(percent))
}
(LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto,
(LengthOrPercentageOrAuto::Calc(calc), Some(block_container_block_size)) => {
MaybeAuto::Specified(calc.length() + block_container_block_size.scale_by(calc.percentage()))
}
(LengthOrPercentageOrAuto::Percentage(_), None) |
(LengthOrPercentageOrAuto::Auto, _) |
(LengthOrPercentageOrAuto::Calc(_), _) => MaybeAuto::Auto,
(LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(length),
};
let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) {
@@ -342,6 +347,10 @@ impl CandidateBSizeIterator {
(LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => {
block_container_block_size.scale_by(percent)
}
(LengthOrPercentage::Calc(calc), Some(block_container_block_size)) => {
calc.length() + block_container_block_size.scale_by(calc.percentage())
}
(LengthOrPercentage::Calc(calc), None) => calc.length(),
(LengthOrPercentage::Percentage(_), None) => Au(0),
(LengthOrPercentage::Length(length), _) => length,
};
@@ -1128,13 +1137,15 @@ impl BlockFlow {
let content_block_size = self.fragment.style().content_block_size();

match (content_block_size, containing_block_size) {
(LengthOrPercentageOrAuto::Calc(calc), Some(container_size)) => {
Some(container_size.scale_by(calc.percentage()) + calc.length())
}
(LengthOrPercentageOrAuto::Length(length), _) => Some(length),
(LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => {
Some(container_size.scale_by(percent))
}
(LengthOrPercentageOrAuto::Percentage(_), None) => {
None
}
(LengthOrPercentageOrAuto::Percentage(_), None) |
(LengthOrPercentageOrAuto::Calc(_), None) |
(LengthOrPercentageOrAuto::Auto, None) => {
None
}
@@ -1959,6 +1959,8 @@ fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32
fmin(1.0, (length as f32) / (total_length as f32))
}
LengthOrPercentage::Percentage(percentage) => percentage as f32,
LengthOrPercentage::Calc(calc) =>
fmin(1.0, calc.percentage() + (calc.length().0 as f32) / (total_length as f32)),
}
}

@@ -167,6 +167,7 @@ impl FlexFlow {
}
(LengthOrPercentageOrAuto::Percentage(_), None) |
(LengthOrPercentageOrAuto::Auto, _) => None,
(LengthOrPercentageOrAuto::Calc(_), _) => None,
(LengthOrPercentageOrAuto::Length(length), _) => Some(length),
};

@@ -463,6 +463,10 @@ impl ReplacedImageFragmentInfo {
MaybeAuto::Specified(container_size.scale_by(pc))
}
(LengthOrPercentageOrAuto::Percentage(_), _, None) => MaybeAuto::Auto,
(LengthOrPercentageOrAuto::Calc(calc), _, Some(container_size)) => {
MaybeAuto::Specified(calc.length() + container_size.scale_by(calc.percentage()))
}
(LengthOrPercentageOrAuto::Calc(_), _, None) => MaybeAuto::Auto,
(LengthOrPercentageOrAuto::Auto, Some(dom_length), _) => MaybeAuto::Specified(dom_length),
(LengthOrPercentageOrAuto::Auto, None, _) => MaybeAuto::Auto,
}
@@ -616,6 +620,10 @@ impl IframeFragmentInfo {
let computed_size = match (content_size, containing_size) {
(LengthOrPercentageOrAuto::Length(length), _) => length,
(LengthOrPercentageOrAuto::Percentage(pc), Some(container_size)) => container_size.scale_by(pc),
(LengthOrPercentageOrAuto::Calc(calc), Some(container_size)) => {
container_size.scale_by(calc.percentage()) + calc.length()
},
(LengthOrPercentageOrAuto::Calc(calc), None) => calc.length(),
(LengthOrPercentageOrAuto::Percentage(_), None) => default_size,
(LengthOrPercentageOrAuto::Auto, _) => default_size,
};
@@ -1285,6 +1293,7 @@ impl Fragment {
}
(Some(dom_inline_size), _) => dom_inline_size,
(None, LengthOrPercentageOrAuto::Length(length)) => length,
(None, LengthOrPercentageOrAuto::Calc(calc)) => calc.length(),
};
result.union_block(&IntrinsicISizes {
minimum_inline_size: image_inline_size,
@@ -988,6 +988,11 @@ impl InlineFlow {
let percent_offset = line_height.scale_by(p);
offset_from_baseline = offset_from_baseline - percent_offset
}
vertical_align::T::Calc(calc) => {
let line_height = fragment.calculate_line_height(layout_context);
let percent_offset = line_height.scale_by(calc.percentage());
offset_from_baseline = offset_from_baseline - percent_offset - calc.length()
}
}
}
(offset_from_baseline - ascent, largest_size_updated)
@@ -379,6 +379,9 @@ impl MaybeAuto {
LengthOrPercentageOrAuto::Percentage(percent) => {
MaybeAuto::Specified(containing_length.scale_by(percent))
}
LengthOrPercentageOrAuto::Calc(calc) => {
MaybeAuto::Specified(calc.length() + containing_length.scale_by(calc.percentage()))
}
LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(length)
}
}
@@ -416,7 +419,9 @@ pub fn specified_or_none(length: LengthOrPercentageOrNone, containing_length: Au
pub fn specified(length: LengthOrPercentage, containing_length: Au) -> Au {
match length {
LengthOrPercentage::Length(length) => length,
LengthOrPercentage::Percentage(p) => containing_length.scale_by(p)
LengthOrPercentage::Percentage(p) => containing_length.scale_by(p),
LengthOrPercentage::Calc(calc) =>
containing_length.scale_by(calc.percentage()) + calc.length(),
}
}

@@ -267,11 +267,13 @@ impl Flow for TableFlow {
self.column_intrinsic_inline_sizes.push(ColumnIntrinsicInlineSize {
minimum_length: match *specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Percentage(_) => Au(0),
LengthOrPercentageOrAuto::Length(length) => length,
},
percentage: match *specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage,
},
@@ -280,20 +280,23 @@ impl Flow for TableRowFlow {
let child_column_inline_size = ColumnIntrinsicInlineSize {
minimum_length: match child_specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Percentage(_) => {
child_base.intrinsic_inline_sizes.minimum_inline_size
}
LengthOrPercentageOrAuto::Length(length) => length,
},
percentage: match child_specified_inline_size {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage,
},
preferred: child_base.intrinsic_inline_sizes.preferred_inline_size,
constrained: match child_specified_inline_size {
LengthOrPercentageOrAuto::Length(_) => true,
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Percentage(_) => false,
},
};
@@ -365,7 +365,8 @@ impl RawLayoutElementHelpers for Element {
match width {
LengthOrPercentageOrAuto::Auto => {}
LengthOrPercentageOrAuto::Percentage(percentage) => {
let width_value = specified::LengthOrPercentageOrAuto::Percentage(percentage);
let width_value =
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage));
hints.push(from_declaration(
PropertyDeclaration::Width(SpecifiedValue(width_value))));
}
@@ -388,7 +389,8 @@ impl RawLayoutElementHelpers for Element {
match height {
LengthOrPercentageOrAuto::Auto => {}
LengthOrPercentageOrAuto::Percentage(percentage) => {
let height_value = specified::LengthOrPercentageOrAuto::Percentage(percentage);
let height_value =
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage));
hints.push(from_declaration(
PropertyDeclaration::Height(SpecifiedValue(height_value))));
}
@@ -4,6 +4,7 @@

#![feature(arc_unique)]
#![feature(box_syntax)]
#![feature(box_patterns)]
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(custom_derive)]
@@ -760,7 +760,7 @@ pub mod longhands {
pub mod computed_value {
use std::fmt;
use util::geometry::Au;
use values::CSSFloat;
use values::{CSSFloat, computed};
#[allow(non_camel_case_types)]
#[derive(PartialEq, Copy, Clone, HeapSizeOf)]
pub enum T {
@@ -769,6 +769,7 @@ pub mod longhands {
% endfor
Length(Au),
Percentage(CSSFloat),
Calc(computed::Calc),
}
impl fmt::Debug for T {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -778,6 +779,7 @@ pub mod longhands {
% endfor
&T::Length(length) => write!(f, "{:?}", length),
&T::Percentage(number) => write!(f, "{}%", number),
&T::Calc(calc) => write!(f, "{:?}", calc)
}
}
}
@@ -789,6 +791,7 @@ pub mod longhands {
% endfor
T::Length(value) => value.to_css(dest),
T::Percentage(percentage) => write!(dest, "{}%", percentage * 100.),
T::Calc(calc) => calc.to_css(dest),
}
}
}
@@ -809,12 +812,12 @@ pub mod longhands {
% endfor
SpecifiedValue::LengthOrPercentage(value) => {
match value.to_computed_value(context) {
computed::LengthOrPercentage::Length(value) => {
computed_value::T::Length(value)
}
computed::LengthOrPercentage::Percentage(value) => {
computed_value::T::Percentage(value)
}
computed::LengthOrPercentage::Length(value) =>
computed_value::T::Length(value),
computed::LengthOrPercentage::Percentage(value) =>
computed_value::T::Percentage(value),
computed::LengthOrPercentage::Calc(value) =>
computed_value::T::Calc(value),
}
}
}
@@ -1909,12 +1912,14 @@ pub mod longhands {
}
/// <length> | <percentage> | <absolute-size> | <relative-size>
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
input.try(specified::LengthOrPercentage::parse_non_negative)
.map(|value| match value {
specified::LengthOrPercentage::Length(value) => value,
let value = try!(input.try(specified::LengthOrPercentage::parse_non_negative));
match value {
specified::LengthOrPercentage::Length(value) => Ok(value),
specified::LengthOrPercentage::Percentage(value) =>
specified::Length::FontRelative(specified::FontRelativeLength::Em(value))
})
Ok(specified::Length::FontRelative(specified::FontRelativeLength::Em(value.0))),
// FIXME(dzbarsky) handle calc for font-size
specified::LengthOrPercentage::Calc(_) => return Err(())
}
.or_else(|()| {
match_ignore_ascii_case! { try!(input.expect_ident()),
"xx-small" => Ok(specified::Length::Absolute(Au::from_px(MEDIUM_PX) * 3 / 5)),
@@ -3984,6 +3989,7 @@ pub mod longhands {
}

pub fn parse_origin(_: &ParserContext, input: &mut Parser) -> Result<OriginParseResult,()> {
use values::specified::{LengthOrPercentage, Percentage};
let (mut horizontal, mut vertical, mut depth) = (None, None, None);
loop {
if let Err(_) = input.try(|input| {
@@ -3992,37 +3998,37 @@ pub mod longhands {
token,
"left" => {
if horizontal.is_none() {
horizontal = Some(specified::LengthOrPercentage::Percentage(0.0))
horizontal = Some(LengthOrPercentage::Percentage(Percentage(0.0)))
} else {
return Err(())
}
},
"center" => {
if horizontal.is_none() {
horizontal = Some(specified::LengthOrPercentage::Percentage(0.5))
horizontal = Some(LengthOrPercentage::Percentage(Percentage(0.5)))
} else if vertical.is_none() {
vertical = Some(specified::LengthOrPercentage::Percentage(0.5))
vertical = Some(LengthOrPercentage::Percentage(Percentage(0.5)))
} else {
return Err(())
}
},
"right" => {
if horizontal.is_none() {
horizontal = Some(specified::LengthOrPercentage::Percentage(1.0))
horizontal = Some(LengthOrPercentage::Percentage(Percentage(1.0)))
} else {
return Err(())
}
},
"top" => {
if vertical.is_none() {
vertical = Some(specified::LengthOrPercentage::Percentage(0.0))
vertical = Some(LengthOrPercentage::Percentage(Percentage(0.0)))
} else {
return Err(())
}
},
"bottom" => {
if vertical.is_none() {
vertical = Some(specified::LengthOrPercentage::Percentage(1.0))
vertical = Some(LengthOrPercentage::Percentage(Percentage(1.0)))
} else {
return Err(())
}
@@ -4031,13 +4037,13 @@ pub mod longhands {
}
Ok(())
}) {
match specified::LengthOrPercentage::parse(input) {
match LengthOrPercentage::parse(input) {
Ok(value) => {
if horizontal.is_none() {
horizontal = Some(value);
} else if vertical.is_none() {
vertical = Some(value);
} else if let specified::LengthOrPercentage::Length(length) = value {
} else if let LengthOrPercentage::Length(length) = value {
depth = Some(length);
} else {
break;
@@ -4065,7 +4071,7 @@ pub mod longhands {

<%self:longhand name="transform-origin">
use values::computed::Context;
use values::specified::{Length, LengthOrPercentage};
use values::specified::{Length, LengthOrPercentage, Percentage};

use cssparser::ToCss;
use std::fmt;
@@ -4121,8 +4127,8 @@ pub mod longhands {
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
let result = try!(super::parse_origin(context, input));
Ok(SpecifiedValue {
horizontal: result.horizontal.unwrap_or(LengthOrPercentage::Percentage(0.5)),
vertical: result.vertical.unwrap_or(LengthOrPercentage::Percentage(0.5)),
horizontal: result.horizontal.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))),
vertical: result.vertical.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))),
depth: result.depth.unwrap_or(Length::Absolute(Au(0))),
})
}
@@ -4147,7 +4153,7 @@ pub mod longhands {

<%self:longhand name="perspective-origin">
use values::computed::Context;
use values::specified::LengthOrPercentage;
use values::specified::{LengthOrPercentage, Percentage};

use cssparser::ToCss;
use std::fmt;
@@ -4197,8 +4203,8 @@ pub mod longhands {
match result.depth {
Some(_) => Err(()),
None => Ok(SpecifiedValue {
horizontal: result.horizontal.unwrap_or(LengthOrPercentage::Percentage(0.5)),
vertical: result.vertical.unwrap_or(LengthOrPercentage::Percentage(0.5)),
horizontal: result.horizontal.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))),
vertical: result.vertical.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))),
})
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.