Changeset 160198 in webkit


Ignore:
Timestamp:
Dec 5, 2013 3:37:08 PM (10 years ago)
Author:
Alexandru Chiculita
Message:

Web Inspector: [CSS Regions] Show a list of containing regions when clicking a node that is part of a flow
https://bugs.webkit.org/show_bug.cgi?id=124614

Reviewed by Timothy Hatcher.

Source/WebInspectorUI:

Added a new function in DOMTreeManager called getNodeContentFlowInfo that can be used
to retrieve an object with the following structure:
{

"regionFlow": <Reference to the ContentFlow object referenced by the -webkit-flow-from property of the node>,
"contentFlow": <Reference to the ContentFlow object referenced by the -webkit-flow-into property of

the node or a parent of the node>,

"regions": [ list of DOMNodes representing the regions containers of the node. The node is split across all these regions. ]

}

Also, used this method to display a two new sections in the Computed Styles panel.

  1. Section "Flows": can have up to two Simple Rows: "Region Flow" and "Content Flow".
  2. Section "Container Regions" contains a DOMTreeDataGrid with the list of regions.

The sections are only visible when there's content to display.

Next to the "Region Flow" simple row I've added an arrow that will take the user to the "ContentFlowDOMTreeContentView" of the
ContentFlow. The same happens for the "Content Flow", but in this case the element will also be highlighted.

Part of the patch I've added the DOMTreeDataGridNode. LayerTreeDataGrid has a lot of CSS in common with it, so I
will make another patch to refactor LayerTreeDataGrid to use DOMTreeDataGridNode as a base class.

  • Localizations/en.lproj/localizedStrings.js:
  • UserInterface/ComputedStyleDetailsPanel.css: Added.

(.details-section > .content > .group > .row.simple.content-flow-link > .label):
(.details-section > .content > .group > .row.simple.content-flow-link > .value):
(.details-section > .content > .group > .row.simple.content-flow-link > .value > div):
(.details-section > .content > .group > .row.simple.content-flow-link > .value > div > .icon):
(.details-section > .content > .group > .row.simple.content-flow-link > .value > div > span):
(.details-section > .content > .group > .row.simple.content-flow-link > .value > div > .go-to-arrow):
(.details-section > .content > .group > .row.simple.content-flow-link:hover > .value > div > .go-to-arrow):

  • UserInterface/ComputedStyleDetailsPanel.js:

(WebInspector.ComputedStyleDetailsPanel):
(WebInspector.ComputedStyleDetailsPanel.prototype.get regionFlow):
(WebInspector.ComputedStyleDetailsPanel.prototype.set regionFlow):
(WebInspector.ComputedStyleDetailsPanel.prototype.get contentFlow):
(WebInspector.ComputedStyleDetailsPanel.prototype.set contentFlow):
(WebInspector.ComputedStyleDetailsPanel.prototype.get containerRegions):
(WebInspector.ComputedStyleDetailsPanel.prototype.set containerRegions):
(WebInspector.ComputedStyleDetailsPanel.prototype.refresh):
(WebInspector.ComputedStyleDetailsPanel.prototype._computedStyleShowAllCheckboxValueChanged):
(WebInspector.ComputedStyleDetailsPanel.prototype._resetFlowDetails):
(WebInspector.ComputedStyleDetailsPanel.prototype._refreshFlowDetails.contentFlowInfoReady):
(WebInspector.ComputedStyleDetailsPanel.prototype._refreshFlowDetails):
(WebInspector.ComputedStyleDetailsPanel.prototype._goToRegionFlowArrowWasClicked):
(WebInspector.ComputedStyleDetailsPanel.prototype._goToContentFlowArrowWasClicked):

  • UserInterface/DOMTreeDataGrid.css: Added.

(.dom-tree-data-grid .data-grid):
(.dom-tree-data-grid .data-grid table.data):
(.dom-tree-data-grid .data-container):
(.dom-tree-data-grid .data-container tr):
(.dom-tree-data-grid .data-container td > div):
(.dom-tree-data-grid .data-container .name-column):
(.dom-tree-data-grid .data-container .name-column .icon):
(.dom-tree-data-grid .data-container .name-column .label):
(.dom-tree-data-grid .data-container tr:hover .name-column .label):
(.dom-tree-data-grid .data-container .go-to-arrow):
(.dom-tree-data-grid .data-container tr:hover .go-to-arrow):
(.dom-tree-data-grid .data-container tbody > tr:nth-child(2n)):
(.dom-tree-data-grid .data-container tbody > tr:nth-child(2n+1)):

  • UserInterface/DOMTreeDataGrid.js: Added.

