summaryrefslogtreecommitdiffstats
path: root/WebCore/dom
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom')
-rw-r--r--WebCore/dom/CharacterData.cpp7
-rw-r--r--WebCore/dom/CharacterData.h7
-rw-r--r--WebCore/dom/ClassNodeList.cpp10
-rw-r--r--WebCore/dom/ClassNodeList.h9
-rw-r--r--WebCore/dom/Comment.cpp4
-rw-r--r--WebCore/dom/Comment.h1
-rw-r--r--WebCore/dom/ContainerNode.cpp4
-rw-r--r--WebCore/dom/Document.cpp65
-rw-r--r--WebCore/dom/Document.h17
-rw-r--r--WebCore/dom/Document.idl8
-rw-r--r--WebCore/dom/DocumentFragment.cpp2
-rw-r--r--WebCore/dom/EditingText.cpp2
-rw-r--r--WebCore/dom/Element.cpp32
-rw-r--r--WebCore/dom/Element.h16
-rw-r--r--WebCore/dom/Element.idl8
-rw-r--r--WebCore/dom/EntityReference.cpp2
-rw-r--r--WebCore/dom/EventNames.h2
-rw-r--r--WebCore/dom/EventTarget.cpp7
-rw-r--r--WebCore/dom/EventTarget.h4
-rw-r--r--WebCore/dom/ExceptionCode.h7
-rw-r--r--WebCore/dom/InputElement.cpp174
-rw-r--r--WebCore/dom/InputElement.h23
-rw-r--r--WebCore/dom/MessagePort.idl12
-rw-r--r--WebCore/dom/NameNodeList.cpp9
-rw-r--r--WebCore/dom/NameNodeList.h8
-rw-r--r--WebCore/dom/Node.cpp284
-rw-r--r--WebCore/dom/Node.h243
-rw-r--r--WebCore/dom/Node.idl14
-rw-r--r--WebCore/dom/NodeFilter.idl2
-rw-r--r--WebCore/dom/NodeIterator.idl4
-rw-r--r--WebCore/dom/NodeRareData.h17
-rw-r--r--WebCore/dom/Notation.cpp2
-rw-r--r--WebCore/dom/PopStateEvent.idl6
-rw-r--r--WebCore/dom/Position.cpp47
-rw-r--r--WebCore/dom/QualifiedName.cpp1
-rw-r--r--WebCore/dom/QualifiedName.h8
-rw-r--r--WebCore/dom/ScriptExecutionContext.h1
-rw-r--r--WebCore/dom/SelectElement.cpp27
-rw-r--r--WebCore/dom/SelectElement.h6
-rw-r--r--WebCore/dom/StyledElement.cpp21
-rw-r--r--WebCore/dom/StyledElement.h11
-rw-r--r--WebCore/dom/TagNodeList.cpp9
-rw-r--r--WebCore/dom/TagNodeList.h8
-rw-r--r--WebCore/dom/Text.cpp5
-rw-r--r--WebCore/dom/Text.h5
-rw-r--r--WebCore/dom/Tokenizer.h2
-rw-r--r--WebCore/dom/TreeDepthLimit.h40
-rw-r--r--WebCore/dom/TreeWalker.idl14
-rw-r--r--WebCore/dom/XMLTokenizer.cpp4
49 files changed, 837 insertions, 384 deletions
diff --git a/WebCore/dom/CharacterData.cpp b/WebCore/dom/CharacterData.cpp
index f5adb6c..9670988 100644
--- a/WebCore/dom/CharacterData.cpp
+++ b/WebCore/dom/CharacterData.cpp
@@ -29,13 +29,6 @@
namespace WebCore {
-CharacterData::CharacterData(Document* document, const String& text, ConstructionType type)
- : Node(document, type)
- , m_data(text.impl() ? text.impl() : StringImpl::empty())
-{
- ASSERT(type == CreateOther || type == CreateText);
-}
-
void CharacterData::setData(const String& data, ExceptionCode&)
{
StringImpl* dataImpl = data.impl() ? data.impl() : StringImpl::empty();
diff --git a/WebCore/dom/CharacterData.h b/WebCore/dom/CharacterData.h
index 6c31933..5ca4b75 100644
--- a/WebCore/dom/CharacterData.h
+++ b/WebCore/dom/CharacterData.h
@@ -43,7 +43,12 @@ public:
StringImpl* dataImpl() { return m_data.get(); }
protected:
- CharacterData(Document*, const String&, ConstructionType);
+ CharacterData(Document* document, const String& text, ConstructionType type)
+ : Node(document, type)
+ , m_data(text.impl() ? text.impl() : StringImpl::empty())
+ {
+ ASSERT(type == CreateComment || type == CreateText);
+ }
virtual bool rendererIsNeeded(RenderStyle*);
diff --git a/WebCore/dom/ClassNodeList.cpp b/WebCore/dom/ClassNodeList.cpp
index a7aefba..d482359 100644
--- a/WebCore/dom/ClassNodeList.cpp
+++ b/WebCore/dom/ClassNodeList.cpp
@@ -35,12 +35,18 @@
namespace WebCore {
-ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, DynamicNodeList::Caches* caches)
- : DynamicNodeList(rootNode, caches)
+ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames)
+ : DynamicNodeList(rootNode)
, m_classNames(classNames, m_rootNode->document()->inCompatMode())
+ , m_originalClassNames(classNames)
{
}
+ClassNodeList::~ClassNodeList()
+{
+ m_rootNode->removeCachedClassNodeList(this, m_originalClassNames);
+}
+
bool ClassNodeList::nodeMatches(Element* testNode) const
{
if (!testNode->hasClass())
diff --git a/WebCore/dom/ClassNodeList.h b/WebCore/dom/ClassNodeList.h
index c519b3e..ea048a2 100644
--- a/WebCore/dom/ClassNodeList.h
+++ b/WebCore/dom/ClassNodeList.h
@@ -37,17 +37,20 @@ namespace WebCore {
class ClassNodeList : public DynamicNodeList {
public:
- static PassRefPtr<ClassNodeList> create(PassRefPtr<Node> rootNode, const String& classNames, Caches* caches)
+ static PassRefPtr<ClassNodeList> create(PassRefPtr<Node> rootNode, const String& classNames)
{
- return adoptRef(new ClassNodeList(rootNode, classNames, caches));
+ return adoptRef(new ClassNodeList(rootNode, classNames));
}
+ virtual ~ClassNodeList();
+
private:
- ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames, Caches*);
+ ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames);
virtual bool nodeMatches(Element*) const;
SpaceSplitString m_classNames;
+ String m_originalClassNames;
};
} // namespace WebCore
diff --git a/WebCore/dom/Comment.cpp b/WebCore/dom/Comment.cpp
index 3dcde38..00f1724 100644
--- a/WebCore/dom/Comment.cpp
+++ b/WebCore/dom/Comment.cpp
@@ -22,10 +22,12 @@
#include "config.h"
#include "Comment.h"
+#include "Document.h"
+
namespace WebCore {
inline Comment::Comment(Document* document, const String& text)
- : CharacterData(document, text, CreateOther)
+ : CharacterData(document, text, CreateComment)
{
}
diff --git a/WebCore/dom/Comment.h b/WebCore/dom/Comment.h
index 680ffae..a0210c4 100644
--- a/WebCore/dom/Comment.h
+++ b/WebCore/dom/Comment.h
@@ -37,7 +37,6 @@ private:
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
- virtual bool isCommentNode() const { return true; }
virtual bool childTypeAllowed(NodeType);
};
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index f42b9cf..b063998 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -616,7 +616,7 @@ void ContainerNode::detach()
{
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->detach();
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
Node::detach();
}
@@ -633,7 +633,7 @@ void ContainerNode::removedFromDocument()
Node::removedFromDocument();
if (document()->cssTarget() == this)
document()->setCSSTarget(0);
- setInDocument(false);
+ clearInDocument();
removedFromTree(false);
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->removedFromDocument();
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index ffbfd24..c6920bf 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -78,6 +78,7 @@
#include "HTMLParser.h"
#include "HTMLStyleElement.h"
#include "HTMLTitleElement.h"
+#include "HTMLTokenizer.h"
#include "HTTPParsers.h"
#include "HistoryItem.h"
#include "HitTestRequest.h"
@@ -191,6 +192,9 @@
#endif
#if ENABLE(TOUCH_EVENTS)
+#if USE(V8)
+#include "RuntimeEnabledFeatures.h"
+#endif
#include "TouchEvent.h"
#endif
@@ -219,6 +223,29 @@ namespace WebCore {
using namespace HTMLNames;
+class SynchronousHTMLTokenizerGuard {
+public:
+ SynchronousHTMLTokenizerGuard(Tokenizer* tokenizer)
+ : m_htmlTokenizer(tokenizer->asHTMLTokenizer())
+ , m_savedForceSynchronous(false)
+ {
+ if (m_htmlTokenizer) {
+ m_savedForceSynchronous = m_htmlTokenizer->forceSynchronous();
+ m_htmlTokenizer->setForceSynchronous(true);
+ }
+ }
+
+ ~SynchronousHTMLTokenizerGuard()
+ {
+ if (m_htmlTokenizer)
+ m_htmlTokenizer->setForceSynchronous(m_savedForceSynchronous);
+ }
+
+private:
+ HTMLTokenizer* m_htmlTokenizer;
+ bool m_savedForceSynchronous;
+};
+
// #define INSTRUMENT_LAYOUT_SCHEDULING 1
// This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
@@ -439,7 +466,7 @@ Document::Document(Frame* frame, bool isXHTML, bool isHTML)
m_textColor = Color::black;
m_listenerTypes = 0;
- m_inDocument = true;
+ setInDocument();
m_inStyleRecalc = false;
m_closeAfterStyleRecalc = false;
@@ -1421,7 +1448,7 @@ void Document::recalcStyle(StyleChange change)
bail_out:
setNeedsStyleRecalc(NoStyleChange);
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
unscheduleStyleRecalc();
if (view())
@@ -1997,8 +2024,11 @@ void Document::write(const SegmentedString& text, Document* ownerDocument)
if (!m_tokenizer)
open(ownerDocument);
- ASSERT(m_tokenizer);
- m_tokenizer->write(text, false);
+ {
+ ASSERT(m_tokenizer);
+ SynchronousHTMLTokenizerGuard tokenizerGuard(m_tokenizer.get());
+ m_tokenizer->write(text, false);
+ }
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!ownerElement())
@@ -2891,7 +2921,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
m_focusedNode = 0;
// Remove focus from the existing focus node (if any)
- if (oldFocusedNode && !oldFocusedNode->m_inDetach) {
+ if (oldFocusedNode && !oldFocusedNode->inDetach()) {
if (oldFocusedNode->active())
oldFocusedNode->setActive(false);
@@ -2927,6 +2957,14 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
if (oldFocusedNode == oldFocusedNode->rootEditableElement())
frame()->editor()->didEndEditing();
+
+ if (view()) {
+ Widget* oldWidget = widgetForNode(oldFocusedNode.get());
+ if (oldWidget)
+ oldWidget->setFocus(false);
+ else
+ view()->setFocus(false);
+ }
}
if (newFocusedNode) {
@@ -2954,7 +2992,7 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
focusChangeBlocked = true;
goto SetFocusedNodeDone;
}
- m_focusedNode->setFocus();
+ m_focusedNode->setFocus(true);
if (m_focusedNode == m_focusedNode->rootEditableElement())
frame()->editor()->didBeginEditing();
@@ -2972,9 +3010,9 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
focusWidget = widgetForNode(m_focusedNode.get());
}
if (focusWidget)
- focusWidget->setFocus();
+ focusWidget->setFocus(true);
else
- view()->setFocus();
+ view()->setFocus(true);
}
}
@@ -3212,7 +3250,11 @@ PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode&
event = SVGZoomEvent::create();
#endif
#if ENABLE(TOUCH_EVENTS)
+#if USE(V8)
+ else if (eventType == "TouchEvent" && RuntimeEnabledFeatures::touchEnabled())
+#else
else if (eventType == "TouchEvent")
+#endif
event = TouchEvent::create();
#endif
if (event)
@@ -4543,6 +4585,8 @@ void Document::setIconURL(const String& iconURL, const String& type)
m_iconURL = iconURL;
else if (!type.isEmpty())
m_iconURL = iconURL;
+ if (Frame* f = frame())
+ f->loader()->setIconURL(m_iconURL);
}
void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
@@ -4900,10 +4944,9 @@ void Document::enqueuePageshowEvent(PageshowEventPersistence persisted)
void Document::enqueueHashchangeEvent(const String& /*oldURL*/, const String& /*newURL*/)
{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36201 Hashchange event needs to fire asynchronously.
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=36335 Hashchange event is now its own interface and takes two
// URL arguments which we need to pass in here.
- dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false));
+ enqueueEvent(Event::create(eventNames().hashchangeEvent, false, false));
}
void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
@@ -4921,7 +4964,7 @@ bool Document::isXHTMLMPDocument() const
// MUST accept XHTMLMP document identified as "application/vnd.wap.xhtml+xml"
// and SHOULD accept it identified as "application/xhtml+xml" , "application/xhtml+xml" is a
// general MIME type for all XHTML documents, not only for XHTMLMP
- return frame()->loader()->responseMIMEType() == "application/vnd.wap.xhtml+xml";
+ return frame()->loader()->writer()->mimeType() == "application/vnd.wap.xhtml+xml";
}
#endif
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 6ac1f01..45031c3 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -958,6 +958,7 @@ public:
#endif
virtual bool isContextThread() const;
+ virtual bool isJSExecutionTerminated() const { return false; }
void setUsingGeolocation(bool f) { m_usingGeolocation = f; }
bool usingGeolocation() const { return m_usingGeolocation; };
@@ -1264,6 +1265,22 @@ inline bool Node::isDocumentNode() const
return this == m_document;
}
+// here because it uses a Document method but we really want to inline it
+inline Node::Node(Document* document, ConstructionType type)
+ : TreeShared<Node>(initialRefCount(type))
+ , m_document(document)
+ , m_previous(0)
+ , m_next(0)
+ , m_renderer(0)
+ , m_nodeFlags(type)
+{
+ if (m_document)
+ m_document->selfOnlyRef();
+#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
+ trackForDebugging();
+#endif
+}
+
} // namespace WebCore
#endif // Document_h
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index 88bd639..cd877b3 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -306,10 +306,10 @@ module core {
attribute [DontEnum] EventListener onreset;
attribute [DontEnum] EventListener onsearch;
attribute [DontEnum] EventListener onselectstart;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchstart;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchmove;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchend;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchcancel;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchstart;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchmove;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchend;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchcancel;
#endif
};
diff --git a/WebCore/dom/DocumentFragment.cpp b/WebCore/dom/DocumentFragment.cpp
index 3663e99..f7df8f6 100644
--- a/WebCore/dom/DocumentFragment.cpp
+++ b/WebCore/dom/DocumentFragment.cpp
@@ -23,6 +23,8 @@
#include "config.h"
#include "DocumentFragment.h"
+#include "Document.h"
+
namespace WebCore {
inline DocumentFragment::DocumentFragment(Document* document)
diff --git a/WebCore/dom/EditingText.cpp b/WebCore/dom/EditingText.cpp
index b36931a..e412ad6 100644
--- a/WebCore/dom/EditingText.cpp
+++ b/WebCore/dom/EditingText.cpp
@@ -20,6 +20,8 @@
#include "config.h"
#include "EditingText.h"
+#include "Document.h"
+
// FIXME: Does this really require a class? Perhaps instead any text node
// inside an editable element could have the "always create a renderer" behavior.
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 3363e95..171a869 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -64,12 +64,6 @@ namespace WebCore {
using namespace HTMLNames;
using namespace XMLNames;
-Element::Element(const QualifiedName& tagName, Document* document, ConstructionType type)
- : ContainerNode(document, type)
- , m_tagName(tagName)
-{
-}
-
PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
{
return adoptRef(new Element(tagName, document, CreateElement));
@@ -161,12 +155,12 @@ PassRefPtr<Element> Element::cloneElementWithoutChildren()
// This is a sanity check as HTML overloads some of the DOM methods.
ASSERT(isHTMLElement() == clone->isHTMLElement());
- clone->copyNonAttributeProperties(this);
-
// Clone attributes.
if (namedAttrMap)
clone->attributes()->setAttributes(*attributes(true)); // Call attributes(true) to force attribute synchronization to occur (for svg and style) before cloning happens.
+ clone->copyNonAttributeProperties(this);
+
return clone.release();
}
@@ -225,11 +219,11 @@ bool Element::hasAttribute(const QualifiedName& name) const
const AtomicString& Element::getAttribute(const QualifiedName& name) const
{
- if (name == styleAttr && !m_isStyleAttributeValid)
+ if (name == styleAttr && !isStyleAttributeValid())
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid)
+ if (!areSVGAttributesValid())
updateAnimatedSVGAttribute(name);
#endif
@@ -532,11 +526,11 @@ const AtomicString& Element::getAttribute(const String& name) const
bool ignoreCase = shouldIgnoreAttributeCase(this);
// Update the 'style' attribute if it's invalid and being requested:
- if (!m_isStyleAttributeValid && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
+ if (!isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid) {
+ if (!areSVGAttributesValid()) {
// We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
}
@@ -583,7 +577,7 @@ void Element::setAttribute(const AtomicString& name, const AtomicString& value,
#if ENABLE(INSPECTOR)
if (Page* page = document()->page()) {
if (InspectorController* inspectorController = page->inspectorController()) {
- if (!m_synchronizingStyleAttribute)
+ if (!isSynchronizingStyleAttribute())
inspectorController->didModifyDOMAttr(this);
}
}
@@ -612,7 +606,7 @@ void Element::setAttribute(const QualifiedName& name, const AtomicString& value,
#if ENABLE(INSPECTOR)
if (Page* page = document()->page()) {
if (InspectorController* inspectorController = page->inspectorController()) {
- if (!m_synchronizingStyleAttribute)
+ if (!isSynchronizingStyleAttribute())
inspectorController->didModifyDOMAttr(this);
}
}
@@ -718,11 +712,11 @@ void Element::setAttributeMap(PassRefPtr<NamedNodeMap> list, FragmentScriptingPe
bool Element::hasAttributes() const
{
- if (!m_isStyleAttributeValid)
+ if (!isStyleAttributeValid())
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid)
+ if (!areSVGAttributesValid())
updateAnimatedSVGAttribute(anyQName());
#endif
@@ -916,7 +910,7 @@ void Element::recalcStyle(StyleChange change)
attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
// attach recalulates the style for all children. No need to do it twice.
setNeedsStyleRecalc(NoStyleChange);
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
return;
}
@@ -982,7 +976,7 @@ void Element::recalcStyle(StyleChange change)
}
setNeedsStyleRecalc(NoStyleChange);
- setChildNeedsStyleRecalc(false);
+ clearChildNeedsStyleRecalc();
}
bool Element::childTypeAllowed(NodeType type)
@@ -1091,7 +1085,7 @@ void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* af
void Element::finishParsingChildren()
{
ContainerNode::finishParsingChildren();
- m_parsingChildrenFinished = true;
+ setIsParsingChildrenFinished();
checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
}
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index eefaeb1..3d02f1b 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -29,6 +29,7 @@
#include "Document.h"
#include "HTMLNames.h"
#include "MappedAttributeEntry.h"
+#include "NamedNodeMap.h"
#include "QualifiedName.h"
#include "ScrollTypes.h"
@@ -236,9 +237,9 @@ public:
// Use Document::registerForMediaVolumeCallbacks() to subscribe to this
virtual void mediaVolumeDidChange() { }
- bool isFinishedParsingChildren() const { return m_parsingChildrenFinished; }
+ bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
virtual void finishParsingChildren();
- virtual void beginParsingChildren() { m_parsingChildrenFinished = false; }
+ virtual void beginParsingChildren() { clearIsParsingChildrenFinished(); }
// ElementTraversal API
Element* firstElementChild() const;
@@ -252,6 +253,7 @@ public:
virtual bool isFormControlElement() const { return false; }
virtual bool isEnabledFormControl() const { return true; }
virtual bool isReadOnlyFormControl() const { return false; }
+ virtual bool isSpinButtonElement() const { return false; }
virtual bool isTextFormControl() const { return false; }
virtual bool isOptionalFormControl() const { return false; }
virtual bool isRequiredFormControl() const { return false; }
@@ -272,7 +274,11 @@ public:
virtual void dispatchFormControlChangeEvent() { }
protected:
- Element(const QualifiedName&, Document*, ConstructionType);
+ Element(const QualifiedName& tagName, Document* document, ConstructionType type)
+ : ContainerNode(document, type)
+ , m_tagName(tagName)
+ {
+ }
virtual void insertedIntoDocument();
virtual void removedFromDocument();
@@ -356,11 +362,11 @@ inline const QualifiedName& Element::idAttributeName() const
inline NamedNodeMap* Element::attributes(bool readonly) const
{
- if (!m_isStyleAttributeValid)
+ if (!isStyleAttributeValid())
updateStyleAttribute();
#if ENABLE(SVG)
- if (!m_areSVGAttributesValid)
+ if (!areSVGAttributesValid())
updateAnimatedSVGAttribute(anyQName());
#endif
diff --git a/WebCore/dom/Element.idl b/WebCore/dom/Element.idl
index 1368503..977d15a 100644
--- a/WebCore/dom/Element.idl
+++ b/WebCore/dom/Element.idl
@@ -195,10 +195,10 @@ module core {
attribute [DontEnum] EventListener onreset;
attribute [DontEnum] EventListener onsearch;
attribute [DontEnum] EventListener onselectstart;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchstart;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchmove;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchend;
- attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchcancel;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchstart;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchmove;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchend;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchcancel;
#endif
};
diff --git a/WebCore/dom/EntityReference.cpp b/WebCore/dom/EntityReference.cpp
index c4c292a..72944ec 100644
--- a/WebCore/dom/EntityReference.cpp
+++ b/WebCore/dom/EntityReference.cpp
@@ -21,6 +21,8 @@
#include "config.h"
#include "EntityReference.h"
+#include "Document.h"
+
namespace WebCore {
inline EntityReference::EntityReference(Document* document, const String& entityName)
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index c50cfb2..ca2ae96 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -159,6 +159,8 @@ namespace WebCore {
\
macro(success) \
\
+ macro(loadend) \
+ \
// end of DOM_EVENT_NAMES_FOR_EACH
class EventNames : public Noncopyable {
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index 1598790..91a5d0c 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -156,6 +156,13 @@ Notification* EventTarget::toNotification()
}
#endif
+#if ENABLE(FILE_READER)
+FileReader* EventTarget::toFileReader()
+{
+ return 0;
+}
+#endif
+
bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
{
EventTargetData* d = ensureEventTargetData();
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index da98d98..96d2d29 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -48,6 +48,7 @@ namespace WebCore {
class Event;
class EventListener;
class EventSource;
+ class FileReader;
class MessagePort;
class Node;
class Notification;
@@ -118,6 +119,9 @@ namespace WebCore {
#if ENABLE(NOTIFICATIONS)
virtual Notification* toNotification();
#endif
+#if ENABLE(FILE_READER)
+ virtual FileReader* toFileReader();
+#endif
virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
diff --git a/WebCore/dom/ExceptionCode.h b/WebCore/dom/ExceptionCode.h
index 573fb36..a5618f8 100644
--- a/WebCore/dom/ExceptionCode.h
+++ b/WebCore/dom/ExceptionCode.h
@@ -58,6 +58,13 @@ namespace WebCore {
ABORT_ERR = 20,
URL_MISMATCH_ERR = 21,
QUOTA_EXCEEDED_ERR = 22,
+
+ // Introduced in File API:
+ // http://www.w3.org/TR/file-upload/#dfn-fileerror
+#if ENABLE(FILE_READER) || ENABLE(FILE_WRITER)
+ NOT_READABLE_ERR = 24,
+ ENCODING_ERR = 26,
+#endif
};
enum ExceptionType {
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index 52812f9..3459906 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -22,6 +22,15 @@
#include "InputElement.h"
#include "BeforeTextInsertedEvent.h"
+
+#if ENABLE(WCSS)
+#include "CSSPropertyNames.h"
+#include "CSSRule.h"
+#include "CSSRuleList.h"
+#include "CSSStyleRule.h"
+#include "CSSStyleSelector.h"
+#endif
+
#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
@@ -138,6 +147,14 @@ void InputElement::setValueFromRenderer(InputElementData& data, InputElement* in
String InputElement::sanitizeValue(const InputElement* inputElement, const String& proposedValue)
{
+#if ENABLE(WCSS)
+ InputElementData data = const_cast<InputElement*>(inputElement)->data();
+ if (!isConformToInputMask(data, proposedValue)) {
+ if (isConformToInputMask(data, data.value()))
+ return data.value();
+ return String();
+ }
+#endif
return InputElement::sanitizeUserInputValue(inputElement, proposedValue, s_maximumLength);
}
@@ -172,8 +189,12 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputEl
// RenderTextControlSingleLine::subtreeHasChanged() in some cases.
unsigned oldLength = numGraphemeClusters(toRenderTextControlSingleLine(element->renderer())->text());
- // selection() may be a pre-edit text.
- unsigned selectionLength = numGraphemeClusters(plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get()));
+ // selectionLength represents the selection length of this text field to be
+ // removed by this insertion.
+ // If the text field has no focus, we don't need to take account of the
+ // selection length. The selection is the source of text drag-and-drop in
+ // that case, and nothing in the text field will be removed.
+ unsigned selectionLength = element->focused() ? numGraphemeClusters(plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get())) : 0;
ASSERT(oldLength >= selectionLength);
// Selected characters will be removed by the next text event.
@@ -183,6 +204,18 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputEl
// Truncate the inserted text to avoid violating the maxLength and other constraints.
BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event);
+#if ENABLE(WCSS)
+ RefPtr<Range> range = element->document()->frame()->selection()->selection().toNormalizedRange();
+ String candidateString = toRenderTextControlSingleLine(element->renderer())->text();
+ if (selectionLength)
+ candidateString.replace(range->startOffset(), range->endOffset(), textEvent->text());
+ else
+ candidateString.insert(textEvent->text(), range->startOffset());
+ if (!isConformToInputMask(inputElement->data(), candidateString)) {
+ textEvent->setText("");
+ return;
+ }
+#endif
textEvent->setText(sanitizeUserInputValue(inputElement, textEvent->text(), appendableLength));
}
@@ -234,6 +267,10 @@ InputElementData::InputElementData()
, m_maxLength(InputElement::s_maximumLength)
, m_cachedSelectionStart(-1)
, m_cachedSelectionEnd(-1)
+#if ENABLE(WCSS)
+ , m_inputFormatMask("*m")
+ , m_maxInputCharsAllowed(InputElement::s_maximumLength)
+#endif
{
}
@@ -255,4 +292,137 @@ InputElement* toInputElement(Element* element)
return 0;
}
+#if ENABLE(WCSS)
+static inline const AtomicString& formatCodes()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, codes, ("AaNnXxMm"));
+ return codes;
+}
+
+static unsigned cursorPositionToMaskIndex(const String& inputFormatMask, unsigned cursorPosition)
+{
+ UChar mask;
+ int index = -1;
+ do {
+ mask = inputFormatMask[++index];
+ if (mask == '\\')
+ ++index;
+ else if (mask == '*' || (isASCIIDigit(mask) && mask != '0')) {
+ index = inputFormatMask.length() - 1;
+ break;
+ }
+ } while (cursorPosition--);
+
+ return index;
+}
+
+bool InputElement::isConformToInputMask(const InputElementData& data, const String& inputChars)
+{
+ for (unsigned i = 0; i < inputChars.length(); ++i)
+ if (!isConformToInputMask(data, inputChars[i], i))
+ return false;
+ return true;
+}
+
+bool InputElement::isConformToInputMask(const InputElementData& data, UChar inChar, unsigned cursorPosition)
+{
+ String inputFormatMask = data.inputFormatMask();
+
+ if (inputFormatMask.isEmpty() || inputFormatMask == "*M" || inputFormatMask == "*m")
+ return true;
+
+ if (cursorPosition >= data.maxInputCharsAllowed())
+ return false;
+
+ unsigned maskIndex = cursorPositionToMaskIndex(inputFormatMask, cursorPosition);
+ bool ok = true;
+ UChar mask = inputFormatMask[maskIndex];
+ // Match the inputed character with input mask
+ switch (mask) {
+ case 'A':
+ ok = !isASCIIDigit(inChar) && !isASCIILower(inChar) && isASCIIPrintable(inChar);
+ break;
+ case 'a':
+ ok = !isASCIIDigit(inChar) && !isASCIIUpper(inChar) && isASCIIPrintable(inChar);
+ break;
+ case 'N':
+ ok = isASCIIDigit(inChar);
+ break;
+ case 'n':
+ ok = !isASCIIAlpha(inChar) && isASCIIPrintable(inChar);
+ break;
+ case 'X':
+ ok = !isASCIILower(inChar) && isASCIIPrintable(inChar);
+ break;
+ case 'x':
+ ok = !isASCIIUpper(inChar) && isASCIIPrintable(inChar);
+ break;
+ case 'M':
+ case 'm':
+ ok = isASCIIPrintable(inChar);
+ break;
+ default:
+ ok = (mask == inChar);
+ break;
+ }
+
+ return ok;
+}
+
+String InputElement::validateInputMask(InputElementData& data, String& inputMask)
+{
+ inputMask.replace("\\\\", "\\");
+
+ bool isValid = true;
+ bool hasWildcard = false;
+ unsigned escapeCharCount = 0;
+ unsigned maskLength = inputMask.length();
+ UChar formatCode;
+ for (unsigned i = 0; i < maskLength; ++i) {
+ formatCode = inputMask[i];
+ if (formatCodes().find(formatCode) == -1) {
+ if (formatCode == '*' || (isASCIIDigit(formatCode) && formatCode != '0')) {
+ // Validate codes which ends with '*f' or 'nf'
+ formatCode = inputMask[++i];
+ if ((i + 1 != maskLength) || formatCodes().find(formatCode) == -1) {
+ isValid = false;
+ break;
+ }
+ hasWildcard = true;
+ } else if (formatCode == '\\') {
+ // skip over the next mask character
+ ++i;
+ ++escapeCharCount;
+ } else {
+ isValid = false;
+ break;
+ }
+ }
+ }
+
+ if (!isValid)
+ return String();
+ // calculate the number of characters allowed to be entered by input mask
+ unsigned allowedLength = maskLength;
+ if (escapeCharCount)
+ allowedLength -= escapeCharCount;
+
+ if (hasWildcard) {
+ formatCode = inputMask[maskLength - 2];
+ if (formatCode == '*')
+ allowedLength = data.maxInputCharsAllowed();
+ else {
+ unsigned leftLen = String(&formatCode).toInt();
+ allowedLength = leftLen + allowedLength - 2;
+ }
+ }
+
+ if (allowedLength < data.maxInputCharsAllowed())
+ data.setMaxInputCharsAllowed(allowedLength);
+
+ return inputMask;
+}
+
+#endif
+
}
diff --git a/WebCore/dom/InputElement.h b/WebCore/dom/InputElement.h
index a24b438..bdd5645 100644
--- a/WebCore/dom/InputElement.h
+++ b/WebCore/dom/InputElement.h
@@ -43,6 +43,7 @@ public:
virtual bool isPasswordField() const = 0;
virtual bool isSearchField() const = 0;
virtual bool isTextField() const = 0;
+ virtual bool hasSpinButton() const { return false; }
virtual bool searchEventsShouldBeDispatched() const = 0;
@@ -57,6 +58,10 @@ public:
virtual void cacheSelection(int start, int end) = 0;
virtual void select() = 0;
+
+#if ENABLE(WCSS)
+ virtual InputElementData data() const = 0;
+#endif
static const int s_maximumLength;
static const int s_defaultSize;
@@ -79,6 +84,11 @@ protected:
static void parseMaxLengthAttribute(InputElementData&, InputElement*, Element*, MappedAttribute*);
static void updateValueIfNeeded(InputElementData&, InputElement*);
static void notifyFormStateChanged(Element*);
+#if ENABLE(WCSS)
+ static bool isConformToInputMask(const InputElementData&, const String&);
+ static bool isConformToInputMask(const InputElementData&, UChar, unsigned);
+ static String validateInputMask(InputElementData&, String&);
+#endif
};
// HTML/WMLInputElement hold this struct as member variable
@@ -108,6 +118,15 @@ public:
int cachedSelectionEnd() const { return m_cachedSelectionEnd; }
void setCachedSelectionEnd(int value) { m_cachedSelectionEnd = value; }
+#if ENABLE(WCSS)
+ String inputFormatMask() const { return m_inputFormatMask; }
+ void setInputFormatMask(const String& mask) { m_inputFormatMask = mask; }
+
+ unsigned maxInputCharsAllowed() const { return m_maxInputCharsAllowed; }
+ void setMaxInputCharsAllowed(unsigned maxLength) { m_maxInputCharsAllowed = maxLength; }
+
+#endif
+
private:
AtomicString m_name;
String m_value;
@@ -116,6 +135,10 @@ private:
int m_maxLength;
int m_cachedSelectionStart;
int m_cachedSelectionEnd;
+#if ENABLE(WCSS)
+ String m_inputFormatMask;
+ unsigned m_maxInputCharsAllowed;
+#endif
};
InputElement* toInputElement(Element*);
diff --git a/WebCore/dom/MessagePort.idl b/WebCore/dom/MessagePort.idl
index 9312430..7bde45e 100644
--- a/WebCore/dom/MessagePort.idl
+++ b/WebCore/dom/MessagePort.idl
@@ -43,12 +43,12 @@ module events {
attribute EventListener onmessage;
// EventTarget interface
- [JSCCustom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [JSCCustom] void removeEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
+ void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
boolean dispatchEvent(in Event evt)
raises(EventException);
#endif
diff --git a/WebCore/dom/NameNodeList.cpp b/WebCore/dom/NameNodeList.cpp
index 4d96de0..2ffa577 100644
--- a/WebCore/dom/NameNodeList.cpp
+++ b/WebCore/dom/NameNodeList.cpp
@@ -31,12 +31,17 @@ namespace WebCore {
using namespace HTMLNames;
-NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const String& name, DynamicNodeList::Caches* caches)
- : DynamicNodeList(rootNode, caches)
+NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const String& name)
+ : DynamicNodeList(rootNode)
, m_nodeName(name)
{
}
+NameNodeList::~NameNodeList()
+{
+ m_rootNode->removeCachedNameNodeList(this, m_nodeName);
+}
+
bool NameNodeList::nodeMatches(Element* testNode) const
{
return testNode->getAttribute(nameAttr) == m_nodeName;
diff --git a/WebCore/dom/NameNodeList.h b/WebCore/dom/NameNodeList.h
index 2fdb43d..4f109b4 100644
--- a/WebCore/dom/NameNodeList.h
+++ b/WebCore/dom/NameNodeList.h
@@ -34,13 +34,15 @@ namespace WebCore {
// NodeList which lists all Nodes in a Element with a given "name" attribute
class NameNodeList : public DynamicNodeList {
public:
- static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, const String& name, Caches* caches)
+ static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, const String& name)
{
- return adoptRef(new NameNodeList(rootNode, name, caches));
+ return adoptRef(new NameNodeList(rootNode, name));
}
+ virtual ~NameNodeList();
+
private:
- NameNodeList(PassRefPtr<Node> rootNode, const String& name, Caches*);
+ NameNodeList(PassRefPtr<Node> rootNode, const String& name);
virtual bool nodeMatches(Element*) const;
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index a8ffc37..83aef21 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -103,8 +103,13 @@
#include "HTMLNoScriptElement.h"
#endif
+<<<<<<< HEAD:WebCore/dom/Node.cpp
#if ENABLE(TOUCH_EVENTS)
#include "ChromeClient.h"
+=======
+#if USE(JSC)
+#include <runtime/JSGlobalData.h>
+>>>>>>> webkit.org at r58956:WebCore/dom/Node.cpp
#endif
#define DUMP_NODE_STATISTICS 0
@@ -339,99 +344,8 @@ Node::StyleChange Node::diff(const RenderStyle* s1, const RenderStyle* s2)
return ch;
}
-inline bool Node::initialRefCount(ConstructionType type)
-{
- switch (type) {
- case CreateContainer:
- case CreateElement:
- case CreateOther:
- case CreateText:
- return 1;
- case CreateElementZeroRefCount:
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 1;
-}
-
-inline bool Node::isContainer(ConstructionType type)
+void Node::trackForDebugging()
{
- switch (type) {
- case CreateContainer:
- case CreateElement:
- case CreateElementZeroRefCount:
- return true;
- case CreateOther:
- case CreateText:
- return false;
- }
- ASSERT_NOT_REACHED();
- return false;
-}
-
-inline bool Node::isElement(ConstructionType type)
-{
- switch (type) {
- case CreateContainer:
- case CreateOther:
- case CreateText:
- return false;
- case CreateElement:
- case CreateElementZeroRefCount:
- return true;
- }
- ASSERT_NOT_REACHED();
- return false;
-}
-
-inline bool Node::isText(ConstructionType type)
-{
- switch (type) {
- case CreateContainer:
- case CreateElement:
- case CreateElementZeroRefCount:
- case CreateOther:
- return false;
- case CreateText:
- return true;
- }
- ASSERT_NOT_REACHED();
- return false;
-}
-
-Node::Node(Document* document, ConstructionType type)
- : TreeShared<Node>(initialRefCount(type))
- , m_document(document)
- , m_previous(0)
- , m_next(0)
- , m_renderer(0)
- , m_styleChange(NoStyleChange)
- , m_hasId(false)
- , m_hasClass(false)
- , m_attached(false)
- , m_childNeedsStyleRecalc(false)
- , m_inDocument(false)
- , m_isLink(false)
- , m_active(false)
- , m_hovered(false)
- , m_inActiveChain(false)
- , m_inDetach(false)
- , m_hasRareData(false)
- , m_isElement(isElement(type))
- , m_isContainer(isContainer(type))
- , m_isText(isText(type))
- , m_parsingChildrenFinished(true)
- , m_isStyleAttributeValid(true)
- , m_synchronizingStyleAttribute(false)
-#if ENABLE(SVG)
- , m_areSVGAttributesValid(true)
- , m_synchronizingSVGAttributes(false)
- , m_hasRareSVGData(false)
-#endif
-{
- if (m_document)
- m_document->selfOnlyRef();
-
#ifndef NDEBUG
if (shouldIgnoreLeaks)
ignoreSet.add(this);
@@ -555,7 +469,7 @@ NodeRareData* Node::ensureRareData()
ASSERT(!NodeRareData::rareDataMap().contains(this));
NodeRareData* data = createRareData();
NodeRareData::rareDataMap().set(this, data);
- m_hasRareData = true;
+ setFlag(HasRareDataFlag);
return data;
}
@@ -771,17 +685,43 @@ IntRect Node::getRect() const
return IntRect();
}
+bool Node::hasNonEmptyBoundingBox() const
+{
+ // Before calling absoluteRects, check for the common case where the renderer
+ // is non-empty, since this is a faster check and almost always returns true.
+ RenderBoxModelObject* box = renderBoxModelObject();
+ if (!box)
+ return false;
+ if (!box->borderBoundingBox().isEmpty())
+ return true;
+
+ Vector<IntRect> rects;
+ FloatPoint absPos = renderer()->localToAbsolute();
+ renderer()->absoluteRects(rects, absPos.x(), absPos.y());
+ size_t n = rects.size();
+ for (size_t i = 0; i < n; ++i)
+ if (!rects[i].isEmpty())
+ return true;
+
+ return false;
+}
+
+inline void Node::setStyleChange(StyleChangeType changeType)
+{
+ m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType;
+}
+
void Node::setNeedsStyleRecalc(StyleChangeType changeType)
{
if ((changeType != NoStyleChange) && !attached()) // changed compared to what?
return;
- if (!(changeType == InlineStyleChange && (m_styleChange == FullStyleChange || m_styleChange == SyntheticStyleChange)))
- m_styleChange = changeType;
+ if (!(changeType == InlineStyleChange && (styleChangeType() == FullStyleChange || styleChangeType() == SyntheticStyleChange)))
+ setStyleChange(changeType);
- if (m_styleChange != NoStyleChange) {
+ if (styleChangeType() != NoStyleChange) {
for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
- p->setChildNeedsStyleRecalc(true);
+ p->setChildNeedsStyleRecalc();
if (document()->childNeedsStyleRecalc())
document()->scheduleStyleRecalc();
}
@@ -805,9 +745,9 @@ void Node::lazyAttach()
}
if (n->firstChild())
- n->setChildNeedsStyleRecalc(true);
- n->m_styleChange = FullStyleChange;
- n->m_attached = true;
+ n->setChildNeedsStyleRecalc();
+ n->setStyleChange(FullStyleChange);
+ n->setAttached();
}
if (mustDoFullAttach) {
@@ -817,7 +757,7 @@ void Node::lazyAttach()
lazyAttachedAncestor->attach();
} else {
for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
- p->setChildNeedsStyleRecalc(true);
+ p->setChildNeedsStyleRecalc();
if (document()->childNeedsStyleRecalc())
document()->scheduleStyleRecalc();
}
@@ -965,6 +905,39 @@ void Node::notifyNodeListsChildrenChanged()
n->notifyLocalNodeListsChildrenChanged();
}
+void Node::removeCachedClassNodeList(ClassNodeList* list, const String& className)
+{
+ ASSERT(rareData());
+ ASSERT(rareData()->nodeLists());
+ ASSERT_UNUSED(list, list->hasOwnCaches());
+
+ NodeListsNodeData* data = rareData()->nodeLists();
+ ASSERT_UNUSED(list, list == data->m_classNodeListCache.get(className));
+ data->m_classNodeListCache.remove(className);
+}
+
+void Node::removeCachedNameNodeList(NameNodeList* list, const String& nodeName)
+{
+ ASSERT(rareData());
+ ASSERT(rareData()->nodeLists());
+ ASSERT_UNUSED(list, list->hasOwnCaches());
+
+ NodeListsNodeData* data = rareData()->nodeLists();
+ ASSERT_UNUSED(list, list == data->m_nameNodeListCache.get(nodeName));
+ data->m_nameNodeListCache.remove(nodeName);
+}
+
+void Node::removeCachedTagNodeList(TagNodeList* list, const QualifiedName& name)
+{
+ ASSERT(rareData());
+ ASSERT(rareData()->nodeLists());
+ ASSERT_UNUSED(list, list->hasOwnCaches());
+
+ NodeListsNodeData* data = rareData()->nodeLists();
+ ASSERT_UNUSED(list, list == data->m_tagNodeListCache.get(name));
+ data->m_tagNodeListCache.remove(name);
+}
+
Node *Node::traverseNextNode(const Node *stayWithin) const
{
if (firstChild())
@@ -1247,7 +1220,7 @@ void Node::attach()
}
}
- m_attached = true;
+ setAttached();
}
void Node::willRemove()
@@ -1256,23 +1229,24 @@ void Node::willRemove()
void Node::detach()
{
- m_inDetach = true;
+ setFlag(InDetachFlag);
if (renderer())
renderer()->destroy();
setRenderer(0);
Document* doc = document();
- if (m_hovered)
+ if (hovered())
doc->hoveredNodeDetached(this);
- if (m_inActiveChain)
+ if (inActiveChain())
doc->activeChainNodeDetached(this);
- m_active = false;
- m_hovered = false;
- m_inActiveChain = false;
- m_attached = false;
- m_inDetach = false;
+ clearFlag(IsActiveFlag);
+ clearFlag(IsHoveredFlag);
+ clearFlag(InActiveChainFlag);
+ clearFlag(IsAttachedFlag);
+
+ clearFlag(InDetachFlag);
}
Node *Node::previousEditable() const
@@ -1595,11 +1569,13 @@ PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceU
AtomicString localNameAtom = name;
- pair<NodeListsNodeData::TagCacheMap::iterator, bool> result = data->nodeLists()->m_tagNodeListCaches.add(QualifiedName(nullAtom, localNameAtom, namespaceURI), 0);
- if (result.second)
- result.first->second = DynamicNodeList::Caches::create();
+ pair<NodeListsNodeData::TagNodeListCache::iterator, bool> result = data->nodeLists()->m_tagNodeListCache.add(QualifiedName(nullAtom, localNameAtom, namespaceURI), 0);
+ if (!result.second)
+ return PassRefPtr<TagNodeList>(result.first->second);
- return TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom, result.first->second.get());
+ RefPtr<TagNodeList> list = TagNodeList::create(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localNameAtom);
+ result.first->second = list.get();
+ return list.release();
}
PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
@@ -1610,11 +1586,13 @@ PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
document()->addNodeListCache();
}
- pair<NodeListsNodeData::CacheMap::iterator, bool> result = data->nodeLists()->m_nameNodeListCaches.add(elementName, 0);
- if (result.second)
- result.first->second = DynamicNodeList::Caches::create();
-
- return NameNodeList::create(this, elementName, result.first->second.get());
+ pair<NodeListsNodeData::NameNodeListCache::iterator, bool> result = data->nodeLists()->m_nameNodeListCache.add(elementName, 0);
+ if (!result.second)
+ return PassRefPtr<NodeList>(result.first->second);
+
+ RefPtr<NameNodeList> list = NameNodeList::create(this, elementName);
+ result.first->second = list.get();
+ return list.release();
}
PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
@@ -1625,11 +1603,13 @@ PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
document()->addNodeListCache();
}
- pair<NodeListsNodeData::CacheMap::iterator, bool> result = data->nodeLists()->m_classNodeListCaches.add(classNames, 0);
- if (result.second)
- result.first->second = DynamicNodeList::Caches::create();
-
- return ClassNodeList::create(this, classNames, result.first->second.get());
+ pair<NodeListsNodeData::ClassNodeListCache::iterator, bool> result = data->nodeLists()->m_classNodeListCache.add(classNames, 0);
+ if (!result.second)
+ return PassRefPtr<NodeList>(result.first->second);
+
+ RefPtr<ClassNodeList> list = ClassNodeList::create(this, classNames);
+ result.first->second = list.get();
+ return list.release();
}
PassRefPtr<Element> Node::querySelector(const String& selectors, ExceptionCode& ec)
@@ -2271,21 +2251,21 @@ void Node::formatForDebugger(char* buffer, unsigned length) const
void NodeListsNodeData::invalidateCaches()
{
m_childNodeListCaches->reset();
- TagCacheMap::const_iterator tagCachesEnd = m_tagNodeListCaches.end();
- for (TagCacheMap::const_iterator it = m_tagNodeListCaches.begin(); it != tagCachesEnd; ++it)
- it->second->reset();
+ TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end();
+ for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it)
+ it->second->invalidateCache();
invalidateCachesThatDependOnAttributes();
}
void NodeListsNodeData::invalidateCachesThatDependOnAttributes()
{
- CacheMap::iterator classCachesEnd = m_classNodeListCaches.end();
- for (CacheMap::iterator it = m_classNodeListCaches.begin(); it != classCachesEnd; ++it)
- it->second->reset();
+ ClassNodeListCache::iterator classCacheEnd = m_classNodeListCache.end();
+ for (ClassNodeListCache::iterator it = m_classNodeListCache.begin(); it != classCacheEnd; ++it)
+ it->second->invalidateCache();
- CacheMap::iterator nameCachesEnd = m_nameNodeListCaches.end();
- for (CacheMap::iterator it = m_nameNodeListCaches.begin(); it != nameCachesEnd; ++it)
- it->second->reset();
+ NameNodeListCache::iterator nameCacheEnd = m_nameNodeListCache.end();
+ for (NameNodeListCache::iterator it = m_nameNodeListCache.begin(); it != nameCacheEnd; ++it)
+ it->second->invalidateCache();
}
bool NodeListsNodeData::isEmpty() const
@@ -2296,20 +2276,20 @@ bool NodeListsNodeData::isEmpty() const
if (m_childNodeListCaches->refCount())
return false;
- TagCacheMap::const_iterator tagCachesEnd = m_tagNodeListCaches.end();
- for (TagCacheMap::const_iterator it = m_tagNodeListCaches.begin(); it != tagCachesEnd; ++it) {
+ TagNodeListCache::const_iterator tagCacheEnd = m_tagNodeListCache.end();
+ for (TagNodeListCache::const_iterator it = m_tagNodeListCache.begin(); it != tagCacheEnd; ++it) {
if (it->second->refCount())
return false;
}
- CacheMap::const_iterator classCachesEnd = m_classNodeListCaches.end();
- for (CacheMap::const_iterator it = m_classNodeListCaches.begin(); it != classCachesEnd; ++it) {
+ ClassNodeListCache::const_iterator classCacheEnd = m_classNodeListCache.end();
+ for (ClassNodeListCache::const_iterator it = m_classNodeListCache.begin(); it != classCacheEnd; ++it) {
if (it->second->refCount())
return false;
}
- CacheMap::const_iterator nameCachesEnd = m_nameNodeListCaches.end();
- for (CacheMap::const_iterator it = m_nameNodeListCaches.begin(); it != nameCachesEnd; ++it) {
+ NameNodeListCache::const_iterator nameCacheEnd = m_nameNodeListCache.end();
+ for (NameNodeListCache::const_iterator it = m_nameNodeListCache.begin(); it != nameCacheEnd; ++it) {
if (it->second->refCount())
return false;
}
@@ -2384,12 +2364,12 @@ ScriptExecutionContext* Node::scriptExecutionContext() const
void Node::insertedIntoDocument()
{
- setInDocument(true);
+ setInDocument();
}
void Node::removedFromDocument()
{
- setInDocument(false);
+ clearInDocument();
}
void Node::willMoveToNewOwnerDocument()
@@ -2569,6 +2549,28 @@ EventTargetData* Node::ensureEventTargetData()
return ensureRareData()->ensureEventTargetData();
}
+#if USE(JSC)
+
+template <class NodeListMap>
+void markNodeLists(const NodeListMap& map, JSC::MarkStack& markStack, JSC::JSGlobalData& globalData)
+{
+ for (typename NodeListMap::const_iterator it = map.begin(); it != map.end(); ++it)
+ markDOMObjectWrapper(markStack, globalData, it->second);
+}
+
+void Node::markCachedNodeListsSlow(JSC::MarkStack& markStack, JSC::JSGlobalData& globalData)
+{
+ NodeListsNodeData* nodeLists = rareData()->nodeLists();
+ if (!nodeLists)
+ return;
+
+ markNodeLists(nodeLists->m_classNodeListCache, markStack, globalData);
+ markNodeLists(nodeLists->m_nameNodeListCache, markStack, globalData);
+ markNodeLists(nodeLists->m_tagNodeListCache, markStack, globalData);
+}
+
+#endif
+
void Node::handleLocalEvents(Event* event)
{
if (!hasRareData() || !rareData()->eventTargetData())
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index b2af8fc..b165615 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -32,10 +32,20 @@
#include "TreeShared.h"
#include <wtf/ListHashSet.h>
+#if USE(JSC)
+namespace JSC {
+
+ class JSGlobalData;
+ class MarkStack;
+
+}
+#endif
+
namespace WebCore {
class AtomicString;
class Attribute;
+class ClassNodeList;
class ContainerNode;
class Document;
class DynamicNodeList;
@@ -48,6 +58,7 @@ class IntRect;
class KeyboardEvent;
class NSResolver;
class NamedNodeMap;
+class NameNodeList;
class NodeList;
class NodeRareData;
class PlatformKeyboardEvent;
@@ -61,13 +72,21 @@ class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
class StringBuilder;
+class TagNodeList;
typedef int ExceptionCode;
+const int nodeStyleChangeShift = 24;
+
// SyntheticStyleChange means that we need to go through the entire style change logic even though
// no style property has actually changed. It is used to restructure the tree when, for instance,
// RenderLayers are created or destroyed due to animation changes.
-enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, SyntheticStyleChange };
+enum StyleChangeType {
+ NoStyleChange = 0,
+ InlineStyleChange = 1 << nodeStyleChangeShift,
+ FullStyleChange = 2 << nodeStyleChangeShift,
+ SyntheticStyleChange = 3 << nodeStyleChangeShift
+};
const unsigned short DOCUMENT_POSITION_EQUIVALENT = 0x00;
const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
@@ -162,17 +181,13 @@ public:
// Other methods (not part of DOM)
- bool isElementNode() const { return m_isElement; }
- bool isContainerNode() const { return m_isContainer; }
- bool isTextNode() const { return m_isText; }
+ bool isElementNode() const { return getFlag(IsElementFlag); }
+ bool isContainerNode() const { return getFlag(IsContainerFlag); }
+ bool isTextNode() const { return getFlag(IsTextFlag); }
- virtual bool isHTMLElement() const { return false; }
+ bool isHTMLElement() const { return getFlag(IsHTMLFlag); }
-#if ENABLE(SVG)
- virtual bool isSVGElement() const { return false; }
-#else
- static bool isSVGElement() { return false; }
-#endif
+ bool isSVGElement() const { return getFlag(IsSVGFlag); }
#if ENABLE(WML)
virtual bool isWMLElement() const { return false; }
@@ -188,10 +203,10 @@ public:
virtual bool isMediaControlElement() const { return false; }
- virtual bool isStyledElement() const { return false; }
+ bool isStyledElement() const { return getFlag(IsStyledElementFlag); }
virtual bool isFrameOwnerElement() const { return false; }
virtual bool isAttributeNode() const { return false; }
- virtual bool isCommentNode() const { return false; }
+ bool isCommentNode() const { return getFlag(IsCommentFlag); }
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
virtual bool isShadowNode() const { return false; }
@@ -268,33 +283,40 @@ public:
// For <link> and <style> elements.
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 hasID() const { return getFlag(HasIDFlag); }
+ bool hasClass() const { return getFlag(HasClassFlag); }
+ bool active() const { return getFlag(IsActiveFlag); }
+ bool inActiveChain() const { return getFlag(InActiveChainFlag); }
+ bool inDetach() const { return getFlag(InDetachFlag); }
+ bool hovered() const { return getFlag(IsHoveredFlag); }
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; }
+ bool attached() const { return getFlag(IsAttachedFlag); }
+ void setAttached() { setFlag(IsAttachedFlag); }
+ bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
+ StyleChangeType styleChangeType() const { return static_cast<StyleChangeType>(m_nodeFlags & StyleChangeMask); }
+ bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
+ bool isLink() const { return getFlag(IsLinkFlag); }
+
+ void setHasID(bool f) { setFlag(f, HasIDFlag); }
+ void setHasClass(bool f) { setFlag(f, HasClassFlag); }
+ void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
+ void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
+ void setInDocument() { setFlag(InDocumentFlag); }
+ void clearInDocument() { clearFlag(InDocumentFlag); }
+
+ void setInActiveChain() { setFlag(InActiveChainFlag); }
+ void clearInActiveChain() { clearFlag(InActiveChainFlag); }
void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
- void setIsLink(bool b = true) { m_isLink = b; }
+ void setIsLink(bool f) { setFlag(f, IsLinkFlag); }
+ void setIsLink() { setFlag(IsLinkFlag); }
+ void clearIsLink() { clearFlag(IsLinkFlag); }
void lazyAttach();
virtual bool canLazyAttach();
virtual void setFocus(bool b = true);
- virtual void setActive(bool b = true, bool /*pause*/ = false) { m_active = b; }
- virtual void setHovered(bool b = true) { m_hovered = b; }
+ virtual void setActive(bool f = true, bool /*pause*/ = false) { setFlag(f, IsActiveFlag); }
+ virtual void setHovered(bool f = true) { setFlag(f, IsHoveredFlag); }
virtual short tabIndex() const;
@@ -311,6 +333,11 @@ public:
virtual bool shouldUseInputMethod() const;
virtual IntRect getRect() const;
+ // Returns true if the node has a non-empty bounding box in layout.
+ // This does not 100% guarantee the user can see it, but is pretty close.
+ // Note: This method only works properly after layout has occurred.
+ bool hasNonEmptyBoundingBox() const;
+
virtual void recalcStyle(StyleChange = NoChange) { }
unsigned nodeIndex() const;
@@ -333,8 +360,8 @@ public:
// node tree, false otherwise.
bool inDocument() const
{
- ASSERT(m_document || !m_inDocument);
- return m_inDocument;
+ ASSERT(m_document || !getFlag(InDocumentFlag));
+ return getFlag(InDocumentFlag);
}
bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; }
@@ -497,6 +524,9 @@ public:
void notifyLocalNodeListsChildrenChanged();
void notifyNodeListsAttributeChanged();
void notifyLocalNodeListsAttributeChanged();
+ void removeCachedClassNodeList(ClassNodeList*, const String&);
+ void removeCachedNameNodeList(NameNodeList*, const String&);
+ void removeCachedTagNodeList(TagNodeList*, const QualifiedName&);
PassRefPtr<NodeList> getElementsByTagName(const String&);
PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const String& localName);
@@ -571,10 +601,82 @@ public:
virtual EventTargetData* eventTargetData();
virtual EventTargetData* ensureEventTargetData();
+#if USE(JSC)
+ void markCachedNodeLists(JSC::MarkStack& markStack, JSC::JSGlobalData& globalData)
+ {
+ // NodeLists may be present. If so, they need to be marked.
+ if (!hasRareData())
+ return;
+
+ markCachedNodeListsSlow(markStack, globalData);
+ }
+#endif
+
+private:
+ enum NodeFlags {
+ IsTextFlag = 1,
+ IsCommentFlag = 1 << 1,
+ IsContainerFlag = 1 << 2,
+ IsElementFlag = 1 << 3,
+ IsStyledElementFlag = 1 << 4,
+ IsHTMLFlag = 1 << 5,
+ IsSVGFlag = 1 << 6,
+ HasIDFlag = 1 << 7,
+ HasClassFlag = 1 << 8,
+ IsAttachedFlag = 1 << 9,
+ ChildNeedsStyleRecalcFlag = 1 << 10,
+ InDocumentFlag = 1 << 11,
+ IsLinkFlag = 1 << 12,
+ IsActiveFlag = 1 << 13,
+ IsHoveredFlag = 1 << 14,
+ InActiveChainFlag = 1 << 15,
+ InDetachFlag = 1 << 16,
+ HasRareDataFlag = 1 << 17,
+
+ // These bits are used by derived classes, pulled up here so they can
+ // be stored in the same memory word as the Node bits above.
+ IsParsingChildrenFinishedFlag = 1 << 18, // Element
+ IsStyleAttributeValidFlag = 1 << 19, // StyledElement
+ IsSynchronizingStyleAttributeFlag = 1 << 20, // StyledElement
+#if ENABLE(SVG)
+ AreSVGAttributesValidFlag = 1 << 21, // Element
+ IsSynchronizingSVGAttributesFlag = 1 << 22, // SVGElement
+ HasSVGRareDataFlag = 1 << 23, // SVGElement
+#endif
+ StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
+ CreateWithZeroRefCountFlag = 1 << 26,
+
+#if ENABLE(SVG)
+ DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag | AreSVGAttributesValidFlag
+#else
+ DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag
+#endif
+ };
+
+ // 5 bits remaining
+
+ bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
+ void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
+ void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; }
+ void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
+
protected:
// CreateElementZeroRefCount is deprecated and can be removed once we convert all element
// classes to start with a reference count of 1.
- enum ConstructionType { CreateContainer, CreateElement, CreateOther, CreateText, CreateElementZeroRefCount };
+ enum ConstructionType {
+ CreateOther = DefaultNodeFlags,
+ CreateText = DefaultNodeFlags | IsTextFlag,
+ CreateComment = DefaultNodeFlags | IsCommentFlag,
+ CreateContainer = DefaultNodeFlags | IsContainerFlag,
+ CreateElement = CreateContainer | IsElementFlag,
+ CreateElementZeroRefCount = IsElementFlag | CreateWithZeroRefCountFlag,
+ CreateStyledElement = CreateElement | IsStyledElementFlag,
+ CreateStyledElementZeroRefCount = CreateStyledElement | CreateWithZeroRefCountFlag,
+ CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
+ CreateHTMLElementZeroRefCount = CreateHTMLElement | CreateWithZeroRefCountFlag,
+ CreateSVGElement = CreateStyledElement | IsSVGFlag,
+ CreateSVGElementZeroRefCount = CreateSVGElement | CreateWithZeroRefCountFlag,
+ };
Node(Document*, ConstructionType);
virtual void willMoveToNewOwnerDocument();
@@ -583,19 +685,18 @@ protected:
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
+ bool hasRareData() const { return getFlag(HasRareDataFlag); }
NodeRareData* rareData() const;
NodeRareData* ensureRareData();
private:
+#if USE(JSC)
+ void markCachedNodeListsSlow(JSC::MarkStack&, JSC::JSGlobalData&);
+#endif
+
static bool initialRefCount(ConstructionType);
- static bool isContainer(ConstructionType);
- static bool isElement(ConstructionType);
- static bool isText(ConstructionType);
+ void setStyleChange(StyleChangeType);
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
@@ -617,45 +718,45 @@ private:
Element* ancestorElement() const;
void appendTextContent(bool convertBRsToNewlines, StringBuilder&) const;
+ void trackForDebugging();
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:
- // These bits are used by derived classes, pulled up here so they can
- // be stored in the same memory word as the Node bits above.
-
- bool m_parsingChildrenFinished : 1; // Element
- mutable bool m_isStyleAttributeValid : 1; // StyledElement
- mutable bool m_synchronizingStyleAttribute : 1; // StyledElement
+ mutable uint32_t m_nodeFlags;
+
+ protected:
+ bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
+ void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
+ void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
+ bool isStyleAttributeValid() const { return getFlag(IsStyleAttributeValidFlag); }
+ void setIsStyleAttributeValid(bool f) { setFlag(f, IsStyleAttributeValidFlag); }
+ void setIsStyleAttributeValid() const { setFlag(IsStyleAttributeValidFlag); }
+ void clearIsStyleAttributeValid() { clearFlag(IsStyleAttributeValidFlag); }
+ bool isSynchronizingStyleAttribute() const { return getFlag(IsSynchronizingStyleAttributeFlag); }
+ void setIsSynchronizingStyleAttribute(bool f) { setFlag(f, IsSynchronizingStyleAttributeFlag); }
+ void setIsSynchronizingStyleAttribute() const { setFlag(IsSynchronizingStyleAttributeFlag); }
+ void clearIsSynchronizingStyleAttribute() const { clearFlag(IsSynchronizingStyleAttributeFlag); }
#if ENABLE(SVG)
- mutable bool m_areSVGAttributesValid : 1; // Element
- mutable bool m_synchronizingSVGAttributes : 1; // SVGElement
- bool m_hasRareSVGData : 1; // SVGElement
+ bool areSVGAttributesValid() const { return getFlag(AreSVGAttributesValidFlag); }
+ void setAreSVGAttributesValid() const { setFlag(AreSVGAttributesValidFlag); }
+ void clearAreSVGAttributesValid() { clearFlag(AreSVGAttributesValidFlag); }
+ bool isSynchronizingSVGAttributes() const { return getFlag(IsSynchronizingSVGAttributesFlag); }
+ void setIsSynchronizingSVGAttributes() const { setFlag(IsSynchronizingSVGAttributesFlag); }
+ void clearIsSynchronizingSVGAttributes() const { clearFlag(IsSynchronizingSVGAttributesFlag); }
+ bool hasRareSVGData() const { return getFlag(HasSVGRareDataFlag); }
+ void setHasRareSVGData() { setFlag(HasSVGRareDataFlag); }
+ void clearHasRareSVGData() { clearFlag(HasSVGRareDataFlag); }
#endif
-
- // 10 bits remaining
};
+inline bool Node::initialRefCount(ConstructionType type)
+{
+ return !(type & CreateWithZeroRefCountFlag);
+}
+
// Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs()
inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
{
diff --git a/WebCore/dom/Node.idl b/WebCore/dom/Node.idl
index c0f159c..7bc6d1d 100644
--- a/WebCore/dom/Node.idl
+++ b/WebCore/dom/Node.idl
@@ -62,9 +62,7 @@ module core {
readonly attribute Node previousSibling;
readonly attribute Node nextSibling;
readonly attribute NamedNodeMap attributes;
-#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT
readonly attribute Document ownerDocument;
-#endif
[OldStyleObjC, Custom] Node insertBefore(in [Return] Node newChild,
in Node refChild)
@@ -136,12 +134,12 @@ module core {
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C
#if !defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT
- [JSCCustom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [JSCCustom] void removeEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
+ void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
boolean dispatchEvent(in Event event)
raises(EventException);
#endif
diff --git a/WebCore/dom/NodeFilter.idl b/WebCore/dom/NodeFilter.idl
index d721f80..16f3f26 100644
--- a/WebCore/dom/NodeFilter.idl
+++ b/WebCore/dom/NodeFilter.idl
@@ -43,7 +43,7 @@ module traversal {
const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x00000400;
const unsigned long SHOW_NOTATION = 0x00000800;
- [Custom] short acceptNode(in Node n);
+ [CallWith=ScriptState] short acceptNode(in Node n);
};
diff --git a/WebCore/dom/NodeIterator.idl b/WebCore/dom/NodeIterator.idl
index e1818a1..9f59ae1 100644
--- a/WebCore/dom/NodeIterator.idl
+++ b/WebCore/dom/NodeIterator.idl
@@ -31,9 +31,9 @@ module traversal {
readonly attribute Node referenceNode;
readonly attribute boolean pointerBeforeReferenceNode;
- [Custom] Node nextNode()
+ [CallWith=ScriptState] Node nextNode()
raises (DOMException);
- [Custom] Node previousNode()
+ [CallWith=ScriptState] Node previousNode()
raises (DOMException);
void detach();
};
diff --git a/WebCore/dom/NodeRareData.h b/WebCore/dom/NodeRareData.h
index 6e9d0e4..3d2cf0c 100644
--- a/WebCore/dom/NodeRareData.h
+++ b/WebCore/dom/NodeRareData.h
@@ -22,11 +22,14 @@
#ifndef NodeRareData_h
#define NodeRareData_h
+#include "ClassNodeList.h"
#include "DynamicNodeList.h"
#include "EventListener.h"
+#include "NameNodeList.h"
+#include "QualifiedName.h"
#include "RegisteredEventListener.h"
#include "StringHash.h"
-#include "QualifiedName.h"
+#include "TagNodeList.h"
#include <wtf/HashSet.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/OwnPtr.h>
@@ -39,12 +42,14 @@ struct NodeListsNodeData : Noncopyable {
RefPtr<DynamicNodeList::Caches> m_childNodeListCaches;
- typedef HashMap<String, RefPtr<DynamicNodeList::Caches> > CacheMap;
- CacheMap m_classNodeListCaches;
- CacheMap m_nameNodeListCaches;
+ typedef HashMap<String, ClassNodeList*> ClassNodeListCache;
+ ClassNodeListCache m_classNodeListCache;
+
+ typedef HashMap<String, NameNodeList*> NameNodeListCache;
+ NameNodeListCache m_nameNodeListCache;
- typedef HashMap<QualifiedName, RefPtr<DynamicNodeList::Caches> > TagCacheMap;
- TagCacheMap m_tagNodeListCaches;
+ typedef HashMap<QualifiedName, TagNodeList*> TagNodeListCache;
+ TagNodeListCache m_tagNodeListCache;
static PassOwnPtr<NodeListsNodeData> create()
{
diff --git a/WebCore/dom/Notation.cpp b/WebCore/dom/Notation.cpp
index cade384..4b3ab28 100644
--- a/WebCore/dom/Notation.cpp
+++ b/WebCore/dom/Notation.cpp
@@ -21,6 +21,8 @@
#include "config.h"
#include "Notation.h"
+#include "Document.h"
+
namespace WebCore {
Notation::Notation(Document* document, const String& name, const String& publicId, const String& systemId)
diff --git a/WebCore/dom/PopStateEvent.idl b/WebCore/dom/PopStateEvent.idl
index f9c9a71..28da9e6 100644
--- a/WebCore/dom/PopStateEvent.idl
+++ b/WebCore/dom/PopStateEvent.idl
@@ -27,11 +27,11 @@
module events {
interface PopStateEvent : Event {
- [Custom] void initPopStateEvent(in DOMString typeArg,
+ void initPopStateEvent(in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
- in any stateArg);
-
+ in SerializedScriptValue stateArg);
+
readonly attribute [V8CustomGetter] any state;
};
diff --git a/WebCore/dom/Position.cpp b/WebCore/dom/Position.cpp
index fa994e3..fdcd7e5 100644
--- a/WebCore/dom/Position.cpp
+++ b/WebCore/dom/Position.cpp
@@ -986,27 +986,46 @@ static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
return 0;
}
+static Position downstreamIgnoringEditingBoundaries(Position position)
+{
+ Position lastPosition;
+ while (position != lastPosition) {
+ lastPosition = position;
+ position = position.downstream(Position::CanCrossEditingBoundary);
+ }
+ return position;
+}
+
+static Position upstreamIgnoringEditingBoundaries(Position position)
+{
+ Position lastPosition;
+ while (position != lastPosition) {
+ lastPosition = position;
+ position = position.upstream(Position::CanCrossEditingBoundary);
+ }
+ return position;
+}
+
void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
{
caretOffset = m_offset;
RenderObject* renderer = node()->renderer();
-
+
if (!renderer->isText()) {
- if (!renderer->isRenderButton() && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
- bool lastPosition = caretOffset == lastOffsetInNode(node());
- Node* startNode = lastPosition ? node()->childNode(caretOffset - 1) : node()->childNode(caretOffset);
- while (startNode && (!startNode->renderer() || (startNode->isTextNode() && toRenderText(startNode->renderer())->isAllCollapsibleWhitespace())))
- startNode = (lastPosition)? startNode->previousSibling(): startNode->nextSibling();
- if (startNode) {
- Position pos(startNode, 0);
- pos = pos.downstream(CanCrossEditingBoundary);
- pos.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
- if (lastPosition && inlineBox)
- caretOffset = inlineBox->caretMaxOffset();
+ inlineBox = 0;
+ if (canHaveChildrenForEditing(node()) && renderer->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
+ // Try a visually equivalent position with possibly opposite editability. This helps in case |this| is in
+ // an editable block but surrounded by non-editable positions. It acts to negate the logic at the beginning
+ // of RenderObject::createVisiblePosition().
+ Position equivalent = downstreamIgnoringEditingBoundaries(*this);
+ if (equivalent == *this)
+ equivalent = upstreamIgnoringEditingBoundaries(*this);
+ if (equivalent == *this)
return;
- }
+
+ equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineBox, caretOffset);
+ return;
}
- inlineBox = 0;
if (renderer->isBox()) {
inlineBox = toRenderBox(renderer)->inlineBoxWrapper();
if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
diff --git a/WebCore/dom/QualifiedName.cpp b/WebCore/dom/QualifiedName.cpp
index 6f5a74f..7cc809f 100644
--- a/WebCore/dom/QualifiedName.cpp
+++ b/WebCore/dom/QualifiedName.cpp
@@ -78,6 +78,7 @@ void QualifiedName::deref()
if (!m_impl)
return;
#endif
+ ASSERT(!isHashTableDeletedValue());
if (m_impl->hasOneRef())
gNameCache->remove(m_impl);
diff --git a/WebCore/dom/QualifiedName.h b/WebCore/dom/QualifiedName.h
index 7581ba1..672a302 100644
--- a/WebCore/dom/QualifiedName.h
+++ b/WebCore/dom/QualifiedName.h
@@ -58,6 +58,8 @@ public:
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
QualifiedName(const AtomicString& prefix, const char* localName, const AtomicString& namespaceURI);
+ QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { }
+ bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
~QualifiedName() { deref(); }
#ifdef QNAME_DEFAULT_CONSTRUCTOR
QualifiedName() : m_impl(0) { }
@@ -92,6 +94,8 @@ private:
void init(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
void ref() const { m_impl->ref(); }
void deref();
+
+ static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); }
QualifiedNameImpl* m_impl;
};
@@ -167,8 +171,8 @@ namespace WTF {
template<> struct HashTraits<WebCore::QualifiedName> : GenericHashTraits<WebCore::QualifiedName> {
static const bool emptyValueIsZero = false;
static WebCore::QualifiedName emptyValue() { return WebCore::QualifiedName(WebCore::nullAtom, WebCore::nullAtom, WebCore::nullAtom); }
- static void constructDeletedValue(WebCore::QualifiedName& slot) { new (&slot) WebCore::QualifiedName(WebCore::nullAtom, WebCore::AtomicString(HashTableDeletedValue), WebCore::nullAtom); }
- static bool isDeletedValue(const WebCore::QualifiedName& slot) { return slot.localName().isHashTableDeletedValue(); }
+ static void constructDeletedValue(WebCore::QualifiedName& slot) { new (&slot) WebCore::QualifiedName(WTF::HashTableDeletedValue); }
+ static bool isDeletedValue(const WebCore::QualifiedName& slot) { return slot.isHashTableDeletedValue(); }
};
}
diff --git a/WebCore/dom/ScriptExecutionContext.h b/WebCore/dom/ScriptExecutionContext.h
index d0f2e26..18e2cd0 100644
--- a/WebCore/dom/ScriptExecutionContext.h
+++ b/WebCore/dom/ScriptExecutionContext.h
@@ -76,6 +76,7 @@ namespace WebCore {
void stopDatabases(DatabaseTaskSynchronizer*);
#endif
virtual bool isContextThread() const = 0;
+ virtual bool isJSExecutionTerminated() const = 0;
const KURL& url() const { return virtualURL(); }
KURL completeURL(const String& url) const { return virtualCompleteURL(url); }
diff --git a/WebCore/dom/SelectElement.cpp b/WebCore/dom/SelectElement.cpp
index 4af90c9..fb7d9a6 100644
--- a/WebCore/dom/SelectElement.cpp
+++ b/WebCore/dom/SelectElement.cpp
@@ -529,12 +529,8 @@ static int nextValidIndex(const Vector<Element*>& listItems, int listIndex, Skip
}
#endif
-void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm)
+void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element* element, Event* event)
{
-#if !ARROW_KEYS_POP_MENU
- UNUSED_PARAM(htmlForm);
-#endif
-
if (event->type() == eventNames().keydownEvent) {
if (!element->renderer() || !event->isKeyboardEvent())
return;
@@ -613,8 +609,6 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element
handled = true;
} else if (keyCode == '\r') {
menuListOnChange(data, element);
- if (htmlForm)
- htmlForm->submitClick(event);
handled = true;
}
#else
@@ -693,7 +687,7 @@ void SelectElement::updateSelectedState(SelectElementData& data, Element* elemen
updateListBoxSelection(data, element, !multiSelect);
}
-void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm)
+void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* element, Event* event)
{
const Vector<Element*>& listItems = data.listItems(element);
@@ -759,29 +753,18 @@ void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element*
listBoxOnChange(data, element);
event->setDefaultHandled();
}
- } else if (event->type() == eventNames().keypressEvent) {
- if (!event->isKeyboardEvent())
- return;
- int keyCode = static_cast<KeyboardEvent*>(event)->keyCode();
-
- if (keyCode == '\r') {
- if (htmlForm)
- htmlForm->submitClick(event);
- event->setDefaultHandled();
- return;
- }
}
}
-void SelectElement::defaultEventHandler(SelectElementData& data, Element* element, Event* event, HTMLFormElement* htmlForm)
+void SelectElement::defaultEventHandler(SelectElementData& data, Element* element, Event* event)
{
if (!element->renderer())
return;
if (data.usesMenuList())
- menuListDefaultEventHandler(data, element, event, htmlForm);
+ menuListDefaultEventHandler(data, element, event);
else
- listBoxDefaultEventHandler(data, element, event, htmlForm);
+ listBoxDefaultEventHandler(data, element, event);
if (event->defaultHandled())
return;
diff --git a/WebCore/dom/SelectElement.h b/WebCore/dom/SelectElement.h
index dcb6879..6db841e 100644
--- a/WebCore/dom/SelectElement.h
+++ b/WebCore/dom/SelectElement.h
@@ -92,7 +92,7 @@ protected:
static void parseMultipleAttribute(SelectElementData&, Element*, MappedAttribute*);
static bool appendFormData(SelectElementData&, Element*, FormDataList&);
static void reset(SelectElementData&, Element*);
- static void defaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement* = 0);
+ static void defaultEventHandler(SelectElementData&, Element*, Event*);
static int lastSelectedListIndex(const SelectElementData&, const Element*);
static void typeAheadFind(SelectElementData&, Element*, KeyboardEvent*);
static void insertedIntoTree(SelectElementData&, Element*);
@@ -103,8 +103,8 @@ protected:
bool multi, bool shift);
private:
- static void menuListDefaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement*);
- static void listBoxDefaultEventHandler(SelectElementData&, Element*, Event*, HTMLFormElement*);
+ static void menuListDefaultEventHandler(SelectElementData&, Element*, Event*);
+ static void listBoxDefaultEventHandler(SelectElementData&, Element*, Event*);
static void setOptionsChangedOnRenderer(SelectElementData&, Element*);
};
diff --git a/WebCore/dom/StyledElement.cpp b/WebCore/dom/StyledElement.cpp
index 3607963..cd5f863 100644
--- a/WebCore/dom/StyledElement.cpp
+++ b/WebCore/dom/StyledElement.cpp
@@ -103,17 +103,12 @@ void StyledElement::removeMappedAttributeDecl(MappedAttributeEntry entryType, co
void StyledElement::updateStyleAttribute() const
{
- ASSERT(!m_isStyleAttributeValid);
- m_isStyleAttributeValid = true;
- m_synchronizingStyleAttribute = true;
+ ASSERT(!isStyleAttributeValid());
+ setIsStyleAttributeValid();
+ setIsSynchronizingStyleAttribute();
if (m_inlineStyleDecl)
const_cast<StyledElement*>(this)->setAttribute(styleAttr, m_inlineStyleDecl->cssText());
- m_synchronizingStyleAttribute = false;
-}
-
-StyledElement::StyledElement(const QualifiedName& name, Document* document, ConstructionType type)
- : Element(name, document, type)
-{
+ clearIsSynchronizingStyleAttribute();
}
StyledElement::~StyledElement()
@@ -208,7 +203,7 @@ bool StyledElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEnt
{
result = eNone;
if (attrName == styleAttr)
- return !m_synchronizingStyleAttribute;
+ return !isSynchronizingStyleAttribute();
return true;
}
@@ -253,7 +248,7 @@ void StyledElement::parseMappedAttribute(MappedAttribute *attr)
destroyInlineStyleDecl();
else
getInlineStyleDecl()->parseDeclaration(attr->value());
- m_isStyleAttributeValid = true;
+ setIsStyleAttributeValid();
setNeedsStyleRecalc();
}
}
@@ -476,8 +471,8 @@ void StyledElement::copyNonAttributeProperties(const Element *sourceElement)
return;
*getInlineStyleDecl() = *source->m_inlineStyleDecl;
- m_isStyleAttributeValid = source->m_isStyleAttributeValid;
- m_synchronizingStyleAttribute = source->m_synchronizingStyleAttribute;
+ setIsStyleAttributeValid(source->isStyleAttributeValid());
+ setIsSynchronizingStyleAttribute(source->isSynchronizingStyleAttribute());
Element::copyNonAttributeProperties(sourceElement);
}
diff --git a/WebCore/dom/StyledElement.h b/WebCore/dom/StyledElement.h
index 52bffd3..279282c 100644
--- a/WebCore/dom/StyledElement.h
+++ b/WebCore/dom/StyledElement.h
@@ -25,6 +25,7 @@
#ifndef StyledElement_h
#define StyledElement_h
+#include "CSSMutableStyleDeclaration.h"
#include "CSSPrimitiveValue.h"
#include "Element.h"
#include "MappedAttributeEntry.h"
@@ -33,7 +34,6 @@
namespace WebCore {
class CSSMappedAttributeDeclaration;
-class CSSMutableStyleDeclaration;
class MappedAttribute;
class StyledElement : public Element {
@@ -73,7 +73,10 @@ public:
virtual PassRefPtr<Attribute> createAttribute(const QualifiedName&, const AtomicString& value);
protected:
- StyledElement(const QualifiedName&, Document*, ConstructionType);
+ StyledElement(const QualifiedName& name, Document* document, ConstructionType type)
+ : Element(name, document, type)
+ {
+ }
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
virtual void parseMappedAttribute(MappedAttribute*);
@@ -89,8 +92,6 @@ protected:
virtual void didMoveToNewOwnerDocument();
private:
- virtual bool isStyledElement() const { return true; }
-
void createMappedDecl(MappedAttribute*);
void createInlineStyleDecl();
@@ -104,7 +105,7 @@ private:
inline void StyledElement::invalidateStyleAttribute()
{
- m_isStyleAttributeValid = false;
+ clearIsStyleAttributeValid();
}
} //namespace
diff --git a/WebCore/dom/TagNodeList.cpp b/WebCore/dom/TagNodeList.cpp
index bec9b8e..4914e09 100644
--- a/WebCore/dom/TagNodeList.cpp
+++ b/WebCore/dom/TagNodeList.cpp
@@ -29,14 +29,19 @@
namespace WebCore {
-TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName, DynamicNodeList::Caches* caches)
- : DynamicNodeList(rootNode, caches)
+TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+ : DynamicNodeList(rootNode)
, m_namespaceURI(namespaceURI)
, m_localName(localName)
{
ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty());
}
+TagNodeList::~TagNodeList()
+{
+ m_rootNode->removeCachedTagNodeList(this, QualifiedName(nullAtom, m_localName, m_namespaceURI));
+}
+
bool TagNodeList::nodeMatches(Element* testNode) const
{
if (m_namespaceURI != starAtom && m_namespaceURI != testNode->namespaceURI())
diff --git a/WebCore/dom/TagNodeList.h b/WebCore/dom/TagNodeList.h
index 0031bad..1b1a038 100644
--- a/WebCore/dom/TagNodeList.h
+++ b/WebCore/dom/TagNodeList.h
@@ -32,13 +32,15 @@ namespace WebCore {
// NodeList that limits to a particular tag.
class TagNodeList : public DynamicNodeList {
public:
- static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName, DynamicNodeList::Caches* caches)
+ static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
{
- return adoptRef(new TagNodeList(rootNode, namespaceURI, localName, caches));
+ return adoptRef(new TagNodeList(rootNode, namespaceURI, localName));
}
+ virtual ~TagNodeList();
+
private:
- TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName, DynamicNodeList::Caches* caches);
+ TagNodeList(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName);
virtual bool nodeMatches(Element*) const;
diff --git a/WebCore/dom/Text.cpp b/WebCore/dom/Text.cpp
index cf98817..14da1a4 100644
--- a/WebCore/dom/Text.cpp
+++ b/WebCore/dom/Text.cpp
@@ -41,11 +41,6 @@ using namespace std;
namespace WebCore {
-Text::Text(Document* document, const String& data)
- : CharacterData(document, data, CreateText)
-{
-}
-
PassRefPtr<Text> Text::create(Document* document, const String& data)
{
return adoptRef(new Text(document, data));
diff --git a/WebCore/dom/Text.h b/WebCore/dom/Text.h
index 4722736..45678ef 100644
--- a/WebCore/dom/Text.h
+++ b/WebCore/dom/Text.h
@@ -44,7 +44,10 @@ public:
virtual void attach();
protected:
- Text(Document*, const String&);
+ Text(Document* document, const String& data)
+ : CharacterData(document, data, CreateText)
+ {
+ }
private:
virtual String nodeName() const;
diff --git a/WebCore/dom/Tokenizer.h b/WebCore/dom/Tokenizer.h
index 9a9b7b3..939ac70 100644
--- a/WebCore/dom/Tokenizer.h
+++ b/WebCore/dom/Tokenizer.h
@@ -25,6 +25,7 @@
namespace WebCore {
+ class HTMLTokenizer;
class SegmentedString;
class XSSAuditor;
@@ -57,6 +58,7 @@ namespace WebCore {
virtual void executeScriptsWaitingForStylesheets() {}
virtual bool isHTMLTokenizer() const { return false; }
+ virtual HTMLTokenizer* asHTMLTokenizer() { return 0; }
XSSAuditor* xssAuditor() const { return m_XSSAuditor; }
void setXSSAuditor(XSSAuditor* auditor) { m_XSSAuditor = auditor; }
diff --git a/WebCore/dom/TreeDepthLimit.h b/WebCore/dom/TreeDepthLimit.h
new file mode 100644
index 0000000..e78e093
--- /dev/null
+++ b/WebCore/dom/TreeDepthLimit.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TreeDepthLimit_h
+#define TreeDepthLimit_h
+
+#ifndef MAX_DOM_TREE_DEPTH
+#define MAX_DOM_TREE_DEPTH 5000
+#endif
+const unsigned maxDOMTreeDepth = MAX_DOM_TREE_DEPTH;
+
+#endif // TreeDepthLimit.h
+
diff --git a/WebCore/dom/TreeWalker.idl b/WebCore/dom/TreeWalker.idl
index f591128..890e315 100644
--- a/WebCore/dom/TreeWalker.idl
+++ b/WebCore/dom/TreeWalker.idl
@@ -31,13 +31,13 @@ module traversal {
attribute Node currentNode
setter raises(DOMException);
- [Custom] Node parentNode();
- [Custom] Node firstChild();
- [Custom] Node lastChild();
- [Custom] Node previousSibling();
- [Custom] Node nextSibling();
- [Custom] Node previousNode();
- [Custom] Node nextNode();
+ [CallWith=ScriptState] Node parentNode();
+ [CallWith=ScriptState] Node firstChild();
+ [CallWith=ScriptState] Node lastChild();
+ [CallWith=ScriptState] Node previousSibling();
+ [CallWith=ScriptState] Node nextSibling();
+ [CallWith=ScriptState] Node previousNode();
+ [CallWith=ScriptState] Node nextNode();
};
}
diff --git a/WebCore/dom/XMLTokenizer.cpp b/WebCore/dom/XMLTokenizer.cpp
index 818dacd..1d98dfe 100644
--- a/WebCore/dom/XMLTokenizer.cpp
+++ b/WebCore/dom/XMLTokenizer.cpp
@@ -50,6 +50,7 @@
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "TextResourceDecoder.h"
+#include "TreeDepthLimit.h"
#include <wtf/text/CString.h>
#include <wtf/StringExtras.h>
#include <wtf/Threading.h>
@@ -67,7 +68,6 @@ namespace WebCore {
using namespace HTMLNames;
const int maxErrors = 25;
-const size_t maxNestingDepth = 4096;
#if ENABLE(WML)
bool XMLTokenizer::isWMLDocument() const
@@ -87,7 +87,7 @@ void XMLTokenizer::pushCurrentNode(Node* n)
n->ref();
m_currentNodeStack.append(m_currentNode);
m_currentNode = n;
- if (m_currentNodeStack.size() > maxNestingDepth)
+ if (m_currentNodeStack.size() > maxDOMTreeDepth)
handleError(fatal, "Excessive node nesting.", lineNumber(), columnNumber());
}