Web Inspector: Option+Click not jumping to resource
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / ComputedStyleDetailsPanel.js
1 /*
2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.ComputedStyleDetailsPanel = class ComputedStyleDetailsPanel extends WebInspector.StyleDetailsPanel
27 {
28     constructor(delegate)
29     {
30         super(delegate, WebInspector.ComputedStyleDetailsPanel.StyleClassName, "computed", WebInspector.UIString("Computed"));
31
32         this._computedStyleShowAllSetting = new WebInspector.Setting("computed-style-show-all", false);
33
34         var computedStyleShowAllLabel = document.createElement("label");
35         computedStyleShowAllLabel.textContent = WebInspector.UIString("Show All");
36
37         this._computedStyleShowAllCheckbox = document.createElement("input");
38         this._computedStyleShowAllCheckbox.type = "checkbox";
39         this._computedStyleShowAllCheckbox.checked = this._computedStyleShowAllSetting.value;
40         this._computedStyleShowAllCheckbox.addEventListener("change", this._computedStyleShowAllCheckboxValueChanged.bind(this));
41         computedStyleShowAllLabel.appendChild(this._computedStyleShowAllCheckbox);
42
43         this._propertiesTextEditor = new WebInspector.CSSStyleDeclarationTextEditor(this);
44         this._propertiesTextEditor.showsImplicitProperties = this._computedStyleShowAllSetting.value;
45         this._propertiesTextEditor.alwaysShowPropertyNames = ["display", "width", "height"];
46         this._propertiesTextEditor.sortProperties = true;
47
48         var propertiesRow = new WebInspector.DetailsSectionRow;
49         var propertiesGroup = new WebInspector.DetailsSectionGroup([propertiesRow]);
50         var propertiesSection = new WebInspector.DetailsSection("computed-style-properties", WebInspector.UIString("Properties"), [propertiesGroup], computedStyleShowAllLabel);
51
52         propertiesRow.element.appendChild(this._propertiesTextEditor.element);
53
54         // Region flow name is used to display the "flow-from" property of the Region Containers.
55         this._regionFlowFragment = document.createElement("span");
56         this._regionFlowFragment.appendChild(document.createElement("img")).className = "icon";
57         this._regionFlowNameLabelValue = this._regionFlowFragment.appendChild(document.createElement("span"));
58
59         var goToRegionFlowButton = this._regionFlowFragment.appendChild(WebInspector.createGoToArrowButton());
60         goToRegionFlowButton.addEventListener("click", this._goToRegionFlowArrowWasClicked.bind(this));
61
62         this._regionFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Region Flow"));
63         this._regionFlowNameRow.element.classList.add("content-flow-link");
64
65         // Content flow name is used to display the "flow-into" property of the Content nodes.
66         this._contentFlowFragment = document.createElement("span");
67         this._contentFlowFragment.appendChild(document.createElement("img")).className = "icon";
68         this._contentFlowNameLabelValue = this._contentFlowFragment.appendChild(document.createElement("span"));
69
70         var goToContentFlowButton = this._contentFlowFragment.appendChild(WebInspector.createGoToArrowButton());
71         goToContentFlowButton.addEventListener("click", this._goToContentFlowArrowWasClicked.bind(this));
72
73         this._contentFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Content Flow"));
74         this._contentFlowNameRow.element.classList.add("content-flow-link");
75
76         var flowNamesGroup = new WebInspector.DetailsSectionGroup([this._regionFlowNameRow, this._contentFlowNameRow]);
77         this._flowNamesSection = new WebInspector.DetailsSection("content-flow", WebInspector.UIString("Flows"), [flowNamesGroup]);
78
79         this._containerRegionsDataGrid = new WebInspector.DOMTreeDataGrid;
80         this._containerRegionsDataGrid.element.classList.add("no-header");
81
82         var containerRegionsRow = new WebInspector.DetailsSectionDataGridRow(this._containerRegionsDataGrid);
83         var containerRegionsGroup = new WebInspector.DetailsSectionGroup([containerRegionsRow]);
84         this._containerRegionsFlowSection = new WebInspector.DetailsSection("container-regions", WebInspector.UIString("Container Regions"), [containerRegionsGroup]);
85
86         this.element.appendChild(propertiesSection.element);
87         this.element.appendChild(this._flowNamesSection.element);
88         this.element.appendChild(this._containerRegionsFlowSection.element);
89
90         this._resetFlowDetails();
91         
92         this.cssStyleDeclarationTextEditorShouldAddPropertyGoToArrows = true;
93     }
94
95     // Public
96
97     get regionFlow()
98     {
99         return this._regionFlow;
100     }
101
102     set regionFlow(regionFlow)
103     {
104         this._regionFlow = regionFlow;
105         this._regionFlowNameLabelValue.textContent = regionFlow ? regionFlow.name : "";
106         this._regionFlowNameRow.value = regionFlow ? this._regionFlowFragment : null;
107         this._updateFlowNamesSectionVisibility();
108     }
109
110     get contentFlow()
111     {
112         return this._contentFlow;
113     }
114
115     set contentFlow(contentFlow)
116     {
117         this._contentFlow = contentFlow;
118         this._contentFlowNameLabelValue.textContent = contentFlow ? contentFlow.name : "";
119         this._contentFlowNameRow.value = contentFlow ? this._contentFlowFragment : null;
120         this._updateFlowNamesSectionVisibility();
121     }
122
123     get containerRegions()
124     {
125         return this._containerRegions;
126     }
127
128     set containerRegions(regions)
129     {
130         this._containerRegions = regions;
131
132         if (!regions || !regions.length) {
133             this._containerRegionsFlowSection.element.classList.add("hidden");
134             return;
135         }
136
137         this._containerRegionsDataGrid.removeChildren();
138         for (var regionNode of regions)
139             this._containerRegionsDataGrid.appendChild(new WebInspector.DOMTreeDataGridNode(regionNode));
140
141         this._containerRegionsFlowSection.element.classList.remove("hidden");
142     }
143
144     cssStyleDeclarationTextEditorShowProperty(property)
145     {
146         if (typeof this._delegate.computedStyleDetailsPanelShowProperty === "function")
147             this._delegate.computedStyleDetailsPanelShowProperty(property);
148     }
149
150     refresh()
151     {
152         this._propertiesTextEditor.style = this.nodeStyles.computedStyle;
153         this._refreshFlowDetails(this.nodeStyles.node);
154
155         super.refresh();
156     }
157
158     filterDidChange(filterBar)
159     {
160         this._propertiesTextEditor.removeNonMatchingProperties(filterBar.filters.text);
161     }
162
163     // Protected
164
165     shown()
166     {
167         super.shown();
168
169         this._propertiesTextEditor.updateLayout();
170     }
171
172     widthDidChange()
173     {
174         this._propertiesTextEditor.updateLayout();
175     }
176
177     // Private
178
179     _computedStyleShowAllCheckboxValueChanged(event)
180     {
181         var checked = this._computedStyleShowAllCheckbox.checked;
182         this._computedStyleShowAllSetting.value = checked;
183         this._propertiesTextEditor.showsImplicitProperties = checked;
184     }
185
186     _updateFlowNamesSectionVisibility()
187     {
188         this._flowNamesSection.element.classList.toggle("hidden", !this._contentFlow && !this._regionFlow);
189     }
190
191     _resetFlowDetails ()
192     {
193         this.regionFlow = null;
194         this.contentFlow = null;
195         this.containerRegions = null;
196     }
197
198     _refreshFlowDetails(domNode)
199     {
200         this._resetFlowDetails();
201         if (!domNode)
202             return;
203
204         function contentFlowInfoReady(error, flowData)
205         {
206             // Element is not part of any flow.
207             if (error || !flowData) {
208                 this._resetFlowDetails();
209                 return;
210             }
211
212             this.regionFlow = flowData.regionFlow;
213             this.contentFlow = flowData.contentFlow;
214             this.containerRegions = flowData.regions;
215         }
216
217         WebInspector.domTreeManager.getNodeContentFlowInfo(domNode, contentFlowInfoReady.bind(this));
218     }
219
220     _goToRegionFlowArrowWasClicked()
221     {
222         WebInspector.showContentFlowDOMTree(this._regionFlow);
223     }
224
225     _goToContentFlowArrowWasClicked()
226     {
227         WebInspector.showContentFlowDOMTree(this._contentFlow, this.nodeStyles.node);
228     }
229 };
230
231 WebInspector.ComputedStyleDetailsPanel.StyleClassName = "computed";