Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (201244 => 201245)
--- trunk/Source/WebInspectorUI/ChangeLog 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/ChangeLog 2016-05-21 19:21:35 UTC (rev 201245)
@@ -1,5 +1,138 @@
2016-05-21 Matt Baker <[email protected]>
+ Web Inspector: Creating the CSSStyleDetailsSidebarPanel takes about 50ms (20%) of main load
+ https://bugs.webkit.org/show_bug.cgi?id=156707
+ <rdar://problem/25780404>
+
+ Reviewed by Timothy Hatcher.
+
+ This patch adds new View concepts, `initialLayout` and `widthDidChange`,
+ making it possible for hidden views to postpone the creation of their
+ UI subtree until they are shown for the first time.
+
+ Sidebar panels get this performance improvement by virtue of SidebarPanel
+ and StyleDetailsPanel, which trigger a layout when shown. This can be
+ removed once <https://webkit.org/b/150741> is fixed, and this is done
+ automatically by View.
+
+ * UserInterface/Views/CSSStyleDeclarationTextEditor.js:
+ (WebInspector.CSSStyleDeclarationTextEditor):
+ Should subclass View.
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype.layout):
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype.get element): Deleted.
+ Handled in View base class.
+ (WebInspector.CSSStyleDeclarationTextEditor.prototype.updateLayout): Deleted.
+ Relocate to `layout` override, ignore unused parameter `force`.
+
+ * UserInterface/Views/CSSStyleDetailsSidebarPanel.js:
+ (WebInspector.CSSStyleDetailsSidebarPanel):
+ Create the minimum required initial state and UI elements. Relocate
+ anything that can be lazy loaded to `initialLayout`.
+
+ (WebInspector.CSSStyleDetailsSidebarPanel.prototype.initialLayout):
+ (WebInspector.CSSStyleDetailsSidebarPanel.prototype.sizeDidChange):
+ (WebInspector.CSSStyleDetailsSidebarPanel.prototype.widthDidChange): Deleted.
+
+ * UserInterface/Views/ComputedStyleDetailsPanel.js:
+ (WebInspector.ComputedStyleDetailsPanel):
+ Relocate anything that can be lazy loaded to `initialLayout`.
+ (WebInspector.ComputedStyleDetailsPanel.prototype.initialLayout):
+ (WebInspector.ComputedStyleDetailsPanel.prototype.shown): Deleted.
+ (WebInspector.ComputedStyleDetailsPanel.prototype.widthDidChange): Deleted.
+ Handled in View base class.
+
+ * UserInterface/Views/DataGrid.js:
+ (WebInspector.DataGrid.prototype.layout):
+ Resize logic can be safely moved to `sizeDidChange`, since columns are
+ always initialized when the width changes.
+ (WebInspector.DataGrid.prototype.sizeDidChange):
+ Reposition headers, scrollbars.
+ (WebInspector.DataGrid.prototype._updateHeaderAndScrollbar):
+ Broke out header repositioning, which needs to be called whenever
+ column widths are initialized or the view size changes.
+
+ * UserInterface/Views/NavigationBar.js:
+ (WebInspector.NavigationBar.prototype.layout):
+
+ * UserInterface/Views/RulesStyleDetailsPanel.js:
+ (WebInspector.RulesStyleDetailsPanel.prototype.sizeDidChange):
+ (WebInspector.RulesStyleDetailsPanel.prototype.widthDidChange): Deleted.
+
+ * UserInterface/Views/Sidebar.js:
+ (WebInspector.Sidebar.prototype._recalculateWidth):
+ Width changes need to be coordinated by the View base class, since the
+ initial layout must have occurred before handling a width change.
+ Force a layout with a resize layout reason.
+
+ * UserInterface/Views/SidebarPanel.js:
+ (WebInspector.SidebarPanel.prototype.get displayName):
+ Drive-by style fix: add getter so that CSSStyleDetailsSidebarPanel
+ doesn't have to read the private property directly.
+
+ (WebInspector.SidebarPanel.prototype.shown):
+ Force a layout whenever the panel is shown.
+ (WebInspector.SidebarPanel.prototype.sizeDidChange):
+ (WebInspector.SidebarPanel):
+ (WebInspector.SidebarPanel.prototype.widthDidChange): Deleted.
+
+ * UserInterface/Views/StyleDetailsPanel.js:
+ (WebInspector.StyleDetailsPanel.prototype.shown):
+ Schedule a layout when shown. A forced layout isn't necessary.
+ Unlike SidebarPanels, the initial state of style panels doesn't depend
+ on its layout, and can be safely initialized by the next rAF.
+
+ (WebInspector.StyleDetailsPanel.prototype.hidden):
+ Cancel a pending layout if the panel is hidden before the next AF.
+ (WebInspector.StyleDetailsPanel.prototype.widthDidChange): Deleted.
+ Not needed, defined in View base class.
+
+ * UserInterface/Views/TimelineOverview.js:
+ (WebInspector.TimelineOverview.prototype.sizeDidChange):
+ (WebInspector.TimelineOverview.prototype.layout):
+ Moved resize logic to `sizeDidChange`.
+
+ * UserInterface/Views/TimelineRuler.js:
+ (WebInspector.TimelineRuler.prototype.sizeDidChange):
+ (WebInspector.TimelineRuler.prototype.layout):
+ Moved resize logic to `sizeDidChange`.
+
+ * UserInterface/Views/View.js:
+ (WebInspector.View):
+ (WebInspector.View.prototype.updateLayout):
+ (WebInspector.View.prototype.cancelLayout):
+ Allow a pending layout to be canceled. Useful when a view with a
+ pending layout is hidden before the layout occurs.
+
+ (WebInspector.View.prototype.get layoutReason):
+ Protected getter for subclasses that need to check the layout reason
+ outside `sizeDidChange`.
+
+ (WebInspector.View.prototype.initialLayout):
+ Subclass hook to create UI subtree the first time a layout occurs.
+ Called only once during the lifetime of the View.
+
+ (WebInspector.View.prototype.layout):
+ Drive-by comment fix.
+ (WebInspector.View.prototype.sizeDidChange):
+ New layout cycle hook for subclasses.
+ (WebInspector.View.prototype._layoutSubtree):
+ Do an initial layout the first time layout is called.
+ Call the `sizeDidChange` hook so that subclasses can update state
+ which depends on size/position before doing layout.
+
+ * UserInterface/Views/VisualStyleDetailsPanel.js:
+ (WebInspector.VisualStyleDetailsPanel):
+ Create the minimum required initial state and UI elements. Relocate
+ anything that can be lazy loaded to `initialLayout`.
+
+ (WebInspector.VisualStyleDetailsPanel.prototype.refresh):
+ No changes, shifting line numbers confused the diff.
+ (WebInspector.VisualStyleDetailsPanel.prototype.initialLayout):
+ (WebInspector.VisualStyleDetailsPanel.prototype.sizeDidChange):
+ (WebInspector.VisualStyleDetailsPanel.prototype.widthDidChange): Deleted.
+
+2016-05-21 Matt Baker <[email protected]>
+
Assertion Failed: StyleDetailsPanel.markAsNeedsRefresh() called with null domNode
https://bugs.webkit.org/show_bug.cgi?id=157955
<rdar://problem/26398943>
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -24,17 +24,16 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-WebInspector.CSSStyleDeclarationTextEditor = class CSSStyleDeclarationTextEditor extends WebInspector.Object
+WebInspector.CSSStyleDeclarationTextEditor = class CSSStyleDeclarationTextEditor extends WebInspector.View
{
- constructor(delegate, style, element)
+ constructor(delegate, style)
{
super();
- this._element = element || document.createElement("div");
- this._element.classList.add(WebInspector.CSSStyleDeclarationTextEditor.StyleClassName);
- this._element.classList.add(WebInspector.SyntaxHighlightedStyleClassName);
- this._element.addEventListener("mousedown", this._handleMouseDown.bind(this));
- this._element.addEventListener("mouseup", this._handleMouseUp.bind(this));
+ this.element.classList.add(WebInspector.CSSStyleDeclarationTextEditor.StyleClassName);
+ this.element.classList.add(WebInspector.SyntaxHighlightedStyleClassName);
+ this.element.addEventListener("mousedown", this._handleMouseDown.bind(this));
+ this.element.addEventListener("mouseup", this._handleMouseUp.bind(this));
this._mouseDownCursorPosition = null;
@@ -93,11 +92,6 @@
// Public
- get element()
- {
- return this._element;
- }
-
get delegate()
{
return this._delegate;
@@ -194,11 +188,6 @@
this._resetContent();
}
- updateLayout(force)
- {
- this._codeMirror.refresh();
- }
-
highlightProperty(property)
{
function propertiesMatch(cssProperty)
@@ -400,6 +389,11 @@
this._propertiesChanged();
}
+ layout()
+ {
+ this._codeMirror.refresh();
+ }
+
// Private
_textAtCursorIsComment(codeMirror, cursor)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -30,100 +30,21 @@
super("css-style", WebInspector.UIString("Styles"), WebInspector.UIString("Style"), null, true);
this._selectedPanel = null;
-
- this._forcedPseudoClassCheckboxes = {};
-
- if (WebInspector.cssStyleManager.canForcePseudoClasses()) {
- this._forcedPseudoClassContainer = document.createElement("div");
- this._forcedPseudoClassContainer.className = "pseudo-classes";
-
- let groupElement = null;
-
- WebInspector.CSSStyleManager.ForceablePseudoClasses.forEach(function(pseudoClass) {
- // We don't localize the label since it is a CSS pseudo-class from the CSS standard.
- let label = pseudoClass.capitalize();
-
- let labelElement = document.createElement("label");
-
- let checkboxElement = document.createElement("input");
- checkboxElement.addEventListener("change", this._forcedPseudoClassCheckboxChanged.bind(this, pseudoClass));
- checkboxElement.type = "checkbox";
-
- this._forcedPseudoClassCheckboxes[pseudoClass] = checkboxElement;
-
- labelElement.appendChild(checkboxElement);
- labelElement.append(label);
-
- if (!groupElement || groupElement.children.length === 2) {
- groupElement = document.createElement("div");
- groupElement.className = "group";
- this._forcedPseudoClassContainer.appendChild(groupElement);
- }
-
- groupElement.appendChild(labelElement);
- }, this);
-
- this.contentView.element.appendChild(this._forcedPseudoClassContainer);
- }
-
this._computedStyleDetailsPanel = new WebInspector.ComputedStyleDetailsPanel(this);
this._rulesStyleDetailsPanel = new WebInspector.RulesStyleDetailsPanel(this);
this._visualStyleDetailsPanel = new WebInspector.VisualStyleDetailsPanel(this);
- this._computedStyleDetailsPanel.addEventListener(WebInspector.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
- this._rulesStyleDetailsPanel.addEventListener(WebInspector.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
-
this._panels = [this._computedStyleDetailsPanel, this._rulesStyleDetailsPanel, this._visualStyleDetailsPanel];
this._panelNavigationInfo = [this._computedStyleDetailsPanel.navigationInfo, this._rulesStyleDetailsPanel.navigationInfo, this._visualStyleDetailsPanel.navigationInfo];
this._lastSelectedSectionSetting = new WebInspector.Setting("last-selected-style-details-panel", this._rulesStyleDetailsPanel.navigationInfo.identifier);
- let selectedPanel = this._panelMatchingIdentifier(this._lastSelectedSectionSetting.value);
- if (!selectedPanel)
- selectedPanel = this._rulesStyleDetailsPanel;
+ this._initiallySelectedPanel = this._panelMatchingIdentifier(this._lastSelectedSectionSetting.value) || this._rulesStyleDetailsPanel;
- this._switchPanels(selectedPanel);
-
- this._navigationItem = new WebInspector.ScopeRadioButtonNavigationItem(this._identifier, this._displayName, this._panelNavigationInfo, selectedPanel.navigationInfo);
+ this._navigationItem = new WebInspector.ScopeRadioButtonNavigationItem(this.identifier, this.displayName, this._panelNavigationInfo, this._initiallySelectedPanel.navigationInfo);
this._navigationItem.addEventListener(WebInspector.ScopeRadioButtonNavigationItem.Event.SelectedItemChanged, this._handleSelectedItemChanged, this);
- let optionsContainer = this.element.createChild("div", "options-container");
-
- let newRuleButton = optionsContainer.createChild("img", "new-rule");
- newRuleButton.title = WebInspector.UIString("New Rule");
- newRuleButton.addEventListener("click", this._newRuleButtonClicked.bind(this));
-
- this._filterBar = new WebInspector.FilterBar;
- this._filterBar.placeholder = WebInspector.UIString("Filter Styles");
- this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
- optionsContainer.appendChild(this._filterBar.element);
-
- this._classToggleButton = optionsContainer.createChild("button", "toggle-class-toggle");
- this._classToggleButton.textContent = WebInspector.UIString("Classes");
- this._classToggleButton.title = WebInspector.UIString("Toggle Classes");
- this._classToggleButton.addEventListener("click", this._classToggleButtonClicked.bind(this));
-
- this._classListContainer = this.element.createChild("div", "class-list-container");
- this._classListContainer.hidden = true;
-
- this._addClassContainer = this._classListContainer.createChild("div", "new-class");
- this._addClassContainer.title = WebInspector.UIString("Add a Class");
- this._addClassContainer.addEventListener("click", this._addClassContainerClicked.bind(this));
-
- let addClassCheckbox = this._addClassContainer.createChild("input");
- addClassCheckbox.type = "checkbox";
- addClassCheckbox.checked = true;
-
- let addClassIcon = useSVGSymbol("Images/Plus13.svg", "add-class-icon");
- this._addClassContainer.appendChild(addClassIcon);
-
- this._addClassInput = this._addClassContainer.createChild("input", "class-name-input");
- this._addClassInput.setAttribute("placeholder", WebInspector.UIString("Enter Class Name"));
- this._addClassInput.addEventListener("keypress", this._addClassInputKeyPressed.bind(this));
- this._addClassInput.addEventListener("blur", this._addClassInputBlur.bind(this));
-
- WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, this.refresh, this);
- WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, this.refresh, this);
+ this._forcedPseudoClassCheckboxes = {};
}
// Public
@@ -170,16 +91,6 @@
this._selectedPanel.markAsNeedsRefresh(this.domNode);
}
- widthDidChange()
- {
- super.widthDidChange();
-
- this._updateNoForcedPseudoClassesScrollOffset();
-
- if (this._selectedPanel)
- this._selectedPanel.widthDidChange();
- }
-
computedStyleDetailsPanelShowProperty(property)
{
this._rulesStyleDetailsPanel.scrollToSectionAndHighlightProperty(property);
@@ -210,6 +121,98 @@
effectiveDOMNode.removeEventListener(null, null, this);
}
+ initialLayout()
+ {
+ if (WebInspector.cssStyleManager.canForcePseudoClasses()) {
+ this._forcedPseudoClassContainer = document.createElement("div");
+ this._forcedPseudoClassContainer.className = "pseudo-classes";
+
+ let groupElement = null;
+
+ WebInspector.CSSStyleManager.ForceablePseudoClasses.forEach(function(pseudoClass) {
+ // We don't localize the label since it is a CSS pseudo-class from the CSS standard.
+ let label = pseudoClass.capitalize();
+
+ let labelElement = document.createElement("label");
+
+ let checkboxElement = document.createElement("input");
+ checkboxElement.addEventListener("change", this._forcedPseudoClassCheckboxChanged.bind(this, pseudoClass));
+ checkboxElement.type = "checkbox";
+
+ this._forcedPseudoClassCheckboxes[pseudoClass] = checkboxElement;
+
+ labelElement.appendChild(checkboxElement);
+ labelElement.append(label);
+
+ if (!groupElement || groupElement.children.length === 2) {
+ groupElement = document.createElement("div");
+ groupElement.className = "group";
+ this._forcedPseudoClassContainer.appendChild(groupElement);
+ }
+
+ groupElement.appendChild(labelElement);
+ }, this);
+
+ this.contentView.element.appendChild(this._forcedPseudoClassContainer);
+ }
+
+ this._computedStyleDetailsPanel.addEventListener(WebInspector.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
+ this._rulesStyleDetailsPanel.addEventListener(WebInspector.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
+
+ console.assert(this._initiallySelectedPanel, "Should have an initially selected panel.");
+
+ this._switchPanels(this._initiallySelectedPanel);
+ this._initiallySelectedPanel = null;
+
+ let optionsContainer = this.element.createChild("div", "options-container");
+
+ let newRuleButton = optionsContainer.createChild("img", "new-rule");
+ newRuleButton.title = WebInspector.UIString("New Rule");
+ newRuleButton.addEventListener("click", this._newRuleButtonClicked.bind(this));
+
+ this._filterBar = new WebInspector.FilterBar;
+ this._filterBar.placeholder = WebInspector.UIString("Filter Styles");
+ this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
+ optionsContainer.appendChild(this._filterBar.element);
+
+ this._classToggleButton = optionsContainer.createChild("button", "toggle-class-toggle");
+ this._classToggleButton.textContent = WebInspector.UIString("Classes");
+ this._classToggleButton.title = WebInspector.UIString("Toggle Classes");
+ this._classToggleButton.addEventListener("click", this._classToggleButtonClicked.bind(this));
+
+ this._classListContainer = this.element.createChild("div", "class-list-container");
+ this._classListContainer.hidden = true;
+
+ this._addClassContainer = this._classListContainer.createChild("div", "new-class");
+ this._addClassContainer.title = WebInspector.UIString("Add a Class");
+ this._addClassContainer.addEventListener("click", this._addClassContainerClicked.bind(this));
+
+ let addClassCheckbox = this._addClassContainer.createChild("input");
+ addClassCheckbox.type = "checkbox";
+ addClassCheckbox.checked = true;
+
+ let addClassIcon = useSVGSymbol("Images/Plus13.svg", "add-class-icon");
+ this._addClassContainer.appendChild(addClassIcon);
+
+ this._addClassInput = this._addClassContainer.createChild("input", "class-name-input");
+ this._addClassInput.setAttribute("placeholder", WebInspector.UIString("Enter Class Name"));
+ this._addClassInput.addEventListener("keypress", this._addClassInputKeyPressed.bind(this));
+ this._addClassInput.addEventListener("blur", this._addClassInputBlur.bind(this));
+
+ WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, this.refresh, this);
+ WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, this.refresh, this);
+ }
+
+ sizeDidChange()
+ {
+ super.sizeDidChange();
+
+ this._updateNoForcedPseudoClassesScrollOffset();
+
+ if (this._selectedPanel)
+ this._selectedPanel.sizeDidChange();
+ }
+
// Private
get _initialScrollOffset()
@@ -458,7 +461,7 @@
}
};
-WebInspector.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = 30; // Default height of the forced pseudo classes container. Updated in widthDidChange.
+WebInspector.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = 30; // Default height of the forced pseudo classes container. Updated in sizeDidChange.
WebInspector.CSSStyleDetailsSidebarPanel.FilterInProgressClassName = "filter-in-progress";
WebInspector.CSSStyleDetailsSidebarPanel.FilterMatchingSectionHasLabelClassName = "filter-section-has-label";
WebInspector.CSSStyleDetailsSidebarPanel.FilterMatchSectionClassName = "filter-matching";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ComputedStyleDetailsPanel.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ComputedStyleDetailsPanel.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ComputedStyleDetailsPanel.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -30,72 +30,6 @@
super(delegate, WebInspector.ComputedStyleDetailsPanel.StyleClassName, "computed", WebInspector.UIString("Styles \u2014 Computed"));
this._computedStyleShowAllSetting = new WebInspector.Setting("computed-style-show-all", false);
-
- var computedStyleShowAllLabel = document.createElement("label");
- computedStyleShowAllLabel.textContent = WebInspector.UIString("Show All");
-
- this._computedStyleShowAllCheckbox = document.createElement("input");
- this._computedStyleShowAllCheckbox.type = "checkbox";
- this._computedStyleShowAllCheckbox.checked = this._computedStyleShowAllSetting.value;
- this._computedStyleShowAllCheckbox.addEventListener("change", this._computedStyleShowAllCheckboxValueChanged.bind(this));
- computedStyleShowAllLabel.appendChild(this._computedStyleShowAllCheckbox);
-
- this._propertiesTextEditor = new WebInspector.CSSStyleDeclarationTextEditor(this);
- this._propertiesTextEditor.showsImplicitProperties = this._computedStyleShowAllSetting.value;
- this._propertiesTextEditor.alwaysShowPropertyNames = ["display", "width", "height"];
- this._propertiesTextEditor.sortProperties = true;
-
- var propertiesRow = new WebInspector.DetailsSectionRow;
- var propertiesGroup = new WebInspector.DetailsSectionGroup([propertiesRow]);
- var propertiesSection = new WebInspector.DetailsSection("computed-style-properties", WebInspector.UIString("Properties"), [propertiesGroup], computedStyleShowAllLabel);
- propertiesSection.addEventListener(WebInspector.DetailsSection.Event.CollapsedStateChanged, this._handleCollapsedStateChanged, this);
-
- propertiesRow.element.appendChild(this._propertiesTextEditor.element);
-
- // Region flow name is used to display the "flow-from" property of the Region Containers.
- this._regionFlowFragment = document.createElement("span");
- this._regionFlowFragment.appendChild(document.createElement("img")).className = "icon";
- this._regionFlowNameLabelValue = this._regionFlowFragment.appendChild(document.createElement("span"));
-
- var goToRegionFlowButton = this._regionFlowFragment.appendChild(WebInspector.createGoToArrowButton());
- goToRegionFlowButton.addEventListener("click", this._goToRegionFlowArrowWasClicked.bind(this));
-
- this._regionFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Region Flow"));
- this._regionFlowNameRow.element.classList.add("content-flow-link");
-
- // Content flow name is used to display the "flow-into" property of the Content nodes.
- this._contentFlowFragment = document.createElement("span");
- this._contentFlowFragment.appendChild(document.createElement("img")).className = "icon";
- this._contentFlowNameLabelValue = this._contentFlowFragment.appendChild(document.createElement("span"));
-
- var goToContentFlowButton = this._contentFlowFragment.appendChild(WebInspector.createGoToArrowButton());
- goToContentFlowButton.addEventListener("click", this._goToContentFlowArrowWasClicked.bind(this));
-
- this._contentFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Content Flow"));
- this._contentFlowNameRow.element.classList.add("content-flow-link");
-
- var flowNamesGroup = new WebInspector.DetailsSectionGroup([this._regionFlowNameRow, this._contentFlowNameRow]);
- this._flowNamesSection = new WebInspector.DetailsSection("content-flow", WebInspector.UIString("Flows"), [flowNamesGroup]);
-
- this._containerRegionsDataGrid = new WebInspector.DOMTreeDataGrid;
- this._containerRegionsDataGrid.element.classList.add("no-header");
-
- var containerRegionsRow = new WebInspector.DetailsSectionDataGridRow(this._containerRegionsDataGrid);
- var containerRegionsGroup = new WebInspector.DetailsSectionGroup([containerRegionsRow]);
- this._containerRegionsFlowSection = new WebInspector.DetailsSection("container-regions", WebInspector.UIString("Container Regions"), [containerRegionsGroup]);
-
- this.element.appendChild(propertiesSection.element);
- this.element.appendChild(this._flowNamesSection.element);
- this.element.appendChild(this._containerRegionsFlowSection.element);
-
- this._resetFlowDetails();
-
- this._boxModelDiagramRow = new WebInspector.BoxModelDetailsSectionRow;
-
- var boxModelGroup = new WebInspector.DetailsSectionGroup([this._boxModelDiagramRow]);
- var boxModelSection = new WebInspector.DetailsSection("style-box-model", WebInspector.UIString("Box Model"), [boxModelGroup]);
-
- this.element.appendChild(boxModelSection.element);
this.cssStyleDeclarationTextEditorShouldAddPropertyGoToArrows = true;
}
@@ -207,16 +141,75 @@
// Protected
- shown()
+ initialLayout()
{
- super.shown();
+ let computedStyleShowAllLabel = document.createElement("label");
+ computedStyleShowAllLabel.textContent = WebInspector.UIString("Show All");
- this._propertiesTextEditor.updateLayout();
- }
+ this._computedStyleShowAllCheckbox = document.createElement("input");
+ this._computedStyleShowAllCheckbox.type = "checkbox";
+ this._computedStyleShowAllCheckbox.checked = this._computedStyleShowAllSetting.value;
+ this._computedStyleShowAllCheckbox.addEventListener("change", this._computedStyleShowAllCheckboxValueChanged.bind(this));
+ computedStyleShowAllLabel.appendChild(this._computedStyleShowAllCheckbox);
- widthDidChange()
- {
- this._propertiesTextEditor.updateLayout();
+ this._propertiesTextEditor = new WebInspector.CSSStyleDeclarationTextEditor(this);
+ this._propertiesTextEditor.showsImplicitProperties = this._computedStyleShowAllSetting.value;
+ this._propertiesTextEditor.alwaysShowPropertyNames = ["display", "width", "height"];
+ this._propertiesTextEditor.sortProperties = true;
+
+ let propertiesRow = new WebInspector.DetailsSectionRow;
+ let propertiesGroup = new WebInspector.DetailsSectionGroup([propertiesRow]);
+ let propertiesSection = new WebInspector.DetailsSection("computed-style-properties", WebInspector.UIString("Properties"), [propertiesGroup], computedStyleShowAllLabel);
+ propertiesSection.addEventListener(WebInspector.DetailsSection.Event.CollapsedStateChanged, this._handleCollapsedStateChanged, this);
+
+ this.addSubview(this._propertiesTextEditor);
+
+ propertiesRow.element.appendChild(this._propertiesTextEditor.element);
+
+ // Region flow name is used to display the "flow-from" property of the Region Containers.
+ this._regionFlowFragment = document.createElement("span");
+ this._regionFlowFragment.appendChild(document.createElement("img")).className = "icon";
+ this._regionFlowNameLabelValue = this._regionFlowFragment.appendChild(document.createElement("span"));
+
+ let goToRegionFlowButton = this._regionFlowFragment.appendChild(WebInspector.createGoToArrowButton());
+ goToRegionFlowButton.addEventListener("click", this._goToRegionFlowArrowWasClicked.bind(this));
+
+ this._regionFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Region Flow"));
+ this._regionFlowNameRow.element.classList.add("content-flow-link");
+
+ // Content flow name is used to display the "flow-into" property of the Content nodes.
+ this._contentFlowFragment = document.createElement("span");
+ this._contentFlowFragment.appendChild(document.createElement("img")).className = "icon";
+ this._contentFlowNameLabelValue = this._contentFlowFragment.appendChild(document.createElement("span"));
+
+ let goToContentFlowButton = this._contentFlowFragment.appendChild(WebInspector.createGoToArrowButton());
+ goToContentFlowButton.addEventListener("click", this._goToContentFlowArrowWasClicked.bind(this));
+
+ this._contentFlowNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Content Flow"));
+ this._contentFlowNameRow.element.classList.add("content-flow-link");
+
+ let flowNamesGroup = new WebInspector.DetailsSectionGroup([this._regionFlowNameRow, this._contentFlowNameRow]);
+ this._flowNamesSection = new WebInspector.DetailsSection("content-flow", WebInspector.UIString("Flows"), [flowNamesGroup]);
+
+ this._containerRegionsDataGrid = new WebInspector.DOMTreeDataGrid;
+ this._containerRegionsDataGrid.element.classList.add("no-header");
+
+ let containerRegionsRow = new WebInspector.DetailsSectionDataGridRow(this._containerRegionsDataGrid);
+ let containerRegionsGroup = new WebInspector.DetailsSectionGroup([containerRegionsRow]);
+ this._containerRegionsFlowSection = new WebInspector.DetailsSection("container-regions", WebInspector.UIString("Container Regions"), [containerRegionsGroup]);
+
+ this.element.appendChild(propertiesSection.element);
+ this.element.appendChild(this._flowNamesSection.element);
+ this.element.appendChild(this._containerRegionsFlowSection.element);
+
+ this._resetFlowDetails();
+
+ this._boxModelDiagramRow = new WebInspector.BoxModelDetailsSectionRow;
+
+ let boxModelGroup = new WebInspector.DetailsSectionGroup([this._boxModelDiagramRow]);
+ let boxModelSection = new WebInspector.DetailsSection("style-box-model", WebInspector.UIString("Box Model"), [boxModelGroup]);
+
+ this.element.appendChild(boxModelSection.element);
}
// Private
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -792,54 +792,58 @@
//
// If this function is not called after the DataGrid is attached to its
// parent element, then the DataGrid's columns will not be resizable.
- layout(layoutReason)
+ layout()
{
- let firstUpdate = false;
-
// Do not attempt to use offsets if we're not attached to the document tree yet.
if (!this._columnWidthsInitialized && this.element.offsetWidth) {
// Give all the columns initial widths now so that during a resize,
// when the two columns that get resized get a percent value for
// their widths, all the other columns already have percent values
// for their widths.
- var headerTableColumnElements = this._headerTableColumnGroupElement.children;
- var tableWidth = this._dataTableElement.offsetWidth;
- var numColumns = headerTableColumnElements.length;
- var cells = this._headerTableBodyElement.rows[0].cells;
+ let headerTableColumnElements = this._headerTableColumnGroupElement.children;
+ let tableWidth = this._dataTableElement.offsetWidth;
+ let numColumns = headerTableColumnElements.length;
+ let cells = this._headerTableBodyElement.rows[0].cells;
// Calculate widths.
- var columnWidths = [];
- for (var i = 0; i < numColumns; ++i) {
- var headerCellElement = cells[i];
+ let columnWidths = [];
+ for (let i = 0; i < numColumns; ++i) {
+ let headerCellElement = cells[i];
if (this._isColumnVisible(headerCellElement.columnIdentifier)) {
- var columnWidth = headerCellElement.offsetWidth;
- var percentWidth = ((columnWidth / tableWidth) * 100) + "%";
+ let columnWidth = headerCellElement.offsetWidth;
+ let percentWidth = ((columnWidth / tableWidth) * 100) + "%";
columnWidths.push(percentWidth);
} else
columnWidths.push(0);
}
// Apply widths.
- for (var i = 0; i < numColumns; i++) {
+ for (let i = 0; i < numColumns; i++) {
let percentWidth = columnWidths[i];
this._headerTableColumnGroupElement.children[i].style.width = percentWidth;
this._dataTableColumnGroupElement.children[i].style.width = percentWidth;
}
this._columnWidthsInitialized = true;
- firstUpdate = true;
+ this._updateHeaderAndScrollbar();
}
- if (layoutReason === WebInspector.View.LayoutReason.Resize || firstUpdate) {
- this._positionResizerElements();
- this._positionHeaderViews();
- this._updateScrollbarPadding();
+ this._updateVisibleRows();
+ }
- this._cachedScrollTop = NaN;
- this._cachedScrollableOffsetHeight = NaN;
- }
+ sizeDidChange()
+ {
+ this._updateHeaderAndScrollbar();
+ }
- this._updateVisibleRows();
+ _updateHeaderAndScrollbar()
+ {
+ this._positionResizerElements();
+ this._positionHeaderViews();
+ this._updateScrollbarPadding();
+
+ this._cachedScrollTop = NaN;
+ this._cachedScrollableOffsetHeight = NaN;
}
columnWidthsMap()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -168,9 +168,9 @@
super.needsLayout();
}
- layout(layoutReason)
+ layout()
{
- if (layoutReason !== WebInspector.View.LayoutReason.Resize && !this._forceLayout)
+ if (this.layoutReason !== WebInspector.View.LayoutReason.Resize && !this._forceLayout)
return;
this._forceLayout = false;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -452,7 +452,7 @@
delete this._sections[i].style.__rulesSection;
}
- widthDidChange()
+ sizeDidChange()
{
for (var i = 0; i < this._sections.length; ++i)
this._sections[i].updateLayout();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/Sidebar.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/Sidebar.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/Sidebar.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -273,7 +273,7 @@
this._navigationBar.needsLayout();
if (!this.collapsed && this._selectedSidebarPanel)
- this._selectedSidebarPanel.widthDidChange();
+ this._selectedSidebarPanel.updateLayout(WebInspector.View.LayoutReason.Resize);
this.dispatchEventToListeners(WebInspector.Sidebar.Event.WidthDidChange);
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SidebarPanel.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SidebarPanel.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SidebarPanel.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -58,6 +58,11 @@
return this._contentView;
}
+ get displayName()
+ {
+ return this._displayName;
+ }
+
get visible()
{
return this.selected && this.parentSidebar && !this.parentSidebar.collapsed;
@@ -129,6 +134,9 @@
{
this._contentView.element.scrollTop = this._savedScrollPosition;
+ // FIXME: remove once <https://webkit.org/b/150741> is fixed.
+ this.updateLayout();
+
// Implemented by subclasses.
}
@@ -139,17 +147,19 @@
// Implemented by subclasses.
}
- widthDidChange()
+ visibilityDidChange()
{
+ // Implemented by subclasses.
+ }
+
+ // Protected
+
+ sizeDidChange()
+ {
let width = this.element.realOffsetWidth;
if (width && width !== this._widthSetting.value)
this._widthSetting.value = width;
// Implemented by subclasses.
}
-
- visibilityDidChange()
- {
- // Implemented by subclasses.
- }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/StyleDetailsPanel.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/StyleDetailsPanel.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/StyleDetailsPanel.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -60,16 +60,16 @@
this._visible = true;
this._refreshNodeStyles();
+
+ // FIXME: remove once <https://webkit.org/b/150741> is fixed.
+ this.needsLayout();
}
hidden()
{
this._visible = false;
- }
- widthDidChange()
- {
- // Implemented by subclasses.
+ this.cancelLayout();
}
markAsNeedsRefresh(domNode)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineOverview.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -429,11 +429,8 @@
return this._timelineRuler;
}
- layout(layoutReason)
+ layout()
{
- if (layoutReason === WebInspector.View.LayoutReason.Resize)
- this._cachedScrollContainerWidth = NaN;
-
let startTime = this._startTime;
let endTime = this._endTime;
let currentTime = this._currentTime;
@@ -488,6 +485,11 @@
}
}
+ sizeDidChange()
+ {
+ this._cachedScrollContainerWidth = NaN;
+ }
+
// Private
_updateElementWidth(element, newWidth)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRuler.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -415,11 +415,8 @@
// Protected
- layout(layoutReason)
+ layout()
{
- if (layoutReason === WebInspector.View.LayoutReason.Resize)
- this._cachedClientWidth = this.element.clientWidth;
-
let visibleWidth = this._recalculate();
if (visibleWidth <= 0)
return;
@@ -532,6 +529,11 @@
this._updateSelection(visibleWidth, duration);
}
+ sizeDidChange()
+ {
+ this._cachedClientWidth = this.element.clientWidth;
+ }
+
// Private
_needsMarkerLayout()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/View.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/View.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/View.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -38,6 +38,7 @@
this._needsLayoutWhenAttachedToRoot = false;
this._isAttachedToRoot = false;
this._layoutReason = null;
+ this._didInitialLayout = false;
}
// Static
@@ -140,7 +141,7 @@
updateLayout(layoutReason)
{
- WebInspector.View._cancelScheduledLayoutForView(this);
+ this.cancelLayout();
this._setLayoutReason(layoutReason);
this._layoutSubtree();
@@ -164,8 +165,15 @@
WebInspector.View._scheduleLayoutForView(this);
}
+ cancelLayout()
+ {
+ WebInspector.View._cancelScheduledLayoutForView(this);
+ }
+
// Protected
+ get layoutReason() { return this._layoutReason; }
+
didMoveToWindow(isAttachedToRoot)
{
this._isAttachedToRoot = isAttachedToRoot;
@@ -200,13 +208,30 @@
}
}
+ initialLayout()
+ {
+ // Implemented by subclasses.
+
+ // Called once when the view is shown for the first time.
+ // Views with complex DOM subtrees should create UI elements in
+ // initialLayout rather than at construction time.
+ }
+
layout()
{
- // Overridden by subclasses.
+ // Implemented by subclasses.
+
// Not responsible for recursing to child views.
// Should not be called directly; use updateLayout() instead.
}
+ sizeDidChange()
+ {
+ // Implemented by subclasses.
+
+ // Called after initialLayout, and before layout.
+ }
+
// Private
_layoutSubtree()
@@ -214,8 +239,16 @@
this._dirty = false;
this._dirtyDescendantsCount = 0;
- this.layout(this._layoutReason);
+ if (!this._didInitialLayout) {
+ this.initialLayout();
+ this._didInitialLayout = true;
+ }
+ if (this._layoutReason === WebInspector.View.LayoutReason.Resize)
+ this.sizeDidChange();
+
+ this.layout();
+
for (let view of this._subviews) {
view._setLayoutReason(this._layoutReason);
view._layoutSubtree();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.js (201244 => 201245)
--- trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.js 2016-05-21 19:21:31 UTC (rev 201244)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.js 2016-05-21 19:21:35 UTC (rev 201245)
@@ -54,7 +54,24 @@
basic: ["%"].concat(this._units.defaultsSansPercent.basic),
advanced: this._units.defaultsSansPercent.advanced
};
+ }
+ // Public
+
+ refresh(significantChange)
+ {
+ if (significantChange)
+ this._selectorSection.update(this._nodeStyles);
+ else
+ this._updateSections();
+
+ super.refresh();
+ }
+
+ // Protected
+
+ initialLayout()
+ {
// Selector Section
this._selectorSection = new WebInspector.VisualStyleSelectorSection(this);
this._selectorSection.addEventListener(WebInspector.VisualStyleSelectorSection.Event.SelectorChanged, this._updateSections, this);
@@ -102,22 +119,10 @@
this.element.appendChild(this._sections.effects.element);
}
- // Public
-
- refresh(significantChange)
+ sizeDidChange()
{
- if (significantChange)
- this._selectorSection.update(this._nodeStyles);
- else
- this._updateSections();
+ super.sizeDidChange();
- super.refresh();
- }
-
- widthDidChange()
- {
- super.widthDidChange();
-
let sidebarWidth = this.element.realOffsetWidth;
for (let key in this._groups) {
let group = this._groups[key];