Title: [208218] trunk
Revision
208218
Author
rn...@webkit.org
Date
2016-11-01 01:12:17 -0700 (Tue, 01 Nov 2016)

Log Message

Web Inspector: Add the support for custom elements
https://bugs.webkit.org/show_bug.cgi?id=164266
Source/_javascript_Core:

<rdar://problem/29038883>

Reviewed by Joseph Pecoraro.

Added customElementState of type CustomElementState to reflect the custom element state on each DOM node
along with customElementStateChanged which fires when the custom element state changes.

* inspector/protocol/DOM.json:

Source/WebCore:

<rdar://problem/29038883>

Reviewed by Joseph Pecoraro.

Set "customElementState" property on each DOMNode object when building a protocol object for the node.
Also added InspectorInstrumentation::didChangeCustomElementState to track the changes to custom element states.

Tests: inspector/dom/customElementState.html

* dom/Element.cpp:
(WebCore::Element::setIsDefinedCustomElement): Invoke didChangeCustomElementState to update the state.
(WebCore::Element::setIsFailedCustomElement): Ditto.
(WebCore::Element::setIsCustomElementUpgradeCandidate): Ditto.
(WebCore::Element::enqueueToUpgrade): Ditto.
* inspector/InspectorDOMAgent.cpp:
(WebCore::customElementState): Added.
(WebCore::InspectorDOMAgent::buildObjectForNode): Set the custom element state.
(WebCore::InspectorDOMAgent::didChangeCustomElementState): Invoke customElementStateChanged.
* inspector/InspectorDOMAgent.h:
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didChangeCustomElementStateImpl): Added.
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::didChangeCustomElementState): Added.

Source/WebInspectorUI:

<rdar://problem/29038883>

Reviewed by Joseph Pecoraro.

Show the custom element state in DOM node's details pane:
 - "Element" for all builtin elements.
 - "Element (Custom)" for any upgraded custom elements.
 - "Element (Waiting to be upgraded)" for any element waiting to be upgraded.
 - "Element (Failed to upgrade)" for any custom element that failed during construction or an upgrade.

And add "Jump to Definition" to the context menu of an node to find the custom element's definition.

* Localizations/en.lproj/localizedStrings.js: Added localized strings.
* UserInterface/Controllers/DOMTreeManager.js:
(WebInspector.DOMTreeManager.prototype._customElementStateChanged): Added. Update the state and fire
WebInspector.DOMTreeManager.Event.CustomElementStateChanged to update the node's details pane.
* UserInterface/Models/DOMNode.js:
(WebInspector.DOMNode): Set the custom element state or default to "builtin". Use null when the node
is not an element.
(WebInspector.DOMNode.prototype.isCustomElement): Added. Returns true if this is a successfully
constructed or upgraded custom element.
(WebInspector.DOMNode.prototype.customElementState): Added.
(WebInspector.DOMNode.CustomElementState): Added.
* UserInterface/Protocol/DOMObserver.js:
(WebInspector.DOMObserver.prototype.customElementStateChanged): Added.
* UserInterface/Protocol/RemoteObject.js:
(WebInspector.RemoteObject.prototype.getProperty): Added. Retrieves the property of a given name from
the remote backend.
* UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
(WebInspector.DOMNodeDetailsSidebarPanel): Call _customElementStateChanged when the custom element
state changes by listening to WebInspector.DOMTreeManager.Event.CustomElementStateChanged.
(WebInspector.DOMNodeDetailsSidebarPanel.prototype.layout):
(WebInspector.DOMNodeDetailsSidebarPanel.prototype._refreshIdentity): Extracted from layout.
(WebInspector.DOMNodeDetailsSidebarPanel.prototype._customElementStateChanged): Added.
(WebInspector.DOMNodeDetailsSidebarPanel.prototype._nodeTypeDisplayName): Include the custom element
state when it's not a builtin element (_customElementState returns null in that case).
(WebInspector.DOMNodeDetailsSidebarPanel.prototype._customElementState): Get the localized string for
each custom element state.
* UserInterface/Views/DOMTreeElement.js:
(WebInspector.DOMTreeElement.prototype._populateNodeContextMenu): Add "Jump to Definition" item in the
context menu of an element when it's a successfully constructed or upgraded custom element.

