blob: b6fafdcc7bccce77684cb79a1204d9221e85bddd [file] [log] [blame]
// This is used by several tests to help get images reliably preloaded.
// Given a node, loads all urls specified in style declarations
// attached to the node or it's decendants.
// imageCount specifies the number of images we expect to find (to try to add some
// protection against brittleness due to imperfect url parsing, since other missing a preload
// will typically result in a test that fails only occasionally).
// If failPattern is specified, then any url that matches the regex
// will be expected to fail to load.
function preloadImagesFromStyle(rootNode, imageCount, onComplete, failPattern) {
var basePath = location.href.substring(0, location.href.lastIndexOf('/') + 1);
var nodes = rootNode.querySelectorAll('[style]');
var imagesToLoad = [];
var seenUrls = {};
for (var i = 0; i < nodes.length; i++) {
var urls = nodes[i].style.cssText.split(/url\w*\("([^)]*)"\)/);
for (var j = 1; j < urls.length; j += 2) {
// Attempt to convert URL to a relative path in order to have deterministic error messages.
var url = urls[j];
if (url.indexOf(basePath) == 0)
url = url.substring(basePath.length);
var error = false;
if (failPattern && failPattern.test(url))
error = true;
if (url in seenUrls)
continue;
seenUrls[url] = true;
imagesToLoad.push({url: url, error: error});
}
}
if (imageCount != imagesToLoad.length) {
var msg = 'Found the following ' + imagesToLoad.length + ' images, when expecting ' + imageCount + ': ';
for (var i = 0; i < imagesToLoad.length; i++) {
msg += '\n' + imagesToLoad[i].url;
}
testFailed(msg);
}
loadImages(imagesToLoad, onComplete);
}
// For each object in the given array, attempt to load the image specified by the
// url property. If the error property is specified and true, then the load is
// expected to fail. Once all loads have completed or failed, onComplete is invoked.
function loadImages(imagesToLoad, onComplete) {
var imagesLeftToLoad = imagesToLoad.length;
function onImageLoad(url, success, e) {
// This debug output order is non-deterministic - only show when not running in DRT
if (!window.testRunner)
debug( 'Event "' + e.type + '": ' + url);
if (!success)
testFailed('Got unexpected \'' + e.type + '\' event for image: ' + url);
imagesLeftToLoad--;
if (imagesLeftToLoad == 0) {
onComplete();
}
if (imagesLeftToLoad < 0)
testFailed('Got more load/error callbacks than expected.');
}
for (var i = 0; i < imagesToLoad.length; i++) {
var img = new Image();
var expectError = imagesToLoad[i].error;
img.addEventListener('load', onImageLoad.bind(undefined, imagesToLoad[i].url, !expectError));
img.addEventListener('error', onImageLoad.bind(undefined, imagesToLoad[i].url, !!expectError));
img.src = imagesToLoad[i].url;
}
}