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 |