Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: Source/core/html/track/TextTrackRegion.cpp

Issue 55653003: Rename TextTrackRegion/TextTrackRegionList to VTTRegion/VTTRegionList (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: update test expectations Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/html/track/TextTrackRegion.h ('k') | Source/core/html/track/TextTrackRegion.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "core/html/track/TextTrackRegion.h"
33
34 #include "bindings/v8/ExceptionState.h"
35 #include "bindings/v8/ExceptionStatePlaceholder.h"
36 #include "core/dom/ClientRect.h"
37 #include "core/dom/DOMTokenList.h"
38 #include "core/html/HTMLDivElement.h"
39 #include "core/html/track/WebVTTParser.h"
40 #include "platform/Logging.h"
41 #include "core/rendering/RenderInline.h"
42 #include "core/rendering/RenderObject.h"
43 #include "wtf/MathExtras.h"
44 #include "wtf/text/StringBuilder.h"
45
46 namespace WebCore {
47
48 // The following values default values are defined within the WebVTT Regions Spe c.
49 // https://dvcs.w3.org/hg/text-tracks/raw-file/default/608toVTT/region.html
50
51 // The region occupies by default 100% of the width of the video viewport.
52 static const float defaultWidth = 100;
53
54 // The region has, by default, 3 lines of text.
55 static const long defaultHeightInLines = 3;
56
57 // The region and viewport are anchored in the bottom left corner.
58 static const float defaultAnchorPointX = 0;
59 static const float defaultAnchorPointY = 100;
60
61 // The region doesn't have scrolling text, by default.
62 static const bool defaultScroll = false;
63
64 // Default region line-height (vh units)
65 static const float lineHeight = 5.33;
66
67 // Default scrolling animation time period (s).
68 static const float scrollTime = 0.433;
69
70 TextTrackRegion::TextTrackRegion()
71 : m_id(emptyString())
72 , m_width(defaultWidth)
73 , m_heightInLines(defaultHeightInLines)
74 , m_regionAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
75 , m_viewportAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
76 , m_scroll(defaultScroll)
77 , m_track(0)
78 , m_currentTop(0)
79 , m_scrollTimer(this, &TextTrackRegion::scrollTimerFired)
80 {
81 }
82
83 TextTrackRegion::~TextTrackRegion()
84 {
85 }
86
87 void TextTrackRegion::setTrack(TextTrack* track)
88 {
89 m_track = track;
90 }
91
92 void TextTrackRegion::setId(const String& id)
93 {
94 m_id = id;
95 }
96
97 void TextTrackRegion::setWidth(double value, ExceptionState& es)
98 {
99 if (std::isinf(value) || std::isnan(value)) {
100 es.throwUninformativeAndGenericTypeError();
101 return;
102 }
103
104 if (value < 0 || value > 100) {
105 es.throwUninformativeAndGenericDOMException(IndexSizeError);
106 return;
107 }
108
109 m_width = value;
110 }
111
112 void TextTrackRegion::setHeight(long value, ExceptionState& es)
113 {
114 if (value < 0) {
115 es.throwUninformativeAndGenericDOMException(IndexSizeError);
116 return;
117 }
118
119 m_heightInLines = value;
120 }
121
122 void TextTrackRegion::setRegionAnchorX(double value, ExceptionState& es)
123 {
124 if (std::isinf(value) || std::isnan(value)) {
125 es.throwUninformativeAndGenericTypeError();
126 return;
127 }
128
129 if (value < 0 || value > 100) {
130 es.throwUninformativeAndGenericDOMException(IndexSizeError);
131 return;
132 }
133
134 m_regionAnchor.setX(value);
135 }
136
137 void TextTrackRegion::setRegionAnchorY(double value, ExceptionState& es)
138 {
139 if (std::isinf(value) || std::isnan(value)) {
140 es.throwUninformativeAndGenericTypeError();
141 return;
142 }
143
144 if (value < 0 || value > 100) {
145 es.throwUninformativeAndGenericDOMException(IndexSizeError);
146 return;
147 }
148
149 m_regionAnchor.setY(value);
150 }
151
152 void TextTrackRegion::setViewportAnchorX(double value, ExceptionState& es)
153 {
154 if (std::isinf(value) || std::isnan(value)) {
155 es.throwUninformativeAndGenericTypeError();
156 return;
157 }
158
159 if (value < 0 || value > 100) {
160 es.throwUninformativeAndGenericDOMException(IndexSizeError);
161 return;
162 }
163
164 m_viewportAnchor.setX(value);
165 }
166
167 void TextTrackRegion::setViewportAnchorY(double value, ExceptionState& es)
168 {
169 if (std::isinf(value) || std::isnan(value)) {
170 es.throwUninformativeAndGenericTypeError();
171 return;
172 }
173
174 if (value < 0 || value > 100) {
175 es.throwUninformativeAndGenericDOMException(IndexSizeError);
176 return;
177 }
178
179 m_viewportAnchor.setY(value);
180 }
181
182 const AtomicString TextTrackRegion::scroll() const
183 {
184 DEFINE_STATIC_LOCAL(const AtomicString, upScrollValueKeyword, ("up", AtomicS tring::ConstructFromLiteral));
185
186 if (m_scroll)
187 return upScrollValueKeyword;
188
189 return "";
190 }
191
192 void TextTrackRegion::setScroll(const AtomicString& value, ExceptionState& es)
193 {
194 DEFINE_STATIC_LOCAL(const AtomicString, upScrollValueKeyword, ("up", AtomicS tring::ConstructFromLiteral));
195
196 if (value != emptyString() && value != upScrollValueKeyword) {
197 es.throwUninformativeAndGenericDOMException(SyntaxError);
198 return;
199 }
200
201 m_scroll = value == upScrollValueKeyword;
202 }
203
204 void TextTrackRegion::updateParametersFromRegion(TextTrackRegion* region)
205 {
206 m_heightInLines = region->height();
207 m_width = region->width();
208
209 m_regionAnchor = FloatPoint(region->regionAnchorX(), region->regionAnchorY() );
210 m_viewportAnchor = FloatPoint(region->viewportAnchorX(), region->viewportAnc horY());
211
212 setScroll(region->scroll(), ASSERT_NO_EXCEPTION);
213 }
214
215 void TextTrackRegion::setRegionSettings(const String& input)
216 {
217 m_settings = input;
218 unsigned position = 0;
219
220 while (position < input.length()) {
221 while (position < input.length() && WebVTTParser::isValidSettingDelimite r(input[position]))
222 position++;
223
224 if (position >= input.length())
225 break;
226
227 parseSetting(input, &position);
228 }
229 }
230
231 TextTrackRegion::RegionSetting TextTrackRegion::getSettingFromString(const Strin g& setting)
232 {
233 DEFINE_STATIC_LOCAL(const AtomicString, idKeyword, ("id", AtomicString::Cons tructFromLiteral));
234 DEFINE_STATIC_LOCAL(const AtomicString, heightKeyword, ("height", AtomicStri ng::ConstructFromLiteral));
235 DEFINE_STATIC_LOCAL(const AtomicString, widthKeyword, ("width", AtomicString ::ConstructFromLiteral));
236 DEFINE_STATIC_LOCAL(const AtomicString, regionAnchorKeyword, ("regionanchor" , AtomicString::ConstructFromLiteral));
237 DEFINE_STATIC_LOCAL(const AtomicString, viewportAnchorKeyword, ("viewportanc hor", AtomicString::ConstructFromLiteral));
238 DEFINE_STATIC_LOCAL(const AtomicString, scrollKeyword, ("scroll", AtomicStri ng::ConstructFromLiteral));
239
240 if (setting == idKeyword)
241 return Id;
242 if (setting == heightKeyword)
243 return Height;
244 if (setting == widthKeyword)
245 return Width;
246 if (setting == viewportAnchorKeyword)
247 return ViewportAnchor;
248 if (setting == regionAnchorKeyword)
249 return RegionAnchor;
250 if (setting == scrollKeyword)
251 return Scroll;
252
253 return None;
254 }
255
256 void TextTrackRegion::parseSettingValue(RegionSetting setting, const String& val ue)
257 {
258 DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, ("up", AtomicS tring::ConstructFromLiteral));
259
260 bool isValidSetting;
261 String numberAsString;
262 int number;
263 unsigned position;
264 FloatPoint anchorPosition;
265
266 switch (setting) {
267 case Id:
268 if (value.find("-->") == kNotFound)
269 m_id = value;
270 break;
271 case Width:
272 number = WebVTTParser::parseFloatPercentageValue(value, isValidSetting);
273 if (isValidSetting)
274 m_width = number;
275 else
276 LOG(Media, "TextTrackRegion::parseSettingValue, invalid Width");
277 break;
278 case Height:
279 position = 0;
280
281 numberAsString = WebVTTParser::collectDigits(value, &position);
282 number = value.toInt(&isValidSetting);
283
284 if (isValidSetting && number >= 0)
285 m_heightInLines = number;
286 else
287 LOG(Media, "TextTrackRegion::parseSettingValue, invalid Height");
288 break;
289 case RegionAnchor:
290 anchorPosition = WebVTTParser::parseFloatPercentageValuePair(value, ',', isValidSetting);
291 if (isValidSetting)
292 m_regionAnchor = anchorPosition;
293 else
294 LOG(Media, "TextTrackRegion::parseSettingValue, invalid RegionAnchor ");
295 break;
296 case ViewportAnchor:
297 anchorPosition = WebVTTParser::parseFloatPercentageValuePair(value, ',', isValidSetting);
298 if (isValidSetting)
299 m_viewportAnchor = anchorPosition;
300 else
301 LOG(Media, "TextTrackRegion::parseSettingValue, invalid ViewportAnch or");
302 break;
303 case Scroll:
304 if (value == scrollUpValueKeyword)
305 m_scroll = true;
306 else
307 LOG(Media, "TextTrackRegion::parseSettingValue, invalid Scroll");
308 break;
309 case None:
310 break;
311 }
312 }
313
314 void TextTrackRegion::parseSetting(const String& input, unsigned* position)
315 {
316 String setting = WebVTTParser::collectWord(input, position);
317
318 size_t equalOffset = setting.find('=', 1);
319 if (equalOffset == kNotFound || !equalOffset || equalOffset == setting.lengt h() - 1)
320 return;
321
322 RegionSetting name = getSettingFromString(setting.substring(0, equalOffset)) ;
323 String value = setting.substring(equalOffset + 1, setting.length() - 1);
324
325 parseSettingValue(name, value);
326 }
327
328 const AtomicString& TextTrackRegion::textTrackCueContainerShadowPseudoId()
329 {
330 DEFINE_STATIC_LOCAL(const AtomicString, trackRegionCueContainerPseudoId,
331 ("-webkit-media-text-track-region-container", AtomicString::ConstructFro mLiteral));
332
333 return trackRegionCueContainerPseudoId;
334 }
335
336 const AtomicString& TextTrackRegion::textTrackCueContainerScrollingClass()
337 {
338 DEFINE_STATIC_LOCAL(const AtomicString, trackRegionCueContainerScrollingClas s,
339 ("scrolling", AtomicString::ConstructFromLiteral));
340
341 return trackRegionCueContainerScrollingClass;
342 }
343
344 const AtomicString& TextTrackRegion::textTrackRegionShadowPseudoId()
345 {
346 DEFINE_STATIC_LOCAL(const AtomicString, trackRegionShadowPseudoId,
347 ("-webkit-media-text-track-region", AtomicString::ConstructFromLiteral)) ;
348
349 return trackRegionShadowPseudoId;
350 }
351
352 PassRefPtr<HTMLDivElement> TextTrackRegion::getDisplayTree(Document& document)
353 {
354 if (!m_regionDisplayTree) {
355 m_regionDisplayTree = HTMLDivElement::create(document);
356 prepareRegionDisplayTree();
357 }
358
359 return m_regionDisplayTree;
360 }
361
362 void TextTrackRegion::willRemoveTextTrackCueBox(TextTrackCueBox* box)
363 {
364 LOG(Media, "TextTrackRegion::willRemoveTextTrackCueBox");
365 ASSERT(m_cueContainer->contains(box));
366
367 double boxHeight = box->getBoundingClientRect()->bottom() - box->getBounding ClientRect()->top();
368
369 m_cueContainer->classList()->remove(textTrackCueContainerScrollingClass(), A SSERT_NO_EXCEPTION);
370
371 m_currentTop += boxHeight;
372 m_cueContainer->setInlineStyleProperty(CSSPropertyTop, m_currentTop, CSSPrim itiveValue::CSS_PX);
373 }
374
375
376 void TextTrackRegion::appendTextTrackCueBox(PassRefPtr<TextTrackCueBox> displayB ox)
377 {
378 ASSERT(m_cueContainer);
379
380 if (m_cueContainer->contains(displayBox.get()))
381 return;
382
383 m_cueContainer->appendChild(displayBox);
384 displayLastTextTrackCueBox();
385 }
386
387 void TextTrackRegion::displayLastTextTrackCueBox()
388 {
389 LOG(Media, "TextTrackRegion::displayLastTextTrackCueBox");
390 ASSERT(m_cueContainer);
391
392 // FIXME: This should not be causing recalc styles in a loop to set the "top " css
393 // property to move elements. We should just scroll the text track cues on t he
394 // compositor with an animation.
395
396 if (m_scrollTimer.isActive())
397 return;
398
399 // If it's a scrolling region, add the scrolling class.
400 if (isScrollingRegion())
401 m_cueContainer->classList()->add(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
402
403 float regionBottom = m_regionDisplayTree->getBoundingClientRect()->bottom();
404
405 // Find first cue that is not entirely displayed and scroll it upwards.
406 for (size_t i = 0; i < m_cueContainer->childNodeCount() && !m_scrollTimer.is Active(); ++i) {
407 float childTop = toHTMLDivElement(m_cueContainer->childNode(i))->getBoun dingClientRect()->top();
408 float childBottom = toHTMLDivElement(m_cueContainer->childNode(i))->getB oundingClientRect()->bottom();
409
410 if (regionBottom >= childBottom)
411 continue;
412
413 float height = childBottom - childTop;
414
415 m_currentTop -= std::min(height, childBottom - regionBottom);
416 m_cueContainer->setInlineStyleProperty(CSSPropertyTop, m_currentTop, CSS PrimitiveValue::CSS_PX);
417
418 startTimer();
419 }
420 }
421
422 void TextTrackRegion::prepareRegionDisplayTree()
423 {
424 ASSERT(m_regionDisplayTree);
425
426 // 7.2 Prepare region CSS boxes
427
428 // FIXME: Change the code below to use viewport units when
429 // http://crbug/244618 is fixed.
430
431 // Let regionWidth be the text track region width.
432 // Let width be 'regionWidth vw' ('vw' is a CSS unit)
433 m_regionDisplayTree->setInlineStyleProperty(CSSPropertyWidth,
434 m_width, CSSPrimitiveValue::CSS_PERCENTAGE);
435
436 // Let lineHeight be '0.0533vh' ('vh' is a CSS unit) and regionHeight be
437 // the text track region height. Let height be 'lineHeight' multiplied
438 // by regionHeight.
439 double height = lineHeight * m_heightInLines;
440 m_regionDisplayTree->setInlineStyleProperty(CSSPropertyHeight,
441 height, CSSPrimitiveValue::CSS_VH);
442
443 // Let viewportAnchorX be the x dimension of the text track region viewport
444 // anchor and regionAnchorX be the x dimension of the text track region
445 // anchor. Let leftOffset be regionAnchorX multiplied by width divided by
446 // 100.0. Let left be leftOffset subtracted from 'viewportAnchorX vw'.
447 double leftOffset = m_regionAnchor.x() * m_width / 100;
448 m_regionDisplayTree->setInlineStyleProperty(CSSPropertyLeft,
449 m_viewportAnchor.x() - leftOffset,
450 CSSPrimitiveValue::CSS_PERCENTAGE);
451
452 // Let viewportAnchorY be the y dimension of the text track region viewport
453 // anchor and regionAnchorY be the y dimension of the text track region
454 // anchor. Let topOffset be regionAnchorY multiplied by height divided by
455 // 100.0. Let top be topOffset subtracted from 'viewportAnchorY vh'.
456 double topOffset = m_regionAnchor.y() * height / 100;
457 m_regionDisplayTree->setInlineStyleProperty(CSSPropertyTop,
458 m_viewportAnchor.y() - topOffset,
459 CSSPrimitiveValue::CSS_PERCENTAGE);
460
461
462 // The cue container is used to wrap the cues and it is the object which is
463 // gradually scrolled out as multiple cues are appended to the region.
464 m_cueContainer = HTMLDivElement::create(m_regionDisplayTree->document());
465 m_cueContainer->setInlineStyleProperty(CSSPropertyTop,
466 0.0,
467 CSSPrimitiveValue::CSS_PX);
468
469 m_cueContainer->setPart(textTrackCueContainerShadowPseudoId());
470 m_regionDisplayTree->appendChild(m_cueContainer);
471
472 // 7.5 Every WebVTT region object is initialised with the following CSS
473 m_regionDisplayTree->setPart(textTrackRegionShadowPseudoId());
474 }
475
476 void TextTrackRegion::startTimer()
477 {
478 LOG(Media, "TextTrackRegion::startTimer");
479
480 if (m_scrollTimer.isActive())
481 return;
482
483 double duration = isScrollingRegion() ? scrollTime : 0;
484 m_scrollTimer.startOneShot(duration);
485 }
486
487 void TextTrackRegion::stopTimer()
488 {
489 LOG(Media, "TextTrackRegion::stopTimer");
490
491 if (m_scrollTimer.isActive())
492 m_scrollTimer.stop();
493 }
494
495 void TextTrackRegion::scrollTimerFired(Timer<TextTrackRegion>*)
496 {
497 LOG(Media, "TextTrackRegion::scrollTimerFired");
498
499 stopTimer();
500 displayLastTextTrackCueBox();
501 }
502
503 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/html/track/TextTrackRegion.h ('k') | Source/core/html/track/TextTrackRegion.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698