Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging
This commit is contained in:
commit
05a50b1f4c
@ -32,6 +32,7 @@ define(function() {
|
|||||||
'#FF00C0', // hot pink
|
'#FF00C0', // hot pink
|
||||||
'#800080', // purple
|
'#800080', // purple
|
||||||
];
|
];
|
||||||
|
config.enableTemplates = true;
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -75,6 +75,11 @@ define(function () {
|
|||||||
out.newButton = 'Nouveau';
|
out.newButton = 'Nouveau';
|
||||||
out.newButtonTitle = 'Créer un nouveau pad';
|
out.newButtonTitle = 'Créer un nouveau pad';
|
||||||
|
|
||||||
|
out.saveTemplateButton = "Sauver en tant que modèle";
|
||||||
|
out.saveTemplatePrompt = "Choisir un titre pour ce modèle";
|
||||||
|
out.templateSaved = "Modèle enregistré !";
|
||||||
|
out.selectTemplate = "Sélectionner un modèle ou appuyer sur Échap";
|
||||||
|
|
||||||
out.presentButtonTitle = "Entrer en mode présentation";
|
out.presentButtonTitle = "Entrer en mode présentation";
|
||||||
out.presentSuccess = 'Appuyer sur Échap pour quitter le mode présentation';
|
out.presentSuccess = 'Appuyer sur Échap pour quitter le mode présentation';
|
||||||
|
|
||||||
@ -146,8 +151,11 @@ define(function () {
|
|||||||
|
|
||||||
// Canvas
|
// Canvas
|
||||||
out.canvas_clear = "Nettoyer";
|
out.canvas_clear = "Nettoyer";
|
||||||
|
out.canvas_delete = "Supprimer la sélection";
|
||||||
out.canvas_disable = "Désactiver le dessin";
|
out.canvas_disable = "Désactiver le dessin";
|
||||||
out.canvas_enable = "Activer le dessin";
|
out.canvas_enable = "Activer le dessin";
|
||||||
|
out.canvas_width = "Épaisseur";
|
||||||
|
out.canvas_opacity = "Opacité";
|
||||||
|
|
||||||
// File manager
|
// File manager
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,11 @@ define(function () {
|
|||||||
out.newButton = 'New';
|
out.newButton = 'New';
|
||||||
out.newButtonTitle = 'Create a new pad';
|
out.newButtonTitle = 'Create a new pad';
|
||||||
|
|
||||||
|
out.saveTemplateButton = "Save as template";
|
||||||
|
out.saveTemplatePrompt = "Choose a title for the template";
|
||||||
|
out.templateSaved = "Template saved!";
|
||||||
|
out.selectTemplate = "Select a template or press escape";
|
||||||
|
|
||||||
out.presentButtonTitle = "Enter presentation mode";
|
out.presentButtonTitle = "Enter presentation mode";
|
||||||
out.presentSuccess = 'Hit ESC to exit presentation mode';
|
out.presentSuccess = 'Hit ESC to exit presentation mode';
|
||||||
|
|
||||||
@ -148,8 +153,11 @@ define(function () {
|
|||||||
|
|
||||||
// Canvas
|
// Canvas
|
||||||
out.canvas_clear = "Clear";
|
out.canvas_clear = "Clear";
|
||||||
|
out.canvas_delete = "Delete selection";
|
||||||
out.canvas_disable = "Disable draw";
|
out.canvas_disable = "Disable draw";
|
||||||
out.canvas_enable = "Enable draw";
|
out.canvas_enable = "Enable draw";
|
||||||
|
out.canvas_width = "Width";
|
||||||
|
out.canvas_opacity = "Opacity";
|
||||||
|
|
||||||
// File manager
|
// File manager
|
||||||
|
|
||||||
|
|||||||
@ -7,13 +7,14 @@ define([
|
|||||||
'json.sortify',
|
'json.sortify',
|
||||||
'/bower_components/chainpad-json-validator/json-ot.js',
|
'/bower_components/chainpad-json-validator/json-ot.js',
|
||||||
'/common/cryptpad-common.js',
|
'/common/cryptpad-common.js',
|
||||||
|
'/common/cryptget.js',
|
||||||
'/common/modes.js',
|
'/common/modes.js',
|
||||||
'/common/themes.js',
|
'/common/themes.js',
|
||||||
'/common/visible.js',
|
'/common/visible.js',
|
||||||
'/common/notify.js',
|
'/common/notify.js',
|
||||||
'/bower_components/file-saver/FileSaver.min.js',
|
'/bower_components/file-saver/FileSaver.min.js',
|
||||||
'/bower_components/jquery/dist/jquery.min.js',
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
], function (Crypto, Realtime, TextPatcher, Toolbar, JSONSortify, JsonOT, Cryptpad, Modes, Themes, Visible, Notify) {
|
], function (Crypto, Realtime, TextPatcher, Toolbar, JSONSortify, JsonOT, Cryptpad, Cryptget, Modes, Themes, Visible, Notify) {
|
||||||
var $ = window.jQuery;
|
var $ = window.jQuery;
|
||||||
var saveAs = window.saveAs;
|
var saveAs = window.saveAs;
|
||||||
var Messages = Cryptpad.Messages;
|
var Messages = Cryptpad.Messages;
|
||||||
@ -401,6 +402,17 @@ define([
|
|||||||
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* save as template */
|
||||||
|
if (!Cryptpad.isTemplate(window.location.href)) {
|
||||||
|
var templateObj = {
|
||||||
|
rt: info.realtime,
|
||||||
|
Crypt: Cryptget,
|
||||||
|
getTitle: function () { return document.title; }
|
||||||
|
};
|
||||||
|
var $templateButton = Cryptpad.createButton('template', true, templateObj);
|
||||||
|
$rightside.append($templateButton);
|
||||||
|
}
|
||||||
|
|
||||||
/* add an export button */
|
/* add an export button */
|
||||||
var $export = Cryptpad.createButton('export', true, {}, exportText);
|
var $export = Cryptpad.createButton('export', true, {}, exportText);
|
||||||
$rightside.append($export);
|
$rightside.append($export);
|
||||||
@ -532,6 +544,8 @@ define([
|
|||||||
|
|
||||||
var userDoc = module.realtime.getUserDoc();
|
var userDoc = module.realtime.getUserDoc();
|
||||||
|
|
||||||
|
var isNew = false;
|
||||||
|
if (userDoc === "" || userDoc === "{}") { isNew = true; }
|
||||||
|
|
||||||
var newDoc = "";
|
var newDoc = "";
|
||||||
if(userDoc !== "") {
|
if(userDoc !== "") {
|
||||||
@ -599,6 +613,9 @@ define([
|
|||||||
onLocal();
|
onLocal();
|
||||||
module.$userNameButton.click();
|
module.$userNameButton.click();
|
||||||
}
|
}
|
||||||
|
if (isNew) {
|
||||||
|
Cryptpad.selectTemplate('code', info.realtime, Cryptget);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -498,7 +498,7 @@ load pinpad dynamically only after you know that it will be needed */
|
|||||||
};
|
};
|
||||||
|
|
||||||
var makePad = function (href, title) {
|
var makePad = function (href, title) {
|
||||||
var now = ''+new Date();
|
var now = +new Date();
|
||||||
return {
|
return {
|
||||||
href: href,
|
href: href,
|
||||||
atime: now,
|
atime: now,
|
||||||
@ -557,6 +557,41 @@ load pinpad dynamically only after you know that it will be needed */
|
|||||||
getStore().addTemplate(href);
|
getStore().addTemplate(href);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var isTemplate = common.isTemplate = function (href) {
|
||||||
|
var rhref = getRelativeHref(href);
|
||||||
|
var templates = listTemplates();
|
||||||
|
return templates.some(function (t) {
|
||||||
|
return t.href === rhref;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var selectTemplate = common.selectTemplate = function (type, rt, Crypt) {
|
||||||
|
if (!AppConfig.enableTemplates) { return; }
|
||||||
|
var temps = listTemplates(type);
|
||||||
|
if (temps.length === 0) { return; }
|
||||||
|
var $content = $('<div>');
|
||||||
|
$('<b>').text(Messages.selectTemplate).appendTo($content);
|
||||||
|
$('<p>', {id:"selectTemplate"}).appendTo($content);
|
||||||
|
Cryptpad.alert($content.html(), null, true);
|
||||||
|
var $p = $('#selectTemplate');
|
||||||
|
temps.forEach(function (t, i) {
|
||||||
|
$('<a>', {href: t.href, title: t.title}).text(t.title).click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var parsed = parsePadUrl(t.href);
|
||||||
|
if(!parsed) { throw new Error("Cannot get template hash"); }
|
||||||
|
common.addLoadingScreen(null, true);
|
||||||
|
Crypt.get(parsed.hash, function (err, val) {
|
||||||
|
if (err) { throw new Error(err); }
|
||||||
|
var p = parsePadUrl(window.location.href);
|
||||||
|
Crypt.put(p.hash, val, function (e) {
|
||||||
|
common.findOKButton().click();
|
||||||
|
common.removeLoadingScreen();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).appendTo($p);
|
||||||
|
if (i !== temps.length) { $('<br>').appendTo($p); }
|
||||||
|
});
|
||||||
|
common.findOKButton().text(Messages.cancelButton);
|
||||||
|
};
|
||||||
|
|
||||||
// STORAGE
|
// STORAGE
|
||||||
/* fetch and migrate your pad history from localStorage */
|
/* fetch and migrate your pad history from localStorage */
|
||||||
@ -1118,6 +1153,56 @@ load pinpad dynamically only after you know that it will be needed */
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'template':
|
||||||
|
if (!AppConfig.enableTemplates) { return; }
|
||||||
|
button = $('<button>', {
|
||||||
|
title: Messages.saveTemplateButton,
|
||||||
|
}).append($('<span>', {'class':'fa fa-bookmark', style: 'font:'+size+' FontAwesome'}));
|
||||||
|
if (data.rt && data.Crypt) {
|
||||||
|
button.click(function () {
|
||||||
|
var title = data.getTitle() || document.title;
|
||||||
|
var todo = function (val) {
|
||||||
|
if (typeof(val) !== "string") { return; }
|
||||||
|
var toSave = data.rt.getUserDoc();
|
||||||
|
if (val.trim()) {
|
||||||
|
val = val.trim();
|
||||||
|
title = val;
|
||||||
|
try {
|
||||||
|
var parsed = JSON.parse(toSave);
|
||||||
|
var meta;
|
||||||
|
if (Array.isArray(parsed) && typeof(parsed[3]) === "object") {
|
||||||
|
meta = parsed[3].metadata; // pad
|
||||||
|
} else if (parsed.info) {
|
||||||
|
meta = parsed.info; // poll
|
||||||
|
} else {
|
||||||
|
meta = parsed.metadata;
|
||||||
|
}
|
||||||
|
if (typeof(meta) === "object") {
|
||||||
|
meta.title = val;
|
||||||
|
meta.defaultTitle = val;
|
||||||
|
delete meta.users;
|
||||||
|
}
|
||||||
|
toSave = JSON.stringify(parsed);
|
||||||
|
} catch(e) {
|
||||||
|
console.error("Parse error while setting the title", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var p = parsePadUrl(window.location.href);
|
||||||
|
if (!p.type) { return; }
|
||||||
|
var hash = createRandomHash();
|
||||||
|
var href = '/' + p.type + '/#' + hash;
|
||||||
|
data.Crypt.put(hash, toSave, function (e) {
|
||||||
|
if (e) { throw new Error(e); }
|
||||||
|
common.addTemplate(makePad(href, title));
|
||||||
|
whenRealtimeSyncs(getStore().getProxy().info.realtime, function () {
|
||||||
|
common.alert(Messages.templateSaved);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
common.prompt(Messages.saveTemplatePrompt, title || document.title, todo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'forget':
|
case 'forget':
|
||||||
button = $('<button>', {
|
button = $('<button>', {
|
||||||
id: 'cryptpad-forget',
|
id: 'cryptpad-forget',
|
||||||
|
|||||||
@ -999,7 +999,10 @@ define([
|
|||||||
// first, we must add it to FILES_DATA, so the input has to be an fileDAta object
|
// first, we must add it to FILES_DATA, so the input has to be an fileDAta object
|
||||||
var addTemplate = exp.addTemplate = function (fileData) {
|
var addTemplate = exp.addTemplate = function (fileData) {
|
||||||
if (workgroup) { return; }
|
if (workgroup) { return; }
|
||||||
if (typeof fileData !== "object" || !fileData.href || !fileData.title) { return; }
|
if (typeof fileData !== "object" || !fileData.href || !fileData.title) {
|
||||||
|
console.error("filedata object expected to add a new template");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var href = fileData.href;
|
var href = fileData.href;
|
||||||
var test = files[FILES_DATA].some(function (o) {
|
var test = files[FILES_DATA].some(function (o) {
|
||||||
|
|||||||
@ -242,20 +242,26 @@ define([
|
|||||||
return $userlist[0];
|
return $userlist[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO deduplicate users by uid
|
|
||||||
var getOtherUsers = function(myUserName, userList, userData) {
|
var getOtherUsers = function(myUserName, userList, userData) {
|
||||||
var i = 0;
|
var i = 0; // duplicates counter
|
||||||
var list = [];
|
var list = [];
|
||||||
|
var myUid = userData[myUserName] ? userData[myUserName].uid : undefined;
|
||||||
|
var uids = [];
|
||||||
userList.forEach(function(user) {
|
userList.forEach(function(user) {
|
||||||
if(user !== myUserName) {
|
if(user !== myUserName) {
|
||||||
var data = (userData) ? (userData[user] || null) : null;
|
var data = (userData) ? (userData[user] || null) : null;
|
||||||
var userName = (data) ? data.name : null;
|
var userName = (data) ? data.name : null;
|
||||||
if(userName) {
|
var userId = (data) ? data.uid : null;
|
||||||
|
if (userName && uids.indexOf(userId) === -1 && (!myUid || userId !== myUid)) {
|
||||||
|
uids.push(userId);
|
||||||
list.push(userName);
|
list.push(userName);
|
||||||
}
|
} else { i++; }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return list;
|
return {
|
||||||
|
list: list,
|
||||||
|
duplicates: i
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var arrayIntersect = function(a, b) {
|
var arrayIntersect = function(a, b) {
|
||||||
@ -293,11 +299,13 @@ define([
|
|||||||
// may contain data about users that have already left the channel.
|
// may contain data about users that have already left the channel.
|
||||||
userList = readOnly === -1 ? userList : arrayIntersect(userList, Object.keys(userData));
|
userList = readOnly === -1 ? userList : arrayIntersect(userList, Object.keys(userData));
|
||||||
|
|
||||||
var numberOfEditUsers = userList.length;
|
|
||||||
var numberOfViewUsers = numberOfUsers - numberOfEditUsers;
|
|
||||||
|
|
||||||
// Names of editing users
|
// Names of editing users
|
||||||
var editUsersNames = getOtherUsers(myUserName, userList, userData);
|
var others = getOtherUsers(myUserName, userList, userData);
|
||||||
|
var editUsersNames = others.list;
|
||||||
|
var duplicates = others.duplicates;
|
||||||
|
|
||||||
|
var numberOfEditUsers = userList.length - duplicates;
|
||||||
|
var numberOfViewUsers = numberOfUsers - numberOfEditUsers - duplicates;
|
||||||
|
|
||||||
// Number of anonymous editing users
|
// Number of anonymous editing users
|
||||||
var anonymous = numberOfEditUsers - editUsersNames.length;
|
var anonymous = numberOfEditUsers - editUsersNames.length;
|
||||||
@ -307,21 +315,19 @@ define([
|
|||||||
var $editUsers = $userButtons.find('.' + USERLIST_CLS);
|
var $editUsers = $userButtons.find('.' + USERLIST_CLS);
|
||||||
$editUsers.html('').append($usersTitle);
|
$editUsers.html('').append($usersTitle);
|
||||||
|
|
||||||
var editUsersList = '';
|
|
||||||
var $editUsersList = $('<pre>');
|
var $editUsersList = $('<pre>');
|
||||||
if (readOnly !== 1) {
|
if (readOnly !== 1) { // Yourself - edit
|
||||||
$editUsers.append('<span class="yourself">' + Messages.yourself + '</span>');
|
$editUsers.append('<span class="yourself">' + Messages.yourself + '</span>');
|
||||||
anonymous--;
|
anonymous--;
|
||||||
}
|
}
|
||||||
if (editUsersNames.length > 0) {
|
// Editors
|
||||||
$editUsersList.text(editUsersNames.join('\n')); // .text() to avoid XSS
|
$editUsersList.text(editUsersNames.join('\n')); // .text() to avoid XSS
|
||||||
$editUsers.append($editUsersList);
|
$editUsers.append($editUsersList);
|
||||||
}
|
if (anonymous > 0) { // Anonymous editors
|
||||||
if (anonymous > 0) {
|
|
||||||
var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers;
|
var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers;
|
||||||
$editUsers.append('<span class="anonymous">' + anonymous + ' ' + text + '</span>');
|
$editUsers.append('<span class="anonymous">' + anonymous + ' ' + text + '</span>');
|
||||||
}
|
}
|
||||||
if (numberOfViewUsers > 0) {
|
if (numberOfViewUsers > 0) { // Viewers
|
||||||
var viewText = '<span class="viewer">';
|
var viewText = '<span class="viewer">';
|
||||||
if (numberOfEditUsers > 0) {
|
if (numberOfEditUsers > 0) {
|
||||||
$editUsers.append('<br>');
|
$editUsers.append('<br>');
|
||||||
|
|||||||
@ -220,6 +220,7 @@ define([
|
|||||||
// Categories dislayed in the menu
|
// Categories dislayed in the menu
|
||||||
// _WORKGROUP_ : do not display unsorted
|
// _WORKGROUP_ : do not display unsorted
|
||||||
var displayedCategories = [ROOT, UNSORTED, TRASH, SEARCH];
|
var displayedCategories = [ROOT, UNSORTED, TRASH, SEARCH];
|
||||||
|
if (AppConfig.enableTemplates) { displayedCategories.push(TEMPLATE); }
|
||||||
if (isWorkgroup()) { displayedCategories = [ROOT, TRASH, SEARCH]; }
|
if (isWorkgroup()) { displayedCategories = [ROOT, TRASH, SEARCH]; }
|
||||||
|
|
||||||
var lastSelectTime;
|
var lastSelectTime;
|
||||||
@ -376,6 +377,10 @@ define([
|
|||||||
paths.forEach(function (p, i) {
|
paths.forEach(function (p, i) {
|
||||||
var path = p.path;
|
var path = p.path;
|
||||||
var $element = p.element;
|
var $element = p.element;
|
||||||
|
if (path.length === 1) {
|
||||||
|
hide.push($menu.find('a.rename'));
|
||||||
|
hide.push($menu.find('a.delete'));
|
||||||
|
}
|
||||||
if (!APP.editable) {
|
if (!APP.editable) {
|
||||||
hide.push($menu.find('a.editable'));
|
hide.push($menu.find('a.editable'));
|
||||||
}
|
}
|
||||||
@ -1709,6 +1714,7 @@ define([
|
|||||||
(isRootOpened ? $folderOpenedIcon : $folderIcon);
|
(isRootOpened ? $folderOpenedIcon : $folderIcon);
|
||||||
var $rootElement = createTreeElement(ROOT_NAME, $rootIcon.clone(), [ROOT], false, true, false, isRootOpened);
|
var $rootElement = createTreeElement(ROOT_NAME, $rootIcon.clone(), [ROOT], false, true, false, isRootOpened);
|
||||||
$rootElement.addClass('root');
|
$rootElement.addClass('root');
|
||||||
|
$rootElement.find('>.element-row').contextmenu(openDirectoryContextMenu);
|
||||||
var $root = $('<ul>').append($rootElement).appendTo($container);
|
var $root = $('<ul>').append($rootElement).appendTo($container);
|
||||||
$container = $rootElement;
|
$container = $rootElement;
|
||||||
} else if (filesOp.isFolderEmpty(root)) { return; }
|
} else if (filesOp.isFolderEmpty(root)) { return; }
|
||||||
|
|||||||
@ -10,6 +10,7 @@ define([
|
|||||||
'json.sortify',
|
'json.sortify',
|
||||||
'/bower_components/textpatcher/TextPatcher.js',
|
'/bower_components/textpatcher/TextPatcher.js',
|
||||||
'/common/cryptpad-common.js',
|
'/common/cryptpad-common.js',
|
||||||
|
'/common/cryptget.js',
|
||||||
'/common/visible.js',
|
'/common/visible.js',
|
||||||
'/common/notify.js',
|
'/common/notify.js',
|
||||||
'/pad/links.js',
|
'/pad/links.js',
|
||||||
@ -17,7 +18,7 @@ define([
|
|||||||
'/bower_components/diff-dom/diffDOM.js',
|
'/bower_components/diff-dom/diffDOM.js',
|
||||||
'/bower_components/jquery/dist/jquery.min.js',
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
], function (Crypto, realtimeInput, Hyperjson,
|
], function (Crypto, realtimeInput, Hyperjson,
|
||||||
Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad,
|
Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad, Cryptget,
|
||||||
Visible, Notify, Links) {
|
Visible, Notify, Links) {
|
||||||
var $ = window.jQuery;
|
var $ = window.jQuery;
|
||||||
var saveAs = window.saveAs;
|
var saveAs = window.saveAs;
|
||||||
@ -616,6 +617,17 @@ define([
|
|||||||
$rightside.append($collapse);
|
$rightside.append($collapse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* save as template */
|
||||||
|
if (!Cryptpad.isTemplate(window.location.href)) {
|
||||||
|
var templateObj = {
|
||||||
|
rt: info.realtime,
|
||||||
|
Crypt: Cryptget,
|
||||||
|
getTitle: function () { return document.title; }
|
||||||
|
};
|
||||||
|
var $templateButton = Cryptpad.createButton('template', true, templateObj);
|
||||||
|
$rightside.append($templateButton);
|
||||||
|
}
|
||||||
|
|
||||||
/* add an export button */
|
/* add an export button */
|
||||||
var $export = Cryptpad.createButton('export', true, {}, exportFile);
|
var $export = Cryptpad.createButton('export', true, {}, exportFile);
|
||||||
$rightside.append($export);
|
$rightside.append($export);
|
||||||
@ -723,6 +735,7 @@ define([
|
|||||||
|
|
||||||
editor.focus();
|
editor.focus();
|
||||||
if (newPad) {
|
if (newPad) {
|
||||||
|
Cryptpad.selectTemplate('pad', info.realtime, Cryptget);
|
||||||
cursor.setToEnd();
|
cursor.setToEnd();
|
||||||
} else {
|
} else {
|
||||||
cursor.setToStart();
|
cursor.setToStart();
|
||||||
|
|||||||
@ -3,6 +3,7 @@ define([
|
|||||||
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
||||||
'/bower_components/chainpad-crypto/crypto.js',
|
'/bower_components/chainpad-crypto/crypto.js',
|
||||||
'/common/cryptpad-common.js',
|
'/common/cryptpad-common.js',
|
||||||
|
'/common/cryptget.js',
|
||||||
'/bower_components/hyperjson/hyperjson.js',
|
'/bower_components/hyperjson/hyperjson.js',
|
||||||
'render.js',
|
'render.js',
|
||||||
'/common/toolbar.js',
|
'/common/toolbar.js',
|
||||||
@ -10,7 +11,7 @@ define([
|
|||||||
'/common/notify.js',
|
'/common/notify.js',
|
||||||
'/bower_components/file-saver/FileSaver.min.js',
|
'/bower_components/file-saver/FileSaver.min.js',
|
||||||
'/bower_components/jquery/dist/jquery.min.js',
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
], function (TextPatcher, Listmap, Crypto, Cryptpad, Hyperjson, Renderer, Toolbar, Visible, Notify) {
|
], function (TextPatcher, Listmap, Crypto, Cryptpad, Cryptget, Hyperjson, Renderer, Toolbar, Visible, Notify) {
|
||||||
var $ = window.jQuery;
|
var $ = window.jQuery;
|
||||||
|
|
||||||
var Messages = Cryptpad.Messages;
|
var Messages = Cryptpad.Messages;
|
||||||
@ -525,6 +526,11 @@ define([
|
|||||||
debug('userid: %s', userid);
|
debug('userid: %s', userid);
|
||||||
|
|
||||||
var proxy = APP.proxy;
|
var proxy = APP.proxy;
|
||||||
|
|
||||||
|
var isNew = false;
|
||||||
|
var userDoc = JSON.stringify(proxy);
|
||||||
|
if (userDoc === "" || userDoc === "{}") { isNew = true; }
|
||||||
|
|
||||||
var uncommitted = APP.uncommitted = {};
|
var uncommitted = APP.uncommitted = {};
|
||||||
prepareProxy(proxy, copyObject(Render.Example));
|
prepareProxy(proxy, copyObject(Render.Example));
|
||||||
prepareProxy(uncommitted, copyObject(Render.Example));
|
prepareProxy(uncommitted, copyObject(Render.Example));
|
||||||
@ -676,6 +682,9 @@ define([
|
|||||||
addToUserData(myData);
|
addToUserData(myData);
|
||||||
APP.$userNameButton.click();
|
APP.$userNameButton.click();
|
||||||
}
|
}
|
||||||
|
if (isNew) {
|
||||||
|
Cryptpad.selectTemplate('poll', info.realtime, Cryptget);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -747,6 +756,17 @@ define([
|
|||||||
// set the hash
|
// set the hash
|
||||||
if (!readOnly) { Cryptpad.replaceHash(editHash); }
|
if (!readOnly) { Cryptpad.replaceHash(editHash); }
|
||||||
|
|
||||||
|
/* save as template */
|
||||||
|
if (!Cryptpad.isTemplate(window.location.href)) {
|
||||||
|
var templateObj = {
|
||||||
|
rt: info.realtime,
|
||||||
|
Crypt: Cryptget,
|
||||||
|
getTitle: function () { return document.title; }
|
||||||
|
};
|
||||||
|
var $templateButton = Cryptpad.createButton('template', true, templateObj);
|
||||||
|
$rightside.append($templateButton);
|
||||||
|
}
|
||||||
|
|
||||||
Cryptpad.onDisplayNameChanged(setName);
|
Cryptpad.onDisplayNameChanged(setName);
|
||||||
|
|
||||||
Cryptpad.getPadTitle(function (err, title) {
|
Cryptpad.getPadTitle(function (err, title) {
|
||||||
|
|||||||
@ -7,6 +7,7 @@ define([
|
|||||||
'json.sortify',
|
'json.sortify',
|
||||||
'/bower_components/chainpad-json-validator/json-ot.js',
|
'/bower_components/chainpad-json-validator/json-ot.js',
|
||||||
'/common/cryptpad-common.js',
|
'/common/cryptpad-common.js',
|
||||||
|
'/common/cryptget.js',
|
||||||
'/common/modes.js',
|
'/common/modes.js',
|
||||||
'/common/themes.js',
|
'/common/themes.js',
|
||||||
'/common/visible.js',
|
'/common/visible.js',
|
||||||
@ -14,7 +15,7 @@ define([
|
|||||||
'/slide/slide.js',
|
'/slide/slide.js',
|
||||||
'/bower_components/file-saver/FileSaver.min.js',
|
'/bower_components/file-saver/FileSaver.min.js',
|
||||||
'/bower_components/jquery/dist/jquery.min.js',
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
], function (Crypto, Realtime, TextPatcher, Toolbar, JSONSortify, JsonOT, Cryptpad, Modes, Themes, Visible, Notify, Slide) {
|
], function (Crypto, Realtime, TextPatcher, Toolbar, JSONSortify, JsonOT, Cryptpad, Cryptget, Modes, Themes, Visible, Notify, Slide) {
|
||||||
var $ = window.jQuery;
|
var $ = window.jQuery;
|
||||||
var saveAs = window.saveAs;
|
var saveAs = window.saveAs;
|
||||||
|
|
||||||
@ -532,6 +533,17 @@ define([
|
|||||||
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* save as template */
|
||||||
|
if (!Cryptpad.isTemplate(window.location.href)) {
|
||||||
|
var templateObj = {
|
||||||
|
rt: info.realtime,
|
||||||
|
Crypt: Cryptget,
|
||||||
|
getTitle: function () { return document.title; }
|
||||||
|
};
|
||||||
|
var $templateButton = Cryptpad.createButton('template', true, templateObj);
|
||||||
|
$rightside.append($templateButton);
|
||||||
|
}
|
||||||
|
|
||||||
/* add an export button */
|
/* add an export button */
|
||||||
var $export = Cryptpad.createButton('export', true, {}, exportText);
|
var $export = Cryptpad.createButton('export', true, {}, exportText);
|
||||||
$rightside.append($export);
|
$rightside.append($export);
|
||||||
@ -720,6 +732,9 @@ define([
|
|||||||
|
|
||||||
var userDoc = module.realtime.getUserDoc();
|
var userDoc = module.realtime.getUserDoc();
|
||||||
|
|
||||||
|
var isNew = false;
|
||||||
|
if (userDoc === "" || userDoc === "{}") { isNew = true; }
|
||||||
|
|
||||||
var newDoc = "";
|
var newDoc = "";
|
||||||
if(userDoc !== "") {
|
if(userDoc !== "") {
|
||||||
var hjson = JSON.parse(userDoc);
|
var hjson = JSON.parse(userDoc);
|
||||||
@ -792,6 +807,9 @@ define([
|
|||||||
onLocal();
|
onLocal();
|
||||||
module.$userNameButton.click();
|
module.$userNameButton.click();
|
||||||
}
|
}
|
||||||
|
if (isNew) {
|
||||||
|
Cryptpad.selectTemplate('slide', info.realtime, Cryptget);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
<div id="controls">
|
<div id="controls">
|
||||||
<button id="clear" data-localization="canvas_clear">Clear</button>
|
<button id="clear" data-localization="canvas_clear">Clear</button>
|
||||||
<button id="toggleDraw" data-localization="canvas_disable"></button>
|
<button id="toggleDraw" data-localization="canvas_disable"></button>
|
||||||
<input id="width" type="range" value="5" min="1" max="100"></input><label for="width">5</label>
|
<button id="delete" style="display: none;" data-localization="canvas_delete"></button>
|
||||||
|
<input id="width" data-localization-title="canvas_width" type="range" value="5" min="1" max="100"></input><label for="width">5</label>
|
||||||
|
<input id="opacity" data-localization-title="canvas_opacity" type="range" value="1" min="0" max="1" step="0.1"></input><label for="opacity">1</label>
|
||||||
<span class="selected"></span>
|
<span class="selected"></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="colors"> </div>
|
<div id="colors"> </div>
|
||||||
|
|||||||
@ -11,13 +11,15 @@ define([
|
|||||||
'json.sortify',
|
'json.sortify',
|
||||||
'/bower_components/chainpad-json-validator/json-ot.js',
|
'/bower_components/chainpad-json-validator/json-ot.js',
|
||||||
'/common/cryptpad-common.js',
|
'/common/cryptpad-common.js',
|
||||||
|
'/common/cryptget.js',
|
||||||
|
'/whiteboard/colors.js',
|
||||||
'/common/visible.js',
|
'/common/visible.js',
|
||||||
'/common/notify.js',
|
'/common/notify.js',
|
||||||
'/customize/application_config.js',
|
'/customize/application_config.js',
|
||||||
'/bower_components/secure-fabric.js/dist/fabric.min.js',
|
'/bower_components/secure-fabric.js/dist/fabric.min.js',
|
||||||
'/bower_components/jquery/dist/jquery.min.js',
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
'/bower_components/file-saver/FileSaver.min.js',
|
'/bower_components/file-saver/FileSaver.min.js',
|
||||||
], function (Config, Realtime, Crypto, Toolbar, TextPatcher, JSONSortify, JsonOT, Cryptpad, Visible, Notify, AppConfig) {
|
], function (Config, Realtime, Crypto, Toolbar, TextPatcher, JSONSortify, JsonOT, Cryptpad, Cryptget, Colors, Visible, Notify, AppConfig) {
|
||||||
var saveAs = window.saveAs;
|
var saveAs = window.saveAs;
|
||||||
var Messages = Cryptpad.Messages;
|
var Messages = Cryptpad.Messages;
|
||||||
|
|
||||||
@ -47,15 +49,23 @@ define([
|
|||||||
var $pickers = $('#pickers');
|
var $pickers = $('#pickers');
|
||||||
var $colors = $('#colors');
|
var $colors = $('#colors');
|
||||||
var $cursors = $('#cursors');
|
var $cursors = $('#cursors');
|
||||||
|
var $deleteButton = $('#delete');
|
||||||
|
|
||||||
|
var brush = {
|
||||||
|
color: '#000000',
|
||||||
|
opacity: 1
|
||||||
|
};
|
||||||
|
|
||||||
var $toggle = $('#toggleDraw');
|
var $toggle = $('#toggleDraw');
|
||||||
var $width = $('#width');
|
var $width = $('#width');
|
||||||
var $widthLabel = $('label[for="width"]');
|
var $widthLabel = $('label[for="width"]');
|
||||||
|
var $opacity = $('#opacity');
|
||||||
|
var $opacityLabel = $('label[for="opacity"]');
|
||||||
|
window.canvas = canvas;
|
||||||
var createCursor = function () {
|
var createCursor = function () {
|
||||||
var w = canvas.freeDrawingBrush.width;
|
var w = canvas.freeDrawingBrush.width;
|
||||||
var c = canvas.freeDrawingBrush.color;
|
var c = canvas.freeDrawingBrush.color;
|
||||||
var size = w > 30 ? w : w+30;
|
var size = w > 30 ? w+2 : w+32;
|
||||||
$cursors.html('<canvas width="'+size+'" height="'+size+'"></canvas>');
|
$cursors.html('<canvas width="'+size+'" height="'+size+'"></canvas>');
|
||||||
var $ccanvas = $cursors.find('canvas');
|
var $ccanvas = $cursors.find('canvas');
|
||||||
var ccanvas = $ccanvas[0];
|
var ccanvas = $ccanvas[0];
|
||||||
@ -69,7 +79,9 @@ define([
|
|||||||
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
|
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
|
||||||
ctx.fillStyle = c;
|
ctx.fillStyle = c;
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.lineWidth = 0;
|
ctx.lineWidth = 1;
|
||||||
|
ctx.strokeStyle = brush.color;
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(size/2, 0); ctx.lineTo(size/2, 10);
|
ctx.moveTo(size/2, 0); ctx.lineTo(size/2, 10);
|
||||||
@ -79,9 +91,6 @@ define([
|
|||||||
ctx.strokeStyle = '#000000';
|
ctx.strokeStyle = '#000000';
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
|
||||||
//context.lineWidth = w/2;
|
|
||||||
//context.strokeStyle = '#000000';
|
|
||||||
//context.stroke();
|
|
||||||
|
|
||||||
var img = ccanvas.toDataURL("image/png");
|
var img = ccanvas.toDataURL("image/png");
|
||||||
var $img = $('<img>', {
|
var $img = $('<img>', {
|
||||||
@ -102,6 +111,17 @@ define([
|
|||||||
|
|
||||||
$width.on('change', updateBrushWidth);
|
$width.on('change', updateBrushWidth);
|
||||||
|
|
||||||
|
var updateBrushOpacity = function () {
|
||||||
|
var val = $opacity.val();
|
||||||
|
brush.opacity = Number(val);
|
||||||
|
canvas.freeDrawingBrush.color = Colors.hex2rgba(brush.color, brush.opacity);
|
||||||
|
$opacityLabel.text(val);
|
||||||
|
createCursor();
|
||||||
|
};
|
||||||
|
updateBrushOpacity();
|
||||||
|
|
||||||
|
$opacity.on('change', updateBrushOpacity);
|
||||||
|
|
||||||
var pickColor = function (current, cb) {
|
var pickColor = function (current, cb) {
|
||||||
var $picker = $('<input>', {
|
var $picker = $('<input>', {
|
||||||
type: 'color',
|
type: 'color',
|
||||||
@ -120,21 +140,15 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var setColor = function (c) {
|
var setColor = function (c) {
|
||||||
canvas.freeDrawingBrush.color = c;
|
c = Colors.rgb2hex(c);
|
||||||
|
brush.color = c;
|
||||||
|
canvas.freeDrawingBrush.color = Colors.hex2rgba(brush.color, brush.opacity);
|
||||||
module.$color.css({
|
module.$color.css({
|
||||||
'color': c,
|
'color': c,
|
||||||
});
|
});
|
||||||
createCursor();
|
createCursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
var rgb2hex = function (rgb) {
|
|
||||||
if (rgb.indexOf('#') === 0) { return rgb; }
|
|
||||||
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
|
||||||
var hex = function (x) {
|
|
||||||
return ("0" + parseInt(x).toString(16)).slice(-2);
|
|
||||||
};
|
|
||||||
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
|
|
||||||
};
|
|
||||||
|
|
||||||
var palette = AppConfig.whiteboardPalette || [
|
var palette = AppConfig.whiteboardPalette || [
|
||||||
'red', 'blue', 'green', 'white', 'black', 'purple',
|
'red', 'blue', 'green', 'white', 'black', 'purple',
|
||||||
@ -151,9 +165,29 @@ define([
|
|||||||
module.draw = !module.draw;
|
module.draw = !module.draw;
|
||||||
canvas.isDrawingMode = module.draw;
|
canvas.isDrawingMode = module.draw;
|
||||||
$toggle.text(module.draw ? Messages.canvas_disable : Messages.canvas_enable);
|
$toggle.text(module.draw ? Messages.canvas_disable : Messages.canvas_enable);
|
||||||
|
if (module.draw) { $deleteButton.hide(); }
|
||||||
|
else { $deleteButton.show(); }
|
||||||
};
|
};
|
||||||
$toggle.click(toggleDrawMode);
|
$toggle.click(toggleDrawMode);
|
||||||
|
|
||||||
|
var deleteSelection = function () {
|
||||||
|
if (canvas.getActiveObject()) {
|
||||||
|
canvas.getActiveObject().remove();
|
||||||
|
}
|
||||||
|
if (canvas.getActiveGroup()) {
|
||||||
|
canvas.getActiveGroup()._objects.forEach(function (el) {
|
||||||
|
el.remove();
|
||||||
|
});
|
||||||
|
canvas.discardActiveGroup();
|
||||||
|
}
|
||||||
|
canvas.renderAll();
|
||||||
|
onLocal();
|
||||||
|
};
|
||||||
|
$deleteButton.click(deleteSelection);
|
||||||
|
$(window).on('keyup', function (e) {
|
||||||
|
if (e.which === 46) { deleteSelection (); }
|
||||||
|
});
|
||||||
|
|
||||||
var setEditable = function (bool) {
|
var setEditable = function (bool) {
|
||||||
if (readOnly && bool) { return; }
|
if (readOnly && bool) { return; }
|
||||||
if (bool) { $controls.show(); }
|
if (bool) { $controls.show(); }
|
||||||
@ -233,12 +267,12 @@ define([
|
|||||||
'background-color': color,
|
'background-color': color,
|
||||||
})
|
})
|
||||||
.click(function () {
|
.click(function () {
|
||||||
var c = rgb2hex($color.css('background-color'));
|
var c = Colors.rgb2hex($color.css('background-color'));
|
||||||
setColor(c);
|
setColor(c);
|
||||||
})
|
})
|
||||||
.on('dblclick', function (e) {
|
.on('dblclick', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
pickColor(rgb2hex($color.css('background-color')), function (c) {
|
pickColor(Colors.rgb2hex($color.css('background-color')), function (c) {
|
||||||
$color.css({
|
$color.css({
|
||||||
'background-color': c,
|
'background-color': c,
|
||||||
});
|
});
|
||||||
@ -327,6 +361,17 @@ define([
|
|||||||
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
|
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
|
||||||
module.$userNameButton = $($bar.find('.' + Toolbar.constants.changeUsername));
|
module.$userNameButton = $($bar.find('.' + Toolbar.constants.changeUsername));
|
||||||
|
|
||||||
|
/* save as template */
|
||||||
|
if (!Cryptpad.isTemplate(window.location.href)) {
|
||||||
|
var templateObj = {
|
||||||
|
rt: info.realtime,
|
||||||
|
Crypt: Cryptget,
|
||||||
|
getTitle: function () { return document.title; }
|
||||||
|
};
|
||||||
|
var $templateButton = Cryptpad.createButton('template', true, templateObj);
|
||||||
|
$rightside.append($templateButton);
|
||||||
|
}
|
||||||
|
|
||||||
var $export = Cryptpad.createButton('export', true, {}, saveImage);
|
var $export = Cryptpad.createButton('export', true, {}, saveImage);
|
||||||
$rightside.append($export);
|
$rightside.append($export);
|
||||||
|
|
||||||
@ -498,6 +543,10 @@ define([
|
|||||||
realtime: realtime
|
realtime: realtime
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var isNew = false;
|
||||||
|
var userDoc = module.realtime.getUserDoc();
|
||||||
|
if (userDoc === "" || userDoc === "{}") { isNew = true; }
|
||||||
|
|
||||||
Cryptpad.removeLoadingScreen();
|
Cryptpad.removeLoadingScreen();
|
||||||
setEditable(true);
|
setEditable(true);
|
||||||
initializing = false;
|
initializing = false;
|
||||||
@ -528,6 +577,9 @@ define([
|
|||||||
onLocal();
|
onLocal();
|
||||||
module.$userNameButton.click();
|
module.$userNameButton.click();
|
||||||
}
|
}
|
||||||
|
if (isNew) {
|
||||||
|
Cryptpad.selectTemplate('whiteboard', info.realtime, Cryptget);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -33,11 +33,13 @@ body {
|
|||||||
line-height: 100px;
|
line-height: 100px;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
#controls #width {
|
#controls #width,
|
||||||
|
#controls #opacity {
|
||||||
position: relative;
|
position: relative;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
#controls #clear,
|
#controls #clear,
|
||||||
|
#controls #delete,
|
||||||
#controls #toggleDraw {
|
#controls #toggleDraw {
|
||||||
display: inline;
|
display: inline;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|||||||
@ -42,10 +42,10 @@ body {
|
|||||||
line-height: 100px;
|
line-height: 100px;
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
|
|
||||||
#width {
|
#width, #opacity {
|
||||||
.middle;
|
.middle;
|
||||||
}
|
}
|
||||||
#clear, #toggleDraw {
|
#clear, #delete, #toggleDraw {
|
||||||
display: inline;
|
display: inline;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user