feat(css/prefixer): Support more properties (#4055)

This commit is contained in:
Alexander Akait 2022-03-17 10:25:51 +03:00 committed by GitHub
parent a9708a5a1f
commit f2517a345b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 411 additions and 39 deletions

View File

@ -94,3 +94,41 @@ where
{ {
node.visit_mut_with(&mut PseudoElementSelectorNameReplacer { from, to }); node.visit_mut_with(&mut PseudoElementSelectorNameReplacer { from, to });
} }
pub struct PseudoElementOnPseudoClassReplacer<'a> {
from: &'a str,
to: &'a str,
}
impl VisitMut for PseudoElementOnPseudoClassReplacer<'_> {
fn visit_mut_subclass_selector(&mut self, n: &mut SubclassSelector) {
n.visit_mut_children_with(self);
match n {
SubclassSelector::PseudoElement(PseudoElementSelector { name, span, .. })
if &*name.value.to_lowercase() == self.from =>
{
*n = SubclassSelector::PseudoClass(PseudoClassSelector {
span: *span,
name: Ident {
span: name.span,
value: self.to.into(),
raw: self.to.into(),
},
children: None,
})
}
_ => {}
}
}
}
pub fn replace_pseudo_class_selector_on_pseudo_element_selector<N>(
node: &mut N,
from: &str,
to: &str,
) where
N: for<'aa> VisitMutWith<PseudoElementOnPseudoClassReplacer<'aa>>,
{
node.visit_mut_with(&mut PseudoElementOnPseudoClassReplacer { from, to });
}

View File

