Web Inspector: Display Named Flows in the Tabbed Pane of the "CSS Named Flows" Drawer
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Sep 2012 18:13:04 +0000 (18:13 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Sep 2012 18:13:04 +0000 (18:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=96733

Patch by Andrei Poenaru <poenaru@adobe.com> on 2012-09-17
Reviewed by Alexander Pavlov.

Added functionality to the Tabbed Pane from the CSS Named Flows Drawer.

* English.lproj/localizedStrings.js:
* WebCore.gypi:
* WebCore.vcproj/WebCore.vcproj:
* inspector/compile-front-end.py:
* inspector/front-end/CSSNamedFlowCollectionsView.js:
(WebInspector.CSSNamedFlowCollectionsView.prototype._appendNamedFlow):
(WebInspector.CSSNamedFlowCollectionsView.prototype._removeNamedFlow):
(WebInspector.CSSNamedFlowCollectionsView.prototype._updateNamedFlow):
(WebInspector.CSSNamedFlowCollectionsView.prototype._showNamedFlow):
(WebInspector.CSSNamedFlowCollectionsView.prototype._selectNamedFlowInSidebar):
(WebInspector.CSSNamedFlowCollectionsView.prototype._selectNamedFlowTab):
(WebInspector.CSSNamedFlowCollectionsView.prototype._tabSelected):
(WebInspector.CSSNamedFlowCollectionsView.prototype._tabClosed):
(WebInspector.CSSNamedFlowCollectionsView.prototype.wasShown):
(WebInspector.CSSNamedFlowCollectionsView.prototype.willHide):
(WebInspector.FlowTreeElement):
(WebInspector.FlowTreeElement.prototype.setOverset):
* inspector/front-end/CSSNamedFlowView.js: Added.
(WebInspector.CSSNamedFlowView):
(WebInspector.CSSNamedFlowView.prototype._createFlowTreeOutline):
(WebInspector.CSSNamedFlowView.prototype._insertContentNode):
(WebInspector.CSSNamedFlowView.prototype._insertRegion):
(WebInspector.CSSNamedFlowView.prototype.get flow):
(WebInspector.CSSNamedFlowView.prototype.set flow):
(WebInspector.CSSNamedFlowView.prototype._updateRegionOverset):
(WebInspector.CSSNamedFlowView.prototype._mergeContentNodes):
(WebInspector.CSSNamedFlowView.prototype._mergeRegions):
(WebInspector.CSSNamedFlowView.prototype._update):
* inspector/front-end/ElementsPanel.js:
* inspector/front-end/Images/regionEmpty.png: Added.
* inspector/front-end/Images/regionFit.png: Added.
* inspector/front-end/Images/regionOverset.png: Added.
* inspector/front-end/WebKit.qrc:
* inspector/front-end/cssNamedFlows.css:
(.css-named-flow-collections-view .split-view-sidebar-left .named-flow-overflow::before, .css-named-flow-collections-view .region-empty:before, .css-named-flow-collections-view .region-fit::before, .css-named-flow-collections-view .region-overset::before):
(.css-named-flow-collections-view .split-view-sidebar-left .named-flow-overflow::before):
(.css-named-flow-collections-view .region-empty::before):
(.css-named-flow-collections-view .region-fit::before):
(.css-named-flow-collections-view .region-overset::before):
(.css-named-flow-collections-view .split-view-contents .named-flow-element):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@128778 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/English.lproj/localizedStrings.js
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/inspector/compile-front-end.py
Source/WebCore/inspector/front-end/CSSNamedFlowCollectionsView.js
Source/WebCore/inspector/front-end/CSSNamedFlowView.js [new file with mode: 0644]
Source/WebCore/inspector/front-end/ElementsPanel.js
Source/WebCore/inspector/front-end/Images/regionEmpty.png [new file with mode: 0644]
Source/WebCore/inspector/front-end/Images/regionFit.png [new file with mode: 0644]
Source/WebCore/inspector/front-end/Images/regionOverset.png [new file with mode: 0644]
Source/WebCore/inspector/front-end/WebKit.qrc
Source/WebCore/inspector/front-end/cssNamedFlows.css

index 7bd61b2..c8e7bd8 100644 (file)
@@ -1,3 +1,53 @@
+2012-09-17  Andrei Poenaru  <poenaru@adobe.com>
+
+        Web Inspector: Display Named Flows in the Tabbed Pane of the "CSS Named Flows" Drawer
+        https://bugs.webkit.org/show_bug.cgi?id=96733
+
+        Reviewed by Alexander Pavlov.
+
+        Added functionality to the Tabbed Pane from the CSS Named Flows Drawer.
+
+        * English.lproj/localizedStrings.js:
+        * WebCore.gypi:
+        * WebCore.vcproj/WebCore.vcproj:
+        * inspector/compile-front-end.py:
+        * inspector/front-end/CSSNamedFlowCollectionsView.js:
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._appendNamedFlow):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._removeNamedFlow):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._updateNamedFlow):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._showNamedFlow):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._selectNamedFlowInSidebar):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._selectNamedFlowTab):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._tabSelected):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype._tabClosed):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype.wasShown):
+        (WebInspector.CSSNamedFlowCollectionsView.prototype.willHide):
+        (WebInspector.FlowTreeElement):
+        (WebInspector.FlowTreeElement.prototype.setOverset):
+        * inspector/front-end/CSSNamedFlowView.js: Added.
+        (WebInspector.CSSNamedFlowView):
+        (WebInspector.CSSNamedFlowView.prototype._createFlowTreeOutline):
+        (WebInspector.CSSNamedFlowView.prototype._insertContentNode):
+        (WebInspector.CSSNamedFlowView.prototype._insertRegion):
+        (WebInspector.CSSNamedFlowView.prototype.get flow):
+        (WebInspector.CSSNamedFlowView.prototype.set flow):
+        (WebInspector.CSSNamedFlowView.prototype._updateRegionOverset):
+        (WebInspector.CSSNamedFlowView.prototype._mergeContentNodes):
+        (WebInspector.CSSNamedFlowView.prototype._mergeRegions):
+        (WebInspector.CSSNamedFlowView.prototype._update):
+        * inspector/front-end/ElementsPanel.js:
+        * inspector/front-end/Images/regionEmpty.png: Added.
+        * inspector/front-end/Images/regionFit.png: Added.
+        * inspector/front-end/Images/regionOverset.png: Added.
+        * inspector/front-end/WebKit.qrc:
+        * inspector/front-end/cssNamedFlows.css:
+        (.css-named-flow-collections-view .split-view-sidebar-left .named-flow-overflow::before, .css-named-flow-collections-view .region-empty:before, .css-named-flow-collections-view .region-fit::before, .css-named-flow-collections-view .region-overset::before):
+        (.css-named-flow-collections-view .split-view-sidebar-left .named-flow-overflow::before):
+        (.css-named-flow-collections-view .region-empty::before):
+        (.css-named-flow-collections-view .region-fit::before):
+        (.css-named-flow-collections-view .region-overset::before):
+        (.css-named-flow-collections-view .split-view-contents .named-flow-element):
+
 2012-09-17  Zan Dobersek  <zandobersek@gmail.com>
 
         [Gtk] Remove configuration options for stable features that are currently enabled
