blob: f79f6fb12f2597baa3aa87b15e84f04e1ef5f426 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>Shadow DOM: Link elements should load stylesheets inside shadow trees</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="Link elements should load inside shadow trees">
<script src='../../resources/testharness.js'></script>
<script src='../../resources/testharnessreport.js'></script>
</head>
<body>
<script>
function wait_for_onload(element, callback = null) {
return new Promise(function (resolve, reject) {
element.onload = resolve;
element.onerror = reject;
setTimeout(() => reject('timeout'), 100);
if (callback)
return callback();
});
}
let test_iframe;
let stylesheet_ready = null;
async function create_iframe() {
if (!stylesheet_ready) { // Cache the stylesheet first to avoid timeout in the very first test case.
stylesheet_ready = new Promise((resolve) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'resources/green-host.css';
link.addEventListener('load', () => {
link.remove();
resolve();
});
document.body.appendChild(link);
});
}
await create_iframe;
if (test_iframe)
test_iframe.remove();
test_iframe = document.createElement('iframe');
return stylesheet_ready.then(() => {
return wait_for_onload();
}).then(() => test_iframe.contentWindow, () => {
document.body.appendChild(test_iframe);
}).then(function () {
const doc = test_iframe.contentWindow.document;
doc.open();
doc.write('<!DOCTYPE html><html><head><body>');
doc.close();
return test_iframe.contentWindow;
});
}
add_result_callback(() => {
if (test_iframe)
test_iframe.remove();
});
function test_stylesheet_load_in_connected_shadow_tree(mode) {
promise_test(() => {
return create_iframe().then(contentWindow => {
const doc = contentWindow.document;
const host = doc.createElement('div');
const link = doc.createElement('link');
return wait_for_onload(link, () => {
link.rel = 'stylesheet';
link.href = 'resources/green-host.css';
host.attachShadow({mode: mode}).appendChild(link);
contentWindow.document.body.appendChild(host);
});
});
}, `Link elements should load stylesheets inside a connected shadow tree with ${mode} mode`);
}
test_stylesheet_load_in_connected_shadow_tree('closed');
test_stylesheet_load_in_connected_shadow_tree('open');
function test_stylesheet_do_not_load_in_disconnected_shadow_tree(mode) {
promise_test(() => {
return create_iframe().then((contentWindow) => {
const doc = contentWindow.document;
const host = doc.createElement('div');
const link = doc.createElement('link');
return wait_for_onload(link, () => {
link.rel = 'stylesheet';
link.href = 'resources/green-host.css';
host.attachShadow({mode: mode}).appendChild(link);
});
}).then(() => {
assert_true(false, 'stylesheet must not load inside a disconnected shadow tree');
}, (error) => {
assert_equals(error, 'timeout');
});
}, `Link elements must not load stylesheets inside a disconnceted shadow tree with ${mode} mode`);
}
test_stylesheet_do_not_load_in_disconnected_shadow_tree('closed');
test_stylesheet_do_not_load_in_disconnected_shadow_tree('open');
function test_loaded_stylesheet_rule_in_shadow_tree_applies_to_div(mode) {
promise_test(() => {
let div;
return create_iframe().then(function (contentWindow) {
const doc = contentWindow.document;
const host = doc.createElement('div');
const shadowRoot = host.attachShadow({mode: mode});
shadowRoot.innerHTML = '<link rel="stylesheet" href="resources/green-host.css"><div>';
div = shadowRoot.querySelector('div');
return wait_for_onload(shadowRoot.querySelector('link'), () => { doc.body.appendChild(host) });
}).then(() => {
assert_equals(getComputedStyle(div).color, 'rgb(0, 128, 0)');
});
}, `Style rules loaded inside a shadow tree with ${mode} mode must apply to a div in the shadow tree`);
}
test_loaded_stylesheet_rule_in_shadow_tree_applies_to_div('closed');
test_loaded_stylesheet_rule_in_shadow_tree_applies_to_div('open');
function test_loaded_stylesheet_rule_in_shadow_tree_applies_to_host(mode) {
promise_test(() => {
let host;
return create_iframe().then(function (contentWindow) {
const doc = contentWindow.document;
host = doc.createElement('div');
const shadowRoot = host.attachShadow({mode: mode});
shadowRoot.innerHTML = '<link rel="stylesheet" href="resources/green-host.css"><div>';
return wait_for_onload(shadowRoot.querySelector('link'), () => { doc.body.appendChild(host) });
}).then(() => {
assert_equals(getComputedStyle(host).color, 'rgb(0, 128, 0)');
});
}, `:host style rules loaded inside a shadow tree with ${mode} mode must apply to the host element`);
}
test_loaded_stylesheet_rule_in_shadow_tree_applies_to_host('closed');
test_loaded_stylesheet_rule_in_shadow_tree_applies_to_host('open');
</script>
</html>
</body>