mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
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:
parent
854d720b21
commit
a0998d30d4
4 changed files with 36 additions and 141 deletions
|
@ -128,10 +128,9 @@ impl PropertyDeclarationBlock {
|
|||
// Step 1.2.3
|
||||
// We don't print !important when serializing individual properties,
|
||||
// so we treat this as a normal-importance property
|
||||
let importance = Importance::Normal;
|
||||
match shorthand.get_shorthand_appendable_value(list) {
|
||||
Some(appendable_value) =>
|
||||
append_declaration_value(dest, appendable_value, importance, false),
|
||||
append_declaration_value(dest, appendable_value),
|
||||
None => return Ok(()),
|
||||
}
|
||||
}
|
||||
|
@ -343,23 +342,28 @@ impl ToCss for PropertyDeclarationBlock {
|
|||
Importance::Normal
|
||||
};
|
||||
|
||||
// Substep 5
|
||||
let was_serialized =
|
||||
try!(
|
||||
shorthand.serialize_shorthand_to_buffer(
|
||||
dest,
|
||||
current_longhands.iter().cloned(),
|
||||
&mut is_first_serialization,
|
||||
importance
|
||||
)
|
||||
);
|
||||
// If serialization occured, Substep 7 & 8 will have been completed
|
||||
// Substep 5 - Let value be the result of invoking serialize a CSS
|
||||
// value of current longhands.
|
||||
let mut value = String::from("");
|
||||
match shorthand.get_shorthand_appendable_value(current_longhands.iter().cloned()) {
|
||||
None => continue,
|
||||
Some(appendable_value) => {
|
||||
// Also demo test of overflow with important - I think it'll not
|
||||
// be correct.
|
||||
try!(append_declaration_value(&mut value, appendable_value));
|
||||
}
|
||||
}
|
||||
|
||||
// Substep 6
|
||||
if !was_serialized {
|
||||
continue;
|
||||
if value == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Substeps 7 and 8
|
||||
try!(append_serialization::<W, Cloned<slice::Iter< &PropertyDeclaration>>, _>(
|
||||
dest, &shorthand, AppendableValue::Css(&value), importance,
|
||||
&mut is_first_serialization));
|
||||
|
||||
for current_longhand in current_longhands {
|
||||
// Substep 9
|
||||
already_serialized.push(current_longhand.id());
|
||||
|
@ -434,31 +438,22 @@ fn handle_first_serialization<W>(dest: &mut W,
|
|||
|
||||
/// Append a given kind of appendable value to a serialization.
|
||||
pub fn append_declaration_value<'a, W, I>(dest: &mut W,
|
||||
appendable_value: AppendableValue<'a, I>,
|
||||
importance: Importance,
|
||||
is_overflow_with_name: bool)
|
||||
appendable_value: AppendableValue<'a, I>)
|
||||
-> fmt::Result
|
||||
where W: fmt::Write,
|
||||
I: Iterator<Item=&'a PropertyDeclaration>,
|
||||
{
|
||||
match appendable_value {
|
||||
// Should be able to use this enum to pass the already serialized css?
|
||||
AppendableValue::Css(css) => {
|
||||
try!(write!(dest, "{}", css))
|
||||
},
|
||||
AppendableValue::Declaration(decl) => {
|
||||
try!(decl.to_css(dest));
|
||||
},
|
||||
AppendableValue::DeclarationsForShorthand(shorthand, decls) => {
|
||||
if is_overflow_with_name {
|
||||
try!(shorthand.overflow_longhands_to_css(decls, dest));
|
||||
} else {
|
||||
try!(shorthand.longhands_to_css(decls, dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if importance.important() {
|
||||
try!(write!(dest, " !important"));
|
||||
},
|
||||
AppendableValue::DeclarationsForShorthand(shorthand, decls) => {
|
||||
try!(shorthand.longhands_to_css(decls, dest));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -477,12 +472,6 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W,
|
|||
{
|
||||
try!(handle_first_serialization(dest, is_first_serialization));
|
||||
|
||||
// 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" and must be handled differently
|
||||
if shorthands::is_overflow_shorthand(&appendable_value) {
|
||||
return append_declaration_value(dest, appendable_value, importance, true);
|
||||
}
|
||||
|
||||
try!(property_name.to_css(dest));
|
||||
try!(dest.write_char(':'));
|
||||
|
||||
|
@ -500,7 +489,12 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W,
|
|||
&AppendableValue::DeclarationsForShorthand(..) => try!(write!(dest, " "))
|
||||
}
|
||||
|
||||
try!(append_declaration_value(dest, appendable_value, importance, false));
|
||||
try!(append_declaration_value(dest, appendable_value));
|
||||
|
||||
if importance.important() {
|
||||
try!(write!(dest, " !important"));
|
||||
}
|
||||
|
||||
write!(dest, ";")
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue