|
1 <html xmlns="http://www.w3.org/1999/xhtml"> |
|
2 <head> |
|
3 <title>Test for hyperlinking</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 <p id="display"></p> |
|
9 <div id="content" style="display:none"> |
|
10 <svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px" |
|
11 onload="this.pauseAnimations()"> |
|
12 <circle cx="-100" cy="20" r="15" fill="blue" id="circle"/> |
|
13 </svg> |
|
14 </div> |
|
15 <pre id="test"> |
|
16 <script class="testbody" type="text/javascript"> |
|
17 <![CDATA[ |
|
18 /** Test for SMIL keySplines **/ |
|
19 |
|
20 /* Global Variables */ |
|
21 const SVGNS="http://www.w3.org/2000/svg"; |
|
22 var gSvg = document.getElementById("svg"); |
|
23 var gAnim; |
|
24 |
|
25 var gTestStages = |
|
26 [ testActive, |
|
27 testSeekToFirst, |
|
28 testKickStart, |
|
29 testKickStartWithUnresolved, |
|
30 testFiltering |
|
31 ]; |
|
32 |
|
33 SimpleTest.waitForExplicitFinish(); |
|
34 |
|
35 function continueTest() |
|
36 { |
|
37 if (gTestStages.length == 0) { |
|
38 SimpleTest.finish(); |
|
39 return; |
|
40 } |
|
41 |
|
42 window.location.hash = ""; |
|
43 if (gAnim) { |
|
44 gAnim.parentNode.removeChild(gAnim); |
|
45 } |
|
46 gAnim = createAnim(); |
|
47 gSvg.setCurrentTime(0); |
|
48 gTestStages.shift()(); |
|
49 } |
|
50 |
|
51 function createAnim() { |
|
52 var anim = document.createElementNS(SVGNS,'animate'); |
|
53 anim.setAttribute('attributeName','cx'); |
|
54 anim.setAttribute('from','0'); |
|
55 anim.setAttribute('to','100'); |
|
56 anim.setAttribute('dur','1s'); |
|
57 anim.setAttribute('begin','indefinite'); |
|
58 anim.setAttribute('id','anim'); |
|
59 return document.getElementById('circle').appendChild(anim); |
|
60 } |
|
61 |
|
62 // Traversing a hyperlink, condition 1: |
|
63 // |
|
64 // "If the target element is active, seek the document time back to the |
|
65 // (current) begin time of the element. If there are multiple begin times, use |
|
66 // the begin time that corresponds to the current "begin instance"." |
|
67 // |
|
68 function testActive() { |
|
69 gAnim.setAttribute('begin','2s; 4s'); |
|
70 gSvg.setCurrentTime(2.5); |
|
71 fireLink(rewindActiveInterval1); |
|
72 } |
|
73 |
|
74 function rewindActiveInterval1() { |
|
75 is(gSvg.getCurrentTime(), 2, |
|
76 "Unexpected time after activating link to animation in the middle of " + |
|
77 "first active interval"); |
|
78 |
|
79 // Seek to second interval |
|
80 gSvg.setCurrentTime(4.5); |
|
81 fireLink(rewindActiveInterval2); |
|
82 } |
|
83 |
|
84 function rewindActiveInterval2() { |
|
85 is(gSvg.getCurrentTime(), 4, |
|
86 "Unexpected time after activating link to animation in the middle of " + |
|
87 "second active interval"); |
|
88 |
|
89 // Try a negative time |
|
90 gAnim.setAttribute("begin", "-0.5"); |
|
91 gSvg.setCurrentTime(0.2); |
|
92 fireLink(rewindActiveIntervalAtZero); |
|
93 } |
|
94 |
|
95 function rewindActiveIntervalAtZero() { |
|
96 is(gSvg.getCurrentTime(), 0, |
|
97 "Unexpected time after activating link to animation in the middle of " + |
|
98 "an active interval that overlaps zero"); |
|
99 |
|
100 continueTest(); |
|
101 } |
|
102 |
|
103 // Traversing a hyperlink, condition 2: |
|
104 // |
|
105 // "Else if the target element begin time is resolved (i.e., there is any |
|
106 // resolved time in the list of begin times, or if the begin time was forced by |
|
107 // an earlier hyperlink or a beginElement() method call), seek the document time |
|
108 // (forward or back, as needed) to the earliest resolved begin time of the |
|
109 // target element. Note that the begin time may be resolved as a result of an |
|
110 // earlier hyperlink, DOM or event activation. Once the begin time is resolved, |
|
111 // hyperlink traversal always seeks." |
|
112 // |
|
113 function testSeekToFirst() { |
|
114 // Seek forwards |
|
115 gAnim.setAttribute('begin','2s'); |
|
116 gSvg.setCurrentTime(0); |
|
117 fireLink(forwardToInterval1); |
|
118 } |
|
119 |
|
120 function forwardToInterval1() { |
|
121 is(gSvg.getCurrentTime(), 2, |
|
122 "Unexpected time after activating link to animation scheduled to start " + |
|
123 "the future"); |
|
124 |
|
125 // Seek backwards |
|
126 gSvg.setCurrentTime(3.5); |
|
127 fireLink(backwardToInterval1); |
|
128 } |
|
129 |
|
130 function backwardToInterval1() { |
|
131 is(gSvg.getCurrentTime(), 2, |
|
132 "Unexpected time after activating link to animation that ran in the past"); |
|
133 |
|
134 // What if the first begin instance is negative? |
|
135 gAnim.setAttribute('begin','-0.5s'); |
|
136 gSvg.setCurrentTime(1); |
|
137 fireLink(backwardToZero); |
|
138 } |
|
139 |
|
140 function backwardToZero() { |
|
141 is(gSvg.getCurrentTime(), 0, |
|
142 "Unexpected time after activating link to animation that ran in the " + |
|
143 "past with a negative time"); |
|
144 |
|
145 continueTest(); |
|
146 } |
|
147 |
|
148 // Traversing a hyperlink, condition 3: |
|
149 // |
|
150 // "Else (animation begin time is unresolved) just resolve the target animation |
|
151 // begin time at current document time. Disregard the sync-base or event base of |
|
152 // the animation, and do not "back-propagate" any timing logic to resolve the |
|
153 // child, but rather treat it as though it were defined with begin="indefinite" |
|
154 // and just resolve begin time to the current document time." |
|
155 // |
|
156 function testKickStart() { |
|
157 gSvg.setCurrentTime(1); |
|
158 fireLink(startedAt1s); |
|
159 } |
|
160 |
|
161 function startedAt1s() { |
|
162 is(gSvg.getCurrentTime(), 1, |
|
163 "Unexpected time after kick-starting animation with indefinite start " + |
|
164 "by hyperlink"); |
|
165 is(gAnim.getStartTime(), 1, |
|
166 "Unexpected start time for kick-started animation"); |
|
167 |
|
168 continueTest(); |
|
169 } |
|
170 |
|
171 function testKickStartWithUnresolved() { |
|
172 gAnim.setAttribute("begin", "circle.click"); |
|
173 gSvg.setCurrentTime(3); |
|
174 fireLink(startedAt3s); |
|
175 } |
|
176 |
|
177 function startedAt3s() { |
|
178 is(gSvg.getCurrentTime(), 3, |
|
179 "Unexpected time after kick-starting animation with unresolved start " + |
|
180 "by hyperlink"); |
|
181 is(gAnim.getStartTime(), 3, |
|
182 "Unexpected start time for kick-started animation with unresolved begin " + |
|
183 "condition"); |
|
184 |
|
185 continueTest(); |
|
186 } |
|
187 |
|
188 function testFiltering() { |
|
189 gAnim.setAttribute('begin','-3s; 1s; 2s; 3s; 4s; 5s; 6s; 7s; 8s; 9s; 10s'); |
|
190 gSvg.setCurrentTime(12); |
|
191 fireLink(rewindToFirst); |
|
192 } |
|
193 |
|
194 function rewindToFirst() { |
|
195 is(gSvg.getCurrentTime(), 1, |
|
196 "Unexpected time after triggering animation with a hyperlink after " + |
|
197 "numerous intervals have passed"); |
|
198 |
|
199 continueTest(); |
|
200 } |
|
201 |
|
202 function fireLink(callback) { |
|
203 // First we need to reset the hash because otherwise the redundant hashchange |
|
204 // events will be suppressed |
|
205 if (window.location.hash === '') { |
|
206 fireLinkPart2(callback); |
|
207 } else { |
|
208 window.location.hash = ''; |
|
209 window.addEventListener("hashchange", |
|
210 function clearHash() { |
|
211 window.removeEventListener("hashchange", clearHash, false); |
|
212 window.setTimeout(fireLinkPart2, 0, callback); |
|
213 }, |
|
214 false); |
|
215 } |
|
216 } |
|
217 |
|
218 function fireLinkPart2(callback) { |
|
219 window.addEventListener("hashchange", |
|
220 function triggerCallback() { |
|
221 window.removeEventListener("hashchange", triggerCallback, false); |
|
222 window.setTimeout(callback, 0); |
|
223 }, |
|
224 false); |
|
225 window.location.hash = '#anim'; |
|
226 } |
|
227 |
|
228 window.addEventListener("load", continueTest, false); |
|
229 ]]> |
|
230 </script> |
|
231 </pre> |
|
232 </body> |
|
233 </html> |