Merge branch 'staging' into sfAllow

pull/1/head
yflory 4 years ago
commit bf8c43e9af

@ -1,3 +1,32 @@
# Thylacine's revenge (3.19.1)
Our upcoming 3.20.0 release is planned for July 7th, 2020, but we are once again releasing a minor version featuring some nice bug fixes and usability improvements which are ready to be deployed now. In case you missed [our announcement](https://social.weho.st/@cryptpad/104360490068671089) we are phasing out our usage of the `master` and basing our releases on the `main` branch. For best results we recommend explicitly checking out code by its tag.
New features:
* We've spent a little time making support tickets a little bit easier for both users and admins.
* Users can now label their tickets with a set of predefined categories, making it easier for admins to sort through related reports.
* Users and admins can both attach encrypted uploads to their messages, making it easier to demonstrate a problem with an image, video, or other example file.
* Teams now take advantage of the same "mailbox" functionality that powers user accounts' notification center. Team members with the "viewer" role can now use this feature to share documents with their team using the "share menu" as they already can with other users. Anyone with the ability to add a document to the team's drive will then be able to receive the notification and add the document to the team's drive for them. Going forward we'll use this functionality to implement more behaviour to make teams function more like shared user accounts.
* The "pad creation screen" which is displayed to registered users when they first create a pad will no longer remember the settings used when they last created a pad. While this behaviour was intended to streamline the process of creating documents, in practice it led to some user's documents getting deleted because they didn't realize they were set to automatically expire. If you prefer not to use the defaults (owned, non-expiring) then you'll have to click a few more times to create a document, but we think that's a worthwhile tradeoff to avoid data loss.
Bug fixes:
* Hitting _ctrl-A_ in the drive used to select lots of the page's elements which had no business being selected. Now it will select the contents of the directory currently being displayed.
* Due to some complications in OnlyOffice (which we use for spreadsheets) remote updates made to a sheet were not displayed for users who had opened the document in "view mode". We still don't have the means to apply these remote changes in real-time, but we now prompt users to click a button to refresh the editor (not the full page) to display the latest document state.
* A recent update set the text color of the team chat input to 'white', matching the input's background and making the text unreadable. We patched it to make it black text on a white background.
* We're slowly working on improving keyboard shortcuts for a variety of actions. This time around we fixed a bug that prevented "ESC" from closing an open "tag prompt" interface.
* We noticed that the zip file constructed in the browser when you downloaded a subtree of a shared folder in your drive contained the correct directory structure but did not contain the files that were supposed to be there. This has been fixed.
* Finally, we've tweaked our styles to use more specific CSS selectors to prevent a variety of styles from being accidentally applied to the wrong elements. This should make the platform a little easier to maintain and help us improve the visual consistency of a variety of elements on different pages.
To update from 3.19.0 to 3.19.1:
1. Stop your server
2. Get the latest code with `git checkout 3.19.1`
3. Restart your server
If you're updating from anything other than 3.19.0 you may need other clientside dependencies (available with `bower update` and `npm i`).
# Thylacine release (3.19.0) # Thylacine release (3.19.0)
## Goals ## Goals

@ -62,7 +62,7 @@ define([
var imprintUrl = AppConfig.imprint && (typeof(AppConfig.imprint) === "boolean" ? var imprintUrl = AppConfig.imprint && (typeof(AppConfig.imprint) === "boolean" ?
'/imprint.html' : AppConfig.imprint); '/imprint.html' : AppConfig.imprint);
Pages.versionString = "CryptPad v3.19.0 (Thylacine)"; Pages.versionString = "CryptPad v3.19.1 (Thylacine's revenge)";
// used for the about menu // used for the about menu
Pages.imprintLink = AppConfig.imprint ? footLink(imprintUrl, 'imprint') : undefined; Pages.imprintLink = AppConfig.imprint ? footLink(imprintUrl, 'imprint') : undefined;

@ -3,7 +3,6 @@
@import (reference) "./variables.less"; @import (reference) "./variables.less";
@import (reference) "./avatar.less"; @import (reference) "./avatar.less";
@import (reference) "./tools.less"; @import (reference) "./tools.less";
@import (reference) "./buttons.less";
.alertify_main() { .alertify_main() {
--LessLoader_require: LessLoader_currentFile(); --LessLoader_require: LessLoader_currentFile();
@ -272,7 +271,6 @@
} }
} }
.buttons_main();
input:not(.form-control), textarea { input:not(.form-control), textarea {
margin-bottom: 15px; margin-bottom: 15px;
} }

@ -1,7 +1,6 @@
@import (reference) "./colortheme-all.less"; @import (reference) "./colortheme-all.less";
@import (reference) "./variables.less"; @import (reference) "./variables.less";
@import (reference) "./avatar.less"; @import (reference) "./avatar.less";
@import (reference) "./buttons.less";
@import (reference) "./tools.less"; @import (reference) "./tools.less";
.comments_main() { .comments_main() {
@ -22,8 +21,6 @@
} }
.buttons_main();
.cp-comment-reply { .cp-comment-reply {
margin-left: 30px; margin-left: 30px;
} }

@ -1,7 +1,7 @@
@import (reference) "./colortheme-all.less"; @import (reference) "./colortheme-all.less";
@import (reference) "./variables.less"; @import (reference) "./variables.less";
.buttons_main() { .forms_main() {
@alertify-fore: @colortheme_modal-fg; @alertify-fore: @colortheme_modal-fg;
@alertify-btn-fg: @alertify-fore; @alertify-btn-fg: @alertify-fore;
@alertify-light-bg: fade(@alertify-fore, 25%); @alertify-light-bg: fade(@alertify-fore, 25%);
@ -30,7 +30,7 @@
div.cp-alertify-type { div.cp-alertify-type {
display: flex; display: flex;
input { input {
margin: 0; margin: 0 !important;
flex: 1; flex: 1;
min-width: 0; min-width: 0;
} }
@ -83,7 +83,7 @@
margin-bottom: 3px !important; margin-bottom: 3px !important;
} }
button:not(.pure-button):not(.md-button):not(.mdl-button) { button.btn {
background-color: @colortheme_alertify-cancel; background-color: @colortheme_alertify-cancel;
box-sizing: border-box; box-sizing: border-box;

@ -16,6 +16,7 @@
@import (reference) "./cursor.less"; @import (reference) "./cursor.less";
@import (reference) "./usergrid.less"; @import (reference) "./usergrid.less";
@import (reference) "./mentions.less"; @import (reference) "./mentions.less";
@import (reference) "./forms.less";
@import (reference) "./modals-ui-elements.less"; @import (reference) "./modals-ui-elements.less";
.framework_main(@bg-color, @warn-color, @color) { .framework_main(@bg-color, @warn-color, @color) {
@ -48,6 +49,7 @@
); );
.cursor_main(); .cursor_main();
.usergrid_main(); .usergrid_main();
.forms_main();
.mentions_main(); .mentions_main();
.creation_main( .creation_main(
@bg-color: @bg-color, @bg-color: @bg-color,
@ -84,6 +86,7 @@
.checkmark_main(20px); .checkmark_main(20px);
.password_main(); .password_main();
.usergrid_main(); .usergrid_main();
.forms_main();
font: @colortheme_app-font; font: @colortheme_app-font;
} }

@ -1,8 +1,5 @@
@import (reference) "./colortheme-all.less"; @import (reference) "./colortheme-all.less";
@import (reference) "./variables.less"; @import (reference) "./variables.less";
@import (reference) './buttons.less';
.modal_base() { .modal_base() {
font-family: @colortheme_font; font-family: @colortheme_font;
@ -39,8 +36,6 @@
background-color: @colortheme_modal-dim; background-color: @colortheme_modal-dim;
.cp-modal { .cp-modal {
.buttons_main();
background-color: @colortheme_modal-bg; background-color: @colortheme_modal-bg;
color: @colortheme_modal-fg; color: @colortheme_modal-fg;
box-shadow: @variables_shadow; box-shadow: @variables_shadow;

@ -1,6 +1,5 @@
@import (reference) "/customize/src/less2/include/colortheme-all.less"; @import (reference) "/customize/src/less2/include/colortheme-all.less";
@import (reference) "/customize/src/less2/include/leftside-menu.less"; @import (reference) "/customize/src/less2/include/leftside-menu.less";
@import (reference) "/customize/src/less2/include/buttons.less";
@import (reference) "/customize/src/less2/include/browser.less"; @import (reference) "/customize/src/less2/include/browser.less";
@sidebar_button-width: 400px; @sidebar_button-width: 400px;
@ -98,7 +97,6 @@
} }
} }
margin-bottom: 20px; margin-bottom: 20px;
.buttons_main();
} }
[type="text"], [type="password"], button { [type="text"], [type="password"], button {
vertical-align: middle; vertical-align: middle;

@ -4,6 +4,9 @@
@msg-bg: #eee; @msg-bg: #eee;
@fromme-bg: #ddd; @fromme-bg: #ddd;
.cp-support-form-container { .cp-support-form-container {
div {
margin-bottom: 10px;
}
[type="text"] { [type="text"] {
width: @sidebar_button-width; width: @sidebar_button-width;
margin-bottom: 10px; margin-bottom: 10px;
@ -15,6 +18,18 @@
height: 300px; height: 300px;
} }
} }
.cp-support-attachments {
display: flex;
.fa {
cursor: pointer;
margin-right: 10px;
}
&> span {
border: 1px solid #ddd;
margin-right: 5px;
padding: 10px;
}
}
.cp-support-container { .cp-support-container {
.cp-support-list-ticket { .cp-support-list-ticket {
display: flex; display: flex;

@ -84,7 +84,6 @@
width: 100%; width: 100%;
min-width: 100% !important; min-width: 100% !important;
&:focus { &:focus {
border-color: transparent;
outline: 0; outline: 0;
box-shadow: none; box-shadow: none;
} }

@ -2,9 +2,11 @@
@import (reference) "../include/colortheme-all.less"; @import (reference) "../include/colortheme-all.less";
@import (reference) "../include/alertify.less"; @import (reference) "../include/alertify.less";
@import (reference) "../include/checkmark.less"; @import (reference) "../include/checkmark.less";
@import (reference) "../include/forms.less";
&.cp-page-register { &.cp-page-register {
.infopages_main(); .infopages_main();
.forms_main();
.alertify_main(); .alertify_main();
.checkmark_main(20px); .checkmark_main(20px);

2
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "cryptpad", "name": "cryptpad",
"version": "3.19.0", "version": "3.19.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,7 +1,7 @@
{ {
"name": "cryptpad", "name": "cryptpad",
"description": "realtime collaborative visual editor with zero knowlege server", "description": "realtime collaborative visual editor with zero knowlege server",
"version": "3.19.0", "version": "3.19.1",
"license": "AGPL-3.0+", "license": "AGPL-3.0+",
"repository": { "repository": {
"type": "git", "type": "git",

@ -185,6 +185,20 @@ define([
var $container = makeBlock('support-list'); var $container = makeBlock('support-list');
var $div = $(h('div.cp-support-container')).appendTo($container); var $div = $(h('div.cp-support-container')).appendTo($container);
var catContainer = h('div.cp-dropdown-container');
$div.append(catContainer);
var category = 'all';
var $drop = APP.support.makeCategoryDropdown(catContainer, function (key) {
category = key;
if (key === 'all') {
$div.find('.cp-support-list-ticket').show();
return;
}
$div.find('.cp-support-list-ticket').hide();
$div.find('.cp-support-list-ticket[data-cat="'+key+'"]').show();
}, true);
$drop.setValue('all');
var metadataMgr = common.getMetadataMgr(); var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData(); var privateData = metadataMgr.getPrivateData();
var cat = privateData.category || ''; var cat = privateData.category || '';
@ -277,6 +291,9 @@ define([
UI.alert(Messages.error); UI.alert(Messages.error);
}); });
}); });
if (category !== 'all' && $ticket.attr('data-cat') !== category) {
$ticket.hide();
}
} }
$ticket.append(APP.support.makeMessage(content, hash)); $ticket.append(APP.support.makeMessage(content, hash));
reorder(); reorder();

@ -145,12 +145,12 @@ define([
}; };
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.btn.ok.primary';
return h(sel, { tabindex: '2', }, content || Messages.okButton); return h(sel, { tabindex: '2', }, content || Messages.okButton);
}; };
dialog.cancelButton = function (content, classString) { dialog.cancelButton = function (content, classString) {
var sel = typeof(classString) === 'string'? 'button.' + classString:'button.cancel'; var sel = typeof(classString) === 'string'? 'button.' + classString:'button.btn.cancel';
return h(sel, { tabindex: '1'}, content || Messages.cancelButton); return h(sel, { tabindex: '1'}, content || Messages.cancelButton);
}; };
@ -356,11 +356,15 @@ define([
var $cancel = findCancelButton(tagger).click(function (e) { var $cancel = findCancelButton(tagger).click(function (e) {
close(null, e); close(null, e);
}); });
listener = listenForKeys(function () { $(tagger).on('keydown', function (e) {
$ok.click(); if (e.which === 27) {
}, function () {
$cancel.click(); $cancel.click();
}, tagger); return;
}
if (e.which === 13) {
$ok.click();
}
});
$(tagger).on('click submit', function (e) { $(tagger).on('click submit', function (e) {
e.stopPropagation(); e.stopPropagation();
@ -392,6 +396,7 @@ define([
buttons.forEach(function (b) { buttons.forEach(function (b) {
if (!b.name || !b.onClick) { return; } if (!b.name || !b.onClick) { return; }
var button = h('button', { tabindex: '1', 'class': b.className || '' }, b.name); var button = h('button', { tabindex: '1', 'class': b.className || '' }, b.name);
button.classList.add('btn');
var todo = function () { var todo = function () {
var noClose = b.onClick(); var noClose = b.onClick();
if (noClose) { return; } if (noClose) { return; }
@ -642,9 +647,6 @@ define([
var $ok = $(ok).click(function (ev) { close(true, ev); }); var $ok = $(ok).click(function (ev) { close(true, ev); });
var $cancel = $(cancel).click(function (ev) { close(false, ev); }); var $cancel = $(cancel).click(function (ev) { close(false, ev); });
if (opt.cancelClass) { $cancel.addClass(opt.cancelClass); }
if (opt.okClass) { $ok.addClass(opt.okClass); }
listener = listenForKeys(function () { listener = listenForKeys(function () {
$ok.click(); $ok.click();
}, function () { }, function () {

@ -313,11 +313,15 @@ define([
var $friends = $div.find('.cp-usergrid-user.cp-selected'); var $friends = $div.find('.cp-usergrid-user.cp-selected');
$friends.each(function (i, el) { $friends.each(function (i, el) {
var curve = $(el).attr('data-curve'); var curve = $(el).attr('data-curve');
// Check if the selected element is a friend or a team var ed = $(el).attr('data-ed');
if (curve) { // Friend var friend = curve && friends[curve];
if (!curve || !friends[curve]) { return; } var team = teams[ed];
var friend = friends[curve]; // If the selected element is a friend or a team without edit right,
if (!friend.notifications || !friend.curvePublic) { return; } // send a notification
var mailbox = friend || ((team && team.viewer) ? team : undefined);
if (mailbox) { // Friend
if (friends[curve] && !mailbox.notifications) { return; }
if (mailbox.notifications && mailbox.curvePublic) {
common.mailbox.sendTo("SHARE_PAD", { common.mailbox.sendTo("SHARE_PAD", {
href: href, href: href,
password: config.password, password: config.password,
@ -325,14 +329,14 @@ define([
name: myName, name: myName,
title: title title: title
}, { }, {
channel: friend.notifications, viewed: team && team.id,
curvePublic: friend.curvePublic channel: mailbox.notifications,
curvePublic: mailbox.curvePublic
}); });
return; return;
} }
// Team }
var ed = $(el).attr('data-ed'); // If it's a team with edit right, add the pad directly
var team = teams[ed];
if (!team) { return; } if (!team) { return; }
sframeChan.query('Q_STORE_IN_TEAM', { sframeChan.query('Q_STORE_IN_TEAM', {
href: href, href: href,
@ -450,10 +454,11 @@ define([
// config.teamId only exists when we're trying to share a pad from a team drive // config.teamId only exists when we're trying to share a pad from a team drive
// In this case, we don't want to share the pad with the current team // In this case, we don't want to share the pad with the current team
if (config.teamId && config.teamId === id) { return; } if (config.teamId && config.teamId === id) { return; }
if (!teamsData[id].hasSecondaryKey) { return; }
var t = teamsData[id]; var t = teamsData[id];
teams[t.edPublic] = { teams[t.edPublic] = {
notifications: true, viewer: !teamsData[id].hasSecondaryKey,
notifications: t.notifications,
curvePublic: t.curvePublic,
displayName: t.name, displayName: t.name,
edPublic: t.edPublic, edPublic: t.edPublic,
avatar: t.avatar, avatar: t.avatar,
@ -2150,6 +2155,11 @@ define([
'class': 'fa fa-caret-down', 'class': 'fa fa-caret-down',
}).prependTo($button); }).prependTo($button);
} }
if (config.angleDown) {
$('<span>', {
'class': 'fa fa-angle-down',
}).prependTo($button);
}
// Menu // Menu
var $innerblock = $('<div>', {'class': 'cp-dropdown-content'}); var $innerblock = $('<div>', {'class': 'cp-dropdown-content'});
@ -2203,7 +2213,9 @@ define([
if (config.isSelect && value) { if (config.isSelect && value) {
var $val = $innerblock.find('[data-value="'+value+'"]'); var $val = $innerblock.find('[data-value="'+value+'"]');
setActive($val); setActive($val);
try {
$innerblock.scrollTop($val.position().top + $innerblock.scrollTop()); $innerblock.scrollTop($val.position().top + $innerblock.scrollTop());
} catch (e) {}
} }
if (config.feedback) { Feedback.send(config.feedback); } if (config.feedback) { Feedback.send(config.feedback); }
}; };
@ -2849,6 +2861,7 @@ define([
}); });
}; };
/*
UIElements.setExpirationValue = function (val, $expire) { UIElements.setExpirationValue = function (val, $expire) {
if (val && typeof (val) === "number") { if (val && typeof (val) === "number") {
$expire.find('#cp-creation-expire').attr('checked', true).trigger('change'); $expire.find('#cp-creation-expire').attr('checked', true).trigger('change');
@ -2872,6 +2885,7 @@ define([
$expire.find('#cp-creation-expire-false').attr('checked', true); $expire.find('#cp-creation-expire-false').attr('checked', true);
} }
}; };
*/
UIElements.getPadCreationScreen = function (common, cfg, appCfg, cb) { UIElements.getPadCreationScreen = function (common, cfg, appCfg, cb) {
appCfg = appCfg || {}; appCfg = appCfg || {};
if (!common.isLoggedIn()) { return void cb(); } if (!common.isLoggedIn()) { return void cb(); }
@ -3184,10 +3198,12 @@ define([
// Initial values // Initial values
/*
if (!cfg.owned && typeof cfg.owned !== "undefined") { if (!cfg.owned && typeof cfg.owned !== "undefined") {
$creation.find('#cp-creation-owned').prop('checked', false); $creation.find('#cp-creation-owned').prop('checked', false);
} }
UIElements.setExpirationValue(cfg.expire, $creation); UIElements.setExpirationValue(cfg.expire, $creation);
*/
// Create the pad // Create the pad
var getFormValues = function () { var getFormValues = function () {
@ -3537,6 +3553,11 @@ define([
link link
]); ]);
var dismiss = function () {
common.mailbox.dismiss(data, function (err) {
console.log(err);
});
};
var answer = function (yes) { var answer = function (yes) {
common.mailbox.sendTo("ADD_OWNER_ANSWER", { common.mailbox.sendTo("ADD_OWNER_ANSWER", {
channel: msg.content.channel, channel: msg.content.channel,
@ -3548,9 +3569,7 @@ define([
channel: msg.content.user.notifications, channel: msg.content.user.notifications,
curvePublic: msg.content.user.curvePublic curvePublic: msg.content.user.curvePublic
}); });
common.mailbox.dismiss(data, function (err) { dismiss();
console.log(err);
});
}; };
var todo = function (yes) { var todo = function (yes) {
@ -3565,6 +3584,8 @@ define([
if (err) { if (err) {
var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden
: Messages.error; : Messages.error;
console.error(err);
dismiss();
return void UI.warn(text); return void UI.warn(text);
} }
UI.log(Messages.saved); UI.log(Messages.saved);

@ -945,6 +945,7 @@ define([
// Ctrl+A select all // Ctrl+A select all
if (e.which === 65 && (e.ctrlKey || (e.metaKey && APP.isMac))) { if (e.which === 65 && (e.ctrlKey || (e.metaKey && APP.isMac))) {
e.preventDefault();
$content.find('.cp-app-drive-element:not(.cp-app-drive-element-selected)') $content.find('.cp-app-drive-element:not(.cp-app-drive-element-selected)')
.each(function (idx, element) { .each(function (idx, element) {
selectElement($(element)); selectElement($(element));
@ -4204,7 +4205,8 @@ define([
if (!manager.isSharedFolder(el)) { if (!manager.isSharedFolder(el)) {
name = path.path[path.path.length - 1]; name = path.path[path.path.length - 1];
folderEl = el; folderEl = el;
downloadFolder(folderEl, name); var sfId = manager.isInSharedFolder(path.path);
downloadFolder(folderEl, name, sfId);
} }
// shared folder // shared folder
else { else {

@ -804,7 +804,7 @@ define([
id: 'cp-app-prop-change-password', id: 'cp-app-prop-change-password',
style: 'flex: 1;' style: 'flex: 1;'
}); });
var passwordOk = h('button', Messages.properties_changePasswordButton); var passwordOk = h('button.btn', Messages.properties_changePasswordButton);
var changePass = h('span.cp-password-change-container', [ var changePass = h('span.cp-password-change-container', [
newPassword, newPassword,
passwordOk passwordOk

@ -499,7 +499,7 @@ define([
}, 500); }, 500);
progress(0, 0);*/ progress(0, 0);*/
}).nThen(function () { }).nThen(function () {
Realtime.whenRealtimeSyncs(store.realtime, Util.bake(cb)); Realtime.whenRealtimeSyncs(store.realtime, Util.mkAsync(Util.bake(cb)));
}); });
}; };
}); });

@ -83,7 +83,6 @@ define([
}; };
// Share pad // Share pad
handlers['SHARE_PAD'] = function(common, data) { handlers['SHARE_PAD'] = function(common, data) {
var content = data.content; var content = data.content;
var msg = content.msg; var msg = content.msg;
@ -91,10 +90,22 @@ define([
var key = type === 'drive' ? 'notification_folderShared' : var key = type === 'drive' ? 'notification_folderShared' :
(type === 'file' ? 'notification_fileShared' : (type === 'file' ? 'notification_fileShared' :
'notification_padShared'); 'notification_padShared');
var teamNotification = /^team-/.test(data.type) && Number(data.type.slice(5));
var teamName = '';
if (teamNotification) {
var privateData = common.getMetadataMgr().getPrivateData();
var teamsData = Util.tryParse(JSON.stringify(privateData.teams)) || {};
var team = teamsData[teamNotification];
if (!team || !team.name) { return; }
key += "Team";
teamName = Util.fixHTML(team.name);
}
var name = Util.fixHTML(msg.content.name) || Messages.anonymous; var name = Util.fixHTML(msg.content.name) || Messages.anonymous;
var title = Util.fixHTML(msg.content.title); var title = Util.fixHTML(msg.content.title);
content.getFormatText = function() { content.getFormatText = function() {
return Messages._getKey(key, [name, title]); return Messages._getKey(key, [name, title, teamName]);
}; };
content.handler = function() { content.handler = function() {
var todo = function() { var todo = function() {
@ -105,6 +116,9 @@ define([
if (msg.content.isTemplate) { if (msg.content.isTemplate) {
common.sessionStorage.put(Constants.newPadPathKey, ['template'], waitFor()); common.sessionStorage.put(Constants.newPadPathKey, ['template'], waitFor());
} }
if (teamNotification) {
common.sessionStorage.put(Constants.newPadTeamKey, teamNotification, waitFor());
}
common.sessionStorage.put('newPadPassword', msg.content.password || '', waitFor()); common.sessionStorage.put('newPadPassword', msg.content.password || '', waitFor());
}).nThen(function() { }).nThen(function() {
todo(); todo();

@ -56,6 +56,7 @@ define([
var DISPLAY_RESTORE_BUTTON = false; var DISPLAY_RESTORE_BUTTON = false;
var NEW_VERSION = 2; var NEW_VERSION = 2;
var PENDING_TIMEOUT = 30000; var PENDING_TIMEOUT = 30000;
var READ_ONLY_REFRESH_DATA_DELAY = 15000;
var debug = function (x) { var debug = function (x) {
if (!window.CP_DEV_MODE) { return; } if (!window.CP_DEV_MODE) { return; }
@ -122,7 +123,6 @@ define([
if (!state && !readOnly) { if (!state && !readOnly) {
$('#cp-app-oo-editor').append(h('div#cp-app-oo-offline')); $('#cp-app-oo-editor').append(h('div#cp-app-oo-offline'));
} }
debug(state);
}; };
var deleteOffline = function () { var deleteOffline = function () {
@ -506,6 +506,87 @@ define([
}, to); }, to);
}; };
var loadInitDocument = function (type, useNewDefault) {
var newText;
switch (type) {
case 'sheet' :
newText = EmptyCell(useNewDefault);
break;
case 'oodoc':
newText = EmptyDoc();
break;
case 'ooslide':
newText = EmptySlide();
break;
default:
newText = '';
}
return new Blob([newText], {type: 'text/plain'});
};
var loadLastDocument = function (lastCp, onCpError, cb) {
ooChannel.cpIndex = lastCp.index || 0;
var parsed = Hash.parsePadUrl(lastCp.file);
var secret = Hash.getSecrets('file', parsed.hash);
if (!secret || !secret.channel) { return; }
var hexFileName = secret.channel;
var fileHost = privateData.fileHost || privateData.origin;
var src = fileHost + Hash.getBlobPathFromHex(hexFileName);
var key = secret.keys && secret.keys.cryptKey;
var xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (/^4/.test('' + this.status)) {
onCpError();
return void console.error('XHR error', this.status);
}
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var u8 = new Uint8Array(arrayBuffer);
FileCrypto.decrypt(u8, key, function (err, decrypted) {
if (err) { return void console.error(err); }
var blob = new Blob([decrypted.content], {type: 'plain/text'});
if (cb) {
return cb(blob, getFileType());
}
startOO(blob, getFileType());
});
}
};
xhr.onerror = function () {
onCpError();
};
xhr.send(null);
};
var refreshReadOnly = function () {
var cancel = h('button.cp-corner-cancel', Messages.cancel);
var reload = h('button.cp-corner-primary', [
h('i.fa.fa-refresh'),
Messages.oo_refresh
]);
var actions = h('div', [cancel, reload]);
var m = UI.cornerPopup(Messages.oo_refreshText, actions, '');
$(reload).click(function () {
ooChannel.ready = false;
var lastCp = getLastCp();
loadLastDocument(lastCp, function () {
var file = getFileType();
var type = common.getMetadataMgr().getPrivateData().ooType;
var blob = loadInitDocument(type, true);
resetData(blob, file);
}, function (blob, file) {
resetData(blob, file);
});
delete APP.refreshPopup;
m.delete();
});
$(cancel).click(function () {
delete APP.refreshPopup;
m.delete();
});
};
var openRtChannel = function (cb) { var openRtChannel = function (cb) {
if (rtChannel.ready) { return void cb(); } if (rtChannel.ready) { return void cb(); }
@ -529,6 +610,18 @@ define([
break; break;
case 'MESSAGE': case 'MESSAGE':
if (ooChannel.ready) { if (ooChannel.ready) {
// In read-only mode, push the message to the queue and prompt
// the user to refresh OO (without reloading the page)
if (readOnly) {
ooChannel.queue.push(obj.data);
if (APP.refreshPopup) { return; }
APP.refreshPopup = true;
// Don't "spam" the user instantly and no more than
// 1 popup every 15s
setTimeout(refreshReadOnly, READ_ONLY_REFRESH_DATA_DELAY);
return;
}
ooChannel.send(obj.data.msg); ooChannel.send(obj.data.msg);
ooChannel.lastHash = obj.data.hash; ooChannel.lastHash = obj.data.hash;
ooChannel.cpIndex++; ooChannel.cpIndex++;
@ -986,8 +1079,10 @@ define([
ooChannel.queue.forEach(function (data) { ooChannel.queue.forEach(function (data) {
ooChannel.send(data.msg); ooChannel.send(data.msg);
}); });
if (!readOnly) {
var last = ooChannel.queue.pop(); var last = ooChannel.queue.pop();
if (last) { ooChannel.lastHash = last.hash; } if (last) { ooChannel.lastHash = last.hash; }
}
ooChannel.cpIndex += ooChannel.queue.length; ooChannel.cpIndex += ooChannel.queue.length;
// Apply existing locks // Apply existing locks
deleteOfflineLocks(); deleteOfflineLocks();
@ -1018,7 +1113,7 @@ define([
UI.openCustomModal(UI.dialog.customModal(div, {buttons: []})); UI.openCustomModal(UI.dialog.customModal(div, {buttons: []}));
setTimeout(function () { setTimeout(function () {
makeCheckpoint(true); makeCheckpoint(true);
}, 1000); }, 5000);
} }
} }
} }
@ -1028,6 +1123,9 @@ define([
if (ifr) { ifr.remove(); } if (ifr) { ifr.remove(); }
}; };
APP.UploadImageFiles = function (files, type, id, jwt, cb) {
cb('NO');
};
APP.AddImage = function(cb1, cb2) { APP.AddImage = function(cb1, cb2) {
APP.AddImageSuccessCallback = cb1; APP.AddImageSuccessCallback = cb1;
APP.AddImageErrorCallback = cb2; APP.AddImageErrorCallback = cb2;
@ -1447,41 +1545,6 @@ define([
}, 100); }, 100);
}; };
var loadLastDocument = function (lastCp, onCpError, cb) {
ooChannel.cpIndex = lastCp.index || 0;
var parsed = Hash.parsePadUrl(lastCp.file);
var secret = Hash.getSecrets('file', parsed.hash);
if (!secret || !secret.channel) { return; }
var hexFileName = secret.channel;
var fileHost = privateData.fileHost || privateData.origin;
var src = fileHost + Hash.getBlobPathFromHex(hexFileName);
var key = secret.keys && secret.keys.cryptKey;
var xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (/^4/.test('' + this.status)) {
onCpError();
return void console.error('XHR error', this.status);
}
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var u8 = new Uint8Array(arrayBuffer);
FileCrypto.decrypt(u8, key, function (err, decrypted) {
if (err) { return void console.error(err); }
var blob = new Blob([decrypted.content], {type: 'plain/text'});
if (cb) {
return cb(blob, getFileType());
}
startOO(blob, getFileType());
});
}
};
xhr.onerror = function () {
onCpError();
};
xhr.send(null);
};
var loadDocument = function (noCp, useNewDefault, i) { var loadDocument = function (noCp, useNewDefault, i) {
if (ooLoaded) { return; } if (ooLoaded) { return; }
var type = common.getMetadataMgr().getPrivateData().ooType; var type = common.getMetadataMgr().getPrivateData().ooType;
@ -1511,7 +1574,7 @@ define([
default: default:
newText = ''; newText = '';
} }
var blob = new Blob([newText], {type: 'text/plain'}); var blob = loadInitDocument(type, useNewDefault);
startOO(blob, file); startOO(blob, file);
}; };
@ -1788,10 +1851,10 @@ define([
var latest = getLastCp(true); var latest = getLastCp(true);
var newLatest = getLastCp(); var newLatest = getLastCp();
if (newLatest.index > latest.index) { if (newLatest.index > latest.index) {
ooChannel.queue = [];
var hasDrawings = checkDrawings(); var hasDrawings = checkDrawings();
if (hasDrawings) { if (hasDrawings) {
ooChannel.ready = false; ooChannel.ready = false;
ooChannel.queue = [];
} }
// New checkpoint // New checkpoint
sframeChan.query('Q_OO_SAVE', { sframeChan.query('Q_OO_SAVE', {

@ -624,10 +624,10 @@ url+'" method="POST" enctype="multipart/form-data"><input id="apiiuFile" name="a
ValidateUploadImage(e.target.files);if(c_oAscServerError.NoError!=nError){callbackOld(mapAscServerErrorToAscError(nError));return}}callbackOld(Asc.c_oAscError.ID.No);fileSubmit.click()}}if(AscBrowser.isOpera)setTimeout(function(){fileName.click()},0);else fileName.click()}function InitDragAndDrop(oHtmlElement,callback){if("undefined"!=typeof FileReader&&null!=oHtmlElement){oHtmlElement["ondragover"]=function(e){e.preventDefault();e.dataTransfer.dropEffect=CanDropFiles(e)?"copy":"none";if(e.dataTransfer.dropEffect== ValidateUploadImage(e.target.files);if(c_oAscServerError.NoError!=nError){callbackOld(mapAscServerErrorToAscError(nError));return}}callbackOld(Asc.c_oAscError.ID.No);fileSubmit.click()}}if(AscBrowser.isOpera)setTimeout(function(){fileName.click()},0);else fileName.click()}function InitDragAndDrop(oHtmlElement,callback){if("undefined"!=typeof FileReader&&null!=oHtmlElement){oHtmlElement["ondragover"]=function(e){e.preventDefault();e.dataTransfer.dropEffect=CanDropFiles(e)?"copy":"none";if(e.dataTransfer.dropEffect==
"copy"){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.beginInlineDropTarget(e)}return false};oHtmlElement["ondrop"]=function(e){e.preventDefault();var files=e.dataTransfer.files;var nError=ValidateUploadImage(files);var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.endInlineDropTarget(e);if(nError==c_oAscServerError.UploadCountFiles){try{var htmlValue=e.dataTransfer.getData("text/html");if(htmlValue&&!AscCommon.AscBrowser.isIE){var index= "copy"){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.beginInlineDropTarget(e)}return false};oHtmlElement["ondrop"]=function(e){e.preventDefault();var files=e.dataTransfer.files;var nError=ValidateUploadImage(files);var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.endInlineDropTarget(e);if(nError==c_oAscServerError.UploadCountFiles){try{var htmlValue=e.dataTransfer.getData("text/html");if(htmlValue&&!AscCommon.AscBrowser.isIE){var index=
htmlValue.indexOf("StartHTML");var indexHtml=htmlValue.indexOf("<html");if(-1==indexHtml)indexHtml=htmlValue.indexOf("<HTML");if(index>0&&indexHtml>0&&index<indexHtml)htmlValue=htmlValue.substr(indexHtml);editor["pluginMethod_PasteHtml"](htmlValue);return}}catch(err){}try{var textValue=e.dataTransfer.getData("text/plain");if(textValue){editor["pluginMethod_PasteText"](textValue);return}}catch(err$11){}try{var textValue=e.dataTransfer.getData("Text");if(textValue){editor["pluginMethod_PasteText"](textValue); htmlValue.indexOf("StartHTML");var indexHtml=htmlValue.indexOf("<html");if(-1==indexHtml)indexHtml=htmlValue.indexOf("<HTML");if(index>0&&indexHtml>0&&index<indexHtml)htmlValue=htmlValue.substr(indexHtml);editor["pluginMethod_PasteHtml"](htmlValue);return}}catch(err){}try{var textValue=e.dataTransfer.getData("text/plain");if(textValue){editor["pluginMethod_PasteText"](textValue);return}}catch(err$11){}try{var textValue=e.dataTransfer.getData("Text");if(textValue){editor["pluginMethod_PasteText"](textValue);
return}}catch(err$12){}}callback(mapAscServerErrorToAscError(nError),files)}}}function UploadImageFiles(files,documentId,documentUserId,jwt,callback){window.parent.APP.UploadImageFiles(files,documentId,documentUserId,jwt,callback);return;if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls= return}}catch(err$12){}}callback(mapAscServerErrorToAscError(nError),files)}}}function UploadImageFiles(files,documentId,documentUserId,jwt,callback){window.parent.APP.UploadImageFiles(files,documentId,documentUserId,jwt,function(err,urls){callback(err||Asc.c_oAscError.ID.No,urls)});return;if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);
[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push(urls[i]);break}if(aFiles.length===0)callback(Asc.c_oAscError.ID.No,aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt); var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push(urls[i]);break}if(aFiles.length===0)callback(Asc.c_oAscError.ID.No,aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+=
xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback(Asc.c_oAscError.ID.UplImageFileCount)};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function UploadImageUrls(files,documentId,documentUserId, "?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback(Asc.c_oAscError.ID.UplImageFileCount)};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function UploadImageUrls(files,
jwt,callback){if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push({path:i, documentId,documentUserId,jwt,callback){if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push({path:i,
url:urls[i]});break}if(aFiles.length===0)callback(aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback([])};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type", url:urls[i]});break}if(aFiles.length===0)callback(aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback([])};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",
file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function ValidateUploadImage(files){var nRes=c_oAscServerError.NoError;if(files.length>0)for(var i=0,length=files.length;i<length;i++){var file=files[i];var sName=file.fileName||file.name;if(sName){var bSupported=false;var ext=GetFileExtension(sName);if(null!==ext)for(var j=0,length2=c_oAscImageUploadProp.SupportedFormats.length;j<length2;j++)if(c_oAscImageUploadProp.SupportedFormats[j]== file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function ValidateUploadImage(files){var nRes=c_oAscServerError.NoError;if(files.length>0)for(var i=0,length=files.length;i<length;i++){var file=files[i];var sName=file.fileName||file.name;if(sName){var bSupported=false;var ext=GetFileExtension(sName);if(null!==ext)for(var j=0,length2=c_oAscImageUploadProp.SupportedFormats.length;j<length2;j++)if(c_oAscImageUploadProp.SupportedFormats[j]==
ext){bSupported=true;break}if(false==bSupported)nRes=c_oAscServerError.UploadExtension}if(Asc.c_oAscError.ID.No==nRes){var nSize=file.fileSize||file.size;if(nSize&&c_oAscImageUploadProp.MaxFileSize<nSize)nRes=c_oAscServerError.UploadContentLength}if(c_oAscServerError.NoError!=nRes)break}else nRes=c_oAscServerError.UploadCountFiles;return nRes}function CanDropFiles(event){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;if(!editor.isEnabledDropTarget())return false;var bRes= ext){bSupported=true;break}if(false==bSupported)nRes=c_oAscServerError.UploadExtension}if(Asc.c_oAscError.ID.No==nRes){var nSize=file.fileSize||file.size;if(nSize&&c_oAscImageUploadProp.MaxFileSize<nSize)nRes=c_oAscServerError.UploadContentLength}if(c_oAscServerError.NoError!=nRes)break}else nRes=c_oAscServerError.UploadCountFiles;return nRes}function CanDropFiles(event){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;if(!editor.isEnabledDropTarget())return false;var bRes=

@ -9413,11 +9413,11 @@ newCDocument;drawingObject.graphicObject.graphicObject.Set_Parent(newCDocument);
node,isIntoShape);else window["AscCommon"].g_specialPasteHelper.Paste_Process_End()};worksheet.objectRender.controller.checkSelectedObjectsAndCallback2(callback);return}if(copyPasteUseBinary){this.activeRange=worksheet.model.selectionRange.getLast().clone();binaryResult=this._pasteFromBinaryClassHtml(worksheet,node,isIntoShape);if(binaryResult===true)return;else if(binaryResult!==false&&binaryResult!=undefined)node=binaryResult}this.activeRange=worksheet.model.selectionRange.getLast().clone();var callBackAfterLoadImages= node,isIntoShape);else window["AscCommon"].g_specialPasteHelper.Paste_Process_End()};worksheet.objectRender.controller.checkSelectedObjectsAndCallback2(callback);return}if(copyPasteUseBinary){this.activeRange=worksheet.model.selectionRange.getLast().clone();binaryResult=this._pasteFromBinaryClassHtml(worksheet,node,isIntoShape);if(binaryResult===true)return;else if(binaryResult!==false&&binaryResult!=undefined)node=binaryResult}this.activeRange=worksheet.model.selectionRange.getLast().clone();var callBackAfterLoadImages=
function(){History.TurnOff();var oTempDrawingDocument=worksheet.model.DrawingDocument;var newCDocument=new CDocument(oTempDrawingDocument,false);newCDocument.bFromDocument=true;newCDocument.Content[0].bFromDocument=true;newCDocument.theme=window["Asc"]["editor"].wbModel.theme;var oOldLogicDocument=oTempDrawingDocument.m_oLogicDocument;oTempDrawingDocument.m_oLogicDocument=newCDocument;var oOldEditor=undefined;if("undefined"!==typeof editor)oOldEditor=editor;editor={WordControl:oTempDrawingDocument, function(){History.TurnOff();var oTempDrawingDocument=worksheet.model.DrawingDocument;var newCDocument=new CDocument(oTempDrawingDocument,false);newCDocument.bFromDocument=true;newCDocument.Content[0].bFromDocument=true;newCDocument.theme=window["Asc"]["editor"].wbModel.theme;var oOldLogicDocument=oTempDrawingDocument.m_oLogicDocument;oTempDrawingDocument.m_oLogicDocument=newCDocument;var oOldEditor=undefined;if("undefined"!==typeof editor)oOldEditor=editor;editor={WordControl:oTempDrawingDocument,
isDocumentEditor:true};var oPasteProcessor=new AscCommon.PasteProcessor({WordControl:{m_oLogicDocument:newCDocument},FontLoader:{}},false,false);oPasteProcessor._Prepeare_recursive(node,true,true);if(window["AscCommon"].g_specialPasteHelper.specialPasteStart&&window["AscCommon"].g_specialPasteHelper.specialPasteData.aContent)oPasteProcessor.aContent=window["AscCommon"].g_specialPasteHelper.specialPasteData.aContent;else{oPasteProcessor._Execute(node,{},true,true,false);window["AscCommon"].g_specialPasteHelper.specialPasteData.aContent= isDocumentEditor:true};var oPasteProcessor=new AscCommon.PasteProcessor({WordControl:{m_oLogicDocument:newCDocument},FontLoader:{}},false,false);oPasteProcessor._Prepeare_recursive(node,true,true);if(window["AscCommon"].g_specialPasteHelper.specialPasteStart&&window["AscCommon"].g_specialPasteHelper.specialPasteData.aContent)oPasteProcessor.aContent=window["AscCommon"].g_specialPasteHelper.specialPasteData.aContent;else{oPasteProcessor._Execute(node,{},true,true,false);window["AscCommon"].g_specialPasteHelper.specialPasteData.aContent=
oPasteProcessor.aContent}editor=oOldEditor;oTempDrawingDocument.m_oLogicDocument=oOldLogicDocument;History.TurnOn();var oPasteFromBinaryWord=new pasteFromBinaryWord(t,worksheet);oPasteFromBinaryWord._paste(worksheet,{content:oPasteProcessor.aContent})};var aImagesToDownload=this._getImageFromHtml(node,true);var specialPasteProps=window["AscCommon"].g_specialPasteHelper.specialPasteProps;if(aImagesToDownload!==null&&(!specialPasteProps||specialPasteProps&&specialPasteProps.images)){var api=Asc["editor"]; oPasteProcessor.aContent}editor=oOldEditor;oTempDrawingDocument.m_oLogicDocument=oOldLogicDocument;History.TurnOn();var oPasteFromBinaryWord=new pasteFromBinaryWord(t,worksheet);oPasteFromBinaryWord._paste(worksheet,{content:oPasteProcessor.aContent})};var aImagesToDownload=this._getImageFromHtml(node,true);if(aImagesToDownload)return;var specialPasteProps=window["AscCommon"].g_specialPasteHelper.specialPasteProps;if(aImagesToDownload!==null&&(!specialPasteProps||specialPasteProps&&specialPasteProps.images)){var api=
AscCommon.sendImgUrls(api,aImagesToDownload,function(data){for(var i=0,length=Math.min(data.length,aImagesToDownload.length);i<length;++i){var elem=data[i];var sFrom=aImagesToDownload[i];if(null!=elem.url)t.oImages[sFrom]=AscCommon.g_oDocumentUrls.imagePath2Local(elem.path);else t.oImages[sFrom]=sFrom}t.alreadyLoadImagesOnServer=true;callBackAfterLoadImages()},true)}else callBackAfterLoadImages()},_pasteFromBinaryClassHtml:function(worksheet,node,isIntoShape){var base64=null,base64FromWord=null,base64FromPresentation= Asc["editor"];AscCommon.sendImgUrls(api,aImagesToDownload,function(data){for(var i=0,length=Math.min(data.length,aImagesToDownload.length);i<length;++i){var elem=data[i];var sFrom=aImagesToDownload[i];if(null!=elem.url)t.oImages[sFrom]=AscCommon.g_oDocumentUrls.imagePath2Local(elem.path);else t.oImages[sFrom]=sFrom}t.alreadyLoadImagesOnServer=true;callBackAfterLoadImages()},true)}else callBackAfterLoadImages()},_pasteFromBinaryClassHtml:function(worksheet,node,isIntoShape){var base64=null,base64FromWord=
null,t=this;var returnBinary=this._getClassBinaryFromHtml(node);base64=returnBinary.base64;base64FromWord=returnBinary.base64FromWord;base64FromPresentation=returnBinary.base64FromPresentation;var result=false;if(base64!=null)result=this._pasteFromBinaryExcel(worksheet,base64,isIntoShape);else if(base64FromWord)result=this._pasteFromBinaryWord(worksheet,base64FromWord,isIntoShape);else if(base64FromPresentation)result=this._pasteFromBinaryPresentation(worksheet,base64FromPresentation,isIntoShape); null,base64FromPresentation=null,t=this;var returnBinary=this._getClassBinaryFromHtml(node);base64=returnBinary.base64;base64FromWord=returnBinary.base64FromWord;base64FromPresentation=returnBinary.base64FromPresentation;var result=false;if(base64!=null)result=this._pasteFromBinaryExcel(worksheet,base64,isIntoShape);else if(base64FromWord)result=this._pasteFromBinaryWord(worksheet,base64FromWord,isIntoShape);else if(base64FromPresentation)result=this._pasteFromBinaryPresentation(worksheet,base64FromPresentation,
return result},_getClassBinaryFromHtml:function(node){var base64=null,base64FromWord=null,base64FromPresentation=null;var classNode=AscCommon.searchBinaryClass(node);if(classNode!=null){var cL=classNode.split(" ");for(var i=0;i<cL.length;i++)if(cL[i].indexOf("xslData;")>-1)base64=cL[i].split("xslData;")[1];else if(cL[i].indexOf("docData;")>-1)base64FromWord=cL[i].split("docData;")[1];else if(cL[i].indexOf("pptData;")>-1)base64FromPresentation=cL[i].split("pptData;")[1]}return{base64:base64,base64FromWord:base64FromWord, isIntoShape);return result},_getClassBinaryFromHtml:function(node){var base64=null,base64FromWord=null,base64FromPresentation=null;var classNode=AscCommon.searchBinaryClass(node);if(classNode!=null){var cL=classNode.split(" ");for(var i=0;i<cL.length;i++)if(cL[i].indexOf("xslData;")>-1)base64=cL[i].split("xslData;")[1];else if(cL[i].indexOf("docData;")>-1)base64FromWord=cL[i].split("docData;")[1];else if(cL[i].indexOf("pptData;")>-1)base64FromPresentation=cL[i].split("pptData;")[1]}return{base64:base64,
base64FromPresentation:base64FromPresentation}},_getImageFromHtml:function(html,isGetUrlsArray){var res=null;if(html){var allImages=html.getElementsByTagName("img");if(allImages&&allImages.length)if(isGetUrlsArray){var arrayImages=[];for(var i=0;i<allImages.length;i++)arrayImages[i]=allImages[i].src;res=arrayImages}else res=allImages}return res},_getBinaryColor:function(c){var bin,m,x,type,r,g,b,a,s;var reColor=/^\s*(?:#?([0-9a-f]{6})|#?([0-9a-f]{3})|rgba?\s*\(\s*((?:\d*\.?\d+)(?:\s*,\s*(?:\d*\.?\d+)){2,3})\s*\))\s*$/i; base64FromWord:base64FromWord,base64FromPresentation:base64FromPresentation}},_getImageFromHtml:function(html,isGetUrlsArray){var res=null;if(html){var allImages=html.getElementsByTagName("img");if(allImages&&allImages.length)if(isGetUrlsArray){var arrayImages=[];for(var i=0;i<allImages.length;i++)arrayImages[i]=allImages[i].src;res=arrayImages}else res=allImages}return res},_getBinaryColor:function(c){var bin,m,x,type,r,g,b,a,s;var reColor=/^\s*(?:#?([0-9a-f]{6})|#?([0-9a-f]{3})|rgba?\s*\(\s*((?:\d*\.?\d+)(?:\s*,\s*(?:\d*\.?\d+)){2,3})\s*\))\s*$/i;
if(typeof c==="number")bin=c;else{m=reColor.exec(c);if(!m)return null;if(m[1]){x=[m[1].slice(0,2),m[1].slice(2,4),m[1].slice(4)];type=1}else if(m[2]){x=[m[2].slice(0,1),m[2].slice(1,2),m[2].slice(2)];type=0}else{x=m[3].split(/\s*,\s*/i);type=x.length===3?2:3}r=parseInt(type!==0?x[0]:x[0]+x[0],type<2?16:10);g=parseInt(type!==0?x[1]:x[1]+x[1],type<2?16:10);b=parseInt(type!==0?x[2]:x[2]+x[2],type<2?16:10);a=type===3?Math.round(parseFloat(x[3])*100)*.01:1;bin=r<<16|g<<8|b}return bin},_checkMaxTextLength:function(aResult, if(typeof c==="number")bin=c;else{m=reColor.exec(c);if(!m)return null;if(m[1]){x=[m[1].slice(0,2),m[1].slice(2,4),m[1].slice(4)];type=1}else if(m[2]){x=[m[2].slice(0,1),m[2].slice(1,2),m[2].slice(2)];type=0}else{x=m[3].split(/\s*,\s*/i);type=x.length===3?2:3}r=parseInt(type!==0?x[0]:x[0]+x[0],type<2?16:10);g=parseInt(type!==0?x[1]:x[1]+x[1],type<2?16:10);b=parseInt(type!==0?x[2]:x[2]+x[2],type<2?16:10);a=type===3?Math.round(parseFloat(x[3])*100)*.01:1;bin=r<<16|g<<8|b}return bin},_checkMaxTextLength:function(aResult,
r,c){var result=false;var isChange=false;var currentCellData=aResult.content[r][c];if(currentCellData&&currentCellData.content){currentCellData=currentCellData.content;for(var i=0;i<currentCellData.length;i++)if(currentCellData[i]&&currentCellData[i].text&&currentCellData[i].text.length>c_oAscMaxCellOrCommentLength){isChange=true;var text=currentCellData[i].text;var format=currentCellData[i].format;var lengthOfText=text.length;var iterCount=Math.ceil(lengthOfText/c_oAscMaxCellOrCommentLength);var splitText; r,c){var result=false;var isChange=false;var currentCellData=aResult.content[r][c];if(currentCellData&&currentCellData.content){currentCellData=currentCellData.content;for(var i=0;i<currentCellData.length;i++)if(currentCellData[i]&&currentCellData[i].text&&currentCellData[i].text.length>c_oAscMaxCellOrCommentLength){isChange=true;var text=currentCellData[i].text;var format=currentCellData[i].format;var lengthOfText=text.length;var iterCount=Math.ceil(lengthOfText/c_oAscMaxCellOrCommentLength);var splitText;
for(var j=0;j<iterCount;j++){splitText=text.substr(c_oAscMaxCellOrCommentLength*j,c_oAscMaxCellOrCommentLength*(j+1));if(!aResult.content[r])aResult.content[r]=[];if(!aResult.content[r][c])aResult.content[r][c]=[];if(!aResult.content[r][c].content)aResult.content[r][c].content=[];aResult.content[r][c].content[0]={format:format,text:splitText};if(iterCount!==j+1)r++}}if(isChange)result={aResult:aResult,r:r,c:c}}return result},_getBorderStyleName:function(borderStyle,borderWidth){var res=null;var nBorderWidth= for(var j=0;j<iterCount;j++){splitText=text.substr(c_oAscMaxCellOrCommentLength*j,c_oAscMaxCellOrCommentLength*(j+1));if(!aResult.content[r])aResult.content[r]=[];if(!aResult.content[r][c])aResult.content[r][c]=[];if(!aResult.content[r][c].content)aResult.content[r][c].content=[];aResult.content[r][c].content[0]={format:format,text:splitText};if(iterCount!==j+1)r++}}if(isChange)result={aResult:aResult,r:r,c:c}}return result},_getBorderStyleName:function(borderStyle,borderWidth){var res=null;var nBorderWidth=

@ -622,10 +622,10 @@ url+'" method="POST" enctype="multipart/form-data"><input id="apiiuFile" name="a
ValidateUploadImage(e.target.files);if(c_oAscServerError.NoError!=nError){callbackOld(mapAscServerErrorToAscError(nError));return}}callbackOld(Asc.c_oAscError.ID.No);fileSubmit.click()}}if(AscBrowser.isOpera)setTimeout(function(){fileName.click()},0);else fileName.click()}function InitDragAndDrop(oHtmlElement,callback){if("undefined"!=typeof FileReader&&null!=oHtmlElement){oHtmlElement["ondragover"]=function(e){e.preventDefault();e.dataTransfer.dropEffect=CanDropFiles(e)?"copy":"none";if(e.dataTransfer.dropEffect== ValidateUploadImage(e.target.files);if(c_oAscServerError.NoError!=nError){callbackOld(mapAscServerErrorToAscError(nError));return}}callbackOld(Asc.c_oAscError.ID.No);fileSubmit.click()}}if(AscBrowser.isOpera)setTimeout(function(){fileName.click()},0);else fileName.click()}function InitDragAndDrop(oHtmlElement,callback){if("undefined"!=typeof FileReader&&null!=oHtmlElement){oHtmlElement["ondragover"]=function(e){e.preventDefault();e.dataTransfer.dropEffect=CanDropFiles(e)?"copy":"none";if(e.dataTransfer.dropEffect==
"copy"){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.beginInlineDropTarget(e)}return false};oHtmlElement["ondrop"]=function(e){e.preventDefault();var files=e.dataTransfer.files;var nError=ValidateUploadImage(files);var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.endInlineDropTarget(e);if(nError==c_oAscServerError.UploadCountFiles){try{var htmlValue=e.dataTransfer.getData("text/html");if(htmlValue&&!AscCommon.AscBrowser.isIE){var index= "copy"){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.beginInlineDropTarget(e)}return false};oHtmlElement["ondrop"]=function(e){e.preventDefault();var files=e.dataTransfer.files;var nError=ValidateUploadImage(files);var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.endInlineDropTarget(e);if(nError==c_oAscServerError.UploadCountFiles){try{var htmlValue=e.dataTransfer.getData("text/html");if(htmlValue&&!AscCommon.AscBrowser.isIE){var index=
htmlValue.indexOf("StartHTML");var indexHtml=htmlValue.indexOf("<html");if(-1==indexHtml)indexHtml=htmlValue.indexOf("<HTML");if(index>0&&indexHtml>0&&index<indexHtml)htmlValue=htmlValue.substr(indexHtml);editor["pluginMethod_PasteHtml"](htmlValue);return}}catch(err){}try{var textValue=e.dataTransfer.getData("text/plain");if(textValue){editor["pluginMethod_PasteText"](textValue);return}}catch(err$16){}try{var textValue=e.dataTransfer.getData("Text");if(textValue){editor["pluginMethod_PasteText"](textValue); htmlValue.indexOf("StartHTML");var indexHtml=htmlValue.indexOf("<html");if(-1==indexHtml)indexHtml=htmlValue.indexOf("<HTML");if(index>0&&indexHtml>0&&index<indexHtml)htmlValue=htmlValue.substr(indexHtml);editor["pluginMethod_PasteHtml"](htmlValue);return}}catch(err){}try{var textValue=e.dataTransfer.getData("text/plain");if(textValue){editor["pluginMethod_PasteText"](textValue);return}}catch(err$16){}try{var textValue=e.dataTransfer.getData("Text");if(textValue){editor["pluginMethod_PasteText"](textValue);
return}}catch(err$17){}}callback(mapAscServerErrorToAscError(nError),files)}}}function UploadImageFiles(files,documentId,documentUserId,jwt,callback){window.parent.APP.UploadImageFiles(files,documentId,documentUserId,jwt,callback);return;if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls= return}}catch(err$17){}}callback(mapAscServerErrorToAscError(nError),files)}}}function UploadImageFiles(files,documentId,documentUserId,jwt,callback){window.parent.APP.UploadImageFiles(files,documentId,documentUserId,jwt,function(err,urls){callback(err||Asc.c_oAscError.ID.No,urls)});return;if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);
[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push(urls[i]);break}if(aFiles.length===0)callback(Asc.c_oAscError.ID.No,aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt); var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push(urls[i]);break}if(aFiles.length===0)callback(Asc.c_oAscError.ID.No,aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+=
xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback(Asc.c_oAscError.ID.UplImageFileCount)};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function UploadImageUrls(files,documentId,documentUserId, "?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback(Asc.c_oAscError.ID.UplImageFileCount)};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function UploadImageUrls(files,
jwt,callback){if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push({path:i, documentId,documentUserId,jwt,callback){if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push({path:i,
url:urls[i]});break}if(aFiles.length===0)callback(aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback([])};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type", url:urls[i]});break}if(aFiles.length===0)callback(aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback([])};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",
file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function ValidateUploadImage(files){var nRes=c_oAscServerError.NoError;if(files.length>0)for(var i=0,length=files.length;i<length;i++){var file=files[i];var sName=file.fileName||file.name;if(sName){var bSupported=false;var ext=GetFileExtension(sName);if(null!==ext)for(var j=0,length2=c_oAscImageUploadProp.SupportedFormats.length;j<length2;j++)if(c_oAscImageUploadProp.SupportedFormats[j]== file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function ValidateUploadImage(files){var nRes=c_oAscServerError.NoError;if(files.length>0)for(var i=0,length=files.length;i<length;i++){var file=files[i];var sName=file.fileName||file.name;if(sName){var bSupported=false;var ext=GetFileExtension(sName);if(null!==ext)for(var j=0,length2=c_oAscImageUploadProp.SupportedFormats.length;j<length2;j++)if(c_oAscImageUploadProp.SupportedFormats[j]==
ext){bSupported=true;break}if(false==bSupported)nRes=c_oAscServerError.UploadExtension}if(Asc.c_oAscError.ID.No==nRes){var nSize=file.fileSize||file.size;if(nSize&&c_oAscImageUploadProp.MaxFileSize<nSize)nRes=c_oAscServerError.UploadContentLength}if(c_oAscServerError.NoError!=nRes)break}else nRes=c_oAscServerError.UploadCountFiles;return nRes}function CanDropFiles(event){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;if(!editor.isEnabledDropTarget())return false;var bRes= ext){bSupported=true;break}if(false==bSupported)nRes=c_oAscServerError.UploadExtension}if(Asc.c_oAscError.ID.No==nRes){var nSize=file.fileSize||file.size;if(nSize&&c_oAscImageUploadProp.MaxFileSize<nSize)nRes=c_oAscServerError.UploadContentLength}if(c_oAscServerError.NoError!=nRes)break}else nRes=c_oAscServerError.UploadCountFiles;return nRes}function CanDropFiles(event){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;if(!editor.isEnabledDropTarget())return false;var bRes=

@ -622,10 +622,10 @@ url+'" method="POST" enctype="multipart/form-data"><input id="apiiuFile" name="a
ValidateUploadImage(e.target.files);if(c_oAscServerError.NoError!=nError){callbackOld(mapAscServerErrorToAscError(nError));return}}callbackOld(Asc.c_oAscError.ID.No);fileSubmit.click()}}if(AscBrowser.isOpera)setTimeout(function(){fileName.click()},0);else fileName.click()}function InitDragAndDrop(oHtmlElement,callback){if("undefined"!=typeof FileReader&&null!=oHtmlElement){oHtmlElement["ondragover"]=function(e){e.preventDefault();e.dataTransfer.dropEffect=CanDropFiles(e)?"copy":"none";if(e.dataTransfer.dropEffect== ValidateUploadImage(e.target.files);if(c_oAscServerError.NoError!=nError){callbackOld(mapAscServerErrorToAscError(nError));return}}callbackOld(Asc.c_oAscError.ID.No);fileSubmit.click()}}if(AscBrowser.isOpera)setTimeout(function(){fileName.click()},0);else fileName.click()}function InitDragAndDrop(oHtmlElement,callback){if("undefined"!=typeof FileReader&&null!=oHtmlElement){oHtmlElement["ondragover"]=function(e){e.preventDefault();e.dataTransfer.dropEffect=CanDropFiles(e)?"copy":"none";if(e.dataTransfer.dropEffect==
"copy"){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.beginInlineDropTarget(e)}return false};oHtmlElement["ondrop"]=function(e){e.preventDefault();var files=e.dataTransfer.files;var nError=ValidateUploadImage(files);var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.endInlineDropTarget(e);if(nError==c_oAscServerError.UploadCountFiles){try{var htmlValue=e.dataTransfer.getData("text/html");if(htmlValue&&!AscCommon.AscBrowser.isIE){var index= "copy"){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.beginInlineDropTarget(e)}return false};oHtmlElement["ondrop"]=function(e){e.preventDefault();var files=e.dataTransfer.files;var nError=ValidateUploadImage(files);var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;editor.endInlineDropTarget(e);if(nError==c_oAscServerError.UploadCountFiles){try{var htmlValue=e.dataTransfer.getData("text/html");if(htmlValue&&!AscCommon.AscBrowser.isIE){var index=
htmlValue.indexOf("StartHTML");var indexHtml=htmlValue.indexOf("<html");if(-1==indexHtml)indexHtml=htmlValue.indexOf("<HTML");if(index>0&&indexHtml>0&&index<indexHtml)htmlValue=htmlValue.substr(indexHtml);editor["pluginMethod_PasteHtml"](htmlValue);return}}catch(err){}try{var textValue=e.dataTransfer.getData("text/plain");if(textValue){editor["pluginMethod_PasteText"](textValue);return}}catch(err$1){}try{var textValue=e.dataTransfer.getData("Text");if(textValue){editor["pluginMethod_PasteText"](textValue); htmlValue.indexOf("StartHTML");var indexHtml=htmlValue.indexOf("<html");if(-1==indexHtml)indexHtml=htmlValue.indexOf("<HTML");if(index>0&&indexHtml>0&&index<indexHtml)htmlValue=htmlValue.substr(indexHtml);editor["pluginMethod_PasteHtml"](htmlValue);return}}catch(err){}try{var textValue=e.dataTransfer.getData("text/plain");if(textValue){editor["pluginMethod_PasteText"](textValue);return}}catch(err$1){}try{var textValue=e.dataTransfer.getData("Text");if(textValue){editor["pluginMethod_PasteText"](textValue);
return}}catch(err$2){}}callback(mapAscServerErrorToAscError(nError),files)}}}function UploadImageFiles(files,documentId,documentUserId,jwt,callback){window.parent.APP.UploadImageFiles(files,documentId,documentUserId,jwt,callback);return;if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls= return}}catch(err$2){}}callback(mapAscServerErrorToAscError(nError),files)}}}function UploadImageFiles(files,documentId,documentUserId,jwt,callback){window.parent.APP.UploadImageFiles(files,documentId,documentUserId,jwt,function(err,urls){callback(err||Asc.c_oAscError.ID.No,urls)});return;if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);
[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push(urls[i]);break}if(aFiles.length===0)callback(Asc.c_oAscError.ID.No,aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt); var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push(urls[i]);break}if(aFiles.length===0)callback(Asc.c_oAscError.ID.No,aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+=
xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback(Asc.c_oAscError.ID.UplImageFileCount)};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function UploadImageUrls(files,documentId,documentUserId, "?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback(Asc.c_oAscError.ID.UplImageFileCount)};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function UploadImageUrls(files,
jwt,callback){if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push({path:i, documentId,documentUserId,jwt,callback){if(files.length>0){var url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);var aFiles=[];for(var i=files.length-1;i>-1;--i)aFiles.push(files[i]);var file=aFiles.pop();var aResultUrls=[];var fOnReadyChnageState=function(){if(4==this.readyState)if(this.status==200||this.status==1223){var urls=JSON.parse(this.responseText);g_oDocumentUrls.addUrls(urls);for(var i in urls)if(urls.hasOwnProperty(i)){aResultUrls.push({path:i,
url:urls[i]});break}if(aFiles.length===0)callback(aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback([])};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type", url:urls[i]});break}if(aFiles.length===0)callback(aResultUrls);else{file=aFiles.pop();var xhr=new XMLHttpRequest;url=sUploadServiceLocalUrl+"/"+documentId+"/"+documentUserId+"/"+g_oDocumentUrls.getMaxIndex();if(jwt)url+="?token="+encodeURIComponent(jwt);xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}}else callback([])};var xhr=new XMLHttpRequest;xhr.open("POST",url,true);xhr.setRequestHeader("Content-Type",
file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function ValidateUploadImage(files){var nRes=c_oAscServerError.NoError;if(files.length>0)for(var i=0,length=files.length;i<length;i++){var file=files[i];var sName=file.fileName||file.name;if(sName){var bSupported=false;var ext=GetFileExtension(sName);if(null!==ext)for(var j=0,length2=c_oAscImageUploadProp.SupportedFormats.length;j<length2;j++)if(c_oAscImageUploadProp.SupportedFormats[j]== file.type||"application/octet-stream");xhr.onreadystatechange=fOnReadyChnageState;xhr.send(file)}else callback(Asc.c_oAscError.ID.UplImageFileCount)}function ValidateUploadImage(files){var nRes=c_oAscServerError.NoError;if(files.length>0)for(var i=0,length=files.length;i<length;i++){var file=files[i];var sName=file.fileName||file.name;if(sName){var bSupported=false;var ext=GetFileExtension(sName);if(null!==ext)for(var j=0,length2=c_oAscImageUploadProp.SupportedFormats.length;j<length2;j++)if(c_oAscImageUploadProp.SupportedFormats[j]==
ext){bSupported=true;break}if(false==bSupported)nRes=c_oAscServerError.UploadExtension}if(Asc.c_oAscError.ID.No==nRes){var nSize=file.fileSize||file.size;if(nSize&&c_oAscImageUploadProp.MaxFileSize<nSize)nRes=c_oAscServerError.UploadContentLength}if(c_oAscServerError.NoError!=nRes)break}else nRes=c_oAscServerError.UploadCountFiles;return nRes}function CanDropFiles(event){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;if(!editor.isEnabledDropTarget())return false;var bRes= ext){bSupported=true;break}if(false==bSupported)nRes=c_oAscServerError.UploadExtension}if(Asc.c_oAscError.ID.No==nRes){var nSize=file.fileSize||file.size;if(nSize&&c_oAscImageUploadProp.MaxFileSize<nSize)nRes=c_oAscServerError.UploadContentLength}if(c_oAscServerError.NoError!=nRes)break}else nRes=c_oAscServerError.UploadCountFiles;return nRes}function CanDropFiles(event){var editor=window["Asc"]["editor"]?window["Asc"]["editor"]:window.editor;if(!editor.isEnabledDropTarget())return false;var bRes=

@ -109,6 +109,17 @@ proxy.mailboxes = {
}); });
var ciphertext = crypto.encrypt(text, user.curvePublic); var ciphertext = crypto.encrypt(text, user.curvePublic);
// If we've sent this message to one of our teams' mailbox, we may want to "dismiss" it
// automatically
if (user.viewed) {
var team = Util.find(ctx, ['store', 'proxy', 'teams', user.viewed]);
if (team) {
var hash = ciphertext.slice(0,64);
var viewed = Util.find(team, ['keys', 'mailbox', 'viewed']);
if (Array.isArray(viewed)) { viewed.push(hash); }
}
}
anonRpc.send("WRITE_PRIVATE_MESSAGE", [ anonRpc.send("WRITE_PRIVATE_MESSAGE", [
user.channel, user.channel,
ciphertext ciphertext
@ -126,10 +137,9 @@ proxy.mailboxes = {
var dismiss = function (ctx, data, cId, cb) { var dismiss = function (ctx, data, cId, cb) {
var type = data.type; var type = data.type;
var hash = data.hash; var hash = data.hash;
var m = Util.find(ctx, ['store', 'proxy', 'mailboxes', type]);
if (!m) { return void cb({error: 'NOT_FOUND'}); }
var box = ctx.boxes[type]; var box = ctx.boxes[type];
if (!box) { return void cb({error: 'NOT_LOADED'}); } if (!box) { return void cb({error: 'NOT_LOADED'}); }
var m = box.data || {};
// If the hash in in our history, get the index from the history: // If the hash in in our history, get the index from the history:
// - if the index is 0, we can change our lastKnownHash // - if the index is 0, we can change our lastKnownHash
@ -191,7 +201,15 @@ proxy.mailboxes = {
}; };
var openChannel = function (ctx, type, m, onReady) { var leaveChannel = function (ctx, type, cb) {
var box = ctx.boxes[type];
if (!box) { return void cb(); }
if (!box.cpNf || typeof(box.cpNf.stop) !== "function") { return void cb('EINVAL'); }
box.cpNf.stop();
delete ctx.boxes[type];
};
var openChannel = function (ctx, type, m, onReady, opts) {
opts = opts || {};
var box = ctx.boxes[type] = { var box = ctx.boxes[type] = {
channel: m.channel, channel: m.channel,
type: type, type: type,
@ -210,7 +228,8 @@ proxy.mailboxes = {
console.error(e); console.error(e);
} }
box.queue.push(msg); box.queue.push(msg);
} },
data: m
}; };
if (!Crypto.Mailbox) { if (!Crypto.Mailbox) {
return void console.error("chainpad-crypto is outdated and doesn't support mailboxes."); return void console.error("chainpad-crypto is outdated and doesn't support mailboxes.");
@ -224,7 +243,7 @@ proxy.mailboxes = {
channel: m.channel, channel: m.channel,
noChainPad: true, noChainPad: true,
crypto: crypto, crypto: crypto,
owners: [ctx.store.proxy.edPublic], owners: opts.owners || [ctx.store.proxy.edPublic],
lastKnownHash: m.lastKnownHash lastKnownHash: m.lastKnownHash
}; };
cfg.onConnectionChange = function () {}; // Allow reconnections in chainpad-netflux cfg.onConnectionChange = function () {}; // Allow reconnections in chainpad-netflux
@ -346,7 +365,7 @@ proxy.mailboxes = {
// Continue // Continue
onReady(); onReady();
}; };
CpNetflux.start(cfg); box.cpNf = CpNetflux.start(cfg);
}; };
var initializeHistory = function (ctx) { var initializeHistory = function (ctx) {
@ -467,6 +486,19 @@ proxy.mailboxes = {
} }
}); });
Object.keys(store.proxy.teams || {}).forEach(function (teamId) {
var team = store.proxy.teams[teamId];
if (!team) { return; }
var teamMailbox = team.keys.mailbox || {};
if (!teamMailbox.channel) { return; }
var opts = {
owners: [Util.find(team, ['keys', 'drive', 'edPublic'])]
};
openChannel(ctx, 'team-'+teamId, teamMailbox, function () {
//console.log('Mailbox team', teamId);
}, opts);
});
mailbox.post = function (box, type, content) { mailbox.post = function (box, type, content) {
var b = ctx.boxes[box]; var b = ctx.boxes[box];
if (!b) { return; } if (!b) { return; }
@ -477,9 +509,12 @@ proxy.mailboxes = {
}); });
}; };
mailbox.open = function (key, m, cb) { mailbox.open = function (key, m, cb, team, opts) {
if (TYPES.indexOf(key) === -1) { return; } if (TYPES.indexOf(key) === -1 && !team) { return; }
openChannel(ctx, key, m, cb); openChannel(ctx, key, m, cb, opts);
};
mailbox.close = function (key, cb) {
leaveChannel(ctx, key, cb);
}; };
mailbox.dismiss = function (data, cb) { mailbox.dismiss = function (data, cb) {

@ -798,7 +798,6 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
return void console.error(err); return void console.error(err);
} }
metadata = ref.internal.metadata = (data && data[0]) || undefined; metadata = ref.internal.metadata = (data && data[0]) || undefined;
console.log("TEAM_METADATA", metadata);
}); });
}).nThen(function (w) { }).nThen(function (w) {
if (!config.keys.teamEdPublic && metadata && metadata.validateKey) { if (!config.keys.teamEdPublic && metadata && metadata.validateKey) {

@ -126,6 +126,9 @@ define([
delete ctx.store.proxy.teams[teamId]; delete ctx.store.proxy.teams[teamId];
ctx.emit('LEAVE_TEAM', teamId, team.clients); ctx.emit('LEAVE_TEAM', teamId, team.clients);
ctx.updateMetadata(); ctx.updateMetadata();
ctx.store.mailbox.close('team-'+teamId, function () {
// Close team mailbox
});
}; };
var getTeamChannelList = function (ctx, id) { var getTeamChannelList = function (ctx, id) {
@ -172,6 +175,23 @@ define([
Pinpad.create(ctx.store.network, data, function (e, call) { Pinpad.create(ctx.store.network, data, function (e, call) {
if (e) { return void cb(e); } if (e) { return void cb(e); }
team.rpc = call; team.rpc = call;
team.pin = function (data, cb) {
if (!team.rpc) { return void cb({error: 'TEAM_RPC_NOT_READY'}); }
if (typeof(cb) !== 'function') { console.error('expected a callback'); }
team.rpc.pin(data, function (e, hash) {
if (e) { return void cb({error: e}); }
cb({hash: hash});
});
};
team.unpin = function (data, cb) {
if (!team.rpc) { return void cb({error: 'TEAM_RPC_NOT_READY'}); }
if (typeof(cb) !== 'function') { console.error('expected a callback'); }
team.rpc.unpin(data, function (e, hash) {
if (e) { return void cb({error: e}); }
cb({hash: hash});
});
};
cb(); cb();
}); });
}); });
@ -242,27 +262,7 @@ define([
nThen(function (waitFor) { nThen(function (waitFor) {
// Init Team RPC // Init Team RPC
if (!keys.drive.edPrivate) { return; } if (!keys.drive.edPrivate) { return; }
initRpc(ctx, team, keys.drive, waitFor(function (err) { initRpc(ctx, team, keys.drive, waitFor(function () {}));
if (err) { return; }
team.pin = function (data, cb) {
if (!team.rpc) { return void cb({error: 'TEAM_RPC_NOT_READY'}); }
if (typeof(cb) !== 'function') { console.error('expected a callback'); }
team.rpc.pin(data, function (e, hash) {
if (e) { return void cb({error: e}); }
cb({hash: hash});
});
};
team.unpin = function (data, cb) {
if (!team.rpc) { return void cb({error: 'TEAM_RPC_NOT_READY'}); }
if (typeof(cb) !== 'function') { console.error('expected a callback'); }
team.rpc.unpin(data, function (e, hash) {
if (e) { return void cb({error: e}); }
cb({hash: hash});
});
};
}));
}).nThen(function () { }).nThen(function () {
// Create the proxy manager // Create the proxy manager
var loadSharedFolder = function (id, data, cb, isNew) { var loadSharedFolder = function (id, data, cb, isNew) {
@ -471,6 +471,16 @@ define([
// Make sure we have not been kicked from the roster // Make sure we have not been kicked from the roster
var state = roster.getState(); var state = roster.getState();
var me = Util.find(ctx, ['store', 'proxy', 'curvePublic']); var me = Util.find(ctx, ['store', 'proxy', 'curvePublic']);
// XXX FIXME roster history temporarily corrupted, don't leave the team
if (!state.members || !Object.keys(state.members).length) {
lm.stop();
roster.stop();
lm.proxy = {};
cb({error: 'EINVAL'});
waitFor.abort();
console.error(JSON.stringify(state));
return;
}
if (!state.members[me]) { if (!state.members[me]) {
lm.stop(); lm.stop();
roster.stop(); roster.stop();
@ -494,6 +504,8 @@ define([
var roHash = Hash.getViewHashFromKeys(secret); var roHash = Hash.getViewHashFromKeys(secret);
var keyPair = Nacl.sign.keyPair(); // keyPair.secretKey , keyPair.publicKey var keyPair = Nacl.sign.keyPair(); // keyPair.secretKey , keyPair.publicKey
var curvePair = Nacl.box.keyPair();
var rosterSeed = Crypto.Team.createSeed(); var rosterSeed = Crypto.Team.createSeed();
var rosterKeys = Crypto.Team.deriveMemberKeys(rosterSeed, { var rosterKeys = Crypto.Team.deriveMemberKeys(rosterSeed, {
curvePublic: ctx.store.proxy.curvePublic, curvePublic: ctx.store.proxy.curvePublic,
@ -585,6 +597,14 @@ define([
proxy.on('ready', function () { proxy.on('ready', function () {
// Store keys in our drive // Store keys in our drive
var keys = { var keys = {
mailbox: {
channel: Hash.createChannelId(),
viewed: [],
keys: {
curvePrivate: Nacl.util.encodeBase64(curvePair.secretKey),
curvePublic: Nacl.util.encodeBase64(curvePair.publicKey)
}
},
drive: { drive: {
edPrivate: Nacl.util.encodeBase64(keyPair.secretKey), edPrivate: Nacl.util.encodeBase64(keyPair.secretKey),
edPublic: Nacl.util.encodeBase64(keyPair.publicKey) edPublic: Nacl.util.encodeBase64(keyPair.publicKey)
@ -601,7 +621,7 @@ define([
view: rosterKeys.viewKeyStr, view: rosterKeys.viewKeyStr,
} }
}; };
ctx.store.proxy.teams[id] = { var t = ctx.store.proxy.teams[id] = {
owner: true, owner: true,
channel: secret.channel, channel: secret.channel,
hash: hash, hash: hash,
@ -618,6 +638,11 @@ define([
onReady(ctx, id, lm, roster, keys, cId, function () { onReady(ctx, id, lm, roster, keys, cId, function () {
Feedback.send('TEAM_CREATION'); Feedback.send('TEAM_CREATION');
ctx.store.mailbox.open('team-'+id, t.keys.mailbox, function () {
// Team mailbox loaded
}, true, {
owners: t.keys.drive.edPublic
});
ctx.updateMetadata(); ctx.updateMetadata();
cb(); cb();
}); });
@ -720,6 +745,11 @@ define([
team.rpc.removePins(waitFor(function (err) { team.rpc.removePins(waitFor(function (err) {
if (err) { console.error(err); } if (err) { console.error(err); }
})); }));
// Delete the mailbox
var mailboxChan = Util.find(teamData, ['keys', 'mailbox', 'channel']);
team.rpc.removeOwnedChannel(mailboxChan, waitFor(function (err) {
if (err) { console.error(err); }
}));
// Delete the roster // Delete the roster
var rosterChan = Util.find(teamData, ['keys', 'roster', 'channel']); var rosterChan = Util.find(teamData, ['keys', 'roster', 'channel']);
ctx.store.rpc.removeOwnedChannel(rosterChan, waitFor(function (err) { ctx.store.rpc.removeOwnedChannel(rosterChan, waitFor(function (err) {
@ -750,6 +780,12 @@ define([
ctx.onReadyHandlers[id] = []; ctx.onReadyHandlers[id] = [];
openChannel(ctx, team, id, function (obj) { openChannel(ctx, team, id, function (obj) {
if (!(obj && obj.error)) { console.debug('Team joined:' + id); } if (!(obj && obj.error)) { console.debug('Team joined:' + id); }
var t = ctx.store.proxy.teams[id];
ctx.store.mailbox.open('team-'+id, t.keys.mailbox, function () {
// Team mailbox loaded
}, true, {
owners: t.keys.drive.edPublic
});
ctx.updateMetadata(); ctx.updateMetadata();
cb(obj); cb(obj);
}); });
@ -1093,6 +1129,7 @@ define([
teamData.hash = data.hash; teamData.hash = data.hash;
teamData.keys.drive.edPrivate = data.keys.drive.edPrivate; teamData.keys.drive.edPrivate = data.keys.drive.edPrivate;
teamData.keys.chat.edit = data.keys.chat.edit; teamData.keys.chat.edit = data.keys.chat.edit;
initRpc(ctx, team, teamData.keys.drive, function () {});
var secret = Hash.getSecrets('team', data.hash, teamData.password); var secret = Hash.getSecrets('team', data.hash, teamData.password);
team.secondaryKey = secret && secret.keys.secondaryKey; team.secondaryKey = secret && secret.keys.secondaryKey;
@ -1101,6 +1138,9 @@ define([
delete teamData.keys.drive.edPrivate; delete teamData.keys.drive.edPrivate;
delete teamData.keys.chat.edit; delete teamData.keys.chat.edit;
delete team.secondaryKey; delete team.secondaryKey;
if (team.rpc && team.rpc.destroy) {
team.rpc.destroy();
}
} }
updateMyRights(ctx, teamId, data.hash); updateMyRights(ctx, teamId, data.hash);
@ -1566,6 +1606,25 @@ define([
}); });
}; };
var deriveMailbox = function (team) {
if (!team) { return; }
if (team.keys && team.keys.mailbox) { return team.keys.mailbox; }
var strSeed = Util.find(team, ['keys', 'roster', 'edit']);
if (!strSeed) { return; }
var hash = Nacl.hash(Nacl.util.decodeUTF8(strSeed));
var seed = hash.slice(0,32);
var mailboxChannel = Util.uint8ArrayToHex(hash.slice(32,48));
var curvePair = Nacl.box.keyPair.fromSecretKey(seed);
return {
channel: mailboxChannel,
viewed: [],
keys: {
curvePrivate: Nacl.util.encodeBase64(curvePair.secretKey),
curvePublic: Nacl.util.encodeBase64(curvePair.publicKey)
}
};
};
Team.init = function (cfg, waitFor, emit) { Team.init = function (cfg, waitFor, emit) {
var team = {}; var team = {};
var store = cfg.store; var store = cfg.store;
@ -1595,6 +1654,9 @@ define([
Object.keys(teams).forEach(function (id) { Object.keys(teams).forEach(function (id) {
ctx.onReadyHandlers[id] = []; ctx.onReadyHandlers[id] = [];
if (!Util.find(teams, [id, 'keys', 'mailbox'])) {
teams[id].keys.mailbox = deriveMailbox(teams[id]);
}
openChannel(ctx, teams[id], id, waitFor(function (err) { openChannel(ctx, teams[id], id, waitFor(function (err) {
if (err) { return void console.error(err); } if (err) { return void console.error(err); }
console.debug('Team '+id+' ready'); console.debug('Team '+id+' ready');
@ -1609,12 +1671,15 @@ define([
var safe = false; var safe = false;
if (['drive', 'teams', 'settings'].indexOf(app) !== -1) { safe = true; } if (['drive', 'teams', 'settings'].indexOf(app) !== -1) { safe = true; }
Object.keys(teams).forEach(function (id) { Object.keys(teams).forEach(function (id) {
if (!ctx.teams[id]) { return; }
t[id] = { t[id] = {
owner: teams[id].owner, owner: teams[id].owner,
name: teams[id].metadata.name, name: teams[id].metadata.name,
edPublic: Util.find(teams[id], ['keys', 'drive', 'edPublic']), edPublic: Util.find(teams[id], ['keys', 'drive', 'edPublic']),
avatar: Util.find(teams[id], ['metadata', 'avatar']), avatar: Util.find(teams[id], ['metadata', 'avatar']),
viewer: !Util.find(teams[id], ['keys', 'drive', 'edPrivate']), viewer: !Util.find(teams[id], ['keys', 'drive', 'edPrivate']),
notifications: Util.find(teams[id], ['keys', 'mailbox', 'channel']),
curvePublic: Util.find(teams[id], ['keys', 'mailbox', 'keys', 'curvePublic']),
}; };
if (safe && ctx.teams[id]) { if (safe && ctx.teams[id]) {
@ -1663,6 +1728,15 @@ define([
team.removeClient = function (clientId) { team.removeClient = function (clientId) {
removeClient(ctx, clientId); removeClient(ctx, clientId);
}; };
var listTeams = function (cb) {
var t = Util.clone(teams);
Object.keys(t).forEach(function (id) {
// If failure to load the team, don't send it
if (ctx.teams[id]) { return; }
t[id].error = true;
});
cb(t);
};
team.execCommand = function (clientId, obj, cb) { team.execCommand = function (clientId, obj, cb) {
if (ctx.store.offline) { if (ctx.store.offline) {
return void cb({ error: 'OFFLINE' }); return void cb({ error: 'OFFLINE' });
@ -1675,7 +1749,7 @@ define([
return void subscribe(ctx, data, clientId, cb); return void subscribe(ctx, data, clientId, cb);
} }
if (cmd === 'LIST_TEAMS') { if (cmd === 'LIST_TEAMS') {
return void cb(store.proxy.teams); return void listTeams(cb);
} }
if (cmd === 'OPEN_TEAM_CHAT') { if (cmd === 'OPEN_TEAM_CHAT') {
return void openTeamChat(ctx, data, clientId, cb); return void openTeamChat(ctx, data, clientId, cb);

@ -490,6 +490,7 @@ define([
}, { }, {
typeInput: $select[0] typeInput: $select[0]
}); });
$select.find('button').addClass('btn');
}); });
toolbar.$drawer.append($export); toolbar.$drawer.append($export);
}; };

@ -105,11 +105,14 @@ define([
}); });
// Call the onMessage handlers // Call the onMessage handlers
var isNotification = function (type) {
return type === "notifications" || /^team-/.test(type);
};
var pushMessage = function (data, handler) { var pushMessage = function (data, handler) {
var todo = function (f) { var todo = function (f) {
try { try {
var el; var el;
if (data.type === 'notifications') { if (isNotification(data.type)) {
Notifications.add(Common, data); Notifications.add(Common, data);
el = createElement(data); el = createElement(data);
} }
@ -129,7 +132,7 @@ define([
onViewedHandlers.forEach(function (f) { onViewedHandlers.forEach(function (f) {
try { try {
f(data); f(data);
if (data.type === 'notifications') { if (isNotification(data.type)) {
Notifications.remove(Common, data); Notifications.remove(Common, data);
} }
} catch (e) { } catch (e) {
@ -141,7 +144,6 @@ define([
var onMessage = function (data, cb) { var onMessage = function (data, cb) {
// data = { type: 'type', content: {msg: 'msg', hash: 'hash'} } // data = { type: 'type', content: {msg: 'msg', hash: 'hash'} }
console.debug(data.type, data.content);
pushMessage(data); pushMessage(data);
if (data.content && typeof (data.content.getFormatText) === "function") { if (data.content && typeof (data.content.getFormatText) === "function") {
var text = $('<div>').html(data.content.getFormatText()).text(); var text = $('<div>').html(data.content.getFormatText()).text();
@ -173,20 +175,23 @@ define([
execCommand('SUBSCRIBE', null, function () {}); execCommand('SUBSCRIBE', null, function () {});
subscribed = true; subscribed = true;
} }
var teams = types.indexOf('team') !== -1;
if (typeof(cfg.onViewed) === "function") { if (typeof(cfg.onViewed) === "function") {
onViewedHandlers.push(function (data) { onViewedHandlers.push(function (data) {
if (types.indexOf(data.type) === -1) { return; } var type = data.type;
if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; }
cfg.onViewed(data); cfg.onViewed(data);
}); });
} }
if (typeof(cfg.onMessage) === "function") { if (typeof(cfg.onMessage) === "function") {
onMessageHandlers.push(function (data, el) { onMessageHandlers.push(function (data, el) {
if (types.indexOf(data.type) === -1) { return; } var type = data.type;
if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; }
cfg.onMessage(data, el); cfg.onMessage(data, el);
}); });
} }
Object.keys(history).forEach(function (type) { Object.keys(history).forEach(function (type) {
if (types.indexOf(type) === -1) { return; } if (types.indexOf(type) === -1 && !(teams && /^team-/.test(type))) { return; }
history[type].forEach(function (data) { history[type].forEach(function (data) {
pushMessage({ pushMessage({
type: type, type: type,

@ -1025,7 +1025,7 @@ MessengerUI, Messages) {
$button.addClass('fa-bell'); $button.addClass('fa-bell');
}; };
Common.mailbox.subscribe(['notifications'], { Common.mailbox.subscribe(['notifications', 'team'], {
onMessage: function (data, el) { onMessage: function (data, el) {
if (el) { if (el) {
$(div).prepend(el); $(div).prepend(el);

@ -148,7 +148,6 @@
"or": "o", "or": "o",
"tags_title": "Etiquetes (només vostres)", "tags_title": "Etiquetes (només vostres)",
"tags_add": "Actualitza les etiquetes d'aquesta pàgina", "tags_add": "Actualitza les etiquetes d'aquesta pàgina",
"tags_searchHint": "Inicieu una cerca amb # al vostre CryptDrive per trobar els vostres documents etiquetats.",
"tags_notShared": "Les vostres etiquetes no es comparteixen amb altres persones usuàries", "tags_notShared": "Les vostres etiquetes no es comparteixen amb altres persones usuàries",
"tags_duplicate": "Etiquetes duplicades: {0}", "tags_duplicate": "Etiquetes duplicades: {0}",
"tags_noentry": "No podeu etiquetar un document esborrat!", "tags_noentry": "No podeu etiquetar un document esborrat!",

@ -21,7 +21,7 @@
"button_newslide": "Neue Präsentation", "button_newslide": "Neue Präsentation",
"button_newwhiteboard": "Neues Whiteboard", "button_newwhiteboard": "Neues Whiteboard",
"button_newkanban": "Neues Kanban", "button_newkanban": "Neues Kanban",
"common_connectionLost": "<b>Die Verbindung zum Server ist abgebrochen</b><br>Du verwendest jetzt das Dokument schreibgeschützt, bis die Verbindung wieder funktioniert.", "common_connectionLost": "<b>Die Verbindung zum Server ist abgebrochen</b><br>Du kannst das Dokument nicht bearbeiten, bis die Verbindung wieder funktioniert.",
"websocketError": "Verbindung zum Websocket fehlgeschlagen...", "websocketError": "Verbindung zum Websocket fehlgeschlagen...",
"typeError": "Dieses Dokument ist nicht mit der ausgewählten Anwendung kompatibel", "typeError": "Dieses Dokument ist nicht mit der ausgewählten Anwendung kompatibel",
"onLogout": "Du bist ausgeloggt. {0}Klicke hier{1}, um dich wieder einzuloggen,<br>oder drücke <em>Escape</em>, um dein Pad schreibgeschützt zu benutzen.", "onLogout": "Du bist ausgeloggt. {0}Klicke hier{1}, um dich wieder einzuloggen,<br>oder drücke <em>Escape</em>, um dein Pad schreibgeschützt zu benutzen.",
@ -146,7 +146,6 @@
"or": "oder", "or": "oder",
"tags_title": "Tags (nur für dich)", "tags_title": "Tags (nur für dich)",
"tags_add": "Tags der ausgewählten Pads bearbeiten", "tags_add": "Tags der ausgewählten Pads bearbeiten",
"tags_searchHint": "Beginne die Suche in deinem CryptDrive mit #, um getaggte Dokumente zu finden.",
"tags_notShared": "Deine Tags werden nicht mit anderen Benutzern geteilt", "tags_notShared": "Deine Tags werden nicht mit anderen Benutzern geteilt",
"tags_duplicate": "Doppeltes Tag: {0}", "tags_duplicate": "Doppeltes Tag: {0}",
"tags_noentry": "Du kannst keine Tags zu einem gelöschten Pad hinzufügen!", "tags_noentry": "Du kannst keine Tags zu einem gelöschten Pad hinzufügen!",
@ -1088,7 +1087,7 @@
"support_disabledTitle": "Support ist nicht aktiviert", "support_disabledTitle": "Support ist nicht aktiviert",
"support_disabledHint": "Diese CryptPad-Instanz wurde noch nicht für die Verwendung eines Support-Formulars konfiguriert.", "support_disabledHint": "Diese CryptPad-Instanz wurde noch nicht für die Verwendung eines Support-Formulars konfiguriert.",
"support_cat_new": "Neues Ticket", "support_cat_new": "Neues Ticket",
"support_formTitle": "Titel des Tickets", "support_formTitle": "Neues Ticket",
"support_formHint": "Mit diesem Formular kann ein neues Support-Ticket eröffnet werden. Es erlaubt die sichere Kontaktaufnahme mit den Administratoren zur Lösung von Problemen oder Beantwortung von Fragen. Bitte eröffne kein neues Ticket, wenn du bereits ein offenes Ticket bezüglich des gleichen Problems hast. Verwende stattdessen die Antworten-Schaltfläche, um weitere Informationen hinzuzufügen.", "support_formHint": "Mit diesem Formular kann ein neues Support-Ticket eröffnet werden. Es erlaubt die sichere Kontaktaufnahme mit den Administratoren zur Lösung von Problemen oder Beantwortung von Fragen. Bitte eröffne kein neues Ticket, wenn du bereits ein offenes Ticket bezüglich des gleichen Problems hast. Verwende stattdessen die Antworten-Schaltfläche, um weitere Informationen hinzuzufügen.",
"support_formButton": "Absenden", "support_formButton": "Absenden",
"support_formTitleError": "Fehler: Titel ist leer", "support_formTitleError": "Fehler: Titel ist leer",
@ -1124,7 +1123,7 @@
"properties_unknownUser": "{0} unbekannte(r) Benutzer", "properties_unknownUser": "{0} unbekannte(r) Benutzer",
"fm_morePads": "Mehr", "fm_morePads": "Mehr",
"fc_openInCode": "Im Code-Editor öffnen", "fc_openInCode": "Im Code-Editor öffnen",
"uploadFolder_modal_title": "Optionen für Ordnerupload", "uploadFolder_modal_title": "Optionen für Hochladen des Ordners",
"uploadFolder_modal_filesPassword": "Passwort für Dateien", "uploadFolder_modal_filesPassword": "Passwort für Dateien",
"uploadFolder_modal_owner": "Eigene Dateien", "uploadFolder_modal_owner": "Eigene Dateien",
"uploadFolder_modal_forceSave": "Dateien im CryptDrive speichern", "uploadFolder_modal_forceSave": "Dateien im CryptDrive speichern",
@ -1182,7 +1181,7 @@
"team_rosterPromote": "Befördern", "team_rosterPromote": "Befördern",
"team_rosterDemote": "Degradieren", "team_rosterDemote": "Degradieren",
"team_rosterKick": "Aus dem Team entfernen", "team_rosterKick": "Aus dem Team entfernen",
"team_inviteButton": "Kontakte einladen", "team_inviteButton": "Mitglieder einladen",
"team_leaveButton": "Dieses Team verlassen", "team_leaveButton": "Dieses Team verlassen",
"team_leaveConfirm": "Wenn du dieses Team verlässt, verlierst du den Zugriff auf das dazugehörige CryptDrive, den Chatverlauf und andere Inhalte. Bist du sicher?", "team_leaveConfirm": "Wenn du dieses Team verlässt, verlierst du den Zugriff auf das dazugehörige CryptDrive, den Chatverlauf und andere Inhalte. Bist du sicher?",
"team_owner": "Eigentümer", "team_owner": "Eigentümer",
@ -1382,5 +1381,18 @@
"settings_safeLinkDefault": "Sichere Links sind nun standardmäßig aktiviert. Bitte verwende zum Kopieren von Links das Menü <i class=\"fa fa-shhare-alt\"></i> <b>Teilen</b> und nicht die Adressleiste des Browsers.", "settings_safeLinkDefault": "Sichere Links sind nun standardmäßig aktiviert. Bitte verwende zum Kopieren von Links das Menü <i class=\"fa fa-shhare-alt\"></i> <b>Teilen</b> und nicht die Adressleiste des Browsers.",
"info_imprintFlavour": "<a>Rechtliche Informationen über die Administratoren dieses Servers</a>.", "info_imprintFlavour": "<a>Rechtliche Informationen über die Administratoren dieses Servers</a>.",
"info_privacyFlavour": "Unsere <a>Datenschutzerklärung</a> beschreibt, wie wir deine Daten verarbeiten.", "info_privacyFlavour": "Unsere <a>Datenschutzerklärung</a> beschreibt, wie wir deine Daten verarbeiten.",
"user_about": "Über CryptPad" "user_about": "Über CryptPad",
"support_cat_all": "Alle",
"support_cat_other": "Anderes",
"support_cat_account": "Benutzerkonto",
"support_cat_data": "Datenverlust",
"notification_folderSharedTeam": "{0} hat einen Ordner mit dem Team {2} geteilt: <b>{1}</b>",
"notification_fileSharedTeam": "{0} hat eine Datei mit dem Team {2} geteilt: <b>{1}</b>",
"notification_padSharedTeam": "{0} hat ein Pad mit dem Team {2} geteilt: <b>{1}</b>",
"support_addAttachment": "Anhang hinzufügen",
"support_attachments": "Anhänge",
"support_cat_bug": "Fehlerbericht",
"oo_refresh": "Neu laden",
"support_category": "Wähle eine Kategorie",
"oo_refreshText": "Dieses Dokument wurde aktualisiert"
} }

@ -119,7 +119,6 @@
"or": "ή", "or": "ή",
"tags_title": "Ετικέτες (για εσάς μόνο)", "tags_title": "Ετικέτες (για εσάς μόνο)",
"tags_add": "Ενημερώστε τις ετικέτες αυτής της σελίδας", "tags_add": "Ενημερώστε τις ετικέτες αυτής της σελίδας",
"tags_searchHint": "Ξεκινήστε μια αναζήτηση με το σύμβολο # στο CryptDrive σας για να βρείτε pads με ετικέτες.",
"tags_notShared": "Οι ετικέτες σας δεν μοιράζονται με άλλους χρήστες", "tags_notShared": "Οι ετικέτες σας δεν μοιράζονται με άλλους χρήστες",
"tags_duplicate": "Διπλή ετικέτα: {0}", "tags_duplicate": "Διπλή ετικέτα: {0}",
"tags_noentry": "Δεν μπορείτε να βάλετε ετικέτα σε διεγραμένο pad!", "tags_noentry": "Δεν μπορείτε να βάλετε ετικέτα σε διεγραμένο pad!",

@ -472,7 +472,6 @@
"printBackgroundRemove": "Eliminar este fondo de pantalla", "printBackgroundRemove": "Eliminar este fondo de pantalla",
"tags_title": "Etiquetas (sólo para tí)", "tags_title": "Etiquetas (sólo para tí)",
"tags_add": "Actualizar las etiquetas de esta página", "tags_add": "Actualizar las etiquetas de esta página",
"tags_searchHint": "Comenzar una búsqueda con # en tú CryptDrive para encontrar las notas etiquetadas.",
"tags_notShared": "Tus etiquetas no están compartidas con otros usuarios", "tags_notShared": "Tus etiquetas no están compartidas con otros usuarios",
"tags_duplicate": "Duplicar etiquetas:{0}", "tags_duplicate": "Duplicar etiquetas:{0}",
"tags_noentry": "No puedes etiquetar una nota eliminada!", "tags_noentry": "No puedes etiquetar una nota eliminada!",

@ -151,7 +151,6 @@
"or": "tai", "or": "tai",
"tags_title": "Tunnisteet (vain sinulle)", "tags_title": "Tunnisteet (vain sinulle)",
"tags_add": "Päivitä sivun tunnisteet", "tags_add": "Päivitä sivun tunnisteet",
"tags_searchHint": "Aloita hakusi CryptDrivessa #-merkillä löytääksesi tunnisteita sisältävät padit.",
"tags_notShared": "Tunnisteitasi ei jaeta muiden käyttäjien kanssa", "tags_notShared": "Tunnisteitasi ei jaeta muiden käyttäjien kanssa",
"tags_duplicate": "Kaksinkertainen tunniste: {0}", "tags_duplicate": "Kaksinkertainen tunniste: {0}",
"tags_noentry": "Et voi lisätä tunnistetta poistettuun padiin!", "tags_noentry": "Et voi lisätä tunnistetta poistettuun padiin!",

@ -148,7 +148,6 @@
"or": "ou", "or": "ou",
"tags_title": "Mots-clés du pad (pour vous uniquement)", "tags_title": "Mots-clés du pad (pour vous uniquement)",
"tags_add": "Modifier les mots-clés de la sélection", "tags_add": "Modifier les mots-clés de la sélection",
"tags_searchHint": "Commencez une recherche par # dans votre CryptDrive pour retrouver vos pads par mot-clé.",
"tags_notShared": "Vos mots-clés ne sont pas partagés avec les autres utilisateurs", "tags_notShared": "Vos mots-clés ne sont pas partagés avec les autres utilisateurs",
"tags_duplicate": "Mot-clé déjà présent : {0}", "tags_duplicate": "Mot-clé déjà présent : {0}",
"tags_noentry": "Vous ne pouvez pas ajouter de mots-clés à un pad supprimé !", "tags_noentry": "Vous ne pouvez pas ajouter de mots-clés à un pad supprimé !",
@ -1087,7 +1086,7 @@
"support_disabledTitle": "Le support n'est pas activé", "support_disabledTitle": "Le support n'est pas activé",
"support_disabledHint": "Cette instance de CryptPad n'est pas encore configurée pour utiliser le formulaire de support.", "support_disabledHint": "Cette instance de CryptPad n'est pas encore configurée pour utiliser le formulaire de support.",
"support_cat_new": "Nouveau ticket", "support_cat_new": "Nouveau ticket",
"support_formTitle": "Titre du ticket", "support_formTitle": "Nouveau Ticket",
"support_formButton": "Envoyer", "support_formButton": "Envoyer",
"support_formTitleError": "Erreur : le titre est vide", "support_formTitleError": "Erreur : le titre est vide",
"support_formContentError": "Erreur : le contenu est vide", "support_formContentError": "Erreur : le contenu est vide",
@ -1165,7 +1164,7 @@
"team_inviteModalButton": "Inviter", "team_inviteModalButton": "Inviter",
"team_pcsSelectLabel": "Sauver dans", "team_pcsSelectLabel": "Sauver dans",
"team_pcsSelectHelp": "Créer un pad dans le drive d'une équipe rend cette équipe propriétaire du pad si l'option est cochée.", "team_pcsSelectHelp": "Créer un pad dans le drive d'une équipe rend cette équipe propriétaire du pad si l'option est cochée.",
"team_invitedToTeam": "{0} vous à inviter à rejoindre l'équipe : <b>{1}</b>", "team_invitedToTeam": "{0} vous a invité à rejoindre l'équipe : <b>{1}</b>",
"team_kickedFromTeam": "{0} vous a exclu de l'équipe : <b>{1}</b>", "team_kickedFromTeam": "{0} vous a exclu de l'équipe : <b>{1}</b>",
"team_acceptInvitation": "{0} a accepté votre offre de rejoindre l'équipe : <b>{1}</b>", "team_acceptInvitation": "{0} a accepté votre offre de rejoindre l'équipe : <b>{1}</b>",
"team_declineInvitation": "{0} a refusé votre offre de rejoindre l'équipe : <b>{1}</b>", "team_declineInvitation": "{0} a refusé votre offre de rejoindre l'équipe : <b>{1}</b>",
@ -1184,7 +1183,7 @@
"team_rosterPromote": "Promouvoir", "team_rosterPromote": "Promouvoir",
"team_rosterDemote": "Rétrograder", "team_rosterDemote": "Rétrograder",
"team_rosterKick": "Expulser de l'équipe", "team_rosterKick": "Expulser de l'équipe",
"team_inviteButton": "Inviter des contacts", "team_inviteButton": "Inviter des membres",
"team_leaveButton": "Quitter cette équipe", "team_leaveButton": "Quitter cette équipe",
"team_leaveConfirm": "Si vous quittez cette équipe, vous perdrez l'accès à son CryptDrive, son chat et les autres contenus. Êtes-vous sûr ?", "team_leaveConfirm": "Si vous quittez cette équipe, vous perdrez l'accès à son CryptDrive, son chat et les autres contenus. Êtes-vous sûr ?",
"team_owner": "Propriétaires", "team_owner": "Propriétaires",
@ -1382,5 +1381,18 @@
"support_languagesPreamble": "L'équipe de support parle les langues suivantes :", "support_languagesPreamble": "L'équipe de support parle les langues suivantes :",
"info_privacyFlavour": "<a>Description de la confidentialité</a> de vos données.", "info_privacyFlavour": "<a>Description de la confidentialité</a> de vos données.",
"user_about": "À propos de CryptPad", "user_about": "À propos de CryptPad",
"info_imprintFlavour": "<a>Informations légales sur les administateurs de cette instance</a>." "info_imprintFlavour": "<a>Informations légales sur les administateurs de cette instance</a>.",
"support_cat_all": "Tout",
"support_cat_other": "Autre",
"support_cat_bug": "Rapport de bug",
"support_cat_data": "Perte de données",
"support_cat_account": "Compte utilisateur",
"notification_folderSharedTeam": "{0} a partagé un dossier avec l'équipe {2} : <b>{1}</b>",
"notification_fileSharedTeam": "{0} a partagé un fichier avec l'équipe {2} : <b>{1}</b>",
"notification_padSharedTeam": "{0} a partagé un pad avec l'équipe {2} : <b>{1}</b>",
"support_addAttachment": "Ajouter une pièce jointe",
"support_attachments": "Pièces jointes",
"oo_refreshText": "Ce document a été mis à jour",
"oo_refresh": "Recharger",
"support_category": "Choisir une catégorie"
} }

@ -148,7 +148,6 @@
"or": "o", "or": "o",
"tags_title": "Tag (mostrati solo a te)", "tags_title": "Tag (mostrati solo a te)",
"tags_add": "Aggiorna i tag di questa pagina", "tags_add": "Aggiorna i tag di questa pagina",
"tags_searchHint": "Inizia una ricerca con # nel tuo CryptDrive per trovare i pad taggati.",
"tags_notShared": "I tuoi tag non sono condivisi con altri utenti", "tags_notShared": "I tuoi tag non sono condivisi con altri utenti",
"tags_duplicate": "Duplica tag: {0}", "tags_duplicate": "Duplica tag: {0}",
"tags_noentry": "Non puoi taggare un pad eliminato!", "tags_noentry": "Non puoi taggare un pad eliminato!",

@ -151,7 +151,6 @@
"or": "or", "or": "or",
"tags_title": "Tags (for you only)", "tags_title": "Tags (for you only)",
"tags_add": "Update the tags for selected pads", "tags_add": "Update the tags for selected pads",
"tags_searchHint": "Start a search with # in your CryptDrive to find your tagged pads.",
"tags_notShared": "Your tags are not shared with other users", "tags_notShared": "Your tags are not shared with other users",
"tags_duplicate": "Duplicate tag: {0}", "tags_duplicate": "Duplicate tag: {0}",
"tags_noentry": "You can't tag a deleted pad!", "tags_noentry": "You can't tag a deleted pad!",
@ -1109,7 +1108,7 @@
"support_disabledTitle": "Support is not enabled", "support_disabledTitle": "Support is not enabled",
"support_disabledHint": "This CryptPad instance is not yet configured to use a support form.", "support_disabledHint": "This CryptPad instance is not yet configured to use a support form.",
"support_cat_new": "New ticket", "support_cat_new": "New ticket",
"support_formTitle": "Ticket title", "support_formTitle": "New Ticket",
"support_formHint": "This form can be used to create a new support ticket. Use it to contact the administrators to solve issues or ask any question in a secure way. Please don't create a new ticket if you already have an open ticket about the same issue, but use the reply button to provide more information.", "support_formHint": "This form can be used to create a new support ticket. Use it to contact the administrators to solve issues or ask any question in a secure way. Please don't create a new ticket if you already have an open ticket about the same issue, but use the reply button to provide more information.",
"support_formButton": "Send", "support_formButton": "Send",
"support_formTitleError": "Error: title is empty", "support_formTitleError": "Error: title is empty",
@ -1188,7 +1187,7 @@
"team_rosterPromote": "Promote", "team_rosterPromote": "Promote",
"team_rosterDemote": "Demote", "team_rosterDemote": "Demote",
"team_rosterKick": "Kick from the team", "team_rosterKick": "Kick from the team",
"team_inviteButton": "Invite contacts", "team_inviteButton": "Invite members",
"team_leaveButton": "Leave this team", "team_leaveButton": "Leave this team",
"team_leaveConfirm": "If you leave this team you will lose access to its CryptDrive, chat history, and other contents. Are you sure?", "team_leaveConfirm": "If you leave this team you will lose access to its CryptDrive, chat history, and other contents. Are you sure?",
"team_owner": "Owners", "team_owner": "Owners",
@ -1382,5 +1381,18 @@
"settings_safeLinkDefault": "Safe Links are now turned on by default. Please use the <i class=\"fa fa-shhare-alt\"></i> <b>Share</b> menu to copy links rather than your browser's address bar.", "settings_safeLinkDefault": "Safe Links are now turned on by default. Please use the <i class=\"fa fa-shhare-alt\"></i> <b>Share</b> menu to copy links rather than your browser's address bar.",
"info_imprintFlavour": "<a>Legal information about the administrators of this instance</a>.", "info_imprintFlavour": "<a>Legal information about the administrators of this instance</a>.",
"user_about": "About CryptPad", "user_about": "About CryptPad",
"info_privacyFlavour": "Our <a>privacy policy</a> describes how we treat your data." "info_privacyFlavour": "Our <a>privacy policy</a> describes how we treat your data.",
"support_cat_account": "User account",
"support_cat_data": "Loss of content",
"support_cat_bug": "Bug report",
"support_cat_other": "Other",
"support_cat_all": "All",
"support_attachments": "Attachments",
"support_addAttachment": "Add attachment",
"notification_padSharedTeam": "{0} has shared a pad with the team {2}: <b>{1}</b>",
"notification_fileSharedTeam": "{0} has shared a file with the team {2}: <b>{1}</b>",
"notification_folderSharedTeam": "{0} has shared a folder with the team {2}: <b>{1}</b>",
"oo_refresh": "Refresh",
"oo_refreshText": "This document has been updated",
"support_category": "Choose a category"
} }

@ -140,7 +140,6 @@
"or": "eller", "or": "eller",
"tags_title": "Tags (kun for ditt bruk)", "tags_title": "Tags (kun for ditt bruk)",
"tags_add": "Oppdater tags for denne sida", "tags_add": "Oppdater tags for denne sida",
"tags_searchHint": "Søk med # i CryptDriven din for å finne pads med slike tags.",
"tags_notShared": "Dine tags deles ikke med andre brukerer", "tags_notShared": "Dine tags deles ikke med andre brukerer",
"tags_duplicate": "Dupliser tag:{0}", "tags_duplicate": "Dupliser tag:{0}",
"tags_noentry": "Du kan ikke tagge en sletta pad!", "tags_noentry": "Du kan ikke tagge en sletta pad!",

@ -74,7 +74,6 @@
"tags_noentry": "U kunt een verwijderde werkomgeving niet markeren!", "tags_noentry": "U kunt een verwijderde werkomgeving niet markeren!",
"tags_duplicate": "Gedupliceerde markering: {0}", "tags_duplicate": "Gedupliceerde markering: {0}",
"tags_notShared": "Uw markeringen worden niet gedeeld met andere gebruikers", "tags_notShared": "Uw markeringen worden niet gedeeld met andere gebruikers",
"tags_searchHint": "Begin een zoekopdracht met # in uw CryptDrive om gemarkeerde werkomgevingen te vinden.",
"tags_add": "Werk de markeringen van deze pagina bij", "tags_add": "Werk de markeringen van deze pagina bij",
"tags_title": "Markeringen (alleen voor u)", "tags_title": "Markeringen (alleen voor u)",
"or": "of", "or": "of",

@ -392,7 +392,6 @@
"or": "", "or": "",
"tags_title": "", "tags_title": "",
"tags_add": "", "tags_add": "",
"tags_searchHint": "",
"tags_notShared": "", "tags_notShared": "",
"tags_duplicate": "", "tags_duplicate": "",
"tags_noentry": "", "tags_noentry": "",

@ -382,7 +382,6 @@
"or": "sau", "or": "sau",
"tags_title": "Etichete (doar pentru tine)", "tags_title": "Etichete (doar pentru tine)",
"tags_add": "Updatează etichetele acestei pagini", "tags_add": "Updatează etichetele acestei pagini",
"tags_searchHint": "Începe o căutare cu # în CryptDrive-ul tău pentru a găsi pad-uri etichetate",
"tags_notShared": "Etichetele tale nu sunt împărțite cu alți utilizatori", "tags_notShared": "Etichetele tale nu sunt împărțite cu alți utilizatori",
"tags_duplicate": "Duplică eticheta: {0}", "tags_duplicate": "Duplică eticheta: {0}",
"tags_noentry": "Nu poți eticheta un pad șters", "tags_noentry": "Nu poți eticheta un pad șters",

@ -140,7 +140,6 @@
"or": "или", "or": "или",
"tags_title": "Теги (только для вас)", "tags_title": "Теги (только для вас)",
"tags_add": "Обновить теги страницы", "tags_add": "Обновить теги страницы",
"tags_searchHint": "Начните поиск в вашем CryptDrive при помощи # чтобы найти пэды с тегами.",
"tags_notShared": "Ваши теги не разделяются с другими пользователями", "tags_notShared": "Ваши теги не разделяются с другими пользователями",
"button_newsheet": "Новый Лист", "button_newsheet": "Новый Лист",
"newButtonTitle": "создать новую запись", "newButtonTitle": "создать новую запись",

@ -38,7 +38,6 @@
"tags_noentry": "Du kan inte tagga ett raderat dokument!", "tags_noentry": "Du kan inte tagga ett raderat dokument!",
"tags_duplicate": "Duplicera tagg: {0}", "tags_duplicate": "Duplicera tagg: {0}",
"tags_notShared": "Dina taggar är inte delade med andra användare", "tags_notShared": "Dina taggar är inte delade med andra användare",
"tags_searchHint": "Påbörja en sökning med # i din CryptDrive för att hitta dina taggade dokument.",
"tags_add": "Uppdatera taggar för denna sida", "tags_add": "Uppdatera taggar för denna sida",
"tags_title": "Taggar (endast för dig)", "tags_title": "Taggar (endast för dig)",
"or": "eller", "or": "eller",

@ -1,7 +1,6 @@
@import (reference) '../../customize/src/less2/include/framework.less'; @import (reference) '../../customize/src/less2/include/framework.less';
@import (reference) '../../customize/src/less2/include/messenger.less'; @import (reference) '../../customize/src/less2/include/messenger.less';
@import (reference) '../../customize/src/less2/include/avatar.less'; @import (reference) '../../customize/src/less2/include/avatar.less';
@import (reference) '../../customize/src/less2/include/buttons.less';
// body // body
&.cp-app-contacts { &.cp-app-contacts {
@ -19,9 +18,6 @@
display: flex; // We need this to remove a 3px border at the bottom of the toolbar display: flex; // We need this to remove a 3px border at the bottom of the toolbar
} }
.cp-app-contacts-friends {
.buttons_main();
}
.cp-contacts-muted-table { .cp-contacts-muted-table {
.avatar_main(50px); .avatar_main(50px);
.cp-contacts-muted-user { .cp-contacts-muted-user {
@ -33,8 +29,6 @@
} }
} }
.messenger_main(); .messenger_main();
} }

@ -3,7 +3,6 @@
@import (reference) "../../customize/src/less2/include/tools.less"; @import (reference) "../../customize/src/less2/include/tools.less";
@import (reference) "../../customize/src/less2/include/markdown.less"; @import (reference) "../../customize/src/less2/include/markdown.less";
@import (reference) "../../customize/src/less2/include/avatar.less"; @import (reference) "../../customize/src/less2/include/avatar.less";
@import (reference) "../../customize/src/less2/include/buttons.less";
// body // body
&.cp-app-kanban { &.cp-app-kanban {
@ -142,6 +141,8 @@
.kanban-edit-item { .kanban-edit-item {
padding: 5px; padding: 5px;
border: 0;
background: transparent;
align-self: flex-start; align-self: flex-start;
} }
@ -310,7 +311,6 @@
position: relative; position: relative;
min-height: 50px; min-height: 50px;
.cp-kanban-filterTags { .cp-kanban-filterTags {
.buttons_main();
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
flex: 1; flex: 1;
@ -346,7 +346,7 @@
margin-left: 10px; margin-left: 10px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
&:not(:empty) { &:not(.cp-empty) {
margin-top: -5px; margin-top: -5px;
} }
em { em {

@ -503,7 +503,7 @@ define([
$container.find('.kanban-item').each(function (i, el) { $container.find('.kanban-item').each(function (i, el) {
var itemId = $(el).attr('data-eid'); var itemId = $(el).attr('data-eid');
$('<button>', { $('<button>', {
'class': 'kanban-edit-item btn btn-default fa fa-pencil', 'class': 'kanban-edit-item fa fa-pencil',
'alt': Messages.kanban_editCard, 'alt': Messages.kanban_editCard,
}).click(function (e) { }).click(function (e) {
getItemEditModal(framework, kanban, itemId); getItemEditModal(framework, kanban, itemId);
@ -513,7 +513,7 @@ define([
$container.find('.kanban-board').each(function (i, el) { $container.find('.kanban-board').each(function (i, el) {
var itemId = $(el).attr('data-id'); var itemId = $(el).attr('data-id');
$('<button>', { $('<button>', {
'class': 'kanban-edit-item btn btn-default fa fa-pencil', 'class': 'kanban-edit-item fa fa-pencil',
'alt': Messages.kanban_editBoard, 'alt': Messages.kanban_editBoard,
}).click(function (e) { }).click(function (e) {
getBoardEditModal(framework, kanban, itemId); getBoardEditModal(framework, kanban, itemId);
@ -913,7 +913,9 @@ define([
var redrawList = function (allTags) { var redrawList = function (allTags) {
if (!Array.isArray(allTags)) { return; } if (!Array.isArray(allTags)) { return; }
$list.empty(); $list.empty();
$list.removeClass('cp-empty');
if (!allTags.length) { if (!allTags.length) {
$list.addClass('cp-empty');
$list.append(h('em', Messages.kanban_noTags)); $list.append(h('em', Messages.kanban_noTags));
return; return;
} }

@ -1,6 +1,5 @@
@import (reference) "../../customize/src/less2/include/framework.less"; @import (reference) "../../customize/src/less2/include/framework.less";
@import (reference) "../../customize/src/less2/include/comments.less"; @import (reference) "../../customize/src/less2/include/comments.less";
@import (reference) "../../customize/src/less2/include/buttons.less";
body.cp-app-pad { body.cp-app-pad {
.framework_main( .framework_main(
@ -71,7 +70,6 @@ body.cp-app-pad {
order: 1; order: 1;
} }
div.cp-comment-bubble { div.cp-comment-bubble {
.buttons_main();
position: relative; position: relative;
order: 2; order: 2;
button { button {

@ -115,8 +115,11 @@ define([
}, { }, {
ok: Messages.register_writtenPassword, ok: Messages.register_writtenPassword,
cancel: Messages.register_cancel, cancel: Messages.register_cancel,
cancelClass: 'safe', /* If we're certain that we aren't using these "*Class" APIs
okClass: 'danger', anywhere else then we can deprecate them and make this a
custom modal in common-interface (or here). */
cancelClass: 'btn.btn-safe',
okClass: 'btn.btn-danger',
reverseOrder: true, reverseOrder: true,
done: function ($dialog) { done: function ($dialog) {
$dialog.find('> div').addClass('half'); $dialog.find('> div').addClass('half');

@ -8,6 +8,7 @@
@import (reference) '../../customize/src/less2/include/password-input.less'; @import (reference) '../../customize/src/less2/include/password-input.less';
@import (reference) '../../customize/src/less2/include/modals-ui-elements.less'; @import (reference) '../../customize/src/less2/include/modals-ui-elements.less';
@import (reference) '../../customize/src/less2/include/usergrid.less'; @import (reference) '../../customize/src/less2/include/usergrid.less';
@import (reference) '../../customize/src/less2/include/forms.less';
&.cp-app-secureiframe { &.cp-app-secureiframe {
.modals-ui-elements_main(); .modals-ui-elements_main();
@ -19,6 +20,7 @@
.password_main(); .password_main();
.modal_main(); .modal_main();
.usergrid_main(); .usergrid_main();
.forms_main();
#cp-filepicker-dialog { #cp-filepicker-dialog {
display: none; display: none;

@ -494,8 +494,8 @@ define([
}, { }, {
ok: Messages.register_writtenPassword, ok: Messages.register_writtenPassword,
cancel: Messages.register_cancel, cancel: Messages.register_cancel,
cancelClass: 'safe', cancelClass: 'btn.btn-safe',
okClass: 'danger', okClass: 'btn.btn-danger',
reverseOrder: true, reverseOrder: true,
done: function($dialog) { done: function($dialog) {
$dialog.find('> div').addClass('half'); $dialog.find('> div').addClass('half');

@ -18,6 +18,15 @@
display: flex; display: flex;
flex-flow: column; flex-flow: column;
.cp-support-form-attachments {
.fa {
cursor: pointer;
}
&> span {
padding: 10px;
}
}
.cp-support-language-list { .cp-support-language-list {
.cp-support-language { .cp-support-language {
margin-left: 5px; margin-left: 5px;

@ -165,8 +165,6 @@ define([
var form = APP.support.makeForm(); var form = APP.support.makeForm();
$div.find('button').before(form);
var id = Util.uid(); var id = Util.uid();
$div.find('button').click(function () { $div.find('button').click(function () {
@ -182,6 +180,7 @@ define([
$('.cp-sidebarlayout-category[data-category="tickets"]').click(); $('.cp-sidebarlayout-category[data-category="tickets"]').click();
} }
}); });
$div.find('button').before(form);
return $div; return $div;
}; };

@ -6,8 +6,9 @@ define([
'/common/common-hash.js', '/common/common-hash.js',
'/common/common-util.js', '/common/common-util.js',
'/common/clipboard.js', '/common/clipboard.js',
'/common/common-ui-elements.js',
'/customize/messages.js', '/customize/messages.js',
], function ($, ApiConfig, h, UI, Hash, Util, Clipboard, Messages) { ], function ($, ApiConfig, h, UI, Hash, Util, Clipboard, UIElements, Messages) {
var send = function (ctx, id, type, data, dest) { var send = function (ctx, id, type, data, dest) {
var common = ctx.common; var common = ctx.common;
@ -61,8 +62,23 @@ define([
}; };
var sendForm = function (ctx, id, form, dest) { var sendForm = function (ctx, id, form, dest) {
var $title = $(form).find('.cp-support-form-title'); var $form = $(form);
var $content = $(form).find('.cp-support-form-msg'); var $cat = $form.find('.cp-support-form-category');
var $title = $form.find('.cp-support-form-title');
var $content = $form.find('.cp-support-form-msg');
// TODO block submission until pending uploads are complete?
var $attachments = $form.find('.cp-support-attachments');
var category = $cat.val().trim();
/*
// || ($form.closest('.cp-support-list-ticket').data('cat') || "").trim();
// Messages.support_formCategoryError = "Error: category is empty"; // TODO ensure this is translated before use
if (!category) {
console.log($cat);
return void UI.alert(Messages.support_formCategoryError);
}
*/
var title = $title.val().trim(); var title = $title.val().trim();
if (!title) { if (!title) {
@ -72,18 +88,55 @@ define([
if (!content) { if (!content) {
return void UI.alert(Messages.support_formContentError); return void UI.alert(Messages.support_formContentError);
} }
$cat.val('');
$content.val(''); $content.val('');
$title.val(''); $title.val('');
var attachments = [];
$attachments.find('> span').each(function (i, el) {
var $el = $(el);
attachments.push({
href: $el.attr('data-href'),
name: $el.attr('data-name')
});
});
$attachments.html('');
send(ctx, id, 'TICKET', { send(ctx, id, 'TICKET', {
category: category,
title: title, title: title,
attachments: attachments,
message: content, message: content,
}, dest); }, dest);
return true; return true;
}; };
var makeForm = function (cb, title) { var makeCategoryDropdown = function (ctx, container, onChange, all) {
var categories = ['account', 'data', 'bug', 'other'];
if (all) { categories.push('all'); }
categories = categories.map(function (key) {
return {
tag: 'a',
content: h('span', Messages['support_cat_'+key]),
action: function () {
onChange(key);
}
};
});
var dropdownCfg = {
text: Messages.support_category,
angleDown: 1,
options: categories,
container: $(container),
isSelect: true
};
var $select = UIElements.createDropdown(dropdownCfg);
$select.find('button').addClass('btn');
return $select;
};
var makeForm = function (ctx, cb, title) {
var button; var button;
if (typeof(cb) === "function") { if (typeof(cb) === "function") {
@ -93,8 +146,22 @@ define([
var cancel = title ? h('button.btn.btn-secondary', Messages.cancel) : undefined; var cancel = title ? h('button.btn.btn-secondary', Messages.cancel) : undefined;
var category = h('input.cp-support-form-category', {
type: 'hidden',
value: ''
});
var catContainer = h('div.cp-dropdown-container' + (title ? '.cp-hidden': ''));
makeCategoryDropdown(ctx, catContainer, function (key) {
$(category).val(key);
});
var attachments, addAttachment;
var content = [ var content = [
h('hr'), h('hr'),
category,
catContainer,
h('br'),
h('input.cp-support-form-title' + (title ? '.cp-hidden' : ''), { h('input.cp-support-form-title' + (title ? '.cp-hidden' : ''), {
placeholder: Messages.support_formTitle, placeholder: Messages.support_formTitle,
type: 'text', type: 'text',
@ -104,11 +171,52 @@ define([
h('textarea.cp-support-form-msg', { h('textarea.cp-support-form-msg', {
placeholder: Messages.support_formMessage placeholder: Messages.support_formMessage
}), }),
h('label', Messages.support_attachments),
attachments = h('div.cp-support-attachments'),
addAttachment = h('button.btn', Messages.support_addAttachment),
h('hr'), h('hr'),
button, button,
cancel cancel
]; ];
$(addAttachment).click(function () {
var $input = $('<input>', {
'type': 'file',
'style': 'display: none;',
'multiple': 'multiple',
'accept': 'image/*'
}).on('change', function (e) {
var files = Util.slice(e.target.files);
files.forEach(function (file) {
var ev = {};
ev.callback = function (data) {
var x, a;
var span = h('span', {
'data-name': data.name,
'data-href': data.url
}, [
x = h('i.fa.fa-times'),
a = h('a', {
href: '#'
}, data.name)
]);
$(x).click(function () {
$(span).remove();
});
$(a).click(function (e) {
e.preventDefault();
ctx.common.openURL(data.url);
});
$(attachments).append(span);
};
// The empty object allows us to bypass the file upload modal
ctx.FM.handleFile(file, ev, {});
});
});
$input.click();
});
var form = h('div.cp-support-form-container', content); var form = h('div.cp-support-form-container', content);
$(cancel).click(function () { $(cancel).click(function () {
@ -125,6 +233,7 @@ define([
var privateData = metadataMgr.getPrivateData(); var privateData = metadataMgr.getPrivateData();
var ticketTitle = content.title + ' (#' + content.id + ')'; var ticketTitle = content.title + ' (#' + content.id + ')';
var ticketCategory;
var answer = h('button.btn.btn-primary.cp-support-answer', Messages.support_answer); var answer = h('button.btn.btn-primary.cp-support-answer', Messages.support_answer);
var close = h('button.btn.btn-danger.cp-support-close', Messages.support_close); var close = h('button.btn.btn-danger.cp-support-close', Messages.support_close);
var hide = h('button.btn.btn-danger.cp-support-hide', Messages.support_remove); var hide = h('button.btn.btn-danger.cp-support-hide', Messages.support_remove);
@ -137,6 +246,7 @@ define([
var url; var url;
if (ctx.isAdmin) { if (ctx.isAdmin) {
ticketCategory = Messages['support_cat_'+(content.category || 'all')] + ' - ';
url = h('button.btn.btn-primary.fa.fa-clipboard'); url = h('button.btn.btn-primary.fa.fa-clipboard');
$(url).click(function () { $(url).click(function () {
var link = privateData.origin + privateData.pathname + '#' + 'support-' + content.id; var link = privateData.origin + privateData.pathname + '#' + 'support-' + content.id;
@ -146,9 +256,10 @@ define([
} }
var $ticket = $(h('div.cp-support-list-ticket', { var $ticket = $(h('div.cp-support-list-ticket', {
'data-cat': content.category,
'data-id': content.id 'data-id': content.id
}, [ }, [
h('h2', [ticketTitle, url]), h('h2', [ticketCategory, ticketTitle, url]),
actions actions
])); ]));
@ -179,7 +290,7 @@ define([
$(answer).click(function () { $(answer).click(function () {
$ticket.find('.cp-support-form-container').remove(); $ticket.find('.cp-support-form-container').remove();
$(actions).hide(); $(actions).hide();
var form = makeForm(function () { var form = makeForm(ctx, function () {
var sent = sendForm(ctx, content.id, form, content.sender); var sent = sendForm(ctx, content.id, form, content.sender);
if (sent) { if (sent) {
$(actions).show(); $(actions).show();
@ -215,6 +326,22 @@ define([
ev.stopPropagation(); ev.stopPropagation();
}); });
var attachments = (content.attachments || []).map(function (obj) {
if (!obj || !obj.name || !obj.href) { return; }
// only support files explicitly beginning with /file/ so that users can't link outside of the instance
if (!/^\/file\//.test(obj.href)) { return; }
var a = h('a', {
href: '#'
}, obj.name);
$(a).click(function (e) {
e.preventDefault();
ctx.common.openURL(obj.href);
});
return h('span', [
a
]);
});
var adminClass = (fromAdmin? '.cp-support-fromadmin': ''); var adminClass = (fromAdmin? '.cp-support-fromadmin': '');
var premiumClass = (fromPremium && !fromAdmin? '.cp-support-frompremium': ''); var premiumClass = (fromPremium && !fromAdmin? '.cp-support-frompremium': '');
var name = Util.fixHTML(content.sender.name) || Messages.anonymous; var name = Util.fixHTML(content.sender.name) || Messages.anonymous;
@ -226,6 +353,7 @@ define([
h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '') h('span.cp-support-message-time', content.time ? new Date(content.time).toLocaleString() : '')
]), ]),
h('pre.cp-support-message-content', content.message), h('pre.cp-support-message-content', content.message),
h('div.cp-support-attachments', attachments),
isAdmin ? userData : undefined, isAdmin ? userData : undefined,
]); ]);
}; };
@ -257,10 +385,25 @@ define([
adminKeys: Array.isArray(ApiConfig.adminKeys)? ApiConfig.adminKeys.slice(): [], adminKeys: Array.isArray(ApiConfig.adminKeys)? ApiConfig.adminKeys.slice(): [],
}; };
var fmConfig = {
body: $('body'),
onUploaded: function (ev, data) {
if (ev.callback) {
ev.callback(data);
}
}
};
ctx.FM = common.createFileManager(fmConfig);
ui.sendForm = function (id, form, dest) { ui.sendForm = function (id, form, dest) {
return sendForm(ctx, id, form, dest); return sendForm(ctx, id, form, dest);
}; };
ui.makeForm = makeForm; ui.makeForm = function (cb, title) {
return makeForm(ctx, cb, title);
};
ui.makeCategoryDropdown = function (container, onChange, all) {
return makeCategoryDropdown(ctx, container, onChange, all);
};
ui.makeTicket = function ($div, content, onHide) { ui.makeTicket = function ($div, content, onHide) {
return makeTicket(ctx, $div, content, onHide); return makeTicket(ctx, $div, content, onHide);
}; };

@ -45,7 +45,7 @@
.cp-app-contacts-input { .cp-app-contacts-input {
textarea { textarea {
border: 0px; border: 0px;
color: white; color: @cryptpad_text_col;
} }
} }
} }

@ -422,6 +422,10 @@ define([
])); ]));
common.displayAvatar($(avatar), team.metadata.avatar, team.metadata.name); common.displayAvatar($(avatar), team.metadata.avatar, team.metadata.name);
$(btn).click(function () { $(btn).click(function () {
if (team.error) {
UI.warn(Messages.error); // XXX better error message - roster bug, can't load the team for now
return;
}
openTeam(common, id, team); openTeam(common, id, team);
}); });
}); });

@ -1,6 +1,5 @@
@import (reference) '../../customize/src/less2/include/tools.less'; @import (reference) '../../customize/src/less2/include/tools.less';
@import (reference) "../../customize/src/less2/include/framework.less"; @import (reference) "../../customize/src/less2/include/framework.less";
@import (reference) "../../customize/src/less2/include/buttons.less";
&.cp-app-whiteboard { &.cp-app-whiteboard {
@ -74,8 +73,6 @@
padding: 10px; padding: 10px;
.buttons_main();
& > * + * { & > * + * {
margin: 0; margin: 0;
margin-left: 1em; margin-left: 1em;

Loading…
Cancel
Save