LayoutTests:

Reviewed by Joseph Pecoraro.

Added a Inspector protocol test for CustomElementState.

* inspector/dom/customElementState-expected.txt: Added.
* inspector/dom/customElementState.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (208217 => 208218)


--- trunk/LayoutTests/ChangeLog	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/LayoutTests/ChangeLog	2016-11-01 08:12:17 UTC (rev 208218)
@@ -1,3 +1,15 @@
+2016-11-01  Ryosuke Niwa  <rn...@webkit.org>
+
+        Web Inspector: Add the support for custom elements
+        https://bugs.webkit.org/show_bug.cgi?id=164266
+
+        Reviewed by Joseph Pecoraro.
+
+        Added a Inspector protocol test for CustomElementState.
+
+        * inspector/dom/customElementState-expected.txt: Added.
+        * inspector/dom/customElementState.html: Added.
+
 2016-10-31  Simon Fraser  <simon.fra...@apple.com>
 
         Add basic visual/layout viewport support for fixed position layout

Added: trunk/LayoutTests/inspector/dom/customElementState-expected.txt (0 => 208218)


--- trunk/LayoutTests/inspector/dom/customElementState-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/dom/customElementState-expected.txt	2016-11-01 08:12:17 UTC (rev 208218)
@@ -0,0 +1,21 @@
+CONSOLE MESSAGE: line 91: failedElementError
+Test for DOMNode.customElementState.
+
+Uncaught exception in test page: failedElementError [customElementState.html:91]
+
+== Running test suite: DOMNode.customElementState
+-- Running test case: CustomElementState.Builtin
+PASS: #builtin should be CustomElementState.Builtin.
+
+-- Running test case: CustomElementState.Custom.Constructed
+PASS: constructed-element should be CustomElementState.Custom.
+
+-- Running test case: CustomElementState.Custom.Upgraded
+PASS: upgraded-element should be CustomElementState.Custom.
+
+-- Running test case: CustomElementState.Waiting
+PASS: undefined-element should be CustomElementState.Waiting.
+
+-- Running test case: CustomElementState.Failed
+PASS: failed-element should be CustomElementState.Failed.
+

Added: trunk/LayoutTests/inspector/dom/customElementState.html (0 => 208218)


--- trunk/LayoutTests/inspector/dom/customElementState.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/dom/customElementState.html	2016-11-01 08:12:17 UTC (rev 208218)
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+TestPage.allowUncaughtExceptions = true;
+TestPage.needToSanitizeUncaughtExceptionURLs = true;
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("DOMNode.customElementState");
+    let documentNode;
+
+    suite.addTestCase({
+        name: "CustomElementState.Builtin",
+        test(resolve, reject) {
+            WebInspector.domTreeManager.querySelector(documentNode.id, "#builtin", (nodeId) => {
+                const node = WebInspector.domTreeManager.nodeForId(nodeId);
+                InspectorTest.expectEqual(node.customElementState(), "builtin", "#builtin should be CustomElementState.Builtin.");
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "CustomElementState.Custom.Constructed",
+        test(resolve, reject) {
+            WebInspector.domTreeManager.querySelector(documentNode.id, "constructed-element", (nodeId) => {
+                const node = WebInspector.domTreeManager.nodeForId(nodeId);
+                InspectorTest.expectEqual(node.customElementState(), "custom", "constructed-element should be CustomElementState.Custom.");
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "CustomElementState.Custom.Upgraded",
+        test(resolve, reject) {
+            WebInspector.domTreeManager.querySelector(documentNode.id, "upgraded-element", (nodeId) => {
+                const node = WebInspector.domTreeManager.nodeForId(nodeId);
+                InspectorTest.expectEqual(node.customElementState(), "custom", "upgraded-element should be CustomElementState.Custom.");
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "CustomElementState.Waiting",
+        test(resolve, reject) {
+            WebInspector.domTreeManager.querySelector(documentNode.id, "undefined-element", (nodeId) => {
+                const node = WebInspector.domTreeManager.nodeForId(nodeId);
+                InspectorTest.expectEqual(node.customElementState(), "waiting", "undefined-element should be CustomElementState.Waiting.");
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "CustomElementState.Failed",
+        test(resolve, reject) {
+            WebInspector.domTreeManager.querySelector(documentNode.id, "failed-element", (nodeId) => {
+                const node = WebInspector.domTreeManager.nodeForId(nodeId);
+                InspectorTest.expectEqual(node.customElementState(), "failed", "failed-element should be CustomElementState.Failed.");
+                resolve();
+            });
+        }
+    });
+
+    WebInspector.domTreeManager.requestDocument((node) => {
+        documentNode = node;
+        suite.runTestCasesAndFinish();
+    });
+}
+
+customElements.define("constructed-element", class extends HTMLElement { });
+
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Test for DOMNode.customElementState.</p>
+<div style="display: none">
+    <input id="builtin">
+    <constructed-element></constructed-element>
+    <upgraded-element></upgraded-element>
+    <undefined-element></undefined-element>
+    <failed-element></failed-element>
+</div>
+<script>
+
+customElements.define("upgraded-element", class extends HTMLElement { });
+customElements.define("failed-element", class extends HTMLElement { constructor() { super(); throw "failedElementError"; } });
+
+</script>
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (208217 => 208218)


--- trunk/Source/_javascript_Core/ChangeLog	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-11-01 08:12:17 UTC (rev 208218)
@@ -1,3 +1,16 @@
+2016-11-01  Ryosuke Niwa  <rn...@webkit.org>
+
+        Web Inspector: Add the support for custom elements
+        https://bugs.webkit.org/show_bug.cgi?id=164266
+        <rdar://problem/29038883>
+
+        Reviewed by Joseph Pecoraro.
+
+        Added customElementState of type CustomElementState to reflect the custom element state on each DOM node
+        along with customElementStateChanged which fires when the custom element state changes.
+
+        * inspector/protocol/DOM.json:
+
 2016-10-31  Simon Fraser  <simon.fra...@apple.com>
 
         Fix the EFL build.

Modified: trunk/Source/_javascript_Core/inspector/protocol/DOM.json (208217 => 208218)


--- trunk/Source/_javascript_Core/inspector/protocol/DOM.json	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/_javascript_Core/inspector/protocol/DOM.json	2016-11-01 08:12:17 UTC (rev 208218)
@@ -26,6 +26,12 @@
             "description": "Shadow root type."
         },
         {
+            "id": "CustomElementState",
+            "type": "string",
+            "enum": ["builtin", "custom", "waiting", "failed"],
+            "description": "Custom element state."
+        },
+        {
             "id": "LiveRegionRelevant",
             "type": "string",
             "enum": ["additions", "removals", "text"],
@@ -52,6 +58,7 @@
                 { "name": "value", "type": "string", "optional": true, "description": "<code>Attr</code>'s value." },
                 { "name": "pseudoType", "$ref": "PseudoType", "optional": true, "description": "Pseudo element type for this node." },
                 { "name": "shadowRootType", "$ref": "ShadowRootType", "optional": true, "description": "Shadow root type." },
+                { "name": "customElementState", "$ref": "CustomElementState", "optional": true, "description": "Custom element state." },
                 { "name": "frameId", "$ref": "Network.FrameId", "optional": true, "description": "Frame ID for frame owner elements." },
                 { "name": "contentDocument", "$ref": "Node", "optional": true, "description": "Content document for frame owner elements." },
                 { "name": "shadowRoots", "type": "array", "optional": true, "items": { "$ref": "Node" }, "description": "Shadow root list for given element host." },
@@ -546,6 +553,14 @@
             "description": "Called when shadow root is popped from the element."
         },
         {
+            "name": "customElementStateChanged",
+            "parameters": [
+                { "name": "nodeId", "$ref": "NodeId", "description": "Element id." },
+                { "name": "customElementState", "$ref": "CustomElementState", "description": "Custom element state." }
+            ],
+            "description": "Called when the custom element state is changed."
+        },
+        {
             "name": "pseudoElementAdded",
             "parameters": [
                 { "name": "parentId", "$ref": "NodeId", "description": "Pseudo element's parent element id." },

Modified: trunk/Source/WebCore/ChangeLog (208217 => 208218)


--- trunk/Source/WebCore/ChangeLog	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebCore/ChangeLog	2016-11-01 08:12:17 UTC (rev 208218)
@@ -1,3 +1,31 @@
+2016-11-01  Ryosuke Niwa  <rn...@webkit.org>
+
+        Web Inspector: Add the support for custom elements
+        https://bugs.webkit.org/show_bug.cgi?id=164266
+        <rdar://problem/29038883>
+
+        Reviewed by Joseph Pecoraro.
+
+        Set "customElementState" property on each DOMNode object when building a protocol object for the node.
+        Also added InspectorInstrumentation::didChangeCustomElementState to track the changes to custom element states.
+
+        Tests: inspector/dom/customElementState.html
+
+        * dom/Element.cpp:
+        (WebCore::Element::setIsDefinedCustomElement): Invoke didChangeCustomElementState to update the state.
+        (WebCore::Element::setIsFailedCustomElement): Ditto.
+        (WebCore::Element::setIsCustomElementUpgradeCandidate): Ditto.
+        (WebCore::Element::enqueueToUpgrade): Ditto.
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::customElementState): Added.
+        (WebCore::InspectorDOMAgent::buildObjectForNode): Set the custom element state.
+        (WebCore::InspectorDOMAgent::didChangeCustomElementState): Invoke customElementStateChanged.
+        * inspector/InspectorDOMAgent.h:
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didChangeCustomElementStateImpl): Added.
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::didChangeCustomElementState): Added.
+
 2016-10-31  Ryosuke Niwa  <rn...@webkit.org>
 
         Add StaticPasteboard.cpp to the cmake after r207841.

Modified: trunk/Source/WebCore/dom/Element.cpp (208217 => 208218)


--- trunk/Source/WebCore/dom/Element.cpp	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebCore/dom/Element.cpp	2016-11-01 08:12:17 UTC (rev 208218)
@@ -1883,6 +1883,7 @@
     auto& data = ""
     if (!data.customElementReactionQueue())
         data.setCustomElementReactionQueue(std::make_unique<CustomElementReactionQueue>(elementInterface));
+    InspectorInstrumentation::didChangeCustomElementState(*this);
 }
 
 void Element::setIsFailedCustomElement(JSCustomElementInterface&)
@@ -1896,6 +1897,7 @@
         if (auto* queue = elementRareData()->customElementReactionQueue())
             queue->clear();
     }
+    InspectorInstrumentation::didChangeCustomElementState(*this);
 }
 
 void Element::setIsCustomElementUpgradeCandidate()
@@ -1903,6 +1905,7 @@
     ASSERT(!getFlag(IsCustomElement));
     setFlag(IsCustomElement);
     setFlag(IsEditingTextOrUndefinedCustomElementFlag);
+    InspectorInstrumentation::didChangeCustomElementState(*this);
 }
 
 void Element::enqueueToUpgrade(JSCustomElementInterface& elementInterface)
@@ -1910,6 +1913,7 @@
     ASSERT(!isDefinedCustomElement() && !isFailedCustomElement());
     setFlag(IsCustomElement);
     setFlag(IsEditingTextOrUndefinedCustomElementFlag);
+    InspectorInstrumentation::didChangeCustomElementState(*this);
 
     auto& data = ""
     ASSERT(!data.customElementReactionQueue());

Modified: trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp (208217 => 208218)


--- trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp	2016-11-01 08:12:17 UTC (rev 208218)
@@ -1303,6 +1303,17 @@
     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;
+}
+
 static String computeContentSecurityPolicySHA256Hash(const Element& element)
 {
     // FIXME: Compute the digest with respect to the raw bytes received from the page.
@@ -1390,6 +1401,10 @@
         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))
@@ -2075,6 +2090,15 @@
         m_frontendDispatcher->shadowRootPopped(hostId, rootId);
 }
 
+void InspectorDOMAgent::didChangeCustomElementState(Element& element)
+{
+    int elementId = m_documentNodeToIdMap.get(&element);
+    if (!elementId)
+        return;
+
+    m_frontendDispatcher->customElementStateChanged(elementId, customElementState(element));
+}
+
 void InspectorDOMAgent::frameDocumentUpdated(Frame* frame)
 {
     Document* document = frame->document();

Modified: trunk/Source/WebCore/inspector/InspectorDOMAgent.h (208217 => 208218)


--- trunk/Source/WebCore/inspector/InspectorDOMAgent.h	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebCore/inspector/InspectorDOMAgent.h	2016-11-01 08:12:17 UTC (rev 208218)
@@ -168,6 +168,7 @@
     void didInvalidateStyleAttr(Node&);
     void didPushShadowRoot(Element& host, ShadowRoot&);
     void willPopShadowRoot(Element& host, ShadowRoot&);
+    void didChangeCustomElementState(Element&);
     bool handleTouchEvent(Node&);
     void didCommitLoad(Document*);
     void frameDocumentUpdated(Frame*);

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (208217 => 208218)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2016-11-01 08:12:17 UTC (rev 208218)
@@ -219,6 +219,12 @@
         domAgent->willPopShadowRoot(host, root);
 }
 
+void InspectorInstrumentation::didChangeCustomElementStateImpl(InstrumentingAgents& instrumentingAgents, Element& element)
+{
+    if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
+        domAgent->didChangeCustomElementState(element);
+}
+
 void InspectorInstrumentation::pseudoElementCreatedImpl(InstrumentingAgents& instrumentingAgents, PseudoElement& pseudoElement)
 {
     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (208217 => 208218)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2016-11-01 08:12:17 UTC (rev 208218)
@@ -122,6 +122,7 @@
     static void activeStyleSheetsUpdated(Document&);
     static void didPushShadowRoot(Element& host, ShadowRoot&);
     static void willPopShadowRoot(Element& host, ShadowRoot&);
+    static void didChangeCustomElementState(Element&);
     static void pseudoElementCreated(Page*, PseudoElement&);
     static void pseudoElementDestroyed(Page*, PseudoElement&);
     static void didCreateNamedFlow(Document*, WebKitNamedFlow&);
@@ -295,6 +296,7 @@
     static void activeStyleSheetsUpdatedImpl(InstrumentingAgents&, Document&);
     static void didPushShadowRootImpl(InstrumentingAgents&, Element& host, ShadowRoot&);
     static void willPopShadowRootImpl(InstrumentingAgents&, Element& host, ShadowRoot&);
+    static void didChangeCustomElementStateImpl(InstrumentingAgents&, Element&);
     static void pseudoElementCreatedImpl(InstrumentingAgents&, PseudoElement&);
     static void pseudoElementDestroyedImpl(InstrumentingAgents&, PseudoElement&);
     static void didCreateNamedFlowImpl(InstrumentingAgents&, Document*, WebKitNamedFlow&);
@@ -567,6 +569,13 @@
         willPopShadowRootImpl(*instrumentingAgents, host, root);
 }
 
+inline void InspectorInstrumentation::didChangeCustomElementState(Element& element)
+{
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(element.document()))
+        didChangeCustomElementStateImpl(*instrumentingAgents, element);
+}
+
 inline void InspectorInstrumentation::pseudoElementCreated(Page* page, PseudoElement& pseudoElement)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());

Modified: trunk/Source/WebInspectorUI/ChangeLog (208217 => 208218)


--- trunk/Source/WebInspectorUI/ChangeLog	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/ChangeLog	2016-11-01 08:12:17 UTC (rev 208218)
@@ -1,3 +1,49 @@
+2016-11-01  Ryosuke Niwa  <rn...@webkit.org>
+
+        Web Inspector: Add the support for custom elements
+        https://bugs.webkit.org/show_bug.cgi?id=164266
+        <rdar://problem/29038883>
+
+        Reviewed by Joseph Pecoraro.
+
+        Show the custom element state in DOM node's details pane:
+         - "Element" for all builtin elements.
+         - "Element (Custom)" for any upgraded custom elements.
+         - "Element (Waiting to be upgraded)" for any element waiting to be upgraded.
+         - "Element (Failed to upgrade)" for any custom element that failed during construction or an upgrade.
+
+        And add "Jump to Definition" to the context menu of an node to find the custom element's definition.
+
+        * Localizations/en.lproj/localizedStrings.js: Added localized strings.
+        * UserInterface/Controllers/DOMTreeManager.js:
+        (WebInspector.DOMTreeManager.prototype._customElementStateChanged): Added. Update the state and fire
+        WebInspector.DOMTreeManager.Event.CustomElementStateChanged to update the node's details pane.
+        * UserInterface/Models/DOMNode.js:
+        (WebInspector.DOMNode): Set the custom element state or default to "builtin". Use null when the node
+        is not an element.
+        (WebInspector.DOMNode.prototype.isCustomElement): Added. Returns true if this is a successfully
+        constructed or upgraded custom element.
+        (WebInspector.DOMNode.prototype.customElementState): Added.
+        (WebInspector.DOMNode.CustomElementState): Added.
+        * UserInterface/Protocol/DOMObserver.js:
+        (WebInspector.DOMObserver.prototype.customElementStateChanged): Added.
+        * UserInterface/Protocol/RemoteObject.js:
+        (WebInspector.RemoteObject.prototype.getProperty): Added. Retrieves the property of a given name from
+        the remote backend.
+        * UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
+        (WebInspector.DOMNodeDetailsSidebarPanel): Call _customElementStateChanged when the custom element
+        state changes by listening to WebInspector.DOMTreeManager.Event.CustomElementStateChanged.
+        (WebInspector.DOMNodeDetailsSidebarPanel.prototype.layout):
+        (WebInspector.DOMNodeDetailsSidebarPanel.prototype._refreshIdentity): Extracted from layout.
+        (WebInspector.DOMNodeDetailsSidebarPanel.prototype._customElementStateChanged): Added. 
+        (WebInspector.DOMNodeDetailsSidebarPanel.prototype._nodeTypeDisplayName): Include the custom element
+        state when it's not a builtin element (_customElementState returns null in that case).
+        (WebInspector.DOMNodeDetailsSidebarPanel.prototype._customElementState): Get the localized string for
+        each custom element state.
+        * UserInterface/Views/DOMTreeElement.js:
+        (WebInspector.DOMTreeElement.prototype._populateNodeContextMenu): Add "Jump to Definition" item in the
+        context menu of an element when it's a successfully constructed or upgraded custom element.
+
 2016-10-31  Joseph Pecoraro  <pecor...@apple.com>
 
         Web Inspector: Shadow DOM scoped styles are missing

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (208217 => 208218)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2016-11-01 08:12:17 UTC (rev 208218)
@@ -219,6 +219,7 @@
 localizedStrings["Create a new tab"] = "Create a new tab";
 localizedStrings["Current"] = "Current";
 localizedStrings["Cursor"] = "Cursor";
+localizedStrings["Custom"] = "Custom";
 localizedStrings["DNS"] = "DNS";
 localizedStrings["DOM Content Loaded \u2014 %s"] = "DOM Content Loaded \u2014 %s";
 localizedStrings["Damping"] = "Damping";
@@ -338,6 +339,7 @@
 localizedStrings["Extension Scripts"] = "Extension Scripts";
 localizedStrings["Extra Scripts"] = "Extra Scripts";
 localizedStrings["Fade unexecuted code"] = "Fade unexecuted code";
+localizedStrings["Failed to upgrade"] = "Failed to upgrade";
 localizedStrings["Family"] = "Family";
 localizedStrings["Features"] = "Features";
 localizedStrings["File or Resource"] = "File or Resource";
@@ -813,6 +815,7 @@
 localizedStrings["Vertical"] = "Vertical";
 localizedStrings["Visibility"] = "Visibility";
 localizedStrings["Visible"] = "Visible";
+localizedStrings["Waiting to be upgraded"] = "Waiting to be upgraded";
 localizedStrings["Warning: "] = "Warning: ";
 localizedStrings["Warnings"] = "Warnings";
 localizedStrings["Watch Expressions"] = "Watch Expressions";

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMTreeManager.js (208217 => 208218)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMTreeManager.js	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMTreeManager.js	2016-11-01 08:12:17 UTC (rev 208218)
@@ -248,6 +248,13 @@
         this._unbind(node);
         this.dispatchEventToListeners(WebInspector.DOMTreeManager.Event.NodeRemoved, {node, parent});
     }
+    
+    _customElementStateChanged(elementId, newState)
+    {
+        const node = this._idToDOMNode[elementId];
+        node._customElementState = newState;
+        this.dispatchEventToListeners(WebInspector.DOMTreeManager.Event.CustomElementStateChanged, {node});
+    }
 
     _pseudoElementAdded(parentId, pseudoElement)
     {
@@ -779,6 +786,7 @@
     CharacterDataModified: "dom-tree-manager-character-data-modified",
     NodeInserted: "dom-tree-manager-node-inserted",
     NodeRemoved: "dom-tree-manager-node-removed",
+    CustomElementStateChanged: "dom-tree-manager-custom-element-state-changed",
     DocumentUpdated: "dom-tree-manager-document-updated",
     ChildNodeCountUpdated: "dom-tree-manager-child-node-count-updated",
     DOMNodeWasInspected: "dom-tree-manager-dom-node-was-inspected",

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js (208217 => 208218)


--- trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js	2016-11-01 08:12:17 UTC (rev 208218)
@@ -83,6 +83,11 @@
             }
         }
 
+        if (this._nodeType === Node.ELEMENT_NODE)
+            this._customElementState = payload.customElementState || WebInspector.DOMNode.CustomElementState.Builtin;
+        else
+            this._customElementState = null;
+
         if (payload.templateContent) {
             this._templateContent = new WebInspector.DOMNode(this._domTreeManager, this.ownerDocument, false, payload.templateContent);
             this._templateContent.parentNode = this;
@@ -263,6 +268,16 @@
         return this._isInShadowTree && this.ancestorShadowRoot().isUserAgentShadowRoot();
     }
 
+    isCustomElement()
+    {
+        return this._customElementState === WebInspector.DOMNode.CustomElementState.Custom;
+    }
+
+    customElementState()
+    {
+        return this._customElementState;
+    }
+
     isShadowRoot()
     {
         return !!this._shadowRootType;
@@ -808,3 +823,10 @@
     Closed: "closed",
     Open: "open",
 };
+                     
+WebInspector.DOMNode.CustomElementState = {
+    Builtin: "builtin",
+    Custom: "custom",
+    Waiting: "waiting",
+    Failed: "failed",
+};

Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/DOMObserver.js (208217 => 208218)


--- trunk/Source/WebInspectorUI/UserInterface/Protocol/DOMObserver.js	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/DOMObserver.js	2016-11-01 08:12:17 UTC (rev 208218)
@@ -82,6 +82,11 @@
         WebInspector.domTreeManager._childNodeRemoved(parentNodeId, nodeId);
     }
 
+    customElementStateChanged(nodeId, customElementState)
+    {
+        WebInspector.domTreeManager._customElementStateChanged(nodeId, customElementState);
+    }
+
     pseudoElementAdded(parentNodeId, pseudoElement)
     {
         WebInspector.domTreeManager._pseudoElementAdded(parentNodeId, pseudoElement);

Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js (208217 => 208218)


--- trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js	2016-11-01 08:12:17 UTC (rev 208218)
@@ -418,6 +418,15 @@
             callback(0);
     }
 
+    getProperty(propertyName, callback)
+    {
+        function inspectedPage_object_getProperty(property) {
+            return this[property];
+        }
+
+        this.callFunction(inspectedPage_object_getProperty, [propertyName], true, callback);
+    }
+
     callFunction(functionDeclaration, args, generatePreview, callback)
     {
         function mycallback(error, result, wasThrown)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js (208217 => 208218)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js	2016-11-01 08:12:17 UTC (rev 208218)
@@ -32,6 +32,7 @@
         WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.AttributeModified, this._attributesChanged, this);
         WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.AttributeRemoved, this._attributesChanged, this);
         WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.CharacterDataModified, this._characterDataModified, this);
+        WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.CustomElementStateChanged, this._customElementStateChanged, this);
 
         this.element.classList.add("dom-node");
 
@@ -100,15 +101,10 @@
 
     layout()
     {
-        var domNode = this.domNode;
-        if (!domNode)
+        if (!this.domNode)
             return;
 
-        this._identityNodeTypeRow.value = this._nodeTypeDisplayName();
-        this._identityNodeNameRow.value = domNode.nodeNameInCorrectCase();
-        this._identityNodeValueRow.value = domNode.nodeValue();
-        this._identityNodeContentSecurityPolicyHashRow.value = domNode.contentSecurityPolicyHash();
-
+        this._refreshIdentity();
         this._refreshAttributes();
         this._refreshProperties();
         this._refreshEventListeners();
@@ -122,6 +118,15 @@
         return window.DOMAgent && DOMAgent.getAccessibilityPropertiesForNode;
     }
 
+    _refreshIdentity()
+    {
+        const domNode = this.domNode;
+        this._identityNodeTypeRow.value = this._nodeTypeDisplayName();
+        this._identityNodeNameRow.value = domNode.nodeNameInCorrectCase();
+        this._identityNodeValueRow.value = domNode.nodeValue();
+        this._identityNodeContentSecurityPolicyHashRow.value = domNode.contentSecurityPolicyHash();
+    }
+
     _refreshAttributes()
     {
         this._attributesDataGridRow.dataGrid = this._createAttributesDataGrid();
@@ -600,11 +605,21 @@
         this._identityNodeValueRow.value = this.domNode.nodeValue();
     }
 
+    _customElementStateChanged(event)
+    {
+        if (event.data.node !== this.domNode)
+            return;
+        this._refreshIdentity();
+    }
+
     _nodeTypeDisplayName()
     {
         switch (this.domNode.nodeType()) {
-        case Node.ELEMENT_NODE:
-            return WebInspector.UIString("Element");
+        case Node.ELEMENT_NODE: {
+            const nodeName = WebInspector.UIString("Element");
+            const state = this._customElementState();
+            return state === null ? nodeName : `${nodeName} (${state})`;
+        }
         case Node.TEXT_NODE:
             return WebInspector.UIString("Text Node");
         case Node.COMMENT_NODE:
@@ -625,6 +640,23 @@
         }
     }
 
+    _customElementState()
+    {
+        const state = this.domNode.customElementState();
+        switch (state) {
+        case WebInspector.DOMNode.CustomElementState.Builtin:
+            return null;
+        case WebInspector.DOMNode.CustomElementState.Custom:
+            return WebInspector.UIString("Custom");
+        case WebInspector.DOMNode.CustomElementState.Waiting:
+            return WebInspector.UIString("Waiting to be upgraded");
+        case WebInspector.DOMNode.CustomElementState.Failed:
+            return WebInspector.UIString("Failed to upgrade");
+        }
+        console.error("Unknown DOM custom element state: ", state);
+        return null;
+    }
+
     _createAttributesDataGrid()
     {
         var domNode = this.domNode;

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js (208217 => 208218)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js	2016-11-01 06:48:01 UTC (rev 208217)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js	2016-11-01 08:12:17 UTC (rev 208218)
@@ -740,6 +740,11 @@
                 InspectorFrontendHost.copyText(xpath);
             });
         }
+
+        if (node.isCustomElement()) {
+            contextMenu.appendSeparator();
+            contextMenu.appendItem(WebInspector.UIString("Jump to Definition"), this._showCustomElementDefinition.bind(this));
+        }
     }
 
     _startEditing()
@@ -1488,6 +1493,35 @@
         WebInspector.RemoteObject.resolveNode(node, "", resolvedNode);
     }
 
+    _showCustomElementDefinition()
+    {
+        const node = this.representedObject;
+        WebInspector.RemoteObject.resolveNode(node, "", (remoteObject) => {
+            if (!remoteObject)
+                return;
+
+            remoteObject.getProperty("constructor", (error, result, wasThrown) => {
+                if (error || result.type !== "function")
+                    return;
+
+                DebuggerAgent.getFunctionDetails(result.objectId, (error, response) => {
+                    if (error)
+                        return;
+
+                    let location = response.location;
+                    let sourceCode = WebInspector.debuggerManager.scriptForIdentifier(location.scriptId);
+                    if (!sourceCode)
+                        return;
+
+                    let sourceCodeLocation = sourceCode.createSourceCodeLocation(location.lineNumber, location.columnNumber || 0);
+                    WebInspector.showSourceCodeLocation(sourceCodeLocation);
+                });
+                result.release();
+            });
+            remoteObject.release();
+        });
+    }
+
     _editAsHTML()
     {
         var treeOutline = this.treeOutline;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to