Index: third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js b/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7ffc4460d263c4677e6cae5cb9de26be8b97fd86 |
--- /dev/null |
+++ b/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js |
@@ -0,0 +1,258 @@ |
+// Copyright 2016 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 |
+ * @extends {WebInspector.Object} |
+ * @param {!WebInspector.Workspace} workspace |
+ * @param {!WebInspector.BreakpointManager} breakpointManager |
+ */ |
+WebInspector.Persistence = function(workspace, breakpointManager) |
+{ |
+ WebInspector.Object.call(this); |
+ this._workspace = workspace; |
+ this._breakpointManager = breakpointManager; |
+ /** @type {!Set<!WebInspector.PersistenceBinding>} */ |
+ this._bindings = new Set(); |
+ this._eventListeners = [ |
+ workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._onUISourceCodeAdded, this), |
+ workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._onUISourceCodeRemoved, this), |
+ workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._onProjectRemoved, this), |
+ WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.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.
|
+ WebInspector.fileSystemMapping.addEventListener(WebInspector.FileSystemMapping.Events.FileMappingRemoved, this._remap, this) |
+ ]; |
+} |
dgozman
2016/09/22 19:55:53
Let's call this._remap().
lushnikov
2016/09/23 21:56:13
Done.
|
+ |
+WebInspector.Persistence._binding = Symbol("Persistence.Binding"); |
+WebInspector.Persistence._muteCommit = Symbol("Persistence.MuteCommit"); |
+ |
+WebInspector.Persistence.NodePrefix = "(function (exports, require, module, __filename, __dirname) { "; |
dgozman
2016/09/22 19:55:53
_NodePrefix
lushnikov
2016/09/23 21:56:13
Done.
|
+WebInspector.Persistence.NodeSuffix = "\n});" |
+WebInspector.Persistence.NodeShebang = "#!/usr/bin/env node\n"; |
+ |
+WebInspector.Persistence.Events = { |
+ BindingCreated: Symbol("BindingCreated"), |
+ BindingRemoved: Symbol("BindingRemoved") |
+} |
+ |
+WebInspector.Persistence.prototype = { |
+ _remap: function() |
+ { |
+ var bindings = this._bindings.valuesArray(); |
+ 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.
|
+ this._unbind(binding.network); |
+ var networkProjects = this._workspace.projectsForType(WebInspector.projectTypes.Network); |
+ for (var networkProject of networkProjects) { |
+ for (var uiSourceCode of networkProject.uiSourceCodes()) |
+ this._bind(uiSourceCode); |
+ } |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onUISourceCodeAdded: function(event) |
+ { |
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data); |
+ this._bind(uiSourceCode); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onUISourceCodeRemoved: function(event) |
+ { |
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data); |
+ this._unbind(uiSourceCode); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onProjectRemoved: function(event) |
+ { |
+ var project = /** @type {!WebInspector.Project} */(event.data); |
+ for (var uiSourceCode of project.uiSourceCodes()) |
+ this._unbind(uiSourceCode); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.UISourceCode} uiSourceCode |
+ * @return {?WebInspector.PersistenceBinding} |
+ */ |
+ _createBinding: function(uiSourceCode) |
+ { |
+ if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) { |
+ var fileSystemPath = WebInspector.FileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id()); |
+ var networkURL = WebInspector.fileSystemMapping.networkURLForFileSystemURL(fileSystemPath, uiSourceCode.url()); |
+ var networkUISC = networkURL ? this._workspace.uiSourceCodeForURL(networkURL) : null; |
dgozman
2016/09/22 19:55:53
networkSourceCode
lushnikov
2016/09/23 21:56:13
Done.
|
+ return networkUISC ? new WebInspector.PersistenceBinding(networkUISC, uiSourceCode) : null; |
+ } |
+ if (uiSourceCode.project().type() === WebInspector.projectTypes.Network) { |
+ var file = WebInspector.fileSystemMapping.fileForURL(uiSourceCode.url()); |
+ var projectId = file ? WebInspector.FileSystemWorkspaceBinding.projectId(file.fileSystemPath) : null; |
+ var fileUISC = file && projectId ? this._workspace.uiSourceCode(projectId, file.fileURL) : null; |
dgozman
2016/09/22 19:55:53
fileSourceCode
lushnikov
2016/09/23 21:56:13
Done.
|
+ return fileUISC ? new WebInspector.PersistenceBinding(uiSourceCode, fileUISC) : null; |
+ } |
+ return null; |
+ }, |
+ |
+ _bind: function(uiSourceCode) |
+ { |
+ if (uiSourceCode[WebInspector.Persistence._binding]) |
dgozman
2016/09/22 19:55:53
How come? Assert!
lushnikov
2016/09/23 21:56:13
Done.
|
+ return; |
+ var binding = this._createBinding(uiSourceCode); |
+ if (!binding) |
+ return; |
+ 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
|
+ var clean = !binding.network.isDirty() || confirm(WebInspector.UIString("Are you sure you want to close unsaved file: %s?", binding.network.name())); |
+ clean = !clean || !binding.persistent.isDirty() || confirm(WebInspector.UIString("Are you sure you want to close unsaved file: %s?", binding.network.name())); |
+ if (!clean) { |
+ WebInspector.console.log(WebInspector.UIString("Failed to map %s. Save your changes and try one more time.", binding.network.name())); |
+ return; |
+ } |
+ binding.network.resetWorkingCopy(); |
+ binding.persistent.resetWorkingCopy(); |
+ } |
+ this._bindings.add(binding); |
+ binding.network[WebInspector.Persistence._binding] = binding; |
+ binding.persistent[WebInspector.Persistence._binding] = binding; |
+ |
+ binding.network.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this); |
+ binding.persistent.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this); |
+ |
+ this._moveBreakpoints(binding.persistent, binding.network); |
+ this.dispatchEventToListeners(WebInspector.Persistence.Events.BindingCreated, binding); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.UISourceCode} uiSourceCode |
+ */ |
+ _unbind: function(uiSourceCode) |
+ { |
+ var binding = uiSourceCode[WebInspector.Persistence._binding]; |
+ if (!binding) |
+ return; |
+ this._bindings.delete(binding); |
+ binding.network[WebInspector.Persistence._binding] = null; |
+ binding.persistent[WebInspector.Persistence._binding] = null; |
+ |
+ binding.network.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this); |
+ binding.persistent.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this); |
+ |
+ this._copyBreakpoints(binding.network, binding.persistent); |
+ this.dispatchEventToListeners(WebInspector.Persistence.Events.BindingRemoved, binding); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.Event} event |
+ */ |
+ _onWorkingCopyCommitted: function(event) |
+ { |
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.target); |
+ var binding = uiSourceCode[WebInspector.Persistence._binding]; |
+ if (!binding || binding[WebInspector.Persistence._muteCommit]) |
+ return; |
+ var other = binding.network === uiSourceCode ? binding.persistent : binding.network; |
+ 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.
|
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.PersistenceBinding} binding |
+ * @param {!WebInspector.UISourceCode} uiSourceCode |
+ * @param {string} currentContent |
+ * @param {string} newContent |
+ */ |
+ _syncContent: function(binding, uiSourceCode, currentContent, newContent) |
+ { |
+ if (uiSourceCode === binding.persistent) { |
+ if (newContent.startsWith(WebInspector.Persistence.NodePrefix) && newContent.endsWith(WebInspector.Persistence.NodeSuffix)) |
+ newContent = newContent.substring(WebInspector.Persistence.NodePrefix.length, newContent.length - WebInspector.Persistence.NodeSuffix.length); |
+ if (currentContent.startsWith(WebInspector.Persistence.NodeShebang)) |
+ newContent = WebInspector.Persistence.NodeShebang + newContent; |
+ } else { |
+ if (newContent.startsWith(WebInspector.Persistence.NodeShebang)) |
+ newContent = newContent.substring(WebInspector.Persistence.NodeShebang.length); |
+ if (currentContent.startsWith(WebInspector.Persistence.NodePrefix) && currentContent.endsWith(WebInspector.Persistence.NodeSuffix)) |
+ newContent = WebInspector.Persistence.NodePrefix + newContent + WebInspector.Persistence.NodeSuffix; |
+ } |
+ binding[WebInspector.Persistence._muteCommit] = true; |
+ uiSourceCode.addRevision(newContent); |
+ binding[WebInspector.Persistence._muteCommit] = false; |
+ this._contentSyncedForTest(); |
+ }, |
+ |
+ _contentSyncedForTest: function() { }, |
+ |
+ /** |
+ * @param {!WebInspector.UISourceCode} from |
+ * @param {!WebInspector.UISourceCode} to |
+ */ |
+ _moveBreakpoints: function(from, to) |
+ { |
+ var breakpoints = this._breakpointManager.breakpointsForUISourceCode(from); |
+ for (var breakpoint of breakpoints) { |
+ breakpoint.remove(); |
+ this._breakpointManager.setBreakpoint(to, breakpoint.lineNumber(), breakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled()); |
+ } |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.UISourceCode} from |
+ * @param {!WebInspector.UISourceCode} to |
+ */ |
+ _copyBreakpoints: function(from, to) |
+ { |
+ var breakpoints = this._breakpointManager.breakpointsForUISourceCode(from); |
+ for (var breakpoint of breakpoints) |
+ this._breakpointManager.setBreakpoint(to, breakpoint.lineNumber(), breakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled()); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.UISourceCode} uiSourceCode |
+ * @return {boolean} |
+ */ |
+ hasUnsavedCommittedChanges: function(uiSourceCode) |
+ { |
+ if (this._workspace.hasResourceContentTrackingExtensions()) |
+ return false; |
+ if (uiSourceCode.url() && WebInspector.fileManager.isURLSaved(uiSourceCode.url())) |
+ return false; |
+ if (uiSourceCode.project().canSetFileContent()) |
+ return false; |
+ if (uiSourceCode[WebInspector.Persistence._binding]) |
+ return false; |
+ return !!uiSourceCode.history.length; |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.UISourceCode} uiSourceCode |
+ * @return {?WebInspector.PersistenceBinding} |
+ */ |
+ binding: function(uiSourceCode) |
+ { |
+ return uiSourceCode[WebInspector.Persistence._binding]; |
dgozman
2016/09/22 19:55:53
|| null
lushnikov
2016/09/23 21:56:13
Done.
|
+ }, |
+ |
+ dispose: function() |
+ { |
+ WebInspector.EventTarget.removeEventListeners(this._eventListeners); |
+ }, |
+ |
+ __proto__: WebInspector.Object.prototype |
+} |
+ |
+/** |
+ * @constructor |
+ * @param {!WebInspector.UISourceCode} network |
+ * @param {!WebInspector.UISourceCode} persistent |
+ */ |
+WebInspector.PersistenceBinding = function(network, persistent) |
+{ |
+ this.network = network; |
+ this.persistent = persistent; |
dgozman
2016/09/22 19:55:53
persistent -> fileSystem
lushnikov
2016/09/23 21:56:12
Done.
|
+} |
+ |
+/** @type {!WebInspector.Persistence} */ |
+WebInspector.persistence; |