vendor servo commit 50bba770d6073bba6e6e219dbc3687087a864a42 draft
authorVCS Sync <vcs-sync@mozilla.com>
Mon, 09 Jan 2017 19:57:01 +0000
changeset 458349 5705140f9cfd29722f04f8e8458a9d637941afa6
parent 458348 9a98b85dd254ed49d24d0906f6aca69dc26cb736
child 458350 3743a98dd69ecfa4a052b7a4fe7a905e7a175df5
push id40933
push userbmo:slyu@mozilla.com
push dateTue, 10 Jan 2017 06:53:24 +0000
milestone53.0a1
vendor servo commit 50bba770d6073bba6e6e219dbc3687087a864a42
servo/components/script/dom/bindings/trace.rs
servo/components/script/dom/css.rs
servo/components/script/dom/cssconditionrule.rs
servo/components/script/dom/cssmediarule.rs
servo/components/script/dom/cssrule.rs
servo/components/script/dom/csssupportsrule.rs
servo/components/script/dom/mod.rs
servo/components/script/dom/webidls/CSS.webidl
servo/components/script/dom/webidls/CSSConditionRule.webidl
servo/components/script/dom/webidls/CSSMediaRule.webidl
servo/components/script/dom/webidls/CSSRule.webidl
servo/components/script/dom/webidls/CSSSupportsRule.webidl
servo/components/style/lib.rs
servo/components/style/parser.rs
servo/components/style/stylesheets.rs
servo/components/style/stylist.rs
servo/components/style/supports.rs
servo/components/url/lib.rs
servo/python/servo/testing_commands.py
servo/rust-stable-version
servo/tests/unit/style/parsing/mod.rs
servo/tests/unit/style/parsing/supports.rs
servo/tests/wpt/include_css.ini
servo/tests/wpt/metadata-css/css-conditional-3_dev/html/001.htm.ini
servo/tests/wpt/metadata-css/css-transitions-1_dev/html/changing-while-transition.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-external-supports-01.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-01.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-02.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-03.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-04.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-05.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-06.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-07.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-08.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-09.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-10.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-11.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-12.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-13.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-14.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-15.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-16.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-17.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-18.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-19.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-20.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-21.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-22.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-23.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-24.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-25.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-26.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-27.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-28.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-29.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-30.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-31.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-32.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-33.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-34.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-35.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-36.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-37.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-38.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-39.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-40.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-41.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-42.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-43.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-44.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-45.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-46.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-47.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-48.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-49.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-50.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-51.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-52.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-53.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-54.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-55.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-56.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-57.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-58.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-59.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-60.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-61.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-62.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-63.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-64.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-65.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-66.htm.ini
servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-67.htm.ini
servo/tests/wpt/metadata-css/cssom-1_dev/html/css-style-declaration-modifications.htm.ini
servo/tests/wpt/metadata-css/cssom-1_dev/html/interfaces.htm.ini
servo/tests/wpt/metadata/MANIFEST.json
servo/tests/wpt/mozilla/tests/mozilla/interfaces.html
--- a/servo/components/script/dom/bindings/trace.rs
+++ b/servo/components/script/dom/bindings/trace.rs
@@ -94,16 +94,17 @@ use style::attr::{AttrIdentifier, AttrVa
 use style::context::QuirksMode;
 use style::element_state::*;
 use style::font_face::FontFaceRule;
 use style::keyframes::Keyframe;
 use style::media_queries::MediaList;
 use style::properties::PropertyDeclarationBlock;
 use style::selector_parser::{PseudoElement, Snapshot};
 use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule, ImportRule};
+use style::stylesheets::SupportsRule;
 use style::values::specified::Length;
 use style::viewport::ViewportRule;
 use time::Duration;
 use url::Origin as UrlOrigin;
 use uuid::Uuid;
 use webrender_traits::{WebGLBufferId, WebGLError, WebGLFramebufferId, WebGLProgramId};
 use webrender_traits::{WebGLRenderbufferId, WebGLShaderId, WebGLTextureId};
 
@@ -526,16 +527,22 @@ unsafe impl JSTraceable for RwLock<Keyfr
 }
 
 unsafe impl JSTraceable for RwLock<ImportRule> {
     unsafe fn trace(&self, _trc: *mut JSTracer) {
         // Do nothing.
     }
 }
 
