diff --git a/lib/client/edit.js b/lib/client/edit.js index 430a1159..f16367e8 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -45,10 +45,11 @@ var CloudCmd, Util, DOM, CloudFunc, io, ace, DiffProto, diff_match_patch, Zip, M exec.series([ CloudCmd.View, load, - Edit.show.bind(null, callback), - function() { + function(callback) { + Util.exec(callback); DOM.loadSocket(initSocket); - } + }, + Edit.show.bind(null, callback), ]); } @@ -63,12 +64,12 @@ var CloudCmd, Util, DOM, CloudFunc, io, ace, DiffProto, diff_match_patch, Zip, M var socket, href = getHost(), FIVE_SECONDS = 5000, - patch = function(path, patch) { - socket.emit('patch', path, patch); + patch = function(name, data) { + socket.emit('patch', name, data); }; if (!error) { - socket = io.connect(href + '/config', { + socket = io.connect(href + '/edit', { 'max reconnection attempts' : Math.pow(2, 32), 'reconnection limit' : FIVE_SECONDS }); @@ -81,6 +82,25 @@ var CloudCmd, Util, DOM, CloudFunc, io, ace, DiffProto, diff_match_patch, Zip, M onSave(msg); }); + socket.on('patch', function(name, data, hashFS) { + if (name === Info.path) + loadDiff(function(error) { + if (error) { + Util.log(error); + } else { + sha(function(error, hash) { + var value; + + if (hash === hashFS) { + value = Edit.getValue(); + value = Diff.applyPatch(value, data); + Edit.setValue(value); + } + }); + } + }); + }); + socket.on('disconnect', function() { Edit.save.patch = patchHttp; }); @@ -127,6 +147,10 @@ var CloudCmd, Util, DOM, CloudFunc, io, ace, DiffProto, diff_match_patch, Zip, M } }; + this.getValue = function() { + return Ace.getValue(); + }; + this.setValue = function(value) { var UndoManager = ace.require('ace/undomanager').UndoManager; @@ -381,21 +405,13 @@ var CloudCmd, Util, DOM, CloudFunc, io, ace, DiffProto, diff_match_patch, Zip, M } function diff(newValue, callback) { - var url = join([ - LIBDIR + 'diff/diff-match-patch.js', - LIBDIR + 'diff.js' - ]); - - DOM.load.js(url, function(error) { + loadDiff(function(error) { var patch, isAllowed = Storage.isAllowed(); if (error) { Dialog.alert(error); } else { - if (!Diff) - Diff = new DiffProto(diff_match_patch); - exec.if(!isAllowed, function() { patch = Diff.createPatch(Value, newValue); exec(callback, patch); @@ -413,6 +429,20 @@ var CloudCmd, Util, DOM, CloudFunc, io, ace, DiffProto, diff_match_patch, Zip, M }); } + function loadDiff(callback) { + var url = join([ + LIBDIR + 'diff/diff-match-patch.js', + LIBDIR + 'diff.js' + ]); + + DOM.load.js(url, function(error) { + if (!error && !Diff) + Diff = new DiffProto(diff_match_patch); + + callback(error); + }); + } + function zip(value, callback) { var dir = CloudCmd.LIBDIRCLIENT, url = join([ diff --git a/lib/cloudcmd.js b/lib/cloudcmd.js index b4c18c9e..76ee6087 100644 --- a/lib/cloudcmd.js +++ b/lib/cloudcmd.js @@ -9,6 +9,7 @@ auth = require(DIR_SERVER + 'auth'), config = require(DIR_SERVER + 'config'), + edit = require(DIR_SERVER + 'edit'), minify = require(DIR_SERVER + 'minify'), rest = require(DIR_SERVER + 'rest'), route = require(DIR_SERVER + 'route'), @@ -58,6 +59,7 @@ }); terminal(socket); + edit(socket); config.socket(socket); }; diff --git a/lib/server/edit.js b/lib/server/edit.js index 1184544b..75aceee9 100644 --- a/lib/server/edit.js +++ b/lib/server/edit.js @@ -7,28 +7,56 @@ path = require('path'), Util = require(DIR_LIB + 'util'), CloudFunc = require(DIR_LIB + 'cloudfunc'), - patch = require(DIR_SERVER + 'patch'); + patch = require(DIR_SERVER + 'patch'), + files = require(DIR_SERVER + 'files'), + hash = require(DIR_SERVER + 'hash'); module.exports = function(sock) { Util.check(arguments, ['socket']); - sock.of('/config') + sock.of('/edit') .on('connection', function(socket) { - socket.on('patch', function(data) { + socket.on('patch', function(name, data) { var options = { - size: CloudFunc.MAX_FILE_SIZE - }; - - patch(name, data, options, function(error) { - var baseName = path.basename(name), - msg = CloudFunc.formatMsg('patch', baseName); + size: CloudFunc.MAX_FILE_SIZE + }; - if (error) - socket.emit('err', error); - else - socket.emit('message', msg); - }); + getHash(name, function(error, hash) { + if (error) + socket.emit('err', error); + else + patch(name, data, options, function(error) { + var msg, baseName; + + if (error) { + socket.emit('err', error); + } else { + baseName = path.basename(name), + msg = CloudFunc.formatMsg('patch', baseName); + + socket.emit('message', msg); + socket.broadcast.emit('patch', name, data, hash); + } + }); + }); }); }); }; + + function getHash(name, callback) { + var error, hashStream = hash(); + + if (!hashStream) { + error = 'hash: not suported, try update node'; + callback(Error(error)); + } else + files.pipe(name, hashStream, function (error) { + var hex; + + if (!error) + hex = hashStream.get(); + + callback(error, hex); + }); + } })();