index eb787f2..fad1f2a 100644 (file)
@@ -334,6 +334,7 @@ localizedStrings["Record"] = "Record";
 localizedStrings["Recording…"] = "Recording…";
 localizedStrings["Redirect"] = "Redirect";
 localizedStrings["Refresh"] = "Refresh";
+localizedStrings["Region is %s."] = "Region is %s.";
 localizedStrings["Remove Breakpoint"] = "Remove Breakpoint";
 localizedStrings["Remove breakpoint"] = "Remove breakpoint";
 localizedStrings["Remove Timer"] = "Remove Timer";
@@ -468,12 +469,16 @@ localizedStrings["\xb1 Size"] = "\xb1 Size";
 localizedStrings["border"] = "border";
 localizedStrings["content"] = "content";
 localizedStrings["deleted"] = "deleted";
+localizedStrings["empty"] = "empty";
+localizedStrings["fit"] = "fit";
 localizedStrings["line %d"] = "line %d";
 localizedStrings["margin"] = "margin";
 localizedStrings["new"] = "new";
 localizedStrings["or"] = "or";
+localizedStrings["overset"] = "overset";
 localizedStrings["padding"] = "padding";
 localizedStrings["position"] = "position";
+localizedStrings["region chain"] = "region chain";
 localizedStrings["user agent stylesheet"] = "user agent stylesheet";
 localizedStrings["user stylesheet"] = "user stylesheet";
 localizedStrings["via inspector"] = "via inspector";
index 4085311..d2913d9 100644 (file)
         ],
         'webinspector_elements_js_files': [
             'inspector/front-end/CSSNamedFlowCollectionsView.js',
+            'inspector/front-end/CSSNamedFlowView.js',
             'inspector/front-end/ElementsPanel.js',
             'inspector/front-end/EventListenersSidebarPane.js',
             'inspector/front-end/MetricsSidebarPane.js',
             'inspector/front-end/Images/profilesSilhouette.png',
             'inspector/front-end/Images/programCounterBorder.png',
             'inspector/front-end/Images/radioDot.png',
+            'inspector/front-end/Images/regionEmpty.png',
+            'inspector/front-end/Images/regionFit.png',
+            'inspector/front-end/Images/regionOverset.png',
             'inspector/front-end/Images/resourceCSSIcon.png',
             'inspector/front-end/Images/resourceDocumentIcon.png',
             'inspector/front-end/Images/resourceDocumentIconSmall.png',
index 06274b9..6de881b 100755 (executable)
                                        >
                                </File>
                                <File
+                                       RelativePath="..\inspector\front-end\CSSNamedFlowView.js"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\inspector\front-end\cssNamedFlows.css"
                                        >
                                </File>
index ef235bf..03eaeee 100755 (executable)
@@ -180,6 +180,7 @@ modules = [
         "dependencies": ["components"],
         "sources": [
             "CSSNamedFlowCollectionsView.js",
+            "CSSNamedFlowView.js",
             "ElementsPanel.js",
             "ElementsPanelDescriptor.js",
             "EventListenersSidebarPane.js",
index b6be9e7..239c507 100644 (file)
@@ -128,20 +128,15 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
         for (var i = 0; i < flow.regions.length; ++i)
             this._regionNodes[flow.regions[i].nodeId] = flowHash;
 
-        var container = document.createElement("div");
-        container.createChild("div", "selection");
-        container.createChild("span", "title").createChild("span").textContent = flow.name;
+        var flowTreeItem = new WebInspector.FlowTreeElement(flowContainer);
+        flowTreeItem.onselect = this._selectNamedFlowTab.bind(this, flowHash);
 
-        var flowTreeElement = new TreeElement(container, flowContainer);
-        if (flow.overset)
-            flowTreeElement.title.addStyleClass("named-flow-overflow")
-
-        flowContainer.flowTreeElement = flowTreeElement;
+        flowContainer.flowTreeItem = flowTreeItem;
         this._namedFlows[flowHash] = flowContainer;
 
         if (!this._flowTree.children.length)
             this._setSidebarHasContent(true);
-        this._flowTree.appendChild(flowTreeElement);
+        this._flowTree.appendChild(flowTreeItem);
     },
 
     /**
@@ -151,7 +146,9 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
     {
         var flowContainer = this._namedFlows[flowHash];
 
-        this._flowTree.removeChild(flowContainer.flowTreeElement);
+        if (this._tabbedPane._tabsById[flowHash])
+            this._tabbedPane.closeTab(flowHash);
+        this._flowTree.removeChild(flowContainer.flowTreeItem);
 
         var flow = flowContainer.flow;
         for (var i = 0; i < flow.content.length; ++i)
@@ -189,12 +186,10 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
         for (var i = 0; i < flow.regions.length; ++i)
             this._regionNodes[flow.regions[i].nodeId] = flowHash;
 
-        if (flow.overset !== oldFlow.overset) {
-            if (flow.overset)
-                flowContainer.flowTreeElement.title.addStyleClass("named-flow-overflow");
-            else
-                flowContainer.flowTreeElement.title.removeStyleClass("named-flow-overflow");
-        }
+        flowContainer.flowTreeItem.setOverset(flow.overset);
+
+        if (flowContainer.flowView)
+            flowContainer.flowView.flow = flow;
     },
 
     /**
@@ -268,6 +263,7 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
     _showNamedFlow: function(flowHash)
     {
         this._selectNamedFlowInSidebar(flowHash);
+        this._selectNamedFlowTab(flowHash);
     },
 
     /**
@@ -275,7 +271,26 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
      */
     _selectNamedFlowInSidebar: function(flowHash)
     {
-        this._namedFlows[flowHash].flowTreeElement.select(true);
+        this._namedFlows[flowHash].flowTreeItem.select(true);
+    },
+
+    /**
+     * @param {string} flowHash
+     */
+    _selectNamedFlowTab: function(flowHash)
+    {
+        var flowContainer = this._namedFlows[flowHash];
+
+        if (this._tabbedPane.selectedTabId === flowHash)
+            return;
+
+        if (!this._tabbedPane.selectTab(flowHash)) {
+            if (!flowContainer.flowView)
+                flowContainer.flowView = new WebInspector.CSSNamedFlowView(flowContainer.flow);
+
+            this._tabbedPane.appendTab(flowHash, flowContainer.flow.name, flowContainer.flowView);
+            this._tabbedPane.selectTab(flowHash);
+        }
     },
 
     /**
@@ -288,6 +303,22 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
     },
 
     /**
+     * @param {WebInspector.Event} event
+     */
+    _tabSelected: function(event)
+    {
+        this._selectNamedFlowInSidebar(event.data.tabId);
+    },
+
+    /**
+     * @param {WebInspector.Event} event
+     */
+    _tabClosed: function(event)
+    {
+        this._namedFlows[event.data.tabId].flowTreeItem.deselect();
+    },
+
+    /**
      * @param {?WebInspector.DOMNode} node
      */
     _showNamedFlowForNode: function(node)
@@ -323,6 +354,9 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
         WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
 
         WebInspector.panel("elements").treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
+
+        this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
+        this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
     },
 
     willHide: function()
@@ -334,7 +368,49 @@ WebInspector.CSSNamedFlowCollectionsView.prototype = {
         WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
 
         WebInspector.panel("elements").treeOutline.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
+
+        this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
+        this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
     }
 }
 
 WebInspector.CSSNamedFlowCollectionsView.prototype.__proto__ = WebInspector.SplitView.prototype;
