Fri, 16 Jan 2015 04:50:19 +0100
Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32
michael@0 | 1 | <!DOCTYPE HTML> |
michael@0 | 2 | <html> |
michael@0 | 3 | <!-- |
michael@0 | 4 | https://bugzilla.mozilla.org/show_bug.cgi?id=833386 |
michael@0 | 5 | --> |
michael@0 | 6 | <head> |
michael@0 | 7 | <meta charset='utf-8'> |
michael@0 | 8 | <title>Test for Bug 833386 - HTMLTrackElement</title> |
michael@0 | 9 | <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> |
michael@0 | 10 | <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
michael@0 | 11 | <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> |
michael@0 | 12 | </head> |
michael@0 | 13 | <body> |
michael@0 | 14 | <p id="display"></p> |
michael@0 | 15 | <div id="content"> |
michael@0 | 16 | </div> |
michael@0 | 17 | <pre id="test"> |
michael@0 | 18 | <script class="testbody" type="text/javascript"> |
michael@0 | 19 | SimpleTest.waitForExplicitFinish(); |
michael@0 | 20 | SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true], |
michael@0 | 21 | ["media.webvtt.regions.enabled", true]]}, |
michael@0 | 22 | function() { |
michael@0 | 23 | var video = document.createElement("video"); |
michael@0 | 24 | video.src = "seek.webm"; |
michael@0 | 25 | video.preload = "auto"; |
michael@0 | 26 | var trackElement = document.createElement("track"); |
michael@0 | 27 | trackElement.src = "basic.vtt"; |
michael@0 | 28 | trackElement.kind = "subtitles"; |
michael@0 | 29 | document.getElementById("content").appendChild(video); |
michael@0 | 30 | video.appendChild(trackElement); |
michael@0 | 31 | video.addEventListener("loadedmetadata", function run_tests() { |
michael@0 | 32 | // Re-que run_tests() at the end of the event loop until the track |
michael@0 | 33 | // element has loaded its data. |
michael@0 | 34 | if (trackElement.readyState == 1) { |
michael@0 | 35 | setTimeout(run_tests, 0); |
michael@0 | 36 | return; |
michael@0 | 37 | } |
michael@0 | 38 | is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED."); |
michael@0 | 39 | // Set mode to hidden so that the active cue lists are being updated. |
michael@0 | 40 | trackElement.track.mode = "hidden"; |
michael@0 | 41 | |
michael@0 | 42 | var cueList = trackElement.track.cues; |
michael@0 | 43 | is(cueList.length, 6, "Cue list length should be 6."); |
michael@0 | 44 | |
michael@0 | 45 | // Check that the typedef of TextTrackCue works in Gecko. |
michael@0 | 46 | is(window.TextTrackCue, undefined, "TextTrackCue should be undefined."); |
michael@0 | 47 | isnot(window.VTTCue, undefined, "VTTCue should be defined."); |
michael@0 | 48 | |
michael@0 | 49 | // Check if first cue was parsed correctly. |
michael@0 | 50 | var cue = cueList[0]; |
michael@0 | 51 | is(cue.id, "1", "Cue's ID should be 1."); |
michael@0 | 52 | is(cue.startTime, 0.5, "Cue's start time should be 0.5."); |
michael@0 | 53 | is(cue.endTime, 0.7, "Cue's end time should be 0.7."); |
michael@0 | 54 | is(cue.pauseOnExit, false, "Cue's pause on exit flag should be false."); |
michael@0 | 55 | is(cue.text, "This", "Cue's text should be set correctly."); |
michael@0 | 56 | is(cue.track, trackElement.track, "Cue's track should be defined."); |
michael@0 | 57 | |
michael@0 | 58 | cue.track = null; |
michael@0 | 59 | isnot(cue.track, null, "Cue's track should not be able to be set."); |
michael@0 | 60 | |
michael@0 | 61 | // Check that all cue times were not rounded |
michael@0 | 62 | is(cueList[1].startTime, 1.2, "Second cue's start time should be 1.2."); |
michael@0 | 63 | is(cueList[1].endTime, 2.4, "Second cue's end time should be 2.4."); |
michael@0 | 64 | is(cueList[2].startTime, 2, "Third cue's start time should be 2."); |
michael@0 | 65 | is(cueList[2].endTime, 3.5, "Third cue's end time should be 3.5."); |
michael@0 | 66 | is(cueList[3].startTime, 2.71, "Fourth cue's start time should be 2.71."); |
michael@0 | 67 | is(cueList[3].endTime, 2.91, "Fourth cue's end time should be 2.91."); |
michael@0 | 68 | is(cueList[4].startTime, 3.217, "Fifth cue's start time should be 3.217."); |
michael@0 | 69 | is(cueList[4].endTime, 3.989, "Fifth cue's end time should be 3.989."); |
michael@0 | 70 | is(cueList[5].startTime, 3.217, "Sixth cue's start time should be 3.217."); |
michael@0 | 71 | is(cueList[5].endTime, 3.989, "Sixth cue's end time should be 3.989."); |
michael@0 | 72 | |
michael@0 | 73 | // Check that Cue setters are working correctly. |
michael@0 | 74 | cue.id = "Cue 01"; |
michael@0 | 75 | is(cue.id, "Cue 01", "Cue's ID should be 'Cue 01'."); |
michael@0 | 76 | cue.startTime = 0.51; |
michael@0 | 77 | is(cue.startTime, 0.51, "Cue's start time should be 0.51."); |
michael@0 | 78 | cue.endTime = 0.71; |
michael@0 | 79 | is(cue.endTime, 0.71, "Cue's end time should be 0.71."); |
michael@0 | 80 | cue.pauseOnExit = true; |
michael@0 | 81 | is(cue.pauseOnExit, true, "Cue's pause on exit flag should be true."); |
michael@0 | 82 | |
michael@0 | 83 | var exceptionHappened; |
michael@0 | 84 | function checkPercentageValue(prop) { |
michael@0 | 85 | ok(prop in cue, prop + " should be a property on VTTCue."); |
michael@0 | 86 | cue[prop] = 20; |
michael@0 | 87 | is(cue[prop], 20, "Cue's " + prop + " should now be 20."); |
michael@0 | 88 | [ 101, -1 ].forEach(function(val) { |
michael@0 | 89 | exceptionHappened = false; |
michael@0 | 90 | try { |
michael@0 | 91 | cue[prop] = val; |
michael@0 | 92 | } catch(e) { |
michael@0 | 93 | exceptionHappened = true; |
michael@0 | 94 | is(e.name, "IndexSizeError", "Should have thrown IndexSizeError."); |
michael@0 | 95 | } |
michael@0 | 96 | ok(exceptionHappened, "Exception should have happened."); |
michael@0 | 97 | }); |
michael@0 | 98 | } |
michael@0 | 99 | |
michael@0 | 100 | checkPercentageValue("size"); |
michael@0 | 101 | checkPercentageValue("position"); |
michael@0 | 102 | |
michael@0 | 103 | ok(cue.snapToLines, "Cue's snapToLines should be set by set."); |
michael@0 | 104 | cue.snapToLines = false; |
michael@0 | 105 | ok(!cue.snapToLines, "Cue's snapToLines should not be set."); |
michael@0 | 106 | |
michael@0 | 107 | function checkEnumValue(prop, initialVal, acceptedValues) { |
michael@0 | 108 | ok(prop in cue, prop + " should be a property on VTTCue."); |
michael@0 | 109 | is(cue[prop], initialVal, "Cue's " + prop + " should be " + initialVal); |
michael@0 | 110 | cue[prop] = "bogus"; |
michael@0 | 111 | is(cue[prop], initialVal, "Cue's " + prop + " should be " + initialVal); |
michael@0 | 112 | acceptedValues.forEach(function(val) { |
michael@0 | 113 | cue[prop] = val; |
michael@0 | 114 | is(cue[prop], val, "Cue's " + prop + " should be " + val); |
michael@0 | 115 | if (typeof val === "string") { |
michael@0 | 116 | cue[prop] = val.toUpperCase(); |
michael@0 | 117 | is(cue[prop], val, "Cue's " + prop + " should be " + val); |
michael@0 | 118 | } |
michael@0 | 119 | }); |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | checkEnumValue("align", "middle", [ "start", "left", "middle", "right", "end" ]); |
michael@0 | 123 | checkEnumValue("vertical", "", [ "", "lr", "rl" ]); |
michael@0 | 124 | |
michael@0 | 125 | // Check that cue line align works properly |
michael@0 | 126 | is(cue.lineAlign, "start", "Cue's default line alignment should be start."); |
michael@0 | 127 | |
michael@0 | 128 | exceptionHappened = false; |
michael@0 | 129 | try { |
michael@0 | 130 | cue.lineAlign = "left"; |
michael@0 | 131 | } catch(e) { |
michael@0 | 132 | exceptionHappened = true; |
michael@0 | 133 | is(e.name, "SyntaxError", "Should have thrown SyntaxError."); |
michael@0 | 134 | } |
michael@0 | 135 | ok(exceptionHappened, "Exception should have happened."); |
michael@0 | 136 | |
michael@0 | 137 | exceptionHappened = false; |
michael@0 | 138 | try { |
michael@0 | 139 | cue.lineAlign = "right"; |
michael@0 | 140 | } catch(e) { |
michael@0 | 141 | exceptionHappened = true; |
michael@0 | 142 | is(e.name, "SyntaxError", "Should have thrown SyntaxError."); |
michael@0 | 143 | } |
michael@0 | 144 | ok(exceptionHappened, "Exception should have happened."); |
michael@0 | 145 | |
michael@0 | 146 | cue.lineAlign = "middle"; |
michael@0 | 147 | is(cue.lineAlign, "middle", "Cue's line align should be middle."); |
michael@0 | 148 | cue.lineAlign = "START"; |
michael@0 | 149 | is(cue.lineAlign, "middle", "Cue's line align should be middle."); |
michael@0 | 150 | cue.lineAlign = "end"; |
michael@0 | 151 | is(cue.lineAlign, "end", "Cue's line align should be end."); |
michael@0 | 152 | |
michael@0 | 153 | // Check that cue position align works properly |
michael@0 | 154 | is(cue.positionAlign, "middle", "Cue's default position alignment should be middle."); |
michael@0 | 155 | |
michael@0 | 156 | var exceptionHappened = false; |
michael@0 | 157 | try { |
michael@0 | 158 | cue.positionAlign = "left"; |
michael@0 | 159 | } catch(e) { |
michael@0 | 160 | exceptionHappened = true; |
michael@0 | 161 | is(e.name, "SyntaxError", "Should have thrown SyntaxError."); |
michael@0 | 162 | } |
michael@0 | 163 | ok(exceptionHappened, "Exception should have happened."); |
michael@0 | 164 | |
michael@0 | 165 | exceptionHappened = false; |
michael@0 | 166 | try { |
michael@0 | 167 | cue.positionAlign = "right"; |
michael@0 | 168 | } catch(e) { |
michael@0 | 169 | exceptionHappened = true; |
michael@0 | 170 | is(e.name, "SyntaxError", "Should have thrown SyntaxError."); |
michael@0 | 171 | } |
michael@0 | 172 | ok(exceptionHappened, "Exception should have happened."); |
michael@0 | 173 | |
michael@0 | 174 | cue.positionAlign = "start"; |
michael@0 | 175 | is(cue.positionAlign, "start", "Cue's position align should be start."); |
michael@0 | 176 | cue.positionAlign = "end"; |
michael@0 | 177 | is(cue.positionAlign, "end", "Cue's position align should be end."); |
michael@0 | 178 | |
michael@0 | 179 | // Check cue.line |
michael@0 | 180 | is(cue.line, "auto", "Cue's line value should initially be auto."); |
michael@0 | 181 | cue.line = 12410 |
michael@0 | 182 | is(cue.line, 12410, "Cue's line value should now be 12410."); |
michael@0 | 183 | cue.line = "auto"; |
michael@0 | 184 | is(cue.line, "auto", "Cue's line value should now be auto."); |
michael@0 | 185 | |
michael@0 | 186 | // Check that we can create and add new VTTCues |
michael@0 | 187 | var vttCue = new VTTCue(3.999, 4, "foo"); |
michael@0 | 188 | is(vttCue.track, undefined, "Cue's track should be undefined."); |
michael@0 | 189 | trackElement.track.addCue(vttCue); |
michael@0 | 190 | is(cue.track, trackElement.track, "Cue's track should be defined."); |
michael@0 | 191 | is(cueList.length, 7, "Cue list length should now be 7."); |
michael@0 | 192 | |
michael@0 | 193 | // Check that new VTTCue was added correctly |
michael@0 | 194 | cue = cueList[6]; |
michael@0 | 195 | is(cue.startTime, 3.999, "Cue's start time should be 3.999."); |
michael@0 | 196 | is(cue.endTime, 4, "Cue's end time should be 4."); |
michael@0 | 197 | is(cue.text, "foo", "Cue's text should be foo."); |
michael@0 | 198 | |
michael@0 | 199 | // Adding the same cue again should not increase the cue count. |
michael@0 | 200 | trackElement.track.addCue(vttCue); |
michael@0 | 201 | is(cueList.length, 7, "Cue list length should be 7."); |
michael@0 | 202 | |
michael@0 | 203 | // Check that we are able to remove cues. |
michael@0 | 204 | trackElement.track.removeCue(cue); |
michael@0 | 205 | is(cueList.length, 6, "Cue list length should be 6."); |
michael@0 | 206 | |
michael@0 | 207 | exceptionHappened = false; |
michael@0 | 208 | try { |
michael@0 | 209 | // We should not be able to remove a cue that is not in the list. |
michael@0 | 210 | cue = new VTTCue(1, 2, "foo"); |
michael@0 | 211 | trackElement.track.removeCue(cue); |
michael@0 | 212 | } catch (e) { |
michael@0 | 213 | // "NotFoundError" should be thrown when trying to remove a cue that is |
michael@0 | 214 | // not in the list. |
michael@0 | 215 | is(e.name, "NotFoundError", "Should have thrown NotFoundError."); |
michael@0 | 216 | exceptionHappened = true; |
michael@0 | 217 | } |
michael@0 | 218 | // If this is false then we did not throw an error and probably removed a cue |
michael@0 | 219 | // when we shouln't have. |
michael@0 | 220 | ok(exceptionHappened, "Exception should have happened."); |
michael@0 | 221 | |
michael@0 | 222 | is(cueList.length, 6, "Cue list length should be 6."); |
michael@0 | 223 | |
michael@0 | 224 | video.currentTime = 2; |
michael@0 | 225 | isnot(trackElement.track.activeCues, null); |
michael@0 | 226 | |
michael@0 | 227 | trackElement.track.mode = "disabled"; |
michael@0 | 228 | is(trackElement.track.activeCues, null); |
michael@0 | 229 | |
michael@0 | 230 | trackElement.track.mode = "showing"; |
michael@0 | 231 | video.currentTime = 0; |
michael@0 | 232 | |
michael@0 | 233 | var regionInfo = [ |
michael@0 | 234 | { lines: 2, width: 30 }, |
michael@0 | 235 | { lines: 4, width: 20 }, |
michael@0 | 236 | { lines: 2, width: 30 } |
michael@0 | 237 | ]; |
michael@0 | 238 | |
michael@0 | 239 | for (var i = 0; i < regionInfo.length; i++) { |
michael@0 | 240 | var cue = cueList[i]; |
michael@0 | 241 | isnot(cue.region, null, "Cue at " + i + " should have a region."); |
michael@0 | 242 | for (var key in regionInfo[i]) { |
michael@0 | 243 | is(cue.region[key], regionInfo[i][key], "Region should have a " + key + |
michael@0 | 244 | " property with a value of " + regionInfo[i][key]) |
michael@0 | 245 | } |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | // Test TextTrack::ActiveCues. |
michael@0 | 249 | var cueInfo = [ |
michael@0 | 250 | { startTime: 0.51, endTime: 0.71, ids: ["Cue 01"] }, |
michael@0 | 251 | { startTime: 0.72, endTime: 1.19, ids: [] }, |
michael@0 | 252 | { startTime: 1.2, endTime: 1.9, ids: [2] }, |
michael@0 | 253 | { startTime: 2, endTime: 2.4, ids: [2, 2.5] }, |
michael@0 | 254 | { startTime: 2.41, endTime: 2.70, ids: [2.5] }, |
michael@0 | 255 | { startTime: 2.71, endTime: 2.91, ids: [2.5, 3] }, |
michael@0 | 256 | { startTime: 2.92, endTime: 3.216, ids: [2.5] }, |
michael@0 | 257 | { startTime: 3.217, endTime: 3.5, ids: [2.5, 4, 5] }, |
michael@0 | 258 | { startTime: 3.51, endTime: 3.989, ids: [4, 5] }, |
michael@0 | 259 | { startTime: 3.99, endTime: 4, ids: [] } |
michael@0 | 260 | ]; |
michael@0 | 261 | |
michael@0 | 262 | video.addEventListener("timeupdate", function() { |
michael@0 | 263 | var activeCues = trackElement.track.activeCues, |
michael@0 | 264 | found = false, |
michael@0 | 265 | playbackTime = video.currentTime; |
michael@0 | 266 | |
michael@0 | 267 | for (var i = 0; i < cueInfo.length; i++) { |
michael@0 | 268 | var cue = cueInfo[i]; |
michael@0 | 269 | if (playbackTime >= cue.startTime && playbackTime <= cue.endTime) { |
michael@0 | 270 | is(activeCues.length, cue.ids.length, "There should be " + cue.ids.length + " currently active cue(s)."); |
michael@0 | 271 | for (var j = 0; j < cue.ids.length; j++) { |
michael@0 | 272 | isnot(activeCues.getCueById(cue.ids[j]), undefined, "The cue with ID " + cue.ids[j] + " should be active."); |
michael@0 | 273 | } |
michael@0 | 274 | break; |
michael@0 | 275 | } |
michael@0 | 276 | } |
michael@0 | 277 | }); |
michael@0 | 278 | |
michael@0 | 279 | video.addEventListener("ended", function(){ |
michael@0 | 280 | SimpleTest.finish(); |
michael@0 | 281 | }); |
michael@0 | 282 | |
michael@0 | 283 | video.play(); |
michael@0 | 284 | }); |
michael@0 | 285 | } |
michael@0 | 286 | ); |
michael@0 | 287 | |
michael@0 | 288 | </script> |
michael@0 | 289 | </pre> |
michael@0 | 290 | </body> |
michael@0 | 291 | </html> |