// 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; } }