test_smilHyperlinking.xhtml (6378B)
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title>Test for hyperlinking</title> 4 <script 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) { 38 SimpleTest.finish(); 39 return; 40 } 41 42 window.location.hash = ""; 43 if (gAnim) { 44 gAnim.remove(); 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() { 211 window.setTimeout(fireLinkPart2, 0, callback); 212 }, {once: true}); 213 } 214 } 215 216 function fireLinkPart2(callback) { 217 window.addEventListener("hashchange", 218 function() { 219 window.setTimeout(callback, 0); 220 }, {once: true}); 221 window.location.hash = '#anim'; 222 } 223 224 window.addEventListener("load", continueTest); 225 ]]> 226 </script> 227 </pre> 228 </body> 229 </html>