blob: 8e3d40793b1d30c58bce35611280298b9d344e9d [file] [edit]
<!doctype html>
<title>StyleSheet and CSSStyleSheet properties</title>
<link rel="help" href="https://drafts.csswg.org/cssom/#the-stylesheet-interface">
<link rel="help" href="https://drafts.csswg.org/cssom/#the-cssstylesheet-interface">
<link rel="help" href="https://drafts.csswg.org/cssom/#remove-a-css-style-sheet">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style id="plain">div { color: green }</style>
<style id="with-title" title="My Sheet">span { color: red }</style>
<style id="with-media" media="screen">p { color: blue }</style>
<style id="with-import">@import url("/css/support/a-green.css");</style>
<link id="link-plain" rel="stylesheet" href="/css/support/a-green.css">
<link id="link-titled" rel="stylesheet" href="/css/support/b-green.css" title="Link Sheet">
<link id="link-media" rel="stylesheet" href="/css/support/c-red.css" media="screen">
<script>
"use strict";
// Wait for @import and <link> sheets to load
async_test(t => {
window.addEventListener("load", t.step_func_done(() => {
const plainSheet = document.getElementById("plain").sheet;
const titledSheet = document.getElementById("with-title").sheet;
const mediaSheet = document.getElementById("with-media").sheet;
const importSheet = document.getElementById("with-import").sheet;
const linkPlainSheet = document.getElementById("link-plain").sheet;
const linkTitledSheet = document.getElementById("link-titled").sheet;
const linkMediaSheet = document.getElementById("link-media").sheet;
// --- <style> element sheets ---
test(() => {
assert_equals(plainSheet.type, "text/css");
}, "<style>: type is 'text/css'");
test(() => {
assert_equals(plainSheet.ownerNode, document.getElementById("plain"));
}, "<style>: ownerNode is the style element");
test(() => {
assert_equals(plainSheet.href, null);
}, "<style>: href is null for inline sheets");
test(() => {
assert_equals(plainSheet.title, null);
}, "<style>: title is null when the style element has no title attribute");
test(() => {
assert_equals(titledSheet.title, "My Sheet");
}, "<style>: title reflects the style element's title attribute");
test(() => {
assert_equals(plainSheet.media.mediaText, "");
assert_equals(plainSheet.media.length, 0);
}, "<style>: media is empty when the style element has no media attribute");
test(() => {
assert_equals(mediaSheet.media.mediaText, "screen");
assert_equals(mediaSheet.media.length, 1);
}, "<style>: media reflects the style element's media attribute");
test(() => {
assert_false(plainSheet.disabled);
}, "<style>: disabled is false initially");
test(() => {
assert_equals(plainSheet.parentStyleSheet, null);
}, "<style>: parentStyleSheet is null for top-level sheets");
test(() => {
assert_equals(plainSheet.ownerRule, null);
}, "<style>: ownerRule is null for non-imported sheets");
test(() => {
assert_true(plainSheet.cssRules instanceof CSSRuleList);
assert_greater_than(plainSheet.cssRules.length, 0);
}, "<style>: cssRules is a CSSRuleList with rules");
// --- <link> element sheets ---
test(() => {
assert_equals(linkPlainSheet.type, "text/css");
}, "<link>: type is 'text/css'");
test(() => {
assert_equals(linkPlainSheet.ownerNode, document.getElementById("link-plain"));
}, "<link>: ownerNode is the link element");
test(() => {
assert_equals(linkPlainSheet.href, new URL("/css/support/a-green.css", document.baseURI).href);
}, "<link>: href is the resolved URL of the stylesheet");
test(() => {
assert_equals(linkPlainSheet.title, null);
}, "<link>: title is null when the link element has no title attribute");
test(() => {
assert_equals(linkTitledSheet.title, "Link Sheet");
}, "<link>: title reflects the link element's title attribute");
test(() => {
assert_equals(linkPlainSheet.media.mediaText, "");
assert_equals(linkPlainSheet.media.length, 0);
}, "<link>: media is empty when the link element has no media attribute");
test(() => {
assert_equals(linkMediaSheet.media.mediaText, "screen");
assert_equals(linkMediaSheet.media.length, 1);
}, "<link>: media reflects the link element's media attribute");
test(() => {
assert_false(linkPlainSheet.disabled);
}, "<link>: disabled is false initially");
test(() => {
assert_equals(linkPlainSheet.parentStyleSheet, null);
}, "<link>: parentStyleSheet is null for top-level sheets");
test(() => {
assert_equals(linkPlainSheet.ownerRule, null);
}, "<link>: ownerRule is null for non-imported sheets");
test(() => {
assert_true(linkPlainSheet.cssRules instanceof CSSRuleList);
assert_greater_than(linkPlainSheet.cssRules.length, 0);
}, "<link>: cssRules is a CSSRuleList with rules");
// --- @import sheets ---
test(() => {
const importRule = importSheet.cssRules[0];
assert_equals(importRule.constructor.name, "CSSImportRule", "setup: should be an import rule");
const imported = importRule.styleSheet;
assert_equals(imported.type, "text/css");
}, "@import: imported sheet type is 'text/css'");
test(() => {
const imported = importSheet.cssRules[0].styleSheet;
assert_equals(imported.ownerNode, null);
}, "@import: imported sheet ownerNode is null");
test(() => {
const imported = importSheet.cssRules[0].styleSheet;
assert_equals(imported.href, new URL("/css/support/a-green.css", document.baseURI).href);
}, "@import: imported sheet href is the resolved URL");
test(() => {
const imported = importSheet.cssRules[0].styleSheet;
assert_equals(imported.title, null);
}, "@import: imported sheet title is null");
test(() => {
const imported = importSheet.cssRules[0].styleSheet;
assert_equals(imported.media.mediaText, "");
assert_equals(imported.media.length, 0);
}, "@import: imported sheet media is empty when @import has no media query");
test(() => {
const imported = importSheet.cssRules[0].styleSheet;
assert_false(imported.disabled);
}, "@import: imported sheet disabled is false initially");
test(() => {
const imported = importSheet.cssRules[0].styleSheet;
assert_equals(imported.parentStyleSheet, importSheet);
}, "@import: imported sheet parentStyleSheet is the importing sheet");
test(() => {
const importRule = importSheet.cssRules[0];
const imported = importRule.styleSheet;
assert_equals(imported.ownerRule, importRule);
}, "@import: imported sheet ownerRule is the CSSImportRule");
test(() => {
const imported = importSheet.cssRules[0].styleSheet;
assert_true(imported.cssRules instanceof CSSRuleList);
assert_greater_than(imported.cssRules.length, 0);
}, "@import: imported sheet cssRules is a CSSRuleList with rules");
// --- Removal ---
test(() => {
const style = document.createElement("style");
style.textContent = "div { color: green }";
document.head.appendChild(style);
const { sheet } = style;
assert_equals(sheet.ownerNode, style);
style.remove();
assert_equals(sheet.ownerNode, null, "ownerNode becomes null after removal");
assert_equals(sheet.parentStyleSheet, null, "parentStyleSheet is null after removal");
assert_equals(sheet.ownerRule, null, "ownerRule is null after removal");
}, "Removing a <style> element nulls ownerNode, parentStyleSheet, and ownerRule");
test(() => {
const link = document.getElementById("link-plain");
const { sheet } = link;
assert_equals(sheet.ownerNode, link);
link.remove();
assert_equals(sheet.ownerNode, null, "ownerNode becomes null after removal");
assert_equals(sheet.parentStyleSheet, null, "parentStyleSheet is null after removal");
assert_equals(sheet.ownerRule, null, "ownerRule is null after removal");
}, "Removing a <link> element nulls ownerNode, parentStyleSheet, and ownerRule");
// --- Programmatic title ---
test(() => {
const style = document.createElement("style");
style.title = "Dynamic Title";
document.head.appendChild(style);
assert_equals(style.sheet.title, "Dynamic Title");
style.remove();
}, "Programmatically setting title on a <style> element is reflected in sheet.title");
}));
}, "StyleSheet and CSSStyleSheet properties");
</script>