| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013, Opera Software ASA. All rights reserved. | 2 * Copyright (c) 2013, Opera Software ASA. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } | 138 } |
| 139 | 139 |
| 140 // Sets inline CSS properties on passed in element if value is not an empty stri
ng | 140 // Sets inline CSS properties on passed in element if value is not an empty stri
ng |
| 141 static void setInlineStylePropertyIfNotEmpty(Element& element, | 141 static void setInlineStylePropertyIfNotEmpty(Element& element, |
| 142 CSSPropertyID propertyID, const String& value) | 142 CSSPropertyID propertyID, const String& value) |
| 143 { | 143 { |
| 144 if (!value.isEmpty()) | 144 if (!value.isEmpty()) |
| 145 element.setInlineStyleProperty(propertyID, value); | 145 element.setInlineStyleProperty(propertyID, value); |
| 146 } | 146 } |
| 147 | 147 |
| 148 VTTCueBox::VTTCueBox(Document& document, VTTCue* cue) | 148 VTTCueBox::VTTCueBox(Document& document) |
| 149 : HTMLDivElement(document) | 149 : HTMLDivElement(document) |
| 150 , m_cue(cue) | 150 , m_snapToLinesPosition(std::numeric_limits<float>::quiet_NaN()) |
| 151 { | 151 { |
| 152 setShadowPseudoId(AtomicString("-webkit-media-text-track-display", AtomicStr
ing::ConstructFromLiteral)); | 152 setShadowPseudoId(AtomicString("-webkit-media-text-track-display", AtomicStr
ing::ConstructFromLiteral)); |
| 153 } | 153 } |
| 154 | 154 |
| 155 void VTTCueBox::applyCSSProperties(const VTTDisplayParameters& displayParameters
) | 155 void VTTCueBox::applyCSSProperties(const VTTDisplayParameters& displayParameters
) |
| 156 { | 156 { |
| 157 // FIXME: Apply all the initial CSS positioning properties. http://wkb.ug/79
916 | 157 // http://dev.w3.org/html5/webvtt/#applying-css-properties-to-webvtt-node-ob
jects |
| 158 if (!m_cue->regionId().isEmpty()) { | |
| 159 setInlineStyleProperty(CSSPropertyPosition, CSSValueRelative); | |
| 160 return; | |
| 161 } | |
| 162 | 158 |
| 163 // 3.5.1 On the (root) List of WebVTT Node Objects: | 159 // Initialize the (root) list of WebVTT Node Objects with the following CSS
settings: |
| 164 | 160 |
| 165 // the 'position' property must be set to 'absolute' | 161 // the 'position' property must be set to 'absolute' |
| 166 setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute); | 162 setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute); |
| 167 | 163 |
| 168 // the 'unicode-bidi' property must be set to 'plaintext' | 164 // the 'unicode-bidi' property must be set to 'plaintext' |
| 169 setInlineStyleProperty(CSSPropertyUnicodeBidi, CSSValueWebkitPlaintext); | 165 setInlineStyleProperty(CSSPropertyUnicodeBidi, CSSValueWebkitPlaintext); |
| 170 | 166 |
| 171 // the 'direction' property must be set to direction | 167 // the 'direction' property must be set to direction |
| 172 setInlineStyleProperty(CSSPropertyDirection, displayParameters.direction); | 168 setInlineStyleProperty(CSSPropertyDirection, displayParameters.direction); |
| 173 | 169 |
| 174 // the 'writing-mode' property must be set to writing-mode | 170 // the 'writing-mode' property must be set to writing-mode |
| 175 setInlineStyleProperty(CSSPropertyWebkitWritingMode, displayParameters.writi
ngMode); | 171 setInlineStyleProperty(CSSPropertyWebkitWritingMode, displayParameters.writi
ngMode); |
| 176 | 172 |
| 177 const FloatPoint& position = displayParameters.position; | 173 const FloatPoint& position = displayParameters.position; |
| 178 | 174 |
| 179 // the 'top' property must be set to top, | 175 // the 'top' property must be set to top, |
| 180 setInlineStyleProperty(CSSPropertyTop, position.y(), CSSPrimitiveValue::CSS_
PERCENTAGE); | 176 setInlineStyleProperty(CSSPropertyTop, position.y(), CSSPrimitiveValue::CSS_
PERCENTAGE); |
| 181 | 177 |
| 182 // the 'left' property must be set to left | 178 // the 'left' property must be set to left |
| 183 setInlineStyleProperty(CSSPropertyLeft, position.x(), CSSPrimitiveValue::CSS
_PERCENTAGE); | 179 setInlineStyleProperty(CSSPropertyLeft, position.x(), CSSPrimitiveValue::CSS
_PERCENTAGE); |
| 184 | 180 |
| 185 // the 'width' property must be set to width, and the 'height' property mus
t be set to height | 181 // the 'width' property must be set to width, and the 'height' property mus
t be set to height |
| 186 if (m_cue->vertical() == horizontalKeyword()) { | 182 if (displayParameters.writingMode == CSSValueHorizontalTb) { |
| 187 setInlineStyleProperty(CSSPropertyWidth, displayParameters.size, CSSPrim
itiveValue::CSS_PERCENTAGE); | 183 setInlineStyleProperty(CSSPropertyWidth, displayParameters.size, CSSPrim
itiveValue::CSS_PERCENTAGE); |
| 188 setInlineStyleProperty(CSSPropertyHeight, CSSValueAuto); | 184 setInlineStyleProperty(CSSPropertyHeight, CSSValueAuto); |
| 189 } else { | 185 } else { |
| 190 setInlineStyleProperty(CSSPropertyWidth, CSSValueAuto); | 186 setInlineStyleProperty(CSSPropertyWidth, CSSValueAuto); |
| 191 setInlineStyleProperty(CSSPropertyHeight, displayParameters.size, CSSPr
imitiveValue::CSS_PERCENTAGE); | 187 setInlineStyleProperty(CSSPropertyHeight, displayParameters.size, CSSPr
imitiveValue::CSS_PERCENTAGE); |
| 192 } | 188 } |
| 193 | 189 |
| 194 // The 'text-align' property on the (root) List of WebVTT Node Objects must | 190 // The 'text-align' property on the (root) List of WebVTT Node Objects must |
| 195 // be set to the value in the second cell of the row of the table below | 191 // be set to the value in the second cell of the row of the table below |
| 196 // whose first cell is the value of the corresponding cue's text track cue | 192 // whose first cell is the value of the corresponding cue's text track cue |
| 197 // alignment: | 193 // alignment: |
| 198 setInlineStyleProperty(CSSPropertyTextAlign, displayAlignmentMap[m_cue->cueA
lignment()]); | 194 setInlineStyleProperty(CSSPropertyTextAlign, displayParameters.textAlign); |
| 199 | 195 |
| 200 if (!m_cue->snapToLines()) { | 196 // TODO(philipj): The position adjustment for non-snap-to-lines cues has |
| 197 // been removed from the spec: |
| 198 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=19178 |
| 199 if (std::isnan(displayParameters.snapToLinesPosition)) { |
| 201 // 10.13.1 Set up x and y: | 200 // 10.13.1 Set up x and y: |
| 202 // Note: x and y are set through the CSS left and top above. | 201 // Note: x and y are set through the CSS left and top above. |
| 203 | 202 |
| 204 // 10.13.2 Position the boxes in boxes such that the point x% along the | 203 // 10.13.2 Position the boxes in boxes such that the point x% along the |
| 205 // width of the bounding box of the boxes in boxes is x% of the way | 204 // width of the bounding box of the boxes in boxes is x% of the way |
| 206 // across the width of the video's rendering area, and the point y% | 205 // across the width of the video's rendering area, and the point y% |
| 207 // along the height of the bounding box of the boxes in boxes is y% | 206 // along the height of the bounding box of the boxes in boxes is y% |
| 208 // of the way across the height of the video's rendering area, while | 207 // of the way across the height of the video's rendering area, while |
| 209 // maintaining the relative positions of the boxes in boxes to each | 208 // maintaining the relative positions of the boxes in boxes to each |
| 210 // other. | 209 // other. |
| 211 setInlineStyleProperty(CSSPropertyTransform, | 210 setInlineStyleProperty(CSSPropertyTransform, |
| 212 String::format("translate(-%.2f%%, -%.2f%%)", position.x(), position
.y())); | 211 String::format("translate(-%.2f%%, -%.2f%%)", position.x(), position
.y())); |
| 213 | 212 |
| 214 setInlineStyleProperty(CSSPropertyWhiteSpace, CSSValuePre); | 213 setInlineStyleProperty(CSSPropertyWhiteSpace, CSSValuePre); |
| 215 } | 214 } |
| 215 |
| 216 // The snap-to-lines position is propagated to LayoutVTTCue. |
| 217 m_snapToLinesPosition = displayParameters.snapToLinesPosition; |
| 216 } | 218 } |
| 217 | 219 |
| 218 LayoutObject* VTTCueBox::createLayoutObject(const ComputedStyle&) | 220 LayoutObject* VTTCueBox::createLayoutObject(const ComputedStyle& style) |
| 219 { | 221 { |
| 220 return new LayoutVTTCue(this); | 222 // If WebVTT Regions are used, the regular WebVTT layout algorithm is no |
| 221 } | 223 // longer necessary, since cues having the region parameter set do not have |
| 224 // any positioning parameters. Also, in this case, the regions themselves |
| 225 // have positioning information. |
| 226 if (style.position() == RelativePosition) |
| 227 return HTMLDivElement::createLayoutObject(style); |
| 222 | 228 |
| 223 DEFINE_TRACE(VTTCueBox) | 229 return new LayoutVTTCue(this, m_snapToLinesPosition); |
| 224 { | |
| 225 visitor->trace(m_cue); | |
| 226 HTMLDivElement::trace(visitor); | |
| 227 } | 230 } |
| 228 | 231 |
| 229 VTTCue::VTTCue(Document& document, double startTime, double endTime, const Strin
g& text) | 232 VTTCue::VTTCue(Document& document, double startTime, double endTime, const Strin
g& text) |
| 230 : TextTrackCue(startTime, endTime) | 233 : TextTrackCue(startTime, endTime) |
| 231 , m_text(text) | 234 , m_text(text) |
| 232 , m_linePosition(std::numeric_limits<float>::quiet_NaN()) | 235 , m_linePosition(std::numeric_limits<float>::quiet_NaN()) |
| 233 , m_textPosition(std::numeric_limits<float>::quiet_NaN()) | 236 , m_textPosition(std::numeric_limits<float>::quiet_NaN()) |
| 234 , m_cueSize(100) | 237 , m_cueSize(100) |
| 235 , m_writingDirection(Horizontal) | 238 , m_writingDirection(Horizontal) |
| 236 , m_cueAlignment(Middle) | 239 , m_cueAlignment(Middle) |
| 237 , m_vttNodeTree(nullptr) | 240 , m_vttNodeTree(nullptr) |
| 238 , m_cueBackgroundBox(HTMLDivElement::create(document)) | 241 , m_cueBackgroundBox(HTMLDivElement::create(document)) |
| 239 , m_snapToLines(true) | 242 , m_snapToLines(true) |
| 240 , m_displayTreeShouldChange(true) | 243 , m_displayTreeShouldChange(true) |
| 241 { | 244 { |
| 242 UseCounter::count(document, UseCounter::VTTCue); | 245 UseCounter::count(document, UseCounter::VTTCue); |
| 243 m_cueBackgroundBox->setShadowPseudoId(cueShadowPseudoId()); | 246 m_cueBackgroundBox->setShadowPseudoId(cueShadowPseudoId()); |
| 244 } | 247 } |
| 245 | 248 |
| 246 VTTCue::~VTTCue() | 249 VTTCue::~VTTCue() |
| 247 { | 250 { |
| 248 // Using oilpan, if m_displayTree is in the document it will strongly keep | |
| 249 // the cue alive. Thus, if the cue is dead, either m_displayTree is not in | |
| 250 // the document or the entire document is dead too. | |
| 251 #if !ENABLE(OILPAN) | |
| 252 // FIXME: This is scary, we should make the life cycle smarter so the destru
ctor | |
| 253 // doesn't need to do DOM mutations. | |
| 254 if (m_displayTree) | |
| 255 m_displayTree->remove(ASSERT_NO_EXCEPTION); | |
| 256 #endif | |
| 257 } | 251 } |
| 258 | 252 |
| 259 #ifndef NDEBUG | 253 #ifndef NDEBUG |
| 260 String VTTCue::toString() const | 254 String VTTCue::toString() const |
| 261 { | 255 { |
| 262 return String::format("%p id=%s interval=%f-->%f cue=%s)", this, id().utf8()
.data(), startTime(), endTime(), text().utf8().data()); | 256 return String::format("%p id=%s interval=%f-->%f cue=%s)", this, id().utf8()
.data(), startTime(), endTime(), text().utf8().data()); |
| 263 } | 257 } |
| 264 #endif | 258 #endif |
| 265 | 259 |
| 266 void VTTCue::cueDidChange() | 260 void VTTCue::cueDidChange() |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 case VTTCue::Right: | 632 case VTTCue::Right: |
| 639 return VTTCue::End; | 633 return VTTCue::End; |
| 640 default: | 634 default: |
| 641 return m_cueAlignment; | 635 return m_cueAlignment; |
| 642 } | 636 } |
| 643 } | 637 } |
| 644 | 638 |
| 645 VTTDisplayParameters::VTTDisplayParameters() | 639 VTTDisplayParameters::VTTDisplayParameters() |
| 646 : size(std::numeric_limits<float>::quiet_NaN()) | 640 : size(std::numeric_limits<float>::quiet_NaN()) |
| 647 , direction(CSSValueNone) | 641 , direction(CSSValueNone) |
| 648 , writingMode(CSSValueNone) { } | 642 , textAlign(CSSValueNone) |
| 643 , writingMode(CSSValueNone) |
| 644 , snapToLinesPosition(std::numeric_limits<float>::quiet_NaN()) { } |
| 649 | 645 |
| 650 VTTDisplayParameters VTTCue::calculateDisplayParameters() const | 646 VTTDisplayParameters VTTCue::calculateDisplayParameters() const |
| 651 { | 647 { |
| 652 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings | 648 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings |
| 653 | 649 |
| 654 VTTDisplayParameters displayParameters; | 650 VTTDisplayParameters displayParameters; |
| 651 |
| 655 // Steps 1 and 2. | 652 // Steps 1 and 2. |
| 656 displayParameters.direction = determineTextDirection(m_vttNodeTree.get()); | 653 displayParameters.direction = determineTextDirection(m_vttNodeTree.get()); |
| 657 | 654 |
| 658 if (displayParameters.direction == CSSValueRtl) | 655 if (displayParameters.direction == CSSValueRtl) |
| 659 UseCounter::count(document(), UseCounter::VTTCueRenderRtl); | 656 UseCounter::count(document(), UseCounter::VTTCueRenderRtl); |
| 660 | 657 |
| 658 // Note: The 'text-align' property is also determined here so that |
| 659 // VTTCueBox::applyCSSProperties need not have access to a VTTCue. |
| 660 displayParameters.textAlign = displayAlignmentMap[cueAlignment()]; |
| 661 |
| 661 // 3. If the text track cue writing direction is horizontal, then let | 662 // 3. If the text track cue writing direction is horizontal, then let |
| 662 // block-flow be 'tb'. Otherwise, if the text track cue writing direction is | 663 // block-flow be 'tb'. Otherwise, if the text track cue writing direction is |
| 663 // vertical growing left, then let block-flow be 'lr'. Otherwise, the text | 664 // vertical growing left, then let block-flow be 'lr'. Otherwise, the text |
| 664 // track cue writing direction is vertical growing right; let block-flow be | 665 // track cue writing direction is vertical growing right; let block-flow be |
| 665 // 'rl'. | 666 // 'rl'. |
| 666 displayParameters.writingMode = displayWritingModeMap[m_writingDirection]; | 667 displayParameters.writingMode = displayWritingModeMap[m_writingDirection]; |
| 667 | 668 |
| 668 // Resolve the cue alignment to one of the values {start, end, middle}. | 669 // Resolve the cue alignment to one of the values {start, end, middle}. |
| 669 CueAlignment computedCueAlignment = calculateComputedCueAlignment(); | 670 CueAlignment computedCueAlignment = calculateComputedCueAlignment(); |
| 670 | 671 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 displayParameters.position.setX(computedLinePosition); | 741 displayParameters.position.setX(computedLinePosition); |
| 741 } else { | 742 } else { |
| 742 if (m_writingDirection == Horizontal) | 743 if (m_writingDirection == Horizontal) |
| 743 displayParameters.position.setY(0); | 744 displayParameters.position.setY(0); |
| 744 else | 745 else |
| 745 displayParameters.position.setX(0); | 746 displayParameters.position.setX(0); |
| 746 } | 747 } |
| 747 | 748 |
| 748 // Step 9 not implemented (margin == 0). | 749 // Step 9 not implemented (margin == 0). |
| 749 | 750 |
| 751 // The snap-to-lines position is propagated to LayoutVTTCue. |
| 752 displayParameters.snapToLinesPosition = m_snapToLines |
| 753 ? computedLinePosition |
| 754 : std::numeric_limits<float>::quiet_NaN(); |
| 755 |
| 750 ASSERT(std::isfinite(displayParameters.size)); | 756 ASSERT(std::isfinite(displayParameters.size)); |
| 751 ASSERT(displayParameters.direction != CSSValueNone); | 757 ASSERT(displayParameters.direction != CSSValueNone); |
| 752 ASSERT(displayParameters.writingMode != CSSValueNone); | 758 ASSERT(displayParameters.writingMode != CSSValueNone); |
| 753 return displayParameters; | 759 return displayParameters; |
| 754 } | 760 } |
| 755 | 761 |
| 756 void VTTCue::updatePastAndFutureNodes(double movieTime) | 762 void VTTCue::updatePastAndFutureNodes(double movieTime) |
| 757 { | 763 { |
| 758 DEFINE_STATIC_LOCAL(const String, timestampTag, ("timestamp")); | 764 DEFINE_STATIC_LOCAL(const String, timestampTag, ("timestamp")); |
| 759 | 765 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 toElement(child).setIdAttribute(id()); | 799 toElement(child).setIdAttribute(id()); |
| 794 } | 800 } |
| 795 } | 801 } |
| 796 } | 802 } |
| 797 | 803 |
| 798 PassRefPtrWillBeRawPtr<VTTCueBox> VTTCue::getDisplayTree() | 804 PassRefPtrWillBeRawPtr<VTTCueBox> VTTCue::getDisplayTree() |
| 799 { | 805 { |
| 800 ASSERT(track() && track()->isRendered() && isActive()); | 806 ASSERT(track() && track()->isRendered() && isActive()); |
| 801 | 807 |
| 802 if (!m_displayTree) { | 808 if (!m_displayTree) { |
| 803 m_displayTree = VTTCueBox::create(document(), this); | 809 m_displayTree = VTTCueBox::create(document()); |
| 804 m_displayTree->appendChild(m_cueBackgroundBox); | 810 m_displayTree->appendChild(m_cueBackgroundBox); |
| 805 } | 811 } |
| 806 | 812 |
| 807 ASSERT(m_displayTree->firstChild() == m_cueBackgroundBox); | 813 ASSERT(m_displayTree->firstChild() == m_cueBackgroundBox); |
| 808 | 814 |
| 809 if (!m_displayTreeShouldChange) { | 815 if (!m_displayTreeShouldChange) { |
| 810 // Apply updated user style overrides for text tracks when display tree
doesn't change. | 816 // Apply updated user style overrides for text tracks when display tree
doesn't change. |
| 811 // This ensures that the track settings are refreshed when the video is | 817 // This ensures that the track settings are refreshed when the video is |
| 812 // replayed or when the user slides back to an already rendered track. | 818 // replayed or when the user slides back to an already rendered track. |
| 813 applyUserOverrideCSSProperties(); | 819 applyUserOverrideCSSProperties(); |
| 814 return m_displayTree; | 820 return m_displayTree; |
| 815 } | 821 } |
| 816 | 822 |
| 817 createVTTNodeTree(); | 823 createVTTNodeTree(); |
| 818 | 824 |
| 819 m_cueBackgroundBox->removeChildren(); | 825 m_cueBackgroundBox->removeChildren(); |
| 820 m_vttNodeTree->cloneChildNodes(m_cueBackgroundBox.get()); | 826 m_vttNodeTree->cloneChildNodes(m_cueBackgroundBox.get()); |
| 821 | 827 |
| 822 VTTDisplayParameters displayParameters = calculateDisplayParameters(); | 828 // TODO(philipj): The region identifier may be non-empty without there being |
| 823 m_displayTree->applyCSSProperties(displayParameters); | 829 // a corresponding region, in which case this VTTCueBox will be added |
| 830 // directly to the text track container in updateDisplay(). |
| 831 if (regionId().isEmpty()) { |
| 832 VTTDisplayParameters displayParameters = calculateDisplayParameters(); |
| 833 m_displayTree->applyCSSProperties(displayParameters); |
| 834 } else { |
| 835 m_displayTree->setInlineStyleProperty(CSSPropertyPosition, CSSValueRelat
ive); |
| 836 } |
| 824 | 837 |
| 825 // Apply user override settings for text tracks | 838 // Apply user override settings for text tracks |
| 826 applyUserOverrideCSSProperties(); | 839 applyUserOverrideCSSProperties(); |
| 827 | 840 |
| 828 m_displayTreeShouldChange = false; | 841 m_displayTreeShouldChange = false; |
| 829 | 842 |
| 830 return m_displayTree; | 843 return m_displayTree; |
| 831 } | 844 } |
| 832 | 845 |
| 833 void VTTCue::removeDisplayTree(RemovalNotification removalNotification) | 846 void VTTCue::removeDisplayTree(RemovalNotification removalNotification) |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 | 1146 |
| 1134 DEFINE_TRACE(VTTCue) | 1147 DEFINE_TRACE(VTTCue) |
| 1135 { | 1148 { |
| 1136 visitor->trace(m_vttNodeTree); | 1149 visitor->trace(m_vttNodeTree); |
| 1137 visitor->trace(m_cueBackgroundBox); | 1150 visitor->trace(m_cueBackgroundBox); |
| 1138 visitor->trace(m_displayTree); | 1151 visitor->trace(m_displayTree); |
| 1139 TextTrackCue::trace(visitor); | 1152 TextTrackCue::trace(visitor); |
| 1140 } | 1153 } |
| 1141 | 1154 |
| 1142 } // namespace blink | 1155 } // namespace blink |
| OLD | NEW |