/* * Copyright (C) 2009, 2015 Apple Inc. All rights reserved. * Copyright (C) 2011 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: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 InspectorDOMAgent_h #define InspectorDOMAgent_h #include "EventTarget.h" #include "InspectorWebAgentBase.h" #include "RenderLayer.h" #include "Timer.h" #include #include #include #include #include #include #include #include #include namespace Deprecated { class ScriptValue; } namespace Inspector { class InjectedScriptManager; } namespace WebCore { class AccessibilityObject; class ContainerNode; class CharacterData; class DOMEditor; class Document; class Element; class Event; class InspectorHistory; class InspectorOverlay; class InspectorPageAgent; class HitTestResult; class HTMLElement; class NameNodeMap; class Node; class RevalidateStyleAttributeTask; class ShadowRoot; struct HighlightConfig; typedef String ErrorString; typedef int BackendNodeId; struct EventListenerInfo { EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector) : node(node) , eventType(eventType) , eventListenerVector(eventListenerVector) { } Node* node; const AtomicString eventType; const EventListenerVector eventListenerVector; }; class InspectorDOMAgent final : public InspectorAgentBase, public Inspector::DOMBackendDispatcherHandler { WTF_MAKE_NONCOPYABLE(InspectorDOMAgent); WTF_MAKE_FAST_ALLOCATED; public: struct DOMListener { virtual ~DOMListener() { } virtual void didRemoveDocument(Document*) = 0; virtual void didRemoveDOMNode(Node*) = 0; virtual void didModifyDOMAttr(Element*) = 0; }; InspectorDOMAgent(WebAgentContext&, InspectorPageAgent*, InspectorOverlay*); virtual ~InspectorDOMAgent(); static String toErrorString(const ExceptionCode&); virtual void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; virtual void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; Vector documents(); void reset(); // Methods called from the frontend for DOM nodes inspection. virtual void querySelector(ErrorString&, int nodeId, const String& selectors, int* elementId) override; virtual void querySelectorAll(ErrorString&, int nodeId, const String& selectors, RefPtr>& result) override; virtual void getDocument(ErrorString&, RefPtr& root) override; virtual void requestChildNodes(ErrorString&, int nodeId, const int* depth) override; virtual void setAttributeValue(ErrorString&, int elementId, const String& name, const String& value) override; virtual void setAttributesAsText(ErrorString&, int elementId, const String& text, const String* name) override; virtual void removeAttribute(ErrorString&, int elementId, const String& name) override; virtual void removeNode(ErrorString&, int nodeId) override; virtual void setNodeName(ErrorString&, int nodeId, const String& name, int* newId) override; virtual void getOuterHTML(ErrorString&, int nodeId, WTF::String* outerHTML) override; virtual void setOuterHTML(ErrorString&, int nodeId, const String& outerHTML) override; virtual void setNodeValue(ErrorString&, int nodeId, const String& value) override; virtual void getEventListenersForNode(ErrorString&, int nodeId, const WTF::String* objectGroup, RefPtr>& listenersArray) override; virtual void getAccessibilityPropertiesForNode(ErrorString&, int nodeId, RefPtr& axProperties) override; virtual void performSearch(ErrorString&, const String& whitespaceTrimmedQuery, const Inspector::InspectorArray* nodeIds, String* searchId, int* resultCount) override; virtual void getSearchResults(ErrorString&, const String& searchId, int fromIndex, int toIndex, RefPtr>&) override; virtual void discardSearchResults(ErrorString&, const String& searchId) override; virtual void resolveNode(ErrorString&, int nodeId, const String* objectGroup, RefPtr& result) override; virtual void getAttributes(ErrorString&, int nodeId, RefPtr>& result) override; virtual void setInspectModeEnabled(ErrorString&, bool enabled, const Inspector::InspectorObject* highlightConfig) override; virtual void requestNode(ErrorString&, const String& objectId, int* nodeId) override; virtual void pushNodeByPathToFrontend(ErrorString&, const String& path, int* nodeId) override; virtual void pushNodeByBackendIdToFrontend(ErrorString&, BackendNodeId, int* nodeId) override; virtual void releaseBackendNodeIds(ErrorString&, const String& nodeGroup) override; virtual void hideHighlight(ErrorString&) override; virtual void highlightRect(ErrorString&, int x, int y, int width, int height, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor, const bool* usePageCoordinates) override; virtual void highlightQuad(ErrorString&, const Inspector::InspectorArray& quad, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor, const bool* usePageCoordinates) override; virtual void highlightSelector(ErrorString&, const Inspector::InspectorObject& highlightConfig, const String& selectorString, const String* frameId) override; virtual void highlightNode(ErrorString&, const Inspector::InspectorObject& highlightConfig, const int* nodeId, const String* objectId) override; virtual void highlightFrame(ErrorString&, const String& frameId, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor) override; virtual void moveTo(ErrorString&, int nodeId, int targetNodeId, const int* anchorNodeId, int* newNodeId) override; virtual void undo(ErrorString&) override; virtual void redo(ErrorString&) override; virtual void markUndoableState(ErrorString&) override; virtual void focus(ErrorString&, int nodeId) override; void getEventListeners(Node*, Vector& listenersArray, bool includeAncestors); // InspectorInstrumentation callbacks. void didInsertDOMNode(Node&); void didRemoveDOMNode(Node&); void willModifyDOMAttr(Element&, const AtomicString& oldValue, const AtomicString& newValue); void didModifyDOMAttr(Element&, const AtomicString& name, const AtomicString& value); void didRemoveDOMAttr(Element&, const AtomicString& name); void characterDataModified(CharacterData&); void didInvalidateStyleAttr(Node&); void didPushShadowRoot(Element& host, ShadowRoot&); void willPopShadowRoot(Element& host, ShadowRoot&); bool handleTouchEvent(Node&); void didCommitLoad(Document*); void frameDocumentUpdated(Frame*); void pseudoElementCreated(PseudoElement&); void pseudoElementDestroyed(PseudoElement&); // Callbacks that don't directly correspond to an instrumentation entry point. void setDocument(Document*); void releaseDanglingNodes(); void mainFrameDOMContentLoaded(); void styleAttributeInvalidated(const Vector& elements); int pushNodeToFrontend(ErrorString&, int documentNodeId, Node*); Node* nodeForId(int nodeId); int boundNodeId(Node*); void setDOMListener(DOMListener*); BackendNodeId backendNodeIdForNode(Node*, const String& nodeGroup); static String documentURLString(Document*); RefPtr resolveNode(Node*, const String& objectGroup); bool handleMousePress(); void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); void inspect(Node*); void focusNode(); InspectorHistory* history() { return m_history.get(); } // We represent embedded doms as a part of the same hierarchy. Hence we treat children of frame owners differently. // We also skip whitespace text nodes conditionally. Following methods encapsulate these specifics. static Node* innerFirstChild(Node*); static Node* innerNextSibling(Node*); static Node* innerPreviousSibling(Node*); static unsigned innerChildNodeCount(Node*); static Node* innerParentNode(Node*); static bool isWhitespace(Node*); Node* assertNode(ErrorString&, int nodeId); Element* assertElement(ErrorString&, int nodeId); Document* assertDocument(ErrorString&, int nodeId); static Node* scriptValueAsNode(Deprecated::ScriptValue); static Deprecated::ScriptValue nodeAsScriptValue(JSC::ExecState*, Node*); // Methods called from other agents. InspectorPageAgent* pageAgent() { return m_pageAgent; } private: void setSearchingForNode(ErrorString&, bool enabled, const Inspector::InspectorObject* highlightConfig); std::unique_ptr highlightConfigFromInspectorObject(ErrorString&, const Inspector::InspectorObject* highlightInspectorObject); // Node-related methods. typedef HashMap, int> NodeToIdMap; int bind(Node*, NodeToIdMap*); void unbind(Node*, NodeToIdMap*); Node* assertEditableNode(ErrorString&, int nodeId); Element* assertEditableElement(ErrorString&, int nodeId); int pushNodePathToFrontend(Node*); void pushChildNodesToFrontend(int nodeId, int depth = 1); bool hasBreakpoint(Node*, int type); void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value); Ref buildObjectForNode(Node*, int depth, NodeToIdMap*); Ref> buildArrayForElementAttributes(Element*); Ref> buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap); RefPtr> buildArrayForPseudoElements(const Element&, NodeToIdMap* nodesMap); Ref buildObjectForEventListener(const RegisteredEventListener&, const AtomicString& eventType, Node*, const String* objectGroupId); RefPtr buildObjectForAccessibilityProperties(Node*); void processAccessibilityChildren(RefPtr&&, RefPtr>&&); Node* nodeForPath(const String& path); Node* nodeForObjectId(const String& objectId); void discardBindings(); void innerHighlightQuad(std::unique_ptr, const Inspector::InspectorObject* color, const Inspector::InspectorObject* outlineColor, const bool* usePageCoordinates); Inspector::InjectedScriptManager& m_injectedScriptManager; std::unique_ptr m_frontendDispatcher; RefPtr m_backendDispatcher; InspectorPageAgent* m_pageAgent { nullptr }; InspectorOverlay* m_overlay { nullptr }; DOMListener* m_domListener { nullptr }; NodeToIdMap m_documentNodeToIdMap; typedef HashMap, BackendNodeId> NodeToBackendIdMap; HashMap m_nodeGroupToBackendIdMap; // Owns node mappings for dangling nodes. Vector> m_danglingNodeToIdMaps; HashMap m_idToNode; HashMap m_idToNodesMap; HashSet m_childrenRequested; HashMap> m_backendIdToNode; int m_lastNodeId { 1 }; BackendNodeId m_lastBackendNodeId { -1 }; RefPtr m_document; typedef HashMap>> SearchResults; SearchResults m_searchResults; std::unique_ptr m_revalidateStyleAttrTask; RefPtr m_nodeToFocus; bool m_searchingForNode { false }; std::unique_ptr m_inspectModeHighlightConfig; std::unique_ptr m_history; std::unique_ptr m_domEditor; bool m_suppressAttributeModifiedEvent { false }; bool m_documentRequested { false }; }; } // namespace WebCore #endif // !defined(InspectorDOMAgent_h)