diff --git a/plugins/c9.core/settings.js b/plugins/c9.core/settings.js index 94d526e0..adee11cd 100644 --- a/plugins/c9.core/settings.js +++ b/plugins/c9.core/settings.js @@ -88,12 +88,13 @@ define(function(require, exports, module) { } var count = KEYS.length; + var hasJSON = json; + if (!json) + json = {}; KEYS.forEach(function(type) { - if (!skipCloud[type] && json) + if (!skipCloud[type] && hasJSON) return --count; - if (!json) - json = {}; if (type == "state" && debugMode) return done(null, localStorage["debugState" + c9.projectName]); fs.readFile(PATH[type], done); diff --git a/plugins/c9.vfs.client/vfs_client_mock.js b/plugins/c9.vfs.client/vfs_client_mock.js index 1321f7ea..b5772a00 100644 --- a/plugins/c9.vfs.client/vfs_client_mock.js +++ b/plugins/c9.vfs.client/vfs_client_mock.js @@ -17,6 +17,7 @@ define(function(require, exports, module) { var fsData = {}; var Stream = require("stream").Stream; + var basename = require("path").basename; var noop = function() { console.error("not implemented"); }; var silent = function() {}; var connection = {}; @@ -87,6 +88,17 @@ define(function(require, exports, module) { stream.emit("end"); } + function readBlob(blob, callback) { + var reader = new FileReader(); + reader.onload = function() { + callback(null, reader.result); + }; + reader.onerror = function(e) { + callback(e); + }; + reader.readAsText(blob); + } + plugin.on("load", load); plugin.on("unload", unload); @@ -104,8 +116,46 @@ define(function(require, exports, module) { get baseUrl() { return vfsBaseUrl; }, get region() { return ""; }, - rest: noop, - download: noop, + rest: function(path, options, callback) { + if (options.method == "PUT") { + if (typeof options.body == "object") { + return readBlob(options.body, function(e, value) { + if (e) return callback(e); + plugin.rest(path, { + method: "PUT", + body: value, + }, callback); + }); + } + sendStream(options.body, function(err, stream) { + if (err) return callback(err); + plugin.mkfile(path, stream, callback); + }); + } else if (options.method == "GET") { + var result = findNode(path); + setTimeout(function() { + callback(null, result); + }, 20); + } + }, + download: function(path, filename, isfile) { + // TODO use jszip for folders + if (Array.isArray(path) && path.length > 1) { + return path.map(function(x) { + plugin.download(x); + }); + } + var data = findNode(path); + if (typeof data !== "string") + return console.error("not implemented"); + var a = document.createElement('a'); + a.href = URL.createObjectURL(new Blob([data], { type: "text/plain" })); + a.download = filename || basename(path); + + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + }, url: noop, reconnect: noop, @@ -224,7 +274,7 @@ define(function(require, exports, module) { var parts = to.split("/"); var toName = "!" + parts.pop(); - var toParent = findNode(parts.join("/")); + var toParent = findNode(parts.join("/"), true); parts = from.split("/"); var fromName = "!" + parts.pop(); diff --git a/plugins/c9.vfs.standalone/www/ide.offline.html b/plugins/c9.vfs.standalone/www/ide.offline.html index 1b8e5868..8c0c977c 100644 --- a/plugins/c9.vfs.standalone/www/ide.offline.html +++ b/plugins/c9.vfs.standalone/www/ide.offline.html @@ -47,6 +47,34 @@ - + + \ No newline at end of file diff --git a/plugins/c9.vfs.standalone/www/offline.preview/serviceWorker.js b/plugins/c9.vfs.standalone/www/offline.preview/serviceWorker.js new file mode 100644 index 00000000..45c362ab --- /dev/null +++ b/plugins/c9.vfs.standalone/www/offline.preview/serviceWorker.js @@ -0,0 +1,61 @@ +/*global clients, BroadcastChannel*/ + +var root = new URL(this.registration.scope); +var bc = new BroadcastChannel("livePreview"); +var id = 0; +var callbacks = {}; +var callBc = function(data, callback) { + data.id = id++; + callbacks[data.id] = callback; + bc.postMessage(data); +}; +bc.onmessage = function(e) { + var data = e.data; + if (data.action == "callback") { + var callback = callbacks[data.id]; + if (!callback) return; + delete callbacks[data.id]; + callback(data.error, data.value); + } +}; +this.onfetch = function(event) { + var url = new URL(event.request.url); + if (url.origin == root.origin) { + var path = url.searchParams.get("u"); + if (!path) path = url.pathname; + if (path.startsWith(root.pathname)) + path = path.substr(root.pathname.length - 1); + if (path) { + event.respondWith( + new Promise(function(resolve, reject) { + callBc({ action: "getFile", path: path }, function(e, v) { + if (e) reject(e); + resolve(v); + }); + }).then(function(v) { + return new Response(v, { + headers: { + "Content-Type": getMime(path) + } + }); + }, function(err) { + return new Response("error fetching " + path + " " + err, { + status: 400, + statusText: "Failure", + headers: { + "Content-Type": "text/x-error" + } + }); + }) + ); + } + } +}; + + +function getMime(path) { + if (path.endsWith(".html")) return "text/html"; + if (path.endsWith(".js")) return "text/javascript"; + if (path.endsWith(".css")) return "text/css"; + if (path.endsWith(".svg")) return "image/svg+xml"; +} \ No newline at end of file