1 /* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 // pixelzoomer is shared with LayoutTests/fast/harness/results.html 27 // Unfortuantely, there's no good way to share code between these two uses. 28 29 var pixelzoomer = pixelzoomer || {}; 30 31 (function() { 32 33 var kZoomFactor = 6; 34 var kDelayTimeoutMS = 400; 35 36 var kResultWidth = 800; 37 var kResultHeight = 600; 38 39 var kZoomedResultWidth = kResultWidth * kZoomFactor; 40 var kZoomedResultHeight = kResultHeight * kZoomFactor; 41 42 function matchesSelector(node, selector) 43 { 44 if (node.webkitMatchesSelector) 45 return node.webkitMatchesSelector(selector); 46 47 if (node.mozMatchesSelector) 48 return node.mozMatchesSelector(selector); 49 } 50 51 function parentOfType(node, selector) 52 { 53 while (node = node.parentNode) { 54 if (matchesSelector(node, selector)) 55 return node; 56 } 57 return null; 58 } 59 60 function zoomImageContainer(url) 61 { 62 var container = document.createElement('div'); 63 container.className = 'zoom-image-container'; 64 65 var title = url.match(/\-([^\-]*)\.png/)[1]; 66 67 var label = document.createElement('div'); 68 label.className = 'label'; 69 label.appendChild(document.createTextNode(title)); 70 container.appendChild(label); 71 72 var imageContainer = document.createElement('div'); 73 imageContainer.className = 'scaled-image-container'; 74 75 var image = new Image(); 76 image.src = url; 77 image.style.width = kZoomedResultWidth + 'px'; 78 image.style.height = kZoomedResultHeight + 'px'; 79 image.style.border = '1px solid black'; 80 imageContainer.appendChild(image); 81 container.appendChild(imageContainer); 82 83 return container; 84 } 85 86 function createContainer(e) 87 { 88 var tbody = parentOfType(e.target, 'tbody'); 89 var row = tbody.querySelector('tr'); 90 var images = row.querySelectorAll('img[src$=".png"]'); 91 92 var container = document.createElement('div'); 93 container.className = 'pixel-zoom-container'; 94 95 for (var i = 0; i < images.length; i++) 96 container.appendChild(zoomImageContainer(images[i].src)); 97 98 document.body.appendChild(container); 99 drawAll(); 100 } 101 102 function draw(imageContainer) 103 { 104 var image = imageContainer.querySelector('img'); 105 var containerBounds = imageContainer.getBoundingClientRect(); 106 image.style.left = (containerBounds.width / 2 - pixelzoomer._percentX * kZoomedResultWidth) + 'px'; 107 image.style.top = (containerBounds.height / 2 - pixelzoomer._percentY * kZoomedResultHeight) + 'px'; 108 } 109 110 function drawAll() 111 { 112 Array.prototype.forEach.call(document.querySelectorAll('.pixel-zoom-container .scaled-image-container'), draw); 113 } 114 115 function handleMouseOut(e) 116 { 117 if (e.relatedTarget && e.relatedTarget.tagName != 'IFRAME') 118 return; 119 120 // If e.relatedTarget is null, we've moused out of the document. 121 $('pixel-zoom-container').detach(); 122 } 123 124 function handleMouseMove(e) 125 { 126 if (pixelzoomer._mouseMoveTimeout) 127 clearTimeout(pixelzoomer._mouseMoveTimeout); 128 129 if (parentOfType(e.target, '.pixel-zoom-container')) 130 return; 131 132 var container = document.querySelector('.pixel-zoom-container'); 133 134 var resultContainer = (e.target.className == 'result-container') ? 135 e.target : parentOfType(e.target, '.result-container'); 136 if (!resultContainer || !resultContainer.querySelector('img')) { 137 $(container).detach(); 138 return; 139 } 140 141 var targetLocation = e.target.getBoundingClientRect(); 142 pixelzoomer._percentX = (e.clientX - targetLocation.left) / targetLocation.width; 143 pixelzoomer._percentY = (e.clientY - targetLocation.top) / targetLocation.height; 144 145 if (!container) { 146 if (pixelzoomer.showOnDelay) { 147 pixelzoomer._mouseMoveTimeout = setTimeout(function() { 148 createContainer(e); 149 }, kDelayTimeoutMS); 150 return; 151 } 152 153 createContainer(e); 154 return; 155 } 156 157 drawAll(); 158 } 159 160 pixelzoomer.showOnDelay = true; 161 162 pixelzoomer.installEventListeners = function() 163 { 164 document.addEventListener('mousemove', handleMouseMove, false); 165 document.addEventListener('mouseout', handleMouseOut, false); 166 }; 167 168 })(); 169