attr-cycle.html (6522B)
1 <!DOCTYPE html> 2 <title>CSS Values and Units Test: attr</title> 3 <meta name="assert" content="test attr values"> 4 <link rel="help" href="https://drafts.csswg.org/css-values-5/#attr-notations"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 8 <div id="attr"></div> 9 <div id="expected"></div> 10 11 <script> 12 function test_attr_cycle(property, propertyValue, attrValue) { 13 var elem = document.getElementById("attr"); 14 var expectedValue = window.getComputedStyle(elem).getPropertyValue(property); 15 16 elem.setAttribute("data-foo", attrValue); 17 elem.style.setProperty(property, propertyValue); 18 19 test(() => { 20 assert_equals(window.getComputedStyle(elem).getPropertyValue(property), expectedValue, 21 "Setting property \'" + property + "\' to the value \'" + propertyValue + 22 "\', where \'data-foo=" + attrValue + "\' should not change it's value."); 23 }); 24 elem.style.setProperty(property, null); 25 } 26 27 function test_attr_no_cycle(property, propertyValue, attrValue, expectedValue) { 28 var elem = document.getElementById("attr"); 29 elem.setAttribute("data-foo", attrValue); 30 elem.style.setProperty(property, propertyValue); 31 32 var expectedElem = document.getElementById("expected"); 33 expectedElem.style.setProperty(property, expectedValue); 34 35 test(() => { 36 assert_equals(window.getComputedStyle(elem).getPropertyValue(property), 37 window.getComputedStyle(expectedElem).getPropertyValue(property), 38 "Value \'" + propertyValue + "\', where \'data-foo=" + attrValue + 39 "\' should be valid for the property \'" + property + "\'."); 40 }); 41 42 elem.style.setProperty(property, null); 43 expectedElem.style.setProperty(property, null); 44 } 45 46 /* Simple cycle */ 47 test_attr_cycle('--x', 'attr(data-foo type(<ident>))', 'attr(data-foo)'); 48 test_attr_cycle('--x', 'attr(data-foo type(<length>))', 'attr(data-foo type(<length>))'); 49 test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-foo type(*))'); 50 51 var attrElem = document.getElementById("attr"); 52 53 attrElem.setAttribute('data-bar', 'attr(data-foo)'); 54 test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar type(*))'); 55 attrElem.removeAttribute('data-bar'); 56 57 /* Cycle with attr() and var() */ 58 attrElem.style.setProperty('--x', 'attr(data-foo type(*))'); 59 test_attr_cycle('--y', 'attr(data-foo type(*))', 'var(--x)'); 60 attrElem.style.setProperty('--x', null); 61 62 attrElem.setAttribute('data-bar', 'var(--y)'); 63 test_attr_cycle('--y', 'attr(data-foo type(<string>))', 'attr(data-bar type(<string>))'); 64 attrElem.removeAttribute('data-bar'); 65 66 attrElem.setAttribute('data-bar', 'var(--x)'); 67 test_attr_cycle('--x', 'attr(data-foo type(*), attr(data-bar type(*)))', 'attr(data-foo type(*))'); 68 attrElem.removeAttribute('data-bar'); 69 70 attrElem.style.setProperty('--x', 'attr(data-foo type(*))'); 71 attrElem.setAttribute('data-bar', 'var(--x)'); 72 test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar type(*), 11) var(--x)'); 73 attrElem.style.setProperty('--x', null); 74 attrElem.removeAttribute('data-bar'); 75 76 /* Cycle with fallback */ 77 test_attr_cycle('--x', 'attr(data-foo type(<length>))', 'attr(data-foo type(<length>), 11px)'); 78 test_attr_cycle('--x', 'attr(data-foo type(<length>), 3px)', 'var(--x)'); 79 test_attr_cycle('--x', 'attr(data-foo type(<length>), 3px)', 'var(--x, 11px)'); 80 81 attrElem.style.setProperty('--y', 'attr(data-foo)'); 82 test_attr_no_cycle('--x', 'attr(data-foo type(<custom-ident>), 3px)', 'var(--y)', '3px'); 83 attrElem.style.setProperty('--y', null); 84 85 /* Cycle within attributes, so we should fallback. */ 86 test_attr_no_cycle('--x', 'attr(data-foo type(<length>), 11px)', 'attr(data-foo type(<length>), 3px)', '11px'); 87 test_attr_no_cycle('--x', 'attr(data-foo type(<length>), 11px)', 'attr(data-foo type(<length>))', '11px'); 88 test_attr_no_cycle('--y', 'attr(data-foo type(*), 11px)', 'attr(data-foo type(*))', '11px'); 89 90 attrElem.setAttribute('data-bar', '11px'); 91 test_attr_no_cycle('--x', 'attr(data-foo type(<length>), attr(data-bar type(<length>)))', 'attr(data-foo type(*))', '11px'); 92 attrElem.removeAttribute('data-bar'); 93 attrElem.setAttribute('data-bar', 'abc'); 94 test_attr_no_cycle('--y', 'attr(data-foo type(*), attr(data-bar))', 'attr(data-foo type(*))', '"abc"'); 95 attrElem.removeAttribute('data-bar'); 96 97 attrElem.setAttribute('data-bar', 'attr(data-baz type(*), 3px)'); 98 attrElem.setAttribute('data-baz', 'attr(data-foo type(*), 4px)'); 99 test_attr_no_cycle('--y', 'attr(data-foo type(*), 1px)', 'attr(data-bar type(*), 2px)', '1px'); 100 attrElem.removeAttribute('data-bar'); 101 attrElem.removeAttribute('data-baz'); 102 103 /* Cycle with var() and fallback */ 104 attrElem.style.setProperty('--x', 'var(--y)'); 105 test_attr_cycle('--y', 'var(--x, 100)', 'var(--y)'); 106 attrElem.style.setProperty('--x', null); 107 108 attrElem.setAttribute('data-bar', 'var(--y)'); 109 attrElem.style.setProperty('--x', 'attr(data-foo)'); 110 test_attr_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar type(*), 11) var(--x, 3)'); 111 attrElem.style.setProperty('--x', null); 112 attrElem.removeAttribute('data-bar'); 113 114 /* Cycle in unused fallbacks */ 115 test_attr_no_cycle('--y', 'attr(data-foo type(*), var(--y))', '3', '3'); 116 test_attr_no_cycle('--y', 'attr(data-foo type(*), attr(data-foo))', '3', '3'); 117 118 attrElem.style.setProperty('--x', 'var(--y)'); 119 test_attr_no_cycle('--y', 'attr(data-foo type(*), var(--x))', '3', '3'); 120 attrElem.style.setProperty('--x', null); 121 122 attrElem.setAttribute('data-bar', 'attr(data-foo type(*))'); 123 test_attr_no_cycle('--y', 'attr(data-foo type(*), attr(data-bar type(*)))', '3', '3'); 124 attrElem.removeAttribute('data-bar'); 125 126 /* Cycle in fallback */ 127 test_attr_cycle('--y', 'attr(data-unknown type(*), var(--y))', '3'); 128 129 /* No cycle, use raw CSS string without substitution */ 130 attrElem.setAttribute('data-bar', 'var(--y)'); 131 test_attr_no_cycle('--y', 'attr(data-foo type(<string>))', 'attr(data-bar type(<string>))', ''); 132 attrElem.removeAttribute('data-bar'); 133 134 attrElem.style.setProperty('--x', 'attr(data-foo)'); 135 attrElem.setAttribute('data-bar', 'var(--x)'); 136 test_attr_no_cycle('--y', 'attr(data-foo type(*))', 'attr(data-bar, 11) var(--x, 3)', '"var(--x)" "attr(data-bar, 11) var(--x, 3)"'); 137 attrElem.removeAttribute('data-bar'); 138 attrElem.style.setProperty('--x', null); 139 140 /* No cycle, wrong attr syntax in attribute */ 141 test_attr_no_cycle('--x', 'attr(data-foo type(*), abc)', 'attr(data-foo', 'abc'); 142 </script>