Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / track / vtt / VTTCue.cpp
index 2766960..d21ce34 100644 (file)
 #include "config.h"
 #include "core/html/track/vtt/VTTCue.h"
 
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/core/v8/ExceptionMessages.h"
+#include "bindings/core/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/events/Event.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLDivElement.h"
 #include "core/html/track/TextTrack.h"
 #include "core/html/track/TextTrackCueList.h"
 #include "core/html/track/vtt/VTTRegionList.h"
 #include "core/html/track/vtt/VTTScanner.h"
 #include "core/rendering/RenderVTTCue.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/text/BidiResolver.h"
 #include "platform/text/TextRunIterator.h"
 #include "wtf/MathExtras.h"
 #include "wtf/text/StringBuilder.h"
 
-namespace WebCore {
+namespace blink {
 
 static const int undefinedPosition = -1;
+static const int undefinedSize = -1;
 
 static const CSSValueID displayWritingModeMap[] = {
     CSSValueHorizontalTb, CSSValueVerticalRl, CSSValueVerticalLr
@@ -114,12 +116,10 @@ static const String& verticalGrowingRightKeyword()
     return verticallr;
 }
 
-static bool isInvalidPercentage(double value, ExceptionState& exceptionState)
+static bool isInvalidPercentage(int value, ExceptionState& exceptionState)
 {
-    if (TextTrackCue::isInfiniteOrNonNumber(value, exceptionState))
-        return true;
     if (value < 0 || value > 100) {
-        exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(value) + ") is not between 0 and 100.");
+        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0, ExceptionMessages::InclusiveBound, 100, ExceptionMessages::InclusiveBound));
         return true;
     }
     return false;
@@ -200,6 +200,12 @@ RenderObject* VTTCueBox::createRenderer(RenderStyle*)
     return new RenderVTTCue(this);
 }
 
+void VTTCueBox::trace(Visitor* visitor)
+{
+    visitor->trace(m_cue);
+    HTMLDivElement::trace(visitor);
+}
+
 VTTCue::VTTCue(Document& document, double startTime, double endTime, const String& text)
     : TextTrackCue(startTime, endTime)
     , m_text(text)
@@ -209,19 +215,29 @@ VTTCue::VTTCue(Document& document, double startTime, double endTime, const Strin
     , m_cueSize(100)
     , m_writingDirection(Horizontal)
     , m_cueAlignment(Middle)
-    , m_vttNodeTree(0)
+    , m_vttNodeTree(nullptr)
     , m_cueBackgroundBox(HTMLDivElement::create(document))
     , m_displayDirection(CSSValueLtr)
+    , m_displaySize(undefinedSize)
     , m_snapToLines(true)
     , m_displayTreeShouldChange(true)
     , m_notifyRegion(true)
 {
     ScriptWrappable::init(this);
+    UseCounter::count(document, UseCounter::VTTCue);
 }
 
 VTTCue::~VTTCue()
 {
-    displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+    // Using oilpan, if m_displayTree is in the document it will strongly keep
+    // the cue alive. Thus, if the cue is dead, either m_displayTree is not in
+    // the document or the entire document is dead too.
+#if !ENABLE(OILPAN)
+    // FIXME: This is scary, we should make the life cycle smarter so the destructor
+    // doesn't need to do DOM mutations.
+    if (m_displayTree)
+        m_displayTree->remove(ASSERT_NO_EXCEPTION);
+#endif
 }
 
 #ifndef NDEBUG
@@ -231,11 +247,11 @@ String VTTCue::toString() const
 }
 #endif
 
-PassRefPtr<VTTCueBox> VTTCue::displayTreeInternal()
+VTTCueBox& VTTCue::ensureDisplayTree()
 {
     if (!m_displayTree)
         m_displayTree = VTTCueBox::create(document(), this);
-    return m_displayTree;
+    return *m_displayTree;
 }
 
 void VTTCue::cueDidChange()
@@ -259,14 +275,8 @@ const String& VTTCue::vertical() const
     }
 }
 
