diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-11 13:45:28 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-11 13:45:28 +0200 |
commit | d6a599dbc9d824a462b2b206316e102bf8136446 (patch) | |
tree | ecb257a5e55b2239d74b90fdad62fccd661cf286 /Source/WebCore/dom | |
parent | 3ccc3a85f09a83557b391aae380d3bf5f81a2911 (diff) | |
download | qtwebkit-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')
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(); }; } |