diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-12 09:27:39 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-08-12 09:27:39 +0200 |
commit | 3749d61e1f7a59f5ec5067e560af1eb610c82015 (patch) | |
tree | 73dc228333948738bbe02976cacca8cd382bc978 /Source/WebCore/dom | |
parent | b32b4dcd9a51ab8de6afc53d9e17f8707e1f7a5e (diff) | |
download | qtwebkit-3749d61e1f7a59f5ec5067e560af1eb610c82015.tar.gz |
Imported WebKit commit a77350243e054f3460d1137301d8b3faee3d2052 (http://svn.webkit.org/repository/webkit/trunk@125365)
New snapshot with build fixes for latest API changes in Qt and all WK1 Win MSVC fixes upstream
Diffstat (limited to 'Source/WebCore/dom')
53 files changed, 1129 insertions, 413 deletions
diff --git a/Source/WebCore/dom/CharacterData.cpp b/Source/WebCore/dom/CharacterData.cpp index af1d8fed4..91f5ac70f 100644 --- a/Source/WebCore/dom/CharacterData.cpp +++ b/Source/WebCore/dom/CharacterData.cpp @@ -94,9 +94,9 @@ unsigned CharacterData::parserAppendData(const UChar* data, unsigned dataLength, void CharacterData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo<CharacterData> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); - info.visitBaseClass<Node>(this); - info.addString(m_data); + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + Node::reportMemoryUsage(memoryObjectInfo); + info.addMember(m_data); } void CharacterData::appendData(const String& data, ExceptionCode&) @@ -209,14 +209,16 @@ void CharacterData::dispatchModifiedEvent(const String& oldData) if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(this)) mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData)); #endif - if (parentNode()) - parentNode()->childrenChanged(); - if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) - dispatchScopedEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, 0, oldData, m_data)); - dispatchSubtreeModifiedEvent(); + if (!isInShadowTree()) { + if (parentNode()) + parentNode()->childrenChanged(); + if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER)) + dispatchScopedEvent(MutationEvent::create(eventNames().DOMCharacterDataModifiedEvent, true, 0, oldData, m_data)); + dispatchSubtreeModifiedEvent(); #if ENABLE(INSPECTOR) - InspectorInstrumentation::characterDataModified(document(), this); + InspectorInstrumentation::characterDataModified(document(), this); #endif + } } void CharacterData::checkCharDataOperation(unsigned offset, ExceptionCode& ec) diff --git a/Source/WebCore/dom/ContainerNode.cpp b/Source/WebCore/dom/ContainerNode.cpp index fd53a2fad..add53ce9a 100644 --- a/Source/WebCore/dom/ContainerNode.cpp +++ b/Source/WebCore/dom/ContainerNode.cpp @@ -60,6 +60,8 @@ static NodeCallbackQueue* s_postAttachCallbackQueue; static size_t s_attachDepth; static bool s_shouldReEnableMemoryCacheCallsAfterAttach; +ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0; + static void collectTargetNodes(Node* node, NodeVector& nodes) { if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) { @@ -271,11 +273,21 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce if (next && (next->previousSibling() == newChild || next == newChild)) // nothing to do return true; + // Does this one more time because removeChild() fires a MutationEvent. + checkReplaceChild(newChild.get(), oldChild, ec); + if (ec) + return false; + NodeVector targets; collectChildrenAndRemoveFromOldParent(newChild.get(), targets, ec); if (ec) return false; + // Does this yet another check because collectChildrenAndRemoveFromOldParent() fires a MutationEvent. + checkReplaceChild(newChild.get(), oldChild, ec); + if (ec) + return false; + InspectorInstrumentation::willInsertDOMNode(document(), this); // Add the new child(ren) @@ -685,22 +697,16 @@ void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int chil void ContainerNode::cloneChildNodes(ContainerNode *clone) { - // disable the delete button so it's elements are not serialized into the markup - bool isEditorEnabled = false; - if (document()->frame() && document()->frame()->editor()->canEdit()) { - FrameSelection* selection = document()->frame()->selection(); - Element* root = selection ? selection->rootEditableElement() : 0; - isEditorEnabled = root && isDescendantOf(root); + HTMLElement* deleteButtonContainerElement = 0; + if (Frame* frame = document()->frame()) + deleteButtonContainerElement = frame->editor()->deleteButtonController()->containerElement(); - if (isEditorEnabled) - document()->frame()->editor()->deleteButtonController()->disable(); - } - ExceptionCode ec = 0; - for (Node* n = firstChild(); n && !ec; n = n->nextSibling()) + for (Node* n = firstChild(); n && !ec; n = n->nextSibling()) { + if (n == deleteButtonContainerElement) + continue; clone->appendChild(n->cloneNode(true), ec); - if (isEditorEnabled && document()->frame()) - document()->frame()->editor()->deleteButtonController()->enable(); + } } bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const diff --git a/Source/WebCore/dom/ContainerNode.h b/Source/WebCore/dom/ContainerNode.h index 9abaf2373..c19ae0bec 100644 --- a/Source/WebCore/dom/ContainerNode.h +++ b/Source/WebCore/dom/ContainerNode.h @@ -27,6 +27,9 @@ #include "ExceptionCodePlaceholder.h" #include "Node.h" +#include <wtf/OwnPtr.h> +#include <wtf/Vector.h> + namespace WebCore { class FloatPoint; @@ -101,8 +104,8 @@ public: virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo<ContainerNode> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); - info.visitBaseClass<Node>(this); + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + Node::reportMemoryUsage(memoryObjectInfo); info.addInstrumentedMember(m_firstChild); info.addInstrumentedMember(m_lastChild); } @@ -298,6 +301,71 @@ inline void getChildNodes(Node* node, NodeVector& nodes) nodes.append(child); } +class ChildNodesLazySnapshot { + WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot); + WTF_MAKE_FAST_ALLOCATED; +public: + explicit ChildNodesLazySnapshot(Node* parentNode) + : m_currentNode(parentNode->firstChild()) + , m_currentIndex(0) + { + m_nextSnapshot = latestSnapshot; + latestSnapshot = this; + } + + ~ChildNodesLazySnapshot() + { + latestSnapshot = m_nextSnapshot; + } + + // Returns 0 if there is no next Node. + Node* nextNode() + { + if (LIKELY(!hasSnapshot())) { + Node* node = m_currentNode; + if (m_currentNode) + m_currentNode = m_currentNode->nextSibling(); + return node; + } + Vector<RefPtr<Node> >* nodeVector = m_childNodes.get(); + if (m_currentIndex >= nodeVector->size()) + return 0; + return (*nodeVector)[m_currentIndex++].get(); + } + + void takeSnapshot() + { + if (hasSnapshot()) + return; + m_childNodes = adoptPtr(new Vector<RefPtr<Node> >()); + Node* node = m_currentNode; + while (node) { + m_childNodes->append(node); + node = node->nextSibling(); + } + } + + ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; } + bool hasSnapshot() { return !!m_childNodes.get(); } + + static void takeChildNodesLazySnapshot() + { + ChildNodesLazySnapshot* snapshot = latestSnapshot; + while (snapshot && !snapshot->hasSnapshot()) { + snapshot->takeSnapshot(); + snapshot = snapshot->nextSnapshot(); + } + } + +private: + static ChildNodesLazySnapshot* latestSnapshot; + + Node* m_currentNode; + unsigned m_currentIndex; + OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated. + ChildNodesLazySnapshot* m_nextSnapshot; +}; + } // namespace WebCore #endif // ContainerNode_h diff --git a/Source/WebCore/dom/ContainerNodeAlgorithms.cpp b/Source/WebCore/dom/ContainerNodeAlgorithms.cpp index c8959dfb8..2edea30e0 100644 --- a/Source/WebCore/dom/ContainerNodeAlgorithms.cpp +++ b/Source/WebCore/dom/ContainerNodeAlgorithms.cpp @@ -34,16 +34,15 @@ namespace WebCore { void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerNode* node) { - NodeVector children; - getChildNodes(node, children); - for (size_t i = 0; i < children.size(); ++i) { + ChildNodesLazySnapshot snapshot(node); + while (Node* child = snapshot.nextNode()) { // If we have been removed from the document during this loop, then // we don't want to tell the rest of our children that they've been // inserted into the document because they haven't. - if (node->inDocument() && children[i]->parentNode() == node) - notifyNodeInsertedIntoDocument(children[i].get()); + if (node->inDocument() && child->parentNode() == node) + notifyNodeInsertedIntoDocument(child); } - + if (!node->isElementNode()) return; @@ -67,14 +66,13 @@ void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(ContainerNode* void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode* node) { - NodeVector children; - getChildNodes(node, children); - for (size_t i = 0; i < children.size(); ++i) { + ChildNodesLazySnapshot snapshot(node); + while (Node* child = snapshot.nextNode()) { // If we have been added to the document during this loop, then we // don't want to tell the rest of our children that they've been // removed from the document because they haven't. - if (!node->inDocument() && children[i]->parentNode() == node) - notifyNodeRemovedFromDocument(children[i].get()); + if (!node->inDocument() && child->parentNode() == node) + notifyNodeRemovedFromDocument(child); } if (!node->isElementNode()) diff --git a/Source/WebCore/dom/DeviceOrientationController.cpp b/Source/WebCore/dom/DeviceOrientationController.cpp index 0d002c1e2..302db6124 100644 --- a/Source/WebCore/dom/DeviceOrientationController.cpp +++ b/Source/WebCore/dom/DeviceOrientationController.cpp @@ -29,11 +29,13 @@ #include "DeviceOrientationClient.h" #include "DeviceOrientationData.h" #include "DeviceOrientationEvent.h" +#include "InspectorInstrumentation.h" namespace WebCore { -DeviceOrientationController::DeviceOrientationController(DeviceOrientationClient* client) +DeviceOrientationController::DeviceOrientationController(Page* page, DeviceOrientationClient* client) : m_client(client) + , m_page(page) , m_timer(this, &DeviceOrientationController::timerFired) { ASSERT(m_client); @@ -45,9 +47,9 @@ DeviceOrientationController::~DeviceOrientationController() m_client->deviceOrientationControllerDestroyed(); } -PassOwnPtr<DeviceOrientationController> DeviceOrientationController::create(DeviceOrientationClient* client) +PassOwnPtr<DeviceOrientationController> DeviceOrientationController::create(Page* page, DeviceOrientationClient* client) { - return adoptPtr(new DeviceOrientationController(client)); + return adoptPtr(new DeviceOrientationController(page, client)); } void DeviceOrientationController::timerFired(Timer<DeviceOrientationController>* timer) @@ -129,6 +131,7 @@ void DeviceOrientationController::resumeEventsForAllListeners(DOMWindow* window) void DeviceOrientationController::didChangeDeviceOrientation(DeviceOrientationData* orientation) { + orientation = InspectorInstrumentation::overrideDeviceOrientation(m_page, orientation); RefPtr<DeviceOrientationEvent> event = DeviceOrientationEvent::create(eventNames().deviceorientationEvent, orientation); Vector<RefPtr<DOMWindow> > listenersVector; copyToVector(m_listeners, listenersVector); @@ -151,7 +154,7 @@ bool DeviceOrientationController::isActiveAt(Page* page) void provideDeviceOrientationTo(Page* page, DeviceOrientationClient* client) { - DeviceOrientationController::provideTo(page, DeviceOrientationController::supplementName(), DeviceOrientationController::create(client)); + DeviceOrientationController::provideTo(page, DeviceOrientationController::supplementName(), DeviceOrientationController::create(page, client)); } } // namespace WebCore diff --git a/Source/WebCore/dom/DeviceOrientationController.h b/Source/WebCore/dom/DeviceOrientationController.h index bfe451745..f5e6f9503 100644 --- a/Source/WebCore/dom/DeviceOrientationController.h +++ b/Source/WebCore/dom/DeviceOrientationController.h @@ -41,7 +41,7 @@ class DeviceOrientationController : public Supplement<Page> { public: ~DeviceOrientationController(); - static PassOwnPtr<DeviceOrientationController> create(DeviceOrientationClient*); + static PassOwnPtr<DeviceOrientationController> create(Page*, DeviceOrientationClient*); void addListener(DOMWindow*); void removeListener(DOMWindow*); @@ -61,11 +61,12 @@ public: static bool isActiveAt(Page*); private: - explicit DeviceOrientationController(DeviceOrientationClient*); + explicit DeviceOrientationController(Page*, DeviceOrientationClient*); void timerFired(Timer<DeviceOrientationController>*); DeviceOrientationClient* m_client; + Page* m_page; typedef HashCountedSet<RefPtr<DOMWindow> > ListenersCountedSet; ListenersCountedSet m_listeners; ListenersCountedSet m_suspendedListeners; diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 169d8a5a0..f4304c607 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -51,9 +51,7 @@ #include "DOMWindow.h" #include "DateComponents.h" #include "DeviceMotionController.h" -#include "DeviceMotionEvent.h" #include "DeviceOrientationController.h" -#include "DeviceOrientationEvent.h" #include "DocumentEventQueue.h" #include "DocumentFragment.h" #include "DocumentLoader.h" @@ -454,7 +452,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML) , m_hasXMLDeclaration(0) , m_savedRenderer(0) , m_designMode(inherit) -#if ENABLE(DASHBOARD_SUPPORT) +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) , m_hasDashboardRegions(false) , m_dashboardRegionsDirty(false) #endif @@ -2045,6 +2043,7 @@ void Document::setIsViewSource(bool isViewSource) return; setSecurityOrigin(SecurityOrigin::createUnique()); + didUpdateSecurityOrigin(); } void Document::combineCSSFeatureFlags() @@ -3714,7 +3713,7 @@ void Document::activeChainNodeDetached(Node* node) m_activeNode = m_activeNode->parentNode(); } -#if ENABLE(DASHBOARD_SUPPORT) +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) const Vector<DashboardRegionValue>& Document::dashboardRegions() const { return m_dashboardRegions; @@ -4148,8 +4147,6 @@ void Document::addListenerTypeIfNeeded(const AtomicString& eventType) #endif else if (eventType == eventNames().scrollEvent) addListenerType(SCROLL_LISTENER); - else if (eventType == eventNames().webkitRegionLayoutUpdateEvent) - addListenerType(REGIONLAYOUTUPDATE_LISTENER); } CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&) @@ -5018,6 +5015,8 @@ void Document::initSecurityContext() securityOrigin()->enforceFilePathSeparation(); } } + if (settings->thirdPartyStorageBlockingEnabled()) + securityOrigin()->blockThirdPartyStorage(); } Document* parentDocument = ownerElement() ? ownerElement()->document() : 0; @@ -5063,8 +5062,9 @@ void Document::initSecurityContext() void Document::initContentSecurityPolicy() { - if (!m_frame->tree()->parent() || !shouldInheritSecurityOriginFromOwner(m_url)) + if (!m_frame->tree()->parent() || (!shouldInheritSecurityOriginFromOwner(m_url) && !isPluginDocument())) return; + contentSecurityPolicy()->copyStateFrom(m_frame->tree()->parent()->document()->contentSecurityPolicy()); } @@ -5615,7 +5615,7 @@ void Document::webkitWillEnterFullScreenForElement(Element* element) } if (m_fullScreenElement != documentElement()) - RenderFullScreen::wrapRenderer(renderer, this); + RenderFullScreen::wrapRenderer(renderer, renderer ? renderer->parent() : 0, this); m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true); @@ -5829,8 +5829,13 @@ void Document::addDocumentToFullScreenChangeEventQueue(Document* doc) #if ENABLE(POINTER_LOCK) void Document::webkitExitPointerLock() { - if (page()) - page()->pointerLockController()->requestPointerUnlock(); + if (!page()) + return; + if (Element* target = page()->pointerLockController()->element()) { + if (target->document() != this) + return; + } + page()->pointerLockController()->requestPointerUnlock(); } Element* Document::webkitPointerLockElement() const @@ -6016,7 +6021,7 @@ DocumentLoader* Document::loader() const PassRefPtr<NodeList> Document::getItems(const String& typeNames) { // Since documet.getItem() is allowed for microdata, typeNames will be null string. - // In this case we need to create an unique string identifier to map such request in the cache. + // In this case we need to create an empty string identifier to map such request in the cache. String localTypeNames = typeNames.isNull() ? MicroDataItemList::undefinedItemType() : typeNames; return ensureRareData()->ensureNodeLists()->addCacheWithName<MicroDataItemList>(this, DynamicNodeList::MicroDataItemListType, localTypeNames); @@ -6087,26 +6092,36 @@ void Document::setContextFeatures(PassRefPtr<ContextFeatures> features) void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo<Document> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); info.addInstrumentedMember(m_styleResolver); - info.visitBaseClass<ContainerNode>(this); + ContainerNode::reportMemoryUsage(memoryObjectInfo); info.addVector(m_customFonts); - info.addString(m_documentURI); - info.addString(m_baseTarget); + info.addMember(m_url); + info.addMember(m_baseURL); + info.addMember(m_baseURLOverride); + info.addMember(m_baseElementURL); + info.addMember(m_cookieURL); + info.addMember(m_firstPartyForCookies); + info.addMember(m_documentURI); + info.addMember(m_baseTarget); + info.addInstrumentedMember(m_frame); + info.addInstrumentedMember(m_cachedResourceLoader); + info.addInstrumentedMember(m_elemSheet); + info.addInstrumentedMember(m_pageUserSheet); if (m_pageGroupUserSheets) - info.addVector(*m_pageGroupUserSheets.get()); + info.addInstrumentedVectorPtr(m_pageGroupUserSheets); if (m_userSheets) - info.addVector(*m_userSheets.get()); + info.addInstrumentedVectorPtr(m_userSheets); info.addHashSet(m_nodeIterators); info.addHashSet(m_ranges); info.addListHashSet(m_styleSheetCandidateNodes); - info.addString(m_preferredStylesheetSet); - info.addString(m_selectedStylesheetSet); - info.addString(m_title.string()); - info.addString(m_rawTitle.string()); - info.addString(m_xmlEncoding); - info.addString(m_xmlVersion); - info.addString(m_contentLanguage); + info.addMember(m_preferredStylesheetSet); + info.addMember(m_selectedStylesheetSet); + info.addMember(m_title.string()); + info.addMember(m_rawTitle.string()); + info.addMember(m_xmlEncoding); + info.addMember(m_xmlVersion); + info.addMember(m_contentLanguage); info.addHashMap(m_documentNamedItemCollections); info.addHashMap(m_windowNamedItemCollections); #if ENABLE(DASHBOARD_SUPPORT) @@ -6118,6 +6133,7 @@ void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const info.addHashSet(m_mediaVolumeCallbackElements); info.addHashSet(m_privateBrowsingStateChangedElements); info.addHashMap(m_elementsByAccessKey); + info.addInstrumentedMember(m_eventQueue); info.addHashSet(m_mediaCanStartListeners); info.addVector(m_pendingTasks); } diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h index 017eb8c85..c6767f864 100644 --- a/Source/WebCore/dom/Document.h +++ b/Source/WebCore/dom/Document.h @@ -153,7 +153,7 @@ class SVGDocumentExtensions; class TransformSource; #endif -#if ENABLE(DASHBOARD_SUPPORT) +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) struct DashboardRegionValue; #endif @@ -794,8 +794,7 @@ public: TRANSITIONEND_LISTENER = 0x800, BEFORELOAD_LISTENER = 0x1000, TOUCH_LISTENER = 0x2000, - SCROLL_LISTENER = 0x4000, - REGIONLAYOUTUPDATE_LISTENER = 0x8000 + SCROLL_LISTENER = 0x4000 }; bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); } @@ -1019,7 +1018,7 @@ public: void setFrameElementsShouldIgnoreScrolling(bool ignore) { m_frameElementsShouldIgnoreScrolling = ignore; } bool frameElementsShouldIgnoreScrolling() const { return m_frameElementsShouldIgnoreScrolling; } -#if ENABLE(DASHBOARD_SUPPORT) +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) void setDashboardRegionsDirty(bool f) { m_dashboardRegionsDirty = f; } bool dashboardRegionsDirty() const { return m_dashboardRegionsDirty; } bool hasDashboardRegions () const { return m_hasDashboardRegions; } @@ -1448,7 +1447,7 @@ private: OwnPtr<SVGDocumentExtensions> m_svgExtensions; #endif -#if ENABLE(DASHBOARD_SUPPORT) +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) Vector<DashboardRegionValue> m_dashboardRegions; bool m_hasDashboardRegions; bool m_dashboardRegionsDirty; diff --git a/Source/WebCore/dom/Document.idl b/Source/WebCore/dom/Document.idl index 742381f2a..b83f40c99 100644 --- a/Source/WebCore/dom/Document.idl +++ b/Source/WebCore/dom/Document.idl @@ -75,7 +75,7 @@ module core { Node adoptNode(in [Optional=DefaultIsUndefined] Node source) raises (DOMException); -#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C +#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C || defined(LANGUAGE_GOBJECT) && LANGUAGE_GOBJECT // document.documentURI was writable in DOM3 Core, but is read-only in DOM4 // (see http://www.w3.org/TR/2011/WD-dom-20110915/#document). We need to keep // the writable version around for Objective C clients, but are moving to diff --git a/Source/WebCore/dom/DocumentEventQueue.cpp b/Source/WebCore/dom/DocumentEventQueue.cpp index 549408252..f9a717e40 100644 --- a/Source/WebCore/dom/DocumentEventQueue.cpp +++ b/Source/WebCore/dom/DocumentEventQueue.cpp @@ -31,6 +31,7 @@ #include "Document.h" #include "Event.h" #include "EventNames.h" +#include "MemoryInstrumentation.h" #include "RuntimeApplicationChecks.h" #include "ScriptExecutionContext.h" #include "SuspendableTimer.h" @@ -107,6 +108,14 @@ void DocumentEventQueue::enqueueOrDispatchScrollEvent(PassRefPtr<Node> target, S enqueueEvent(scrollEvent.release()); } +void DocumentEventQueue::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addMember(m_pendingEventTimer); + info.addInstrumentedHashSet(m_queuedEvents); + info.addInstrumentedHashSet(m_nodesWithQueuedScrollEvents); +} + bool DocumentEventQueue::cancelEvent(Event* event) { bool found = m_queuedEvents.contains(event); diff --git a/Source/WebCore/dom/DocumentEventQueue.h b/Source/WebCore/dom/DocumentEventQueue.h index 1f7e0dd96..14157b151 100644 --- a/Source/WebCore/dom/DocumentEventQueue.h +++ b/Source/WebCore/dom/DocumentEventQueue.h @@ -38,6 +38,7 @@ namespace WebCore { class Event; class DocumentEventQueueTimer; +class MemoryObjectInfo; class Node; class ScriptExecutionContext; @@ -58,6 +59,8 @@ public: void enqueueOrDispatchScrollEvent(PassRefPtr<Node>, ScrollEventTargetType); + void reportMemoryUsage(MemoryObjectInfo*) const; + private: explicit DocumentEventQueue(ScriptExecutionContext*); diff --git a/Source/WebCore/dom/DynamicNodeList.cpp b/Source/WebCore/dom/DynamicNodeList.cpp index b6a87d41b..b6a3a6fcd 100644 --- a/Source/WebCore/dom/DynamicNodeList.cpp +++ b/Source/WebCore/dom/DynamicNodeList.cpp @@ -33,19 +33,20 @@ namespace WebCore { Node* DynamicNodeListCacheBase::rootNode() const { - if ((isRootedAtDocument() || ownerNodeHasItemRefAttribute()) && m_ownerNode->inDocument()) + if (isRootedAtDocument() && m_ownerNode->inDocument()) return m_ownerNode->document(); - return m_ownerNode.get(); -} -ALWAYS_INLINE bool DynamicNodeListCacheBase::ownerNodeHasItemRefAttribute() const -{ -#if ENABLE(MICRODATA) - if (m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr) - return toElement(ownerNode())->fastHasAttribute(HTMLNames::itemrefAttr); -#endif + if (ownerNodeHasItemRefAttribute()) { + if (m_ownerNode->inDocument()) + return m_ownerNode->document(); + + Node* root = m_ownerNode.get(); + while (Node* parent = root->parentNode()) + root = parent; + return root; + } - return false; + return m_ownerNode.get(); } void DynamicNodeListCacheBase::invalidateCache() const diff --git a/Source/WebCore/dom/DynamicNodeList.h b/Source/WebCore/dom/DynamicNodeList.h index 860e2269a..3ba692df9 100644 --- a/Source/WebCore/dom/DynamicNodeList.h +++ b/Source/WebCore/dom/DynamicNodeList.h @@ -26,6 +26,7 @@ #include "CollectionType.h" #include "Document.h" +#include "Element.h" #include "HTMLNames.h" #include "NodeList.h" #include <wtf/Forward.h> @@ -33,9 +34,6 @@ namespace WebCore { -class Element; -class Node; - enum NodeListRootType { NodeListIsRootedAtNode, NodeListIsRootedAtDocument, @@ -70,7 +68,7 @@ public: } public: - ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument; } + ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument || m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr; } ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); } ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); } Node* ownerNode() const { return m_ownerNode.get(); } @@ -166,7 +164,8 @@ ALWAYS_INLINE bool DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChan return attrName == HTMLNames::hrefAttr; case InvalidateOnItemAttrChange: #if ENABLE(MICRODATA) - return attrName == HTMLNames::itemscopeAttr || attrName == HTMLNames::itempropAttr || attrName == HTMLNames::itemtypeAttr || attrName == HTMLNames::itemrefAttr; + return attrName == HTMLNames::itemscopeAttr || attrName == HTMLNames::itempropAttr + || attrName == HTMLNames::itemtypeAttr || attrName == HTMLNames::itemrefAttr || attrName == HTMLNames::idAttr; #endif // Intentionally fall through case DoNotInvalidateOnAttributeChanges: return false; @@ -176,6 +175,16 @@ ALWAYS_INLINE bool DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChan return false; } +ALWAYS_INLINE bool DynamicNodeListCacheBase::ownerNodeHasItemRefAttribute() const +{ +#if ENABLE(MICRODATA) + if (m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr) + return toElement(ownerNode())->fastHasAttribute(HTMLNames::itemrefAttr); +#endif + + return false; +} + class DynamicNodeList : public NodeList, public DynamicNodeListCacheBase { public: enum NodeListType { diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index c323fa10d..287780268 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -416,12 +416,8 @@ int Element::clientLeft() { document()->updateLayoutIgnorePendingStylesheets(); - if (RenderBox* renderer = renderBox()) { - LayoutUnit clientLeft = renderer->clientLeft(); - if (renderer->style() && renderer->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) - clientLeft += renderer->verticalScrollbarWidth(); - return adjustForAbsoluteZoom(roundToInt(clientLeft), renderer); - } + if (RenderBox* renderer = renderBox()) + return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer); return 0; } @@ -656,31 +652,36 @@ void Element::setAttribute(const AtomicString& name, const AtomicString& value, size_t index = ensureUpdatedAttributeData()->getAttributeItemIndex(localName, false); const QualifiedName& qName = index != notFound ? attributeItem(index)->name() : QualifiedName(nullAtom, localName, nullAtom); - setAttributeInternal(index, qName, value, NotInUpdateStyleAttribute); + setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute); +} + +void Element::setAttribute(const QualifiedName& name, const AtomicString& value) +{ + setAttributeInternal(ensureUpdatedAttributeData()->getAttributeItemIndex(name), name, value, NotInSynchronizationOfLazyAttribute); } -void Element::setAttribute(const QualifiedName& name, const AtomicString& value, EInUpdateStyleAttribute inUpdateStyleAttribute) +void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value) { - setAttributeInternal(ensureUpdatedAttributeData()->getAttributeItemIndex(name), name, value, inUpdateStyleAttribute); + setAttributeInternal(mutableAttributeData()->getAttributeItemIndex(name), name, value, InSynchronizationOfLazyAttribute); } -inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& value, EInUpdateStyleAttribute inUpdateStyleAttribute) +inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute) { ElementAttributeData* attributeData = mutableAttributeData(); Attribute* old = index != notFound ? attributeData->attributeItem(index) : 0; if (value.isNull()) { if (old) - attributeData->removeAttribute(index, this, inUpdateStyleAttribute); + attributeData->removeAttribute(index, this, inSynchronizationOfLazyAttribute); return; } if (!old) { - attributeData->addAttribute(Attribute(name, value), this, inUpdateStyleAttribute); + attributeData->addAttribute(Attribute(name, value), this, inSynchronizationOfLazyAttribute); return; } - if (inUpdateStyleAttribute == NotInUpdateStyleAttribute) + if (inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) willModifyAttribute(name, old->value(), value); if (RefPtr<Attr> attrNode = attrIfExists(name)) @@ -688,7 +689,7 @@ inline void Element::setAttributeInternal(size_t index, const QualifiedName& nam else old->setValue(value); - if (inUpdateStyleAttribute == NotInUpdateStyleAttribute) + if (inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) didModifyAttribute(Attribute(old->name(), old->value())); } @@ -755,9 +756,11 @@ static bool isEventHandlerAttribute(const QualifiedName& name) return name.namespaceURI().isNull() && name.localName().startsWith("on"); } +// FIXME: Share code with Element::isURLAttribute. static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& value) -{ - return (name.localName().endsWith(hrefAttr.localName()) || name == srcAttr || name == actionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value)); +{ + return (name.localName() == hrefAttr.localName() || name.localName() == nohrefAttr.localName() + || name == srcAttr || name == actionAttr || name == formactionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value)); } void Element::parserSetAttributes(const Vector<Attribute>& attributeVector, FragmentScriptingPermission scriptingPermission) @@ -1202,14 +1205,6 @@ ShadowRoot* Element::userAgentShadowRoot() const return 0; } -ShadowRoot* Element::ensureShadowRoot() -{ - if (ElementShadow* shadow = this->shadow()) - return shadow->oldestShadowRoot(); - - return ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot).get(); -} - const AtomicString& Element::shadowPseudoId() const { return hasRareData() ? elementRareData()->m_shadowPseudoId : nullAtom; @@ -1495,12 +1490,12 @@ void Element::removeAttribute(size_t index) mutableAttributeData()->removeAttribute(index, this); } -void Element::removeAttribute(const String& name) +void Element::removeAttribute(const AtomicString& name) { if (!attributeData()) return; - String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; + AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; size_t index = attributeData()->getAttributeItemIndex(localName, false); if (index == notFound) return; @@ -1508,12 +1503,12 @@ void Element::removeAttribute(const String& name) mutableAttributeData()->removeAttribute(index, this); } -void Element::removeAttributeNS(const String& namespaceURI, const String& localName) +void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) { removeAttribute(QualifiedName(nullAtom, localName, namespaceURI)); } -PassRefPtr<Attr> Element::getAttributeNode(const String& name) +PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& name) { const ElementAttributeData* attributeData = updatedAttributeData(); if (!attributeData) @@ -1521,7 +1516,7 @@ PassRefPtr<Attr> Element::getAttributeNode(const String& name) return attributeData->getAttributeNode(name, shouldIgnoreAttributeCase(this), this); } -PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName) +PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName) { const ElementAttributeData* attributeData = updatedAttributeData(); if (!attributeData) @@ -1529,18 +1524,18 @@ PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const S return attributeData->getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), this); } -bool Element::hasAttribute(const String& name) const +bool Element::hasAttribute(const AtomicString& name) const { if (!attributeData()) return false; // This call to String::lower() seems to be required but // there may be a way to remove it. - String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; + AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; return updatedAttributeData()->getAttributeItem(localName, false); } -bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const +bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const { const ElementAttributeData* attributeData = updatedAttributeData(); if (!attributeData) @@ -1783,6 +1778,16 @@ unsigned Element::childElementCount() const return count; } +bool Element::shouldMatchReadOnlySelector() const +{ + return false; +} + +bool Element::shouldMatchReadWriteSelector() const +{ + return false; +} + bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec) { if (selector.isEmpty()) { @@ -1917,7 +1922,7 @@ void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(boo void Element::webkitRequestPointerLock() { if (document()->page()) - document()->page()->pointerLockController()->requestPointerLock(this, 0, 0); + document()->page()->pointerLockController()->requestPointerLock(this); } #endif @@ -1972,30 +1977,40 @@ PassRefPtr<WebKitAnimationList> Element::webkitGetAnimations() const return animController->animationsForRenderer(renderer()); } -const AtomicString& Element::webkitRegionOverflow() const +RenderRegion* Element::renderRegion() const +{ + if (renderer() && renderer()->isRenderRegion()) + return toRenderRegion(renderer()); + + return 0; +} + +const AtomicString& Element::webkitRegionOverset() const { document()->updateLayoutIgnorePendingStylesheets(); - if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) { - RenderRegion* region = toRenderRegion(renderer()); - switch (region->regionState()) { - case RenderRegion::RegionFit: { - DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit")); - return fitState; - } - case RenderRegion::RegionEmpty: { - DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty")); - return emptyState; - } - case RenderRegion::RegionOverflow: { - DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overflow")); - return overflowState; - } - default: - break; - } - } DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined")); + if (!document()->cssRegionsEnabled() || !renderRegion()) + return undefinedState; + + switch (renderRegion()->regionState()) { + case RenderRegion::RegionFit: { + DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit")); + return fitState; + } + case RenderRegion::RegionEmpty: { + DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty")); + return emptyState; + } + case RenderRegion::RegionOverset: { + DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset")); + return overflowState; + } + case RenderRegion::RegionUndefined: + return undefinedState; + } + + ASSERT_NOT_REACHED(); return undefinedState; } diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h index 01590217c..d056a9d43 100644 --- a/Source/WebCore/dom/Element.h +++ b/Source/WebCore/dom/Element.h @@ -40,9 +40,10 @@ class ClientRectList; class DOMStringMap; class DOMTokenList; class ElementRareData; +class ElementShadow; class IntSize; +class RenderRegion; class ShadowRoot; -class ElementShadow; class WebKitAnimationList; enum SpellcheckAttributeState { @@ -113,7 +114,8 @@ public: bool hasAttribute(const QualifiedName&) const; const AtomicString& getAttribute(const QualifiedName&) const; - void setAttribute(const QualifiedName&, const AtomicString& value, EInUpdateStyleAttribute = NotInUpdateStyleAttribute); + void setAttribute(const QualifiedName&, const AtomicString& value); + void setSynchronizedLazyAttribute(const QualifiedName&, const AtomicString& value); void removeAttribute(const QualifiedName&); void removeAttribute(size_t index); @@ -139,8 +141,8 @@ public: // in style attribute or one of the SVG animation attributes. bool hasAttributesWithoutUpdate() const; - bool hasAttribute(const String& name) const; - bool hasAttributeNS(const String& namespaceURI, const String& localName) const; + bool hasAttribute(const AtomicString& name) const; + bool hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const; const AtomicString& getAttribute(const AtomicString& name) const; const AtomicString& getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const; @@ -199,13 +201,13 @@ public: // Returns the absolute bounding box translated into screen coordinates: IntRect screenRect() const; - void removeAttribute(const String& name); - void removeAttributeNS(const String& namespaceURI, const String& localName); + void removeAttribute(const AtomicString& name); + void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName); PassRefPtr<Attr> detachAttribute(size_t index); - PassRefPtr<Attr> getAttributeNode(const String& name); - PassRefPtr<Attr> getAttributeNodeNS(const String& namespaceURI, const String& localName); + PassRefPtr<Attr> getAttributeNode(const AtomicString& name); + PassRefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName); PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionCode&); PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionCode&); PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionCode&); @@ -275,10 +277,6 @@ public: ShadowRoot* userAgentShadowRoot() const; - // FIXME: Remove Element::ensureShadowRoot - // https://bugs.webkit.org/show_bug.cgi?id=77608 - ShadowRoot* ensureShadowRoot(); - virtual const AtomicString& shadowPseudoId() const; void setShadowPseudoId(const AtomicString&, ExceptionCode& = ASSERT_NO_EXCEPTION); @@ -350,6 +348,8 @@ public: Element* nextElementSibling() const; unsigned childElementCount() const; + virtual bool shouldMatchReadOnlySelector() const; + virtual bool shouldMatchReadWriteSelector() const; bool webkitMatchesSelector(const String& selectors, ExceptionCode&); DOMTokenList* classList(); @@ -373,7 +373,6 @@ public: virtual bool isFormControlElement() const { return false; } virtual bool isEnabledFormControl() const { return true; } - virtual bool isReadOnlyFormControl() const { return false; } virtual bool isSpinButtonElement() const { return false; } virtual bool isTextFormControl() const { return false; } virtual bool isOptionalFormControl() const { return false; } @@ -424,7 +423,8 @@ public: PassRefPtr<RenderStyle> styleForRenderer(); - const AtomicString& webkitRegionOverflow() const; + RenderRegion* renderRegion() const; + const AtomicString& webkitRegionOverset() const; bool hasID() const; bool hasClass() const; @@ -434,10 +434,10 @@ public: virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo<Element> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); - info.visitBaseClass<ContainerNode>(this); + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + ContainerNode::reportMemoryUsage(memoryObjectInfo); info.addInstrumentedMember(m_tagName); - info.addInstrumentedMember(attributeData()); + info.addInstrumentedMember(m_attributeData); } #if ENABLE(UNDO_MANAGER) @@ -478,7 +478,7 @@ private: virtual NodeType nodeType() const; virtual bool childTypeAllowed(NodeType) const; - void setAttributeInternal(size_t index, const QualifiedName&, const AtomicString& value, EInUpdateStyleAttribute); + void setAttributeInternal(size_t index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute); #ifndef NDEBUG virtual void formatForDebugger(char* buffer, unsigned length) const; diff --git a/Source/WebCore/dom/Element.idl b/Source/WebCore/dom/Element.idl index 17a4a7ec4..3bdd03bef 100644 --- a/Source/WebCore/dom/Element.idl +++ b/Source/WebCore/dom/Element.idl @@ -96,6 +96,9 @@ module core { // HTML 5 NodeList getElementsByClassName(in [Optional=DefaultIsUndefined] DOMString name); + attribute [Reflect=class] DOMString className; + readonly attribute DOMTokenList classList; + #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT readonly attribute DOMStringMap dataset; #endif @@ -140,7 +143,7 @@ module core { [Conditional=POINTER_LOCK, V8EnabledAtRuntime=pointerLock] void webkitRequestPointerLock(); // CSS Regions API - readonly attribute DOMString webkitRegionOverflow; + readonly attribute DOMString webkitRegionOverset; #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT readonly attribute [Conditional=UNDO_MANAGER] UndoManager undoManager; diff --git a/Source/WebCore/dom/ElementAttributeData.cpp b/Source/WebCore/dom/ElementAttributeData.cpp index 6fb53d5d3..bddc6e027 100644 --- a/Source/WebCore/dom/ElementAttributeData.cpp +++ b/Source/WebCore/dom/ElementAttributeData.cpp @@ -28,6 +28,7 @@ #include "Attr.h" #include "CSSStyleSheet.h" +#include "MemoryInstrumentation.h" #include "StyledElement.h" namespace WebCore { @@ -217,20 +218,20 @@ void ElementAttributeData::destroyInlineStyle(StyledElement* element) const m_inlineStyleDecl = 0; } -void ElementAttributeData::addAttribute(const Attribute& attribute, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute) +void ElementAttributeData::addAttribute(const Attribute& attribute, Element* element, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute) { ASSERT(isMutable()); - if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute) + if (element && inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) element->willModifyAttribute(attribute.name(), nullAtom, attribute.value()); m_mutableAttributeVector->append(attribute); - if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute) + if (element && inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) element->didAddAttribute(attribute); } -void ElementAttributeData::removeAttribute(size_t index, Element* element, EInUpdateStyleAttribute inUpdateStyleAttribute) +void ElementAttributeData::removeAttribute(size_t index, Element* element, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute) { ASSERT(isMutable()); ASSERT(index < length()); @@ -238,7 +239,7 @@ void ElementAttributeData::removeAttribute(size_t index, Element* element, EInUp Attribute& attribute = m_mutableAttributeVector->at(index); QualifiedName name = attribute.name(); - if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute) + if (element && inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) element->willRemoveAttribute(name, attribute.value()); if (RefPtr<Attr> attr = attrIfExists(element, name)) @@ -246,7 +247,7 @@ void ElementAttributeData::removeAttribute(size_t index, Element* element, EInUp m_mutableAttributeVector->remove(index); - if (element && inUpdateStyleAttribute == NotInUpdateStyleAttribute) + if (element && inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) element->didRemoveAttribute(name); } @@ -283,6 +284,19 @@ void ElementAttributeData::detachAttrObjectsFromElement(Element* element) const ASSERT(!element->hasAttrList()); } +void ElementAttributeData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addInstrumentedMember(m_inlineStyleDecl); + info.addInstrumentedMember(m_attributeStyle); + info.addMember(m_classNames); + info.addMember(m_idForStyleResolution); + if (m_isMutable) + info.addVectorPtr(m_mutableAttributeVector); + else + info.addRawBuffer(m_attributes, m_arraySize * sizeof(Attribute)); +} + size_t ElementAttributeData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const { // Continue to checking case-insensitively and/or full namespaced names if necessary: diff --git a/Source/WebCore/dom/ElementAttributeData.h b/Source/WebCore/dom/ElementAttributeData.h index 1c2b2fea3..691f7332c 100644 --- a/Source/WebCore/dom/ElementAttributeData.h +++ b/Source/WebCore/dom/ElementAttributeData.h @@ -27,7 +27,6 @@ #define ElementAttributeData_h #include "Attribute.h" -#include "MemoryInstrumentation.h" #include "SpaceSplitString.h" #include "StylePropertySet.h" #include <wtf/NotFound.h> @@ -36,8 +35,9 @@ namespace WebCore { class Attr; class Element; +class MemoryObjectInfo; -enum EInUpdateStyleAttribute { NotInUpdateStyleAttribute, InUpdateStyleAttribute }; +enum SynchronizationOfLazyAttribute { NotInSynchronizationOfLazyAttribute, InSynchronizationOfLazyAttribute }; class ElementAttributeData { WTF_MAKE_FAST_ALLOCATED; @@ -60,7 +60,7 @@ public: void updateInlineStyleAvoidingMutation(StyledElement*, const String& text) const; void destroyInlineStyle(StyledElement*) const; - StylePropertySet* attributeStyle() const { return m_attributeStyle.get(); } + const StylePropertySet* attributeStyle() const { return m_attributeStyle.get(); } void setAttributeStyle(PassRefPtr<StylePropertySet> style) const { m_attributeStyle = style; } size_t length() const; @@ -78,9 +78,9 @@ public: size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const; // These functions do no error checking. - void addAttribute(const Attribute&, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute); + void addAttribute(const Attribute&, Element*, SynchronizationOfLazyAttribute = NotInSynchronizationOfLazyAttribute); void removeAttribute(const QualifiedName&, Element*); - void removeAttribute(size_t index, Element*, EInUpdateStyleAttribute = NotInUpdateStyleAttribute); + void removeAttribute(size_t index, Element*, SynchronizationOfLazyAttribute = NotInSynchronizationOfLazyAttribute); PassRefPtr<Attr> takeAttribute(size_t index, Element*); bool hasID() const { return !m_idForStyleResolution.isNull(); } @@ -94,16 +94,7 @@ public: PassRefPtr<Attr> ensureAttr(Element*, const QualifiedName&) const; void detachAttrObjectsFromElement(Element*) const; - void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const - { - MemoryClassInfo<ElementAttributeData> info(memoryObjectInfo, this, MemoryInstrumentation::DOM, m_arraySize * sizeof(Attribute)); - info.addInstrumentedMember(m_inlineStyleDecl.get()); - info.addInstrumentedMember(m_attributeStyle.get()); - info.addMember(m_classNames); - info.addString(m_idForStyleResolution); - if (m_isMutable) - info.addVector(*m_mutableAttributeVector); - } + void reportMemoryUsage(MemoryObjectInfo*) const; private: friend class Element; diff --git a/Source/WebCore/dom/ElementShadow.cpp b/Source/WebCore/dom/ElementShadow.cpp index 6f5e33245..a68ef3575 100644 --- a/Source/WebCore/dom/ElementShadow.cpp +++ b/Source/WebCore/dom/ElementShadow.cpp @@ -79,7 +79,8 @@ void ElementShadow::addShadowRoot(Element* shadowHost, PassRefPtr<ShadowRoot> sh shadowRoot->setHost(shadowHost); shadowRoot->setParentTreeScope(shadowHost->treeScope()); m_shadowRoots.push(shadowRoot.get()); - invalidateDistribution(shadowHost, InvalidateIfNeeded); + setValidityUndetermined(); + invalidateDistribution(shadowHost); ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get()); if (shadowHost->attached() && !shadowRoot->attached()) @@ -108,7 +109,7 @@ void ElementShadow::removeAllShadowRoots() ChildNodeRemovalNotifier(shadowHost).notify(oldRoot.get()); } - invalidateDistribution(shadowHost, InvalidateIfNeeded); + invalidateDistribution(shadowHost); } void ElementShadow::attach() @@ -188,18 +189,20 @@ void ElementShadow::ensureDistribution() m_distributor.distribute(host()); } -void ElementShadow::invalidateDistribution(InvalidationType type) +void ElementShadow::setValidityUndetermined() { - invalidateDistribution(host(), type); + m_distributor.setValidity(ContentDistributor::Undetermined); } -void ElementShadow::invalidateDistribution(Element* host, InvalidationType type) +void ElementShadow::invalidateDistribution() { - bool needsReattach = (type == InvalidateAndForceReattach); - bool needsInvalidation = m_distributor.needsInvalidation(); + invalidateDistribution(host()); +} - if (needsInvalidation) - needsReattach |= m_distributor.invalidate(host); +void ElementShadow::invalidateDistribution(Element* host) +{ + bool needsInvalidation = m_distributor.needsInvalidation(); + bool needsReattach = needsInvalidation ? m_distributor.invalidate(host) : false; if (needsReattach && host->attached()) { host->detach(); diff --git a/Source/WebCore/dom/ElementShadow.h b/Source/WebCore/dom/ElementShadow.h index 3ab5c075d..f58616efb 100644 --- a/Source/WebCore/dom/ElementShadow.h +++ b/Source/WebCore/dom/ElementShadow.h @@ -62,12 +62,8 @@ public: bool needsStyleRecalc(); void recalcStyle(Node::StyleChange); - enum InvalidationType { - InvalidateIfNeeded, - InvalidateAndForceReattach - }; - - void invalidateDistribution(InvalidationType = InvalidateIfNeeded); + void setValidityUndetermined(); + void invalidateDistribution(); void ensureDistribution(); InsertionPoint* insertionPointFor(const Node*) const; @@ -76,7 +72,7 @@ public: const ContentDistributor& distributor() const; private: - void invalidateDistribution(Element* host, InvalidationType); + void invalidateDistribution(Element* host); DoublyLinkedList<ShadowRoot> m_shadowRoots; ContentDistributor m_distributor; diff --git a/Source/WebCore/dom/Event.cpp b/Source/WebCore/dom/Event.cpp index 761313c59..08e644ff6 100644 --- a/Source/WebCore/dom/Event.cpp +++ b/Source/WebCore/dom/Event.cpp @@ -155,6 +155,15 @@ void Event::storeResult(const String&) { } +void Event::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addMember(m_type); + info.addMember(m_currentTarget); + info.addMember(m_target); + info.addInstrumentedMember(m_underlyingEvent); +} + void Event::setTarget(PassRefPtr<EventTarget> target) { if (m_target == target) diff --git a/Source/WebCore/dom/Event.h b/Source/WebCore/dom/Event.h index d298d90a7..e72342315 100644 --- a/Source/WebCore/dom/Event.h +++ b/Source/WebCore/dom/Event.h @@ -31,6 +31,7 @@ namespace WebCore { + class MemoryInstrumentation; class EventTarget; class EventDispatcher; @@ -152,6 +153,8 @@ namespace WebCore { bool isBeingDispatched() const { return eventPhase(); } + virtual void reportMemoryUsage(MemoryObjectInfo*) const; + protected: Event(); Event(const AtomicString& type, bool canBubble, bool cancelable); diff --git a/Source/WebCore/dom/EventDispatcher.cpp b/Source/WebCore/dom/EventDispatcher.cpp index a75aab0e3..e1a60f3d4 100644 --- a/Source/WebCore/dom/EventDispatcher.cpp +++ b/Source/WebCore/dom/EventDispatcher.cpp @@ -27,6 +27,7 @@ #include "EventDispatcher.h" #include "ComposedShadowTreeWalker.h" +#include "ContainerNode.h" #include "ElementShadow.h" #include "EventContext.h" #include "EventDispatchMediator.h" @@ -162,8 +163,6 @@ void EventDispatcher::dispatchSimulatedClick(Node* node, PassRefPtr<Event> under if (node->disabled()) return; - EventDispatcher dispatcher(node); - if (!gNodesDispatchingSimulatedClicks) gNodesDispatchingSimulatedClicks = new HashSet<Node*>; else if (gNodesDispatchingSimulatedClicks->contains(node)) @@ -173,14 +172,14 @@ void EventDispatcher::dispatchSimulatedClick(Node* node, PassRefPtr<Event> under // send mousedown and mouseup before the click, if requested if (sendMouseEvents) - dispatcher.dispatchEvent(SimulatedMouseEvent::create(eventNames().mousedownEvent, node->document()->defaultView(), underlyingEvent)); + EventDispatcher(node).dispatchEvent(SimulatedMouseEvent::create(eventNames().mousedownEvent, node->document()->defaultView(), underlyingEvent)); node->setActive(true, showPressedLook); if (sendMouseEvents) - dispatcher.dispatchEvent(SimulatedMouseEvent::create(eventNames().mouseupEvent, node->document()->defaultView(), underlyingEvent)); + EventDispatcher(node).dispatchEvent(SimulatedMouseEvent::create(eventNames().mouseupEvent, node->document()->defaultView(), underlyingEvent)); node->setActive(false); // always send click - dispatcher.dispatchEvent(SimulatedMouseEvent::create(eventNames().clickEvent, node->document()->defaultView(), underlyingEvent)); + EventDispatcher(node).dispatchEvent(SimulatedMouseEvent::create(eventNames().clickEvent, node->document()->defaultView(), underlyingEvent)); gNodesDispatchingSimulatedClicks->remove(node); } @@ -201,7 +200,9 @@ void EventDispatcher::adjustRelatedTarget(Event* event, PassRefPtr<EventTarget> EventDispatcher::EventDispatcher(Node* node) : m_node(node) , m_ancestorsInitialized(false) - , m_shouldPreventDispatch(false) +#ifndef NDEBUG + , m_eventDispatched(false) +#endif { ASSERT(node); m_view = node->document()->view(); @@ -237,31 +238,53 @@ void EventDispatcher::ensureEventAncestors(Event* event) } } -bool EventDispatcher::dispatchEvent(PassRefPtr<Event> event) +bool EventDispatcher::dispatchEvent(PassRefPtr<Event> prpEvent) { - event->setTarget(eventTargetRespectingSVGTargetRules(m_node.get())); +#ifndef NDEBUG + ASSERT(!m_eventDispatched); + m_eventDispatched = true; +#endif + RefPtr<Event> event = prpEvent; + ChildNodesLazySnapshot::takeChildNodesLazySnapshot(); + event->setTarget(eventTargetRespectingSVGTargetRules(m_node.get())); ASSERT(!eventDispatchForbidden()); ASSERT(event->target()); ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null. - - RefPtr<EventTarget> originalTarget = event->target(); ensureEventAncestors(event.get()); + WindowEventContext windowEventContext(event.get(), m_node.get(), topEventContext()); + InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowEventContext.window(), m_node.get(), m_ancestors); - WindowEventContext windowContext(event.get(), m_node.get(), topEventContext()); + void* preDispatchEventHandlerResult; + if (dispatchEventPreProcess(event, preDispatchEventHandlerResult) == ContinueDispatching) + if (dispatchEventAtCapturing(event, windowEventContext) == ContinueDispatching) + if (dispatchEventAtTarget(event) == ContinueDispatching) + dispatchEventAtBubbling(event, windowEventContext); + dispatchEventPostProcess(event, preDispatchEventHandlerResult); - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowContext.window(), m_node.get(), m_ancestors); + // Ensure that after event dispatch, the event's target object is the + // outermost shadow DOM boundary. + event->setTarget(windowEventContext.target()); + event->setCurrentTarget(0); + InspectorInstrumentation::didDispatchEvent(cookie); + + return !event->defaultPrevented(); +} +inline EventDispatchContinuation EventDispatcher::dispatchEventPreProcess(PassRefPtr<Event> event, void*& preDispatchEventHandlerResult) +{ // Give the target node a chance to do some work before DOM event handlers get a crack. - void* data = m_node->preDispatchEventHandler(event.get()); - if (m_ancestors.isEmpty() || m_shouldPreventDispatch || event->propagationStopped()) - goto doneDispatching; + preDispatchEventHandlerResult = m_node->preDispatchEventHandler(event.get()); + return (m_ancestors.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching; +} +inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing(PassRefPtr<Event> event, WindowEventContext& windowEventContext) +{ // Trigger capturing event handlers, starting at the top and working our way down. event->setEventPhase(Event::CAPTURING_PHASE); - if (windowContext.handleLocalEvents(event.get()) && event->propagationStopped()) - goto doneDispatching; + if (windowEventContext.handleLocalEvents(event.get()) && event->propagationStopped()) + return DoneDispatching; for (size_t i = m_ancestors.size() - 1; i > 0; --i) { const EventContext& eventContext = m_ancestors[i]; @@ -273,16 +296,21 @@ bool EventDispatcher::dispatchEvent(PassRefPtr<Event> event) event->setEventPhase(Event::CAPTURING_PHASE); eventContext.handleLocalEvents(event.get()); if (event->propagationStopped()) - goto doneDispatching; + return DoneDispatching; } + return ContinueDispatching; +} + +inline EventDispatchContinuation EventDispatcher::dispatchEventAtTarget(PassRefPtr<Event> event) +{ event->setEventPhase(Event::AT_TARGET); - event->setTarget(originalTarget.get()); - event->setCurrentTarget(eventTargetRespectingSVGTargetRules(m_node.get())); m_ancestors[0].handleLocalEvents(event.get()); - if (event->propagationStopped()) - goto doneDispatching; + return event->propagationStopped() ? DoneDispatching : ContinueDispatching; +} +inline EventDispatchContinuation EventDispatcher::dispatchEventAtBubbling(PassRefPtr<Event> event, WindowEventContext& windowContext) +{ if (event->bubbles() && !event->cancelBubble()) { // Trigger bubbling event handlers, starting at the bottom and working our way up. event->setEventPhase(Event::BUBBLING_PHASE); @@ -296,18 +324,21 @@ bool EventDispatcher::dispatchEvent(PassRefPtr<Event> event) event->setEventPhase(Event::BUBBLING_PHASE); eventContext.handleLocalEvents(event.get()); if (event->propagationStopped() || event->cancelBubble()) - goto doneDispatching; + return DoneDispatching; } windowContext.handleLocalEvents(event.get()); } + return ContinueDispatching; +} -doneDispatching: - event->setTarget(originalTarget.get()); +inline void EventDispatcher::dispatchEventPostProcess(PassRefPtr<Event> event, void* preDispatchEventHandlerResult) +{ + event->setTarget(eventTargetRespectingSVGTargetRules(m_node.get())); event->setCurrentTarget(0); event->setEventPhase(0); // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler. - m_node->postDispatchEventHandler(event.get(), data); + m_node->postDispatchEventHandler(event.get(), preDispatchEventHandlerResult); // Call default event handlers. While the DOM does have a concept of preventing // default handling, the detail of which handlers are called is an internal @@ -317,7 +348,7 @@ doneDispatching: m_node->defaultEventHandler(event.get()); ASSERT(!event->defaultPrevented()); if (event->defaultHandled()) - goto doneWithDefault; + return; // For bubbling events, call default event handlers on the same targets in the // same order as the bubbling phase. if (event->bubbles()) { @@ -326,20 +357,10 @@ doneDispatching: m_ancestors[i].node()->defaultEventHandler(event.get()); ASSERT(!event->defaultPrevented()); if (event->defaultHandled()) - goto doneWithDefault; + return; } } } - -doneWithDefault: - - // Ensure that after event dispatch, the event's target object is the - // outermost shadow DOM boundary. - event->setTarget(windowContext.target()); - event->setCurrentTarget(0); - InspectorInstrumentation::didDispatchEvent(cookie); - - return !event->defaultPrevented(); } const EventContext* EventDispatcher::topEventContext() diff --git a/Source/WebCore/dom/EventDispatcher.h b/Source/WebCore/dom/EventDispatcher.h index 34c55e4db..5bfead0d0 100644 --- a/Source/WebCore/dom/EventDispatcher.h +++ b/Source/WebCore/dom/EventDispatcher.h @@ -42,12 +42,18 @@ class PlatformKeyboardEvent; class PlatformMouseEvent; class ShadowRoot; class TreeScope; +class WindowEventContext; enum EventDispatchBehavior { RetargetEvent, StayInsideShadowDOM }; +enum EventDispatchContinuation { + ContinueDispatching, + DoneDispatching +}; + class EventRelatedTargetAdjuster { public: EventRelatedTargetAdjuster(PassRefPtr<Node>, PassRefPtr<Node> relatedTarget); @@ -80,12 +86,19 @@ private: void ensureEventAncestors(Event*); const EventContext* topEventContext(); + EventDispatchContinuation dispatchEventPreProcess(PassRefPtr<Event>, void*& preDispatchEventHandlerResult); + EventDispatchContinuation dispatchEventAtCapturing(PassRefPtr<Event>, WindowEventContext&); + EventDispatchContinuation dispatchEventAtTarget(PassRefPtr<Event>); + EventDispatchContinuation dispatchEventAtBubbling(PassRefPtr<Event>, WindowEventContext&); + void dispatchEventPostProcess(PassRefPtr<Event>, void* preDispatchEventHandlerResult); + Vector<EventContext> m_ancestors; RefPtr<Node> m_node; - RefPtr<EventTarget> m_originalTarget; RefPtr<FrameView> m_view; bool m_ancestorsInitialized; - bool m_shouldPreventDispatch; +#ifndef NDEBUG + bool m_eventDispatched; +#endif }; inline Node* EventDispatcher::node() const diff --git a/Source/WebCore/dom/EventListener.h b/Source/WebCore/dom/EventListener.h index c3c2d6cbd..d1a6e8f24 100644 --- a/Source/WebCore/dom/EventListener.h +++ b/Source/WebCore/dom/EventListener.h @@ -42,7 +42,8 @@ namespace WebCore { CPPEventListenerType, ConditionEventListenerType, GObjectEventListenerType, - NativeEventListenerType + NativeEventListenerType, + SVGTRefTargetEventListenerType }; virtual ~EventListener() { } diff --git a/Source/WebCore/dom/EventNames.cpp b/Source/WebCore/dom/EventNames.cpp index 08646f714..6df1290ee 100644 --- a/Source/WebCore/dom/EventNames.cpp +++ b/Source/WebCore/dom/EventNames.cpp @@ -24,10 +24,10 @@ namespace WebCore { #define INITIALIZE_EVENT_NAME(name) \ - , name##Event(#name) + , name##Event(#name, AtomicString::ConstructFromLiteral) #define INITIALIZE_EVENT_INTERFACE(name) \ - , interfaceFor##name(#name) + , interfaceFor##name(#name, AtomicString::ConstructFromLiteral) EventNames::EventNames() : dummy(0) diff --git a/Source/WebCore/dom/EventNames.h b/Source/WebCore/dom/EventNames.h index b0efbe765..6d0a10573 100644 --- a/Source/WebCore/dom/EventNames.h +++ b/Source/WebCore/dom/EventNames.h @@ -71,6 +71,11 @@ namespace WebCore { macro(focus) \ macro(focusin) \ macro(focusout) \ + macro(gesturetap) \ + macro(gesturetapdown) \ + macro(gesturescrollstart) \ + macro(gesturescrollend) \ + macro(gesturescrollupdate) \ macro(hashchange) \ macro(input) \ macro(invalid) \ @@ -224,7 +229,6 @@ namespace WebCore { \ macro(show) \ \ - macro(webkitpointerlocklost) \ macro(webkitpointerlockchange) \ macro(webkitpointerlockerror) \ \ @@ -234,6 +238,8 @@ namespace WebCore { \ macro(webkitresourcetimingbufferfull) \ \ + macro(webkitdeviceproximity) \ + \ // end of DOM_EVENT_NAMES_FOR_EACH @@ -262,6 +268,15 @@ namespace WebCore { || eventType == touchcancelEvent; } + inline bool isGestureEventType(const AtomicString& eventType) const + { + return eventType == gesturetapEvent + || eventType == gesturetapdownEvent + || eventType == gesturescrollstartEvent + || eventType == gesturescrollendEvent + || eventType == gesturescrollupdateEvent; + } + Vector<AtomicString> touchEventNames() const { Vector<AtomicString> names; diff --git a/Source/WebCore/dom/EventNames.in b/Source/WebCore/dom/EventNames.in index 9c0ac5558..5da57ffc6 100644 --- a/Source/WebCore/dom/EventNames.in +++ b/Source/WebCore/dom/EventNames.in @@ -43,6 +43,7 @@ IDBVersionChangeEvent conditional=INDEXED_DATABASE TouchEvent conditional=TOUCH_EVENTS, runtimeConditional=touchEnabled DeviceMotionEvent conditional=DEVICE_ORIENTATION DeviceOrientationEvent conditional=DEVICE_ORIENTATION +DeviceProximityEvent conditional=PROXIMITY_EVENTS OrientationEvent interfaceName=Event, conditional=ORIENTATION_EVENTS MediaKeyEvent conditional=ENCRYPTED_MEDIA TrackEvent conditional=VIDEO_TRACK diff --git a/Source/WebCore/dom/EventTarget.h b/Source/WebCore/dom/EventTarget.h index ab0d7c7f1..d85a8c4c9 100644 --- a/Source/WebCore/dom/EventTarget.h +++ b/Source/WebCore/dom/EventTarget.h @@ -56,6 +56,7 @@ namespace WebCore { class JavaScriptAudioNode; class LocalMediaStream; class MediaController; + class MediaSource; class MediaStream; class MessagePort; class Node; @@ -68,6 +69,7 @@ namespace WebCore { class TextTrack; class TextTrackCue; class WebSocket; + class WebKitNamedFlow; class Worker; class XMLHttpRequest; class XMLHttpRequestUpload; diff --git a/Source/WebCore/dom/EventTargetFactory.in b/Source/WebCore/dom/EventTargetFactory.in index ff60aad4d..6d972c396 100644 --- a/Source/WebCore/dom/EventTargetFactory.in +++ b/Source/WebCore/dom/EventTargetFactory.in @@ -15,6 +15,7 @@ IDBVersionChangeRequest conditional=INDEXED_DATABASE JavaScriptAudioNode conditional=WEB_AUDIO LocalMediaStream conditional=MEDIA_STREAM MediaController conditional=VIDEO +MediaSource conditional=MEDIA_SOURCE MediaStream conditional=MEDIA_STREAM MediaStreamTrack conditional=MEDIA_STREAM MediaStreamTrackList conditional=MEDIA_STREAM @@ -24,6 +25,7 @@ Node Notification conditional=NOTIFICATIONS|LEGACY_NOTIFICATIONS PeerConnection00 conditional=MEDIA_STREAM Performance conditional=WEB_TIMING +RTCPeerConnection conditional=MEDIA_STREAM SharedWorker conditional=SHARED_WORKERS SharedWorkerContext conditional=SHARED_WORKERS SourceBufferList conditional=MEDIA_SOURCE @@ -32,6 +34,7 @@ SVGElementInstance conditional=SVG TextTrack conditional=VIDEO_TRACK TextTrackCue conditional=VIDEO_TRACK TextTrackList conditional=VIDEO_TRACK +WebKitNamedFlow WebSocket conditional=WEB_SOCKETS Worker conditional=WORKERS XMLHttpRequest diff --git a/Source/WebCore/dom/GenericEventQueue.cpp b/Source/WebCore/dom/GenericEventQueue.cpp index 75543c7b6..a177d61a8 100644 --- a/Source/WebCore/dom/GenericEventQueue.cpp +++ b/Source/WebCore/dom/GenericEventQueue.cpp @@ -85,6 +85,7 @@ void GenericEventQueue::timerFired(Timer<GenericEventQueue>*) Vector<RefPtr<Event> > pendingEvents; m_pendingEvents.swap(pendingEvents); + RefPtr<EventTarget> protect(m_owner); for (unsigned i = 0; i < pendingEvents.size(); ++i) { EventTarget* target = pendingEvents[i]->target() ? pendingEvents[i]->target() : m_owner; target->dispatchEvent(pendingEvents[i].release()); diff --git a/Source/WebCore/dom/GestureEvent.cpp b/Source/WebCore/dom/GestureEvent.cpp new file mode 100644 index 000000000..d75cdaa09 --- /dev/null +++ b/Source/WebCore/dom/GestureEvent.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(GESTURE_EVENTS) + +#include "GestureEvent.h" + +#include <wtf/text/AtomicString.h> + +namespace WebCore { + +PassRefPtr<GestureEvent> GestureEvent::create() +{ + return adoptRef(new GestureEvent); +} + +PassRefPtr<GestureEvent> GestureEvent::create(PassRefPtr<AbstractView> view, const PlatformGestureEvent& event) +{ + AtomicString eventType; + switch (event.type()) { + case PlatformEvent::GestureScrollBegin: + eventType = eventNames().gesturescrollstartEvent; break; + case PlatformEvent::GestureScrollEnd: + eventType = eventNames().gesturescrollendEvent; break; + case PlatformEvent::GestureScrollUpdate: + eventType = eventNames().gesturescrollupdateEvent; break; + case PlatformEvent::GestureTap: + eventType = eventNames().gesturetapEvent; break; + case PlatformEvent::GestureTapDown: + eventType = eventNames().gesturetapdownEvent; break; + case PlatformEvent::GestureDoubleTap: + case PlatformEvent::GestureTwoFingerTap: + case PlatformEvent::GestureLongPress: + case PlatformEvent::GesturePinchBegin: + case PlatformEvent::GesturePinchEnd: + case PlatformEvent::GesturePinchUpdate: + default: + return 0; + } + return adoptRef(new GestureEvent(eventType, view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.deltaX(), event.deltaY())); +} + +void GestureEvent::initGestureEvent(const AtomicString& type, PassRefPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY) +{ + if (dispatched()) + return; + + initUIEvent(type, true, true, view, 0); + m_screenLocation = IntPoint(screenX, screenY); + m_ctrlKey = ctrlKey; + m_altKey = altKey; + m_shiftKey = shiftKey; + m_metaKey = metaKey; + + m_deltaX = deltaX; + m_deltaY = deltaY; + + initCoordinates(IntPoint(clientX, clientY)); +} + +const AtomicString& GestureEvent::interfaceName() const +{ + DEFINE_STATIC_LOCAL(AtomicString, name, ("TBDInterface")); + return name; +} + +GestureEvent::GestureEvent() + : m_deltaX(0) + , m_deltaY(0) +{ +} + +GestureEvent::GestureEvent(const AtomicString& type, PassRefPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY) + : MouseRelatedEvent(type, true, true, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY), +#if ENABLE(POINTER_LOCK) + IntPoint(0, 0), +#endif + ctrlKey, altKey, shiftKey, metaKey) + , m_deltaX(deltaX) + , m_deltaY(deltaY) +{ +} + +GestureEventDispatchMediator::GestureEventDispatchMediator(PassRefPtr<GestureEvent> gestureEvent) + : EventDispatchMediator(gestureEvent) +{ +} + +GestureEvent* GestureEventDispatchMediator::event() const +{ + return static_cast<GestureEvent*>(EventDispatchMediator::event()); +} + +bool GestureEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const +{ + if (dispatcher->node()->disabled()) + return true; + + dispatcher->dispatchEvent(event()); + ASSERT(!event()->defaultPrevented()); + return event()->defaultHandled() || event()->defaultPrevented(); +} + +} // namespace WebCore + +#endif // ENABLE(GESTURE_EVENTS) diff --git a/Source/WebCore/dom/GestureEvent.h b/Source/WebCore/dom/GestureEvent.h new file mode 100644 index 000000000..ff083c3f2 --- /dev/null +++ b/Source/WebCore/dom/GestureEvent.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GestureEvent_h +#define GestureEvent_h + +#if ENABLE(GESTURE_EVENTS) + +#include "EventDispatcher.h" +#include "EventNames.h" +#include "Frame.h" +#include "FrameView.h" +#include "MouseRelatedEvent.h" +#include "PlatformEvent.h" +#include "PlatformGestureEvent.h" + +namespace WebCore { + +class GestureEvent : public MouseRelatedEvent { +public: + virtual ~GestureEvent() { } + + static PassRefPtr<GestureEvent> create(); + static PassRefPtr<GestureEvent> create(PassRefPtr<AbstractView>, const PlatformGestureEvent&); + + void initGestureEvent(const AtomicString& type, PassRefPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY); + + virtual const AtomicString& interfaceName() const; + + float deltaX() const { return m_deltaX; } + float deltaY() const { return m_deltaY; } + +private: + GestureEvent(); + GestureEvent(const AtomicString& type, PassRefPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY); + + float m_deltaX; + float m_deltaY; +}; + +class GestureEventDispatchMediator : public EventDispatchMediator { +public: + static PassRefPtr<GestureEventDispatchMediator> create(PassRefPtr<GestureEvent> gestureEvent) + { + return adoptRef(new GestureEventDispatchMediator(gestureEvent)); + } + +private: + explicit GestureEventDispatchMediator(PassRefPtr<GestureEvent>); + + GestureEvent* event() const; + + virtual bool dispatchEvent(EventDispatcher*) const; +}; + +} // namespace WebCore + +#endif // ENABLE(GESTURE_EVENTS) + +#endif // GestureEvent_h diff --git a/Source/WebCore/dom/MemoryInstrumentation.cpp b/Source/WebCore/dom/MemoryInstrumentation.cpp new file mode 100644 index 000000000..8a0175356 --- /dev/null +++ b/Source/WebCore/dom/MemoryInstrumentation.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "MemoryInstrumentation.h" + +#include "KURL.h" +#include <wtf/text/StringImpl.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +void MemoryInstrumentation::addObject(const String& string, ObjectType objectType) +{ + addObject(string.impl(), objectType); +} + +void MemoryInstrumentation::addObject(const StringImpl* stringImpl, ObjectType objectType) +{ + if (!stringImpl || visited(stringImpl)) + return; + countObjectSize(objectType, stringImpl->sizeInBytes()); +} + +void MemoryInstrumentation::addObject(const KURL& url, ObjectType objectType) +{ + if (visited(&url)) + return; + addObject(url.string(), objectType); + if (url.innerURL()) + addObject(url.innerURL(), objectType); +} + +} // namespace WebCore diff --git a/Source/WebCore/dom/MemoryInstrumentation.h b/Source/WebCore/dom/MemoryInstrumentation.h index 96c017887..33f2e6e8a 100644 --- a/Source/WebCore/dom/MemoryInstrumentation.h +++ b/Source/WebCore/dom/MemoryInstrumentation.h @@ -1,3 +1,4 @@ + /* * Copyright (C) 2012 Google Inc. All rights reserved. * @@ -30,7 +31,6 @@ #ifndef MemoryInstrumentation_h #define MemoryInstrumentation_h -#include <stdio.h> #include <wtf/Assertions.h> #include <wtf/Forward.h> @@ -40,6 +40,8 @@ namespace WebCore { +template <typename T> class DataRef; +class KURL; class MemoryObjectInfo; class MemoryInstrumentation { @@ -52,32 +54,72 @@ public: CSS, Binding, Loader, + MemoryCacheStructures, + CachedResource, + CachedResourceCSS, + CachedResourceFont, + CachedResourceImage, + CachedResourceScript, + CachedResourceSVG, + CachedResourceShader, + CachedResourceXSLT, LastTypeEntry }; - template <typename T> void addInstrumentedMember(const T& t) + template <typename T> void addRootObject(const T& t) { - OwningTraits<T>::addInstrumentedMember(this, t); + addInstrumentedObject(t, Other); + processDeferredInstrumentedPointers(); } - template <typename T> void addMember(const T& t, ObjectType objectType) + template <typename Container> static size_t calculateContainerSize(const Container&, bool contentOnly = false); + +protected: + class InstrumentedPointerBase { + public: + virtual ~InstrumentedPointerBase() { } + virtual void process(MemoryInstrumentation*) = 0; + }; + +private: + virtual void countObjectSize(ObjectType, size_t) = 0; + virtual void deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase>) = 0; + virtual bool visited(const void*) = 0; + virtual void processDeferredInstrumentedPointers() = 0; + + friend class MemoryClassInfo; + template <typename T> class InstrumentedPointer : public InstrumentedPointerBase { + public: + explicit InstrumentedPointer(const T* pointer, ObjectType ownerObjectType) : m_pointer(pointer), m_ownerObjectType(ownerObjectType) { } + virtual void process(MemoryInstrumentation*) OVERRIDE; + + private: + const T* m_pointer; + const ObjectType m_ownerObjectType; + }; + + template <typename T> void addObject(const T& t, ObjectType ownerObjectType) { - OwningTraits<T>::addMember(this, t, objectType); + OwningTraits<T>::addObject(this, t, ownerObjectType); } - + void addObject(const String&, ObjectType); + void addObject(const StringImpl*, ObjectType); + void addObject(const KURL&, ObjectType); + template <typename T> void addInstrumentedObject(const T& t, ObjectType ownerObjectType) { OwningTraits<T>::addInstrumentedObject(this, t, ownerObjectType); } template <typename HashMapType> void addHashMap(const HashMapType&, ObjectType, bool contentOnly = false); template <typename HashSetType> void addHashSet(const HashSetType&, ObjectType, bool contentOnly = false); template <typename CollectionType> void addInstrumentedCollection(const CollectionType&, ObjectType, bool contentOnly = false); + template <typename MapType> void addInstrumentedMapEntries(const MapType&, ObjectType); + template <typename MapType> void addInstrumentedMapValues(const MapType&, ObjectType); template <typename ListHashSetType> void addListHashSet(const ListHashSetType&, ObjectType, bool contentOnly = false); template <typename VectorType> void addVector(const VectorType&, ObjectType, bool contentOnly = false); - void addRawBuffer(const void* const& buffer, ObjectType objectType, size_t size) + void addRawBuffer(const void* const& buffer, ObjectType ownerObjectType, size_t size) { if (!buffer || visited(buffer)) return; - countObjectSize(objectType, size); + countObjectSize(ownerObjectType, size); } -protected: enum OwningType { byPointer, byReference @@ -85,69 +127,34 @@ protected: template <typename T> struct OwningTraits { // Default byReference implementation. - static void addInstrumentedMember(MemoryInstrumentation* instrumentation, const T& t) { instrumentation->addInstrumentedMemberImpl(&t, byReference); } - static void addMember(MemoryInstrumentation* instrumentation, const T& t, MemoryInstrumentation::ObjectType objectType) { instrumentation->addMemberImpl(&t, objectType, byReference); } + static void addInstrumentedObject(MemoryInstrumentation* instrumentation, const T& t, ObjectType ownerObjectType) { instrumentation->addInstrumentedObjectImpl(&t, ownerObjectType, byReference); } + static void addObject(MemoryInstrumentation* instrumentation, const T& t, ObjectType ownerObjectType) { instrumentation->addObjectImpl(&t, ownerObjectType, byReference); } }; template <typename T> struct OwningTraits<T*> { // Custom byPointer implementation. - static void addInstrumentedMember(MemoryInstrumentation* instrumentation, const T* const& t) { instrumentation->addInstrumentedMemberImpl(t, byPointer); } - static void addMember(MemoryInstrumentation* instrumentation, const T* const& t, MemoryInstrumentation::ObjectType objectType) { instrumentation->addMemberImpl(t, objectType, byPointer); } + static void addInstrumentedObject(MemoryInstrumentation* instrumentation, const T* const& t, ObjectType ownerObjectType) { instrumentation->addInstrumentedObjectImpl(t, ownerObjectType, byPointer); } + static void addObject(MemoryInstrumentation* instrumentation, const T* const& t, ObjectType ownerObjectType) { instrumentation->addObjectImpl(t, ownerObjectType, byPointer); } }; - template <typename T> void addInstrumentedMemberImpl(const T* const&, OwningType); - template <typename T> void addInstrumentedMemberImpl(const OwnPtr<T>* const& object, MemoryInstrumentation::OwningType owningType) { addInstrumentedMemberImpl(object->get(), owningType); } - template <typename T> void addInstrumentedMemberImpl(const RefPtr<T>* const& object, MemoryInstrumentation::OwningType owningType) { addInstrumentedMemberImpl(object->get(), owningType); } - - template <typename T> - void addMemberImpl(const T* const& object, ObjectType objectType, OwningType owningType) - { - if (!object || visited(object)) - return; - if (owningType == byReference) - return; - countObjectSize(objectType, sizeof(T)); - } + template <typename T> void addInstrumentedObjectImpl(const T* const&, ObjectType, OwningType); + template <typename T> void addInstrumentedObjectImpl(const DataRef<T>* const&, ObjectType, OwningType); + template <typename T> void addInstrumentedObjectImpl(const OwnPtr<T>* const&, ObjectType, OwningType); + template <typename T> void addInstrumentedObjectImpl(const RefPtr<T>* const&, ObjectType, OwningType); - 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: - template <typename T> friend class MemoryClassInfo; - 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 addString(const String&, ObjectType) = 0; - virtual void countObjectSize(ObjectType, size_t) = 0; - virtual void deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase>) = 0; - virtual bool visited(const void*) = 0; + template <typename T> void addObjectImpl(const T* const&, ObjectType, OwningType); + template <typename T> void addObjectImpl(const DataRef<T>* const&, ObjectType, OwningType); + template <typename T> void addObjectImpl(const OwnPtr<T>* const&, ObjectType, OwningType); + template <typename T> void addObjectImpl(const RefPtr<T>* const&, ObjectType, OwningType); }; class MemoryObjectInfo { public: - explicit MemoryObjectInfo(MemoryInstrumentation* memoryInstrumentation) + MemoryObjectInfo(MemoryInstrumentation* memoryInstrumentation, MemoryInstrumentation::ObjectType ownerObjectType) : m_memoryInstrumentation(memoryInstrumentation) - , m_objectType(MemoryInstrumentation::Other) + , m_objectType(ownerObjectType) , m_objectSize(0) - { } + { } MemoryInstrumentation::ObjectType objectType() const { return m_objectType; } size_t objectSize() const { return m_objectSize; } @@ -155,14 +162,15 @@ public: MemoryInstrumentation* memoryInstrumentation() { return m_memoryInstrumentation; } private: - template <typename T> friend class MemoryClassInfo; + friend class MemoryClassInfo; - template <typename T> void reportObjectInfo(const T*, MemoryInstrumentation::ObjectType objectType, size_t extraObjectSize) + template <typename T> void reportObjectInfo(MemoryInstrumentation::ObjectType objectType) { - if (m_objectType != MemoryInstrumentation::Other) - return; - m_objectType = objectType; - m_objectSize = sizeof(T) + extraObjectSize; + if (!m_objectSize) { + m_objectSize = sizeof(T); + if (objectType != MemoryInstrumentation::Other) + m_objectType = objectType; + } } MemoryInstrumentation* m_memoryInstrumentation; @@ -170,50 +178,38 @@ private: size_t m_objectSize; }; -// Link time guard for string members. They produce link error is a string is reported via addMember. -template <> void MemoryInstrumentation::addMemberImpl<AtomicString>(const AtomicString* const&, MemoryInstrumentation::ObjectType, MemoryInstrumentation::OwningType); -template <> void MemoryInstrumentation::addMemberImpl<String>(const String* const&, MemoryInstrumentation::ObjectType, MemoryInstrumentation::OwningType); - - -template <typename T> -void MemoryInstrumentation::addInstrumentedMemberImpl(const T* const& object, MemoryInstrumentation::OwningType owningType) -{ - if (!object || visited(object)) - return; - if (owningType == byReference) { - MemoryObjectInfo memoryObjectInfo(this); - object->reportMemoryUsage(&memoryObjectInfo); - } else - deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object))); -} - - -template <typename T> class MemoryClassInfo { public: - MemoryClassInfo(MemoryObjectInfo* memoryObjectInfo, const T* ptr, MemoryInstrumentation::ObjectType objectType, size_t extraObjectSize = 0) + template <typename T> + MemoryClassInfo(MemoryObjectInfo* memoryObjectInfo, const T*, MemoryInstrumentation::ObjectType objectType) : m_memoryObjectInfo(memoryObjectInfo) , m_memoryInstrumentation(memoryObjectInfo->memoryInstrumentation()) { - m_memoryObjectInfo->reportObjectInfo(ptr, objectType, extraObjectSize); + m_memoryObjectInfo->reportObjectInfo<T>(objectType); m_objectType = memoryObjectInfo->objectType(); } - template <typename P> void visitBaseClass(const P* ptr) { ptr->P::reportMemoryUsage(m_memoryObjectInfo); } - - template <typename M> void addInstrumentedMember(const M& member) { m_memoryInstrumentation->addInstrumentedMember(member); } - template <typename M> void addMember(const M& member) { m_memoryInstrumentation->addMember(member, m_objectType); } + template <typename M> void addInstrumentedMember(const M& member) { m_memoryInstrumentation->addInstrumentedObject(member, m_objectType); } + template <typename M> void addMember(const M& member) { m_memoryInstrumentation->addObject(member, m_objectType); } template <typename HashMapType> void addHashMap(const HashMapType& map) { m_memoryInstrumentation->addHashMap(map, m_objectType, true); } template <typename HashSetType> void addHashSet(const HashSetType& set) { m_memoryInstrumentation->addHashSet(set, m_objectType, true); } + template <typename HashSetType> void addHashCountedSet(const HashSetType& set) { m_memoryInstrumentation->addHashSet(set, m_objectType, true); } template <typename HashSetType> void addInstrumentedHashSet(const HashSetType& set) { m_memoryInstrumentation->addInstrumentedCollection(set, m_objectType, true); } template <typename VectorType> void addInstrumentedVector(const VectorType& vector) { m_memoryInstrumentation->addInstrumentedCollection(vector, m_objectType, true); } + template <typename VectorType> void addInstrumentedVectorPtr(const OwnPtr<VectorType>& vector) { m_memoryInstrumentation->addInstrumentedCollection(*vector, m_objectType, false); } + template <typename VectorType> void addInstrumentedVectorPtr(const VectorType* const& vector) { m_memoryInstrumentation->addInstrumentedCollection(*vector, m_objectType, false); } + template <typename MapType> void addInstrumentedMapEntries(const MapType& map) { m_memoryInstrumentation->addInstrumentedMapEntries(map, m_objectType); } + template <typename MapType> void addInstrumentedMapValues(const MapType& map) { m_memoryInstrumentation->addInstrumentedMapValues(map, m_objectType); } template <typename ListHashSetType> void addListHashSet(const ListHashSetType& set) { m_memoryInstrumentation->addListHashSet(set, m_objectType, true); } template <typename VectorType> void addVector(const VectorType& vector) { m_memoryInstrumentation->addVector(vector, m_objectType, true); } + template <typename VectorType> void addVectorPtr(const VectorType* const vector) { m_memoryInstrumentation->addVector(*vector, m_objectType, false); } void addRawBuffer(const void* const& buffer, size_t size) { m_memoryInstrumentation->addRawBuffer(buffer, m_objectType, size); } - void addString(const String& string) { m_memoryInstrumentation->addString(string, m_objectType); } - void addString(const AtomicString& string) { m_memoryInstrumentation->addString((const String&)string, m_objectType); } + void addMember(const String& string) { m_memoryInstrumentation->addObject(string, m_objectType); } + void addMember(const AtomicString& string) { m_memoryInstrumentation->addObject((const String&)string, m_objectType); } + void addMember(const StringImpl* string) { m_memoryInstrumentation->addObject(string, m_objectType); } + void addMember(const KURL& url) { m_memoryInstrumentation->addObject(url, m_objectType); } private: MemoryObjectInfo* m_memoryObjectInfo; @@ -221,54 +217,149 @@ private: MemoryInstrumentation::ObjectType m_objectType; }; +template <typename T> +void MemoryInstrumentation::addInstrumentedObjectImpl(const T* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (owningType == byReference) { + MemoryObjectInfo memoryObjectInfo(this, ownerObjectType); + object->reportMemoryUsage(&memoryObjectInfo); + } else { + if (!object || visited(object)) + return; + deferInstrumentedPointer(adoptPtr(new InstrumentedPointer<T>(object, ownerObjectType))); + } +} + +template <typename T> +void MemoryInstrumentation::addInstrumentedObjectImpl(const DataRef<T>* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (owningType == byPointer) + countObjectSize(ownerObjectType, sizeof(DataRef<T>)); + addInstrumentedObjectImpl(object->get(), ownerObjectType, byPointer); +} + +template <typename T> +void MemoryInstrumentation::addInstrumentedObjectImpl(const OwnPtr<T>* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (owningType == byPointer) + countObjectSize(ownerObjectType, sizeof(OwnPtr<T>)); + addInstrumentedObjectImpl(object->get(), ownerObjectType, byPointer); +} + +template <typename T> +void MemoryInstrumentation::addInstrumentedObjectImpl(const RefPtr<T>* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (owningType == byPointer) + countObjectSize(ownerObjectType, sizeof(RefPtr<T>)); + addInstrumentedObjectImpl(object->get(), ownerObjectType, byPointer); +} + +template <typename T> +void MemoryInstrumentation::addObjectImpl(const DataRef<T>* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (owningType == byPointer) + countObjectSize(ownerObjectType, sizeof(DataRef<T>)); + addObjectImpl(object->get(), ownerObjectType, byPointer); +} + +template <typename T> +void MemoryInstrumentation::addObjectImpl(const OwnPtr<T>* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (owningType == byPointer) + countObjectSize(ownerObjectType, sizeof(RefPtr<T>)); + addObjectImpl(object->get(), ownerObjectType, byPointer); +} + +template <typename T> +void MemoryInstrumentation::addObjectImpl(const RefPtr<T>* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (owningType == byPointer) + countObjectSize(ownerObjectType, sizeof(RefPtr<T>)); + addObjectImpl(object->get(), ownerObjectType, byPointer); +} + +template <typename T> +void MemoryInstrumentation::addObjectImpl(const T* const& object, ObjectType ownerObjectType, OwningType owningType) +{ + if (!object || visited(object)) + return; + if (owningType == byReference) + return; + countObjectSize(ownerObjectType, sizeof(T)); +} + template<typename HashMapType> -void MemoryInstrumentation::addHashMap(const HashMapType& hashMap, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addHashMap(const HashMapType& hashMap, ObjectType ownerObjectType, bool contentOnly) { if (visited(&hashMap)) return; - countObjectSize(objectType, calculateContainerSize(hashMap, contentOnly)); + countObjectSize(ownerObjectType, calculateContainerSize(hashMap, contentOnly)); } template<typename HashSetType> -void MemoryInstrumentation::addHashSet(const HashSetType& hashSet, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addHashSet(const HashSetType& hashSet, ObjectType ownerObjectType, bool contentOnly) { if (visited(&hashSet)) return; - countObjectSize(objectType, calculateContainerSize(hashSet, contentOnly)); + countObjectSize(ownerObjectType, calculateContainerSize(hashSet, contentOnly)); } template <typename CollectionType> -void MemoryInstrumentation::addInstrumentedCollection(const CollectionType& collection, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addInstrumentedCollection(const CollectionType& collection, ObjectType ownerObjectType, bool contentOnly) { if (visited(&collection)) return; - countObjectSize(objectType, calculateContainerSize(collection, contentOnly)); + countObjectSize(ownerObjectType, calculateContainerSize(collection, contentOnly)); typename CollectionType::const_iterator end = collection.end(); for (typename CollectionType::const_iterator i = collection.begin(); i != end; ++i) - addInstrumentedMember(*i); + addInstrumentedObject(*i, ownerObjectType); +} + +template <typename MapType> +void MemoryInstrumentation::addInstrumentedMapEntries(const MapType& map, ObjectType ownerObjectType) +{ + typename MapType::const_iterator end = map.end(); + for (typename MapType::const_iterator i = map.begin(); i != end; ++i) { + addInstrumentedObject(i->first, ownerObjectType); + addInstrumentedObject(i->second, ownerObjectType); + } +} + +template <typename MapType> +void MemoryInstrumentation::addInstrumentedMapValues(const MapType& map, ObjectType ownerObjectType) +{ + typename MapType::const_iterator end = map.end(); + for (typename MapType::const_iterator i = map.begin(); i != end; ++i) + addInstrumentedObject(i->second, ownerObjectType); } template<typename ListHashSetType> -void MemoryInstrumentation::addListHashSet(const ListHashSetType& hashSet, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addListHashSet(const ListHashSetType& hashSet, ObjectType ownerObjectType, 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); + countObjectSize(ownerObjectType, size); } template <typename VectorType> -void MemoryInstrumentation::addVector(const VectorType& vector, ObjectType objectType, bool contentOnly) +void MemoryInstrumentation::addVector(const VectorType& vector, ObjectType ownerObjectType, bool contentOnly) { if (!vector.data() || visited(vector.data())) return; - countObjectSize(objectType, calculateContainerSize(vector, contentOnly)); + countObjectSize(ownerObjectType, calculateContainerSize(vector, contentOnly)); +} + +template <typename Container> +size_t MemoryInstrumentation::calculateContainerSize(const Container& container, bool contentOnly) +{ + return (contentOnly ? 0 : sizeof(container)) + container.capacity() * sizeof(typename Container::ValueType); } template<typename T> void MemoryInstrumentation::InstrumentedPointer<T>::process(MemoryInstrumentation* memoryInstrumentation) { - MemoryObjectInfo memoryObjectInfo(memoryInstrumentation); + MemoryObjectInfo memoryObjectInfo(memoryInstrumentation, m_ownerObjectType); m_pointer->reportMemoryUsage(&memoryObjectInfo); memoryInstrumentation->countObjectSize(memoryObjectInfo.objectType(), memoryObjectInfo.objectSize()); } diff --git a/Source/WebCore/dom/MicroDataItemList.cpp b/Source/WebCore/dom/MicroDataItemList.cpp index 6fc53936e..38460ce3d 100644 --- a/Source/WebCore/dom/MicroDataItemList.cpp +++ b/Source/WebCore/dom/MicroDataItemList.cpp @@ -40,7 +40,7 @@ using namespace HTMLNames; const String& MicroDataItemList::undefinedItemType() { - DEFINE_STATIC_LOCAL(String, undefinedItemTypeString, ("http://webkit.org/microdata/undefinedItemType")); + DEFINE_STATIC_LOCAL(String, undefinedItemTypeString, ("")); return undefinedItemTypeString; } @@ -65,7 +65,7 @@ bool MicroDataItemList::nodeMatches(Element* testNode) const if (!testElement->fastHasAttribute(itemscopeAttr) || testElement->fastHasAttribute(itempropAttr)) return false; - if (m_originalTypeNames == undefinedItemType()) + if (!m_typeNames.size()) return true; return testElement->itemType()->tokens().containsAll(m_typeNames); diff --git a/Source/WebCore/dom/MouseEvent.cpp b/Source/WebCore/dom/MouseEvent.cpp index cf2e2660a..9edda71ea 100644 --- a/Source/WebCore/dom/MouseEvent.cpp +++ b/Source/WebCore/dom/MouseEvent.cpp @@ -207,22 +207,21 @@ bool MouseEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) cons dispatcher->dispatchEvent(event()); bool swallowEvent = event()->defaultHandled() || event()->defaultPrevented(); + if (event()->type() != eventNames().clickEvent || event()->detail() != 2) + return swallowEvent; // Special case: If it's a double click event, we also send the dblclick event. This is not part // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same. - if (event()->type() == eventNames().clickEvent && event()->detail() == 2) { - RefPtr<MouseEvent> doubleClickEvent = MouseEvent::create(); - doubleClickEvent->initMouseEvent(eventNames().dblclickEvent, event()->bubbles(), event()->cancelable(), event()->view(), - event()->detail(), event()->screenX(), event()->screenY(), event()->clientX(), event()->clientY(), - event()->ctrlKey(), event()->altKey(), event()->shiftKey(), event()->metaKey(), - event()->button(), relatedTarget); - if (event()->defaultHandled()) - doubleClickEvent->setDefaultHandled(); - dispatcher->dispatchEvent(doubleClickEvent); - if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented()) - swallowEvent = true; - } - + RefPtr<MouseEvent> doubleClickEvent = MouseEvent::create(); + doubleClickEvent->initMouseEvent(eventNames().dblclickEvent, event()->bubbles(), event()->cancelable(), event()->view(), + event()->detail(), event()->screenX(), event()->screenY(), event()->clientX(), event()->clientY(), + event()->ctrlKey(), event()->altKey(), event()->shiftKey(), event()->metaKey(), + event()->button(), relatedTarget); + if (event()->defaultHandled()) + doubleClickEvent->setDefaultHandled(); + EventDispatcher::dispatchEvent(dispatcher->node(), MouseEventDispatchMediator::create(doubleClickEvent)); + if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented()) + return true; return swallowEvent; } diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp index f30c3fcbf..3841e0cdd 100644 --- a/Source/WebCore/dom/Node.cpp +++ b/Source/WebCore/dom/Node.cpp @@ -67,6 +67,7 @@ #include "KeyboardEvent.h" #include "LabelsNodeList.h" #include "Logging.h" +#include "MemoryInstrumentation.h" #include "MouseEvent.h" #include "MutationEvent.h" #include "NameNodeList.h" @@ -109,6 +110,10 @@ #include <wtf/text/CString.h> #include <wtf/text/StringBuilder.h> +#if ENABLE(GESTURE_EVENTS) +#include "GestureEvent.h" +#endif + #if ENABLE(INSPECTOR) #include "InspectorController.h" #endif @@ -2127,7 +2132,7 @@ void Node::showNodePathForThis() const const Node* node = chain[index - 1]; if (node->isShadowRoot()) { int count = 0; - for (ShadowRoot* shadowRoot = oldestShadowRootFor(node); shadowRoot && shadowRoot != node; shadowRoot = shadowRoot->youngerShadowRoot()) + for (ShadowRoot* shadowRoot = oldestShadowRootFor(toShadowRoot(node)->host()); shadowRoot && shadowRoot != node; shadowRoot = shadowRoot->youngerShadowRoot()) ++count; fprintf(stderr, "/#shadow-root[%d]", count); continue; @@ -2262,7 +2267,7 @@ void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName) for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) it->second->invalidateCache(attrName); - if (!attrName) + if (attrName) return; TagNodeListCacheNS::iterator tagCacheEnd = m_tagNodeListCacheNS.end(); @@ -2576,16 +2581,6 @@ bool Node::dispatchEvent(PassRefPtr<Event> event) return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event)); } -void Node::dispatchRegionLayoutUpdateEvent() -{ - ASSERT(!eventDispatchForbidden()); - - if (!document()->hasListenerType(Document::REGIONLAYOUTUPDATE_LISTENER)) - return; - - dispatchScopedEvent(UIEvent::create(eventNames().webkitRegionLayoutUpdateEvent, true, true, document()->defaultView(), 0)); -} - void Node::dispatchSubtreeModifiedEvent() { if (isInShadowTree()) @@ -2633,6 +2628,16 @@ bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicStrin return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(MouseEvent::create(eventType, document()->defaultView(), event, detail, relatedTarget))); } +#if ENABLE(GESTURE_EVENTS) +bool Node::dispatchGestureEvent(const PlatformGestureEvent& event) +{ + RefPtr<GestureEvent> gestureEvent = GestureEvent::create(document()->defaultView(), event); + if (!gestureEvent.get()) + return false; + return EventDispatcher::dispatchEvent(this, GestureEventDispatchMediator::create(gestureEvent)); +} +#endif + void Node::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook) { EventDispatcher::dispatchSimulatedClick(this, event, sendMouseEvents, showPressedLook); @@ -2742,6 +2747,20 @@ void Node::defaultEventHandler(Event* event) } } +bool Node::willRespondToMouseMoveEvents() +{ + if (disabled()) + return false; + return hasEventListeners(eventNames().mousemoveEvent) || hasEventListeners(eventNames().mouseoverEvent) || hasEventListeners(eventNames().mouseoutEvent); +} + +bool Node::willRespondToMouseClickEvents() +{ + if (disabled()) + return false; + return isContentEditable() || hasEventListeners(eventNames().mouseupEvent) || hasEventListeners(eventNames().mousedownEvent) || hasEventListeners(eventNames().clickEvent) || hasEventListeners(eventNames().DOMActivateEvent); +} + #if ENABLE(MICRODATA) DOMSettableTokenList* Node::itemProp() { @@ -2798,12 +2817,14 @@ void Node::removedLastRef() void Node::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo<Node> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); - info.visitBaseClass<TreeShared<Node, ContainerNode> >(this); - info.visitBaseClass<ScriptWrappable>(this); + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + TreeShared<Node, ContainerNode>::reportMemoryUsage(memoryObjectInfo); + ScriptWrappable::reportMemoryUsage(memoryObjectInfo); info.addInstrumentedMember(m_document); info.addInstrumentedMember(m_next); info.addInstrumentedMember(m_previous); + if (m_renderer) + info.addInstrumentedMember(m_renderer->style()); } } // namespace WebCore diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h index 86a7d39ed..141ce96bb 100644 --- a/Source/WebCore/dom/Node.h +++ b/Source/WebCore/dom/Node.h @@ -29,7 +29,6 @@ #include "EventTarget.h" #include "KURLHash.h" #include "LayoutTypes.h" -#include "MemoryInstrumentation.h" #include "MutationObserver.h" #include "RenderStyleConstants.h" #include "ScriptWrappable.h" @@ -66,6 +65,7 @@ class Frame; class HTMLInputElement; class IntRect; class KeyboardEvent; +class MemoryObjectInfo; class NSResolver; class NamedNodeMap; class NameNodeList; @@ -88,6 +88,10 @@ class ShadowRoot; class TagNodeList; class TreeScope; +#if ENABLE(GESTURE_EVENTS) +class PlatformGestureEvent; +#endif + #if ENABLE(MICRODATA) class HTMLPropertiesCollection; class PropertyNodeList; @@ -218,6 +222,7 @@ public: virtual bool isAttributeNode() const { return false; } virtual bool isCharacterDataNode() const { return false; } virtual bool isFrameOwnerElement() const { return false; } + virtual bool isPluginElement() const { return false; } bool isDocumentNode() const; bool isShadowRoot() const { return getFlag(IsShadowRootFlag); } bool inNamedFlow() const { return getFlag(InNamedFlowFlag); } @@ -573,6 +578,9 @@ public: PassRefPtr<NodeList> getElementsByClassName(const String& classNames); PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&); + virtual bool willRespondToMouseMoveEvents(); + virtual bool willRespondToMouseClickEvents(); + PassRefPtr<Element> querySelector(const AtomicString& selectors, ExceptionCode&); PassRefPtr<NodeList> querySelectorAll(const AtomicString& selectors, ExceptionCode&); @@ -599,8 +607,6 @@ public: virtual void handleLocalEvents(Event*); - void dispatchRegionLayoutUpdateEvent(); - void dispatchSubtreeModifiedEvent(); bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent); void dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Node> oldFocusedNode); @@ -609,6 +615,9 @@ public: bool dispatchKeyEvent(const PlatformKeyboardEvent&); bool dispatchWheelEvent(const PlatformWheelEvent&); bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0); +#if ENABLE(GESTURE_EVENTS) + bool dispatchGestureEvent(const PlatformGestureEvent&); +#endif void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true); bool dispatchBeforeLoadEvent(const String& sourceURL); diff --git a/Source/WebCore/dom/NodeRareData.h b/Source/WebCore/dom/NodeRareData.h index 0bdc3e8ac..1fdebb6d2 100644 --- a/Source/WebCore/dom/NodeRareData.h +++ b/Source/WebCore/dom/NodeRareData.h @@ -137,19 +137,15 @@ public: NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end(); for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) { DynamicSubtreeNodeList* list = it->second; - if (list->isRootedAtDocument()) { - oldDocument->unregisterNodeListCache(list); - newDocument->registerNodeListCache(list); - } + oldDocument->unregisterNodeListCache(list); + newDocument->registerNodeListCache(list); } NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end(); for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) { DynamicSubtreeNodeList* list = it->second; - if (list->isRootedAtDocument()) { - oldDocument->unregisterNodeListCache(list); - newDocument->registerNodeListCache(list); - } + oldDocument->unregisterNodeListCache(list); + newDocument->registerNodeListCache(list); } TagNodeListCacheNS::const_iterator tagEnd = m_tagNodeListCacheNS.end(); diff --git a/Source/WebCore/dom/NodeRenderingContext.cpp b/Source/WebCore/dom/NodeRenderingContext.cpp index 180aa94fe..84bdf90eb 100644 --- a/Source/WebCore/dom/NodeRenderingContext.cpp +++ b/Source/WebCore/dom/NodeRenderingContext.cpp @@ -325,7 +325,7 @@ void NodeRendererFactory::createRendererIfNeeded() #if ENABLE(FULLSCREEN_API) if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == node) - newRenderer = RenderFullScreen::wrapRenderer(newRenderer, document); + newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, document); #endif if (!newRenderer) diff --git a/Source/WebCore/dom/PropertyNodeList.cpp b/Source/WebCore/dom/PropertyNodeList.cpp index 3d3c042ba..1ebed0837 100644 --- a/Source/WebCore/dom/PropertyNodeList.cpp +++ b/Source/WebCore/dom/PropertyNodeList.cpp @@ -78,7 +78,7 @@ void PropertyNodeList::updateRefElements() const bool PropertyNodeList::nodeMatches(Element* testElement) const { - if (!testElement->isHTMLElement() || !testElement->fastHasAttribute(itempropAttr)) + if (!testElement->isHTMLElement() || !testElement->fastHasAttribute(itempropAttr) || testElement == ownerNode()) return false; for (unsigned i = 0; i < m_itemRefElementsCache.size(); ++i) { diff --git a/Source/WebCore/dom/QualifiedName.h b/Source/WebCore/dom/QualifiedName.h index de3827175..a62d4c2da 100644 --- a/Source/WebCore/dom/QualifiedName.h +++ b/Source/WebCore/dom/QualifiedName.h @@ -52,11 +52,11 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo<QualifiedNameImpl> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); - info.addString(m_prefix); - info.addString(m_localName); - info.addString(m_namespace); - info.addString(m_localNameUpper); + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + info.addMember(m_prefix); + info.addMember(m_localName); + info.addMember(m_namespace); + info.addMember(m_localNameUpper); } private: QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI) @@ -103,7 +103,7 @@ public: void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { - MemoryClassInfo<QualifiedName> info(memoryObjectInfo, this, MemoryInstrumentation::DOM); + MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::DOM); info.addInstrumentedMember(m_impl); } private: diff --git a/Source/WebCore/dom/Range.cpp b/Source/WebCore/dom/Range.cpp index 3a9fb48d8..e943cf5d9 100644 --- a/Source/WebCore/dom/Range.cpp +++ b/Source/WebCore/dom/Range.cpp @@ -303,13 +303,7 @@ bool Range::isPointInRange(Node* refNode, int offset, ExceptionCode& ec) return false; } - if (!refNode->attached()) { - // Firefox doesn't throw an exception for this case; it returns false. - return false; - } - - if (refNode->document() != m_ownerDocument) { - ec = WRONG_DOCUMENT_ERR; + if (!refNode->attached() || refNode->document() != m_ownerDocument) { return false; } diff --git a/Source/WebCore/dom/SecurityContext.h b/Source/WebCore/dom/SecurityContext.h index fc9df3e34..9cf49d398 100644 --- a/Source/WebCore/dom/SecurityContext.h +++ b/Source/WebCore/dom/SecurityContext.h @@ -49,6 +49,7 @@ enum SandboxFlag { SandboxPopups = 1 << 6, // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=12393 SandboxAutomaticFeatures = 1 << 7, SandboxSeamlessIframes = 1 << 8, + SandboxPointerLock = 1 << 9, SandboxAll = -1 // Mask with all bits set to 1. }; diff --git a/Source/WebCore/dom/ShadowRoot.cpp b/Source/WebCore/dom/ShadowRoot.cpp index 9e82ab2b4..b9c481c18 100644 --- a/Source/WebCore/dom/ShadowRoot.cpp +++ b/Source/WebCore/dom/ShadowRoot.cpp @@ -35,9 +35,12 @@ #include "Element.h" #include "ElementShadow.h" #include "HTMLContentElement.h" +#include "HTMLInputElement.h" #include "HTMLNames.h" +#include "HTMLTextAreaElement.h" #include "InsertionPoint.h" #include "NodeRareData.h" +#include "RuntimeEnabledFeatures.h" #include "SVGNames.h" #include "StyleResolver.h" #include "markup.h" @@ -75,6 +78,19 @@ ShadowRoot::~ShadowRoot() static bool allowsAuthorShadowRoot(Element* element) { +#if ENABLE(SHADOW_DOM) + if (RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled()) + return true; +#endif + + // FIXME: The elements in Shadow DOM of an input element assumes that they have renderer if the input + // element has a renderer. However, this does not hold until input elemnet is AuthorShadowDOM-ready. + // So we would like to prohibit having a AuthorShadowDOM for a while. The same thing happens to + // textarea element also. + // https://bugs.webkit.org/show_bug.cgi?id=92608 + if (isHTMLInputElement(element) || isHTMLTextAreaElement(element)) + return false; + // FIXME: We disable multiple shadow subtrees for SVG for while, because there will be problems to support it. // https://bugs.webkit.org/show_bug.cgi?id=78205 // Especially SVG TREF recreates shadow root dynamically. diff --git a/Source/WebCore/dom/StyledElement.cpp b/Source/WebCore/dom/StyledElement.cpp index 9ae672fa3..c5616b082 100644 --- a/Source/WebCore/dom/StyledElement.cpp +++ b/Source/WebCore/dom/StyledElement.cpp @@ -127,7 +127,7 @@ void StyledElement::updateStyleAttribute() const ASSERT(!isStyleAttributeValid()); setIsStyleAttributeValid(); if (const StylePropertySet* inlineStyle = this->inlineStyle()) - const_cast<StyledElement*>(this)->setAttribute(styleAttr, inlineStyle->asText(), InUpdateStyleAttribute); + const_cast<StyledElement*>(this)->setSynchronizedLazyAttribute(styleAttr, inlineStyle->asText()); } StyledElement::StyledElement(const QualifiedName& name, Document* document, ConstructionType type) @@ -170,10 +170,12 @@ void StyledElement::classAttributeChanged(const AtomicString& newClassString) if (hasClass) { const bool shouldFoldCase = document()->inQuirksMode(); ensureAttributeData()->setClass(newClassString, shouldFoldCase); - if (DOMTokenList* classList = optionalClassList()) - static_cast<ClassList*>(classList)->reset(newClassString); } else if (attributeData()) mutableAttributeData()->clearClass(); + + if (DOMTokenList* classList = optionalClassList()) + static_cast<ClassList*>(classList)->reset(newClassString); + setNeedsStyleRecalc(); } diff --git a/Source/WebCore/dom/StyledElement.h b/Source/WebCore/dom/StyledElement.h index 0f61d1c66..a080dc136 100644 --- a/Source/WebCore/dom/StyledElement.h +++ b/Source/WebCore/dom/StyledElement.h @@ -37,7 +37,7 @@ class StyledElement : public Element { public: virtual ~StyledElement(); - virtual StylePropertySet* additionalAttributeStyle() { return 0; } + virtual const StylePropertySet* additionalAttributeStyle() { return 0; } void invalidateStyleAttribute(); const StylePropertySet* inlineStyle() const { return attributeData() ? attributeData()->inlineStyle() : 0; } @@ -51,7 +51,7 @@ public: virtual CSSStyleDeclaration* style() OVERRIDE; - StylePropertySet* attributeStyle(); + const StylePropertySet* attributeStyle(); const SpaceSplitString& classNames() const; @@ -106,7 +106,7 @@ inline void StyledElement::invalidateStyleAttribute() clearIsStyleAttributeValid(); } -inline StylePropertySet* StyledElement::attributeStyle() +inline const StylePropertySet* StyledElement::attributeStyle() { if (attributeStyleDirty()) updateAttributeStyle(); diff --git a/Source/WebCore/dom/WebKitNamedFlow.cpp b/Source/WebCore/dom/WebKitNamedFlow.cpp index 7a07fba17..aa5901b67 100644 --- a/Source/WebCore/dom/WebKitNamedFlow.cpp +++ b/Source/WebCore/dom/WebKitNamedFlow.cpp @@ -30,9 +30,12 @@ #include "config.h" #include "WebKitNamedFlow.h" +#include "EventNames.h" #include "RenderNamedFlowThread.h" #include "RenderRegion.h" +#include "ScriptExecutionContext.h" #include "StaticNodeList.h" +#include "UIEvent.h" #include "WebKitNamedFlowCollection.h" namespace WebCore { @@ -114,7 +117,8 @@ PassRefPtr<NodeList> WebKitNamedFlow::getRegionsByContent(Node* contentNode) const RenderRegionList& regionList = m_parentFlowThread->renderRegionList(); for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) { const RenderRegion* renderRegion = *iter; - if (!renderRegion->isValid()) + // FIXME: Pseudo-elements are not included in the list + if (!renderRegion->isValid() || !renderRegion->node()) continue; if (m_parentFlowThread->objectInFlowRegion(contentNode->renderer(), renderRegion)) regionNodes.append(renderRegion->node()); @@ -124,6 +128,30 @@ PassRefPtr<NodeList> WebKitNamedFlow::getRegionsByContent(Node* contentNode) return StaticNodeList::adopt(regionNodes); } +PassRefPtr<NodeList> WebKitNamedFlow::getRegions() +{ + Vector<RefPtr<Node> > regionNodes; + + if (m_flowManager->document()) + m_flowManager->document()->updateLayoutIgnorePendingStylesheets(); + + // The renderer may be destroyed or created after the style update. + // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary. + if (!m_parentFlowThread) + return StaticNodeList::adopt(regionNodes); + + const RenderRegionList& regionList = m_parentFlowThread->renderRegionList(); + for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) { + const RenderRegion* renderRegion = *iter; + // FIXME: Pseudo-elements are not included in the list + if (!renderRegion->isValid() || !renderRegion->node()) + continue; + regionNodes.append(renderRegion->node()); + } + + return StaticNodeList::adopt(regionNodes); +} + PassRefPtr<NodeList> WebKitNamedFlow::getContent() { Vector<RefPtr<Node> > contentNodes; @@ -155,5 +183,40 @@ void WebKitNamedFlow::setRenderer(RenderNamedFlowThread* parentFlowThread) m_parentFlowThread = parentFlowThread; } +EventTargetData* WebKitNamedFlow::eventTargetData() +{ + return &m_eventTargetData; +} + +EventTargetData* WebKitNamedFlow::ensureEventTargetData() +{ + return &m_eventTargetData; +} + +void WebKitNamedFlow::dispatchRegionLayoutUpdateEvent() +{ + ASSERT(!eventDispatchForbidden()); + ASSERT(m_parentFlowThread); + + RefPtr<Event> event = UIEvent::create(eventNames().webkitRegionLayoutUpdateEvent, false, false, m_parentFlowThread->document()->defaultView(), 0); + + dispatchEvent(event); +} + +const AtomicString& WebKitNamedFlow::interfaceName() const +{ + return eventNames().interfaceForWebKitNamedFlow; +} + +ScriptExecutionContext* WebKitNamedFlow::scriptExecutionContext() const +{ + return m_flowManager->document(); +} + +Node* WebKitNamedFlow::base() const +{ + return m_flowManager->document(); +} + } // namespace WebCore diff --git a/Source/WebCore/dom/WebKitNamedFlow.h b/Source/WebCore/dom/WebKitNamedFlow.h index 5a39e8d9c..b51eadfb9 100644 --- a/Source/WebCore/dom/WebKitNamedFlow.h +++ b/Source/WebCore/dom/WebKitNamedFlow.h @@ -30,18 +30,23 @@ #ifndef WebKitNamedFlow_h #define WebKitNamedFlow_h -#include <Node.h> +#include "EventTarget.h" + #include <wtf/ListHashSet.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/text/AtomicString.h> namespace WebCore { +class Document; +class Node; class NodeList; class RenderNamedFlowThread; +class ScriptExecutionContext; class WebKitNamedFlowCollection; -class WebKitNamedFlow : public RefCounted<WebKitNamedFlow> { +class WebKitNamedFlow : public RefCounted<WebKitNamedFlow>, public EventTarget { public: static PassRefPtr<WebKitNamedFlow> create(PassRefPtr<WebKitNamedFlowCollection> manager, const AtomicString& flowThreadName); @@ -51,8 +56,19 @@ public: bool overset() const; int firstEmptyRegionIndex() const; PassRefPtr<NodeList> getRegionsByContent(Node*); + PassRefPtr<NodeList> getRegions(); PassRefPtr<NodeList> getContent(); + using RefCounted<WebKitNamedFlow>::ref; + using RefCounted<WebKitNamedFlow>::deref; + + virtual const AtomicString& interfaceName() const; + virtual ScriptExecutionContext* scriptExecutionContext() const; + + // This function is called from the JS binding code to determine if the NamedFlow object is reachable or not. + // If the object has listeners, the object should only be discarded if the parent Document is not reachable. + Node* base() const; + void setRenderer(RenderNamedFlowThread* parentFlowThread); enum FlowState { @@ -62,14 +78,25 @@ public: FlowState flowState() const { return m_parentFlowThread ? FlowStateCreated : FlowStateNull; } + void dispatchRegionLayoutUpdateEvent(); + private: WebKitNamedFlow(PassRefPtr<WebKitNamedFlowCollection>, const AtomicString&); + // EventTarget implementation. + virtual void refEventTarget() { ref(); } + virtual void derefEventTarget() { deref(); } + + virtual EventTargetData* eventTargetData() OVERRIDE; + virtual EventTargetData* ensureEventTargetData() OVERRIDE; + // The name of the flow thread as specified in CSS. AtomicString m_flowThreadName; RefPtr<WebKitNamedFlowCollection> m_flowManager; RenderNamedFlowThread* m_parentFlowThread; + + EventTargetData m_eventTargetData; }; } diff --git a/Source/WebCore/dom/WebKitNamedFlow.idl b/Source/WebCore/dom/WebKitNamedFlow.idl index 4d4e99b7e..45b43e787 100644 --- a/Source/WebCore/dom/WebKitNamedFlow.idl +++ b/Source/WebCore/dom/WebKitNamedFlow.idl @@ -29,13 +29,26 @@ module core { interface [ - JSGenerateToJSObject + EventTarget, + JSGenerateToJSObject, + GenerateIsReachable=ImplBaseRoot ] WebKitNamedFlow { readonly attribute DOMString name; readonly attribute boolean overset; readonly attribute long firstEmptyRegionIndex; NodeList getRegionsByContent(in Node contentNode); + NodeList getRegions(); NodeList getContent(); + + // EventTarget interface + void addEventListener(in DOMString type, + in EventListener listener, + in [Optional] boolean useCapture); + void removeEventListener(in DOMString type, + in EventListener listener, + in [Optional] boolean useCapture); + boolean dispatchEvent(in Event event) + raises(EventException); }; } diff --git a/Source/WebCore/dom/WebKitNamedFlowCollection.cpp b/Source/WebCore/dom/WebKitNamedFlowCollection.cpp index c50e0572f..9273727ef 100644 --- a/Source/WebCore/dom/WebKitNamedFlowCollection.cpp +++ b/Source/WebCore/dom/WebKitNamedFlowCollection.cpp @@ -31,6 +31,7 @@ #include "WebKitNamedFlowCollection.h" #include "Document.h" +#include "InspectorInstrumentation.h" #include "WebKitNamedFlow.h" #include <wtf/text/StringHash.h> @@ -43,15 +44,15 @@ WebKitNamedFlowCollection::WebKitNamedFlowCollection(Document* doc) { } -Vector<String> WebKitNamedFlowCollection::namedFlowsNames() +Vector<RefPtr<WebKitNamedFlow> > WebKitNamedFlowCollection::namedFlows() { - Vector<String> namedFlows; + Vector<RefPtr<WebKitNamedFlow> > namedFlows; for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it) { if ((*it)->flowState() == WebKitNamedFlow::FlowStateNull) continue; - namedFlows.append((*it)->name().string()); + namedFlows.append(RefPtr<WebKitNamedFlow>(*it)); } return namedFlows; @@ -79,6 +80,8 @@ PassRefPtr<WebKitNamedFlow> WebKitNamedFlowCollection::ensureFlowWithName(const RefPtr<WebKitNamedFlow> newFlow = WebKitNamedFlow::create(this, flowName); m_namedFlows.add(newFlow.get()); + InspectorInstrumentation::didCreateNamedFlow(m_document, newFlow->name()); + return newFlow.release(); } @@ -92,6 +95,8 @@ void WebKitNamedFlowCollection::discardNamedFlow(WebKitNamedFlow* namedFlow) ASSERT(m_namedFlows.contains(namedFlow)); m_namedFlows.remove(namedFlow); + + InspectorInstrumentation::didRemoveNamedFlow(m_document, namedFlow->name()); } void WebKitNamedFlowCollection::documentDestroyed() diff --git a/Source/WebCore/dom/WebKitNamedFlowCollection.h b/Source/WebCore/dom/WebKitNamedFlowCollection.h index 67878a71a..bf01d4b84 100644 --- a/Source/WebCore/dom/WebKitNamedFlowCollection.h +++ b/Source/WebCore/dom/WebKitNamedFlowCollection.h @@ -45,7 +45,7 @@ class WebKitNamedFlowCollection : public RefCounted<WebKitNamedFlowCollection> { public: static PassRefPtr<WebKitNamedFlowCollection> create(Document* doc) { return adoptRef(new WebKitNamedFlowCollection(doc)); } - Vector<String> namedFlowsNames(); + Vector<RefPtr<WebKitNamedFlow> > namedFlows(); WebKitNamedFlow* flowByName(const String&); PassRefPtr<WebKitNamedFlow> ensureFlowWithName(const String&); |