(WebInspector.DOMTreeDataGrid):
(WebInspector.DOMTreeDataGrid.prototype._onmousemove):
(WebInspector.DOMTreeDataGrid.prototype._onmouseout):

  • UserInterface/DOMTreeDataGridNode.js: Added.

(WebInspector.DOMTreeDataGridNode):
(WebInspector.DOMTreeDataGridNode.prototype.get domNode):
(WebInspector.DOMTreeDataGridNode.prototype.createCellContent):
(WebInspector.DOMTreeDataGridNode.prototype._updateNodeName):
(WebInspector.DOMTreeDataGridNode.prototype._makeNameCell):
(WebInspector.DOMTreeDataGridNode.prototype._updateNameCellData):
(WebInspector.DOMTreeDataGridNode.prototype._goToArrowWasClicked):

  • UserInterface/DOMTreeManager.js:

(WebInspector.DOMTreeManager.prototype.unregisteredNamedFlowContentElement):
(WebInspector.DOMTreeManager.prototype.nodeRequested):
(WebInspector.DOMTreeManager.prototype._coerceRemoteArrayOfDOMNodes):
(WebInspector.DOMTreeManager.prototype.domNodeResolved):
(WebInspector.DOMTreeManager.prototype.regionNodesAvailable):
(WebInspector.DOMTreeManager.prototype.get if):
(WebInspector.DOMTreeManager.prototype.get var):
(WebInspector.DOMTreeManager.prototype.backendFunction.getComputedProperty):
(WebInspector.DOMTreeManager.prototype.backendFunction.getContentFlowName):
(WebInspector.DOMTreeManager.prototype.):

  • UserInterface/DataGrid.css:

(.data-grid.no-header > table.header):
(.data-grid.no-header .data-container):

  • UserInterface/DetailsSection.js:

(WebInspector.DetailsSection):

  • UserInterface/InspectorBackend.js:

(InspectorBackendClass.prototype._wrap):

  • UserInterface/Main.html:
  • UserInterface/ResourceSidebarPanel.js:

(WebInspector.ResourceSidebarPanel.prototype.showContentFlowDOMTree):

  • UserInterface/RuntimeManager.js:

(WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow):
(WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject):

LayoutTests:

Added a new test to check the new WebInspector function called DOMTreeManager.getNodeContentFlowInfo.

  • http/tests/inspector-protocol/resources/InspectorTest.js:

When testing the inspector code, we want to catch and log any uncaught exceptions or console.errors/asserts.
(InspectorTest.importInspectorScripts.console.error.window.onerror):
(InspectorTest.importInspectorScripts.console.assert):
(InspectorTest.importInspectorScripts):

  • inspector-protocol/model/content-node-region-info-expected.txt: Added.
  • inspector-protocol/model/content-node-region-info.html: Added.
