Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (222341 => 222342)
--- trunk/Source/WebInspectorUI/ChangeLog 2017-09-21 20:16:52 UTC (rev 222341)
+++ trunk/Source/WebInspectorUI/ChangeLog 2017-09-21 20:18:01 UTC (rev 222342)
@@ -1,3 +1,37 @@
+2017-09-21 Ross Kirsling <[email protected]>
+
+ Web Inspector: Add details sidebar to Layers tab.
+ https://bugs.webkit.org/show_bug.cgi?id=177115
+
+ Reviewed by Devin Rousso.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Main.html:
+ * UserInterface/Views/LayerDetailsSidebarPanel.css: Added.
+ * UserInterface/Views/LayerDetailsSidebarPanel.js: Added.
+ New files and strings for sidebar.
+
+ * UserInterface/Base/Utilities.js:
+ Add global identifier for "×" character.
+
+ * UserInterface/Models/Layer.js: Added.
+ Add a model class for layers so that we can instanceof-check them.
+
+ * UserInterface/Controllers/LayerTreeManager.js:
+ (WI.LayerTreeManager.prototype.layersForNode):
+ Utilize model class WI.Layer.
+
+ * UserInterface/Views/Layers3DContentView.js:
+ (WI.Layers3DContentView):
+ (WI.Layers3DContentView.prototype.get supplementalRepresentedObjects):
+ (WI.Layers3DContentView.prototype.layout):
+ (WI.Layers3DContentView.prototype._addLayer):
+ Pass layer data to sidebar and utilize model class WI.Layer.
+
+ * UserInterface/Views/LayersTabContentView.js:
+ (WI.LayersTabContentView):
+ Attach details sidebar.
+
2017-09-21 Brian Burg <[email protected]>
Web Inspector: keyboard shortcut for "Reload page from origin" doesn't match Safari, and doesn't work
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (222341 => 222342)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2017-09-21 20:16:52 UTC (rev 222341)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2017-09-21 20:18:01 UTC (rev 222342)
@@ -81,6 +81,7 @@
localizedStrings["All"] = "All";
localizedStrings["All Changes"] = "All Changes";
localizedStrings["All Exceptions"] = "All Exceptions";
+localizedStrings["All Layers"] = "All Layers";
localizedStrings["All Requests"] = "All Requests";
localizedStrings["All Resources"] = "All Resources";
localizedStrings["All Storage"] = "All Storage";
@@ -208,6 +209,7 @@
localizedStrings["Compare snapshots"] = "Compare snapshots";
localizedStrings["Comparison of total memory size at the end of the selected time range to the maximum memory size in this recording"] = "Comparison of total memory size at the end of the selected time range to the maximum memory size in this recording";
localizedStrings["Composite"] = "Composite";
+localizedStrings["Composited"] = "Composited";
localizedStrings["Compressed"] = "Compressed";
localizedStrings["Compression"] = "Compression";
localizedStrings["Condition"] = "Condition";
@@ -941,6 +943,7 @@
localizedStrings["Vertex Shader"] = "Vertex Shader";
localizedStrings["Vertical"] = "Vertical";
localizedStrings["View variable value"] = "View variable value";
+localizedStrings["Visible"] = "Visible";
localizedStrings["Visibility"] = "Visibility";
localizedStrings["Warning: "] = "Warning: ";
localizedStrings["Warnings"] = "Warnings";
Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js (222341 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2017-09-21 20:16:52 UTC (rev 222341)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js 2017-09-21 20:18:01 UTC (rev 222342)
@@ -28,6 +28,7 @@
var figureDash = "\u2012";
var ellipsis = "\u2026";
var zeroWidthSpace = "\u200b";
+var multiplicationSign = "\u00d7";
Object.defineProperty(Object, "shallowCopy",
{
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/LayerTreeManager.js (222341 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/LayerTreeManager.js 2017-09-21 20:16:52 UTC (rev 222341)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/LayerTreeManager.js 2017-09-21 20:18:01 UTC (rev 222342)
@@ -128,6 +128,8 @@
return;
}
+ layers = layers.map(WI.Layer.fromPayload);
+
var firstLayer = layers[0];
var layerForNode = firstLayer.nodeId === node.id && !firstLayer.isGeneratedContent ? layers.shift() : null;
callback(layerForNode, layers);
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (222341 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2017-09-21 20:16:52 UTC (rev 222341)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2017-09-21 20:18:01 UTC (rev 222342)
@@ -110,6 +110,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=""
@@ -370,6 +371,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
@@ -627,6 +629,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Added: trunk/Source/WebInspectorUI/UserInterface/Models/Layer.js (0 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Layer.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Layer.js 2017-09-21 20:18:01 UTC (rev 222342)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * 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.Layer = class Layer {
+ constructor(layerId, nodeId, bounds, paintCount, memory, compositedBounds, isInShadowTree, isReflection, isGeneratedContent, isAnonymous, pseudoElementId, pseudoElement)
+ {
+ console.assert(typeof bounds === "object");
+
+ this._layerId = layerId;
+ this._nodeId = nodeId;
+ this._bounds = bounds;
+ this._paintCount = paintCount;
+ this._memory = memory;
+ this._compositedBounds = compositedBounds;
+ this._isInShadowTree = isInShadowTree;
+ this._isReflection = isReflection;
+ this._isGeneratedContent = isGeneratedContent;
+ this._isAnonymous = isAnonymous;
+ this._pseudoElementId = pseudoElementId;
+ this._pseudoElement = pseudoElement;
+
+ // FIXME: This should probably be moved to the backend.
+ this._compositedBounds.x = this._bounds.x;
+ this._compositedBounds.y = this._bounds.y;
+ }
+
+ // Static
+
+ static fromPayload(payload)
+ {
+ return new WI.Layer(
+ payload.layerId,
+ payload.nodeId,
+ payload.bounds,
+ payload.paintCount,
+ payload.memory,
+ payload.compositedBounds,
+ payload.isInShadowTree,
+ payload.isReflection,
+ payload.isGeneratedContent,
+ payload.isAnonymous,
+ payload.pseudoElementId,
+ payload.pseudoElement
+ );
+ }
+
+ // Public
+
+ get layerId() { return this._layerId; }
+ get nodeId() { return this._nodeId; }
+ get bounds() { return this._bounds; }
+ get paintCount() { return this._paintCount; }
+ get memory() { return this._memory; }
+ get compositedBounds() { return this._compositedBounds; }
+ get isInShadowTree() { return this._isInShadowTree; }
+ get isReflection() { return this._isReflection; }
+ get isGeneratedContent() { return this._isGeneratedContent; }
+ get isAnonymous() { return this._isAnonymous; }
+ get pseudoElementId() { return this._pseudoElementId; }
+ get pseudoElement() { return this._pseudoElement; }
+};
Added: trunk/Source/WebInspectorUI/UserInterface/Views/LayerDetailsSidebarPanel.css (0 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LayerDetailsSidebarPanel.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayerDetailsSidebarPanel.css 2017-09-21 20:18:01 UTC (rev 222342)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * 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.
+ */
+
+.sidebar > .panel.details.layer > .content {
+ bottom: var(--console-prompt-min-height);
+}
+
+.panel.details.layer .data-grid {
+ height: 100%;
+ border: none;
+}
+
+.panel.details.layer .name-column .icon {
+ content: url(../Images/DOMElement.svg);
+}
+
+.panel.details.layer tr.reflection .name-column .icon {
+ content: url(../Images/Reflection.svg);
+}
+
+.panel.details.layer tr.pseudo-element .name-column .icon {
+ content: url(../Images/PseudoElement.svg);
+}
+
+.panel.details.layer .name-column :matches(.pseudo-element, .reflection) {
+ color: var(--text-color-gray-medium);
+}
+
+.panel.details.layer tr.selected .name-column :matches(.pseudo-element, .reflection) {
+ color: var(--selected-secondary-text-color);
+}
+
+.panel.details.layer .bottom-bar {
+ position: absolute;
+ display: flex;
+ bottom: 0;
+ height: var(--console-prompt-min-height);
+ width: 100%;
+ border-top: 1px solid var(--border-color);
+ background-color: white;
+}
+
+.panel.details.layer .bottom-bar > div {
+ display: flex;
+ flex: 1;
+ padding: 4px 6px;
+ line-height: 20px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.panel.details.layer .layers-memory-label {
+ justify-content: flex-end;
+}
+
+.layer-popover {
+ max-width: 300px;
+ padding: 5px;
+}
+
+.layer-popover > div {
+ font-size: 1.1em;
+ font-weight: bold;
+}
+
+.layer-popover table {
+ margin: 10px 0;
+}
+.layer-popover td {
+ padding: 0 5px;
+ line-height: 1.3em;
+}
+
+.layer-popover ul {
+ margin: 10px 0 0;
+ padding: 0;
+
+ -webkit-margin-start: 1em;
+ -webkit-padding-start: 1em;
+}
+
+.layer-popover li {
+ line-height: 1.3em;
+}
Added: trunk/Source/WebInspectorUI/UserInterface/Views/LayerDetailsSidebarPanel.js (0 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LayerDetailsSidebarPanel.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayerDetailsSidebarPanel.js 2017-09-21 20:18:01 UTC (rev 222342)
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * 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.LayerDetailsSidebarPanel = class LayerDetailsSidebarPanel extends WI.DetailsSidebarPanel
+{
+ constructor()
+ {
+ super("layer", WI.UIString("All Layers"));
+
+ this.element.classList.add("layer");
+
+ this._layers = [];
+ this._dataGridNodesByLayerId = new Map;
+
+ this._dataGrid = null;
+ this._bottomBar = null;
+ this._layersCountLabel = null;
+ this._layersMemoryLabel = null;
+ this._popover = null;
+ }
+
+ // Public
+
+ inspect(objects)
+ {
+ if (!(objects instanceof Array))
+ objects = [objects];
+
+ let layers = objects.filter((object) => object instanceof WI.Layer);
+ this._updateDisplayWithLayers(layers);
+
+ return !!layers.length;
+ }
+
+ // Private
+
+ _buildDataGrid()
+ {
+ const columns = {
+ name: {
+ title: WI.UIString("Node"),
+ sortable: false,
+ },
+ paintCount: {
+ title: WI.UIString("Paints"),
+ sortable: true,
+ aligned: "right",
+ width: "50px",
+ },
+ memory: {
+ title: WI.UIString("Memory"),
+ sortable: true,
+ aligned: "right",
+ width: "70px",
+ }
+ };
+
+ this._dataGrid = new WI.DataGrid(columns);
+ this._dataGrid.addEventListener(WI.DataGrid.Event.SortChanged, this._sortDataGrid, this);
+ this._dataGrid.addEventListener(WI.DataGrid.Event.SelectedNodeChanged, this._dataGridSelectedNodeChanged, this);
+
+ this._dataGrid.sortColumnIdentifier = "memory";
+ this._dataGrid.sortOrder = WI.DataGrid.SortOrder.Descending;
+ this._dataGrid.createSettings("layer-details-sidebar-panel");
+
+ this._dataGrid.element.addEventListener("focus", this._dataGridFocused.bind(this), false);
+ this._dataGrid.element.addEventListener("blur", this._dataGridBlurred.bind(this), false);
+ this._dataGrid.element.addEventListener("click", this._dataGridClicked.bind(this), false);
+
+ this.contentView.addSubview(this._dataGrid);
+ }
+
+ _buildBottomBar()
+ {
+ this._bottomBar = this.element.appendChild(document.createElement("div"));
+ this._bottomBar.className = "bottom-bar";
+
+ this._layersCountLabel = this._bottomBar.appendChild(document.createElement("div"));
+ this._layersCountLabel.className = "layers-count-label";
+
+ this._layersMemoryLabel = this._bottomBar.appendChild(document.createElement("div"));
+ this._layersMemoryLabel.className = "layers-memory-label";
+ }
+
+ _sortDataGrid()
+ {
+ let sortColumnIdentifier = this._dataGrid.sortColumnIdentifier;
+
+ function comparator(a, b) {
+ let itemA = a.layer[sortColumnIdentifier] || 0;
+ let itemB = b.layer[sortColumnIdentifier] || 0;
+ return itemA - itemB;
+ }
+
+ this._dataGrid.sortNodes(comparator);
+ this._updatePopoverForSelectedNode();
+ }
+
+ _dataGridSelectedNodeChanged()
+ {
+ if (this._dataGrid.selectedNode) {
+ this._highlightSelectedNode();
+ this._showPopoverForSelectedNode();
+ } else {
+ WI.domTreeManager.hideDOMNodeHighlight();
+ this._hidePopover();
+ }
+ }
+
+ _dataGridFocused(event)
+ {
+ this._highlightSelectedNode();
+ this._showPopoverForSelectedNode();
+ }
+
+ _dataGridBlurred(event)
+ {
+ WI.domTreeManager.hideDOMNodeHighlight();
+ this._hidePopover();
+ }
+
+ _dataGridClicked(event)
+ {
+ if (this._dataGrid.selectedNode && event.target.parentNode.classList.contains("filler"))
+ this._dataGrid.selectedNode.deselect();
+ }
+
+ _highlightSelectedNode()
+ {
+ if (!this._dataGrid.selectedNode)
+ return;
+
+ let layer = this._dataGrid.selectedNode.layer;
+ if (layer.isGeneratedContent || layer.isReflection || layer.isAnonymous) {
+ const usePageCoordinates = true;
+ WI.domTreeManager.highlightRect(layer.bounds, usePageCoordinates);
+ } else
+ WI.domTreeManager.highlightDOMNode(layer.nodeId);
+ }
+
+ _updateDisplayWithLayers(newLayers)
+ {
+ let previousLayers = this._layers;
+ this._layers = newLayers;
+
+ this._updateDataGrid(previousLayers);
+ this._updateBottomBar();
+ }
+
+ _updateDataGrid(previousLayers)
+ {
+ if (!this._dataGrid)
+ this._buildDataGrid();
+
+ let mutations = WI.layerTreeManager.layerTreeMutations(previousLayers, this._layers);
+
+ mutations.removals.forEach((layer) => {
+ let node = this._dataGridNodesByLayerId.get(layer.layerId);
+ if (!node)
+ return;
+
+ this._dataGrid.removeChild(node);
+ this._dataGridNodesByLayerId.delete(layer.layerId);
+ });
+
+ mutations.additions.forEach((layer) => {
+ let node = this._dataGridNodeForLayer(layer);
+ this._dataGrid.appendChild(node);
+ });
+
+ mutations.preserved.forEach((layer) => {
+ let node = this._dataGridNodesByLayerId.get(layer.layerId);
+ if (!node)
+ return;
+
+ node.layer = layer;
+ });
+
+ this._sortDataGrid();
+ }
+
+ _dataGridNodeForLayer(layer)
+ {
+ let node = new WI.LayerTreeDataGridNode(layer);
+ this._dataGridNodesByLayerId.set(layer.layerId, node);
+
+ return node;
+ }
+
+ _updateBottomBar()
+ {
+ if (!this._bottomBar)
+ this._buildBottomBar();
+
+ this._layersCountLabel.textContent = WI.UIString("Layer Count: %d").format(this._layers.length);
+
+ let totalMemory = this._layers.reduce((total, layer) => total + (layer.memory || 0), 0);
+ this._layersMemoryLabel.textContent = WI.UIString("Memory: %s").format(Number.bytesToString(totalMemory));
+ }
+
+ _showPopoverForSelectedNode()
+ {
+ let dataGridNode = this._dataGrid.selectedNode;
+ if (!dataGridNode)
+ return;
+
+ this._contentForPopover(dataGridNode.layer, (content) => {
+ if (dataGridNode === this._dataGrid.selectedNode)
+ this._updatePopoverForSelectedNode(content);
+ });
+ }
+
+ _updatePopoverForSelectedNode(content)
+ {
+ if (!this._dataGrid.selectedNode)
+ return;
+
+ if (!this._popover) {
+ this._popover = new WI.Popover;
+ this._popover.windowResizeHandler = () => { this._updatePopoverForSelectedNode(); };
+ }
+
+ let targetFrame = WI.Rect.rectFromClientRect(this._dataGrid.selectedNode.element.getBoundingClientRect());
+
+ if (content)
+ this._popover.content = content;
+
+ this._popover.present(targetFrame.pad(2), [WI.RectEdge.MIN_X]);
+ }
+
+ _hidePopover()
+ {
+ if (this._popover)
+ this._popover.dismiss();
+ }
+
+ _contentForPopover(layer, callback)
+ {
+ let content = document.createElement("div");
+ content.className = "layer-popover";
+
+ let dimensionsTitle = content.appendChild(document.createElement("div"));
+ dimensionsTitle.textContent = WI.UIString("Dimensions");
+
+ let dimensionsTable = content.appendChild(document.createElement("table"));
+
+ let compositedRow = dimensionsTable.appendChild(document.createElement("tr"));
+ let compositedLabel = compositedRow.appendChild(document.createElement("td"));
+ let compositedValue = compositedRow.appendChild(document.createElement("td"));
+ compositedLabel.textContent = WI.UIString("Composited");
+ compositedValue.textContent = `${layer.compositedBounds.width}px ${multiplicationSign} ${layer.compositedBounds.height}px`;
+
+ let visibleRow = dimensionsTable.appendChild(document.createElement("tr"));
+ let visibleLabel = visibleRow.appendChild(document.createElement("td"));
+ let visibleValue = visibleRow.appendChild(document.createElement("td"));
+ visibleLabel.textContent = WI.UIString("Visible");
+ visibleValue.textContent = `${layer.bounds.width}px ${multiplicationSign} ${layer.bounds.height}px`;
+
+ let reasonsTitle = content.appendChild(document.createElement("div"));
+ reasonsTitle.textContent = WI.UIString("Reasons for compositing:");
+
+ let list = content.appendChild(document.createElement("ul"));
+
+ WI.layerTreeManager.reasonsForCompositingLayer(layer, (compositingReasons) => {
+ if (isEmptyObject(compositingReasons)) {
+ callback(content);
+ return;
+ }
+
+ this._populateListOfCompositingReasons(list, compositingReasons);
+
+ callback(content);
+ });
+
+ return content;
+ }
+
+ _populateListOfCompositingReasons(list, compositingReasons)
+ {
+ function addReason(reason) {
+ let item = list.appendChild(document.createElement("li"));
+ item.textContent = reason;
+ }
+
+ if (compositingReasons.transform3D)
+ addReason(WI.UIString("Element has a 3D transform"));
+ if (compositingReasons.video)
+ addReason(WI.UIString("Element is <video>"));
+ if (compositingReasons.canvas)
+ addReason(WI.UIString("Element is <canvas>"));
+ if (compositingReasons.plugin)
+ addReason(WI.UIString("Element is a plug-in"));
+ if (compositingReasons.iFrame)
+ addReason(WI.UIString("Element is <iframe>"));
+ if (compositingReasons.backfaceVisibilityHidden)
+ addReason(WI.UIString("Element has “backface-visibility: hidden” style"));
+ if (compositingReasons.clipsCompositingDescendants)
+ addReason(WI.UIString("Element clips compositing descendants"));
+ if (compositingReasons.animation)
+ addReason(WI.UIString("Element is animated"));
+ if (compositingReasons.filters)
+ addReason(WI.UIString("Element has CSS filters applied"));
+ if (compositingReasons.positionFixed)
+ addReason(WI.UIString("Element has “position: fixed” style"));
+ if (compositingReasons.positionSticky)
+ addReason(WI.UIString("Element has “position: sticky” style"));
+ if (compositingReasons.overflowScrollingTouch)
+ addReason(WI.UIString("Element has “-webkit-overflow-scrolling: touch” style"));
+ if (compositingReasons.stacking)
+ addReason(WI.UIString("Element may overlap another compositing element"));
+ if (compositingReasons.overlap)
+ addReason(WI.UIString("Element overlaps other compositing element"));
+ if (compositingReasons.negativeZIndexChildren)
+ addReason(WI.UIString("Element has children with a negative z-index"));
+ if (compositingReasons.transformWithCompositedDescendants)
+ addReason(WI.UIString("Element has a 2D transform and composited descendants"));
+ if (compositingReasons.opacityWithCompositedDescendants)
+ addReason(WI.UIString("Element has opacity applied and composited descendants"));
+ if (compositingReasons.maskWithCompositedDescendants)
+ addReason(WI.UIString("Element is masked and composited descendants"));
+ if (compositingReasons.reflectionWithCompositedDescendants)
+ addReason(WI.UIString("Element has a reflection and composited descendants"));
+ if (compositingReasons.filterWithCompositedDescendants)
+ addReason(WI.UIString("Element has CSS filters applied and composited descendants"));
+ if (compositingReasons.blendingWithCompositedDescendants)
+ addReason(WI.UIString("Element has CSS blending applied and composited descendants"));
+ if (compositingReasons.isolatesCompositedBlendingDescendants)
+ addReason(WI.UIString("Element is a stacking context and has composited descendants with CSS blending applied"));
+ if (compositingReasons.perspective)
+ addReason(WI.UIString("Element has perspective applied"));
+ if (compositingReasons.preserve3D)
+ addReason(WI.UIString("Element has “transform-style: preserve-3d” style"));
+ if (compositingReasons.willChange)
+ addReason(WI.UIString("Element has “will-change” style with includes opacity, transform, transform-style, perspective, filter or backdrop-filter"));
+ if (compositingReasons.root)
+ addReason(WI.UIString("Element is the root element"));
+ if (compositingReasons.blending)
+ addReason(WI.UIString("Element has “blend-mode” style"));
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/Layers3DContentView.js (222341 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Views/Layers3DContentView.js 2017-09-21 20:16:52 UTC (rev 222341)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/Layers3DContentView.js 2017-09-21 20:18:01 UTC (rev 222342)
@@ -33,6 +33,7 @@
WI.layerTreeManager.addEventListener(WI.LayerTreeManager.Event.LayerTreeDidChange, this._layerTreeDidChange, this);
+ this._layers = [];
this._layersChangedWhileHidden = false;
this._renderer = null;
this._camera = null;
@@ -45,6 +46,11 @@
// Public
+ get supplementalRepresentedObjects()
+ {
+ return this._layers;
+ }
+
shown()
{
super.shown();
@@ -117,6 +123,9 @@
this._clearLayers();
for (let i = 0; i < childLayers.length; i++)
this._addLayer(childLayers[i], i);
+
+ this._layers = childLayers;
+ this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
});
});
}
@@ -165,15 +174,8 @@
_addLayer(layer, index)
{
- let compositedBounds = {
- x: layer.bounds.x,
- y: layer.bounds.y,
- width: layer.compositedBounds.width,
- height: layer.compositedBounds.height,
- };
-
this._boundsGroup.add(this._createLayerMesh(layer.bounds, index));
- this._compositedBoundsGroup.add(this._createLayerMesh(compositedBounds, index, true));
+ this._compositedBoundsGroup.add(this._createLayerMesh(layer.compositedBounds, index, true));
}
_createLayerMesh(rect, index, isOutline = false)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LayersTabContentView.js (222341 => 222342)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LayersTabContentView.js 2017-09-21 20:16:52 UTC (rev 222341)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayersTabContentView.js 2017-09-21 20:18:01 UTC (rev 222342)
@@ -31,7 +31,7 @@
let tabBarItem = new WI.GeneralTabBarItem(image, title);
const navigationSidebarPanelConstructor = null;
- const detailsSidebarPanelConstructors = null;
+ const detailsSidebarPanelConstructors = [WI.LayerDetailsSidebarPanel];
const disableBackForward = true;
super("layers", "layers", tabBarItem, navigationSidebarPanelConstructor, detailsSidebarPanelConstructors, disableBackForward);