Bug 1307710 - part1: Return Documentfragment instead of div for convertCueToDOMTree. r=rillian, smaug draft
authorbechen <bechen@mozilla.com>
Wed, 01 Mar 2017 15:01:52 +0800
changeset 490736 92fcce340a8ed6250dc292f6b8851baf64f9ebcd
parent 490433 1bc2ad020aee2830e0a7941f10958dbec108c254
child 490737 041252e2153fedb856e1c37cf6c1c1e75bbb09a7
push id47210
push userbechen@mozilla.com
push dateWed, 01 Mar 2017 08:00:49 +0000
reviewersrillian, smaug
bugs1307710
milestone54.0a1
Bug 1307710 - part1: Return Documentfragment instead of div for convertCueToDOMTree. r=rillian, smaug MozReview-Commit-ID: KV1MNaMhNOG
dom/media/TextTrackCue.cpp
dom/media/webvtt/nsIWebVTTParserWrapper.idl
dom/media/webvtt/vtt.jsm
--- a/dom/media/TextTrackCue.cpp
+++ b/dom/media/TextTrackCue.cpp
@@ -128,28 +128,20 @@ TextTrackCue::GetCueAsHTML()
     ClearOnShutdown(&sParserWrapper);
   }
 
   nsPIDOMWindowInner* window = mDocument->GetInnerWindow();
   if (!window) {
     return mDocument->CreateDocumentFragment();
   }
 
-  nsCOMPtr<nsIDOMHTMLElement> div;
+  nsCOMPtr<nsIDOMDocumentFragment> frag;
   sParserWrapper->ConvertCueToDOMTree(window, this,
-                                      getter_AddRefs(div));
-  nsCOMPtr<nsINode> divNode = do_QueryInterface(div);
-  if (!divNode) {
-    return mDocument->CreateDocumentFragment();
-  }
-  RefPtr<DocumentFragment> docFrag = mDocument->CreateDocumentFragment();
-  IgnoredErrorResult rv;
-  docFrag->AppendChild(*divNode, rv);
-
-  return docFrag.forget();
+                                      getter_AddRefs(frag));
+  return frag.forget().downcast<DocumentFragment>();
 }
 
 void
 TextTrackCue::SetTrackElement(HTMLTrackElement* aTrackElement)
 {
   mTrackElement = aTrackElement;
 }
 
--- a/dom/media/webvtt/nsIWebVTTParserWrapper.idl
+++ b/dom/media/webvtt/nsIWebVTTParserWrapper.idl
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMHTMLElement;
+interface nsIDOMDocumentFragment;
 interface nsIWebVTTListener;
 interface mozIDOMWindow;
 interface nsIVariant;
 
 /**
  * Interface for a wrapper of a JS WebVTT parser (vtt.js).
  */
 [scriptable, uuid(8dfe016e-1701-4618-9f5e-9a6154e853f0)]
@@ -55,18 +55,18 @@ interface nsIWebVTTParserWrapper : nsISu
    * Convert the text content of a WebVTT cue to a document fragment so that
    * we can display it on the page.
    *
    * @param window A window object with which the document fragment will be
    *               created.
    * @param cue    The cue whose content will be converted to a document
    *               fragment.
    */
-  nsIDOMHTMLElement convertCueToDOMTree(in mozIDOMWindow window,
-                                        in nsISupports cue);
+  nsIDOMDocumentFragment convertCueToDOMTree(in mozIDOMWindow window,
+                                             in nsISupports cue);
 
 
   /**
    * Compute the display state of the VTTCues in cues along with any VTTRegions
    * that they might be in. First, it computes the positioning and styling of
    * the cues and regions passed and converts them into a DOM tree rooted at
    * a containing HTMLDivElement. It then adjusts those computed divs for
    * overlap avoidance using the dimensions of 'overlay'. Finally, it adds the
--- a/dom/media/webvtt/vtt.jsm
+++ b/dom/media/webvtt/vtt.jsm
@@ -298,17 +298,17 @@ Cu.import('resource://gre/modules/Servic
     lang: "lang"
   };
 
   var NEEDS_PARENT = {
     rt: "ruby"
   };
 
   // Parse content into a document fragment.
-  function parseContent(window, input) {
+  function parseContent(window, input, bReturnFrag) {
     function nextToken() {
       // Check for end-of-string.
       if (!input) {
         return null;
       }
 
       // Consume 'n' characters from the input.
       function consume(result) {
@@ -348,18 +348,23 @@ Cu.import('resource://gre/modules/Servic
       element.localName = tagName;
       var name = TAG_ANNOTATION[type];
       if (name && annotation) {
         element[name] = annotation.trim();
       }
       return element;
     }
 
-    var rootDiv = window.document.createElement("div"),
-        current = rootDiv,
+    var root;
+    if (bReturnFrag) {
+      root = window.document.createDocumentFragment();
+    } else {
+      root = window.document.createElement("div");
+    }
+    var current = root,
         t,
         tagStack = [];
 
     while ((t = nextToken()) !== null) {
       if (t[0] === '<') {
         if (t[1] === "/") {
           // If the closing tag matches, move back up to the parent node.
           if (tagStack.length &&
@@ -404,17 +409,17 @@ Cu.import('resource://gre/modules/Servic
         current = node;
         continue;
       }
 
       // Text nodes are leaf nodes.
       current.appendChild(window.document.createTextNode(unescape(t)));
     }
 
-    return rootDiv;
+    return root;
   }
 
   function StyleBox() {
   }
 
   // Apply styles to a div. If there is no div passed then it defaults to the
   // div on 'this'.
   StyleBox.prototype.applyStyles = function(styles, div) {
@@ -443,17 +448,17 @@ Cu.import('resource://gre/modules/Servic
       backgroundColor = "rgb(0, 0, 0)";
     }
 
     StyleBox.call(this);
     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);
+    this.cueDiv = parseContent(window, cue.text, false);
     var styles = {
       color: color,
       backgroundColor: backgroundColor,
       position: "relative",
       left: 0,
       right: 0,
       top: 0,
       bottom: 0,
@@ -832,20 +837,20 @@ Cu.import('resource://gre/modules/Servic
           throw new Error("Error - expected string data.");
         }
         return decodeURIComponent(encodeURIComponent(data));
       }
     };
   };
 
   WebVTT.convertCueToDOMTree = function(window, cuetext) {
-    if (!window || !cuetext) {
+    if (!window) {
       return null;
     }
-    return parseContent(window, cuetext);
+    return parseContent(window, cuetext, true);
   };
 
   var FONT_SIZE_PERCENT = 0.05;
   var FONT_STYLE = "sans-serif";
   var CUE_BACKGROUND_PADDING = "1.5%";
 
   // Runs the processing model over the cues and regions passed to it.
   // @param overlay A block level element (usually a div) that the computed cues