Log Message
Web Inspector: load heap snapshot implementation. https://bugs.webkit.org/show_bug.cgi?id=86097
The idea is to have a hidden file selector control. When the user select a context menu item or click a button we redirect this user-action to file selector. As result we see the standard file selector dialog. When the user selects a file we load it's chunks and push the chunks to the worker. The loaded snapshot can be completely unrelated to the current page. Thats why we have to skip range selection options in Summary tab. Reviewed by Yury Semikhatsky. * English.lproj/localizedStrings.js: * inspector/front-end/CSSSelectorProfileView.js: (WebInspector.CSSSelectorProfileType.prototype.createTemporaryProfile): now it accepts a custom title. * inspector/front-end/HeapSnapshotView.js: (WebInspector.HeapSnapshotView.prototype._updateFilterOptions): we have to skip the profiles loaded from file because there is no guaranty t (WebInspector.HeapSnapshotProfileType.prototype.createTemporaryProfile): now it accepts a custom title. (WebInspector.HeapSnapshotProfileType.prototype.createProfile): cosmetic changes. (WebInspector.HeapProfileHeader): (WebInspector.HeapProfileHeader.prototype._setupWorker): a common part was extracted from load method and reused in loadFromFile. (WebInspector.HeapProfileHeader.prototype._saveStatusUpdate): cosmetic changes. (WebInspector.HeapProfileHeader.prototype.finishHeapSnapshot): (WebInspector.HeapProfileHeader.prototype.canSaveToFile): cosmetic rename for better consistency with 'load' part. (WebInspector.HeapProfileHeader.prototype.saveToFile): cosmetic rename for better consistency with 'load' part. (WebInspector.HeapProfileHeader.prototype.canLoadFromFile): cosmetic rename for better consistency with 'load' part. (WebInspector.HeapProfileHeader.prototype.loadFromFile): chunk based file loader. (WebInspector.HeapProfileHeader.prototype.loadFromFile.loadNextChunk): (WebInspector.HeapProfileHeader.prototype.loadFromFile.onLoad): * inspector/front-end/ProfileView.js: (WebInspector.CPUProfileType.prototype.createTemporaryProfile): now it accepts a custom title. * inspector/front-end/ProfilesPanel.js: (WebInspector.ProfileType.prototype.createTemporaryProfile): now it accepts a custom title. (WebInspector.ProfileHeader.prototype.canSaveToFile): cosmetic rename for better consistency with 'load' part. (WebInspector.ProfileHeader.prototype.saveToFile): cosmetic rename for better consistency with 'load' part. (WebInspector.ProfileHeader.prototype.canLoadFromFile): default implementation for 'load' part. (WebInspector.ProfileHeader.prototype.loadFromFile): default implementation for 'load' part. (WebInspector.ProfilesPanel.prototype._createFileSelectorElement): (WebInspector.ProfilesPanel.prototype._loadFromFile): (WebInspector.ProfileSidebarTreeElement.prototype.handleContextMenuEvent):
Modified Paths
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/English.lproj/localizedStrings.js
- trunk/Source/WebCore/inspector/front-end/CSSSelectorProfileView.js
- trunk/Source/WebCore/inspector/front-end/HeapSnapshotView.js
- trunk/Source/WebCore/inspector/front-end/ProfileView.js
- trunk/Source/WebCore/inspector/front-end/ProfilesPanel.js
Diff
Modified: trunk/Source/WebCore/ChangeLog (116763 => 116764)
--- trunk/Source/WebCore/ChangeLog 2012-05-11 13:49:17 UTC (rev 116763)
+++ trunk/Source/WebCore/ChangeLog 2012-05-11 13:53:30 UTC (rev 116764)
@@ -1,3 +1,75 @@
+2012-05-11 Ilya Tikhonovsky <loi...@chromium.org>
+
+ Web Inspector: load heap snapshot implementation.
+ https://bugs.webkit.org/show_bug.cgi?id=86097
+
+ The idea is to have a hidden file selector control.
+ When the user select a context menu item or click a button
+ we redirect this user-action to file selector.
+ As result we see the standard file selector dialog.
+ When the user selects a file we load it's chunks and push the chunks to the worker.
+ The loaded snapshot can be completely unrelated to the current page.
+ Thats why we have to skip range selection options in Summary tab.
+
+ Reviewed by Yury Semikhatsky.
+
+ * English.lproj/localizedStrings.js:
+ * inspector/front-end/CSSSelectorProfileView.js:
+ (WebInspector.CSSSelectorProfileType.prototype.createTemporaryProfile): now it accepts a custom title.
+ * inspector/front-end/HeapSnapshotView.js:
+ (WebInspector.HeapSnapshotView.prototype._updateFilterOptions): we have to skip the profiles loaded from file because there is no guaranty t
+ (WebInspector.HeapSnapshotProfileType.prototype.createTemporaryProfile): now it accepts a custom title.
+ (WebInspector.HeapSnapshotProfileType.prototype.createProfile): cosmetic changes.
+ (WebInspector.HeapProfileHeader):
+ (WebInspector.HeapProfileHeader.prototype._setupWorker): a common part was extracted from load method and reused in loadFromFile.
+ (WebInspector.HeapProfileHeader.prototype._saveStatusUpdate): cosmetic changes.
+ (WebInspector.HeapProfileHeader.prototype.finishHeapSnapshot):
+ (WebInspector.HeapProfileHeader.prototype.canSaveToFile): cosmetic rename for better consistency with 'load' part.
+ (WebInspector.HeapProfileHeader.prototype.saveToFile): cosmetic rename for better consistency with 'load' part.
+ (WebInspector.HeapProfileHeader.prototype.canLoadFromFile): cosmetic rename for better consistency with 'load' part.
+ (WebInspector.HeapProfileHeader.prototype.loadFromFile): chunk based file loader.
+ (WebInspector.HeapProfileHeader.prototype.loadFromFile.loadNextChunk):
+ (WebInspector.HeapProfileHeader.prototype.loadFromFile.onLoad):
+ * inspector/front-end/ProfileView.js:
+ (WebInspector.CPUProfileType.prototype.createTemporaryProfile): now it accepts a custom title.
+ * inspector/front-end/ProfilesPanel.js:
+ (WebInspector.ProfileType.prototype.createTemporaryProfile): now it accepts a custom title.
+ (WebInspector.ProfileHeader.prototype.canSaveToFile): cosmetic rename for better consistency with 'load' part.
+ (WebInspector.ProfileHeader.prototype.saveToFile): cosmetic rename for better consistency with 'load' part.
+ (WebInspector.ProfileHeader.prototype.canLoadFromFile): default implementation for 'load' part.
+ (WebInspector.ProfileHeader.prototype.loadFromFile): default implementation for 'load' part.
+ (WebInspector.ProfilesPanel.prototype._createFileSelectorElement):
+ (WebInspector.ProfilesPanel.prototype._loadFromFile):
+ (WebInspector.ProfileSidebarTreeElement.prototype.handleContextMenuEvent):
+
+2012-05-11 Dominik Röttsches <dominik.rottsc...@intel.com>
+
+ [EFL][DRT] Input Attribute Placeholder RefTests failing
+ https://bugs.webkit.org/show_bug.cgi?id=85603
+
+ Reviewed by Hajime Morita.
+
+ Refrain from overriding style coloring by theme coloring.
+ RenderThemeEfl was always overriding colors and whitespace
+ handling leading to failures in reftests that verify placeholder styling
+ which expect the user agent stylesheet to be applied correctly
+ without any color overrides. Also, leave whitespace handling untouched.
+
+ No new tests, covered by existing tests. See also
+ the LayoutTests/ChangeLog in this commit for the required
+ rebaselining.
+
+ * platform/efl/RenderThemeEfl.cpp:
+ (WebCore::RenderThemeEfl::createEdje):
+ (WebCore::RenderThemeEfl::applyEdjeColors):
+ (WebCore::RenderThemeEfl::RenderThemeEfl):
+ (WebCore::RenderThemeEfl::adjustButtonStyle):
+ (WebCore::RenderThemeEfl::adjustMenuListStyle):
+ (WebCore::RenderThemeEfl::adjustTextFieldStyle):
+ (WebCore::RenderThemeEfl::adjustSearchFieldStyle):
+ * platform/efl/RenderThemeEfl.h:
+ (RenderThemeEfl):
+
2012-05-11 Christophe Dumez <christophe.du...@intel.com>
Web Intents code only supports V8
Modified: trunk/Source/WebCore/English.lproj/localizedStrings.js
(Binary files differ)
Modified: trunk/Source/WebCore/inspector/front-end/CSSSelectorProfileView.js (116763 => 116764)
--- trunk/Source/WebCore/inspector/front-end/CSSSelectorProfileView.js 2012-05-11 13:49:17 UTC (rev 116763)
+++ trunk/Source/WebCore/inspector/front-end/CSSSelectorProfileView.js 2012-05-11 13:53:30 UTC (rev 116764)
@@ -353,11 +353,13 @@
/**
* @override
+ * @param {string=} title
* @return {WebInspector.ProfileHeader}
*/
- createTemporaryProfile: function()
+ createTemporaryProfile: function(title)
{
- return new WebInspector.ProfileHeader(WebInspector.CSSSelectorProfileType.TypeId, WebInspector.UIString("Recording\u2026"));
+ title = title || WebInspector.UIString("Recording\u2026");
+ return new WebInspector.ProfileHeader(WebInspector.CSSSelectorProfileType.TypeId, title);
},
/**
Modified: trunk/Source/WebCore/inspector/front-end/HeapSnapshotView.js (116763 => 116764)
--- trunk/Source/WebCore/inspector/front-end/HeapSnapshotView.js 2012-05-11 13:49:17 UTC (rev 116763)
+++ trunk/Source/WebCore/inspector/front-end/HeapSnapshotView.js 2012-05-11 13:53:30 UTC (rev 116764)
@@ -688,7 +688,10 @@
this.filterSelectElement.appendChild(filterOption);
}
+ if (this.profile._fromFile)
+ return;
for (var i = this.filterSelectElement.length - 1, n = list.length; i < n; ++i) {
+ var profile = ""
var filterOption = document.createElement("option");
var title = list[i].title;
if (!title.indexOf(UserInitiatedProfileName)) {
@@ -751,11 +754,13 @@
/**
* @override
+ * @param {string=} title
* @return {WebInspector.ProfileHeader}
*/
- createTemporaryProfile: function()
+ createTemporaryProfile: function(title)
{
- return new WebInspector.ProfileHeader(WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("Snapshotting\u2026"));
+ title = title || WebInspector.UIString("Snapshotting\u2026");
+ return new WebInspector.HeapProfileHeader(title);
},
/**
@@ -765,7 +770,7 @@
*/
createProfile: function(profile)
{
- return new WebInspector.HeapProfileHeader(profile.typeId, profile.title, profile.uid, profile.maxJSObjectId || 0);
+ return new WebInspector.HeapProfileHeader(profile.title, profile.uid, profile.maxJSObjectId || 0);
}
}
@@ -774,16 +779,16 @@
/**
* @constructor
* @extends {WebInspector.ProfileHeader}
- * @param {string} profileType
* @param {string} title
- * @param {number} uid
- * @param {number} maxJSObjectId
+ * @param {number=} uid
+ * @param {number=} maxJSObjectId
*/
-WebInspector.HeapProfileHeader = function(profileType, title, uid, maxJSObjectId)
+WebInspector.HeapProfileHeader = function(title, uid, maxJSObjectId)
{
- WebInspector.ProfileHeader.call(this, profileType, title, uid);
+ WebInspector.ProfileHeader.call(this, WebInspector.HeapSnapshotProfileType.TypeId, title, uid);
this.maxJSObjectId = maxJSObjectId;
this._loaded = false;
+ this._fromFile = false;
this._totalNumberOfChunks = 0;
}
@@ -799,14 +804,8 @@
return;
}
- if (!this._proxy) {
- function setProfileWait(event) {
- this.sidebarElement.wait = event.data;
- }
- var worker = new WebInspector.HeapSnapshotWorker();
- worker.addEventListener("wait", setProfileWait, this);
- this._proxy = worker.createObject("WebInspector.HeapSnapshotLoader");
- }
+ if (!this._proxy)
+ this._setupWorker();
if (this._proxy.startLoading(callback)) {
this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026");
@@ -819,6 +818,16 @@
}
},
+ _setupWorker: function()
+ {
+ function setProfileWait(event) {
+ this.sidebarElement.wait = event.data;
+ }
+ var worker = new WebInspector.HeapSnapshotWorker();
+ worker.addEventListener("wait", setProfileWait, this);
+ this._proxy = worker.createObject("WebInspector.HeapSnapshotLoader");
+ },
+
/**
* @param {WebInspector.Event} event
*/
@@ -832,7 +841,7 @@
this._savedChunksCount = 0;
WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._saveStatusUpdate, this);
} else
- this.sidebarElement.subtitle = WebInspector.UIString("Saving\u2026 %d\%", Math.floor(this._savedChunksCount * 100 / this._totalNumberOfChunks));
+ this.sidebarElement.subtitle = WebInspector.UIString("Saving\u2026 %d\%", (this._savedChunksCount * 100 / this._totalNumberOfChunks).toFixed(2));
},
/**
@@ -857,6 +866,7 @@
this.sidebarElement.subtitle = Number.bytesToString(snapshotProxy.totalSize);
this.sidebarElement.wait = false;
var worker = /** @type {WebInspector.HeapSnapshotWorker} */ snapshotProxy.worker;
+ this.isTemporary = false;
worker.startCheckingForLongRunningCalls();
}
if (this._proxy.finishLoading(parsed.bind(this)))
@@ -867,34 +877,107 @@
* @override
* @return {boolean}
*/
- canSave: function()
+ canSaveToFile: function()
{
- return this._loaded && !this._savedChunksCount && WebInspector.fileManager.canAppend();
+ return !this._fromFile && this._loaded && !this._savedChunksCount && WebInspector.fileManager.canAppend();
},
/**
* @override
*/
- save: function()
+ saveToFile: function()
{
/**
* @param {WebInspector.Event} event
*/
- function startWritingSnapshot(event)
+ function startSavingSnapshot(event)
{
if (event.data !== this._fileName)
return;
this.sidebarElement.wait = true;
this.sidebarElement.subtitle = WebInspector.UIString("Saving\u2026 %d\%", 0);
this._savedChunksCount = 0;
- WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.SavedURL, startWritingSnapshot, this);
+ WebInspector.fileManager.removeEventListener(WebInspector.FileManager.EventTypes.SavedURL, startSavingSnapshot, this);
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.AppendedToURL, this._saveStatusUpdate, this);
ProfilerAgent.getProfile(this.typeId, this.uid);
}
this._fileName = this._fileName || "Heap-" + new Date().toISO8601Compact() + ".json";
- WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.SavedURL, startWritingSnapshot, this);
+ WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.SavedURL, startSavingSnapshot, this);
WebInspector.fileManager.save(this._fileName, "", true);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ canLoadFromFile: function()
+ {
+ return false;
+ },
+
+ /**
+ * @override
+ * @param {File} file
+ */
+ loadFromFile: function(file)
+ {
+ function onError(e)
+ {
+ switch(e.target.error.code) {
+ case e.target.error.NOT_FOUND_ERR:
+ this.sidebarElement.subtitle = WebInspector.UIString("'%s' not found.", file.name);
+ break;
+ case e.target.error.NOT_READABLE_ERR:
+ this.sidebarElement.subtitle = WebInspector.UIString("'%s' is not readable", file.name);
+ break;
+ case e.target.error.ABORT_ERR:
+ break;
+ default:
+ this.sidebarElement.subtitle = WebInspector.UIString("'%s' error %d", file.name, e.target.error.code);
+ }
+ }
+
+ this._fromFile = true;
+ this.title = file.name;
+ this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026");
+ this.sidebarElement.wait = true;
+ this._setupWorker();
+ this._proxy.startLoading(function() { });
+
+ function loadNextChunk(file, reader, loadedSize)
+ {
+ var chunkSize = 10000000;
+ var size = file.size < loadedSize + chunkSize ? file.size - loadedSize : chunkSize;
+ var nextPart = file.webkitSlice(loadedSize, loadedSize + size);
+ reader.readAsText(nextPart);
+ }
+
+ /**
+ * @param {Event} event
+ */
+ function onLoad(event)
+ {
+ if (event.target.readyState !== FileReader.DONE)
+ return;
+
+ this._loadedSize += event.target.result.length;
+ this._proxy.pushJSONChunk(event.target.result);
+ this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026 %d%", (this._loadedSize * 100 / file.size).toFixed(2));
+
+ if (this._loadedSize === file.size) {
+ this._loaded = true;
+ this.finishHeapSnapshot();
+ return;
+ }
+
+ loadNextChunk(file, reader, this._loadedSize);
+ }
+
+ var reader = new FileReader();
+ reader._onload_ = onLoad.bind(this);
+ reader._onerror_ = onError;
+ this._loadedSize = 0;
+ loadNextChunk(file, reader, this._loadedSize);
}
}
Modified: trunk/Source/WebCore/inspector/front-end/ProfileView.js (116763 => 116764)
--- trunk/Source/WebCore/inspector/front-end/ProfileView.js 2012-05-11 13:49:17 UTC (rev 116763)
+++ trunk/Source/WebCore/inspector/front-end/ProfileView.js 2012-05-11 13:53:30 UTC (rev 116764)
@@ -620,11 +620,13 @@
/**
* @override
+ * @param {string=} title
* @return {WebInspector.ProfileHeader}
*/
- createTemporaryProfile: function()
+ createTemporaryProfile: function(title)
{
- return new WebInspector.ProfileHeader(WebInspector.CPUProfileType.TypeId, WebInspector.UIString("Recording\u2026"));
+ title = title || WebInspector.UIString("Recording\u2026");
+ return new WebInspector.ProfileHeader(WebInspector.CPUProfileType.TypeId, title);
},
/**
Modified: trunk/Source/WebCore/inspector/front-end/ProfilesPanel.js (116763 => 116764)
--- trunk/Source/WebCore/inspector/front-end/ProfilesPanel.js 2012-05-11 13:49:17 UTC (rev 116763)
+++ trunk/Source/WebCore/inspector/front-end/ProfilesPanel.js 2012-05-11 13:53:30 UTC (rev 116764)
@@ -91,9 +91,10 @@
// Must be implemented by subclasses.
/**
+ * @param {string=} title
* @return {WebInspector.ProfileHeader}
*/
- createTemporaryProfile: function()
+ createTemporaryProfile: function(title)
{
throw new Error("Needs implemented.");
},
@@ -145,9 +146,19 @@
/**
* @return {boolean}
*/
- canSave: function() { return false; },
+ canSaveToFile: function() { return false; },
- save: function() { throw new Error("Needs implemented"); }
+ saveToFile: function() { throw new Error("Needs implemented"); },
+
+ /**
+ * @return {boolean}
+ */
+ canLoadFromFile: function() { return false; },
+
+ /**
+ * @param {File} file
+ */
+ loadFromFile: function(file) { throw new Error("Needs implemented"); }
}
/**
@@ -210,6 +221,8 @@
if (!Capabilities.profilerCausesRecompilation || WebInspector.settings.profilerEnabled.get())
ProfilerAgent.enable(this._profilerWasEnabled.bind(this));
+
+ this._createFileSelectorElement();
}
WebInspector.ProfilesPanel.EventTypes = {
@@ -218,6 +231,41 @@
}
WebInspector.ProfilesPanel.prototype = {
+ _createFileSelectorElement: function()
+ {
+ if (this._fileSelectorElement)
+ this.element.removeChild(this._fileSelectorElement);
+
+ var fileSelectorElement = document.createElement("input");
+ fileSelectorElement.type = "file";
+ fileSelectorElement.style.zIndex = -1;
+ fileSelectorElement.style.position = "absolute";
+ fileSelectorElement._onchange_ = this._loadFromFile.bind(this);
+ this.element.appendChild(fileSelectorElement);
+ this._fileSelectorElement = fileSelectorElement;
+ },
+
+ _loadFromFile: function(event)
+ {
+ var file = this._fileSelectorElement.files[0];
+ if (!file.name.endsWith(".heapsnapshot")) {
+ WebInspector.log(WebInspector.UIString("Only heap snapshots from files with extension '.heapsnapshot' can be loaded."));
+ return;
+ }
+
+ if (!!this.findTemporaryProfile(WebInspector.HeapSnapshotProfileType.TypeId)) {
+ WebInspector.log(WebInspector.UIString("Can't load profile when other profile is recording."));
+ return;
+ }
+
+ var profileType = this.getProfileType(WebInspector.HeapSnapshotProfileType.TypeId);
+ var temporaryProfile = profileType.createTemporaryProfile(UserInitiatedProfileName + "." + file.name);
+ this.addProfileHeader(temporaryProfile);
+
+ temporaryProfile.loadFromFile(file);
+ this._createFileSelectorElement();
+ },
+
get toolbarItemLabel()
{
return WebInspector.UIString("Profiles");
@@ -1109,10 +1157,10 @@
handleContextMenuEvent: function(event)
{
var profile = ""
- if (!profile.canSave())
- return;
var contextMenu = new WebInspector.ContextMenu();
- contextMenu.appendItem(WebInspector.UIString("Save profile"), profile.save.bind(profile));
+ if (profile.canSaveToFile())
+ contextMenu.appendItem(WebInspector.UIString("Save profile\u2026"), profile.saveToFile.bind(profile));
+ contextMenu.appendItem(WebInspector.UIString("Load profile\u2026"), WebInspector.panels.profiles._fileSelectorElement.click.bind(WebInspector.panels.profiles._fileSelectorElement));
contextMenu.show(event);
}
}
_______________________________________________ webkit-changes mailing list webkit-changes@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes