#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
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;
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)
, 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
}
#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()
}
}
-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;
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;
// 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;
}
}
}
-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;
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;
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();
}
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
}
}
-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();
}
// 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
else
m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2;
break;
- case NumberOfAlignments:
+ default:
ASSERT_NOT_REACHED();
}
} else {
case Middle:
m_displayPosition.second = m_textPosition - m_displaySize / 2;
break;
- case NumberOfAlignments:
+ default:
ASSERT_NOT_REACHED();
}
}
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();
// 10.15. Let cue's text track cue display state have the CSS boxes in
// boxes.
- return displayTree;
+ return displayTree.release();
}
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());
// 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()))
int VTTCue::getCSSSize() const
{
+ ASSERT(m_displaySize != undefinedSize);
return m_displaySize;
}
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