-void VTTCue::setVertical(const String& value, ExceptionState& exceptionState)
+void VTTCue::setVertical(const String& value)
 {
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-vertical
-    // On setting, the text track cue writing direction must be set to the value given
-    // in the first cell of the row in the table above whose second cell is a
-    // case-sensitive match for the new value, if any. If none of the values match, then
-    // the user agent must instead throw a SyntaxError exception.
-
     WritingDirection direction = m_writingDirection;
     if (value == horizontalKeyword())
         direction = Horizontal;
@@ -275,7 +285,7 @@ void VTTCue::setVertical(const String& value, ExceptionState& exceptionState)
     else if (value == verticalGrowingRightKeyword())
         direction = VerticalGrowingRight;
     else
-        exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("vertical", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'rl', 'lr', and the empty string are accepted."));
+        ASSERT_NOT_REACHED();
 
     if (direction == m_writingDirection)
         return;
@@ -301,7 +311,7 @@ void VTTCue::setLine(int position, ExceptionState& exceptionState)
     // On setting, if the text track cue snap-to-lines flag is not set, and the new
     // value is negative or greater than 100, then throw an IndexSizeError exception.
     if (!m_snapToLines && (position < 0 || position > 100)) {
-        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::failedToSet("line", "TextTrackCue", "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100."));
+        exceptionState.throwDOMException(IndexSizeError, "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100.");
         return;
     }
 
@@ -368,14 +378,8 @@ const String& VTTCue::align() const
     }
 }
 
-void VTTCue::setAlign(const String& value, ExceptionState& exceptionState)
+void VTTCue::setAlign(const String& value)
 {
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-align
-    // On setting, the text track cue alignment must be set to the value given in the
-    // first cell of the row in the table above whose second cell is a case-sensitive
-    // match for the new value, if any. If none of the values match, then the user
-    // agent must instead throw a SyntaxError exception.
-
     CueAlignment alignment = m_cueAlignment;
     if (value == startKeyword())
         alignment = Start;
@@ -388,7 +392,7 @@ void VTTCue::setAlign(const String& value, ExceptionState& exceptionState)
     else if (value == rightKeyword())
         alignment = Right;
     else
-        exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("align", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'start', 'middle', 'end', 'left', and 'right' are accepted."));
+        ASSERT_NOT_REACHED();
 
     if (alignment == m_cueAlignment)
         return;
@@ -406,7 +410,7 @@ void VTTCue::setText(const String& text)
     cueWillChange();
     // Clear the document fragment but don't bother to create it again just yet as we can do that
     // when it is requested.
-    m_vttNodeTree = 0;
+    m_vttNodeTree = nullptr;
     m_text = text;
     cueDidChange();
 }
@@ -420,7 +424,7 @@ void VTTCue::createVTTNodeTree()
 void VTTCue::copyVTTNodeToDOMTree(ContainerNode* vttNode, ContainerNode* parent)
 {
     for (Node* node = vttNode->firstChild(); node; node = node->nextSibling()) {
-        RefPtr<Node> clonedNode;
+        RefPtrWillBeRawPtr<Node> clonedNode;
         if (node->isVTTElement())
             clonedNode = toVTTElement(node)->createEquivalentHTMLElement(document());
         else
@@ -431,19 +435,18 @@ void VTTCue::copyVTTNodeToDOMTree(ContainerNode* vttNode, ContainerNode* parent)
     }
 }
 
-PassRefPtr<DocumentFragment> VTTCue::getCueAsHTML()
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTCue::getCueAsHTML()
 {
     createVTTNodeTree();
-    RefPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
+    RefPtrWillBeRawPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
     copyVTTNodeToDOMTree(m_vttNodeTree.get(), clonedFragment.get());
     return clonedFragment.release();
 }
 
-PassRefPtr<DocumentFragment> VTTCue::createCueRenderingTree()
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTCue::createCueRenderingTree()
 {
-    RefPtr<DocumentFragment> clonedFragment;
     createVTTNodeTree();
-    clonedFragment = DocumentFragment::create(document());
+    RefPtrWillBeRawPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
     m_vttNodeTree->cloneChildNodes(clonedFragment.get());
     return clonedFragment.release();
 }
@@ -551,6 +554,9 @@ void VTTCue::calculateDisplayParameters()
     // Steps 10.2, 10.3
     m_displayDirection = determineTextDirection(m_vttNodeTree.get());
 
+    if (m_displayDirection == CSSValueRtl)
+        UseCounter::count(document(), UseCounter::VTTCueRenderRtl);
+
     // 10.4 If the text track cue writing direction is horizontal, then let
     // block-flow be 'tb'. Otherwise, if the text track cue writing direction is
     // vertical growing left, then let block-flow be 'lr'. Otherwise, the text
@@ -622,7 +628,7 @@ void VTTCue::calculateDisplayParameters()
             else
                 m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2;
             break;
-        case NumberOfAlignments:
+        default:
             ASSERT_NOT_REACHED();
         }
     } else {
@@ -639,7 +645,7 @@ void VTTCue::calculateDisplayParameters()
         case Middle:
             m_displayPosition.second = m_textPosition - m_displaySize / 2;
             break;
-        case NumberOfAlignments:
+        default:
             ASSERT_NOT_REACHED();
         }
     }
