Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(626)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js

Issue 2542073002: DevTools: [Persistence] validate persistence binding. (Closed)
Patch Set: rebaseline tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/main/Main.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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;
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/devtools/front_end/main/Main.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698