#ifndef Node_h
#define Node_h
#include "EventTarget.h"
#include "KURLHash.h"
#include "ScriptWrappable.h"
#include "TreeShared.h"
#include <wtf/ListHashSet.h>
namespace WebCore {
class AtomicString;
class Attribute;
class ContainerNode;
class Document;
class DynamicNodeList;
class Element;
class Event;
class EventListener;
class FloatPoint;
class Frame;
class IntRect;
class KeyboardEvent;
class NSResolver;
class NamedNodeMap;
class NodeList;
class NodeRareData;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
class PlatformWheelEvent;
class QualifiedName;
class RegisteredEventListener;
class RenderArena;
class RenderBox;
class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
class StringBuilder;
typedef int ExceptionCode;
enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, SyntheticStyleChange };
const unsigned short DOCUMENT_POSITION_EQUIVALENT = 0x00;
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
class Node : public EventTarget, public TreeShared<Node>, public ScriptWrappable {
friend class Document;
public:
enum NodeType {
ELEMENT_NODE = 1,
ATTRIBUTE_NODE = 2,
TEXT_NODE = 3,
CDATA_SECTION_NODE = 4,
ENTITY_REFERENCE_NODE = 5,
ENTITY_NODE = 6,
PROCESSING_INSTRUCTION_NODE = 7,
COMMENT_NODE = 8,
DOCUMENT_NODE = 9,
DOCUMENT_TYPE_NODE = 10,
DOCUMENT_FRAGMENT_NODE = 11,
NOTATION_NODE = 12,
XPATH_NAMESPACE_NODE = 13
};
static bool isSupported(const String& feature, const String& version);
static void startIgnoringLeaks();
static void stopIgnoringLeaks();
static void dumpStatistics();
enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
static StyleChange diff(const RenderStyle*, const RenderStyle*);
virtual ~Node();
bool hasTagName(const QualifiedName&) const;
virtual String nodeName() const = 0;
virtual String nodeValue() const;
virtual void setNodeValue(const String&, ExceptionCode&);
virtual NodeType nodeType() const = 0;
Node* parentNode() const { return parent(); }
Element* parentElement() const;
Node* previousSibling() const { return m_previous; }
Node* nextSibling() const { return m_next; }
PassRefPtr<NodeList> childNodes();
Node* firstChild() const { return isContainerNode() ? containerFirstChild() : 0; }
Node* lastChild() const { return isContainerNode() ? containerLastChild() : 0; }
bool hasAttributes() const;
NamedNodeMap* attributes() const;
virtual KURL baseURI() const;
void getSubresourceURLs(ListHashSet<KURL>&) const;
virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
virtual bool removeChild(Node* child, ExceptionCode&);
virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
void remove(ExceptionCode&);
bool hasChildNodes() const { return firstChild(); }
virtual PassRefPtr<Node> cloneNode(bool deep) = 0;
const AtomicString& localName() const { return virtualLocalName(); }
const AtomicString& namespaceURI() const { return virtualNamespaceURI(); }
const AtomicString& prefix() const { return virtualPrefix(); }
virtual void setPrefix(const AtomicString&, ExceptionCode&);
void normalize();
bool isSameNode(Node* other) const { return this == other; }
bool isEqualNode(Node*) const;
bool isDefaultNamespace(const AtomicString& namespaceURI) const;
String lookupPrefix(const AtomicString& namespaceURI) const;
String lookupNamespaceURI(const String& prefix) const;
String lookupNamespacePrefix(const AtomicString& namespaceURI, const Element* originalElement) const;
String textContent(bool convertBRsToNewlines = false) const;
void setTextContent(const String&, ExceptionCode&);
Node* lastDescendant() const;
Node* firstDescendant() const;
bool isElementNode() const { return m_isElement; }
bool isContainerNode() const { return m_isContainer; }
bool isTextNode() const { return m_isText; }
virtual bool isHTMLElement() const { return false; }
#if ENABLE(SVG)
virtual bool isSVGElement() const { return false; }
#else
static bool isSVGElement() { return false; }
#endif
#if ENABLE(WML)
virtual bool isWMLElement() const { return false; }
#else
static bool isWMLElement() { return false; }
#endif
#if ENABLE(MATHML)
virtual bool isMathMLElement() const { return false; }
#else
static bool isMathMLElement() { return false; }
#endif
virtual bool isMediaControlElement() const { return false; }
virtual bool isStyledElement() const { return false; }
virtual bool isFrameOwnerElement() const { return false; }
virtual bool isAttributeNode() const { return false; }
virtual bool isCommentNode() const { return false; }
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
virtual bool isShadowNode() const { return false; }
virtual Node* shadowParentNode() { return 0; }
Node* shadowAncestorNode();
Node* shadowTreeRootNode();
bool isInShadowTree();
virtual ContainerNode* eventParentNode();
Node* enclosingLinkEventParentOrSelf();
void eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors);
bool isBlockFlow() const;
bool isBlockFlowOrBlockTable() const;
void setPreviousSibling(Node* previous) { m_previous = previous; }
void setNextSibling(Node* next) { m_next = next; }
Node* previousNodeConsideringAtomicNodes() const;
Node* nextNodeConsideringAtomicNodes() const;
Node* nextLeafNode() const;
Node* previousLeafNode() const;
bool isEditableBlock() const;
Element* enclosingBlockFlowElement() const;
Element* enclosingInlineElement() const;
Element* rootEditableElement() const;
bool inSameContainingBlockFlowElement(Node*);
virtual ContainerNode* addChild(PassRefPtr<Node>);
virtual void finishParsingChildren() { }
virtual void beginParsingChildren() { }
virtual void aboutToUnload() { }
virtual bool sheetLoaded() { return true; }
bool hasID() const { return m_hasId; }
bool hasClass() const { return m_hasClass; }
bool active() const { return m_active; }
bool inActiveChain() const { return m_inActiveChain; }
bool inDetach() const { return m_inDetach; }
bool hovered() const { return m_hovered; }
bool focused() const { return hasRareData() ? rareDataFocused() : false; }
bool attached() const { return m_attached; }
void setAttached(bool b = true) { m_attached = b; }
bool needsStyleRecalc() const { return m_styleChange != NoStyleChange; }
StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_styleChange); }
bool childNeedsStyleRecalc() const { return m_childNeedsStyleRecalc; }
bool isLink() const { return m_isLink; }
void setHasID(bool b = true) { m_hasId = b; }
void setHasClass(bool b = true) { m_hasClass = b; }
void setChildNeedsStyleRecalc(bool b = true) { m_childNeedsStyleRecalc = b; }
void setInDocument(bool b = true) { m_inDocument = b; }
void setInActiveChain(bool b = true) { m_inActiveChain = b; }
void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
void setIsLink(bool b = true) { m_isLink = b; }
void lazyAttach();
virtual bool canLazyAttach();
virtual void setFocus(bool b = true);
virtual void setActive(bool b = true, bool = false) { m_active = b; }
virtual void setHovered(bool b = true) { m_hovered = b; }
virtual short tabIndex() const;
virtual bool supportsFocus() const;
virtual bool isFocusable() const;
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
virtual bool isMouseFocusable() const;
virtual bool isContentEditable() const;
virtual bool isContentRichlyEditable() const;
virtual bool shouldUseInputMethod() const;
virtual IntRect getRect() const;
virtual void recalcStyle(StyleChange = NoChange) { }
unsigned nodeIndex() const;
virtual Document* ownerDocument() const;
Document* document() const
{
ASSERT(this);
ASSERT(m_document || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
return m_document;
}
void setDocument(Document*);
bool inDocument() const
{
ASSERT(m_document || !m_inDocument);
return m_inDocument;
}
bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; }
virtual bool childTypeAllowed(NodeType) { return false; }
unsigned childNodeCount() const { return isContainerNode() ? containerChildNodeCount() : 0; }
Node* childNode(unsigned index) const { return isContainerNode() ? containerChildNode(index) : 0; }
Node* traverseNextNode(const Node* stayWithin = 0) const;
Node* traverseNextSibling(const Node* stayWithin = 0) const;
Node* traversePreviousNode(const Node * stayWithin = 0) const;
Node* traverseNextNodePostOrder() const;
Node* traversePreviousNodePostOrder(const Node *stayWithin = 0) const;
Node* traversePreviousSiblingPostOrder(const Node *stayWithin = 0) const;
Node* previousEditable() const;
Node* nextEditable() const;
RenderObject* renderer() const { return m_renderer; }
RenderObject* nextRenderer();
RenderObject* previousRenderer();
void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
RenderBox* renderBox() const;
RenderBoxModelObject* renderBoxModelObject() const;
void checkSetPrefix(const AtomicString& prefix, ExceptionCode&);
bool isDescendantOrShadowDescendantOf(const Node* otherNode);
bool isDescendantOf(const Node*) const;
bool contains(const Node*) const;
void checkAddChild(Node* newChild, ExceptionCode&); virtual bool childAllowed(Node* newChild);
void checkReplaceChild(Node* newChild, Node* oldChild, ExceptionCode&);
virtual bool canReplaceChild(Node* newChild, Node* oldChild);
virtual bool offsetInCharacters() const;
virtual int maxCharacterOffset() const;
virtual bool canSelectAll() const { return false; }
virtual void selectAll() { }
virtual bool canStartSelection() const;
FloatPoint convertToPage(const FloatPoint& p) const;
FloatPoint convertFromPage(const FloatPoint& p) const;
virtual void attach();
virtual void detach();
virtual void willRemove();
void createRendererIfNeeded();
PassRefPtr<RenderStyle> styleForRenderer();
virtual bool rendererIsNeeded(RenderStyle*);
#if ENABLE(SVG) || ENABLE(XHTMLMP)
virtual bool childShouldCreateRenderer(Node*) const { return true; }
#endif
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
RenderStyle* renderStyle() const;
virtual void setRenderStyle(PassRefPtr<RenderStyle>);
virtual RenderStyle* computedStyle();
virtual void insertedIntoDocument();
virtual void removedFromDocument();
virtual void insertedIntoTree(bool ) { }
virtual void removedFromTree(bool ) { }
virtual void childrenChanged(bool = false, Node* = 0, Node* = 0, int = 0) { }
#ifndef NDEBUG
virtual void formatForDebugger(char* buffer, unsigned length) const;
void showNode(const char* prefix = "") const;
void showTreeForThis() const;
void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
#endif
void registerDynamicNodeList(DynamicNodeList*);
void unregisterDynamicNodeList(DynamicNodeList*);
void notifyNodeListsChildrenChanged();
void notifyLocalNodeListsChildrenChanged();
void notifyNodeListsAttributeChanged();
void notifyLocalNodeListsAttributeChanged();
PassRefPtr<NodeList> getElementsByTagName(const String&);
PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const String& localName);
PassRefPtr<NodeList> getElementsByName(const String& elementName);
PassRefPtr<NodeList> getElementsByClassName(const String& classNames);
virtual bool willRespondToMouseMoveEvents();
virtual bool willRespondToMouseWheelEvents();
virtual bool willRespondToMouseClickEvents();
PassRefPtr<Element> querySelector(const String& selectors, ExceptionCode&);
PassRefPtr<NodeList> querySelectorAll(const String& selectors, ExceptionCode&);
unsigned short compareDocumentPosition(Node*);
virtual Node* toNode() { return this; }
virtual ScriptExecutionContext* scriptExecutionContext() const;
virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
virtual void* preDispatchEventHandler(Event*) { return 0; }
virtual void postDispatchEventHandler(Event*, void* ) { }
using EventTarget::dispatchEvent;
virtual bool dispatchEvent(PassRefPtr<Event>);
bool dispatchGenericEvent(PassRefPtr<Event>);
virtual void handleLocalEvents(Event*);
void dispatchSubtreeModifiedEvent();
void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent);
bool dispatchKeyEvent(const PlatformKeyboardEvent&);
void dispatchWheelEvent(PlatformWheelEvent&);
bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType,
int clickCount = 0, Node* relatedTarget = 0);
bool dispatchMouseEvent(const AtomicString& eventType, int button, int clickCount,
int pageX, int pageY, int screenX, int screenY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
bool isSimulated, Node* relatedTarget, PassRefPtr<Event> underlyingEvent);
void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent);
void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
virtual void dispatchFocusEvent();
virtual void dispatchBlurEvent();
virtual void defaultEventHandler(Event*);
virtual bool disabled() const;
using TreeShared<Node>::ref;
using TreeShared<Node>::deref;
virtual EventTargetData* eventTargetData();
virtual EventTargetData* ensureEventTargetData();
protected:
enum ConstructionType { CreateContainer, CreateElement, CreateOther, CreateText, CreateElementZeroRefCount };
Node(Document*, ConstructionType);
virtual void willMoveToNewOwnerDocument();
virtual void didMoveToNewOwnerDocument();
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
void setTabIndexExplicitly(short);
bool hasRareData() const { return m_hasRareData; }
#if ENABLE(SVG)
bool hasRareSVGData() const { return m_hasRareSVGData; }
#endif
NodeRareData* rareData() const;
NodeRareData* ensureRareData();
private:
static bool initialRefCount(ConstructionType);
static bool isContainer(ConstructionType);
static bool isElement(ConstructionType);
static bool isText(ConstructionType);
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
void removeAllEventListenersSlowCase();
virtual NodeRareData* createRareData();
Node* containerChildNode(unsigned index) const;
unsigned containerChildNodeCount() const;
Node* containerFirstChild() const;
Node* containerLastChild() const;
bool rareDataFocused() const;
virtual RenderStyle* nonRendererRenderStyle() const;
virtual const AtomicString& virtualPrefix() const;
virtual const AtomicString& virtualLocalName() const;
virtual const AtomicString& virtualNamespaceURI() const;
Element* ancestorElement() const;
void appendTextContent(bool convertBRsToNewlines, StringBuilder&) const;
Document* m_document;
Node* m_previous;
Node* m_next;
RenderObject* m_renderer;
unsigned m_styleChange : 2;
bool m_hasId : 1;
bool m_hasClass : 1;
bool m_attached : 1;
bool m_childNeedsStyleRecalc : 1;
bool m_inDocument : 1;
bool m_isLink : 1;
bool m_active : 1;
bool m_hovered : 1;
bool m_inActiveChain : 1;
bool m_inDetach : 1;
bool m_hasRareData : 1;
const bool m_isElement : 1;
const bool m_isContainer : 1;
const bool m_isText : 1;
protected:
bool m_parsingChildrenFinished : 1; mutable bool m_isStyleAttributeValid : 1; mutable bool m_synchronizingStyleAttribute : 1;
#if ENABLE(SVG)
mutable bool m_areSVGAttributesValid : 1; mutable bool m_synchronizingSVGAttributes : 1; bool m_hasRareSVGData : 1; #endif
};
inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
{
if (!url.isNull())
urls.add(url);
}
}
#ifndef NDEBUG
void showTree(const WebCore::Node*);
#endif
#endif