@@ -705,16 +711,16 @@ void VTTCue::updateDisplayTree(double movieTime)
     m_cueBackgroundBox->removeChildren();
 
     // Update the two sets containing past and future WebVTT objects.
-    RefPtr<DocumentFragment> referenceTree = createCueRenderingTree();
+    RefPtrWillBeRawPtr<DocumentFragment> referenceTree = createCueRenderingTree();
     markFutureAndPastNodes(referenceTree.get(), startTime(), movieTime);
     m_cueBackgroundBox->appendChild(referenceTree, ASSERT_NO_EXCEPTION);
 }
 
-PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
+PassRefPtrWillBeRawPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
 {
-    RefPtr<VTTCueBox> displayTree = displayTreeInternal();
+    RefPtrWillBeRawPtr<VTTCueBox> displayTree(ensureDisplayTree());
     if (!m_displayTreeShouldChange || !track()->isRendered())
-        return displayTree;
+        return displayTree.release();
 
     // 10.1 - 10.10
     calculateDisplayParameters();
@@ -751,7 +757,7 @@ PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
 
     // 10.15. Let cue's text track cue display state have the CSS boxes in
     // boxes.
-    return displayTree;
+    return displayTree.release();
 }
 
 void VTTCue::removeDisplayTree()
@@ -763,12 +769,33 @@ void VTTCue::removeDisplayTree()
             region->willRemoveVTTCueBox(m_displayTree.get());
     }
 
-    displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+    if (m_displayTree)
+        m_displayTree->remove(ASSERT_NO_EXCEPTION);
 }
 
 void VTTCue::updateDisplay(const IntSize& videoSize, HTMLDivElement& container)
 {
-    RefPtr<VTTCueBox> displayBox = getDisplayTree(videoSize);
+    UseCounter::count(document(), UseCounter::VTTCueRender);
+
+    if (m_writingDirection != Horizontal)
+        UseCounter::count(document(), UseCounter::VTTCueRenderVertical);
+
+    if (!m_snapToLines)
+        UseCounter::count(document(), UseCounter::VTTCueRenderSnapToLinesFalse);
+
+    if (m_linePosition != undefinedPosition)
+        UseCounter::count(document(), UseCounter::VTTCueRenderLineNotAuto);
+
+    if (m_textPosition != 50)
+        UseCounter::count(document(), UseCounter::VTTCueRenderPositionNot50);
+
+    if (m_cueSize != 100)
+        UseCounter::count(document(), UseCounter::VTTCueRenderSizeNot100);
+
+    if (m_cueAlignment != Middle)
+        UseCounter::count(document(), UseCounter::VTTCueRenderAlignNotMiddle);
+
+    RefPtrWillBeRawPtr<VTTCueBox> displayBox = getDisplayTree(videoSize);
     VTTRegion* region = 0;
     if (track()->regions())
         region = track()->regions()->getRegionById(regionId());
@@ -777,14 +804,14 @@ void VTTCue::updateDisplay(const IntSize& videoSize, HTMLDivElement& container)
         // If cue has an empty text track cue region identifier or there is no
         // WebVTT region whose region identifier is identical to cue's text
         // track cue region identifier, run the following substeps:
-        if (displayBox->hasChildNodes() && !container.contains(displayBox.get())) {
+        if (displayBox->hasChildren() && !container.contains(displayBox.get())) {
             // Note: the display tree of a cue is removed when the active flag of the cue is unset.
             container.appendChild(displayBox);
         }
     } else {
         // Let region be the WebVTT region whose region identifier
         // matches the text track cue region identifier of cue.
-        RefPtr<HTMLDivElement> regionNode = region->getDisplayTree(document());
+        RefPtrWillBeRawPtr<HTMLDivElement> regionNode = region->getDisplayTree(document());
 
         // Append the region to the viewport, if it was not already.
         if (!container.contains(regionNode.get()))
@@ -1045,6 +1072,7 @@ CSSValueID VTTCue::getCSSWritingMode() const
 
 int VTTCue::getCSSSize() const
 {
+    ASSERT(m_displaySize != undefinedSize);
     return m_displaySize;
 }
 
@@ -1068,4 +1096,12 @@ Document& VTTCue::document() const
     return m_cueBackgroundBox->document();
 }
 
-} // namespace WebCore
+void VTTCue::trace(Visitor* visitor)
+{
+    visitor->trace(m_vttNodeTree);
+    visitor->trace(m_cueBackgroundBox);
+    visitor->trace(m_displayTree);
+    TextTrackCue::trace(visitor);
+}
+
+} // namespace blink