auto merge of #1711 : SimonSapin/servo/background-image, r=pcwalton

This commit is contained in:
bors-servo 2014-02-19 11:20:01 -05:00
commit d10bbd5d47
6 changed files with 63 additions and 140 deletions

View file

@ -51,9 +51,7 @@ STYLE_STRUCTS = []
THIS_STYLE_STRUCT = None THIS_STYLE_STRUCT = None
LONGHANDS = [] LONGHANDS = []
LONGHANDS_BY_NAME = {} LONGHANDS_BY_NAME = {}
LONGHANDS_WITH_URL = []
SHORTHANDS = [] SHORTHANDS = []
SHORTHANDS_WITH_URL = []
def new_style_struct(name, is_inherited): def new_style_struct(name, is_inherited):
global THIS_STYLE_STRUCT global THIS_STYLE_STRUCT
@ -94,32 +92,6 @@ pub mod longhands {
% endif % endif
pub use self::computed_value::*; pub use self::computed_value::*;
${caller.body()} ${caller.body()}
pub fn parse_declared(input: &[ComponentValue])
-> Option<DeclaredValue<SpecifiedValue>> {
match CSSWideKeyword::parse(input) {
Some(Some(keyword)) => Some(CSSWideKeyword(keyword)),
Some(None) => Some(CSSWideKeyword(${
"Inherit" if THIS_STYLE_STRUCT.inherited else "Initial"})),
None => parse_specified(input),
}
}
}
</%def>
<%def name="url_longhand(name, no_super=False)">
<%
property = Longhand(name)
THIS_STYLE_STRUCT.longhands.append(property)
LONGHANDS_WITH_URL.append(property)
LONGHANDS_BY_NAME[name] = property
%>
pub mod ${property.ident} {
% if not no_super:
use super::*;
% endif
pub use self::computed_value::*;
${caller.body()}
pub fn parse_declared(input: &[ComponentValue], base_url: &Url) pub fn parse_declared(input: &[ComponentValue], base_url: &Url)
-> Option<DeclaredValue<SpecifiedValue>> { -> Option<DeclaredValue<SpecifiedValue>> {
match CSSWideKeyword::parse(input) { match CSSWideKeyword::parse(input) {
@ -135,9 +107,9 @@ pub mod longhands {
<%def name="longhand(name, no_super=False)"> <%def name="longhand(name, no_super=False)">
<%self:raw_longhand name="${name}"> <%self:raw_longhand name="${name}">
${caller.body()} ${caller.body()}
pub fn parse_specified(input: &[ComponentValue]) pub fn parse_specified(input: &[ComponentValue], base_url: &Url)
-> Option<DeclaredValue<SpecifiedValue>> { -> Option<DeclaredValue<SpecifiedValue>> {
parse(input).map(super::SpecifiedValue) parse(input, base_url).map(super::SpecifiedValue)
} }
</%self:raw_longhand> </%self:raw_longhand>
</%def> </%def>
@ -145,8 +117,8 @@ pub mod longhands {
<%def name="single_component_value(name)"> <%def name="single_component_value(name)">
<%self:longhand name="${name}"> <%self:longhand name="${name}">
${caller.body()} ${caller.body()}
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> { pub fn parse(input: &[ComponentValue], base_url: &Url) -> Option<SpecifiedValue> {
one_component_value(input).and_then(from_component_value) one_component_value(input).and_then(|c| from_component_value(c, base_url))
} }
</%self:longhand> </%self:longhand>
</%def> </%def>
@ -166,7 +138,8 @@ pub mod longhands {
#[inline] pub fn get_initial_value() -> computed_value::T { #[inline] pub fn get_initial_value() -> computed_value::T {
${to_rust_ident(values.split()[0])} ${to_rust_ident(values.split()[0])}
} }
pub fn from_component_value(v: &ComponentValue) -> Option<SpecifiedValue> { pub fn from_component_value(v: &ComponentValue, _base_url: &Url)
-> Option<SpecifiedValue> {
get_ident_lower(v).and_then(|keyword| { get_ident_lower(v).and_then(|keyword| {
match keyword.as_slice() { match keyword.as_slice() {
% for value in values.split(): % for value in values.split():
@ -195,7 +168,8 @@ pub mod longhands {
pub type T = super::super::computed::${type}; pub type T = super::super::computed::${type};
} }
#[inline] pub fn get_initial_value() -> computed_value::T { ${initial_value} } #[inline] pub fn get_initial_value() -> computed_value::T { ${initial_value} }
#[inline] pub fn from_component_value(v: &ComponentValue) -> Option<SpecifiedValue> { #[inline] pub fn from_component_value(v: &ComponentValue, _base_url: &Url)
-> Option<SpecifiedValue> {
specified::${type}::${parse_method}(v) specified::${type}::${parse_method}(v)
} }
</%self:single_component_value> </%self:single_component_value>
@ -238,7 +212,8 @@ pub mod longhands {
</%self:longhand> </%self:longhand>
% endfor % endfor
pub fn parse_border_width(component_value: &ComponentValue) -> Option<specified::Length> { pub fn parse_border_width(component_value: &ComponentValue, _base_url: &Url)
-> Option<specified::Length> {
match component_value { match component_value {
&Ident(ref value) => { &Ident(ref value) => {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
@ -263,8 +238,8 @@ pub mod longhands {
#[inline] pub fn get_initial_value() -> computed_value::T { #[inline] pub fn get_initial_value() -> computed_value::T {
Au::from_px(3) // medium Au::from_px(3) // medium
} }
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> { pub fn parse(input: &[ComponentValue], base_url: &Url) -> Option<SpecifiedValue> {
one_component_value(input).and_then(parse_border_width) one_component_value(input).and_then(|c| parse_border_width(c, base_url))
} }
#[inline] #[inline]
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
@ -349,7 +324,8 @@ pub mod longhands {
// percentage are the same as em. // percentage are the same as em.
} }
/// normal | <number> | <length> | <percentage> /// normal | <number> | <length> | <percentage>
pub fn from_component_value(input: &ComponentValue) -> Option<SpecifiedValue> { pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
-> Option<SpecifiedValue> {
match input { match input {
&ast::Number(ref value) if value.value >= 0. &ast::Number(ref value) if value.value >= 0.
=> Some(SpecifiedNumber(value.value)), => Some(SpecifiedNumber(value.value)),
@ -399,7 +375,8 @@ pub mod longhands {
} }
/// baseline | sub | super | top | text-top | middle | bottom | text-bottom /// baseline | sub | super | top | text-top | middle | bottom | text-bottom
/// | <percentage> | <length> /// | <percentage> | <length>
pub fn from_component_value(input: &ComponentValue) -> Option<SpecifiedValue> { pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
-> Option<SpecifiedValue> {
match input { match input {
&Ident(ref value) => { &Ident(ref value) => {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
@ -476,7 +453,7 @@ pub mod longhands {
// normal | none | [ <string> ]+ // normal | none | [ <string> ]+
// TODO: <uri>, <counter>, attr(<identifier>), open-quote, close-quote, no-open-quote, no-close-quote // TODO: <uri>, <counter>, attr(<identifier>), open-quote, close-quote, no-open-quote, no-close-quote
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> { pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Option<SpecifiedValue> {
match one_component_value(input) { match one_component_value(input) {
Some(&Ident(ref keyword)) => match keyword.to_ascii_lower().as_slice() { Some(&Ident(ref keyword)) => match keyword.to_ascii_lower().as_slice() {
"normal" => return Some(normal), "normal" => return Some(normal),
@ -504,7 +481,7 @@ pub mod longhands {
${predefined_type("background-color", "CSSColor", ${predefined_type("background-color", "CSSColor",
"RGBA(RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")} "RGBA(RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")}
<%self:url_longhand name="background-image"> <%self:single_component_value name="background-image">
// The computed value is the same as the specified value. // The computed value is the same as the specified value.
pub use to_computed_value = super::computed_as_specified; pub use to_computed_value = super::computed_as_specified;
pub mod computed_value { pub mod computed_value {
@ -515,16 +492,7 @@ pub mod longhands {
#[inline] pub fn get_initial_value() -> SpecifiedValue { #[inline] pub fn get_initial_value() -> SpecifiedValue {
None None
} }
pub fn parse(input: &[ComponentValue], base_url: &Url) -> Option<SpecifiedValue> { pub fn from_component_value(component_value: &ComponentValue, base_url: &Url) -> Option<SpecifiedValue> {
from_iter(input.skip_whitespace(), base_url)
}
pub fn from_iter<'a>(mut iter: SkipWhitespaceIterator<'a>, base_url: &Url) -> Option<SpecifiedValue> {
match iter.next() {
Some(v) => from_component_value_with_url(v, base_url),
_ => None
}
}
pub fn from_component_value_with_url(component_value: &ComponentValue, base_url: &Url) -> Option<SpecifiedValue> {
match component_value { match component_value {
&ast::URL(ref url) => { &ast::URL(ref url) => {
let image_url = parse_url(url.as_slice(), Some(base_url.clone())); let image_url = parse_url(url.as_slice(), Some(base_url.clone()));
@ -533,11 +501,7 @@ pub mod longhands {
_ => None, _ => None,
} }
} }
pub fn parse_specified(input: &[ComponentValue], base_url: &Url) </%self:single_component_value>
-> Option<DeclaredValue<SpecifiedValue>> {
parse(input, base_url).map(super::SpecifiedValue)
}
</%self:url_longhand>
${new_style_struct("Color", is_inherited=True)} ${new_style_struct("Color", is_inherited=True)}
@ -551,7 +515,8 @@ pub mod longhands {
#[inline] pub fn get_initial_value() -> computed_value::T { #[inline] pub fn get_initial_value() -> computed_value::T {
RGBA { red: 0., green: 0., blue: 0., alpha: 1. } /* black */ RGBA { red: 0., green: 0., blue: 0., alpha: 1. } /* black */
} }
pub fn parse_specified(input: &[ComponentValue]) -> Option<DeclaredValue<SpecifiedValue>> { pub fn parse_specified(input: &[ComponentValue], _base_url: &Url)
-> Option<DeclaredValue<SpecifiedValue>> {
match one_component_value(input).and_then(Color::parse) { match one_component_value(input).and_then(Color::parse) {
Some(RGBA(rgba)) => Some(SpecifiedValue(rgba)), Some(RGBA(rgba)) => Some(SpecifiedValue(rgba)),
Some(CurrentColor) => Some(CSSWideKeyword(Inherit)), Some(CurrentColor) => Some(CSSWideKeyword(Inherit)),
@ -584,7 +549,7 @@ pub mod longhands {
/// <familiy-name># /// <familiy-name>#
/// <familiy-name> = <string> | [ <ident>+ ] /// <familiy-name> = <string> | [ <ident>+ ]
/// TODO: <generic-familiy> /// TODO: <generic-familiy>
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> { pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Option<SpecifiedValue> {
from_iter(input.skip_whitespace()) from_iter(input.skip_whitespace())
} }
pub fn from_iter<'a>(mut iter: SkipWhitespaceIterator<'a>) -> Option<SpecifiedValue> { pub fn from_iter<'a>(mut iter: SkipWhitespaceIterator<'a>) -> Option<SpecifiedValue> {
@ -655,7 +620,8 @@ pub mod longhands {
% endfor % endfor
} }
/// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 /// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
pub fn from_component_value(input: &ComponentValue) -> Option<SpecifiedValue> { pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
-> Option<SpecifiedValue> {
match input { match input {
&Ident(ref value) => { &Ident(ref value) => {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683 // FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
@ -751,7 +717,8 @@ pub mod longhands {
} }
/// <length> | <percentage> /// <length> | <percentage>
/// TODO: support <absolute-size> and <relative-size> /// TODO: support <absolute-size> and <relative-size>
pub fn from_component_value(input: &ComponentValue) -> Option<SpecifiedValue> { pub fn from_component_value(input: &ComponentValue, _base_url: &Url)
-> Option<SpecifiedValue> {
specified::LengthOrPercentage::parse_non_negative(input).map(|value| { specified::LengthOrPercentage::parse_non_negative(input).map(|value| {
match value { match value {
specified::LP_Length(value) => value, specified::LP_Length(value) => value,
@ -788,7 +755,7 @@ pub mod longhands {
none none
} }
/// none | [ underline || overline || line-through || blink ] /// none | [ underline || overline || line-through || blink ]
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> { pub fn parse(input: &[ComponentValue], _base_url: &Url) -> Option<SpecifiedValue> {
let mut result = SpecifiedValue { let mut result = SpecifiedValue {
underline: false, overline: false, line_through: false, underline: false, overline: false, line_through: false,
}; };
@ -836,25 +803,6 @@ pub mod shorthands {
%> %>
pub mod ${shorthand.ident} { pub mod ${shorthand.ident} {
use super::*; use super::*;
struct Longhands {
% for sub_property in shorthand.sub_properties:
${sub_property.ident}: Option<${sub_property.ident}::SpecifiedValue>,
% endfor
}
pub fn parse(input: &[ComponentValue]) -> Option<Longhands> {
${caller.body()}
}
}
</%def>
<%def name="url_shorthand(name, sub_properties)">
<%
shorthand = Shorthand(name, sub_properties.split())
SHORTHANDS_WITH_URL.append(shorthand)
%>
pub mod ${shorthand.ident} {
use super::*;
struct Longhands { struct Longhands {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
${sub_property.ident}: Option<${sub_property.ident}::SpecifiedValue>, ${sub_property.ident}: Option<${sub_property.ident}::SpecifiedValue>,
@ -865,11 +813,12 @@ pub mod shorthands {
} }
} }
</%def> </%def>
<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function)"> <%def name="four_sides_shorthand(name, sub_property_pattern, parser_function)">
<%self:shorthand name="${name}" sub_properties="${ <%self:shorthand name="${name}" sub_properties="${
' '.join(sub_property_pattern % side ' '.join(sub_property_pattern % side
for side in ['top', 'right', 'bottom', 'left'])}"> for side in ['top', 'right', 'bottom', 'left'])}">
let mut iter = input.skip_whitespace().map(${parser_function}); let mut iter = input.skip_whitespace().map(|c| ${parser_function}(c, base_url));
// zero or more than four values is invalid. // zero or more than four values is invalid.
// one value sets them all // one value sets them all
// two values set (top, bottom) and (left, right) // two values set (top, bottom) and (left, right)
@ -893,21 +842,21 @@ pub mod shorthands {
</%def> </%def>
// TODO: other background-* properties // TODO: other background-* properties
<%self:url_shorthand name="background" sub_properties="background-color background-image"> <%self:shorthand name="background" sub_properties="background-color background-image">
let mut color = None; let mut color = None;
let mut image = None; let mut image = None;
let mut any = false; let mut any = false;
for component_value in input.skip_whitespace() { for component_value in input.skip_whitespace() {
if color.is_none() { if color.is_none() {
match background_color::from_component_value(component_value) { match background_color::from_component_value(component_value, base_url) {
Some(v) => { color = Some(v); any = true; continue }, Some(v) => { color = Some(v); any = true; continue },
None => () None => ()
} }
} }
if image.is_none() { if image.is_none() {
match background_image::from_component_value_with_url(component_value, base_url) { match background_image::from_component_value(component_value, base_url) {
Some(v) => { image = Some(v); any = true; continue }, Some(v) => { image = Some(v); any = true; continue },
None => (), None => (),
} }
@ -916,17 +865,20 @@ pub mod shorthands {
} }
if any { Some(Longhands { background_color: color, background_image: image }) } if any { Some(Longhands { background_color: color, background_image: image }) }
else { None } else { None }
</%self:url_shorthand> </%self:shorthand>
${four_sides_shorthand("margin", "margin-%s", "margin_top::from_component_value")} ${four_sides_shorthand("margin", "margin-%s", "margin_top::from_component_value")}
${four_sides_shorthand("padding", "padding-%s", "padding_top::from_component_value")} ${four_sides_shorthand("padding", "padding-%s", "padding_top::from_component_value")}
${four_sides_shorthand("border-color", "border-%s-color", "specified::CSSColor::parse")} pub fn parse_color(value: &ComponentValue, _base_url: &Url) -> Option<specified::CSSColor> {
specified::CSSColor::parse(value)
}
${four_sides_shorthand("border-color", "border-%s-color", "parse_color")}
${four_sides_shorthand("border-style", "border-%s-style", ${four_sides_shorthand("border-style", "border-%s-style",
"border_top_style::from_component_value")} "border_top_style::from_component_value")}
${four_sides_shorthand("border-width", "border-%s-width", "parse_border_width")} ${four_sides_shorthand("border-width", "border-%s-width", "parse_border_width")}
pub fn parse_border(input: &[ComponentValue]) pub fn parse_border(input: &[ComponentValue], base_url: &Url)
-> Option<(Option<specified::CSSColor>, -> Option<(Option<specified::CSSColor>,
Option<border_top_style::SpecifiedValue>, Option<border_top_style::SpecifiedValue>,
Option<specified::Length>)> { Option<specified::Length>)> {
@ -942,13 +894,13 @@ pub mod shorthands {
} }
} }
if style.is_none() { if style.is_none() {
match border_top_style::from_component_value(component_value) { match border_top_style::from_component_value(component_value, base_url) {
Some(s) => { style = Some(s); any = true; continue }, Some(s) => { style = Some(s); any = true; continue },
None => () None => ()
} }
} }
if width.is_none() { if width.is_none() {
match parse_border_width(component_value) { match parse_border_width(component_value, base_url) {
Some(w) => { width = Some(w); any = true; continue }, Some(w) => { width = Some(w); any = true; continue },
None => () None => ()
} }
@ -964,7 +916,7 @@ pub mod shorthands {
'border-%s-%s' % (side, prop) 'border-%s-%s' % (side, prop)
for prop in ['color', 'style', 'width'] for prop in ['color', 'style', 'width']
)}"> )}">
parse_border(input).map(|(color, style, width)| { parse_border(input, base_url).map(|(color, style, width)| {
Longhands { Longhands {
% for prop in ["color", "style", "width"]: % for prop in ["color", "style", "width"]:
${"border_%s_%s: %s," % (side, prop, prop)} ${"border_%s_%s: %s," % (side, prop, prop)}
@ -979,7 +931,7 @@ pub mod shorthands {
for side in ['top', 'right', 'bottom', 'left'] for side in ['top', 'right', 'bottom', 'left']
for prop in ['color', 'style', 'width'] for prop in ['color', 'style', 'width']
)}"> )}">
parse_border(input).map(|(color, style, width)| { parse_border(input, base_url).map(|(color, style, width)| {
Longhands { Longhands {
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
% for prop in ["color", "style", "width"]: % for prop in ["color", "style", "width"]:
@ -1009,24 +961,24 @@ pub mod shorthands {
continue; continue;
} }
if style.is_none() { if style.is_none() {
match font_style::from_component_value(component_value) { match font_style::from_component_value(component_value, base_url) {
Some(s) => { style = Some(s); continue }, Some(s) => { style = Some(s); continue },
None => () None => ()
} }
} }
if weight.is_none() { if weight.is_none() {
match font_weight::from_component_value(component_value) { match font_weight::from_component_value(component_value, base_url) {
Some(w) => { weight = Some(w); continue }, Some(w) => { weight = Some(w); continue },
None => () None => ()
} }
} }
if variant.is_none() { if variant.is_none() {
match font_variant::from_component_value(component_value) { match font_variant::from_component_value(component_value, base_url) {
Some(v) => { variant = Some(v); continue }, Some(v) => { variant = Some(v); continue },
None => () None => ()
} }
} }
match font_size::from_component_value(component_value) { match font_size::from_component_value(component_value, base_url) {
Some(s) => { size = Some(s); break }, Some(s) => { size = Some(s); break },
None => return None None => return None
} }
@ -1046,7 +998,7 @@ pub mod shorthands {
Some(&Delim('/')) => { Some(&Delim('/')) => {
iter = copied_iter; iter = copied_iter;
line_height = match iter.next() { line_height = match iter.next() {
Some(v) => line_height::from_component_value(v), Some(v) => line_height::from_component_value(v, base_url),
_ => return None, _ => return None,
}; };
if line_height.is_none() { return None } if line_height.is_none() { return None }
@ -1137,9 +1089,6 @@ pub enum PropertyDeclaration {
% for property in LONGHANDS: % for property in LONGHANDS:
${property.ident}_declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>), ${property.ident}_declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
% endfor % endfor
% for property in LONGHANDS_WITH_URL:
${property.ident}_declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
% endfor
} }
@ -1158,14 +1107,6 @@ impl PropertyDeclaration {
let name_lower = name.to_ascii_lower(); let name_lower = name.to_ascii_lower();
match name_lower.as_slice() { match name_lower.as_slice() {
% for property in LONGHANDS: % for property in LONGHANDS:
"${property.name}" => result_list.push(${property.ident}_declaration(
match longhands::${property.ident}::parse_declared(value) {
Some(value) => value,
None => return InvalidValue,
}
)),
% endfor
% for property in LONGHANDS_WITH_URL:
"${property.name}" => result_list.push(${property.ident}_declaration( "${property.name}" => result_list.push(${property.ident}_declaration(
match longhands::${property.ident}::parse_declared(value, base_url) { match longhands::${property.ident}::parse_declared(value, base_url) {
Some(value) => value, Some(value) => value,
@ -1174,38 +1115,6 @@ impl PropertyDeclaration {
)), )),
% endfor % endfor
% for shorthand in SHORTHANDS: % for shorthand in SHORTHANDS:
"${shorthand.name}" => match CSSWideKeyword::parse(value) {
Some(Some(keyword)) => {
% for sub_property in shorthand.sub_properties:
result_list.push(${sub_property.ident}_declaration(
CSSWideKeyword(keyword)
));
% endfor
},
Some(None) => {
% for sub_property in shorthand.sub_properties:
result_list.push(${sub_property.ident}_declaration(
CSSWideKeyword(${
"Inherit" if sub_property.style_struct.inherited else "Initial"})
));
% endfor
},
None => match shorthands::${shorthand.ident}::parse(value) {
Some(result) => {
% for sub_property in shorthand.sub_properties:
result_list.push(${sub_property.ident}_declaration(
match result.${sub_property.ident} {
Some(value) => SpecifiedValue(value),
None => CSSWideKeyword(Initial),
}
));
% endfor
},
None => return InvalidValue,
}
},
% endfor
% for shorthand in SHORTHANDS_WITH_URL:
"${shorthand.name}" => match CSSWideKeyword::parse(value) { "${shorthand.name}" => match CSSWideKeyword::parse(value) {
Some(Some(keyword)) => { Some(Some(keyword)) => {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="subdirectory/background_image.css">
</head>
<body>
<div class="test" style="width:200px; height:200px;"></div>
</body>
</html>

View file

@ -29,4 +29,5 @@
== position_relative_a.html position_relative_b.html == position_relative_a.html position_relative_b.html
== attr_exists_selector.html attr_exists_selector_ref.html == attr_exists_selector.html attr_exists_selector_ref.html
== data_img_a.html data_img_b.html == data_img_a.html data_img_b.html
== background_a.html background_b.html == background_style_attr.html background_ref.html
== background_external_stylesheet.html background_ref.html

View file

@ -0,0 +1,3 @@
.test {
background: url(../rust-0.png)
}