var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue, nonce, integrityValueAfterPrepare) {
this.pass = pass;
this.name = "Script: " + name;
this.src = src;
this.integrityValue = integrityValue;
this.crossoriginValue = crossoriginValue;
this.nonce = nonce;
this.integrityValueAfterPrepare = integrityValueAfterPrepare;
}
SRIScriptTest.prototype.execute = function() {
var test = async_test(this.name);
var e = document.createElement("script");
e.src = this.src;
if (this.integrityValue) {
e.setAttribute("integrity", this.integrityValue);
}
if(this.crossoriginValue) {
e.setAttribute("crossorigin", this.crossoriginValue);
}
if(this.nonce) {
e.setAttribute("nonce", this.nonce);
}
if(this.pass) {
e.addEventListener("load", function() {test.done()});
e.addEventListener("error", function() {
test.step(function(){ assert_unreached("Good load fired error handler.") })
});
} else {
e.addEventListener("load", function() {
test.step(function() { assert_unreached("Bad load succeeded.") })
});
e.addEventListener("error", function() {test.done()});
}
document.body.appendChild(e);
if (this.integrityValueAfterPrepare === null) {
e.removeAttribute("integrity");
} else if (this.integrityValueAfterPrepare !== undefined) {
e.setAttribute("integrity", this.integrityValueAfterPrepare);
}
};
function set_extra_attributes(element, attrs) {
for (const [attr_name, attr_val] of Object.entries(attrs)) {
element[attr_name] = attr_val;
}
}
function buildElementFromDestination(resource_url, destination, attrs) {
let element;
switch (destination) {
case "script":
element = document.createElement(destination);
set_extra_attributes(element, attrs);
element.src = resource_url;
break;
case "style":
element = document.createElement('link');
set_extra_attributes(element, attrs);
element.rel = 'stylesheet';
element.href = resource_url;
break;
case "image":
element = document.createElement('img');
set_extra_attributes(element, attrs);
element.src = resource_url;
break;
default:
assert_unreached("INVALID DESTINATION");
}
return element;
}
const SRIPreloadTest = (preload_sri_success, subresource_sri_success, name,
number_of_requests, destination, resource_url,
link_attrs, subresource_attrs) => {
const test = async_test(name);
const link = document.createElement('link');
test.step_func(() => {
assert_true(link.relList.supports('preload'),
"This test is automatically failing because the browser does not" +
"support `preload` links.");
})();
link.rel = 'preload';
link.as = destination;
link.href = resource_url;
for (const [attr_name, attr_val] of Object.entries(link_attrs)) {
link[attr_name] = attr_val;
}
const valid_preload_failed = test.step_func(() =>
{ assert_unreached("Valid preload fired error handler.") });
const invalid_preload_succeeded = test.step_func(() =>
{ assert_unreached("Invalid preload load succeeded.") });
const valid_subresource_failed = test.step_func(() =>
{ assert_unreached("Valid subresource fired error handler.") });
const invalid_subresource_succeeded = test.step_func(() =>
{ assert_unreached("Invalid subresource load succeeded.") });
const subresource_pass = test.step_func(() => {
verifyNumberOfResourceTimingEntries(resource_url, number_of_requests);
test.done();
});
const preload_pass = test.step_func(() => {
const subresource_element = buildElementFromDestination(
resource_url,
destination,
subresource_attrs
);
if (subresource_sri_success) {
subresource_element.onload = subresource_pass;
subresource_element.onerror = valid_subresource_failed;
} else {
subresource_element.onload = invalid_subresource_succeeded;
subresource_element.onerror = subresource_pass;
}
document.body.append(subresource_element);
});
if (preload_sri_success) {
link.onload = preload_pass;
link.onerror = valid_preload_failed;
} else {
link.onload = invalid_preload_succeeded;
link.onerror = preload_pass;
}
document.head.append(link);
}
var SRIStyleTest = function(queue, pass, name, attrs, customCallback, altPassValue) {
this.pass = pass;
this.name = "Style: " + name;
this.customCallback = customCallback || function () {};
this.attrs = attrs || {};
this.passValue = altPassValue || "rgb(255, 255, 0)";
this.test = async_test(this.name);
this.queue = queue;
this.queue.push(this);
}
SRIStyleTest.prototype.execute = function() {
var that = this;
var container = document.getElementById("container");
while (container.hasChildNodes()) {
container.removeChild(container.firstChild);
}
var test = this.test;
var div = document.createElement("div");
div.className = "testdiv";
var e = document.createElement("link");
this.attrs.rel = this.attrs.rel || "stylesheet";
for (var key in this.attrs) {
if (this.attrs.hasOwnProperty(key)) {
e.setAttribute(key, this.attrs[key]);
}
}
if(this.pass) {
e.addEventListener("load", function() {
test.step(function() {
var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
assert_equals(background, that.passValue);
test.done();
});
});
e.addEventListener("error", function() {
test.step(function(){ assert_unreached("Good load fired error handler.") })
});
} else {
e.addEventListener("load", function() {
test.step(function() { assert_unreached("Bad load succeeded.") })
});
e.addEventListener("error", function() {
test.step(function() {
var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
assert_not_equals(background, that.passValue);
test.done();
});
});
}
container.appendChild(div);
container.appendChild(e);
this.customCallback(e, container);
};