'use strict'; // serializedValue can be the expected serialization of value, // or an array of permitted serializations, // or omitted if value should serialize as value. function test_valid_value(property, value, serializedValue) { if (arguments.length < 3) serializedValue = value; var stringifiedValue = JSON.stringify(value); test(function(){ var div = document.getElementById('target') || document.createElement('div'); div.style[property] = ""; div.style[property] = value; var readValue = div.style.getPropertyValue(property); assert_not_equals(readValue, "", "property should be set"); if (Array.isArray(serializedValue)) assert_in_array(readValue, serializedValue, "serialization should be sound"); else assert_equals(readValue, serializedValue, "serialization should be canonical"); div.style[property] = readValue; assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); } function test_invalid_value(property, value) { var stringifiedValue = JSON.stringify(value); test(function(){ var div = document.getElementById('target') || document.createElement('div'); div.style[property] = ""; div.style[property] = value; assert_equals(div.style.getPropertyValue(property), ""); }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); } // serializedSelector can be the expected serialization of selector, // or an array of permitted serializations, // or omitted if value should serialize as selector. function test_valid_selector(selector, serializedSelector) { if (arguments.length < 2) serializedSelector = selector; const stringifiedSelector = JSON.stringify(selector); test(function(){ document.querySelector(selector); assert_true(true, stringifiedSelector + " should not throw in querySelector"); const style = document.createElement("style"); document.head.append(style); const {sheet} = style; document.head.removeChild(style); const {cssRules} = sheet; assert_equals(cssRules.length, 0, "Sheet should have no rule"); sheet.insertRule(selector + "{}"); assert_equals(cssRules.length, 1, "Sheet should have 1 rule"); const readSelector = cssRules[0].selectorText; if (Array.isArray(serializedSelector)) assert_in_array(readSelector, serializedSelector, "serialization should be sound"); else assert_equals(readSelector, serializedSelector, "serialization should be canonical"); sheet.deleteRule(0); assert_equals(cssRules.length, 0, "Sheet should have no rule"); sheet.insertRule(readSelector + "{}"); assert_equals(cssRules.length, 1, "Sheet should have 1 rule"); assert_equals(cssRules[0].selectorText, readSelector, "serialization should round-trip"); }, stringifiedSelector + " should be a valid selector"); } function test_invalid_selector(selector) { const stringifiedSelector = JSON.stringify(selector); test(function(){ assert_throws_dom( DOMException.SYNTAX_ERR, () => document.querySelector(selector), stringifiedSelector + " should throw in querySelector"); const style = document.createElement("style"); document.head.append(style); const {sheet} = style; document.head.removeChild(style); assert_throws_dom( DOMException.SYNTAX_ERR, () => sheet.insertRule(selector + "{}"), stringifiedSelector + " should throw in insertRule"); }, stringifiedSelector + " should be an invalid selector"); } // serialized can be the expected serialization of rule, or an array of // permitted serializations, or omitted if value should serialize as rule. function test_valid_rule(rule, serialized) { if (serialized === undefined) serialized = rule; test(function(){ const style = document.createElement("style"); document.head.append(style); const {sheet} = style; document.head.removeChild(style); const {cssRules} = sheet; assert_equals(cssRules.length, 0, "Sheet should have no rules"); sheet.insertRule(rule); assert_equals(cssRules.length, 1, "Sheet should have 1 rule"); const serialization = cssRules[0].cssText; if (Array.isArray(serialized)) assert_in_array(serialization, serialized, "serialization should be sound"); else assert_equals(serialization, serialized, "serialization should be canonical"); sheet.deleteRule(0); assert_equals(cssRules.length, 0, "Sheet should have no rule"); sheet.insertRule(serialization); assert_equals(cssRules.length, 1, "Sheet should have 1 rule"); assert_equals(cssRules[0].cssText, serialization, "serialization should round-trip"); }, rule + " should be a valid rule"); } function test_invalid_rule(rule) { test(function(){ const style = document.createElement("style"); document.head.append(style); const {sheet} = style; document.head.removeChild(style); assert_throws_dom( DOMException.SYNTAX_ERR, () => sheet.insertRule(rule), rule + " should throw in insertRule"); }, rule + " should be an invalid rule"); } function _set_style(rule) { const style = document.createElement('style'); style.innerText = rule; document.head.append(style); const { sheet } = style; document.head.removeChild(style); return sheet; } function test_keyframes_name_valid(keyframes_name) { test(t => { const sheet = _set_style(`@keyframes ${keyframes_name} {}`); assert_equals(sheet.cssRules.length, 1); }, `valid: @keyframes ${keyframes_name} { }`); } function test_keyframes_name_invalid(keyframes_name) { test(t => { const sheet = _set_style(`@keyframes ${keyframes_name} {}`); assert_equals(sheet.cssRules.length, 0); }, `invalid: @keyframes ${keyframes_name} { }`); }