blob: 7a6a97b104bbf52a9ddba302557683d8d82be069 [file] [edit]
<!doctype html>
<title>CSSKeyframeRule keyText edge cases</title>
<link rel="help" href="https://drafts.csswg.org/css-animations-1/#dom-csskeyframerule-keytext">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
@keyframes test {
0% { opacity: 0 }
}
</style>
<script>
"use strict";
const rule = document.styleSheets[0].cssRules[0].cssRules[0];
function setAndObserve(value) {
let threw = false;
try {
rule.keyText = value;
} catch {
threw = true;
}
return { threw, keyText: rule.keyText };
}
// Out-of-range percentages
test(() => {
rule.keyText = "0%";
const result = setAndObserve("150%");
assert_true(
result.threw || result.keyText === "0%",
`expected throw or no change, got keyText=${result.keyText}, threw=${result.threw}`
);
}, "setter rejects 150%");
test(() => {
rule.keyText = "0%";
const result = setAndObserve("-5%");
assert_true(
result.threw || result.keyText === "0%",
`expected throw or no change, got keyText=${result.keyText}, threw=${result.threw}`
);
}, "setter rejects -5%");
// Valid percentage formats
test(() => {
rule.keyText = "0%";
const result = setAndObserve(".5%");
assert_false(result.threw, "should not throw for .5%");
assert_equals(result.keyText, "0.5%");
}, "setter accepts and normalizes .5%");
test(() => {
rule.keyText = "0%";
const result = setAndObserve("1e1%");
assert_false(result.threw, "should not throw for 1e1%");
assert_equals(result.keyText, "10%");
}, "setter accepts and normalizes 1e1%");
test(() => {
rule.keyText = "0%";
const result = setAndObserve("100.0%");
assert_false(result.threw, "should not throw for 100.0%");
assert_equals(result.keyText, "100%");
}, "setter accepts and normalizes 100.0%");
test(() => {
rule.keyText = "0%";
const result = setAndObserve("0.0%");
assert_false(result.threw, "should not throw for 0.0%");
assert_equals(result.keyText, "0%");
}, "setter accepts and normalizes 0.0%");
// Case insensitivity
test(() => {
rule.keyText = "0%";
const result = setAndObserve("FROM");
assert_false(result.threw, "should not throw for FROM");
assert_equals(result.keyText, "0%");
}, "setter accepts and normalizes FROM");
test(() => {
rule.keyText = "0%";
const result = setAndObserve("To");
assert_false(result.threw, "should not throw for To");
assert_equals(result.keyText, "100%");
}, "setter accepts and normalizes To");
test(() => {
rule.keyText = "0%";
const result = setAndObserve("From, TO");
assert_false(result.threw, "should not throw for From, TO");
assert_equals(result.keyText, "0%, 100%");
}, "setter accepts and normalizes mixed-case From, TO");
// Whitespace
test(() => {
rule.keyText = " 50% ";
assert_equals(rule.keyText, "50%");
}, "setter trims whitespace");
test(() => {
rule.keyText = " 25% , 75% ";
assert_equals(rule.keyText, "25%, 75%");
}, "setter trims whitespace in comma-separated selectors");
// Getter normalization for parsed stylesheets
test(() => {
const style = document.createElement("style");
style.textContent = "@keyframes test2 { .5% { opacity: 0 } }";
document.head.appendChild(style);
const r = document.styleSheets[document.styleSheets.length - 1].cssRules[0].cssRules[0];
assert_equals(r.keyText, "0.5%");
style.remove();
}, "getter normalizes .5% from parsed stylesheet");
test(() => {
const style = document.createElement("style");
style.textContent = "@keyframes test3 { 100.0% { opacity: 0 } }";
document.head.appendChild(style);
const r = document.styleSheets[document.styleSheets.length - 1].cssRules[0].cssRules[0];
assert_equals(r.keyText, "100%");
style.remove();
}, "getter normalizes 100.0% from parsed stylesheet");
test(() => {
const style = document.createElement("style");
style.textContent = "@keyframes test4 { 1e1% { opacity: 0 } }";
document.head.appendChild(style);
const r = document.styleSheets[document.styleSheets.length - 1].cssRules[0].cssRules[0];
assert_equals(r.keyText, "10%");
style.remove();
}, "getter normalizes 1e1% from parsed stylesheet");
</script>