blob: 35abf89dd55f2f6b683867be31eb042ad516b13c [file] [log] [blame]
// 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));
this._workspaceInfobarAllowedSetting = WebInspector.settings.createSetting("workspaceInfobarAllowed", true);
}
WebInspector.WorkspaceMappingTip._infobarSymbol = Symbol("infobar");
WebInspector.WorkspaceMappingTip.prototype = {
/**
* @param {!WebInspector.Event} event
*/
_editorSelected: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
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.Network);
networkProjects = networkProjects.concat(this._workspace.projectsForType(WebInspector.projectTypes.ContentScripts));
for (var i = 0; i < networkProjects.length; ++i) {
if (!this._isLocalHost(networkProjects[i].url()))
continue;
var name = uiSourceCode.name();
var networkUiSourceCodes = networkProjects[i].uiSourceCodes();
for (var j = 0; j < networkUiSourceCodes.length; ++j) {
if (networkUiSourceCodes[j].name() === name) {
this._showMappingInfobar(uiSourceCode, false);
return;
}
}
}
}
// Then map network -> filesystem.
if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) {
// Suggest for localhost only.
if (!this._isLocalHost(uiSourceCode.originURL()))
return;
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._showMappingInfobar(uiSourceCode, true);
return;
}
}
}
if (this._workspaceInfobarAllowedSetting.get())
this._showWorkspaceInfobar(uiSourceCode);
}
},
/**
* @param {string} url
* @return {boolean}
*/
_isLocalHost: function(url)
{
var parsedURL = url.asParsedURL();
return !!parsedURL && parsedURL.host === "localhost";
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_showWorkspaceInfobar: 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."), this._onWorkspaceInfobarDispose.bind(this));
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);
},
_onWorkspaceInfobarDispose: function()
{
this._workspaceInfobarAllowedSetting.set(false);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {boolean} isNetwork
*/
_showMappingInfobar: 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 anchor = createElementWithClass("a", "link");
anchor.textContent = WebInspector.UIString("Establish the mapping now...");
anchor.addEventListener("click", this._establishTheMapping.bind(this, uiSourceCode), false);
infobar.createDetailsRowMessage("").appendChild(anchor);
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);
var rowElement = infobar.createDetailsRowMessage(WebInspector.UIString("For more information on workspaces, refer to the "));
rowElement.appendChild(WebInspector.createDocumentationAnchor("workspaces", WebInspector.UIString("workspaces documentation")));
rowElement.createTextChild(".");
uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol] = infobar;
uiSourceCodeFrame.attachInfobars([infobar]);
WebInspector.runCSSAnimationOnce(infobar.element, "source-frame-infobar-animation");
}
}