Merge branch 'staging' into ooPassword
This commit is contained in:
commit
3528516ab9
36
CHANGELOG.md
36
CHANGELOG.md
@ -1,3 +1,39 @@
|
|||||||
|
# GoldenFrog release (3.6.0)
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
We're following up our last few releases of major core developments with an effort to improve reliability in some unstable areas and make some superficial tweaks to improve usability of some critical interfaces.
|
||||||
|
|
||||||
|
## Update notes
|
||||||
|
|
||||||
|
Update to 3.6.0 from 3.5.0 using the normal update procedure:
|
||||||
|
|
||||||
|
1. stop your server
|
||||||
|
2. pull the latest code via git
|
||||||
|
3. run `bower update`
|
||||||
|
4. restart your server
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* We've introduced a word-count feature in our rich text editor.
|
||||||
|
* The "share modal" which is accessible from both the "right-click menu" in the drive and the sharing button in the toolbar has been redesigned:
|
||||||
|
* different means of sharing access to documents have been split into different tabs to present users with less information to process
|
||||||
|
* each sharing method has an associated icon to make their actions easier to recognize at a glance
|
||||||
|
* various UI elements have been restyled to make their purpose and importance more obvious
|
||||||
|
* cancel buttons have a grey border to draw less attention
|
||||||
|
* OK buttons have a blue or grey background depending on whether they are active
|
||||||
|
* secondary buttons like "preview" have only a thin blue border so that they don't draw attention away from the primary button
|
||||||
|
* read-only text fields have a subtler appearance since they are shown primarily for the purpose of previewing your action
|
||||||
|
* text input fields (such as search) have a light background to suggest that you can use them
|
||||||
|
* We've made a minor adjustment to some of our styles for small screen to detect when a screen is very short in addition to when it is very narrow. As a result it should be somewhat easier to use on-screen keyboards.
|
||||||
|
|
||||||
|
## Bug fixes
|
||||||
|
|
||||||
|
* We found and fixed a subtle race condition which caused teams' quotas to be calculated incorrectly in certain circumstances.
|
||||||
|
* A minor bug in our login process caused users with premium accounts to incorrectly see an entry in their user menu as linking to our 'pricing' page instead of their 'subscription' management tools. This has since been fixed.
|
||||||
|
* We noticed that some of the rendered messages in the history mode of the notifications panel could fail to display text for some message types. These incorrect messages will be hidden from view wherever it is impossible to decide what should be displayed. We plan to address the issue in a deeper way in the near future.
|
||||||
|
* We've become aware of some odd behaviour in long-lived sessions where tabs seem to lose their connection to the sharedWorker which is common to all tabs open in a particular browser session. As far as we can tell the bug only affects Firefox browser. Unfortunately, debugging sharedWorkers in Firefox has been broken for a number of major versions, so we haven't been able to determine the cause of the issue. Until we're able to determine the underlying cause we've added extra checks to detect when particular features become isolated from the worker, where previously we assumed that if the worker was connected to the server then everything was behaving correctly. We recommend that you reload the tab if you notice that aspects of your shared folders or drives (for users or teams) display a read-only warning while your other tabs are behaving normally.
|
||||||
|
|
||||||
# FalklandWolf release (3.5.0)
|
# FalklandWolf release (3.5.0)
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
"tests"
|
"tests"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jquery": "~2.1.3",
|
"jquery": "2.2.4",
|
||||||
"tweetnacl": "0.12.2",
|
"tweetnacl": "0.12.2",
|
||||||
"components-font-awesome": "^4.6.3",
|
"components-font-awesome": "^4.6.3",
|
||||||
"ckeditor": "4.7.3",
|
"ckeditor": "4.7.3",
|
||||||
@ -51,6 +51,7 @@
|
|||||||
"requirejs-plugins": "^1.0.3"
|
"requirejs-plugins": "^1.0.3"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"bootstrap": "^v4.0.0"
|
"bootstrap": "^v4.0.0",
|
||||||
|
"jquery": "2.2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -159,6 +159,9 @@
|
|||||||
margin-bottom: @alertify_padding-base;
|
margin-bottom: @alertify_padding-base;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.alertify-tabs {
|
.alertify-tabs {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
@ -222,14 +225,22 @@
|
|||||||
background-color: @alertify-input-fg;
|
background-color: @alertify-input-fg;
|
||||||
color: @cryptpad_text_col;
|
color: @cryptpad_text_col;
|
||||||
border: 1px solid @alertify-input-bg;
|
border: 1px solid @alertify-input-bg;
|
||||||
margin-bottom: 15px;
|
margin-bottom: @alertify_padding-base;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
padding: @alertify_padding-base;
|
padding: @alertify_padding-base;
|
||||||
&[readonly] {
|
&[readonly] {
|
||||||
background-color: @alertify-light-bg;
|
background-color: @alertify-light-bg;
|
||||||
color: @cryptpad_text_col;
|
color: @cryptpad_text_col;
|
||||||
border-color: @alertify-input-fg;
|
border-color: @alertify-light-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 8px;
|
||||||
|
&[readonly] {
|
||||||
|
resize: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,5 +520,33 @@
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Bootstrap Alerts
|
||||||
|
.alert {
|
||||||
|
margin: 0px 0px @alertify_padding-base 0px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 0px;
|
||||||
|
i {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
&.alert-primary {
|
||||||
|
background-color: @alertify-base;
|
||||||
|
color: @alertify-fg;
|
||||||
|
border-color: @alertify-fg;
|
||||||
|
a {
|
||||||
|
color: @alertify-fg;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.dismissable {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
span.fa-times {
|
||||||
|
font-size: @colortheme_app-font-size;
|
||||||
|
margin-left: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
@import (reference) "./tools.less";
|
@import (reference) "./tools.less";
|
||||||
|
@import (reference) "./colortheme-all.less";
|
||||||
.avatar_vars(
|
.avatar_vars(
|
||||||
@width: 30px
|
@width: 30px
|
||||||
) {
|
) {
|
||||||
@avatar-width: @width;
|
@avatar-width: @width;
|
||||||
@avatar-font-size: @width / 1.2;
|
@avatar-font-size: @width / 1.2;
|
||||||
|
@avatar-default-bg: #D9D8D8;
|
||||||
|
@avatar-default-fg: darken(@avatar-default-bg, 40%);
|
||||||
}
|
}
|
||||||
.avatar_main(@width: 30px) {
|
.avatar_main(@width: 30px) {
|
||||||
--LessLoader_require: LessLoader_currentFile();
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
@ -30,16 +33,16 @@
|
|||||||
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
}
|
}
|
||||||
.cp-avatar-default {
|
.cp-avatar-default {
|
||||||
.tools_unselectable();
|
.tools_unselectable();
|
||||||
background: white;
|
background: @avatar-default-bg;
|
||||||
color: black;
|
color: @avatar-default-fg;
|
||||||
font-size: @avatar-font-size;
|
font-size: @avatar-font-size;
|
||||||
font-size: var(--avatar-font-size);
|
font-size: var(--avatar-font-size);
|
||||||
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
media-tag {
|
media-tag {
|
||||||
min-height: @avatar-width;
|
min-height: @avatar-width;
|
||||||
|
|||||||
@ -1,12 +1,16 @@
|
|||||||
@import (reference) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
|
@import (reference) "./variables.less";
|
||||||
.modals-ui-elements_main() {
|
.modals-ui-elements_main() {
|
||||||
--LessLoader_require: LessLoader_currentFile();
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
}
|
}
|
||||||
& {
|
& {
|
||||||
|
.cp-spacer {
|
||||||
|
height: @variables_padding;
|
||||||
|
}
|
||||||
// Share modal
|
// Share modal
|
||||||
.msg.cp-inline-radio-group {
|
.msg.cp-inline-radio-group {
|
||||||
overflow: unset !important;
|
overflow: unset !important;
|
||||||
|
padding: 0px @variables_padding;
|
||||||
.radio-group {
|
.radio-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
@import (reference) "./colortheme-all.less";
|
||||||
.password_main() {
|
.password_main() {
|
||||||
--LessLoader_require: LessLoader_currentFile();
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
}
|
}
|
||||||
@ -17,7 +18,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(0,0,0,0.1);
|
color: darken(@colortheme_alertify-primary, 10%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,16 +6,18 @@
|
|||||||
--LessLoader_require: LessLoader_currentFile();
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
};
|
};
|
||||||
& {
|
& {
|
||||||
|
|
||||||
.cp-usergrid-container {
|
.cp-usergrid-container {
|
||||||
|
margin-bottom: 12px !important; // even when last child of .msg
|
||||||
.cp-usergrid-grid {
|
.cp-usergrid-grid {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
&:not(.large) {
|
|
||||||
.cp-usergrid-grid {
|
|
||||||
margin: -3px;
|
margin: -3px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
max-height: 130px;
|
||||||
|
overflow-y: auto;
|
||||||
|
@media screen and (max-height: 515px) {
|
||||||
|
max-height: unset; // remove double scrollbar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.cp-usergrid-empty {
|
&.cp-usergrid-empty {
|
||||||
@ -28,17 +30,22 @@
|
|||||||
input {
|
input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
margin: 0;
|
||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
|
height: 38px;
|
||||||
&::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
|
&::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
|
||||||
color: @cryptpad_color_grey;
|
color: @cryptpad_color_grey;
|
||||||
opacity: 1; /* Firefox */
|
opacity: 1; /* Firefox */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
margin-bottom: 15px;
|
margin-bottom: 10px;
|
||||||
&:empty {
|
&:empty {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
button:last-child {
|
||||||
|
margin-right: 0px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.cp-usergrid-user {
|
.cp-usergrid-user {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
@ -58,33 +65,48 @@
|
|||||||
background-color: @colortheme_alertify-primary;
|
background-color: @colortheme_alertify-primary;
|
||||||
color: @colortheme_alertify-primary-text;
|
color: @colortheme_alertify-primary-text;
|
||||||
order: -1 !important;
|
order: -1 !important;
|
||||||
|
.cp-usergrid-avatar {
|
||||||
|
media-tag, .cp-avatar-default {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.cp-usergrid-user-avatar {
|
.cp-usergrid-user-avatar {
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cp-usergrid-user-name {
|
.cp-usergrid-user-name {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 18px;
|
line-height: 20px;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
border: 1px solid @colortheme_alertify-primary;
|
|
||||||
|
|
||||||
&:not(.large) {
|
&:not(.large) {
|
||||||
.avatar_main(40px);
|
.avatar_main(40px);
|
||||||
}
|
}
|
||||||
&.large {
|
&.large {
|
||||||
.avatar_main(25px);
|
.avatar_main(25px);
|
||||||
width: 140px;
|
width: 145px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
flex-flow: row;
|
flex-flow: row;
|
||||||
margin: 0;
|
margin: 3px;
|
||||||
margin-right: 15px;
|
flex-basis: calc(33.3333333% - 6px);
|
||||||
margin-bottom: 1px;
|
flex-shrink: 1;
|
||||||
&:nth-child(3n) {
|
min-width: 0;
|
||||||
margin-right: 0;
|
.cp-usergrid-user-name {
|
||||||
|
margin-left: 5px;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 150%;
|
||||||
|
color: @cryptpad_text_col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.cp-selected {
|
||||||
|
.cp-usergrid-user-name {
|
||||||
|
color: @colortheme_alertify-primary-text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
customize.dist/translations/messages.fi.js
Normal file
14
customize.dist/translations/messages.fi.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* You can override the translation text using this file.
|
||||||
|
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
|
||||||
|
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
|
||||||
|
* If you want to check all the existing translation keys, you can open the internal language file
|
||||||
|
but you should not change it directly (/common/translations/messages.{LANG}.js)
|
||||||
|
*/
|
||||||
|
define(['/common/translations/messages.fi.js'], function (Messages) {
|
||||||
|
// Replace the existing keys in your copied file here:
|
||||||
|
// Messages.button_newpad = "New Rich Text Document";
|
||||||
|
|
||||||
|
return Messages;
|
||||||
|
});
|
||||||
|
|
||||||
@ -8,6 +8,8 @@ If the result of IO or computation is requested while an identical request
|
|||||||
is already in progress, wait until the first one completes and provide its
|
is already in progress, wait until the first one completes and provide its
|
||||||
result to every routine that requested it.
|
result to every routine that requested it.
|
||||||
|
|
||||||
|
Asynchrony is guaranteed.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Provide:
|
Provide:
|
||||||
@ -51,11 +53,12 @@ module.exports = function (/* task */) {
|
|||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
|
||||||
//if (map[id] && map[id].length > 1) { console.log("BATCH-READ DID ITS JOB for [%s][%s]", task, id); }
|
//if (map[id] && map[id].length > 1) { console.log("BATCH-READ DID ITS JOB for [%s][%s]", task, id); }
|
||||||
|
setTimeout(function () {
|
||||||
map[id].forEach(function (h) {
|
map[id].forEach(function (h) {
|
||||||
h.apply(null, args);
|
h.apply(null, args);
|
||||||
});
|
});
|
||||||
delete map[id];
|
delete map[id];
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,7 +4,7 @@ q(id, function (next) {
|
|||||||
// whatever you need to do....
|
// whatever you need to do....
|
||||||
|
|
||||||
// when you're done
|
// when you're done
|
||||||
next();
|
next(); // guaranteed to be asynchronous :D
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -16,9 +16,11 @@ module.exports = function () {
|
|||||||
var map = {};
|
var map = {};
|
||||||
|
|
||||||
var next = function (id) {
|
var next = function (id) {
|
||||||
|
setTimeout(function () {
|
||||||
if (map[id] && map[id].length === 0) { return void delete map[id]; }
|
if (map[id] && map[id].length === 0) { return void delete map[id]; }
|
||||||
var task = map[id].shift();
|
var task = map[id].shift();
|
||||||
task(fix1(next, id));
|
task(fix1(next, id));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return function (id, task) {
|
return function (id, task) {
|
||||||
|
|||||||
@ -7,6 +7,10 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/xwiki-labs/cryptpad.git"
|
"url": "git://github.com/xwiki-labs/cryptpad.git"
|
||||||
},
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/cryptpad"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chainpad-crypto": "^0.2.2",
|
"chainpad-crypto": "^0.2.2",
|
||||||
"chainpad-server": "^3.0.5",
|
"chainpad-server": "^3.0.5",
|
||||||
|
|||||||
46
rpc.js
46
rpc.js
@ -228,13 +228,15 @@ var truthyKeys = function (O) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var getChannelList = function (Env, publicKey, cb) {
|
var getChannelList = function (Env, publicKey, _cb) {
|
||||||
|
var cb = Util.once(Util.mkAsync(_cb));
|
||||||
loadUserPins(Env, publicKey, function (pins) {
|
loadUserPins(Env, publicKey, function (pins) {
|
||||||
cb(truthyKeys(pins));
|
cb(truthyKeys(pins));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var getFileSize = function (Env, channel, cb) {
|
var getFileSize = function (Env, channel, _cb) {
|
||||||
|
var cb = Util.once(Util.mkAsync(_cb));
|
||||||
if (!isValidId(channel)) { return void cb('INVALID_CHAN'); }
|
if (!isValidId(channel)) { return void cb('INVALID_CHAN'); }
|
||||||
if (channel.length === 32) {
|
if (channel.length === 32) {
|
||||||
if (typeof(Env.msgStore.getChannelSize) !== 'function') {
|
if (typeof(Env.msgStore.getChannelSize) !== 'function') {
|
||||||
@ -416,14 +418,41 @@ var getDeletedPads = function (Env, channels, cb) {
|
|||||||
|
|
||||||
const batchTotalSize = BatchRead("GET_TOTAL_SIZE");
|
const batchTotalSize = BatchRead("GET_TOTAL_SIZE");
|
||||||
var getTotalSize = function (Env, publicKey, cb) {
|
var getTotalSize = function (Env, publicKey, cb) {
|
||||||
batchTotalSize(publicKey, cb, function (done) {
|
var unescapedKey = unescapeKeyCharacters(publicKey);
|
||||||
var bytes = 0;
|
var limit = Env.limits[unescapedKey];
|
||||||
return void getChannelList(Env, publicKey, function (channels) {
|
|
||||||
if (!channels) { return done('INVALID_PIN_LIST'); } // unexpected
|
|
||||||
|
|
||||||
nThen(function (w) {
|
// Get a common key if multiple users share the same quota, otherwise take the public key
|
||||||
|
var batchKey = (limit && Array.isArray(limit.users)) ? limit.users.join('') : publicKey;
|
||||||
|
|
||||||
|
batchTotalSize(batchKey, cb, function (done) {
|
||||||
|
var channels = [];
|
||||||
|
var bytes = 0;
|
||||||
|
nThen(function (waitFor) {
|
||||||
|
// Get the channels list for our user account
|
||||||
|
getChannelList(Env, publicKey, waitFor(function (_channels) {
|
||||||
|
if (!_channels) {
|
||||||
|
waitFor.abort();
|
||||||
|
return done('INVALID_PIN_LIST');
|
||||||
|
}
|
||||||
|
Array.prototype.push.apply(channels, _channels);
|
||||||
|
}));
|
||||||
|
// Get the channels list for users sharing our quota
|
||||||
|
if (limit && Array.isArray(limit.users) && limit.users.length > 1) {
|
||||||
|
limit.users.forEach(function (key) {
|
||||||
|
if (key === unescapedKey) { return; } // Don't count ourselves twice
|
||||||
|
getChannelList(Env, key, waitFor(function (_channels) {
|
||||||
|
if (!_channels) { return; } // Broken user, don't count their quota
|
||||||
|
Array.prototype.push.apply(channels, _channels);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
// Get size of the channels
|
||||||
|
var list = []; // Contains the channels already counted in the quota to avoid duplicates
|
||||||
channels.forEach(function (channel) { // TODO semaphore?
|
channels.forEach(function (channel) { // TODO semaphore?
|
||||||
getFileSize(Env, channel, w(function (e, size) {
|
if (list.indexOf(channel) !== -1) { return; }
|
||||||
|
list.push(channel);
|
||||||
|
getFileSize(Env, channel, waitFor(function (e, size) {
|
||||||
if (!e) { bytes += size; }
|
if (!e) { bytes += size; }
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
@ -431,7 +460,6 @@ var getTotalSize = function (Env, publicKey, cb) {
|
|||||||
done(void 0, bytes);
|
done(void 0, bytes);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var hashChannelList = function (A) {
|
var hashChannelList = function (A) {
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
define([
|
define([
|
||||||
'jquery',
|
'jquery',
|
||||||
'/common/cryptpad-common.js',
|
'/common/cryptget.js',
|
||||||
|
'/common/pinpad.js',
|
||||||
'/common/common-constants.js',
|
'/common/common-constants.js',
|
||||||
'/common/outer/local-store.js',
|
'/common/outer/local-store.js',
|
||||||
|
'/common/outer/login-block.js',
|
||||||
|
'/common/outer/network-config.js',
|
||||||
|
'/customize/login.js',
|
||||||
'/common/test.js',
|
'/common/test.js',
|
||||||
'/bower_components/nthen/index.js',
|
'/bower_components/nthen/index.js',
|
||||||
|
'/bower_components/netflux-websocket/netflux-client.js',
|
||||||
'/bower_components/tweetnacl/nacl-fast.min.js'
|
'/bower_components/tweetnacl/nacl-fast.min.js'
|
||||||
], function ($, Cryptpad, Constants, LocalStore, Test, nThen) {
|
], function ($, Crypt, Pinpad, Constants, LocalStore, Block, NetConfig, Login, Test, nThen, Netflux) {
|
||||||
var Nacl = window.nacl;
|
var Nacl = window.nacl;
|
||||||
|
|
||||||
var signMsg = function (msg, privKey) {
|
var signMsg = function (msg, privKey) {
|
||||||
@ -27,9 +32,57 @@ define([
|
|||||||
sessionStorage[Constants.userHashKey];
|
sessionStorage[Constants.userHashKey];
|
||||||
|
|
||||||
var proxy;
|
var proxy;
|
||||||
|
var rpc;
|
||||||
|
var network;
|
||||||
|
var rpcError;
|
||||||
|
|
||||||
|
var loadProxy = function (hash) {
|
||||||
|
nThen(function (waitFor) {
|
||||||
|
var wsUrl = NetConfig.getWebsocketURL();
|
||||||
|
var w = waitFor();
|
||||||
|
Netflux.connect(wsUrl).then(function (_network) {
|
||||||
|
network = _network;
|
||||||
|
w();
|
||||||
|
}, function (err) {
|
||||||
|
rpcError = err;
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
Crypt.get(hash, waitFor(function (err, val) {
|
||||||
|
if (err) {
|
||||||
|
waitFor.abort();
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var parsed = JSON.parse(val);
|
||||||
|
proxy = parsed;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Can't parse user drive", e);
|
||||||
|
}
|
||||||
|
}), {
|
||||||
|
network: network
|
||||||
|
});
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
if (!network) { return void waitFor.abort(); }
|
||||||
|
Pinpad.create(network, proxy, waitFor(function (e, call) {
|
||||||
|
if (e) {
|
||||||
|
rpcError = e;
|
||||||
|
return void waitFor.abort();
|
||||||
|
}
|
||||||
|
rpc = call;
|
||||||
|
}));
|
||||||
|
}).nThen(function () {
|
||||||
|
Test(function () {
|
||||||
|
// This is only here to maybe trigger an error.
|
||||||
|
window.drive = proxy['drive'];
|
||||||
|
Test.passed();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var whenReady = function (cb) {
|
var whenReady = function (cb) {
|
||||||
if (proxy) { return void cb(); }
|
if (proxy && (rpc || rpcError)) { return void cb(); }
|
||||||
console.log('CryptPad not ready...');
|
console.log('CryptPad not ready...');
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
whenReady(cb);
|
whenReady(cb);
|
||||||
@ -45,6 +98,17 @@ define([
|
|||||||
console.log('CP receiving', data);
|
console.log('CP receiving', data);
|
||||||
if (data.cmd === 'PING') {
|
if (data.cmd === 'PING') {
|
||||||
ret.res = 'PONG';
|
ret.res = 'PONG';
|
||||||
|
} else if (data.cmd === 'LOGIN') {
|
||||||
|
Login.loginOrRegister(data.data.name, data.data.password, false, false, function (err) {
|
||||||
|
if (err) {
|
||||||
|
ret.error = 'LOGIN_ERROR';
|
||||||
|
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadProxy(LocalStore.getUserHash());
|
||||||
|
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||||||
|
});
|
||||||
|
return;
|
||||||
} else if (data.cmd === 'SIGN') {
|
} else if (data.cmd === 'SIGN') {
|
||||||
if (!AUTHORIZED_DOMAINS.filter(function (x) { return x.test(domain); }).length) {
|
if (!AUTHORIZED_DOMAINS.filter(function (x) { return x.test(domain); }).length) {
|
||||||
ret.error = "UNAUTH_DOMAIN";
|
ret.error = "UNAUTH_DOMAIN";
|
||||||
@ -63,7 +127,16 @@ define([
|
|||||||
}
|
}
|
||||||
} else if (data.cmd === 'UPDATE_LIMIT') {
|
} else if (data.cmd === 'UPDATE_LIMIT') {
|
||||||
return void whenReady(function () {
|
return void whenReady(function () {
|
||||||
Cryptpad.updatePinLimit(function (e, limit, plan, note) {
|
if (rpcError) {
|
||||||
|
// Tell the user on accounts that there was an issue and they need to wait maximum 24h or contact an admin
|
||||||
|
ret.warning = true;
|
||||||
|
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rpc.updatePinLimits(function (e, limit, plan, note) {
|
||||||
|
if (e) {
|
||||||
|
ret.warning = true;
|
||||||
|
}
|
||||||
ret.res = [limit, plan, note];
|
ret.res = [limit, plan, note];
|
||||||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||||||
});
|
});
|
||||||
@ -74,18 +147,8 @@ define([
|
|||||||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||||||
});
|
});
|
||||||
|
|
||||||
nThen(function (waitFor) {
|
var userHash = LocalStore.getUserHash();
|
||||||
Cryptpad.ready(waitFor());
|
if (userHash) {
|
||||||
}).nThen(function (waitFor) {
|
loadProxy(userHash);
|
||||||
Cryptpad.getUserObject(null, waitFor(function (obj) {
|
}
|
||||||
proxy = obj;
|
|
||||||
}));
|
|
||||||
}).nThen(function () {
|
|
||||||
console.log('IFRAME READY');
|
|
||||||
Test(function () {
|
|
||||||
// This is only here to maybe trigger an error.
|
|
||||||
window.drive = proxy['drive'];
|
|
||||||
Test.passed();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -131,7 +131,7 @@ define([
|
|||||||
if (['markdown', 'gfm'].indexOf(CodeMirror.highlightMode) === -1) { return; }
|
if (['markdown', 'gfm'].indexOf(CodeMirror.highlightMode) === -1) { return; }
|
||||||
if (!$previewButton.is('.cp-toolbar-button-active')) { return; }
|
if (!$previewButton.is('.cp-toolbar-button-active')) { return; }
|
||||||
forceDrawPreview();
|
forceDrawPreview();
|
||||||
}, 150);
|
}, 400);
|
||||||
|
|
||||||
var previewTo;
|
var previewTo;
|
||||||
$previewButton.click(function () {
|
$previewButton.click(function () {
|
||||||
|
|||||||
@ -121,6 +121,10 @@ text.actor {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
text-height: 14px;
|
text-height: 14px;
|
||||||
}
|
}
|
||||||
|
.sectionTitle, .titleText {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* Grid and axis */
|
/* Grid and axis */
|
||||||
.grid .tick {
|
.grid .tick {
|
||||||
stroke: lightgrey;
|
stroke: lightgrey;
|
||||||
|
|||||||
@ -6,22 +6,24 @@ define([
|
|||||||
|
|
||||||
CodeMirror.defineSimpleMode("orgmode", {
|
CodeMirror.defineSimpleMode("orgmode", {
|
||||||
start: [
|
start: [
|
||||||
{regex: /^(^\*{1,6}\s)(TODO|DOING|WAITING|NEXT){0,1}(CANCELLED|CANCEL|DEFERRED|DONE|REJECTED|STOP|STOPPED){0,1}(.*)$/, token: ["header org-level-star", "header org-todo", "header org-done", "header"]},
|
{regex: /(\*\s)(TODO|DOING|WAITING|NEXT|PENDING|)(CANCELLED|CANCELED|CANCEL|DONE|REJECTED|STOP|STOPPED|)(\s+\[\#[A-C]\]\s+|)(.*?)(?:(\s{10,}|))(\:[\S]+\:|)$/, sol: true, token: ["header level1 org-level-star","header level1 org-todo","header level1 org-done", "header level1 org-priority", "header level1", "header level1 void", "header level1 comment"]},
|
||||||
|
{regex: /(\*{1,}\s)(TODO|DOING|WAITING|NEXT|PENDING|)(CANCELLED|CANCELED|CANCEL|DEFERRED|DONE|REJECTED|STOP|STOPPED|)(\s+\[\#[A-C]\]\s+|)(.*?)(?:(\s{10,}|))(\:[\S]+\:|)$/, sol: true, token: ["header org-level-star","header org-todo","header org-done", "header org-priority", "header", "header void", "header comment"]},
|
||||||
{regex: /(\+[^\+]+\+)/, token: ["strikethrough"]},
|
{regex: /(\+[^\+]+\+)/, token: ["strikethrough"]},
|
||||||
{regex: /(\*[^\*]+\*)/, token: ["strong"]},
|
{regex: /(\*[^\*]+\*)/, token: ["strong"]},
|
||||||
{regex: /(\/[^\/]+\/)/, token: ["em"]},
|
{regex: /(\/[^\/]+\/)/, token: ["em"]},
|
||||||
{regex: /(\_[^\_]+\_)/, token: ["link"]},
|
{regex: /(\_[^\_]+\_)/, token: ["link"]},
|
||||||
{regex: /(\~[^\~]+\~)/, token: ["comment"]},
|
{regex: /(\~[^\~]+\~)/, token: ["comment"]},
|
||||||
{regex: /(\=[^\=]+\=)/, token: ["comment"]},
|
{regex: /(\=[^\=]+\=)/, token: ["comment"]},
|
||||||
{regex: /\[\[[^\[\]]*\]\[[^\[\]]*\]\]/, token: "url"}, // links
|
{regex: /\[\[[^\[\]]+\]\[[^\[\]]+\]\]/, token: "org-url"}, // links
|
||||||
{regex: /\[[xX\s]?\]/, token: 'qualifier'}, // checkbox
|
{regex: /\[\[[^\[\]]+\]\]/, token: "org-image"}, // image
|
||||||
{regex: /\#\+BEGIN_[A-Z]*/, token: "comment", next: "env"}, // comments
|
{regex: /\[[xX\s\-\_]\]/, token: 'qualifier org-toggle'}, // checkbox
|
||||||
{regex: /:?[A-Z_]+\:.*/, token: "comment"}, // property drawers
|
{regex: /\#\+(?:(BEGIN|begin))_[a-zA-Z]*/, token: "comment", next: "env", sol: true}, // comments
|
||||||
{regex: /(\#\+[A-Z_]*)(\:.*)/, token: ["keyword", 'qualifier']}, // environments
|
{regex: /:?[A-Z_]+\:.*/, token: "comment", sol: true}, // property drawers
|
||||||
{regex: /(CLOCK\:|SHEDULED\:)(\s.+)/, token: ["comment", "keyword"]}
|
{regex: /(\#\+[a-zA-Z_]*)(\:.*)/, token: ["keyword", 'qualifier'], sol: true}, // environments
|
||||||
|
{regex: /(CLOCK\:|SHEDULED\:|DEADLINE\:)(\s.+)/, token: ["comment", "keyword"]}
|
||||||
],
|
],
|
||||||
env: [
|
env: [
|
||||||
{regex: /.*?\#\+END_[A-Z]*/, token: "comment", next: "start"},
|
{regex: /\#\+(?:(END|end))_[a-zA-Z]*/, token: "comment", next: "start", sol: true},
|
||||||
{regex: /.*/, token: "comment"}
|
{regex: /.*/, token: "comment"}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
@ -127,6 +127,18 @@ define([
|
|||||||
return input;
|
return input;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dialog.selectableArea = function (value, opt) {
|
||||||
|
var attrs = merge({
|
||||||
|
readonly: 'readonly',
|
||||||
|
}, opt);
|
||||||
|
|
||||||
|
var input = h('textarea', attrs);
|
||||||
|
$(input).val(value).click(function () {
|
||||||
|
input.select();
|
||||||
|
});
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
|
||||||
dialog.okButton = function (content, classString) {
|
dialog.okButton = function (content, classString) {
|
||||||
var sel = typeof(classString) === 'string'? 'button.ok.' + classString:'button.ok.primary';
|
var sel = typeof(classString) === 'string'? 'button.ok.' + classString:'button.ok.primary';
|
||||||
return h(sel, { tabindex: '2', }, content || Messages.okButton);
|
return h(sel, { tabindex: '2', }, content || Messages.okButton);
|
||||||
@ -187,7 +199,8 @@ define([
|
|||||||
dialog.tabs = function (tabs) {
|
dialog.tabs = function (tabs) {
|
||||||
var contents = [];
|
var contents = [];
|
||||||
var titles = [];
|
var titles = [];
|
||||||
tabs.forEach(function (tab) {
|
var active = 0;
|
||||||
|
tabs.forEach(function (tab, i) {
|
||||||
if (!tab.content || !tab.title) { return; }
|
if (!tab.content || !tab.title) { return; }
|
||||||
var content = h('div.alertify-tabs-content', tab.content);
|
var content = h('div.alertify-tabs-content', tab.content);
|
||||||
var title = h('span.alertify-tabs-title', tab.title);
|
var title = h('span.alertify-tabs-title', tab.title);
|
||||||
@ -203,10 +216,11 @@ define([
|
|||||||
});
|
});
|
||||||
titles.push(title);
|
titles.push(title);
|
||||||
contents.push(content);
|
contents.push(content);
|
||||||
|
if (tab.active) { active = i; }
|
||||||
});
|
});
|
||||||
if (contents.length) {
|
if (contents.length) {
|
||||||
$(contents[0]).addClass('alertify-tabs-content-active');
|
$(contents[active]).addClass('alertify-tabs-content-active');
|
||||||
$(titles[0]).addClass('alertify-tabs-active');
|
$(titles[active]).addClass('alertify-tabs-active');
|
||||||
}
|
}
|
||||||
return h('div.alertify-tabs', [
|
return h('div.alertify-tabs', [
|
||||||
h('div.alertify-tabs-titles', titles),
|
h('div.alertify-tabs-titles', titles),
|
||||||
|
|||||||
@ -147,6 +147,7 @@ define([
|
|||||||
: Messages.owner_removeText;
|
: Messages.owner_removeText;
|
||||||
var removeCol = UIElements.getUserGrid(msg, {
|
var removeCol = UIElements.getUserGrid(msg, {
|
||||||
common: common,
|
common: common,
|
||||||
|
large: true,
|
||||||
data: _owners,
|
data: _owners,
|
||||||
noFilter: true
|
noFilter: true
|
||||||
}, function () {
|
}, function () {
|
||||||
@ -238,6 +239,7 @@ define([
|
|||||||
});
|
});
|
||||||
var addCol = UIElements.getUserGrid(Messages.owner_addText, {
|
var addCol = UIElements.getUserGrid(Messages.owner_addText, {
|
||||||
common: common,
|
common: common,
|
||||||
|
large: true,
|
||||||
data: _friends
|
data: _friends
|
||||||
}, function () {
|
}, function () {
|
||||||
//console.log(arguments);
|
//console.log(arguments);
|
||||||
@ -254,6 +256,7 @@ define([
|
|||||||
});
|
});
|
||||||
var teamsList = UIElements.getUserGrid(Messages.owner_addTeamText, {
|
var teamsList = UIElements.getUserGrid(Messages.owner_addTeamText, {
|
||||||
common: common,
|
common: common,
|
||||||
|
large: true,
|
||||||
noFilter: true,
|
noFilter: true,
|
||||||
data: teamsData
|
data: teamsData
|
||||||
}, function () {});
|
}, function () {});
|
||||||
@ -739,12 +742,22 @@ define([
|
|||||||
UIElements.getProperties = function (common, data, cb) {
|
UIElements.getProperties = function (common, data, cb) {
|
||||||
var c1;
|
var c1;
|
||||||
var c2;
|
var c2;
|
||||||
|
var button = [{
|
||||||
|
className: 'primary',
|
||||||
|
name: Messages.okButton,
|
||||||
|
onClick: function () {},
|
||||||
|
keys: [13]
|
||||||
|
}];
|
||||||
NThen(function (waitFor) {
|
NThen(function (waitFor) {
|
||||||
getPadProperties(common, data, waitFor(function (e, c) {
|
getPadProperties(common, data, waitFor(function (e, c) {
|
||||||
c1 = c[0];
|
c1 = UI.dialog.customModal(c[0], {
|
||||||
|
buttons: button
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
getRightsProperties(common, data, waitFor(function (e, c) {
|
getRightsProperties(common, data, waitFor(function (e, c) {
|
||||||
c2 = c[0];
|
c2 = UI.dialog.customModal(c[0], {
|
||||||
|
buttons: button
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
}).nThen(function () {
|
}).nThen(function () {
|
||||||
var tabs = UI.dialog.tabs([{
|
var tabs = UI.dialog.tabs([{
|
||||||
@ -784,8 +797,6 @@ define([
|
|||||||
|
|
||||||
var noOthers = icons.length === 0 ? '.cp-usergrid-empty' : '';
|
var noOthers = icons.length === 0 ? '.cp-usergrid-empty' : '';
|
||||||
|
|
||||||
var buttonSelect = h('button', Messages.share_selectAll);
|
|
||||||
var buttonDeselect = h('button', Messages.share_deselectAll);
|
|
||||||
var inputFilter = h('input', {
|
var inputFilter = h('input', {
|
||||||
placeholder: Messages.share_filterFriend
|
placeholder: Messages.share_filterFriend
|
||||||
});
|
});
|
||||||
@ -793,9 +804,7 @@ define([
|
|||||||
var div = h('div.cp-usergrid-container' + noOthers + (config.large?'.large':''), [
|
var div = h('div.cp-usergrid-container' + noOthers + (config.large?'.large':''), [
|
||||||
label ? h('label', label) : undefined,
|
label ? h('label', label) : undefined,
|
||||||
h('div.cp-usergrid-filter', (config.noFilter || config.noSelect) ? undefined : [
|
h('div.cp-usergrid-filter', (config.noFilter || config.noSelect) ? undefined : [
|
||||||
inputFilter,
|
inputFilter
|
||||||
buttonSelect,
|
|
||||||
buttonDeselect
|
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
var $div = $(div);
|
var $div = $(div);
|
||||||
@ -808,23 +817,8 @@ define([
|
|||||||
$div.find('.cp-usergrid-user:not(.cp-selected):not([data-name*="'+name+'"])').hide();
|
$div.find('.cp-usergrid-user:not(.cp-selected):not([data-name*="'+name+'"])').hide();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$(inputFilter).on('keydown keyup change', redraw);
|
$(inputFilter).on('keydown keyup change', redraw);
|
||||||
|
|
||||||
$(buttonSelect).click(function () {
|
|
||||||
$div.find('.cp-usergrid-user:not(.cp-selected):visible').addClass('cp-selected');
|
|
||||||
onSelect();
|
|
||||||
});
|
|
||||||
$(buttonDeselect).click(function () {
|
|
||||||
$div.find('.cp-usergrid-user.cp-selected').removeClass('cp-selected').each(function (i, el) {
|
|
||||||
var order = $(el).attr('data-order');
|
|
||||||
if (!order) { return; }
|
|
||||||
$(el).attr('style', 'order:'+order);
|
|
||||||
});
|
|
||||||
redraw();
|
|
||||||
onSelect();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(div).append(h('div.cp-usergrid-grid', icons));
|
$(div).append(h('div.cp-usergrid-grid', icons));
|
||||||
if (!config.noSelect) {
|
if (!config.noSelect) {
|
||||||
$div.on('click', '.cp-usergrid-user', function () {
|
$div.on('click', '.cp-usergrid-user', function () {
|
||||||
@ -885,7 +879,8 @@ define([
|
|||||||
var friendsList = UIElements.getUserGrid(null, {
|
var friendsList = UIElements.getUserGrid(null, {
|
||||||
common: common,
|
common: common,
|
||||||
data: friends,
|
data: friends,
|
||||||
noFilter: false
|
noFilter: false,
|
||||||
|
large: true
|
||||||
}, refreshButtons);
|
}, refreshButtons);
|
||||||
var friendDiv = friendsList.div;
|
var friendDiv = friendsList.div;
|
||||||
$div.append(friendDiv);
|
$div.append(friendDiv);
|
||||||
@ -911,6 +906,7 @@ define([
|
|||||||
var teamsList = UIElements.getUserGrid(Messages.share_linkTeam, {
|
var teamsList = UIElements.getUserGrid(Messages.share_linkTeam, {
|
||||||
common: common,
|
common: common,
|
||||||
noFilter: true,
|
noFilter: true,
|
||||||
|
large: true,
|
||||||
data: teams
|
data: teams
|
||||||
}, refreshButtons);
|
}, refreshButtons);
|
||||||
$div.append(teamsList.div);
|
$div.append(teamsList.div);
|
||||||
@ -1016,12 +1012,29 @@ define([
|
|||||||
|
|
||||||
if (!hashes || (!hashes.editHash && !hashes.viewHash)) { return; }
|
if (!hashes || (!hashes.editHash && !hashes.viewHash)) { return; }
|
||||||
|
|
||||||
|
// check if the pad is password protected
|
||||||
|
var hash = hashes.editHash || hashes.viewHash;
|
||||||
|
var href = origin + pathname + '#' + hash;
|
||||||
|
var parsedHref = Hash.parsePadUrl(href);
|
||||||
|
var hasPassword = parsedHref.hashData.password;
|
||||||
|
|
||||||
|
var makeFaqLink = function () {
|
||||||
|
var link = h('span', [
|
||||||
|
h('i.fa.fa-question-circle'),
|
||||||
|
h('a', {href: '#'}, Messages.passwordFaqLink)
|
||||||
|
]);
|
||||||
|
$(link).click(function () {
|
||||||
|
common.openURL(config.origin + "/faq.html#security-pad_password");
|
||||||
|
});
|
||||||
|
return link;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var parsed = Hash.parsePadUrl(pathname);
|
var parsed = Hash.parsePadUrl(pathname);
|
||||||
var canPresent = ['code', 'slide'].indexOf(parsed.type) !== -1;
|
var canPresent = ['code', 'slide'].indexOf(parsed.type) !== -1;
|
||||||
|
|
||||||
var rights = h('div.msg.cp-inline-radio-group', [
|
var rights = h('div.msg.cp-inline-radio-group', [
|
||||||
h('label', Messages.share_linkAccess),
|
h('label', Messages.share_linkAccess),
|
||||||
h('br'),
|
|
||||||
h('div.radio-group',[
|
h('div.radio-group',[
|
||||||
UI.createRadio('accessRights', 'cp-share-editable-false',
|
UI.createRadio('accessRights', 'cp-share-editable-false',
|
||||||
Messages.share_linkView, true, { mark: {tabindex:1} }),
|
Messages.share_linkView, true, { mark: {tabindex:1} }),
|
||||||
@ -1068,9 +1081,42 @@ define([
|
|||||||
h('br'),
|
h('br'),
|
||||||
] : [
|
] : [
|
||||||
UI.createCheckbox('cp-share-embed', Messages.share_linkEmbed, false, { mark: {tabindex:1} }),
|
UI.createCheckbox('cp-share-embed', Messages.share_linkEmbed, false, { mark: {tabindex:1} }),
|
||||||
h('br'),
|
|
||||||
];
|
];
|
||||||
linkContent.push(UI.dialog.selectable('', { id: 'cp-share-link-preview', tabindex: 1 }));
|
linkContent.push(h('div.cp-spacer'));
|
||||||
|
linkContent.push(UI.dialog.selectableArea('', { id: 'cp-share-link-preview', tabindex: 1, rows:3}));
|
||||||
|
|
||||||
|
// Show alert if the pad is password protected
|
||||||
|
if (hasPassword) {
|
||||||
|
linkContent.push(h('div.alert.alert-primary', [
|
||||||
|
h('i.fa.fa-lock'),
|
||||||
|
Messages.share_linkPasswordAlert, h('br'),
|
||||||
|
makeFaqLink()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// warning about sharing links
|
||||||
|
var localStore = window.cryptpadStore;
|
||||||
|
var dismissButton = h('span.fa.fa-times');
|
||||||
|
var shareLinkWarning = h('div.alert.alert-warning.dismissable',
|
||||||
|
{ style: 'display: none;' },
|
||||||
|
[
|
||||||
|
h('span.cp-inline-alert-text', Messages.share_linkWarning),
|
||||||
|
dismissButton
|
||||||
|
]);
|
||||||
|
linkContent.push(shareLinkWarning);
|
||||||
|
|
||||||
|
localStore.get('hide-alert-shareLinkWarning', function (val) {
|
||||||
|
if (val === '1') { return; }
|
||||||
|
$(shareLinkWarning).show();
|
||||||
|
|
||||||
|
$(dismissButton).on('click', function () {
|
||||||
|
localStore.put('hide-alert-shareLinkWarning', '1');
|
||||||
|
$(shareLinkWarning).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var link = h('div.cp-share-modal', linkContent);
|
var link = h('div.cp-share-modal', linkContent);
|
||||||
var $link = $(link);
|
var $link = $(link);
|
||||||
@ -1137,7 +1183,19 @@ define([
|
|||||||
|
|
||||||
// XXX Don't display access rights if no contacts
|
// XXX Don't display access rights if no contacts
|
||||||
var contactsContent = h('div.cp-share-modal');
|
var contactsContent = h('div.cp-share-modal');
|
||||||
$(contactsContent).append(friendsList);
|
var $contactsContent = $(contactsContent);
|
||||||
|
|
||||||
|
$contactsContent.append(friendsList);
|
||||||
|
|
||||||
|
// Show alert if the pad is password protected
|
||||||
|
if (hasPassword) {
|
||||||
|
$contactsContent.append(h('div.alert.alert-primary', [
|
||||||
|
h('i.fa.fa-unlock'),
|
||||||
|
Messages.share_contactPasswordAlert, h('br'),
|
||||||
|
makeFaqLink()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var contactButtons = [makeCancelButton(),
|
var contactButtons = [makeCancelButton(),
|
||||||
friendsObject.button];
|
friendsObject.button];
|
||||||
@ -1156,9 +1214,18 @@ define([
|
|||||||
};
|
};
|
||||||
var embedContent = [
|
var embedContent = [
|
||||||
h('p', Messages.viewEmbedTag),
|
h('p', Messages.viewEmbedTag),
|
||||||
h('br'),
|
UI.dialog.selectableArea(getEmbedValue(), { id: 'cp-embed-link-preview', tabindex: 1, rows: 3})
|
||||||
UI.dialog.selectable(getEmbedValue(), { id: 'cp-embed-link-preview', tabindex: 1 })
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Show alert if the pad is password protected
|
||||||
|
if (hasPassword) {
|
||||||
|
embedContent.push(h('div.alert.alert-primary', [
|
||||||
|
h('i.fa.fa-lock'), ' ',
|
||||||
|
Messages.share_embedPasswordAlert, h('br'),
|
||||||
|
makeFaqLink()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
var embedButtons = [
|
var embedButtons = [
|
||||||
makeCancelButton(), {
|
makeCancelButton(), {
|
||||||
className: 'primary',
|
className: 'primary',
|
||||||
@ -1187,13 +1254,15 @@ define([
|
|||||||
|
|
||||||
// Create modal
|
// Create modal
|
||||||
var tabs = [{
|
var tabs = [{
|
||||||
title: Messages.share_linkCategory,
|
|
||||||
icon: "fa fa-link",
|
|
||||||
content: frameLink
|
|
||||||
}, {
|
|
||||||
title: Messages.share_contactCategory,
|
title: Messages.share_contactCategory,
|
||||||
icon: "fa fa-address-book",
|
icon: "fa fa-address-book",
|
||||||
content: frameContacts
|
content: frameContacts,
|
||||||
|
active: hasFriends
|
||||||
|
}, {
|
||||||
|
title: Messages.share_linkCategory,
|
||||||
|
icon: "fa fa-link",
|
||||||
|
content: frameLink,
|
||||||
|
active: !hasFriends
|
||||||
}, {
|
}, {
|
||||||
title: Messages.share_embedCategory,
|
title: Messages.share_embedCategory,
|
||||||
icon: "fa fa-code",
|
icon: "fa fa-code",
|
||||||
@ -1261,6 +1330,21 @@ define([
|
|||||||
if (!hashes.fileHash) { throw new Error("You must provide a file hash"); }
|
if (!hashes.fileHash) { throw new Error("You must provide a file hash"); }
|
||||||
var url = origin + pathname + '#' + hashes.fileHash;
|
var url = origin + pathname + '#' + hashes.fileHash;
|
||||||
|
|
||||||
|
// check if the file is password protected
|
||||||
|
var parsedHref = Hash.parsePadUrl(url);
|
||||||
|
var hasPassword = parsedHref.hashData.password;
|
||||||
|
|
||||||
|
var makeFaqLink = function () {
|
||||||
|
var link = h('span', [
|
||||||
|
h('i.fa.fa-question-circle'),
|
||||||
|
h('a', {href: '#'}, Messages.passwordFaqLink)
|
||||||
|
]);
|
||||||
|
$(link).click(function () {
|
||||||
|
common.openURL(config.origin + "/faq.html#security-pad_password");
|
||||||
|
});
|
||||||
|
return link;
|
||||||
|
};
|
||||||
|
|
||||||
var getLinkValue = function () { return url; };
|
var getLinkValue = function () { return url; };
|
||||||
|
|
||||||
var makeCancelButton = function() {
|
var makeCancelButton = function() {
|
||||||
@ -1272,9 +1356,40 @@ define([
|
|||||||
|
|
||||||
// Share link tab
|
// Share link tab
|
||||||
var linkContent = [
|
var linkContent = [
|
||||||
UI.dialog.selectable(getLinkValue(), { id: 'cp-share-link-preview', tabindex: 1 })
|
UI.dialog.selectableArea(getLinkValue(), { id: 'cp-share-link-preview', tabindex: 1, rows:2 })
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Show alert if the pad is password protected
|
||||||
|
if (hasPassword) {
|
||||||
|
linkContent.push(h('div.alert.alert-primary', [
|
||||||
|
h('i.fa.fa-lock'),
|
||||||
|
Messages.share_linkPasswordAlert, h('br'),
|
||||||
|
makeFaqLink()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// warning about sharing links
|
||||||
|
var localStore = window.cryptpadStore;
|
||||||
|
var dismissButton = h('span.fa.fa-times');
|
||||||
|
var shareLinkWarning = h('div.alert.alert-warning.dismissable',
|
||||||
|
{ style: 'display: none;' },
|
||||||
|
[
|
||||||
|
h('span.cp-inline-alert-text', Messages.share_linkWarning),
|
||||||
|
dismissButton
|
||||||
|
]);
|
||||||
|
linkContent.push(shareLinkWarning);
|
||||||
|
|
||||||
|
localStore.get('hide-alert-shareLinkWarning', function (val) {
|
||||||
|
if (val === '1') { return; }
|
||||||
|
$(shareLinkWarning).show();
|
||||||
|
|
||||||
|
$(dismissButton).on('click', function () {
|
||||||
|
localStore.put('hide-alert-shareLinkWarning', '1');
|
||||||
|
$(shareLinkWarning).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
var link = h('div.cp-share-modal', linkContent);
|
var link = h('div.cp-share-modal', linkContent);
|
||||||
|
|
||||||
var linkButtons = [
|
var linkButtons = [
|
||||||
@ -1307,7 +1422,17 @@ define([
|
|||||||
var friendsList = friendsObject.content;
|
var friendsList = friendsObject.content;
|
||||||
|
|
||||||
var contactsContent = h('div.cp-share-modal');
|
var contactsContent = h('div.cp-share-modal');
|
||||||
$(contactsContent).append(friendsList);
|
var $contactsContent = $(contactsContent);
|
||||||
|
$contactsContent.append(friendsList);
|
||||||
|
|
||||||
|
// Show alert if the pad is password protected
|
||||||
|
if (hasPassword) {
|
||||||
|
$contactsContent.append(h('div.alert.alert-primary', [
|
||||||
|
h('i.fa.fa-unlock'),
|
||||||
|
Messages.share_contactPasswordAlert, h('br'),
|
||||||
|
makeFaqLink()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
var contactButtons = [makeCancelButton(),
|
var contactButtons = [makeCancelButton(),
|
||||||
friendsObject.button];
|
friendsObject.button];
|
||||||
@ -1321,12 +1446,20 @@ define([
|
|||||||
// Embed tab
|
// Embed tab
|
||||||
var embed = h('div.cp-share-modal', [
|
var embed = h('div.cp-share-modal', [
|
||||||
h('p', Messages.fileEmbedScript),
|
h('p', Messages.fileEmbedScript),
|
||||||
h('br'),
|
|
||||||
UI.dialog.selectable(common.getMediatagScript()),
|
UI.dialog.selectable(common.getMediatagScript()),
|
||||||
h('p', Messages.fileEmbedTag),
|
h('p', Messages.fileEmbedTag),
|
||||||
h('br'),
|
|
||||||
UI.dialog.selectable(common.getMediatagFromHref(fileData)),
|
UI.dialog.selectable(common.getMediatagFromHref(fileData)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Show alert if the pad is password protected
|
||||||
|
if (hasPassword) {
|
||||||
|
embed.append(h('div.alert.alert-primary', [
|
||||||
|
h('i.fa.fa-lock'), ' ',
|
||||||
|
Messages.share_embedPasswordAlert, h('br'),
|
||||||
|
makeFaqLink()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
var embedButtons = [{
|
var embedButtons = [{
|
||||||
className: 'cancel',
|
className: 'cancel',
|
||||||
name: Messages.cancel,
|
name: Messages.cancel,
|
||||||
@ -1349,13 +1482,15 @@ define([
|
|||||||
|
|
||||||
// Create modal
|
// Create modal
|
||||||
var tabs = [{
|
var tabs = [{
|
||||||
title: Messages.share_linkCategory,
|
|
||||||
icon: "fa fa-link",
|
|
||||||
content: frameLink
|
|
||||||
}, {
|
|
||||||
title: Messages.share_contactCategory,
|
title: Messages.share_contactCategory,
|
||||||
icon: "fa fa-address-book",
|
icon: "fa fa-address-book",
|
||||||
content: frameContacts
|
content: frameContacts,
|
||||||
|
active: hasFriends,
|
||||||
|
}, {
|
||||||
|
title: Messages.share_linkCategory,
|
||||||
|
icon: "fa fa-link",
|
||||||
|
content: frameLink,
|
||||||
|
active: !hasFriends
|
||||||
}, {
|
}, {
|
||||||
title: Messages.share_embedCategory,
|
title: Messages.share_embedCategory,
|
||||||
icon: "fa fa-code",
|
icon: "fa fa-code",
|
||||||
@ -1759,7 +1894,7 @@ define([
|
|||||||
if (e) { return void console.error(e); }
|
if (e) { return void console.error(e); }
|
||||||
UIElements.getProperties(common, data, function (e, $prop) {
|
UIElements.getProperties(common, data, function (e, $prop) {
|
||||||
if (e) { return void console.error(e); }
|
if (e) { return void console.error(e); }
|
||||||
UI.alert($prop[0], undefined, true);
|
UI.openCustomModal($prop[0]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -84,7 +84,7 @@ define([
|
|||||||
|
|
||||||
var defaultCode = renderer.code;
|
var defaultCode = renderer.code;
|
||||||
renderer.code = function (code, language) {
|
renderer.code = function (code, language) {
|
||||||
if (language === 'mermaid' && (code.match(/^sequenceDiagram/) || code.match(/^graph/))) {
|
if (language === 'mermaid' && code.match(/^(graph|pie|gantt|sequenceDiagram|classDiagram|gitGraph)/)) {
|
||||||
return '<pre class="mermaid">'+code+'</pre>';
|
return '<pre class="mermaid">'+code+'</pre>';
|
||||||
} else {
|
} else {
|
||||||
return defaultCode.apply(renderer, arguments);
|
return defaultCode.apply(renderer, arguments);
|
||||||
@ -197,7 +197,6 @@ define([
|
|||||||
'APPLET',
|
'APPLET',
|
||||||
'VIDEO', // privacy implications of videos are the same as images
|
'VIDEO', // privacy implications of videos are the same as images
|
||||||
'AUDIO', // same with audio
|
'AUDIO', // same with audio
|
||||||
'SVG'
|
|
||||||
];
|
];
|
||||||
var unsafeTag = function (info) {
|
var unsafeTag = function (info) {
|
||||||
/*if (info.node && $(info.node).parents('media-tag').length) {
|
/*if (info.node && $(info.node).parents('media-tag').length) {
|
||||||
@ -307,8 +306,39 @@ define([
|
|||||||
|
|
||||||
var Dom = domFromHTML($('<div>').append($div).html());
|
var Dom = domFromHTML($('<div>').append($div).html());
|
||||||
$content[0].normalize();
|
$content[0].normalize();
|
||||||
$content.find('pre.mermaid[data-processed="true"]').remove();
|
|
||||||
|
var mermaid_source = [];
|
||||||
|
var mermaid_cache = {};
|
||||||
|
|
||||||
|
// iterate over the unrendered mermaid inputs, caching their source as you go
|
||||||
|
$(newDomFixed).find('pre.mermaid').each(function (index, el) {
|
||||||
|
if (el.childNodes.length === 1 && el.childNodes[0].nodeType === 3) {
|
||||||
|
var src = el.childNodes[0].wholeText;
|
||||||
|
el.setAttribute('mermaid-source', src);
|
||||||
|
mermaid_source[index] = src;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// iterate over rendered mermaid charts
|
||||||
|
$content.find('pre.mermaid:not([processed="true"])').each(function (index, el) {
|
||||||
|
// retrieve the attached source code which it was drawn
|
||||||
|
var src = el.getAttribute('mermaid-source');
|
||||||
|
|
||||||
|
// check if that source exists in the set of charts which are about to be rendered
|
||||||
|
if (mermaid_source.indexOf(src) === -1) {
|
||||||
|
// if it's not, then you can remove it
|
||||||
|
if (el.parentNode && el.parentNode.children.length) {
|
||||||
|
el.parentNode.removeChild(el);
|
||||||
|
}
|
||||||
|
} else if (el.childNodes.length === 1 && el.childNodes[0].nodeType !== 3) {
|
||||||
|
// otherwise, confirm that the content of the rendered chart is not a text node
|
||||||
|
// and keep a copy of it
|
||||||
|
mermaid_cache[src] = el.childNodes[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var oldDom = domFromHTML($content[0].outerHTML);
|
var oldDom = domFromHTML($content[0].outerHTML);
|
||||||
|
|
||||||
var patch = makeDiff(oldDom, Dom, id);
|
var patch = makeDiff(oldDom, Dom, id);
|
||||||
if (typeof(patch) === 'string') {
|
if (typeof(patch) === 'string') {
|
||||||
throw new Error(patch);
|
throw new Error(patch);
|
||||||
@ -348,8 +378,32 @@ define([
|
|||||||
var target = document.getElementById($a.attr('data-href'));
|
var target = document.getElementById($a.attr('data-href'));
|
||||||
if (target) { target.scrollIntoView(); }
|
if (target) { target.scrollIntoView(); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// loop over mermaid elements in the rendered content
|
||||||
|
$content.find('pre.mermaid').each(function (index, el) {
|
||||||
|
// since you've simply drawn the content that was supplied via markdown
|
||||||
|
// you can assume that the index of your rendered charts matches that
|
||||||
|
// of those in the markdown source.
|
||||||
|
var src = mermaid_source[index];
|
||||||
|
el.setAttribute('mermaid-source', src);
|
||||||
|
var cached = mermaid_cache[src];
|
||||||
|
|
||||||
|
// check if you had cached a pre-rendered instance of the supplied source
|
||||||
|
if (typeof(cached) !== 'object') { return; }
|
||||||
|
|
||||||
|
// if there's a cached rendering, empty out the contained source code
|
||||||
|
// which would otherwise be drawn again.
|
||||||
|
// apparently this is the fastest way to empty out an element
|
||||||
|
while (el.firstChild) { el.removeChild(el.firstChild); } //el.innerHTML = '';
|
||||||
|
// insert the cached graph
|
||||||
|
el.appendChild(cached);
|
||||||
|
// and set a flag indicating that this graph need not be reprocessed
|
||||||
|
el.setAttribute('data-processed', true);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Mermaid.init();
|
// finally, draw any graphs which have changed and were thus not cached
|
||||||
|
Mermaid.init(undefined, $content.find('pre.mermaid:not([data-processed="true"])'));
|
||||||
} catch (e) { console.error(e); }
|
} catch (e) { console.error(e); }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -79,7 +79,7 @@ define([
|
|||||||
var faColor = 'cptools-palette';
|
var faColor = 'cptools-palette';
|
||||||
var faTrash = 'fa-trash';
|
var faTrash = 'fa-trash';
|
||||||
var faDelete = 'fa-eraser';
|
var faDelete = 'fa-eraser';
|
||||||
var faProperties = 'fa-database';
|
var faProperties = 'fa-info-circle';
|
||||||
var faTags = 'fa-hashtag';
|
var faTags = 'fa-hashtag';
|
||||||
var faUploadFiles = 'cptools-file-upload';
|
var faUploadFiles = 'cptools-file-upload';
|
||||||
var faUploadFolder = 'cptools-folder-upload';
|
var faUploadFolder = 'cptools-folder-upload';
|
||||||
@ -4187,7 +4187,7 @@ define([
|
|||||||
}
|
}
|
||||||
getProperties(el, function (e, $prop) {
|
getProperties(el, function (e, $prop) {
|
||||||
if (e) { return void logError(e); }
|
if (e) { return void logError(e); }
|
||||||
UI.alert($prop[0], undefined, true);
|
UI.openCustomModal($prop[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if ($this.hasClass("cp-app-drive-context-hashtag")) {
|
else if ($this.hasClass("cp-app-drive-context-hashtag")) {
|
||||||
|
|||||||
@ -43,7 +43,7 @@ define([
|
|||||||
MessengerUI.create = function ($container, common, toolbar) {
|
MessengerUI.create = function ($container, common, toolbar) {
|
||||||
var metadataMgr = common.getMetadataMgr();
|
var metadataMgr = common.getMetadataMgr();
|
||||||
var origin = metadataMgr.getPrivateData().origin;
|
var origin = metadataMgr.getPrivateData().origin;
|
||||||
var readOnly = metadataMgr.getPrivateData().readOnly || toolbar.readOnly;
|
var readOnly = metadataMgr.getPrivateData().readOnly || (toolbar && toolbar.readOnly);
|
||||||
|
|
||||||
var isApp = typeof(toolbar) !== "undefined";
|
var isApp = typeof(toolbar) !== "undefined";
|
||||||
|
|
||||||
|
|||||||
@ -769,18 +769,18 @@ define([
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var href;
|
var decryptedHref;
|
||||||
try {
|
try {
|
||||||
href = el.href && ((el.href.indexOf('#') !== -1) ? el.href : exp.cryptor.decrypt(el.href));
|
decryptedHref = el.href && ((el.href.indexOf('#') !== -1) ? el.href : exp.cryptor.decrypt(el.href));
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
if (href && href.indexOf('#') === -1) {
|
if (decryptedHref && decryptedHref.indexOf('#') === -1) {
|
||||||
// If we can't decrypt the href, it means we don't have the correct secondaryKey and we're in readOnly mode:
|
// If we can't decrypt the href, it means we don't have the correct secondaryKey and we're in readOnly mode:
|
||||||
// abort now, we won't be able to fix anything anyway
|
// abort now, we won't be able to fix anything anyway
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsed = Hash.parsePadUrl(href || el.roHref);
|
var parsed = Hash.parsePadUrl(decryptedHref || el.roHref);
|
||||||
var secret;
|
var secret;
|
||||||
|
|
||||||
// Clean invalid hash
|
// Clean invalid hash
|
||||||
@ -797,9 +797,9 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we have an edit link, check the view link
|
// If we have an edit link, check the view link
|
||||||
if (href && parsed.hashData.type === "pad" && parsed.hashData.version) {
|
if (decryptedHref && parsed.hashData.type === "pad" && parsed.hashData.version) {
|
||||||
if (parsed.hashData.mode === "view") {
|
if (parsed.hashData.mode === "view") {
|
||||||
el.roHref = href;
|
el.roHref = decryptedHref;
|
||||||
delete el.href;
|
delete el.href;
|
||||||
} else if (!el.roHref) {
|
} else if (!el.roHref) {
|
||||||
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
|
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
|
||||||
@ -818,7 +818,9 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fix href
|
// Fix href
|
||||||
if (href && href.slice(0,1) !== '/') { el.href = exp.cryptor.encrypt(Hash.getRelativeHref(el.href)); }
|
if (decryptedHref && decryptedHref.slice(0,1) !== '/') {
|
||||||
|
el.href = exp.cryptor.encrypt(Hash.getRelativeHref(decryptedHref));
|
||||||
|
}
|
||||||
// Fix creation time
|
// Fix creation time
|
||||||
if (!el.ctime) { el.ctime = el.atime; }
|
if (!el.ctime) { el.ctime = el.atime; }
|
||||||
// Fix title
|
// Fix title
|
||||||
|
|||||||
@ -488,6 +488,20 @@ define([
|
|||||||
Cryptpad.storeInTeam(data, cb);
|
Cryptpad.storeInTeam(data, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sframeChan.on('EV_GOTO_URL', function (url) {
|
||||||
|
if (url) {
|
||||||
|
window.location.href = url;
|
||||||
|
} else {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sframeChan.on('EV_OPEN_URL', function (url) {
|
||||||
|
if (url) {
|
||||||
|
window.open(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
addCommonRpc(sframeChan);
|
addCommonRpc(sframeChan);
|
||||||
|
|
||||||
@ -956,20 +970,6 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('EV_GOTO_URL', function (url) {
|
|
||||||
if (url) {
|
|
||||||
window.location.href = url;
|
|
||||||
} else {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sframeChan.on('EV_OPEN_URL', function (url) {
|
|
||||||
if (url) {
|
|
||||||
window.open(url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sframeChan.on('Q_PIN_GET_USAGE', function (teamId, cb) {
|
sframeChan.on('Q_PIN_GET_USAGE', function (teamId, cb) {
|
||||||
Cryptpad.isOverPinLimit(teamId, function (err, overLimit, data) {
|
Cryptpad.isOverPinLimit(teamId, function (err, overLimit, data) {
|
||||||
cb({
|
cb({
|
||||||
|
|||||||
2
www/common/translations/messages.fi.json
Normal file
2
www/common/translations/messages.fi.json
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
||||||
@ -54,6 +54,7 @@
|
|||||||
.kanban-item-text {
|
.kanban-item-text {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +68,7 @@
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
//white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
#kanban-edit {
|
#kanban-edit {
|
||||||
|
|||||||
@ -286,7 +286,7 @@ define([
|
|||||||
kanban.inEditMode = true;
|
kanban.inEditMode = true;
|
||||||
// create a form to enter element
|
// create a form to enter element
|
||||||
var boardId = $(el.parentNode.parentNode).attr("data-id");
|
var boardId = $(el.parentNode.parentNode).attr("data-id");
|
||||||
var $item = $('<div>', {'class': 'kanban-item'});
|
var $item = $('<div>', {'class': 'kanban-item new-item'});
|
||||||
var $input = getInput().val(name).appendTo($item);
|
var $input = getInput().val(name).appendTo($item);
|
||||||
kanban.addForm(boardId, $item[0]);
|
kanban.addForm(boardId, $item[0]);
|
||||||
$input.focus();
|
$input.focus();
|
||||||
|
|||||||
@ -147,9 +147,13 @@
|
|||||||
self.drake = self.dragula(self.boardContainer, {
|
self.drake = self.dragula(self.boardContainer, {
|
||||||
moves: function (el, source, handle, sibling) {
|
moves: function (el, source, handle, sibling) {
|
||||||
if (self.options.readOnly) { return false; }
|
if (self.options.readOnly) { return false; }
|
||||||
|
if (el.classList.contains('new-item')) { return false; }
|
||||||
return handle.classList.contains('kanban-item');
|
return handle.classList.contains('kanban-item');
|
||||||
},
|
},
|
||||||
accepts: function (el, target, source, sibling) {
|
accepts: function (el, target, source, sibling) {
|
||||||
|
if (sibling === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (self.options.readOnly) { return false; }
|
if (self.options.readOnly) { return false; }
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -349,7 +353,7 @@
|
|||||||
titleBoard = document.createElement('div');
|
titleBoard = document.createElement('div');
|
||||||
titleBoard.classList.add('kanban-title-board');
|
titleBoard.classList.add('kanban-title-board');
|
||||||
titleBoard.innerHTML = board.title;
|
titleBoard.innerHTML = board.title;
|
||||||
titleBoard.setAttribute('title', board.title);
|
//titleBoard.setAttribute('title', board.title);
|
||||||
titleBoard.clickfn = board.boardTitleClick;
|
titleBoard.clickfn = board.boardTitleClick;
|
||||||
__onboardTitleClickHandler(titleBoard);
|
__onboardTitleClickHandler(titleBoard);
|
||||||
headerBoard.appendChild(titleBoard);
|
headerBoard.appendChild(titleBoard);
|
||||||
|
|||||||
@ -51,6 +51,7 @@ define([
|
|||||||
'cp-settings-info-block',
|
'cp-settings-info-block',
|
||||||
'cp-settings-displayname',
|
'cp-settings-displayname',
|
||||||
'cp-settings-language-selector',
|
'cp-settings-language-selector',
|
||||||
|
'cp-settings-resettips',
|
||||||
'cp-settings-logout-everywhere',
|
'cp-settings-logout-everywhere',
|
||||||
'cp-settings-autostore',
|
'cp-settings-autostore',
|
||||||
'cp-settings-userfeedback',
|
'cp-settings-userfeedback',
|
||||||
@ -67,7 +68,6 @@ define([
|
|||||||
],
|
],
|
||||||
'drive': [
|
'drive': [
|
||||||
'cp-settings-drive-duplicate',
|
'cp-settings-drive-duplicate',
|
||||||
'cp-settings-resettips',
|
|
||||||
'cp-settings-thumbnails',
|
'cp-settings-thumbnails',
|
||||||
'cp-settings-drive-backup',
|
'cp-settings-drive-backup',
|
||||||
'cp-settings-drive-import-local',
|
'cp-settings-drive-import-local',
|
||||||
@ -835,7 +835,7 @@ define([
|
|||||||
var localStore = window.cryptpadStore;
|
var localStore = window.cryptpadStore;
|
||||||
$button.click(function () {
|
$button.click(function () {
|
||||||
Object.keys(localStore.store).forEach(function (k) {
|
Object.keys(localStore.store).forEach(function (k) {
|
||||||
if(k.slice(0, 9) === "hide-info") {
|
if(/^(hide-(info|alert))/.test(k)) {
|
||||||
localStore.put(k, null);
|
localStore.put(k, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user