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

📄 htmlparser.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // let's be stupid and just try to insert it.    // this should work if the document is well-formed    Node* newNode = m_current->addChild(n);    if (!newNode)        return handleError(n, flat, localName, tagPriority); // Try to handle the error.    // don't push elements without end tags (e.g., <img>) on the stack    bool parentAttached = m_current->attached();    if (tagPriority > 0 && !flat) {        if (newNode == m_current) {            // This case should only be hit when a demoted <form> is placed inside a table.            ASSERT(localName == formTag);            reportError(FormInsideTablePartError, &m_current->localName());        } else {            // The pushBlock function transfers ownership of current to the block stack            // so we're guaranteed that m_didRefCurrent is false. The code below is an            // optimized version of setCurrent that takes advantage of that fact and also            // assumes that newNode is neither 0 nor a pointer to the document.            pushBlock(localName, tagPriority);            newNode->beginParsingChildren();            ASSERT(!m_didRefCurrent);            newNode->ref();             m_current = newNode;            m_didRefCurrent = true;        }        if (parentAttached && !n->attached() && !m_isParsingFragment)            n->attach();    } else {        if (parentAttached && !n->attached() && !m_isParsingFragment)            n->attach();        n->finishParsingChildren();    }    if (localName == htmlTag && m_document->frame())        m_document->frame()->loader()->dispatchDocumentElementAvailable();    return true;}bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName, int tagPriority){    // Error handling code.  This is just ad hoc handling of specific parent/child combinations.    HTMLElement* e;    bool handled = false;    // 1. Check out the element's tag name to decide how to deal with errors.    if (n->isHTMLElement()) {        HTMLElement* h = static_cast<HTMLElement*>(n);        if (h->hasLocalName(trTag) || h->hasLocalName(thTag) || h->hasLocalName(tdTag)) {            if (m_inStrayTableContent && !isTableRelated(m_current)) {                reportError(MisplacedTablePartError, &localName, &m_current->localName());                // pop out to the nearest enclosing table-related tag.                while (m_blockStack && !isTableRelated(m_current))                    popOneBlock();                return insertNode(n);            }        } else if (h->hasLocalName(headTag)) {            if (!m_current->isDocumentNode() && !m_current->hasTagName(htmlTag)) {                reportError(MisplacedHeadError);                return false;            }        } else if (h->hasLocalName(metaTag) || h->hasLocalName(linkTag) || h->hasLocalName(baseTag)) {            bool createdHead = false;            if (!m_head) {                createHead();                createdHead = true;            }            if (m_head) {                if (!createdHead)                    reportError(MisplacedHeadContentError, &localName, &m_current->localName());                if (m_head->addChild(n)) {                    if (!n->attached() && !m_isParsingFragment)                        n->attach();                    return true;                } else                    return false;            }        } else if (h->hasLocalName(htmlTag)) {            if (!m_current->isDocumentNode() ) {                if (m_document->documentElement() && m_document->documentElement()->hasTagName(htmlTag)) {                    reportError(RedundantHTMLBodyError, &localName);                    // we have another <HTML> element.... apply attributes to existing one                    // make sure we don't overwrite already existing attributes                    NamedAttrMap* map = static_cast<Element*>(n)->attributes(true);                    Element* existingHTML = static_cast<Element*>(m_document->documentElement());                    NamedAttrMap* bmap = existingHTML->attributes(false);                    for (unsigned l = 0; map && l < map->length(); ++l) {                        Attribute* it = map->attributeItem(l);                        if (!bmap->getAttributeItem(it->name()))                            existingHTML->setAttribute(it->name(), it->value());                    }                }                return false;            }        } else if (h->hasLocalName(titleTag) || h->hasLocalName(styleTag)) {            bool createdHead = false;            if (!m_head) {                createHead();                createdHead = true;            }            if (m_head) {                Node* newNode = m_head->addChild(n);                if (!newNode) {                    setSkipMode(h->tagQName());                    return false;                }                                if (!createdHead)                    reportError(MisplacedHeadContentError, &localName, &m_current->localName());                                pushBlock(localName, tagPriority);                newNode->beginParsingChildren();                setCurrent(newNode);                if (!n->attached() && !m_isParsingFragment)                    n->attach();                return true;            }            if (m_inBody) {                setSkipMode(h->tagQName());                return false;            }        } else if (h->hasLocalName(bodyTag)) {            if (m_inBody && m_document->body()) {                // we have another <BODY> element.... apply attributes to existing one                // make sure we don't overwrite already existing attributes                // some sites use <body bgcolor=rightcolor>...<body bgcolor=wrongcolor>                reportError(RedundantHTMLBodyError, &localName);                NamedAttrMap* map = static_cast<Element*>(n)->attributes(true);                Element* existingBody = m_document->body();                NamedAttrMap* bmap = existingBody->attributes(false);                for (unsigned l = 0; map && l < map->length(); ++l) {                    Attribute* it = map->attributeItem(l);                    if (!bmap->getAttributeItem(it->name()))                        existingBody->setAttribute(it->name(), it->value());                }                return false;            }            else if (!m_current->isDocumentNode())                return false;        } else if (h->hasLocalName(areaTag)) {            if (m_currentMapElement) {                reportError(MisplacedAreaError, &m_current->localName());                m_currentMapElement->addChild(n);                if (!n->attached() && !m_isParsingFragment)                    n->attach();                handled = true;                return true;            }            return false;        } else if (h->hasLocalName(colgroupTag) || h->hasLocalName(captionTag)) {            if (isTableRelated(m_current)) {                while (m_blockStack && isTablePart(m_current))                    popOneBlock();                return insertNode(n);            }        }    } else if (n->isCommentNode() && !m_head)        return false;    // 2. Next we examine our currently active element to do some further error handling.    if (m_current->isHTMLElement()) {        HTMLElement* h = static_cast<HTMLElement*>(m_current);        const AtomicString& currentTagName = h->localName();        if (h->hasLocalName(htmlTag)) {            HTMLElement* elt = n->isHTMLElement() ? static_cast<HTMLElement*>(n) : 0;            if (elt && (elt->hasLocalName(scriptTag) || elt->hasLocalName(styleTag) ||                elt->hasLocalName(metaTag) || elt->hasLocalName(linkTag) ||                elt->hasLocalName(objectTag) || elt->hasLocalName(embedTag) ||                elt->hasLocalName(titleTag) || elt->hasLocalName(isindexTag) ||                elt->hasLocalName(baseTag))) {                if (!m_head) {                    m_head = new HTMLHeadElement(headTag, m_document);                    e = m_head;                    insertNode(e);                    handled = true;                }            } else {                if (n->isTextNode()) {                    Text* t = static_cast<Text*>(n);                    if (t->containsOnlyWhitespace())                        return false;                }                if (!m_haveFrameSet) {                    e = new HTMLBodyElement(bodyTag, m_document);                    startBody();                    insertNode(e);                    handled = true;                } else                    reportError(MisplacedFramesetContentError, &localName);            }        } else if (h->hasLocalName(headTag)) {            if (n->hasTagName(htmlTag))                return false;            else {                // This means the body starts here...                if (!m_haveFrameSet) {                    popBlock(currentTagName);                    e = new HTMLBodyElement(bodyTag, m_document);                    startBody();                    insertNode(e);                    handled = true;                } else                    reportError(MisplacedFramesetContentError, &localName);            }        } else if (h->hasLocalName(addressTag) || h->hasLocalName(fontTag)                   || h->hasLocalName(styleTag) || h->hasLocalName(titleTag)) {            reportError(MisplacedContentRetryError, &localName, &currentTagName);            popBlock(currentTagName);            handled = true;        } else if (h->hasLocalName(captionTag)) {            // Illegal content in a caption. Close the caption and try again.            reportError(MisplacedCaptionContentError, &localName);            popBlock(currentTagName);            if (isTablePart(n))                return insertNode(n, flat);        } else if (h->hasLocalName(tableTag) || h->hasLocalName(trTag) || isTableSection(h)) {            if (n->hasTagName(tableTag)) {                reportError(MisplacedTableError, &currentTagName);                if (m_isParsingFragment && !h->hasLocalName(tableTag))                    // fragment may contain table parts without <table> ancestor, pop them one by one                    popBlock(h->localName());                popBlock(localName); // end the table                handled = true;      // ...and start a new one            } else {                ExceptionCode ec = 0;                Node* node = m_current;                Node* parent = node->parentNode();                // A script may have removed the current node's parent from the DOM                // http://bugs.webkit.org/show_bug.cgi?id=7137                // FIXME: we should do real recovery here and re-parent with the correct node.                if (!parent)                    return false;                Node* grandparent = parent->parentNode();                if (n->isTextNode() ||                    (h->hasLocalName(trTag) &&                     isTableSection(parent) && grandparent && grandparent->hasTagName(tableTag)) ||                     ((!n->hasTagName(tdTag) && !n->hasTagName(thTag) &&                       !n->hasTagName(formTag) && !n->hasTagName(scriptTag)) && isTableSection(node) &&                     parent->hasTagName(tableTag))) {                    node = (node->hasTagName(tableTag)) ? node :                            ((node->hasTagName(trTag)) ? grandparent : parent);                    // This can happen with fragments                    if (!node)                        return false;                    Node* parent = node->parentNode();                    if (!parent)                        return false;                    parent->insertBefore(n, node, ec);                    if (!ec) {                        reportError(StrayTableContentError, &localName, &currentTagName);                        if (n->isHTMLElement() && tagPriority > 0 &&                             !flat && static_cast<HTMLElement*>(n)->endTagRequirement() != TagStatusForbidden)                        {                            pushBlock(localName, tagPriority);                            n->beginParsingChildren();                            setCurrent(n);                            m_inStrayTableContent++;                            m_blockStack->strayTableContent = true;                        }                        return true;                    }                }                if (!ec) {                    if (m_current->hasTagName(trTag)) {                        reportError(TablePartRequiredError, &localName, &tdTag.localName());                        e = new HTMLTableCellElement(tdTag, m_document);                    } else if (m_current->hasTagName(tableTag)) {                        // Don't report an error in this case, since making a <tbody> happens all the time when you have <table><tr>,                        // and it isn't really a parse error per se.                        e = new HTMLTableSectionElement(tbodyTag, m_document);                    } else {                        reportError(TablePartRequiredError, &localName, &trTag.localName());                        e = new HTMLTableRowElement(trTag, m_document);                    }                    insertNode(e);                    handled = true;                }            }        } else if (h->hasLocalName(objectTag)) {            reportError(MisplacedContentRetryError, &localName, &currentTagName);            popBlock(objectTag);            handled = true;        } else if (h->hasLocalName(pTag) || isHeaderTag(currentTagName)) {            if (!isInline(n)) {                popBlock(currentTagName);                handled = true;            }        } else if (h->hasLocalName(optionTag) || h->hasLocalName(optgroupTag)) {            if (localName == optgroupTag) {                popBlock(currentTagName);                handled = true;            } else if (localName == selectTag) {                // IE treats a nested select as </select>. Let's do the same                popBlock(localName);            }        } else if (h->hasLocalName(selectTag)) {            if (localName == inputTag || localName == textareaTag) {                reportError(MisplacedContentRetryError, &localName, &currentTagName);                popBlock(currentTagName);                handled = true;            }        } else if (h->hasLocalName(colgroupTag)) {            popBlock(currentTagName);            handled = true;        } else if (!h->hasLocalName(bodyTag)) {            if (isInline(m_current)) {                popInlineBlocks();                handled = true;            }        }    } else if (m_current->isDocumentNode()) {        if (n->isTextNode()) {            Text* t = static_cast<Text*>(n);            if (t->containsOnlyWhitespace())                return false;        }        if (!m_document->documentElement()) {            e = new HTMLHtmlElement(htmlTag, m_document);

⌨️ 快捷键说明

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