Bug 1415821 - Support multi-line parsing for REGION/STYLE block. r=alwu draft
authorbechen@mozilla.com <bechen@mozilla.com>
Wed, 15 Nov 2017 10:25:02 +0800
changeset 698025 91a1342ced7dbdf5956fe1914b2ae4b27aab7bc8
parent 698024 ec51494805f2c83e06e65c2ad57c531ac7f21c91
child 698026 047e41d3ed400e333bf7340e5525d969218e63e1
child 698103 65e54177e6c9fbf964d50059fc38bed4fa3b7f78
push id89180
push userbmo:bechen@mozilla.com
push dateWed, 15 Nov 2017 06:25:27 +0000
reviewersalwu
bugs1415821
milestone58.0
Bug 1415821 - Support multi-line parsing for REGION/STYLE block. r=alwu MozReview-Commit-ID: HhRkv27UPO
dom/media/webvtt/vtt.jsm
--- a/dom/media/webvtt/vtt.jsm
+++ b/dom/media/webvtt/vtt.jsm
@@ -1195,17 +1195,16 @@ const { XPCOMUtils } = require("resource
           self.cue = null;
           self.state = "BADCUE";
         }
       }
 
       // 3.4 WebVTT region and WebVTT region settings syntax
       function parseRegion(input) {
         var settings = new Settings();
-
         parseOptions(input, function (k, v) {
           switch (k) {
           case "id":
             settings.set(k, v);
             break;
           case "width":
             settings.percent(k, v);
             break;
@@ -1270,58 +1269,81 @@ const { XPCOMUtils } = require("resource
         let signature = collectNextLine();
         if (!/^WEBVTT([ \t].*)?$/.test(signature)) {
           throw new ParsingError(ParsingError.Errors.BadSignature);
         } else {
           self.state = "HEADER";
         }
       }
 
+      function parseRegionOrStyle(input) {
+        switch (self.substate) {
+          case "REGION":
+            parseRegion(input);
+          break;
+          case "STYLE":
+            // TODO : not supported yet.
+          break;
+        }
+      }
       // Parsing the region and style information.
       // See spec, https://w3c.github.io/webvtt/#collect-a-webvtt-block
       //
       // There are sereval things would appear in header,
       //   1. Region or Style setting
       //   2. Garbage (meaningless string)
       //   3. Empty line
       //   4. Cue's timestamp
       // The case 4 happens when there is no line interval between the header
       // and the cue blocks. In this case, we should preserve the line and
       // return it for the next phase parsing.
       function parseHeader() {
         let line = null;
         while (self.buffer && self.state === "HEADER") {
           line = collectNextLine();
+          var tempStr = "";
+          if (/^REGION|^STYLE/.test(line)) {
+            self.substate = /^REGION/.test(line) ? "REGION" : "STYLE";
 
-          if (/^REGION|^STYLE/i.test(line)) {
-            parseOptions(line, function (k, v) {
-              switch (k.toUpperCase()) {
-              case "REGION":
-                parseRegion(v);
+            while (true) {
+              line = collectNextLine();
+              if (!line || maybeIsTimeStampFormat(line) || onlyContainsWhiteSpaces(line) || containsTimeDirectionSymbol(line)) {
+                // parse the tempStr and break the while loop.
+                parseRegionOrStyle(tempStr);
                 break;
-              case "STYLE":
-                // TODO : not supported yet.
-                break;
+              } else if (/^REGION|^STYLE/.test(line)) {
+                // The line is another REGION/STYLE, parse tempStr then reset tempStr.
+                // Don't break the while loop to parse the next REGION/STYLE.
+                parseRegionOrStyle(tempStr);
+                self.substate = /^REGION/.test(line) ? "REGION" : "STYLE";
+                tempStr = "";
+              } else {
+                tempStr += line;;
               }
-            }, ":");
-          } else if (maybeIsTimeStampFormat(line)) {
+            }
+          }
+
+          if (maybeIsTimeStampFormat(line)) {
             self.state = "CUE";
             break;
-          } else if (!line ||
-                     onlyContainsWhiteSpaces(line) ||
-                     containsTimeDirectionSymbol(line)) {
-            // empty line, whitespaces or string contains "-->"
+          } else if (containsTimeDirectionSymbol(line)) {
+            // string contains "-->"
+            break;
+          } else if (!line || onlyContainsWhiteSpaces(line)) {
+            // empty line, whitespaces
+            continue;
+          } else {
+            //It is an ID.
             break;
           }
-        }
+        } // self.state === "HEADER"
 
         // End parsing header part and doesn't see the timestamp.
         if (self.state === "HEADER") {
           self.state = "ID";
-          line = null
         }
         return line;
       }
 
       // 5.1 WebVTT file parsing.
       try {
         if (self.state === "INITIAL") {
           parseSignatureMayThrow();