Location:
trunk
Files:
6 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r160185 r160198  
     12013-12-05  Alexandru Chiculita  <achicu@adobe.com>
     2
     3        Web Inspector: [CSS Regions] Show a list of containing regions when clicking a node that is part of a flow
     4        https://bugs.webkit.org/show_bug.cgi?id=124614
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Added a new test to check the new WebInspector function called DOMTreeManager.getNodeContentFlowInfo.
     9
     10        * http/tests/inspector-protocol/resources/InspectorTest.js:
     11        When testing the inspector code, we want to catch and log any uncaught exceptions or console.errors/asserts.
     12        (InspectorTest.importInspectorScripts.console.error.window.onerror):
     13        (InspectorTest.importInspectorScripts.console.assert):
     14        (InspectorTest.importInspectorScripts):
     15        * inspector-protocol/model/content-node-region-info-expected.txt: Added.
     16        * inspector-protocol/model/content-node-region-info.html: Added.
     17
    1182013-12-05  Zoltan Horvath  <zoltan@webkit.org>
    219
  • trunk/LayoutTests/http/tests/inspector-protocol/resources/InspectorTest.js

    r159357 r160198  
    154154InspectorTest.importInspectorScripts = function()
    155155{
     156    // Catch any errors and finish the test early.
     157    console.error = window.onerror = function()
     158    {
     159        console.log(Array.prototype.join.call(arguments, ', '));
     160        InspectorTest.completeTest();
     161    };
     162
     163    console.assert = function(assertion, message)
     164    {
     165        if (assertion)
     166            return;
     167        console.log("ASSERT:" + message);
     168        InspectorTest.completeTest();
     169    };
     170
    156171    // Note: This function overwrites the InspectorFrontendAPI, so there's currently no
    157172    // way to intercept the messages from the backend.
     
    183198        "ContentFlow",
    184199        "DOMTree",
     200        "DOMUtilities",
    185201        "ExecutionContext",
    186202        "ExecutionContextList",
    187203        "CSSStyleManager",
    188         "Color"
     204        "Color",
     205        "RuntimeObserver",
     206        "RuntimeManager"
    189207    ];
    190208    for (var i = 0; i < inspectorScripts.length; ++i)
     
    198216    InspectorBackend.registerDOMDispatcher(new WebInspector.DOMObserver);
    199217    InspectorBackend.registerCSSDispatcher(new WebInspector.CSSObserver);
     218    if (InspectorBackend.registerRuntimeDispatcher)
     219        InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
    200220
    201221    WebInspector.frameResourceManager = new WebInspector.FrameResourceManager;
    202222    WebInspector.domTreeManager = new WebInspector.DOMTreeManager;
    203223    WebInspector.cssStyleManager = new WebInspector.CSSStyleManager;
     224    WebInspector.runtimeManager = new WebInspector.RuntimeManager;
    204225
    205226    InspectorFrontendHost.loaded();
  • trunk/Source/WebInspectorUI/ChangeLog

    r160145 r160198  
     12013-12-05  Alexandru Chiculita  <achicu@adobe.com>
     2
     3        Web Inspector: [CSS Regions] Show a list of containing regions when clicking a node that is part of a flow
     4        https://bugs.webkit.org/show_bug.cgi?id=124614
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Added a new function in DOMTreeManager called getNodeContentFlowInfo that can be used
     9        to retrieve an object with the following structure:
     10        {
     11             "regionFlow": <Reference to the ContentFlow object referenced by the -webkit-flow-from property of the node>,
     12             "contentFlow": <Reference to the ContentFlow object referenced by the -webkit-flow-into property of
     13                             the node or a parent of the node>,
     14             "regions": [ list of DOMNodes representing the regions containers of the node. The node is split across all these regions. ]
     15        }
     16
     17        Also, used this method to display a two new sections in the Computed Styles panel.
     18        1. Section "Flows": can have up to two Simple Rows: "Region Flow" and "Content Flow".
     19        2. Section "Container Regions" contains a DOMTreeDataGrid with the list of regions.
     20
     21        The sections are only visible when there's content to display.
     22
     23        Next to the "Region Flow" simple row I've added an arrow that will take the user to the "ContentFlowDOMTreeContentView" of the
     24        ContentFlow. The same happens for the "Content Flow", but in this case the element will also be highlighted.
     25
     26        Part of the patch I've added the DOMTreeDataGridNode. LayerTreeDataGrid has a lot of CSS in common with it, so I
     27        will make another patch to refactor LayerTreeDataGrid to use DOMTreeDataGridNode as a base class.
     28
     29        * Localizations/en.lproj/localizedStrings.js:
     30        * UserInterface/ComputedStyleDetailsPanel.css: Added.
     31        (.details-section > .content > .group > .row.simple.content-flow-link > .label):
     32        (.details-section > .content > .group > .row.simple.content-flow-link > .value):
     33        (.details-section > .content > .group > .row.simple.content-flow-link > .value > div):
     34        (.details-section > .content > .group > .row.simple.content-flow-link > .value > div > .icon):
     35        (.details-section > .content > .group > .row.simple.content-flow-link > .value > div > span):
     36        (.details-section > .content > .group > .row.simple.content-flow-link > .value > div > .go-to-arrow):
     37        (.details-section > .content > .group > .row.simple.content-flow-link:hover > .value > div > .go-to-arrow):
     38        * UserInterface/ComputedStyleDetailsPanel.js:
     39        (WebInspector.ComputedStyleDetailsPanel):
     40        (WebInspector.ComputedStyleDetailsPanel.prototype.get regionFlow):
     41        (WebInspector.ComputedStyleDetailsPanel.prototype.set regionFlow):
     42        (WebInspector.ComputedStyleDetailsPanel.prototype.get contentFlow):
     43        (WebInspector.ComputedStyleDetailsPanel.prototype.set contentFlow):
     44        (WebInspector.ComputedStyleDetailsPanel.prototype.get containerRegions):
     45        (WebInspector.ComputedStyleDetailsPanel.prototype.set containerRegions):
     46        (WebInspector.ComputedStyleDetailsPanel.prototype.refresh):
     47        (WebInspector.ComputedStyleDetailsPanel.prototype._computedStyleShowAllCheckboxValueChanged):
     48        (WebInspector.ComputedStyleDetailsPanel.prototype._resetFlowDetails):
     49        (WebInspector.ComputedStyleDetailsPanel.prototype._refreshFlowDetails.contentFlowInfoReady):
     50        (WebInspector.ComputedStyleDetailsPanel.prototype._refreshFlowDetails):
     51        (WebInspector.ComputedStyleDetailsPanel.prototype._goToRegionFlowArrowWasClicked):
     52        (WebInspector.ComputedStyleDetailsPanel.prototype._goToContentFlowArrowWasClicked):
     53        * UserInterface/DOMTreeDataGrid.css: Added.
     54        (.dom-tree-data-grid .data-grid):
     55        (.dom-tree-data-grid .data-grid table.data):
     56        (.dom-tree-data-grid .data-container):
     57        (.dom-tree-data-grid .data-container tr):
     58        (.dom-tree-data-grid .data-container td > div):
     59        (.dom-tree-data-grid .data-container .name-column):
     60        (.dom-tree-data-grid .data-container .name-column .icon):
     61        (.dom-tree-data-grid .data-container .name-column .label):
     62        (.dom-tree-data-grid .data-container tr:hover .name-column .label):
     63        (.dom-tree-data-grid .data-container .go-to-arrow):
     64        (.dom-tree-data-grid .data-container tr:hover .go-to-arrow):
     65        (.dom-tree-data-grid .data-container tbody > tr:nth-child(2n)):
     66        (.dom-tree-data-grid .data-container tbody > tr:nth-child(2n+1)):
     67        * UserInterface/DOMTreeDataGrid.js: Added.
     68        (WebInspector.DOMTreeDataGrid):
     69        (WebInspector.DOMTreeDataGrid.prototype._onmousemove):
     70        (WebInspector.DOMTreeDataGrid.prototype._onmouseout):
     71        * UserInterface/DOMTreeDataGridNode.js: Added.
     72        (WebInspector.DOMTreeDataGridNode):
     73        (WebInspector.DOMTreeDataGridNode.prototype.get domNode):
     74        (WebInspector.DOMTreeDataGridNode.prototype.createCellContent):
     75        (WebInspector.DOMTreeDataGridNode.prototype._updateNodeName):
     76        (WebInspector.DOMTreeDataGridNode.prototype._makeNameCell):
     77        (WebInspector.DOMTreeDataGridNode.prototype._updateNameCellData):
     78        (WebInspector.DOMTreeDataGridNode.prototype._goToArrowWasClicked):
     79        * UserInterface/DOMTreeManager.js:
     80        (WebInspector.DOMTreeManager.prototype.unregisteredNamedFlowContentElement):
     81        (WebInspector.DOMTreeManager.prototype.nodeRequested):
     82        (WebInspector.DOMTreeManager.prototype._coerceRemoteArrayOfDOMNodes):
     83        (WebInspector.DOMTreeManager.prototype.domNodeResolved):
     84        (WebInspector.DOMTreeManager.prototype.regionNodesAvailable):
     85        (WebInspector.DOMTreeManager.prototype.get if):
     86        (WebInspector.DOMTreeManager.prototype.get var):
     87        (WebInspector.DOMTreeManager.prototype.backendFunction.getComputedProperty):
     88        (WebInspector.DOMTreeManager.prototype.backendFunction.getContentFlowName):
     89        (WebInspector.DOMTreeManager.prototype.):
     90        * UserInterface/DataGrid.css:
     91        (.data-grid.no-header > table.header):
     92        (.data-grid.no-header .data-container):
     93        * UserInterface/DetailsSection.js:
     94        (WebInspector.DetailsSection):
     95        * UserInterface/InspectorBackend.js:
     96        (InspectorBackendClass.prototype._wrap):
     97        * UserInterface/Main.html:
     98        * UserInterface/ResourceSidebarPanel.js:
     99        (WebInspector.ResourceSidebarPanel.prototype.showContentFlowDOMTree):
     100        * UserInterface/RuntimeManager.js:
     101        (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow):
     102        (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject):
     103
    11042013-12-04  Antoine Quint  <graouts@apple.com>
    2105
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r159467 r160198  
    9494localizedStrings["Console logs, click to show the Console"] = "Console logs, click to show the Console";
    9595localizedStrings["Console warnings, click to show the Console"] = "Console warnings, click to show the Console";
     96localizedStrings["Container Regions"] = "Container Regions";
    9697localizedStrings["Content"] = "Content";
     98localizedStrings["Content Flow"] = "Content Flow";
    9799localizedStrings["Continue script execution (%s or %s)"] = "Continue script execution (%s or %s)";
    98100localizedStrings["Continue to Here"] = "Continue to Here";
     
    308310localizedStrings["Reflection"] = "Reflection";
    309311localizedStrings["Refresh"] = "Refresh";
     312localizedStrings["Region Flow"] = "Region Flow";
    310313localizedStrings["Reload page (%s)\nReload ignoring cache (%s)"] = "Reload page (%s)\nReload ignoring cache (%s)";
    311314localizedStrings["Remove this breakpoint action"] = "Remove this breakpoint action";
  • trunk/Source/WebInspectorUI/UserInterface/ComputedStyleDetailsPanel.js

    r151453 r160198  
    5050    propertiesRow.element.appendChild(this._propertiesTextEditor.element);
    5151
     52    // Region flow name is used to display the "flow-from" property of the Region Containers.
     53    this._regionFlowFragment = document.createElement("span");
     54    this._regionFlowFragment.appendChild(document.createElement("img")).className = "icon";
     55    this._regionFlowNameLabelValue = this._regionFlowFragment.appendChild(document.createElement("span"));
     56
     57    var goToRegionFlowButton = this._regionFlowFragment.appendChild(WebInspector.createGoToArrowButton());
     58    goToRegionFlowButton.addEventListener("click", this._goToRegionFlowArrowWasClicked.bind(this));
     59
     60    this._regionFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Region Flow"));
     61    this._regionFlowNameRow.element.classList.add("content-flow-link");
     62
     63    // Content flow name is used to display the "flow-into" property of the Content nodes.
     64    this._contentFlowFragment = document.createElement("span");
     65    this._contentFlowFragment.appendChild(document.createElement("img")).className = "icon";
     66    this._contentFlowNameLabelValue = this._contentFlowFragment.appendChild(document.createElement("span"));
     67
     68    var goToContentFlowButton = this._contentFlowFragment.appendChild(WebInspector.createGoToArrowButton());
     69    goToContentFlowButton.addEventListener("click", this._goToContentFlowArrowWasClicked.bind(this));
     70
     71    this._contentFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Content Flow"));
     72    this._contentFlowNameRow.element.classList.add("content-flow-link");
     73
     74    var flowNamesGroup = new WebInspector.DetailsSectionGroup([this._regionFlowNameRow, this._contentFlowNameRow]);
     75    this._flowNamesSection = new WebInspector.DetailsSection("content-flow", WebInspector.UIString("Flows"), [flowNamesGroup]);
     76
     77    this._containerRegionsDataGrid = new WebInspector.DOMTreeDataGrid;
     78    this._containerRegionsDataGrid.element.classList.add("no-header");
     79
     80    var containerRegionsRow = new WebInspector.DetailsSectionDataGridRow(this._containerRegionsDataGrid);
     81    var containerRegionsGroup = new WebInspector.DetailsSectionGroup([containerRegionsRow]);
     82    this._containerRegionsFlowSection = new WebInspector.DetailsSection("container-regions", WebInspector.UIString("Container Regions"), [containerRegionsGroup]);
     83
    5284    this.element.appendChild(propertiesSection.element);
     85    this.element.appendChild(this._flowNamesSection.element);
     86    this.element.appendChild(this._containerRegionsFlowSection.element);
     87
     88    this._resetFlowDetails();
    5389};
    5490
     
    6096    // Public
    6197
     98    get regionFlow()
     99    {
     100        return this._regionFlow;
     101    },
     102
     103    set regionFlow(regionFlow)
     104    {
     105        this._regionFlow = regionFlow;
     106        this._regionFlowNameLabelValue.textContent = regionFlow ? regionFlow.name : "";
     107        this._regionFlowNameRow.value = regionFlow ? this._regionFlowFragment : null;
     108        this._updateFlowNamesSectionVisibility();
     109    },
     110
     111    get contentFlow()
     112    {
     113        return this._contentFlow;
     114    },
     115
     116    set contentFlow(contentFlow)
     117    {
     118        this._contentFlow = contentFlow;
     119        this._contentFlowNameLabelValue.textContent = contentFlow ? contentFlow.name : "";
     120        this._contentFlowNameRow.value = contentFlow ? this._contentFlowFragment : null;
     121        this._updateFlowNamesSectionVisibility();
     122    },
     123
     124    get containerRegions()
     125    {
     126        return this._containerRegions;
     127    },
     128
     129    set containerRegions(regions)
     130    {
     131        this._containerRegions = regions;
     132
     133        if (!regions || !regions.length) {
     134            this._containerRegionsFlowSection.element.classList.add("hidden");
     135            return;
     136        }
     137
     138        this._containerRegionsDataGrid.removeChildren();
     139        for (var regionNode of regions)
     140            this._containerRegionsDataGrid.appendChild(new WebInspector.DOMTreeDataGridNode(regionNode));
     141
     142        this._containerRegionsFlowSection.element.classList.remove("hidden");
     143    },
     144
    62145    refresh: function()
    63146    {
    64147        this._propertiesTextEditor.style = this.nodeStyles.computedStyle;
     148        this._refreshFlowDetails(this.nodeStyles.node);
    65149    },
    66150
     
    86170        this._computedStyleShowAllSetting.value = checked;
    87171        this._propertiesTextEditor.showsImplicitProperties = checked;
     172    },
     173
     174    _updateFlowNamesSectionVisibility: function()
     175    {
     176        this._flowNamesSection.element.classList.toggle("hidden", !this._contentFlow && !this._regionFlow);
     177    },
     178
     179    _resetFlowDetails : function()
     180    {
     181        this.regionFlow = null;
     182        this.contentFlow = null;
     183        this.containerRegions = null;
     184    },
     185
     186    _refreshFlowDetails: function(domNode)
     187    {
     188        this._resetFlowDetails();
     189        if (!domNode)
     190            return;
     191
     192        function contentFlowInfoReady(error, flowData)
     193        {
     194            // Element is not part of any flow.
     195            if (error || !flowData) {
     196                this._resetFlowDetails();
     197                return;
     198            }
     199
     200            this.regionFlow = flowData.regionFlow;
     201            this.contentFlow = flowData.contentFlow;
     202            this.containerRegions = flowData.regions;
     203        }
     204
     205        WebInspector.domTreeManager.getNodeContentFlowInfo(domNode, contentFlowInfoReady.bind(this));
     206    },
     207
     208    _goToRegionFlowArrowWasClicked: function()
     209    {
     210        WebInspector.resourceSidebarPanel.showContentFlowDOMTree(this._regionFlow);
     211    },
     212
     213    _goToContentFlowArrowWasClicked: function()
     214    {
     215        WebInspector.resourceSidebarPanel.showContentFlowDOMTree(this._contentFlow, this.nodeStyles.node, true);
    88216    }
    89217};
  • trunk/Source/WebInspectorUI/UserInterface/DOMTreeManager.js

    r159777 r160198  
    662662        this._contentNodesToFlowsMap.delete(contentNodeId);
    663663        flow.removeContentNode(this.nodeForId(contentNodeId));
     664    },
     665
     666    _coerceRemoteArrayOfDOMNodes: function(objectId, callback)
     667    {
     668        var length, nodes, received = 0, lastError = null, domTreeManager = this;
     669
     670        function nodeRequested(index, error, nodeId)
     671        {
     672            if (error)
     673                lastError = error;
     674            else
     675                nodes[index] = domTreeManager._idToDOMNode[nodeId];
     676            if (++received === length)
     677                callback(lastError, nodes);
     678        }
     679
     680        WebInspector.runtimeManager.getPropertiesForRemoteObject(objectId, function(error, properties) {
     681            if (error) {
     682                callback(error);
     683                return;
     684            }
     685
     686            var lengthProperty = properties.get("length");
     687            if (!lengthProperty || lengthProperty.value.type !== "number") {
     688                callback(null);
     689                return;
     690            }
     691
     692            length = lengthProperty.value.value;
     693            if (!length) {
     694                callback(null, []);
     695                return;
     696            }
     697
     698            nodes = new Array(length);
     699            for (var i = 0; i < length; ++i) {
     700                var nodeProperty = properties.get(String(i));
     701                console.assert(nodeProperty.value.type === "object");
     702                DOMAgent.requestNode(nodeProperty.value.objectId, nodeRequested.bind(null, i));
     703            }
     704        });
     705    },
     706
     707    getNodeContentFlowInfo: function(domNode, resultReadyCallback)
     708    {
     709        DOMAgent.resolveNode(domNode.id, domNodeResolved.bind(this));
     710
     711        function domNodeResolved(error, remoteObject)
     712        {
     713            if (error) {
     714                resultReadyCallback(error);
     715                return;
     716            }
     717            // Serialize "backendFunction" and execute it in the context of the page
     718            // passing the DOMNode as the "this" reference.
     719            var evalParameters = {
     720                objectId: remoteObject.objectId,
     721                functionDeclaration: backendFunction.toString(),
     722                doNotPauseOnExceptionsAndMuteConsole: true,
     723                returnByValue: false,
     724                generatePreview: false
     725            };
     726            RuntimeAgent.callFunctionOn.invoke(evalParameters, regionNodesAvailable.bind(this));
     727        }
     728
     729        function regionNodesAvailable(error, remoteObject, wasThrown)
     730        {
     731            if (error) {
     732                resultReadyCallback(error);
     733                return;
     734            }
     735
     736            if (wasThrown) {
     737                // We should never get here, but having the error is useful for debugging.
     738                console.error("Error while executing backend function:", JSON.stringify(remoteObject));
     739                resultReadyCallback(null);
     740                return;
     741            }
     742
     743            // The backend function can never return null.
     744            console.assert(remoteObject.type === "object");
     745            console.assert(remoteObject.objectId);
     746            WebInspector.runtimeManager.getPropertiesForRemoteObject(remoteObject.objectId, remoteObjectPropertiesAvailable.bind(this));
     747        }
     748
     749        function remoteObjectPropertiesAvailable(error, properties) {
     750            if (error) {
     751                resultReadyCallback(error);
     752                return;
     753            }
     754
     755            var result = {
     756                regionFlow: null,
     757                contentFlow: null,
     758                regions: null
     759            };
     760
     761            var regionFlowNameProperty = properties.get("regionFlowName");
     762            if (regionFlowNameProperty && regionFlowNameProperty.value && regionFlowNameProperty.value.value) {
     763                console.assert(regionFlowNameProperty.value.type === "string");
     764                var regionFlowKey = WebInspector.DOMTreeManager._flowPayloadHashKey({documentNodeId: domNode.ownerDocument.id, name: regionFlowNameProperty.value.value});
     765                result.regionFlow = this._flows.get(regionFlowKey);
     766            }
     767
     768            var contentFlowNameProperty = properties.get("contentFlowName");
     769            if (contentFlowNameProperty && contentFlowNameProperty.value && contentFlowNameProperty.value.value) {
     770                console.assert(contentFlowNameProperty.value.type === "string");
     771                var contentFlowKey = WebInspector.DOMTreeManager._flowPayloadHashKey({documentNodeId: domNode.ownerDocument.id, name: contentFlowNameProperty.value.value});
     772                result.contentFlow = this._flows.get(contentFlowKey);
     773            }
     774
     775            var regionsProperty = properties.get("regions");
     776            if (!regionsProperty || !regionsProperty.value.objectId) {
     777                // The list of regions is null.
     778                resultReadyCallback(null, result);
     779                return;
     780            }
     781
     782            console.assert(regionsProperty.value.type === "object");
     783            console.assert(regionsProperty.value.subtype === "array");
     784            this._coerceRemoteArrayOfDOMNodes(regionsProperty.value.objectId, function(error, nodes) {
     785                result.regions = nodes;
     786                resultReadyCallback(error, result);
     787            });
     788        }
     789
     790        // Note that "backendFunction" is serialized and executed in the context of the page.
     791        function backendFunction()
     792        {
     793            function getComputedProperty(node, propertyName)
     794            {
     795                if (!node.ownerDocument || !node.ownerDocument.defaultView)
     796                    return null;
     797                var computedStyle = node.ownerDocument.defaultView.getComputedStyle(node);
     798                return computedStyle ? computedStyle[propertyName] : null;
     799            }
     800
     801            function getContentFlowName(node)
     802            {
     803                for (; node; node = node.parentNode) {
     804                    var flowName = getComputedProperty(node, "webkitFlowInto");
     805                    if (flowName && flowName !== "none")
     806                        return flowName;
     807                }
     808                return null;
     809            }
     810
     811            var node = this;
     812
     813            // Even detached nodes have an ownerDocument.
     814            console.assert(node.ownerDocument);
     815
     816            var result = {
     817                regionFlowName: getComputedProperty(node, "webkitFlowFrom"),
     818                contentFlowName: getContentFlowName(node),
     819                regions: null
     820            };
     821
     822            if (result.contentFlowName) {
     823                var flowThread = node.ownerDocument.webkitGetNamedFlows().namedItem(result.contentFlowName);
     824                if (flowThread)
     825                    result.regions = flowThread.getRegionsByContent(node);
     826            }
     827
     828            return result;
     829        }
    664830    }
    665831}
  • trunk/Source/WebInspectorUI/UserInterface/DataGrid.css

    r155241 r160198  
    6565}
    6666
     67.data-grid.no-header > table.header {
     68    display: none;
     69}
     70
     71.data-grid.no-header .data-container {
     72    top: 0;
     73}
     74
    6775.data-grid th {
    6876    text-align: left;
  • trunk/Source/WebInspectorUI/UserInterface/DetailsSection.js

    r153894 r160198  
    3131    this._element = document.createElement("div");
    3232    this._element.className = WebInspector.DetailsSection.StyleClassName;
     33    this._element.classList.add(identifier);
    3334
    3435    this._headerElement = document.createElement("div");
  • trunk/Source/WebInspectorUI/UserInterface/InspectorBackend.js

    r155241 r160198  
    5858        if (this.dumpInspectorTimeStats)
    5959            callback.sendRequestTime = Date.now();
    60        
     60
    6161        return callbackId;
    6262    },
  • trunk/Source/WebInspectorUI/UserInterface/Main.html

    r160134 r160198  
    9393    <link rel="stylesheet" href="NetworkTimeline.css">
    9494    <link rel="stylesheet" href="CSSStyleDetailsSidebarPanel.css">
     95    <link rel="stylesheet" href="DOMTreeDataGrid.css">
    9596    <link rel="stylesheet" href="LayerTreeSidebarPanel.css">
    9697    <link rel="stylesheet" href="EventListenerSectionGroup.css">
     
    125126    <link rel="stylesheet" href="GoToLineDialog.css">
    126127    <link rel="stylesheet" href="HoverMenu.css">
     128    <link rel="stylesheet" href="ComputedStyleDetailsPanel.css">
    127129
    128130    <script src="External/CodeMirror/codemirror.js"></script>
     
    307309    <script src="EventListenerSection.js"></script>
    308310    <script src="DOMNodeDetailsSidebarPanel.js"></script>
     311    <script src="DOMTreeDataGrid.js"></script>
     312    <script src="DOMTreeDataGridNode.js"></script>
    309313    <script src="LayerTreeDataGridNode.js"></script>
    310314    <script src="LayerTreeDataGrid.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/ResourceSidebarPanel.js

    r158879 r160198  
    113113    },
    114114
     115    showContentFlowDOMTree: function(contentFlow, nodeToSelect, preventFocusChange)
     116    {
     117        var contentView = WebInspector.contentBrowser.contentViewForRepresentedObject(contentFlow);
     118        if (nodeToSelect)
     119            contentView.selectAndRevealDOMNode(nodeToSelect, preventFocusChange);
     120        WebInspector.contentBrowser.showContentView(contentView);
     121    },
     122
    115123    showSourceCodeForFrame: function(frameIdentifier, revealAndSelectTreeElement)
    116124    {
  • trunk/Source/WebInspectorUI/UserInterface/RuntimeManager.js

    r155134 r160198  
    6868        var contextId = WebInspector.quickConsole.executionContextIdentifier;
    6969        RuntimeAgent.evaluate.invoke({expression: expression, objectGroup: objectGroup, includeCommandLineAPI: includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole: doNotPauseOnExceptionsAndMuteConsole, contextId: contextId, frameId: contextId, returnByValue: returnByValue}, evalCallback);
     70    },
     71
     72    getPropertiesForRemoteObject: function(objectId, callback)
     73    {
     74        RuntimeAgent.getProperties(objectId, function(error, result) {
     75            if (error) {
     76                callback(error);
     77                return;
     78            }
     79
     80            var properties = new Map;
     81            for (var property of result)
     82                properties.set(property.name, property);
     83
     84            callback(null, properties);
     85        });
    7086    }
    7187};
Note: See TracChangeset for help on using the changeset viewer.