@ -4,7 +4,7 @@ use swc_common::DUMMY_SP;
use swc_css_ast::*; use swc_css_ast::*;
use swc_css_utils::{ use swc_css_utils::{
replace_function_name, replace_ident, replace_pseudo_class_selector_name, replace_function_name, replace_ident, replace_pseudo_class_selector_name,
replace_pseudo_element_selector_name, replace_pseudo_class_selector_on_pseudo_element_selector, replace_pseudo_element_selector_name,
}; };
use swc_css_visit::{VisitMut, VisitMutWith}; use swc_css_visit::{VisitMut, VisitMutWith};
@ -12,9 +12,184 @@ pub fn prefixer() -> impl VisitMut {
Prefixer::default() Prefixer::default()
} }
pub struct CrossFadeFunctionReplacerOnLegacyVariant<'a> {
from: &'a str,
to: &'a str,
}
impl VisitMut for CrossFadeFunctionReplacerOnLegacyVariant<'_> {
fn visit_mut_function(&mut self, n: &mut Function) {
n.visit_mut_children_with(self);
if &*n.name.value.to_lowercase() == self.from {
let mut transparency_values = vec![];
for group in n.value.split_mut(|n| {
matches!(
n,
ComponentValue::Delimiter(Delimiter {
value: DelimiterValue::Comma,
..
})
)
}) {
if transparency_values.len() >= 2 {
return;
}
let mut transparency_value = None;
for n in group {
match n {
ComponentValue::Percentage(Percentage {
value: Number { value, .. },
..
}) => {
if transparency_value.is_some() {
return;
}
transparency_value = Some(*value / 100.0);
}
ComponentValue::Number(Number { value, .. }) => {
if transparency_value.is_some() {
return;
}
transparency_value = Some(*value);
}
ComponentValue::Integer(Integer { value, .. }) => {
if transparency_value.is_some() {
return;
}
transparency_value = Some((*value) as f64);
}
_ => {}
}
}
transparency_values.push(transparency_value);
}
if transparency_values.len() != 2 {
return;
}
let transparency_value = match (transparency_values[0], transparency_values[1]) {
(None, None) => 0.5,
(Some(number), None) => number,
(None, Some(number)) => 1.0 - number,
(Some(first), Some(second)) if first + second == 1.0 => first,
_ => {
return;
}
};
let mut new_value: Vec<ComponentValue> = n
.value
.iter()
.filter(|n| {
!matches!(
n,
ComponentValue::Percentage(_)
| ComponentValue::Number(_)
| ComponentValue::Integer(_)
)
})
.cloned()
.collect();
new_value.extend(vec![
ComponentValue::Delimiter(Delimiter {
span: DUMMY_SP,
value: DelimiterValue::Comma,
}),
ComponentValue::Number(Number {
span: DUMMY_SP,
value: transparency_value,
raw: transparency_value.to_string().into(),
}),
]);
n.value = new_value;
n.name.value = self.to.into();
n.name.raw = self.to.into();
}
}
}
pub fn replace_cross_fade_function_on_legacy_variant<N>(node: &mut N, from: &str, to: &str)
where
N: for<'aa> VisitMutWith<CrossFadeFunctionReplacerOnLegacyVariant<'aa>>,
{
node.visit_mut_with(&mut CrossFadeFunctionReplacerOnLegacyVariant { from, to });
}
pub struct ImageSetFunctionReplacerOnLegacyVariant<'a> {
from: &'a str,
to: &'a str,
in_function: bool,
}
impl VisitMut for ImageSetFunctionReplacerOnLegacyVariant<'_> {
fn visit_mut_component_value(&mut self, n: &mut ComponentValue) {
n.visit_mut_children_with(self);
if !self.in_function {
return;
}
if let ComponentValue::Str(Str { value, raw, span }) = n {
*n = ComponentValue::Url(Url {
span: *span,
name: Ident {
span: DUMMY_SP,
value: "url".into(),
raw: "url".into(),
},
value: Some(UrlValue::Str(Str {
span: DUMMY_SP,
value: value.as_ref().into(),
raw: raw.as_ref().into(),
})),
modifiers: Some(vec![]),
})
}
}
fn visit_mut_function(&mut self, n: &mut Function) {
let old_in_function = self.in_function;
self.in_function = true;
n.visit_mut_children_with(self);
if &*n.name.value.to_lowercase() == self.from {
n.name.value = self.to.into();
n.name.raw = self.to.into();
}
self.in_function = old_in_function;
}
}
pub fn replace_image_set_function_on_legacy_variant<N>(node: &mut N, from: &str, to: &str)
where
N: for<'aa> VisitMutWith<ImageSetFunctionReplacerOnLegacyVariant<'aa>>,
{
node.visit_mut_with(&mut ImageSetFunctionReplacerOnLegacyVariant {
from,
to,
in_function: false,
});
}
#[derive(Default)] #[derive(Default)]
struct Prefixer { struct Prefixer {
in_stylesheet: bool, in_stylesheet: bool,
in_keyframe_block: bool,
added_rules: Vec<Rule>, added_rules: Vec<Rule>,
in_simple_block: bool, in_simple_block: bool,
added_declarations: Vec<Declaration>, added_declarations: Vec<Declaration>,
@ -28,12 +203,21 @@ pub enum Prefix {
} }
impl VisitMut for Prefixer { impl VisitMut for Prefixer {
fn visit_mut_keyframe_block(&mut self, n: &mut KeyframeBlock) {
let old_in_keyframe_block = self.in_keyframe_block;
self.in_keyframe_block = true;
n.visit_mut_children_with(self);
self.in_keyframe_block = old_in_keyframe_block;
}
// TODO handle `resolution` in media/supports at-rules // TODO handle `resolution` in media/supports at-rules
// TODO handle declarations in `@media`/`@support` // TODO handle declarations in `@media`/`@support`
// TODO handle `@viewport` // TODO handle `@viewport`
// TODO handle `@keyframes` // TODO handle `@keyframes`
// TODO improve legacy `::placeholder` pseudo
fn visit_mut_qualified_rule(&mut self, n: &mut QualifiedRule) { fn visit_mut_qualified_rule(&mut self, n: &mut QualifiedRule) {
n.visit_mut_children_with(self); n.visit_mut_children_with(self);
@ -55,11 +239,11 @@ impl VisitMut for Prefixer {
"file-selector-button", "file-selector-button",
"-webkit-file-upload-button", "-webkit-file-upload-button",
); );
replace_pseudo_element_selector_name(&mut new_prelude, "backdrop", "-ms-backdrop"); replace_pseudo_element_selector_name(&mut new_prelude, "backdrop", "-webkit-backdrop");
replace_pseudo_element_selector_name( replace_pseudo_element_selector_name(
&mut new_prelude, &mut new_prelude,
"placeholder", "placeholder",
"-ms-input-placeholder", "-webkit-input-placeholder",
); );
if n.prelude != new_prelude { if n.prelude != new_prelude {
@ -82,6 +266,25 @@ impl VisitMut for Prefixer {
"-moz-placeholder-shown", "-moz-placeholder-shown",
); );
replace_pseudo_element_selector_name(&mut new_prelude, "selection", "-moz-selection"); replace_pseudo_element_selector_name(&mut new_prelude, "selection", "-moz-selection");
{
let mut new_prelude_with_previous = new_prelude.clone();
replace_pseudo_class_selector_on_pseudo_element_selector(
&mut new_prelude_with_previous,
"placeholder",
"-moz-placeholder",
);
if new_prelude_with_previous != new_prelude {
self.added_rules.push(Rule::QualifiedRule(QualifiedRule {
span: DUMMY_SP,
prelude: new_prelude_with_previous,
block: n.block.clone(),
}));
}
}
replace_pseudo_element_selector_name(&mut new_prelude, "placeholder", "-moz-placeholder"); replace_pseudo_element_selector_name(&mut new_prelude, "placeholder", "-moz-placeholder");
if n.prelude != new_prelude { if n.prelude != new_prelude {
@ -105,11 +308,30 @@ impl VisitMut for Prefixer {
"file-selector-button", "file-selector-button",
"-ms-browse", "-ms-browse",
); );
replace_pseudo_element_selector_name(&mut new_prelude, "backdrop", "-webkit-backdrop"); replace_pseudo_element_selector_name(&mut new_prelude, "backdrop", "-ms-backdrop");
{
let mut new_prelude_with_previous = new_prelude.clone();
replace_pseudo_class_selector_on_pseudo_element_selector(
&mut new_prelude_with_previous,
"placeholder",
"-ms-input-placeholder",
);
if new_prelude_with_previous != new_prelude {
self.added_rules.push(Rule::QualifiedRule(QualifiedRule {
span: DUMMY_SP,
prelude: new_prelude_with_previous,
block: n.block.clone(),
}));
}
}
replace_pseudo_element_selector_name( replace_pseudo_element_selector_name(
&mut new_prelude, &mut new_prelude,
"placeholder", "placeholder",
"-webkit-input-placeholder", "-ms-input-placeholder",
); );
if n.prelude != new_prelude { if n.prelude != new_prelude {
@ -171,8 +393,17 @@ impl VisitMut for Prefixer {
let mut webkit_new_value = n.value.clone(); let mut webkit_new_value = n.value.clone();
replace_function_name(&mut webkit_new_value, "filter", "-webkit-filter"); replace_function_name(&mut webkit_new_value, "filter", "-webkit-filter");
replace_function_name(&mut webkit_new_value, "image-set", "-webkit-image-set"); replace_image_set_function_on_legacy_variant(
&mut webkit_new_value,
"image-set",
"-webkit-image-set",
);
replace_function_name(&mut webkit_new_value, "calc", "-webkit-calc"); replace_function_name(&mut webkit_new_value, "calc", "-webkit-calc");
replace_cross_fade_function_on_legacy_variant(
&mut webkit_new_value,
"cross-fade",
"-webkit-cross-fade",
);
let mut moz_new_value = n.value.clone(); let mut moz_new_value = n.value.clone();
@ -320,6 +551,7 @@ impl VisitMut for Prefixer {
same_content!(Prefix::O, "-o-animation-timing-function"); same_content!(Prefix::O, "-o-animation-timing-function");
} }
// TODO improve me https://developer.mozilla.org/en-US/docs/Web/CSS/background-clip
"background-clip" => { "background-clip" => {
if let ComponentValue::Ident(Ident { value, .. }) = &n.value[0] { if let ComponentValue::Ident(Ident { value, .. }) = &n.value[0] {
if &*value.to_lowercase() == "text" { if &*value.to_lowercase() == "text" {
@ -516,6 +748,7 @@ impl VisitMut for Prefixer {
same_content!(Prefix::Ms, "-ms-flex-line-pack"); same_content!(Prefix::Ms, "-ms-flex-line-pack");
} }
// TODO fix me https://developer.mozilla.org/en-US/docs/Web/CSS/Image-Rendering
"image-rendering" => { "image-rendering" => {
if let ComponentValue::Ident(Ident { value, .. }) = &n.value[0] { if let ComponentValue::Ident(Ident { value, .. }) = &n.value[0] {
if &*value.to_lowercase() == "pixelated" { if &*value.to_lowercase() == "pixelated" {
@ -712,7 +945,10 @@ impl VisitMut for Prefixer {
same_content!(Prefix::Moz, "-moz-transform"); same_content!(Prefix::Moz, "-moz-transform");
if !has_3d_function { if !has_3d_function {
if !self.in_keyframe_block {
same_content!(Prefix::Ms, "-ms-transform"); same_content!(Prefix::Ms, "-ms-transform");
}
same_content!(Prefix::O, "-o-transform"); same_content!(Prefix::O, "-o-transform");
} }
} }
@ -720,7 +956,11 @@ impl VisitMut for Prefixer {
"transform-origin" => { "transform-origin" => {
same_content!(Prefix::Webkit, "-webkit-transform-origin"); same_content!(Prefix::Webkit, "-webkit-transform-origin");
same_content!(Prefix::Moz, "-moz-transform-origin"); same_content!(Prefix::Moz, "-moz-transform-origin");
if !self.in_keyframe_block {
same_content!(Prefix::Ms, "-ms-transform-origin"); same_content!(Prefix::Ms, "-ms-transform-origin");
}
same_content!(Prefix::O, "-o-transform-origin"); same_content!(Prefix::O, "-o-transform-origin");
} }
@ -809,8 +1049,10 @@ impl VisitMut for Prefixer {
} }
// TODO improve me for `filter` values https://github.com/postcss/autoprefixer/blob/main/test/cases/transition.css#L6 // TODO improve me for `filter` values https://github.com/postcss/autoprefixer/blob/main/test/cases/transition.css#L6
// TODO https://github.com/postcss/autoprefixer/blob/main/lib/transition.js
"transition" => { "transition" => {
replace_ident(&mut webkit_new_value, "transform", "-webkit-transform"); replace_ident(&mut webkit_new_value, "transform", "-webkit-transform");
replace_ident(&mut webkit_new_value, "filter", "-webkit-filter");
same_content!(Prefix::Webkit, "-webkit-transition"); same_content!(Prefix::Webkit, "-webkit-transition");
@ -910,7 +1152,6 @@ impl VisitMut for Prefixer {
"stretch" => { "stretch" => {
same_name!("-webkit-fill-available"); same_name!("-webkit-fill-available");
same_name!("-moz-available"); same_name!("-moz-available");
same_name!("fill-available");
} }
_ => {} _ => {}
@ -1094,11 +1335,13 @@ impl VisitMut for Prefixer {
"background-origin" => { "background-origin" => {
same_content!(Prefix::Webkit, "-webkit-background-origin"); same_content!(Prefix::Webkit, "-webkit-background-origin");
same_content!(Prefix::Moz, "-moz-background-origin");
same_content!(Prefix::O, "-o-background-origin"); same_content!(Prefix::O, "-o-background-origin");
} }
"background-size" => { "background-size" => {
same_content!(Prefix::Webkit, "-webkit-background-size"); same_content!(Prefix::Webkit, "-webkit-background-size");
same_content!(Prefix::Moz, "-moz-background-size");
same_content!(Prefix::O, "-o-background-size"); same_content!(Prefix::O, "-o-background-size");
} }
@ -1195,11 +1438,7 @@ impl VisitMut for Prefixer {
// TODO add `grid` support https://github.com/postcss/autoprefixer/tree/main/lib/hacks (starting with grid) and https://github.com/postcss/autoprefixer/blob/main/data/prefixes.js#L559 and https://github.com/postcss/autoprefixer/blob/main/lib/hacks/intrinsic.js // TODO add `grid` support https://github.com/postcss/autoprefixer/tree/main/lib/hacks (starting with grid) and https://github.com/postcss/autoprefixer/blob/main/data/prefixes.js#L559 and https://github.com/postcss/autoprefixer/blob/main/lib/hacks/intrinsic.js
// TODO handle https://github.com/postcss/autoprefixer/blob/main/data/prefixes.js#L938 // TODO handle https://github.com/postcss/autoprefixer/blob/main/data/prefixes.js#L938
// TODO handle `image-set()` https://github.com/postcss/autoprefixer/blob/main/lib/hacks/image-set.js
// TODO handle `linear-gradient()`/`repeating-linear-gradient()`/`radial-gradient()`/`repeating-radial-gradient()` in all properties https://github.com/postcss/autoprefixer/blob/main/data/prefixes.js#L168 // TODO handle `linear-gradient()`/`repeating-linear-gradient()`/`radial-gradient()`/`repeating-radial-gradient()` in all properties https://github.com/postcss/autoprefixer/blob/main/data/prefixes.js#L168
// TODO add https://github.com/postcss/autoprefixer/blob/main/lib/hacks/filter-value.js
// TODO add https://github.com/postcss/autoprefixer/blob/main/lib/hacks/cross-fade.js
// TODO handle transform functions https://github.com/postcss/autoprefixer/blob/main/lib/hacks/transform-decl.js
// TODO fix me https://github.com/postcss/autoprefixer/blob/main/test/cases/custom-prefix.out.css // TODO fix me https://github.com/postcss/autoprefixer/blob/main/test/cases/custom-prefix.out.css
_ => {} _ => {}
} }

View File

@ -1,7 +1,7 @@
dialog::-ms-backdrop { dialog::-webkit-backdrop {
background: rgba(255, 0, 0, .25); background: rgba(255, 0, 0, .25);
} }
dialog::-webkit-backdrop { dialog::-ms-backdrop {
background: rgba(255, 0, 0, .25); background: rgba(255, 0, 0, .25);
} }
dialog::backdrop { dialog::backdrop {

View File

@ -1,10 +1,12 @@
.class { .class {
-webkit-background-origin: initial; -webkit-background-origin: initial;
-moz-background-origin: initial;
-o-background-origin: initial; -o-background-origin: initial;
background-origin: initial; background-origin: initial;
} }
.class { .class {
-webkit-background-size: contain; -webkit-background-size: contain;
-moz-background-size: contain;
-o-background-size: contain; -o-background-size: contain;
background-size: contain; background-size: contain;
} }

View File

@ -1,10 +1,12 @@
a { a {
-webkit-background-size: 20px; -webkit-background-size: 20px;
-moz-background-size: 20px;
-o-background-size: 20px; -o-background-size: 20px;
background-size: 20px; background-size: 20px;
} }
b { b {
-webkit-background-size: contain; -webkit-background-size: contain;
-moz-background-size: contain;
-o-background-size: contain; -o-background-size: contain;
background-size: contain; background-size: contain;
} }

View File

@ -10,6 +10,7 @@
} }
div { div {
-webkit-background-size: -webkit-calc(20px); -webkit-background-size: -webkit-calc(20px);
-moz-background-size: -moz-calc(20px);
-o-background-size: calc(20px); -o-background-size: calc(20px);
background-size: -webkit-calc(20px); background-size: -webkit-calc(20px);
background-size: -moz-calc(20px); background-size: -moz-calc(20px);

View File

@ -21,3 +21,18 @@ h3 {
.foo { .foo {
background-image: cross-fade(.59 linear-gradient(white, black), radial-gradient(circle closest-corner, white, black)); background-image: cross-fade(.59 linear-gradient(white, black), radial-gradient(circle closest-corner, white, black));
} }
.class {
background-image: cross-fade( url(white.png) 0%, url(black.png) 100%); /* fully black */
background-image: cross-fade( url(white.png) 25%, url(black.png) 75%); /* 25% white, 75% black */
background-image: cross-fade( url(white.png) 50%, url(black.png) 50%); /* 50% white, 50% black */
background-image: cross-fade( url(white.png) 75%, url(black.png) 25%); /* 75% white, 25% black */
background-image: cross-fade( url(white.png) 100%, url(black.png) 0%); /* fully white */
background-image: cross-fade( url(green.png) 75%, url(red.png) 75%); /* both green and red at 75% */
background-image: cross-fade( url(white.png), url(black.png) 75%);
background-image: cross-fade( url(red.png) 33.33%, url(yellow.png) 33.33%, url(blue.png) 33.33%);
}
.broken {
background-image: cross-fade(url(red.png) 33.33%);
}

View File

@ -1,18 +1,43 @@
a { a {
background-image: -webkit-cross-fade(url(foo.png), url(bar.png), 0.2);
background-image: cross-fade(20% url(foo.png), url(bar.png)); background-image: cross-fade(20% url(foo.png), url(bar.png));
} }
b { b {
background-image: -webkit-cross-fade(url(foo.png), url(bar.png), 0.5);
background-image: cross-fade(url(foo.png), url(bar.png)); background-image: cross-fade(url(foo.png), url(bar.png));
} }
h1 { h1 {
background-image: -webkit-cross-fade(url(foo.png), url(bar.png), 0.10823);
background-image: cross-fade(10.823% url(foo.png), url(bar.png)); background-image: cross-fade(10.823% url(foo.png), url(bar.png));
} }
h2 { h2 {
background-image: -webkit-cross-fade(url(foo.png), url(bar.png), 0.59);
background-image: cross-fade(0.59 url(foo.png), url(bar.png)); background-image: cross-fade(0.59 url(foo.png), url(bar.png));
} }
h3 { h3 {
background-image: -webkit-cross-fade(url(foo.png), url(bar.png), 0.59);
background-image: cross-fade(.59 url(foo.png), url(bar.png)); background-image: cross-fade(.59 url(foo.png), url(bar.png));
} }
.foo { .foo {
background-image: -webkit-cross-fade(linear-gradient(white, black), radial-gradient(circle closest-corner, white, black), 0.59);
background-image: cross-fade(.59 linear-gradient(white, black), radial-gradient(circle closest-corner, white, black)); background-image: cross-fade(.59 linear-gradient(white, black), radial-gradient(circle closest-corner, white, black));
} }
.class {
background-image: -webkit-cross-fade(url(white.png), url(black.png), 0);
background-image: cross-fade(url(white.png) 0%, url(black.png) 100%);
background-image: -webkit-cross-fade(url(white.png), url(black.png), 0.25);
background-image: cross-fade(url(white.png) 25%, url(black.png) 75%);
background-image: -webkit-cross-fade(url(white.png), url(black.png), 0.5);
background-image: cross-fade(url(white.png) 50%, url(black.png) 50%);
background-image: -webkit-cross-fade(url(white.png), url(black.png), 0.75);
background-image: cross-fade(url(white.png) 75%, url(black.png) 25%);
background-image: -webkit-cross-fade(url(white.png), url(black.png), 1);
background-image: cross-fade(url(white.png) 100%, url(black.png) 0%);
background-image: cross-fade(url(green.png) 75%, url(red.png) 75%);
background-image: -webkit-cross-fade(url(white.png), url(black.png), 0.25);
background-image: cross-fade(url(white.png), url(black.png) 75%);
background-image: cross-fade(url(red.png) 33.33%, url(yellow.png) 33.33%, url(blue.png) 33.33%);
}
.broken {
background-image: cross-fade(url(red.png) 33.33%);
}

View File

@ -6,9 +6,10 @@
a { a {
-webkit-filter: blur(10px); -webkit-filter: blur(10px);
filter: blur(10px); filter: blur(10px);
-webkit-transition: filter 2s; -webkit-transition: -webkit-filter 2s;
-moz-transition: filter 2s; -moz-transition: filter 2s;
-o-transition: filter 2s; -o-transition: filter 2s;
transition: -webkit-filter 2s;
transition: filter 2s; transition: filter 2s;
} }
div { div {

View File

@ -5,7 +5,14 @@
.b, .b,
.c::selection, .c::selection,
.d:read-only, .d:read-only,
.e::-ms-input-placeholder { .e::-webkit-input-placeholder {
color: yellow;
}
.a,
.b,
.c::-moz-selection,
.d:-moz-read-only,
.e:-moz-placeholder {
color: yellow; color: yellow;
} }
.a, .a,
@ -19,7 +26,14 @@
.b, .b,
.c::selection, .c::selection,
.d:read-only, .d:read-only,
.e::-webkit-input-placeholder { .e:-ms-input-placeholder {
color: yellow;
}
.a,
.b,
.c::selection,
.d:read-only,
.e::-ms-input-placeholder {
color: yellow; color: yellow;
} }
.a, .a,

View File

@ -33,3 +33,7 @@ h1 {
.class { .class {
content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.broken {
content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x) "test";
}

View File

@ -3,39 +3,43 @@ a {
background-image: image-set(url(foo@1x.png) 1x, url(foo@2x.png) 2x); background-image: image-set(url(foo@1x.png) 1x, url(foo@2x.png) 2x);
} }
h1 { h1 {
background-image: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); background-image: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
background-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); background-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.class { .class {
background-image: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); background-image: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
background-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); background-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.class { .class {
-webkit-border-image: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); -webkit-border-image: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
-moz-border-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); -moz-border-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
-o-border-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); -o-border-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
border-image: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); border-image: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
border-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); border-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.class { .class {
-webkit-mask: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); -webkit-mask: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
mask: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); mask: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
mask: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); mask: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.class { .class {
-webkit-mask-image: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); -webkit-mask-image: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
mask-image: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); mask-image: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
mask-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); mask-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.class { .class {
list-style: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); list-style: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
list-style: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); list-style: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.class { .class {
list-style-image: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); list-style-image: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
list-style-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); list-style-image: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.class { .class {
content: -webkit-image-set('foo@1x.png' 1x, "foo@2x.png" 2x); content: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x);
content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x); content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x);
} }
.broken {
content: -webkit-image-set(url('foo@1x.png') 1x, url("foo@2x.png") 2x) "test";
content: image-set('foo@1x.png' 1x, "foo@2x.png" 2x) "test";
}

View File

@ -5,7 +5,6 @@
top: calc(10% + 10px); top: calc(10% + 10px);
-webkit-transform: rotate(10deg); -webkit-transform: rotate(10deg);
-moz-transform: rotate(10deg); -moz-transform: rotate(10deg);
-ms-transform: rotate(10deg);
-o-transform: rotate(10deg); -o-transform: rotate(10deg);
transform: rotate(10deg); transform: rotate(10deg);
} }
@ -23,7 +22,6 @@
top: calc(10%); top: calc(10%);
-webkit-transform: rotate(0); -webkit-transform: rotate(0);
-moz-transform: rotate(0); -moz-transform: rotate(0);
-ms-transform: rotate(0);
-o-transform: rotate(0); -o-transform: rotate(0);
transform: rotate(0); transform: rotate(0);
} }

View File

@ -1,3 +1,7 @@
input::placeholder { input::placeholder {
color: red; color: red;
} }
input::placeholder, #fs-toggle:fullscreen {
color: red;
}

View File

@ -1,12 +1,42 @@
input::-ms-input-placeholder { input::-webkit-input-placeholder {
color: red;
}
input:-moz-placeholder {
color: red; color: red;
} }
input::-moz-placeholder { input::-moz-placeholder {
color: red; color: red;
} }
input::-webkit-input-placeholder { input:-ms-input-placeholder {
color: red;
}
input::-ms-input-placeholder {
color: red; color: red;
} }
input::placeholder { input::placeholder {
color: red; color: red;
} }
input::-webkit-input-placeholder,
#fs-toggle:-webkit-full-screen {
color: red;
}
input:-moz-placeholder,
#fs-toggle:-moz-full-screen {
color: red;
}
input::-moz-placeholder,
#fs-toggle:-moz-full-screen {
color: red;
}
input:-ms-input-placeholder,
#fs-toggle:-ms-fullscreen {
color: red;
}
input::-ms-input-placeholder,
#fs-toggle:-ms-fullscreen {
color: red;
}
input::placeholder,
#fs-toggle:fullscreen {
color: red;
}

View File

@ -38,7 +38,6 @@ em {
from { from {
-webkit-transform: rotate(90deg); -webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg); -moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg); -o-transform: rotate(90deg);
transform: rotate(90deg); transform: rotate(90deg);
} }

View File

@ -13,7 +13,6 @@ div {
width: fill-available; width: fill-available;
width: -webkit-fill-available; width: -webkit-fill-available;
width: -moz-available; width: -moz-available;
width: fill-available;
width: stretch; width: stretch;
min-width: -webkit-fit-content; min-width: -webkit-fit-content;
min-width: -moz-fit-content; min-width: -moz-fit-content;
@ -57,7 +56,6 @@ div {
a { a {
width: -webkit-fill-available; width: -webkit-fill-available;
width: -moz-available; width: -moz-available;
width: fill-available;
width: stretch; width: stretch;
} }
b { b {

View File

@ -59,13 +59,11 @@
.class { .class {
width: -webkit-fill-available; width: -webkit-fill-available;
width: -moz-available; width: -moz-available;
width: fill-available;
width: stretch; width: stretch;
} }
.class { .class {
width: -webkit-fill-available !important; width: -webkit-fill-available !important;
width: -moz-available !important; width: -moz-available !important;
width: fill-available !important;
width: stretch !important; width: stretch !important;
} }
.class { .class {