<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=879963 --> <head> <meta charset="utf-8"> <title>Test for bug 879963</title> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> </head> <body> <!-- Two <style> elements with identical @font-face rules. Although multiple @font-face at-rules for the same family are legal, and add faces to the family, we should NOT download the same resource twice just because we have a duplicate face entry. --> <style type="text/css"> @font-face { font-family: foo; src: url("redundant_font_download.sjs?q=font"); } .test { font-family: foo; } </style> <style type="text/css"> @font-face { font-family: foo; src: url("redundant_font_download.sjs?q=font"); } .test { font-family: foo; } </style> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=879963">Mozilla Bug 879963</a> <div> <!-- the 'init' request returns an image (just so we can see it's working) and initializes the request logging in our sjs server --> <img src="redundant_font_download.sjs?q=init"> </div> <div id="test"> Test </div> <div> <img id="image2" src=""> </div> <script type="application/javascript"> // helper to retrieve the server's request log as text function getRequestLog() { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "redundant_font_download.sjs?q=report", false); xmlHttp.send(null); return xmlHttp.responseText; } // retrieve just the most recent request the server has seen function getLastRequest() { return getRequestLog().split(";").pop(); } // poll the server at intervals of 'delay' ms until it has seen a specific request, // or until maxTime ms have passed function waitForRequest(request, delay, maxTime, func) { timeLimit = Date.now() + maxTime; var intervalId = window.setInterval(function() { var req = getLastRequest(); if (req == request || Date.now() > timeLimit) { window.clearInterval(intervalId); func(); } }.bind(this), delay); } // initially disable the second of the <style> elements, // so we only have a single copy of the font-face document.getElementsByTagName("style")[1].disabled = true; SimpleTest.waitForExplicitFinish(); // We perform a series of actions that trigger requests to the .sjs server, // and poll the server's request log at each stage to check that it has // seen the request we expected before we proceed to the next step. function startTest() { is(getRequestLog(), "init", "request log has been initialized"); // this should trigger a font download document.getElementById("test").className = "test"; // wait to confirm that the server has received the request waitForRequest("font", 10, 5000, continueTest1); } function continueTest1() { is(getRequestLog(), "init;font", "server received font request"); // trigger a request for the second image, to provide an explicit // delimiter in the log before we enable the second @font-face rule document.getElementById("image2").src = "redundant_font_download.sjs?q=image"; waitForRequest("image", 10, 5000, continueTest2); } function continueTest2() { is(getRequestLog(), "init;font;image", "server received image request"); // enable the second <style> element: we should NOT see a second font request, // we expect waitForRequest to time out instead document.getElementsByTagName("style")[1].disabled = false; waitForRequest("font", 10, 1000, continueTest3); } function continueTest3() { is(getRequestLog(), "init;font;image", "should NOT have re-requested the font"); SimpleTest.finish(); } waitForRequest("init", 10, 5000, startTest); </script> </body> </html>