Added document max length limit, enforceMaxLength on change and show modal when reach the limit.

This commit is contained in:
Wu Cheng-Han 2015-07-16 22:46:06 +08:00
parent 57253d28a7
commit d14c5bdc9c
6 changed files with 59 additions and 9 deletions

View file

@ -46,6 +46,7 @@ var config = {
sessiontouch: 1 * 3600, //1 hour sessiontouch: 1 * 3600, //1 hour
heartbeatinterval: 5000, heartbeatinterval: 5000,
heartbeattimeout: 10000, heartbeattimeout: 10000,
documentmaxlength: 100000,
//auth //auth
facebook: { facebook: {
clientID: 'change this', clientID: 'change this',

View file

@ -95,6 +95,7 @@ EditorSocketIOServer.prototype.onOperation = function (socket, revision, operati
try { try {
var clientId = socket.id; var clientId = socket.id;
var wrappedPrime = this.receiveOperation(revision, wrapped); var wrappedPrime = this.receiveOperation(revision, wrapped);
if(!wrappedPrime) return;
//console.log("new operation: " + JSON.stringify(wrapped)); //console.log("new operation: " + JSON.stringify(wrapped));
this.getClient(clientId).selection = wrappedPrime.meta; this.getClient(clientId).selection = wrappedPrime.meta;
revision = this.operations.length; revision = this.operations.length;

View file

@ -1,3 +1,5 @@
var config = require('../../config');
if (typeof ot === 'undefined') { if (typeof ot === 'undefined') {
var ot = {}; var ot = {};
} }
@ -28,7 +30,10 @@ ot.Server = (function (global) {
} }
// ... and apply that on the document. // ... 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. // Store operation in history.
this.operations.push(operation); this.operations.push(operation);

View file

@ -207,6 +207,7 @@ function emitRefresh(socket) {
if (!notename || !notes[notename]) return; if (!notename || !notes[notename]) return;
var note = notes[notename]; var note = notes[notename];
socket.emit('refresh', { socket.emit('refresh', {
docmaxlength: config.documentmaxlength,
owner: note.owner, owner: note.owner,
permission: note.permission, permission: note.permission,
updatetime: note.updatetime updatetime: note.updatetime
@ -218,13 +219,12 @@ var connectionSocketQueue = [];
var isDisconnectBusy = false; var isDisconnectBusy = false;
var disconnectSocketQueue = []; var disconnectSocketQueue = [];
function finishConnection(socket, notename) { function finishConnection(socket, note, user) {
var note = notes[notename]; note.users[socket.id] = user;
note.users[socket.id] = users[socket.id];
note.socks.push(socket); note.socks.push(socket);
note.server.addClient(socket); note.server.addClient(socket);
note.server.setName(socket, users[socket.id].name); note.server.setName(socket, user.name);
note.server.setColor(socket, users[socket.id].color); note.server.setColor(socket, user.color);
emitOnlineUsers(socket); emitOnlineUsers(socket);
emitRefresh(socket); emitRefresh(socket);
@ -240,8 +240,9 @@ function finishConnection(socket, notename) {
startConnection(connectionSocketQueue[0]); startConnection(connectionSocketQueue[0]);
if (config.debug) { if (config.debug) {
var notename = getNotenameFromSocket(socket);
logger.info('SERVER connected a client to [' + notename + ']:'); logger.info('SERVER connected a client to [' + notename + ']:');
logger.info(JSON.stringify(users[socket.id])); logger.info(JSON.stringify(user));
//logger.info(notes); //logger.info(notes);
getStatus(function (data) { getStatus(function (data) {
logger.info(JSON.stringify(data)); logger.info(JSON.stringify(data));
@ -293,11 +294,11 @@ function startConnection(socket) {
updatetime: moment(updatetime).valueOf(), updatetime: moment(updatetime).valueOf(),
server: server server: server
}; };
finishConnection(socket, notename); finishConnection(socket, notes[notename], users[socket.id]);
}); });
}); });
} else { } else {
finishConnection(socket, notename); finishConnection(socket, notes[notename], users[socket.id]);
} }
} }

View file

@ -909,10 +909,13 @@ socket.on('permission', function (data) {
permission = data.permission; permission = data.permission;
checkPermission(); checkPermission();
}); });
var docmaxlength = null;
var otk = null; var otk = null;
var owner = null; var owner = null;
var permission = null; var permission = null;
socket.on('refresh', function (data) { socket.on('refresh', function (data) {
docmaxlength = data.docmaxlength;
editor.setOption("maxLength", docmaxlength);
otk = data.otk; otk = data.otk;
owner = data.owner; owner = data.owner;
permission = data.permission; permission = data.permission;
@ -1435,10 +1438,30 @@ function buildCursor(user) {
} }
//editor actions //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']; var ignoreEmitEvents = ['setValue', 'ignoreHistory'];
editor.on('beforeChange', function (cm, change) { editor.on('beforeChange', function (cm, change) {
if (debug) if (debug)
console.debug(change); console.debug(change);
if (enforceMaxLength(cm, change)) {
$('.limit-modal').modal('show');
}
var isIgnoreEmitEvent = (ignoreEmitEvents.indexOf(change.origin) != -1); var isIgnoreEmitEvent = (ignoreEmitEvents.indexOf(change.origin) != -1);
if (!isIgnoreEmitEvent) { if (!isIgnoreEmitEvent) {
switch (permission) { switch (permission) {

View file

@ -110,4 +110,23 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- limit modal -->
<div class="modal fade limit-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel"><i class="fa fa-exclamation-triangle"></i> Reach the limit</h4>
</div>
<div class="modal-body" style="color:black;">
<h5>Sorry, you've reached the max length this note can be.</h5>
<strong>Please reduce the content or divided it to more notes, thank you!</strong>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div> </div>