test_redundant_font_download.html (4071B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=879963 --> 4 <head> 5 <meta charset="utf-8"> 6 <title>Test for bug 879963</title> 7 <script src="/tests/SimpleTest/SimpleTest.js"></script> 8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 9 </head> 10 11 <body> 12 <!-- Two <style> elements with identical @font-face rules. 13 Although multiple @font-face at-rules for the same family are legal, 14 and add faces to the family, we should NOT download the same resource 15 twice just because we have a duplicate face entry. --> 16 <style type="text/css"> 17 @font-face { 18 font-family: foo; 19 src: url("redundant_font_download.sjs?q=font"); 20 } 21 .test { 22 font-family: foo; 23 } 24 </style> 25 26 <style type="text/css"> 27 @font-face { 28 font-family: foo; 29 src: url("redundant_font_download.sjs?q=font"); 30 } 31 .test { 32 font-family: foo; 33 } 34 </style> 35 36 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=879963">Mozilla Bug 879963</a> 37 38 <div> 39 <!-- the 'init' request returns an image (just so we can see it's working) 40 and initializes the request logging in our sjs server --> 41 <img src="redundant_font_download.sjs?q=init"> 42 </div> 43 44 <div id="test"> 45 Test 46 </div> 47 48 <div> 49 <img id="image2" src=""> 50 </div> 51 52 <script type="application/javascript"> 53 // helper to retrieve the server's request log as text, synchronously 54 function getRequestLog() { 55 var xmlHttp = new XMLHttpRequest(); 56 xmlHttp.open("GET", "redundant_font_download.sjs?q=report", false); 57 xmlHttp.send(null); 58 return xmlHttp.responseText; 59 } 60 61 // retrieve just the most recent request the server has seen 62 function getLastRequest() { 63 return getRequestLog().split(";").pop(); 64 } 65 66 // poll the server at intervals of animation frame callback until it has 67 // seen a specific request, or until maxTime ms have passed 68 function waitForRequest(request, maxTime, func) { 69 timeLimit = Date.now() + maxTime; 70 requestAnimationFrame(function rAF() { 71 var req = getLastRequest(); 72 if (req == request || Date.now() > timeLimit) { 73 func(); 74 return; 75 } 76 requestAnimationFrame(rAF); 77 }); 78 } 79 80 // initially disable the second of the <style> elements, 81 // so we only have a single copy of the font-face 82 document.getElementsByTagName("style")[1].disabled = true; 83 84 SimpleTest.waitForExplicitFinish(); 85 86 // We perform a series of actions that trigger requests to the .sjs server, 87 // and poll the server's request log at each stage to check that it has 88 // seen the request we expected before we proceed to the next step. 89 function startTest() { 90 is(getRequestLog(), "init", "request log has been initialized"); 91 92 // this should trigger a font download 93 document.getElementById("test").className = "test"; 94 95 // wait to confirm that the server has received the request 96 waitForRequest("font", 5000, continueTest1); 97 } 98 99 function continueTest1() { 100 is(getRequestLog(), "init;font", "server received font request"); 101 102 // trigger a request for the second image, to provide an explicit 103 // delimiter in the log before we enable the second @font-face rule 104 document.getElementById("image2").src = "redundant_font_download.sjs?q=image"; 105 106 waitForRequest("image", 5000, continueTest2); 107 } 108 109 function continueTest2() { 110 is(getRequestLog(), "init;font;image", "server received image request"); 111 112 // enable the second <style> element: we should NOT see a second font request, 113 // we expect waitForRequest to time out instead 114 document.getElementsByTagName("style")[1].disabled = false; 115 116 waitForRequest("font", 1000, continueTest3); 117 } 118 119 function continueTest3() { 120 is(getRequestLog(), "init;font;image", "should NOT have re-requested the font"); 121 122 SimpleTest.finish(); 123 } 124 125 waitForRequest("init", 5000, startTest); 126 127 </script> 128 129 </body> 130 131 </html>