diff --git a/customize.dist/src/less2/include/toolbar.less b/customize.dist/src/less2/include/toolbar.less
index 985f6bd83..a5e7ea251 100644
--- a/customize.dist/src/less2/include/toolbar.less
+++ b/customize.dist/src/less2/include/toolbar.less
@@ -1033,6 +1033,7 @@
flex-flow: column;
z-index: 10000; //Z cp-toolbar-drawer-content
color: black;
+ .tools_unselectable();
.fa {
font-size: 17px;
}
diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js
index 386353339..fc514ef3b 100644
--- a/www/common/common-ui-elements.js
+++ b/www/common/common-ui-elements.js
@@ -2299,7 +2299,9 @@ define([
value = val;
var $val = $innerblock.find('[data-value="'+val+'"]');
var textValue = name || $val.html() || val;
- $button.find('.cp-dropdown-button-title').html(textValue);
+ setTimeout(function () {
+ $button.find('.cp-dropdown-button-title').html(textValue);
+ });
};
$container.getValue = function () {
return value || '';
diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js
index 19faf940b..6b09656a0 100644
--- a/www/common/cryptpad-common.js
+++ b/www/common/cryptpad-common.js
@@ -1604,6 +1604,26 @@ define([
var allocated = Login.allocateBytes(bytes);
blockKeys = allocated.blockKeys;
}));
+ }).nThen(function (waitFor) {
+ var blockUrl = Block.getBlockUrl(blockKeys);
+ // Check whether there is a block at that location
+ Util.fetch(blockUrl, waitFor(function (err, block) {
+ // If there is no block or the block is invalid, continue.
+ if (err) {
+ console.log("no block found");
+ return;
+ }
+
+ var decryptedBlock = Block.decrypt(block, blockKeys);
+ if (!decryptedBlock) {
+ console.error("Found a login block but failed to decrypt");
+ return;
+ }
+
+ // If there is already a valid block, abort! We risk overriding another user's data
+ waitFor.abort();
+ cb({ error: 'EEXISTS' });
+ }));
}).nThen(function (waitFor) {
// Write the new login block
var temp = {
diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js
index cd3759d8d..803e0a715 100644
--- a/www/common/drive-ui.js
+++ b/www/common/drive-ui.js
@@ -2779,30 +2779,34 @@ define([
$sortBlock.on('click', 'a', onSortByClick);
return $fhSort;
};
- var getFolderListHeader = function () {
+ var getFolderListHeader = function (clickable, small) {
var $fohElement = $('
', {
'class': 'cp-app-drive-element-header cp-app-drive-element-list'
});
+ var clickCls = clickable ? 'cp-app-drive-sort-clickable ' : '';
+ var onClick = clickable ? onSortByClick : function () {};
//var $fohElement = $('', {'class': 'element'}).appendTo($folderHeader);
var $fhIcon = $('', {'class': 'cp-app-drive-content-icon'});
var $name = $('', {
- 'class': 'cp-app-drive-element-name cp-app-drive-sort-foldername ' +
- 'cp-app-drive-sort-clickable'
- }).text(Messages.fm_folderName).click(onSortByClick);
+ 'class': 'cp-app-drive-element-name cp-app-drive-sort-foldername ' + clickCls
+ }).text(Messages.fm_folderName).click(onClick);
var $state = $('', {'class': 'cp-app-drive-element-state'});
- var $subfolders = $('', {
- 'class': 'cp-app-drive-element-folders cp-app-drive-element-list'
- }).text(Messages.fm_numberOfFolders);
- var $files = $('', {
- 'class': 'cp-app-drive-element-files cp-app-drive-element-list'
- }).text(Messages.fm_numberOfFiles);
+ var $subfolders, $files;
+ if (!small) {
+ $subfolders = $('', {
+ 'class': 'cp-app-drive-element-folders cp-app-drive-element-list'
+ }).text(Messages.fm_numberOfFolders);
+ $files = $('', {
+ 'class': 'cp-app-drive-element-files cp-app-drive-element-list'
+ }).text(Messages.fm_numberOfFiles);
+ }
var $filler = $('', {
'class': 'cp-app-drive-element-filler cp-app-drive-element-list'
});
$fohElement.append($fhIcon).append($name).append($state)
.append($subfolders).append($files).append($filler);
- addFolderSortIcon($fohElement);
+ if (clickable) { addFolderSortIcon($fohElement); }
return $fohElement;
};
var addFileSortIcon = function ($list) {
@@ -2859,15 +2863,16 @@ define([
});
if (keys.length < 2) { return keys; }
var mult = asc ? 1 : -1;
- var getProp = function (el) {
- if (folder && root[el] && manager.isSharedFolder(root[el])) {
- var title = manager.getSharedFolderData(root[el]).title || el;
+ var getProp = function (_el) {
+ var el = useId ? _el : root[_el];
+ var sfId = (el && el.root && el.key) ? el.root[el.key] : el;
+ if (folder && el && manager.isSharedFolder(sfId)) {
+ var title = manager.getSharedFolderData(sfId).title || el;
return String(title).toLowerCase();
} else if (folder) {
- return el.toLowerCase();
+ return String((el && el.key) || el).toLowerCase();
}
- var id = useId ? el : root[el];
- var data = manager.getFileData(id);
+ var data = manager.getFileData(el);
if (!data) { return ''; }
if (prop === 'type') {
var hrefData = Hash.parsePadUrl(data.href || data.roHref);
@@ -2876,15 +2881,19 @@ define([
if (prop === 'atime' || prop === 'ctime') {
return typeof(data[prop]) === "number" ? data[prop] : new Date(data[prop]);
}
- return (manager.getTitle(id) || "").toLowerCase();
+ return (manager.getTitle(el) || "").toLowerCase();
};
var props = {};
keys.forEach(function (k) {
- props[k] = getProp(k);
+ var uid = k;
+ if (typeof(k) === "object") {
+ uid = k.uid = Util.uid();
+ }
+ props[uid] = getProp(k);
});
keys.sort(function(a, b) {
- var _a = props[a];
- var _b = props[b];
+ var _a = props[(a && a.uid) || a];
+ var _b = props[(b && b.uid) || b];
if (_a < _b) { return mult * -1; }
if (_b < _a) { return mult; }
return 0;
@@ -3233,9 +3242,10 @@ define([
$input.focus();
});
- getFileListHeader(false).appendTo($list);
$list.closest('#cp-app-drive-content-folder').addClass('cp-app-drive-content-list');
var filesList = manager.search(value);
+ var sortable = {};
+ var sortableFolders = [];
filesList.forEach(function (r) {
// if r.id === null, then it's a folder, not a file
r.paths.forEach(function (path) {
@@ -3244,33 +3254,56 @@ define([
var _path = path.slice();
var key = path.pop();
var root = manager.find(path);
- var isFolder = manager.isFolder(root[key]);
- var $element = createElement(path, key, root, isFolder);
- $element.addClass('cp-app-drive-element-notrash cp-app-drive-search-result');
- $element.off('contextmenu');
- $element.contextmenu(openContextMenu('default'));
- $element.data('context', 'default');
- if (isFolder) {
- $element.find('.cp-app-drive-element-list').css({
- visibility: 'hidden'
- }).text('');
- $element.find('.cp-app-drive-element-folders').css({
- visibility: ''
- }).text(Messages.fm_folder);
- }
-
- if (manager.isPathIn(_path, ['hrefArray'])) {
- _path.pop();
- _path.push(r.data.title);
+ var obj = {
+ path: path,
+ _path: _path,
+ key: key,
+ root: root,
+ data: r.data
+ };
+ if (manager.isFolder(root[key])) {
+ sortableFolders.push(obj);
+ return;
}
- var $path = $('', {
- 'class': 'cp-app-drive-search-path'
- }).appendTo($element.find('.cp-app-drive-element-name'));
- createTitle($path, _path);
-
- $list.append($element);
+ sortable[root[key]] = obj;
});
});
+ var _folders = sortElements(true, [ROOT], sortableFolders, null, !getSortFolderDesc(), true);
+ var sortableKeys = Object.keys(sortable).map(Number);
+ var _files = sortElements(false, [ROOT], sortableKeys, APP.store[SORT_FILE_BY], !getSortFileDesc(), true);
+
+ var addEl = function (obj, folder) {
+ var $element = createElement(obj.path, obj.key, obj.root, folder);
+ $element.addClass('cp-app-drive-element-notrash cp-app-drive-search-result');
+ $element.off('contextmenu');
+ $element.contextmenu(openContextMenu('default'));
+ $element.data('context', 'default');
+ if (folder) {
+ $element.find('.cp-app-drive-element-list').css({
+ visibility: 'hidden'
+ }).text('');
+ }
+ if (manager.isPathIn(obj._path, ['hrefArray'])) {
+ obj._path.pop();
+ obj._path.push(obj.data.title);
+ }
+ var $path = $('', {
+ 'class': 'cp-app-drive-search-path'
+ }).appendTo($element.find('.cp-app-drive-element-name'));
+ createTitle($path, obj._path);
+
+ $list.append($element);
+ };
+ if (_folders.length) { getFolderListHeader(true, true).appendTo($list); }
+ _folders.forEach(function (el) {
+ var obj = el;
+ addEl(obj, true);
+ });
+ if (_files.length) { getFileListHeader(true).appendTo($list); }
+ _files.forEach(function (el) {
+ var obj = sortable[el];
+ addEl(obj, false);
+ });
setTimeout(collapseDrivePath);
};
@@ -3415,7 +3448,7 @@ define([
}
var fId = APP.newSharedFolder;
var data = folders[fId];
- var $folderHeader = getFolderListHeader();
+ var $folderHeader = getFolderListHeader(true);
var $fileHeader = getFileListHeader(true);
var path = currentPath.slice(1);
var root = Util.find(data, path);
@@ -3593,7 +3626,7 @@ define([
}
updateContextButton();
- var $folderHeader = getFolderListHeader();
+ var $folderHeader = getFolderListHeader(true);
var $fileHeader = getFileListHeader(true);
if (isTemplate) {
diff --git a/www/common/migrate-user-object.js b/www/common/migrate-user-object.js
index b13aacb1c..000744cc9 100644
--- a/www/common/migrate-user-object.js
+++ b/www/common/migrate-user-object.js
@@ -478,6 +478,7 @@ define([
store: store,
};
var myData = Messaging.createData(userObject);
+ if (!myData.curvePublic) { return void done(); }
Mailbox.sendTo(ctx, 'SAFE_LINKS_DEFAULT', {
user: myData,
diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json
index 3ab3680ea..8992a1b0b 100644
--- a/www/common/translations/messages.de.json
+++ b/www/common/translations/messages.de.json
@@ -1394,5 +1394,6 @@
"support_cat_bug": "Fehlerbericht",
"oo_refresh": "Neu laden",
"support_category": "Wähle eine Kategorie",
- "oo_refreshText": "Dieses Dokument wurde aktualisiert"
+ "oo_refreshText": "Dieses Dokument wurde aktualisiert",
+ "support_formCategoryError": "Fehler: Kategorie ist leer"
}
diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json
index d99fd8d18..ede0c1a5a 100644
--- a/www/common/translations/messages.json
+++ b/www/common/translations/messages.json
@@ -1394,5 +1394,6 @@
"notification_folderSharedTeam": "{0} has shared a folder with the team {2}: {1}",
"oo_refresh": "Refresh",
"oo_refreshText": "This document has been updated",
- "support_category": "Choose a category"
+ "support_category": "Choose a category",
+ "support_formCategoryError": "Error: category is empty"
}
diff --git a/www/common/userObject.js b/www/common/userObject.js
index fbe28864a..23978cb65 100644
--- a/www/common/userObject.js
+++ b/www/common/userObject.js
@@ -640,6 +640,7 @@ define([
var res = [];
// Search title
var allFilesList = files[FILES_DATA];
+ var allSFList = files[SHARED_FOLDERS];
var lValue = value.toLowerCase();
// parse the search string into tags
@@ -661,13 +662,14 @@ define([
});
};
- getFiles([FILES_DATA]).forEach(function (id) {
- var data = allFilesList[id];
+ getFiles([FILES_DATA, SHARED_FOLDERS]).forEach(function (id) {
+ var data = allFilesList[id] || allSFList[id];
if (!data) { return; }
if (Array.isArray(data.tags) && containsSearchedTag(data.tags)) {
- res.push(id);
- } else
- if ((data.title && data.title.toLowerCase().indexOf(lValue) !== -1) ||
+ return void res.push(id);
+ }
+ var title = data.title || data.lastTitle;
+ if ((title && title.toLowerCase().indexOf(lValue) !== -1) ||
(data.filename && data.filename.toLowerCase().indexOf(lValue) !== -1)) {
res.push(id);
}
diff --git a/www/common/visible.js b/www/common/visible.js
index f73fa49bc..61512ff59 100644
--- a/www/common/visible.js
+++ b/www/common/visible.js
@@ -25,10 +25,12 @@
typeof document[hidden] === "undefined");
};
- Visible.onChange = function (f) {
+ Visible.onChange = function (f, once) {
document.addEventListener(visibilityChange, function (ev) {
f(!document[hidden], ev);
- }, false);
+ }, {
+ once: once
+ });
};
Visible.currently = function () {
diff --git a/www/kanban/jkanban_cp.js b/www/kanban/jkanban_cp.js
index 54fb71f46..1604a1315 100644
--- a/www/kanban/jkanban_cp.js
+++ b/www/kanban/jkanban_cp.js
@@ -1,8 +1,9 @@
define([
'jquery',
'/customize/messages.js',
+ '/common/visible.js',
'/bower_components/dragula.js/dist/dragula.min.js',
-], function ($, Messages, Dragula) {
+], function ($, Messages, Visible, Dragula) {
/**
* jKanban
* Vanilla Javascript plugin for manage kanban boards
@@ -739,6 +740,8 @@ define([
return self;
};
+ var todoOnVisible = function () {};
+ var onVisibleHandler = false;
this.setBoards = function (boards) {
var scroll = {};
// Fix the tags
@@ -754,15 +757,30 @@ define([
this.removeBoard(boardkey);
}
this.options.boards = boards;
- // Add all new boards
- this.addBoards();
- self.options.refresh();
- // Preserve scroll
- this.options.boards.list.forEach(function (id) {
- if (!scroll[id]) { return; }
- $('.kanban-board[data-id="'+id+'"] .kanban-drag').scrollTop(scroll[id]);
- });
- $el.scrollLeft(scrollLeft);
+
+ todoOnVisible = function () {
+ // Add all new boards
+ self.addBoards();
+ self.options.refresh();
+ // Preserve scroll
+ self.options.boards.list.forEach(function (id) {
+ if (!scroll[id]) { return; }
+ $('.kanban-board[data-id="'+id+'"] .kanban-drag').scrollTop(scroll[id]);
+ });
+ $el.scrollLeft(scrollLeft);
+ };
+
+ // If the tab is not focused, redraw on focus
+ if (!Visible.currently()) {
+ if (onVisibleHandler) { return; }
+ onVisibleHandler = true;
+ return void Visible.onChange(function (visible) {
+ if (!visible) { return; }
+ todoOnVisible();
+ onVisibleHandler = false;
+ }, true);
+ }
+ todoOnVisible();
};
this.findBoard = function (id) {
diff --git a/www/pad/app-pad.less b/www/pad/app-pad.less
index 103241a52..e3de1fcf0 100644
--- a/www/pad/app-pad.less
+++ b/www/pad/app-pad.less
@@ -36,6 +36,9 @@ body.cp-app-pad {
align-items: center;
padding: 4px;
}
+ .cke_button__print {
+ display: none !important;
+ }
}
.cke_wysiwyg_frame {
width: 100%;
diff --git a/www/pad/inner.js b/www/pad/inner.js
index 05cf2c788..f189d7447 100644
--- a/www/pad/inner.js
+++ b/www/pad/inner.js
@@ -456,6 +456,15 @@ define([
});
};
+ var mkPrintButton = function (framework, editor) {
+ var $printButton = framework._.sfCommon.createButton('print', true);
+ $printButton.click(function () {
+ editor.execCommand('print');
+ framework.feedback('PRINT_PAD');
+ });
+ framework._.toolbar.$drawer.append($printButton);
+ };
+
var andThen2 = function(editor, Ckeditor, framework) {
var mediaTagMap = {};
var $contentContainer = $('#cke_1_contents');
@@ -480,6 +489,8 @@ define([
framework._.sfCommon.addShortcuts(ifrWindow);
+ mkPrintButton(framework, editor, Ckeditor);
+
var documentBody = ifrWindow.document.body;
var inner = window.inner = documentBody;
var $inner = $(inner);
diff --git a/www/settings/inner.js b/www/settings/inner.js
index 3fc87d175..234402ab5 100644
--- a/www/settings/inner.js
+++ b/www/settings/inner.js
@@ -488,6 +488,7 @@ define([
UI.removeLoadingScreen();
if (obj && obj.error) {
// TODO
+ // XXX EEXISTS error message?
UI.alert(Messages.settings_changePasswordError);
}
});