Bug 1318542 - Make CueStyleBox apply ::cue. r=rillian, heycam draft
authorbechen <bechen@mozilla.com>
Wed, 05 Apr 2017 10:47:36 +0800
changeset 555878 28966bb852714160499328b890b38396452b604d
parent 555725 b043233ec04f06768d59dcdfb9e928142280f3cc
child 555879 588511e9e641ce2fcb10809dc71d29fb071b56b1
push id52372
push userbechen@mozilla.com
push dateWed, 05 Apr 2017 03:09:42 +0000
reviewersrillian, heycam
bugs1318542
milestone55.0a1
Bug 1318542 - Make CueStyleBox apply ::cue. r=rillian, heycam MozReview-Commit-ID: CNhFlffGAfh * * * [mq]: trash MozReview-Commit-ID: KY2DfqPDmx0
dom/media/webvtt/vtt.jsm
layout/style/nsCSSPseudoElementList.h
layout/style/res/html.css
--- a/dom/media/webvtt/vtt.jsm
+++ b/dom/media/webvtt/vtt.jsm
@@ -377,19 +377,22 @@ Cu.import('resource://gre/modules/Servic
       if (f[1]) {
         f = f[1].slice(0, 3).padEnd(3, "0");
       } else {
         f = "000";
       }
       return hours + ':' + minutes + ':' + seconds + '.' + f;
     }
 
+    var isFirefox = (/firefox/i.test(window.navigator.userAgent));
     var root;
     if (bReturnFrag) {
       root = window.document.createDocumentFragment();
+    } else if (isFirefox) {
+      root = window.document.createElement("div", {pseudo: "::cue"});
     } else {
       root = window.document.createElement("div");
     }
     var current = root,
         t,
         tagStack = [];
 
     while ((t = nextToken()) !== null) {
@@ -464,16 +467,18 @@ Cu.import('resource://gre/modules/Servic
     return val === 0 ? 0 : val + unit;
   };
 
   // Constructs the computed display state of the cue (a div). Places the div
   // into the overlay which should be a block level element (usually a div).
   function CueStyleBox(window, cue, styleOptions) {
     var isIE8 = (typeof navigator !== "undefined") &&
       (/MSIE\s8\.0/).test(navigator.userAgent);
+
+    var isFirefox = (/firefox/i.test(window.navigator.userAgent));
     var color = "rgba(255, 255, 255, 1)";
     var backgroundColor = "rgba(0, 0, 0, 0.8)";
 
     if (isIE8) {
       color = "rgb(255, 255, 255)";
       backgroundColor = "rgb(0, 0, 0)";
     }
 
@@ -481,41 +486,43 @@ Cu.import('resource://gre/modules/Servic
     this.cue = cue;
 
     // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
     // have inline positioning and will function as the cue background box.
     this.cueDiv = parseContent(window, cue.text, false);
     var styles = {
       color: color,
       backgroundColor: backgroundColor,
-      position: "relative",
-      left: 0,
-      right: 0,
-      top: 0,
-      bottom: 0,
-      display: "inline"
+      display: "inline",
+      font: styleOptions.font,
+      whiteSpace: "pre-line",
     };
+    if (isFirefox) {
+      delete styles.color;
+      delete styles.backgroundColor;
+      delete styles.font;
+      delete styles.whiteSpace;
+    }
 
     if (!isIE8) {
       styles.writingMode = cue.vertical === "" ? "horizontal-tb"
                                                : cue.vertical === "lr" ? "vertical-lr"
                                                                        : "vertical-rl";
       styles.unicodeBidi = "plaintext";
     }
     this.applyStyles(styles, this.cueDiv);
 
     // Create an absolutely positioned div that will be used to position the cue
     // div.
-    this.div = window.document.createElement("div");
     styles = {
+      position: "absolute",
       textAlign: cue.align,
-      font: styleOptions.font,
-      whiteSpace: "pre-line",
-      position: "absolute"
     };
+
+    this.div = window.document.createElement("div");
     this.applyStyles(styles);
 
     this.div.appendChild(this.cueDiv);
 
     // Calculate the distance from the reference edge of the viewport to the text
     // position of the cue box. The reference edge will be resolved later when
     // the box orientation styles are applied.
     var textPos = 0;
@@ -953,16 +960,17 @@ Cu.import('resource://gre/modules/Servic
         boxPositions.push(BoxPosition.getSimpleBoxPosition(controlBar));
       }
 
       for (var i = 0; i < cues.length; i++) {
         cue = cues[i];
 
         // Compute the intial position and styles of the cue div.
         styleBox = new CueStyleBox(window, cue, styleOptions);
+        styleBox.cueDiv.style.setProperty("--cue-font-size", fontSize + "px");
         paddedOverlay.appendChild(styleBox.div);
 
         // Move the cue div to it's correct line position.
         moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
 
         // Remember the computed div so that we don't have to recompute it later
         // if we don't have too.
         cue.displayState = styleBox.div;
--- a/layout/style/nsCSSPseudoElementList.h
+++ b/layout/style/nsCSSPseudoElementList.h
@@ -25,16 +25,19 @@
 // OUTPUT_CLASS=nsCSSPseudoElements
 // MACRO_NAME=CSS_PSEUDO_ELEMENT
 
 CSS_PSEUDO_ELEMENT(after, ":after", CSS_PSEUDO_ELEMENT_IS_CSS2)
 CSS_PSEUDO_ELEMENT(before, ":before", CSS_PSEUDO_ELEMENT_IS_CSS2)
 
 CSS_PSEUDO_ELEMENT(backdrop, ":backdrop", 0)
 
+CSS_PSEUDO_ELEMENT(cue, ":cue", CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC |
+                                CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE)
+
 CSS_PSEUDO_ELEMENT(firstLetter, ":first-letter",
                    CSS_PSEUDO_ELEMENT_IS_CSS2 |
                    CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
 CSS_PSEUDO_ELEMENT(firstLine, ":first-line",
                    CSS_PSEUDO_ELEMENT_IS_CSS2 |
                    CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
 
 CSS_PSEUDO_ELEMENT(mozSelection, ":-moz-selection",
--- a/layout/style/res/html.css
+++ b/layout/style/res/html.css
@@ -771,16 +771,24 @@ audio[controls] {
 
 video > .caption-box {
   width: 100%;
   height: 100%;
   position: relative;
   overflow: hidden;
 }
 
+/* ::cue default settings */
+::cue {
+  color: rgba(255, 255, 255, 1);
+  white-space: pre-line;
+  background-color: rgba(0, 0, 0, 0.8);
+  font: var(--cue-font-size) sans-serif;
+}
+
 /* datetime elements */
 
 input[type="time"] > xul|datetimebox {
   display: flex;
   -moz-binding: url("chrome://global/content/bindings/datetimebox.xml#time-input");
 }
 
 input[type="date"] > xul|datetimebox {