+
+/**
+ * @constructor
+ * @extends {TreeElement}
+ */
+WebInspector.FlowTreeElement = function(flowContainer)
+{
+    var container = document.createElement("div");
+    container.createChild("div", "selection");
+    container.createChild("span", "title").createChild("span").textContent = flowContainer.flow.name;
+
+    TreeElement.call(this, container, flowContainer, false);
+
+    this._overset = false;
+    this.setOverset(flowContainer.flow.overset);
+}
+
+WebInspector.FlowTreeElement.prototype = {
+    /**
+     * @param {boolean} newOverset
+     */
+    setOverset: function(newOverset)
+    {
+        if (this._overset === newOverset)
+            return;
+
+        if (newOverset) {
+            this.title.addStyleClass("named-flow-overflow");
+            this.tooltip = WebInspector.UIString("Overflows.");
+        } else {
+            this.title.removeStyleClass("named-flow-overflow");
+            this.tooltip = "";
+        }
+
+        this._overset = newOverset;
+    }
+}
+
+WebInspector.FlowTreeElement.prototype.__proto__ = TreeElement.prototype;
diff --git a/Source/WebCore/inspector/front-end/CSSNamedFlowView.js b/Source/WebCore/inspector/front-end/CSSNamedFlowView.js
new file mode 100644 (file)
index 0000000..afb8c1d
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. 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 THE COPYRIGHT HOLDERS AND 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 THE
+ * COPYRIGHT HOLDER OR 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.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.View}
+ * @param {WebInspector.NamedFlow} flow
+ */
+WebInspector.CSSNamedFlowView = function(flow)
+{
+    WebInspector.View.call(this);
+    this.element.addStyleClass("css-named-flow");
+    this.element.addStyleClass("outline-disclosure");
+
+    this._treeOutline = new TreeOutline(this.element.createChild("ol"), true);
+
+    this._contentTreeItem = new TreeElement(WebInspector.UIString("content"), null, true);
+    this._treeOutline.appendChild(this._contentTreeItem);
+
+    this._regionsTreeItem = new TreeElement(WebInspector.UIString("region chain"), null, true);
+    this._regionsTreeItem.expand();
+    this._treeOutline.appendChild(this._regionsTreeItem);
+
+    this._flow = flow;
+
+    var content = flow.content;
+    for (var i = 0; i < content.length; ++i)
+        this._insertContentNode(content[i]);
+
+    var regions = flow.regions;
+    for (var i = 0; i < regions.length; ++i)
+        this._insertRegion(regions[i]);
+}
+
+WebInspector.CSSNamedFlowView.OversetTypeMessageMap = {
+    empty: "empty",
+    fit: "fit",
+    overset: "overset"
+}
+
+WebInspector.CSSNamedFlowView.prototype = {
+    /**
+     * @param {WebInspector.DOMNode=} rootDOMNode
+     * @return {?WebInspector.ElementsTreeOutline}
+     */
+    _createFlowTreeOutline: function(rootDOMNode)
+    {
+        if (!rootDOMNode)
+            return null;
+
+        var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
+        treeOutline.element.addStyleClass("named-flow-element");
+        treeOutline.setVisible(true);
+        treeOutline.rootDOMNode = rootDOMNode;
+        treeOutline.wireToDomAgent();
+        WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, treeOutline._elementsTreeUpdater._documentUpdated, treeOutline._elementsTreeUpdater);
+
+        return treeOutline;        
+    },
+
+    /**
+     * @param {DOMAgent.NodeId} contentNodeId
+     * @param {number=} index
+     */
+    _insertContentNode: function(contentNodeId, index)
+    {
+        var treeOutline = this._createFlowTreeOutline(WebInspector.domAgent.nodeForId(contentNodeId));
+        var treeItem = new TreeElement(treeOutline.element, treeOutline);
+
+        if (index === undefined) {
+            this._contentTreeItem.appendChild(treeItem);
+            return;
+        }
+
+        this._contentTreeItem.insertChild(treeItem, index);
+    },
+
+    /**
+     * @param {CSSAgent.Region} region
+     * @param {number=} index
+     */
+    _insertRegion: function(region, index)
+    {
+        var treeOutline = this._createFlowTreeOutline(WebInspector.domAgent.nodeForId(region.nodeId));
+        treeOutline.element.addStyleClass("region-" + region.regionOverset);
+
+        var treeItem = new TreeElement(treeOutline.element, treeOutline);
+        var oversetText = WebInspector.UIString(WebInspector.CSSNamedFlowView.OversetTypeMessageMap[region.regionOverset]);
+        treeItem.tooltip = WebInspector.UIString("Region is %s.", oversetText);
+
+        if (index === undefined) {
+            this._regionsTreeItem.appendChild(treeItem);
+            return;
+        }
+
+        this._regionsTreeItem.insertChild(treeItem, index);
+    },
+
+    get flow()
+    {
+        return this._flow;
+    },
+
+    set flow(newFlow)
+    {
+        this._update(newFlow);
+    },
+
+    /**
+     * @param {TreeElement} regionTreeItem
+     * @param {string} newRegionOverset
+     * @param {string} oldRegionOverset
+     */
+    _updateRegionOverset: function(regionTreeItem, newRegionOverset, oldRegionOverset)
+    {
+        var element = regionTreeItem.representedObject.element;
+        element.removeStyleClass("region-" + oldRegionOverset);
+        element.addStyleClass("region-" + newRegionOverset);
+
+        var oversetText = WebInspector.UIString(WebInspector.CSSNamedFlowView.OversetTypeMessageMap[newRegionOverset]);
+        regionTreeItem.tooltip = WebInspector.UIString("Region is %s." , oversetText);
+    },
+
+    /**
+     * @param {Array.<DOMAgent.NodeId>} oldContent
+     * @param {Array.<DOMAgent.NodeId>} newContent
+     */
+    _mergeContentNodes: function(oldContent, newContent)
+    {
+        var nodeIdSet = {};
+        for (var i = 0; i < newContent.length; ++i)
+            nodeIdSet[newContent[i]] = true;
+
+        var oldContentIndex = 0;
+        var newContentIndex = 0;
+        var contentTreeChildIndex = 0;
+
+        while(oldContentIndex < oldContent.length || newContentIndex < newContent.length) {
+            if (oldContentIndex === oldContent.length) {
+                this._insertContentNode(newContent[newContentIndex]);
+                ++newContentIndex;
+                continue;
+            }
+
+            if (newContentIndex === newContent.length) {
+                this._contentTreeItem.removeChildAtIndex(contentTreeChildIndex);
+                ++oldContentIndex;
+                continue;
+            }
+
+            if (oldContent[oldContentIndex] === newContent[newContentIndex]) {
+                ++oldContentIndex;
+                ++newContentIndex;
+                ++contentTreeChildIndex;
+                continue;
+            }
+
+            if (nodeIdSet[oldContent[oldContentIndex]]) {
+                this._insertContentNode(newContent[newContentIndex], contentTreeChildIndex);
+                ++newContentIndex;
+                ++contentTreeChildIndex;
+                continue;
+            }
+
+            this._contentTreeItem.removeChildAtIndex(contentTreeChildIndex);
+            ++oldContentIndex;
+        }
+    },
+
+    /**
+     * @param {Array.<CSSAgent.Region>} oldRegions
+     * @param {Array.<CSSAgent.Region>} newRegions
+     */
+    _mergeRegions: function(oldRegions, newRegions)
+    {
+        var nodeIdSet = {};
+        for (var i = 0; i < newRegions.length; ++i)
+            nodeIdSet[newRegions[i].nodeId] = true;
+
+        var oldRegionsIndex = 0;
+        var newRegionsIndex = 0;
+        var regionsTreeChildIndex = 0;
+
+        while(oldRegionsIndex < oldRegions.length || newRegionsIndex < newRegions.length) {
+            if (oldRegionsIndex === oldRegions.length) {
+                this._insertRegion(newRegions[newRegionsIndex]);
+                ++newRegionsIndex;
+                continue;
+            }
+
+            if (newRegionsIndex === newRegions.length) {
+                this._regionsTreeItem.removeChildAtIndex(regionsTreeChildIndex);
+                ++oldRegionsIndex;
+                continue;
+            }
+
+            if (oldRegions[oldRegionsIndex].nodeId === newRegions[newRegionsIndex].nodeId) {
+                if (oldRegions[oldRegionsIndex].regionOverset !== newRegions[newRegionsIndex].regionOverset)
+                    this._updateRegionOverset(this._regionsTreeItem.children[regionsTreeChildIndex], newRegions[newRegionsIndex].regionOverset, oldRegions[oldRegionsIndex].regionOverset);
+                ++oldRegionsIndex;
+                ++newRegionsIndex;
+                ++regionsTreeChildIndex;
+                continue;
+            }
+
+            if (nodeIdSet[oldRegions[oldRegionsIndex].nodeId]) {
+                this._insertRegion(newRegions[newRegionsIndex], regionsTreeChildIndex);
+                ++newRegionsIndex;
+                ++regionsTreeChildIndex;
+                continue;
+            }
+
+            this._regionsTreeItem.removeChildAtIndex(regionsTreeChildIndex);
+            ++oldRegionsIndex;
+        }
+    },
+
+    /**
+     * @param {WebInspector.NamedFlow} newFlow
+     */
+    _update: function(newFlow)
+    {
+        this._mergeContentNodes(this._flow.content, newFlow.content);
+        this._mergeRegions(this._flow.regions, newFlow.regions);
+
+        this._flow = newFlow;
+    }
+}
+
+WebInspector.CSSNamedFlowView.prototype.__proto__ = WebInspector.View.prototype;
index e735880..2fa6fc3 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 importScript("CSSNamedFlowCollectionsView.js");
+importScript("CSSNamedFlowView.js");
 importScript("EventListenersSidebarPane.js");
 importScript("MetricsSidebarPane.js");
 importScript("PropertiesSidebarPane.js");
diff --git a/Source/WebCore/inspector/front-end/Images/regionEmpty.png b/Source/WebCore/inspector/front-end/Images/regionEmpty.png
new file mode 100644 (file)
index 0000000..9b62eb5
Binary files /dev/null and b/Source/WebCore/inspector/front-end/Images/regionEmpty.png differ
diff --git a/Source/WebCore/inspector/front-end/Images/regionFit.png b/Source/WebCore/inspector/front-end/Images/regionFit.png
new file mode 100644 (file)
index 0000000..88fb408
Binary files /dev/null and b/Source/WebCore/inspector/front-end/Images/regionFit.png differ
diff --git a/Source/WebCore/inspector/front-end/Images/regionOverset.png b/Source/WebCore/inspector/front-end/Images/regionOverset.png
new file mode 100644 (file)
index 0000000..ee930d8
Binary files /dev/null and b/Source/WebCore/inspector/front-end/Images/regionOverset.png differ
index 2e1e2a2..cfeb194 100644 (file)
@@ -32,6 +32,7 @@
     <file>CSSCompletions.js</file>
     <file>CSSKeywordCompletions.js</file>
     <file>CSSNamedFlowCollectionsView.js</file>
+    <file>CSSNamedFlowView.js</file>
     <file>CSSSelectorProfileView.js</file>
     <file>CSSStyleModel.js</file>
     <file>cm/codemirror.css</file>
     <file>Images/profilesSilhouette.png</file>
     <file>Images/programCounterBorder.png</file>
     <file>Images/radioDot.png</file>
