manual merge of staging
18
bower.json
|
@ -19,12 +19,12 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"jquery": "~2.1.3",
|
||||
"tweetnacl": "~0.12.2",
|
||||
"tweetnacl": "0.12.2",
|
||||
"components-font-awesome": "^4.6.3",
|
||||
"ckeditor": "~4.7",
|
||||
"codemirror": "^5.19.0",
|
||||
"requirejs": "~2.1.15",
|
||||
"marked": "~0.3.5",
|
||||
"requirejs": "2.1.15",
|
||||
"marked": "0.3.5",
|
||||
"rangy": "rangy-release#~1.3.0",
|
||||
"json.sortify": "~2.1.0",
|
||||
"secure-fabric.js": "secure-v1.7.9",
|
||||
|
@ -33,12 +33,12 @@
|
|||
"chainpad-json-validator": "^0.2.0",
|
||||
"chainpad-crypto": "^0.1.3",
|
||||
"chainpad-listmap": "^0.3.0",
|
||||
"file-saver": "^1.3.1",
|
||||
"diff-dom": "^2.1.1",
|
||||
"alertifyjs": "^1.0.11",
|
||||
"scrypt-async": "^1.2.0",
|
||||
"require-css": "^0.1.10",
|
||||
"file-saver": "1.3.1",
|
||||
"alertifyjs": "1.0.11",
|
||||
"scrypt-async": "1.2.0",
|
||||
"require-css": "0.1.10",
|
||||
"less": "^2.7.2",
|
||||
"bootstrap": "#v4.0.0-alpha.6"
|
||||
"bootstrap": "#v4.0.0-alpha.6",
|
||||
"diff-dom": "2.1.1"
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 121 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
@ -171,6 +171,10 @@ define([
|
|||
$('button.gotodrive').click(function () {
|
||||
document.location.href = '/drive/';
|
||||
});
|
||||
|
||||
$('button#loggedInLogout').click(function () {
|
||||
$('#user-menu .logout').click();
|
||||
});
|
||||
};
|
||||
|
||||
displayCreateButtons();
|
||||
|
|
|
@ -444,7 +444,7 @@ define([
|
|||
h('div#poll', [
|
||||
h('div#howItWorks', [
|
||||
h('h1', 'CryptPoll'),
|
||||
h('h2', Msg.poll_subtitle),
|
||||
setHTML(h('h2'), Msg.poll_subtitle),
|
||||
h('p', Msg.poll_p_save),
|
||||
h('p', Msg.poll_p_encryption)
|
||||
]),
|
||||
|
|
|
@ -112,17 +112,19 @@ h6 {
|
|||
padding-top: .65001rem;
|
||||
}
|
||||
|
||||
a:not(.btn) {
|
||||
cursor: pointer;
|
||||
color: @cp-link;
|
||||
p {
|
||||
a:not(.btn) {
|
||||
cursor: pointer;
|
||||
color: @cp-link;
|
||||
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: @cp-link-hover;
|
||||
}
|
||||
&:visited {
|
||||
color: @cp-link-visited;
|
||||
&:hover {
|
||||
color: @cp-link-hover;
|
||||
}
|
||||
&:visited {
|
||||
color: @cp-link-visited;
|
||||
}
|
||||
}
|
||||
}
|
||||
a.btn {
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
margin-right: 0px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
* {
|
||||
.unselectable();
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-bar-content {
|
||||
|
|
|
@ -16,15 +16,28 @@
|
|||
color: inherit;
|
||||
}
|
||||
|
||||
#cke_editor1 {
|
||||
.cke_inner {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
.padColor { color: @toolbar-pad-bg; }
|
||||
.codeColor { color: @toolbar-code-bg; }
|
||||
.slideColor { color: @toolbar-slide-bg; }
|
||||
.pollColor { color: @toolbar-poll-bg; }
|
||||
.fileColor { color: @toolbar-file-bg; }
|
||||
.whiteboardColor { color: @toolbar-whiteboard-bg; }
|
||||
.driveColor { color: @toolbar-drive-bg; }
|
||||
.defaultColor { color: @toolbar-default-bg; }
|
||||
|
||||
.toolbar-container {
|
||||
display: flex;
|
||||
}
|
||||
#cke_editor1 .cke_inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
.cke_toolbox_main {
|
||||
display: inline-block;
|
||||
|
@ -35,17 +48,12 @@
|
|||
margin-top: -1px;
|
||||
display: flex;
|
||||
overflow: visible;
|
||||
iframe {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.padColor { color: @toolbar-pad-bg; }
|
||||
.codeColor { color: @toolbar-code-bg; }
|
||||
.slideColor { color: @toolbar-slide-bg; }
|
||||
.pollColor { color: @toolbar-poll-bg; }
|
||||
.fileColor { color: @toolbar-file-bg; }
|
||||
.whiteboardColor { color: @toolbar-whiteboard-bg; }
|
||||
.driveColor { color: @toolbar-drive-bg; }
|
||||
.defaultColor { color: @toolbar-default-bg; }
|
||||
|
||||
body .userlist-drawer {
|
||||
font: normal normal normal 16px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;
|
||||
min-width: 175px;
|
||||
|
@ -104,6 +112,51 @@ body .userlist-drawer {
|
|||
background: rgba(0,0,0,0.1);
|
||||
margin: 2px 0;
|
||||
font-size: 16px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
}
|
||||
}
|
||||
.default, media-tag {
|
||||
display: inline-flex;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 5px;
|
||||
border-radius: 10px / 6px;
|
||||
overflow: hidden;
|
||||
border: 1px solid black;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.default {
|
||||
.unselectable();
|
||||
background: white;
|
||||
color: black;
|
||||
font-size: 40px;
|
||||
}
|
||||
.name {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
media-tag {
|
||||
min-height: 50px;
|
||||
min-width: 50px;
|
||||
max-height: 50px;
|
||||
max-width: 50px;
|
||||
img {
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
max-width: none;
|
||||
max-height: none; // To override 'media-tag img' in slide.less
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -718,6 +771,8 @@ body .cryptpad-toolbar {
|
|||
padding: 0px;
|
||||
margin: 0;
|
||||
&::before {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding-top: 4px;
|
||||
}
|
||||
&:hover {
|
||||
|
@ -796,11 +851,10 @@ body .cryptpad-toolbar {
|
|||
width: 64px;
|
||||
padding: 0;
|
||||
span {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
cursor: default;
|
||||
font-size: 32px;
|
||||
.fa {
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -850,8 +904,10 @@ body .cryptpad-toolbar {
|
|||
}
|
||||
}
|
||||
.cryptpad-toolbar-rightside {
|
||||
height: 32px;
|
||||
min-height: 32px;
|
||||
overflow: hidden;
|
||||
&:empty {
|
||||
min-height: 0;
|
||||
height: 0;
|
||||
}
|
||||
text-align: right;
|
||||
|
@ -873,7 +929,7 @@ body .cryptpad-toolbar {
|
|||
background: @dropdown-bg;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
z-index:1000;
|
||||
z-index:10000;
|
||||
color: black;
|
||||
.fa {
|
||||
font-size: 17px;
|
||||
|
@ -881,7 +937,7 @@ body .cryptpad-toolbar {
|
|||
&> span {
|
||||
box-sizing: border-box;
|
||||
min-width: 150px;
|
||||
height: 26px;
|
||||
height: 32px;
|
||||
border-radius: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
a {
|
||||
&.link a {
|
||||
font-weight: 500;
|
||||
font-size: 0.75em;
|
||||
color: @cp-link;
|
||||
|
|
|
@ -240,6 +240,18 @@ define(function () {
|
|||
out.canvas_opacityLabel = "opacité: {0}";
|
||||
out.canvas_widthLabel = "taille: {0}";
|
||||
|
||||
// Profile
|
||||
out.profileButton = "Profil"; // dropdown menu
|
||||
out.profile_urlPlaceholder = 'URL';
|
||||
out.profile_namePlaceholder = 'Nom ou pseudo pour le profil';
|
||||
out.profile_avatar = "Avatar";
|
||||
out.profile_upload = " Importer un nouvel avatar";
|
||||
out.profile_error = "Erreur lors de la création du profil : {0}";
|
||||
out.profile_register = "Vous devez vous inscrire pour pouvoir créer un profil !";
|
||||
out.profile_create = "Créer un profil";
|
||||
out.profile_description = "Description";
|
||||
out.profile_fieldSaved = 'Nouvelle valeur enregistrée: {0}';
|
||||
|
||||
// File manager
|
||||
|
||||
out.fm_rootName = "Documents";
|
||||
|
|
|
@ -241,7 +241,18 @@ define(function () {
|
|||
out.canvas_opacity = "Opacity";
|
||||
out.canvas_opacityLabel = "opacity: {0}";
|
||||
out.canvas_widthLabel = "Width: {0}";
|
||||
|
||||
|
||||
// Profile
|
||||
out.profileButton = "Profile"; // dropdown menu
|
||||
out.profile_urlPlaceholder = 'URL';
|
||||
out.profile_namePlaceholder = 'Name displayed in your profile';
|
||||
out.profile_avatar = "Avatar";
|
||||
out.profile_upload = " Upload a new avatar";
|
||||
out.profile_error = "Error while creating your profile: {0}";
|
||||
out.profile_register = "You have to sign up to create a profile!";
|
||||
out.profile_create = "Create a profile";
|
||||
out.profile_description = "Description";
|
||||
out.profile_fieldSaved = 'New value saved: {0}';
|
||||
|
||||
// File manager
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "cryptpad",
|
||||
"description": "realtime collaborative visual editor with zero knowlege server",
|
||||
"version": "1.9.0-1",
|
||||
"version": "1.10.0",
|
||||
"dependencies": {
|
||||
"chainpad-server": "^1.0.1",
|
||||
"express": "~4.10.1",
|
||||
|
|
|
@ -30,7 +30,7 @@ const sizeForHashes = (hashes, dsFileStats) => {
|
|||
let sum = 0;
|
||||
hashes.forEach((h) => {
|
||||
const s = dsFileStats[h];
|
||||
if (typeof(s) !== 'number') {
|
||||
if (typeof(s) !== 'object' || typeof(s.size) !== 'number') {
|
||||
//console.log('missing ' + h + ' ' + typeof(s));
|
||||
} else {
|
||||
sum += s.size;
|
||||
|
@ -62,11 +62,26 @@ nThen((waitFor) => {
|
|||
});
|
||||
});
|
||||
}).nThen((waitFor) => {
|
||||
|
||||
Fs.readdir('./blob', waitFor((err, list) => {
|
||||
if (err) { throw err; }
|
||||
dirList = list;
|
||||
}));
|
||||
}).nThen((waitFor) => {
|
||||
dirList.forEach((f) => {
|
||||
sema.take((returnAfter) => {
|
||||
Fs.readdir('./blob/' + f, waitFor(returnAfter((err, list2) => {
|
||||
if (err) { throw err; }
|
||||
list2.forEach((ff) => { fileList.push('./blob/' + f + '/' + ff); });
|
||||
})));
|
||||
});
|
||||
});
|
||||
}).nThen((waitFor) => {
|
||||
fileList.forEach((f) => {
|
||||
sema.take((returnAfter) => {
|
||||
Fs.stat(f, waitFor(returnAfter((err, st) => {
|
||||
if (err) { throw err; }
|
||||
dsFileStats[f.replace(/^.*\/([^\/]*)\.ndjson$/, (all, a) => (a))] = st;
|
||||
dsFileStats[f.replace(/^.*\/([^\/\.]*)(\.ndjson)?$/, (all, a) => (a))] = st;
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
|
64
rpc.js
|
@ -281,7 +281,7 @@ var getUploadSize = function (Env, channel, cb) {
|
|||
var paths = Env.paths;
|
||||
var path = makeFilePath(paths.blob, channel);
|
||||
if (!path) {
|
||||
return cb('INVALID_UPLOAD_ID');
|
||||
return cb('INVALID_UPLOAD_ID', path);
|
||||
}
|
||||
|
||||
Fs.stat(path, function (err, stats) {
|
||||
|
@ -583,9 +583,10 @@ var resetUserPins = function (Env, publicKey, channelList, cb) {
|
|||
if (e) { return void cb(e); }
|
||||
var pinSize = sumChannelSizes(sizes);
|
||||
|
||||
getFreeSpace(Env, publicKey, function (e, free) {
|
||||
|
||||
getLimit(Env, publicKey, function (e, limit) {
|
||||
if (e) {
|
||||
WARN('getFreeSpace', e);
|
||||
WARN('[RESET_ERR]', e);
|
||||
return void cb(e);
|
||||
}
|
||||
|
||||
|
@ -597,7 +598,7 @@ var resetUserPins = function (Env, publicKey, channelList, cb) {
|
|||
|
||||
They will not be able to pin additional pads until they upgrade
|
||||
or delete enough files to go back under their limit. */
|
||||
if (pinSize > free && session.hasPinned) { return void(cb('E_OVER_LIMIT')); }
|
||||
if (pinSize > limit && session.hasPinned) { return void(cb('E_OVER_LIMIT')); }
|
||||
pinStore.message(publicKey, JSON.stringify(['RESET', channelList]),
|
||||
function (e) {
|
||||
if (e) { return void cb(e); }
|
||||
|
@ -826,6 +827,13 @@ var upload_status = function (Env, publicKey, filesize, cb) {
|
|||
});
|
||||
};
|
||||
|
||||
var isUnauthenticatedCall = function (call) {
|
||||
return [
|
||||
'GET_FILE_SIZE',
|
||||
'GET_MULTIPLE_FILE_SIZE',
|
||||
].indexOf(call) !== -1;
|
||||
};
|
||||
|
||||
var isAuthenticatedCall = function (call) {
|
||||
return [
|
||||
'COOKIE',
|
||||
|
@ -834,11 +842,8 @@ var isAuthenticatedCall = function (call) {
|
|||
'UNPIN',
|
||||
'GET_HASH',
|
||||
'GET_TOTAL_SIZE',
|
||||
'GET_FILE_SIZE',
|
||||
'UPDATE_LIMITS',
|
||||
'GET_LIMIT',
|
||||
'GET_MULTIPLE_FILE_SIZE',
|
||||
//'UPLOAD',
|
||||
'UPLOAD_COMPLETE',
|
||||
'UPLOAD_CANCEL',
|
||||
].indexOf(call) !== -1;
|
||||
|
@ -867,6 +872,34 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
|
|||
var blobPath = paths.blob = keyOrDefaultString('blobPath', './blob');
|
||||
var blobStagingPath = paths.staging = keyOrDefaultString('blobStagingPath', './blobstage');
|
||||
|
||||
var isUnauthenticateMessage = function (msg) {
|
||||
return msg && msg.length === 2 && isUnauthenticatedCall(msg[0]);
|
||||
};
|
||||
|
||||
var handleUnauthenticatedMessage = function (msg, respond) {
|
||||
switch (msg[0]) {
|
||||
case 'GET_FILE_SIZE':
|
||||
return void getFileSize(Env, msg[1], function (e, size) {
|
||||
if (e) {
|
||||
console.error(e);
|
||||
}
|
||||
WARN(e, msg[1]);
|
||||
respond(e, [null, size, null]);
|
||||
});
|
||||
case 'GET_MULTIPLE_FILE_SIZE':
|
||||
return void getMultipleFileSize(Env, msg[1], function (e, dict) {
|
||||
if (e) {
|
||||
WARN(e, dict);
|
||||
return respond(e);
|
||||
}
|
||||
respond(e, [null, dict, null]);
|
||||
});
|
||||
default:
|
||||
console.error("unsupported!");
|
||||
return respond('UNSUPPORTED_RPC_CALL', msg);
|
||||
}
|
||||
};
|
||||
|
||||
var rpc = function (
|
||||
ctx /*:{ store: Object }*/,
|
||||
data /*:Array<Array<any>>*/,
|
||||
|
@ -888,11 +921,19 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
|
|||
return void respond('INVALID_ARG_FORMAT');
|
||||
}
|
||||
|
||||
if (isUnauthenticateMessage(msg)) {
|
||||
return handleUnauthenticatedMessage(msg, respond);
|
||||
}
|
||||
|
||||
var signature = msg.shift();
|
||||
var publicKey = msg.shift();
|
||||
|
||||
// make sure a user object is initialized in the cookie jar
|
||||
beginSession(Sessions, publicKey);
|
||||
if (publicKey) {
|
||||
beginSession(Sessions, publicKey);
|
||||
} else {
|
||||
console.log("No public key");
|
||||
}
|
||||
|
||||
var cookie = msg[0];
|
||||
if (!isValidCookie(Sessions, publicKey, cookie)) {
|
||||
|
@ -928,7 +969,8 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
|
|||
msg.shift();
|
||||
|
||||
var Respond = function (e, msg) {
|
||||
var token = Sessions[safeKey].tokens.slice(-1)[0];
|
||||
var session = Sessions[safeKey];
|
||||
var token = session? session.tokens.slice(-1)[0]: '';
|
||||
var cookie = makeCookie(token).join('|');
|
||||
respond(e, [cookie].concat(typeof(msg) !== 'undefined' ?msg: []));
|
||||
};
|
||||
|
@ -1046,8 +1088,8 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
|
|||
return void handleMessage(false);
|
||||
}
|
||||
|
||||
// restrict upload capability unless explicitly disabled
|
||||
if (config.restrictUploads === false) {
|
||||
// allow unrestricted uploads unless restrictUploads is true
|
||||
if (config.restrictUploads !== true) {
|
||||
return void handleMessage(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,33 +3,6 @@
|
|||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<script src="/bower_components/codemirror/lib/codemirror.js"></script>
|
||||
<link rel="stylesheet" href="/bower_components/codemirror/lib/codemirror.css">
|
||||
<link rel="stylesheet" href="/bower_components/codemirror/addon/dialog/dialog.css">
|
||||
<link rel="stylesheet" href="/bower_components/codemirror/addon/fold/foldgutter.css" />
|
||||
<script src="/bower_components/codemirror/mode/javascript/javascript.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/mode/loadmode.js"></script>
|
||||
<script src="/bower_components/codemirror/mode/meta.js"></script>
|
||||
|
||||
<script src="/bower_components/codemirror/addon/mode/overlay.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/mode/multiplex.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/mode/simple.js"></script>
|
||||
|
||||
<script src="/bower_components/codemirror/addon/edit/closebrackets.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/edit/matchbrackets.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/edit/trailingspace.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/selection/active-line.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/search/search.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/search/match-highlighter.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/search/searchcursor.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/dialog/dialog.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/foldcode.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/foldgutter.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/brace-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/xml-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/markdown-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/comment-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/display/placeholder.js"></script>
|
||||
<script async data-bootload="inner.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.1.15"></script>
|
||||
<style> .loading-hidden { display: none; } </style>
|
||||
</head>
|
||||
|
|
|
@ -1,8 +1,37 @@
|
|||
define([
|
||||
'jquery',
|
||||
|
||||
'cm/lib/codemirror',
|
||||
|
||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
'less!/code/code.less',
|
||||
'less!/customize/src/less/toolbar.less',
|
||||
], function ($) {
|
||||
'css!cm/lib/codemirror.css',
|
||||
'css!cm/addon/dialog/dialog.css',
|
||||
'css!cm/addon/fold/foldgutter.css',
|
||||
|
||||
'cm/mode/markdown/markdown',
|
||||
'cm/addon/mode/loadmode',
|
||||
'cm/mode/meta',
|
||||
'cm/addon/mode/overlay',
|
||||
'cm/addon/mode/multiplex',
|
||||
'cm/addon/mode/simple',
|
||||
'cm/addon/edit/closebrackets',
|
||||
'cm/addon/edit/matchbrackets',
|
||||
'cm/addon/edit/trailingspace',
|
||||
'cm/addon/selection/active-line',
|
||||
'cm/addon/search/search',
|
||||
'cm/addon/search/match-highlighter',
|
||||
'cm/addon/search/searchcursor',
|
||||
'cm/addon/dialog/dialog',
|
||||
'cm/addon/fold/foldcode',
|
||||
'cm/addon/fold/foldgutter',
|
||||
'cm/addon/fold/brace-fold',
|
||||
'cm/addon/fold/xml-fold',
|
||||
'cm/addon/fold/markdown-fold',
|
||||
'cm/addon/fold/comment-fold',
|
||||
'cm/addon/display/placeholder',
|
||||
], function ($, CMeditor) {
|
||||
window.CodeMirror = CMeditor;
|
||||
$('.loading-hidden').removeClass('loading-hidden');
|
||||
});
|
||||
|
|
|
@ -9,7 +9,6 @@ define([
|
|||
'/common/cryptpad-common.js',
|
||||
'/common/cryptget.js',
|
||||
'/common/diffMarked.js',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js', // needed for media-tag
|
||||
|
||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
'less!/customize/src/less/cryptpad.less'
|
||||
|
@ -58,7 +57,7 @@ define([
|
|||
}
|
||||
});
|
||||
|
||||
var CodeMirror = Cryptpad.createCodemirror(CMeditor, ifrw, Cryptpad);
|
||||
var CodeMirror = Cryptpad.createCodemirror(ifrw, Cryptpad, null, CMeditor);
|
||||
$iframe.find('.CodeMirror').addClass('fullPage');
|
||||
editor = CodeMirror.editor;
|
||||
|
||||
|
@ -429,7 +428,6 @@ define([
|
|||
};
|
||||
|
||||
var interval = 100;
|
||||
|
||||
var second = function (CM) {
|
||||
Cryptpad.ready(function () {
|
||||
andThen(CM);
|
||||
|
@ -444,11 +442,9 @@ define([
|
|||
|
||||
var first = function () {
|
||||
if (ifrw.CodeMirror) {
|
||||
// it exists, call your continuation
|
||||
second(ifrw.CodeMirror);
|
||||
} else {
|
||||
console.log("CodeMirror was not defined. Trying again in %sms", interval);
|
||||
// try again in 'interval' ms
|
||||
setTimeout(first, interval);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ define([], function () {
|
|||
"json.sortify": "/bower_components/json.sortify/dist/JSON.sortify",
|
||||
//"pdfjs-dist/build/pdf": "/bower_components/pdfjs-dist/build/pdf",
|
||||
//"pdfjs-dist/build/pdf.worker": "/bower_components/pdfjs-dist/build/pdf.worker"
|
||||
cm: '/bower_components/codemirror'
|
||||
},
|
||||
map: {
|
||||
'*': {
|
||||
|
|
|
@ -2,18 +2,18 @@ define([
|
|||
'jquery',
|
||||
'/common/modes.js',
|
||||
'/common/themes.js',
|
||||
|
||||
'/bower_components/file-saver/FileSaver.min.js'
|
||||
], function ($, Modes, Themes) {
|
||||
var saveAs = window.saveAs;
|
||||
var module = {};
|
||||
|
||||
module.create = function (CMeditor, ifrw, Cryptpad) {
|
||||
module.create = function (ifrw, Cryptpad, defaultMode, CMeditor) {
|
||||
var exp = {};
|
||||
|
||||
var Messages = Cryptpad.Messages;
|
||||
|
||||
var CodeMirror = exp.CodeMirror = CMeditor;
|
||||
CodeMirror.modeURL = "/bower_components/codemirror/mode/%N/%N.js";
|
||||
CodeMirror.modeURL = "cm/mode/%N/%N";
|
||||
|
||||
var $pad = $('#pad-iframe');
|
||||
var $textarea = exp.$textarea = $pad.contents().find('#editor1');
|
||||
|
@ -43,14 +43,16 @@ define([
|
|||
extraKeys: {"Shift-Ctrl-R": undefined},
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
mode: "javascript",
|
||||
mode: defaultMode || "javascript",
|
||||
readOnly: true
|
||||
});
|
||||
editor.setValue(Messages.codeInitialState);
|
||||
|
||||
var setMode = exp.setMode = function (mode, cb) {
|
||||
exp.highlightMode = mode;
|
||||
if (mode !== "text") { CMeditor.autoLoadMode(editor, mode); }
|
||||
if (mode !== "text") {
|
||||
CMeditor.autoLoadMode(editor, mode);
|
||||
}
|
||||
editor.setOption('mode', mode);
|
||||
if (exp.$language) {
|
||||
var name = exp.$language.find('a[data-value="' + mode + '"]').text() || undefined;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(function () {
|
||||
define(['jquery'], function ($) {
|
||||
var module = {};
|
||||
|
||||
module.create = function (cfg, onLocal, Cryptpad) {
|
||||
|
@ -45,7 +45,8 @@ define(function () {
|
|||
};
|
||||
|
||||
// update title: href is optional; if not specified, we use window.location.href
|
||||
exp.updateTitle = function (newTitle, href) {
|
||||
exp.updateTitle = function (newTitle, href, cb) {
|
||||
cb = cb || $.noop;
|
||||
if (newTitle === exp.title) { return; }
|
||||
// Change the title now, and set it back to the old value if there is an error
|
||||
var oldTitle = exp.title;
|
||||
|
@ -54,9 +55,10 @@ define(function () {
|
|||
console.log("Couldn't set pad title");
|
||||
console.error(err);
|
||||
updateLocalTitle(oldTitle);
|
||||
return;
|
||||
return void cb(err);
|
||||
}
|
||||
updateLocalTitle(data);
|
||||
cb(null, data);
|
||||
if (!$title) { return; }
|
||||
$title.find('span.title').text(data);
|
||||
$title.find('input').val(data);
|
||||
|
|
|
@ -49,8 +49,10 @@ define(function () {
|
|||
exp.myUserName = myUserNameTemp;
|
||||
myData = {};
|
||||
myData[exp.myNetfluxId] = {
|
||||
name: exp.myUserName,
|
||||
uid: Cryptpad.getUid(),
|
||||
name: exp.myUserName,
|
||||
uid: Cryptpad.getUid(),
|
||||
avatar: Cryptpad.getAvatarUrl(),
|
||||
profile: Cryptpad.getProfileUrl()
|
||||
};
|
||||
addToUserData(myData);
|
||||
Cryptpad.setAttribute('username', exp.myUserName, function (err) {
|
||||
|
@ -78,6 +80,8 @@ define(function () {
|
|||
myData[exp.myNetfluxId] = {
|
||||
name: "",
|
||||
uid: Cryptpad.getUid(),
|
||||
avatar: Cryptpad.getAvatarUrl(),
|
||||
profile: Cryptpad.getProfileUrl()
|
||||
};
|
||||
addToUserData(myData);
|
||||
onLocal();
|
||||
|
|
|
@ -16,9 +16,10 @@ define([
|
|||
|
||||
'/common/clipboard.js',
|
||||
'/common/pinpad.js',
|
||||
'/customize/application_config.js'
|
||||
'/customize/application_config.js',
|
||||
'/common/media-tag.js',
|
||||
], function ($, Config, Messages, Store, Util, Hash, UI, History, UserList, Title, Metadata,
|
||||
CodeMirror, Files, FileCrypto, Clipboard, Pinpad, AppConfig) {
|
||||
CodeMirror, Files, FileCrypto, Clipboard, Pinpad, AppConfig, MediaTag) {
|
||||
|
||||
/* This file exposes functionality which is specific to Cryptpad, but not to
|
||||
any particular pad type. This includes functions for committing metadata
|
||||
|
@ -49,6 +50,7 @@ define([
|
|||
|
||||
var store;
|
||||
var rpc;
|
||||
var anon_rpc;
|
||||
|
||||
// import UI elements
|
||||
common.findCancelButton = UI.findCancelButton;
|
||||
|
@ -76,7 +78,7 @@ define([
|
|||
var deduplicateString = common.deduplicateString = Util.deduplicateString;
|
||||
common.uint8ArrayToHex = Util.uint8ArrayToHex;
|
||||
common.replaceHash = Util.replaceHash;
|
||||
var getHash = common.getHash = Util.getHash;
|
||||
common.getHash = Util.getHash;
|
||||
common.fixFileName = Util.fixFileName;
|
||||
common.bytesToMegabytes = Util.bytesToMegabytes;
|
||||
common.bytesToKilobytes = Util.bytesToKilobytes;
|
||||
|
@ -146,6 +148,16 @@ define([
|
|||
}
|
||||
return;
|
||||
};
|
||||
common.getProfileUrl = function () {
|
||||
if (store && store.getProfile()) {
|
||||
return store.getProfile().view;
|
||||
}
|
||||
};
|
||||
common.getAvatarUrl = function () {
|
||||
if (store && store.getProfile()) {
|
||||
return store.getProfile().avatar;
|
||||
}
|
||||
};
|
||||
|
||||
var feedback = common.feedback = function (action, force) {
|
||||
if (force !== true) {
|
||||
|
@ -414,9 +426,8 @@ define([
|
|||
|
||||
// STORAGE
|
||||
common.setPadAttribute = function (attr, value, cb) {
|
||||
getStore().setDrive([getHash(), attr].join('.'), value, function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
var href = getRelativeHref(window.location.href);
|
||||
getStore().setPadAttribute(href, attr, value, cb);
|
||||
};
|
||||
common.setAttribute = function (attr, value, cb) {
|
||||
getStore().set(["cryptpad", attr].join('.'), value, function (err, data) {
|
||||
|
@ -429,9 +440,8 @@ define([
|
|||
|
||||
// STORAGE
|
||||
common.getPadAttribute = function (attr, cb) {
|
||||
getStore().getDrive([getHash(), attr].join('.'), function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
var href = getRelativeHref(window.location.href);
|
||||
getStore().getPadAttribute(href, attr, cb);
|
||||
};
|
||||
common.getAttribute = function (attr, cb) {
|
||||
getStore().get(["cryptpad", attr].join('.'), function (err, data) {
|
||||
|
@ -777,11 +787,32 @@ define([
|
|||
};
|
||||
|
||||
common.getFileSize = function (href, cb) {
|
||||
if (!pinsReady()) { return void cb('RPC_NOT_READY'); }
|
||||
if (!anon_rpc) { return void cb('ANON_RPC_NOT_READY'); }
|
||||
//if (!pinsReady()) { return void cb('RPC_NOT_READY'); }
|
||||
var channelId = Hash.hrefToHexChannelId(href);
|
||||
rpc.getFileSize(channelId, function (e, bytes) {
|
||||
anon_rpc.send("GET_FILE_SIZE", channelId, function (e, response) {
|
||||
if (e) { return void cb(e); }
|
||||
cb(void 0, bytes);
|
||||
if (response && response.length && typeof(response[0]) === 'number') {
|
||||
return void cb(void 0, response[0]);
|
||||
} else {
|
||||
cb('INVALID_RESPONSE');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
common.getMultipleFileSize = function (files, cb) {
|
||||
if (!anon_rpc) { return void cb('ANON_RPC_NOT_READY'); }
|
||||
if (!Array.isArray(files)) {
|
||||
return void setTimeout(function () { cb('INVALID_FILE_LIST'); });
|
||||
}
|
||||
|
||||
anon_rpc.send('GET_MULTIPLE_FILE_SIZE', files, function (e, res) {
|
||||
if (e) { return cb(e); }
|
||||
if (res && res.length && typeof(res[0]) === 'object') {
|
||||
cb(void 0, res[0]);
|
||||
} else {
|
||||
cb('UNEXPECTED_RESPONSE');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -800,7 +831,9 @@ define([
|
|||
if (!pinsReady()) { return void cb('RPC_NOT_READY'); }
|
||||
|
||||
var account = common.account;
|
||||
if (typeof(account.limit) !== 'number' ||
|
||||
|
||||
var ALWAYS_REVALIDATE = true;
|
||||
if (ALWAYS_REVALIDATE || typeof(account.limit) !== 'number' ||
|
||||
typeof(account.plan) !== 'string' ||
|
||||
typeof(account.note) !== 'string') {
|
||||
return void rpc.getLimit(function (e, limit, plan, note) {
|
||||
|
@ -863,7 +896,6 @@ define([
|
|||
var $container = $('<span>', {'class':'limit-container'});
|
||||
var todo;
|
||||
var updateUsage = window.updateUsage = common.notAgainForAnother(function () {
|
||||
console.log("updating usage bar");
|
||||
common.getPinnedUsage(todo);
|
||||
}, LIMIT_REFRESH_RATE);
|
||||
|
||||
|
@ -933,21 +965,12 @@ define([
|
|||
};
|
||||
|
||||
setInterval(function () {
|
||||
var t = updateUsage();
|
||||
if (t) {
|
||||
console.log("usage already updated. eligible for refresh in %sms", t);
|
||||
}
|
||||
updateUsage();
|
||||
}, LIMIT_REFRESH_RATE * 3);
|
||||
|
||||
updateUsage();
|
||||
getProxy().on('change', ['drive'], function () {
|
||||
var t = updateUsage();
|
||||
if (t) {
|
||||
console.log("usage bar update throttled due to overuse." +
|
||||
" Eligible for update in %sms", t);
|
||||
} else {
|
||||
console.log("usage bar updated");
|
||||
}
|
||||
updateUsage();
|
||||
});
|
||||
cb(null, $container);
|
||||
};
|
||||
|
@ -1162,67 +1185,132 @@ define([
|
|||
return button;
|
||||
};
|
||||
|
||||
|
||||
var emoji_patt = /([\uD800-\uDBFF][\uDC00-\uDFFF])/;
|
||||
var isEmoji = function (str) {
|
||||
return emoji_patt.test(str);
|
||||
};
|
||||
var emojiStringToArray = function (str) {
|
||||
var split = str.split(emoji_patt);
|
||||
var arr = [];
|
||||
for (var i=0; i<split.length; i++) {
|
||||
var char = split[i];
|
||||
if (char !== "") {
|
||||
arr.push(char);
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
var getFirstEmojiOrCharacter = function (str) {
|
||||
if (!str || !str.trim()) { return '?'; }
|
||||
var emojis = emojiStringToArray(str);
|
||||
return isEmoji(emojis[0])? emojis[0]: str[0];
|
||||
};
|
||||
$(window.document).on('decryption', function (e) {
|
||||
var decrypted = e.originalEvent;
|
||||
if (decrypted.callback) {
|
||||
var cb = decrypted.callback;
|
||||
cb(function (mediaObject) {
|
||||
if (mediaObject.type !== 'download') { return; }
|
||||
var root = mediaObject.rootElement;
|
||||
if (!root) { return; }
|
||||
|
||||
var metadata = decrypted.metadata;
|
||||
|
||||
var title = '';
|
||||
var size = 0;
|
||||
if (metadata && metadata.name) {
|
||||
title = metadata.name;
|
||||
}
|
||||
|
||||
if (decrypted.blob) {
|
||||
size = decrypted.blob.size;
|
||||
}
|
||||
|
||||
var sizeMb = common.bytesToMegabytes(size);
|
||||
|
||||
var $btn = $(root).find('button');
|
||||
$btn.addClass('btn btn-success')
|
||||
.attr('type', 'download')
|
||||
.html(function () {
|
||||
var text = Messages.download_mt_button + '<br>';
|
||||
if (title) {
|
||||
text += '<b>' + common.fixHTML(title) + '</b><br>';
|
||||
}
|
||||
if (size) {
|
||||
text += '<em>' + Messages._getKey('formattedMB', [sizeMb]) + '</em>';
|
||||
}
|
||||
return text;
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
common.avatarAllowedTypes = [
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/gif',
|
||||
];
|
||||
common.displayAvatar = function ($container, href) {
|
||||
common.displayAvatar = function ($container, href, name, cb) {
|
||||
var MutationObserver = window.MutationObserver;
|
||||
$container.html('');
|
||||
if (href) {
|
||||
var parsed = common.parsePadUrl(href);
|
||||
var secret = common.getSecrets('file', parsed.hash);
|
||||
if (secret.keys && secret.channel) {
|
||||
var cryptKey = secret.keys && secret.keys.fileKeyStr;
|
||||
var hexFileName = common.base64ToHex(secret.channel);
|
||||
var src = common.getBlobPathFromHex(hexFileName);
|
||||
common.getFileSize(href, function (e, data) {
|
||||
if (e) { return void console.error(e); }
|
||||
if (typeof data !== "number") { return; }
|
||||
if (common.bytesToMegabytes(data) > 0.5) { return; }
|
||||
var $img = $('<media-tag>').appendTo($container);
|
||||
$img.attr('src', src);
|
||||
$img.attr('data-crypto-key', 'cryptpad:' + cryptKey);
|
||||
require(['/common/media-tag.js'], function (MediaTag) {
|
||||
MediaTag.CryptoFilter.setAllowedMediaTypes(common.avatarAllowedTypes);
|
||||
MediaTag($img[0]);
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.type === 'childList' && mutation.addedNodes.length) {
|
||||
console.log(mutation);
|
||||
if (mutation.addedNodes.length > 1 ||
|
||||
mutation.addedNodes[0].nodeName !== 'IMG') {
|
||||
$img.remove();
|
||||
return;
|
||||
//TODO display default avatar
|
||||
}
|
||||
var $image = $img.find('img');
|
||||
var onLoad = function () {
|
||||
var w = $image.width();
|
||||
var h = $image.height();
|
||||
if (w>h) {
|
||||
$image.css('max-height', '100%');
|
||||
$img.css('flex-direction', 'row');
|
||||
return;
|
||||
}
|
||||
$image.css('max-width', '100%');
|
||||
$img.css('flex-direction', 'column');
|
||||
};
|
||||
if ($image[0].complete) { onLoad(); }
|
||||
$image.on('load', onLoad);
|
||||
var displayDefault = function () {
|
||||
var text = getFirstEmojiOrCharacter(name);
|
||||
var $avatar = $('<span>', {'class': 'default'}).text(text);
|
||||
$container.append($avatar);
|
||||
if (cb) { cb(); }
|
||||
};
|
||||
|
||||
if (!href) { return void displayDefault(); }
|
||||
var parsed = common.parsePadUrl(href);
|
||||
var secret = common.getSecrets('file', parsed.hash);
|
||||
if (secret.keys && secret.channel) {
|
||||
var cryptKey = secret.keys && secret.keys.fileKeyStr;
|
||||
var hexFileName = common.base64ToHex(secret.channel);
|
||||
var src = common.getBlobPathFromHex(hexFileName);
|
||||
common.getFileSize(href, function (e, data) {
|
||||
if (e) {
|
||||
displayDefault();
|
||||
return void console.error(e);
|
||||
}
|
||||
if (typeof data !== "number") { return void displayDefault(); }
|
||||
if (common.bytesToMegabytes(data) > 0.5) { return void displayDefault(); }
|
||||
var $img = $('<media-tag>').appendTo($container);
|
||||
$img.attr('src', src);
|
||||
$img.attr('data-crypto-key', 'cryptpad:' + cryptKey);
|
||||
MediaTag($img[0]);
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.type === 'childList' && mutation.addedNodes.length) {
|
||||
if (mutation.addedNodes.length > 1 ||
|
||||
mutation.addedNodes[0].nodeName !== 'IMG') {
|
||||
$img.remove();
|
||||
return void displayDefault();
|
||||
}
|
||||
var $image = $img.find('img');
|
||||
var onLoad = function () {
|
||||
var w = $image.width();
|
||||
var h = $image.height();
|
||||
if (w>h) {
|
||||
$image.css('max-height', '100%');
|
||||
$img.css('flex-direction', 'row');
|
||||
if (cb) { cb($img); }
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe($img[0], {
|
||||
attributes: false,
|
||||
childList: true,
|
||||
characterData: false
|
||||
});
|
||||
$image.css('max-width', '100%');
|
||||
$img.css('flex-direction', 'column');
|
||||
if (cb) { cb($img); }
|
||||
};
|
||||
if ($image[0].complete) { onLoad(); }
|
||||
$image.on('load', onLoad);
|
||||
}
|
||||
});
|
||||
observer.observe($img[0], {
|
||||
attributes: false,
|
||||
childList: true,
|
||||
characterData: false
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1301,7 +1389,7 @@ define([
|
|||
setActive($val);
|
||||
$innerblock.scrollTop($val.position().top + $innerblock.scrollTop());
|
||||
}
|
||||
if (config.feedback) { common.feedback(config.feedback); }
|
||||
if (config.feedback && store) { common.feedback(config.feedback); }
|
||||
};
|
||||
|
||||
$container.click(function (e) {
|
||||
|
@ -1457,6 +1545,13 @@ define([
|
|||
content: Messages.user_rename
|
||||
});
|
||||
}
|
||||
if (account) {
|
||||
options.push({
|
||||
tag: 'a',
|
||||
attributes: {'class': 'profile'},
|
||||
content: Messages.profileButton
|
||||
});
|
||||
}
|
||||
if (parsed && (!parsed.type || parsed.type !== 'settings')) {
|
||||
options.push({
|
||||
tag: 'a',
|
||||
|
@ -1516,6 +1611,13 @@ define([
|
|||
window.location.href = '/settings/';
|
||||
}
|
||||
});
|
||||
$userAdmin.find('a.profile').click(function () {
|
||||
if (parsed && parsed.type) {
|
||||
window.open('/profile/');
|
||||
} else {
|
||||
window.location.href = '/profile/';
|
||||
}
|
||||
});
|
||||
$userAdmin.find('a.login').click(function () {
|
||||
if (window.location.pathname !== "/") {
|
||||
sessionStorage.redirectTo = window.location.href;
|
||||
|
@ -1666,6 +1768,21 @@ define([
|
|||
console.log('pinning disabled');
|
||||
}
|
||||
|
||||
block++;
|
||||
require([
|
||||
'/common/rpc.js',
|
||||
], function (Rpc) {
|
||||
Rpc.createAnonymous(network, function (e, call) {
|
||||
if (e) {
|
||||
console.error(e);
|
||||
return void cb();
|
||||
}
|
||||
anon_rpc = common.anon_rpc = env.anon_rpc = call;
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Everything's ready, continue...
|
||||
if($('#pad-iframe').length) {
|
||||
block++;
|
||||
|
|
|
@ -171,11 +171,6 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
$(window.document).on('decryption', function (e) {
|
||||
var decrypted = e.originalEvent;
|
||||
if (decrypted.callback) { decrypted.callback(); }
|
||||
});
|
||||
|
||||
return DiffMd;
|
||||
});
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@ define([
|
|||
cb(void 0, res);
|
||||
};
|
||||
|
||||
ret.setPadAttribute = filesOp.setAttribute;
|
||||
ret.getPadAttribute = filesOp.getAttribute;
|
||||
|
||||
ret.getDrive = function (key, cb) {
|
||||
cb(void 0, storeObj.drive[key]);
|
||||
};
|
||||
|
@ -211,6 +214,10 @@ define([
|
|||
if (typeof(n) !== "string") { return; }
|
||||
Cryptpad.changeDisplayName(n);
|
||||
});
|
||||
proxy.on('change', ['profile'], function () {
|
||||
// Trigger userlist update when the avatar has changed
|
||||
Cryptpad.changeDisplayName(proxy[Cryptpad.displayNameKey]);
|
||||
});
|
||||
proxy.on('change', [tokenKey], function () {
|
||||
console.log('wut');
|
||||
var localToken = tryParsing(localStorage.getItem(tokenKey));
|
||||
|
|
|
@ -86,7 +86,7 @@ define([
|
|||
exp.anonDriveIntoUser = function (proxy, cb) {
|
||||
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
||||
if (!localStorage.FS_hash || !Cryptpad.isLoggedIn()) {
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
if (typeof(cb) === "function") { return void cb(); }
|
||||
}
|
||||
// Get the content of FS_hash and then merge the objects, remove the migration key and cb
|
||||
var todo = function (err, doc) {
|
||||
|
|
|
@ -54,11 +54,9 @@ define(function () {
|
|||
"jsx jsx .jsx",
|
||||
"julia julia",
|
||||
"livescript livescript",
|
||||
"loadmode.js loadmode.js",
|
||||
"lua lua",
|
||||
"markdown markdown .md",
|
||||
"mathematica mathematica",
|
||||
"meta.js meta.js",
|
||||
"mirc mirc",
|
||||
"mllike mllike",
|
||||
"modelica modelica",
|
||||
|
|
|
@ -100,21 +100,6 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
// take a list of channels and return a dictionary of their sizes
|
||||
exp.getMultipleFileSize = function (files, cb) {
|
||||
if (!Array.isArray(files)) {
|
||||
return window.setTimeout(function () {
|
||||
cb('[TypeError] pin expects an array');
|
||||
});
|
||||
}
|
||||
rpc.send('GET_MULTIPLE_FILE_SIZE', files, function (e, res) {
|
||||
if (e) { return void cb(e); }
|
||||
if (typeof(res) !== 'object') {
|
||||
return void cb('INVALID_RESPONSE');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// get the combined size of all channels (in bytes) for all the
|
||||
// channels which the server has pinned for your publicKey
|
||||
exp.getFileListSize = function (cb) {
|
||||
|
|
|
@ -99,7 +99,12 @@ types of messages:
|
|||
delete ctx.pending[txid];
|
||||
return;
|
||||
}
|
||||
console.error("received message [%s] for txid[%s] with no callback", msg, txid);
|
||||
|
||||
// HACK to hide messages from the anon rpc
|
||||
if (parsed.length !== 4) {
|
||||
console.log(parsed);
|
||||
console.error("received message [%s] for txid[%s] with no callback", msg, txid);
|
||||
}
|
||||
};
|
||||
|
||||
var create = function (network, edPrivateKey, edPublicKey, cb) {
|
||||
|
@ -217,5 +222,104 @@ types of messages:
|
|||
});
|
||||
};
|
||||
|
||||
return { create: create };
|
||||
var onAnonMsg = function (ctx, msg) {
|
||||
var parsed = parse(msg);
|
||||
|
||||
if (!parsed) {
|
||||
return void console.error(new Error('could not parse message: %s', msg));
|
||||
}
|
||||
|
||||
// RPC messages are always arrays.
|
||||
if (!Array.isArray(parsed)) { return; }
|
||||
var txid = parsed[0];
|
||||
|
||||
// txid must be a string, or this message is not meant for us
|
||||
if (typeof(txid) !== 'string') { return; }
|
||||
|
||||
var pending = ctx.pending[txid];
|
||||
|
||||
if (!(parsed && parsed.slice)) {
|
||||
// RPC responses are arrays. this message isn't meant for us.
|
||||
return;
|
||||
}
|
||||
if (/FULL_HISTORY/.test(parsed[0])) { return; }
|
||||
var response = parsed.slice(2);
|
||||
|
||||
if (typeof(pending) === 'function') {
|
||||
if (parsed[1] === 'ERROR') {
|
||||
pending(parsed[2]);
|
||||
delete ctx.pending[txid];
|
||||
return;
|
||||
}
|
||||
pending(void 0, response);
|
||||
|
||||
// if successful, delete the callback...
|
||||
delete ctx.pending[txid];
|
||||
return;
|
||||
}
|
||||
// HACK: filter out ugly messages we don't care about
|
||||
if (typeof(msg) !== 'string') {
|
||||
console.error("received message [%s] for txid[%s] with no callback", msg, txid);
|
||||
}
|
||||
};
|
||||
|
||||
var createAnonymous = function (network, cb) {
|
||||
var ctx = {
|
||||
network: network,
|
||||
timeouts: {}, // timeouts
|
||||
pending: {}, // callbacks
|
||||
cookie: null,
|
||||
connected: true,
|
||||
};
|
||||
|
||||
var send = ctx.send = function (type, msg, cb) {
|
||||
if (!ctx.connected) {
|
||||
return void window.setTimeout(function () {
|
||||
cb('DISCONNECTED');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// construct an unsigned message...
|
||||
var data = [type, msg];
|
||||
|
||||
// [sig, edPublicKey, cookie, type, msg]
|
||||
return sendMsg(ctx, data, cb);
|
||||
};
|
||||
|
||||
ctx.resend = function (txid) {
|
||||
var pending = ctx.pending[txid];
|
||||
if (pending.called) {
|
||||
console.error("[%s] called too many times", txid);
|
||||
return true;
|
||||
}
|
||||
pending.called++;
|
||||
|
||||
try {
|
||||
return ctx.network.sendto(ctx.network.historyKeeper,
|
||||
JSON.stringify([txid, pending.data]));
|
||||
} catch (e) {
|
||||
console.log("failed to resend");
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
network.on('message', function (msg) {
|
||||
onAnonMsg(ctx, msg);
|
||||
});
|
||||
|
||||
network.on('disconnect', function () {
|
||||
ctx.connected = false;
|
||||
});
|
||||
|
||||
network.on('reconnect', function () {
|
||||
ctx.connected = true;
|
||||
});
|
||||
|
||||
cb(void 0, {
|
||||
send: send
|
||||
});
|
||||
};
|
||||
|
||||
return { create: create, createAnonymous: createAnonymous };
|
||||
});
|
||||
|
|
|
@ -81,15 +81,31 @@ define([
|
|||
|
||||
var $rightside = $toolbar.find('.'+RIGHTSIDE_CLS);
|
||||
if (!config.hideDrawer) {
|
||||
var $drawerContent = $('<div>', {'class': DRAWER_CLS}).appendTo($rightside).hide();
|
||||
var $drawerContent = $('<div>', {
|
||||
'class': DRAWER_CLS,// + ' dropdown-bar-content cryptpad-dropdown'
|
||||
'tabindex': 1
|
||||
}).appendTo($rightside).hide();
|
||||
var $drawer = Cryptpad.createButton('more', true).appendTo($rightside);
|
||||
$drawer.click(function () {
|
||||
$drawerContent.toggle();
|
||||
$drawer.removeClass('active');
|
||||
if ($drawerContent.is(':visible')) {
|
||||
$drawer.addClass('active');
|
||||
$drawerContent.focus();
|
||||
}
|
||||
});
|
||||
var onBlur = function (e) {
|
||||
if (e.relatedTarget) {
|
||||
if ($(e.relatedTarget).is('.drawer-button')) { return; }
|
||||
if ($(e.relatedTarget).parents('.'+DRAWER_CLS).length) {
|
||||
$(e.relatedTarget).blur(onBlur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$drawer.removeClass('active');
|
||||
$drawerContent.hide();
|
||||
};
|
||||
$drawerContent.blur(onBlur);
|
||||
}
|
||||
|
||||
// The 'notitle' class removes the line added for the title with a small screen
|
||||
|
@ -149,6 +165,7 @@ define([
|
|||
return $.inArray(i, b) > -1;
|
||||
});
|
||||
};
|
||||
var avatars = {};
|
||||
var updateUserList = function (toolbar, config) {
|
||||
// Make sure the elements are displayed
|
||||
var $userButtons = toolbar.userlist;
|
||||
|
@ -189,7 +206,25 @@ define([
|
|||
// Editors
|
||||
editUsersNames.forEach(function (data) {
|
||||
var name = data.name || Messages.anonymous;
|
||||
var $span = $('<span>', {'title': name}).text(name);
|
||||
var $name = $('<span>', {'class': 'name'}).text(name);
|
||||
var $span = $('<span>', {'title': name});
|
||||
if (data.profile) {
|
||||
$span.addClass('clickable');
|
||||
$span.click(function () {
|
||||
window.open('/profile/#' + data.profile);
|
||||
});
|
||||
}
|
||||
if (data.avatar && avatars[data.avatar]) {
|
||||
$span.append(avatars[data.avatar]);
|
||||
$span.append($name);
|
||||
} else {
|
||||
Cryptpad.displayAvatar($span, data.avatar, name, function ($img) {
|
||||
if (data.avatar && $img) {
|
||||
avatars[data.avatar] = $img[0].outerHTML;
|
||||
}
|
||||
$span.append($name);
|
||||
});
|
||||
}
|
||||
$span.data('uid', data.uid);
|
||||
$editUsersList.append($span);
|
||||
});
|
||||
|
@ -197,9 +232,9 @@ define([
|
|||
|
||||
// Viewers
|
||||
if (numberOfViewUsers > 0) {
|
||||
var viewText = '<span class="viewer">';
|
||||
var viewText = '<div class="viewer">';
|
||||
var viewerText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer;
|
||||
viewText += numberOfViewUsers + ' ' + viewerText + '</span>';
|
||||
viewText += numberOfViewUsers + ' ' + viewerText + '</div>';
|
||||
$editUsers.append(viewText);
|
||||
}
|
||||
|
||||
|
@ -299,6 +334,11 @@ define([
|
|||
if ($content.is(':visible')) { return void show(); }
|
||||
hide();
|
||||
});
|
||||
$(window).on('resize', function () {
|
||||
mobile = $('body').width() <= 600;
|
||||
var h = $ck.is(':visible') ? -$ck.height() : 0;
|
||||
$content.css('margin-top', h+'px');
|
||||
});
|
||||
$closeIcon.click(hide);
|
||||
$button.click(function () {
|
||||
var visible = $content.is(':visible');
|
||||
|
@ -553,17 +593,17 @@ define([
|
|||
|
||||
// We need to override the "a" tag action here because it is inside the iframe!
|
||||
var $aTag = $('<a>', {
|
||||
href: "/",
|
||||
href: "/drive/",
|
||||
title: Messages.header_logoTitle,
|
||||
'class': "cryptpad-logo fa fa-hdd-o"
|
||||
});
|
||||
var onClick = function (e) {
|
||||
e.preventDefault();
|
||||
if (e.ctrlKey) {
|
||||
window.open('/drive');
|
||||
window.open('/drive/');
|
||||
return;
|
||||
}
|
||||
window.location = "/drive";
|
||||
window.location = "/drive/";
|
||||
};
|
||||
|
||||
var onContext = function (e) { e.stopPropagation(); };
|
||||
|
|
|
@ -132,6 +132,21 @@ define([
|
|||
if (type === 'name') { return data.filename; }
|
||||
return data.filename || data.title || NEW_FILE_NAME;
|
||||
};
|
||||
exp.getAttribute = function (href, attr, cb) {
|
||||
cb = cb || $.noop;
|
||||
var id = exp.getIdFromHref(href);
|
||||
if (!id) { return void cb(null, undefined); }
|
||||
var data = getFileData(id);
|
||||
cb(null, data[attr]);
|
||||
};
|
||||
exp.setAttribute = function (href, attr, value, cb) {
|
||||
cb = cb || $.noop;
|
||||
var id = exp.getIdFromHref(href);
|
||||
if (!id) { return void cb("E_INVAL_HREF"); }
|
||||
if (!attr || !attr.trim()) { return void cb("E_INVAL_ATTR"); }
|
||||
var data = getFileData(id);
|
||||
data[attr] = value;
|
||||
};
|
||||
|
||||
// PATHS
|
||||
|
||||
|
@ -970,6 +985,20 @@ define([
|
|||
us.splice(idx, 1);
|
||||
});
|
||||
};
|
||||
var migrateAttributes = function (el, id, parsed) {
|
||||
// Migrate old pad attributes
|
||||
['userid', 'previewMode'].forEach(function (attr) {
|
||||
var key = parsed.hash + '.' + attr;
|
||||
var key2 = parsed.hash.slice(0,-1) + '.' + attr;// old pads not ending with /
|
||||
if (files[key] || files[key2]) {
|
||||
debug("Migrating pad attribute", attr, "for pad", id);
|
||||
el[attr] = files[key] || files[key2];
|
||||
}
|
||||
delete files[key];
|
||||
delete files[key2];
|
||||
});
|
||||
// Migration done
|
||||
};
|
||||
var fixFilesData = function () {
|
||||
if (typeof files[FILES_DATA] !== "object") { debug("OLD_FILES_DATA was not an object"); files[FILES_DATA] = {}; }
|
||||
var fd = files[FILES_DATA];
|
||||
|
@ -989,6 +1018,15 @@ define([
|
|||
toClean.push(id);
|
||||
continue;
|
||||
}
|
||||
var parsed = Cryptpad.parsePadUrl(el.href);
|
||||
if (!parsed.hash) {
|
||||
debug("Removing an element in filesData with a invalid href.", el);
|
||||
toClean.push(id);
|
||||
continue;
|
||||
}
|
||||
|
||||
migrateAttributes(el, id, parsed);
|
||||
|
||||
if ((Cryptpad.isLoggedIn() || config.testMode) && rootFiles.indexOf(id) === -1) {
|
||||
debug("An element in filesData was not in ROOT, TEMPLATE or TRASH.", id, el);
|
||||
var newName = Cryptpad.createChannelId();
|
||||
|
@ -1001,12 +1039,19 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
var fixDrive = function () {
|
||||
Object.keys(files).forEach(function (key) {
|
||||
if (key.slice(0,1) === '/') { delete files[key]; }
|
||||
});
|
||||
};
|
||||
|
||||
fixRoot();
|
||||
fixTrashRoot();
|
||||
if (!workgroup) {
|
||||
fixTemplate();
|
||||
fixFilesData();
|
||||
}
|
||||
fixDrive();
|
||||
|
||||
if (JSON.stringify(files) !== before) {
|
||||
debug("Your file system was corrupted. It has been cleaned so that the pads you visit can be stored safely");
|
||||
|
|
|
@ -621,7 +621,7 @@ span {
|
|||
margin: 0;
|
||||
}
|
||||
button {
|
||||
height: 100%;
|
||||
height: 32px;
|
||||
padding: 0 10px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
|
|
|
@ -1170,7 +1170,7 @@ define([
|
|||
var element = filesOp.find(newPath);
|
||||
var $icon = !isFolder ? getFileIcon(element) : undefined;
|
||||
var ro = filesOp.isReadOnlyFile(element);
|
||||
// ro undefined mens it's an old hash which doesn't support read-only
|
||||
// ro undefined means it's an old hash which doesn't support read-only
|
||||
var roClass = typeof(ro) === 'undefined' ? ' noreadonly' : ro ? ' readonly' : '';
|
||||
var liClass = 'file-item file-element element' + roClass;
|
||||
if (isFolder) {
|
||||
|
@ -2140,6 +2140,7 @@ define([
|
|||
$trashContextMenu.hide();
|
||||
$contentContextMenu.hide();
|
||||
$defaultContextMenu.hide();
|
||||
$iframe.find('.cryptpad-dropdown').hide();
|
||||
};
|
||||
|
||||
var stringifyPath = function (path) {
|
||||
|
|
|
@ -242,6 +242,18 @@ define([
|
|||
fo.migrate(todo);
|
||||
}, "DRIVE4: migration and fixFiles with a pad in trash not root");
|
||||
|
||||
// Pad attributes migration
|
||||
assert(function (cb) {
|
||||
console.log('START PAD ATTRIBUTES');
|
||||
var files = JSON.parse(JSON.stringify(example));
|
||||
files[href1.slice(6) + '.userid'] = 'value';
|
||||
files[href1.slice(6) + '.previewMode'] = true;
|
||||
var fo = FO.init(files, config);
|
||||
fo.fixFiles();
|
||||
return cb(files.filesData[id1].userid === 'value'
|
||||
&& files.filesData[id1].previewMode);
|
||||
}, "PAD ATTRIBUTES");
|
||||
|
||||
// userObject Tests
|
||||
|
||||
// UTILS
|
||||
|
|
|
@ -7,12 +7,14 @@ define([
|
|||
'/common/visible.js',
|
||||
'/common/notify.js',
|
||||
'/file/file-crypto.js',
|
||||
|
||||
'/common/media-tag.js',
|
||||
|
||||
'/bower_components/file-saver/FileSaver.min.js',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||
|
||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
'less!/customize/src/less/cryptpad.less',
|
||||
], function ($, Crypto, realtimeInput, Toolbar, Cryptpad, Visible, Notify, FileCrypto) {
|
||||
], function ($, Crypto, realtimeInput, Toolbar, Cryptpad, Visible, Notify, FileCrypto, MediaTag) {
|
||||
var Messages = Cryptpad.Messages;
|
||||
var saveAs = window.saveAs;
|
||||
var Nacl = window.nacl;
|
||||
|
@ -91,7 +93,9 @@ define([
|
|||
|
||||
$(window.document).on('decryption', function (e) {
|
||||
var decrypted = e.originalEvent;
|
||||
if (decrypted.callback) { decrypted.callback(); }
|
||||
if (decrypted.callback) {
|
||||
decrypted.callback();
|
||||
}
|
||||
|
||||
console.log(decrypted);
|
||||
$dlview.show();
|
||||
|
@ -131,32 +135,30 @@ define([
|
|||
console.log(progress.percent);
|
||||
});
|
||||
|
||||
require(['/common/media-tag.js'], function (MediaTag) {
|
||||
/**
|
||||
* Allowed mime types that have to be set for a rendering after a decryption.
|
||||
*
|
||||
* @type {Array}
|
||||
*/
|
||||
var allowedMediaTypes = [
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/gif',
|
||||
'audio/mp3',
|
||||
'audio/ogg',
|
||||
'audio/wav',
|
||||
'audio/webm',
|
||||
'video/mp4',
|
||||
'video/ogg',
|
||||
'video/webm',
|
||||
'application/pdf',
|
||||
'application/dash+xml',
|
||||
'download'
|
||||
];
|
||||
MediaTag.CryptoFilter.setAllowedMediaTypes(allowedMediaTypes);
|
||||
/**
|
||||
* Allowed mime types that have to be set for a rendering after a decryption.
|
||||
*
|
||||
* @type {Array}
|
||||
*/
|
||||
var allowedMediaTypes = [
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/gif',
|
||||
'audio/mp3',
|
||||
'audio/ogg',
|
||||
'audio/wav',
|
||||
'audio/webm',
|
||||
'video/mp4',
|
||||
'video/ogg',
|
||||
'video/webm',
|
||||
'application/pdf',
|
||||
'application/dash+xml',
|
||||
'download'
|
||||
];
|
||||
MediaTag.CryptoFilter.setAllowedMediaTypes(allowedMediaTypes);
|
||||
|
||||
MediaTag($mt[0]);
|
||||
});
|
||||
MediaTag($mt[0]);
|
||||
};
|
||||
|
||||
var todoBigFile = function (sizeMb) {
|
||||
|
@ -181,9 +183,6 @@ define([
|
|||
};
|
||||
Cryptpad.getFileSize(window.location.href, function (e, data) {
|
||||
if (e) {
|
||||
// TODO when GET_FILE_SIZE is made unauthenticated
|
||||
// you won't need to handle this error (there won't be one)
|
||||
if (e === 'RPC_NOT_READY') { return todoBigFile(); }
|
||||
return void Cryptpad.errorLoadingScreen(e);
|
||||
}
|
||||
var size = Cryptpad.bytesToMegabytes(data);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#cke_1_top {
|
||||
overflow: visible;
|
||||
padding: 0px;
|
||||
display: flex;
|
||||
}
|
||||
#cke_1_toolbox {
|
||||
display: inline-block;
|
||||
|
|
|
@ -570,16 +570,10 @@ define([
|
|||
// this should only ever get called once, when the chain syncs
|
||||
realtimeOptions.onReady = function (info) {
|
||||
if (!module.isMaximized) {
|
||||
editor.execCommand('maximize');
|
||||
module.isMaximized = true;
|
||||
// We have to call it 3 times in Safari
|
||||
// in order to have the editor fully maximized -_-
|
||||
if ((''+window.navigator.vendor).indexOf('Apple') !== -1) {
|
||||
editor.execCommand('maximize');
|
||||
editor.execCommand('maximize');
|
||||
}
|
||||
$iframe.find('iframe.cke_wysiwyg_frame').css('width', '');
|
||||
$iframe.find('iframe.cke_wysiwyg_frame').css('height', '');
|
||||
}
|
||||
// editor.execCommand('maximize') removes all the classes from the body tag
|
||||
$iframe.find('body').addClass('app-pad');
|
||||
|
||||
if (module.realtime !== info.realtime) {
|
||||
|
@ -727,12 +721,11 @@ define([
|
|||
if (Ckeditor) {
|
||||
// mobile configuration
|
||||
Ckeditor.config.toolbarCanCollapse = true;
|
||||
Ckeditor.config.height = '72vh';
|
||||
if (screen.height < 800) {
|
||||
Ckeditor.config.toolbarStartupExpanded = false;
|
||||
$('meta[name=viewport]').attr('content', 'width=device-width, initial-scale=1.0, user-scalable=no');
|
||||
Ckeditor.config.toolbarStartupExpanded = false;
|
||||
$('meta[name=viewport]').attr('content', 'width=device-width, initial-scale=1.0, user-scalable=no');
|
||||
} else {
|
||||
$('meta[name=viewport]').attr('content', 'width=device-width, initial-scale=1.0, user-scalable=yes');
|
||||
$('meta[name=viewport]').attr('content', 'width=device-width, initial-scale=1.0, user-scalable=yes');
|
||||
}
|
||||
second(Ckeditor);
|
||||
} else {
|
||||
|
|
|
@ -552,11 +552,19 @@ var ready = function (info, userid, readOnly) {
|
|||
} else {
|
||||
APP.proxy.info.defaultTitle = Title.defaultTitle;
|
||||
}
|
||||
|
||||
var andThen = function () {
|
||||
if (readOnly) { return; }
|
||||
Cryptpad.setPadAttribute('userid', userid, function (e) {
|
||||
if (e) { console.error(e); }
|
||||
});
|
||||
};
|
||||
|
||||
if (Cryptpad.initialName && !APP.proxy.info.title) {
|
||||
APP.proxy.info.title = Cryptpad.initialName;
|
||||
Title.updateTitle(Cryptpad.initialName);
|
||||
Title.updateTitle(Cryptpad.initialName, null, andThen);
|
||||
} else {
|
||||
Title.updateTitle(APP.proxy.info.title || Title.defaultTitle);
|
||||
Title.updateTitle(APP.proxy.info.title || Title.defaultTitle, null, andThen);
|
||||
}
|
||||
|
||||
// Description
|
||||
|
@ -621,6 +629,7 @@ var ready = function (info, userid, readOnly) {
|
|||
} else {
|
||||
publish(true);
|
||||
}
|
||||
|
||||
Cryptpad.removeLoadingScreen();
|
||||
|
||||
if (readOnly) { return; }
|
||||
|
@ -760,10 +769,7 @@ var create = function (info) {
|
|||
if (e) { console.error(e); }
|
||||
if (!userid) { userid = Render.coluid(); }
|
||||
APP.userid = userid;
|
||||
Cryptpad.setPadAttribute('userid', userid, function (e) {
|
||||
if (e) { console.error(e); }
|
||||
ready(info, userid, readOnly);
|
||||
});
|
||||
ready(info, userid, readOnly);
|
||||
});
|
||||
})
|
||||
.on('disconnect', disconnect)
|
||||
|
|
|
@ -1,422 +0,0 @@
|
|||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
#content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
#content #poll {
|
||||
flex: 1;
|
||||
}
|
||||
.cryptpad-toolbar h2 {
|
||||
font: normal normal normal 12px Arial, Helvetica, Tahoma, Verdana, Sans-Serif;
|
||||
color: #000;
|
||||
line-height: auto;
|
||||
}
|
||||
.cryptpad-toolbar {
|
||||
display: inline-block;
|
||||
}
|
||||
.realtime {
|
||||
display: block;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.realtime input[type="text"] {
|
||||
height: 1em;
|
||||
margin: 0px;
|
||||
}
|
||||
.text-cell input[type="text"] {
|
||||
width: 400px;
|
||||
}
|
||||
input[type="text"][disabled],
|
||||
textarea[disabled] {
|
||||
background-color: transparent;
|
||||
font: white;
|
||||
border: 0px;
|
||||
}
|
||||
input[type="text"]::placeholder {
|
||||
color: #666;
|
||||
}
|
||||
table#table {
|
||||
margin: 0px;
|
||||
}
|
||||
#tableContainer {
|
||||
position: relative;
|
||||
padding: 29px;
|
||||
padding-right: 79px;
|
||||
}
|
||||
#tableContainer button {
|
||||
height: 2rem;
|
||||
display: none;
|
||||
}
|
||||
#publish {
|
||||
display: none;
|
||||
}
|
||||
#publish,
|
||||
#admin {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
#create-user {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
/*left: 0px;*/
|
||||
top: 55px;
|
||||
width: 50px;
|
||||
overflow: hidden;
|
||||
}
|
||||
#create-option {
|
||||
width: 50px;
|
||||
}
|
||||
#tableScroll {
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
margin-left: calc(30% - 50px + 31px);
|
||||
max-width: 70%;
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
}
|
||||
#description {
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
min-width: 80%;
|
||||
width: 80%;
|
||||
min-height: 5em;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
#description[disabled] {
|
||||
resize: none;
|
||||
color: #000;
|
||||
border: 1px solid #444;
|
||||
}
|
||||
#commit {
|
||||
width: 100%;
|
||||
}
|
||||
#howItWorks {
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
}
|
||||
div.upper {
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
margin: 20px;
|
||||
}
|
||||
tbody {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
tbody * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
tbody tr {
|
||||
text-align: center;
|
||||
}
|
||||
tbody tr:first-of-type th {
|
||||
font-size: 20px;
|
||||
border-top: 0px;
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
tbody tr:first-of-type th.table-refresh {
|
||||
color: #46E981;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
tbody tr:nth-child(odd) {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
tbody tr th:first-of-type {
|
||||
border-left: 0px;
|
||||
}
|
||||
tbody tr th {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #555;
|
||||
}
|
||||
tbody tr th,
|
||||
tbody tr td {
|
||||
color: #555;
|
||||
}
|
||||
tbody tr th.remove,
|
||||
tbody tr td.remove {
|
||||
cursor: pointer;
|
||||
}
|
||||
tbody tr th:last-child {
|
||||
border-right: 0px;
|
||||
}
|
||||
tbody td {
|
||||
border-right: 1px solid #555;
|
||||
padding: 12px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
tbody td:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
form.realtime,
|
||||
div.realtime {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
form.realtime > textarea,
|
||||
div.realtime > textarea {
|
||||
width: 50%;
|
||||
height: 15vh;
|
||||
}
|
||||
form.realtime table,
|
||||
div.realtime table {
|
||||
border-collapse: collapse;
|
||||
width: calc(100% - 1px);
|
||||
}
|
||||
form.realtime table .editing,
|
||||
div.realtime table .editing {
|
||||
background-color: #88b8cc;
|
||||
}
|
||||
form.realtime table tr td:first-child,
|
||||
div.realtime table tr td:first-child {
|
||||
position: absolute;
|
||||
left: 29px;
|
||||
top: auto;
|
||||
width: calc(30% - 50px);
|
||||
}
|
||||
form.realtime table tr td,
|
||||
div.realtime table tr td {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
form.realtime table tr td div.text-cell,
|
||||
div.realtime table tr td div.text-cell {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
form.realtime table tr td div.text-cell input,
|
||||
div.realtime table tr td div.text-cell input {
|
||||
width: 80%;
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
border: 0px;
|
||||
}
|
||||
form.realtime table tr td div.text-cell input[disabled],
|
||||
div.realtime table tr td div.text-cell input[disabled] {
|
||||
background-color: transparent;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell,
|
||||
div.realtime table tr td.checkbox-cell {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
height: 100%;
|
||||
min-width: 150px;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain label,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain label {
|
||||
background-color: transparent;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable),
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) {
|
||||
display: none;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
display: block;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover:after,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover:after {
|
||||
height: 100%;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover.yes,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover.yes {
|
||||
background-color: #46E981;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover.uncommitted,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover.uncommitted {
|
||||
background: #ddd;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover.mine,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"]:not(.editable) ~ .cover.mine {
|
||||
display: none;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="0"] ~ .cover,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="0"] ~ .cover {
|
||||
background-color: #FA5858;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="0"] ~ .cover:after,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="0"] ~ .cover:after {
|
||||
content: "✖";
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="1"] ~ .cover,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="1"] ~ .cover {
|
||||
background-color: #46E981;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="1"] ~ .cover:after,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="1"] ~ .cover:after {
|
||||
content: "✔";
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="2"] ~ .cover,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="2"] ~ .cover {
|
||||
background-color: #ff5;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="2"] ~ .cover:after,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="2"] ~ .cover:after {
|
||||
content: "~";
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="3"] ~ .cover,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="3"] ~ .cover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="3"] ~ .cover:after,
|
||||
div.realtime table tr td.checkbox-cell div.checkbox-contain input[type="number"][value="3"] ~ .cover:after {
|
||||
content: "?";
|
||||
}
|
||||
form.realtime table input[type="text"],
|
||||
div.realtime table input[type="text"] {
|
||||
height: auto;
|
||||
border: 1px solid #fff;
|
||||
width: 80%;
|
||||
}
|
||||
form.realtime table span,
|
||||
div.realtime table span {
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
form.realtime table thead td,
|
||||
div.realtime table thead td {
|
||||
padding: 0px 5px;
|
||||
background: #aaa;
|
||||
border-radius: 20px 20px 0 0;
|
||||
}
|
||||
form.realtime table thead td:nth-of-type(2),
|
||||
div.realtime table thead td:nth-of-type(2) {
|
||||
background: #999;
|
||||
}
|
||||
form.realtime table thead td:nth-of-type(2) .lock,
|
||||
div.realtime table thead td:nth-of-type(2) .lock {
|
||||
cursor: default;
|
||||
}
|
||||
form.realtime table thead td input[type="text"],
|
||||
div.realtime table thead td input[type="text"] {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
form.realtime table thead td input[type="text"][disabled],
|
||||
div.realtime table thead td input[type="text"][disabled] {
|
||||
color: #000;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
form.realtime table tbody td:not(.editing) .text-cell,
|
||||
div.realtime table tbody td:not(.editing) .text-cell {
|
||||
background: #aaa;
|
||||
}
|
||||
form.realtime table tbody .text-cell input[type="text"],
|
||||
div.realtime table tbody .text-cell input[type="text"] {
|
||||
width: calc(100% - 50px);
|
||||
}
|
||||
form.realtime table tbody .text-cell .edit,
|
||||
div.realtime table tbody .text-cell .edit {
|
||||
float: right;
|
||||
margin: 0 10px 0 0;
|
||||
}
|
||||
form.realtime table tbody .text-cell .remove,
|
||||
div.realtime table tbody .text-cell .remove {
|
||||
float: left;
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
form.realtime table tbody tr:not(:first-child) td:not(:first-child) label,
|
||||
div.realtime table tbody tr:not(:first-child) td:not(:first-child) label {
|
||||
border-top: 1px solid #555;
|
||||
}
|
||||
form.realtime table .edit,
|
||||
div.realtime table .edit {
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
}
|
||||
form.realtime table .lock,
|
||||
div.realtime table .lock {
|
||||
margin-left: calc(50% - 0.5em);
|
||||
cursor: pointer;
|
||||
width: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
form.realtime table .remove,
|
||||
div.realtime table .remove {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
form.realtime table thead tr th input[type="text"][disabled],
|
||||
div.realtime table thead tr th input[type="text"][disabled] {
|
||||
background-color: transparent;
|
||||
color: #555;
|
||||
font-weight: bold;
|
||||
}
|
||||
form.realtime table thead tr th .remove,
|
||||
div.realtime table thead tr th .remove {
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
}
|
||||
form.realtime table tfoot tr,
|
||||
div.realtime table tfoot tr {
|
||||
border: none;
|
||||
}
|
||||
form.realtime table tfoot tr td,
|
||||
div.realtime table tfoot tr td {
|
||||
border: none;
|
||||
text-align: center;
|
||||
}
|
||||
form.realtime table tfoot tr td .save,
|
||||
div.realtime table tfoot tr td .save {
|
||||
padding: 15px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
form.realtime #adduser,
|
||||
div.realtime #adduser,
|
||||
form.realtime #addoption,
|
||||
div.realtime #addoption {
|
||||
color: #46E981;
|
||||
border: 1px solid #46E981;
|
||||
padding: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
form.realtime #adduser,
|
||||
div.realtime #adduser {
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
form.realtime #addoption,
|
||||
div.realtime #addoption {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
|
@ -22,6 +22,7 @@ html, body {
|
|||
body {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
#content {
|
||||
display: flex;
|
||||
|
|
|
@ -11,7 +11,6 @@ define([
|
|||
'/bower_components/marked/marked.min.js',
|
||||
'cm/lib/codemirror',
|
||||
'cm/mode/markdown/markdown',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||
'less!/profile/main.less',
|
||||
], function ($, Cryptpad, Listmap, Crypto, Marked, CodeMirror) {
|
||||
|
||||
|
@ -105,7 +104,7 @@ define([
|
|||
if (err) { return void console.error(err); }
|
||||
Cryptpad.whenRealtimeSyncs(realtime, function () {
|
||||
lastVal = newVal;
|
||||
Cryptpad.log('TODO: '+name+' saved');
|
||||
Cryptpad.log(Messages._getKey('profile_fieldSaved', [newVal]));
|
||||
editing = false;
|
||||
});
|
||||
});
|
||||
|
@ -156,11 +155,11 @@ define([
|
|||
var getValue = function (cb) {
|
||||
cb(APP.lm.proxy.name);
|
||||
};
|
||||
var placeholder = Messages.anonymous;
|
||||
var placeholder = Messages.profile_namePlaceholder;
|
||||
if (APP.readOnly) {
|
||||
var $span = $('<span>', {'class': DISPLAYNAME_ID}).appendTo($block);
|
||||
getValue(function (value) {
|
||||
$span.text(value || placeholder);
|
||||
$span.text(value || Messages.anonymous);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -196,7 +195,7 @@ define([
|
|||
cb();
|
||||
};
|
||||
var rt = APP.lm.realtime;
|
||||
var placeholder = "URL"; //XXX
|
||||
var placeholder = Messages.profile_urlPlaceholder;
|
||||
createEditableInput($block, LINK_ID, placeholder, getValue, setValue, rt);
|
||||
};
|
||||
|
||||
|
@ -209,7 +208,7 @@ define([
|
|||
if (!APP.lm.proxy.avatar) {
|
||||
$('<img>', {
|
||||
src: '/customize/images/avatar.png',
|
||||
title: 'Avatar', // XXX
|
||||
title: Messages.profile_avatar,
|
||||
alt: 'Avatar'
|
||||
}).appendTo($span);
|
||||
return;
|
||||
|
@ -218,21 +217,20 @@ define([
|
|||
|
||||
if (APP.readOnly) { return; }
|
||||
|
||||
var $delButton = $('<button>', {'class': 'delete btn btn-danger fa fa-times'}); //XXX
|
||||
var $delButton = $('<button>', {
|
||||
'class': 'delete btn btn-danger fa fa-times',
|
||||
title: Messages.fc_delete
|
||||
});
|
||||
$span.append($delButton);
|
||||
$delButton.click(function () {
|
||||
console.log('clicked');
|
||||
var oldChanId = Cryptpad.hrefToHexChannelId(APP.lm.proxy.avatar);
|
||||
Cryptpad.unpinPads([oldChanId], function (e) {
|
||||
if (e) { Cryptpad.log(e); }
|
||||
console.log('unpinned');
|
||||
delete APP.lm.proxy.avatar;
|
||||
delete Cryptpad.getProxy().profile.avatar;
|
||||
Cryptpad.whenRealtimeSyncs(APP.lm.realtime, function () {
|
||||
console.log('synced1');
|
||||
var driveRt = Cryptpad.getStore().getProxy().info.realtime;
|
||||
Cryptpad.whenRealtimeSyncs(driveRt, function () {
|
||||
console.log('synced2');
|
||||
displayAvatar();
|
||||
});
|
||||
});
|
||||
|
@ -285,7 +283,7 @@ define([
|
|||
accept: ".gif,.jpg,.jpeg,.png"
|
||||
};
|
||||
var $upButton = Cryptpad.createButton('upload', false, data);
|
||||
$upButton.text(" Upload a new avatar");
|
||||
$upButton.text(Messages.profile_upload);
|
||||
$upButton.prepend($('<span>', {'class': 'fa fa-upload'}));
|
||||
$block.append($upButton);
|
||||
};
|
||||
|
@ -300,6 +298,7 @@ define([
|
|||
$div.html(val);
|
||||
return;
|
||||
}
|
||||
$('<h3>').text(Messages.profile_description).insertBefore($block);
|
||||
|
||||
var $ok = $('<span>', {'class': 'ok fa fa-check', title: Messages.saved}).appendTo($block);
|
||||
var $spinner = $('<span>', {'class': 'spin fa fa-spinner fa-pulse'}).appendTo($block);
|
||||
|
@ -388,17 +387,16 @@ define([
|
|||
if (e === 'E_OVER_LIMIT') {
|
||||
Cryptpad.alert(Messages.pinLimitNotPinned, null, true);
|
||||
}
|
||||
return void Cryptpad.log('Error while creating your profile: ' + e); // XXX
|
||||
return void Cryptpad.log(Messages._getKey('profile_error', [e]));
|
||||
}
|
||||
obj.profile.edit = Cryptpad.getEditHashFromKeys(channel, secret.keys);
|
||||
obj.profile.view = Cryptpad.getViewHashFromKeys(channel, secret.keys);
|
||||
obj.profile.name = APP.rt.proxy[Cryptpad.displayNameKey] || '';
|
||||
andThen(obj.profile.edit);
|
||||
});
|
||||
};
|
||||
|
||||
if (!Cryptpad.isLoggedIn()) { // XXX
|
||||
var $p = $('<p>').text('TODO: You have to register to create a profile');
|
||||
if (!Cryptpad.isLoggedIn()) {
|
||||
var $p = $('<p>', {id: CREATE_ID}).append(Messages.profile_register);
|
||||
var $a = $('<a>', {
|
||||
href: '/register/'
|
||||
});
|
||||
|
@ -411,7 +409,7 @@ define([
|
|||
}
|
||||
var $create = $('<div>', {id: CREATE_ID});
|
||||
var $button = $('<button>', {'class': 'btn btn-success'});
|
||||
$button.text('TODO: create a profile?').click(todo).appendTo($create); // XXX
|
||||
$button.text(Messages.profile_create).click(todo).appendTo($create);
|
||||
APP.$container.append($create);
|
||||
};
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
width: 1000px;
|
||||
max-width: 90%;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
#container {
|
||||
font-size: 25px;
|
||||
width: 100%;
|
||||
|
@ -129,4 +127,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
#createProfile {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ define([
|
|||
return void Cryptpad.alert(Messages.register_mustAcceptTerms);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
Cryptpad.confirm("<h2 class='bright'>" + Messages.register_warning + "</h2>",
|
||||
function (yes) {
|
||||
if (!yes) { return; }
|
||||
|
@ -200,6 +201,24 @@ define([
|
|||
}, true, function ($dialog) {
|
||||
$dialog.find('> div').addClass('half');
|
||||
});
|
||||
}, 150);
|
||||
});
|
||||
|
||||
var clickRegister = Cryptpad.notAgainForAnother(function () {
|
||||
$register.click();
|
||||
}, 500);
|
||||
|
||||
$register.on('keypress', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
console.error(e.which);
|
||||
switch (e.which) {
|
||||
case 13: return clickRegister();
|
||||
case 13: return clickRegister();
|
||||
default:
|
||||
//console.log(e.which);
|
||||
}
|
||||
});
|
||||
|
||||
Test(function () {
|
||||
|
|
|
@ -6,34 +6,6 @@
|
|||
|
||||
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<script src="/bower_components/codemirror/lib/codemirror.js"></script>
|
||||
<link rel="stylesheet" href="/bower_components/codemirror/lib/codemirror.css">
|
||||
<link rel="stylesheet" href="/bower_components/codemirror/addon/dialog/dialog.css">
|
||||
<link rel="stylesheet" href="/bower_components/codemirror/addon/fold/foldgutter.css" />
|
||||
<script src="/bower_components/codemirror/mode/javascript/javascript.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/mode/loadmode.js"></script>
|
||||
<script src="/bower_components/codemirror/mode/meta.js"></script>
|
||||
|
||||
<script src="/bower_components/codemirror/addon/mode/overlay.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/mode/multiplex.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/mode/simple.js"></script>
|
||||
|
||||
<script src="/bower_components/codemirror/addon/edit/closebrackets.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/edit/matchbrackets.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/edit/trailingspace.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/selection/active-line.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/search/search.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/search/match-highlighter.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/search/searchcursor.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/dialog/dialog.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/foldcode.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/foldgutter.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/brace-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/xml-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/markdown-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/comment-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/display/placeholder.js"></script>
|
||||
|
||||
<script async data-bootload="inner.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.1.15"></script>
|
||||
<style>.loading-hidden { display: none; } </style>
|
||||
</head>
|
||||
|
|
|
@ -1,8 +1,41 @@
|
|||
define([
|
||||
'jquery',
|
||||
|
||||
'cm/lib/codemirror',
|
||||
|
||||
|
||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||
'less!/customize/src/less/toolbar.less',
|
||||
'less!/customize/src/less/cryptpad.less',
|
||||
'less!/slide/slide.less',
|
||||
], function ($) {
|
||||
|
||||
'css!cm/lib/codemirror.css',
|
||||
'css!cm/addon/dialog/dialog.css',
|
||||
'css!cm/addon/fold/foldgutter.css',
|
||||
|
||||
'cm/mode/markdown/markdown',
|
||||
'cm/addon/mode/loadmode',
|
||||
'cm/mode/meta',
|
||||
'cm/addon/mode/overlay',
|
||||
'cm/addon/mode/multiplex',
|
||||
'cm/addon/mode/simple',
|
||||
'cm/addon/edit/closebrackets',
|
||||
'cm/addon/edit/matchbrackets',
|
||||
'cm/addon/edit/trailingspace',
|
||||
'cm/addon/selection/active-line',
|
||||
'cm/addon/search/search',
|
||||
'cm/addon/search/match-highlighter',
|
||||
'cm/addon/search/searchcursor',
|
||||
'cm/addon/dialog/dialog',
|
||||
'cm/addon/fold/foldcode',
|
||||
'cm/addon/fold/foldgutter',
|
||||
'cm/addon/fold/brace-fold',
|
||||
'cm/addon/fold/xml-fold',
|
||||
'cm/addon/fold/markdown-fold',
|
||||
'cm/addon/fold/comment-fold',
|
||||
'cm/addon/display/placeholder',
|
||||
|
||||
], function ($, CMeditor) {
|
||||
window.CodeMirror = CMeditor;
|
||||
$('.loading-hidden').removeClass('loading-hidden');
|
||||
});
|
||||
|
|
|
@ -9,7 +9,6 @@ define([
|
|||
'/common/cryptpad-common.js',
|
||||
'/common/cryptget.js',
|
||||
'/slide/slide.js',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js', // needed for media-tag
|
||||
|
||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
'less!/customize/src/less/cryptpad.less',
|
||||
|
@ -53,7 +52,7 @@ define([
|
|||
var andThen = function (CMeditor) {
|
||||
var $iframe = $('#pad-iframe').contents();
|
||||
var $contentContainer = $iframe.find('#editorContainer');
|
||||
var CodeMirror = Cryptpad.createCodemirror(CMeditor, ifrw, Cryptpad);
|
||||
var CodeMirror = Cryptpad.createCodemirror(ifrw, Cryptpad, null, CMeditor);
|
||||
editor = CodeMirror.editor;
|
||||
|
||||
var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox');
|
||||
|
@ -468,7 +467,10 @@ define([
|
|||
Cryptpad.feedback('PRINT_SLIDES');
|
||||
//$('body').append(createPrintDialog());
|
||||
}).append($('<span>', {'class': 'drawer'}).text(Messages.printText));
|
||||
$drawer.append($printButton);
|
||||
|
||||
// TODO reenable this when it is working again
|
||||
$printButton = $printButton;
|
||||
//$drawer.append($printButton);
|
||||
|
||||
var $slideOptions = $('<button>', {
|
||||
title: Messages.slideOptionsTitle,
|
||||
|
@ -590,7 +592,7 @@ define([
|
|||
|
||||
Cryptpad.getPadAttribute('previewMode', function (e, data) {
|
||||
if (e) { return void console.error(e); }
|
||||
if (data === true && APP.$previewButton) {
|
||||
if ([true, undefined].indexOf(data) !== -1 && APP.$previewButton) {
|
||||
APP.$previewButton.click();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -19,6 +19,7 @@ html, body{
|
|||
position: relative;
|
||||
}
|
||||
body {
|
||||
font-size: unset;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
@ -238,6 +239,9 @@ div.modal, div#modal {
|
|||
transition: margin-left 1s;
|
||||
}
|
||||
}
|
||||
media-tag button {
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
|
||||
box-sizing: border-box;
|
||||
|
@ -321,8 +325,6 @@ div#modal #content, #print {
|
|||
img {
|
||||
position: relative;
|
||||
min-width: 1%;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
margin: auto;
|
||||
}
|
||||
.slideNumber {
|
||||
|
|