summaryrefslogtreecommitdiff
path: root/Source/WebCore/inspector/InspectorDOMAgent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/inspector/InspectorDOMAgent.cpp')
-rw-r--r--Source/WebCore/inspector/InspectorDOMAgent.cpp1364
1 files changed, 934 insertions, 430 deletions
diff --git a/Source/WebCore/inspector/InspectorDOMAgent.cpp b/Source/WebCore/inspector/InspectorDOMAgent.cpp
index f24caaa74..69331f427 100644
--- a/Source/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/Source/WebCore/inspector/InspectorDOMAgent.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2015-2016 Apple Inc. All rights reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2009 Joseph Pecoraro
*
@@ -12,7 +12,7 @@
* 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 Computer, Inc. ("Apple") nor the names of
+ * 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.
*
@@ -29,11 +29,10 @@
*/
#include "config.h"
-
-#if ENABLE(INSPECTOR)
-
#include "InspectorDOMAgent.h"
+#include "AXObjectCache.h"
+#include "AccessibilityNodeObject.h"
#include "Attr.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSPropertyNames.h"
@@ -50,27 +49,28 @@
#include "DOMPatchSupport.h"
#include "DOMWindow.h"
#include "Document.h"
-#include "DocumentFragment.h"
#include "DocumentType.h"
#include "Element.h"
#include "Event.h"
#include "EventListener.h"
-#include "EventNames.h"
-#include "EventTarget.h"
+#include "ExceptionCodeDescription.h"
#include "FrameTree.h"
#include "HTMLElement.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
+#include "HTMLScriptElement.h"
+#include "HTMLStyleElement.h"
#include "HTMLTemplateElement.h"
#include "HitTestResult.h"
-#include "IdentifiersFactory.h"
+#include "InspectorClient.h"
+#include "InspectorController.h"
#include "InspectorHistory.h"
#include "InspectorNodeFinder.h"
#include "InspectorOverlay.h"
#include "InspectorPageAgent.h"
-#include "InspectorWebFrontendDispatchers.h"
#include "InstrumentingAgents.h"
#include "IntRect.h"
+#include "JSDOMBindingSecurity.h"
#include "JSEventListener.h"
#include "JSNode.h"
#include "MainFrame.h"
@@ -79,23 +79,26 @@
#include "NodeList.h"
#include "Page.h"
#include "Pasteboard.h"
+#include "PseudoElement.h"
#include "RenderStyle.h"
#include "RenderStyleConstants.h"
#include "ScriptState.h"
-#include "Settings.h"
#include "ShadowRoot.h"
#include "StyleProperties.h"
#include "StyleResolver.h"
#include "StyleSheetList.h"
#include "Text.h"
+#include "TextNodeTraversal.h"
+#include "Timer.h"
#include "XPathResult.h"
#include "htmlediting.h"
#include "markup.h"
+#include <inspector/IdentifiersFactory.h>
#include <inspector/InjectedScript.h>
#include <inspector/InjectedScriptManager.h>
-#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/Vector.h>
+#include <pal/crypto/CryptoDigest.h>
+#include <runtime/JSCInlines.h>
+#include <wtf/text/Base64.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
@@ -108,23 +111,19 @@ using namespace HTMLNames;
static const size_t maxTextSize = 10000;
static const UChar ellipsisUChar[] = { 0x2026, 0 };
-static Color parseColor(const RefPtr<InspectorObject>* colorObject)
+static Color parseColor(const InspectorObject* colorObject)
{
- if (!colorObject || !(*colorObject))
+ if (!colorObject)
return Color::transparent;
- int r;
- int g;
- int b;
- bool success = (*colorObject)->getNumber("r", &r);
- success |= (*colorObject)->getNumber("g", &g);
- success |= (*colorObject)->getNumber("b", &b);
- if (!success)
+ int r = 0;
+ int g = 0;
+ int b = 0;
+ if (!colorObject->getInteger("r", r) || !colorObject->getInteger("g", g) || !colorObject->getInteger("b", b))
return Color::transparent;
- double a;
- success = (*colorObject)->getNumber("a", &a);
- if (!success)
+ double a = 1.0;
+ if (!colorObject->getDouble("a", a))
return Color(r, g, b);
// Clamp alpha to the [0..1] range.
@@ -136,22 +135,22 @@ static Color parseColor(const RefPtr<InspectorObject>* colorObject)
return Color(r, g, b, static_cast<int>(a * 255));
}
-static Color parseConfigColor(const String& fieldName, InspectorObject* configObject)
+static Color parseConfigColor(const String& fieldName, const InspectorObject* configObject)
{
- const RefPtr<InspectorObject> colorObject = configObject->getObject(fieldName);
- return parseColor(&colorObject);
+ RefPtr<InspectorObject> colorObject;
+ configObject->getObject(fieldName, colorObject);
+
+ return parseColor(colorObject.get());
}
-static bool parseQuad(const RefPtr<InspectorArray>& quadArray, FloatQuad* quad)
+static bool parseQuad(const InspectorArray& quadArray, FloatQuad* quad)
{
- if (!quadArray)
- return false;
const size_t coordinatesInQuad = 8;
double coordinates[coordinatesInQuad];
- if (quadArray->length() != coordinatesInQuad)
+ if (quadArray.length() != coordinatesInQuad)
return false;
for (size_t i = 0; i < coordinatesInQuad; ++i) {
- if (!quadArray->get(i)->asNumber(coordinates + i))
+ if (!quadArray.get(i)->asDouble(*(coordinates + i)))
return false;
}
quad->setP1(FloatPoint(coordinates[0], coordinates[1]));
@@ -168,17 +167,17 @@ public:
RevalidateStyleAttributeTask(InspectorDOMAgent*);
void scheduleFor(Element*);
void reset() { m_timer.stop(); }
- void timerFired(Timer<RevalidateStyleAttributeTask>&);
+ void timerFired();
private:
InspectorDOMAgent* m_domAgent;
- Timer<RevalidateStyleAttributeTask> m_timer;
+ Timer m_timer;
HashSet<RefPtr<Element>> m_elements;
};
RevalidateStyleAttributeTask::RevalidateStyleAttributeTask(InspectorDOMAgent* domAgent)
: m_domAgent(domAgent)
- , m_timer(this, &RevalidateStyleAttributeTask::timerFired)
+ , m_timer(*this, &RevalidateStyleAttributeTask::timerFired)
{
}
@@ -189,37 +188,38 @@ void RevalidateStyleAttributeTask::scheduleFor(Element* element)
m_timer.startOneShot(0);
}
-void RevalidateStyleAttributeTask::timerFired(Timer<RevalidateStyleAttributeTask>&)
+void RevalidateStyleAttributeTask::timerFired()
{
// The timer is stopped on m_domAgent destruction, so this method will never be called after m_domAgent has been destroyed.
Vector<Element*> elements;
- for (HashSet<RefPtr<Element>>::iterator it = m_elements.begin(), end = m_elements.end(); it != end; ++it)
- elements.append(it->get());
+ for (auto& element : m_elements)
+ elements.append(element.get());
m_domAgent->styleAttributeInvalidated(elements);
m_elements.clear();
}
-String InspectorDOMAgent::toErrorString(const ExceptionCode& ec)
+String InspectorDOMAgent::toErrorString(ExceptionCode ec)
{
if (ec) {
ExceptionCodeDescription description(ec);
return description.name;
}
- return "";
+ return emptyString();
}
-InspectorDOMAgent::InspectorDOMAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
- : InspectorAgentBase(ASCIILiteral("DOM"), instrumentingAgents)
+String InspectorDOMAgent::toErrorString(Exception&& exception)
+{
+ return ExceptionCodeDescription { exception.code() }.name;
+}
+
+InspectorDOMAgent::InspectorDOMAgent(WebAgentContext& context, InspectorPageAgent* pageAgent, InspectorOverlay* overlay)
+ : InspectorAgentBase(ASCIILiteral("DOM"), context)
+ , m_injectedScriptManager(context.injectedScriptManager)
+ , m_frontendDispatcher(std::make_unique<Inspector::DOMFrontendDispatcher>(context.frontendRouter))
+ , m_backendDispatcher(Inspector::DOMBackendDispatcher::create(context.backendDispatcher, this))
, m_pageAgent(pageAgent)
- , m_injectedScriptManager(injectedScriptManager)
, m_overlay(overlay)
- , m_domListener(0)
- , m_lastNodeId(1)
- , m_lastBackendNodeId(-1)
- , m_searchingForNode(false)
- , m_suppressAttributeModifiedEvent(false)
- , m_documentRequested(false)
{
}
@@ -229,34 +229,29 @@ InspectorDOMAgent::~InspectorDOMAgent()
ASSERT(!m_searchingForNode);
}
-void InspectorDOMAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
+void InspectorDOMAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*)
{
- m_frontendDispatcher = std::make_unique<InspectorDOMFrontendDispatcher>(frontendChannel);
- m_backendDispatcher = InspectorDOMBackendDispatcher::create(backendDispatcher, this);
-
- m_history = adoptPtr(new InspectorHistory());
- m_domEditor = adoptPtr(new DOMEditor(m_history.get()));
+ m_history = std::make_unique<InspectorHistory>();
+ m_domEditor = std::make_unique<DOMEditor>(*m_history);
- m_instrumentingAgents->setInspectorDOMAgent(this);
- m_document = m_pageAgent->mainFrame()->document();
+ m_instrumentingAgents.setInspectorDOMAgent(this);
+ m_document = m_pageAgent->mainFrame().document();
if (m_nodeToFocus)
focusNode();
}
-void InspectorDOMAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
+void InspectorDOMAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
{
- m_frontendDispatcher = nullptr;
- m_backendDispatcher.clear();
-
- m_history.clear();
- m_domEditor.clear();
+ m_history.reset();
+ m_domEditor.reset();
+ m_mousedOverNode = nullptr;
- ErrorString error;
- setSearchingForNode(&error, false, 0);
- hideHighlight(&error);
+ ErrorString unused;
+ setSearchingForNode(unused, false, nullptr);
+ hideHighlight(unused);
- m_instrumentingAgents->setInspectorDOMAgent(0);
+ m_instrumentingAgents.setInspectorDOMAgent(nullptr);
m_documentRequested = false;
reset();
}
@@ -281,7 +276,7 @@ void InspectorDOMAgent::reset()
discardBindings();
if (m_revalidateStyleAttrTask)
m_revalidateStyleAttrTask->reset();
- m_document = 0;
+ m_document = nullptr;
}
void InspectorDOMAgent::setDOMListener(DOMListener* listener)
@@ -289,20 +284,20 @@ void InspectorDOMAgent::setDOMListener(DOMListener* listener)
m_domListener = listener;
}
-void InspectorDOMAgent::setDocument(Document* doc)
+void InspectorDOMAgent::setDocument(Document* document)
{
- if (doc == m_document.get())
+ if (document == m_document.get())
return;
reset();
- m_document = doc;
+ m_document = document;
if (!m_documentRequested)
return;
- // Immediately communicate 0 document or document that has finished loading.
- if (!doc || !doc->parsing())
+ // Immediately communicate null document or document that has finished loading.
+ if (!document || !document->parsing())
m_frontendDispatcher->documentUpdated();
}
@@ -333,21 +328,23 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
if (node->isFrameOwnerElement()) {
const HTMLFrameOwnerElement* frameOwner = static_cast<const HTMLFrameOwnerElement*>(node);
- Document* contentDocument = frameOwner->contentDocument();
- if (m_domListener)
- m_domListener->didRemoveDocument(contentDocument);
- if (contentDocument)
+ if (Document* contentDocument = frameOwner->contentDocument())
unbind(contentDocument, nodesMap);
}
- if (node->isElementNode()) {
- if (ShadowRoot* root = toElement(node)->shadowRoot())
+ if (is<Element>(*node)) {
+ Element& element = downcast<Element>(*node);
+ if (ShadowRoot* root = element.shadowRoot())
unbind(root, nodesMap);
+ if (PseudoElement* beforeElement = element.beforePseudoElement())
+ unbind(beforeElement, nodesMap);
+ if (PseudoElement* afterElement = element.afterPseudoElement())
+ unbind(afterElement, nodesMap);
}
nodesMap->remove(node);
if (m_domListener)
- m_domListener->didRemoveDOMNode(node);
+ m_domListener->didRemoveDOMNode(*node, id);
bool childrenRequested = m_childrenRequested.contains(id);
if (childrenRequested) {
@@ -361,70 +358,78 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
}
}
-Node* InspectorDOMAgent::assertNode(ErrorString* errorString, int nodeId)
+Node* InspectorDOMAgent::assertNode(ErrorString& errorString, int nodeId)
{
Node* node = nodeForId(nodeId);
if (!node) {
- *errorString = "Could not find node with given id";
+ errorString = ASCIILiteral("Could not find node with given id");
return nullptr;
}
return node;
}
-Document* InspectorDOMAgent::assertDocument(ErrorString* errorString, int nodeId)
+Document* InspectorDOMAgent::assertDocument(ErrorString& errorString, int nodeId)
{
Node* node = assertNode(errorString, nodeId);
if (!node)
return nullptr;
- if (!node->isDocumentNode()) {
- *errorString = "Document is not available";
+ if (!is<Document>(*node)) {
+ errorString = ASCIILiteral("Document is not available");
return nullptr;
}
- return toDocument(node);
+ return downcast<Document>(node);
}
-Element* InspectorDOMAgent::assertElement(ErrorString* errorString, int nodeId)
+Element* InspectorDOMAgent::assertElement(ErrorString& errorString, int nodeId)
{
Node* node = assertNode(errorString, nodeId);
if (!node)
return nullptr;
- if (!node->isElementNode()) {
- *errorString = "Node is not an Element";
+ if (!is<Element>(*node)) {
+ errorString = ASCIILiteral("Node is not an Element");
return nullptr;
}
- return toElement(node);
+ return downcast<Element>(node);
}
-Node* InspectorDOMAgent::assertEditableNode(ErrorString* errorString, int nodeId)
+Node* InspectorDOMAgent::assertEditableNode(ErrorString& errorString, int nodeId)
{
Node* node = assertNode(errorString, nodeId);
if (!node)
return nullptr;
- if (node->isInShadowTree()) {
- *errorString = "Can not edit nodes from shadow trees";
+ if (node->isInUserAgentShadowTree()) {
+ errorString = ASCIILiteral("Cannot edit nodes in user agent shadow trees");
+ return nullptr;
+ }
+ if (node->isPseudoElement()) {
+ errorString = ASCIILiteral("Cannot edit pseudo elements");
return nullptr;
}
return node;
}
-Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int nodeId)
+Element* InspectorDOMAgent::assertEditableElement(ErrorString& errorString, int nodeId)
{
Element* element = assertElement(errorString, nodeId);
if (!element)
return nullptr;
- if (element->isInShadowTree()) {
- *errorString = "Can not edit elements from shadow trees";
+ if (element->isInUserAgentShadowTree()) {
+ errorString = ASCIILiteral("Cannot edit elements in user agent shadow trees");
+ return nullptr;
+ }
+ if (element->isPseudoElement()) {
+ errorString = ASCIILiteral("Cannot edit pseudo elements");
return nullptr;
}
return element;
}
-void InspectorDOMAgent::getDocument(ErrorString* errorString, RefPtr<Inspector::TypeBuilder::DOM::Node>& root)
+void InspectorDOMAgent::getDocument(ErrorString& errorString, RefPtr<Inspector::Protocol::DOM::Node>& root)
{
m_documentRequested = true;
if (!m_document) {
- *errorString = "Document is not available";
+ errorString = ASCIILiteral("Document is not available");
return;
}
@@ -459,8 +464,8 @@ void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth)
return;
}
- RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = buildArrayForContainerChildren(node, depth, nodeMap);
- m_frontendDispatcher->setChildNodes(nodeId, children.release());
+ auto children = buildArrayForContainerChildren(node, depth, nodeMap);
+ m_frontendDispatcher->setChildNodes(nodeId, WTFMove(children));
}
void InspectorDOMAgent::discardBindings()
@@ -473,13 +478,13 @@ void InspectorDOMAgent::discardBindings()
m_nodeGroupToBackendIdMap.clear();
}
-int InspectorDOMAgent::pushNodeToFrontend(ErrorString* errorString, int documentNodeId, Node* nodeToPush)
+int InspectorDOMAgent::pushNodeToFrontend(ErrorString& errorString, int documentNodeId, Node* nodeToPush)
{
Document* document = assertDocument(errorString, documentNodeId);
if (!document)
return 0;
if (&nodeToPush->document() != document) {
- *errorString = "Node is not part of the document with given id";
+ errorString = ASCIILiteral("Node is not part of the document with given id");
return 0;
}
@@ -497,7 +502,7 @@ Node* InspectorDOMAgent::nodeForId(int id)
return 0;
}
-void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, int nodeId, const int* depth)
+void InspectorDOMAgent::requestChildNodes(ErrorString& errorString, int nodeId, const int* depth)
{
int sanitizedDepth;
@@ -508,54 +513,52 @@ void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, int nodeId,
else if (*depth > 0)
sanitizedDepth = *depth;
else {
- *errorString = "Please provide a positive integer as a depth or -1 for entire subtree";
+ errorString = ASCIILiteral("Please provide a positive integer as a depth or -1 for entire subtree");
return;
}
pushChildNodesToFrontend(nodeId, sanitizedDepth);
}
-void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, const String& selectors, int* elementId)
+void InspectorDOMAgent::querySelector(ErrorString& errorString, int nodeId, const String& selectors, int* elementId)
{
*elementId = 0;
Node* node = assertNode(errorString, nodeId);
if (!node)
return;
- if (!node->isContainerNode()) {
+ if (!is<ContainerNode>(*node)) {
assertElement(errorString, nodeId);
return;
}
- ExceptionCode ec = 0;
- RefPtr<Element> element = toContainerNode(node)->querySelector(selectors, ec);
- if (ec) {
- *errorString = "DOM Error while querying";
+ auto queryResult = downcast<ContainerNode>(*node).querySelector(selectors);
+ if (queryResult.hasException()) {
+ errorString = ASCIILiteral("DOM Error while querying");
return;
}
- if (element)
- *elementId = pushNodePathToFrontend(element.get());
+ if (auto* element = queryResult.releaseReturnValue())
+ *elementId = pushNodePathToFrontend(element);
}
-void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, const String& selectors, RefPtr<Inspector::TypeBuilder::Array<int>>& result)
+void InspectorDOMAgent::querySelectorAll(ErrorString& errorString, int nodeId, const String& selectors, RefPtr<Inspector::Protocol::Array<int>>& result)
{
Node* node = assertNode(errorString, nodeId);
if (!node)
return;
- if (!node->isContainerNode()) {
+ if (!is<ContainerNode>(*node)) {
assertElement(errorString, nodeId);
return;
}
- ExceptionCode ec = 0;
- RefPtr<NodeList> nodes = toContainerNode(node)->querySelectorAll(selectors, ec);
- if (ec) {
- *errorString = "DOM Error while querying";
+ auto queryResult = downcast<ContainerNode>(*node).querySelectorAll(selectors);
+ if (queryResult.hasException()) {
+ errorString = ASCIILiteral("DOM Error while querying");
return;
}
- result = Inspector::TypeBuilder::Array<int>::create();
-
+ auto nodes = queryResult.releaseReturnValue();
+ result = Inspector::Protocol::Array<int>::create();
for (unsigned i = 0; i < nodes->length(); ++i)
result->addItem(pushNodePathToFrontend(nodes->item(i)));
}
@@ -582,12 +585,12 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
Node* parent = innerParentNode(node);
if (!parent) {
// Node being pushed is detached -> push subtree root.
- OwnPtr<NodeToIdMap> newMap = adoptPtr(new NodeToIdMap);
+ auto newMap = std::make_unique<NodeToIdMap>();
danglingMap = newMap.get();
m_danglingNodeToIdMaps.append(newMap.release());
- RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>::create();
+ auto children = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create();
children->addItem(buildObjectForNode(node, 0, danglingMap));
- m_frontendDispatcher->setChildNodes(0, children);
+ m_frontendDispatcher->setChildNodes(0, WTFMove(children));
break;
} else {
path.append(parent);
@@ -607,9 +610,9 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
return map->get(nodeToPush);
}
-int InspectorDOMAgent::boundNodeId(Node* node)
+int InspectorDOMAgent::boundNodeId(const Node* node)
{
- return m_documentNodeToIdMap.get(node);
+ return m_documentNodeToIdMap.get(const_cast<Node*>(node));
}
BackendNodeId InspectorDOMAgent::backendNodeIdForNode(Node* node, const String& nodeGroup)
@@ -631,50 +634,49 @@ BackendNodeId InspectorDOMAgent::backendNodeIdForNode(Node* node, const String&
return id;
}
-void InspectorDOMAgent::releaseBackendNodeIds(ErrorString* errorString, const String& nodeGroup)
+void InspectorDOMAgent::releaseBackendNodeIds(ErrorString& errorString, const String& nodeGroup)
{
if (m_nodeGroupToBackendIdMap.contains(nodeGroup)) {
NodeToBackendIdMap& map = m_nodeGroupToBackendIdMap.find(nodeGroup)->value;
- for (NodeToBackendIdMap::iterator it = map.begin(); it != map.end(); ++it)
- m_backendIdToNode.remove(it->value);
+ for (auto& backendId : map.values())
+ m_backendIdToNode.remove(backendId);
m_nodeGroupToBackendIdMap.remove(nodeGroup);
return;
}
- *errorString = "Group name not found";
+ errorString = ASCIILiteral("Group name not found");
}
-void InspectorDOMAgent::setAttributeValue(ErrorString* errorString, int elementId, const String& name, const String& value)
+void InspectorDOMAgent::setAttributeValue(ErrorString& errorString, int elementId, const String& name, const String& value)
{
Element* element = assertEditableElement(errorString, elementId);
if (!element)
return;
- m_domEditor->setAttribute(element, name, value, errorString);
+ m_domEditor->setAttribute(*element, name, value, errorString);
}
-void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elementId, const String& text, const String* const name)
+void InspectorDOMAgent::setAttributesAsText(ErrorString& errorString, int elementId, const String& text, const String* const name)
{
Element* element = assertEditableElement(errorString, elementId);
if (!element)
return;
- RefPtr<HTMLElement> parsedElement = createHTMLElement(element->document(), spanTag);
- ExceptionCode ec = 0;
- parsedElement.get()->setInnerHTML("<span " + text + "></span>", ec);
- if (ec) {
- *errorString = InspectorDOMAgent::toErrorString(ec);
+ auto parsedElement = createHTMLElement(element->document(), spanTag);
+ auto result = parsedElement.get().setInnerHTML("<span " + text + "></span>");
+ if (result.hasException()) {
+ errorString = toErrorString(result.releaseException());
return;
}
Node* child = parsedElement->firstChild();
if (!child) {
- *errorString = "Could not parse value as attributes";
+ errorString = ASCIILiteral("Could not parse value as attributes");
return;
}
- Element* childElement = toElement(child);
+ Element* childElement = downcast<Element>(child);
if (!childElement->hasAttributes() && name) {
- m_domEditor->removeAttribute(element, *name, errorString);
+ m_domEditor->removeAttribute(*element, *name, errorString);
return;
}
@@ -682,24 +684,24 @@ void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elemen
for (const Attribute& attribute : childElement->attributesIterator()) {
// Add attribute pair
foundOriginalAttribute = foundOriginalAttribute || (name && attribute.name().toString() == *name);
- if (!m_domEditor->setAttribute(element, attribute.name().toString(), attribute.value(), errorString))
+ if (!m_domEditor->setAttribute(*element, attribute.name().toString(), attribute.value(), errorString))
return;
}
if (!foundOriginalAttribute && name && !name->stripWhiteSpace().isEmpty())
- m_domEditor->removeAttribute(element, *name, errorString);
+ m_domEditor->removeAttribute(*element, *name, errorString);
}
-void InspectorDOMAgent::removeAttribute(ErrorString* errorString, int elementId, const String& name)
+void InspectorDOMAgent::removeAttribute(ErrorString& errorString, int elementId, const String& name)
{
Element* element = assertEditableElement(errorString, elementId);
if (!element)
return;
- m_domEditor->removeAttribute(element, name, errorString);
+ m_domEditor->removeAttribute(*element, name, errorString);
}
-void InspectorDOMAgent::removeNode(ErrorString* errorString, int nodeId)
+void InspectorDOMAgent::removeNode(ErrorString& errorString, int nodeId)
{
Node* node = assertEditableNode(errorString, nodeId);
if (!node)
@@ -707,49 +709,49 @@ void InspectorDOMAgent::removeNode(ErrorString* errorString, int nodeId)
ContainerNode* parentNode = node->parentNode();
if (!parentNode) {
- *errorString = "Can not remove detached node";
+ errorString = ASCIILiteral("Cannot remove detached node");
return;
}
- m_domEditor->removeChild(parentNode, node, errorString);
+ m_domEditor->removeChild(*parentNode, *node, errorString);
}
-void InspectorDOMAgent::setNodeName(ErrorString* errorString, int nodeId, const String& tagName, int* newId)
+void InspectorDOMAgent::setNodeName(ErrorString& errorString, int nodeId, const String& tagName, int* newId)
{
*newId = 0;
- Node* oldNode = nodeForId(nodeId);
- if (!oldNode || !oldNode->isElementNode())
+ RefPtr<Node> oldNode = nodeForId(nodeId);
+ if (!is<Element>(oldNode.get()))
return;
- ExceptionCode ec = 0;
- RefPtr<Element> newElem = oldNode->document().createElement(tagName, ec);
- if (ec)
+ auto createElementResult = oldNode->document().createElementForBindings(tagName);
+ if (createElementResult.hasException())
return;
+ auto newElement = createElementResult.releaseReturnValue();
// Copy over the original node's attributes.
- newElem->cloneAttributesFromElement(*toElement(oldNode));
+ newElement->cloneAttributesFromElement(downcast<Element>(*oldNode));
// Copy over the original node's children.
- Node* child;
+ RefPtr<Node> child;
while ((child = oldNode->firstChild())) {
- if (!m_domEditor->insertBefore(newElem.get(), child, 0, errorString))
+ if (!m_domEditor->insertBefore(newElement, *child, 0, errorString))
return;
}
// Replace the old node with the new node
- ContainerNode* parent = oldNode->parentNode();
- if (!m_domEditor->insertBefore(parent, newElem.get(), oldNode->nextSibling(), errorString))
+ RefPtr<ContainerNode> parent = oldNode->parentNode();
+ if (!m_domEditor->insertBefore(*parent, newElement.copyRef(), oldNode->nextSibling(), errorString))
return;
- if (!m_domEditor->removeChild(parent, oldNode, errorString))
+ if (!m_domEditor->removeChild(*parent, *oldNode, errorString))
return;
- *newId = pushNodePathToFrontend(newElem.get());
+ *newId = pushNodePathToFrontend(newElement.ptr());
if (m_childrenRequested.contains(nodeId))
pushChildNodesToFrontend(*newId);
}
-void InspectorDOMAgent::getOuterHTML(ErrorString* errorString, int nodeId, WTF::String* outerHTML)
+void InspectorDOMAgent::getOuterHTML(ErrorString& errorString, int nodeId, WTF::String* outerHTML)
{
Node* node = assertNode(errorString, nodeId);
if (!node)
@@ -758,11 +760,10 @@ void InspectorDOMAgent::getOuterHTML(ErrorString* errorString, int nodeId, WTF::
*outerHTML = createMarkup(*node);
}
-void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const String& outerHTML)
+void InspectorDOMAgent::setOuterHTML(ErrorString& errorString, int nodeId, const String& outerHTML)
{
if (!nodeId) {
- DOMPatchSupport domPatchSupport(m_domEditor.get(), m_document.get());
- domPatchSupport.patchDocument(outerHTML);
+ DOMPatchSupport { *m_domEditor, *m_document }.patchDocument(outerHTML);
return;
}
@@ -771,17 +772,13 @@ void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const
return;
Document& document = node->document();
- if (!document.isHTMLDocument() && !document.isXHTMLDocument()
-#if ENABLE(SVG)
- && !document.isSVGDocument()
-#endif
- ) {
- *errorString = "Not an HTML/XML document";
+ if (!document.isHTMLDocument() && !document.isXMLDocument()) {
+ errorString = ASCIILiteral("Not an HTML/XML document");
return;
}
- Node* newNode = 0;
- if (!m_domEditor->setOuterHTML(*node, outerHTML, &newNode, errorString))
+ Node* newNode = nullptr;
+ if (!m_domEditor->setOuterHTML(*node, outerHTML, newNode, errorString))
return;
if (!newNode) {
@@ -796,23 +793,23 @@ void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const
pushChildNodesToFrontend(newId);
}
-void InspectorDOMAgent::setNodeValue(ErrorString* errorString, int nodeId, const String& value)
+void InspectorDOMAgent::setNodeValue(ErrorString& errorString, int nodeId, const String& value)
{
Node* node = assertEditableNode(errorString, nodeId);
if (!node)
return;
- if (node->nodeType() != Node::TEXT_NODE) {
- *errorString = "Can only set value of text nodes";
+ if (!is<Text>(*node)) {
+ errorString = ASCIILiteral("Can only set value of text nodes");
return;
}
- m_domEditor->replaceWholeText(toText(node), value, errorString);
+ m_domEditor->replaceWholeText(downcast<Text>(*node), value, errorString);
}
-void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int nodeId, const String* objectGroup, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::EventListener>>& listenersArray)
+void InspectorDOMAgent::getEventListenersForNode(ErrorString& errorString, int nodeId, const String* objectGroup, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::EventListener>>& listenersArray)
{
- listenersArray = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::EventListener>::create();
+ listenersArray = Inspector::Protocol::Array<Inspector::Protocol::DOM::EventListener>::create();
Node* node = assertNode(errorString, nodeId);
if (!node)
return;
@@ -821,24 +818,19 @@ void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int n
// Get Capturing Listeners (in this order)
size_t eventInformationLength = eventInformation.size();
- for (size_t i = 0; i < eventInformationLength; ++i) {
- const EventListenerInfo& info = eventInformation[i];
- const EventListenerVector& vector = info.eventListenerVector;
- for (size_t j = 0; j < vector.size(); ++j) {
- const RegisteredEventListener& listener = vector[j];
- if (listener.useCapture)
- listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup));
+ for (auto& info : eventInformation) {
+ for (auto& listener : info.eventListenerVector) {
+ if (listener->useCapture())
+ listenersArray->addItem(buildObjectForEventListener(*listener, info.eventType, info.node, objectGroup));
}
}
// Get Bubbling Listeners (reverse order)
for (size_t i = eventInformationLength; i; --i) {
const EventListenerInfo& info = eventInformation[i - 1];
- const EventListenerVector& vector = info.eventListenerVector;
- for (size_t j = 0; j < vector.size(); ++j) {
- const RegisteredEventListener& listener = vector[j];
- if (!listener.useCapture)
- listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup));
+ for (auto& listener : info.eventListenerVector) {
+ if (!listener->useCapture())
+ listenersArray->addItem(buildObjectForEventListener(*listener, info.eventType, info.node, objectGroup));
}
}
}
@@ -861,49 +853,54 @@ void InspectorDOMAgent::getEventListeners(Node* node, Vector<EventListenerInfo>&
if (!d)
continue;
// Get the list of event types this Node is concerned with
- Vector<AtomicString> eventTypes = d->eventListenerMap.eventTypes();
- for (size_t j = 0; j < eventTypes.size(); ++j) {
- AtomicString& type = eventTypes[j];
- const EventListenerVector& listeners = ancestor->getEventListeners(type);
+ for (auto& type : d->eventListenerMap.eventTypes()) {
+ auto& listeners = ancestor->eventListeners(type);
EventListenerVector filteredListeners;
- filteredListeners.reserveCapacity(listeners.size());
- for (size_t k = 0; k < listeners.size(); ++k) {
- if (listeners[k].listener->type() == EventListener::JSEventListenerType)
- filteredListeners.append(listeners[k]);
+ filteredListeners.reserveInitialCapacity(listeners.size());
+ for (auto& listener : listeners) {
+ if (listener->callback().type() == EventListener::JSEventListenerType)
+ filteredListeners.uncheckedAppend(listener);
}
if (!filteredListeners.isEmpty())
- eventInformation.append(EventListenerInfo(ancestor, type, filteredListeners));
+ eventInformation.append(EventListenerInfo(ancestor, type, WTFMove(filteredListeners)));
}
}
}
-void InspectorDOMAgent::performSearch(ErrorString* errorString, const String& whitespaceTrimmedQuery, const RefPtr<InspectorArray>* nodeIds, String* searchId, int* resultCount)
+void InspectorDOMAgent::getAccessibilityPropertiesForNode(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::DOM::AccessibilityProperties>& axProperties)
+{
+ Node* node = assertNode(errorString, nodeId);
+ if (!node)
+ return;
+
+ axProperties = buildObjectForAccessibilityProperties(node);
+}
+
+void InspectorDOMAgent::performSearch(ErrorString& errorString, const String& whitespaceTrimmedQuery, const InspectorArray* nodeIds, String* searchId, int* resultCount)
{
// FIXME: Search works with node granularity - number of matches within node is not calculated.
InspectorNodeFinder finder(whitespaceTrimmedQuery);
if (nodeIds) {
- const RefPtr<InspectorArray>& nodeIdsRef = *nodeIds;
- for (unsigned i = 0; i < nodeIdsRef->length(); ++i) {
- RefPtr<InspectorValue> nodeValue = nodeIdsRef->get(i);
+ for (auto& nodeValue : *nodeIds) {
if (!nodeValue) {
- *errorString = "Invalid nodeIds item.";
+ errorString = ASCIILiteral("Invalid nodeIds item.");
return;
}
int nodeId = 0;
- if (!nodeValue->asNumber(&nodeId)) {
- *errorString = "Invalid nodeIds item type. Expecting integer types.";
+ if (!nodeValue->asInteger(nodeId)) {
+ errorString = ASCIILiteral("Invalid nodeIds item type. Expecting integer types.");
return;
}
Node* node = assertNode(errorString, nodeId);
if (!node) {
// assertNode should have filled the errorString for us.
- ASSERT(errorString->length());
+ ASSERT(errorString.length());
return;
}
finder.performSearch(node);
}
- } else if (m_document) {
+ } else {
// There's no need to iterate the frames tree because
// the search helper will go inside the frame owner elements.
finder.performSearch(m_document.get());
@@ -912,32 +909,32 @@ void InspectorDOMAgent::performSearch(ErrorString* errorString, const String& wh
*searchId = IdentifiersFactory::createIdentifier();
auto& resultsVector = m_searchResults.add(*searchId, Vector<RefPtr<Node>>()).iterator->value;
- for (auto iterator = finder.results().begin(); iterator != finder.results().end(); ++iterator)
- resultsVector.append(*iterator);
+ for (auto& result : finder.results())
+ resultsVector.append(result);
*resultCount = resultsVector.size();
}
-void InspectorDOMAgent::getSearchResults(ErrorString* errorString, const String& searchId, int fromIndex, int toIndex, RefPtr<Inspector::TypeBuilder::Array<int>>& nodeIds)
+void InspectorDOMAgent::getSearchResults(ErrorString& errorString, const String& searchId, int fromIndex, int toIndex, RefPtr<Inspector::Protocol::Array<int>>& nodeIds)
{
SearchResults::iterator it = m_searchResults.find(searchId);
if (it == m_searchResults.end()) {
- *errorString = "No search session with given id found";
+ errorString = ASCIILiteral("No search session with given id found");
return;
}
int size = it->value.size();
if (fromIndex < 0 || toIndex > size || fromIndex >= toIndex) {
- *errorString = "Invalid search result range";
+ errorString = ASCIILiteral("Invalid search result range");
return;
}
- nodeIds = Inspector::TypeBuilder::Array<int>::create();
+ nodeIds = Inspector::Protocol::Array<int>::create();
for (int i = fromIndex; i < toIndex; ++i)
nodeIds->addItem(pushNodePathToFrontend((it->value)[i].get()));
}
-void InspectorDOMAgent::discardSearchResults(ErrorString*, const String& searchId)
+void InspectorDOMAgent::discardSearchResults(ErrorString&, const String& searchId)
{
m_searchResults.remove(searchId);
}
@@ -954,13 +951,13 @@ bool InspectorDOMAgent::handleMousePress()
return false;
}
-bool InspectorDOMAgent::handleTouchEvent(Node* node)
+bool InspectorDOMAgent::handleTouchEvent(Node& node)
{
if (!m_searchingForNode)
return false;
- if (node && m_inspectModeHighlightConfig) {
- m_overlay->highlightNode(node, *m_inspectModeHighlightConfig);
- inspect(node);
+ if (m_inspectModeHighlightConfig) {
+ m_overlay->highlightNode(&node, *m_inspectModeHighlightConfig);
+ inspect(&node);
return true;
}
return false;
@@ -968,14 +965,17 @@ bool InspectorDOMAgent::handleTouchEvent(Node* node)
void InspectorDOMAgent::inspect(Node* inspectedNode)
{
- ErrorString error;
+ ErrorString unused;
RefPtr<Node> node = inspectedNode;
- setSearchingForNode(&error, false, 0);
+ setSearchingForNode(unused, false, nullptr);
if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE)
node = node->parentNode();
m_nodeToFocus = node;
+ if (!m_nodeToFocus)
+ return;
+
focusNode();
}
@@ -987,130 +987,173 @@ void InspectorDOMAgent::focusNode()
ASSERT(m_nodeToFocus);
RefPtr<Node> node = m_nodeToFocus.get();
- m_nodeToFocus = 0;
+ m_nodeToFocus = nullptr;
Frame* frame = node->document().frame();
if (!frame)
return;
JSC::ExecState* scriptState = mainWorldExecState(frame);
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
+ InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(scriptState);
if (injectedScript.hasNoValue())
return;
- injectedScript.inspectObject(InspectorDOMAgent::nodeAsScriptValue(scriptState, node.get()));
+ injectedScript.inspectObject(nodeAsScriptValue(*scriptState, node.get()));
}
void InspectorDOMAgent::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
{
+ m_mousedOverNode = result.innerNode();
+
if (!m_searchingForNode)
return;
- Node* node = result.innerNode();
+ highlightMousedOverNode();
+}
+
+void InspectorDOMAgent::highlightMousedOverNode()
+{
+ Node* node = m_mousedOverNode.get();
while (node && node->nodeType() == Node::TEXT_NODE)
node = node->parentNode();
if (node && m_inspectModeHighlightConfig)
m_overlay->highlightNode(node, *m_inspectModeHighlightConfig);
}
-void InspectorDOMAgent::setSearchingForNode(ErrorString* errorString, bool enabled, InspectorObject* highlightInspectorObject)
+void InspectorDOMAgent::setSearchingForNode(ErrorString& errorString, bool enabled, const InspectorObject* highlightInspectorObject)
{
if (m_searchingForNode == enabled)
return;
+
m_searchingForNode = enabled;
+
if (enabled) {
m_inspectModeHighlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject);
if (!m_inspectModeHighlightConfig)
return;
+ highlightMousedOverNode();
} else
hideHighlight(errorString);
m_overlay->didSetSearchingForNode(m_searchingForNode);
+
+ if (InspectorClient* client = m_pageAgent->page().inspectorController().inspectorClient())
+ client->elementSelectionChanged(m_searchingForNode);
}
-PassOwnPtr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObject(ErrorString* errorString, InspectorObject* highlightInspectorObject)
+std::unique_ptr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObject(ErrorString& errorString, const InspectorObject* highlightInspectorObject)
{
if (!highlightInspectorObject) {
- *errorString = "Internal error: highlight configuration parameter is missing";
+ errorString = ASCIILiteral("Internal error: highlight configuration parameter is missing");
return nullptr;
}
- OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
+ auto highlightConfig = std::make_unique<HighlightConfig>();
bool showInfo = false; // Default: false (do not show a tooltip).
- highlightInspectorObject->getBoolean("showInfo", &showInfo);
+ highlightInspectorObject->getBoolean("showInfo", showInfo);
highlightConfig->showInfo = showInfo;
- bool showRulers = false; // Default: false (do not show rulers).
- highlightInspectorObject->getBoolean("showRulers", &showRulers);
- highlightConfig->showRulers = showRulers;
highlightConfig->content = parseConfigColor("contentColor", highlightInspectorObject);
highlightConfig->contentOutline = parseConfigColor("contentOutlineColor", highlightInspectorObject);
highlightConfig->padding = parseConfigColor("paddingColor", highlightInspectorObject);
highlightConfig->border = parseConfigColor("borderColor", highlightInspectorObject);
highlightConfig->margin = parseConfigColor("marginColor", highlightInspectorObject);
- return highlightConfig.release();
+ return highlightConfig;
}
-void InspectorDOMAgent::setInspectModeEnabled(ErrorString* errorString, bool enabled, const RefPtr<InspectorObject>* highlightConfig)
+void InspectorDOMAgent::setInspectModeEnabled(ErrorString& errorString, bool enabled, const InspectorObject* highlightConfig)
{
- setSearchingForNode(errorString, enabled, highlightConfig ? highlightConfig->get() : 0);
+ setSearchingForNode(errorString, enabled, highlightConfig ? highlightConfig : nullptr);
}
-void InspectorDOMAgent::highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates)
+void InspectorDOMAgent::highlightRect(ErrorString&, int x, int y, int width, int height, const InspectorObject* color, const InspectorObject* outlineColor, const bool* usePageCoordinates)
{
- OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad(FloatRect(x, y, width, height)));
- innerHighlightQuad(quad.release(), color, outlineColor, usePageCoordinates);
+ auto quad = std::make_unique<FloatQuad>(FloatRect(x, y, width, height));
+ innerHighlightQuad(WTFMove(quad), color, outlineColor, usePageCoordinates);
}
-void InspectorDOMAgent::highlightQuad(ErrorString* errorString, const RefPtr<InspectorArray>& quadArray, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates)
+void InspectorDOMAgent::highlightQuad(ErrorString& errorString, const InspectorArray& quadArray, const InspectorObject* color, const InspectorObject* outlineColor, const bool* usePageCoordinates)
{
- OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad());
+ auto quad = std::make_unique<FloatQuad>();
if (!parseQuad(quadArray, quad.get())) {
- *errorString = "Invalid Quad format";
+ errorString = ASCIILiteral("Invalid Quad format");
return;
}
- innerHighlightQuad(quad.release(), color, outlineColor, usePageCoordinates);
+ innerHighlightQuad(WTFMove(quad), color, outlineColor, usePageCoordinates);
}
-void InspectorDOMAgent::innerHighlightQuad(PassOwnPtr<FloatQuad> quad, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates)
+void InspectorDOMAgent::innerHighlightQuad(std::unique_ptr<FloatQuad> quad, const InspectorObject* color, const InspectorObject* outlineColor, const bool* usePageCoordinates)
{
- OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
+ auto highlightConfig = std::make_unique<HighlightConfig>();
highlightConfig->content = parseColor(color);
highlightConfig->contentOutline = parseColor(outlineColor);
highlightConfig->usePageCoordinates = usePageCoordinates ? *usePageCoordinates : false;
- m_overlay->highlightQuad(quad, *highlightConfig);
+ m_overlay->highlightQuad(WTFMove(quad), *highlightConfig);
}
-void InspectorDOMAgent::highlightNode(ErrorString* errorString, const RefPtr<InspectorObject>& highlightInspectorObject, const int* nodeId, const String* objectId)
+void InspectorDOMAgent::highlightSelector(ErrorString& errorString, const InspectorObject& highlightInspectorObject, const String& selectorString, const String* frameId)
{
- Node* node = 0;
- if (nodeId) {
+ RefPtr<Document> document;
+
+ if (frameId) {
+ Frame* frame = m_pageAgent->frameForId(*frameId);
+ if (!frame) {
+ errorString = ASCIILiteral("No frame for given id found");
+ return;
+ }
+
+ document = frame->document();
+ } else
+ document = m_document;
+
+ if (!document) {
+ errorString = ASCIILiteral("Document could not be found");
+ return;
+ }
+
+ auto queryResult = document->querySelectorAll(selectorString);
+ // FIXME: <https://webkit.org/b/146161> Web Inspector: DOM.highlightSelector should work for "a:visited"
+ if (queryResult.hasException()) {
+ errorString = ASCIILiteral("DOM Error while querying");
+ return;
+ }
+
+ auto highlightConfig = highlightConfigFromInspectorObject(errorString, &highlightInspectorObject);
+ if (!highlightConfig)
+ return;
+
+ m_overlay->highlightNodeList(queryResult.releaseReturnValue(), *highlightConfig);
+}
+
+void InspectorDOMAgent::highlightNode(ErrorString& errorString, const InspectorObject& highlightInspectorObject, const int* nodeId, const String* objectId)
+{
+ Node* node = nullptr;
+ if (nodeId)
node = assertNode(errorString, *nodeId);
- } else if (objectId) {
+ else if (objectId) {
node = nodeForObjectId(*objectId);
if (!node)
- *errorString = "Node for given objectId not found";
+ errorString = ASCIILiteral("Node for given objectId not found");
} else
- *errorString = "Either nodeId or objectId must be specified";
+ errorString = ASCIILiteral("Either nodeId or objectId must be specified");
if (!node)
return;
- OwnPtr<HighlightConfig> highlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject.get());
+ std::unique_ptr<HighlightConfig> highlightConfig = highlightConfigFromInspectorObject(errorString, &highlightInspectorObject);
if (!highlightConfig)
return;
m_overlay->highlightNode(node, *highlightConfig);
}
-void InspectorDOMAgent::highlightFrame(
- ErrorString*,
- const String& frameId,
- const RefPtr<InspectorObject>* color,
- const RefPtr<InspectorObject>* outlineColor)
+void InspectorDOMAgent::highlightFrame(ErrorString& errorString, const String& frameId, const InspectorObject* color, const InspectorObject* outlineColor)
{
- Frame* frame = m_pageAgent->frameForId(frameId);
- if (frame && frame->ownerElement()) {
- OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
+ Frame* frame = m_pageAgent->assertFrame(errorString, frameId);
+ if (!frame)
+ return;
+
+ if (frame->ownerElement()) {
+ auto highlightConfig = std::make_unique<HighlightConfig>();
highlightConfig->showInfo = true; // Always show tooltips for frames.
highlightConfig->content = parseColor(color);
highlightConfig->contentOutline = parseColor(outlineColor);
@@ -1118,12 +1161,12 @@ void InspectorDOMAgent::highlightFrame(
}
}
-void InspectorDOMAgent::hideHighlight(ErrorString*)
+void InspectorDOMAgent::hideHighlight(ErrorString&)
{
m_overlay->hideHighlight();
}
-void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
+void InspectorDOMAgent::moveTo(ErrorString& errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
{
Node* node = assertEditableNode(errorString, nodeId);
if (!node)
@@ -1139,65 +1182,65 @@ void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetE
if (!anchorNode)
return;
if (anchorNode->parentNode() != targetElement) {
- *errorString = "Anchor node must be child of the target element";
+ errorString = ASCIILiteral("Anchor node must be child of the target element");
return;
}
}
- if (!m_domEditor->insertBefore(targetElement, node, anchorNode, errorString))
+ if (!m_domEditor->insertBefore(*targetElement, *node, anchorNode, errorString))
return;
*newNodeId = pushNodePathToFrontend(node);
}
-void InspectorDOMAgent::undo(ErrorString* errorString)
+void InspectorDOMAgent::undo(ErrorString& errorString)
{
- ExceptionCode ec = 0;
- m_history->undo(ec);
- *errorString = InspectorDOMAgent::toErrorString(ec);
+ auto result = m_history->undo();
+ if (result.hasException())
+ errorString = toErrorString(result.releaseException());
}
-void InspectorDOMAgent::redo(ErrorString* errorString)
+void InspectorDOMAgent::redo(ErrorString& errorString)
{
- ExceptionCode ec = 0;
- m_history->redo(ec);
- *errorString = InspectorDOMAgent::toErrorString(ec);
+ auto result = m_history->redo();
+ if (result.hasException())
+ errorString = toErrorString(result.releaseException());
}
-void InspectorDOMAgent::markUndoableState(ErrorString*)
+void InspectorDOMAgent::markUndoableState(ErrorString&)
{
m_history->markUndoableState();
}
-void InspectorDOMAgent::focus(ErrorString* errorString, int nodeId)
+void InspectorDOMAgent::focus(ErrorString& errorString, int nodeId)
{
Element* element = assertElement(errorString, nodeId);
if (!element)
return;
if (!element->isFocusable()) {
- *errorString = "Element is not focusable";
+ errorString = ASCIILiteral("Element is not focusable");
return;
}
element->focus();
}
-void InspectorDOMAgent::resolveNode(ErrorString* errorString, int nodeId, const String* const objectGroup, RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject>& result)
+void InspectorDOMAgent::resolveNode(ErrorString& errorString, int nodeId, const String* const objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result)
{
- String objectGroupName = objectGroup ? *objectGroup : "";
+ String objectGroupName = objectGroup ? *objectGroup : emptyString();
Node* node = nodeForId(nodeId);
if (!node) {
- *errorString = "No node with given id found";
+ errorString = ASCIILiteral("No node with given id found");
return;
}
- RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> object = resolveNode(node, objectGroupName);
+ RefPtr<Inspector::Protocol::Runtime::RemoteObject> object = resolveNode(node, objectGroupName);
if (!object) {
- *errorString = "Node with given id does not belong to the document";
+ errorString = ASCIILiteral("Node with given id does not belong to the document");
return;
}
result = object;
}
-void InspectorDOMAgent::getAttributes(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::Array<String>>& result)
+void InspectorDOMAgent::getAttributes(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::Array<String>>& result)
{
Element* element = assertElement(errorString, nodeId);
if (!element)
@@ -1206,7 +1249,7 @@ void InspectorDOMAgent::getAttributes(ErrorString* errorString, int nodeId, RefP
result = buildArrayForElementAttributes(element);
}
-void InspectorDOMAgent::requestNode(ErrorString*, const String& objectId, int* nodeId)
+void InspectorDOMAgent::requestNode(ErrorString&, const String& objectId, int* nodeId)
{
Node* node = nodeForObjectId(objectId);
if (node)
@@ -1215,20 +1258,72 @@ void InspectorDOMAgent::requestNode(ErrorString*, const String& objectId, int* n
*nodeId = 0;
}
-// static
String InspectorDOMAgent::documentURLString(Document* document)
{
if (!document || document->url().isNull())
- return "";
+ return emptyString();
return document->url().string();
}
static String documentBaseURLString(Document* document)
{
- return document->completeURL("").string();
+ return document->completeURL(emptyString()).string();
+}
+
+static bool pseudoElementType(PseudoId pseudoId, Inspector::Protocol::DOM::PseudoType* type)
+{
+ switch (pseudoId) {
+ case BEFORE:
+ *type = Inspector::Protocol::DOM::PseudoType::Before;
+ return true;
+ case AFTER:
+ *type = Inspector::Protocol::DOM::PseudoType::After;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static Inspector::Protocol::DOM::ShadowRootType shadowRootType(ShadowRootMode mode)
+{
+ switch (mode) {
+ case ShadowRootMode::UserAgent:
+ return Inspector::Protocol::DOM::ShadowRootType::UserAgent;
+ case ShadowRootMode::Closed:
+ return Inspector::Protocol::DOM::ShadowRootType::Closed;
+ case ShadowRootMode::Open:
+ return Inspector::Protocol::DOM::ShadowRootType::Open;
+ }
+
+ ASSERT_NOT_REACHED();
+ return Inspector::Protocol::DOM::ShadowRootType::UserAgent;
+}
+
+static Inspector::Protocol::DOM::CustomElementState customElementState(const Element& element)
+{
+ if (element.isDefinedCustomElement())
+ return Inspector::Protocol::DOM::CustomElementState::Custom;
+ if (element.isFailedCustomElement())
+ return Inspector::Protocol::DOM::CustomElementState::Failed;
+ if (element.isUndefinedCustomElement() || element.isCustomElementUpgradeCandidate())
+ return Inspector::Protocol::DOM::CustomElementState::Waiting;
+ return Inspector::Protocol::DOM::CustomElementState::Builtin;
}
-PassRefPtr<Inspector::TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap)
+static String computeContentSecurityPolicySHA256Hash(const Element& element)
+{
+ // FIXME: Compute the digest with respect to the raw bytes received from the page.
+ // See <https://bugs.webkit.org/show_bug.cgi?id=155184>.
+ TextEncoding documentEncoding = element.document().textEncoding();
+ const TextEncoding& encodingToUse = documentEncoding.isValid() ? documentEncoding : UTF8Encoding();
+ CString content = encodingToUse.encode(TextNodeTraversal::contentsAsString(element), EntitiesForUnencodables);
+ auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_256);
+ cryptoDigest->addBytes(content.data(), content.length());
+ Vector<uint8_t> digest = cryptoDigest->computeHash();
+ return makeString("sha256-", base64Encode(digest.data(), digest.size()));
+}
+
+Ref<Inspector::Protocol::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap)
{
int id = bind(node, nodesMap);
String nodeName;
@@ -1236,6 +1331,10 @@ PassRefPtr<Inspector::TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForN
String nodeValue;
switch (node->nodeType()) {
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ nodeName = node->nodeName();
+ localName = node->localName();
+ FALLTHROUGH;
case Node::TEXT_NODE:
case Node::COMMENT_NODE:
case Node::CDATA_SECTION_NODE:
@@ -1257,80 +1356,108 @@ PassRefPtr<Inspector::TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForN
break;
}
- RefPtr<Inspector::TypeBuilder::DOM::Node> value = Inspector::TypeBuilder::DOM::Node::create()
+ auto value = Inspector::Protocol::DOM::Node::create()
.setNodeId(id)
.setNodeType(static_cast<int>(node->nodeType()))
.setNodeName(nodeName)
.setLocalName(localName)
- .setNodeValue(nodeValue);
+ .setNodeValue(nodeValue)
+ .release();
if (node->isContainerNode()) {
int nodeCount = innerChildNodeCount(node);
value->setChildNodeCount(nodeCount);
- RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = buildArrayForContainerChildren(node, depth, nodesMap);
+ Ref<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> children = buildArrayForContainerChildren(node, depth, nodesMap);
if (children->length() > 0)
- value->setChildren(children.release());
+ value->setChildren(WTFMove(children));
}
- if (node->isElementNode()) {
- Element* element = toElement(node);
- value->setAttributes(buildArrayForElementAttributes(element));
- if (node->isFrameOwnerElement()) {
- HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(node);
- Frame* frame = frameOwner->contentFrame();
+ if (is<Element>(*node)) {
+ Element& element = downcast<Element>(*node);
+ value->setAttributes(buildArrayForElementAttributes(&element));
+ if (is<HTMLFrameOwnerElement>(element)) {
+ HTMLFrameOwnerElement& frameOwner = downcast<HTMLFrameOwnerElement>(element);
+ Frame* frame = frameOwner.contentFrame();
if (frame)
value->setFrameId(m_pageAgent->frameId(frame));
- Document* doc = frameOwner->contentDocument();
- if (doc)
- value->setContentDocument(buildObjectForNode(doc, 0, nodesMap));
+ Document* document = frameOwner.contentDocument();
+ if (document)
+ value->setContentDocument(buildObjectForNode(document, 0, nodesMap));
}
- if (ShadowRoot* root = element->shadowRoot()) {
- RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> shadowRoots = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>::create();
+ if (ShadowRoot* root = element.shadowRoot()) {
+ auto shadowRoots = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create();
shadowRoots->addItem(buildObjectForNode(root, 0, nodesMap));
- value->setShadowRoots(shadowRoots);
+ value->setShadowRoots(WTFMove(shadowRoots));
+ }
+
+ if (is<HTMLTemplateElement>(element))
+ value->setTemplateContent(buildObjectForNode(&downcast<HTMLTemplateElement>(element).content(), 0, nodesMap));
+
+ if (is<HTMLStyleElement>(element) || (is<HTMLScriptElement>(element) && !element.hasAttributeWithoutSynchronization(HTMLNames::srcAttr)))
+ value->setContentSecurityPolicyHash(computeContentSecurityPolicySHA256Hash(element));
+
+ auto state = customElementState(element);
+ if (state != Inspector::Protocol::DOM::CustomElementState::Builtin)
+ value->setCustomElementState(state);
+
+ if (element.pseudoId()) {
+ Inspector::Protocol::DOM::PseudoType pseudoType;
+ if (pseudoElementType(element.pseudoId(), &pseudoType))
+ value->setPseudoType(pseudoType);
+ } else {
+ if (auto pseudoElements = buildArrayForPseudoElements(element, nodesMap))
+ value->setPseudoElements(WTFMove(pseudoElements));
}
-#if ENABLE(TEMPLATE_ELEMENT)
- if (element->hasTagName(HTMLNames::templateTag))
- value->setTemplateContent(buildObjectForNode(toHTMLTemplateElement(element)->content(), 0, nodesMap));
-#endif
+ } else if (is<Document>(*node)) {
+ Document& document = downcast<Document>(*node);
+ value->setFrameId(m_pageAgent->frameId(document.frame()));
+ value->setDocumentURL(documentURLString(&document));
+ value->setBaseURL(documentBaseURLString(&document));
+ value->setXmlVersion(document.xmlVersion());
+ } else if (is<DocumentType>(*node)) {
+ DocumentType& docType = downcast<DocumentType>(*node);
+ value->setPublicId(docType.publicId());
+ value->setSystemId(docType.systemId());
+ } else if (is<Attr>(*node)) {
+ Attr& attribute = downcast<Attr>(*node);
+ value->setName(attribute.name());
+ value->setValue(attribute.value());
+ } else if (is<ShadowRoot>(*node)) {
+ ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node);
+ value->setShadowRootType(shadowRootType(shadowRoot.mode()));
+ }
+
+ // Need to enable AX to get the computed role.
+ if (!WebCore::AXObjectCache::accessibilityEnabled())
+ WebCore::AXObjectCache::enableAccessibility();
- } else if (node->isDocumentNode()) {
- Document* document = toDocument(node);
- value->setDocumentURL(documentURLString(document));
- value->setBaseURL(documentBaseURLString(document));
- value->setXmlVersion(document->xmlVersion());
- } else if (node->nodeType() == Node::DOCUMENT_TYPE_NODE) {
- DocumentType* docType = toDocumentType(node);
- value->setPublicId(docType->publicId());
- value->setSystemId(docType->systemId());
- value->setInternalSubset(docType->internalSubset());
- } else if (node->isAttributeNode()) {
- Attr* attribute = toAttr(node);
- value->setName(attribute->name());
- value->setValue(attribute->value());
+ if (AXObjectCache* axObjectCache = node->document().axObjectCache()) {
+ if (AccessibilityObject* axObject = axObjectCache->getOrCreate(node))
+ value->setRole(axObject->computedRoleString());
}
- return value.release();
+
+ return value;
}
-PassRefPtr<Inspector::TypeBuilder::Array<String>> InspectorDOMAgent::buildArrayForElementAttributes(Element* element)
+Ref<Inspector::Protocol::Array<String>> InspectorDOMAgent::buildArrayForElementAttributes(Element* element)
{
- RefPtr<Inspector::TypeBuilder::Array<String>> attributesValue = Inspector::TypeBuilder::Array<String>::create();
+ auto attributesValue = Inspector::Protocol::Array<String>::create();
// Go through all attributes and serialize them.
if (!element->hasAttributes())
- return attributesValue.release();
+ return attributesValue;
for (const Attribute& attribute : element->attributesIterator()) {
// Add attribute pair
attributesValue->addItem(attribute.name().toString());
attributesValue->addItem(attribute.value());
}
- return attributesValue.release();
+ return attributesValue;
}
-PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> InspectorDOMAgent::buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap)
+Ref<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> InspectorDOMAgent::buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap)
{
- RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> children = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>::create();
+ auto children = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create();
if (depth == 0) {
// Special-case the only text child - pretend that container's children have been requested.
Node* firstChild = container->firstChild();
@@ -1338,7 +1465,7 @@ PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> Ins
children->addItem(buildObjectForNode(firstChild, 0, nodesMap));
m_childrenRequested.add(bind(container, nodesMap));
}
- return children.release();
+ return children;
}
Node* child = innerFirstChild(container);
@@ -1349,29 +1476,46 @@ PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::DOM::Node>> Ins
children->addItem(buildObjectForNode(child, depth, nodesMap));
child = innerNextSibling(child);
}
- return children.release();
+ return children;
}
-PassRefPtr<Inspector::TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node, const String* objectGroupId)
+RefPtr<Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>> InspectorDOMAgent::buildArrayForPseudoElements(const Element& element, NodeToIdMap* nodesMap)
{
- RefPtr<EventListener> eventListener = registeredEventListener.listener;
+ PseudoElement* beforeElement = element.beforePseudoElement();
+ PseudoElement* afterElement = element.afterPseudoElement();
+ if (!beforeElement && !afterElement)
+ return nullptr;
+
+ auto pseudoElements = Inspector::Protocol::Array<Inspector::Protocol::DOM::Node>::create();
+ if (beforeElement)
+ pseudoElements->addItem(buildObjectForNode(beforeElement, 0, nodesMap));
+ if (afterElement)
+ pseudoElements->addItem(buildObjectForNode(afterElement, 0, nodesMap));
+ return WTFMove(pseudoElements);
+}
+
+Ref<Inspector::Protocol::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node, const String* objectGroupId)
+{
+ Ref<EventListener> eventListener = registeredEventListener.callback();
JSC::ExecState* state = nullptr;
JSC::JSObject* handler = nullptr;
String body;
int lineNumber = 0;
+ int columnNumber = 0;
String scriptID;
String sourceName;
- if (auto scriptListener = JSEventListener::cast(eventListener.get())) {
+ if (auto scriptListener = JSEventListener::cast(eventListener.ptr())) {
JSC::JSLockHolder lock(scriptListener->isolatedWorld().vm());
state = execStateFromNode(scriptListener->isolatedWorld(), &node->document());
handler = scriptListener->jsFunction(&node->document());
- if (handler) {
+ if (handler && state) {
body = handler->toString(state)->value(state);
- if (auto function = JSC::jsDynamicCast<JSC::JSFunction*>(handler)) {
- if (!function->isHostFunction()) {
+ if (auto function = jsDynamicDowncast<JSC::JSFunction*>(state->vm(), handler)) {
+ if (!function->isHostOrBuiltinFunction()) {
if (auto executable = function->jsExecutable()) {
- lineNumber = executable->lineNo() - 1;
+ lineNumber = executable->firstLine() - 1;
+ columnNumber = executable->startColumn() - 1;
scriptID = executable->sourceID() == JSC::SourceProvider::nullID ? emptyString() : String::number(executable->sourceID());
sourceName = executable->sourceURL();
}
@@ -1380,26 +1524,349 @@ PassRefPtr<Inspector::TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildO
}
}
- RefPtr<Inspector::TypeBuilder::DOM::EventListener> value = Inspector::TypeBuilder::DOM::EventListener::create()
+ auto value = Inspector::Protocol::DOM::EventListener::create()
.setType(eventType)
- .setUseCapture(registeredEventListener.useCapture)
+ .setUseCapture(registeredEventListener.useCapture())
.setIsAttribute(eventListener->isAttribute())
.setNodeId(pushNodePathToFrontend(node))
- .setHandlerBody(body);
+ .setHandlerBody(body)
+ .release();
if (objectGroupId && handler && state) {
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(state);
+ InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(state);
if (!injectedScript.hasNoValue())
- value->setHandler(injectedScript.wrapObject(Deprecated::ScriptValue(state->vm(), handler), *objectGroupId));
+ value->setHandler(injectedScript.wrapObject(handler, *objectGroupId));
}
if (!scriptID.isNull()) {
- RefPtr<Inspector::TypeBuilder::Debugger::Location> location = Inspector::TypeBuilder::Debugger::Location::create()
+ auto location = Inspector::Protocol::Debugger::Location::create()
.setScriptId(scriptID)
- .setLineNumber(lineNumber);
- value->setLocation(location.release());
+ .setLineNumber(lineNumber)
+ .release();
+ location->setColumnNumber(columnNumber);
+ value->setLocation(WTFMove(location));
if (!sourceName.isEmpty())
value->setSourceName(sourceName);
}
- return value.release();
+ return value;
+}
+
+void InspectorDOMAgent::processAccessibilityChildren(RefPtr<AccessibilityObject>&& axObject, RefPtr<Inspector::Protocol::Array<int>>&& childNodeIds)
+{
+ const auto& children = axObject->children();
+ if (!children.size())
+ return;
+
+ if (!childNodeIds)
+ childNodeIds = Inspector::Protocol::Array<int>::create();
+
+ for (const auto& childObject : children) {
+ if (Node* childNode = childObject->node())
+ childNodeIds->addItem(pushNodePathToFrontend(childNode));
+ else
+ processAccessibilityChildren(childObject.copyRef(), childNodeIds.copyRef());
+ }
+}
+
+RefPtr<Inspector::Protocol::DOM::AccessibilityProperties> InspectorDOMAgent::buildObjectForAccessibilityProperties(Node* node)
+{
+ ASSERT(node);
+ if (!node)
+ return nullptr;
+
+ if (!WebCore::AXObjectCache::accessibilityEnabled())
+ WebCore::AXObjectCache::enableAccessibility();
+
+ Node* activeDescendantNode = nullptr;
+ bool busy = false;
+ auto checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::False;
+ RefPtr<Inspector::Protocol::Array<int>> childNodeIds;
+ RefPtr<Inspector::Protocol::Array<int>> controlledNodeIds;
+ auto currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::False;
+ bool exists = false;
+ bool expanded = false;
+ bool disabled = false;
+ RefPtr<Inspector::Protocol::Array<int>> flowedNodeIds;
+ bool focused = false;
+ bool ignored = true;
+ bool ignoredByDefault = false;
+ auto invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::False;
+ bool hidden = false;
+ String label;
+ bool liveRegionAtomic = false;
+ RefPtr<Inspector::Protocol::Array<String>> liveRegionRelevant;
+ auto liveRegionStatus = Inspector::Protocol::DOM::AccessibilityProperties::LiveRegionStatus::Off;
+ Node* mouseEventNode = nullptr;
+ RefPtr<Inspector::Protocol::Array<int>> ownedNodeIds;
+ Node* parentNode = nullptr;
+ bool pressed = false;
+ bool readonly = false;
+ bool required = false;
+ String role;
+ bool selected = false;
+ RefPtr<Inspector::Protocol::Array<int>> selectedChildNodeIds;
+ bool supportsChecked = false;
+ bool supportsExpanded = false;
+ bool supportsLiveRegion = false;
+ bool supportsPressed = false;
+ bool supportsRequired = false;
+ bool supportsFocused = false;
+ bool isPopupButton = false;
+ int headingLevel = 0;
+ unsigned hierarchicalLevel = 0;
+ unsigned level = 0;
+
+ if (AXObjectCache* axObjectCache = node->document().axObjectCache()) {
+ if (AccessibilityObject* axObject = axObjectCache->getOrCreate(node)) {
+
+ if (AccessibilityObject* activeDescendant = axObject->activeDescendant())
+ activeDescendantNode = activeDescendant->node();
+
+ // An AX object is "busy" if it or any ancestor has aria-busy="true" set.
+ AccessibilityObject* current = axObject;
+ while (!busy && current) {
+ busy = current->isBusy();
+ current = current->parentObject();
+ }
+
+ supportsChecked = axObject->supportsChecked();
+ if (supportsChecked) {
+ int checkValue = axObject->checkboxOrRadioValue(); // Element using aria-checked.
+ if (checkValue == 1)
+ checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::True;
+ else if (checkValue == 2)
+ checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::Mixed;
+ else if (axObject->isChecked()) // Native checkbox.
+ checked = Inspector::Protocol::DOM::AccessibilityProperties::Checked::True;
+ }
+
+ processAccessibilityChildren(axObject, WTFMove(childNodeIds));
+
+ Vector<Element*> controlledElements;
+ axObject->elementsFromAttribute(controlledElements, aria_controlsAttr);
+ if (controlledElements.size()) {
+ controlledNodeIds = Inspector::Protocol::Array<int>::create();
+ for (Element* controlledElement : controlledElements)
+ controlledNodeIds->addItem(pushNodePathToFrontend(controlledElement));
+ }
+
+ switch (axObject->ariaCurrentState()) {
+ case ARIACurrentFalse:
+ currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::False;
+ break;
+ case ARIACurrentPage:
+ currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Page;
+ break;
+ case ARIACurrentStep:
+ currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Step;
+ break;
+ case ARIACurrentLocation:
+ currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Location;
+ break;
+ case ARIACurrentDate:
+ currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Date;
+ break;
+ case ARIACurrentTime:
+ currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::Time;
+ break;
+ default:
+ case ARIACurrentTrue:
+ currentState = Inspector::Protocol::DOM::AccessibilityProperties::Current::True;
+ break;
+ }
+
+ disabled = !axObject->isEnabled();
+ exists = true;
+
+ supportsExpanded = axObject->supportsExpanded();
+ if (supportsExpanded)
+ expanded = axObject->isExpanded();
+
+ Vector<Element*> flowedElements;
+ axObject->elementsFromAttribute(flowedElements, aria_flowtoAttr);
+ if (flowedElements.size()) {
+ flowedNodeIds = Inspector::Protocol::Array<int>::create();
+ for (Element* flowedElement : flowedElements)
+ flowedNodeIds->addItem(pushNodePathToFrontend(flowedElement));
+ }
+
+ if (is<Element>(*node)) {
+ supportsFocused = axObject->canSetFocusAttribute();
+ if (supportsFocused)
+ focused = axObject->isFocused();
+ }
+
+ ignored = axObject->accessibilityIsIgnored();
+ ignoredByDefault = axObject->accessibilityIsIgnoredByDefault();
+
+ String invalidValue = axObject->invalidStatus();
+ if (invalidValue == "false")
+ invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::False;
+ else if (invalidValue == "grammar")
+ invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::Grammar;
+ else if (invalidValue == "spelling")
+ invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::Spelling;
+ else // Future versions of ARIA may allow additional truthy values. Ex. format, order, or size.
+ invalid = Inspector::Protocol::DOM::AccessibilityProperties::Invalid::True;
+
+ if (axObject->isARIAHidden() || axObject->isDOMHidden())
+ hidden = true;
+
+ label = axObject->computedLabel();
+
+ if (axObject->supportsARIALiveRegion()) {
+ supportsLiveRegion = true;
+ liveRegionAtomic = axObject->ariaLiveRegionAtomic();
+
+ String ariaRelevantAttrValue = axObject->ariaLiveRegionRelevant();
+ if (!ariaRelevantAttrValue.isEmpty()) {
+ // FIXME: Pass enum values rather than strings once unblocked. http://webkit.org/b/133711
+ String ariaRelevantAdditions = Inspector::Protocol::InspectorHelpers::getEnumConstantValue(Inspector::Protocol::DOM::LiveRegionRelevant::Additions);
+ String ariaRelevantRemovals = Inspector::Protocol::InspectorHelpers::getEnumConstantValue(Inspector::Protocol::DOM::LiveRegionRelevant::Removals);
+ String ariaRelevantText = Inspector::Protocol::InspectorHelpers::getEnumConstantValue(Inspector::Protocol::DOM::LiveRegionRelevant::Text);
+ liveRegionRelevant = Inspector::Protocol::Array<String>::create();
+ const SpaceSplitString& values = SpaceSplitString(ariaRelevantAttrValue, true);
+ // @aria-relevant="all" is exposed as ["additions","removals","text"], in order.
+ // This order is controlled in WebCore and expected in WebInspectorUI.
+ if (values.contains("all")) {
+ liveRegionRelevant->addItem(ariaRelevantAdditions);
+ liveRegionRelevant->addItem(ariaRelevantRemovals);
+ liveRegionRelevant->addItem(ariaRelevantText);
+ } else {
+ if (values.contains(ariaRelevantAdditions))
+ liveRegionRelevant->addItem(ariaRelevantAdditions);
+ if (values.contains(ariaRelevantRemovals))
+ liveRegionRelevant->addItem(ariaRelevantRemovals);
+ if (values.contains(ariaRelevantText))
+ liveRegionRelevant->addItem(ariaRelevantText);
+ }
+ }
+
+ String ariaLive = axObject->ariaLiveRegionStatus();
+ if (ariaLive == "assertive")
+ liveRegionStatus = Inspector::Protocol::DOM::AccessibilityProperties::LiveRegionStatus::Assertive;
+ else if (ariaLive == "polite")
+ liveRegionStatus = Inspector::Protocol::DOM::AccessibilityProperties::LiveRegionStatus::Polite;
+ }
+
+ if (is<AccessibilityNodeObject>(*axObject))
+ mouseEventNode = downcast<AccessibilityNodeObject>(*axObject).mouseButtonListener(MouseButtonListenerResultFilter::IncludeBodyElement);
+
+ if (axObject->supportsARIAOwns()) {
+ Vector<Element*> ownedElements;
+ axObject->elementsFromAttribute(ownedElements, aria_ownsAttr);
+ if (ownedElements.size()) {
+ ownedNodeIds = Inspector::Protocol::Array<int>::create();
+ for (Element* ownedElement : ownedElements)
+ ownedNodeIds->addItem(pushNodePathToFrontend(ownedElement));
+ }
+ }
+
+ if (AccessibilityObject* parentObject = axObject->parentObjectUnignored())
+ parentNode = parentObject->node();
+
+ supportsPressed = axObject->ariaPressedIsPresent();
+ if (supportsPressed)
+ pressed = axObject->isPressed();
+
+ if (axObject->isTextControl())
+ readonly = !axObject->canSetValueAttribute();
+
+ supportsRequired = axObject->supportsRequiredAttribute();
+ if (supportsRequired)
+ required = axObject->isRequired();
+
+ role = axObject->computedRoleString();
+ selected = axObject->isSelected();
+
+ AccessibilityObject::AccessibilityChildrenVector selectedChildren;
+ axObject->selectedChildren(selectedChildren);
+ if (selectedChildren.size()) {
+ selectedChildNodeIds = Inspector::Protocol::Array<int>::create();
+ for (auto& selectedChildObject : selectedChildren) {
+ if (Node* selectedChildNode = selectedChildObject->node())
+ selectedChildNodeIds->addItem(pushNodePathToFrontend(selectedChildNode));
+ }
+ }
+
+ headingLevel = axObject->headingLevel();
+ hierarchicalLevel = axObject->hierarchicalLevel();
+
+ level = hierarchicalLevel ? hierarchicalLevel : headingLevel;
+ isPopupButton = axObject->isPopUpButton() || axObject->ariaHasPopup();
+ }
+ }
+
+ Ref<Inspector::Protocol::DOM::AccessibilityProperties> value = Inspector::Protocol::DOM::AccessibilityProperties::create()
+ .setExists(exists)
+ .setLabel(label)
+ .setRole(role)
+ .setNodeId(pushNodePathToFrontend(node))
+ .release();
+
+ if (exists) {
+ if (activeDescendantNode)
+ value->setActiveDescendantNodeId(pushNodePathToFrontend(activeDescendantNode));
+ if (busy)
+ value->setBusy(busy);
+ if (supportsChecked)
+ value->setChecked(checked);
+ if (childNodeIds)
+ value->setChildNodeIds(childNodeIds);
+ if (controlledNodeIds)
+ value->setControlledNodeIds(controlledNodeIds);
+ if (currentState != Inspector::Protocol::DOM::AccessibilityProperties::Current::False)
+ value->setCurrent(currentState);
+ if (disabled)
+ value->setDisabled(disabled);
+ if (supportsExpanded)
+ value->setExpanded(expanded);
+ if (flowedNodeIds)
+ value->setFlowedNodeIds(flowedNodeIds);
+ if (supportsFocused)
+ value->setFocused(focused);
+ if (ignored)
+ value->setIgnored(ignored);
+ if (ignoredByDefault)
+ value->setIgnoredByDefault(ignoredByDefault);
+ if (invalid != Inspector::Protocol::DOM::AccessibilityProperties::Invalid::False)
+ value->setInvalid(invalid);
+ if (hidden)
+ value->setHidden(hidden);
+ if (supportsLiveRegion) {
+ value->setLiveRegionAtomic(liveRegionAtomic);
+ if (liveRegionRelevant->length())
+ value->setLiveRegionRelevant(liveRegionRelevant);
+ value->setLiveRegionStatus(liveRegionStatus);
+ }
+ if (mouseEventNode)
+ value->setMouseEventNodeId(pushNodePathToFrontend(mouseEventNode));
+ if (ownedNodeIds)
+ value->setOwnedNodeIds(ownedNodeIds);
+ if (parentNode)
+ value->setParentNodeId(pushNodePathToFrontend(parentNode));
+ if (supportsPressed)
+ value->setPressed(pressed);
+ if (readonly)
+ value->setReadonly(readonly);
+ if (supportsRequired)
+ value->setRequired(required);
+ if (selected)
+ value->setSelected(selected);
+ if (selectedChildNodeIds)
+ value->setSelectedChildNodeIds(selectedChildNodeIds);
+
+ // H1 -- H6 always have a headingLevel property that can be complimented by a hierarchicalLevel
+ // property when aria-level is set on the element, in which case we want to remain calling
+ // this value the "Heading Level" in the inspector.
+ // Also, we do not want it to say Hierarchy Level: 0
+ if (headingLevel)
+ value->setHeadingLevel(level);
+ else if (level)
+ value->setHierarchyLevel(level);
+ if (isPopupButton)
+ value->setIsPopUpButton(isPopupButton);
+ }
+
+ return WTFMove(value);
}
Node* InspectorDOMAgent::innerFirstChild(Node* node)
@@ -1439,10 +1906,11 @@ unsigned InspectorDOMAgent::innerChildNodeCount(Node* node)
Node* InspectorDOMAgent::innerParentNode(Node* node)
{
- if (node->isDocumentNode()) {
- Document* document = toDocument(node);
- return document->ownerElement();
- }
+ ASSERT(node);
+ if (is<Document>(*node))
+ return downcast<Document>(*node).ownerElement();
+ if (is<ShadowRoot>(*node))
+ return downcast<ShadowRoot>(*node).host();
return node->parentNode();
}
@@ -1462,7 +1930,7 @@ void InspectorDOMAgent::mainFrameDOMContentLoaded()
void InspectorDOMAgent::didCommitLoad(Document* document)
{
- Element* frameOwner = document->ownerElement();
+ RefPtr<Element> frameOwner = document->ownerElement();
if (!frameOwner)
return;
@@ -1471,25 +1939,25 @@ void InspectorDOMAgent::didCommitLoad(Document* document)
return;
// Re-add frame owner element together with its new children.
- int parentId = m_documentNodeToIdMap.get(innerParentNode(frameOwner));
+ int parentId = m_documentNodeToIdMap.get(innerParentNode(frameOwner.get()));
m_frontendDispatcher->childNodeRemoved(parentId, frameOwnerId);
- unbind(frameOwner, &m_documentNodeToIdMap);
+ unbind(frameOwner.get(), &m_documentNodeToIdMap);
- RefPtr<Inspector::TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, &m_documentNodeToIdMap);
- Node* previousSibling = innerPreviousSibling(frameOwner);
+ Ref<Inspector::Protocol::DOM::Node> value = buildObjectForNode(frameOwner.get(), 0, &m_documentNodeToIdMap);
+ Node* previousSibling = innerPreviousSibling(frameOwner.get());
int prevId = previousSibling ? m_documentNodeToIdMap.get(previousSibling) : 0;
- m_frontendDispatcher->childNodeInserted(parentId, prevId, value.release());
+ m_frontendDispatcher->childNodeInserted(parentId, prevId, WTFMove(value));
}
-void InspectorDOMAgent::didInsertDOMNode(Node* node)
+void InspectorDOMAgent::didInsertDOMNode(Node& node)
{
- if (isWhitespace(node))
+ if (isWhitespace(&node))
return;
// We could be attaching existing subtree. Forget the bindings.
- unbind(node, &m_documentNodeToIdMap);
+ unbind(&node, &m_documentNodeToIdMap);
- ContainerNode* parent = node->parentNode();
+ ContainerNode* parent = node.parentNode();
if (!parent)
return;
@@ -1503,19 +1971,19 @@ void InspectorDOMAgent::didInsertDOMNode(Node* node)
m_frontendDispatcher->childNodeCountUpdated(parentId, innerChildNodeCount(parent));
} else {
// Children have been requested -> return value of a new child.
- Node* prevSibling = innerPreviousSibling(node);
+ Node* prevSibling = innerPreviousSibling(&node);
int prevId = prevSibling ? m_documentNodeToIdMap.get(prevSibling) : 0;
- RefPtr<Inspector::TypeBuilder::DOM::Node> value = buildObjectForNode(node, 0, &m_documentNodeToIdMap);
- m_frontendDispatcher->childNodeInserted(parentId, prevId, value.release());
+ Ref<Inspector::Protocol::DOM::Node> value = buildObjectForNode(&node, 0, &m_documentNodeToIdMap);
+ m_frontendDispatcher->childNodeInserted(parentId, prevId, WTFMove(value));
}
}
-void InspectorDOMAgent::didRemoveDOMNode(Node* node)
+void InspectorDOMAgent::didRemoveDOMNode(Node& node)
{
- if (isWhitespace(node))
+ if (isWhitespace(&node))
return;
- ContainerNode* parent = node->parentNode();
+ ContainerNode* parent = node.parentNode();
// If parent is not mapped yet -> ignore the event.
if (!m_documentNodeToIdMap.contains(parent))
@@ -1528,23 +1996,23 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node)
if (innerChildNodeCount(parent) == 1)
m_frontendDispatcher->childNodeCountUpdated(parentId, 0);
} else
- m_frontendDispatcher->childNodeRemoved(parentId, m_documentNodeToIdMap.get(node));
- unbind(node, &m_documentNodeToIdMap);
+ m_frontendDispatcher->childNodeRemoved(parentId, m_documentNodeToIdMap.get(&node));
+ unbind(&node, &m_documentNodeToIdMap);
}
-void InspectorDOMAgent::willModifyDOMAttr(Element*, const AtomicString& oldValue, const AtomicString& newValue)
+void InspectorDOMAgent::willModifyDOMAttr(Element&, const AtomicString& oldValue, const AtomicString& newValue)
{
m_suppressAttributeModifiedEvent = (oldValue == newValue);
}
-void InspectorDOMAgent::didModifyDOMAttr(Element* element, const AtomicString& name, const AtomicString& value)
+void InspectorDOMAgent::didModifyDOMAttr(Element& element, const AtomicString& name, const AtomicString& value)
{
bool shouldSuppressEvent = m_suppressAttributeModifiedEvent;
m_suppressAttributeModifiedEvent = false;
if (shouldSuppressEvent)
return;
- int id = boundNodeId(element);
+ int id = boundNodeId(&element);
// If node is not mapped yet -> ignore the event.
if (!id)
return;
@@ -1555,9 +2023,9 @@ void InspectorDOMAgent::didModifyDOMAttr(Element* element, const AtomicString& n
m_frontendDispatcher->attributeModified(id, name, value);
}
-void InspectorDOMAgent::didRemoveDOMAttr(Element* element, const AtomicString& name)
+void InspectorDOMAgent::didRemoveDOMAttr(Element& element, const AtomicString& name)
{
- int id = boundNodeId(element);
+ int id = boundNodeId(&element);
// If node is not mapped yet -> ignore the event.
if (!id)
return;
@@ -1570,68 +2038,74 @@ void InspectorDOMAgent::didRemoveDOMAttr(Element* element, const AtomicString& n
void InspectorDOMAgent::styleAttributeInvalidated(const Vector<Element*>& elements)
{
- RefPtr<Inspector::TypeBuilder::Array<int>> nodeIds = Inspector::TypeBuilder::Array<int>::create();
- for (unsigned i = 0, size = elements.size(); i < size; ++i) {
- Element* element = elements.at(i);
+ auto nodeIds = Inspector::Protocol::Array<int>::create();
+ for (auto& element : elements) {
int id = boundNodeId(element);
// If node is not mapped yet -> ignore the event.
if (!id)
continue;
if (m_domListener)
- m_domListener->didModifyDOMAttr(element);
+ m_domListener->didModifyDOMAttr(*element);
nodeIds->addItem(id);
}
- m_frontendDispatcher->inlineStyleInvalidated(nodeIds.release());
+ m_frontendDispatcher->inlineStyleInvalidated(WTFMove(nodeIds));
}
-void InspectorDOMAgent::characterDataModified(CharacterData* characterData)
+void InspectorDOMAgent::characterDataModified(CharacterData& characterData)
{
- int id = m_documentNodeToIdMap.get(characterData);
+ int id = m_documentNodeToIdMap.get(&characterData);
if (!id) {
// Push text node if it is being created.
didInsertDOMNode(characterData);
return;
}
- m_frontendDispatcher->characterDataModified(id, characterData->data());
+ m_frontendDispatcher->characterDataModified(id, characterData.data());
}
-void InspectorDOMAgent::didInvalidateStyleAttr(Node* node)
+void InspectorDOMAgent::didInvalidateStyleAttr(Node& node)
{
- int id = m_documentNodeToIdMap.get(node);
+ int id = m_documentNodeToIdMap.get(&node);
// If node is not mapped yet -> ignore the event.
if (!id)
return;
if (!m_revalidateStyleAttrTask)
- m_revalidateStyleAttrTask = adoptPtr(new RevalidateStyleAttributeTask(this));
- m_revalidateStyleAttrTask->scheduleFor(toElement(node));
+ m_revalidateStyleAttrTask = std::make_unique<RevalidateStyleAttributeTask>(this);
+ m_revalidateStyleAttrTask->scheduleFor(downcast<Element>(&node));
}
-void InspectorDOMAgent::didPushShadowRoot(Element* host, ShadowRoot* root)
+void InspectorDOMAgent::didPushShadowRoot(Element& host, ShadowRoot& root)
{
- int hostId = m_documentNodeToIdMap.get(host);
+ int hostId = m_documentNodeToIdMap.get(&host);
if (hostId)
- m_frontendDispatcher->shadowRootPushed(hostId, buildObjectForNode(root, 0, &m_documentNodeToIdMap));
+ m_frontendDispatcher->shadowRootPushed(hostId, buildObjectForNode(&root, 0, &m_documentNodeToIdMap));
}
-void InspectorDOMAgent::willPopShadowRoot(Element* host, ShadowRoot* root)
+void InspectorDOMAgent::willPopShadowRoot(Element& host, ShadowRoot& root)
{
- int hostId = m_documentNodeToIdMap.get(host);
- int rootId = m_documentNodeToIdMap.get(root);
+ int hostId = m_documentNodeToIdMap.get(&host);
+ int rootId = m_documentNodeToIdMap.get(&root);
if (hostId && rootId)
m_frontendDispatcher->shadowRootPopped(hostId, rootId);
}
-void InspectorDOMAgent::frameDocumentUpdated(Frame* frame)
+void InspectorDOMAgent::didChangeCustomElementState(Element& element)
{
- Document* document = frame->document();
+ int elementId = m_documentNodeToIdMap.get(&element);
+ if (!elementId)
+ return;
+
+ m_frontendDispatcher->customElementStateChanged(elementId, customElementState(element));
+}
+
+void InspectorDOMAgent::frameDocumentUpdated(Frame& frame)
+{
+ Document* document = frame.document();
if (!document)
return;
- Page* page = frame->page();
- ASSERT(page);
- if (frame != &page->mainFrame())
+ if (!frame.isMainFrame())
return;
// Only update the main frame document, nested frame document updates are not required
@@ -1639,6 +2113,36 @@ void InspectorDOMAgent::frameDocumentUpdated(Frame* frame)
setDocument(document);
}
+void InspectorDOMAgent::pseudoElementCreated(PseudoElement& pseudoElement)
+{
+ Element* parent = pseudoElement.hostElement();
+ if (!parent)
+ return;
+
+ int parentId = m_documentNodeToIdMap.get(parent);
+ if (!parentId)
+ return;
+
+ pushChildNodesToFrontend(parentId, 1);
+ m_frontendDispatcher->pseudoElementAdded(parentId, buildObjectForNode(&pseudoElement, 0, &m_documentNodeToIdMap));
+}
+
+void InspectorDOMAgent::pseudoElementDestroyed(PseudoElement& pseudoElement)
+{
+ int pseudoElementId = m_documentNodeToIdMap.get(&pseudoElement);
+ if (!pseudoElementId)
+ return;
+
+ // If a PseudoElement is bound, its parent element must have been bound.
+ Element* parent = pseudoElement.hostElement();
+ ASSERT(parent);
+ int parentId = m_documentNodeToIdMap.get(parent);
+ ASSERT(parentId);
+
+ unbind(&pseudoElement, &m_documentNodeToIdMap);
+ m_frontendDispatcher->pseudoElementRemoved(parentId, pseudoElementId);
+}
+
Node* InspectorDOMAgent::nodeForPath(const String& path)
{
// The path is of form "1,HTML,2,BODY,1,DIV"
@@ -1647,7 +2151,7 @@ Node* InspectorDOMAgent::nodeForPath(const String& path)
Node* node = m_document.get();
Vector<String> pathTokens;
- path.split(",", false, pathTokens);
+ path.split(',', false, pathTokens);
if (!pathTokens.size())
return 0;
for (size_t i = 0; i < pathTokens.size() - 1; i += 2) {
@@ -1672,67 +2176,67 @@ Node* InspectorDOMAgent::nodeForPath(const String& path)
Node* InspectorDOMAgent::nodeForObjectId(const String& objectId)
{
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
- Deprecated::ScriptValue value = injectedScript.findObjectById(objectId);
- return InspectorDOMAgent::scriptValueAsNode(value);
+ InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId);
+ if (injectedScript.hasNoValue())
+ return nullptr;
+
+ return scriptValueAsNode(injectedScript.findObjectById(objectId));
}
-void InspectorDOMAgent::pushNodeByPathToFrontend(ErrorString* errorString, const String& path, int* nodeId)
+void InspectorDOMAgent::pushNodeByPathToFrontend(ErrorString& errorString, const String& path, int* nodeId)
{
if (Node* node = nodeForPath(path))
*nodeId = pushNodePathToFrontend(node);
else
- *errorString = "No node with given path found";
+ errorString = ASCIILiteral("No node with given path found");
}
-void InspectorDOMAgent::pushNodeByBackendIdToFrontend(ErrorString* errorString, BackendNodeId backendNodeId, int* nodeId)
+void InspectorDOMAgent::pushNodeByBackendIdToFrontend(ErrorString& errorString, BackendNodeId backendNodeId, int* nodeId)
{
- if (!m_backendIdToNode.contains(backendNodeId)) {
- *errorString = "No node with given backend id found";
+ auto iterator = m_backendIdToNode.find(backendNodeId);
+ if (iterator == m_backendIdToNode.end()) {
+ errorString = ASCIILiteral("No node with given backend id found");
return;
}
- Node* node = m_backendIdToNode.get(backendNodeId).first;
- String nodeGroup = m_backendIdToNode.get(backendNodeId).second;
+ Node* node = iterator->value.first;
+ String nodeGroup = iterator->value.second;
+
*nodeId = pushNodePathToFrontend(node);
- if (nodeGroup == "") {
- m_backendIdToNode.remove(backendNodeId);
+ if (nodeGroup.isEmpty()) {
+ m_backendIdToNode.remove(iterator);
+ // FIXME: We really do the following only when nodeGroup is the empty string? Seems wrong.
+ ASSERT(m_nodeGroupToBackendIdMap.contains(nodeGroup));
m_nodeGroupToBackendIdMap.find(nodeGroup)->value.remove(node);
}
}
-PassRefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
+RefPtr<Inspector::Protocol::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
{
- Frame* frame = node->document().frame();
+ auto* frame = node->document().frame();
if (!frame)
- return 0;
+ return nullptr;
- JSC::ExecState* scriptState = mainWorldExecState(frame);
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
+ auto& state = *mainWorldExecState(frame);
+ auto injectedScript = m_injectedScriptManager.injectedScriptFor(&state);
if (injectedScript.hasNoValue())
- return 0;
+ return nullptr;
- return injectedScript.wrapObject(InspectorDOMAgent::nodeAsScriptValue(scriptState, node), objectGroup);
+ return injectedScript.wrapObject(nodeAsScriptValue(state, node), objectGroup);
}
-Node* InspectorDOMAgent::scriptValueAsNode(Deprecated::ScriptValue value)
+Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value)
{
- if (!value.isObject() || value.isNull())
+ if (!value || !value.isObject())
return nullptr;
-
- return toNode(value.jsValue());
+ return JSNode::toWrapped(*value.getObject()->vm(), value.getObject());
}
-Deprecated::ScriptValue InspectorDOMAgent::nodeAsScriptValue(JSC::ExecState* state, Node* node)
+JSC::JSValue InspectorDOMAgent::nodeAsScriptValue(JSC::ExecState& state, Node* node)
{
- if (!shouldAllowAccessToNode(state, node))
- return Deprecated::ScriptValue(state->vm(), JSC::jsNull());
-
- JSC::JSLockHolder lock(state);
- return Deprecated::ScriptValue(state->vm(), toJS(state, deprecatedGlobalObjectForPrototype(state), node));
+ JSC::JSLockHolder lock(&state);
+ return toJS(&state, deprecatedGlobalObjectForPrototype(&state), BindingSecurity::checkSecurityForNode(state, node));
}
} // namespace WebCore
-
-#endif // ENABLE(INSPECTOR)