mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Implement 'background-clip' property in CSS3 Background
This property determines the background painting area, which determines the area within which the background is painted. Spec: http://dev.w3.org/csswg/css-backgrounds-3/#background-clip Fixes #6066.
This commit is contained in:
parent
09f5648153
commit
a51d5de860
7 changed files with 116 additions and 5 deletions
|
@ -43,7 +43,7 @@ use std::sync::Arc;
|
|||
use std::sync::mpsc::channel;
|
||||
use style::computed_values::filter::Filter;
|
||||
use style::computed_values::transform::ComputedMatrix;
|
||||
use style::computed_values::{background_attachment, background_origin, background_repeat, background_size};
|
||||
use style::computed_values::{background_attachment, background_clip, background_origin, background_repeat, background_size};
|
||||
use style::computed_values::{border_style, image_rendering, overflow_x, position, visibility};
|
||||
use style::properties::ComputedValues;
|
||||
use style::properties::style_structs::Border;
|
||||
|
@ -309,8 +309,31 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
// inefficient. What we really want is something like "nearest ancestor element that
|
||||
// doesn't have a fragment".
|
||||
let background_color = style.resolve_color(style.get_background().background_color);
|
||||
|
||||
// 'background-clip' determines the area within which the background is painted.
|
||||
// http://dev.w3.org/csswg/css-backgrounds-3/#the-background-clip
|
||||
let mut bounds = *absolute_bounds;
|
||||
|
||||
match style.get_background().background_clip {
|
||||
background_clip::T::border_box => {}
|
||||
background_clip::T::padding_box => {
|
||||
let border = style.logical_border_width().to_physical(style.writing_mode);
|
||||
bounds.origin.x = bounds.origin.x + border.left;
|
||||
bounds.origin.y = bounds.origin.y + border.top;
|
||||
bounds.size.width = bounds.size.width - border.horizontal();
|
||||
bounds.size.height = bounds.size.height - border.vertical();
|
||||
}
|
||||
background_clip::T::content_box => {
|
||||
let border_padding = self.border_padding.to_physical(style.writing_mode);
|
||||
bounds.origin.x = bounds.origin.x + border_padding.left;
|
||||
bounds.origin.y = bounds.origin.y + border_padding.top;
|
||||
bounds.size.width = bounds.size.width - border_padding.horizontal();
|
||||
bounds.size.height = bounds.size.height - border_padding.vertical();
|
||||
}
|
||||
}
|
||||
|
||||
display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
|
||||
base: BaseDisplayItem::new(*absolute_bounds,
|
||||
base: BaseDisplayItem::new(bounds,
|
||||
DisplayItemMetadata::new(self.node,
|
||||
style,
|
||||
Cursor::DefaultCursor),
|
||||
|
|
|
@ -40,6 +40,7 @@ partial interface CSSStyleDeclaration {
|
|||
[TreatNullAs=EmptyString] attribute DOMString backgroundAttachment;
|
||||
[TreatNullAs=EmptyString] attribute DOMString backgroundSize;
|
||||
[TreatNullAs=EmptyString] attribute DOMString backgroundOrigin;
|
||||
[TreatNullAs=EmptyString] attribute DOMString backgroundClip;
|
||||
|
||||
[TreatNullAs=EmptyString] attribute DOMString border;
|
||||
[TreatNullAs=EmptyString] attribute DOMString borderColor;
|
||||
|
|
|
@ -1295,6 +1295,8 @@ pub mod longhands {
|
|||
|
||||
${single_keyword("background-attachment", "scroll fixed")}
|
||||
|
||||
${single_keyword("background-clip", "border-box padding-box content-box")}
|
||||
|
||||
${single_keyword("background-origin", "padding-box border-box content-box")}
|
||||
|
||||
<%self:longhand name="background-size">
|
||||
|
@ -4247,9 +4249,9 @@ pub mod shorthands {
|
|||
// TODO: other background-* properties
|
||||
<%self:shorthand name="background"
|
||||
sub_properties="background-color background-position background-repeat background-attachment
|
||||
background-image background-size background-origin">
|
||||
use properties::longhands::{background_color, background_position, background_repeat};
|
||||
use properties::longhands::{background_attachment, background_image, background_size, background_origin};
|
||||
background-image background-size background-origin background-clip">
|
||||
use properties::longhands::{background_color, background_position, background_repeat, background_attachment};
|
||||
use properties::longhands::{background_image, background_size, background_origin, background_clip};
|
||||
|
||||
let mut color = None;
|
||||
let mut image = None;
|
||||
|
@ -4259,6 +4261,7 @@ pub mod shorthands {
|
|||
let mut attachment = None;
|
||||
let mut any = false;
|
||||
let mut origin = None;
|
||||
let mut clip = None;
|
||||
|
||||
loop {
|
||||
if position.is_none() {
|
||||
|
@ -4310,6 +4313,13 @@ pub mod shorthands {
|
|||
continue
|
||||
}
|
||||
}
|
||||
if clip.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_clip::parse(context, input)) {
|
||||
clip = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -4322,6 +4332,7 @@ pub mod shorthands {
|
|||
background_attachment: attachment,
|
||||
background_size: size,
|
||||
background_origin: origin,
|
||||
background_clip: clip,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
|
|
34
tests/ref/background_clip_a.html
Normal file
34
tests/ref/background_clip_a.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
div {
|
||||
background: green;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 20px;
|
||||
border-width: 10px 20px 30px 40px;
|
||||
border-style: dotted;
|
||||
border-color: red;
|
||||
}
|
||||
#foo1 {
|
||||
background-clip: border-box;
|
||||
}
|
||||
#foo2 {
|
||||
background-clip: padding-box;
|
||||
}
|
||||
#foo3 {
|
||||
background-clip: content-box;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>background-clip: border-box;</p>
|
||||
<div id=foo1></div>
|
||||
<p>background-clip: padding-box;</p>
|
||||
<div id=foo2></div>
|
||||
<p>background-clip: content-box;</p>
|
||||
<div id=foo3></div>
|
||||
</body>
|
||||
</html>
|
||||
|
40
tests/ref/background_clip_ref.html
Normal file
40
tests/ref/background_clip_ref.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
#foo1 {
|
||||
background: green;
|
||||
}
|
||||
#foo1, #foo2, #foo3 {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 20px;
|
||||
border-width: 10px 20px 30px 40px;
|
||||
border-style: dotted;
|
||||
border-color: red;
|
||||
}
|
||||
#foo2-color {
|
||||
background: green;
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
position: relative;
|
||||
left: -20px;
|
||||
top: -20px;
|
||||
}
|
||||
#foo3-color {
|
||||
background: green;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>background-clip: border-box;</p>
|
||||
<div id=foo1></div>
|
||||
<p>background-clip: padding-box;</p>
|
||||
<div id=foo2><div id=foo2-color></div></div>
|
||||
<p>background-clip: content-box;</p>
|
||||
<div id=foo3><div id=foo3-color></div></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -22,6 +22,7 @@ fragment=top != ../html/acid2.html acid2_ref.html
|
|||
flaky_cpu == append_style_a.html append_style_b.html
|
||||
== attr_exists_selector.html attr_exists_selector_ref.html
|
||||
== attr_selector_case_sensitivity.html attr_selector_case_sensitivity_ref.html
|
||||
== background_clip_a.html background_clip_ref.html
|
||||
== background_external_stylesheet.html background_ref.html
|
||||
== background_image_position_a.html background_image_position_ref.html
|
||||
== background_none_a.html background_none_b.html
|
||||
|
|
|
@ -116,6 +116,7 @@ fn test_parse_stylesheet() {
|
|||
],
|
||||
declarations: PropertyDeclarationBlock {
|
||||
normal: Arc::new(vec![
|
||||
PropertyDeclaration::BackgroundClip(DeclaredValue::Initial),
|
||||
PropertyDeclaration::BackgroundOrigin(DeclaredValue::Initial),
|
||||
PropertyDeclaration::BackgroundSize(DeclaredValue::Initial),
|
||||
PropertyDeclaration::BackgroundImage(DeclaredValue::Initial),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue