Index: Source/core/html/track/vtt/VTTCue.cpp |
diff --git a/Source/core/html/track/vtt/VTTCue.cpp b/Source/core/html/track/vtt/VTTCue.cpp |
index e96b84963494dc62e91620fc17cdfe3ace7e9f28..e5ec5977a049c9d17e6c7f147c59d23d90aceef9 100644 |
--- a/Source/core/html/track/vtt/VTTCue.cpp |
+++ b/Source/core/html/track/vtt/VTTCue.cpp |
@@ -32,6 +32,7 @@ |
#include "bindings/core/v8/ExceptionMessages.h" |
#include "bindings/core/v8/ExceptionStatePlaceholder.h" |
+#include "bindings/core/v8/UnionTypesCore.h" |
#include "core/CSSPropertyNames.h" |
#include "core/CSSValueKeywords.h" |
#include "core/dom/DocumentFragment.h" |
@@ -46,6 +47,7 @@ |
#include "core/html/track/vtt/VTTRegionList.h" |
#include "core/html/track/vtt/VTTScanner.h" |
#include "core/rendering/RenderVTTCue.h" |
+#include "platform/FloatConversion.h" |
#include "platform/RuntimeEnabledFeatures.h" |
#include "platform/text/BidiResolver.h" |
#include "platform/text/TextRunIterator.h" |
@@ -54,6 +56,7 @@ |
namespace blink { |
+static const float autoPosition = -1; |
static const int undefinedPosition = -1; |
static const int undefinedSize = -1; |
@@ -69,6 +72,12 @@ static const CSSValueID displayAlignmentMap[] = { |
static_assert(WTF_ARRAY_LENGTH(displayAlignmentMap) == VTTCue::NumberOfAlignments, |
"displayAlignmentMap should have the same number of elements as VTTCue::NumberOfAlignments"); |
+static const String& autoKeyword() |
+{ |
+ DEFINE_STATIC_LOCAL(const String, autoString, ("auto")); |
+ return autoString; |
+} |
+ |
static const String& startKeyword() |
{ |
DEFINE_STATIC_LOCAL(const String, start, ("start")); |
@@ -116,10 +125,11 @@ static const String& verticalGrowingRightKeyword() |
return verticallr; |
} |
-static bool isInvalidPercentage(int value, ExceptionState& exceptionState) |
+template<typename NumberType> |
+static bool isInvalidPercentage(NumberType value, ExceptionState& exceptionState) |
{ |
if (value < 0 || value > 100) { |
- exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0, ExceptionMessages::InclusiveBound, 100, ExceptionMessages::InclusiveBound)); |
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange<NumberType>("value", value, 0, ExceptionMessages::InclusiveBound, 100, ExceptionMessages::InclusiveBound)); |
return true; |
} |
return false; |
@@ -211,7 +221,7 @@ VTTCue::VTTCue(Document& document, double startTime, double endTime, const Strin |
, m_text(text) |
, m_linePosition(undefinedPosition) |
, m_computedLinePosition(undefinedPosition) |
- , m_textPosition(50) |
+ , m_textPosition(autoPosition) |
, m_cueSize(100) |
, m_writingDirection(Horizontal) |
, m_cueAlignment(Middle) |
@@ -324,20 +334,45 @@ void VTTCue::setLine(int position, ExceptionState& exceptionState) |
cueDidChange(); |
} |
-void VTTCue::setPosition(int position, ExceptionState& exceptionState) |
+bool VTTCue::textPositionIsAuto() const |
{ |
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-position |
- // On setting, if the new value is negative or greater than 100, then throw an IndexSizeError exception. |
- // Otherwise, set the text track cue text position to the new value. |
- if (isInvalidPercentage(position, exceptionState)) |
- return; |
+ return m_textPosition == autoPosition; |
+} |
+ |
+void VTTCue::position(DoubleOrString& result) const |
+{ |
+ if (textPositionIsAuto()) |
+ result.setString(autoKeyword()); |
+ else |
+ result.setDouble(m_textPosition); |
+} |
+ |
+void VTTCue::setPosition(const DoubleOrString& position, ExceptionState& exceptionState) |
+{ |
+ float specifiedPosition = autoPosition; |
+ if (position.isString()) { |
+ // FIXME: Would be handled by bindings if the union had AutoKeyword and not DOMString. |
+ if (position.getAsString() != autoKeyword()) |
philipj_slow
2015/01/15 09:08:57
This should throw a TypeError, or whatever cue.ali
fs
2015/01/15 10:07:16
No, assigning an "invalid" enum value to an attrib
philipj_slow
2015/01/19 14:44:26
Acknowledged.
fs
2015/01/19 18:10:40
Actually, now I'm not so sure anymore... [1] (step
|
+ return; |
+ } else { |
+ ASSERT(position.isDouble()); |
+ double doublePosition = position.getAsDouble(); |
+ |
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-position |
philipj_slow
2015/01/15 09:08:57
Broken link, should be http://dev.w3.org/html5/web
|
+ // On setting, if the new value is negative or greater than 100, then throw an IndexSizeError exception. |
+ // Otherwise, set the text track cue text position to the new value. |
+ if (isInvalidPercentage(doublePosition, exceptionState)) |
+ return; |
+ |
+ specifiedPosition = narrowPrecisionToFloat(doublePosition); |
+ } |
// Otherwise, set the text track cue line position to the new value. |
- if (m_textPosition == position) |
+ if (m_textPosition == specifiedPosition) |
return; |
cueWillChange(); |
- m_textPosition = position; |
+ m_textPosition = specifiedPosition; |
cueDidChange(); |
} |
@@ -554,6 +589,34 @@ static CSSValueID determineTextDirection(DocumentFragment* vttRoot) |
return isLeftToRightDirection(textDirection) ? CSSValueLtr : CSSValueRtl; |
} |
+int VTTCue::calculateComputedTextPosition() const |
+{ |
+ // http://dev.w3.org/html5/webvtt/#dfn-text-track-cue-computed-text-position |
+ |
+ // 1. If the text track cue text position is numeric, then return the value |
+ // of the text track cue text position and abort these steps. (Otherwise, |
+ // the text track cue text position is the special value auto.) |
+ if (!textPositionIsAuto()) |
+ return static_cast<int>(m_textPosition); |
philipj_slow
2015/01/15 09:08:57
Per spec there is no rounding of position to integ
fs
2015/01/15 10:07:16
I was trying to avoid "two steps at once" here by
philipj_slow
2015/01/19 14:44:26
As long as the whole change ends up in the same mi
fs
2015/01/19 15:09:05
Yes, that should be feasible. I'm currently lookin
|
+ |
+ switch (m_cueAlignment) { |
+ // 2. If the text track cue text alignment is start or left, return 0 and abort these steps. |
+ case Start: |
+ case Left: |
+ return 0; |
+ // 3. If the text track cue text alignment is end or right, return 100 and abort these steps. |
+ case End: |
+ case Right: |
+ return 100; |
+ // 4. If the text track cue text alignment is middle, return 50 and abort these steps. |
+ case Middle: |
+ return 50; |
+ default: |
+ ASSERT_NOT_REACHED(); |
+ return 0; |
+ } |
+} |
+ |
void VTTCue::calculateDisplayParameters() |
{ |
createVTTNodeTree(); |
@@ -574,21 +637,22 @@ void VTTCue::calculateDisplayParameters() |
// 10.5 Determine the value of maximum size for cue as per the appropriate |
// rules from the following list: |
- int maximumSize = m_textPosition; |
+ int computedTextPosition = calculateComputedTextPosition(); |
+ int maximumSize = computedTextPosition; |
if ((m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueLtr) |
|| (m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueRtl) |
|| (m_writingDirection == Horizontal && m_cueAlignment == Left) |
|| (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == Start || m_cueAlignment == Left)) |
|| (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == Start || m_cueAlignment == Left))) { |
- maximumSize = 100 - m_textPosition; |
+ maximumSize = 100 - computedTextPosition; |
} else if ((m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueLtr) |
|| (m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueRtl) |
|| (m_writingDirection == Horizontal && m_cueAlignment == Right) |
|| (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == End || m_cueAlignment == Right)) |
|| (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == End || m_cueAlignment == Right))) { |
- maximumSize = m_textPosition; |
+ maximumSize = computedTextPosition; |
} else if (m_cueAlignment == Middle) { |
- maximumSize = m_textPosition <= 50 ? m_textPosition : (100 - m_textPosition); |
+ maximumSize = computedTextPosition <= 50 ? computedTextPosition : (100 - computedTextPosition); |
maximumSize = maximumSize * 2; |
} else { |
ASSERT_NOT_REACHED(); |
@@ -607,33 +671,33 @@ void VTTCue::calculateDisplayParameters() |
switch (m_cueAlignment) { |
case Start: |
if (m_displayDirection == CSSValueLtr) |
- m_displayPosition.first = m_textPosition; |
+ m_displayPosition.first = computedTextPosition; |
else |
- m_displayPosition.first = 100 - m_textPosition - m_displaySize; |
+ m_displayPosition.first = 100 - computedTextPosition - m_displaySize; |
break; |
case End: |
if (m_displayDirection == CSSValueRtl) |
- m_displayPosition.first = 100 - m_textPosition; |
+ m_displayPosition.first = 100 - computedTextPosition; |
else |
- m_displayPosition.first = m_textPosition - m_displaySize; |
+ m_displayPosition.first = computedTextPosition - m_displaySize; |
break; |
case Left: |
if (m_displayDirection == CSSValueLtr) |
- m_displayPosition.first = m_textPosition; |
+ m_displayPosition.first = computedTextPosition; |
else |
- m_displayPosition.first = 100 - m_textPosition; |
+ m_displayPosition.first = 100 - computedTextPosition; |
break; |
case Right: |
if (m_displayDirection == CSSValueLtr) |
- m_displayPosition.first = m_textPosition - m_displaySize; |
+ m_displayPosition.first = computedTextPosition - m_displaySize; |
else |
- m_displayPosition.first = 100 - m_textPosition - m_displaySize; |
+ m_displayPosition.first = 100 - computedTextPosition - m_displaySize; |
break; |
case Middle: |
if (m_displayDirection == CSSValueLtr) |
- m_displayPosition.first = m_textPosition - m_displaySize / 2; |
+ m_displayPosition.first = computedTextPosition - m_displaySize / 2; |
else |
- m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2; |
+ m_displayPosition.first = 100 - computedTextPosition - m_displaySize / 2; |
break; |
default: |
ASSERT_NOT_REACHED(); |
@@ -643,14 +707,14 @@ void VTTCue::calculateDisplayParameters() |
switch (m_cueAlignment) { |
case Start: |
case Left: |
- m_displayPosition.second = m_textPosition; |
+ m_displayPosition.second = computedTextPosition; |
break; |
case End: |
case Right: |
- m_displayPosition.second = m_textPosition - m_displaySize; |
+ m_displayPosition.second = computedTextPosition - m_displaySize; |
break; |
case Middle: |
- m_displayPosition.second = m_textPosition - m_displaySize / 2; |
+ m_displayPosition.second = computedTextPosition - m_displaySize / 2; |
break; |
default: |
ASSERT_NOT_REACHED(); |
@@ -793,7 +857,7 @@ void VTTCue::updateDisplay(const IntSize& videoSize, HTMLDivElement& container) |
if (m_linePosition != undefinedPosition) |
UseCounter::count(document(), UseCounter::VTTCueRenderLineNotAuto); |
- if (m_textPosition != 50) |
+ if (textPositionIsAuto()) |
fs
2015/01/14 13:13:40
Changed this on the assumption that we want to che
philipj_slow
2015/01/15 09:08:57
Yeah. Too bad the name will suck, but oh well.
|
UseCounter::count(document(), UseCounter::VTTCueRenderPositionNot50); |
if (m_cueSize != 100) |
@@ -832,16 +896,17 @@ std::pair<double, double> VTTCue::getPositionCoordinates() const |
{ |
// This method is used for setting x and y when snap to lines is not set. |
std::pair<double, double> coordinates; |
+ int computedTextPosition = calculateComputedTextPosition(); |
if (m_writingDirection == Horizontal && m_displayDirection == CSSValueLtr) { |
- coordinates.first = m_textPosition; |
+ coordinates.first = computedTextPosition; |
coordinates.second = m_computedLinePosition; |
return coordinates; |
} |
if (m_writingDirection == Horizontal && m_displayDirection == CSSValueRtl) { |
- coordinates.first = 100 - m_textPosition; |
+ coordinates.first = 100 - computedTextPosition; |
coordinates.second = m_computedLinePosition; |
return coordinates; |
@@ -849,14 +914,14 @@ std::pair<double, double> VTTCue::getPositionCoordinates() const |
if (m_writingDirection == VerticalGrowingLeft) { |
coordinates.first = 100 - m_computedLinePosition; |
- coordinates.second = m_textPosition; |
+ coordinates.second = computedTextPosition; |
return coordinates; |
} |
if (m_writingDirection == VerticalGrowingRight) { |
coordinates.first = m_computedLinePosition; |
- coordinates.second = m_textPosition; |
+ coordinates.second = computedTextPosition; |
return coordinates; |
} |