From d14c5bdc9cabf632262067466ef02374cee496cd Mon Sep 17 00:00:00 2001 From: Wu Cheng-Han Date: Thu, 16 Jul 2015 22:46:06 +0800 Subject: [PATCH] Added document max length limit, enforceMaxLength on change and show modal when reach the limit. --- config.js | 1 + lib/ot/editor-socketio-server.js | 1 + lib/ot/server.js | 7 ++++++- lib/realtime.js | 17 +++++++++-------- public/js/index.js | 23 +++++++++++++++++++++++ public/views/body.ejs | 19 +++++++++++++++++++ 6 files changed, 59 insertions(+), 9 deletions(-) diff --git a/config.js b/config.js index 54a8ae3..cfd9f20 100644 --- a/config.js +++ b/config.js @@ -46,6 +46,7 @@ var config = { sessiontouch: 1 * 3600, //1 hour heartbeatinterval: 5000, heartbeattimeout: 10000, + documentmaxlength: 100000, //auth facebook: { clientID: 'change this', diff --git a/lib/ot/editor-socketio-server.js b/lib/ot/editor-socketio-server.js index ade8fc5..67920cb 100755 --- a/lib/ot/editor-socketio-server.js +++ b/lib/ot/editor-socketio-server.js @@ -95,6 +95,7 @@ EditorSocketIOServer.prototype.onOperation = function (socket, revision, operati try { var clientId = socket.id; var wrappedPrime = this.receiveOperation(revision, wrapped); + if(!wrappedPrime) return; //console.log("new operation: " + JSON.stringify(wrapped)); this.getClient(clientId).selection = wrappedPrime.meta; revision = this.operations.length; diff --git a/lib/ot/server.js b/lib/ot/server.js index 608d434..fec3b6f 100644 --- a/lib/ot/server.js +++ b/lib/ot/server.js @@ -1,3 +1,5 @@ +var config = require('../../config'); + if (typeof ot === 'undefined') { var ot = {}; } @@ -28,7 +30,10 @@ ot.Server = (function (global) { } // ... and apply that on the document. - this.document = operation.apply(this.document); + var newDocument = operation.apply(this.document); + // ignore if exceed the max length of document + if(newDocument.length > config.documentmaxlength) return; + this.document = newDocument; // Store operation in history. this.operations.push(operation); diff --git a/lib/realtime.js b/lib/realtime.js index 3e36715..0b5a46b 100644 --- a/lib/realtime.js +++ b/lib/realtime.js @@ -207,6 +207,7 @@ function emitRefresh(socket) { if (!notename || !notes[notename]) return; var note = notes[notename]; socket.emit('refresh', { + docmaxlength: config.documentmaxlength, owner: note.owner, permission: note.permission, updatetime: note.updatetime @@ -218,13 +219,12 @@ var connectionSocketQueue = []; var isDisconnectBusy = false; var disconnectSocketQueue = []; -function finishConnection(socket, notename) { - var note = notes[notename]; - note.users[socket.id] = users[socket.id]; +function finishConnection(socket, note, user) { + note.users[socket.id] = user; note.socks.push(socket); note.server.addClient(socket); - note.server.setName(socket, users[socket.id].name); - note.server.setColor(socket, users[socket.id].color); + note.server.setName(socket, user.name); + note.server.setColor(socket, user.color); emitOnlineUsers(socket); emitRefresh(socket); @@ -240,8 +240,9 @@ function finishConnection(socket, notename) { startConnection(connectionSocketQueue[0]); if (config.debug) { + var notename = getNotenameFromSocket(socket); logger.info('SERVER connected a client to [' + notename + ']:'); - logger.info(JSON.stringify(users[socket.id])); + logger.info(JSON.stringify(user)); //logger.info(notes); getStatus(function (data) { logger.info(JSON.stringify(data)); @@ -293,11 +294,11 @@ function startConnection(socket) { updatetime: moment(updatetime).valueOf(), server: server }; - finishConnection(socket, notename); + finishConnection(socket, notes[notename], users[socket.id]); }); }); } else { - finishConnection(socket, notename); + finishConnection(socket, notes[notename], users[socket.id]); } } diff --git a/public/js/index.js b/public/js/index.js index c90255e..4068d59 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -909,10 +909,13 @@ socket.on('permission', function (data) { permission = data.permission; checkPermission(); }); +var docmaxlength = null; var otk = null; var owner = null; var permission = null; socket.on('refresh', function (data) { + docmaxlength = data.docmaxlength; + editor.setOption("maxLength", docmaxlength); otk = data.otk; owner = data.owner; permission = data.permission; @@ -1435,10 +1438,30 @@ function buildCursor(user) { } //editor actions +function enforceMaxLength(cm, change) { + var maxLength = cm.getOption("maxLength"); + if (maxLength && change.update) { + var str = change.text.join("\n"); + var delta = str.length - (cm.indexFromPos(change.to) - cm.indexFromPos(change.from)); + if (delta <= 0) { + return false; + } + delta = cm.getValue().length + delta - maxLength; + if (delta > 0) { + str = str.substr(0, str.length - delta); + change.update(change.from, change.to, str.split("\n")); + return true; + } + } + return false; +} var ignoreEmitEvents = ['setValue', 'ignoreHistory']; editor.on('beforeChange', function (cm, change) { if (debug) console.debug(change); + if (enforceMaxLength(cm, change)) { + $('.limit-modal').modal('show'); + } var isIgnoreEmitEvent = (ignoreEmitEvents.indexOf(change.origin) != -1); if (!isIgnoreEmitEvent) { switch (permission) { diff --git a/public/views/body.ejs b/public/views/body.ejs index 1367d9f..d67267b 100644 --- a/public/views/body.ejs +++ b/public/views/body.ejs @@ -110,4 +110,23 @@ + + + \ No newline at end of file