Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * @constructor | |
| 7 * @extends {WebInspector.Object} | |
| 8 * @param {!WebInspector.Workspace} workspace | |
| 9 * @param {!WebInspector.BreakpointManager} breakpointManager | |
| 10 */ | |
| 11 WebInspector.Persistence = function(workspace, breakpointManager) | |
| 12 { | |
| 13 WebInspector.Object.call(this); | |
| 14 this._workspace = workspace; | |
| 15 this._breakpointManager = breakpointManager; | |
| 16 /** @type {!Set<!WebInspector.PersistenceBinding>} */ | |
| 17 this._bindings = new Set(); | |
| 18 this._eventListeners = [ | |
| 19 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdd ed, this._onUISourceCodeAdded, this), | |
| 20 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRem oved, this._onUISourceCodeRemoved, this), | |
| 21 workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._onProjectRemoved, this), | |
| 22 WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemM apping.Events.FileMappingAdded, this._remap, this), | |
|
dgozman
2016/09/22 19:55:53
Let's pass the fileSystemMapping.
lushnikov
2016/09/23 21:56:13
Done.
| |
| 23 WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemM apping.Events.FileMappingRemoved, this._remap, this) | |
| 24 ]; | |
| 25 } | |
|
dgozman
2016/09/22 19:55:53
Let's call this._remap().
lushnikov
2016/09/23 21:56:13
Done.
| |
| 26 | |
| 27 WebInspector.Persistence._binding = Symbol("Persistence.Binding"); | |
| 28 WebInspector.Persistence._muteCommit = Symbol("Persistence.MuteCommit"); | |
| 29 | |
| 30 WebInspector.Persistence.NodePrefix = "(function (exports, require, module, __fi lename, __dirname) { "; | |
|
dgozman
2016/09/22 19:55:53
_NodePrefix
lushnikov
2016/09/23 21:56:13
Done.
| |
| 31 WebInspector.Persistence.NodeSuffix = "\n});" | |
| 32 WebInspector.Persistence.NodeShebang = "#!/usr/bin/env node\n"; | |
| 33 | |
| 34 WebInspector.Persistence.Events = { | |
| 35 BindingCreated: Symbol("BindingCreated"), | |
| 36 BindingRemoved: Symbol("BindingRemoved") | |
| 37 } | |
| 38 | |
| 39 WebInspector.Persistence.prototype = { | |
| 40 _remap: function() | |
| 41 { | |
| 42 var bindings = this._bindings.valuesArray(); | |
| 43 for (var binding of this._bindings.valuesArray()) | |
|
dgozman
2016/09/22 19:55:53
var binding of bindings
lushnikov
2016/09/23 21:56:13
Done.
| |
| 44 this._unbind(binding.network); | |
| 45 var networkProjects = this._workspace.projectsForType(WebInspector.proje ctTypes.Network); | |
| 46 for (var networkProject of networkProjects) { | |
| 47 for (var uiSourceCode of networkProject.uiSourceCodes()) | |
| 48 this._bind(uiSourceCode); | |
| 49 } | |
| 50 }, | |
| 51 | |
| 52 /** | |
| 53 * @param {!WebInspector.Event} event | |
| 54 */ | |
| 55 _onUISourceCodeAdded: function(event) | |
| 56 { | |
| 57 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data) ; | |
| 58 this._bind(uiSourceCode); | |
| 59 }, | |
| 60 | |
| 61 /** | |
| 62 * @param {!WebInspector.Event} event | |
| 63 */ | |
| 64 _onUISourceCodeRemoved: function(event) | |
| 65 { | |
| 66 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data) ; | |
| 67 this._unbind(uiSourceCode); | |
| 68 }, | |
| 69 | |
| 70 /** | |
| 71 * @param {!WebInspector.Event} event | |
| 72 */ | |
| 73 _onProjectRemoved: function(event) | |
| 74 { | |
| 75 var project = /** @type {!WebInspector.Project} */(event.data); | |
| 76 for (var uiSourceCode of project.uiSourceCodes()) | |
| 77 this._unbind(uiSourceCode); | |
| 78 }, | |
| 79 | |
| 80 /** | |
| 81 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 82 * @return {?WebInspector.PersistenceBinding} | |
| 83 */ | |
| 84 _createBinding: function(uiSourceCode) | |
| 85 { | |
| 86 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSyst em) { | |
| 87 var fileSystemPath = WebInspector.FileSystemWorkspaceBinding.fileSys temPath(uiSourceCode.project().id()); | |
| 88 var networkURL = WebInspector.fileSystemMapping.networkURLForFileSys temURL(fileSystemPath, uiSourceCode.url()); | |
| 89 var networkUISC = networkURL ? this._workspace.uiSourceCodeForURL(ne tworkURL) : null; | |
|
dgozman
2016/09/22 19:55:53
networkSourceCode
lushnikov
2016/09/23 21:56:13
Done.
| |
| 90 return networkUISC ? new WebInspector.PersistenceBinding(networkUISC , uiSourceCode) : null; | |
| 91 } | |
| 92 if (uiSourceCode.project().type() === WebInspector.projectTypes.Network) { | |
| 93 var file = WebInspector.fileSystemMapping.fileForURL(uiSourceCode.ur l()); | |
| 94 var projectId = file ? WebInspector.FileSystemWorkspaceBinding.proje ctId(file.fileSystemPath) : null; | |
| 95 var fileUISC = file && projectId ? this._workspace.uiSourceCode(proj ectId, file.fileURL) : null; | |
|
dgozman
2016/09/22 19:55:53
fileSourceCode
lushnikov
2016/09/23 21:56:13
Done.
| |
| 96 return fileUISC ? new WebInspector.PersistenceBinding(uiSourceCode, fileUISC) : null; | |
| 97 } | |
| 98 return null; | |
| 99 }, | |
| 100 | |
| 101 _bind: function(uiSourceCode) | |
| 102 { | |
| 103 if (uiSourceCode[WebInspector.Persistence._binding]) | |
|
dgozman
2016/09/22 19:55:53
How come? Assert!
lushnikov
2016/09/23 21:56:13
Done.
| |
| 104 return; | |
| 105 var binding = this._createBinding(uiSourceCode); | |
| 106 if (!binding) | |
| 107 return; | |
| 108 if (binding.network.isDirty() || binding.persistent.isDirty()) { | |
|
dgozman
2016/09/22 19:55:53
We'll have to do something smarter. For now, let's
lushnikov
2016/09/23 21:56:13
Did this without the "10 times" thingy - there won
| |
| 109 var clean = !binding.network.isDirty() || confirm(WebInspector.UIStr ing("Are you sure you want to close unsaved file: %s?", binding.network.name())) ; | |
| 110 clean = !clean || !binding.persistent.isDirty() || confirm(WebInspec tor.UIString("Are you sure you want to close unsaved file: %s?", binding.network .name())); | |
| 111 if (!clean) { | |
| 112 WebInspector.console.log(WebInspector.UIString("Failed to map %s . Save your changes and try one more time.", binding.network.name())); | |
| 113 return; | |
| 114 } | |
| 115 binding.network.resetWorkingCopy(); | |
| 116 binding.persistent.resetWorkingCopy(); | |
| 117 } | |
| 118 this._bindings.add(binding); | |
| 119 binding.network[WebInspector.Persistence._binding] = binding; | |
| 120 binding.persistent[WebInspector.Persistence._binding] = binding; | |
| 121 | |
| 122 binding.network.addEventListener(WebInspector.UISourceCode.Events.Workin gCopyCommitted, this._onWorkingCopyCommitted, this); | |
| 123 binding.persistent.addEventListener(WebInspector.UISourceCode.Events.Wor kingCopyCommitted, this._onWorkingCopyCommitted, this); | |
| 124 | |
| 125 this._moveBreakpoints(binding.persistent, binding.network); | |
| 126 this.dispatchEventToListeners(WebInspector.Persistence.Events.BindingCre ated, binding); | |
| 127 }, | |
| 128 | |
| 129 /** | |
| 130 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 131 */ | |
| 132 _unbind: function(uiSourceCode) | |
| 133 { | |
| 134 var binding = uiSourceCode[WebInspector.Persistence._binding]; | |
| 135 if (!binding) | |
| 136 return; | |
| 137 this._bindings.delete(binding); | |
| 138 binding.network[WebInspector.Persistence._binding] = null; | |
| 139 binding.persistent[WebInspector.Persistence._binding] = null; | |
| 140 | |
| 141 binding.network.removeEventListener(WebInspector.UISourceCode.Events.Wor kingCopyCommitted, this._onWorkingCopyCommitted, this); | |
| 142 binding.persistent.removeEventListener(WebInspector.UISourceCode.Events. WorkingCopyCommitted, this._onWorkingCopyCommitted, this); | |
| 143 | |
| 144 this._copyBreakpoints(binding.network, binding.persistent); | |
| 145 this.dispatchEventToListeners(WebInspector.Persistence.Events.BindingRem oved, binding); | |
| 146 }, | |
| 147 | |
| 148 /** | |
| 149 * @param {!WebInspector.Event} event | |
| 150 */ | |
| 151 _onWorkingCopyCommitted: function(event) | |
| 152 { | |
| 153 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.targe t); | |
| 154 var binding = uiSourceCode[WebInspector.Persistence._binding]; | |
| 155 if (!binding || binding[WebInspector.Persistence._muteCommit]) | |
| 156 return; | |
| 157 var other = binding.network === uiSourceCode ? binding.persistent : bind ing.network; | |
| 158 other.requestContent().then(currentContent => this._syncContent(binding, other, currentContent, /** @type {string} */(event.data.content))); | |
|
dgozman
2016/09/22 19:55:53
if (Runtime.queryParam("v8only"))
...
else
j
lushnikov
2016/09/23 21:56:13
Done.
| |
| 159 }, | |
| 160 | |
| 161 /** | |
| 162 * @param {!WebInspector.PersistenceBinding} binding | |
| 163 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 164 * @param {string} currentContent | |
| 165 * @param {string} newContent | |
| 166 */ | |
| 167 _syncContent: function(binding, uiSourceCode, currentContent, newContent) | |
| 168 { | |
| 169 if (uiSourceCode === binding.persistent) { | |
| 170 if (newContent.startsWith(WebInspector.Persistence.NodePrefix) && ne wContent.endsWith(WebInspector.Persistence.NodeSuffix)) | |
| 171 newContent = newContent.substring(WebInspector.Persistence.NodeP refix.length, newContent.length - WebInspector.Persistence.NodeSuffix.length); | |
| 172 if (currentContent.startsWith(WebInspector.Persistence.NodeShebang)) | |
| 173 newContent = WebInspector.Persistence.NodeShebang + newContent; | |
| 174 } else { | |
| 175 if (newContent.startsWith(WebInspector.Persistence.NodeShebang)) | |
| 176 newContent = newContent.substring(WebInspector.Persistence.NodeS hebang.length); | |
| 177 if (currentContent.startsWith(WebInspector.Persistence.NodePrefix) & & currentContent.endsWith(WebInspector.Persistence.NodeSuffix)) | |
| 178 newContent = WebInspector.Persistence.NodePrefix + newContent + WebInspector.Persistence.NodeSuffix; | |
| 179 } | |
| 180 binding[WebInspector.Persistence._muteCommit] = true; | |
| 181 uiSourceCode.addRevision(newContent); | |
| 182 binding[WebInspector.Persistence._muteCommit] = false; | |
| 183 this._contentSyncedForTest(); | |
| 184 }, | |
| 185 | |
| 186 _contentSyncedForTest: function() { }, | |
| 187 | |
| 188 /** | |
| 189 * @param {!WebInspector.UISourceCode} from | |
| 190 * @param {!WebInspector.UISourceCode} to | |
| 191 */ | |
| 192 _moveBreakpoints: function(from, to) | |
| 193 { | |
| 194 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(fro m); | |
| 195 for (var breakpoint of breakpoints) { | |
| 196 breakpoint.remove(); | |
| 197 this._breakpointManager.setBreakpoint(to, breakpoint.lineNumber(), b reakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled()); | |
| 198 } | |
| 199 }, | |
| 200 | |
| 201 /** | |
| 202 * @param {!WebInspector.UISourceCode} from | |
| 203 * @param {!WebInspector.UISourceCode} to | |
| 204 */ | |
| 205 _copyBreakpoints: function(from, to) | |
| 206 { | |
| 207 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(fro m); | |
| 208 for (var breakpoint of breakpoints) | |
| 209 this._breakpointManager.setBreakpoint(to, breakpoint.lineNumber(), b reakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled()); | |
| 210 }, | |
| 211 | |
| 212 /** | |
| 213 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 214 * @return {boolean} | |
| 215 */ | |
| 216 hasUnsavedCommittedChanges: function(uiSourceCode) | |
| 217 { | |
| 218 if (this._workspace.hasResourceContentTrackingExtensions()) | |
| 219 return false; | |
| 220 if (uiSourceCode.url() && WebInspector.fileManager.isURLSaved(uiSourceCo de.url())) | |
| 221 return false; | |
| 222 if (uiSourceCode.project().canSetFileContent()) | |
| 223 return false; | |
| 224 if (uiSourceCode[WebInspector.Persistence._binding]) | |
| 225 return false; | |
| 226 return !!uiSourceCode.history.length; | |
| 227 }, | |
| 228 | |
| 229 /** | |
| 230 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 231 * @return {?WebInspector.PersistenceBinding} | |
| 232 */ | |
| 233 binding: function(uiSourceCode) | |
| 234 { | |
| 235 return uiSourceCode[WebInspector.Persistence._binding]; | |
|
dgozman
2016/09/22 19:55:53
|| null
lushnikov
2016/09/23 21:56:13
Done.
| |
| 236 }, | |
| 237 | |
| 238 dispose: function() | |
| 239 { | |
| 240 WebInspector.EventTarget.removeEventListeners(this._eventListeners); | |
| 241 }, | |
| 242 | |
| 243 __proto__: WebInspector.Object.prototype | |
| 244 } | |
| 245 | |
| 246 /** | |
| 247 * @constructor | |
| 248 * @param {!WebInspector.UISourceCode} network | |
| 249 * @param {!WebInspector.UISourceCode} persistent | |
| 250 */ | |
| 251 WebInspector.PersistenceBinding = function(network, persistent) | |
| 252 { | |
| 253 this.network = network; | |
| 254 this.persistent = persistent; | |
|
dgozman
2016/09/22 19:55:53
persistent -> fileSystem
lushnikov
2016/09/23 21:56:12
Done.
| |
| 255 } | |
| 256 | |
| 257 /** @type {!WebInspector.Persistence} */ | |
| 258 WebInspector.persistence; | |
| OLD | NEW |