+    <file>Images/regionEmpty.png</file>
+    <file>Images/regionFit.png</file>
+    <file>Images/regionOverset.png</file>
     <file>Images/resourceCSSIcon.png</file>
     <file>Images/resourceDocumentIcon.png</file>
     <file>Images/resourceDocumentIconSmall.png</file>
index 523a516..d090b2e 100644 (file)
     position: relative;
 }
 
-.css-named-flow-collections-view .split-view-sidebar-left .named-flow-overflow::before {
-    content: url(Images/namedFlowOverflow.png);
+.css-named-flow-collections-view .split-view-sidebar-left .named-flow-overflow::before, .css-named-flow-collections-view .region-empty:before, .css-named-flow-collections-view .region-fit::before, .css-named-flow-collections-view .region-overset::before {
     cursor: default;
     float: left;
     height: 10px;
-    margin: 2px 3px 0px -13px;
+    margin-top: 1px;
     opacity: 0.75;
     position: relative;
     vertical-align: middle;
     z-index: 1;
 }
+
+.css-named-flow-collections-view .split-view-sidebar-left .named-flow-overflow::before {
+    content: url(Images/namedFlowOverflow.png);
+    margin: 2px 3px 0px -13px;
+}
+
+.css-named-flow-collections-view .region-empty::before {
+    content: url(Images/regionEmpty.png);
+}
+
+.css-named-flow-collections-view .region-fit::before {
+    content: url(Images/regionFit.png);
+}
+
+.css-named-flow-collections-view .region-overset::before {
+    content: url(Images/regionOverset.png);
+}
+
+.css-named-flow-collections-view .split-view-contents .named-flow-element {
+    margin: 0px 0px 0px -24px;
+}