Commit 843169d9 authored by vsevik@chromium.org's avatar vsevik@chromium.org

DevTools: Extract workspace mapping suggesting logic from sources panel.

R=pfeldman

Review URL: https://codereview.chromium.org/625843002

git-svn-id: svn://svn.chromium.org/blink/trunk@183655 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 48171caa
...@@ -502,6 +502,7 @@ ...@@ -502,6 +502,7 @@
'front_end/sources/ThreadsSidebarPane.js', 'front_end/sources/ThreadsSidebarPane.js',
'front_end/sources/UISourceCodeFrame.js', 'front_end/sources/UISourceCodeFrame.js',
'front_end/sources/WatchExpressionsSidebarPane.js', 'front_end/sources/WatchExpressionsSidebarPane.js',
'front_end/sources/WorkspaceMappingTip.js',
], ],
'devtools_temp_storage_shared_worker_js_files': [ 'devtools_temp_storage_shared_worker_js_files': [
'front_end/temp_storage_shared_worker/TempStorageSharedWorker.js', 'front_end/temp_storage_shared_worker/TempStorageSharedWorker.js',
......
...@@ -107,12 +107,11 @@ WebInspector.SourcesPanel = function(workspaceForTest) ...@@ -107,12 +107,11 @@ WebInspector.SourcesPanel = function(workspaceForTest)
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
WebInspector.targetManager.observeTargets(this); WebInspector.targetManager.observeTargets(this);
new WebInspector.WorkspaceMappingTip(this, this._workspace);
} }
WebInspector.SourcesPanel.minToolbarWidth = 215; WebInspector.SourcesPanel.minToolbarWidth = 215;
WebInspector.SourcesPanel._infobarSymbol = Symbol("infobar");
WebInspector.SourcesPanel.prototype = { WebInspector.SourcesPanel.prototype = {
/** /**
* @param {?WebInspector.Target} target * @param {?WebInspector.Target} target
...@@ -478,129 +477,6 @@ WebInspector.SourcesPanel.prototype = { ...@@ -478,129 +477,6 @@ WebInspector.SourcesPanel.prototype = {
{ {
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._editorChanged(uiSourceCode); this._editorChanged(uiSourceCode);
if (Runtime.experiments.isEnabled("suggestUsingWorkspace")) {
if (this._editorSelectedTimer)
clearTimeout(this._editorSelectedTimer);
this._editorSelectedTimer = setTimeout(this._updateSuggestedMappingInfobar.bind(this, uiSourceCode), 3000);
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_updateSuggestedMappingInfobar: function(uiSourceCode)
{
if (!this.isShowing())
return;
if (uiSourceCode[WebInspector.SourcesPanel._infobarSymbol])
return;
// First try mapping filesystem -> network.
var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode);
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
var hasMappings = !!uiSourceCode.url;
if (hasMappings)
return;
var targets = WebInspector.targetManager.targets();
for (var i = 0; i < targets.length; ++i)
targets[i].resourceTreeModel.forAllResources(matchResource.bind(this));
}
/**
* @param {!WebInspector.Resource} resource
* @return {boolean}
* @this {WebInspector.SourcesPanel}
*/
function matchResource(resource)
{
if (resource.contentURL().endsWith(uiSourceCode.name())) {
createMappingInfobar.call(this, false);
return true;
}
return false;
}
// Then map network -> filesystem.
if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) {
if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) !== uiSourceCode)
return;
var filesystemProjects = this._workspace.projectsForType(WebInspector.projectTypes.FileSystem);
for (var i = 0; i < filesystemProjects.length; ++i) {
var name = uiSourceCode.name();
var fsUiSourceCodes = filesystemProjects[i].uiSourceCodes();
for (var j = 0; j < fsUiSourceCodes.length; ++j) {
if (fsUiSourceCodes[j].name() === name) {
createMappingInfobar.call(this, true);
return;
}
}
}
// There are no matching filesystems. Suggest adding a filesystem in case of localhost.
var originURL = uiSourceCode.originURL().asParsedURL();
if (originURL && originURL.host === "localhost")
createWorkspaceInfobar();
}
/**
* @param {boolean} isNetwork
* @this {WebInspector.SourcesPanel}
*/
function createMappingInfobar(isNetwork)
{
var title;
if (isNetwork)
title = WebInspector.UIString("Map network resource '%s' to workspace?", uiSourceCode.originURL());
else
title = WebInspector.UIString("Map workspace resource '%s' to network?", uiSourceCode.path());
var infobar = new WebInspector.UISourceCodeFrame.Infobar(WebInspector.UISourceCodeFrame.Infobar.Level.Info, title);
infobar.createDetailsRowMessage(WebInspector.UIString("You can map files in your workspace to the ones loaded over the network. As a result, changes made in DevTools will be persisted to disk."));
infobar.createDetailsRowMessage(WebInspector.UIString("Use context menu to establish the mapping at any time."));
var actionLink = infobar.createDetailsRowMessage("").createChild("a");
actionLink.href = "";
actionLink.onclick = establishTheMapping.bind(this);
actionLink.textContent = WebInspector.UIString("Establish the mapping now...");
appendInfobar(infobar);
}
/**
* @param {?Event} event
* @this {WebInspector.SourcesPanel}
*/
function establishTheMapping(event)
{
event.consume(true);
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem)
this._mapFileSystemToNetwork(uiSourceCode);
else
this._mapNetworkToFileSystem(uiSourceCode);
}
function createWorkspaceInfobar()
{
var infobar = new WebInspector.UISourceCodeFrame.Infobar(WebInspector.UISourceCodeFrame.Infobar.Level.Info, WebInspector.UIString("Serving from the file system? Add your files into the workspace."));
infobar.createDetailsRowMessage(WebInspector.UIString("If you add files into your DevTools workspace, your changes will be persisted to disk."));
infobar.createDetailsRowMessage(WebInspector.UIString("To add a folder into the workspace, drag and drop it into the Sources panel."));
appendInfobar(infobar);
}
/**
* @param {!WebInspector.UISourceCodeFrame.Infobar} infobar
*/
function appendInfobar(infobar)
{
infobar.createDetailsRowMessage("").createChild("br");
var rowElement = infobar.createDetailsRowMessage(WebInspector.UIString("For more information on workspaces, refer to the "));
var a = rowElement.createChild("a");
a.textContent = "workspaces documentation";
a.href = "https://developer.chrome.com/devtools/docs/workspaces";
rowElement.createTextChild(".");
uiSourceCode[WebInspector.SourcesPanel._infobarSymbol] = infobar;
uiSourceCodeFrame.attachInfobars([infobar]);
}
}, },
/** /**
...@@ -912,7 +788,7 @@ WebInspector.SourcesPanel.prototype = { ...@@ -912,7 +788,7 @@ WebInspector.SourcesPanel.prototype = {
/** /**
* @param {!WebInspector.UISourceCode} uiSourceCode * @param {!WebInspector.UISourceCode} uiSourceCode
*/ */
_mapFileSystemToNetwork: function(uiSourceCode) mapFileSystemToNetwork: function(uiSourceCode)
{ {
WebInspector.SelectUISourceCodeForProjectTypesDialog.show(uiSourceCode.name(), [WebInspector.projectTypes.Network, WebInspector.projectTypes.ContentScripts], mapFileSystemToNetwork.bind(this), this.editorView.mainElement()) WebInspector.SelectUISourceCodeForProjectTypesDialog.show(uiSourceCode.name(), [WebInspector.projectTypes.Network, WebInspector.projectTypes.ContentScripts], mapFileSystemToNetwork.bind(this), this.editorView.mainElement())
...@@ -927,21 +803,10 @@ WebInspector.SourcesPanel.prototype = { ...@@ -927,21 +803,10 @@ WebInspector.SourcesPanel.prototype = {
} }
}, },
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_removeNetworkMapping: function(uiSourceCode)
{
if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?"))) {
this._workspace.removeMapping(uiSourceCode);
this._suggestReload();
}
},
/** /**
* @param {!WebInspector.UISourceCode} networkUISourceCode * @param {!WebInspector.UISourceCode} networkUISourceCode
*/ */
_mapNetworkToFileSystem: function(networkUISourceCode) mapNetworkToFileSystem: function(networkUISourceCode)
{ {
WebInspector.SelectUISourceCodeForProjectTypesDialog.show(networkUISourceCode.name(), [WebInspector.projectTypes.FileSystem], mapNetworkToFileSystem.bind(this), this.editorView.mainElement()) WebInspector.SelectUISourceCodeForProjectTypesDialog.show(networkUISourceCode.name(), [WebInspector.projectTypes.FileSystem], mapNetworkToFileSystem.bind(this), this.editorView.mainElement())
...@@ -956,6 +821,17 @@ WebInspector.SourcesPanel.prototype = { ...@@ -956,6 +821,17 @@ WebInspector.SourcesPanel.prototype = {
} }
}, },
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_removeNetworkMapping: function(uiSourceCode)
{
if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?"))) {
this._workspace.removeMapping(uiSourceCode);
this._suggestReload();
}
},
/** /**
* @param {!WebInspector.ContextMenu} contextMenu * @param {!WebInspector.ContextMenu} contextMenu
* @param {!WebInspector.UISourceCode} uiSourceCode * @param {!WebInspector.UISourceCode} uiSourceCode
...@@ -965,7 +841,7 @@ WebInspector.SourcesPanel.prototype = { ...@@ -965,7 +841,7 @@ WebInspector.SourcesPanel.prototype = {
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) { if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
var hasMappings = !!uiSourceCode.url; var hasMappings = !!uiSourceCode.url;
if (!hasMappings) if (!hasMappings)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this._mapFileSystemToNetwork.bind(this, uiSourceCode)); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this.mapFileSystemToNetwork.bind(this, uiSourceCode));
else else
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode)); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode));
} }
...@@ -982,7 +858,7 @@ WebInspector.SourcesPanel.prototype = { ...@@ -982,7 +858,7 @@ WebInspector.SourcesPanel.prototype = {
if (!this._workspace.projects().filter(filterProject).length) if (!this._workspace.projects().filter(filterProject).length)
return; return;
if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode) if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this._mapNetworkToFileSystem.bind(this, uiSourceCode)); contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this.mapNetworkToFileSystem.bind(this, uiSourceCode));
} }
}, },
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @constructor
* @param {!WebInspector.SourcesPanel} sourcesPanel
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.WorkspaceMappingTip = function(sourcesPanel, workspace)
{
this._sourcesPanel = sourcesPanel;
this._workspace = workspace;
this._sourcesView = this._sourcesPanel.sourcesView();
this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
}
WebInspector.WorkspaceMappingTip._infobarSymbol = Symbol("infobar");
WebInspector.WorkspaceMappingTip.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_editorSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
if (Runtime.experiments.isEnabled("suggestUsingWorkspace")) {
if (this._editorSelectedTimer)
clearTimeout(this._editorSelectedTimer);
this._editorSelectedTimer = setTimeout(this._updateSuggestedMappingInfobar.bind(this, uiSourceCode), 3000);
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_updateSuggestedMappingInfobar: function(uiSourceCode)
{
var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode);
if (!uiSourceCodeFrame.isShowing())
return;
if (uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol])
return;
// First try mapping filesystem -> network.
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
var hasMappings = !!uiSourceCode.url;
if (hasMappings)
return;
}
var networkProjects = this._workspace.projectsForType(WebInspector.projectTypes.FileSystem);
networkProjects = networkProjects.concat(this._workspace.projectsForType(WebInspector.projectTypes.ContentScripts));
for (var i = 0; i < networkProjects.length; ++i) {
var name = uiSourceCode.name();
var networkUiSourceCodes = networkProjects[i].uiSourceCodes();
for (var j = 0; j < networkUiSourceCodes.length; ++j) {
if (networkUiSourceCodes[j].name() === name) {
this._createMappingInfobar(uiSourceCode, false);
return;
}
}
}
// Then map network -> filesystem.
if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) {
if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) !== uiSourceCode)
return;
var filesystemProjects = this._workspace.projectsForType(WebInspector.projectTypes.FileSystem);
for (var i = 0; i < filesystemProjects.length; ++i) {
var name = uiSourceCode.name();
var fsUiSourceCodes = filesystemProjects[i].uiSourceCodes();
for (var j = 0; j < fsUiSourceCodes.length; ++j) {
if (fsUiSourceCodes[j].name() === name) {
this._createMappingInfobar(uiSourceCode, true);
return;
}
}
}
// There are no matching filesystems. Suggest adding a filesystem in case of localhost.
var originURL = uiSourceCode.originURL().asParsedURL();
if (originURL && originURL.host === "localhost")
this._createWorkspaceInfobar(uiSourceCode);
}
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_createWorkspaceInfobar: function(uiSourceCode)
{
var infobar = new WebInspector.UISourceCodeFrame.Infobar(WebInspector.UISourceCodeFrame.Infobar.Level.Info, WebInspector.UIString("Serving from the file system? Add your files into the workspace."));
infobar.createDetailsRowMessage(WebInspector.UIString("If you add files into your DevTools workspace, your changes will be persisted to disk."));
infobar.createDetailsRowMessage(WebInspector.UIString("To add a folder into the workspace, drag and drop it into the Sources panel."));
this._appendInfobar(uiSourceCode, infobar);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {boolean} isNetwork
*/
_createMappingInfobar: function(uiSourceCode, isNetwork)
{
var title;
if (isNetwork)
title = WebInspector.UIString("Map network resource '%s' to workspace?", uiSourceCode.originURL());
else
title = WebInspector.UIString("Map workspace resource '%s' to network?", uiSourceCode.path());
var infobar = new WebInspector.UISourceCodeFrame.Infobar(WebInspector.UISourceCodeFrame.Infobar.Level.Info, title);
infobar.createDetailsRowMessage(WebInspector.UIString("You can map files in your workspace to the ones loaded over the network. As a result, changes made in DevTools will be persisted to disk."));
infobar.createDetailsRowMessage(WebInspector.UIString("Use context menu to establish the mapping at any time."));
var actionLink = infobar.createDetailsRowMessage("").createChild("a");
actionLink.href = "";
actionLink.onclick = this._establishTheMapping.bind(this, uiSourceCode);
actionLink.textContent = WebInspector.UIString("Establish the mapping now...");
this._appendInfobar(uiSourceCode, infobar);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {?Event} event
*/
_establishTheMapping: function(uiSourceCode, event)
{
event.consume(true);
if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem)
this._sourcesPanel.mapFileSystemToNetwork(uiSourceCode);
else
this._sourcesPanel.mapNetworkToFileSystem(uiSourceCode);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {!WebInspector.UISourceCodeFrame.Infobar} infobar
*/
_appendInfobar: function(uiSourceCode, infobar)
{
var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode);
infobar.createDetailsRowMessage("").createChild("br");
var rowElement = infobar.createDetailsRowMessage(WebInspector.UIString("For more information on workspaces, refer to the "));
var a = rowElement.createChild("a");
a.textContent = "workspaces documentation";
a.href = "https://developer.chrome.com/devtools/docs/workspaces";
rowElement.createTextChild(".");
uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol] = infobar;
uiSourceCodeFrame.attachInfobars([infobar]);
}
}
...@@ -212,7 +212,8 @@ ...@@ -212,7 +212,8 @@
"AdvancedSearchView.js", "AdvancedSearchView.js",
"FileBasedSearchResultsPane.js", "FileBasedSearchResultsPane.js",
"SourcesSearchScope.js", "SourcesSearchScope.js",
"SourcesPanel.js" "SourcesPanel.js",
"WorkspaceMappingTip.js"
], ],
"skip_compilation": [ "skip_compilation": [
"jsdifflib.js" "jsdifflib.js"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment