Update PropertyDeclarationBlock::to_css so that the iteration of

possible shorthands matches the linked spec.

Previously substep 5 attempted to serialize the complete shorthand
declaration and substep 6 skipped to the next shorthand only if the
current shorthand was not serialized, but this did not catch empty
serializations. The spec on the other hand specifically says that the
*value* should be evaluated first and if the value is empty substep 6
should skip to the next shorthand - which is what happens now.

To do this required some refactoring which mostly simplifies the code.
Specifically:
 - append_declaration_value was refactored so that importance is not
   required as a arg (by moving it to the end of append_serialization)
   and is_overflow_with_name was removed as an arg also (initially I
   refactored it elsewhere, but it turns out it's no longer required at
   all - more below). With these changes, append_declaration_value can
   be used within the algorithm for to_css to obtain just the value for
   substep 5.
 - Substeps 7 and 8 of the algorithm become explicit (they were implicit
   before) by passing the value, shorthand and importance to
   append_serialization.
 - serialize_shorthand_to_buffer is no longer required (as the algorithm
   serializes the value first instead, as per the spec.

A surprising result of this was that I could also remove a lot of code
handling the special case of the overflow properties serialization. This
is because the overflow's LonghandToCss implementation of
to_css_declared already does the right thing according to the spec - it
writes the single value if both overflow-x and -y are equal, and
writes nothing otherwise - so that the algorithm now skips that shorthand
instead rendering the longhands.
This commit is contained in:
Michael Nelson 2017-02-22 20:58:33 +11:00
parent 854d720b21
commit a0998d30d4
4 changed files with 36 additions and 141 deletions

View file

@ -13,7 +13,7 @@
use std::borrow::Cow;
use std::boxed::Box as StdBox;
use std::collections::HashSet;
use std::fmt::{self, Write};
use std::fmt;
use std::sync::Arc;
use app_units::Au;
@ -549,59 +549,10 @@ impl ShorthandId {
}
}
/// Overflow does not behave like a normal shorthand. When overflow-x and
/// overflow-y are not of equal values, they no longer use the shared
/// property name "overflow".
/// Find an return an appendable value for the given declarations.
///
/// We use this function as a special-case for that.
pub fn overflow_longhands_to_css<'a, W, I>(&self,
declarations: I,
dest: &mut W)
-> fmt::Result
where W: fmt::Write,
I: Iterator<Item=&'a PropertyDeclaration>,
{
match *self {
ShorthandId::Overflow => {
match shorthands::overflow::LonghandsToSerialize::from_iter(declarations) {
Ok(longhands) => longhands.to_css_declared_with_name(dest),
Err(_) => Err(fmt::Error)
}
},
_ => Err(fmt::Error)
}
}
/// Serializes the possible shorthand name with value to input buffer given
/// a list of longhand declarations.
///
/// On success, returns true if the shorthand value is written, or false if
/// no shorthand value is present.
pub fn serialize_shorthand_to_buffer<'a, W, I>(self,
dest: &mut W,
declarations: I,
is_first_serialization: &mut bool,
importance: Importance)
-> Result<bool, fmt::Error>
where W: Write,
I: IntoIterator<Item=&'a PropertyDeclaration>,
I::IntoIter: Clone,
{
match self.get_shorthand_appendable_value(declarations) {
None => Ok(false),
Some(appendable_value) => {
append_serialization(
dest,
&self,
appendable_value,
importance,
is_first_serialization
).and_then(|_| Ok(true))
}
}
}
fn get_shorthand_appendable_value<'a, I>(self,
/// Returns the optional appendable value.
pub fn get_shorthand_appendable_value<'a, I>(self,
declarations: I)
-> Option<AppendableValue<'a, I::IntoIter>>
where I: IntoIterator<Item=&'a PropertyDeclaration>,