Пример #1
0
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;
    }
}
Пример #2
0
static WebVTTNodeType tokenToNodeType(WebVTTToken& token)
{
    switch (token.name().size()) {
    case 1:
        if (token.name()[0] == 'c')
            return WebVTTNodeTypeClass;
        if (token.name()[0] == 'v')
            return WebVTTNodeTypeVoice;
        if (token.name()[0] == 'b')
            return WebVTTNodeTypeBold;
        if (token.name()[0] == 'i')
            return WebVTTNodeTypeItalic;
        if (token.name()[0] == 'u')
            return WebVTTNodeTypeUnderline;
        break;
    case 2:
        if (token.name()[0] == 'r' && token.name()[1] == 't')
            return WebVTTNodeTypeRubyText;
        break;
    case 4:
        if (token.name()[0] == 'r' && token.name()[1] == 'u' && token.name()[2] == 'b' && token.name()[3] == 'y')
            return WebVTTNodeTypeRuby;
        if (token.name()[0] == 'l' && token.name()[1] == 'a' && token.name()[2] == 'n' && token.name()[3] == 'g')
            return WebVTTNodeTypeLanguage;
        break;
    }
    return WebVTTNodeTypeNone;
}
Пример #3
0
static inline bool isLangToken(WebVTTToken& token)
{
    return token.name().size() == 4 && token.name()[0] == 'l' && token.name()[1] == 'a' && token.name()[2] == 'n' && token.name()[3] == 'g';
}