void TextTrackCue::updateDisplayTree(float movieTime) { // The display tree may contain WebVTT timestamp objects representing // timestamps (processing instructions), along with displayable nodes. DEFINE_STATIC_LOCAL(const String, timestampTag, ("timestamp")); DEFINE_STATIC_LOCAL(const AtomicString, trackPastNodesShadowPseudoId, ("-webkit-media-text-track-past-nodes")); DEFINE_STATIC_LOCAL(const AtomicString, trackFutureNodesShadowPseudoId, ("-webkit-media-text-track-future-nodes")); if (!track()->isRendered()) return; bool isPastNode = true; // Clear the contents of the two sets. m_futureDocumentNodes->removeChildren(); m_futureDocumentNodes->setShadowPseudoId(trackFutureNodesShadowPseudoId); m_pastDocumentNodes->removeChildren(); m_pastDocumentNodes->setShadowPseudoId(trackPastNodesShadowPseudoId); // Update the two sets containing past and future WebVTT objects. RefPtr<DocumentFragment> referenceTree = getCueAsHTML(); if (!m_hasInnerTimestamps) { m_pastDocumentNodes->appendChild(referenceTree); return; } for (Node *child = referenceTree->firstChild(); child; child = child->nextSibling()) { if (child->nodeName() == timestampTag) { unsigned int position = 0; String timestamp = child->nodeValue(); double timestampTime = WebVTTParser::create(0, m_scriptExecutionContext)->collectTimeStamp(timestamp, &position); ASSERT(timestampTime != -1); if (timestampTime > movieTime) isPastNode = false; } if (isPastNode) m_pastDocumentNodes->appendChild(child->cloneNode(true), ASSERT_NO_EXCEPTION, false); else m_futureDocumentNodes->appendChild(child->cloneNode(true), ASSERT_NO_EXCEPTION, false); } }
PassRefPtr<HTMLDivElement> TextTrackCue::getDisplayTree() { DEFINE_STATIC_LOCAL(const AtomicString, trackBackgroundShadowPseudoId, ("-webkit-media-text-track-background")); DEFINE_STATIC_LOCAL(const AtomicString, trackDisplayBoxShadowPseudoId, ("-webkit-media-text-track-display")); if (!m_displayTreeShouldChange) return m_displayTree; // 10.1 - 10.10 calculateDisplayParameters(); // 10.11. Apply the terms of the CSS specifications to nodes within the // following constraints, thus obtaining a set of CSS boxes positioned // relative to an initial containing block: m_displayTree->removeChildren(); // The document tree is the tree of WebVTT Node Objects rooted at nodes. // The children of the nodes must be wrapped in an anonymous box whose // 'display' property has the value 'inline'. This is the WebVTT cue // background box. RefPtr<HTMLDivElement> cueBackgroundBox = HTMLDivElement::create(static_cast<Document*>(m_scriptExecutionContext)); cueBackgroundBox->setShadowPseudoId(trackBackgroundShadowPseudoId); cueBackgroundBox->appendChild(getCueAsHTML(), ASSERT_NO_EXCEPTION, true); m_displayTree->setShadowPseudoId(trackDisplayBoxShadowPseudoId, ASSERT_NO_EXCEPTION); m_displayTree->appendChild(cueBackgroundBox, ASSERT_NO_EXCEPTION, true); // FIXME(BUG 79916): Runs of children of WebVTT Ruby Objects that are not // WebVTT Ruby Text Objects must be wrapped in anonymous boxes whose // 'display' property has the value 'ruby-base'. // FIXME(BUG 79916): Text runs must be wrapped according to the CSS // line-wrapping rules, except that additionally, regardless of the value of // the 'white-space' property, lines must be wrapped at the edge of their // containing blocks, even if doing so requires splitting a word where there // is no line breaking opportunity. (Thus, normally text wraps as needed, // but if there is a particularly long word, it does not overflow as it // normally would in CSS, it is instead forcibly wrapped at the box's edge.) // FIXME(BUG 79916): CSS width property should be set to 'size vw', when the // maximum cue size computation is corrected in the specification. if (m_snapToLines) m_displayTree->setInlineStyleProperty(CSSPropertyWidth, (double) m_cueSize, CSSPrimitiveValue::CSS_PERCENTAGE); // FIXME(BUG 79750, 79751): Steps 10.12 - 10.14 if (!m_snapToLines) { std::pair<double, double> position = getPositionCoordinates(); // 10.13.1 Set up x and y: m_displayTree->setInlineStyleProperty(CSSPropertyLeft, position.first, CSSPrimitiveValue::CSS_PERCENTAGE); m_displayTree->setInlineStyleProperty(CSSPropertyTop, position.second, CSSPrimitiveValue::CSS_PERCENTAGE); // 10.13.2 Position the boxes in boxes such that the point x% along the // width of the bounding box of the boxes in boxes is x% of the way // across the width of the video's rendering area, and the point y% // along the height of the bounding box of the boxes in boxes is y% // of the way across the height of the video's rendering area, while // maintaining the relative positions of the boxes in boxes to each // other. String translateX = "-" + String::number(position.first) + "%"; String translateY = "-" + String::number(position.second) + "%"; String webkitTransformTranslateValue = "translate(" + translateX + "," + translateY + ")"; m_displayTree->setInlineStyleProperty(CSSPropertyWebkitTransform, webkitTransformTranslateValue); m_displayTree->setInlineStyleProperty(CSSPropertyWhiteSpace, CSSValuePre); } m_displayTreeShouldChange = false; // 10.15. Let cue's text track cue display state have the CSS boxes in // boxes. return m_displayTree; }