Created
April 19, 2017 21:40
-
-
Save flapenguin/5503b96e235c2a8fc1197ff634eba7bc to your computer and use it in GitHub Desktop.
Firefox foreignObject background-image canvas rendering bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<meta http-equiv="Cache-Control" content="no-cache"> | |
<title>Firefox foreignObject background-image canvas rendering bug</title> | |
<style> | |
td { border: 1px darkblue solid; } | |
</style> | |
</head> | |
<body> | |
<button id="reproduce">reproduce</button> | |
<table> | |
<tr> | |
<td>img</td> | |
<td>canvas</td> | |
</tr> | |
<tr> | |
<td><img id="src"></td> | |
<td><canvas id="dst"></canvas></td> | |
</tr> | |
</table> | |
<script> | |
document.body.onload = async () => { | |
try { | |
await main(); | |
} catch (e) { | |
console.error(e); | |
} | |
}; | |
async function main() { | |
const N = +(location.search.replace(/^\?/, '')||'0'); | |
document.querySelector('#reproduce').onclick = () => { | |
window.location = window.location.href.replace(/(\?\d*)?$/, `?${N+1}`); | |
}; | |
const image = document.querySelector('#image'), | |
{width, height} = image.dataset; | |
let imageUrl = image.innerText.trim(); | |
// Add three dummy zero bytes to the end of png N times to confuse cache. | |
imageUrl = imageUrl.replace(/=*$/, 'AAAA'.repeat(N) + '$&'); | |
const svg = ` | |
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"> | |
<foreignObject width="100%" height="100%"> | |
<div xmlns="http://www.w3.org/1999/xhtml" style="position: relative;"> | |
<div style="background: url(${imageUrl}); width: ${width}px; height: ${height}px;"></div> | |
</div> | |
</foreignObject> | |
</svg> | |
`; | |
const svgUrl = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' })); | |
const src = document.querySelector('#src'); | |
src.width = width; | |
src.height = height; | |
await new Promise((resolve, reject) => { | |
src.onload = resolve; | |
src.onerror = reject; | |
src.src = svgUrl; | |
}); | |
const ctx = document.querySelector('#dst').getContext('2d'); | |
ctx.canvas.width = width; | |
ctx.canvas.height = height; | |
URL.revokeObjectURL(svgUrl); | |
ctx.drawImage(src, 0, 0); | |
}; | |
</script> | |
<script id="image" type="text/plain" data-width="32" data-height="32"> | |
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAQAAAAEsBnfPAAAABGdBTUEAAYagMeiWXwAAAJBJREFUeJwtjTEOwjAMRd/GgsQVGHoApC4Zergeg7En4AxWOQATY6WA2FgsZckQNXxLeLC/v99PcBaMGeesuXCj8tHe2Wlc5b9ZY9/ZKq9Mn9kn6kSeZIffW5w255m5G98IK01L1AFP5AFLAat6F67mlNKNMootY4N6cEUeFkhwLZqf9KEdL3pRqiHloYx//QCU41EdZhgi8gAAAABJRU5ErkJggg== | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment