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