resolve merge conflicts and jquery errors

pull/1/head
ansuz 8 years ago
commit f7e96b4e8c

@ -32,7 +32,10 @@ define(function() {
'#FF00C0', // hot pink '#FF00C0', // hot pink
'#800080', // purple '#800080', // purple
]; ];
config.enableTemplates = true; config.enableTemplates = true;
config.enableHistory = true;
return config; return config;
}); });

@ -409,6 +409,31 @@
.cryptpad-toolbar-rightside { .cryptpad-toolbar-rightside {
text-align: right; text-align: right;
} }
.cryptpad-toolbar-history {
display: none;
text-align: center;
.next {
float: right;
}
.previous {
float: left;
}
.goto {
display: inline-block;
input { width: 50px; }
}
.gotoInput {
vertical-align: middle;
}
}
.cke_toolbox .cryptpad-toolbar-history {
input.gotoInput {
background: white;
height: 20px;
padding: 3px 3px;
border-radius: 5px;
}
}
.cryptpad-spinner { .cryptpad-spinner {
height: 16px; height: 16px;
width: 16px; width: 16px;

@ -472,6 +472,31 @@
.cryptpad-toolbar-rightside { .cryptpad-toolbar-rightside {
text-align: right; text-align: right;
} }
.cryptpad-toolbar-history {
display: none;
text-align: center;
}
.cryptpad-toolbar-history .next {
float: right;
}
.cryptpad-toolbar-history .previous {
float: left;
}
.cryptpad-toolbar-history .goto {
display: inline-block;
}
.cryptpad-toolbar-history .goto input {
width: 50px;
}
.cryptpad-toolbar-history .gotoInput {
vertical-align: middle;
}
.cke_toolbox .cryptpad-toolbar-history input.gotoInput {
background: white;
height: 20px;
padding: 3px 3px;
border-radius: 5px;
}
.cryptpad-spinner { .cryptpad-spinner {
height: 16px; height: 16px;
width: 16px; width: 16px;

@ -115,6 +115,17 @@ define(function () {
out.cancel = "Annuler"; out.cancel = "Annuler";
out.cancelButton = 'Annuler (Echap)'; out.cancelButton = 'Annuler (Echap)';
out.historyButton = "Afficher l'historique du document";
out.history_next = "Voir la version suivante";
out.history_prev = "Voir la version précédente";
out.history_goTo = "Voir la version sélectionnée";
out.history_close = "Retour";
out.history_closeTitle = "Fermer l'historique";
out.history_restore = "Restaurer";
out.history_restoreTitle = "Restaurer la version du document sélectionnée";
out.history_restorePrompt = "Êtes-vous sûr de vouloir remplacer la version actuelle du document par la version affichée ?";
out.history_restoreDone = "Document restauré";
// Polls // Polls
out.poll_title = "Sélecteur de date Zero Knowledge"; out.poll_title = "Sélecteur de date Zero Knowledge";

@ -117,6 +117,17 @@ define(function () {
out.cancel = "Cancel"; out.cancel = "Cancel";
out.cancelButton = 'Cancel (esc)'; out.cancelButton = 'Cancel (esc)';
out.historyButton = "Display the document history";
out.history_next = "Go to the next version";
out.history_prev = "Go to the previous version";
out.history_goTo = "Go to the selected version";
out.history_close = "Back";
out.history_closeTitle = "Close the history";
out.history_restore = "Restore";
out.history_restoreTitle = "Restore the selected version of the document";
out.history_restorePrompt = "Are you sure you want to replace the current version of the document by the displayed one?";
out.history_restoreDone = "Document restored";
// Polls // Polls
out.poll_title = "Zero Knowledge Date Picker"; out.poll_title = "Zero Knowledge Date Picker";

@ -52,6 +52,8 @@ define([
var defaultName = Cryptpad.getDefaultName(parsedHash); var defaultName = Cryptpad.getDefaultName(parsedHash);
var initialState = Messages.codeInitialState; var initialState = Messages.codeInitialState;
var isHistoryMode = false;
var editor = module.editor = CMeditor.fromTextArea($textarea[0], { var editor = module.editor = CMeditor.fromTextArea($textarea[0], {
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
@ -162,6 +164,14 @@ define([
var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); }; var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); };
var setHistory = function (bool, update) {
isHistoryMode = bool;
setEditable(!bool);
if (!bool && update) {
config.onRemote();
}
};
var isDefaultTitle = function () { var isDefaultTitle = function () {
var parsed = Cryptpad.parsePadUrl(window.location.href); var parsed = Cryptpad.parsePadUrl(window.location.href);
return Cryptpad.isDefaultName(parsed, document.title); return Cryptpad.isDefaultName(parsed, document.title);
@ -189,6 +199,7 @@ define([
var onLocal = config.onLocal = function () { var onLocal = config.onLocal = function () {
if (initializing) { return; } if (initializing) { return; }
if (isHistoryMode) { return; }
if (readOnly) { return; } if (readOnly) { return; }
editor.save(); editor.save();
@ -370,7 +381,7 @@ define([
var onInit = config.onInit = function (info) { var onInit = config.onInit = function (info) {
userList = info.userList; userList = info.userList;
var config = { var configTb = {
displayed: ['useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad'], displayed: ['useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad'],
userData: userData, userData: userData,
readOnly: readOnly, readOnly: readOnly,
@ -386,8 +397,7 @@ define([
}, },
common: Cryptpad common: Cryptpad
}; };
if (readOnly) {delete config.changeNameID; } toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, userList, configTb);
toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside); var $rightside = $bar.find('.' + Toolbar.constants.rightside);
var $userBlock = $bar.find('.' + Toolbar.constants.username); var $userBlock = $bar.find('.' + Toolbar.constants.username);
@ -400,6 +410,38 @@ define([
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys); editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
} }
/* add a history button */
var histConfig = {};
histConfig.onRender = function (val) {
if (typeof val === "undefined") { return; }
try {
var hjson = JSON.parse(val || '{}');
var remoteDoc = hjson.content;
editor.setValue(remoteDoc || '');
editor.save();
} catch (e) {
// Probably a parse error
console.error(e);
}
};
histConfig.onClose = function () {
// Close button clicked
setHistory(false, true);
};
histConfig.onRevert = function () {
// Revert button clicked
setHistory(false, false);
config.onLocal();
config.onRemote();
};
histConfig.onReady = function () {
// Called when the history is loaded and the UI displayed
setHistory(true);
};
histConfig.$toolbar = $bar;
var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig});
$rightside.append($hist);
/* save as template */ /* save as template */
if (!Cryptpad.isTemplate(window.location.href)) { if (!Cryptpad.isTemplate(window.location.href)) {
var templateObj = { var templateObj = {
@ -646,6 +688,7 @@ define([
var onRemote = config.onRemote = function () { var onRemote = config.onRemote = function () {
if (initializing) { return; } if (initializing) { return; }
if (isHistoryMode) { return; }
var scroll = editor.getScrollInfo(); var scroll = editor.getScrollInfo();
var oldDoc = canonicalize($textarea.val()); var oldDoc = canonicalize($textarea.val());

@ -0,0 +1,225 @@
define([
'jquery',
'/bower_components/chainpad-json-validator/json-ot.js',
'/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad/chainpad.dist.js',
], function ($, JsonOT, Crypto) {
var ChainPad = window.ChainPad;
var History = {};
var getStates = function (rt) {
var states = [];
var b = rt.getAuthBlock();
if (b) { states.unshift(b); }
while (b.getParent()) {
b = b.getParent();
states.unshift(b);
}
return states;
};
var loadHistory = function (common, cb) {
var network = common.getNetwork();
var hkn = network.historyKeeper;
var wcId = common.hrefToHexChannelId(window.location.href);
var createRealtime = function(chan) {
return ChainPad.create({
userName: 'history',
initialState: '',
transformFunction: JsonOT.validate,
logLevel: 0,
noPrune: true
});
};
var realtime = createRealtime();
var secret = common.getSecrets();
var crypto = Crypto.createEncryptor(secret.keys);
var to = window.setTimeout(function () {
cb('[GET_FULL_HISTORY_TIMEOUT]');
}, 30000);
var parse = function (msg) {
try {
return JSON.parse(msg);
} catch (e) {
return null;
}
};
var onMsg = function (msg) {
var parsed = parse(msg);
if (parsed[0] === 'FULL_HISTORY_END') {
console.log('END');
window.clearTimeout(to);
cb(null, realtime);
return;
}
if (parsed[0] !== 'FULL_HISTORY') { return; }
msg = parsed[1][4];
if (msg) {
msg = msg.replace(/^cp\|/, '');
var decryptedMsg = crypto.decrypt(msg, secret.keys.validateKey);
realtime.message(decryptedMsg);
}
};
network.on('message', function (msg, sender) {
onMsg(msg);
});
network.sendto(hkn, JSON.stringify(['GET_FULL_HISTORY', wcId, secret.keys.validateKey]));
};
var create = History.create = function (common, config) {
if (!config.$toolbar) { return void console.error("config.$toolbar is undefined");}
var $toolbar = config.$toolbar;
var noFunc = function () {};
var render = config.onRender || noFunc;
var onClose = config.onClose || noFunc;
var onRevert = config.onRevert || noFunc;
var onReady = config.onReady || noFunc;
var Messages = common.Messages;
var realtime;
var states = [];
var c = states.length - 1;
var $hist = $toolbar.find('.cryptpad-toolbar-history');
var $left = $toolbar.find('.cryptpad-toolbar-leftside');
var $right = $toolbar.find('.cryptpad-toolbar-rightside');
var $cke = $toolbar.find('.cke_toolbox_main');
var onUpdate;
var update = function () {
if (!realtime) { return []; }
states = getStates(realtime);
if (typeof onUpdate === "function") { onUpdate(); }
return states;
};
// Get the content of the selected version, and change the version number
var get = function (i) {
i = parseInt(i);
if (isNaN(i)) { return; }
if (i < 0) { i = 0; }
if (i > states.length - 1) { i = states.length - 1; }
var val = states[i].getContent().doc;
c = i;
if (typeof onUpdate === "function") { onUpdate(); }
$hist.find('.next, .previous').show();
if (c === states.length - 1) { $hist.find('.next').hide(); }
if (c === 0) { $hist.find('.previous').hide(); }
return val || '';
};
var getNext = function (step) {
return typeof step === "number" ? get(c + step) : get(c + 1);
};
var getPrevious = function (step) {
return typeof step === "number" ? get(c - step) : get(c - 1);
};
// Create the history toolbar
var display = function () {
$hist.html('').show();
$left.hide();
$right.hide();
$cke.hide();
var $prev =$('<button>', {
'class': 'previous fa fa-step-backward',
title: Messages.history_prev
}).appendTo($hist);
var $next = $('<button>', {
'class': 'next fa fa-step-forward',
title: Messages.history_next
}).appendTo($hist);
var $nav = $('<div>', {'class': 'goto'}).appendTo($hist);
var $cur = $('<input>', {
'class' : 'gotoInput',
'type' : 'number',
'min' : '1',
'max' : states.length
}).val(c + 1).appendTo($nav);
var $label = $('<label>').text(' / '+ states.length).appendTo($nav);
var $goTo = $('<button>', {
'class': 'fa fa-check',
'title': Messages.history_goTo
}).appendTo($nav);
$('<br>').appendTo($nav);
var $rev = $('<button>', {
'class':'revertHistory',
title: Messages.history_restoreTitle
}).text(Messages.history_restore).appendTo($nav);
var $close = $('<button>', {
'class':'closeHistory',
title: Messages.history_closeTitle
}).text(Messages.history_close).appendTo($nav);
onUpdate = function () {
$cur.attr('max', states.length);
$cur.val(c+1);
$label.text(' / ' + states.length);
};
var close = function () {
$hist.hide();
$left.show();
$right.show();
$cke.show();
};
// Buttons actions
$prev.click(function () { render(getPrevious()); });
$next.click(function () { render(getNext()); });
$goTo.click(function () { render( get($cur.val() - 1) ); });
$cur.keydown(function (e) {
var p = function () { e.preventDefault(); };
if (e.which === 13) { p(); return render( get($cur.val() - 1) ); } // Enter
if ([37, 40].indexOf(e.which) >= 0) { p(); return render(getPrevious()); } // Left
if ([38, 39].indexOf(e.which) >= 0) { p(); return render(getNext()); } // Right
if (e.which === 33) { p(); return render(getNext(10)); } // PageUp
if (e.which === 34) { p(); return render(getPrevious(10)); } // PageUp
if (e.which === 27) { p(); $close.click(); }
}).focus();
$cur.on('change', function () {
$goTo.click();
});
$close.click(function () {
states = [];
close();
onClose();
});
$rev.click(function () {
common.confirm(Messages.history_restorePrompt, function (yes) {
if (!yes) { return; }
close();
onRevert();
common.log(Messages.history_restoreDone);
});
});
// Display the latest content
render(get(c));
};
// Load all the history messages into a new chainpad object
loadHistory(common, function (err, newRt) {
if (err) { throw new Error(err); }
realtime = newRt;
update();
c = states.length - 1;
display();
onReady();
});
};
return History;
});

@ -6,11 +6,12 @@ define([
'/common/common-util.js', '/common/common-util.js',
'/common/common-hash.js', '/common/common-hash.js',
'/common/common-interface.js', '/common/common-interface.js',
'/common/common-history.js',
'/common/clipboard.js', '/common/clipboard.js',
'/common/pinpad.js', '/common/pinpad.js',
'/customize/application_config.js' '/customize/application_config.js'
], function ($, Config, Messages, Store, Util, Hash, UI, Clipboard, Pinpad, AppConfig) { ], function ($, Config, Messages, Store, Util, Hash, UI, History, Clipboard, Pinpad, AppConfig) {
/* This file exposes functionality which is specific to Cryptpad, but not to /* This file exposes functionality which is specific to Cryptpad, but not to
any particular pad type. This includes functions for committing metadata any particular pad type. This includes functions for committing metadata
@ -81,6 +82,9 @@ define([
common.findWeaker = Hash.findWeaker; common.findWeaker = Hash.findWeaker;
common.findStronger = Hash.findStronger; common.findStronger = Hash.findStronger;
// History
common.getHistory = function (config) { return History.create(common, config); };
var getStore = common.getStore = function () { var getStore = common.getStore = function () {
if (store) { return store; } if (store) { return store; }
throw new Error("Store is not ready!"); throw new Error("Store is not ready!");
@ -816,6 +820,22 @@ define([
style: 'font:'+size+' FontAwesome' style: 'font:'+size+' FontAwesome'
}); });
break; break;
case 'history':
if (!AppConfig.enableHistory) {
button = $('<span>');
break;
}
button = $('<button>', {
title: Messages.historyButton,
'class': "fa fa-history",
style: 'font:'+size+' FontAwesome'
});
if (data.histConfig) {
button.click(function () {
common.getHistory(data.histConfig);
});
}
break;
default: default:
button = $('<button>', { button = $('<button>', {
'class': "fa fa-question", 'class': "fa fa-question",

@ -22,6 +22,7 @@ define([
var TOP_CLS = Bar.constants.top = 'cryptpad-toolbar-top'; var TOP_CLS = Bar.constants.top = 'cryptpad-toolbar-top';
var LEFTSIDE_CLS = Bar.constants.leftside = 'cryptpad-toolbar-leftside'; var LEFTSIDE_CLS = Bar.constants.leftside = 'cryptpad-toolbar-leftside';
var RIGHTSIDE_CLS = Bar.constants.rightside = 'cryptpad-toolbar-rightside'; var RIGHTSIDE_CLS = Bar.constants.rightside = 'cryptpad-toolbar-rightside';
var HISTORY_CLS = Bar.constants.history = 'cryptpad-toolbar-history';
var SPINNER_CLS = Bar.constants.spinner = 'cryptpad-spinner'; var SPINNER_CLS = Bar.constants.spinner = 'cryptpad-spinner';
@ -73,7 +74,8 @@ define([
}) })
.append($('<div>', {'class': TOP_CLS})) .append($('<div>', {'class': TOP_CLS}))
.append($('<div>', {'class': LEFTSIDE_CLS})) .append($('<div>', {'class': LEFTSIDE_CLS}))
.append($('<div>', {'class': RIGHTSIDE_CLS})); .append($('<div>', {'class': RIGHTSIDE_CLS}))
.append($('<div>', {'class': HISTORY_CLS}));
// The 'notitle' class removes the line added for the title with a small screen // The 'notitle' class removes the line added for the title with a small screen
if (!config || typeof config !== "object") { if (!config || typeof config !== "object") {

@ -108,6 +108,8 @@ define([
var parsedHash = Cryptpad.parsePadUrl(window.location.href); var parsedHash = Cryptpad.parsePadUrl(window.location.href);
var defaultName = Cryptpad.getDefaultName(parsedHash); var defaultName = Cryptpad.getDefaultName(parsedHash);
var isHistoryMode = false;
if (readOnly) { if (readOnly) {
$('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox > .cke_toolbox_main').hide(); $('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox > .cke_toolbox_main').hide();
} }
@ -411,6 +413,14 @@ define([
} }
}; };
var setHistory = function (bool, update) {
isHistoryMode = bool;
setEditable(!bool);
if (!bool && update) {
realtimeOptions.onRemote();
}
};
var updateTitle = function (newTitle) { var updateTitle = function (newTitle) {
if (newTitle === document.title) { return; } if (newTitle === document.title) { return; }
// Change the title now, and set it back to the old value if there is an error // Change the title now, and set it back to the old value if there is an error
@ -475,6 +485,7 @@ define([
var onRemote = realtimeOptions.onRemote = function () { var onRemote = realtimeOptions.onRemote = function () {
if (initializing) { return; } if (initializing) { return; }
if (isHistoryMode) { return; }
var oldShjson = stringifyDOM(inner); var oldShjson = stringifyDOM(inner);
@ -566,7 +577,7 @@ define([
var onInit = realtimeOptions.onInit = function (info) { var onInit = realtimeOptions.onInit = function (info) {
userList = info.userList; userList = info.userList;
var config = { var configTb = {
displayed: ['useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad'], displayed: ['useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad'],
userData: userData, userData: userData,
readOnly: readOnly, readOnly: readOnly,
@ -582,8 +593,7 @@ define([
}, },
common: Cryptpad common: Cryptpad
}; };
if (readOnly) {delete config.changeNameID; } toolbar = info.realtime.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, userList, configTb);
toolbar = info.realtime.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside); var $rightside = $bar.find('.' + Toolbar.constants.rightside);
var $userBlock = $bar.find('.' + Toolbar.constants.username); var $userBlock = $bar.find('.' + Toolbar.constants.username);
@ -615,6 +625,35 @@ define([
$rightside.append($collapse); $rightside.append($collapse);
} }
/* add a history button */
var histConfig = {};
histConfig.onRender = function (val) {
if (typeof val === "undefined") { return; }
try {
applyHjson(val || '["BODY",{},[]]');
} catch (e) {
// Probably a parse error
console.error(e);
}
};
histConfig.onClose = function () {
// Close button clicked
setHistory(false, true);
};
histConfig.onRevert = function () {
// Revert button clicked
setHistory(false, false);
realtimeOptions.onLocal();
realtimeOptions.onRemote();
};
histConfig.onReady = function () {
// Called when the history is loaded and the UI displayed
setHistory(true);
};
histConfig.$toolbar = $bar;
var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig});
$rightside.append($hist);
/* save as template */ /* save as template */
if (!Cryptpad.isTemplate(window.location.href)) { if (!Cryptpad.isTemplate(window.location.href)) {
var templateObj = { var templateObj = {
@ -765,6 +804,7 @@ define([
var onLocal = realtimeOptions.onLocal = function () { var onLocal = realtimeOptions.onLocal = function () {
if (initializing) { return; } if (initializing) { return; }
if (isHistoryMode) { return; }
if (readOnly) { return; } if (readOnly) { return; }
// stringify the json and send it into chainpad // stringify the json and send it into chainpad

@ -72,6 +72,8 @@ define([
var defaultName = Cryptpad.getDefaultName(parsedHash); var defaultName = Cryptpad.getDefaultName(parsedHash);
var initialState = Messages.slideInitialState; var initialState = Messages.slideInitialState;
var isHistoryMode = false;
var editor = module.editor = CMeditor.fromTextArea($textarea[0], { var editor = module.editor = CMeditor.fromTextArea($textarea[0], {
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
@ -212,6 +214,14 @@ define([
var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); }; var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); };
var setHistory = function (bool, update) {
isHistoryMode = bool;
setEditable(!bool);
if (!bool && update) {
config.onRemote();
}
};
var isDefaultTitle = function () { var isDefaultTitle = function () {
var parsed = Cryptpad.parsePadUrl(window.location.href); var parsed = Cryptpad.parsePadUrl(window.location.href);
return Cryptpad.isDefaultName(parsed, APP.title); return Cryptpad.isDefaultName(parsed, APP.title);
@ -243,6 +253,7 @@ define([
var onLocal = config.onLocal = function () { var onLocal = config.onLocal = function () {
if (initializing) { return; } if (initializing) { return; }
if (isHistoryMode) { return; }
if (readOnly) { return; } if (readOnly) { return; }
editor.save(); editor.save();
@ -501,7 +512,7 @@ define([
var onInit = config.onInit = function (info) { var onInit = config.onInit = function (info) {
userList = info.userList; userList = info.userList;
var config = { var configTb = {
displayed: ['useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad'], displayed: ['useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad'],
userData: userData, userData: userData,
readOnly: readOnly, readOnly: readOnly,
@ -517,8 +528,7 @@ define([
}, },
common: Cryptpad common: Cryptpad
}; };
if (readOnly) {delete config.changeNameID; } toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, configTb);
toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside); var $rightside = $bar.find('.' + Toolbar.constants.rightside);
var $userBlock = $bar.find('.' + Toolbar.constants.username); var $userBlock = $bar.find('.' + Toolbar.constants.username);
@ -531,6 +541,38 @@ define([
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys); editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
} }
/* add a history button */
var histConfig = {};
histConfig.onRender = function (val) {
if (typeof val === "undefined") { return; }
try {
var hjson = JSON.parse(val || '{}');
var remoteDoc = hjson.content;
editor.setValue(remoteDoc || '');
editor.save();
} catch (e) {
// Probably a parse error
console.error(e);
}
};
histConfig.onClose = function () {
// Close button clicked
setHistory(false, true);
};
histConfig.onRevert = function () {
// Revert button clicked
setHistory(false, false);
config.onLocal();
config.onRemote();
};
histConfig.onReady = function () {
// Called when the history is loaded and the UI displayed
setHistory(true);
};
histConfig.$toolbar = $bar;
var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig});
$rightside.append($hist);
/* save as template */ /* save as template */
if (!Cryptpad.isTemplate(window.location.href)) { if (!Cryptpad.isTemplate(window.location.href)) {
var templateObj = { var templateObj = {
@ -840,6 +882,7 @@ define([
var onRemote = config.onRemote = function () { var onRemote = config.onRemote = function () {
if (initializing) { return; } if (initializing) { return; }
if (isHistoryMode) { return; }
var scroll = editor.getScrollInfo(); var scroll = editor.getScrollInfo();
var oldDoc = canonicalize($textarea.val()); var oldDoc = canonicalize($textarea.val());

Loading…
Cancel
Save