Commit 7b5206fb authored by lushnikov's avatar lushnikov Committed by Commit bot

DevTools: [Persistence] validate persistence binding.

This patch ensures that persistence binding is not established if working copy
of network UISourceCode does not match with the working copy of filesystem
UISourceCode.

This validation is done proactively: whenever automapping reports a binding,
we fetch contents of both network and filesystem UISourceCodes and compare them.

For this to work fast, we do *not* validate the following types of bindings:
- bindings of source map sources. These could be slow to fetch, and they don't break us in any
  way.
- bindings of binary files (e.g. images). These are never going to be edited, and
  thus can't deal any harm.

To sum up, we request contents only of those text resources which were already
succesfully loaded by the website itself, which means they are of manageble size.
However, to be on the safe side, this change is guarded by on-by-default experiment.

BUG=649837
R=dgozman

Review-Url: https://codereview.chromium.org/2542073002
Cr-Commit-Position: refs/heads/master@{#437761}
parent 31d36e81
Tests file system project mappings. Tests file system project mappings.
Running: testAutomaticMapping
Adding file system.
Adding network resource.
UISourceCode uri to url mappings:
file:///var/www/html/foo.js ->
file:///var/www/bar.js ->
Adding mapping between network and file system resources.
Emulate reloading inspector.
UISourceCode uri to url mappings:
file:///var/www/html/foo.js -> http://127.0.0.1:8000/inspector/resources/html/foo.js
file:///var/www/bar.js -> http://127.0.0.1:8000/inspector/resources/bar.js
Removing mapping between network and file system resources.
Emulate reloading inspector.
UISourceCode uri to url mappings:
file:///var/www/html/foo.js ->
file:///var/www/bar.js ->
Running: testProjectBasedMapping Running: testProjectBasedMapping
Adding file system. Adding file system.
UISourceCode uri to url mappings: UISourceCode uri to url mappings:
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<head> <head>
<script src="inspector-test.js"></script> <script src="inspector-test.js"></script>
<script src="debugger-test.js"></script> <script src="debugger-test.js"></script>
<script src="persistence/persistence-test.js"></script>
<script src="isolated-filesystem-test.js"></script> <script src="isolated-filesystem-test.js"></script>
<script> <script>
function addScript(url) function addScript(url)
...@@ -14,7 +15,6 @@ function addScript(url) ...@@ -14,7 +15,6 @@ function addScript(url)
function test() function test()
{ {
var target = InspectorTest.mainTarget; var target = InspectorTest.mainTarget;
var persistence = Persistence.persistence;
var fileSystemProjectId = Persistence.FileSystemWorkspaceBinding.projectId("file:///var/www"); var fileSystemProjectId = Persistence.FileSystemWorkspaceBinding.projectId("file:///var/www");
function dumpFileSystemUISourceCodesMappings() function dumpFileSystemUISourceCodesMappings()
...@@ -22,78 +22,19 @@ function test() ...@@ -22,78 +22,19 @@ function test()
var uiSourceCodes = Workspace.workspace.project(fileSystemProjectId).uiSourceCodes(); var uiSourceCodes = Workspace.workspace.project(fileSystemProjectId).uiSourceCodes();
InspectorTest.addResult("UISourceCode uri to url mappings:"); InspectorTest.addResult("UISourceCode uri to url mappings:");
for (var uiSourceCode of uiSourceCodes) { for (var uiSourceCode of uiSourceCodes) {
var binding = persistence.binding(uiSourceCode); var binding = Persistence.persistence.binding(uiSourceCode);
var url = binding ? binding.network.url() : ""; var url = binding ? binding.network.url() : "";
InspectorTest.addResult(" " + uiSourceCode.url() + " -> " + url); InspectorTest.addResult(" " + uiSourceCode.url() + " -> " + url);
} }
} }
InspectorTest.runTestSuite([ InspectorTest.runTestSuite([
function testAutomaticMapping(next)
{
InspectorTest.addResult("Adding file system.");
var fs = new InspectorTest.TestFileSystem("file:///var/www");
fs.root.mkdir("html").addFile("foo.js", "<foo content>");
fs.root.addFile("bar.js", "<bar content>");
fs.reportCreated(fileSystemCreated1);
var networkUISourceCode;
function fileSystemCreated1()
{
InspectorTest.addResult("Adding network resource.");
InspectorTest.waitForUISourceCode(scriptsAdded, "resources/bar.js");
InspectorTest.evaluateInPage("addScript('resources/html/foo.js')");
InspectorTest.evaluateInPage("addScript('resources/bar.js')");
}
function scriptsAdded()
{
dumpFileSystemUISourceCodesMappings();
var uiSourceCode = Workspace.workspace.uiSourceCode(fileSystemProjectId, "file:///var/www/html/foo.js");
networkUISourceCode = Workspace.workspace.uiSourceCode(Bindings.NetworkProject.projectId(target, InspectorTest.resourceTreeModel.mainFrame, false), "http://127.0.0.1:8000/inspector/resources/html/foo.js");
InspectorTest.addResult("Adding mapping between network and file system resources.");
var fileSystemPath = Persistence.FileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id());
Workspace.fileSystemMapping.addMappingForResource(networkUISourceCode.url(), fileSystemPath, uiSourceCode.url());
var setting = JSON.stringify(Workspace.fileSystemMapping._fileSystemMappingSetting.get());
InspectorTest.addResult("Emulate reloading inspector.");
fs.reportRemoved();
Workspace.fileSystemMapping._fileSystemMappingSetting.set(JSON.parse(setting));
Workspace.fileSystemMapping._loadFromSettings();
fs.reportCreated(fileSystemCreated2);
}
function fileSystemCreated2()
{
dumpFileSystemUISourceCodesMappings();
InspectorTest.addResult("Removing mapping between network and file system resources.");
var uiSourceCode = Workspace.workspace.uiSourceCode(fileSystemProjectId, "file:///var/www/html/foo.js");
Workspace.fileSystemMapping.removeMappingForURL(uiSourceCode.url());
InspectorTest.addResult("Emulate reloading inspector.");
fs.reportRemoved();
fs.reportCreated(fileSystemCreated3);
}
function fileSystemCreated3()
{
dumpFileSystemUISourceCodesMappings();
Workspace.fileSystemMapping.removeMappingForURL(networkUISourceCode.url());
fs.reportRemoved();
next();
}
},
function testProjectBasedMapping(next) function testProjectBasedMapping(next)
{ {
InspectorTest.addResult("Adding file system."); InspectorTest.addResult("Adding file system.");
var fs = new InspectorTest.TestFileSystem("file:///var/www"); var fs = new InspectorTest.TestFileSystem("file:///var/www");
fs.root.mkdir("html").addFile("foo.js", "<foo content>"); fs.root.mkdir("html").addFile("foo.js", "var foo = 1;");
fs.root.mkdir("html2").addFile("bar.js", "<bar content>"); fs.root.mkdir("html2").addFile("bar.js", "var bar = 2;");
fs.root.addFile(".devtools", JSON.stringify({ mappings: [ { folder: "/html/", url: "http://127.0.0.1:8000/inspector/resources/html/" }, { folder: "/html2/", url: "http://127.0.0.1:8000/inspector/resources/html2/" } ]})); fs.root.addFile(".devtools", JSON.stringify({ mappings: [ { folder: "/html/", url: "http://127.0.0.1:8000/inspector/resources/html/" }, { folder: "/html2/", url: "http://127.0.0.1:8000/inspector/resources/html2/" } ]}));
fs.reportCreated(fileSystemCreated); fs.reportCreated(fileSystemCreated);
...@@ -101,10 +42,13 @@ function test() ...@@ -101,10 +42,13 @@ function test()
{ {
InspectorTest.evaluateInPage("addScript('resources/html/foo.js')"); InspectorTest.evaluateInPage("addScript('resources/html/foo.js')");
InspectorTest.evaluateInPage("addScript('resources/html2/bar.js')"); InspectorTest.evaluateInPage("addScript('resources/html2/bar.js')");
InspectorTest.waitForUISourceCode(scriptsAdded, "resources/html2/bar.js"); Promise.all([
InspectorTest.waitForBinding("foo.js"),
InspectorTest.waitForBinding("bar.js")
]).then(onBindings);
} }
function scriptsAdded() function onBindings()
{ {
dumpFileSystemUISourceCodesMappings(); dumpFileSystemUISourceCodesMappings();
fs.reportRemoved(); fs.reportRemoved();
......
...@@ -4,7 +4,9 @@ Verify that dirty uiSourceCodes are not bound. ...@@ -4,7 +4,9 @@ Verify that dirty uiSourceCodes are not bound.
Running: waitForUISourceCodes Running: waitForUISourceCodes
Running: addFileSystemMapping Running: addFileSystemMapping
Failed to create binding: {
Running: dumpConsoleMessages network: http://127.0.0.1:8000/inspector/persistence/resources/foo.js
foo.js can not be persisted to file system due to unsaved changes. fileSystem: file:///var/www/inspector/persistence/resources/foo.js
exactMatch: false
}
...@@ -26,14 +26,14 @@ function test() ...@@ -26,14 +26,14 @@ function test()
function addFileSystemMapping(next) function addFileSystemMapping(next)
{ {
InspectorTest.addSniffer(Persistence.Persistence.prototype, '_prevalidationFailedForTest', onPrevalidationFailed);
Workspace.fileSystemMapping.addFileMapping(fs.fileSystemPath, "http://127.0.0.1:8000", "/"); Workspace.fileSystemMapping.addFileMapping(fs.fileSystemPath, "http://127.0.0.1:8000", "/");
next();
},
function dumpConsoleMessages(next) function onPrevalidationFailed(binding)
{ {
InspectorTest.dumpConsoleMessages(); InspectorTest.addResult("Failed to create binding: " + binding);
next(); next();
}
}, },
]); ]);
}; };
......
Verify that tabs get merged and split when binding is added and removed. Verify that tabs get merged when binding is added and removed.
Running: addFileSystem Running: addFileSystem
...@@ -13,7 +13,7 @@ Running: openFileSystemTab ...@@ -13,7 +13,7 @@ Running: openFileSystemTab
SourceFrame: file:///var/www/inspector/persistence/resources/foo.js SourceFrame: file:///var/www/inspector/persistence/resources/foo.js
selection: {"startLine":0,"startColumn":0,"endLine":0,"endColumn":0} selection: {"startLine":0,"startColumn":0,"endLine":0,"endColumn":0}
firstVisibleLine: 0 firstVisibleLine: 0
isDirty: true isDirty: false
Opened tabs: Opened tabs:
file:///var/www/inspector/persistence/resources/foo.js file:///var/www/inspector/persistence/resources/foo.js
http://127.0.0.1:8000/inspector/persistence/resources/foo.js http://127.0.0.1:8000/inspector/persistence/resources/foo.js
...@@ -24,7 +24,7 @@ Opened tabs: ...@@ -24,7 +24,7 @@ Opened tabs:
SourceFrame: file:///var/www/inspector/persistence/resources/foo.js SourceFrame: file:///var/www/inspector/persistence/resources/foo.js
selection: {"startLine":2,"startColumn":0,"endLine":2,"endColumn":5} selection: {"startLine":2,"startColumn":0,"endLine":2,"endColumn":5}
firstVisibleLine: 2 firstVisibleLine: 2
isDirty: true isDirty: false
Running: removeFileMapping Running: removeFileMapping
Opened tabs: Opened tabs:
...@@ -32,5 +32,5 @@ Opened tabs: ...@@ -32,5 +32,5 @@ Opened tabs:
SourceFrame: file:///var/www/inspector/persistence/resources/foo.js SourceFrame: file:///var/www/inspector/persistence/resources/foo.js
selection: {"startLine":2,"startColumn":0,"endLine":2,"endColumn":5} selection: {"startLine":2,"startColumn":0,"endLine":2,"endColumn":5}
firstVisibleLine: 2 firstVisibleLine: 2
isDirty: true isDirty: false
...@@ -38,15 +38,9 @@ function test() ...@@ -38,15 +38,9 @@ function test()
function openFileSystemTab(next) function openFileSystemTab(next)
{ {
InspectorTest.waitForUISourceCode("foo.js", Workspace.projectTypes.FileSystem) InspectorTest.waitForUISourceCode("foo.js", Workspace.projectTypes.FileSystem)
.then(onFileSystemSourceCode) .then(code => InspectorTest.showUISourceCodePromise(code))
.then(onFileSystemTab); .then(onFileSystemTab);
function onFileSystemSourceCode(code)
{
code.setWorkingCopy("\n\nwindow.foo = ()=>'foo2';");
return InspectorTest.showUISourceCodePromise(code);
}
function onFileSystemTab(sourceFrame) function onFileSystemTab(sourceFrame)
{ {
fileSystemSourceFrame = sourceFrame; fileSystemSourceFrame = sourceFrame;
...@@ -108,6 +102,6 @@ function test() ...@@ -108,6 +102,6 @@ function test()
</script> </script>
</head> </head>
<body onload="runTest()"> <body onload="runTest()">
<p>Verify that tabs get merged and split when binding is added and removed.</p> <p>Verify that tabs get merged when binding is added and removed.</p>
</body> </body>
</html> </html>
...@@ -40,7 +40,6 @@ Network: ...@@ -40,7 +40,6 @@ Network:
(function (exports, require, module, __filename, __dirname) { (function (exports, require, module, __filename, __dirname) {
var express = require("express"); var express = require("express");
network();
workingCopy1(); workingCopy1();
//TODO //TODO
}); });
...@@ -49,7 +48,6 @@ FileSystem: ...@@ -49,7 +48,6 @@ FileSystem:
#!/usr/bin/env node #!/usr/bin/env node
var express = require("express"); var express = require("express");
network();
workingCopy1(); workingCopy1();
//TODO //TODO
...@@ -76,7 +74,6 @@ Network: ...@@ -76,7 +74,6 @@ Network:
(function (exports, require, module, __filename, __dirname) { (function (exports, require, module, __filename, __dirname) {
var express = require("express"); var express = require("express");
filesystem();
workingCopy2(); workingCopy2();
//TODO //TODO
}); });
...@@ -85,7 +82,6 @@ FileSystem: ...@@ -85,7 +82,6 @@ FileSystem:
#!/usr/bin/env node #!/usr/bin/env node
var express = require("express"); var express = require("express");
filesystem();
workingCopy2(); workingCopy2();
//TODO //TODO
......
...@@ -52,9 +52,9 @@ function test() ...@@ -52,9 +52,9 @@ function test()
var testSuite = [ var testSuite = [
function addNetworkUISourceCodeRevision(next) function addNetworkUISourceCodeRevision(next)
{ {
nodeContent = nodeContent.replace("//TODO", "network();\n//TODO"); var newContent = nodeContent.replace("//TODO", "network();\n//TODO");
InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced); InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced);
binding.network.addRevision(nodeContent); binding.network.addRevision(newContent);
function onSynced() function onSynced()
{ {
...@@ -65,9 +65,9 @@ function test() ...@@ -65,9 +65,9 @@ function test()
function setNetworkUISourceCodeWorkingCopy(next) function setNetworkUISourceCodeWorkingCopy(next)
{ {
nodeContent = nodeContent.replace("//TODO", "workingCopy1();\n//TODO"); var newContent = nodeContent.replace("//TODO", "workingCopy1();\n//TODO");
InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced); InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced);
binding.network.setWorkingCopy(nodeContent); binding.network.setWorkingCopy(newContent);
function onSynced() function onSynced()
{ {
...@@ -78,9 +78,9 @@ function test() ...@@ -78,9 +78,9 @@ function test()
function changeFileSystemFile(next) function changeFileSystemFile(next)
{ {
fsContent = fsContent.replace("//TODO", "filesystem();\n//TODO"); var newContent = fsContent.replace("//TODO", "filesystem();\n//TODO");
InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced); InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced);
fsEntry.setContent(fsContent); fsEntry.setContent(newContent);
function onSynced() function onSynced()
{ {
...@@ -91,9 +91,9 @@ function test() ...@@ -91,9 +91,9 @@ function test()
function setFileSystemUISourceCodeWorkingCopy(next) function setFileSystemUISourceCodeWorkingCopy(next)
{ {
nodeContent = fsContent.replace("//TODO", "workingCopy2();\n//TODO"); var newContent = fsContent.replace("//TODO", "workingCopy2();\n//TODO");
InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced); InspectorTest.addSniffer(Persistence.Persistence.prototype, "_contentSyncedForTest", onSynced);
binding.fileSystem.setWorkingCopy(nodeContent); binding.fileSystem.setWorkingCopy(newContent);
function onSynced() function onSynced()
{ {
......
...@@ -3,6 +3,8 @@ var initialize_PersistenceTest = function() { ...@@ -3,6 +3,8 @@ var initialize_PersistenceTest = function() {
InspectorTest.preloadModule("persistence"); InspectorTest.preloadModule("persistence");
InspectorTest.preloadModule("sources"); InspectorTest.preloadModule("sources");
Runtime.experiments.enableForTest("persistenceValidation");
Persistence.PersistenceBinding.prototype.toString = function() Persistence.PersistenceBinding.prototype.toString = function()
{ {
var lines = [ var lines = [
......
<html> <html>
<head> <head>
<script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/inspector-test.js"></script>
<script src="../../../http/tests/inspector/persistence/persistence-test.js"></script>
<script src="../../../http/tests/inspector/debugger-test.js"></script> <script src="../../../http/tests/inspector/debugger-test.js"></script>
<script src="../../../http/tests/inspector/isolated-filesystem-test.js"></script> <script src="../../../http/tests/inspector/isolated-filesystem-test.js"></script>
<script src="../../../http/tests/inspector/live-edit-test.js"></script> <script src="../../../http/tests/inspector/live-edit-test.js"></script>
...@@ -26,7 +27,8 @@ function test() ...@@ -26,7 +27,8 @@ function test()
function fileSystemCreated() function fileSystemCreated()
{ {
InspectorTest.evaluateInPage("addScript()", didAddScript); InspectorTest.evaluateInPage("addScript()");
InspectorTest.waitForBinding("edit-me.js").then(didAddScript);
} }
function didAddScript() function didAddScript()
......
...@@ -104,6 +104,7 @@ Main.Main = class { ...@@ -104,6 +104,7 @@ Main.Main = class {
Runtime.experiments.register('liveSASS', 'Live SASS'); Runtime.experiments.register('liveSASS', 'Live SASS');
Runtime.experiments.register('nodeDebugging', 'Node debugging', true); Runtime.experiments.register('nodeDebugging', 'Node debugging', true);
Runtime.experiments.register('persistence2', 'Persistence 2.0'); Runtime.experiments.register('persistence2', 'Persistence 2.0');
Runtime.experiments.register('persistenceValidation', 'Validate persistence bindings');
Runtime.experiments.register('privateScriptInspection', 'Private script inspection'); Runtime.experiments.register('privateScriptInspection', 'Private script inspection');
Runtime.experiments.register('requestBlocking', 'Request blocking', true); Runtime.experiments.register('requestBlocking', 'Request blocking', true);
Runtime.experiments.register('timelineShowAllEvents', 'Show all events on Timeline', true); Runtime.experiments.register('timelineShowAllEvents', 'Show all events on Timeline', true);
...@@ -126,7 +127,7 @@ Main.Main = class { ...@@ -126,7 +127,7 @@ Main.Main = class {
Runtime.experiments.enableForTest('accessibilityInspection'); Runtime.experiments.enableForTest('accessibilityInspection');
} }
Runtime.experiments.setDefaultExperiments(['timelineRecordingPerspectives']); Runtime.experiments.setDefaultExperiments(['timelineRecordingPerspectives', 'persistenceValidation']);
} }
/** /**
......
...@@ -21,25 +21,62 @@ Persistence.Persistence = class extends Common.Object { ...@@ -21,25 +21,62 @@ Persistence.Persistence = class extends Common.Object {
var linkDecorator = new Persistence.PersistenceUtils.LinkDecorator(this); var linkDecorator = new Persistence.PersistenceUtils.LinkDecorator(this);
Components.Linkifier.setLinkDecorator(linkDecorator); Components.Linkifier.setLinkDecorator(linkDecorator);
this._mapping = this._mapping =
new Persistence.Automapping(workspace, this._onBindingCreated.bind(this), this._onBindingRemoved.bind(this)); new Persistence.Automapping(workspace, this._validateBinding.bind(this), this._onBindingRemoved.bind(this));
} else { } else {
this._mapping = new Persistence.DefaultMapping( this._mapping = new Persistence.DefaultMapping(
workspace, fileSystemMapping, this._onBindingCreated.bind(this), this._onBindingRemoved.bind(this)); workspace, fileSystemMapping, this._validateBinding.bind(this), this._onBindingRemoved.bind(this));
} }
} }
/** /**
* @param {!Persistence.PersistenceBinding} binding * @param {!Persistence.PersistenceBinding} binding
*/ */
_onBindingCreated(binding) { _validateBinding(binding) {
if (binding.network.isDirty()) { if (!Runtime.experiments.isEnabled('persistenceValidation') || binding.network.contentType().isFromSourceMap() ||
Common.console.log( !binding.fileSystem.contentType().isTextType()) {
Common.UIString('%s can not be persisted to file system due to unsaved changes.', binding.network.name())); this._establishBinding(binding);
return; return;
} }
if (binding.fileSystem.isDirty())
binding.network.setWorkingCopy(binding.fileSystem.workingCopy());
Promise.all([binding.network.requestContent(), binding.fileSystem.requestContent()]).then(onContents.bind(this));
/**
* @this {Persistence.Persistence}
*/
function onContents() {
if (binding._removed)
return;
var fileSystemContent = binding.fileSystem.workingCopy();
var networkContent = binding.network.workingCopy();
var target = Bindings.NetworkProject.targetForUISourceCode(binding.network);
var isValid = false;
if (target.isNodeJS()) {
var rewrappedNetworkContent = Persistence.Persistence._rewrapNodeJSContent(
binding, binding.fileSystem, fileSystemContent, networkContent);
isValid = (fileSystemContent === rewrappedNetworkContent);
} else {
// Trim trailing whitespaces because V8 adds trailing newline.
isValid = (fileSystemContent.trimRight() === networkContent.trimRight());
}
if (isValid)
this._establishBinding(binding);
else
this._prevalidationFailedForTest(binding);
}
}
/**
* @param {!Persistence.PersistenceBinding} binding
*/
_prevalidationFailedForTest(binding) {
}
/**
* @param {!Persistence.PersistenceBinding} binding
*/
_establishBinding(binding) {
binding.network[Persistence.Persistence._binding] = binding; binding.network[Persistence.Persistence._binding] = binding;
binding.fileSystem[Persistence.Persistence._binding] = binding; binding.fileSystem[Persistence.Persistence._binding] = binding;
...@@ -64,6 +101,13 @@ Persistence.Persistence = class extends Common.Object { ...@@ -64,6 +101,13 @@ Persistence.Persistence = class extends Common.Object {
* @param {!Persistence.PersistenceBinding} binding * @param {!Persistence.PersistenceBinding} binding
*/ */
_onBindingRemoved(binding) { _onBindingRemoved(binding) {
binding._removed = true;
if (binding.network[Persistence.Persistence._binding] !== binding)
return;
console.assert(
binding.network[Persistence.Persistence._binding] === binding.fileSystem[Persistence.Persistence._binding],
'ERROR: inconsistent binding for networkURL ' + binding.network.url());
binding.network[Persistence.Persistence._binding] = null; binding.network[Persistence.Persistence._binding] = null;
binding.fileSystem[Persistence.Persistence._binding] = null; binding.fileSystem[Persistence.Persistence._binding] = null;
...@@ -95,7 +139,8 @@ Persistence.Persistence = class extends Common.Object { ...@@ -95,7 +139,8 @@ Persistence.Persistence = class extends Common.Object {
if (target.isNodeJS()) { if (target.isNodeJS()) {
var newContent = uiSourceCode.workingCopy(); var newContent = uiSourceCode.workingCopy();
other.requestContent().then(() => { other.requestContent().then(() => {
var nodeJSContent = this._rewrapNodeJSContent(binding, other, other.workingCopy(), newContent); var nodeJSContent =
Persistence.Persistence._rewrapNodeJSContent(binding, other, other.workingCopy(), newContent);
setWorkingCopy.call(this, () => nodeJSContent); setWorkingCopy.call(this, () => nodeJSContent);
}); });
return; return;
...@@ -128,7 +173,7 @@ Persistence.Persistence = class extends Common.Object { ...@@ -128,7 +173,7 @@ Persistence.Persistence = class extends Common.Object {
var target = Bindings.NetworkProject.targetForUISourceCode(binding.network); var target = Bindings.NetworkProject.targetForUISourceCode(binding.network);
if (target.isNodeJS()) { if (target.isNodeJS()) {
other.requestContent().then(currentContent => { other.requestContent().then(currentContent => {
var nodeJSContent = this._rewrapNodeJSContent(binding, other, currentContent, newContent); var nodeJSContent = Persistence.Persistence._rewrapNodeJSContent(binding, other, currentContent, newContent);
setContent.call(this, nodeJSContent); setContent.call(this, nodeJSContent);
}); });
return; return;
...@@ -154,7 +199,7 @@ Persistence.Persistence = class extends Common.Object { ...@@ -154,7 +199,7 @@ Persistence.Persistence = class extends Common.Object {
* @param {string} newContent * @param {string} newContent
* @return {string} * @return {string}
*/ */
_rewrapNodeJSContent(binding, uiSourceCode, currentContent, newContent) { static _rewrapNodeJSContent(binding, uiSourceCode, currentContent, newContent) {
if (uiSourceCode === binding.fileSystem) { if (uiSourceCode === binding.fileSystem) {
if (newContent.startsWith(Persistence.Persistence._NodePrefix) && if (newContent.startsWith(Persistence.Persistence._NodePrefix) &&
newContent.endsWith(Persistence.Persistence._NodeSuffix)) { newContent.endsWith(Persistence.Persistence._NodeSuffix)) {
...@@ -290,6 +335,7 @@ Persistence.PersistenceBinding = class { ...@@ -290,6 +335,7 @@ Persistence.PersistenceBinding = class {
this.network = network; this.network = network;
this.fileSystem = fileSystem; this.fileSystem = fileSystem;
this.exactMatch = exactMatch; this.exactMatch = exactMatch;
this._removed = false;
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment