| OLD | NEW |
| 1 | |
| 2 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 5 | |
| 6 /** | 4 /** |
| 7 * @constructor | 5 * @unrestricted |
| 8 * @param {!WebInspector.SourcesPanel} sourcesPanel | |
| 9 * @param {!WebInspector.Workspace} workspace | |
| 10 */ | 6 */ |
| 11 WebInspector.WorkspaceMappingTip = function(sourcesPanel, workspace) | 7 WebInspector.WorkspaceMappingTip = class { |
| 12 { | 8 /** |
| 9 * @param {!WebInspector.SourcesPanel} sourcesPanel |
| 10 * @param {!WebInspector.Workspace} workspace |
| 11 */ |
| 12 constructor(sourcesPanel, workspace) { |
| 13 this._sourcesPanel = sourcesPanel; | 13 this._sourcesPanel = sourcesPanel; |
| 14 this._workspace = workspace; | 14 this._workspace = workspace; |
| 15 | 15 |
| 16 this._sourcesView = this._sourcesPanel.sourcesView(); | 16 this._sourcesView = this._sourcesPanel.sourcesView(); |
| 17 this._workspaceInfobarDisabledSetting = WebInspector.settings.createSetting(
"workspaceInfobarDisabled", false); | 17 this._workspaceInfobarDisabledSetting = WebInspector.settings.createSetting(
'workspaceInfobarDisabled', false); |
| 18 this._workspaceMappingInfobarDisabledSetting = WebInspector.settings.createS
etting("workspaceMappingInfobarDisabled", false); | 18 this._workspaceMappingInfobarDisabledSetting = |
| 19 WebInspector.settings.createSetting('workspaceMappingInfobarDisabled', f
alse); |
| 19 | 20 |
| 20 if (this._workspaceInfobarDisabledSetting.get() && this._workspaceMappingInf
obarDisabledSetting.get()) | 21 if (this._workspaceInfobarDisabledSetting.get() && this._workspaceMappingInf
obarDisabledSetting.get()) |
| 22 return; |
| 23 this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSel
ected, this._editorSelected.bind(this)); |
| 24 WebInspector.persistence.addEventListener( |
| 25 WebInspector.Persistence.Events.BindingCreated, this._bindingCreated, th
is); |
| 26 } |
| 27 |
| 28 /** |
| 29 * @param {!WebInspector.Event} event |
| 30 */ |
| 31 _bindingCreated(event) { |
| 32 var binding = /** @type {!WebInspector.PersistenceBinding} */ (event.data); |
| 33 if (binding.network[WebInspector.WorkspaceMappingTip._infobarSymbol]) |
| 34 binding.network[WebInspector.WorkspaceMappingTip._infobarSymbol].dispose()
; |
| 35 if (binding.fileSystem[WebInspector.WorkspaceMappingTip._infobarSymbol]) |
| 36 binding.fileSystem[WebInspector.WorkspaceMappingTip._infobarSymbol].dispos
e(); |
| 37 } |
| 38 |
| 39 /** |
| 40 * @param {!WebInspector.Event} event |
| 41 */ |
| 42 _editorSelected(event) { |
| 43 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); |
| 44 if (this._editorSelectedTimer) |
| 45 clearTimeout(this._editorSelectedTimer); |
| 46 this._editorSelectedTimer = setTimeout(this._updateSuggestedMappingInfobar.b
ind(this, uiSourceCode), 3000); |
| 47 } |
| 48 |
| 49 /** |
| 50 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 51 */ |
| 52 _updateSuggestedMappingInfobar(uiSourceCode) { |
| 53 var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode); |
| 54 |
| 55 if (!uiSourceCodeFrame.isShowing()) |
| 56 return; |
| 57 if (uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol]) |
| 58 return; |
| 59 |
| 60 // First try mapping filesystem -> network. |
| 61 if (!this._workspaceMappingInfobarDisabledSetting.get() && |
| 62 uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem)
{ |
| 63 if (WebInspector.persistence.binding(uiSourceCode)) |
| 21 return; | 64 return; |
| 22 this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSel
ected, this._editorSelected.bind(this)); | 65 |
| 23 WebInspector.persistence.addEventListener(WebInspector.Persistence.Events.Bi
ndingCreated, this._bindingCreated, this); | 66 var networkProjects = this._workspace.projectsForType(WebInspector.project
Types.Network); |
| 67 networkProjects = |
| 68 networkProjects.concat(this._workspace.projectsForType(WebInspector.pr
ojectTypes.ContentScripts)); |
| 69 for (var i = 0; i < networkProjects.length; ++i) { |
| 70 var name = uiSourceCode.name(); |
| 71 var networkUiSourceCodes = networkProjects[i].uiSourceCodes(); |
| 72 for (var j = 0; j < networkUiSourceCodes.length; ++j) { |
| 73 if (networkUiSourceCodes[j].name() === name && this._isLocalHost(netwo
rkUiSourceCodes[j].url())) { |
| 74 this._showMappingInfobar(uiSourceCode, false); |
| 75 return; |
| 76 } |
| 77 } |
| 78 } |
| 79 } |
| 80 |
| 81 // Then map network -> filesystem. |
| 82 if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || |
| 83 uiSourceCode.project().type() === WebInspector.projectTypes.ContentScrip
ts) { |
| 84 // Suggest for localhost only. |
| 85 if (!this._isLocalHost(uiSourceCode.url()) || WebInspector.persistence.bin
ding(uiSourceCode)) |
| 86 return; |
| 87 |
| 88 var filesystemProjects = this._workspace.projectsForType(WebInspector.proj
ectTypes.FileSystem); |
| 89 for (var i = 0; i < filesystemProjects.length; ++i) { |
| 90 var name = uiSourceCode.name(); |
| 91 var fsUiSourceCodes = filesystemProjects[i].uiSourceCodes(); |
| 92 for (var j = 0; j < fsUiSourceCodes.length; ++j) { |
| 93 if (fsUiSourceCodes[j].name() === name) { |
| 94 this._showMappingInfobar(uiSourceCode, true); |
| 95 return; |
| 96 } |
| 97 } |
| 98 } |
| 99 |
| 100 this._showWorkspaceInfobar(uiSourceCode); |
| 101 } |
| 102 } |
| 103 |
| 104 /** |
| 105 * @param {string} url |
| 106 * @return {boolean} |
| 107 */ |
| 108 _isLocalHost(url) { |
| 109 var parsedURL = url.asParsedURL(); |
| 110 return !!parsedURL && parsedURL.host === 'localhost'; |
| 111 } |
| 112 |
| 113 /** |
| 114 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 115 */ |
| 116 _showWorkspaceInfobar(uiSourceCode) { |
| 117 var infobar = WebInspector.Infobar.create( |
| 118 WebInspector.Infobar.Type.Info, |
| 119 WebInspector.UIString('Serving from the file system? Add your files into
the workspace.'), |
| 120 this._workspaceInfobarDisabledSetting); |
| 121 if (!infobar) |
| 122 return; |
| 123 infobar.createDetailsRowMessage(WebInspector.UIString( |
| 124 'If you add files into your DevTools workspace, your changes will be per
sisted to disk.')); |
| 125 infobar.createDetailsRowMessage( |
| 126 WebInspector.UIString('To add a folder into the workspace, drag and drop
it into the Sources panel.')); |
| 127 this._appendInfobar(uiSourceCode, infobar); |
| 128 } |
| 129 |
| 130 /** |
| 131 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 132 * @param {boolean} isNetwork |
| 133 */ |
| 134 _showMappingInfobar(uiSourceCode, isNetwork) { |
| 135 var title; |
| 136 if (isNetwork) |
| 137 title = WebInspector.UIString('Map network resource \'%s\' to workspace?',
uiSourceCode.url()); |
| 138 else |
| 139 title = WebInspector.UIString('Map workspace resource \'%s\' to network?',
uiSourceCode.url()); |
| 140 |
| 141 var infobar = WebInspector.Infobar.create( |
| 142 WebInspector.Infobar.Type.Info, title, this._workspaceMappingInfobarDisa
bledSetting); |
| 143 if (!infobar) |
| 144 return; |
| 145 infobar.createDetailsRowMessage(WebInspector.UIString( |
| 146 '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.')); |
| 147 infobar.createDetailsRowMessage(WebInspector.UIString('Use context menu to e
stablish the mapping at any time.')); |
| 148 var anchor = createElementWithClass('a', 'link'); |
| 149 anchor.textContent = WebInspector.UIString('Establish the mapping now...'); |
| 150 anchor.addEventListener('click', this._establishTheMapping.bind(this, uiSour
ceCode), false); |
| 151 infobar.createDetailsRowMessage('').appendChild(anchor); |
| 152 this._appendInfobar(uiSourceCode, infobar); |
| 153 } |
| 154 |
| 155 /** |
| 156 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 157 * @param {?Event} event |
| 158 */ |
| 159 _establishTheMapping(uiSourceCode, event) { |
| 160 event.consume(true); |
| 161 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) |
| 162 this._sourcesPanel.mapFileSystemToNetwork(uiSourceCode); |
| 163 else |
| 164 this._sourcesPanel.mapNetworkToFileSystem(uiSourceCode); |
| 165 } |
| 166 |
| 167 /** |
| 168 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 169 * @param {!WebInspector.Infobar} infobar |
| 170 */ |
| 171 _appendInfobar(uiSourceCode, infobar) { |
| 172 var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode); |
| 173 |
| 174 var rowElement = |
| 175 infobar.createDetailsRowMessage(WebInspector.UIString('For more informat
ion on workspaces, refer to the ')); |
| 176 rowElement.appendChild(WebInspector.linkifyDocumentationURLAsNode( |
| 177 '../setup/setup-workflow', WebInspector.UIString('workspaces documentati
on'))); |
| 178 rowElement.createTextChild('.'); |
| 179 uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol] = infobar; |
| 180 uiSourceCodeFrame.attachInfobars([infobar]); |
| 181 WebInspector.runCSSAnimationOnce(infobar.element, 'source-frame-infobar-anim
ation'); |
| 182 } |
| 24 }; | 183 }; |
| 25 | 184 |
| 26 WebInspector.WorkspaceMappingTip._infobarSymbol = Symbol("infobar"); | 185 WebInspector.WorkspaceMappingTip._infobarSymbol = Symbol('infobar'); |
| 27 | |
| 28 WebInspector.WorkspaceMappingTip.prototype = { | |
| 29 /** | |
| 30 * @param {!WebInspector.Event} event | |
| 31 */ | |
| 32 _bindingCreated: function(event) | |
| 33 { | |
| 34 var binding = /** @type {!WebInspector.PersistenceBinding} */(event.data
); | |
| 35 if (binding.network[WebInspector.WorkspaceMappingTip._infobarSymbol]) | |
| 36 binding.network[WebInspector.WorkspaceMappingTip._infobarSymbol].dis
pose(); | |
| 37 if (binding.fileSystem[WebInspector.WorkspaceMappingTip._infobarSymbol]) | |
| 38 binding.fileSystem[WebInspector.WorkspaceMappingTip._infobarSymbol].
dispose(); | |
| 39 }, | |
| 40 | |
| 41 /** | |
| 42 * @param {!WebInspector.Event} event | |
| 43 */ | |
| 44 _editorSelected: function(event) | |
| 45 { | |
| 46 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data
); | |
| 47 if (this._editorSelectedTimer) | |
| 48 clearTimeout(this._editorSelectedTimer); | |
| 49 this._editorSelectedTimer = setTimeout(this._updateSuggestedMappingInfob
ar.bind(this, uiSourceCode), 3000); | |
| 50 }, | |
| 51 | |
| 52 /** | |
| 53 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 54 */ | |
| 55 _updateSuggestedMappingInfobar: function(uiSourceCode) | |
| 56 { | |
| 57 var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode); | |
| 58 | |
| 59 if (!uiSourceCodeFrame.isShowing()) | |
| 60 return; | |
| 61 if (uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol]) | |
| 62 return; | |
| 63 | |
| 64 // First try mapping filesystem -> network. | |
| 65 if (!this._workspaceMappingInfobarDisabledSetting.get() && uiSourceCode.
project().type() === WebInspector.projectTypes.FileSystem) { | |
| 66 if (WebInspector.persistence.binding(uiSourceCode)) | |
| 67 return; | |
| 68 | |
| 69 var networkProjects = this._workspace.projectsForType(WebInspector.p
rojectTypes.Network); | |
| 70 networkProjects = networkProjects.concat(this._workspace.projectsFor
Type(WebInspector.projectTypes.ContentScripts)); | |
| 71 for (var i = 0; i < networkProjects.length; ++i) { | |
| 72 var name = uiSourceCode.name(); | |
| 73 var networkUiSourceCodes = networkProjects[i].uiSourceCodes(); | |
| 74 for (var j = 0; j < networkUiSourceCodes.length; ++j) { | |
| 75 if (networkUiSourceCodes[j].name() === name && this._isLocal
Host(networkUiSourceCodes[j].url())) { | |
| 76 this._showMappingInfobar(uiSourceCode, false); | |
| 77 return; | |
| 78 } | |
| 79 } | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 // Then map network -> filesystem. | |
| 84 if (uiSourceCode.project().type() === WebInspector.projectTypes.Network
|| uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) { | |
| 85 // Suggest for localhost only. | |
| 86 if (!this._isLocalHost(uiSourceCode.url()) || WebInspector.persisten
ce.binding(uiSourceCode)) | |
| 87 return; | |
| 88 | |
| 89 var filesystemProjects = this._workspace.projectsForType(WebInspecto
r.projectTypes.FileSystem); | |
| 90 for (var i = 0; i < filesystemProjects.length; ++i) { | |
| 91 var name = uiSourceCode.name(); | |
| 92 var fsUiSourceCodes = filesystemProjects[i].uiSourceCodes(); | |
| 93 for (var j = 0; j < fsUiSourceCodes.length; ++j) { | |
| 94 if (fsUiSourceCodes[j].name() === name) { | |
| 95 this._showMappingInfobar(uiSourceCode, true); | |
| 96 return; | |
| 97 } | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 this._showWorkspaceInfobar(uiSourceCode); | |
| 102 } | |
| 103 }, | |
| 104 | |
| 105 /** | |
| 106 * @param {string} url | |
| 107 * @return {boolean} | |
| 108 */ | |
| 109 _isLocalHost: function(url) | |
| 110 { | |
| 111 var parsedURL = url.asParsedURL(); | |
| 112 return !!parsedURL && parsedURL.host === "localhost"; | |
| 113 }, | |
| 114 | |
| 115 /** | |
| 116 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 117 */ | |
| 118 _showWorkspaceInfobar: function(uiSourceCode) | |
| 119 { | |
| 120 var infobar = WebInspector.Infobar.create(WebInspector.Infobar.Type.Info
, WebInspector.UIString("Serving from the file system? Add your files into the w
orkspace."), this._workspaceInfobarDisabledSetting); | |
| 121 if (!infobar) | |
| 122 return; | |
| 123 infobar.createDetailsRowMessage(WebInspector.UIString("If you add files
into your DevTools workspace, your changes will be persisted to disk.")); | |
| 124 infobar.createDetailsRowMessage(WebInspector.UIString("To add a folder i
nto the workspace, drag and drop it into the Sources panel.")); | |
| 125 this._appendInfobar(uiSourceCode, infobar); | |
| 126 }, | |
| 127 | |
| 128 /** | |
| 129 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 130 * @param {boolean} isNetwork | |
| 131 */ | |
| 132 _showMappingInfobar: function(uiSourceCode, isNetwork) | |
| 133 { | |
| 134 var title; | |
| 135 if (isNetwork) | |
| 136 title = WebInspector.UIString("Map network resource '%s' to workspac
e?", uiSourceCode.url()); | |
| 137 else | |
| 138 title = WebInspector.UIString("Map workspace resource '%s' to networ
k?", uiSourceCode.url()); | |
| 139 | |
| 140 var infobar = WebInspector.Infobar.create(WebInspector.Infobar.Type.Info
, title, this._workspaceMappingInfobarDisabledSetting); | |
| 141 if (!infobar) | |
| 142 return; | |
| 143 infobar.createDetailsRowMessage(WebInspector.UIString("You can map files
in your workspace to the ones loaded over the network. As a result, changes mad
e in DevTools will be persisted to disk.")); | |
| 144 infobar.createDetailsRowMessage(WebInspector.UIString("Use context menu
to establish the mapping at any time.")); | |
| 145 var anchor = createElementWithClass("a", "link"); | |
| 146 anchor.textContent = WebInspector.UIString("Establish the mapping now...
"); | |
| 147 anchor.addEventListener("click", this._establishTheMapping.bind(this, ui
SourceCode), false); | |
| 148 infobar.createDetailsRowMessage("").appendChild(anchor); | |
| 149 this._appendInfobar(uiSourceCode, infobar); | |
| 150 }, | |
| 151 | |
| 152 /** | |
| 153 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 154 * @param {?Event} event | |
| 155 */ | |
| 156 _establishTheMapping: function(uiSourceCode, event) | |
| 157 { | |
| 158 event.consume(true); | |
| 159 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSyst
em) | |
| 160 this._sourcesPanel.mapFileSystemToNetwork(uiSourceCode); | |
| 161 else | |
| 162 this._sourcesPanel.mapNetworkToFileSystem(uiSourceCode); | |
| 163 }, | |
| 164 | |
| 165 /** | |
| 166 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 167 * @param {!WebInspector.Infobar} infobar | |
| 168 */ | |
| 169 _appendInfobar: function(uiSourceCode, infobar) | |
| 170 { | |
| 171 var uiSourceCodeFrame = this._sourcesView.viewForFile(uiSourceCode); | |
| 172 | |
| 173 var rowElement = infobar.createDetailsRowMessage(WebInspector.UIString("
For more information on workspaces, refer to the ")); | |
| 174 rowElement.appendChild(WebInspector.linkifyDocumentationURLAsNode("../se
tup/setup-workflow", WebInspector.UIString("workspaces documentation"))); | |
| 175 rowElement.createTextChild("."); | |
| 176 uiSourceCode[WebInspector.WorkspaceMappingTip._infobarSymbol] = infobar; | |
| 177 uiSourceCodeFrame.attachInfobars([infobar]); | |
| 178 WebInspector.runCSSAnimationOnce(infobar.element, "source-frame-infobar-
animation"); | |
| 179 } | |
| 180 }; | |
| OLD | NEW |