Source code

Revision control

Other Tools

Test Info:

<meta charset="utf-8">
<title>Test for bug 879963</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<!-- 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 type="text/css">
@font-face {
font-family: foo;
src: url("redundant_font_download.sjs?q=font");
.test {
font-family: foo;
<a target="_blank" href="">Mozilla Bug 879963</a>
<!-- 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 id="test">
<img id="image2" src="">
<script type="application/javascript">
// helper to retrieve the server's request log as text
function getRequestLog() {
var xmlHttp = new XMLHttpRequest();"GET", "redundant_font_download.sjs?q=report", false);
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 = + maxTime;
var intervalId = window.setInterval(() => {
var req = getLastRequest();
if (req == request || > timeLimit) {
}, 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;
// 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");
waitForRequest("init", 10, 5000, startTest);