⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmlparser.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // Set our strayTableContent boolean if needed, so that the reopened tag also knows        // that it is inside a malformed table.        m_blockStack->strayTableContent = malformedTableParent != 0;        if (m_blockStack->strayTableContent)            m_inStrayTableContent++;        // Clear our malformed table parent variable.        malformedTableParent = 0;        // Update |current| manually to point to the new node.        setCurrent(newNode.get());                // Advance to the next tag that needs to be reopened.        HTMLStackElem* next = elem->next;        elem->derefNode();        delete elem;        elem = next;    }}void HTMLParser::pushBlock(const AtomicString& tagName, int level){    m_blockStack = new HTMLStackElem(tagName, level, m_current, m_didRefCurrent, m_blockStack);    m_didRefCurrent = false;    if (tagName == pTag)        m_hasPElementInScope = InScope;    else if (isScopingTag(tagName))        m_hasPElementInScope = NotInScope;}void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors){    HTMLStackElem* elem = m_blockStack;        int maxLevel = 0;    while (elem && (elem->tagName != tagName)) {        if (maxLevel < elem->level)            maxLevel = elem->level;        elem = elem->next;    }    if (!elem) {        if (reportErrors)            reportError(StrayCloseTagError, &tagName, 0, true);        return;    }    if (maxLevel > elem->level) {        // We didn't match because the tag is in a different scope, e.g.,        // <b><p>Foo</b>.  Try to correct the problem.        if (!isResidualStyleTag(tagName))            return;        return handleResidualStyleCloseTagAcrossBlocks(elem);    }    bool isAffectedByStyle = isAffectedByResidualStyle(elem->tagName);    HTMLStackElem* residualStyleStack = 0;    Node* malformedTableParent = 0;        elem = m_blockStack;    unsigned stackDepth = 1;    unsigned redundantStyleCount = 0;    while (elem) {        if (elem->tagName == tagName) {            int strayTable = m_inStrayTableContent;            popOneBlock();            elem = 0;            // This element was the root of some malformed content just inside an implicit or            // explicit <tbody> or <tr>.            // If we end up needing to reopen residual style tags, the root of the reopened chain            // must also know that it is the root of malformed content inside a <tbody>/<tr>.            if (strayTable && (m_inStrayTableContent < strayTable) && residualStyleStack) {                Node* curr = m_current;                while (curr && !curr->hasTagName(tableTag))                    curr = curr->parentNode();                malformedTableParent = curr ? curr->parentNode() : 0;            }        }        else {            if (m_currentFormElement && elem->tagName == formTag)                // A <form> is being closed prematurely (and this is                // malformed HTML).  Set an attribute on the form to clear out its                // bottom margin.                m_currentFormElement->setMalformed(true);            // Schedule this tag for reopening            // after we complete the close of this entire block.            if (isAffectedByStyle && isResidualStyleTag(elem->tagName) && stackDepth++ < cResidualStyleMaxDepth) {                // We've overloaded the use of stack elements and are just reusing the                // struct with a slightly different meaning to the variables.  Instead of chaining                // from innermost to outermost, we build up a list of all the tags we need to reopen                // from the outermost to the innermost, i.e., residualStyleStack will end up pointing                // to the outermost tag we need to reopen.                // We also set elem->node to be the actual element that corresponds to the ID stored in                // elem->id rather than the node that you should pop to when the element gets pulled off                // the stack.                if (residualStyleStack && elem->tagName == residualStyleStack->tagName && elem->node->attributes()->mapsEquivalent(residualStyleStack->node->attributes()))                    redundantStyleCount++;                else                    redundantStyleCount = 0;                if (redundantStyleCount < cMaxRedundantTagDepth)                    moveOneBlockToStack(residualStyleStack);                else                    popOneBlock();            } else                popOneBlock();            elem = m_blockStack;        }    }    reopenResidualStyleTags(residualStyleStack, malformedTableParent);}inline HTMLStackElem* HTMLParser::popOneBlockCommon(){    HTMLStackElem* elem = m_blockStack;    // Form elements restore their state during the parsing process.    // Also, a few elements (<applet>, <object>) need to know when all child elements (<param>s) are available.    if (m_current && elem->node != m_current)        m_current->finishParsingChildren();    m_blockStack = elem->next;    m_current = elem->node;    m_didRefCurrent = elem->didRefNode;    if (elem->strayTableContent)        m_inStrayTableContent--;    if (elem->tagName == pTag)        m_hasPElementInScope = NotInScope;    else if (isScopingTag(elem->tagName))        m_hasPElementInScope = Unknown;    return elem;}void HTMLParser::popOneBlock(){    // Store the current node before popOneBlockCommon overwrites it.    Node* lastCurrent = m_current;    bool didRefLastCurrent = m_didRefCurrent;    delete popOneBlockCommon();    if (didRefLastCurrent)        lastCurrent->deref();}void HTMLParser::moveOneBlockToStack(HTMLStackElem*& head){    // We'll be using the stack element we're popping, but for the current node.    // See the two callers for details.    // Store the current node before popOneBlockCommon overwrites it.    Node* lastCurrent = m_current;    bool didRefLastCurrent = m_didRefCurrent;    // Pop the block, but don't deref the current node as popOneBlock does because    // we'll be using the pointer in the new stack element.    HTMLStackElem* elem = popOneBlockCommon();    // Transfer the current node into the stack element.    // No need to deref the old elem->node because popOneBlockCommon transferred    // it into the m_current/m_didRefCurrent fields.    elem->node = lastCurrent;    elem->didRefNode = didRefLastCurrent;    elem->next = head;    head = elem;}void HTMLParser::checkIfHasPElementInScope(){    m_hasPElementInScope = NotInScope;    HTMLStackElem* elem = m_blockStack;    while (elem) {        const AtomicString& tagName = elem->tagName;        if (tagName == pTag) {            m_hasPElementInScope = InScope;            return;        } else if (isScopingTag(tagName))            return;        elem = elem->next;    }}void HTMLParser::popInlineBlocks(){    while (m_blockStack && isInline(m_current))        popOneBlock();}void HTMLParser::freeBlock(){    while (m_blockStack)        popOneBlock();}void HTMLParser::createHead(){    if (m_head || !m_document->documentElement())        return;    m_head = new HTMLHeadElement(headTag, m_document);    HTMLElement* body = m_document->body();    ExceptionCode ec = 0;    m_document->documentElement()->insertBefore(m_head, body, ec);    if (ec)        m_head = 0;            // If the body does not exist yet, then the <head> should be pushed as the current block.    if (m_head && !body) {        pushBlock(m_head->localName(), m_head->tagPriority());        setCurrent(m_head);    }}PassRefPtr<Node> HTMLParser::handleIsindex(Token* t){    RefPtr<Node> n = new HTMLDivElement(divTag, m_document);    NamedMappedAttrMap* attrs = t->attrs.get();    RefPtr<HTMLIsIndexElement> isIndex = new HTMLIsIndexElement(isindexTag, m_document, m_currentFormElement.get());    isIndex->setAttributeMap(attrs);    isIndex->setAttribute(typeAttr, "khtml_isindex");    String text = searchableIndexIntroduction();    if (attrs) {        if (Attribute* a = attrs->getAttributeItem(promptAttr))            text = a->value().string() + " ";        t->attrs = 0;    }    n->addChild(new HTMLHRElement(hrTag, m_document));    n->addChild(new Text(m_document, text));    n->addChild(isIndex.release());    n->addChild(new HTMLHRElement(hrTag, m_document));    return n.release();}void HTMLParser::startBody(){    if (m_inBody)        return;    m_inBody = true;    if (m_isindexElement) {        insertNode(m_isindexElement.get(), true /* don't descend into this node */);        m_isindexElement = 0;    }}void HTMLParser::finished(){    // In the case of a completely empty document, here's the place to create the HTML element.    if (m_current && m_current->isDocumentNode() && !m_document->documentElement())        insertNode(new HTMLHtmlElement(htmlTag, m_document));    // This ensures that "current" is not left pointing to a node when the document is destroyed.    freeBlock();    setCurrent(0);    // Warning, this may delete the tokenizer and parser, so don't try to do anything else after this.    if (!m_isParsingFragment)        m_document->finishedParsing();}void HTMLParser::reportErrorToConsole(HTMLParserErrorCode errorCode, const AtomicString* tagName1, const AtomicString* tagName2, bool closeTags){        Frame* frame = m_document->frame();    if (!frame)        return;        HTMLTokenizer* htmlTokenizer = static_cast<HTMLTokenizer*>(m_document->tokenizer());    int lineNumber = htmlTokenizer->lineNumber() + 1;    AtomicString tag1;    AtomicString tag2;    if (tagName1) {        if (*tagName1 == "#text")            tag1 = "Text";        else if (*tagName1 == "#comment")            tag1 = "<!-- comment -->";        else            tag1 = (closeTags ? "</" : "<") + *tagName1 + ">";    }    if (tagName2) {        if (*tagName2 == "#text")            tag2 = "Text";        else if (*tagName2 == "#comment")            tag2 = "<!-- comment -->";        else            tag2 = (closeTags ? "</" : "<") + *tagName2 + ">";    }            const char* errorMsg = htmlParserErrorMessageTemplate(errorCode);    if (!errorMsg)        return;            String message;    if (htmlTokenizer->processingContentWrittenByScript())        message += htmlParserDocumentWriteMessage();    message += errorMsg;    message.replace("%tag1", tag1);    message.replace("%tag2", tag2);    frame->domWindow()->console()->addMessage(HTMLMessageSource,        isWarning(errorCode) ? WarningMessageLevel : ErrorMessageLevel,        message, lineNumber, m_document->url().string());}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -