Diff
Modified: trunk/LayoutTests/ChangeLog (237027 => 237028)
--- trunk/LayoutTests/ChangeLog 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/LayoutTests/ChangeLog 2018-10-11 04:13:17 UTC (rev 237028)
@@ -1,3 +1,17 @@
+2018-10-10 Devin Rousso <[email protected]>
+
+ Web Inspector: create special Network waterfall for media events
+ https://bugs.webkit.org/show_bug.cgi?id=189773
+ <rdar://problem/44626605>
+
+ Reviewed by Joseph Pecoraro.
+
+ * http/tests/inspector/dom/didFireEvent-expected.txt: Added.
+ * http/tests/inspector/dom/didFireEvent.html: Added.
+
+ * inspector/unit-tests/array-utilities-expected.txt:
+ * inspector/unit-tests/array-utilities.html:
+
2018-10-10 Brent Fulgham <[email protected]>
Only report the supported WebGL version
Added: trunk/LayoutTests/http/tests/inspector/dom/didFireEvent-expected.txt (0 => 237028)
--- trunk/LayoutTests/http/tests/inspector/dom/didFireEvent-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/dom/didFireEvent-expected.txt 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,10 @@
+Tests that listeners registered by InspectorDOMAgent::addEventListenersToNode are working.
+
+
+
+== Running test suite: DOM.didFireEvent
+-- Running test case: DOM.didFireEvent
+Adding video source "resources/white.mp4"...
+PASS: Should recieve a "loadstart" event.
+PASS: Event timestamp should be greater than 0.
+
Added: trunk/LayoutTests/http/tests/inspector/dom/didFireEvent.html (0 => 237028)
--- trunk/LayoutTests/http/tests/inspector/dom/didFireEvent.html (rev 0)
+++ trunk/LayoutTests/http/tests/inspector/dom/didFireEvent.html 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function loadSource(url, type) {
+ let sourceElement = document.createElement("source");
+ sourceElement.type = type;
+ sourceElement.src = ""
+
+ document.getElementById("video").appendChild(sourceElement);
+}
+
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("DOM.didFireEvent");
+
+ let videoNode = null;
+
+ suite.addTestCase({
+ name: "DOM.didFireEvent",
+ description: "Check that HTMLMediaElement events work.",
+ test(resolve, reject) {
+ const file = "white.mp4";
+
+ let listener = videoNode.addEventListener(WI.DOMNode.Event.DidFireEvent, (event) => {
+ let {domEvent} = event.data;
+ if (domEvent.eventName !== "loadstart")
+ return;
+
+ InspectorTest.pass(`Should recieve a "loadstart" event.`)
+ InspectorTest.expectGreaterThan(domEvent.timestamp, 0, "Event timestamp should be greater than 0.");
+
+ videoNode.removeEventListener(WI.DOMNode.Event.DidFireEvent, listener);
+ resolve();
+ });
+
+ InspectorTest.log(`Adding video source "resources/${file}"...`);
+ InspectorTest.evaluateInPage(`loadSource("resources/${file}", "video/mp4")`);
+ }
+ });
+
+ WI.domManager.requestDocument((documentNode) => {
+ WI.domManager.querySelector(documentNode.id, "#video", (videoNodeId) => {
+ videoNode = WI.domManager.nodeForId(videoNodeId);
+ if (videoNode)
+ suite.runTestCasesAndFinish();
+ else {
+ InspectorTest.fail(`DOM node for "#video" not found.`);
+ InspectorTest.completeTest();
+ }
+ });
+ });
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Tests that listeners registered by InspectorDOMAgent::addEventListenersToNode are working.</p>
+ <video id="video" muted autoplay></video>
+</body>
+</html>
Modified: trunk/LayoutTests/inspector/unit-tests/array-utilities-expected.txt (237027 => 237028)
--- trunk/LayoutTests/inspector/unit-tests/array-utilities-expected.txt 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/LayoutTests/inspector/unit-tests/array-utilities-expected.txt 2018-10-11 04:13:17 UTC (rev 237028)
@@ -74,6 +74,13 @@
PASS: lastValue of a nonempty array should be the last value.
PASS: lastValue of an empty array should be undefined.
+-- Running test case: Array.prototype.adjacencies
+[] => []
+[1] => []
+[1,2] => [[1,2]]
+[1,2,3] => [[1,2],[2,3]]
+[1,2,3,4] => [[1,2],[2,3],[3,4]]
+
-- Running test case: Array.prototype.remove
PASS: remove should only remove the first matching value.
PASS: remove should only remove values that strictly match.
Modified: trunk/LayoutTests/inspector/unit-tests/array-utilities.html (237027 => 237028)
--- trunk/LayoutTests/inspector/unit-tests/array-utilities.html 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/LayoutTests/inspector/unit-tests/array-utilities.html 2018-10-11 04:13:17 UTC (rev 237028)
@@ -164,6 +164,23 @@
});
suite.addTestCase({
+ name: "Array.prototype.adjacencies",
+ test() {
+ function logAdjacencies(array) {
+ InspectorTest.log(JSON.stringify(array) + " => " + JSON.stringify(Array.from(array.adjacencies())));
+ }
+
+ logAdjacencies([]);
+ logAdjacencies([1]);
+ logAdjacencies([1, 2]);
+ logAdjacencies([1, 2, 3]);
+ logAdjacencies([1, 2, 3, 4]);
+
+ return true;
+ }
+ });
+
+ suite.addTestCase({
name: "Array.prototype.remove",
test() {
let arr1 = [1, 2, 3, 1];
Modified: trunk/Source/_javascript_Core/ChangeLog (237027 => 237028)
--- trunk/Source/_javascript_Core/ChangeLog 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-10-11 04:13:17 UTC (rev 237028)
@@ -1,3 +1,15 @@
+2018-10-10 Devin Rousso <[email protected]>
+
+ Web Inspector: create special Network waterfall for media events
+ https://bugs.webkit.org/show_bug.cgi?id=189773
+ <rdar://problem/44626605>
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/protocol/DOM.json:
+ Add `didFireEvent` event that is fired when specific event listeners added by
+ `InspectorInstrumentation::addEventListenersToNode` are fired.
+
2018-10-10 Michael Saboff <[email protected]>
Increase executable memory pool from 64MB to 128MB for ARM64
Modified: trunk/Source/_javascript_Core/inspector/protocol/DOM.json (237027 => 237028)
--- trunk/Source/_javascript_Core/inspector/protocol/DOM.json 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/_javascript_Core/inspector/protocol/DOM.json 2018-10-11 04:13:17 UTC (rev 237028)
@@ -659,6 +659,15 @@
"parameters": [
{ "name": "nodeId", "$ref": "NodeId" }
]
+ },
+ {
+ "name": "didFireEvent",
+ "description": "Called when an event is fired on a node.",
+ "parameters": [
+ { "name": "nodeId", "$ref": "NodeId" },
+ { "name": "eventName", "type": "string" },
+ { "name": "timestamp", "$ref": "Network.Timestamp", "description": "Time when the event was fired" }
+ ]
}
]
}
Modified: trunk/Source/WebCore/ChangeLog (237027 => 237028)
--- trunk/Source/WebCore/ChangeLog 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebCore/ChangeLog 2018-10-11 04:13:17 UTC (rev 237028)
@@ -1,3 +1,31 @@
+2018-10-10 Devin Rousso <[email protected]>
+
+ Web Inspector: create special Network waterfall for media events
+ https://bugs.webkit.org/show_bug.cgi?id=189773
+ <rdar://problem/44626605>
+
+ Reviewed by Joseph Pecoraro.
+
+ Test: http/tests/inspector/dom/didFireEvent.html
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement):
+
+ * inspector/InspectorInstrumentation.h:
+ (WebCore::InspectorInstrumentation::addEventListenersToNode): Added.
+ * inspector/InspectorInstrumentation.cpp:
+ (WebCore::InspectorInstrumentation::addEventListenersToNodeImpl): Added.
+
+ * inspector/agents/InspectorDOMAgent.h:
+ * inspector/agents/InspectorDOMAgent.cpp:
+ (WebCore::EventFiredCallback): Added.
+ (WebCore::EventFiredCallback::create): Added.
+ (WebCore::EventFiredCallback::operator==): Added.
+ (WebCore::EventFiredCallback::handleEvent): Added.
+ (WebCore::EventFiredCallback::EventFiredCallback): Added.
+ (WebCore::InspectorDOMAgent::didCreateFrontendAndBackend):
+ (WebCore::InspectorDOMAgent::addEventListenersToNode): Added.
+
2018-10-10 Daniel Bates <[email protected]>
[iOS] Cleanup -[WAKView _selfHandleEvent:] and -[WAKWindow sendEventSynchronously:]
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (237027 => 237028)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-10-11 04:13:17 UTC (rev 237028)
@@ -53,6 +53,7 @@
#include "HTMLParserIdioms.h"
#include "HTMLSourceElement.h"
#include "HTMLVideoElement.h"
+#include "InspectorInstrumentation.h"
#include "JSDOMException.h"
#include "JSDOMPromiseDeferred.h"
#include "JSHTMLMediaElement.h"
@@ -522,6 +523,8 @@
ALWAYS_LOG(LOGIDENTIFIER);
setHasCustomStyleResolveCallbacks();
+
+ InspectorInstrumentation::addEventListenersToNode(*this);
}
void HTMLMediaElement::finishInitialization()
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (237027 => 237028)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp 2018-10-11 04:13:17 UTC (rev 237028)
@@ -135,6 +135,12 @@
return 0;
}
+void InspectorInstrumentation::addEventListenersToNodeImpl(InstrumentingAgents& instrumentingAgents, Node& node)
+{
+ if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
+ domAgent->addEventListenersToNode(node);
+}
+
void InspectorInstrumentation::willInsertDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& parent)
{
if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (237027 => 237028)
--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h 2018-10-11 04:13:17 UTC (rev 237028)
@@ -107,6 +107,7 @@
static bool isDebuggerPaused(Frame*);
static int identifierForNode(Node&);
+ static void addEventListenersToNode(Node&);
static void willInsertDOMNode(Document&, Node& parent);
static void didInsertDOMNode(Document&, Node&);
static void willRemoveDOMNode(Document&, Node&);
@@ -292,6 +293,7 @@
static bool isDebuggerPausedImpl(InstrumentingAgents&);
static int identifierForNodeImpl(InstrumentingAgents&, Node&);
+ static void addEventListenersToNodeImpl(InstrumentingAgents&, Node&);
static void willInsertDOMNodeImpl(InstrumentingAgents&, Node& parent);
static void didInsertDOMNodeImpl(InstrumentingAgents&, Node&);
static void willRemoveDOMNodeImpl(InstrumentingAgents&, Node&);
@@ -480,6 +482,13 @@
return 0;
}
+inline void InspectorInstrumentation::addEventListenersToNode(Node& node)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (auto* instrumentingAgents = instrumentingAgentsForDocument(node.document()))
+ addEventListenersToNodeImpl(*instrumentingAgents, node);
+}
+
inline void InspectorInstrumentation::willInsertDOMNode(Document& document, Node& parent)
{
FAST_RETURN_IF_NO_FRONTENDS(void());
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp (237027 => 237028)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2018-10-11 04:13:17 UTC (rev 237028)
@@ -61,6 +61,7 @@
#include "FrameTree.h"
#include "HTMLElement.h"
#include "HTMLFrameOwnerElement.h"
+#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "HTMLScriptElement.h"
@@ -219,6 +220,42 @@
RefPtr<Node> m_node;
};
+class EventFiredCallback final : public EventListener {
+public:
+ static Ref<EventFiredCallback> create(InspectorDOMAgent& domAgent)
+ {
+ return adoptRef(*new EventFiredCallback(domAgent));
+ }
+
+ bool operator==(const EventListener& other) const final
+ {
+ return this == &other;
+ }
+
+ void handleEvent(ScriptExecutionContext&, Event& event) final
+ {
+ if (!is<Node>(event.target()))
+ return;
+
+ auto* node = downcast<Node>(event.target());
+ int nodeId = m_domAgent.pushNodePathToFrontend(node);
+ if (!nodeId)
+ return;
+
+ auto timestamp = m_domAgent.m_environment.executionStopwatch()->elapsedTime().seconds();
+ m_domAgent.m_frontendDispatcher->didFireEvent(nodeId, event.type(), timestamp);
+ }
+
+private:
+ EventFiredCallback(InspectorDOMAgent& domAgent)
+ : EventListener(EventListener::CPPEventListenerType)
+ , m_domAgent(domAgent)
+ {
+ }
+
+ InspectorDOMAgent& m_domAgent;
+};
+
String InspectorDOMAgent::toErrorString(ExceptionCode ec)
{
return ec ? String(DOMException::name(ec)) : emptyString();
@@ -253,6 +290,9 @@
m_instrumentingAgents.setInspectorDOMAgent(this);
m_document = m_pageAgent->mainFrame().document();
+ for (auto* mediaElement : HTMLMediaElement::allMediaElements())
+ addEventListenersToNode(*mediaElement);
+
if (m_nodeToFocus)
focusNode();
}
@@ -2090,6 +2130,39 @@
return pushNodePathToFrontend(&node);
}
+void InspectorDOMAgent::addEventListenersToNode(Node& node)
+{
+ auto callback = EventFiredCallback::create(*this);
+
+ auto createEventListener = [&] (const AtomicString& eventName) {
+ node.addEventListener(eventName, callback.copyRef(), false);
+ };
+
+ if (is<HTMLMediaElement>(node)) {
+ createEventListener(eventNames().abortEvent);
+ createEventListener(eventNames().canplayEvent);
+ createEventListener(eventNames().canplaythroughEvent);
+ createEventListener(eventNames().durationchangeEvent);
+ createEventListener(eventNames().emptiedEvent);
+ createEventListener(eventNames().endedEvent);
+ createEventListener(eventNames().errorEvent);
+ createEventListener(eventNames().loadeddataEvent);
+ createEventListener(eventNames().loadedmetadataEvent);
+ createEventListener(eventNames().loadstartEvent);
+ createEventListener(eventNames().pauseEvent);
+ createEventListener(eventNames().playEvent);
+ createEventListener(eventNames().playingEvent);
+ createEventListener(eventNames().ratechangeEvent);
+ createEventListener(eventNames().seekedEvent);
+ createEventListener(eventNames().seekingEvent);
+ createEventListener(eventNames().stalledEvent);
+ createEventListener(eventNames().suspendEvent);
+ createEventListener(eventNames().timeupdateEvent);
+ createEventListener(eventNames().volumechangeEvent);
+ createEventListener(eventNames().waitingEvent);
+ }
+}
+
void InspectorDOMAgent::didInsertDOMNode(Node& node)
{
if (containsOnlyHTMLWhitespace(&node))
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h (237027 => 237028)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2018-10-11 04:13:17 UTC (rev 237028)
@@ -158,6 +158,7 @@
// InspectorInstrumentation
int identifierForNode(Node&);
+ void addEventListenersToNode(Node&);
void didInsertDOMNode(Node&);
void didRemoveDOMNode(Node&);
void willModifyDOMAttr(Element&, const AtomicString& oldValue, const AtomicString& newValue);
@@ -316,6 +317,8 @@
}
};
+ friend class EventFiredCallback;
+
HashMap<int, InspectorEventListener> m_eventListenerEntries;
int m_lastEventListenerId { 1 };
};
Modified: trunk/Source/WebInspectorUI/ChangeLog (237027 => 237028)
--- trunk/Source/WebInspectorUI/ChangeLog 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/ChangeLog 2018-10-11 04:13:17 UTC (rev 237028)
@@ -1,5 +1,163 @@
2018-10-10 Devin Rousso <[email protected]>
+ Web Inspector: create special Network waterfall for media events
+ https://bugs.webkit.org/show_bug.cgi?id=189773
+ <rdar://problem/44626605>
+
+ Reviewed by Joseph Pecoraro.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Main.html:
+ * UserInterface/Base/Utilities.js:
+
+ * UserInterface/Protocol/DOMObserver.js:
+ (WI.DOMObserver.prototype.didFireEvent): Added.
+ * UserInterface/Controllers/DOMManager.js:
+ (WI.DOMManager.prototype.didFireEvent): Added.
+ * UserInterface/Models/DOMNode.js:
+ (WI.DOMNode):
+ (WI.DOMNode.prototype.get domEvents): Added.
+ (WI.DOMNode.prototype.didFireEvent): Added.
+ (WI.DOMNode.prototype._addDOMEvent): Added.
+
+ * UserInterface/Views/NetworkTableContentView.js:
+ (WI.NetworkTableContentView):
+ (WI.NetworkTableContentView.prototype.shown):
+ (WI.NetworkTableContentView.prototype.hidden):
+ (WI.NetworkTableContentView.prototype.closed):
+ (WI.NetworkTableContentView.prototype.reset):
+ (WI.NetworkTableContentView.prototype.showRepresentedObject):
+ (WI.NetworkTableContentView.prototype.networkDetailViewClose): Added.
+ (WI.NetworkTableContentView.prototype.tableSortChanged):
+ (WI.NetworkTableContentView.prototype.tableSelectionDidChange):
+ (WI.NetworkTableContentView.prototype._populateNameCell):
+ (WI.NetworkTableContentView.prototype._populateWaterfallGraph.positionByStartOffset): Added.
+ (WI.NetworkTableContentView.prototype._populateWaterfallGraph.setWidthForDuration): Added.
+ (WI.NetworkTableContentView.prototype._populateWaterfallGraph.createDOMEventLine): Added.
+ (WI.NetworkTableContentView.prototype._populateWaterfallGraph.appendBlock):
+ (WI.NetworkTableContentView.prototype._populateWaterfallGraph):
+ (WI.NetworkTableContentView.prototype._processPendingEntries):
+ (WI.NetworkTableContentView.prototype._rowIndexForRepresentedObject): Added.
+ (WI.NetworkTableContentView.prototype._updateEntryForResource):
+ (WI.NetworkTableContentView.prototype._hideDetailView): Added.
+ (WI.NetworkTableContentView.prototype._showDetailView): Added.
+ (WI.NetworkTableContentView.prototype._positionDetailView): Added.
+ (WI.NetworkTableContentView.prototype._resourceTransferSizeDidChange):
+ (WI.NetworkTableContentView.prototype._tryLinkResourceToDOMNode):
+ (WI.NetworkTableContentView.prototype._handleNodeDidFireEvent): Added.
+ (WI.NetworkTableContentView.prototype._updateFilteredEntries):
+ (WI.NetworkTableContentView.prototype._typeFilterScopeBarSelectionChanged):
+ (WI.NetworkTableContentView.prototype._urlFilterDidChange):
+ (WI.NetworkTableContentView.prototype._restoreSelectedRow):
+ (WI.NetworkTableContentView.prototype._waterfallPopoverContent): Added.
+ (WI.NetworkTableContentView.prototype._waterfallPopoverContentForResourceEntry): Added.
+ (WI.NetworkTableContentView.prototype._waterfallPopoverContentForNodeEntry): Added.
+ (WI.NetworkTableContentView.prototype._handleResourceEntryMousedownWaterfall): Added.
+ (WI.NetworkTableContentView.prototype._handleNodeEntryMousedownWaterfall): Added.
+ (WI.NetworkTableContentView.prototype._handleMousedownWaterfall): Added.
+ (WI.NetworkTableContentView.prototype.networkResourceDetailViewClose): Deleted.
+ (WI.NetworkTableContentView.prototype._rowIndexForResource): Deleted.
+ (WI.NetworkTableContentView.prototype._hideResourceDetailView): Deleted.
+ (WI.NetworkTableContentView.prototype._showResourceDetailView): Deleted.
+ (WI.NetworkTableContentView.prototype._waterfallPopoverContentForResource): Deleted.
+ * UserInterface/Views/NetworkTableContentView.css:
+ (.content-view.network .network-table): Added.
+ (.network-table :not(.header) .cell.waterfall .waterfall-container > .dom-event): Added.
+ (.network-table :not(.header) .cell.waterfall .waterfall-container > .dom-activity): Added.
+ (.network-table :not(.header) .cell.waterfall .waterfall-container > .dom-activity.playing): Added.
+
+ * UserInterface/Views/NetworkDOMNodeDetailView.js: Added.
+ (WI.NetworkDOMNodeDetailView):
+ (WI.NetworkDOMNodeDetailView.prototype.initialLayout):
+ (WI.NetworkDOMNodeDetailView.prototype.showContentViewForIdentifier):
+
+ * UserInterface/Views/NetworkResourceDetailView.css:
+ (.content-view.resource-details):
+ (.network-resource-detail): Deleted.
+ (.network-resource-detail .navigation-bar): Deleted.
+ (.network-resource-detail .item.close > .glyph): Deleted.
+ (.network-resource-detail .item.close > .glyph:hover): Deleted.
+ (.network-resource-detail .item.close > .glyph:active): Deleted.
+ (.network .network-resource-detail .navigation-bar .item.radio.button.text-only): Deleted.
+ (.network .network-resource-detail .navigation-bar .item.radio.button.text-only.selected): Deleted.
+ (.network-resource-detail > .content-browser): Deleted.
+ (@media (prefers-dark-interface)): Deleted.
+ * UserInterface/Views/NetworkResourceDetailView.js:
+ (WI.NetworkResourceDetailView):
+ (WI.NetworkResourceDetailView.prototype.shown):
+ (WI.NetworkResourceDetailView.prototype.headersContentViewGoToRequestData):
+ (WI.NetworkResourceDetailView.prototype.sizesContentViewGoToHeaders):
+ (WI.NetworkResourceDetailView.prototype.sizesContentViewGoToRequestBody):
+ (WI.NetworkResourceDetailView.prototype.sizesContentViewGoToResponseBody):
+ (WI.NetworkResourceDetailView.prototype.initialLayout):
+ (WI.NetworkResourceDetailView.prototype.showContentViewForIdentifier):
+ (WI.NetworkResourceDetailView.prototype.get resource): Deleted.
+ (WI.NetworkResourceDetailView.prototype.hidden): Deleted.
+ (WI.NetworkResourceDetailView.prototype.dispose): Deleted.
+ (WI.NetworkResourceDetailView.prototype.willShowWithCookie): Deleted.
+ (WI.NetworkResourceDetailView.prototype.initialLayout): Deleted.
+ (WI.NetworkResourceDetailView.prototype._showPreferredContentView): Deleted.
+ (WI.NetworkResourceDetailView.prototype._showContentViewForNavigationItem): Deleted.
+ (WI.NetworkResourceDetailView.prototype._navigationItemSelected): Deleted.
+ (WI.NetworkResourceDetailView.prototype._handleCloseButton): Deleted.
+
+ * UserInterface/Views/NetworkDetailView.js: Added.
+ (WI.NetworkDetailView):
+ (WI.NetworkDetailView.prototype.get representedObject):
+ (WI.NetworkDetailView.prototype.shown):
+ (WI.NetworkDetailView.prototype.hidden):
+ (WI.NetworkDetailView.prototype.dispose):
+ (WI.NetworkDetailView.prototype.willShowWithCookie):
+ (WI.NetworkDetailView.prototype.initialLayout):
+ (WI.NetworkDetailView.prototype.createDetailNavigationItem):
+ (WI.NetworkDetailView.prototype.detailNavigationItemForIdentifier):
+ (WI.NetworkDetailView.prototype.showContentViewForIdentifier):
+ (WI.NetworkDetailView.prototype._showPreferredContentView):
+ (WI.NetworkDetailView.prototype._navigationItemSelected):
+ (WI.NetworkDetailView.prototype._handleCloseButton):
+ * UserInterface/Views/NetworkDetailView.css: Added.
+ (.network-detail):
+ (.network-detail .navigation-bar):
+ (.network-detail .item.close > .glyph):
+ (.network-detail .item.close > .glyph:hover):
+ (.network-detail .item.close > .glyph:active):
+ (.network .network-detail .navigation-bar .item.radio.button.text-only):
+ (.network .network-detail .navigation-bar .item.radio.button.text-only.selected):
+ (.network-detail > .content-browser):
+ (@media (prefers-dark-interface)):
+ Create base class for detail views shown in the Network tab.
+
+ * UserInterface/Views/DOMNodeEventsContentView.js: Added.
+ (WI.DOMNodeEventsContentView):
+ (WI.DOMNodeEventsContentView.prototype.initialLayout):
+ (WI.DOMNodeEventsContentView.prototype.closed):
+ (WI.DOMNodeEventsContentView.prototype._handleDOMNodeDidFireEvent):
+ * UserInterface/Views/DOMNodeEventsContentView.css: Added.
+ (.dom-node-details.dom-events):
+
+ * UserInterface/Views/DOMEventsBreakdownView.js: Added.
+ (WI.DOMEventsBreakdownView):
+ (WI.DOMEventsBreakdownView.prototype.addEvent):
+ (WI.DOMEventsBreakdownView.prototype.initialLayout):
+ (WI.DOMEventsBreakdownView.prototype._populateTable.percentOfTotalTime):
+ (WI.DOMEventsBreakdownView.prototype._populateTable):
+ * UserInterface/Views/DOMEventsBreakdownView.css: Added.
+ (.waterfall-popover-content .dom-events-breakdown):
+ (.dom-events-breakdown):
+ (.dom-events-breakdown table):
+ (.dom-events-breakdown tr > :matches(th, td)):
+ (.dom-events-breakdown tbody > tr):
+ (.dom-events-breakdown .graph):
+ (.dom-events-breakdown .graph > :matches(.point, .area)):
+ (.dom-events-breakdown .graph > .point):
+ (.dom-events-breakdown .time):
+
+ * UserInterface/Views/ResourceTimingBreakdownView.css:
+ (.resource-timing-breakdown > table > tr.header:not(.total-row) > td): Added.
+ (.popover.waterfall-popover): Deleted.
+
+2018-10-10 Devin Rousso <[email protected]>
+
Web Inspector: REGRESSION(r236853): Uncaught Exception: undefined is not an object (evaluating 'entry.resource')
https://bugs.webkit.org/show_bug.cgi?id=190442
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (237027 => 237028)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -243,6 +243,7 @@
localizedStrings["DNS"] = "DNS";
localizedStrings["DOM Content Loaded \u2014 %s"] = "DOM Content Loaded \u2014 %s";
localizedStrings["DOM Event"] = "DOM Event";
+localizedStrings["DOM Events"] = "DOM Events";
localizedStrings["Damping"] = "Damping";
localizedStrings["Data"] = "Data";
localizedStrings["Data returned from the database is too large."] = "Data returned from the database is too large.";
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -464,6 +464,14 @@
}
});
+Object.defineProperty(Array.prototype, "adjacencies",
+{
+ value: function*() {
+ for (let i = 1; i < this.length; ++i)
+ yield [this[i - 1], this[i]];
+ }
+});
+
Object.defineProperty(Array.prototype, "remove",
{
value(value)
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -122,6 +122,17 @@
node.dispatchEventToListeners(WI.DOMNode.Event.EventListenersChanged);
}
+ didFireEvent(nodeId, eventName, timestamp)
+ {
+ // Called from WI.DOMObserver.
+
+ let node = this._idToDOMNode[nodeId];
+ if (!node)
+ return;
+
+ node.didFireEvent(eventName, timestamp);
+ }
+
// Private
_wrapClientCallback(callback)
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2018-10-11 04:13:17 UTC (rev 237028)
@@ -66,7 +66,9 @@
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
+ <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
+ <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
@@ -123,6 +125,7 @@
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
+ <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
@@ -496,6 +499,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
@@ -578,7 +582,9 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
@@ -661,6 +667,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -137,10 +137,14 @@
this.name = payload.name;
this.value = payload.value;
}
+
+ this._domEvents = [];
}
// Public
+ get domEvents() { return this._domEvents; }
+
get frameIdentifier()
{
return this._frameIdentifier || this.ownerDocument.frameIdentifier;
@@ -697,6 +701,23 @@
return !!this.ownerSVGElement;
}
+ didFireEvent(eventName, timestamp)
+ {
+ // Called from WI.DOMManager.
+
+ this._addDOMEvent({
+ eventName,
+ timestamp: WI.timelineManager.computeElapsedTime(timestamp),
+ });
+ }
+
+ _addDOMEvent(domEvent)
+ {
+ this._domEvents.push(domEvent);
+
+ this.dispatchEventToListeners(WI.DOMNode.Event.DidFireEvent, {domEvent});
+ }
+
_setAttributesPayload(attrs)
{
this._attributes = [];
@@ -844,6 +865,7 @@
AttributeModified: "dom-node-attribute-modified",
AttributeRemoved: "dom-node-attribute-removed",
EventListenersChanged: "dom-node-event-listeners-changed",
+ DidFireEvent: "dom-node-did-fire-event",
};
WI.DOMNode.PseudoElementType = {
Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/DOMObserver.js (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/DOMObserver.js 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/DOMObserver.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -111,4 +111,9 @@
{
WI.domManager.willRemoveEventListener(nodeId);
}
+
+ didFireEvent(nodeId, eventName, timestamp)
+ {
+ WI.domManager.didFireEvent(nodeId, eventName, timestamp);
+ }
};
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.css (from rev 237027, trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingBreakdownView.css) (0 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.css 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.waterfall-popover-content .dom-events-breakdown {
+ -webkit-user-select: text;
+ max-height: 210px;
+ overflow-y: scroll;
+}
+
+.dom-events-breakdown {
+ margin: 5px;
+}
+
+.dom-events-breakdown table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.dom-events-breakdown tr > :matches(th, td) {
+ padding: 2px 4px;
+ text-align: start;
+}
+
+.dom-events-breakdown tbody > tr {
+ /* FIXME: <https://webkit.org/b/94128> */
+ border-top: 1px solid lightgrey;
+}
+
+.dom-events-breakdown .graph {
+ position: relative;
+ width: 100%;
+ border-right: var(--point-size) solid transparent;
+ border-left: var(--point-size) solid transparent;
+
+ --point-size: 8px;
+}
+
+.dom-events-breakdown .graph > :matches(.point, .area) {
+ position: absolute;
+}
+
+.dom-events-breakdown .graph > .point {
+ top: calc(50% - (var(--point-size) / 2));
+ width: var(--point-size);
+ height: var(--point-size);
+ background-color: var(--selected-background-color);
+ border-radius: 50%;
+}
+
+.dom-events-breakdown .time {
+ text-align: end;
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.js (0 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMEventsBreakdownView.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.DOMEventsBreakdownView = class DOMEventsBreakdownView extends WI.View
+{
+ constructor(domEvents, {includeGraph, startTimestamp} = {})
+ {
+ super();
+
+ this._domEvents = domEvents;
+ this._includeGraph = includeGraph || false;
+ this._startTimestamp = startTimestamp || 0;
+
+ this._tableBodyElement = null;
+
+ this.element.classList.add("dom-events-breakdown");
+ }
+
+ // Public
+
+ addEvent(domEvent)
+ {
+ this._domEvents.push(domEvent);
+
+ this.soon._populateTable();
+ }
+
+ // Protected
+
+ initialLayout()
+ {
+ super.initialLayout();
+
+ let tableElement = this.element.appendChild(document.createElement("table"));
+
+ let headElement = tableElement.appendChild(document.createElement("thead"));
+
+ let headRowElement = headElement.appendChild(document.createElement("tr"));
+
+ let eventHeadCell = headRowElement.appendChild(document.createElement("th"));
+ eventHeadCell.textContent = WI.UIString("Event");
+
+ if (this._includeGraph)
+ headRowElement.appendChild(document.createElement("th"));
+
+ let timeHeadCell = headRowElement.appendChild(document.createElement("th"));
+ timeHeadCell.classList.add("time");
+ timeHeadCell.textContent = WI.UIString("Time");
+
+ this._tableBodyElement = tableElement.appendChild(document.createElement("tbody"));
+
+ this._populateTable();
+ }
+
+ // Private
+
+ _populateTable()
+ {
+ this._tableBodyElement.removeChildren();
+
+ let startTimestamp = this._domEvents[0].timestamp;
+ let endTimestamp = this._domEvents.lastValue.timestamp;
+ let totalTime = endTimestamp - startTimestamp;
+ let styleAttribute = WI.resolvedLayoutDirection() === WI.LayoutDirection.LTR ? "left" : "right";
+
+ function percentOfTotalTime(time) {
+ return time / totalTime * 100;
+ }
+
+ for (let domEvent of this._domEvents) {
+ let rowElement = this._tableBodyElement.appendChild(document.createElement("tr"));
+
+ let nameCell = rowElement.appendChild(document.createElement("td"));
+ nameCell.classList.add("name");
+ nameCell.textContent = domEvent.eventName;
+
+ if (this._includeGraph) {
+ let graphCell = rowElement.appendChild(document.createElement("td"));
+ graphCell.classList.add("graph");
+
+ let graphPoint = graphCell.appendChild(document.createElement("div"));
+ graphPoint.classList.add("point");
+ graphPoint.style.setProperty(styleAttribute, `calc(${percentOfTotalTime(domEvent.timestamp - startTimestamp)}% - (var(--point-size) / 2))`);
+ }
+
+ let timeCell = rowElement.appendChild(document.createElement("td"));
+ timeCell.classList.add("time");
+
+ const higherResolution = true;
+ timeCell.textContent = Number.secondsToString(domEvent.timestamp - this._startTimestamp, higherResolution);
+ }
+ }
+};
Added: trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.css (0 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.css 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.dom-node-details.dom-events {
+ overflow-y: scroll;
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js (0 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeEventsContentView.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.DOMNodeEventsContentView = class DOMNodeEventsContentView extends WI.ContentView
+{
+ constructor(domNode, {startTimestamp} = {})
+ {
+ console.assert(domNode instanceof WI.DOMNode);
+
+ const representedObject = null;
+ super(representedObject);
+
+ this._domNode = domNode;
+ this._startTimestamp = startTimestamp || 0;
+
+ this.element.classList.add("dom-node-details", "dom-events");
+
+ this._breakdownView = null;
+ }
+
+ // Protected
+
+ initialLayout()
+ {
+ super.initialLayout();
+
+ this._breakdownView = new WI.DOMEventsBreakdownView(this._domNode.domEvents.slice(), {
+ includeGraph: true,
+ startTimestamp: this._startTimestamp,
+ });
+ this.addSubview(this._breakdownView);
+
+ this._domNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);
+ }
+
+ closed()
+ {
+ this._domNode.removeEventListener(null, null, this);
+
+ super.closed();
+ }
+
+ // Private
+
+ _handleDOMNodeDidFireEvent(event)
+ {
+ let {domEvent} = event.data;
+
+ if (this._breakdownView)
+ this._breakdownView.addEvent(domEvent);
+ }
+};
Added: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDOMNodeDetailView.js (0 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDOMNodeDetailView.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDOMNodeDetailView.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.NetworkDOMNodeDetailView = class NetworkDOMNodeDetailView extends WI.NetworkDetailView
+{
+ constructor(domNode, delegate, {startTimestamp} = {})
+ {
+ console.assert(domNode instanceof WI.DOMNode);
+
+ super(domNode, delegate);
+
+ this._startTimestamp = startTimestamp || 0;
+
+ this.element.classList.add("dom-node");
+
+ this._domEventsContentView = null;
+ }
+
+ // Protected
+
+ initialLayout()
+ {
+ this.createDetailNavigationItem("dom-events", WI.UIString("DOM Events"));
+
+ super.initialLayout();
+ }
+
+ // Private
+
+ showContentViewForIdentifier(identifier)
+ {
+ super.showContentViewForIdentifier(identifier);
+
+ switch (identifier) {
+ case "dom-events":
+ if (!this._domEventsContentView) {
+ this._domEventsContentView = new WI.DOMNodeEventsContentView(this.representedObject, {
+ startTimestamp: this._startTimestamp,
+ });
+ }
+ this._contentBrowser.showContentView(this._domEventsContentView, this._contentViewCookie);
+ break;
+ }
+ }
+};
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDetailView.css (from rev 237027, trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.css) (0 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDetailView.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDetailView.css 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.network-detail {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ /* left or right set by NetworkTableView on display / resize */
+ z-index: 10;
+ background-color: white;
+}
+
+.network-detail .navigation-bar {
+ position: -webkit-sticky;
+ top: 0;
+ z-index: 1;
+}
+
+.network-detail .item.close > .glyph {
+ border-radius: 2px;
+ padding: 2px;
+ background: white;
+}
+
+.network-detail .item.close > .glyph:hover {
+ background-color: var(--button-background-color-hover);
+}
+
+.network-detail .item.close > .glyph:active {
+ background-color: var(--button-background-color-pressed);
+}
+
+.network .network-detail .navigation-bar .item.radio.button.text-only {
+ color: inherit;
+ background-color: inherit;
+}
+
+.network .network-detail .navigation-bar .item.radio.button.text-only.selected {
+ color: var(--selected-background-color);
+ background-color: white;
+}
+
+.network-detail > .content-browser {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+@media (prefers-dark-interface) {
+ .network-detail {
+ background-color: var(--background-color);
+ }
+
+ .network-detail .item.close > .glyph {
+ background-color: hsla(0, 0%, 100%, 0.2);
+ }
+
+ .network .network-detail .navigation-bar .item.radio.button.text-only.selected {
+ background-color: unset;
+ color: var(--glyph-color-active);
+ }
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDetailView.js (0 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDetailView.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkDetailView.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.NetworkDetailView = class NetworkDetailView extends WI.View
+{
+ constructor(representedObject, delegate)
+ {
+ super();
+
+ this._representedObject = representedObject;
+ this._delegate = delegate || null;
+
+ this.element.classList.add("network-detail");
+
+ this._contentBrowser = null;
+
+ this._detailNavigationItemMap = new Map;
+
+ this._contentViewCookie = null;
+ }
+
+ // Public
+
+ get representedObject() { return this._representedObject; }
+
+ shown()
+ {
+ if (!this._contentBrowser)
+ return;
+
+ this._showPreferredContentView();
+
+ if (this._contentViewCookie) {
+ this._contentBrowser.showContentView(this._contentBrowser.currentContentView, this._contentViewCookie);
+ this._contentViewCookie = null;
+ }
+
+ this._contentBrowser.shown();
+ }
+
+ hidden()
+ {
+ this._contentBrowser.hidden();
+ }
+
+ dispose()
+ {
+ this._delegate = null;
+
+ this._contentBrowser.contentViewContainer.closeAllContentViews();
+ }
+
+ willShowWithCookie(cookie)
+ {
+ this._contentViewCookie = cookie;
+ }
+
+ // Protected
+
+ initialLayout()
+ {
+ let closeNavigationItem = new WI.ButtonNavigationItem("close", WI.UIString("Close detail view"), "Images/CloseLarge.svg", 16, 16);
+ closeNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCloseButton.bind(this));
+ closeNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
+
+ let contentViewNavigationItemsGroup = new WI.GroupNavigationItem;
+ let contentViewNavigationItemsFlexItem = new WI.FlexibleSpaceNavigationItem(contentViewNavigationItemsGroup, WI.FlexibleSpaceNavigationItem.Align.End);
+ contentViewNavigationItemsFlexItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
+
+ const element = null;
+ const disableBackForward = true;
+ const disableFindBanner = false;
+ this._contentBrowser = new WI.ContentBrowser(element, this, disableBackForward, disableFindBanner, contentViewNavigationItemsFlexItem, contentViewNavigationItemsGroup);
+
+ // Insert all of our custom navigation items at the start of the ContentBrowser's NavigationBar.
+ let index = 0;
+ this._contentBrowser.navigationBar.insertNavigationItem(closeNavigationItem, index++);
+ this._contentBrowser.navigationBar.insertNavigationItem(new WI.FlexibleSpaceNavigationItem, index++);
+ for (let detailNavigationItem of this._detailNavigationItemMap.values())
+ this._contentBrowser.navigationBar.insertNavigationItem(detailNavigationItem, index++);
+
+ this._contentBrowser.navigationBar.addEventListener(WI.NavigationBar.Event.NavigationItemSelected, this._navigationItemSelected, this);
+
+ this.addSubview(this._contentBrowser);
+
+ this._showPreferredContentView();
+ }
+
+ createDetailNavigationItem(identifier, toolTip)
+ {
+ this._detailNavigationItemMap.set(identifier, new WI.RadioButtonNavigationItem(identifier, toolTip));
+ }
+
+ detailNavigationItemForIdentifier(identifier)
+ {
+ return this._detailNavigationItemMap.get(identifier);
+ }
+
+ showContentViewForIdentifier(identifier)
+ {
+ // Implemented by subclasses.
+ }
+
+ // Private
+
+ _showPreferredContentView()
+ {
+ let detailNavigationItems = Array.from(this._detailNavigationItemMap.values());
+
+ // Restore the preferred navigation item.
+ let firstNavigationItem = null;
+ let defaultIdentifier = WI.settings.selectedNetworkDetailContentViewIdentifier.value;
+ for (let navigationItem of this._contentBrowser.navigationBar.navigationItems) {
+ if (!(navigationItem instanceof WI.RadioButtonNavigationItem))
+ continue;
+
+ if (!detailNavigationItems.includes(navigationItem))
+ continue;
+
+ if (!firstNavigationItem)
+ firstNavigationItem = navigationItem;
+
+ if (navigationItem.identifier === defaultIdentifier) {
+ this._contentBrowser.navigationBar.selectedNavigationItem = navigationItem;
+ return;
+ }
+ }
+
+ console.assert(firstNavigationItem, "Should have found at least one navigation item above");
+ this._contentBrowser.navigationBar.selectedNavigationItem = firstNavigationItem;
+ }
+
+ _navigationItemSelected(event)
+ {
+ let navigationItem = event.target.selectedNavigationItem;
+ if (!(navigationItem instanceof WI.RadioButtonNavigationItem))
+ return;
+
+ this.showContentViewForIdentifier(navigationItem.identifier);
+
+ console.assert(navigationItem.identifier);
+ WI.settings.selectedNetworkDetailContentViewIdentifier.value = navigationItem.identifier;
+ }
+
+ _handleCloseButton(event)
+ {
+ if (this._delegate && this._delegate.networkDetailViewClose)
+ this._delegate.networkDetailViewClose(this);
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.css (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.css 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.css 2018-10-11 04:13:17 UTC (rev 237028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,55 +23,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-.network-resource-detail {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- /* left or right set by NetworkTableView on display / resize */
- z-index: 10;
- background-color: var(--background-color);
-}
-
-.network-resource-detail .navigation-bar {
- position: -webkit-sticky;
- top: 0;
- z-index: 1;
-}
-
-.network-resource-detail .item.close > .glyph {
- border-radius: 2px;
- padding: 2px;
- background: white;
-}
-
-.network-resource-detail .item.close > .glyph:hover {
- background-color: var(--button-background-color-hover);
-}
-
-.network-resource-detail .item.close > .glyph:active {
- background-color: var(--button-background-color-pressed);
-}
-
-.network .network-resource-detail .navigation-bar .item.radio.button.text-only {
- color: inherit;
- background-color: inherit;
-}
-
-.network .network-resource-detail .navigation-bar .item.radio.button.text-only.selected {
- color: var(--selected-background-color);
- background-color: var(--background-color);
-}
-
-.network-resource-detail > .content-browser {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
.content-view.resource-details {
position: absolute;
top: 0;
@@ -85,14 +36,3 @@
-webkit-user-select: text;
white-space: nowrap;
}
-
-@media (prefers-dark-interface) {
- .network-resource-detail .item.close > .glyph {
- background-color: hsla(0, 0%, 100%, 0.2);
- }
-
- .network .network-resource-detail .navigation-bar .item.radio.button.text-only.selected {
- background-color: unset;
- color: var(--glyph-color-active);
- }
-}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.js (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.js 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkResourceDetailView.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,73 +23,38 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-WI.NetworkResourceDetailView = class NetworkResourceDetailView extends WI.View
+WI.NetworkResourceDetailView = class NetworkResourceDetailView extends WI.NetworkDetailView
{
constructor(resource, delegate)
{
- super();
-
console.assert(resource instanceof WI.Resource);
- this._resource = resource;
- this._delegate = delegate || null;
+ super(resource, delegate);
- this.element.classList.add("network-resource-detail");
+ this.element.classList.add("resource");
- this._contentBrowser = null;
this._resourceContentView = null;
this._headersContentView = null;
this._cookiesContentView = null;
this._sizesContentView = null;
this._timingContentView = null;
-
- this._contentViewCookie = null;
}
// Public
- get resource() { return this._resource; }
-
shown()
{
- if (!this._contentBrowser)
- return;
+ if (this._contentBrowser && this._contentViewCookie && "lineNumber" in this._contentViewCookie && "columnNumber" in this._contentViewCookie)
+ this._contentBrowser.navigationBar.selectedNavigationItem = this.detailNavigationItemForIdentifier("preview");
- this._showPreferredContentView();
-
- if (this._contentViewCookie) {
- if ("lineNumber" in this._contentViewCookie && "columnNumber" in this._contentViewCookie)
- this._contentBrowser.navigationBar.selectedNavigationItem = this._previewNavigationItem;
-
- this._contentBrowser.showContentView(this._contentBrowser.currentContentView, this._contentViewCookie);
- this._contentViewCookie = null;
- }
-
- this._contentBrowser.shown();
+ super.shown();
}
- hidden()
- {
- this._contentBrowser.hidden();
- }
-
- dispose()
- {
- this._delegate = null;
-
- this._contentBrowser.contentViewContainer.closeAllContentViews();
- }
-
- willShowWithCookie(cookie)
- {
- this._contentViewCookie = cookie;
- }
-
// ResourceHeadersContentView delegate
headersContentViewGoToRequestData(headersContentView)
{
- this._contentBrowser.navigationBar.selectedNavigationItem = this._previewNavigationItem;
+ this._contentBrowser.navigationBar.selectedNavigationItem = this.detailNavigationItemForIdentifier("preview");
this._resourceContentView.showRequest();
}
@@ -98,12 +63,12 @@
sizesContentViewGoToHeaders(metricsContentView)
{
- this._contentBrowser.navigationBar.selectedNavigationItem = this._headersNavigationItem;
+ this._contentBrowser.navigationBar.selectedNavigationItem = this.detailNavigationItemForIdentifier("headers");
}
sizesContentViewGoToRequestBody(metricsContentView)
{
- this._contentBrowser.navigationBar.selectedNavigationItem = this._previewNavigationItem;
+ this._contentBrowser.navigationBar.selectedNavigationItem = this.detailNavigationItemForIdentifier("preview");
this._resourceContentView.showRequest();
}
@@ -110,7 +75,7 @@
sizesContentViewGoToResponseBody(metricsContentView)
{
- this._contentBrowser.navigationBar.selectedNavigationItem = this._previewNavigationItem;
+ this._contentBrowser.navigationBar.selectedNavigationItem = this.detailNavigationItemForIdentifier("preview");
this._resourceContentView.showResponse();
}
@@ -119,101 +84,48 @@
initialLayout()
{
- let closeNavigationItem = new WI.ButtonNavigationItem("close", WI.UIString("Close detail view"), "Images/CloseLarge.svg", 16, 16);
- closeNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleCloseButton.bind(this));
- closeNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
+ this.createDetailNavigationItem("preview", WI.UIString("Preview"));
+ this.createDetailNavigationItem("headers", WI.UIString("Headers"));
+ this.createDetailNavigationItem("cookies", WI.UIString("Cookies"));
+ this.createDetailNavigationItem("sizes", WI.UIString("Sizes"));
+ this.createDetailNavigationItem("timing", WI.UIString("Timing"));
- let contentViewNavigationItemsGroup = new WI.GroupNavigationItem;
- let contentViewNavigationItemsFlexItem = new WI.FlexibleSpaceNavigationItem(contentViewNavigationItemsGroup, WI.FlexibleSpaceNavigationItem.Align.End);
- contentViewNavigationItemsFlexItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
-
- const disableBackForward = true;
- const disableFindBanner = false;
- this._contentBrowser = new WI.ContentBrowser(null, this, disableBackForward, disableFindBanner, contentViewNavigationItemsFlexItem, contentViewNavigationItemsGroup);
-
- this._previewNavigationItem = new WI.RadioButtonNavigationItem("preview", WI.UIString("Preview"));
- this._headersNavigationItem = new WI.RadioButtonNavigationItem("headers", WI.UIString("Headers"));
- this._cookiesNavigationItem = new WI.RadioButtonNavigationItem("cookies", WI.UIString("Cookies"));
- this._sizesNavigationItem = new WI.RadioButtonNavigationItem("sizes", WI.UIString("Sizes"));
- this._timingNavigationItem = new WI.RadioButtonNavigationItem("timing", WI.UIString("Timing"));
-
- // Insert all of our custom navigation items at the start of the ContentBrowser's NavigationBar.
- let index = 0;
- this._contentBrowser.navigationBar.insertNavigationItem(closeNavigationItem, index++);
- this._contentBrowser.navigationBar.insertNavigationItem(new WI.FlexibleSpaceNavigationItem, index++);
- this._contentBrowser.navigationBar.insertNavigationItem(this._previewNavigationItem, index++);
- this._contentBrowser.navigationBar.insertNavigationItem(this._headersNavigationItem, index++);
- this._contentBrowser.navigationBar.insertNavigationItem(this._cookiesNavigationItem, index++);
- this._contentBrowser.navigationBar.insertNavigationItem(this._sizesNavigationItem, index++);
- this._contentBrowser.navigationBar.insertNavigationItem(this._timingNavigationItem, index++);
- this._contentBrowser.navigationBar.addEventListener(WI.NavigationBar.Event.NavigationItemSelected, this._navigationItemSelected, this);
-
- this.addSubview(this._contentBrowser);
-
- this._showPreferredContentView();
+ super.initialLayout();
}
// Private
- _showPreferredContentView()
+ showContentViewForIdentifier(identifier)
{
- // Restore the preferred navigation item.
- let firstNavigationItem = null;
- let defaultIdentifier = WI.settings.selectedNetworkDetailContentViewIdentifier.value;
- for (let navigationItem of this._contentBrowser.navigationBar.navigationItems) {
- if (!(navigationItem instanceof WI.RadioButtonNavigationItem))
- continue;
+ super.showContentViewForIdentifier(identifier);
- if (navigationItem !== this._previewNavigationItem
- && navigationItem !== this._headersNavigationItem
- && navigationItem !== this._cookiesNavigationItem
- && navigationItem !== this._sizesNavigationItem
- && navigationItem !== this._timingNavigationItem)
- continue;
-
- if (!firstNavigationItem)
- firstNavigationItem = navigationItem;
-
- if (navigationItem.identifier === defaultIdentifier) {
- this._contentBrowser.navigationBar.selectedNavigationItem = navigationItem;
- return;
- }
- }
-
- console.assert(firstNavigationItem, "Should have found at least one navigation item above");
- this._contentBrowser.navigationBar.selectedNavigationItem = firstNavigationItem;
- }
-
- _showContentViewForNavigationItem(navigationItem)
- {
- let identifier = navigationItem.identifier;
if (this._contentViewCookie && "lineNumber" in this._contentViewCookie && "columnNumber" in this._contentViewCookie)
- identifier = this._previewNavigationItem.identifier;
+ identifier = "preview";
switch (identifier) {
case "preview":
if (!this._resourceContentView)
- this._resourceContentView = this._contentBrowser.showContentViewForRepresentedObject(this._resource);
+ this._resourceContentView = this._contentBrowser.showContentViewForRepresentedObject(this.representedObject);
this._contentBrowser.showContentView(this._resourceContentView, this._contentViewCookie);
break;
case "headers":
if (!this._headersContentView)
- this._headersContentView = new WI.ResourceHeadersContentView(this._resource, this);
+ this._headersContentView = new WI.ResourceHeadersContentView(this.representedObject, this);
this._contentBrowser.showContentView(this._headersContentView, this._contentViewCookie);
break;
case "cookies":
if (!this._cookiesContentView)
- this._cookiesContentView = new WI.ResourceCookiesContentView(this._resource);
+ this._cookiesContentView = new WI.ResourceCookiesContentView(this.representedObject);
this._contentBrowser.showContentView(this._cookiesContentView, this._contentViewCookie);
break;
case "sizes":
if (!this._sizesContentView)
- this._sizesContentView = new WI.ResourceSizesContentView(this._resource, this);
+ this._sizesContentView = new WI.ResourceSizesContentView(this.representedObject, this);
this._contentBrowser.showContentView(this._sizesContentView, this._contentViewCookie);
break;
case "timing":
if (!this._timingContentView)
- this._timingContentView = new WI.ResourceTimingContentView(this._resource);
+ this._timingContentView = new WI.ResourceTimingContentView(this.representedObject);
this._contentBrowser.showContentView(this._timingContentView, this._contentViewCookie);
break;
}
@@ -220,22 +132,4 @@
this._contentViewCookie = null;
}
-
- _navigationItemSelected(event)
- {
- let navigationItem = event.target.selectedNavigationItem;
- if (!(navigationItem instanceof WI.RadioButtonNavigationItem))
- return;
-
- this._showContentViewForNavigationItem(navigationItem);
-
- console.assert(navigationItem.identifier);
- WI.settings.selectedNetworkDetailContentViewIdentifier.value = navigationItem.identifier;
- }
-
- _handleCloseButton(event)
- {
- if (this._delegate && this._delegate.networkResourceDetailViewClose)
- this._delegate.networkResourceDetailViewClose(this);
- }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.css (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.css 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.css 2018-10-11 04:13:17 UTC (rev 237028)
@@ -23,6 +23,10 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+.content-view.network .network-table {
+ --node-waterfall-dom-event-size: 8px; /* Keep this in sync with `domEventElementSize`. */
+}
+
.content-view.network .navigation-bar .filter-bar {
background: none;
}
@@ -152,6 +156,25 @@
bottom: 0;
}
+.network-table :not(.header) .cell.waterfall .waterfall-container > .dom-event {
+ position: absolute;
+ top: calc(50% - (var(--node-waterfall-dom-event-size) / 2));
+ min-width: var(--node-waterfall-dom-event-size);
+ height: var(--node-waterfall-dom-event-size);
+ background-color: var(--selected-background-color);
+ border-radius: calc(var(--node-waterfall-dom-event-size) / 2);
+}
+
+.network-table :not(.header) .cell.waterfall .waterfall-container > .dom-activity {
+ position: absolute;
+ top: calc(50% - 0.5px);
+ border-top: 1px dashed var(--selected-background-color);
+}
+
+.network-table :not(.header) .cell.waterfall .waterfall-container > .dom-activity.playing {
+ border-top-style: solid;
+}
+
.network-table .timeline-ruler {
position: absolute;
top: 0;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js 2018-10-11 04:13:17 UTC (rev 237028)
@@ -40,9 +40,9 @@
this._table = null;
this._nameColumnWidthSetting = new WI.Setting("network-table-content-view-name-column-width", 250);
- this._selectedResource = null;
- this._resourceDetailView = null;
- this._resourceDetailViewMap = new Map;
+ this._selectedObject = null;
+ this._detailView = null;
+ this._detailViewMap = new Map;
this._domNodeEntries = new Map;
@@ -223,8 +223,8 @@
{
super.shown();
- if (this._resourceDetailView)
- this._resourceDetailView.shown();
+ if (this._detailView)
+ this._detailView.shown();
if (this._table)
this._table.restoreScrollPosition();
@@ -234,8 +234,8 @@
{
this._hidePopover();
- if (this._resourceDetailView)
- this._resourceDetailView.hidden();
+ if (this._detailView)
+ this._detailView.hidden();
super.hidden();
}
@@ -242,14 +242,14 @@
closed()
{
- for (let detailView of this._resourceDetailViewMap.values())
+ for (let detailView of this._detailViewMap.values())
detailView.dispose();
- this._resourceDetailViewMap.clear();
+ this._detailViewMap.clear();
this._domNodeEntries.clear();
this._hidePopover();
- this._hideResourceDetailView();
+ this._hideDetailView();
WI.Frame.removeEventListener(null, null, this);
WI.Resource.removeEventListener(null, null, this);
@@ -267,9 +267,9 @@
this._filteredEntries = [];
this._pendingInsertions = [];
- for (let detailView of this._resourceDetailViewMap.values())
+ for (let detailView of this._detailViewMap.values())
detailView.dispose();
- this._resourceDetailViewMap.clear();
+ this._detailViewMap.clear();
this._domNodeEntries.clear();
@@ -282,7 +282,7 @@
this._selectedResource = null;
this._table.reloadData();
this._hidePopover();
- this._hideResourceDetailView();
+ this._hideDetailView();
}
}
@@ -290,11 +290,11 @@
{
console.assert(representedObject instanceof WI.Resource);
- let rowIndex = this._rowIndexForResource(representedObject);
+ let rowIndex = this._rowIndexForRepresentedObject(representedObject);
if (rowIndex === -1) {
this._selectedResource = null;
this._table.deselectAll();
- this._hideResourceDetailView();
+ this._hideDetailView();
return;
}
@@ -303,13 +303,13 @@
this._showingRepresentedObjectCookie = null;
}
- // NetworkResourceDetailView delegate
+ // NetworkDetailView delegate
- networkResourceDetailViewClose(resourceDetailView)
+ networkDetailViewClose(networkDetailView)
{
this._selectedResource = null;
this._table.deselectAll();
- this._hideResourceDetailView();
+ this._hideDetailView();
}
// Table dataSource
@@ -326,7 +326,7 @@
if (!this._entriesSortComparator)
return;
- this._hideResourceDetailView();
+ this._hideDetailView();
for (let nodeEntry of this._domNodeEntries.values())
nodeEntry.initiatedResourceEntries.sort(this._entriesSortComparator);
@@ -362,20 +362,20 @@
{
let rowIndex = table.selectedRow;
if (isNaN(rowIndex)) {
- this._selectedResource = null;
- this._hideResourceDetailView();
+ this._selectedObject = null;
+ this._hideDetailView();
return;
}
let entry = this._filteredEntries[rowIndex];
- if (entry.resource === this._selectedResource)
+ if (entry.resource === this._selectedObject || entry.domNode === this._selectedObject)
return;
- this._selectedResource = entry.resource;
- if (this._selectedResource)
- this._showResourceDetailView(this._selectedResource);
+ this._selectedObject = entry.resource || entry.domNode;
+ if (this._selectedObject)
+ this._showDetailView(this._selectedObject);
else
- this._hideResourceDetailView();
+ this._hideDetailView();
}
tablePopulateCell(table, cell, column, rowIndex)
@@ -516,7 +516,7 @@
if (WI.settings.groupByDOMNode.value && resource.initiatorNode) {
let nodeEntry = this._domNodeEntries.get(resource.initiatorNode);
- if (nodeEntry.initiatedResourceEntries.length > 1) {
+ if (nodeEntry.initiatedResourceEntries.length > 1 || nodeEntry.domNode.domEvents.length) {
cell.classList.add("child");
let range = resource.requestedByteRange;
@@ -641,9 +641,83 @@
{
cell.removeChildren();
+ let container = cell.appendChild(document.createElement("div"));
+ container.className = "waterfall-container";
+
+ let graphStartTime = this._waterfallTimelineRuler.startTime;
+ let secondsPerPixel = this._waterfallTimelineRuler.secondsPerPixel;
+
+ function positionByStartOffset(element, timestamp) {
+ let styleAttribute = WI.resolvedLayoutDirection() === WI.LayoutDirection.LTR ? "left" : "right";
+ element.style.setProperty(styleAttribute, ((timestamp - graphStartTime) / secondsPerPixel) + "px");
+ }
+
+ function setWidthForDuration(element, startTimestamp, endTimestamp) {
+ element.style.setProperty("width", ((endTimestamp - startTimestamp) / secondsPerPixel) + "px");
+ }
+
let domNode = entry.domNode;
if (domNode) {
- // FIXME: <https://webkit.org/b/189773> Web Inspector: create special Network waterfall for media events
+ const domEventElementSize = 8; // Keep this in sync with `--node-waterfall-dom-event-size`.
+
+ let groupedDOMEvents = domNode.domEvents.reduce((accumulator, current) => {
+ if (!accumulator.length || (current.timestamp - accumulator.lastValue.endTimestamp) >= (domEventElementSize * secondsPerPixel)) {
+ accumulator.push({
+ startTimestamp: current.timestamp,
+ domEvents: [],
+ });
+ }
+ accumulator.lastValue.endTimestamp = current.timestamp;
+ accumulator.lastValue.domEvents.push(current);
+ return accumulator;
+ }, []);
+
+ let playing = false;
+
+ function createDOMEventLine(domEvents, startTimestamp, endTimestamp) {
+ if (domEvents.lastValue.eventName === "ended")
+ return;
+
+ for (let i = domEvents.length - 1; i >= 0; --i) {
+ let domEvent = domEvents[i];
+ if (domEvent.eventName === "play" || domEvent.eventName === "playing" || domEvent.eventName === "timeupdate") {
+ playing = true;
+ break;
+ }
+
+ if (domEvent.eventName === "pause" || domEvent.eventName === "stall") {
+ playing = false;
+ break;
+ }
+ }
+
+ let lineElement = container.appendChild(document.createElement("div"));
+ lineElement.classList.add("dom-activity");
+ lineElement.classList.toggle("playing", playing);
+ positionByStartOffset(lineElement, startTimestamp);
+ setWidthForDuration(lineElement, startTimestamp, endTimestamp);
+ }
+
+ for (let [a, b] of groupedDOMEvents.adjacencies())
+ createDOMEventLine(a.domEvents, a.endTimestamp, b.startTimestamp);
+
+ if (groupedDOMEvents.length)
+ createDOMEventLine(groupedDOMEvents.lastValue.domEvents, groupedDOMEvents.lastValue.endTimestamp, this._waterfallEndTime);
+
+ for (let {startTimestamp, endTimestamp, domEvents} of groupedDOMEvents) {
+ let paddingForCentering = domEventElementSize * secondsPerPixel / 2;
+
+ let eventElement = container.appendChild(document.createElement("div"));
+ eventElement.classList.add("dom-event");
+ positionByStartOffset(eventElement, startTimestamp - paddingForCentering);
+ setWidthForDuration(eventElement, startTimestamp, endTimestamp + paddingForCentering);
+ eventElement.addEventListener("mousedown", (event) => {
+ if (event.button !== 0 || event.ctrlKey)
+ return;
+ this._handleNodeEntryMousedownWaterfall(eventElement, entry, domEvents);
+ });
+ }
+
return;
}
@@ -659,7 +733,6 @@
return;
}
- let graphStartTime = this._waterfallTimelineRuler.startTime;
if (responseEnd < graphStartTime) {
cell.textContent = zeroWidthSpace;
return;
@@ -671,22 +744,14 @@
return;
}
- let secondsPerPixel = this._waterfallTimelineRuler.secondsPerPixel;
-
- let container = cell.appendChild(document.createElement("div"));
- container.className = "waterfall-container";
-
function appendBlock(startTimestamp, endTimestamp, className) {
if (isNaN(startTimestamp) || isNaN(endTimestamp) || endTimestamp - startTimestamp <= 0)
return null;
- let startOffset = (startTimestamp - graphStartTime) / secondsPerPixel;
- let width = (endTimestamp - startTimestamp) / secondsPerPixel;
let block = container.appendChild(document.createElement("div"));
block.classList.add("block", className);
- let styleAttribute = WI.resolvedLayoutDirection() === WI.LayoutDirection.LTR ? "left" : "right";
- block.style[styleAttribute] = startOffset + "px";
- block.style.width = width + "px";
+ positionByStartOffset(block, startTimestamp);
+ setWidthForDuration(block, startTimestamp, endTimestamp);
return block;
}
@@ -696,7 +761,7 @@
mouseBlock.addEventListener("mousedown", (event) => {
if (event.button !== 0 || event.ctrlKey)
return;
- this._handleMousedownWaterfall(mouseBlock, entry, event);
+ this._handleResourceEntryMousedownWaterfall(mouseBlock, entry);
});
// Super small visualization.
@@ -1049,8 +1114,10 @@
}
this._pendingInsertions = [];
- for (let resource of this._pendingUpdates)
- this._updateEntryForResource(resource);
+ for (let updateObject of this._pendingUpdates) {
+ if (updateObject instanceof WI.Resource)
+ this._updateEntryForResource(updateObject);
+ }
this._pendingUpdates = [];
this._pendingFilter = false;
@@ -1112,9 +1179,15 @@
}
}
- _rowIndexForResource(resource)
+ _rowIndexForRepresentedObject(object)
{
- return this._filteredEntries.findIndex((x) => x.resource === resource);
+ return this._filteredEntries.findIndex((x) => {
+ if (x.resource === object)
+ return true;
+ if (x.domNode === object)
+ return true;
+ return false;
+ });
}
_updateEntryForResource(resource)
@@ -1132,7 +1205,7 @@
let entry = this._entryForResource(resource);
updateExistingEntry(this._entries[index], entry);
- let rowIndex = this._rowIndexForResource(resource);
+ let rowIndex = this._rowIndexForRepresentedObject(resource);
if (rowIndex === -1)
return;
@@ -1145,43 +1218,50 @@
this._waterfallPopover.dismiss();
}
- _hideResourceDetailView()
+ _hideDetailView()
{
- if (!this._resourceDetailView)
+ if (!this._detailView)
return;
this.element.classList.remove("showing-detail");
this._table.scrollContainer.style.removeProperty("width");
- this.removeSubview(this._resourceDetailView);
+ this.removeSubview(this._detailView);
- this._resourceDetailView.hidden();
- this._resourceDetailView = null;
+ this._detailView.hidden();
+ this._detailView = null;
this._table.resize();
this._table.reloadVisibleColumnCells(this._waterfallColumn);
}
- _showResourceDetailView(resource)
+ _showDetailView(object)
{
- let oldResourceDetailView = this._resourceDetailView;
+ let oldDetailView = this._detailView;
- this._resourceDetailView = this._resourceDetailViewMap.get(resource);
- if (!this._resourceDetailView) {
- this._resourceDetailView = new WI.NetworkResourceDetailView(resource, this);
- this._resourceDetailViewMap.set(resource, this._resourceDetailView);
+ this._detailView = this._detailViewMap.get(object);
+ if (!this._detailView) {
+ if (object instanceof WI.Resource)
+ this._detailView = new WI.NetworkResourceDetailView(object, this);
+ else if (object instanceof WI.DOMNode) {
+ this._detailView = new WI.NetworkDOMNodeDetailView(object, this, {
+ startTimestamp: this._waterfallStartTime,
+ });
+ }
+
+ this._detailViewMap.set(object, this._detailView);
}
- if (oldResourceDetailView) {
- oldResourceDetailView.hidden();
- this.replaceSubview(oldResourceDetailView, this._resourceDetailView);
+ if (oldDetailView) {
+ oldDetailView.hidden();
+ this.replaceSubview(oldDetailView, this._detailView);
} else
- this.addSubview(this._resourceDetailView);
+ this.addSubview(this._detailView);
if (this._showingRepresentedObjectCookie)
- this._resourceDetailView.willShowWithCookie(this._showingRepresentedObjectCookie);
+ this._detailView.willShowWithCookie(this._showingRepresentedObjectCookie);
- this._resourceDetailView.shown();
+ this._detailView.shown();
this.element.classList.add("showing-detail");
this._table.scrollContainer.style.width = this._nameColumn.width + "px";
@@ -1194,11 +1274,11 @@
_positionDetailView()
{
- if (!this._resourceDetailView)
+ if (!this._detailView)
return;
let side = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
- this._resourceDetailView.element.style[side] = this._nameColumn.width + "px";
+ this._detailView.element.style[side] = this._nameColumn.width + "px";
this._table.scrollContainer.style.width = this._nameColumn.width + "px";
}
@@ -1331,7 +1411,7 @@
let entry = this._entries[index];
entry.transferSize = !isNaN(resource.networkTotalTransferSize) ? resource.networkTotalTransferSize : resource.estimatedTotalTransferSize;
- let rowIndex = this._rowIndexForResource(resource);
+ let rowIndex = this._rowIndexForRepresentedObject(resource);
if (rowIndex === -1)
return;
@@ -1444,6 +1524,8 @@
if (!nodeEntry) {
nodeEntry = this._entryForDOMNode(resource.initiatorNode, Object.keys(resourceEntry));
this._domNodeEntries.set(resource.initiatorNode, nodeEntry);
+
+ resource.initiatorNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleNodeDidFireEvent, this);
}
if (!this._entriesSortComparator)
@@ -1466,6 +1548,19 @@
}, new Set);
}
+ _handleNodeDidFireEvent(event)
+ {
+ let domNode = event.target;
+ let {domEvent} = event.data;
+
+ this._pendingUpdates.push(domNode);
+
+ if (domEvent.timestamp > this._waterfallEndTime)
+ this._waterfallEndTime = domEvent.timestamp + (this._waterfallTimelineRuler.secondsPerPixel * 10);
+
+ this.needsLayout();
+ }
+
_hasTypeFilter()
{
return !!this._activeTypeFilters;
@@ -1517,7 +1612,7 @@
if (WI.settings.groupByDOMNode.value) {
for (let nodeEntry of this._domNodeEntries.values()) {
- if (nodeEntry.initiatedResourceEntries.length < 2)
+ if (nodeEntry.initiatedResourceEntries.length < 2 && !nodeEntry.domNode.domEvents.length)
continue;
let firstIndex = Infinity;
@@ -1614,7 +1709,7 @@
return;
// Even if the selected resource would still be visible, lets close the detail view if a filter changes.
- this._hideResourceDetailView();
+ this._hideDetailView();
this._activeTypeFilters = newFilter;
this._updateFilteredEntries();
@@ -1640,7 +1735,7 @@
return;
// Even if the selected resource would still be visible, lets close the detail view if a filter changes.
- this._hideResourceDetailView();
+ this._hideDetailView();
// Search cleared.
if (!searchQuery) {
@@ -1669,10 +1764,10 @@
_restoreSelectedRow()
{
- if (!this._selectedResource)
+ if (!this._selectedObject)
return;
- let rowIndex = this._rowIndexForResource(this._selectedResource);
+ let rowIndex = this._rowIndexForRepresentedObject(this._selectedObject);
if (rowIndex === -1) {
this._selectedResource = null;
this._table.deselectAll();
@@ -1709,11 +1804,18 @@
}).catch(handlePromiseException);
}
- _waterfallPopoverContentForResource(resource)
+ _waterfallPopoverContent()
{
let contentElement = document.createElement("div");
- contentElement.className = "waterfall-popover-content";
+ contentElement.classList.add("waterfall-popover-content");
+ return contentElement;
+ }
+ _waterfallPopoverContentForResourceEntry(resourceEntry)
+ {
+ let contentElement = this._waterfallPopoverContent();
+
+ let resource = resourceEntry.resource;
if (!resource.hasResponse() || !resource.firstTimestamp || !resource.lastTimestamp) {
contentElement.textContent = WI.UIString("Resource has no timing data");
return contentElement;
@@ -1726,8 +1828,33 @@
return contentElement;
}
- _handleMousedownWaterfall(mouseBlock, entry, event)
+ _waterfallPopoverContentForNodeEntry(nodeEntry, domEvents)
{
+ let contentElement = this._waterfallPopoverContent();
+
+ let breakdownView = new WI.DOMEventsBreakdownView(domEvents, {
+ startTimestamp: this._waterfallStartTime,
+ });
+ contentElement.appendChild(breakdownView.element);
+ breakdownView.updateLayout();
+
+ return contentElement;
+ }
+
+ _handleResourceEntryMousedownWaterfall(targetElement, resourceEntry)
+ {
+ let popoverContentElement = this._waterfallPopoverContentForResourceEntry(resourceEntry);
+ this._handleMousedownWaterfall(resourceEntry, targetElement, popoverContentElement);
+ }
+
+ _handleNodeEntryMousedownWaterfall(targetElement, nodeEntry, domEvents)
+ {
+ let popoverContentElement = this._waterfallPopoverContentForNodeEntry(nodeEntry, domEvents);
+ this._handleMousedownWaterfall(nodeEntry, targetElement, popoverContentElement);
+ }
+
+ _handleMousedownWaterfall(entry, targetElement, popoverContentElement)
+ {
if (!this._waterfallPopover) {
this._waterfallPopover = new WI.Popover;
this._waterfallPopover.element.classList.add("waterfall-popover");
@@ -1737,7 +1864,10 @@
return;
let calculateTargetFrame = () => {
- let rowIndex = this._rowIndexForResource(entry.resource);
+ if (!entry.resource)
+ return WI.Rect.rectFromClientRect(targetElement.getBoundingClientRect());
+
+ let rowIndex = this._rowIndexForRepresentedObject(entry.resource);
let cell = this._table.cellForRowAndColumn(rowIndex, this._waterfallColumn);
if (!cell) {
this._waterfallPopover.dismiss();
@@ -1767,7 +1897,6 @@
this._waterfallPopover.present(bounds, preferredEdges);
};
- let popoverContentElement = this._waterfallPopoverContentForResource(entry.resource);
this._waterfallPopover.presentNewContentWithFrame(popoverContentElement, targetFrame, preferredEdges);
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingBreakdownView.css (237027 => 237028)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingBreakdownView.css 2018-10-11 03:08:34 UTC (rev 237027)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimingBreakdownView.css 2018-10-11 04:13:17 UTC (rev 237028)
@@ -23,10 +23,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-.popover.waterfall-popover {
- --popover-background-color: white;
-}
-
.waterfall-popover-content .resource-timing-breakdown {
margin: 5px;
-webkit-user-select: text;
@@ -73,8 +69,8 @@
}
@media (prefers-dark-interface) {
- .popover.waterfall-popover {
- --popover-background-color: var(--panel-background-color);
+ .resource-timing-breakdown > table > tr.header:not(.total-row) > td {
+ color: var(--text-color);
}
.resource-timing-breakdown > table > tr > td.label,