void TextTrackCue::markFutureAndPastNodes(ContainerNode* root, double previousTimestamp, double movieTime) { DEFINE_STATIC_LOCAL(const String, timestampTag, (ASCIILiteral("timestamp"))); bool isPastNode = true; double currentTimestamp = previousTimestamp; if (currentTimestamp > movieTime) isPastNode = false; for (Node* child = root->firstChild(); child; child = NodeTraversal::next(child, root)) { if (child->nodeName() == timestampTag) { unsigned position = 0; String timestamp = child->nodeValue(); double currentTimestamp = WebVTTParser::create(0, m_scriptExecutionContext)->collectTimeStamp(timestamp, &position); ASSERT(currentTimestamp != -1); if (currentTimestamp > movieTime) isPastNode = false; } if (child->isWebVTTElement()) { toWebVTTElement(child)->setIsPastNode(isPastNode); // Make an elemenet id match a cue id for style matching purposes. if (!m_id.isEmpty()) toElement(child)->setIdAttribute(AtomicString(m_id.characters(), m_id.length())); } } }
void VTTCue::markFutureAndPastNodes(ContainerNode* root, double previousTimestamp, double movieTime) { DEPRECATED_DEFINE_STATIC_LOCAL(const String, timestampTag, (ASCIILiteral("timestamp"))); bool isPastNode = true; double currentTimestamp = previousTimestamp; if (currentTimestamp > movieTime) isPastNode = false; for (Node* child = root->firstChild(); child; child = NodeTraversal::next(child, root)) { if (child->nodeName() == timestampTag) { double currentTimestamp; bool check = WebVTTParser::collectTimeStamp(child->nodeValue(), currentTimestamp); ASSERT_UNUSED(check, check); currentTimestamp += m_originalStartTime; if (currentTimestamp > movieTime) isPastNode = false; } if (child->isWebVTTElement()) { toWebVTTElement(child)->setIsPastNode(isPastNode); // Make an elemenet id match a cue id for style matching purposes. if (!id().isEmpty()) toElement(child)->setIdAttribute(id()); } } }
void TextTrackCue::copyWebVTTNodeToDOMTree(ContainerNode* webVTTNode, ContainerNode* parent) { for (Node* node = webVTTNode->firstChild(); node; node = node->nextSibling()) { RefPtr<Node> clonedNode; if (node->isWebVTTElement()) clonedNode = toWebVTTElement(node)->createEquivalentHTMLElement(ownerDocument()); else clonedNode = node->cloneNode(false); parent->appendChild(clonedNode, ASSERT_NO_EXCEPTION); if (node->isContainerNode()) copyWebVTTNodeToDOMTree(toContainerNode(node), toContainerNode(clonedNode.get())); } }
void WebVTTParser::constructTreeFromToken(Document& document) { QualifiedName tagName(nullAtom, AtomicString(m_token.name()), xhtmlNamespaceURI); // http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules switch (m_token.type()) { case WebVTTTokenTypes::Character: { String content(m_token.characters()); // FIXME: This should be 8bit if possible. RefPtr<Text> child = Text::create(document, content); m_currentNode->parserAppendChild(child); break; } case WebVTTTokenTypes::StartTag: { RefPtr<WebVTTElement> child; WebVTTNodeType nodeType = tokenToNodeType(m_token); if (nodeType != WebVTTNodeTypeNone) child = WebVTTElement::create(nodeType, &document); if (child) { if (m_token.classes().size() > 0) child->setAttribute(classAttr, AtomicString(m_token.classes())); if (child->webVTTNodeType() == WebVTTNodeTypeVoice) child->setAttribute(WebVTTElement::voiceAttributeName(), AtomicString(m_token.annotation())); else if (child->webVTTNodeType() == WebVTTNodeTypeLanguage) { m_languageStack.append(AtomicString(m_token.annotation())); child->setAttribute(WebVTTElement::langAttributeName(), m_languageStack.last()); } if (!m_languageStack.isEmpty()) child->setLanguage(m_languageStack.last()); m_currentNode->parserAppendChild(child); m_currentNode = child; } break; } case WebVTTTokenTypes::EndTag: { WebVTTNodeType nodeType = tokenToNodeType(m_token); if (nodeType != WebVTTNodeTypeNone) { if (nodeType == WebVTTNodeTypeLanguage && m_currentNode->isWebVTTElement() && toWebVTTElement(m_currentNode.get())->webVTTNodeType() == WebVTTNodeTypeLanguage) m_languageStack.removeLast(); if (m_currentNode->parentNode()) m_currentNode = m_currentNode->parentNode(); } break; } case WebVTTTokenTypes::TimestampTag: { unsigned position = 0; String charactersString(StringImpl::create8BitIfPossible(m_token.characters())); double time = collectTimeStamp(charactersString, &position); if (time != malformedTime) m_currentNode->parserAppendChild(ProcessingInstruction::create(document, "timestamp", charactersString)); break; } default: break; } m_token.clear(); }
void WebVTTTreeBuilder::constructTreeFromToken(Document& document) { // http://dev.w3.org/html5/webvtt/#webvtt-cue-text-dom-construction-rules switch (m_token.type()) { case WebVTTTokenTypes::Character: { RefPtr<Text> child = Text::create(document, m_token.characters()); m_currentNode->parserAppendChild(child); break; } case WebVTTTokenTypes::StartTag: { WebVTTNodeType nodeType = tokenToNodeType(m_token); if (nodeType == WebVTTNodeTypeNone) break; WebVTTNodeType currentType = m_currentNode->isWebVTTElement() ? toWebVTTElement(m_currentNode.get())->webVTTNodeType() : WebVTTNodeTypeNone; // <rt> is only allowed if the current node is <ruby>. if (nodeType == WebVTTNodeTypeRubyText && currentType != WebVTTNodeTypeRuby) break; RefPtr<WebVTTElement> child = WebVTTElement::create(nodeType, document); if (!m_token.classes().isEmpty()) child->setAttribute(classAttr, m_token.classes()); if (nodeType == WebVTTNodeTypeVoice) child->setAttribute(WebVTTElement::voiceAttributeName(), m_token.annotation()); else if (nodeType == WebVTTNodeTypeLanguage) { m_languageStack.append(m_token.annotation()); child->setAttribute(WebVTTElement::langAttributeName(), m_languageStack.last()); } if (!m_languageStack.isEmpty()) child->setLanguage(m_languageStack.last()); m_currentNode->parserAppendChild(child); m_currentNode = child; break; } case WebVTTTokenTypes::EndTag: { WebVTTNodeType nodeType = tokenToNodeType(m_token); if (nodeType == WebVTTNodeTypeNone) break; // The only non-VTTElement would be the DocumentFragment root. (Text // nodes and PIs will never appear as m_currentNode.) if (!m_currentNode->isWebVTTElement()) break; WebVTTNodeType currentType = toWebVTTElement(m_currentNode.get())->webVTTNodeType(); bool matchesCurrent = nodeType == currentType; if (!matchesCurrent) { // </ruby> auto-closes <rt> if (currentType == WebVTTNodeTypeRubyText && nodeType == WebVTTNodeTypeRuby) { if (m_currentNode->parentNode()) m_currentNode = m_currentNode->parentNode(); } else break; } if (nodeType == WebVTTNodeTypeLanguage) m_languageStack.removeLast(); if (m_currentNode->parentNode()) m_currentNode = m_currentNode->parentNode(); break; } case WebVTTTokenTypes::TimestampTag: { String charactersString = m_token.characters(); double parsedTimeStamp; if (WebVTTParser::collectTimeStamp(charactersString, parsedTimeStamp)) m_currentNode->parserAppendChild(ProcessingInstruction::create(document, "timestamp", charactersString)); break; } default: break; } }