+unsafe impl JSTraceable for RwLock<SupportsRule> {
+    unsafe fn trace(&self, _trc: *mut JSTracer) {
+        // Do nothing.
+    }
+}
+
 unsafe impl JSTraceable for RwLock<MediaRule> {
     unsafe fn trace(&self, _trc: *mut JSTracer) {
         // Do nothing.
     }
 }
 
 unsafe impl JSTraceable for RwLock<NamespaceRule> {
     unsafe fn trace(&self, _trc: *mut JSTracer) {
--- a/servo/components/script/dom/css.rs
+++ b/servo/components/script/dom/css.rs
@@ -1,23 +1,47 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-use cssparser::serialize_identifier;
+use cssparser::{Parser, serialize_identifier};
+use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
 use dom::bindings::error::Fallible;
 use dom::bindings::reflector::Reflector;
 use dom::bindings::str::DOMString;
 use dom::window::Window;
+use style::parser::ParserContext;
+use style::supports::{Declaration, parse_condition_or_declaration};
 
 #[dom_struct]
 pub struct CSS {
     reflector_: Reflector,
 }
 
 impl CSS {
-    // http://dev.w3.org/csswg/cssom/#serialize-an-identifier
+    /// http://dev.w3.org/csswg/cssom/#serialize-an-identifier
     pub fn Escape(_: &Window, ident: DOMString) -> Fallible<DOMString> {
         let mut escaped = String::new();
         serialize_identifier(&ident, &mut escaped).unwrap();
         Ok(DOMString::from(escaped))
     }
+
+    /// https://drafts.csswg.org/css-conditional/#dom-css-supports
+    pub fn Supports(win: &Window, property: DOMString, value: DOMString) -> bool {
+        let decl = Declaration { prop: property.into(), val: value.into() };
+        let url = win.Document().url();
+        let context = ParserContext::new_for_cssom(&url);
+        decl.eval(&context)
+    }
+
+    /// https://drafts.csswg.org/css-conditional/#dom-css-supports
+    pub fn Supports_(win: &Window, condition: DOMString) -> bool {
+        let mut input = Parser::new(&condition);
+        let cond = parse_condition_or_declaration(&mut input);
+        if let Ok(cond) = cond {
+            let url = win.Document().url();
+            let context = ParserContext::new_for_cssom(&url);
+            cond.eval(&context)
+        } else {
+            false
+        }
+    }
 }
new file mode 100644
--- /dev/null
+++ b/servo/components/script/dom/cssconditionrule.rs
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use dom::bindings::codegen::Bindings::CSSConditionRuleBinding::CSSConditionRuleMethods;
+use dom::bindings::inheritance::Castable;
+use dom::bindings::str::DOMString;
+use dom::cssgroupingrule::CSSGroupingRule;
+use dom::cssmediarule::CSSMediaRule;
+use dom::cssstylesheet::CSSStyleSheet;
+use dom::csssupportsrule::CSSSupportsRule;
+use parking_lot::RwLock;
+use std::sync::Arc;
+use style::stylesheets::CssRules as StyleCssRules;
+
+#[dom_struct]
+pub struct CSSConditionRule {
+    cssgroupingrule: CSSGroupingRule,
+}
+
+impl CSSConditionRule {
+    pub fn new_inherited(parent_stylesheet: &CSSStyleSheet,
+                         rules: Arc<RwLock<StyleCssRules>>) -> CSSConditionRule {
+        CSSConditionRule {
+            cssgroupingrule: CSSGroupingRule::new_inherited(parent_stylesheet, rules),
+        }
+    }
+
+}
+
+impl CSSConditionRuleMethods for CSSConditionRule {
+    /// https://drafts.csswg.org/css-conditional-3/#dom-cssconditionrule-conditiontext
+    fn ConditionText(&self) -> DOMString {
+        if let Some(rule) = self.downcast::<CSSMediaRule>() {
+            rule.get_condition_text()
+        } else if let Some(rule) = self.downcast::<CSSSupportsRule>() {
+            rule.get_condition_text()
+        } else {
+            unreachable!()
+        }
+    }
+
+    /// https://drafts.csswg.org/css-conditional-3/#dom-cssconditionrule-conditiontext
+    fn SetConditionText(&self, text: DOMString) {
+        if let Some(rule) = self.downcast::<CSSMediaRule>() {
+            rule.set_condition_text(text)
+        } else if let Some(rule) = self.downcast::<CSSSupportsRule>() {
+            rule.set_condition_text(text)
+        } else {
+            unreachable!()
+        }
+    }
+}
--- a/servo/components/script/dom/cssmediarule.rs
+++ b/servo/components/script/dom/cssmediarule.rs
@@ -1,41 +1,43 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+use cssparser::Parser;
 use dom::bindings::codegen::Bindings::CSSMediaRuleBinding;
 use dom::bindings::codegen::Bindings::CSSMediaRuleBinding::CSSMediaRuleMethods;
 use dom::bindings::js::{MutNullableJS, Root};
 use dom::bindings::reflector::{DomObject, reflect_dom_object};
 use dom::bindings::str::DOMString;
-use dom::cssgroupingrule::CSSGroupingRule;
+use dom::cssconditionrule::CSSConditionRule;
 use dom::cssrule::SpecificCSSRule;
 use dom::cssstylesheet::CSSStyleSheet;
 use dom::medialist::MediaList;
 use dom::window::Window;
 use parking_lot::RwLock;
 use std::sync::Arc;
+use style::media_queries::parse_media_query_list;
 use style::stylesheets::MediaRule;
 use style_traits::ToCss;
 
 #[dom_struct]
 pub struct CSSMediaRule {
-    cssrule: CSSGroupingRule,
+    cssrule: CSSConditionRule,
     #[ignore_heap_size_of = "Arc"]
     mediarule: Arc<RwLock<MediaRule>>,
     medialist: MutNullableJS<MediaList>,
 }
 
 impl CSSMediaRule {
     fn new_inherited(parent_stylesheet: &CSSStyleSheet, mediarule: Arc<RwLock<MediaRule>>)
                      -> CSSMediaRule {
         let list = mediarule.read().rules.clone();
         CSSMediaRule {
-            cssrule: CSSGroupingRule::new_inherited(parent_stylesheet, list),
+            cssrule: CSSConditionRule::new_inherited(parent_stylesheet, list),
             mediarule: mediarule,
             medialist: MutNullableJS::new(None),
         }
     }
 
     #[allow(unrooted_must_root)]
     pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet,
                mediarule: Arc<RwLock<MediaRule>>) -> Root<CSSMediaRule> {
@@ -43,16 +45,32 @@ impl CSSMediaRule {
                            window,
                            CSSMediaRuleBinding::Wrap)
     }
 
     fn medialist(&self) -> Root<MediaList> {
         self.medialist.or_init(|| MediaList::new(self.global().as_window(),
                                                  self.mediarule.read().media_queries.clone()))
     }
+
+    /// https://drafts.csswg.org/css-conditional-3/#the-cssmediarule-interface
+    pub fn get_condition_text(&self) -> DOMString {
+        let rule = self.mediarule.read();
+        let list = rule.media_queries.read();
+        list.to_css_string().into()
+    }
+
+    /// https://drafts.csswg.org/css-conditional-3/#the-cssmediarule-interface
+    pub fn set_condition_text(&self, text: DOMString) {
+        let mut input = Parser::new(&text);
+        let new_medialist = parse_media_query_list(&mut input);
+        let rule = self.mediarule.read();
+        let mut list = rule.media_queries.write();
+        *list = new_medialist;
+    }
 }
 
 impl SpecificCSSRule for CSSMediaRule {
     fn ty(&self) -> u16 {
         use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
         CSSRuleConstants::MEDIA_RULE
     }
 
--- a/servo/components/script/dom/cssrule.rs
+++ b/servo/components/script/dom/cssrule.rs
@@ -10,16 +10,17 @@ use dom::bindings::str::DOMString;
 use dom::cssfontfacerule::CSSFontFaceRule;
 use dom::cssimportrule::CSSImportRule;
 use dom::csskeyframerule::CSSKeyframeRule;
 use dom::csskeyframesrule::CSSKeyframesRule;
 use dom::cssmediarule::CSSMediaRule;
 use dom::cssnamespacerule::CSSNamespaceRule;
 use dom::cssstylerule::CSSStyleRule;
 use dom::cssstylesheet::CSSStyleSheet;
+use dom::csssupportsrule::CSSSupportsRule;
 use dom::cssviewportrule::CSSViewportRule;
 use dom::window::Window;
 use std::cell::Cell;
 use style::stylesheets::CssRule as StyleCssRule;
 
 
 #[dom_struct]
 pub struct CSSRule {
@@ -54,16 +55,18 @@ impl CSSRule {
         } else if let Some(rule) = self.downcast::<CSSNamespaceRule>() {
             rule as &SpecificCSSRule
         } else if let Some(rule) = self.downcast::<CSSViewportRule>() {
             rule as &SpecificCSSRule
         } else if let Some(rule) = self.downcast::<CSSKeyframeRule>() {
             rule as &SpecificCSSRule
         } else if let Some(rule) = self.downcast::<CSSImportRule>() {
             rule as &SpecificCSSRule
+        } else if let Some(rule) = self.downcast::<CSSSupportsRule>() {
+            rule as &SpecificCSSRule
         } else {
             unreachable!()
         }
     }
 
     // Given a StyleCssRule, create a new instance of a derived class of
     // CSSRule based on which rule it is
     pub fn new_specific(window: &Window, parent_stylesheet: &CSSStyleSheet,
@@ -72,16 +75,17 @@ impl CSSRule {
         match rule {
             StyleCssRule::Import(s) => Root::upcast(CSSImportRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Style(s) => Root::upcast(CSSStyleRule::new(window, parent_stylesheet, s)),
             StyleCssRule::FontFace(s) => Root::upcast(CSSFontFaceRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Keyframes(s) => Root::upcast(CSSKeyframesRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Media(s) => Root::upcast(CSSMediaRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Namespace(s) => Root::upcast(CSSNamespaceRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::new(window, parent_stylesheet, s)),
+            StyleCssRule::Supports(s) => Root::upcast(CSSSupportsRule::new(window, parent_stylesheet, s)),
         }
     }
 
     /// Sets owner sheet/rule to null
     pub fn detach(&self) {
         self.deparent();
         // should set parent rule to None when we add parent rule support
     }
new file mode 100644
--- /dev/null
+++ b/servo/components/script/dom/csssupportsrule.rs
@@ -0,0 +1,77 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use cssparser::Parser;
+use dom::bindings::codegen::Bindings::CSSSupportsRuleBinding;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
+use dom::bindings::js::Root;
+use dom::bindings::reflector::{DomObject, reflect_dom_object};
+use dom::bindings::str::DOMString;
+use dom::cssconditionrule::CSSConditionRule;
+use dom::cssrule::SpecificCSSRule;
+use dom::cssstylesheet::CSSStyleSheet;
+use dom::window::Window;
+use parking_lot::RwLock;
+use std::sync::Arc;
+use style::parser::ParserContext;
+use style::stylesheets::SupportsRule;
+use style::supports::SupportsCondition;
+use style_traits::ToCss;
+
+#[dom_struct]
+pub struct CSSSupportsRule {
+    cssrule: CSSConditionRule,
+    #[ignore_heap_size_of = "Arc"]
+    supportsrule: Arc<RwLock<SupportsRule>>,
+}
+
+impl CSSSupportsRule {
+    fn new_inherited(parent_stylesheet: &CSSStyleSheet, supportsrule: Arc<RwLock<SupportsRule>>)
+                     -> CSSSupportsRule {
+        let list = supportsrule.read().rules.clone();
+        CSSSupportsRule {
+            cssrule: CSSConditionRule::new_inherited(parent_stylesheet, list),
+            supportsrule: supportsrule,
+        }
+    }
+
+    #[allow(unrooted_must_root)]
+    pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet,
+               supportsrule: Arc<RwLock<SupportsRule>>) -> Root<CSSSupportsRule> {
+        reflect_dom_object(box CSSSupportsRule::new_inherited(parent_stylesheet, supportsrule),
+                           window,
+                           CSSSupportsRuleBinding::Wrap)
+    }
+
+    /// https://drafts.csswg.org/css-conditional-3/#the-csssupportsrule-interface
+    pub fn get_condition_text(&self) -> DOMString {
+        let rule = self.supportsrule.read();
+        rule.condition.to_css_string().into()
+    }
+
+    /// https://drafts.csswg.org/css-conditional-3/#the-csssupportsrule-interface
+    pub fn set_condition_text(&self, text: DOMString) {
+        let mut input = Parser::new(&text);
+        let cond = SupportsCondition::parse(&mut input);
+        if let Ok(cond) = cond {
+            let url = self.global().as_window().Document().url();
+            let context = ParserContext::new_for_cssom(&url);
+            let enabled = cond.eval(&context);
+            let mut rule = self.supportsrule.write();
+            rule.condition = cond;
+            rule.enabled = enabled;
+        }
+    }
+}
+
+impl SpecificCSSRule for CSSSupportsRule {
+    fn ty(&self) -> u16 {
+        use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
+        CSSRuleConstants::SUPPORTS_RULE
+    }
+
+    fn get_css(&self) -> DOMString {
+        self.supportsrule.read().to_css_string().into()
+    }
+}
--- a/servo/components/script/dom/mod.rs
+++ b/servo/components/script/dom/mod.rs
@@ -235,28 +235,30 @@ pub mod canvasrenderingcontext2d;
 pub mod characterdata;
 pub mod client;
 pub mod closeevent;
 pub mod comment;
 pub mod console;
 mod create;
 pub mod crypto;
 pub mod css;
+pub mod cssconditionrule;
 pub mod cssfontfacerule;
 pub mod cssgroupingrule;
 pub mod cssimportrule;
 pub mod csskeyframerule;
 pub mod csskeyframesrule;
 pub mod cssmediarule;
 pub mod cssnamespacerule;
 pub mod cssrule;
 pub mod cssrulelist;
 pub mod cssstyledeclaration;
 pub mod cssstylerule;
 pub mod cssstylesheet;
+pub mod csssupportsrule;
 pub mod cssviewportrule;
 pub mod customevent;
 pub mod dedicatedworkerglobalscope;
 pub mod document;
 pub mod documentfragment;
 pub mod documenttype;
 pub mod domexception;
 pub mod domimplementation;
--- a/servo/components/script/dom/webidls/CSS.webidl
+++ b/servo/components/script/dom/webidls/CSS.webidl
@@ -6,8 +6,14 @@
  * http://dev.w3.org/csswg/cssom/#the-css-interface
  */
 
 [Abstract, Exposed=Window]
 interface CSS {
   [Throws]
   static DOMString escape(DOMString ident);
 };
+
+// https://drafts.csswg.org/css-conditional-3/#the-css-interface
+partial interface CSS {
+  static boolean supports(DOMString property, DOMString value);
+  static boolean supports(DOMString conditionText);
+};
new file mode 100644
--- /dev/null
+++ b/servo/components/script/dom/webidls/CSSConditionRule.webidl
@@ -0,0 +1,9 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// https://drafts.csswg.org/css-conditional/#cssconditionrule
+[Abstract, Exposed=Window]
+interface CSSConditionRule : CSSGroupingRule {
+    attribute DOMString conditionText;
+};
--- a/servo/components/script/dom/webidls/CSSMediaRule.webidl
+++ b/servo/components/script/dom/webidls/CSSMediaRule.webidl
@@ -1,9 +1,10 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // https://drafts.csswg.org/cssom/#the-cssmediarule-interface
+// https://drafts.csswg.org/css-conditional/#cssmediarule
 [Exposed=Window]
-interface CSSMediaRule : CSSGroupingRule {
+interface CSSMediaRule : CSSConditionRule {
   [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
 };
--- a/servo/components/script/dom/webidls/CSSRule.webidl
+++ b/servo/components/script/dom/webidls/CSSRule.webidl
@@ -26,8 +26,12 @@ partial interface CSSRule {
     const unsigned short KEYFRAME_RULE = 8;
 };
 
 // https://drafts.csswg.org/css-device-adapt/#css-rule-interface
 partial interface CSSRule {
     const unsigned short VIEWPORT_RULE = 15;
 };
 
+// https://drafts.csswg.org/css-conditional-3/#extentions-to-cssrule-interface
+partial interface CSSRule {
+    const unsigned short SUPPORTS_RULE = 12;
+};
new file mode 100644
--- /dev/null
+++ b/servo/components/script/dom/webidls/CSSSupportsRule.webidl
@@ -0,0 +1,8 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// https://drafts.csswg.org/css-conditional/#csssupportsrule
+[Exposed=Window]
+interface CSSSupportsRule : CSSConditionRule {
+};
--- a/servo/components/style/lib.rs
+++ b/servo/components/style/lib.rs
@@ -117,16 +117,17 @@ pub mod rule_tree;
 pub mod scoped_tls;
 pub mod selector_parser;
 pub mod stylist;
 #[cfg(feature = "servo")] #[allow(unsafe_code)] pub mod servo;
 pub mod sequential;
 pub mod sink;
 pub mod str;
 pub mod stylesheets;
+pub mod supports;
 pub mod thread_state;
 pub mod timer;
 pub mod traversal;
 #[macro_use]
 #[allow(non_camel_case_types)]
 pub mod values;
 pub mod viewport;
 
--- a/servo/components/style/parser.rs
+++ b/servo/components/style/parser.rs
@@ -6,17 +6,17 @@
 
 #![deny(missing_docs)]
 
 use cssparser::{Parser, SourcePosition};
 use error_reporting::ParseErrorReporter;
 #[cfg(feature = "gecko")]
 use gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
 use servo_url::ServoUrl;
-use stylesheets::Origin;
+use stylesheets::{MemoryHoleReporter, Origin};
 
 /// Extra data that the style backend may need to parse stylesheets.
 #[cfg(not(feature = "gecko"))]
 pub struct ParserContextExtraData;
 
 /// Extra data that the style backend may need to parse stylesheets.
 #[cfg(feature = "gecko")]
 pub struct ParserContextExtraData {
@@ -73,16 +73,21 @@ impl<'a> ParserContext<'a> {
     /// Create a parser context with the default extra data.
     pub fn new(stylesheet_origin: Origin,
                base_url: &'a ServoUrl,
                error_reporter: Box<ParseErrorReporter + Send>)
                -> ParserContext<'a> {
         let extra_data = ParserContextExtraData::default();
         Self::new_with_extra_data(stylesheet_origin, base_url, error_reporter, extra_data)
     }
+
+    /// Create a parser context for on-the-fly parsing in CSSOM
+    pub fn new_for_cssom(base_url: &'a ServoUrl) -> ParserContext<'a> {
+        Self::new(Origin::User, base_url, Box::new(MemoryHoleReporter))
+    }
 }
 
 /// Defaults to a no-op.
 /// Set a `RUST_LOG=style::errors` environment variable
 /// to log CSS parse errors to stderr.
 pub fn log_css_error(input: &mut Parser, position: SourcePosition, message: &str, parsercontext: &ParserContext) {
     parsercontext.error_reporter.report_error(input, position, message);
 }
--- a/servo/components/style/stylesheets.rs
+++ b/servo/components/style/stylesheets.rs
@@ -23,16 +23,17 @@ use selectors::parser::SelectorList;
 use servo_config::prefs::PREFS;
 use servo_url::ServoUrl;
 use std::cell::Cell;
 use std::fmt;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicBool, Ordering};
 use style_traits::ToCss;
 use stylist::FnvHashMap;
+use supports::SupportsCondition;
 use values::specified::url::SpecifiedUrl;
 use viewport::ViewportRule;
 
 
 /// Each style rule has an origin, which determines where it enters the cascade.
 ///
 /// http://dev.w3.org/csswg/css-cascade/#cascading-origins
 #[derive(Clone, PartialEq, Eq, Copy, Debug)]
@@ -210,16 +211,17 @@ pub enum CssRule {
 
     Namespace(Arc<RwLock<NamespaceRule>>),
     Import(Arc<RwLock<ImportRule>>),
     Style(Arc<RwLock<StyleRule>>),
     Media(Arc<RwLock<MediaRule>>),
     FontFace(Arc<RwLock<FontFaceRule>>),
     Viewport(Arc<RwLock<ViewportRule>>),
     Keyframes(Arc<RwLock<KeyframesRule>>),
+    Supports(Arc<RwLock<SupportsRule>>),
 }
 
 #[allow(missing_docs)]
 pub enum CssRuleType {
     // https://drafts.csswg.org/cssom/#the-cssrule-interface
     Style               = 1,
     Charset             = 2,
     Import              = 3,
@@ -269,35 +271,37 @@ impl CssRule {
         match *self {
             CssRule::Style(_)     => CssRuleType::Style,
             CssRule::Import(_)    => CssRuleType::Import,
             CssRule::Media(_)     => CssRuleType::Media,
             CssRule::FontFace(_)  => CssRuleType::FontFace,
             CssRule::Keyframes(_) => CssRuleType::Keyframes,
             CssRule::Namespace(_) => CssRuleType::Namespace,
             CssRule::Viewport(_)  => CssRuleType::Viewport,
+            CssRule::Supports(_)  => CssRuleType::Supports,
         }
     }
 
     fn rule_state(&self) -> State {
         match *self {
             // CssRule::Charset(..) => State::Start,
             CssRule::Import(..) => State::Imports,
             CssRule::Namespace(..) => State::Namespaces,
             _ => State::Body,
         }
     }
 
     /// Call `f` with the slice of rules directly contained inside this rule.
     ///
     /// Note that only some types of rules can contain rules. An empty slice is
     /// used for others.
+    ///
+    /// This will not recurse down unsupported @supports rules
     pub fn with_nested_rules_and_mq<F, R>(&self, mut f: F) -> R
-        where F: FnMut(&[CssRule], Option<&MediaList>) -> R
-    {
+    where F: FnMut(&[CssRule], Option<&MediaList>) -> R {
         match *self {
             CssRule::Import(ref lock) => {
                 let rule = lock.read();
                 let media = rule.stylesheet.media.read();
                 let rules = rule.stylesheet.rules.read();
                 // FIXME(emilio): Include the nested rules if the stylesheet is
                 // loaded.
                 f(&rules.0, Some(&media))
@@ -310,16 +314,26 @@ impl CssRule {
                 f(&[], None)
             }
             CssRule::Media(ref lock) => {
                 let media_rule = lock.read();
                 let mq = media_rule.media_queries.read();
                 let rules = &media_rule.rules.read().0;
                 f(rules, Some(&mq))
             }
+            CssRule::Supports(ref lock) => {
+                let supports_rule = lock.read();
+                let enabled = supports_rule.enabled;
+                if enabled {
+                    let rules = &supports_rule.rules.read().0;
+                    f(rules, None)
+                } else {
+                    f(&[], None)
+                }
+            }
         }
     }
 
     // input state is None for a nested rule
     // Returns a parsed CSS rule and the final state of the parser
     #[allow(missing_docs)]
     pub fn parse(css: &str,
                  parent_stylesheet: &Stylesheet,
@@ -362,16 +376,17 @@ impl ToCss for CssRule {
         match *self {
             CssRule::Namespace(ref lock) => lock.read().to_css(dest),
             CssRule::Import(ref lock) => lock.read().to_css(dest),
             CssRule::Style(ref lock) => lock.read().to_css(dest),
             CssRule::FontFace(ref lock) => lock.read().to_css(dest),
             CssRule::Viewport(ref lock) => lock.read().to_css(dest),
             CssRule::Keyframes(ref lock) => lock.read().to_css(dest),
             CssRule::Media(ref lock) => lock.read().to_css(dest),
+            CssRule::Supports(ref lock) => lock.read().to_css(dest),
         }
     }
 }
 
 #[derive(Debug, PartialEq)]
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 #[allow(missing_docs)]
 pub struct NamespaceRule {
@@ -436,17 +451,22 @@ pub struct KeyframesRule {
 
 impl ToCss for KeyframesRule {
     // Serialization of KeyframesRule is not specced.
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
         try!(dest.write_str("@keyframes "));
         try!(dest.write_str(&*self.name.to_string()));
         try!(dest.write_str(" { "));
         let iter = self.keyframes.iter();
+        let mut first = true;
         for lock in iter {
+            if !first {
+                try!(dest.write_str(" "));
+            }
+            first = false;
             let keyframe = lock.read();
             try!(keyframe.to_css(dest));
         }
         dest.write_str(" }")
     }
 }
 
 #[allow(missing_docs)]
@@ -455,19 +475,44 @@ pub struct MediaRule {
     pub media_queries: Arc<RwLock<MediaList>>,
     pub rules: Arc<RwLock<CssRules>>,
 }
 
 impl ToCss for MediaRule {
     // Serialization of MediaRule is not specced.
     // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSMediaRule
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-        try!(dest.write_str("@media ("));
+        try!(dest.write_str("@media "));
         try!(self.media_queries.read().to_css(dest));
-        try!(dest.write_str(") {"));
+        try!(dest.write_str(" {"));
+        for rule in self.rules.read().0.iter() {
+            try!(dest.write_str(" "));
+            try!(rule.to_css(dest));
+        }
+        dest.write_str(" }")
+    }
+}
+
+
+#[derive(Debug)]
+/// An @supports rule
+pub struct SupportsRule {
+    /// The parsed condition
+    pub condition: SupportsCondition,
+    /// Child rules
+    pub rules: Arc<RwLock<CssRules>>,
+    /// The result of evaluating the condition
+    pub enabled: bool,
+}
+
+impl ToCss for SupportsRule {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        try!(dest.write_str("@supports "));
+        try!(self.condition.to_css(dest));
+        try!(dest.write_str(" {"));
         for rule in self.rules.read().0.iter() {
             try!(dest.write_str(" "));
             try!(rule.to_css(dest));
         }
         dest.write_str(" }")
     }
 }
 
@@ -707,16 +752,17 @@ macro_rules! rule_filter {
 }
 
 rule_filter! {
     effective_style_rules(Style => StyleRule),
     effective_media_rules(Media => MediaRule),
     effective_font_face_rules(FontFace => FontFaceRule),
     effective_viewport_rules(Viewport => ViewportRule),
     effective_keyframes_rules(Keyframes => KeyframesRule),
+    effective_supports_rules(Supports => SupportsRule),
 }
 
 /// The stylesheet loader is the abstraction used to trigger network requests
 /// for `@import` rules.
 pub trait StylesheetLoader {
     /// Request a stylesheet after parsing a given `@import` rule.
     ///
     /// The called code is responsible to update the `stylesheet` rules field
@@ -753,16 +799,18 @@ pub enum State {
 }
 
 
 enum AtRulePrelude {
     /// A @font-face rule prelude.
     FontFace,
     /// A @media rule prelude, with its media queries.
     Media(Arc<RwLock<MediaList>>),
+    /// An @supports rule, with its conditional
+    Supports(SupportsCondition),
     /// A @viewport rule prelude.
     Viewport,
     /// A @keyframes rule, with its animation name.
     Keyframes(Atom),
 }
 
 
 impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
@@ -908,16 +956,20 @@ impl<'a, 'b> AtRuleParser for NestedRule
 
     fn parse_prelude(&mut self, name: &str, input: &mut Parser)
                      -> Result<AtRuleType<AtRulePrelude, CssRule>, ()> {
         match_ignore_ascii_case! { name,
             "media" => {
                 let media_queries = parse_media_query_list(input);
                 Ok(AtRuleType::WithBlock(AtRulePrelude::Media(Arc::new(RwLock::new(media_queries)))))
             },
+            "supports" => {
+                let cond = SupportsCondition::parse(input)?;
+                Ok(AtRuleType::WithBlock(AtRulePrelude::Supports(cond)))
+            },
             "font-face" => {
                 Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace))
             },
             "viewport" => {
                 if PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) ||
                    cfg!(feature = "gecko") {
                     Ok(AtRuleType::WithBlock(AtRulePrelude::Viewport))
                 } else {
@@ -944,16 +996,24 @@ impl<'a, 'b> AtRuleParser for NestedRule
                     try!(parse_font_face_block(self.context, input))))))
             }
             AtRulePrelude::Media(media_queries) => {
                 Ok(CssRule::Media(Arc::new(RwLock::new(MediaRule {
                     media_queries: media_queries,
                     rules: self.parse_nested_rules(input),
                 }))))
             }
+            AtRulePrelude::Supports(cond) => {
+                let enabled = cond.eval(self.context);
+                Ok(CssRule::Supports(Arc::new(RwLock::new(SupportsRule {
+                    condition: cond,
+                    rules: self.parse_nested_rules(input),
+                    enabled: enabled,
+                }))))
+            }
             AtRulePrelude::Viewport => {
                 Ok(CssRule::Viewport(Arc::new(RwLock::new(
                     try!(ViewportRule::parse(input, self.context))))))
             }
             AtRulePrelude::Keyframes(name) => {
                 Ok(CssRule::Keyframes(Arc::new(RwLock::new(KeyframesRule {
                     name: name,
                     keyframes: parse_keyframe_list(&self.context, input),
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -403,24 +403,25 @@ impl Stylist {
             ViewportConstraints::maybe_new(&device, &cascaded_rule);
 
         if let Some(ref constraints) = self.viewport_constraints {
             device.account_for_viewport_rule(constraints);
         }
 
         fn mq_eval_changed(rules: &[CssRule], before: &Device, after: &Device) -> bool {
             for rule in rules {
-                if rule.with_nested_rules_and_mq(|rules, mq| {
+                let changed = rule.with_nested_rules_and_mq(|rules, mq| {
                     if let Some(mq) = mq {
                         if mq.evaluate(before) != mq.evaluate(after) {
                             return true
                         }
                     }
                     mq_eval_changed(rules, before, after)
-                }) {
+                });
+                if changed {
                     return true
                 }
             }
             false
         }
         self.is_device_dirty |= stylesheets.iter().any(|stylesheet| {
             mq_eval_changed(&stylesheet.rules.read().0, &self.device, &device)
         });
new file mode 100644
--- /dev/null
+++ b/servo/components/style/supports.rs
@@ -0,0 +1,231 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//! [@supports rules](https://drafts.csswg.org/css-conditional-3/#at-supports)
+
+use cssparser::{parse_important, Parser, Token};
+use parser::ParserContext;
+use properties::{PropertyDeclaration, PropertyId};
+use std::fmt;
+use style_traits::ToCss;
+
+#[derive(Debug)]
+/// An @supports condition
+///
+/// https://drafts.csswg.org/css-conditional-3/#at-supports
+pub enum SupportsCondition {
+    /// `not (condition)`
+    Not(Box<SupportsCondition>),
+    /// `(condition)`
+    Parenthesized(Box<SupportsCondition>),
+    /// `(condition) and (condition) and (condition) ..`
+    And(Vec<SupportsCondition>),
+    /// `(condition) or (condition) or (condition) ..`
+    Or(Vec<SupportsCondition>),
+    /// `property-ident: value` (value can be any tokens)
+    Declaration(Declaration),
+    /// `(any tokens)` or `func(any tokens)`
+    FutureSyntax(String),
+}
+
+impl SupportsCondition {
+    /// Parse a condition
+    ///
+    /// https://drafts.csswg.org/css-conditional/#supports_condition
+    pub fn parse(input: &mut Parser) -> Result<SupportsCondition, ()> {
+        if let Ok(_) = input.try(|i| i.expect_ident_matching("not")) {
+            let inner = SupportsCondition::parse_in_parens(input)?;
+            return Ok(SupportsCondition::Not(Box::new(inner)));
+        }
+
+        let in_parens = SupportsCondition::parse_in_parens(input)?;
+
+        let (keyword, wrapper) = match input.next() {
+            Err(()) => {
+                // End of input
+                return Ok(in_parens)
+            }
+            Ok(Token::Ident(ident)) => {
+                match_ignore_ascii_case! { ident,
+                    "and" => ("and", SupportsCondition::And as fn(_) -> _),
+                    "or" => ("or", SupportsCondition::Or as fn(_) -> _),
+                    _ => return Err(())
+                }
+            }
+            _ => return Err(())
+        };
+
+        let mut conditions = Vec::with_capacity(2);
+        conditions.push(in_parens);
+        loop {
+            conditions.push(SupportsCondition::parse_in_parens(input)?);
+            if input.try(|input| input.expect_ident_matching(keyword)).is_err() {
+                // Did not find the expected keyword.
+                // If we found some other token,
+                // it will be rejected by `Parser::parse_entirely` somewhere up the stack.
+                return Ok(wrapper(conditions))
+            }
+        }
+    }
+
+    /// https://drafts.csswg.org/css-conditional-3/#supports_condition_in_parens
+    fn parse_in_parens(input: &mut Parser) -> Result<SupportsCondition, ()> {
+        // Whitespace is normally taken care of in `Parser::next`,
+        // but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases.
+        while input.try(Parser::expect_whitespace).is_ok() {}
+        let pos = input.position();
+        match input.next()? {
+            Token::ParenthesisBlock => {
+                input.parse_nested_block(|input| {
+                    // `input.try()` not needed here since the alternative uses `consume_all()`.
+                    parse_condition_or_declaration(input).or_else(|()| {
+                        consume_all(input);
+                        Ok(SupportsCondition::FutureSyntax(input.slice_from(pos).to_owned()))
+                    })
+                })
+            }
+            Token::Function(_) => {
+                input.parse_nested_block(|i| Ok(consume_all(i))).unwrap();
+                Ok(SupportsCondition::FutureSyntax(input.slice_from(pos).to_owned()))
+            }
+            _ => Err(())
+        }
+    }
+
+    /// Evaluate a supports condition
+    pub fn eval(&self, cx: &ParserContext) -> bool {
+        match *self {
+            SupportsCondition::Not(ref cond) => !cond.eval(cx),
+            SupportsCondition::Parenthesized(ref cond) => cond.eval(cx),
+            SupportsCondition::And(ref vec) => vec.iter().all(|c| c.eval(cx)),
+            SupportsCondition::Or(ref vec) => vec.iter().any(|c| c.eval(cx)),
+            SupportsCondition::Declaration(ref decl) => decl.eval(cx),
+            SupportsCondition::FutureSyntax(_) => false
+        }
+    }
+}
+
+/// supports_condition | declaration
+/// https://drafts.csswg.org/css-conditional/#dom-css-supports-conditiontext-conditiontext
+pub fn parse_condition_or_declaration(input: &mut Parser) -> Result<SupportsCondition, ()> {
+    if let Ok(condition) = input.try(SupportsCondition::parse) {
+        Ok(SupportsCondition::Parenthesized(Box::new(condition)))
+    } else {
+        Declaration::parse(input).map(SupportsCondition::Declaration)
+    }
+}
+
+impl ToCss for SupportsCondition {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+        where W: fmt::Write {
+        match *self {
+            SupportsCondition::Not(ref cond) => {
+                dest.write_str("not ")?;
+                cond.to_css(dest)
+            }
+            SupportsCondition::Parenthesized(ref cond) => {
+                dest.write_str("(")?;
+                cond.to_css(dest)?;
+                dest.write_str(")")
+            }
+            SupportsCondition::And(ref vec) => {
+                let mut first = true;
+                for cond in vec {
+                    if !first {
+                        dest.write_str(" and ")?;
+                    }
+                    first = false;
+                    cond.to_css(dest)?;
+                }
+                Ok(())
+            }
+            SupportsCondition::Or(ref vec) => {
+                let mut first = true;
+                for cond in vec {
+                    if !first {
+                        dest.write_str(" or ")?;
+                    }
+                    first = false;
+                    cond.to_css(dest)?;
+                }
+                Ok(())
+            }
+            SupportsCondition::Declaration(ref decl) => {
+                dest.write_str("(")?;
+                decl.to_css(dest)?;
+                dest.write_str(")")
+            }
+            SupportsCondition::FutureSyntax(ref s) => dest.write_str(&s),
+        }
+    }
+}
+
+#[derive(Debug)]
+/// A possibly-invalid property declaration
+pub struct Declaration {
+    /// The property name
+    pub prop: String,
+    /// The property value
+    pub val: String,
+}
+
+impl ToCss for Declaration {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+        where W: fmt::Write {
+        dest.write_str(&self.prop)?;
+        dest.write_str(":")?;
+        // no space, the `val` already contains any possible spaces
+        dest.write_str(&self.val)
+    }
+}
+
+/// Slurps up input till exhausted, return string from source position
+fn parse_anything(input: &mut Parser) -> String {
+    let pos = input.position();
+    consume_all(input);
+    input.slice_from(pos).to_owned()
+}
+
+/// consume input till done
+fn consume_all(input: &mut Parser) {
+    while let Ok(_) = input.next() {}
+}
+
+impl Declaration {
+    /// Parse a declaration
+    pub fn parse(input: &mut Parser) -> Result<Declaration, ()> {
+        let prop = input.expect_ident()?.into_owned();
+        input.expect_colon()?;
+        let val = parse_anything(input);
+        Ok(Declaration { prop: prop, val: val })
+    }
+
+    /// Determine if a declaration parses
+    ///
+    /// https://drafts.csswg.org/css-conditional-3/#support-definition
+    pub fn eval(&self, cx: &ParserContext) -> bool {
+        use properties::PropertyDeclarationParseResult::*;
+        let id = if let Ok(id) = PropertyId::parse((&*self.prop).into()) {
+            id
+        } else {
+            return false
+        };
+        let mut input = Parser::new(&self.val);
+        let mut list = Vec::new();
+        let res = PropertyDeclaration::parse(id, cx, &mut input,
+                                             &mut list, /* in_keyframe */ false);
+        let _ = input.try(parse_important);
+        if !input.is_exhausted() {
+            return false;
+        }
+        match res {
+            UnknownProperty => false,
+            ExperimentalProperty => false, // only happens for experimental props
+                                           // that haven't been enabled
+            InvalidValue => false,
+            AnimationPropertyInKeyframeBlock => unreachable!(),
+            ValidOrIgnoredDeclaration => true,
+        }
+    }
+}
--- a/servo/components/url/lib.rs
+++ b/servo/components/url/lib.rs
@@ -180,8 +180,14 @@ impl Index<RangeTo<Position>> for ServoU
 }
 
 impl Index<Range<Position>> for ServoUrl {
     type Output = str;
     fn index(&self, range: Range<Position>) -> &str {
         &self.0[range]
     }
 }
+
+impl From<Url> for ServoUrl {
+    fn from(url: Url) -> Self {
+        ServoUrl::from_url(url)
+    }
+}
--- a/servo/python/servo/testing_commands.py
+++ b/servo/python/servo/testing_commands.py
@@ -271,16 +271,21 @@ class MachCommands(CommandBase):
 
         # Run style tests with the testing feature
         if has_style:
             args = ["cargo", "bench" if bench else "test", "-p", "style_tests", "--features"]
             if features:
                 args += ["%s" % ' '.join(features + ["testing"])]
             else:
                 args += ["testing"]
+
+            args += test_patterns
+
+            if nocapture:
+                args += ["--", "--nocapture"]
             return call(args, env=env, cwd=self.servo_crate())
 
     @Command('test-stylo',
              description='Run stylo unit tests',
              category='testing')
     @CommandArgument('--release', default=False, action="store_true",
                      help="Run with a release build of servo")
     def test_stylo(self, release=False):
--- a/servo/rust-stable-version
+++ b/servo/rust-stable-version
@@ -1,1 +1,1 @@
-1.12.0
+1.13.0
--- a/servo/tests/unit/style/parsing/mod.rs
+++ b/servo/tests/unit/style/parsing/mod.rs
@@ -34,16 +34,35 @@ macro_rules! assert_roundtrip_with_conte
         let mut parser = Parser::new(&serialized);
         let re_parsed = $fun(&context, &mut parser)
                         .expect(&format!("Failed to parse serialization {}", $input));
         let re_serialized = ToCss::to_css_string(&re_parsed);
         assert_eq!(serialized, re_serialized);
     }
 }
 
+macro_rules! assert_roundtrip {
+    ($fun:expr, $string:expr) => {
+        assert_roundtrip!($fun, $string, $string);
+    };
+    ($fun:expr,$input:expr, $output:expr) => {
+        let mut parser = Parser::new($input);
+        let parsed = $fun(&mut parser)
+                     .expect(&format!("Failed to parse {}", $input));
+        let serialized = ToCss::to_css_string(&parsed);
+        assert_eq!(serialized, $output);
+
+        let mut parser = Parser::new(&serialized);
+        let re_parsed = $fun(&mut parser)
+                        .expect(&format!("Failed to parse serialization {}", $input));
+        let re_serialized = ToCss::to_css_string(&re_parsed);
+        assert_eq!(serialized, re_serialized);
+    }
+}
+
 macro_rules! parse_longhand {
     ($name:ident, $s:expr) => {{
         let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
         let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest));
         $name::parse(&context, &mut Parser::new($s)).unwrap()
     }};
 }
 
@@ -53,8 +72,9 @@ mod basic_shape;
 mod border;
 mod font;
 mod image;
 mod inherited_box;
 mod inherited_text;
 mod mask;
 mod position;
 mod selectors;
+mod supports;
new file mode 100644
--- /dev/null
+++ b/servo/tests/unit/style/parsing/supports.rs
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use cssparser::Parser;
+use style::supports::SupportsCondition;
+use style_traits::ToCss;
+
+#[test]
+fn test_supports_condition() {
+    assert_roundtrip!(SupportsCondition::parse, "(margin: 1px)");
+    assert_roundtrip!(SupportsCondition::parse, "not (--be: to be)");
+    assert_roundtrip!(SupportsCondition::parse, "(color: blue) and future-extension(4)");
+}
--- a/servo/tests/wpt/include_css.ini
+++ b/servo/tests/wpt/include_css.ini
@@ -16,16 +16,23 @@ skip: true
 
 [css-color-3_dev]
   skip: false
   [xhtml1]
     skip: true
   [xhtml1print]
     skip: true
 
+[css-conditional-3_dev]
+  skip: false
+  [xhtml1]
+    skip: true
+  [xhtml1print]
+    skip: true
+
 [css-flexbox-1_dev]
   skip: false
   [xhtml1]
     skip: true
   [xhtml1print]
     skip: true
 
 [css-multicol-1_dev]
new file mode 100644
--- /dev/null
+++ b/servo/tests/wpt/metadata-css/css-conditional-3_dev/html/001.htm.ini
@@ -0,0 +1,8 @@
+[001.htm]
+  type: testharness
+  [Inserting @font-face inside @supports works]
+    expected: FAIL
+
+  [Inserting an @supports inside a style rule should fail]
+    expected: FAIL
+
--- a/servo/tests/wpt/metadata-css/css-transitions-1_dev/html/changing-while-transition.htm.ini
+++ b/servo/tests/wpt/metadata-css/css-transitions-1_dev/html/changing-while-transition.htm.ini
@@ -1,4 +1,5 @@
 [changing-while-transition.htm]
   type: testharness
   [changing transition-property / values]
     expected: FAIL
+
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-external-supports-01.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-external-supports-01.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-01.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-01.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-02.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-02.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-03.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-03.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-04.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-04.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-05.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-05.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-06.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-06.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-07.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-07.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-08.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-08.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-09.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-09.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-10.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-10.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-11.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-11.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-12.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-12.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-13.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-13.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-14.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-14.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-15.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-15.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-16.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-16.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-17.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-17.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-18.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-18.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-19.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-19.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-20.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-20.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-21.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-21.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-22.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-22.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-23.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-23.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-24.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-24.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-25.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-25.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-26.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-26.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-27.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-27.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-28.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-28.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-29.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-29.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-30.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-30.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-31.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-31.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-32.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-32.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-33.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-33.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-34.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-34.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-35.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-35.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-36.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-36.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-37.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-37.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-38.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-38.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-39.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-39.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-40.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-40.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-41.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-41.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-42.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-42.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-43.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-43.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-44.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-44.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-45.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-45.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-46.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-46.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-47.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-47.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-48.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-48.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-49.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-49.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-50.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-50.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-51.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-51.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-52.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-52.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-53.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-53.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-54.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-54.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-55.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-55.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-56.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-56.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-57.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-57.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-58.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-58.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-59.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-59.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-60.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-60.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-61.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-61.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-62.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-62.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-63.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-63.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-64.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-64.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-65.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-65.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-66.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-66.htm]
-  type: reftest
-  expected: FAIL
deleted file mode 100644
--- a/servo/tests/wpt/metadata-css/css-variables-1_dev/html/variable-supports-67.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[variable-supports-67.htm]
-  type: reftest
-  expected: FAIL
--- a/servo/tests/wpt/metadata-css/cssom-1_dev/html/css-style-declaration-modifications.htm.ini
+++ b/servo/tests/wpt/metadata-css/cssom-1_dev/html/css-style-declaration-modifications.htm.ini
@@ -1,10 +1,11 @@
 [css-style-declaration-modifications.htm]
   type: testharness
+  expected: TIMEOUT
   [CSSStyleDeclaration_accessible]
     expected: FAIL
 
   [read]
     expected: FAIL
 
   [csstext_write]
     expected: FAIL
--- a/servo/tests/wpt/metadata-css/cssom-1_dev/html/interfaces.htm.ini
+++ b/servo/tests/wpt/metadata-css/cssom-1_dev/html/interfaces.htm.ini
@@ -199,8 +199,14 @@
     expected: FAIL
 
   [PseudoElement interface: attribute rawComputedStyle]
     expected: FAIL
 
   [PseudoElement interface: attribute usedStyle]
     expected: FAIL
 
+  [CSSMediaRule interface: existence and properties of interface object]
+    expected: FAIL
+
+  [CSSMediaRule interface: existence and properties of interface prototype object]
+    expected: FAIL
+
--- a/servo/tests/wpt/metadata/MANIFEST.json
+++ b/servo/tests/wpt/metadata/MANIFEST.json
@@ -45842,16 +45842,22 @@
       }
     ]
   },
   "local_changes": {
     "deleted": [],
     "deleted_reftests": {},
     "items": {
       "testharness": {
+        "cssom/CSS.html": [
+          {
+            "path": "cssom/CSS.html",
+            "url": "/cssom/CSS.html"
+          }
+        ],
         "cssom/CSSKeyframeRule.html": [
           {
             "path": "cssom/CSSKeyframeRule.html",
             "url": "/cssom/CSSKeyframeRule.html"
           }
         ],
         "cssom/overflow-serialization.html": [
           {
--- a/servo/tests/wpt/mozilla/tests/mozilla/interfaces.html
+++ b/servo/tests/wpt/mozilla/tests/mozilla/interfaces.html
@@ -15,28 +15,30 @@ test_interfaces([
   "BeforeUnloadEvent",
   "Blob",
   "CanvasGradient",
   "CanvasRenderingContext2D",
   "CanvasPattern",
   "CharacterData",
   "CloseEvent",
   "CSS",
+  "CSSConditionRule",
   "CSSFontFaceRule",
   "CSSGroupingRule",
   "CSSImportRule",
   "CSSKeyframeRule",
   "CSSKeyframesRule",
   "CSSMediaRule",
   "CSSNamespaceRule",
   "CSSRule",
   "CSSRuleList",
   "CSSStyleDeclaration",
   "CSSStyleRule",
   "CSSStyleSheet",
+  "CSSSupportsRule",
   "CSSViewportRule",
   "DOMMatrix",
   "DOMMatrixReadOnly",
   "DOMPoint",
   "DOMPointReadOnly",
   "DOMQuad",
   "DOMRect",
   "DOMRectReadOnly",