summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-07-11 13:45:28 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-07-11 13:45:28 +0200
commitd6a599dbc9d824a462b2b206316e102bf8136446 (patch)
treeecb257a5e55b2239d74b90fdad62fccd661cf286 /Source/WebCore/dom
parent3ccc3a85f09a83557b391aae380d3bf5f81a2911 (diff)
downloadqtwebkit-d6a599dbc9d824a462b2b206316e102bf8136446.tar.gz
Imported WebKit commit 8ff1f22783a32de82fee915abd55bd1b298f2644 (http://svn.webkit.org/repository/webkit/trunk@122325)
New snapshot that should work with the latest Qt build system changes
Diffstat (limited to 'Source/WebCore/dom')
-rw-r--r--Source/WebCore/dom/CharacterData.cpp9
-rw-r--r--Source/WebCore/dom/CharacterData.h2
-rw-r--r--Source/WebCore/dom/ChildListMutationScope.h4
-rw-r--r--Source/WebCore/dom/ChildNodeList.cpp33
-rw-r--r--Source/WebCore/dom/ComposedShadowTreeWalker.cpp88
-rw-r--r--Source/WebCore/dom/ComposedShadowTreeWalker.h55
-rw-r--r--Source/WebCore/dom/ContextFeatures.cpp12
-rw-r--r--Source/WebCore/dom/ContextFeatures.h15
-rw-r--r--Source/WebCore/dom/DOMAllInOne.cpp2
-rw-r--r--Source/WebCore/dom/DataTransferItemList.idl2
-rw-r--r--Source/WebCore/dom/Document.cpp172
-rw-r--r--Source/WebCore/dom/Document.h62
-rw-r--r--Source/WebCore/dom/DynamicNodeList.cpp27
-rw-r--r--Source/WebCore/dom/DynamicNodeList.h112
-rw-r--r--Source/WebCore/dom/Element.cpp120
-rw-r--r--Source/WebCore/dom/Element.h15
-rw-r--r--Source/WebCore/dom/ElementAttributeData.cpp2
-rw-r--r--Source/WebCore/dom/ElementAttributeData.h10
-rw-r--r--Source/WebCore/dom/ElementRareData.h22
-rw-r--r--Source/WebCore/dom/Event.cpp5
-rw-r--r--Source/WebCore/dom/Event.h1
-rw-r--r--Source/WebCore/dom/EventNames.h1
-rw-r--r--Source/WebCore/dom/EventNames.in1
-rw-r--r--Source/WebCore/dom/EventTargetFactory.in1
-rw-r--r--Source/WebCore/dom/MemoryInstrumentation.h108
-rw-r--r--Source/WebCore/dom/MutationCallback.h4
-rw-r--r--Source/WebCore/dom/MutationCallback.idl2
-rw-r--r--Source/WebCore/dom/MutationObserver.cpp (renamed from Source/WebCore/dom/WebKitMutationObserver.cpp)52
-rw-r--r--Source/WebCore/dom/MutationObserver.h (renamed from Source/WebCore/dom/WebKitMutationObserver.h)14
-rw-r--r--Source/WebCore/dom/MutationObserver.idl (renamed from Source/WebCore/dom/WebKitMutationObserver.idl)2
-rw-r--r--Source/WebCore/dom/MutationObserverInterestGroup.cpp14
-rw-r--r--Source/WebCore/dom/MutationObserverInterestGroup.h20
-rw-r--r--Source/WebCore/dom/MutationObserverRegistration.cpp10
-rw-r--r--Source/WebCore/dom/MutationObserverRegistration.h18
-rw-r--r--Source/WebCore/dom/Node.cpp53
-rw-r--r--Source/WebCore/dom/Node.h15
-rw-r--r--Source/WebCore/dom/NodeList.idl5
-rw-r--r--Source/WebCore/dom/NodeRareData.h11
-rw-r--r--Source/WebCore/dom/NodeRenderingContext.cpp89
-rw-r--r--Source/WebCore/dom/NodeRenderingContext.h11
-rw-r--r--Source/WebCore/dom/ScriptElement.cpp5
-rw-r--r--Source/WebCore/dom/ShadowRoot.cpp9
-rw-r--r--Source/WebCore/dom/ShadowRoot.h16
-rw-r--r--Source/WebCore/dom/SpaceSplitString.h3
-rw-r--r--Source/WebCore/dom/Touch.cpp5
-rw-r--r--Source/WebCore/dom/Touch.h3
-rw-r--r--Source/WebCore/dom/TouchEvent.cpp5
-rw-r--r--Source/WebCore/dom/TouchEvent.h1
-rw-r--r--Source/WebCore/dom/ViewportArguments.cpp8
-rw-r--r--Source/WebCore/dom/ViewportArguments.h11
-rw-r--r--Source/WebCore/dom/WebKitNamedFlow.cpp20
-rw-r--r--Source/WebCore/dom/WebKitNamedFlow.h5
-rw-r--r--Source/WebCore/dom/WebKitNamedFlow.idl5
53 files changed, 835 insertions, 462 deletions
diff --git a/Source/WebCore/dom/CharacterData.cpp b/Source/WebCore/dom/CharacterData.cpp
index 76198fbe5..225a1399d 100644
--- a/Source/WebCore/dom/CharacterData.cpp
+++ b/Source/WebCore/dom/CharacterData.cpp
@@ -26,13 +26,13 @@
#include "EventNames.h"
#include "ExceptionCode.h"
#include "InspectorInstrumentation.h"
+#include "MemoryInstrumentation.h"
#include "MutationEvent.h"
#include "MutationObserverInterestGroup.h"
#include "MutationRecord.h"
#include "NodeRenderingContext.h"
#include "RenderText.h"
#include "TextBreakIterator.h"
-#include "WebKitMutationObserver.h"
using namespace std;
@@ -92,6 +92,13 @@ unsigned CharacterData::parserAppendData(const UChar* data, unsigned dataLength,
return end;
}
+void CharacterData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM);
+ Node::reportMemoryUsage(memoryObjectInfo);
+ memoryObjectInfo->reportString(m_data);
+}
+
void CharacterData::appendData(const String& data, ExceptionCode&)
{
String newStr = m_data;
diff --git a/Source/WebCore/dom/CharacterData.h b/Source/WebCore/dom/CharacterData.h
index 5eaedf3ce..5e413a95c 100644
--- a/Source/WebCore/dom/CharacterData.h
+++ b/Source/WebCore/dom/CharacterData.h
@@ -47,6 +47,8 @@ public:
// Returns how much could be added before length limit was met.
unsigned parserAppendData(const UChar*, unsigned dataLength, unsigned lengthLimit);
+ virtual void reportMemoryUsage(MemoryObjectInfo*) const;
+
protected:
CharacterData(Document* document, const String& text, ConstructionType type)
: Node(document, type)
diff --git a/Source/WebCore/dom/ChildListMutationScope.h b/Source/WebCore/dom/ChildListMutationScope.h
index 6dd523640..bce26751c 100644
--- a/Source/WebCore/dom/ChildListMutationScope.h
+++ b/Source/WebCore/dom/ChildListMutationScope.h
@@ -34,8 +34,8 @@
#if ENABLE(MUTATION_OBSERVERS)
#include "Document.h"
+#include "MutationObserver.h"
#include "Node.h"
-#include "WebKitMutationObserver.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
@@ -46,7 +46,7 @@ class ChildListMutationScope {
WTF_MAKE_NONCOPYABLE(ChildListMutationScope);
public:
ChildListMutationScope(Node* target)
- : m_target(target->document()->hasMutationObserversOfType(WebKitMutationObserver::ChildList) ? target : 0)
+ : m_target(target->document()->hasMutationObserversOfType(MutationObserver::ChildList) ? target : 0)
{
if (m_target)
MutationAccumulationRouter::instance()->incrementScopingLevel(m_target);
diff --git a/Source/WebCore/dom/ChildNodeList.cpp b/Source/WebCore/dom/ChildNodeList.cpp
index 449fb829a..4b50bc88e 100644
--- a/Source/WebCore/dom/ChildNodeList.cpp
+++ b/Source/WebCore/dom/ChildNodeList.cpp
@@ -39,15 +39,14 @@ ChildNodeList::~ChildNodeList()
unsigned ChildNodeList::length() const
{
- if (m_caches.isLengthCacheValid)
- return m_caches.cachedLength;
+ if (isLengthCacheValid())
+ return cachedLength();
unsigned len = 0;
for (Node* n = rootNode()->firstChild(); n; n = n->nextSibling())
len++;
- m_caches.cachedLength = len;
- m_caches.isLengthCacheValid = true;
+ setLengthCache(len);
return len;
}
@@ -57,27 +56,27 @@ Node* ChildNodeList::item(unsigned index) const
unsigned int pos = 0;
Node* n = rootNode()->firstChild();
- if (m_caches.isItemCacheValid) {
- if (index == m_caches.lastItemOffset)
- return m_caches.lastItem;
-
- int diff = index - m_caches.lastItemOffset;
+ if (isItemCacheValid()) {
+ if (index == cachedItemOffset())
+ return cachedItem();
+
+ int diff = index - cachedItemOffset();
unsigned dist = abs(diff);
if (dist < index) {
- n = m_caches.lastItem;
- pos = m_caches.lastItemOffset;
+ n = cachedItem();
+ pos = cachedItemOffset();
}
}
- if (m_caches.isLengthCacheValid) {
- if (index >= m_caches.cachedLength)
+ if (isLengthCacheValid()) {
+ if (index >= cachedLength())
return 0;
int diff = index - pos;
unsigned dist = abs(diff);
- if (dist > m_caches.cachedLength - 1 - index) {
+ if (dist > cachedLength() - 1 - index) {
n = rootNode()->lastChild();
- pos = m_caches.cachedLength - 1;
+ pos = cachedLength() - 1;
}
}
@@ -94,9 +93,7 @@ Node* ChildNodeList::item(unsigned index) const
}
if (n) {
- m_caches.lastItem = n;
- m_caches.lastItemOffset = pos;
- m_caches.isItemCacheValid = true;
+ setItemCache(n, pos);
return n;
}
diff --git a/Source/WebCore/dom/ComposedShadowTreeWalker.cpp b/Source/WebCore/dom/ComposedShadowTreeWalker.cpp
index a48345ab6..1d8feed18 100644
--- a/Source/WebCore/dom/ComposedShadowTreeWalker.cpp
+++ b/Source/WebCore/dom/ComposedShadowTreeWalker.cpp
@@ -43,19 +43,29 @@ static inline ElementShadow* shadowFor(const Node* node)
static inline ElementShadow* shadowOfParent(const Node* node)
{
- if (node && node->parentNode())
- return shadowFor(node->parentNode());
+ if (!node)
+ return 0;
+ if (Node* parent = node->parentNode())
+ if (parent->isElementNode())
+ return toElement(parent)->shadow();
return 0;
}
-ComposedShadowTreeWalker::ComposedShadowTreeWalker(const Node* node, Policy policy)
- : m_node(node)
- , m_policy(policy)
+inline void ComposedShadowTreeWalker::ParentTranversalDetails::didTraverseInsertionPoint(InsertionPoint* insertionPoint)
+{
+ if (!m_insertionPoint)
+ m_insertionPoint = insertionPoint;
+}
+
+inline void ComposedShadowTreeWalker::ParentTranversalDetails::didTraverseShadowRoot(const ShadowRoot* root)
{
-#ifndef NDEBUG
- if (m_node)
- assertPrecondition();
-#endif
+ m_resetStyleInheritance = m_resetStyleInheritance || root->resetStyleInheritance();
+}
+
+inline void ComposedShadowTreeWalker::ParentTranversalDetails::didFindNode(ContainerNode* node)
+{
+ if (!m_outOfComposition)
+ m_node = node;
}
ComposedShadowTreeWalker ComposedShadowTreeWalker::fromFirstChild(const Node* node, Policy policy)
@@ -65,6 +75,14 @@ ComposedShadowTreeWalker ComposedShadowTreeWalker::fromFirstChild(const Node* no
return walker;
}
+void ComposedShadowTreeWalker::findParent(const Node* node, ParentTranversalDetails* details)
+{
+ ComposedShadowTreeWalker walker(node, CrossUpperBoundary, CanStartFromShadowBoundary);
+ ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
+ if (found)
+ details->didFindNode(found);
+}
+
void ComposedShadowTreeWalker::firstChild()
{
assertPrecondition();
@@ -177,7 +195,7 @@ Node* ComposedShadowTreeWalker::traverseSiblingOrBackToYoungerShadowRoot(const N
return 0;
}
-Node* ComposedShadowTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
+inline Node* ComposedShadowTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
{
ASSERT(node);
if (node->parentNode() && isActiveInsertionPoint(node->parentNode()))
@@ -185,12 +203,14 @@ Node* ComposedShadowTreeWalker::escapeFallbackContentElement(const Node* node, T
return 0;
}
-Node* ComposedShadowTreeWalker::traverseNodeEscapingFallbackContents(const Node* node) const
+inline Node* ComposedShadowTreeWalker::traverseNodeEscapingFallbackContents(const Node* node, ParentTranversalDetails* details) const
{
ASSERT(node);
- if (isActiveInsertionPoint(node))
- return traverseParent(node);
- return const_cast<Node*>(node);
+ if (!isInsertionPoint(node))
+ return const_cast<Node*>(node);
+ const InsertionPoint* insertionPoint = toInsertionPoint(node);
+ return insertionPoint->hasDistribution() ? 0 :
+ insertionPoint->isActive() ? traverseParent(node, details) : const_cast<Node*>(node);
}
void ComposedShadowTreeWalker::parent()
@@ -200,36 +220,56 @@ void ComposedShadowTreeWalker::parent()
assertPostcondition();
}
-Node* ComposedShadowTreeWalker::traverseParent(const Node* node) const
+// FIXME: Use an iterative algorithm so that it can be inlined.
+// https://bugs.webkit.org/show_bug.cgi?id=90415
+Node* ComposedShadowTreeWalker::traverseParent(const Node* node, ParentTranversalDetails* details) const
{
if (!canCrossUpperBoundary() && node->isShadowRoot()) {
ASSERT(toShadowRoot(node)->isYoungest());
return 0;
}
if (ElementShadow* shadow = shadowOfParent(node)) {
- if (InsertionPoint* insertionPoint = shadow->insertionPointFor(node))
- return traverseParent(insertionPoint);
+ shadow->ensureDistribution();
+ if (InsertionPoint* insertionPoint = shadow->insertionPointFor(node)) {
+ if (details)
+ details->didTraverseInsertionPoint(insertionPoint);
+ return traverseParent(insertionPoint, details);
+ }
+
+ // The node is a non-distributed light child or older shadow's child.
+ if (details)
+ details->childWasOutOfComposition();
}
- return traverseParentInCurrentTree(node);
+ return traverseParentInCurrentTree(node, details);
}
-Node* ComposedShadowTreeWalker::traverseParentInCurrentTree(const Node* node) const
+inline Node* ComposedShadowTreeWalker::traverseParentInCurrentTree(const Node* node, ParentTranversalDetails* details) const
{
if (Node* parent = node->parentNode())
- return parent->isShadowRoot() ? traverseParentBackToYoungerShadowRootOrHost(toShadowRoot(parent)) : traverseNodeEscapingFallbackContents(parent);
+ return parent->isShadowRoot() ? traverseParentBackToYoungerShadowRootOrHost(toShadowRoot(parent), details) : traverseNodeEscapingFallbackContents(parent, details);
return 0;
}
-Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot) const
+Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTranversalDetails* details) const
{
ASSERT(shadowRoot);
if (shadowRoot->isYoungest()) {
- if (canCrossUpperBoundary())
+ if (canCrossUpperBoundary()) {
+ if (details)
+ details->didTraverseShadowRoot(shadowRoot);
return shadowRoot->host();
+ }
+
return const_cast<ShadowRoot*>(shadowRoot);
}
- InsertionPoint* assignedInsertionPoint = shadowRoot->assignedTo();
- return assignedInsertionPoint ? traverseParent(assignedInsertionPoint) : 0;
+
+ if (InsertionPoint* assignedInsertionPoint = shadowRoot->assignedTo()) {
+ if (details)
+ details->didTraverseShadowRoot(shadowRoot);
+ return traverseParent(assignedInsertionPoint, details);
+ }
+
+ return 0;
}
Node* ComposedShadowTreeWalker::traverseNextSibling(const Node* node)
diff --git a/Source/WebCore/dom/ComposedShadowTreeWalker.h b/Source/WebCore/dom/ComposedShadowTreeWalker.h
index bb9f41671..0af34cd42 100644
--- a/Source/WebCore/dom/ComposedShadowTreeWalker.h
+++ b/Source/WebCore/dom/ComposedShadowTreeWalker.h
@@ -44,11 +44,43 @@ public:
DoNotCrossUpperBoundary,
};
- ComposedShadowTreeWalker(const Node*, Policy = CrossUpperBoundary);
+ enum StartPolicy {
+ CanStartFromShadowBoundary,
+ CannotStartFromShadowBoundary
+ };
+
+ class ParentTranversalDetails {
+ public:
+ ParentTranversalDetails()
+ : m_node(0)
+ , m_insertionPoint(0)
+ , m_resetStyleInheritance(false)
+ , m_outOfComposition(false)
+ { }
+
+ ContainerNode* node() const { return m_node; }
+ InsertionPoint* insertionPoint() const { return m_insertionPoint; }
+ bool resetStyleInheritance() const { return m_resetStyleInheritance; }
+ bool outOfComposition() const { return m_outOfComposition; }
+
+ void didFindNode(ContainerNode*);
+ void didTraverseInsertionPoint(InsertionPoint*);
+ void didTraverseShadowRoot(const ShadowRoot*);
+ void childWasOutOfComposition() { m_outOfComposition = true; }
+
+ private:
+ ContainerNode* m_node;
+ InsertionPoint* m_insertionPoint;
+ bool m_resetStyleInheritance;
+ bool m_outOfComposition;
+ };
+
+ ComposedShadowTreeWalker(const Node*, Policy = CrossUpperBoundary, StartPolicy = CannotStartFromShadowBoundary);
// For a common use case such as:
// for (ComposedShadowTreeWalker walker = ComposedShadowTreeWalker::fromFirstChild(node); walker.get(); walker.nextSibling())
static ComposedShadowTreeWalker fromFirstChild(const Node*, Policy = CrossUpperBoundary);
+ static void findParent(const Node*, ParentTranversalDetails*);
Node* get() const { return const_cast<Node*>(m_node); }
@@ -64,6 +96,8 @@ public:
void previous();
private:
+ ComposedShadowTreeWalker(const Node*, ParentTranversalDetails*);
+
enum TraversalDirection {
TraversalDirectionForward,
TraversalDirectionBackward
@@ -97,7 +131,7 @@ private:
Node* traverseFirstChild(const Node*) const;
Node* traverseLastChild(const Node*) const;
Node* traverseChild(const Node*, TraversalDirection) const;
- Node* traverseParent(const Node*) const;
+ Node* traverseParent(const Node*, ParentTranversalDetails* = 0) const;
static Node* traverseNextSibling(const Node*);
static Node* traversePreviousSibling(const Node*);
@@ -108,14 +142,25 @@ private:
static Node* traverseSiblingOrBackToYoungerShadowRoot(const Node*, TraversalDirection);
static Node* escapeFallbackContentElement(const Node*, TraversalDirection);
- Node* traverseNodeEscapingFallbackContents(const Node*) const;
- Node* traverseParentInCurrentTree(const Node*) const;
- Node* traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot*) const;
+ Node* traverseNodeEscapingFallbackContents(const Node*, ParentTranversalDetails* = 0) const;
+ Node* traverseParentInCurrentTree(const Node*, ParentTranversalDetails* = 0) const;
+ Node* traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot*, ParentTranversalDetails* = 0) const;
const Node* m_node;
Policy m_policy;
};
+inline ComposedShadowTreeWalker::ComposedShadowTreeWalker(const Node* node, Policy policy, StartPolicy startPolicy)
+ : m_node(node)
+ , m_policy(policy)
+{
+ UNUSED_PARAM(startPolicy);
+#ifndef NDEBUG
+ if (m_node && startPolicy == CannotStartFromShadowBoundary)
+ assertPrecondition();
+#endif
+}
+
// A special walker class which is only used for traversing a parent node, including
// insertion points and shadow roots.
class ComposedShadowTreeParentWalker {
diff --git a/Source/WebCore/dom/ContextFeatures.cpp b/Source/WebCore/dom/ContextFeatures.cpp
index 887db4cb2..7e3daa671 100644
--- a/Source/WebCore/dom/ContextFeatures.cpp
+++ b/Source/WebCore/dom/ContextFeatures.cpp
@@ -51,6 +51,18 @@ ContextFeatures* ContextFeatures::defaultSwitch()
return instance.get();
}
+bool ContextFeatures::dialogElementEnabled(Document* document)
+{
+#if ENABLE(DIALOG_ELEMENT)
+ if (!document)
+ return RuntimeEnabledFeatures::dialogElementEnabled();
+ return document->contextFeatures()->isEnabled(document, DialogElement, RuntimeEnabledFeatures::dialogElementEnabled());
+#else
+ UNUSED_PARAM(document);
+ return false;
+#endif
+}
+
bool ContextFeatures::shadowDOMEnabled(Document* document)
{
#if ENABLE(SHADOW_DOM)
diff --git a/Source/WebCore/dom/ContextFeatures.h b/Source/WebCore/dom/ContextFeatures.h
index ef662207e..31dda92df 100644
--- a/Source/WebCore/dom/ContextFeatures.h
+++ b/Source/WebCore/dom/ContextFeatures.h
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
@@ -40,20 +39,24 @@ class Page;
class ContextFeatures : public RefCountedSupplement<Page, ContextFeatures> {
public:
enum FeatureType {
+ DialogElement = 0,
ShadowDOM,
StyleScoped,
- PagePopup
+ PagePopup,
+ FeatureTypeSize // Should be the last entry.
};
static const AtomicString& supplementName();
static ContextFeatures* defaultSwitch();
static PassRefPtr<ContextFeatures> create(ContextFeaturesClient*);
+ static bool dialogElementEnabled(Document*);
static bool shadowDOMEnabled(Document*);
static bool styleScopedEnabled(Document*);
static bool pagePopupEnabled(Document*);
bool isEnabled(Document*, FeatureType, bool) const;
+ void urlDidChange(Document*);
private:
explicit ContextFeatures(ContextFeaturesClient* client)
@@ -77,6 +80,7 @@ public:
virtual ~ContextFeaturesClient() { }
virtual bool isEnabled(Document*, ContextFeatures::FeatureType, bool defaultValue) { return defaultValue; }
+ virtual void urlDidChange(Document*) { }
};
void provideContextFeaturesTo(Page*, ContextFeaturesClient*);
@@ -94,6 +98,13 @@ inline bool ContextFeatures::isEnabled(Document* document, FeatureType type, boo
return m_client->isEnabled(document, type, defaultValue);
}
+inline void ContextFeatures::urlDidChange(Document* document)
+{
+ if (m_client)
+ return;
+ m_client->urlDidChange(document);
+}
+
} // namespace WebCore
#endif // ContextFeatures_h
diff --git a/Source/WebCore/dom/DOMAllInOne.cpp b/Source/WebCore/dom/DOMAllInOne.cpp
index d3d4902d4..592d72992 100644
--- a/Source/WebCore/dom/DOMAllInOne.cpp
+++ b/Source/WebCore/dom/DOMAllInOne.cpp
@@ -92,6 +92,7 @@
#include "MouseEvent.cpp"
#include "MouseRelatedEvent.cpp"
#include "MutationEvent.cpp"
+#include "MutationObserver.cpp"
#include "MutationObserverInterestGroup.cpp"
#include "MutationObserverRegistration.cpp"
#include "MutationRecord.cpp"
@@ -142,7 +143,6 @@
#include "UserTypingGestureIndicator.cpp"
#include "ViewportArguments.cpp"
#include "WebKitAnimationEvent.cpp"
-#include "WebKitMutationObserver.cpp"
#include "WebKitNamedFlow.cpp"
#include "WebKitTransitionEvent.cpp"
#include "WheelEvent.cpp"
diff --git a/Source/WebCore/dom/DataTransferItemList.idl b/Source/WebCore/dom/DataTransferItemList.idl
index d1de50e79..aee92e7aa 100644
--- a/Source/WebCore/dom/DataTransferItemList.idl
+++ b/Source/WebCore/dom/DataTransferItemList.idl
@@ -42,7 +42,7 @@ module core {
DataTransferItem item(in [Optional=DefaultIsUndefined] unsigned long index);
void clear();
- void add(in File file);
+ void add(in File? file);
void add(in [Optional=DefaultIsUndefined] DOMString data,
in [Optional=DefaultIsUndefined] DOMString type) raises(DOMException);
};
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 7f190b269..bc5eabbda 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -109,6 +109,7 @@
#include "Logging.h"
#include "MediaQueryList.h"
#include "MediaQueryMatcher.h"
+#include "MemoryInstrumentation.h"
#include "MouseEventWithHitTestResults.h"
#include "NameNodeList.h"
#include "NestingLevelIncrementer.h"
@@ -216,6 +217,10 @@
#include "Prerenderer.h"
#endif
+#if ENABLE(TEXT_AUTOSIZING)
+#include "TextAutosizer.h"
+#endif
+
using namespace std;
using namespace WTF;
using namespace Unicode;
@@ -342,19 +347,6 @@ static bool acceptsEditingFocus(Node* node)
return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
}
-static bool disableRangeMutation(Page* page)
-{
- // This check is made on super-hot code paths, so we only want this on Leopard.
-#ifdef TARGETING_LEOPARD
- // Disable Range mutation on document modifications in Leopard Mail.
- // See <rdar://problem/5865171>
- return page && page->settings()->needsLeopardMailQuirks();
-#else
- UNUSED_PARAM(page);
- return false;
-#endif
-}
-
static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
{
// targetFrame can be 0 when we're trying to navigate a top-level frame
@@ -470,6 +462,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_isViewSource(false)
, m_sawElementsInKnownNamespaces(false)
, m_isSrcdocDocument(false)
+ , m_documentRareData(0)
, m_eventQueue(DocumentEventQueue::create(this))
, m_weakReference(DocumentWeakReference::create(this))
, m_idAttributeName(idAttr)
@@ -528,6 +521,9 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
#if ENABLE(LINK_PRERENDER)
m_prerenderer = Prerenderer::create(this);
#endif
+#if ENABLE(TEXT_AUTOSIZING)
+ m_textAutosizer = TextAutosizer::create(this);
+#endif
m_visuallyOrdered = false;
m_bParsing = false;
m_wellFormed = false;
@@ -569,6 +565,9 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
static int docID = 0;
m_docID = docID++;
+ for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_collections); i++)
+ m_collections[i] = 0;
+
InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter);
}
@@ -606,7 +605,6 @@ Document::~Document()
// if the DocumentParser outlives the Document it won't cause badness.
ASSERT(!m_parser || m_parser->refCount() == 1);
detachParser();
- m_document = 0;
m_renderArena.clear();
@@ -650,6 +648,8 @@ Document::~Document()
if (hasRareData())
clearRareData();
+ m_document = 0;
+
InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
}
@@ -2009,6 +2009,11 @@ void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int&
marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width, view);
}
+void Document::setDocumentRareData(NodeRareData* rareData)
+{
+ m_documentRareData = rareData;
+}
+
void Document::setIsViewSource(bool isViewSource)
{
m_isViewSource = isViewSource;
@@ -2682,6 +2687,7 @@ void Document::setURL(const KURL& url)
m_url = newURL;
m_documentURI = m_url.string();
updateBaseURL();
+ contextFeatures()->urlDidChange(this);
}
void Document::updateBaseURL()
@@ -3902,7 +3908,7 @@ void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
{
- if (!disableRangeMutation(page()) && !m_ranges.isEmpty()) {
+ if (!m_ranges.isEmpty()) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenChanged(container);
@@ -3911,7 +3917,7 @@ void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
{
- if (!disableRangeMutation(page()) && !m_ranges.isEmpty()) {
+ if (!m_ranges.isEmpty()) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenWillBeRemoved(container);
@@ -3938,7 +3944,7 @@ void Document::nodeWillBeRemoved(Node* n)
for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
(*it)->nodeWillBeRemoved(n);
- if (!disableRangeMutation(page()) && !m_ranges.isEmpty()) {
+ if (!m_ranges.isEmpty()) {
HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
(*it)->nodeWillBeRemoved(n);
@@ -3953,7 +3959,7 @@ void Document::nodeWillBeRemoved(Node* n)
void Document::textInserted(Node* text, unsigned offset, unsigned length)
{
- if (!disableRangeMutation(page()) && !m_ranges.isEmpty()) {
+ if (!m_ranges.isEmpty()) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textInserted(text, offset, length);
@@ -3965,7 +3971,7 @@ void Document::textInserted(Node* text, unsigned offset, unsigned length)
void Document::textRemoved(Node* text, unsigned offset, unsigned length)
{
- if (!disableRangeMutation(page()) && !m_ranges.isEmpty()) {
+ if (!m_ranges.isEmpty()) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textRemoved(text, offset, length);
@@ -3978,7 +3984,7 @@ void Document::textRemoved(Node* text, unsigned offset, unsigned length)
void Document::textNodesMerged(Text* oldNode, unsigned offset)
{
- if (!disableRangeMutation(page()) && !m_ranges.isEmpty()) {
+ if (!m_ranges.isEmpty()) {
NodeWithIndex oldNodeWithIndex(oldNode);
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
@@ -3990,7 +3996,7 @@ void Document::textNodesMerged(Text* oldNode, unsigned offset)
void Document::textNodeSplit(Text* oldNode)
{
- if (!disableRangeMutation(page()) && !m_ranges.isEmpty()) {
+ if (!m_ranges.isEmpty()) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textNodeSplit(oldNode);
@@ -4577,7 +4583,7 @@ KURL Document::openSearchDescriptionURL()
if (!head())
return KURL();
- HTMLCollection* children = head()->children();
+ RefPtr<HTMLCollection> children = head()->children();
for (unsigned i = 0; Node* child = children->item(i); i++) {
if (!child->hasTagName(linkTag))
continue;
@@ -4695,81 +4701,113 @@ bool Document::hasSVGRootNode() const
}
#endif
-HTMLCollection* Document::cachedCollection(CollectionType type)
+// FIXME: This caching mechanism should be merged that of DynamicNodeList in NodeRareData.
+PassRefPtr<HTMLCollection> Document::cachedCollection(CollectionType type)
{
ASSERT(static_cast<unsigned>(type) < NumUnnamedDocumentCachedTypes);
- if (!m_collections[type])
- m_collections[type] = HTMLCollection::create(this, type);
- return m_collections[type].get();
+ if (m_collections[type])
+ return m_collections[type];
+
+ RefPtr<HTMLCollection> collection;
+ if (type == DocAll)
+ collection = HTMLAllCollection::create(this);
+ else
+ collection = HTMLCollection::create(this, type);
+ m_collections[type] = collection.get();
+
+ return collection.release();
+}
+
+void Document::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
+{
+ ASSERT_UNUSED(collection, m_collections[type] == collection);
+ m_collections[type] = 0;
}
-HTMLCollection* Document::images()
+PassRefPtr<HTMLCollection> Document::images()
{
return cachedCollection(DocImages);
}
-HTMLCollection* Document::applets()
+PassRefPtr<HTMLCollection> Document::applets()
{
return cachedCollection(DocApplets);
}
-HTMLCollection* Document::embeds()
+PassRefPtr<HTMLCollection> Document::embeds()
{
return cachedCollection(DocEmbeds);
}
-HTMLCollection* Document::plugins()
+PassRefPtr<HTMLCollection> Document::plugins()
{
// This is an alias for embeds() required for the JS DOM bindings.
return cachedCollection(DocEmbeds);
}
-HTMLCollection* Document::objects()
+PassRefPtr<HTMLCollection> Document::objects()
{
return cachedCollection(DocObjects);
}
-HTMLCollection* Document::scripts()
+PassRefPtr<HTMLCollection> Document::scripts()
{
return cachedCollection(DocScripts);
}
-HTMLCollection* Document::links()
+PassRefPtr<HTMLCollection> Document::links()
{
return cachedCollection(DocLinks);
}
-HTMLCollection* Document::forms()
+PassRefPtr<HTMLCollection> Document::forms()
{
return cachedCollection(DocForms);
}
-HTMLCollection* Document::anchors()
+PassRefPtr<HTMLCollection> Document::anchors()
{
return cachedCollection(DocAnchors);
}
-HTMLAllCollection* Document::all()
+PassRefPtr<HTMLCollection> Document::all()
{
- if (!m_allCollection)
- m_allCollection = HTMLAllCollection::create(this);
- return m_allCollection.get();
+ return cachedCollection(DocAll);
}
-HTMLCollection* Document::windowNamedItems(const AtomicString& name)
+PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
{
- OwnPtr<HTMLNameCollection>& collection = m_windowNamedItemCollections.add(name.impl(), nullptr).iterator->second;
- if (!collection)
- collection = HTMLNameCollection::create(this, WindowNamedItems, name);
- return collection.get();
+ NamedCollectionMap::AddResult result = m_windowNamedItemCollections.add(name, 0);
+ if (!result.isNewEntry)
+ return result.iterator->second;
+
+ RefPtr<HTMLNameCollection> collection = HTMLNameCollection::create(this, WindowNamedItems, name);
+ result.iterator->second = collection.get();
+ return collection.release();
}
-HTMLCollection* Document::documentNamedItems(const AtomicString& name)
+PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
{
- OwnPtr<HTMLNameCollection>& collection = m_documentNamedItemCollections.add(name.impl(), nullptr).iterator->second;
- if (!collection)
- collection = HTMLNameCollection::create(this, DocumentNamedItems, name);
- return collection.get();
+ NamedCollectionMap::AddResult result = m_documentNamedItemCollections.add(name, 0);
+ if (!result.isNewEntry)
+ return result.iterator->second;
+
+ RefPtr<HTMLNameCollection> collection = HTMLNameCollection::create(this, DocumentNamedItems, name);
+ result.iterator->second = collection.get();
+ return collection.release();
+}
+
+// FIXME: This caching mechanism should be merged that of DynamicNodeList in NodeRareData.
+void Document::removeWindowNamedItemCache(HTMLCollection* collection, const AtomicString& name)
+{
+ ASSERT_UNUSED(collection, m_windowNamedItemCollections.get(name) == collection);
+ m_windowNamedItemCollections.remove(name);
+}
+
+void Document::removeDocumentNamedItemCache(HTMLCollection* collection, const AtomicString& name)
+{
+ ASSERT_UNUSED(collection, m_documentNamedItemCollections.get(name) == collection);
+ m_documentNamedItemCollections.remove(name);
}
void Document::finishedParsing()
@@ -5993,6 +6031,42 @@ void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
m_contextFeatures = features;
}
+void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM);
+ ContainerNode::reportMemoryUsage(memoryObjectInfo);
+ memoryObjectInfo->reportVector(m_customFonts);
+ memoryObjectInfo->reportString(m_documentURI);
+ memoryObjectInfo->reportString(m_baseTarget);
+ if (m_pageGroupUserSheets)
+ memoryObjectInfo->reportVector(*m_pageGroupUserSheets.get());
+ if (m_userSheets)
+ memoryObjectInfo->reportVector(*m_userSheets.get());
+ memoryObjectInfo->reportHashSet(m_nodeIterators);
+ memoryObjectInfo->reportHashSet(m_ranges);
+ memoryObjectInfo->reportListHashSet(m_styleSheetCandidateNodes);
+ memoryObjectInfo->reportString(m_preferredStylesheetSet);
+ memoryObjectInfo->reportString(m_selectedStylesheetSet);
+ memoryObjectInfo->reportString(m_title.string());
+ memoryObjectInfo->reportString(m_rawTitle.string());
+ memoryObjectInfo->reportString(m_xmlEncoding);
+ memoryObjectInfo->reportString(m_xmlVersion);
+ memoryObjectInfo->reportString(m_contentLanguage);
+ memoryObjectInfo->reportHashMap(m_documentNamedItemCollections);
+ memoryObjectInfo->reportHashMap(m_windowNamedItemCollections);
+#if ENABLE(DASHBOARD_SUPPORT)
+ memoryObjectInfo->reportVector(m_dashboardRegions);
+#endif
+ memoryObjectInfo->reportHashMap(m_cssCanvasElements);
+ memoryObjectInfo->reportVector(m_iconURLs);
+ memoryObjectInfo->reportHashSet(m_documentSuspensionCallbackElements);
+ memoryObjectInfo->reportHashSet(m_mediaVolumeCallbackElements);
+ memoryObjectInfo->reportHashSet(m_privateBrowsingStateChangedElements);
+ memoryObjectInfo->reportHashMap(m_elementsByAccessKey);
+ memoryObjectInfo->reportHashSet(m_mediaCanStartListeners);
+ memoryObjectInfo->reportVector(m_pendingTasks);
+}
+
#if ENABLE(UNDO_MANAGER)
PassRefPtr<UndoManager> Document::undoManager()
{
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index 68885fb33..87dfa32c2 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -38,6 +38,7 @@
#include "InspectorCounters.h"
#include "IntRect.h"
#include "LayoutTypes.h"
+#include "MutationObserver.h"
#include "PageVisibilityState.h"
#include "PlatformScreen.h"
#include "QualifiedName.h"
@@ -47,7 +48,6 @@
#include "Timer.h"
#include "TreeScope.h"
#include "ViewportArguments.h"
-#include "WebKitMutationObserver.h"
#include <wtf/Deque.h>
#include <wtf/FixedArray.h>
#include <wtf/OwnPtr.h>
@@ -111,6 +111,7 @@ class MediaQueryMatcher;
class MouseEventWithHitTestResults;
class NodeFilter;
class NodeIterator;
+class NodeRareData;
class Page;
class PlatformMouseEvent;
class ProcessingInstruction;
@@ -172,6 +173,10 @@ class MicroDataItemList;
class Prerenderer;
#endif
+#if ENABLE(TEXT_AUTOSIZING)
+class TextAutosizer;
+#endif
+
typedef int ExceptionCode;
enum PageshowEventPersistence {
@@ -401,19 +406,22 @@ public:
PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionCode&);
- HTMLCollection* images();
- HTMLCollection* embeds();
- HTMLCollection* plugins(); // an alias for embeds() required for the JS DOM bindings.
- HTMLCollection* applets();
- HTMLCollection* links();
- HTMLCollection* forms();
- HTMLCollection* anchors();
- HTMLCollection* objects();
- HTMLCollection* scripts();
- HTMLCollection* windowNamedItems(const AtomicString& name);
- HTMLCollection* documentNamedItems(const AtomicString& name);
-
- HTMLAllCollection* all();
+ PassRefPtr<HTMLCollection> images();
+ PassRefPtr<HTMLCollection> embeds();
+ PassRefPtr<HTMLCollection> plugins(); // an alias for embeds() required for the JS DOM bindings.
+ PassRefPtr<HTMLCollection> applets();
+ PassRefPtr<HTMLCollection> links();
+ PassRefPtr<HTMLCollection> forms();
+ PassRefPtr<HTMLCollection> anchors();
+ PassRefPtr<HTMLCollection> objects();
+ PassRefPtr<HTMLCollection> scripts();
+ PassRefPtr<HTMLCollection> all();
+ void removeCachedHTMLCollection(HTMLCollection*, CollectionType);
+
+ PassRefPtr<HTMLCollection> windowNamedItems(const AtomicString& name);
+ PassRefPtr<HTMLCollection> documentNamedItems(const AtomicString& name);
+ void removeWindowNamedItemCache(HTMLCollection*, const AtomicString&);
+ void removeDocumentNamedItemCache(HTMLCollection*, const AtomicString&);
// Other methods (not part of DOM)
bool isHTMLDocument() const { return m_isHTML; }
@@ -432,6 +440,9 @@ public:
bool isSrcdocDocument() const { return m_isSrcdocDocument; }
+ NodeRareData* documentRareData() const { return m_documentRareData; };
+ void setDocumentRareData(NodeRareData*);
+
StyleResolver* styleResolverIfExists() const { return m_styleResolver.get(); }
bool isViewSource() const { return m_isViewSource; }
@@ -771,7 +782,7 @@ public:
void addListenerTypeIfNeeded(const AtomicString& eventType);
#if ENABLE(MUTATION_OBSERVERS)
- bool hasMutationObserversOfType(WebKitMutationObserver::MutationType type) const
+ bool hasMutationObserversOfType(MutationObserver::MutationType type) const
{
return m_mutationObserverTypes & type;
}
@@ -1125,12 +1136,18 @@ public:
Prerenderer* prerenderer() { return m_prerenderer.get(); }
#endif
+#if ENABLE(TEXT_AUTOSIZING)
+ TextAutosizer* textAutosizer() { return m_textAutosizer.get(); }
+#endif
+
void adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(Vector<FloatQuad>&, RenderObject*);
void adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(FloatRect&, RenderObject*);
void setContextFeatures(PassRefPtr<ContextFeatures>);
ContextFeatures* contextFeatures() { return m_contextFeatures.get(); }
+ virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
+
protected:
Document(Frame*, const KURL&, bool isXHTML, bool isHTML);
@@ -1202,7 +1219,7 @@ private:
PageVisibilityState visibilityState() const;
#endif
- HTMLCollection* cachedCollection(CollectionType);
+ PassRefPtr<HTMLCollection> cachedCollection(CollectionType);
#if ENABLE(FULLSCREEN_API)
void clearFullscreenElementStack();
@@ -1390,12 +1407,11 @@ private:
RefPtr<TextResourceDecoder> m_decoder;
InheritedBool m_designMode;
-
- OwnPtr<HTMLCollection> m_collections[NumUnnamedDocumentCachedTypes];
- OwnPtr<HTMLAllCollection> m_allCollection;
+
HashSet<DynamicSubtreeNodeList*> m_listsInvalidatedAtDocument;
- typedef HashMap<AtomicStringImpl*, OwnPtr<HTMLNameCollection> > NamedCollectionMap;
+ HTMLCollection* m_collections[NumUnnamedDocumentCachedTypes];
+ typedef HashMap<AtomicString, HTMLNameCollection*> NamedCollectionMap;
NamedCollectionMap m_documentNamedItemCollections;
NamedCollectionMap m_windowNamedItemCollections;
@@ -1435,6 +1451,8 @@ private:
bool m_sawElementsInKnownNamespaces;
bool m_isSrcdocDocument;
+ NodeRareData* m_documentRareData;
+
RefPtr<DocumentEventQueue> m_eventQueue;
RefPtr<DocumentWeakReference> m_weakReference;
@@ -1489,6 +1507,10 @@ private:
OwnPtr<Prerenderer> m_prerenderer;
#endif
+#if ENABLE(TEXT_AUTOSIZING)
+ OwnPtr<TextAutosizer> m_textAutosizer;
+#endif
+
bool m_scheduledTasksAreSuspended;
bool m_visualUpdatesAllowed;
diff --git a/Source/WebCore/dom/DynamicNodeList.cpp b/Source/WebCore/dom/DynamicNodeList.cpp
index d169a6cda..b97125c6b 100644
--- a/Source/WebCore/dom/DynamicNodeList.cpp
+++ b/Source/WebCore/dom/DynamicNodeList.cpp
@@ -34,8 +34,8 @@ DynamicSubtreeNodeList::~DynamicSubtreeNodeList()
unsigned DynamicSubtreeNodeList::length() const
{
- if (m_caches.isLengthCacheValid)
- return m_caches.cachedLength;
+ if (isLengthCacheValid())
+ return cachedLength();
unsigned length = 0;
Node* rootNode = this->rootNode();
@@ -43,8 +43,7 @@ unsigned DynamicSubtreeNodeList::length() const
for (Node* n = rootNode->firstChild(); n; n = n->traverseNextNode(rootNode))
length += n->isElementNode() && nodeMatches(static_cast<Element*>(n));
- m_caches.cachedLength = length;
- m_caches.isLengthCacheValid = true;
+ setLengthCache(length);
return length;
}
@@ -56,9 +55,7 @@ Node* DynamicSubtreeNodeList::itemForwardsFromCurrent(Node* start, unsigned offs
for (Node* n = start; n; n = n->traverseNextNode(rootNode)) {
if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) {
if (!remainingOffset) {
- m_caches.lastItem = n;
- m_caches.lastItemOffset = offset;
- m_caches.isItemCacheValid = true;
+ setItemCache(n, offset);
return n;
}
--remainingOffset;
@@ -75,9 +72,7 @@ Node* DynamicSubtreeNodeList::itemBackwardsFromCurrent(Node* start, unsigned off
for (Node* n = start; n; n = n->traversePreviousNode(rootNode)) {
if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) {
if (!remainingOffset) {
- m_caches.lastItem = n;
- m_caches.lastItemOffset = offset;
- m_caches.isItemCacheValid = true;
+ setItemCache(n, offset);
return n;
}
++remainingOffset;
@@ -91,12 +86,12 @@ Node* DynamicSubtreeNodeList::item(unsigned offset) const
{
int remainingOffset = offset;
Node* start = rootNode()->firstChild();
- if (m_caches.isItemCacheValid) {
- if (offset == m_caches.lastItemOffset)
- return m_caches.lastItem;
- if (offset > m_caches.lastItemOffset || m_caches.lastItemOffset - offset < offset) {
- start = m_caches.lastItem;
- remainingOffset -= m_caches.lastItemOffset;
+ if (isItemCacheValid()) {
+ if (offset == cachedItemOffset())
+ return cachedItem();
+ if (offset > cachedItemOffset() || cachedItemOffset() - offset < offset) {
+ start = cachedItem();
+ remainingOffset -= cachedItemOffset();
}
}
diff --git a/Source/WebCore/dom/DynamicNodeList.h b/Source/WebCore/dom/DynamicNodeList.h
index 8b33e0d0d..83b2ed3eb 100644
--- a/Source/WebCore/dom/DynamicNodeList.h
+++ b/Source/WebCore/dom/DynamicNodeList.h
@@ -34,7 +34,68 @@ namespace WebCore {
class Element;
class Node;
-class DynamicNodeList : public NodeList {
+class DynamicNodeListCacheBase {
+public:
+ enum RootType {
+ RootedAtNode,
+ RootedAtDocument,
+ };
+
+ enum InvalidationType {
+ AlwaysInvalidate,
+ DoNotInvalidateOnAttributeChange,
+ };
+
+ DynamicNodeListCacheBase(RootType rootType, InvalidationType invalidationType)
+ : m_rootedAtDocument(rootType == RootedAtDocument)
+ , m_shouldInvalidateOnAttributeChange(invalidationType == AlwaysInvalidate)
+ {
+ clearCache();
+ }
+
+public:
+ ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootedAtDocument; }
+ ALWAYS_INLINE bool shouldInvalidateOnAttributeChange() const { return m_shouldInvalidateOnAttributeChange; }
+
+protected:
+ ALWAYS_INLINE bool isItemCacheValid() const { return m_isItemCacheValid; }
+ ALWAYS_INLINE Node* cachedItem() const { return m_cachedItem; }
+ ALWAYS_INLINE unsigned cachedItemOffset() const { return m_cachedItemOffset; }
+
+ ALWAYS_INLINE bool isLengthCacheValid() const { return m_isLengthCacheValid; }
+ ALWAYS_INLINE unsigned cachedLength() const { return m_cachedLength; }
+ ALWAYS_INLINE void setLengthCache(unsigned length) const
+ {
+ m_cachedLength = length;
+ m_isLengthCacheValid = true;
+ }
+ ALWAYS_INLINE void setItemCache(Node* item, unsigned offset) const
+ {
+ m_cachedItem = item;
+ m_cachedItemOffset = offset;
+ m_isItemCacheValid = true;
+ }
+
+ void clearCache() const
+ {
+ m_cachedItem = 0;
+ m_isLengthCacheValid = false;
+ m_isItemCacheValid = false;
+ }
+
+private:
+ mutable Node* m_cachedItem;
+ mutable unsigned m_cachedLength;
+ mutable unsigned m_cachedItemOffset;
+ mutable unsigned m_isLengthCacheValid : 1;
+ mutable unsigned m_isItemCacheValid : 1;
+
+ // From DynamicNodeList
+ const unsigned m_rootedAtDocument : 1;
+ const unsigned m_shouldInvalidateOnAttributeChange : 1;
+};
+
+class DynamicNodeList : public NodeList, public DynamicNodeListCacheBase {
public:
enum NodeListType {
ChildNodeListType,
@@ -45,17 +106,9 @@ public:
LabelsNodeListType,
MicroDataItemListType,
};
- enum RootType {
- RootedAtNode,
- RootedAtDocument,
- };
- enum InvalidationType {
- AlwaysInvalidate,
- DoNotInvalidateOnAttributeChange,
- };
DynamicNodeList(PassRefPtr<Node> ownerNode, RootType rootType, InvalidationType invalidationType)
- : m_ownerNode(ownerNode)
- , m_caches(rootType, invalidationType)
+ : DynamicNodeListCacheBase(rootType, invalidationType)
+ , m_ownerNode(ownerNode)
{ }
virtual ~DynamicNodeList() { }
@@ -66,52 +119,21 @@ public:
// Other methods (not part of DOM)
Node* ownerNode() const { return m_ownerNode.get(); }
- bool isRootedAtDocument() const { return m_caches.rootedAtDocument; }
- bool shouldInvalidateOnAttributeChange() const { return m_caches.shouldInvalidateOnAttributeChange; }
- void invalidateCache() { m_caches.reset(); }
+ void invalidateCache() { clearCache(); }
protected:
Node* rootNode() const
{
- if (m_caches.rootedAtDocument && m_ownerNode->inDocument())
+ if (isRootedAtDocument() && m_ownerNode->inDocument())
return m_ownerNode->document();
return m_ownerNode.get();
}
Document* document() const { return m_ownerNode->document(); }
virtual bool nodeMatches(Element*) const = 0;
- struct Caches {
- Caches(RootType rootType, InvalidationType invalidationType)
- : rootedAtDocument(rootType == RootedAtDocument)
- , shouldInvalidateOnAttributeChange(invalidationType == AlwaysInvalidate)
- {
- reset();
- }
-
- void reset()
- {
- lastItem = 0;
- isLengthCacheValid = false;
- isItemCacheValid = false;
- }
-
- Node* lastItem;
- unsigned cachedLength;
- unsigned lastItemOffset;
- unsigned isLengthCacheValid : 1;
- unsigned isItemCacheValid : 1;
-
- // Following flags should belong in DynamicSubtreeNode but are here for bit-packing.
- unsigned type : 4;
- unsigned rootedAtDocument : 1;
- unsigned shouldInvalidateOnAttributeChange : 1;
- };
-
- RefPtr<Node> m_ownerNode;
- mutable Caches m_caches;
-
private:
virtual bool isDynamicNodeList() const OVERRIDE { return true; }
+ RefPtr<Node> m_ownerNode;
};
class DynamicSubtreeNodeList : public DynamicNodeList {
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp
index 9da156b4f..2287f40b1 100644
--- a/Source/WebCore/dom/Element.cpp
+++ b/Source/WebCore/dom/Element.cpp
@@ -46,9 +46,12 @@
#include "HTMLCollection.h"
#include "HTMLDocument.h"
#include "HTMLElement.h"
+#include "HTMLFormCollection.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
+#include "HTMLOptionsCollection.h"
#include "HTMLParserIdioms.h"
+#include "HTMLTableRowsCollection.h"
#include "InspectorInstrumentation.h"
#include "MutationObserverInterestGroup.h"
#include "MutationRecord.h"
@@ -68,7 +71,6 @@
#include "Text.h"
#include "TextIterator.h"
#include "VoidCallback.h"
-#include "WebKitMutationObserver.h"
#include "WebKitAnimationList.h"
#include "XMLNSNames.h"
#include "XMLNames.h"
@@ -137,7 +139,7 @@ Element::~Element()
if (ElementShadow* elementShadow = shadow()) {
elementShadow->removeAllShadowRoots();
- rareData()->m_shadow.clear();
+ elementRareData()->m_shadow.clear();
}
if (hasAttrList()) {
@@ -146,15 +148,15 @@ Element::~Element()
}
}
-inline ElementRareData* Element::rareData() const
+inline ElementRareData* Element::elementRareData() const
{
ASSERT(hasRareData());
return static_cast<ElementRareData*>(NodeRareData::rareDataFromMap(this));
}
-inline ElementRareData* Element::ensureRareData()
+inline ElementRareData* Element::ensureElementRareData()
{
- return static_cast<ElementRareData*>(Node::ensureRareData());
+ return static_cast<ElementRareData*>(ensureRareData());
}
OwnPtr<NodeRareData> Element::createRareData()
@@ -234,7 +236,7 @@ void Element::setBooleanAttribute(const QualifiedName& name, bool value)
NamedNodeMap* Element::attributes() const
{
ensureUpdatedAttributeData();
- ElementRareData* rareData = const_cast<Element*>(this)->ensureRareData();
+ ElementRareData* rareData = const_cast<Element*>(this)->ensureElementRareData();
if (NamedNodeMap* attributeMap = rareData->m_attributeMap.get())
return attributeMap;
@@ -607,10 +609,10 @@ static inline bool shouldIgnoreAttributeCase(const Element* e)
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
}
-const AtomicString& Element::getAttribute(const String& name) const
+const AtomicString& Element::getAttribute(const AtomicString& name) const
{
bool ignoreCase = shouldIgnoreAttributeCase(this);
-
+
// Update the 'style' attribute if it's invalid and being requested:
if (!isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
updateStyleAttribute();
@@ -677,7 +679,7 @@ inline void Element::setAttributeInternal(size_t index, const QualifiedName& nam
old->setValue(value);
if (inUpdateStyleAttribute == NotInUpdateStyleAttribute)
- didModifyAttribute(*old);
+ didModifyAttribute(Attribute(old->name(), old->value()));
}
void Element::attributeChanged(const Attribute& attribute)
@@ -948,7 +950,7 @@ void Element::attach()
}
if (hasRareData()) {
- ElementRareData* data = rareData();
+ ElementRareData* data = elementRareData();
if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
if (isFocusable() && document()->focusedNode() == this)
document()->updateFocusAppearanceSoon(false /* don't restore selection */);
@@ -974,7 +976,7 @@ void Element::detach()
unregisterNamedFlowContentNode();
cancelFocusAppearanceUpdate();
if (hasRareData())
- rareData()->resetComputedStyle();
+ elementRareData()->resetComputedStyle();
if (ElementShadow* shadow = this->shadow()) {
detachChildrenIfNeeded();
@@ -1048,7 +1050,7 @@ void Element::recalcStyle(StyleChange change)
if ((change > NoChange || needsStyleRecalc())) {
if (hasRareData()) {
- ElementRareData* data = rareData();
+ ElementRareData* data = elementRareData();
data->resetComputedStyle();
data->m_styleAffectedByEmpty = false;
}
@@ -1162,16 +1164,16 @@ ElementShadow* Element::shadow() const
if (!hasRareData())
return 0;
- return rareData()->m_shadow.get();
+ return elementRareData()->m_shadow.get();
}
ElementShadow* Element::ensureShadow()
{
- if (ElementShadow* shadow = ensureRareData()->m_shadow.get())
+ if (ElementShadow* shadow = ensureElementRareData()->m_shadow.get())
return shadow;
- rareData()->m_shadow = adoptPtr(new ElementShadow());
- return rareData()->m_shadow.get();
+ elementRareData()->m_shadow = adoptPtr(new ElementShadow());
+ return elementRareData()->m_shadow.get();
}
ShadowRoot* Element::ensureShadowRoot()
@@ -1179,12 +1181,12 @@ ShadowRoot* Element::ensureShadowRoot()
if (ElementShadow* shadow = this->shadow())
return shadow->oldestShadowRoot();
- return ShadowRoot::create(this, ShadowRoot::CreatingUserAgentShadowRoot).get();
+ return ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot).get();
}
const AtomicString& Element::shadowPseudoId() const
{
- return hasRareData() ? rareData()->m_shadowPseudoId : nullAtom;
+ return hasRareData() ? elementRareData()->m_shadowPseudoId : nullAtom;
}
void Element::setShadowPseudoId(const AtomicString& id, ExceptionCode& ec)
@@ -1197,7 +1199,7 @@ void Element::setShadowPseudoId(const AtomicString& id, ExceptionCode& ec)
return;
}
- ensureRareData()->m_shadowPseudoId = id;
+ ensureElementRareData()->m_shadowPseudoId = id;
}
bool Element::childTypeAllowed(NodeType type) const
@@ -1254,7 +1256,7 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
firstElementAfterInsertion->setNeedsStyleRecalc();
// We also have to handle node removal.
- if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())
+ if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle()->firstChildState()))
newFirstChild->setNeedsStyleRecalc();
}
@@ -1277,7 +1279,7 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
// We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
// to match now.
- if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !newLastChild->renderStyle()->lastChildState())
+ if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !newLastChild->renderStyle()->lastChildState()))
newLastChild->setNeedsStyleRecalc();
}
@@ -1554,7 +1556,7 @@ void Element::focus(bool restorePreviousSelection)
doc->updateLayoutIgnorePendingStylesheets();
if (!isFocusable()) {
- ensureRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
+ ensureElementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
return;
}
@@ -1624,14 +1626,14 @@ String Element::title() const
LayoutSize Element::minimumSizeForResizing() const
{
- return hasRareData() ? rareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
+ return hasRareData() ? elementRareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
}
void Element::setMinimumSizeForResizing(const LayoutSize& size)
{
if (size == defaultMinimumSizeForResizing() && !hasRareData())
return;
- ensureRareData()->m_minimumSizeForResizing = size;
+ ensureElementRareData()->m_minimumSizeForResizing = size;
}
RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
@@ -1652,7 +1654,7 @@ RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
// document tree and figure out when to destroy the computed style for such elements.
return 0;
- ElementRareData* data = ensureRareData();
+ ElementRareData* data = ensureElementRareData();
if (!data->m_computedStyle)
data->m_computedStyle = document()->styleForElementIgnoringPendingStylesheets(this);
return pseudoElementSpecifier ? data->m_computedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : data->m_computedStyle.get();
@@ -1660,13 +1662,13 @@ RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
void Element::setStyleAffectedByEmpty()
{
- ElementRareData* data = ensureRareData();
+ ElementRareData* data = ensureElementRareData();
data->m_styleAffectedByEmpty = true;
}
bool Element::styleAffectedByEmpty() const
{
- return hasRareData() && rareData()->m_styleAffectedByEmpty;
+ return hasRareData() && elementRareData()->m_styleAffectedByEmpty;
}
AtomicString Element::computeInheritedLanguage() const
@@ -1694,7 +1696,7 @@ AtomicString Element::computeInheritedLanguage() const
void Element::cancelFocusAppearanceUpdate()
{
if (hasRareData())
- rareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
+ elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
if (document()->focusedNode() == this)
document()->cancelFocusAppearanceUpdate();
}
@@ -1754,7 +1756,7 @@ bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
DOMTokenList* Element::classList()
{
- ElementRareData* data = ensureRareData();
+ ElementRareData* data = ensureElementRareData();
if (!data->m_classList)
data->m_classList = ClassList::create(this);
return data->m_classList.get();
@@ -1764,12 +1766,12 @@ DOMTokenList* Element::optionalClassList() const
{
if (!hasRareData())
return 0;
- return rareData()->m_classList.get();
+ return elementRareData()->m_classList.get();
}
DOMStringMap* Element::dataset()
{
- ElementRareData* data = ensureRareData();
+ ElementRareData* data = ensureElementRareData();
if (!data->m_datasetDOMStringMap)
data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this);
return data->m_datasetDOMStringMap.get();
@@ -1846,12 +1848,12 @@ void Element::webkitRequestFullScreen(unsigned short flags)
bool Element::containsFullScreenElement() const
{
- return hasRareData() ? rareData()->m_containsFullScreenElement : false;
+ return hasRareData() ? elementRareData()->m_containsFullScreenElement : false;
}
void Element::setContainsFullScreenElement(bool flag)
{
- ensureRareData()->m_containsFullScreenElement = flag;
+ ensureElementRareData()->m_containsFullScreenElement = flag;
setNeedsStyleRecalc(SyntheticStyleChange);
}
@@ -1972,7 +1974,7 @@ bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
#ifdef DUMP_NODE_STATISTICS
bool Element::hasNamedNodeMap() const
{
- return hasRareData() && rareData()->m_attributeMap;
+ return hasRareData() && elementRareData()->m_attributeMap;
}
#endif
@@ -2039,21 +2041,63 @@ void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const
static_cast<HTMLDocument*>(document())->addExtraNamedItem(newId);
}
-HTMLCollection* Element::ensureCachedHTMLCollection(CollectionType type)
+PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
+{
+ return ensureElementRareData()->ensureCachedHTMLCollection(this, type);
+}
+
+PassRefPtr<HTMLCollection> ElementRareData::ensureCachedHTMLCollection(Element* element, CollectionType type)
+{
+ if (!m_cachedCollections) {
+ m_cachedCollections = adoptPtr(new CachedHTMLCollectionArray);
+ for (unsigned i = 0; i < NumNodeCollectionTypes; i++)
+ (*m_cachedCollections)[i] = 0;
+ }
+
+ if (HTMLCollection* collection = (*m_cachedCollections)[type - FirstNodeCollectionType])
+ return collection;
+
+ RefPtr<HTMLCollection> collection;
+ if (type == TableRows) {
+ ASSERT(element->hasTagName(tableTag));
+ collection = HTMLTableRowsCollection::create(element);
+ } else if (type == SelectOptions) {
+ ASSERT(element->hasTagName(selectTag));
+ collection = HTMLOptionsCollection::create(element);
+ } else if (type == FormControls) {
+ ASSERT(element->hasTagName(formTag) || element->hasTagName(fieldsetTag));
+ collection = HTMLFormCollection::create(element);
+#if ENABLE(MICRODATA)
+ } else if (type == ItemProperties) {
+ collection = HTMLPropertiesCollection::create(element);
+#endif
+ } else
+ collection = HTMLCollection::create(element, type);
+ (*m_cachedCollections)[type - FirstNodeCollectionType] = collection.get();
+ return collection.release();
+}
+
+HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
{
- return ensureRareData()->ensureCachedHTMLCollection(this, type);
+ return hasRareData() ? elementRareData()->cachedHTMLCollection(type) : 0;
+}
+
+void Element::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
+{
+ ASSERT(hasRareData());
+ elementRareData()->removeCachedHTMLCollection(collection, type);
}
IntSize Element::savedLayerScrollOffset() const
{
- return hasRareData() ? rareData()->m_savedLayerScrollOffset : IntSize();
+ return hasRareData() ? elementRareData()->m_savedLayerScrollOffset : IntSize();
}
void Element::setSavedLayerScrollOffset(const IntSize& size)
{
if (size.isZero() && !hasRareData())
return;
- ensureRareData()->m_savedLayerScrollOffset = size;
+ ensureElementRareData()->m_savedLayerScrollOffset = size;
}
PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h
index 6c52a603c..1d576a81a 100644
--- a/Source/WebCore/dom/Element.h
+++ b/Source/WebCore/dom/Element.h
@@ -142,7 +142,7 @@ public:
bool hasAttribute(const String& name) const;
bool hasAttributeNS(const String& namespaceURI, const String& localName) const;
- const AtomicString& getAttribute(const String& name) const;
+ const AtomicString& getAttribute(const AtomicString& name) const;
const AtomicString& getAttributeNS(const String& namespaceURI, const String& localName) const;
void setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode&);
@@ -165,7 +165,7 @@ public:
Attribute* attributeItem(unsigned index) const;
Attribute* getAttributeItem(const QualifiedName&) const;
size_t getAttributeItemIndex(const QualifiedName& name) const { return attributeData()->getAttributeItemIndex(name); }
- size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const { return attributeData()->getAttributeItemIndex(name, shouldIgnoreAttributeCase); }
+ size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return attributeData()->getAttributeItemIndex(name, shouldIgnoreAttributeCase); }
void scrollIntoView(bool alignToTop = true);
void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
@@ -312,6 +312,8 @@ public:
void didModifyAttribute(const Attribute&);
void didRemoveAttribute(const QualifiedName&);
+ void removeCachedHTMLCollection(HTMLCollection*, CollectionType);
+
LayoutSize minimumSizeForResizing() const;
void setMinimumSizeForResizing(const LayoutSize&);
@@ -447,7 +449,8 @@ protected:
virtual bool shouldRegisterAsNamedItem() const { return false; }
virtual bool shouldRegisterAsExtraNamedItem() const { return false; }
- HTMLCollection* ensureCachedHTMLCollection(CollectionType);
+ PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
+ HTMLCollection* cachedHTMLCollection(CollectionType);
private:
void updateInvalidAttributes() const;
@@ -489,9 +492,6 @@ private:
QualifiedName m_tagName;
virtual OwnPtr<NodeRareData> createRareData();
- ElementRareData* rareData() const;
- ElementRareData* ensureRareData();
-
SpellcheckAttributeState spellcheckAttributeState() const;
void updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
@@ -500,6 +500,9 @@ private:
void unregisterNamedFlowContentNode();
private:
+ ElementRareData* elementRareData() const;
+ ElementRareData* ensureElementRareData();
+
mutable OwnPtr<ElementAttributeData> m_attributeData;
};
diff --git a/Source/WebCore/dom/ElementAttributeData.cpp b/Source/WebCore/dom/ElementAttributeData.cpp
index 0722cc838..ab2768e66 100644
--- a/Source/WebCore/dom/ElementAttributeData.cpp
+++ b/Source/WebCore/dom/ElementAttributeData.cpp
@@ -230,7 +230,7 @@ void ElementAttributeData::detachAttrObjectsFromElement(Element* element)
ASSERT(!element->hasAttrList());
}
-size_t ElementAttributeData::getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const
+size_t ElementAttributeData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
// Continue to checking case-insensitively and/or full namespaced names if necessary:
for (unsigned i = 0; i < m_attributes.size(); ++i) {
diff --git a/Source/WebCore/dom/ElementAttributeData.h b/Source/WebCore/dom/ElementAttributeData.h
index 90f1b91df..a13d4d258 100644
--- a/Source/WebCore/dom/ElementAttributeData.h
+++ b/Source/WebCore/dom/ElementAttributeData.h
@@ -82,7 +82,7 @@ public:
Attribute* attributeItem(unsigned index) const { return &const_cast<ElementAttributeData*>(this)->m_attributes[index]; }
Attribute* getAttributeItem(const QualifiedName& name) const { return findAttributeInVector(m_attributes, name); }
size_t getAttributeItemIndex(const QualifiedName&) const;
- size_t getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const;
+ size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
// These functions do no error checking.
void addAttribute(const Attribute&, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute);
@@ -122,8 +122,8 @@ private:
Vector<Attribute> clonedAttributeVector() const { return m_attributes; }
void detachAttrObjectsFromElement(Element*);
- Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
- size_t getAttributeItemIndexSlowCase(const String& name, bool shouldIgnoreAttributeCase) const;
+ Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
void cloneDataFrom(const ElementAttributeData& sourceData, const Element& sourceElement, Element& targetElement);
void clearAttributes(Element*);
void replaceAttribute(size_t index, const Attribute&, Element*);
@@ -145,7 +145,7 @@ inline void ElementAttributeData::removeAttribute(const QualifiedName& name, Ele
return;
}
-inline Attribute* ElementAttributeData::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
+inline Attribute* ElementAttributeData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
if (index != notFound)
@@ -164,7 +164,7 @@ inline size_t ElementAttributeData::getAttributeItemIndex(const QualifiedName& n
// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
-inline size_t ElementAttributeData::getAttributeItemIndex(const String& name, bool shouldIgnoreAttributeCase) const
+inline size_t ElementAttributeData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
unsigned len = length();
bool doSlowCheck = shouldIgnoreAttributeCase;
diff --git a/Source/WebCore/dom/ElementRareData.h b/Source/WebCore/dom/ElementRareData.h
index 8e7bcbcf4..3723d1a08 100644
--- a/Source/WebCore/dom/ElementRareData.h
+++ b/Source/WebCore/dom/ElementRareData.h
@@ -26,13 +26,14 @@
#include "DatasetDOMStringMap.h"
#include "Element.h"
#include "ElementShadow.h"
-#include "HTMLCollection.h"
#include "NamedNodeMap.h"
#include "NodeRareData.h"
#include <wtf/OwnPtr.h>
namespace WebCore {
+class HTMLCollection;
+
class ElementRareData : public NodeRareData {
public:
ElementRareData();
@@ -43,24 +44,27 @@ public:
using NodeRareData::needsFocusAppearanceUpdateSoonAfterAttach;
using NodeRareData::setNeedsFocusAppearanceUpdateSoonAfterAttach;
- typedef FixedArray<OwnPtr<HTMLCollection>, NumNodeCollectionTypes> CachedHTMLCollectionArray;
-
bool hasCachedHTMLCollections() const
{
return m_cachedCollections;
}
- HTMLCollection* ensureCachedHTMLCollection(Element* element, CollectionType type)
+ PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(Element*, CollectionType);
+ HTMLCollection* cachedHTMLCollection(CollectionType type)
{
if (!m_cachedCollections)
- m_cachedCollections = adoptPtr(new CachedHTMLCollectionArray);
+ return 0;
- OwnPtr<HTMLCollection>& collection = (*m_cachedCollections)[type - FirstNodeCollectionType];
- if (!collection)
- collection = HTMLCollection::create(element, type);
- return collection.get();
+ return (*m_cachedCollections)[type - FirstNodeCollectionType];
+ }
+ void removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
+ {
+ ASSERT(m_cachedCollections);
+ ASSERT_UNUSED(collection, (*m_cachedCollections)[type - FirstNodeCollectionType] == collection);
+ (*m_cachedCollections)[type - FirstNodeCollectionType] = 0;
}
+ typedef FixedArray<HTMLCollection*, NumNodeCollectionTypes> CachedHTMLCollectionArray;
OwnPtr<CachedHTMLCollectionArray> m_cachedCollections;
LayoutSize m_minimumSizeForResizing;
diff --git a/Source/WebCore/dom/Event.cpp b/Source/WebCore/dom/Event.cpp
index c9a45dc49..761313c59 100644
--- a/Source/WebCore/dom/Event.cpp
+++ b/Source/WebCore/dom/Event.cpp
@@ -126,6 +126,11 @@ bool Event::isKeyboardEvent() const
return false;
}
+bool Event::isTouchEvent() const
+{
+ return false;
+}
+
bool Event::isDragEvent() const
{
return false;
diff --git a/Source/WebCore/dom/Event.h b/Source/WebCore/dom/Event.h
index 36ed9a6d9..d298d90a7 100644
--- a/Source/WebCore/dom/Event.h
+++ b/Source/WebCore/dom/Event.h
@@ -120,6 +120,7 @@ namespace WebCore {
virtual bool isUIEvent() const;
virtual bool isMouseEvent() const;
virtual bool isKeyboardEvent() const;
+ virtual bool isTouchEvent() const;
// Drag events are a subset of mouse events.
virtual bool isDragEvent() const;
diff --git a/Source/WebCore/dom/EventNames.h b/Source/WebCore/dom/EventNames.h
index 598bcdde5..836e6308b 100644
--- a/Source/WebCore/dom/EventNames.h
+++ b/Source/WebCore/dom/EventNames.h
@@ -216,6 +216,7 @@ namespace WebCore {
macro(addstream) \
macro(removestream) \
macro(statechange) \
+ macro(removetrack) \
\
macro(show) \
\
diff --git a/Source/WebCore/dom/EventNames.in b/Source/WebCore/dom/EventNames.in
index f42b4b4fb..9c0ac5558 100644
--- a/Source/WebCore/dom/EventNames.in
+++ b/Source/WebCore/dom/EventNames.in
@@ -30,6 +30,7 @@ XMLHttpRequestProgressEvent
AudioProcessingEvent conditional=WEB_AUDIO
OfflineAudioCompletionEvent conditional=WEB_AUDIO
MediaStreamEvent conditional=MEDIA_STREAM
+MediaStreamTrackEvent conditional=MEDIA_STREAM
SpeechInputEvent conditional=INPUT_SPEECH
SpeechRecognitionError conditional=SCRIPTED_SPEECH
SpeechRecognitionEvent conditional=SCRIPTED_SPEECH
diff --git a/Source/WebCore/dom/EventTargetFactory.in b/Source/WebCore/dom/EventTargetFactory.in
index 3ec6db944..821717b0d 100644
--- a/Source/WebCore/dom/EventTargetFactory.in
+++ b/Source/WebCore/dom/EventTargetFactory.in
@@ -17,6 +17,7 @@ JavaScriptAudioNode conditional=WEB_AUDIO
LocalMediaStream conditional=MEDIA_STREAM
MediaController conditional=VIDEO
MediaStream conditional=MEDIA_STREAM
+MediaStreamTrackList conditional=MEDIA_STREAM
MessagePort
NetworkInfoConnection conditional=NETWORK_INFO
Node
diff --git a/Source/WebCore/dom/MemoryInstrumentation.h b/Source/WebCore/dom/MemoryInstrumentation.h
index 6f0e7a470..7a0d41c50 100644
--- a/Source/WebCore/dom/MemoryInstrumentation.h
+++ b/Source/WebCore/dom/MemoryInstrumentation.h
@@ -31,7 +31,9 @@
#ifndef MemoryInstrumentation_h
#define MemoryInstrumentation_h
+#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -46,6 +48,7 @@ public:
Other,
DOM,
CSS,
+ Binding,
LastTypeEntry
};
@@ -58,11 +61,42 @@ public:
return;
countObjectSize(objectType, sizeof(T));
}
+ template <typename HashMapType> void reportHashMap(const HashMapType&, ObjectType, bool contentOnly = false);
+ template <typename HashSetType> void reportHashSet(const HashSetType&, ObjectType, bool contentOnly = false);
+ template <typename ListHashSetType> void reportListHashSet(const ListHashSetType&, ObjectType, bool contentOnly = false);
+ template <typename VectorType> void reportVector(const VectorType&, ObjectType, bool contentOnly = false);
+
+protected:
+ class InstrumentedPointerBase {
+ public:
+ virtual ~InstrumentedPointerBase() { }
+
+ virtual void process(MemoryInstrumentation*) = 0;
+ };
+
+ template <typename Container>
+ size_t calculateContainerSize(const Container& container, bool contentOnly = false)
+ {
+ return (contentOnly ? 0 : sizeof(container)) + container.capacity() * sizeof(typename Container::ValueType);
+ }
private:
friend class MemoryObjectInfo;
+ template <typename T>
+ class InstrumentedPointer : public InstrumentedPointerBase {
+ public:
+ explicit InstrumentedPointer(const T* pointer) : m_pointer(pointer) { }
+
+ virtual void process(MemoryInstrumentation*) OVERRIDE;
+
+ private:
+ const T* m_pointer;
+ };
+
+ virtual void reportString(ObjectType, const String&) = 0;
virtual void countObjectSize(ObjectType, size_t) = 0;
+ virtual void deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase>) = 0;
virtual bool visited(const void*) = 0;
};
@@ -104,9 +138,40 @@ public:
m_objectSize = sizeof(T);
}
+ template <typename HashMapType>
+ void reportHashMap(const HashMapType& map)
+ {
+ m_memoryInstrumentation->reportHashMap(map, objectType(), true);
+ }
+
+ template <typename HashSetType>
+ void reportHashSet(const HashSetType& set)
+ {
+ m_memoryInstrumentation->reportHashSet(set, objectType(), true);
+ }
+
+ template <typename ListHashSetType>
+ void reportListHashSet(const ListHashSetType& set)
+ {
+ m_memoryInstrumentation->reportListHashSet(set, objectType(), true);
+ }
+
+ template <typename VectorType>
+ void reportVector(const VectorType& vector)
+ {
+ m_memoryInstrumentation->reportVector(vector, objectType(), true);
+ }
+
+ void reportString(const String& string)
+ {
+ m_memoryInstrumentation->reportString(objectType(), string);
+ }
+
MemoryInstrumentation::ObjectType objectType() const { return m_objectType; }
size_t objectSize() const { return m_objectSize; }
+ MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; }
+
private:
MemoryInstrumentation* m_memoryInstrumentation;
MemoryInstrumentation::ObjectType m_objectType;
@@ -118,9 +183,7 @@ void MemoryInstrumentation::reportInstrumentedPointer(const T* const object)
{
if (!object || visited(object))
return;
- MemoryObjectInfo memoryObjectInfo(this);
- object->reportMemoryUsage(&memoryObjectInfo);
- countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
+ deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object)));
}
template<typename T>
@@ -132,6 +195,45 @@ void MemoryInstrumentation::reportInstrumentedObject(const T& object)
object.reportMemoryUsage(&memoryObjectInfo);
}
+template<typename HashMapType>
+void MemoryInstrumentation::reportHashMap(const HashMapType& hashMap, ObjectType objectType, bool contentOnly)
+{
+ countObjectSize(objectType, calculateContainerSize(hashMap, contentOnly));
+}
+
+template<typename HashSetType>
+void MemoryInstrumentation::reportHashSet(const HashSetType& hashSet, ObjectType objectType, bool contentOnly)
+{
+ if (visited(&hashSet))
+ return;
+ countObjectSize(objectType, calculateContainerSize(hashSet, contentOnly));
+}
+
+template<typename ListHashSetType>
+void MemoryInstrumentation::reportListHashSet(const ListHashSetType& hashSet, ObjectType objectType, bool contentOnly)
+{
+ if (visited(&hashSet))
+ return;
+ size_t size = (contentOnly ? 0 : sizeof(ListHashSetType)) + hashSet.capacity() * sizeof(void*) + hashSet.size() * (sizeof(typename ListHashSetType::ValueType) + 2 * sizeof(void*));
+ countObjectSize(objectType, size);
+}
+
+template <typename VectorType>
+void MemoryInstrumentation::reportVector(const VectorType& vector, ObjectType objectType, bool contentOnly)
+{
+ if (visited(vector.data()))
+ return;
+ countObjectSize(objectType, calculateContainerSize(vector, contentOnly));
+}
+
+template<typename T>
+void MemoryInstrumentation::InstrumentedPointer<T>::process(MemoryInstrumentation* memoryInstrumentation)
+{
+ MemoryObjectInfo memoryObjectInfo(memoryInstrumentation);
+ m_pointer->reportMemoryUsage(&memoryObjectInfo);
+ memoryInstrumentation->countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize());
+}
+
} // namespace WebCore
#endif // !defined(MemoryInstrumentation_h)
diff --git a/Source/WebCore/dom/MutationCallback.h b/Source/WebCore/dom/MutationCallback.h
index 80739c88a..119197abe 100644
--- a/Source/WebCore/dom/MutationCallback.h
+++ b/Source/WebCore/dom/MutationCallback.h
@@ -40,7 +40,7 @@
namespace WebCore {
class MutationRecord;
-class WebKitMutationObserver;
+class MutationObserver;
typedef Vector<RefPtr<MutationRecord> > MutationRecordArray;
@@ -48,7 +48,7 @@ class MutationCallback : public RefCounted<MutationCallback> {
public:
virtual ~MutationCallback() { }
- virtual bool handleEvent(MutationRecordArray*, WebKitMutationObserver*) = 0;
+ virtual bool handleEvent(MutationRecordArray*, MutationObserver*) = 0;
};
}
diff --git a/Source/WebCore/dom/MutationCallback.idl b/Source/WebCore/dom/MutationCallback.idl
index 16381714c..2aecd9be9 100644
--- a/Source/WebCore/dom/MutationCallback.idl
+++ b/Source/WebCore/dom/MutationCallback.idl
@@ -33,6 +33,6 @@ module core {
Conditional=MUTATION_OBSERVERS,
Callback
] MutationCallback {
- [Custom] boolean handleEvent(in MutationRecordArray mutations, in WebKitMutationObserver observer);
+ [Custom] boolean handleEvent(in MutationRecordArray mutations, in MutationObserver observer);
};
}
diff --git a/Source/WebCore/dom/WebKitMutationObserver.cpp b/Source/WebCore/dom/MutationObserver.cpp
index 80c26a577..a40d507fe 100644
--- a/Source/WebCore/dom/WebKitMutationObserver.cpp
+++ b/Source/WebCore/dom/MutationObserver.cpp
@@ -32,7 +32,7 @@
#if ENABLE(MUTATION_OBSERVERS)
-#include "WebKitMutationObserver.h"
+#include "MutationObserver.h"
#include "Dictionary.h"
#include "Document.h"
@@ -50,31 +50,31 @@ namespace WebCore {
static unsigned s_observerPriority = 0;
-struct WebKitMutationObserver::ObserverLessThan {
- bool operator()(const RefPtr<WebKitMutationObserver>& lhs, const RefPtr<WebKitMutationObserver>& rhs)
+struct MutationObserver::ObserverLessThan {
+ bool operator()(const RefPtr<MutationObserver>& lhs, const RefPtr<MutationObserver>& rhs)
{
return lhs->m_priority < rhs->m_priority;
}
};
-PassRefPtr<WebKitMutationObserver> WebKitMutationObserver::create(PassRefPtr<MutationCallback> callback)
+PassRefPtr<MutationObserver> MutationObserver::create(PassRefPtr<MutationCallback> callback)
{
ASSERT(isMainThread());
- return adoptRef(new WebKitMutationObserver(callback));
+ return adoptRef(new MutationObserver(callback));
}
-WebKitMutationObserver::WebKitMutationObserver(PassRefPtr<MutationCallback> callback)
+MutationObserver::MutationObserver(PassRefPtr<MutationCallback> callback)
: m_callback(callback)
, m_priority(s_observerPriority++)
{
}
-WebKitMutationObserver::~WebKitMutationObserver()
+MutationObserver::~MutationObserver()
{
ASSERT(m_registrations.isEmpty());
}
-bool WebKitMutationObserver::validateOptions(MutationObserverOptions options)
+bool MutationObserver::validateOptions(MutationObserverOptions options)
{
return (options & (Attributes | CharacterData | ChildList))
&& ((options & Attributes) || !(options & AttributeOldValue))
@@ -82,7 +82,7 @@ bool WebKitMutationObserver::validateOptions(MutationObserverOptions options)
&& ((options & CharacterData) || !(options & CharacterDataOldValue));
}
-void WebKitMutationObserver::observe(Node* node, const Dictionary& optionsDictionary, ExceptionCode& ec)
+void MutationObserver::observe(Node* node, const Dictionary& optionsDictionary, ExceptionCode& ec)
{
if (!node) {
ec = NOT_FOUND_ERR;
@@ -93,12 +93,12 @@ void WebKitMutationObserver::observe(Node* node, const Dictionary& optionsDictio
const char* name;
MutationObserverOptions value;
} booleanOptions[] = {
- { "childList", WebKitMutationObserver::ChildList },
- { "attributes", WebKitMutationObserver::Attributes },
- { "characterData", WebKitMutationObserver::CharacterData },
- { "subtree", WebKitMutationObserver::Subtree },
- { "attributeOldValue", WebKitMutationObserver::AttributeOldValue },
- { "characterDataOldValue", WebKitMutationObserver::CharacterDataOldValue }
+ { "childList", ChildList },
+ { "attributes", Attributes },
+ { "characterData", CharacterData },
+ { "subtree", Subtree },
+ { "attributeOldValue", AttributeOldValue },
+ { "characterDataOldValue", CharacterDataOldValue }
};
MutationObserverOptions options = 0;
for (unsigned i = 0; i < sizeof(booleanOptions) / sizeof(booleanOptions[0]); ++i) {
@@ -109,7 +109,7 @@ void WebKitMutationObserver::observe(Node* node, const Dictionary& optionsDictio
HashSet<AtomicString> attributeFilter;
if (optionsDictionary.get("attributeFilter", attributeFilter))
- options |= WebKitMutationObserver::AttributeFilter;
+ options |= AttributeFilter;
if (!validateOptions(options)) {
ec = SYNTAX_ERR;
@@ -122,14 +122,14 @@ void WebKitMutationObserver::observe(Node* node, const Dictionary& optionsDictio
node->document()->addMutationObserverTypes(registration->mutationTypes());
}
-Vector<RefPtr<MutationRecord> > WebKitMutationObserver::takeRecords()
+Vector<RefPtr<MutationRecord> > MutationObserver::takeRecords()
{
Vector<RefPtr<MutationRecord> > records;
records.swap(m_records);
return records;
}
-void WebKitMutationObserver::disconnect()
+void MutationObserver::disconnect()
{
m_records.clear();
HashSet<MutationObserverRegistration*> registrations(m_registrations);
@@ -137,19 +137,19 @@ void WebKitMutationObserver::disconnect()
(*iter)->unregister();
}
-void WebKitMutationObserver::observationStarted(MutationObserverRegistration* registration)
+void MutationObserver::observationStarted(MutationObserverRegistration* registration)
{
ASSERT(!m_registrations.contains(registration));
m_registrations.add(registration);
}
-void WebKitMutationObserver::observationEnded(MutationObserverRegistration* registration)
+void MutationObserver::observationEnded(MutationObserverRegistration* registration)
{
ASSERT(m_registrations.contains(registration));
m_registrations.remove(registration);
}
-typedef HashSet<RefPtr<WebKitMutationObserver> > MutationObserverSet;
+typedef HashSet<RefPtr<MutationObserver> > MutationObserverSet;
static MutationObserverSet& activeMutationObservers()
{
@@ -157,20 +157,20 @@ static MutationObserverSet& activeMutationObservers()
return activeObservers;
}
-void WebKitMutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation)
+void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation)
{
ASSERT(isMainThread());
m_records.append(mutation);
activeMutationObservers().add(this);
}
-void WebKitMutationObserver::setHasTransientRegistration()
+void MutationObserver::setHasTransientRegistration()
{
ASSERT(isMainThread());
activeMutationObservers().add(this);
}
-void WebKitMutationObserver::deliver()
+void MutationObserver::deliver()
{
// Calling clearTransientRegistrations() can modify m_registrations, so it's necessary
// to make a copy of the transient registrations before operating on them.
@@ -191,7 +191,7 @@ void WebKitMutationObserver::deliver()
m_callback->handleEvent(&records, this);
}
-void WebKitMutationObserver::deliverAllMutations()
+void MutationObserver::deliverAllMutations()
{
ASSERT(isMainThread());
static bool deliveryInProgress = false;
@@ -200,7 +200,7 @@ void WebKitMutationObserver::deliverAllMutations()
deliveryInProgress = true;
while (!activeMutationObservers().isEmpty()) {
- Vector<RefPtr<WebKitMutationObserver> > observers;
+ Vector<RefPtr<MutationObserver> > observers;
copyToVector(activeMutationObservers(), observers);
activeMutationObservers().clear();
std::sort(observers.begin(), observers.end(), ObserverLessThan());
diff --git a/Source/WebCore/dom/WebKitMutationObserver.h b/Source/WebCore/dom/MutationObserver.h
index bf0964726..7fd372069 100644
--- a/Source/WebCore/dom/WebKitMutationObserver.h
+++ b/Source/WebCore/dom/MutationObserver.h
@@ -28,8 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WebKitMutationObserver_h
-#define WebKitMutationObserver_h
+#ifndef MutationObserver_h
+#define MutationObserver_h
#if ENABLE(MUTATION_OBSERVERS)
@@ -54,7 +54,7 @@ typedef int ExceptionCode;
typedef unsigned char MutationObserverOptions;
typedef unsigned char MutationRecordDeliveryOptions;
-class WebKitMutationObserver : public RefCounted<WebKitMutationObserver> {
+class MutationObserver : public RefCounted<MutationObserver> {
public:
enum MutationType {
ChildList = 1 << 0,
@@ -74,10 +74,10 @@ public:
CharacterDataOldValue = 1 << 6,
};
- static PassRefPtr<WebKitMutationObserver> create(PassRefPtr<MutationCallback>);
+ static PassRefPtr<MutationObserver> create(PassRefPtr<MutationCallback>);
static void deliverAllMutations();
- ~WebKitMutationObserver();
+ ~MutationObserver();
void observe(Node*, const Dictionary&, ExceptionCode&);
Vector<RefPtr<MutationRecord> > takeRecords();
@@ -90,7 +90,7 @@ public:
private:
struct ObserverLessThan;
- WebKitMutationObserver(PassRefPtr<MutationCallback>);
+ MutationObserver(PassRefPtr<MutationCallback>);
void deliver();
static bool validateOptions(MutationObserverOptions);
@@ -105,4 +105,4 @@ private:
#endif // ENABLE(MUTATION_OBSERVERS)
-#endif // WebKitMutationObserver_h
+#endif // MutationObserver_h
diff --git a/Source/WebCore/dom/WebKitMutationObserver.idl b/Source/WebCore/dom/MutationObserver.idl
index c338be28d..0ae992e6d 100644
--- a/Source/WebCore/dom/WebKitMutationObserver.idl
+++ b/Source/WebCore/dom/MutationObserver.idl
@@ -33,7 +33,7 @@ module core {
Conditional=MUTATION_OBSERVERS,
CustomConstructor,
ConstructorParameters=1
- ] WebKitMutationObserver {
+ ] MutationObserver {
void observe(in Node target, in Dictionary options)
raises(DOMException);
sequence<MutationRecord> takeRecords();
diff --git a/Source/WebCore/dom/MutationObserverInterestGroup.cpp b/Source/WebCore/dom/MutationObserverInterestGroup.cpp
index dd0288d51..24c0cb586 100644
--- a/Source/WebCore/dom/MutationObserverInterestGroup.cpp
+++ b/Source/WebCore/dom/MutationObserverInterestGroup.cpp
@@ -41,10 +41,10 @@
namespace WebCore {
-PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node* target, WebKitMutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
+PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node* target, MutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
{
- ASSERT((type == WebKitMutationObserver::Attributes && attributeName) || !attributeName);
- HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers;
+ ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
+ HashMap<MutationObserver*, MutationRecordDeliveryOptions> observers;
target->getRegisteredMutationObserversOfType(observers, type, attributeName);
if (observers.isEmpty())
return nullptr;
@@ -52,7 +52,7 @@ PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createI
return adoptPtr(new MutationObserverInterestGroup(observers, oldValueFlag));
}
-MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
+MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
: m_oldValueFlag(oldValueFlag)
{
ASSERT(!observers.isEmpty());
@@ -61,7 +61,7 @@ MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<WebKitMutat
bool MutationObserverInterestGroup::isOldValueRequested()
{
- for (HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
+ for (HashMap<MutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
if (hasOldValue(iter->second))
return true;
}
@@ -72,8 +72,8 @@ void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRec
{
RefPtr<MutationRecord> mutation = prpMutation;
RefPtr<MutationRecord> mutationWithNullOldValue;
- for (HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
- WebKitMutationObserver* observer = iter->first;
+ for (HashMap<MutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
+ MutationObserver* observer = iter->first;
if (hasOldValue(iter->second)) {
observer->enqueueMutationRecord(mutation);
continue;
diff --git a/Source/WebCore/dom/MutationObserverInterestGroup.h b/Source/WebCore/dom/MutationObserverInterestGroup.h
index 933334a1b..7fde32eea 100644
--- a/Source/WebCore/dom/MutationObserverInterestGroup.h
+++ b/Source/WebCore/dom/MutationObserverInterestGroup.h
@@ -34,9 +34,9 @@
#if ENABLE(MUTATION_OBSERVERS)
#include "Document.h"
+#include "MutationObserver.h"
#include "Node.h"
#include "QualifiedName.h"
-#include "WebKitMutationObserver.h"
#include <wtf/HashMap.h>
#include <wtf/PassOwnPtr.h>
@@ -46,39 +46,39 @@ class MutationObserverInterestGroup {
public:
static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node* target)
{
- if (!target->document()->hasMutationObserversOfType(WebKitMutationObserver::ChildList))
+ if (!target->document()->hasMutationObserversOfType(MutationObserver::ChildList))
return nullptr;
MutationRecordDeliveryOptions oldValueFlag = 0;
- return createIfNeeded(target, WebKitMutationObserver::ChildList, oldValueFlag);
+ return createIfNeeded(target, MutationObserver::ChildList, oldValueFlag);
}
static PassOwnPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node* target)
{
- if (!target->document()->hasMutationObserversOfType(WebKitMutationObserver::CharacterData))
+ if (!target->document()->hasMutationObserversOfType(MutationObserver::CharacterData))
return nullptr;
- return createIfNeeded(target, WebKitMutationObserver::CharacterData, WebKitMutationObserver::CharacterDataOldValue);
+ return createIfNeeded(target, MutationObserver::CharacterData, MutationObserver::CharacterDataOldValue);
}
static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node* target, const QualifiedName& attributeName)
{
- if (!target->document()->hasMutationObserversOfType(WebKitMutationObserver::Attributes))
+ if (!target->document()->hasMutationObserversOfType(MutationObserver::Attributes))
return nullptr;
- return createIfNeeded(target, WebKitMutationObserver::Attributes, WebKitMutationObserver::AttributeOldValue, &attributeName);
+ return createIfNeeded(target, MutationObserver::Attributes, MutationObserver::AttributeOldValue, &attributeName);
}
bool isOldValueRequested();
void enqueueMutationRecord(PassRefPtr<MutationRecord>);
private:
- static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node* target, WebKitMutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
- MutationObserverInterestGroup(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
+ static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node* target, MutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
+ MutationObserverInterestGroup(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
- HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> m_observers;
+ HashMap<MutationObserver*, MutationRecordDeliveryOptions> m_observers;
MutationRecordDeliveryOptions m_oldValueFlag;
};
diff --git a/Source/WebCore/dom/MutationObserverRegistration.cpp b/Source/WebCore/dom/MutationObserverRegistration.cpp
index 190b85bd8..5895ef49f 100644
--- a/Source/WebCore/dom/MutationObserverRegistration.cpp
+++ b/Source/WebCore/dom/MutationObserverRegistration.cpp
@@ -40,12 +40,12 @@
namespace WebCore {
-PassOwnPtr<MutationObserverRegistration> MutationObserverRegistration::create(PassRefPtr<WebKitMutationObserver> observer, Node* registrationNode)
+PassOwnPtr<MutationObserverRegistration> MutationObserverRegistration::create(PassRefPtr<MutationObserver> observer, Node* registrationNode)
{
return adoptPtr(new MutationObserverRegistration(observer, registrationNode));
}
-MutationObserverRegistration::MutationObserverRegistration(PassRefPtr<WebKitMutationObserver> observer, Node* registrationNode)
+MutationObserverRegistration::MutationObserverRegistration(PassRefPtr<MutationObserver> observer, Node* registrationNode)
: m_observer(observer)
, m_registrationNode(registrationNode)
, m_options(0)
@@ -105,16 +105,16 @@ void MutationObserverRegistration::unregister()
// The above line will cause this object to be deleted, so don't do any more in this function.
}
-bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, WebKitMutationObserver::MutationType type, const QualifiedName* attributeName)
+bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, MutationObserver::MutationType type, const QualifiedName* attributeName)
{
- ASSERT((type == WebKitMutationObserver::Attributes && attributeName) || !attributeName);
+ ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
if (!(m_options & type))
return false;
if (m_registrationNode != node && !isSubtree())
return false;
- if (type != WebKitMutationObserver::Attributes || !(m_options & WebKitMutationObserver::AttributeFilter))
+ if (type != MutationObserver::Attributes || !(m_options & MutationObserver::AttributeFilter))
return true;
if (!attributeName->namespaceURI().isNull())
diff --git a/Source/WebCore/dom/MutationObserverRegistration.h b/Source/WebCore/dom/MutationObserverRegistration.h
index 232ee25d5..d4914625a 100644
--- a/Source/WebCore/dom/MutationObserverRegistration.h
+++ b/Source/WebCore/dom/MutationObserverRegistration.h
@@ -33,7 +33,7 @@
#if ENABLE(MUTATION_OBSERVERS)
-#include "WebKitMutationObserver.h"
+#include "MutationObserver.h"
#include <wtf/HashSet.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/AtomicStringHash.h>
@@ -45,7 +45,7 @@ class QualifiedName;
class MutationObserverRegistration {
public:
- static PassOwnPtr<MutationObserverRegistration> create(PassRefPtr<WebKitMutationObserver>, Node*);
+ static PassOwnPtr<MutationObserverRegistration> create(PassRefPtr<MutationObserver>, Node*);
~MutationObserverRegistration();
@@ -55,19 +55,19 @@ public:
bool hasTransientRegistrations() { return m_transientRegistrationNodes && !m_transientRegistrationNodes->isEmpty(); }
void unregister();
- bool shouldReceiveMutationFrom(Node*, WebKitMutationObserver::MutationType, const QualifiedName* attributeName);
- bool inline isSubtree() const { return m_options & WebKitMutationObserver::Subtree; }
+ bool shouldReceiveMutationFrom(Node*, MutationObserver::MutationType, const QualifiedName* attributeName);
+ bool inline isSubtree() const { return m_options & MutationObserver::Subtree; }
- WebKitMutationObserver* observer() { return m_observer.get(); }
- MutationRecordDeliveryOptions deliveryOptions() const { return m_options & (WebKitMutationObserver::AttributeOldValue | WebKitMutationObserver::CharacterDataOldValue); }
- MutationObserverOptions mutationTypes() const { return m_options & WebKitMutationObserver::AllMutationTypes; }
+ MutationObserver* observer() { return m_observer.get(); }
+ MutationRecordDeliveryOptions deliveryOptions() const { return m_options & (MutationObserver::AttributeOldValue | MutationObserver::CharacterDataOldValue); }
+ MutationObserverOptions mutationTypes() const { return m_options & MutationObserver::AllMutationTypes; }
private:
- MutationObserverRegistration(PassRefPtr<WebKitMutationObserver>, Node*);
+ MutationObserverRegistration(PassRefPtr<MutationObserver>, Node*);
const HashSet<AtomicString>& caseInsensitiveAttributeFilter();
- RefPtr<WebKitMutationObserver> m_observer;
+ RefPtr<MutationObserver> m_observer;
Node* m_registrationNode;
RefPtr<Node> m_registrationNodeKeepAlive;
typedef HashSet<RefPtr<Node> > NodeHashSet;
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index ae3945be5..0950cd933 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -399,7 +399,6 @@ Node::~Node()
liveNodeSet.remove(this);
#endif
- ASSERT(hasRareData() == NodeRareData::rareDataMap().contains(this));
if (hasRareData())
clearRareData();
@@ -459,17 +458,25 @@ TreeScope* Node::treeScope() const
NodeRareData* Node::rareData() const
{
ASSERT(hasRareData());
- return NodeRareData::rareDataFromMap(this);
+ NodeRareData* data = isDocumentNode() ? static_cast<const Document*>(this)->documentRareData() : NodeRareData::rareDataFromMap(this);
+ ASSERT(data);
+ return data;
}
NodeRareData* Node::ensureRareData()
{
if (hasRareData())
return rareData();
-
- ASSERT(!NodeRareData::rareDataMap().contains(this));
+
NodeRareData* data = createRareData().leakPtr();
- NodeRareData::rareDataMap().set(this, data);
+ if (isDocumentNode()) {
+ // Fast path for a Document. A Document knows a pointer to NodeRareData.
+ ASSERT(!static_cast<Document*>(this)->documentRareData());
+ static_cast<Document*>(this)->setDocumentRareData(data);
+ } else {
+ ASSERT(!NodeRareData::rareDataMap().contains(this));
+ NodeRareData::rareDataMap().set(this, data);
+ }
setFlag(HasRareDataFlag);
return data;
}
@@ -489,11 +496,19 @@ void Node::clearRareData()
ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty());
#endif
- NodeRareData::NodeRareDataMap& dataMap = NodeRareData::rareDataMap();
- NodeRareData::NodeRareDataMap::iterator it = dataMap.find(this);
- ASSERT(it != dataMap.end());
- delete it->second;
- dataMap.remove(it);
+ if (isDocumentNode()) {
+ Document* document = static_cast<Document*>(this);
+ NodeRareData* data = document->documentRareData();
+ ASSERT(data);
+ delete data;
+ document->setDocumentRareData(0);
+ } else {
+ NodeRareData::NodeRareDataMap& dataMap = NodeRareData::rareDataMap();
+ NodeRareData::NodeRareDataMap::iterator it = dataMap.find(this);
+ ASSERT(it != dataMap.end());
+ delete it->second;
+ dataMap.remove(it);
+ }
clearFlag(HasRareDataFlag);
}
@@ -2403,16 +2418,16 @@ HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry(
return hasRareData() ? rareData()->transientMutationObserverRegistry() : 0;
}
-void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, Node* fromNode, WebKitMutationObserver::MutationType type, const QualifiedName* attributeName)
+void Node::collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Node* fromNode, MutationObserver::MutationType type, const QualifiedName* attributeName)
{
- ASSERT((type == WebKitMutationObserver::Attributes && attributeName) || !attributeName);
+ ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
if (Vector<OwnPtr<MutationObserverRegistration> >* registry = fromNode->mutationObserverRegistry()) {
const size_t size = registry->size();
for (size_t i = 0; i < size; ++i) {
MutationObserverRegistration* registration = registry->at(i).get();
if (registration->shouldReceiveMutationFrom(this, type, attributeName)) {
MutationRecordDeliveryOptions deliveryOptions = registration->deliveryOptions();
- HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration->observer(), deliveryOptions);
+ HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration->observer(), deliveryOptions);
if (!result.isNewEntry)
result.iterator->second |= deliveryOptions;
@@ -2425,7 +2440,7 @@ void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*,
MutationObserverRegistration* registration = *iter;
if (registration->shouldReceiveMutationFrom(this, type, attributeName)) {
MutationRecordDeliveryOptions deliveryOptions = registration->deliveryOptions();
- HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration->observer(), deliveryOptions);
+ HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration->observer(), deliveryOptions);
if (!result.isNewEntry)
result.iterator->second |= deliveryOptions;
}
@@ -2433,15 +2448,15 @@ void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*,
}
}
-void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, WebKitMutationObserver::MutationType type, const QualifiedName* attributeName)
+void Node::getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
{
- ASSERT((type == WebKitMutationObserver::Attributes && attributeName) || !attributeName);
+ ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
collectMatchingObserversForMutation(observers, this, type, attributeName);
for (Node* node = parentNode(); node; node = node->parentNode())
collectMatchingObserversForMutation(observers, node, type, attributeName);
}
-MutationObserverRegistration* Node::registerMutationObserver(PassRefPtr<WebKitMutationObserver> observer)
+MutationObserverRegistration* Node::registerMutationObserver(PassRefPtr<MutationObserver> observer)
{
Vector<OwnPtr<MutationObserverRegistration> >* registry = ensureRareData()->ensureMutationObserverRegistry();
for (size_t i = 0; i < registry->size(); ++i) {
@@ -2763,10 +2778,6 @@ void Node::setItemType(const String& value)
ensureRareData()->setItemType(value);
}
-HTMLPropertiesCollection* Node::properties()
-{
- return ensureRareData()->properties(this);
-}
#endif
void NodeRareData::createNodeLists(Node* node)
diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h
index c9c2674d2..93a66d9ec 100644
--- a/Source/WebCore/dom/Node.h
+++ b/Source/WebCore/dom/Node.h
@@ -30,10 +30,10 @@
#include "KURLHash.h"
#include "LayoutTypes.h"
#include "MemoryInstrumentation.h"
+#include "MutationObserver.h"
#include "RenderStyleConstants.h"
#include "ScriptWrappable.h"
#include "TreeShared.h"
-#include "WebKitMutationObserver.h"
#include <wtf/Forward.h>
#include <wtf/ListHashSet.h>
#include <wtf/text/AtomicString.h>
@@ -630,12 +630,11 @@ public:
DOMSettableTokenList* itemProp();
DOMSettableTokenList* itemRef();
DOMSettableTokenList* itemType();
- HTMLPropertiesCollection* properties();
#endif
#if ENABLE(MUTATION_OBSERVERS)
- void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, WebKitMutationObserver::MutationType, const QualifiedName* attributeName);
- MutationObserverRegistration* registerMutationObserver(PassRefPtr<WebKitMutationObserver>);
+ void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
+ MutationObserverRegistration* registerMutationObserver(PassRefPtr<MutationObserver>);
void unregisterMutationObserver(MutationObserverRegistration*);
void registerTransientMutationObserver(MutationObserverRegistration*);
void unregisterTransientMutationObserver(MutationObserverRegistration*);
@@ -781,7 +780,7 @@ private:
#if ENABLE(MUTATION_OBSERVERS)
Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry();
HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
- void collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, Node* fromNode, WebKitMutationObserver::MutationType, const QualifiedName* attributeName);
+ void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, Node* fromNode, MutationObserver::MutationType, const QualifiedName* attributeName);
#endif
mutable uint32_t m_nodeFlags;
@@ -808,9 +807,9 @@ protected:
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); }
+ bool hasSVGRareData() const { return getFlag(HasSVGRareDataFlag); }
+ void setHasSVGRareData() { setFlag(HasSVGRareDataFlag); }
+ void clearHasSVGRareData() { clearFlag(HasSVGRareDataFlag); }
#endif
#if ENABLE(MICRODATA)
diff --git a/Source/WebCore/dom/NodeList.idl b/Source/WebCore/dom/NodeList.idl
index 71544d16b..e5d0f9074 100644
--- a/Source/WebCore/dom/NodeList.idl
+++ b/Source/WebCore/dom/NodeList.idl
@@ -21,9 +21,10 @@
module core {
interface [
- JSCustomIsReachable,
+ CustomIsReachable,
IndexedGetter,
- NamedGetter
+ NamedGetter,
+ V8DependentLifetime
] NodeList {
Node item(in [IsIndex,Optional=DefaultIsUndefined] unsigned long index);
diff --git a/Source/WebCore/dom/NodeRareData.h b/Source/WebCore/dom/NodeRareData.h
index b7f359e60..5c03d8b38 100644
--- a/Source/WebCore/dom/NodeRareData.h
+++ b/Source/WebCore/dom/NodeRareData.h
@@ -25,10 +25,10 @@
#include "ChildNodeList.h"
#include "DOMSettableTokenList.h"
#include "DynamicNodeList.h"
+#include "MutationObserver.h"
#include "MutationObserverRegistration.h"
#include "QualifiedName.h"
#include "TagNodeList.h"
-#include "WebKitMutationObserver.h"
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
@@ -305,14 +305,6 @@ public:
m_itemType->setValue(value);
}
-
- HTMLPropertiesCollection* properties(Node* node)
- {
- if (!m_properties)
- m_properties = HTMLPropertiesCollection::create(node);
-
- return m_properties.get();
- }
#endif
#if ENABLE(STYLE_SCOPED)
@@ -368,7 +360,6 @@ private:
mutable RefPtr<DOMSettableTokenList> m_itemProp;
mutable RefPtr<DOMSettableTokenList> m_itemRef;
mutable RefPtr<DOMSettableTokenList> m_itemType;
- mutable OwnPtr<HTMLPropertiesCollection> m_properties;
#endif
#if ENABLE(STYLE_SCOPED)
diff --git a/Source/WebCore/dom/NodeRenderingContext.cpp b/Source/WebCore/dom/NodeRenderingContext.cpp
index b62ffe20e..180aa94fe 100644
--- a/Source/WebCore/dom/NodeRenderingContext.cpp
+++ b/Source/WebCore/dom/NodeRenderingContext.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "NodeRenderingContext.h"
+#include "ComposedShadowTreeWalker.h"
#include "ContainerNode.h"
#include "ContentDistributor.h"
#include "ElementShadow.h"
@@ -53,80 +54,14 @@ static RenderObject* lastRendererOf(Node*);
NodeRenderingContext::NodeRenderingContext(Node* node)
: m_node(node)
- , m_parentNodeForRenderingAndStyle(0)
- , m_resetStyleInheritance(false)
- , m_insertionPoint(0)
, m_style(0)
, m_parentFlowRenderer(0)
{
- ContainerNode* parent = m_node->parentOrHostNode();
- if (!parent)
- return;
-
- if (parent->isShadowRoot() && toShadowRoot(parent)->isYoungest()) {
- m_parentNodeForRenderingAndStyle = toShadowRoot(parent)->host();
- m_resetStyleInheritance = toShadowRoot(parent)->resetStyleInheritance();
- return;
- }
-
- if (parent->isElementNode() || parent->isShadowRoot()) {
- ElementShadow* parentShadow = 0;
-
- if (parent->isElementNode())
- parentShadow = toElement(parent)->shadow();
- else if (parent->isShadowRoot())
- parentShadow = toShadowRoot(parent)->owner();
-
- if (parentShadow) {
- parentShadow->ensureDistribution();
-
- if (InsertionPoint* insertionPoint = parentShadow->insertionPointFor(m_node)) {
- if (insertionPoint->shadowRoot()->isUsedForRendering()) {
- NodeRenderingContext insertionPointContext(insertionPoint);
- m_parentNodeForRenderingAndStyle = insertionPointContext.parentNodeForRenderingAndStyle();
- m_resetStyleInheritance = insertionPointContext.resetStyleInheritance();
- m_insertionPoint = insertionPoint;
- return;
- }
- }
-
- return;
- }
-
- if (isLowerEncapsulationBoundary(parent)) {
- ShadowRoot* parentScope = parent->shadowRoot();
- parentScope->owner()->ensureDistribution();
-
- // The shadow tree isn't part of composed tree.
- if (!parentScope->isUsedForRendering())
- return;
-
- // the parent insertion point doesn't need any fallback content.
- if (toInsertionPoint(parent)->hasDistribution())
- return;
-
- if (toInsertionPoint(parent)->isActive()) {
- // Uses m_node as a fallback node of the insertion point.
- NodeRenderingContext parentContext(parent);
- m_parentNodeForRenderingAndStyle = parentContext.parentNodeForRenderingAndStyle();
- m_resetStyleInheritance = parentContext.resetStyleInheritance();
- return;
- }
-
- // The insertion point isn't active thus behaves as a plain old element.
- m_parentNodeForRenderingAndStyle = parent;
- return;
- }
- }
-
- m_parentNodeForRenderingAndStyle = parent;
+ ComposedShadowTreeWalker::findParent(m_node, &m_parentDetails);
}
NodeRenderingContext::NodeRenderingContext(Node* node, RenderStyle* style)
: m_node(node)
- , m_parentNodeForRenderingAndStyle(0)
- , m_resetStyleInheritance(false)
- , m_insertionPoint(0)
, m_style(style)
, m_parentFlowRenderer(0)
{
@@ -242,10 +177,10 @@ RenderObject* NodeRenderingContext::nextRenderer() const
if (m_parentFlowRenderer)
return m_parentFlowRenderer->nextRendererForNode(m_node);
- if (m_insertionPoint) {
- if (RenderObject* found = nextRendererOfInsertionPoint(m_insertionPoint, m_node))
+ if (m_parentDetails.insertionPoint()) {
+ if (RenderObject* found = nextRendererOfInsertionPoint(m_parentDetails.insertionPoint(), m_node))
return found;
- return NodeRenderingContext(m_insertionPoint).nextRenderer();
+ return NodeRenderingContext(m_parentDetails.insertionPoint()).nextRenderer();
}
// Avoid an O(N^2) problem with this function by not checking for
@@ -264,10 +199,10 @@ RenderObject* NodeRenderingContext::previousRenderer() const
if (m_parentFlowRenderer)
return m_parentFlowRenderer->previousRendererForNode(m_node);
- if (m_insertionPoint) {
- if (RenderObject* found = previousRendererOfInsertionPoint(m_insertionPoint, m_node))
+ if (m_parentDetails.insertionPoint()) {
+ if (RenderObject* found = previousRendererOfInsertionPoint(m_parentDetails.insertionPoint(), m_node))
return found;
- return NodeRenderingContext(m_insertionPoint).previousRenderer();
+ return NodeRenderingContext(m_parentDetails.insertionPoint()).previousRenderer();
}
// FIXME: We should have the same O(N^2) avoidance as nextRenderer does
@@ -282,19 +217,19 @@ RenderObject* NodeRenderingContext::parentRenderer() const
if (m_parentFlowRenderer)
return m_parentFlowRenderer;
- return m_parentNodeForRenderingAndStyle ? m_parentNodeForRenderingAndStyle->renderer() : 0;
+ return m_parentDetails.node() ? m_parentDetails.node()->renderer() : 0;
}
bool NodeRenderingContext::shouldCreateRenderer() const
{
- if (!m_parentNodeForRenderingAndStyle)
+ if (!m_parentDetails.node())
return false;
RenderObject* parentRenderer = this->parentRenderer();
if (!parentRenderer)
return false;
if (!parentRenderer->canHaveChildren())
return false;
- if (!m_parentNodeForRenderingAndStyle->childShouldCreateRenderer(*this))
+ if (!m_parentDetails.node()->childShouldCreateRenderer(*this))
return false;
return true;
}
@@ -327,7 +262,7 @@ void NodeRenderingContext::moveToFlowThreadIfNeeded()
bool NodeRenderingContext::isOnEncapsulationBoundary() const
{
- return isOnUpperEncapsulationBoundary() || isLowerEncapsulationBoundary(m_insertionPoint) || isLowerEncapsulationBoundary(m_node->parentNode());
+ return isOnUpperEncapsulationBoundary() || isLowerEncapsulationBoundary(m_parentDetails.insertionPoint()) || isLowerEncapsulationBoundary(m_node->parentNode());
}
bool NodeRenderingContext::isOnUpperEncapsulationBoundary() const
diff --git a/Source/WebCore/dom/NodeRenderingContext.h b/Source/WebCore/dom/NodeRenderingContext.h
index 28f028fe9..36171dd1e 100644
--- a/Source/WebCore/dom/NodeRenderingContext.h
+++ b/Source/WebCore/dom/NodeRenderingContext.h
@@ -26,6 +26,7 @@
#ifndef NodeRenderingContext_h
#define NodeRenderingContext_h
+#include "ComposedShadowTreeWalker.h"
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
#include <wtf/text/AtomicString.h>
@@ -69,9 +70,7 @@ public:
private:
Node* m_node;
- ContainerNode* m_parentNodeForRenderingAndStyle;
- bool m_resetStyleInheritance;
- InsertionPoint* m_insertionPoint;
+ ComposedShadowTreeWalker::ParentTranversalDetails m_parentDetails;
RefPtr<RenderStyle> m_style;
RenderNamedFlowThread* m_parentFlowRenderer;
AtomicString m_flowThread;
@@ -84,12 +83,12 @@ inline Node* NodeRenderingContext::node() const
inline ContainerNode* NodeRenderingContext::parentNodeForRenderingAndStyle() const
{
- return m_parentNodeForRenderingAndStyle;
+ return m_parentDetails.node();
}
inline bool NodeRenderingContext::resetStyleInheritance() const
{
- return m_resetStyleInheritance;
+ return m_parentDetails.resetStyleInheritance();
}
inline RenderStyle* NodeRenderingContext::style() const
@@ -99,7 +98,7 @@ inline RenderStyle* NodeRenderingContext::style() const
inline InsertionPoint* NodeRenderingContext::insertionPoint() const
{
- return m_insertionPoint;
+ return m_parentDetails.insertionPoint();
}
class NodeRendererFactory {
diff --git a/Source/WebCore/dom/ScriptElement.cpp b/Source/WebCore/dom/ScriptElement.cpp
index 746e6c37b..9c1654e1f 100644
--- a/Source/WebCore/dom/ScriptElement.cpp
+++ b/Source/WebCore/dom/ScriptElement.cpp
@@ -250,6 +250,8 @@ bool ScriptElement::requestScript(const String& sourceUrl)
return false;
if (!m_element->inDocument() || m_element->document() != originalDocument)
return false;
+ if (!m_element->document()->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr), m_element->document()->url(), m_startLineNumber, m_element->document()->completeURL(sourceUrl)))
+ return false;
ASSERT(!m_cachedScript);
if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
@@ -281,6 +283,9 @@ void ScriptElement::executeScript(const ScriptSourceCode& sourceCode)
if (sourceCode.isEmpty())
return;
+ if (!m_element->document()->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr), m_element->document()->url(), m_startLineNumber))
+ return;
+
if (!m_isExternalScript && !m_element->document()->contentSecurityPolicy()->allowInlineScript(m_element->document()->url(), m_startLineNumber))
return;
diff --git a/Source/WebCore/dom/ShadowRoot.cpp b/Source/WebCore/dom/ShadowRoot.cpp
index 2c57560bf..6c2e5c7d1 100644
--- a/Source/WebCore/dom/ShadowRoot.cpp
+++ b/Source/WebCore/dom/ShadowRoot.cpp
@@ -99,10 +99,10 @@ static bool allowsAuthorShadowRoot(Element* element)
PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ExceptionCode& ec)
{
- return create(element, CreatingAuthorShadowRoot, ec);
+ return create(element, AuthorShadowRoot, ec);
}
-PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ShadowRootCreationPurpose purpose, ExceptionCode& ec)
+PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ShadowRootType type, ExceptionCode& ec)
{
if (!element) {
ec = HIERARCHY_REQUEST_ERR;
@@ -111,12 +111,15 @@ PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ShadowRootCreationPu
// Since some elements recreates shadow root dynamically, multiple shadow subtrees won't work well in that element.
// Until they are fixed, we disable adding author shadow root for them.
- if (purpose == CreatingAuthorShadowRoot && !allowsAuthorShadowRoot(element)) {
+ if (type == AuthorShadowRoot && !allowsAuthorShadowRoot(element)) {
ec = HIERARCHY_REQUEST_ERR;
return 0;
}
RefPtr<ShadowRoot> shadowRoot = adoptRef(new ShadowRoot(element->document()));
+#ifndef NDEBUG
+ shadowRoot->m_type = type;
+#endif
ec = 0;
element->ensureShadow()->addShadowRoot(element, shadowRoot, ec);
diff --git a/Source/WebCore/dom/ShadowRoot.h b/Source/WebCore/dom/ShadowRoot.h
index 6a76e4f22..9c9fcd006 100644
--- a/Source/WebCore/dom/ShadowRoot.h
+++ b/Source/WebCore/dom/ShadowRoot.h
@@ -51,11 +51,11 @@ public:
// if a shadow root is dynamically created. So we prohibit multiple shadow subtrees
// in several elements for a while.
// See https://bugs.webkit.org/show_bug.cgi?id=77503 and related bugs.
- enum ShadowRootCreationPurpose {
- CreatingUserAgentShadowRoot,
- CreatingAuthorShadowRoot,
+ enum ShadowRootType {
+ UserAgentShadowRoot,
+ AuthorShadowRoot
};
- static PassRefPtr<ShadowRoot> create(Element*, ShadowRootCreationPurpose, ExceptionCode& = ASSERT_NO_EXCEPTION);
+ static PassRefPtr<ShadowRoot> create(Element*, ShadowRootType, ExceptionCode& = ASSERT_NO_EXCEPTION);
void recalcShadowTreeStyle(StyleChange);
@@ -89,6 +89,10 @@ public:
InsertionPoint* assignedTo() const;
void setAssignedTo(InsertionPoint*);
+#ifndef NDEBUG
+ ShadowRootType type() const { return m_type; }
+#endif
+
private:
ShadowRoot(Document*);
virtual ~ShadowRoot();
@@ -102,6 +106,10 @@ private:
bool m_applyAuthorStyles : 1;
bool m_resetStyleInheritance : 1;
InsertionPoint* m_insertionPointAssignedTo;
+
+#ifndef NDEBUG
+ ShadowRootType m_type;
+#endif
};
inline Element* ShadowRoot::host() const
diff --git a/Source/WebCore/dom/SpaceSplitString.h b/Source/WebCore/dom/SpaceSplitString.h
index 36521d46e..6c5037ddb 100644
--- a/Source/WebCore/dom/SpaceSplitString.h
+++ b/Source/WebCore/dom/SpaceSplitString.h
@@ -49,6 +49,7 @@ namespace WebCore {
void add(const AtomicString&);
void remove(const AtomicString&);
+ bool isUnique() const { return m_keyString.isNull(); }
size_t size() const { return m_vector.size(); }
const AtomicString& operator[](size_t i) { ASSERT(i < size()); return m_vector[i]; }
@@ -82,7 +83,7 @@ namespace WebCore {
private:
void ensureUnique()
{
- if (m_data && !m_data->hasOneRef())
+ if (m_data && !m_data->isUnique())
m_data = SpaceSplitStringData::createUnique(*m_data);
}
diff --git a/Source/WebCore/dom/Touch.cpp b/Source/WebCore/dom/Touch.cpp
index cf721df90..a6bda2568 100644
--- a/Source/WebCore/dom/Touch.cpp
+++ b/Source/WebCore/dom/Touch.cpp
@@ -29,6 +29,7 @@
#include "Touch.h"
+#include "DOMWindow.h"
#include "Frame.h"
#include "FrameView.h"
@@ -68,6 +69,10 @@ Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier, int screenX
, m_rotationAngle(rotationAngle)
, m_force(force)
{
+ float scaleFactor = frame->pageZoomFactor() * frame->frameScaleFactor();
+ float x = pageX * scaleFactor;
+ float y = pageY * scaleFactor;
+ m_absoluteLocation = roundedLayoutPoint(FloatPoint(x, y));
}
} // namespace WebCore
diff --git a/Source/WebCore/dom/Touch.h b/Source/WebCore/dom/Touch.h
index f4c9e8061..1e80253e6 100644
--- a/Source/WebCore/dom/Touch.h
+++ b/Source/WebCore/dom/Touch.h
@@ -29,6 +29,7 @@
#if ENABLE(TOUCH_EVENTS)
#include "EventTarget.h"
+#include "LayoutTypes.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -59,6 +60,7 @@ public:
int webkitRadiusY() const { return m_radiusY; }
float webkitRotationAngle() const { return m_rotationAngle; }
float webkitForce() const { return m_force; }
+ const LayoutPoint& absoluteLocation() const { return m_absoluteLocation; }
private:
Touch(Frame* frame, EventTarget* target, unsigned identifier,
@@ -77,6 +79,7 @@ private:
int m_radiusY;
float m_rotationAngle;
float m_force;
+ LayoutPoint m_absoluteLocation;
};
} // namespace WebCore
diff --git a/Source/WebCore/dom/TouchEvent.cpp b/Source/WebCore/dom/TouchEvent.cpp
index bfd6360fb..a58f1dcc9 100644
--- a/Source/WebCore/dom/TouchEvent.cpp
+++ b/Source/WebCore/dom/TouchEvent.cpp
@@ -94,6 +94,11 @@ const AtomicString& TouchEvent::interfaceName() const
return eventNames().interfaceForTouchEvent;
}
+bool TouchEvent::isTouchEvent() const
+{
+ return true;
+}
+
} // namespace WebCore
#endif // ENABLE(TOUCH_EVENTS)
diff --git a/Source/WebCore/dom/TouchEvent.h b/Source/WebCore/dom/TouchEvent.h
index 297e340f4..b2e5b2ee3 100644
--- a/Source/WebCore/dom/TouchEvent.h
+++ b/Source/WebCore/dom/TouchEvent.h
@@ -69,6 +69,7 @@ public:
void setTouchHold(bool touchHold) { m_touchHold = touchHold; }
bool isTouchHold() const { return m_touchHold; }
#endif
+ virtual bool isTouchEvent() const OVERRIDE;
virtual const AtomicString& interfaceName() const;
diff --git a/Source/WebCore/dom/ViewportArguments.cpp b/Source/WebCore/dom/ViewportArguments.cpp
index a93e14eea..dc22e6e1f 100644
--- a/Source/WebCore/dom/ViewportArguments.cpp
+++ b/Source/WebCore/dom/ViewportArguments.cpp
@@ -41,11 +41,9 @@ using namespace std;
namespace WebCore {
-// FIXME: We shouldn't hardcode the targetDPI to 160.
-// See https://bugs.webkit.org/show_bug.cgi?id=88114
-static float targetDPI = 160;
+const float ViewportArguments::deprecatedTargetDPI = 160;
-ViewportAttributes computeViewportAttributes(ViewportArguments args, int desktopWidth, int deviceWidth, int deviceHeight, int deviceDPI, IntSize visibleViewport)
+ViewportAttributes computeViewportAttributes(ViewportArguments args, int desktopWidth, int deviceWidth, int deviceHeight, float devicePixelRatio, IntSize visibleViewport)
{
ViewportAttributes result;
@@ -54,7 +52,7 @@ ViewportAttributes computeViewportAttributes(ViewportArguments args, int desktop
ASSERT(availableWidth > 0 && availableHeight > 0);
- result.devicePixelRatio = deviceDPI / targetDPI;
+ result.devicePixelRatio = devicePixelRatio;
// Resolve non-'auto' width and height to pixel values.
if (result.devicePixelRatio != 1.0) {
diff --git a/Source/WebCore/dom/ViewportArguments.h b/Source/WebCore/dom/ViewportArguments.h
index 707630592..94fb1fab8 100644
--- a/Source/WebCore/dom/ViewportArguments.h
+++ b/Source/WebCore/dom/ViewportArguments.h
@@ -72,10 +72,6 @@ struct ViewportArguments {
ValueDesktopWidth = -2,
ValueDeviceWidth = -3,
ValueDeviceHeight = -4,
- ValueDeviceDPI = -5,
- ValueLowDPI = -6,
- ValueMediumDPI = -7,
- ValueHighDPI = -8
};
ViewportArguments(Type type = Implicit)
@@ -112,9 +108,14 @@ struct ViewportArguments {
{
return !(*this == other);
}
+
+ // FIXME: We're going to keep this constant around until all embedders
+ // refactor their code to no longer need it.
+ static const float deprecatedTargetDPI;
};
-ViewportAttributes computeViewportAttributes(ViewportArguments args, int desktopWidth, int deviceWidth, int deviceHeight, int deviceDPI, IntSize visibleViewport);
+ViewportAttributes computeViewportAttributes(ViewportArguments args, int desktopWidth, int deviceWidth, int deviceHeight, float devicePixelRatio, IntSize visibleViewport);
+
void restrictMinimumScaleFactorToViewportSize(ViewportAttributes& result, IntSize visibleViewport);
void restrictScaleFactorToInitialScaleIfNotUserScalable(ViewportAttributes& result);
float computeMinimumScaleFactorForContentContained(const ViewportAttributes& result, const IntSize& viewportSize, const IntSize& contentSize);
diff --git a/Source/WebCore/dom/WebKitNamedFlow.cpp b/Source/WebCore/dom/WebKitNamedFlow.cpp
index 19e122922..0ffb703fd 100644
--- a/Source/WebCore/dom/WebKitNamedFlow.cpp
+++ b/Source/WebCore/dom/WebKitNamedFlow.cpp
@@ -56,7 +56,23 @@ bool WebKitNamedFlow::overset() const
return m_parentFlowThread->overset();
}
-PassRefPtr<NodeList> WebKitNamedFlow::getRegionsByContentNode(Node* contentNode)
+int WebKitNamedFlow::firstEmptyRegionIndex() const
+{
+ m_parentFlowThread->document()->updateLayoutIgnorePendingStylesheets();
+
+ const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
+ if (regionList.isEmpty())
+ return -1;
+ RenderRegionList::const_iterator iter = regionList.begin();
+ for (int index = 0; iter != regionList.end(); ++index, ++iter) {
+ const RenderRegion* renderRegion = *iter;
+ if (renderRegion->regionState() == RenderRegion::RegionEmpty)
+ return index;
+ }
+ return -1;
+}
+
+PassRefPtr<NodeList> WebKitNamedFlow::getRegionsByContent(Node* contentNode)
{
if (!contentNode)
return 0;
@@ -79,7 +95,7 @@ PassRefPtr<NodeList> WebKitNamedFlow::getRegionsByContentNode(Node* contentNode)
return StaticNodeList::adopt(regionNodes);
}
-PassRefPtr<NodeList> WebKitNamedFlow::contentNodes() const
+PassRefPtr<NodeList> WebKitNamedFlow::getContent()
{
m_parentFlowThread->document()->updateLayoutIgnorePendingStylesheets();
diff --git a/Source/WebCore/dom/WebKitNamedFlow.h b/Source/WebCore/dom/WebKitNamedFlow.h
index b81e5a4b0..f0c6a124c 100644
--- a/Source/WebCore/dom/WebKitNamedFlow.h
+++ b/Source/WebCore/dom/WebKitNamedFlow.h
@@ -51,8 +51,9 @@ public:
String name() const;
bool overset() const;
- PassRefPtr<NodeList> getRegionsByContentNode(Node*);
- PassRefPtr<NodeList> contentNodes() const;
+ int firstEmptyRegionIndex() const;
+ PassRefPtr<NodeList> getRegionsByContent(Node*);
+ PassRefPtr<NodeList> getContent();
private:
WebKitNamedFlow(RenderNamedFlowThread*);
diff --git a/Source/WebCore/dom/WebKitNamedFlow.idl b/Source/WebCore/dom/WebKitNamedFlow.idl
index 0da90e00c..f586a9d08 100644
--- a/Source/WebCore/dom/WebKitNamedFlow.idl
+++ b/Source/WebCore/dom/WebKitNamedFlow.idl
@@ -33,8 +33,9 @@ module core {
] WebKitNamedFlow {
readonly attribute DOMString name;
readonly attribute boolean overset;
- NodeList getRegionsByContentNode(in Node contentNode);
- readonly attribute NodeList contentNodes;
+ readonly attribute int firstEmptyRegionIndex;
+ NodeList getRegionsByContent(in Node contentNode);
+ NodeList getContent();
};
}