Bug 978163 - Part 3: Vtt.js should add VTTRegions directly to the VTTCue. r=rillian
authorRick Eyre <rick.eyre@hotmail.com>
Tue, 11 Mar 2014 13:36:07 -0400
changeset 191640 a35718f7ef732b8cb5a2bb74a5a384f1b47c3d31
parent 191639 3f3712a1272945243febeca51d30605b1b9b6691
child 191641 2b3efd1687ecf27e7c583615b6ed381d39e9e65c
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian
bugs978163, 24380
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 978163 - Part 3: Vtt.js should add VTTRegions directly to the VTTCue. r=rillian See spec bug https://www.w3.org/Bugs/Public/show_bug.cgi?id=24380.
content/media/webvtt/vtt.jsm
--- a/content/media/webvtt/vtt.jsm
+++ b/content/media/webvtt/vtt.jsm
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 this.EXPORTED_SYMBOLS = ["WebVTTParser"];
 
 /**
  * Code below is vtt.js the JS WebVTTParser.
  * Current source code can be found at http://github.com/andreasgal/vtt.js
  *
- * Code taken from commit b812cd783d4284de1bc6b0349b7bda151052a1df
+ * Code taken from commit ae06fb75793d3a8171a8c34666c2a3c32b5fde89
  */
 /**
  * Copyright 2013 vtt.js Contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
@@ -132,17 +132,17 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
         continue;
       }
       var k = kv[0];
       var v = kv[1];
       callback(k, v);
     }
   }
 
-  function parseCue(input, cue) {
+  function parseCue(input, cue, regionList) {
     // 4.1 WebVTT timestamp
     function consumeTimeStamp() {
       var ts = parseTimeStamp(input);
       if (ts === null) {
         throw new ParsingError("Malformed time stamp.");
       }
       // Remove time stamp from input.
       input = input.replace(/^[^\sa-zA-Z-]+/, "");
@@ -151,17 +151,23 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
 
     // 4.4.2 WebVTT cue settings
     function consumeCueSettings(input, cue) {
       var settings = new Settings();
 
       parseOptions(input, function (k, v) {
         switch (k) {
         case "region":
-          settings.set(k, v);
+          // Find the last region we parsed with the same region id.
+          for (var i = regionList.length - 1; i >= 0; i--) {
+            if (regionList[i].id === v) {
+              settings.set(k, regionList[i].region);
+              break;
+            }
+          }
           break;
         case "vertical":
           settings.alt(k, v, ["rl", "lr"]);
           break;
         case "line":
           var vals = v.split(","),
               vals0 = vals[0];
           settings.integer(k, vals0);
@@ -183,17 +189,17 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
           break;
         case "align":
           settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
           break;
         }
       }, /:/, /\s/);
 
       // Apply default values for any missing fields.
-      cue.regionId = settings.get("region", "");
+      cue.region = settings.get("region", null);
       cue.vertical = settings.get("vertical", "");
       cue.line = settings.get("line", "auto");
       cue.lineAlign = settings.get("lineAlign", "start");
       cue.snapToLines = settings.get("snapToLines", true);
       cue.size = settings.get("size", 100);
       cue.align = settings.get("align", "middle");
       cue.position = settings.get("position", {
         start: 0,
@@ -1022,16 +1028,17 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
     styleBox.move(bestPosition.toCSSCompatValues(containerBox));
   }
 
   function WebVTTParser(window, decoder) {
     this.window = window;
     this.state = "INITIAL";
     this.buffer = "";
     this.decoder = decoder || new TextDecoder("utf8");
+    this.regionList = [];
   }
 
   // Helper to allow strings to be decoded instead of the default binary utf8 data.
   WebVTTParser.StringDecoder = function() {
     return {
       decode: function(data) {
         if (!data) {
           return "";
@@ -1183,29 +1190,35 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
             settings.set(k + "Y", anchor.get("y"));
             break;
           case "scroll":
             settings.alt(k, v, ["up"]);
             break;
           }
         }, /=/, /\s/);
 
-        // Register the region, using default values for any values that were not
+        // Create the region, using default values for any values that were not
         // specified.
-        if (self.onregion && settings.has("id")) {
+        if (settings.has("id")) {
           var region = new self.window.VTTRegion();
-          region.id = settings.get("id");
           region.width = settings.get("width", 100);
           region.lines = settings.get("lines", 3);
           region.regionAnchorX = settings.get("regionanchorX", 0);
           region.regionAnchorY = settings.get("regionanchorY", 100);
           region.viewportAnchorX = settings.get("viewportanchorX", 0);
           region.viewportAnchorY = settings.get("viewportanchorY", 100);
           region.scroll = settings.get("scroll", "");
-          self.onregion(region);
+          // Register the region.
+          self.onregion && self.onregion(region);
+          // Remember the VTTRegion for later in case we parse any VTTCues that
+          // reference it.
+          self.regionList.push({
+            id: settings.get("id"),
+            region: region
+          });
         }
       }
 
       // 3.2 WebVTT metadata header syntax
       function parseHeader(input) {
         parseOptions(input, function (k, v) {
           switch (k) {
           case "Region":
@@ -1276,17 +1289,17 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
               self.cue.id = line;
               continue;
             }
             // Process line as start of a cue.
             /*falls through*/
           case "CUE":
             // 40 - Collect cue timings and settings.
             try {
-              parseCue(line, self.cue);
+              parseCue(line, self.cue, self.regionList);
             } catch (e) {
               // If it's not a parsing error then throw it to the consumer.
               if (!(e instanceof ParsingError)) {
                 throw e;
               }
               // In case of an error ignore rest of the cue.
               self.cue = null;
               self.state = "BADCUE";