Diff
Modified: trunk/LayoutTests/ChangeLog (126267 => 126268)
--- trunk/LayoutTests/ChangeLog 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/LayoutTests/ChangeLog 2012-08-22 06:58:30 UTC (rev 126268)
@@ -1,3 +1,14 @@
+2012-08-21 Pavel Feldman <[email protected]>
+
+ Web Inspector: TabbedPane: measure tab widths in batches.
+ https://bugs.webkit.org/show_bug.cgi?id=94484
+
+ Reviewed by Vsevolod Vlasov.
+
+ * inspector/start-end-batch-update-expected.txt: Added.
+ * inspector/start-end-batch-update.html: Added.
+ * inspector/tabbed-pane-tabs-to-show.html:
+
2012-08-21 Dominic Cooney <[email protected]>
[Chromium] Unreviewed gardening.
Modified: trunk/LayoutTests/inspector/tabbed-pane-tabs-to-show.html (126267 => 126268)
--- trunk/LayoutTests/inspector/tabbed-pane-tabs-to-show.html 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/LayoutTests/inspector/tabbed-pane-tabs-to-show.html 2012-08-22 06:58:30 UTC (rev 126268)
@@ -10,7 +10,7 @@
{
return title;
}
- return { width: width, title: title, toString: toString };
+ return { width: function() { return width; }, title: title, toString: toString };
}
var dropDownButtonMeasuredWidth = 10;
Modified: trunk/Source/WebCore/ChangeLog (126267 => 126268)
--- trunk/Source/WebCore/ChangeLog 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/Source/WebCore/ChangeLog 2012-08-22 06:58:30 UTC (rev 126268)
@@ -1,3 +1,35 @@
+2012-08-21 Pavel Feldman <[email protected]>
+
+ Web Inspector: TabbedPane: measure tab widths in batches.
+ https://bugs.webkit.org/show_bug.cgi?id=94484
+
+ Reviewed by Vsevolod Vlasov.
+
+ - Introduces global batch update schema
+ - Migrates Toolbar and TabbedPane to the new schema
+
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel):
+ * inspector/front-end/TabbedPane.js:
+ (WebInspector.TabbedPane.prototype.appendTab):
+ (WebInspector.TabbedPane.prototype._updateTabElements):
+ (WebInspector.TabbedPane.prototype._innerUpdateTabElements):
+ (WebInspector.TabbedPane.prototype._updateWidths):
+ (WebInspector.TabbedPane.prototype._measureWidths):
+ (WebInspector.TabbedPaneTab):
+ (WebInspector.TabbedPaneTab.prototype.width):
+ (WebInspector.TabbedPaneTab.prototype.setWidth):
+ * inspector/front-end/Toolbar.js:
+ (WebInspector.Toolbar):
+ (WebInspector.Toolbar.prototype._updateDropdownButtonAndHideDropdown):
+ (WebInspector.Toolbar.prototype._innerUpdateDropdownButtonAndHideDropdown):
+ * inspector/front-end/UIUtils.js:
+ (WebInspector.startBatchUpdate):
+ (WebInspector.invokeOnceAfterBatchUpdate.get if):
+ (WebInspector.invokeOnceAfterBatchUpdate):
+ * inspector/front-end/inspector.js:
+ * inspector/front-end/utilities.js:
+
2012-08-21 Kentaro Hara <[email protected]>
[V8] Move String related code in V8Binding to a separate file
Modified: trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js (126267 => 126268)
--- trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/Source/WebCore/inspector/front-end/ScriptsPanel.js 2012-08-22 06:58:30 UTC (rev 126268)
@@ -185,9 +185,11 @@
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ExecutionLineChanged, this._executionLineChanged, this);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
+ WebInspector.startBatchUpdate();
var uiSourceCodes = this._workspace.uiSourceCodes();
for (var i = 0; i < uiSourceCodes.length; ++i)
this._addUISourceCode(uiSourceCodes[i]);
+ WebInspector.endBatchUpdate();
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.UISourceCodeProvider.Events.UISourceCodeReplaced, this._uiSourceCodeReplaced, this);
Modified: trunk/Source/WebCore/inspector/front-end/TabbedPane.js (126267 => 126268)
--- trunk/Source/WebCore/inspector/front-end/TabbedPane.js 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/Source/WebCore/inspector/front-end/TabbedPane.js 2012-08-22 06:58:30 UTC (rev 126268)
@@ -101,7 +101,7 @@
*/
appendTab: function(id, tabTitle, view, tabTooltip, userGesture)
{
- var tab = new WebInspector.TabbedPaneTab(this, this._tabsElement, id, tabTitle, this._closeableTabs, view, tabTooltip);
+ var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, this._closeableTabs, view, tabTooltip);
this._tabsById[id] = tab;
this._tabs.push(tab);
@@ -254,6 +254,11 @@
_updateTabElements: function()
{
+ WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
+ },
+
+ _innerUpdateTabElements: function()
+ {
if (!this.isShowing())
return;
@@ -265,9 +270,7 @@
if (!this._measuredDropDownButtonWidth)
this._measureDropDownButton();
- if (this._shrinkableTabs)
- this._updateWidths();
-
+ this._updateWidths();
this._updateTabsDropDown();
},
@@ -374,18 +377,46 @@
_updateWidths: function()
{
- var measuredWidths = [];
- for (var tabId in this._tabs)
- measuredWidths.push(this._tabs[tabId].measuredWidth);
-
- var maxWidth = this._calculateMaxWidth(measuredWidths, this._totalWidth());
-
+ var measuredWidths = this._measureWidths();
+ var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE;
+
+ var i = 0;
for (var tabId in this._tabs) {
var tab = this._tabs[tabId];
- tab.width = Math.min(tab.measuredWidth, maxWidth);
+ tab.setWidth(Math.min(maxWidth, measuredWidths[i++]));
}
},
+ _measureWidths: function()
+ {
+ // Add all elements to measure into this._tabsElement
+ var measuringTabElements = [];
+ for (var tabId in this._tabs) {
+ var tab = this._tabs[tabId];
+ if (typeof tab._measuredWidth === "number")
+ continue;
+ var measuringTabElement = tab._createTabElement(true);
+ measuringTabElement.__tab = tab;
+ measuringTabElements.push(measuringTabElement);
+ this._tabsElement.appendChild(measuringTabElement);
+ }
+
+ // Perform measurement
+ for (var i = 0; i < measuringTabElements.length; ++i)
+ measuringTabElements[i].__tab._measuredWidth = measuringTabElements[i].getBoundingClientRect().width;
+
+ // Nuke elements from the UI
+ for (var i = 0; i < measuringTabElements.length; ++i)
+ measuringTabElements[i].parentElement.removeChild(measuringTabElements[i]);
+
+ // Combine the results.
+ var measuredWidths = [];
+ for (var tabId in this._tabs)
+ measuredWidths.push(this._tabs[tabId]._measuredWidth);
+
+ return measuredWidths;
+ },
+
/**
* @param {Array.<number>} measuredWidths
* @param {number} totalWidth
@@ -429,7 +460,7 @@
var totalTabsWidth = 0;
for (var i = 0; i < tabsHistory.length; ++i) {
- totalTabsWidth += tabsHistory[i].width;
+ totalTabsWidth += tabsHistory[i].width();
var minimalRequiredWidth = totalTabsWidth;
if (i !== tabsHistory.length - 1)
minimalRequiredWidth += measuredDropDownButtonWidth;
@@ -510,18 +541,16 @@
/**
* @constructor
* @param {WebInspector.TabbedPane} tabbedPane
- * @param {Element} measureElement
* @param {string} id
* @param {string} title
* @param {boolean} closeable
* @param {WebInspector.View} view
* @param {string=} tooltip
*/
-WebInspector.TabbedPaneTab = function(tabbedPane, measureElement, id, title, closeable, view, tooltip)
+WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip)
{
this._closeable = closeable;
this._tabbedPane = tabbedPane;
- this._measureElement = measureElement;
this._id = id;
this._title = title;
this._tooltip = tooltip;
@@ -599,25 +628,16 @@
/**
* @return {number}
*/
- get measuredWidth()
+ width: function()
{
- if (typeof(this._measuredWidth) !== "undefined")
- return this._measuredWidth;
-
- this._measure();
- return this._measuredWidth;
+ return this._width;
},
/**
- * @return {number}
+ * @param {number} width
*/
- get width()
+ setWidth: function(width)
{
- return this._width || this.measuredWidth;
- },
-
- set width(width)
- {
this.tabElement.style.width = width + "px";
this._width = width;
},
@@ -657,14 +677,6 @@
return tabElement;
},
- _measure: function()
- {
- var measuringTabElement = this._createTabElement(true);
- this._measureElement.appendChild(measuringTabElement);
- this._measuredWidth = measuringTabElement.getBoundingClientRect().width;
- this._measureElement.removeChild(measuringTabElement);
- },
-
/**
* @param {Event} event
*/
Modified: trunk/Source/WebCore/inspector/front-end/Toolbar.js (126267 => 126268)
--- trunk/Source/WebCore/inspector/front-end/Toolbar.js 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/Source/WebCore/inspector/front-end/Toolbar.js 2012-08-22 06:58:30 UTC (rev 126268)
@@ -42,20 +42,9 @@
document.getElementById("close-button-left").addEventListener("click", this._onClose, true);
document.getElementById("close-button-right").addEventListener("click", this._onClose, true);
- this._coalescingLevel = 0;
}
WebInspector.Toolbar.prototype = {
- /**
- * @param {boolean} enabled
- */
- setCoalescingUpdate: function(enabled)
- {
- this._coalescingLevel += enabled ? 1 : -1;
- if (!this._coalescingLevel)
- this._updateDropdownButtonAndHideDropdown();
- },
-
resize: function()
{
this._updateDropdownButtonAndHideDropdown();
@@ -179,8 +168,11 @@
_updateDropdownButtonAndHideDropdown: function()
{
- if (this._coalescingLevel)
- return;
+ WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateDropdownButtonAndHideDropdown);
+ },
+
+ _innerUpdateDropdownButtonAndHideDropdown: function()
+ {
this._setDropdownVisible(false);
var toolbar = document.getElementById("toolbar");
Modified: trunk/Source/WebCore/inspector/front-end/UIUtils.js (126267 => 126268)
--- trunk/Source/WebCore/inspector/front-end/UIUtils.js 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/Source/WebCore/inspector/front-end/UIUtils.js 2012-08-22 06:58:30 UTC (rev 126268)
@@ -1109,6 +1109,51 @@
return true;
}
+WebInspector._coalescingLevel = 0;
+
+WebInspector.startBatchUpdate = function()
+{
+ if (!WebInspector._coalescingLevel)
+ WebInspector._postUpdateHandlers = new Map();
+ WebInspector._coalescingLevel++;
+}
+
+WebInspector.endBatchUpdate = function()
+{
+ if (--WebInspector._coalescingLevel)
+ return;
+
+ var handlers = WebInspector._postUpdateHandlers;
+ delete WebInspector._postUpdateHandlers;
+
+ var keys = handlers.keys();
+ for (var i = 0; i < keys.length; ++i) {
+ var object = keys[i];
+ var methods = handlers.get(object).keys();
+ for (var j = 0; j < methods.length; ++j)
+ methods[j].call(object);
+ }
+}
+
+/**
+ * @param {Object} object
+ * @param {function()} method
+ */
+WebInspector.invokeOnceAfterBatchUpdate = function(object, method)
+{
+ if (!WebInspector._coalescingLevel) {
+ method.call(object);
+ return;
+ }
+
+ var methods = WebInspector._postUpdateHandlers.get(object);
+ if (!methods) {
+ methods = new Map();
+ WebInspector._postUpdateHandlers.put(object, methods);
+ }
+ methods.put(method);
+}
+
;(function() {
function windowLoaded()
Modified: trunk/Source/WebCore/inspector/front-end/inspector.js (126267 => 126268)
--- trunk/Source/WebCore/inspector/front-end/inspector.js 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/Source/WebCore/inspector/front-end/inspector.js 2012-08-22 06:58:30 UTC (rev 126268)
@@ -527,11 +527,11 @@
WebInspector._installDockToRight();
this.toolbar = new WebInspector.Toolbar();
- this.toolbar.setCoalescingUpdate(true);
+ WebInspector.startBatchUpdate();
var panelDescriptors = this._panelDescriptors();
for (var i = 0; i < panelDescriptors.length; ++i)
WebInspector.inspectorView.addPanel(panelDescriptors[i]);
- this.toolbar.setCoalescingUpdate(false);
+ WebInspector.endBatchUpdate();
this.addMainEventListeners(document);
WebInspector.registerLinkifierPlugin(this._profilesLinkifier.bind(this));
Modified: trunk/Source/WebCore/inspector/front-end/utilities.js (126267 => 126268)
--- trunk/Source/WebCore/inspector/front-end/utilities.js 2012-08-22 06:47:38 UTC (rev 126267)
+++ trunk/Source/WebCore/inspector/front-end/utilities.js 2012-08-22 06:58:30 UTC (rev 126268)
@@ -690,42 +690,57 @@
objectIdentifier = ++Map._lastObjectIdentifier;
key.__identifier = objectIdentifier;
}
- this._map[objectIdentifier] = value;
+ this._map[objectIdentifier] = [key, value];
},
/**
* @param {Object} key
- * @return {Object} value
*/
remove: function(key)
{
var result = this._map[key.__identifier];
delete this._map[key.__identifier];
- return result;
+ return result ? result[1] : undefined;
},
-
+
+ /**
+ * @return {Array.<Object>}
+ */
+ keys: function()
+ {
+ return this._list(0);
+ },
+
values: function()
{
+ return this._list(1);
+ },
+
+ /**
+ * @param {number} index
+ */
+ _list: function(index)
+ {
var result = [];
for (var objectIdentifier in this._map)
- result.push(this._map[objectIdentifier]);
+ result.push(this._map[objectIdentifier][index]);
return result;
},
-
+
/**
* @param {Object} key
*/
get: function(key)
{
- return this._map[key.__identifier];
+ var entry = this._map[key.__identifier];
+ return entry ? entry[1] : undefined;
},
clear: function()
{
this._map = {};
}
-};
-
+}
/**
* @param {string} url
* @param {boolean=} async