Chromium Code Reviews| 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() | |
|
sof
2015/07/20 08:15:39
It would be preferable to keep an empty destructor
philipj_slow
2015/07/20 08:34:16
Done.
| |
| 247 { | |
| 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 } | |
| 258 | |
| 259 #ifndef NDEBUG | 249 #ifndef NDEBUG |
| 260 String VTTCue::toString() const | 250 String VTTCue::toString() const |
| 261 { | 251 { |
| 262 return String::format("%p id=%s interval=%f-->%f cue=%s)", this, id().utf8() .data(), startTime(), endTime(), text().utf8().data()); | 252 return String::format("%p id=%s interval=%f-->%f cue=%s)", this, id().utf8() .data(), startTime(), endTime(), text().utf8().data()); |
| 263 } | 253 } |
| 264 #endif | 254 #endif |
| 265 | 255 |
| 266 void VTTCue::cueDidChange() | 256 void VTTCue::cueDidChange() |
| 267 { | 257 { |
| 268 TextTrackCue::cueDidChange(); | 258 TextTrackCue::cueDidChange(); |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 case VTTCue::Right: | 628 case VTTCue::Right: |
| 639 return VTTCue::End; | 629 return VTTCue::End; |
| 640 default: | 630 default: |
| 641 return m_cueAlignment; | 631 return m_cueAlignment; |
| 642 } | 632 } |
| 643 } | 633 } |
| 644 | 634 |
| 645 VTTDisplayParameters::VTTDisplayParameters() | 635 VTTDisplayParameters::VTTDisplayParameters() |
| 646 : size(std::numeric_limits<float>::quiet_NaN()) | 636 : size(std::numeric_limits<float>::quiet_NaN()) |
| 647 , direction(CSSValueNone) | 637 , direction(CSSValueNone) |
| 648 , writingMode(CSSValueNone) { } | 638 , textAlign(CSSValueNone) |
| 639 , writingMode(CSSValueNone) | |
| 640 , snapToLinesPosition(std::numeric_limits<float>::quiet_NaN()) { } | |
| 649 | 641 |
| 650 VTTDisplayParameters VTTCue::calculateDisplayParameters() const | 642 VTTDisplayParameters VTTCue::calculateDisplayParameters() const |
| 651 { | 643 { |
| 652 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings | 644 // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings |
| 653 | 645 |
| 654 VTTDisplayParameters displayParameters; | 646 VTTDisplayParameters displayParameters; |
| 647 | |
| 655 // Steps 1 and 2. | 648 // Steps 1 and 2. |
| 656 displayParameters.direction = determineTextDirection(m_vttNodeTree.get()); | 649 displayParameters.direction = determineTextDirection(m_vttNodeTree.get()); |
| 657 | 650 |
| 658 if (displayParameters.direction == CSSValueRtl) | 651 if (displayParameters.direction == CSSValueRtl) |
| 659 UseCounter::count(document(), UseCounter::VTTCueRenderRtl); | 652 UseCounter::count(document(), UseCounter::VTTCueRenderRtl); |
| 660 | 653 |
| 654 // Note: The 'text-align' property is also determined here so that | |
| 655 // VTTCueBox::applyCSSProperties need not have access to a VTTCue. | |
| 656 displayParameters.textAlign = displayAlignmentMap[cueAlignment()]; | |
| 657 | |
| 661 // 3. If the text track cue writing direction is horizontal, then let | 658 // 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 | 659 // 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 | 660 // 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 | 661 // track cue writing direction is vertical growing right; let block-flow be |
| 665 // 'rl'. | 662 // 'rl'. |
| 666 displayParameters.writingMode = displayWritingModeMap[m_writingDirection]; | 663 displayParameters.writingMode = displayWritingModeMap[m_writingDirection]; |
| 667 | 664 |
| 668 // Resolve the cue alignment to one of the values {start, end, middle}. | 665 // Resolve the cue alignment to one of the values {start, end, middle}. |
| 669 CueAlignment computedCueAlignment = calculateComputedCueAlignment(); | 666 CueAlignment computedCueAlignment = calculateComputedCueAlignment(); |
| 670 | 667 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 displayParameters.position.setX(computedLinePosition); | 737 displayParameters.position.setX(computedLinePosition); |
| 741 } else { | 738 } else { |
| 742 if (m_writingDirection == Horizontal) | 739 if (m_writingDirection == Horizontal) |
| 743 displayParameters.position.setY(0); | 740 displayParameters.position.setY(0); |
| 744 else | 741 else |
| 745 displayParameters.position.setX(0); | 742 displayParameters.position.setX(0); |
| 746 } | 743 } |
| 747 | 744 |
| 748 // Step 9 not implemented (margin == 0). | 745 // Step 9 not implemented (margin == 0). |
| 749 | 746 |
| 747 // The snap-to-lines position is propagated to LayoutVTTCue. | |
| 748 displayParameters.snapToLinesPosition = m_snapToLines | |
| 749 ? computedLinePosition | |
| 750 : std::numeric_limits<float>::quiet_NaN(); | |
| 751 | |
| 750 ASSERT(std::isfinite(displayParameters.size)); | 752 ASSERT(std::isfinite(displayParameters.size)); |
| 751 ASSERT(displayParameters.direction != CSSValueNone); | 753 ASSERT(displayParameters.direction != CSSValueNone); |
| 752 ASSERT(displayParameters.writingMode != CSSValueNone); | 754 ASSERT(displayParameters.writingMode != CSSValueNone); |
| 753 return displayParameters; | 755 return displayParameters; |
| 754 } | 756 } |
| 755 | 757 |
| 756 void VTTCue::updatePastAndFutureNodes(double movieTime) | 758 void VTTCue::updatePastAndFutureNodes(double movieTime) |
| 757 { | 759 { |
| 758 DEFINE_STATIC_LOCAL(const String, timestampTag, ("timestamp")); | 760 DEFINE_STATIC_LOCAL(const String, timestampTag, ("timestamp")); |
| 759 | 761 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 793 toElement(child).setIdAttribute(id()); | 795 toElement(child).setIdAttribute(id()); |
| 794 } | 796 } |
| 795 } | 797 } |
| 796 } | 798 } |
| 797 | 799 |
| 798 PassRefPtrWillBeRawPtr<VTTCueBox> VTTCue::getDisplayTree() | 800 PassRefPtrWillBeRawPtr<VTTCueBox> VTTCue::getDisplayTree() |
| 799 { | 801 { |
| 800 ASSERT(track() && track()->isRendered() && isActive()); | 802 ASSERT(track() && track()->isRendered() && isActive()); |
| 801 | 803 |
| 802 if (!m_displayTree) { | 804 if (!m_displayTree) { |
| 803 m_displayTree = VTTCueBox::create(document(), this); | 805 m_displayTree = VTTCueBox::create(document()); |
| 804 m_displayTree->appendChild(m_cueBackgroundBox); | 806 m_displayTree->appendChild(m_cueBackgroundBox); |
| 805 } | 807 } |
| 806 | 808 |
| 807 ASSERT(m_displayTree->firstChild() == m_cueBackgroundBox); | 809 ASSERT(m_displayTree->firstChild() == m_cueBackgroundBox); |
| 808 | 810 |
| 809 if (!m_displayTreeShouldChange) { | 811 if (!m_displayTreeShouldChange) { |
| 810 // Apply updated user style overrides for text tracks when display tree doesn't change. | 812 // 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 | 813 // 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. | 814 // replayed or when the user slides back to an already rendered track. |
| 813 applyUserOverrideCSSProperties(); | 815 applyUserOverrideCSSProperties(); |
| 814 return m_displayTree; | 816 return m_displayTree; |
| 815 } | 817 } |
| 816 | 818 |
| 817 createVTTNodeTree(); | 819 createVTTNodeTree(); |
| 818 | 820 |
| 819 m_cueBackgroundBox->removeChildren(); | 821 m_cueBackgroundBox->removeChildren(); |
| 820 m_vttNodeTree->cloneChildNodes(m_cueBackgroundBox.get()); | 822 m_vttNodeTree->cloneChildNodes(m_cueBackgroundBox.get()); |
| 821 | 823 |
| 822 VTTDisplayParameters displayParameters = calculateDisplayParameters(); | 824 // TODO(philipj): The region identifier may be non-empty without there being |
| 823 m_displayTree->applyCSSProperties(displayParameters); | 825 // a corresponding region, in which case this VTTCueBox will be added |
| 826 // directly to the text track container in updateDisplay(). | |
| 827 if (regionId().isEmpty()) { | |
|
fs
2015/07/17 14:31:48
Maybe you could add a "VTTRegion* region() { retur
philipj_slow
2015/07/20 07:33:30
Yes, I changed the spec such that it should be pos
| |
| 828 VTTDisplayParameters displayParameters = calculateDisplayParameters(); | |
| 829 m_displayTree->applyCSSProperties(displayParameters); | |
| 830 } else { | |
| 831 m_displayTree->setInlineStyleProperty(CSSPropertyPosition, CSSValueRelat ive); | |
| 832 } | |
| 824 | 833 |
| 825 // Apply user override settings for text tracks | 834 // Apply user override settings for text tracks |
| 826 applyUserOverrideCSSProperties(); | 835 applyUserOverrideCSSProperties(); |
| 827 | 836 |
| 828 m_displayTreeShouldChange = false; | 837 m_displayTreeShouldChange = false; |
| 829 | 838 |
| 830 return m_displayTree; | 839 return m_displayTree; |
| 831 } | 840 } |
| 832 | 841 |
| 833 void VTTCue::removeDisplayTree(RemovalNotification removalNotification) | 842 void VTTCue::removeDisplayTree(RemovalNotification removalNotification) |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 | 1142 |
| 1134 DEFINE_TRACE(VTTCue) | 1143 DEFINE_TRACE(VTTCue) |
| 1135 { | 1144 { |
| 1136 visitor->trace(m_vttNodeTree); | 1145 visitor->trace(m_vttNodeTree); |
| 1137 visitor->trace(m_cueBackgroundBox); | 1146 visitor->trace(m_cueBackgroundBox); |
| 1138 visitor->trace(m_displayTree); | 1147 visitor->trace(m_displayTree); |
| 1139 TextTrackCue::trace(visitor); | 1148 TextTrackCue::trace(visitor); |
| 1140 } | 1149 } |
| 1141 | 1150 |
| 1142 } // namespace blink | 1151 } // namespace blink |
| OLD | NEW |