| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 /** | 4 /** |
| 5 * @unrestricted | 5 * @unrestricted |
| 6 */ | 6 */ |
| 7 Persistence.Persistence = class extends Common.Object { | 7 Persistence.Persistence = class extends Common.Object { |
| 8 /** | 8 /** |
| 9 * @param {!Workspace.Workspace} workspace | 9 * @param {!Workspace.Workspace} workspace |
| 10 * @param {!Bindings.BreakpointManager} breakpointManager | 10 * @param {!Bindings.BreakpointManager} breakpointManager |
| 11 * @param {!Workspace.FileSystemMapping} fileSystemMapping | 11 * @param {!Workspace.FileSystemMapping} fileSystemMapping |
| 12 */ | 12 */ |
| 13 constructor(workspace, breakpointManager, fileSystemMapping) { | 13 constructor(workspace, breakpointManager, fileSystemMapping) { |
| 14 super(); | 14 super(); |
| 15 this._workspace = workspace; | 15 this._workspace = workspace; |
| 16 this._breakpointManager = breakpointManager; | 16 this._breakpointManager = breakpointManager; |
| 17 /** @type {!Map<string, number>} */ | 17 /** @type {!Map<string, number>} */ |
| 18 this._filePathPrefixesToBindingCount = new Map(); | 18 this._filePathPrefixesToBindingCount = new Map(); |
| 19 | 19 |
| 20 if (Runtime.experiments.isEnabled('persistence2')) { | 20 if (Runtime.experiments.isEnabled('persistence2')) { |
| 21 var linkDecorator = new Persistence.PersistenceUtils.LinkDecorator(this); | 21 var linkDecorator = new Persistence.PersistenceUtils.LinkDecorator(this); |
| 22 Components.Linkifier.setLinkDecorator(linkDecorator); | 22 Components.Linkifier.setLinkDecorator(linkDecorator); |
| 23 this._mapping = | 23 this._mapping = |
| 24 new Persistence.Automapping(workspace, this._onBindingCreated.bind(thi
s), this._onBindingRemoved.bind(this)); | 24 new Persistence.Automapping(workspace, this._validateBinding.bind(this
), this._onBindingRemoved.bind(this)); |
| 25 } else { | 25 } else { |
| 26 this._mapping = new Persistence.DefaultMapping( | 26 this._mapping = new Persistence.DefaultMapping( |
| 27 workspace, fileSystemMapping, this._onBindingCreated.bind(this), this.
_onBindingRemoved.bind(this)); | 27 workspace, fileSystemMapping, this._validateBinding.bind(this), this._
onBindingRemoved.bind(this)); |
| 28 } | 28 } |
| 29 } | 29 } |
| 30 | 30 |
| 31 /** | 31 /** |
| 32 * @param {!Persistence.PersistenceBinding} binding | 32 * @param {!Persistence.PersistenceBinding} binding |
| 33 */ | 33 */ |
| 34 _onBindingCreated(binding) { | 34 _validateBinding(binding) { |
| 35 if (binding.network.isDirty()) { | 35 if (!Runtime.experiments.isEnabled('persistenceValidation') || binding.netwo
rk.contentType().isFromSourceMap() || |
| 36 Common.console.log( | 36 !binding.fileSystem.contentType().isTextType()) { |
| 37 Common.UIString('%s can not be persisted to file system due to unsaved
changes.', binding.network.name())); | 37 this._establishBinding(binding); |
| 38 return; | 38 return; |
| 39 } | 39 } |
| 40 if (binding.fileSystem.isDirty()) | |
| 41 binding.network.setWorkingCopy(binding.fileSystem.workingCopy()); | |
| 42 | 40 |
| 41 Promise.all([binding.network.requestContent(), binding.fileSystem.requestCon
tent()]).then(onContents.bind(this)); |
| 42 |
| 43 /** |
| 44 * @this {Persistence.Persistence} |
| 45 */ |
| 46 function onContents() { |
| 47 if (binding._removed) |
| 48 return; |
| 49 |
| 50 var fileSystemContent = binding.fileSystem.workingCopy(); |
| 51 var networkContent = binding.network.workingCopy(); |
| 52 var target = Bindings.NetworkProject.targetForUISourceCode(binding.network
); |
| 53 var isValid = false; |
| 54 if (target.isNodeJS()) { |
| 55 var rewrappedNetworkContent = Persistence.Persistence._rewrapNodeJSConte
nt( |
| 56 binding, binding.fileSystem, fileSystemContent, networkContent); |
| 57 isValid = (fileSystemContent === rewrappedNetworkContent); |
| 58 } else { |
| 59 // Trim trailing whitespaces because V8 adds trailing newline. |
| 60 isValid = (fileSystemContent.trimRight() === networkContent.trimRight())
; |
| 61 } |
| 62 |
| 63 if (isValid) |
| 64 this._establishBinding(binding); |
| 65 else |
| 66 this._prevalidationFailedForTest(binding); |
| 67 } |
| 68 } |
| 69 |
| 70 /** |
| 71 * @param {!Persistence.PersistenceBinding} binding |
| 72 */ |
| 73 _prevalidationFailedForTest(binding) { |
| 74 } |
| 75 |
| 76 /** |
| 77 * @param {!Persistence.PersistenceBinding} binding |
| 78 */ |
| 79 _establishBinding(binding) { |
| 43 binding.network[Persistence.Persistence._binding] = binding; | 80 binding.network[Persistence.Persistence._binding] = binding; |
| 44 binding.fileSystem[Persistence.Persistence._binding] = binding; | 81 binding.fileSystem[Persistence.Persistence._binding] = binding; |
| 45 | 82 |
| 46 binding.fileSystem.forceLoadOnCheckContent(); | 83 binding.fileSystem.forceLoadOnCheckContent(); |
| 47 | 84 |
| 48 binding.network.addEventListener( | 85 binding.network.addEventListener( |
| 49 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); | 86 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); |
| 50 binding.fileSystem.addEventListener( | 87 binding.fileSystem.addEventListener( |
| 51 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); | 88 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); |
| 52 binding.network.addEventListener( | 89 binding.network.addEventListener( |
| 53 Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyCha
nged, this); | 90 Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyCha
nged, this); |
| 54 binding.fileSystem.addEventListener( | 91 binding.fileSystem.addEventListener( |
| 55 Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyCha
nged, this); | 92 Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyCha
nged, this); |
| 56 | 93 |
| 57 this._addFilePathBindingPrefixes(binding.fileSystem.url()); | 94 this._addFilePathBindingPrefixes(binding.fileSystem.url()); |
| 58 | 95 |
| 59 this._moveBreakpoints(binding.fileSystem, binding.network); | 96 this._moveBreakpoints(binding.fileSystem, binding.network); |
| 60 this.dispatchEventToListeners(Persistence.Persistence.Events.BindingCreated,
binding); | 97 this.dispatchEventToListeners(Persistence.Persistence.Events.BindingCreated,
binding); |
| 61 } | 98 } |
| 62 | 99 |
| 63 /** | 100 /** |
| 64 * @param {!Persistence.PersistenceBinding} binding | 101 * @param {!Persistence.PersistenceBinding} binding |
| 65 */ | 102 */ |
| 66 _onBindingRemoved(binding) { | 103 _onBindingRemoved(binding) { |
| 104 binding._removed = true; |
| 105 if (binding.network[Persistence.Persistence._binding] !== binding) |
| 106 return; |
| 107 console.assert( |
| 108 binding.network[Persistence.Persistence._binding] === binding.fileSystem
[Persistence.Persistence._binding], |
| 109 'ERROR: inconsistent binding for networkURL ' + binding.network.url()); |
| 110 |
| 67 binding.network[Persistence.Persistence._binding] = null; | 111 binding.network[Persistence.Persistence._binding] = null; |
| 68 binding.fileSystem[Persistence.Persistence._binding] = null; | 112 binding.fileSystem[Persistence.Persistence._binding] = null; |
| 69 | 113 |
| 70 binding.network.removeEventListener( | 114 binding.network.removeEventListener( |
| 71 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); | 115 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); |
| 72 binding.fileSystem.removeEventListener( | 116 binding.fileSystem.removeEventListener( |
| 73 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); | 117 Workspace.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyC
ommitted, this); |
| 74 binding.network.removeEventListener( | 118 binding.network.removeEventListener( |
| 75 Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyCha
nged, this); | 119 Workspace.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyCha
nged, this); |
| 76 binding.fileSystem.removeEventListener( | 120 binding.fileSystem.removeEventListener( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 88 _onWorkingCopyChanged(event) { | 132 _onWorkingCopyChanged(event) { |
| 89 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target); | 133 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target); |
| 90 var binding = uiSourceCode[Persistence.Persistence._binding]; | 134 var binding = uiSourceCode[Persistence.Persistence._binding]; |
| 91 if (!binding || binding[Persistence.Persistence._muteWorkingCopy]) | 135 if (!binding || binding[Persistence.Persistence._muteWorkingCopy]) |
| 92 return; | 136 return; |
| 93 var other = binding.network === uiSourceCode ? binding.fileSystem : binding.
network; | 137 var other = binding.network === uiSourceCode ? binding.fileSystem : binding.
network; |
| 94 var target = Bindings.NetworkProject.targetForUISourceCode(binding.network); | 138 var target = Bindings.NetworkProject.targetForUISourceCode(binding.network); |
| 95 if (target.isNodeJS()) { | 139 if (target.isNodeJS()) { |
| 96 var newContent = uiSourceCode.workingCopy(); | 140 var newContent = uiSourceCode.workingCopy(); |
| 97 other.requestContent().then(() => { | 141 other.requestContent().then(() => { |
| 98 var nodeJSContent = this._rewrapNodeJSContent(binding, other, other.work
ingCopy(), newContent); | 142 var nodeJSContent = |
| 143 Persistence.Persistence._rewrapNodeJSContent(binding, other, other.w
orkingCopy(), newContent); |
| 99 setWorkingCopy.call(this, () => nodeJSContent); | 144 setWorkingCopy.call(this, () => nodeJSContent); |
| 100 }); | 145 }); |
| 101 return; | 146 return; |
| 102 } | 147 } |
| 103 | 148 |
| 104 setWorkingCopy.call(this, () => uiSourceCode.workingCopy()); | 149 setWorkingCopy.call(this, () => uiSourceCode.workingCopy()); |
| 105 | 150 |
| 106 /** | 151 /** |
| 107 * @param {function():string} workingCopyGetter | 152 * @param {function():string} workingCopyGetter |
| 108 * @this {Persistence.Persistence} | 153 * @this {Persistence.Persistence} |
| (...skipping 12 matching lines...) Expand all Loading... |
| 121 _onWorkingCopyCommitted(event) { | 166 _onWorkingCopyCommitted(event) { |
| 122 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target); | 167 var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.target); |
| 123 var binding = uiSourceCode[Persistence.Persistence._binding]; | 168 var binding = uiSourceCode[Persistence.Persistence._binding]; |
| 124 if (!binding || binding[Persistence.Persistence._muteCommit]) | 169 if (!binding || binding[Persistence.Persistence._muteCommit]) |
| 125 return; | 170 return; |
| 126 var newContent = /** @type {string} */ (event.data.content); | 171 var newContent = /** @type {string} */ (event.data.content); |
| 127 var other = binding.network === uiSourceCode ? binding.fileSystem : binding.
network; | 172 var other = binding.network === uiSourceCode ? binding.fileSystem : binding.
network; |
| 128 var target = Bindings.NetworkProject.targetForUISourceCode(binding.network); | 173 var target = Bindings.NetworkProject.targetForUISourceCode(binding.network); |
| 129 if (target.isNodeJS()) { | 174 if (target.isNodeJS()) { |
| 130 other.requestContent().then(currentContent => { | 175 other.requestContent().then(currentContent => { |
| 131 var nodeJSContent = this._rewrapNodeJSContent(binding, other, currentCon
tent, newContent); | 176 var nodeJSContent = Persistence.Persistence._rewrapNodeJSContent(binding
, other, currentContent, newContent); |
| 132 setContent.call(this, nodeJSContent); | 177 setContent.call(this, nodeJSContent); |
| 133 }); | 178 }); |
| 134 return; | 179 return; |
| 135 } | 180 } |
| 136 setContent.call(this, newContent); | 181 setContent.call(this, newContent); |
| 137 | 182 |
| 138 /** | 183 /** |
| 139 * @param {string} newContent | 184 * @param {string} newContent |
| 140 * @this {Persistence.Persistence} | 185 * @this {Persistence.Persistence} |
| 141 */ | 186 */ |
| 142 function setContent(newContent) { | 187 function setContent(newContent) { |
| 143 binding[Persistence.Persistence._muteCommit] = true; | 188 binding[Persistence.Persistence._muteCommit] = true; |
| 144 other.addRevision(newContent); | 189 other.addRevision(newContent); |
| 145 binding[Persistence.Persistence._muteCommit] = false; | 190 binding[Persistence.Persistence._muteCommit] = false; |
| 146 this._contentSyncedForTest(); | 191 this._contentSyncedForTest(); |
| 147 } | 192 } |
| 148 } | 193 } |
| 149 | 194 |
| 150 /** | 195 /** |
| 151 * @param {!Persistence.PersistenceBinding} binding | 196 * @param {!Persistence.PersistenceBinding} binding |
| 152 * @param {!Workspace.UISourceCode} uiSourceCode | 197 * @param {!Workspace.UISourceCode} uiSourceCode |
| 153 * @param {string} currentContent | 198 * @param {string} currentContent |
| 154 * @param {string} newContent | 199 * @param {string} newContent |
| 155 * @return {string} | 200 * @return {string} |
| 156 */ | 201 */ |
| 157 _rewrapNodeJSContent(binding, uiSourceCode, currentContent, newContent) { | 202 static _rewrapNodeJSContent(binding, uiSourceCode, currentContent, newContent)
{ |
| 158 if (uiSourceCode === binding.fileSystem) { | 203 if (uiSourceCode === binding.fileSystem) { |
| 159 if (newContent.startsWith(Persistence.Persistence._NodePrefix) && | 204 if (newContent.startsWith(Persistence.Persistence._NodePrefix) && |
| 160 newContent.endsWith(Persistence.Persistence._NodeSuffix)) { | 205 newContent.endsWith(Persistence.Persistence._NodeSuffix)) { |
| 161 newContent = newContent.substring( | 206 newContent = newContent.substring( |
| 162 Persistence.Persistence._NodePrefix.length, newContent.length - Pers
istence.Persistence._NodeSuffix.length); | 207 Persistence.Persistence._NodePrefix.length, newContent.length - Pers
istence.Persistence._NodeSuffix.length); |
| 163 } | 208 } |
| 164 if (currentContent.startsWith(Persistence.Persistence._NodeShebang)) | 209 if (currentContent.startsWith(Persistence.Persistence._NodeShebang)) |
| 165 newContent = Persistence.Persistence._NodeShebang + newContent; | 210 newContent = Persistence.Persistence._NodeShebang + newContent; |
| 166 } else { | 211 } else { |
| 167 if (newContent.startsWith(Persistence.Persistence._NodeShebang)) | 212 if (newContent.startsWith(Persistence.Persistence._NodeShebang)) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 Persistence.PersistenceBinding = class { | 328 Persistence.PersistenceBinding = class { |
| 284 /** | 329 /** |
| 285 * @param {!Workspace.UISourceCode} network | 330 * @param {!Workspace.UISourceCode} network |
| 286 * @param {!Workspace.UISourceCode} fileSystem | 331 * @param {!Workspace.UISourceCode} fileSystem |
| 287 * @param {boolean} exactMatch | 332 * @param {boolean} exactMatch |
| 288 */ | 333 */ |
| 289 constructor(network, fileSystem, exactMatch) { | 334 constructor(network, fileSystem, exactMatch) { |
| 290 this.network = network; | 335 this.network = network; |
| 291 this.fileSystem = fileSystem; | 336 this.fileSystem = fileSystem; |
| 292 this.exactMatch = exactMatch; | 337 this.exactMatch = exactMatch; |
| 338 this._removed = false; |
| 293 } | 339 } |
| 294 }; | 340 }; |
| 295 | 341 |
| 296 /** @type {!Persistence.Persistence} */ | 342 /** @type {!Persistence.Persistence} */ |
| 297 Persistence.persistence; | 343 Persistence.persistence; |
| OLD | NEW |