<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>CSS Test (Conditional Rules): @supports rules OM support</title> <link href="mailto:florian@rivoal.net" rel="author" title="Florian Rivoal" /> <link href="http://opera.com" rel="author" title="Opera Software ASA" /> <link href="http://www.w3.org/TR/css3-conditional/#at-supports" rel="help" /> <meta content="" name="flags" /> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style> @supports (padding: 0) { dfn { width:0; } @supports (width: 0) { br { height:0; } } ol { display:none; } } @media all { @supports (padding: 0) { @keyframes foo { 0% { top: 0; left: 0; } 100% { top: 100px; left: 100px; } } } } @supports (border: black) and (padding: 0) and (width: 0) { dfn { width:0; } } @supports (border: black) or (padding: 0) or (width: 0) { dfn { width:0; } } </style> <script> /** * Asserts tha the two strings are equal, after normalizing whitespace * * If the serialization of whitespace and identation ever becomes * specified to a sufficient degree of presition, this should be * replaced by a strict textual comparison with assert_equals. */ function assert_equals_normalized(a, b) { var normal_a = a.replace(/\s+/g, " "); var normal_b = b.replace(/\s+/g, " "); assert_equals(normal_a, normal_b); } test(function(){ var base_rule = document.styleSheets[0].cssRules[0]; var child_rule = base_rule.cssRules[1]; assert_equals_normalized(base_rule.cssText, "@supports (padding: 0) {\n" +" dfn { width: 0px; }\n" +" @supports (width: 0) {\n" +" br { height: 0px; }\n" +" }\n" +" ol { display: none; }\n" +"}"); assert_equals_normalized(child_rule.cssText, "@supports (width: 0) {\n" +" br { height: 0px; }\n" +"}"); }, "nested @supports serialize properly"); test(function(){ var base_rule = document.styleSheets[0].cssRules[1]; var child_rule = base_rule.cssRules[0]; var grand_child_rule = child_rule.cssRules[0]; assert_equals_normalized(base_rule.cssText, "@media all {\n" +" @supports (padding: 0) {\n" +" @keyframes foo {\n" +" 0% { top: 0px; left: 0px; }\n" +" 100% { top: 100px; left: 100px; }\n" +" }\n" +" }\n" +"}"); assert_equals_normalized(child_rule.cssText, "@supports (padding: 0) {\n" +" @keyframes foo {\n" +" 0% { top: 0px; left: 0px; }\n" +" 100% { top: 100px; left: 100px; }\n" +" }\n" +"}"); assert_equals_normalized(grand_child_rule.cssText, "@keyframes foo {\n" +" 0% { top: 0px; left: 0px; }\n" +" 100% { top: 100px; left: 100px; }\n" +"}"); }, "@keyframes nested in @supports serialize properly"); test(function(){ var rules = document.styleSheets[0].cssRules; assert_equals(rules.length, 4); assert_equals(rules[0].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[1].type, CSSRule.MEDIA_RULE); assert_equals(rules[0].cssRules.length, 3); assert_equals(rules[0].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules[2].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules.length, 1); assert_equals(rules[0].cssRules[1].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[1].cssRules.length, 1); assert_equals(rules[1].cssRules[0].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[1].cssRules[0].cssRules.length, 1); assert_equals(rules[1].cssRules[0].cssRules[0].type, CSSRule.KEYFRAMES_RULE); assert_equals(rules[2].cssRules.length, 1); assert_equals(rules[2].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[3].cssRules.length, 1); assert_equals(rules[3].cssRules[0].type, CSSRule.STYLE_RULE); }, "The style sheet structure is properly represented"); test(function(){ document.styleSheets[0].deleteRule(1); var rules = document.styleSheets[0].cssRules; assert_equals(rules.length, 3); assert_equals(rules[0].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules.length, 3); assert_equals(rules[0].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules[2].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules.length, 1); assert_equals(rules[0].cssRules[1].cssRules[0].type, CSSRule.STYLE_RULE); }, "Deleting the top level of a nested structue works"); test(function(){ var rules = document.styleSheets[0].cssRules; rules[0].cssRules[1].insertRule("img { visibility:hidden; }", 0); assert_equals(rules.length, 3); assert_equals(rules[0].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules.length, 3); assert_equals(rules[0].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules[2].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules.length, 2); assert_equals(rules[0].cssRules[1].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules[0].cssText, "img { visibility: hidden; }"); assert_equals(rules[0].cssRules[1].cssRules[1].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules[1].cssText, "br { height: 0px; }"); }, "Rule insertion works in nested @supports rules"); test(function(){ var rules = document.styleSheets[0].cssRules; rules[0].insertRule("@supports (left: 42px) { #foo { color:green; } }", 1); assert_equals(rules.length, 3); assert_equals(rules[0].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules.length, 4); assert_equals(rules[0].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules[2].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules[3].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules.length, 1); assert_equals(rules[0].cssRules[1].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules[0].cssText, "#foo { color: green; }"); assert_equals(rules[0].cssRules[2].cssRules.length, 2); assert_equals(rules[0].cssRules[2].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[2].cssRules[0].cssText, "img { visibility: hidden; }"); assert_equals(rules[0].cssRules[2].cssRules[1].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[2].cssRules[1].cssText, "br { height: 0px; }"); }, "Insertion @supports rules into another @supports rule works"); test(function(){ var rules = document.styleSheets[0].cssRules; rules[0].deleteRule(2); assert_equals(rules.length, 3); assert_equals(rules[0].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules.length, 3); assert_equals(rules[0].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules[2].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules.length, 1); assert_equals(rules[0].cssRules[1].cssRules[0].type, CSSRule.STYLE_RULE); assert_equals(rules[0].cssRules[1].cssRules[0].cssText, "#foo { color: green; }"); }, "Deletion of a nested @supports rule works"); test(function(){ var rules = document.styleSheets[0].cssRules; rules[0].insertRule("@font-face { font-familly: foo; src: url('http://www.example.com/foo'; }", 0); assert_equals(rules.length, 3); assert_equals(rules[0].type, CSSRule.SUPPORTS_RULE); assert_equals(rules[0].cssRules.length, 4); assert_equals(rules[0].cssRules[0].type, CSSRule.FONT_FACE_RULE); }, "Inserting @font-face inside @supports works"); test(function(){ var style_rule = document.styleSheets[0].cssRules[0].cssRules[1]; assert_throws(new TypeError(), function() { style_rule.insertRule("@supports (width: 0) { ol { width: 0; } }", 0);} ); }, "Inserting an @supports inside a style rule should fail"); test(function(){ var rule = document.styleSheets[0].cssRules[1]; assert_equals_normalized(rule.cssText, "@supports (border: black) and (padding: 0) and (width: 0) {\n" +" dfn { width: 0px; }\n" +"}"); }, "'and' arguments in @supports serialize in the correct order and with extra parentheses"); test(function(){ var rule = document.styleSheets[0].cssRules[2]; assert_equals_normalized(rule.cssText, "@supports (border: black) or (padding: 0) or (width: 0) {\n" +" dfn { width: 0px; }\n" +"}"); }, "'or' arguments in @supports serialize in the correct order and with extra parentheses"); </script> </head><body><div id="log"></div> </body></html>