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

📄 htmlelement.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */#include "config.h"#include "HTMLElement.h"#include "CSSPropertyNames.h"#include "CSSValueKeywords.h"#include "DocumentFragment.h"#include "Event.h"#include "EventListener.h"#include "EventNames.h"#include "ExceptionCode.h"#include "Frame.h"#include "HTMLBRElement.h"#include "HTMLDocument.h"#include "HTMLElementFactory.h"#include "HTMLFormElement.h"#include "HTMLNames.h"#include "HTMLTokenizer.h" // parseHTMLDocumentFragment#include "RenderWordBreak.h"#include "Settings.h"#include "Text.h"#include "TextIterator.h"#include "XMLTokenizer.h"#include "markup.h"#include <wtf/StdLibExtras.h>namespace WebCore {using namespace HTMLNames;using std::min;using std::max;HTMLElement::HTMLElement(const QualifiedName& tagName, Document *doc)    : StyledElement(tagName, doc){}HTMLElement::~HTMLElement(){}String HTMLElement::nodeName() const{    // FIXME: Would be nice to have an atomicstring lookup based off uppercase chars that does not have to copy    // the string on a hit in the hash.    if (document()->isHTMLDocument())        return tagQName().localName().string().upper();    return Element::nodeName();}    HTMLTagStatus HTMLElement::endTagRequirement() const{    if (hasLocalName(wbrTag))        return TagStatusForbidden;    if (hasLocalName(dtTag) || hasLocalName(ddTag))        return TagStatusOptional;    // Same values as <span>.  This way custom tag name elements will behave like inline spans.    return TagStatusRequired;}int HTMLElement::tagPriority() const{    if (hasLocalName(wbrTag))        return 0;    if (hasLocalName(addressTag) || hasLocalName(ddTag) || hasLocalName(dtTag) || hasLocalName(noscriptTag))        return 3;    if (hasLocalName(centerTag) || hasLocalName(nobrTag))        return 5;    if (hasLocalName(noembedTag) || hasLocalName(noframesTag))        return 10;    // Same values as <span>.  This way custom tag name elements will behave like inline spans.    return 1;}bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const{    if (attrName == alignAttr ||        attrName == contenteditableAttr) {        result = eUniversal;        return false;    }    if (attrName == dirAttr) {        result = hasLocalName(bdoTag) ? eBDO : eUniversal;        return false;    }    return StyledElement::mapToEntry(attrName, result);}    void HTMLElement::parseMappedAttribute(MappedAttribute *attr){    if (attr->name() == idAttr || attr->name() == classAttr || attr->name() == styleAttr)        return StyledElement::parseMappedAttribute(attr);    String indexstring;    if (attr->name() == alignAttr) {        if (equalIgnoringCase(attr->value(), "middle"))            addCSSProperty(attr, CSSPropertyTextAlign, "center");        else            addCSSProperty(attr, CSSPropertyTextAlign, attr->value());    } else if (attr->name() == contenteditableAttr) {        setContentEditable(attr);    } else if (attr->name() == tabindexAttr) {        indexstring = getAttribute(tabindexAttr);        if (indexstring.length()) {            bool parsedOK;            int tabindex = indexstring.toIntStrict(&parsedOK);            if (parsedOK)                // Clamp tabindex to the range of 'short' to match Firefox's behavior.                setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));        }    } else if (attr->name() == langAttr) {        // FIXME: Implement    } else if (attr->name() == dirAttr) {        addCSSProperty(attr, CSSPropertyDirection, attr->value());        addCSSProperty(attr, CSSPropertyUnicodeBidi, hasLocalName(bdoTag) ? CSSValueBidiOverride : CSSValueEmbed);    }// standard events    else if (attr->name() == onclickAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().clickEvent, attr);    } else if (attr->name() == oncontextmenuAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().contextmenuEvent, attr);    } else if (attr->name() == ondblclickAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dblclickEvent, attr);    } else if (attr->name() == onmousedownAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().mousedownEvent, attr);    } else if (attr->name() == onmousemoveAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().mousemoveEvent, attr);    } else if (attr->name() == onmouseoutAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().mouseoutEvent, attr);    } else if (attr->name() == onmouseoverAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().mouseoverEvent, attr);    } else if (attr->name() == onmouseupAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().mouseupEvent, attr);    } else if (attr->name() == onmousewheelAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().mousewheelEvent, attr);    } else if (attr->name() == onfocusAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().focusEvent, attr);    } else if (attr->name() == onblurAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().blurEvent, attr);    } else if (attr->name() == onkeydownAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().keydownEvent, attr);    } else if (attr->name() == onkeypressAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().keypressEvent, attr);    } else if (attr->name() == onkeyupAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().keyupEvent, attr);    } else if (attr->name() == onscrollAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().scrollEvent, attr);    } else if (attr->name() == onbeforecutAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().beforecutEvent, attr);    } else if (attr->name() == oncutAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().cutEvent, attr);    } else if (attr->name() == onbeforecopyAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().beforecopyEvent, attr);    } else if (attr->name() == oncopyAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().copyEvent, attr);    } else if (attr->name() == onbeforepasteAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().beforepasteEvent, attr);    } else if (attr->name() == onpasteAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().pasteEvent, attr);    } else if (attr->name() == ondragenterAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dragenterEvent, attr);    } else if (attr->name() == ondragoverAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dragoverEvent, attr);    } else if (attr->name() == ondragleaveAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dragleaveEvent, attr);    } else if (attr->name() == ondropAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dropEvent, attr);    } else if (attr->name() == ondragstartAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dragstartEvent, attr);    } else if (attr->name() == ondragAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dragEvent, attr);    } else if (attr->name() == ondragendAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().dragendEvent, attr);    } else if (attr->name() == onselectstartAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().selectstartEvent, attr);    } else if (attr->name() == onsubmitAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().submitEvent, attr);    } else if (attr->name() == onerrorAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().errorEvent, attr);    } else if (attr->name() == onwebkitanimationstartAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationStartEvent, attr);    } else if (attr->name() == onwebkitanimationiterationAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationIterationEvent, attr);    } else if (attr->name() == onwebkitanimationendAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().webkitAnimationEndEvent, attr);    } else if (attr->name() == onwebkittransitionendAttr) {        setInlineEventListenerForTypeAndAttribute(eventNames().webkitTransitionEndEvent, attr);    }}String HTMLElement::innerHTML() const{    return createMarkup(this, ChildrenOnly);}String HTMLElement::outerHTML() const{    return createMarkup(this);}PassRefPtr<DocumentFragment> HTMLElement::createContextualFragment(const String &html){    // the following is in accordance with the definition as used by IE    if (endTagRequirement() == TagStatusForbidden)        return 0;    if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) ||        hasLocalName(headTag) || hasLocalName(styleTag) || hasLocalName(titleTag))        return 0;    RefPtr<DocumentFragment> fragment = new DocumentFragment(document());        if (document()->isHTMLDocument())         parseHTMLDocumentFragment(html, fragment.get());    else {        if (!parseXMLDocumentFragment(html, fragment.get(), this))            // FIXME: We should propagate a syntax error exception out here.            return 0;    }    // Exceptions are ignored because none ought to happen here.    int ignoredExceptionCode;    // we need to pop <html> and <body> elements and remove <head> to    // accommodate folks passing complete HTML documents to make the    // child of an element.    RefPtr<Node> nextNode;    for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {        nextNode = node->nextSibling();        if (node->hasTagName(htmlTag) || node->hasTagName(bodyTag)) {            Node *firstChild = node->firstChild();            if (firstChild)                nextNode = firstChild;            RefPtr<Node> nextChild;            for (RefPtr<Node> child = firstChild; child; child = nextChild) {                nextChild = child->nextSibling();                node->removeChild(child.get(), ignoredExceptionCode);                ASSERT(!ignoredExceptionCode);                fragment->insertBefore(child, node.get(), ignoredExceptionCode);                ASSERT(!ignoredExceptionCode);            }            fragment->removeChild(node.get(), ignoredExceptionCode);            ASSERT(!ignoredExceptionCode);        } else if (node->hasTagName(headTag)) {            fragment->removeChild(node.get(), ignoredExceptionCode);            ASSERT(!ignoredExceptionCode);        }    }    return fragment.release();}static inline bool hasOneChild(ContainerNode* node){    Node* firstChild = node->firstChild();    return firstChild && !firstChild->nextSibling();}static inline bool hasOneTextChild(ContainerNode* node){    return hasOneChild(node) && node->firstChild()->isTextNode();}static void replaceChildrenWithFragment(HTMLElement* element, PassRefPtr<DocumentFragment> fragment, ExceptionCode& ec){    if (!fragment->firstChild()) {        element->removeChildren();        return;    }    if (hasOneTextChild(element) && hasOneTextChild(fragment.get())) {        static_cast<Text*>(element->firstChild())->setData(static_cast<Text*>(fragment->firstChild())->string(), ec);        return;    }    if (hasOneChild(element)) {        element->replaceChild(fragment, element->firstChild(), ec);        return;    }    element->removeChildren();    element->appendChild(fragment, ec);}static void replaceChildrenWithText(HTMLElement* element, const String& text, ExceptionCode& ec){    if (hasOneTextChild(element)) {        static_cast<Text*>(element->firstChild())->setData(text, ec);        return;    }    RefPtr<Text> textNode = new Text(element->document(), text);    if (hasOneChild(element)) {        element->replaceChild(textNode.release(), element->firstChild(), ec);        return;    }    element->removeChildren();    element->appendChild(textNode.release(), ec);}void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec){    RefPtr<DocumentFragment> fragment = createContextualFragment(html);    if (!fragment) {        ec = NO_MODIFICATION_ALLOWED_ERR;        return;    }    replaceChildrenWithFragment(this, fragment.release(), ec);

⌨️ 快捷键说明

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