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 * @param {!WebInspector.FileSystemMapping} fileSystemMapping | |
11 */ | |
12 WebInspector.Persistence = function(workspace, breakpointManager, fileSystemMapp ing) | |
13 { | |
14 WebInspector.Object.call(this); | |
15 this._workspace = workspace; | |
16 this._breakpointManager = breakpointManager; | |
17 this._fileSystemMapping = fileSystemMapping; | |
18 /** @type {!Set<!WebInspector.PersistenceBinding>} */ | |
19 this._bindings = new Set(); | |
20 this._eventListeners = [ | |
21 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdd ed, this._onUISourceCodeAdded, this), | |
22 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRem oved, this._onUISourceCodeRemoved, this), | |
23 workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._onProjectRemoved, this), | |
24 this._fileSystemMapping.addEventListener(WebInspector.FileSystemMapping. Events.FileMappingAdded, this._remap, this), | |
25 this._fileSystemMapping.addEventListener(WebInspector.FileSystemMapping. Events.FileMappingRemoved, this._remap, this) | |
26 ]; | |
27 this._remap(); | |
28 } | |
29 | |
30 WebInspector.Persistence._binding = Symbol("Persistence.Binding"); | |
31 WebInspector.Persistence._muteCommit = Symbol("Persistence.MuteCommit"); | |
32 | |
33 WebInspector.Persistence._NodePrefix = "(function (exports, require, module, __f ilename, __dirname) { "; | |
34 WebInspector.Persistence._NodeSuffix = "\n});" | |
35 WebInspector.Persistence._NodeShebang = "#!/usr/bin/env node\n"; | |
36 | |
37 WebInspector.Persistence.Events = { | |
38 BindingCreated: Symbol("BindingCreated"), | |
39 BindingRemoved: Symbol("BindingRemoved") | |
40 } | |
41 | |
42 WebInspector.Persistence.prototype = { | |
43 _remap: function() | |
44 { | |
45 for (var binding of this._bindings.valuesArray()) | |
46 this._unbind(binding.network); | |
47 var networkProjects = this._workspace.projectsForType(WebInspector.proje ctTypes.Network); | |
48 for (var networkProject of networkProjects) { | |
49 for (var uiSourceCode of networkProject.uiSourceCodes()) | |
50 this._bind(uiSourceCode); | |
51 } | |
52 }, | |
53 | |
54 /** | |
55 * @param {!WebInspector.Event} event | |
56 */ | |
57 _onUISourceCodeAdded: function(event) | |
58 { | |
59 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data) ; | |
60 this._bind(uiSourceCode); | |
61 }, | |
62 | |
63 /** | |
64 * @param {!WebInspector.Event} event | |
65 */ | |
66 _onUISourceCodeRemoved: function(event) | |
67 { | |
68 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.data) ; | |
69 this._unbind(uiSourceCode); | |
70 }, | |
71 | |
72 /** | |
73 * @param {!WebInspector.Event} event | |
74 */ | |
75 _onProjectRemoved: function(event) | |
76 { | |
77 var project = /** @type {!WebInspector.Project} */(event.data); | |
78 for (var uiSourceCode of project.uiSourceCodes()) | |
79 this._unbind(uiSourceCode); | |
80 }, | |
81 | |
82 /** | |
83 * @param {!WebInspector.UISourceCode} uiSourceCode | |
84 * @return {?WebInspector.PersistenceBinding} | |
85 */ | |
86 _createBinding: function(uiSourceCode) | |
87 { | |
88 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSyst em) { | |
89 var fileSystemPath = WebInspector.FileSystemWorkspaceBinding.fileSys temPath(uiSourceCode.project().id()); | |
90 var networkURL = this._fileSystemMapping.networkURLForFileSystemURL( fileSystemPath, uiSourceCode.url()); | |
91 var networkSourceCode = networkURL ? this._workspace.uiSourceCodeFor URL(networkURL) : null; | |
92 return networkSourceCode ? new WebInspector.PersistenceBinding(netwo rkSourceCode, uiSourceCode) : null; | |
93 } | |
94 if (uiSourceCode.project().type() === WebInspector.projectTypes.Network) { | |
95 var file = this._fileSystemMapping.fileForURL(uiSourceCode.url()); | |
96 var projectId = file ? WebInspector.FileSystemWorkspaceBinding.proje ctId(file.fileSystemPath) : null; | |
97 var fileSourceCode = file && projectId ? this._workspace.uiSourceCod e(projectId, file.fileURL) : null; | |
98 return fileSourceCode ? new WebInspector.PersistenceBinding(uiSource Code, fileSourceCode) : null; | |
99 } | |
100 return null; | |
101 }, | |
102 | |
103 /** | |
104 * @param {!WebInspector.UISourceCode} uiSourceCode | |
105 */ | |
106 _bind: function(uiSourceCode) | |
107 { | |
108 console.assert(!uiSourceCode[WebInspector.Persistence._binding], "Cannot bind already bound UISourceCode!"); | |
109 var binding = this._createBinding(uiSourceCode); | |
110 if (!binding) | |
111 return; | |
112 if (binding.network.isDirty() || binding.fileSystem.isDirty()) { | |
113 WebInspector.console.log(WebInspector.UIString("Failed to map %s. Sa ve your changes and reload page.", binding.network.name())); | |
dgozman
2016/09/23 23:03:21
"%s can not be persisted to file system due to uns
lushnikov
2016/09/24 00:30:50
Done.
| |
114 return; | |
115 } | |
116 this._bindings.add(binding); | |
117 binding.network[WebInspector.Persistence._binding] = binding; | |
118 binding.fileSystem[WebInspector.Persistence._binding] = binding; | |
119 | |
120 binding.fileSystem.forceLoadOnCheckContent(); | |
121 | |
122 binding.network.addEventListener(WebInspector.UISourceCode.Events.Workin gCopyCommitted, this._onWorkingCopyCommitted, this); | |
123 binding.fileSystem.addEventListener(WebInspector.UISourceCode.Events.Wor kingCopyCommitted, this._onWorkingCopyCommitted, this); | |
124 binding.fileSystem.addEventListener(WebInspector.UISourceCode.Events.Tit leChanged, this._onFileSystemUISourceCodeRenamed, this); | |
125 | |
126 this._moveBreakpoints(binding.fileSystem, binding.network); | |
127 this.dispatchEventToListeners(WebInspector.Persistence.Events.BindingCre ated, binding); | |
128 }, | |
129 | |
130 /** | |
131 * @param {!WebInspector.UISourceCode} uiSourceCode | |
132 */ | |
133 _unbind: function(uiSourceCode) | |
134 { | |
135 var binding = uiSourceCode[WebInspector.Persistence._binding]; | |
136 if (!binding) | |
137 return; | |
138 this._bindings.delete(binding); | |
139 binding.network[WebInspector.Persistence._binding] = null; | |
140 binding.fileSystem[WebInspector.Persistence._binding] = null; | |
141 | |
142 binding.network.removeEventListener(WebInspector.UISourceCode.Events.Wor kingCopyCommitted, this._onWorkingCopyCommitted, this); | |
143 binding.fileSystem.removeEventListener(WebInspector.UISourceCode.Events. WorkingCopyCommitted, this._onWorkingCopyCommitted, this); | |
144 binding.fileSystem.removeEventListener(WebInspector.UISourceCode.Events. TitleChanged, this._onFileSystemUISourceCodeRenamed, this); | |
145 | |
146 this._copyBreakpoints(binding.network, binding.fileSystem); | |
147 this.dispatchEventToListeners(WebInspector.Persistence.Events.BindingRem oved, binding); | |
148 }, | |
149 | |
150 /** | |
151 * @param {!WebInspector.Event} event | |
152 */ | |
153 _onFileSystemUISourceCodeRenamed: function(event) | |
154 { | |
155 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.targe t); | |
156 var binding = uiSourceCode[WebInspector.Persistence._binding]; | |
157 this._unbind(binding.network); | |
158 this._bind(binding.network); | |
159 }, | |
160 | |
161 /** | |
162 * @param {!WebInspector.Event} event | |
163 */ | |
164 _onWorkingCopyCommitted: function(event) | |
165 { | |
166 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */(event.targe t); | |
167 var binding = uiSourceCode[WebInspector.Persistence._binding]; | |
168 if (!binding || binding[WebInspector.Persistence._muteCommit]) | |
169 return; | |
170 var newContent = /** @type {string} */(event.data.content); | |
171 var other = binding.network === uiSourceCode ? binding.fileSystem : bind ing.network; | |
172 if (Runtime.queryParam("v8only")) { | |
173 other.requestContent().then(currentContent => this._syncNodeJSConten t(binding, other, currentContent, newContent)); | |
174 return; | |
175 } | |
176 binding[WebInspector.Persistence._muteCommit] = true; | |
177 other.addRevision(newContent); | |
178 binding[WebInspector.Persistence._muteCommit] = false; | |
179 this._contentSyncedForTest(); | |
180 }, | |
181 | |
182 /** | |
183 * @param {!WebInspector.PersistenceBinding} binding | |
184 * @param {!WebInspector.UISourceCode} uiSourceCode | |
185 * @param {string} currentContent | |
186 * @param {string} newContent | |
187 */ | |
188 _syncNodeJSContent: function(binding, uiSourceCode, currentContent, newConte nt) | |
189 { | |
190 if (uiSourceCode === binding.fileSystem) { | |
191 if (newContent.startsWith(WebInspector.Persistence._NodePrefix) && n ewContent.endsWith(WebInspector.Persistence._NodeSuffix)) | |
192 newContent = newContent.substring(WebInspector.Persistence._Node Prefix.length, newContent.length - WebInspector.Persistence._NodeSuffix.length); | |
193 if (currentContent.startsWith(WebInspector.Persistence._NodeShebang) ) | |
194 newContent = WebInspector.Persistence._NodeShebang + newContent; | |
195 } else { | |
196 if (newContent.startsWith(WebInspector.Persistence._NodeShebang)) | |
197 newContent = newContent.substring(WebInspector.Persistence._Node Shebang.length); | |
198 if (currentContent.startsWith(WebInspector.Persistence._NodePrefix) && currentContent.endsWith(WebInspector.Persistence._NodeSuffix)) | |
199 newContent = WebInspector.Persistence._NodePrefix + newContent + WebInspector.Persistence._NodeSuffix; | |
200 } | |
201 binding[WebInspector.Persistence._muteCommit] = true; | |
202 uiSourceCode.addRevision(newContent); | |
203 binding[WebInspector.Persistence._muteCommit] = false; | |
204 this._contentSyncedForTest(); | |
205 }, | |
206 | |
207 _contentSyncedForTest: function() { }, | |
208 | |
209 /** | |
210 * @param {!WebInspector.UISourceCode} from | |
211 * @param {!WebInspector.UISourceCode} to | |
212 */ | |
213 _moveBreakpoints: function(from, to) | |
214 { | |
215 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(fro m); | |
216 for (var breakpoint of breakpoints) { | |
217 breakpoint.remove(); | |
218 this._breakpointManager.setBreakpoint(to, breakpoint.lineNumber(), b reakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled()); | |
219 } | |
220 }, | |
221 | |
222 /** | |
223 * @param {!WebInspector.UISourceCode} from | |
224 * @param {!WebInspector.UISourceCode} to | |
225 */ | |
226 _copyBreakpoints: function(from, to) | |
227 { | |
228 var breakpoints = this._breakpointManager.breakpointsForUISourceCode(fro m); | |
229 for (var breakpoint of breakpoints) | |
230 this._breakpointManager.setBreakpoint(to, breakpoint.lineNumber(), b reakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled()); | |
231 }, | |
232 | |
233 /** | |
234 * @param {!WebInspector.UISourceCode} uiSourceCode | |
235 * @return {boolean} | |
236 */ | |
237 hasUnsavedCommittedChanges: function(uiSourceCode) | |
238 { | |
239 if (this._workspace.hasResourceContentTrackingExtensions()) | |
240 return false; | |
241 if (uiSourceCode.url() && WebInspector.fileManager.isURLSaved(uiSourceCo de.url())) | |
242 return false; | |
243 if (uiSourceCode.project().canSetFileContent()) | |
244 return false; | |
245 if (uiSourceCode[WebInspector.Persistence._binding]) | |
246 return false; | |
247 return !!uiSourceCode.history.length; | |
248 }, | |
249 | |
250 /** | |
251 * @param {!WebInspector.UISourceCode} uiSourceCode | |
252 * @return {?WebInspector.PersistenceBinding} | |
253 */ | |
254 binding: function(uiSourceCode) | |
255 { | |
256 return uiSourceCode[WebInspector.Persistence._binding] || null; | |
257 }, | |
258 | |
259 dispose: function() | |
260 { | |
261 WebInspector.EventTarget.removeEventListeners(this._eventListeners); | |
262 }, | |
263 | |
264 __proto__: WebInspector.Object.prototype | |
265 } | |
266 | |
267 /** | |
268 * @constructor | |
269 * @param {!WebInspector.UISourceCode} network | |
270 * @param {!WebInspector.UISourceCode} fileSystem | |
271 */ | |
272 WebInspector.PersistenceBinding = function(network, fileSystem) | |
273 { | |
274 this.network = network; | |
275 this.fileSystem = fileSystem; | |
276 } | |
277 | |
278 /** @type {!WebInspector.Persistence} */ | |
279 WebInspector.persistence; | |
OLD | NEW |