Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 <html xmlns="http://www.w3.org/1999/xhtml">
2 <head>
3 <title>Test for SMIL keyTimes</title>
4 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
5 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
6 </head>
7 <body>
8 <a target="_blank"
9 href="https://bugzilla.mozilla.org/show_bug.cgi?id=557885">Mozilla Bug
10 557885</a>
11 <p id="display"></p>
12 <div id="content" style="display: none">
13 <svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
14 <circle cx="-100" cy="20" r="15" fill="blue" id="circle"/>
15 </svg>
16 </div>
17 <pre id="test">
18 <script class="testbody" type="text/javascript">
19 <![CDATA[
20 /** Test for SMIL keyTimes **/
22 var gSvg = document.getElementById("svg");
23 SimpleTest.waitForExplicitFinish();
25 function main()
26 {
27 gSvg.pauseAnimations();
29 var testCases = Array();
31 // Simple case
32 testCases.push({
33 'attr' : { 'values': '0; 50; 100',
34 'keyTimes': '0; .8; 1' },
35 'times': [ [ 4, 25 ],
36 [ 8, 50 ],
37 [ 9, 75 ],
38 [ 10, 100 ] ]
39 });
41 // Parsing tests
42 testCases.push(parseOk(' 0 ; .8;1 ')); // extra whitespace
43 testCases.push(parseNotOk(';0; .8; 1')); // leading semi-colon
44 testCases.push(parseNotOk('; .8; 1')); // leading semi-colon
45 testCases.push(parseOk('0; .8; 1;')); // trailing semi-colon
46 testCases.push(parseNotOk('')); // empty string
47 testCases.push(parseNotOk(' ')); // empty string
48 testCases.push(parseNotOk('0; .8')); // too few values
49 testCases.push(parseNotOk('0; .8; .9; 1')); // too many values
50 testCases.push(parseNotOk('0; 1; .8')); // non-increasing
51 testCases.push(parseNotOk('0; .8; .9')); // final value non-1 with
52 // calcMode=linear
53 testCases.push(parseOk('0; .8; .9', { 'calcMode': 'discrete' }));
54 testCases.push(parseNotOk('0.01; .8; 1')); // first value not 0
55 testCases.push(parseNotOk('0.01; .8; 1', { 'calcMode': 'discrete' }));
56 // first value not 0
57 testCases.push(parseNotOk('0; .8; 1.1')); // out of range
58 testCases.push(parseNotOk('-0.1; .8; 1')); // out of range
61 // 2 values
62 testCases.push({
63 'attr' : { 'values': '0; 50',
64 'keyTimes': '0; 1' },
65 'times': [ [ 6, 30 ] ]
66 });
68 // 1 value
69 testCases.push({
70 'attr' : { 'values': '50',
71 'keyTimes': ' 0' },
72 'times': [ [ 7, 50 ] ]
73 });
75 // 1 bad value
76 testCases.push({
77 'attr' : { 'values': '50',
78 'keyTimes': '0.1' },
79 'times': [ [ 0, -100 ] ]
80 });
82 // 1 value, calcMode=discrete
83 testCases.push({
84 'attr' : { 'values': '50',
85 'calcMode': 'discrete',
86 'keyTimes': ' 0' },
87 'times': [ [ 7, 50 ] ]
88 });
90 // 1 bad value, calcMode=discrete
91 testCases.push({
92 'attr' : { 'values': '50',
93 'calcMode': 'discrete',
94 'keyTimes': '0.1' },
95 'times': [ [ 0, -100 ] ]
96 });
98 // from-to
99 testCases.push({
100 'attr' : { 'from': '10',
101 'to': '20',
102 'keyTimes': '0.0; 1.0' },
103 'times': [ [ 3.5, 13.5 ] ]
104 });
106 // from-to calcMode=discrete
107 testCases.push({
108 'attr' : { 'from': '10',
109 'to': '20',
110 'calcMode': 'discrete',
111 'keyTimes': '0.0; 0.7' },
112 'times': [ [ 0, 10 ],
113 [ 6.9, 10 ],
114 [ 7.0, 20 ],
115 [ 10.0, 20 ],
116 [ 11.0, 20 ] ]
117 });
119 // from-to calcMode=discrete one keyTime only
120 testCases.push({
121 'attr' : { 'values': '20',
122 'calcMode': 'discrete',
123 'keyTimes': '0' },
124 'times': [ [ 0, 20 ],
125 [ 6.9, 20 ],
126 [ 7.0, 20 ],
127 [ 10.0, 20 ],
128 [ 11.0, 20 ] ]
129 });
131 // from-to calcMode=discrete one keyTime, mismatches no. values
132 testCases.push({
133 'attr' : { 'values': '10; 20',
134 'calcMode': 'discrete',
135 'keyTimes': '0' },
136 'times': [ [ 0, -100 ] ]
137 });
139 // to
140 testCases.push({
141 'attr' : { 'to': '100',
142 'keyTimes': '0.0; 1.0' },
143 'times': [ [ 0, -100 ],
144 [ 7, 40 ] ]
145 });
147 // to -- bad number of keyTimes (too many)
148 testCases.push({
149 'attr' : { 'to': '100',
150 'keyTimes': '0.0; 0.5; 1.0' },
151 'times': [ [ 2, -100 ] ]
152 });
154 // unfrozen to calcMode=discrete two keyTimes
155 testCases.push({
156 'attr' : { 'to': '100',
157 'calcMode': 'discrete',
158 'keyTimes': '0.0; 1.0',
159 'fill': 'remove' },
160 'times': [ [ 0, -100 ],
161 [ 7, -100 ],
162 [ 10, -100 ],
163 [ 12, -100 ]]
164 });
166 // frozen to calcMode=discrete two keyTimes
167 testCases.push({
168 'attr' : { 'to': '100',
169 'calcMode': 'discrete',
170 'keyTimes': '0.0; 1.0' },
171 'times': [ [ 0, -100 ],
172 [ 7, -100 ],
173 [ 10, 100 ],
174 [ 12, 100 ] ]
175 });
177 // to calcMode=discrete -- bad number of keyTimes (one, expecting two)
178 testCases.push({
179 'attr' : { 'to': '100',
180 'calcMode': 'discrete',
181 'keyTimes': '0' },
182 'times': [ [ 0, -100 ],
183 [ 7, -100 ] ]
184 });
186 // values calcMode=discrete
187 testCases.push({
188 'attr' : { 'values': '0; 10; 20; 30',
189 'calcMode': 'discrete',
190 'keyTimes': '0;.2;.4;.6' },
191 'times': [ [ 0, 0 ],
192 [ 1.9, 0 ],
193 [ 2, 10 ],
194 [ 3.9, 10 ],
195 [ 4.0, 20 ],
196 [ 5.9, 20 ],
197 [ 6.0, 30 ],
198 [ 9.9, 30 ],
199 [ 10.0, 30 ] ]
200 });
202 // The following two accumulate tests are from SMIL 3.0
203 // (Note that this behaviour differs from that defined for SVG Tiny 1.2 which
204 // specifically excludes the last value: "Note that in the case of discrete
205 // animation, the frozen value that is used is the value of the animation just
206 // before the end of the active duration.")
207 // accumulate=none
208 testCases.push({
209 'attr' : { 'values': '0; 10; 20',
210 'calcMode': 'discrete',
211 'keyTimes': '0;.5;1',
212 'fill': 'freeze',
213 'repeatCount': '2',
214 'accumulate': 'none' },
215 'times': [ [ 0, 0 ],
216 [ 5, 10 ],
217 [ 10, 0 ],
218 [ 15, 10 ],
219 [ 20, 20 ],
220 [ 25, 20 ] ]
221 });
223 // accumulate=sum
224 testCases.push({
225 'attr' : { 'values': '0; 10; 20',
226 'calcMode': 'discrete',
227 'keyTimes': '0;.5;1',
228 'fill': 'freeze',
229 'repeatCount': '2',
230 'accumulate': 'sum' },
231 'times': [ [ 0, 0 ],
232 [ 5, 10 ],
233 [ 10, 20 ],
234 [ 15, 30 ],
235 [ 20, 40 ],
236 [ 25, 40 ] ]
237 });
239 // If the interpolation mode is paced, the keyTimes attribute is ignored.
240 testCases.push({
241 'attr' : { 'values': '0; 10; 20',
242 'calcMode': 'paced',
243 'keyTimes': '0;.2;1' },
244 'times': [ [ 0, 0 ],
245 [ 2, 4 ],
246 [ 5, 10 ] ]
247 });
249 // SMIL 3 has:
250 // If the simple duration is indefinite and the interpolation mode is
251 // linear or spline, any keyTimes specification will be ignored.
252 // However, since keyTimes represent "a proportional offset into the simple
253 // duration of the animation element" surely discrete animation too cannot use
254 // keyTimes when the simple duration is indefinite. Hence SVGT 1.2 is surely
255 // more correct when it has:
256 // If the simple duration is indefinite, any 'keyTimes' specification will
257 // be ignored.
258 // (linear)
259 testCases.push({
260 'attr' : { 'values': '0; 10; 20',
261 'dur': 'indefinite',
262 'keyTimes': '0;.2;1' },
263 'times': [ [ 0, 0 ],
264 [ 5, 0 ] ]
265 });
266 // (spline)
267 testCases.push({
268 'attr' : { 'values': '0; 10; 20',
269 'dur': 'indefinite',
270 'calcMode': 'spline',
271 'keyTimes': '0;.2;1',
272 'keySplines': '0 0 1 1; 0 0 1 1' },
273 'times': [ [ 0, 0 ],
274 [ 5, 0 ] ]
275 });
276 // (discrete)
277 testCases.push({
278 'attr' : { 'values': '0; 10; 20',
279 'dur': 'indefinite',
280 'calcMode': 'discrete',
281 'keyTimes': '0;.2;1' },
282 'times': [ [ 0, 0 ],
283 [ 5, 0 ] ]
284 });
286 for (var i = 0; i < testCases.length; i++) {
287 gSvg.setCurrentTime(0);
288 var test = testCases[i];
290 // Create animation elements
291 var anim = createAnim(test.attr);
293 // Run samples
294 for (var j = 0; j < test.times.length; j++) {
295 var times = test.times[j];
296 gSvg.setCurrentTime(times[0]);
297 checkSample(anim, times[1], times[0], i);
298 }
300 anim.parentNode.removeChild(anim);
301 }
303 // fallback to discrete for non-additive animation
304 var attr = { 'values': 'butt; round; square',
305 'attributeName': 'stroke-linecap',
306 'calcMode': 'linear',
307 'keyTimes': '0;.2;1',
308 'fill': 'remove' };
309 var anim = createAnim(attr);
310 var samples = [ [ 0, 'butt' ],
311 [ 1.9, 'butt' ],
312 [ 2.0, 'round' ],
313 [ 9.9, 'round' ],
314 [ 10, 'butt' ] // fill=remove so we'll never set it to square
315 ];
316 for (var i = 0; i < samples.length; i++) {
317 var sample = samples[i];
318 gSvg.setCurrentTime(sample[0]);
319 checkLineCapSample(anim, sample[1], sample[0],
320 "[non-interpolatable fallback]");
321 }
322 anim.parentNode.removeChild(anim);
324 SimpleTest.finish();
325 }
327 function parseOk(str, extra)
328 {
329 var attr = { 'values': '0; 50; 100',
330 'keyTimes': str };
331 if (typeof(extra) == "object") {
332 for (name in extra) {
333 attr[name] = extra[name];
334 }
335 }
336 return {
337 'attr' : attr,
338 'times': [ [ 0, 0 ] ]
339 };
340 }
342 function parseNotOk(str, extra)
343 {
344 var result = parseOk(str, extra);
345 result.times = [ [ 0, -100 ] ];
346 return result;
347 }
349 function createAnim(attr)
350 {
351 const svgns = "http://www.w3.org/2000/svg";
352 var anim = document.createElementNS(svgns, 'animate');
353 anim.setAttribute('attributeName','cx');
354 anim.setAttribute('dur','10s');
355 anim.setAttribute('begin','0s');
356 anim.setAttribute('fill','freeze');
357 for (name in attr) {
358 anim.setAttribute(name, attr[name]);
359 }
360 return document.getElementById('circle').appendChild(anim);
361 }
363 function checkSample(anim, expectedValue, sampleTime, caseNum)
364 {
365 var msg = "Test case " + caseNum +
366 " (keyTimes: '" + anim.getAttribute('keyTimes') + "'" +
367 " calcMode: " + anim.getAttribute('calcMode') + "), " +
368 "t=" + sampleTime +
369 ": Unexpected sample value:";
370 is(anim.targetElement.cx.animVal.value, expectedValue, msg);
371 }
373 function checkLineCapSample(anim, expectedValue, sampleTime, caseDescr)
374 {
375 var msg = "Test case " + caseDescr +
376 " (keyTimes: '" + anim.getAttribute('keyTimes') + "'" +
377 " calcMode: " + anim.getAttribute('calcMode') + "), " +
378 "t=" + sampleTime +
379 ": Unexpected sample value:";
380 var actualValue =
381 window.getComputedStyle(anim.targetElement, null).
382 getPropertyValue('stroke-linecap');
383 is(actualValue, expectedValue, msg);
384 }
386 window.addEventListener("load", main, false);
387 ]]>
388 </script>
389 </pre>
390 </body>
391 </html>