From eb9a39eb68274184d8aa2784b2a4e57e9690b981 Mon Sep 17 00:00:00 2001 From: Pierre Bondoerffer Date: Tue, 28 Feb 2017 23:15:47 +0100 Subject: [PATCH 01/84] Add hover on elements in drive and make grid slightly prettier --- www/drive/file.css | 5 +++++ www/drive/file.less | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/www/drive/file.css b/www/drive/file.css index 0013e063c..466637c0d 100644 --- a/www/drive/file.css +++ b/www/drive/file.css @@ -220,6 +220,9 @@ span.fa-folder-open { #content li:not(.header) *:not(input) { /*pointer-events: none;*/ } +#content li:not(.header):hover:not(.selected) { + background-color: #eee; +} #content li:not(.header):hover .name { /*text-decoration: underline;*/ } @@ -233,6 +236,8 @@ span.fa-folder-open { text-align: center; vertical-align: top; overflow: hidden; + padding-top: 10px; + padding-bottom: 5px; } #content div.grid li .name { width: 100%; diff --git a/www/drive/file.less b/www/drive/file.less index d3f49709a..c1cc1d34e 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -261,6 +261,9 @@ span { /*pointer-events: none;*/ } &:hover { + &:not(.selected) { + background-color: #eee; + } .name { /*text-decoration: underline;*/ } @@ -276,6 +279,8 @@ span { text-align: center; vertical-align: top; overflow: hidden; + padding-top: 10px; + padding-bottom: 5px; .name { width: 100%; From a2b5200381016b1233fff0546f3b4e8eccefec9b Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 14:44:43 +0100 Subject: [PATCH 02/84] Add a container for the folders in the tree in the drive --- www/drive/main.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/drive/main.js b/www/drive/main.js index 94c5d91b2..c1448f435 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -1489,9 +1489,11 @@ define([ if (collapsable) { $collapse = $expandIcon.clone(); } - var $element = $('
  • ').append($collapse).append($icon).append($name).click(function (e) { + var $elementRow = $('', {'class': 'element-row'}).append($collapse).append($icon).append($name).click(function (e) { + e.stopPropagation(); module.displayDirectory(path); }); + var $element = $('
  • ').append($elementRow); if (draggable) { $element.attr('draggable', true); } if (collapsable) { $element.addClass('collapsed'); From a26b9d32405e4ca1bd9bc01babc96f6db6485e05 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 15:46:10 +0100 Subject: [PATCH 03/84] Don't select subfolders in the tree when right-click on drag&drop --- www/drive/main.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/www/drive/main.js b/www/drive/main.js index c1448f435..209e40eb3 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -245,6 +245,8 @@ define([ var removeInput = function () { $iframe.find('li > span:hidden').removeAttr('style'); $iframe.find('li > input').remove(); + $iframe.find('.element-row > input').remove(); + $iframe.find('.element-row > span:hidden').removeAttr('style'); }; var compareDays = function (date1, date2) { @@ -438,6 +440,7 @@ define([ if (!$element.is('li')) { $element = $element.closest('li'); } + if ($element.find('>.element-row').length) { $element = $element.find('>.element-row'); } if (!$element.length) { log(Messages.fm_selectError); return; @@ -457,6 +460,7 @@ define([ e.stopPropagation(); var $element = $(e.target).closest('li'); + if ($element.find('>.element-row').length) { $element = $element.find('>.element-row'); } if (!$element.length) { logError("Unable to locate the .element tag", e.target); $menu.hide(); @@ -660,7 +664,7 @@ define([ } }); - var newPath = $(ev.target).data('path') || $(ev.target).parent('li').data('path'); + var newPath = $(ev.target).data('path') || $(ev.target).parent('.element-row').data('path') || $(ev.target).parent('li').data('path'); if (!newPath) { return; } if (movedPaths && movedPaths.length) { moveElements(movedPaths, newPath, null, refresh); @@ -1348,6 +1352,7 @@ define([ // NOTE: Elements in the trash are not using the same storage structure as the others // _WORKGROUP_ : do not change the lastOpenedFolder value in localStorage var displayDirectory = module.displayDirectory = function (path, force) { + module.hideMenu(); if (!APP.editable) { debug("Read-only mode"); } if (!appStatus.isReady && !force) { return; } // Only Trash and Root are available in not-owned files manager @@ -1494,7 +1499,7 @@ define([ module.displayDirectory(path); }); var $element = $('
  • ').append($elementRow); - if (draggable) { $element.attr('draggable', true); } + if (draggable) { $elementRow.attr('draggable', true); } if (collapsable) { $element.addClass('collapsed'); $collapse.click(function(e) { @@ -1522,8 +1527,8 @@ define([ $collapse.click(); } } - $element.data('path', path); - addDragAndDropHandlers($element, path, true, droppable); + $elementRow.data('path', path); + addDragAndDropHandlers($elementRow, path, true, droppable); if (active) { $name.addClass('active'); } return $element; }; @@ -1562,7 +1567,7 @@ define([ (isCurrentFolder ? $folderOpenedIcon : $folderIcon); var $element = createTreeElement(key, $icon.clone(), newPath, true, true, subfolder, isCurrentFolder); $element.appendTo($list); - $element.contextmenu(openDirectoryContextMenu); + $element.find('>.element-row').contextmenu(openDirectoryContextMenu); createTree($element, newPath); }); }; From c6c3e1bbb566234b13a6ec9f0e60ffd5d0050e29 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 15:53:31 +0100 Subject: [PATCH 04/84] Don't select subfolders in the tree when drag&drop --- www/drive/main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/drive/main.js b/www/drive/main.js index 209e40eb3..c4aa73d63 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -609,6 +609,7 @@ define([ var onDrag = function (ev, path) { var paths = []; var $element = $(ev.target).closest('li'); + if ($element.find('>.element-row').length) { $element = $element.find('>.element-row'); } if ($element.hasClass('selected')) { var $selected = $iframe.find('.selected'); $selected.each(function (idx, elmt) { From 3e9c4d0901463ea9f20e077341670bc281f6132b Mon Sep 17 00:00:00 2001 From: Pierre Bondoerffer Date: Wed, 1 Mar 2017 15:57:22 +0100 Subject: [PATCH 05/84] Add hover to file manager tree --- www/drive/file.css | 11 +++++++---- www/drive/file.less | 15 ++++++++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/www/drive/file.css b/www/drive/file.css index 466637c0d..e80d6f98a 100644 --- a/www/drive/file.css +++ b/www/drive/file.css @@ -101,18 +101,21 @@ span.fa-folder-open { color: #000; } #tree li { - /*cursor: pointer;*/ cursor: auto; } -#tree li:hover > span.element { - text-decoration: underline; -} #tree li.collapsed ul { display: none; } #tree li input { width: calc(70%); } +#tree li > span.element-row { + width: 100%; + display: inline-block; +} +#tree li > span.element-row:not(.selected):hover { + background-color: #eee; +} #tree span.element { cursor: pointer; } diff --git a/www/drive/file.less b/www/drive/file.less index c1cc1d34e..d5a7c1d73 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -2,6 +2,8 @@ @tree-fg: #000; @tree-lines-col: #888; +@drive-hover: #eee; + @content-bg: @tree-bg; @content-bg-ro: darken(@content-bg, 10%); @content-fg: @tree-fg; @@ -134,17 +136,20 @@ span { padding: 10px 0px; color: @tree-fg; li { - /*cursor: pointer;*/ cursor: auto; - &:hover > span.element { - text-decoration: underline; - } &.collapsed ul { display: none; } input { width: calc(100% - 30px); } + & > span.element-row { + width: 100%; + display: inline-block; + } + & > span.element-row:not(.selected):hover { + background-color: @drive-hover; + } } span.element { cursor: pointer; @@ -262,7 +267,7 @@ span { } &:hover { &:not(.selected) { - background-color: #eee; + background-color: @drive-hover; } .name { /*text-decoration: underline;*/ From 55210f17eb3895afdc1affe8770fd1b44645886c Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 16:15:48 +0100 Subject: [PATCH 06/84] Clean the code to be less dependant on 'li' --- www/drive/main.js | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/www/drive/main.js b/www/drive/main.js index c4aa73d63..1b6dd4a79 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -236,6 +236,10 @@ define([ } }; + var findDataHolder = function ($el) { + return $el.is('.element-row') ? $el : $el.closest('.element-row'); + }; + var removeSelected = function () { $iframe.find('.selected').removeClass("selected"); var $container = $driveToolbar.find('#contextButtonsContainer'); @@ -243,8 +247,6 @@ define([ $container.html(''); }; var removeInput = function () { - $iframe.find('li > span:hidden').removeAttr('style'); - $iframe.find('li > input').remove(); $iframe.find('.element-row > input').remove(); $iframe.find('.element-row > span:hidden').removeAttr('style'); }; @@ -376,7 +378,7 @@ define([ var updateContextButton = function () { var $li = $content.find('.selected'); if ($li.length !== 1) { - $li = $tree.find('.element.active').closest('li'); + $li = findDataHolder($tree.find('.element.active')); } var $button = $driveToolbar.find('#contextButton'); if ($button.length) { // mobile @@ -437,10 +439,7 @@ define([ if (!e || !e.ctrlKey) { removeSelected(); } - if (!$element.is('li')) { - $element = $element.closest('li'); - } - if ($element.find('>.element-row').length) { $element = $element.find('>.element-row'); } + $element = findDataHolder($element); if (!$element.length) { log(Messages.fm_selectError); return; @@ -459,8 +458,7 @@ define([ module.hideMenu(); e.stopPropagation(); - var $element = $(e.target).closest('li'); - if ($element.find('>.element-row').length) { $element = $element.find('>.element-row'); } + var $element = findDataHolder($(e.target)); if (!$element.length) { logError("Unable to locate the .element tag", e.target); $menu.hide(); @@ -514,7 +512,7 @@ define([ }; var openTrashContextMenu = function (e) { - var path = $(e.target).closest('li').data('path'); + var path = findDataHolder($(e.target)).data('path'); if (!path) { return; } $trashContextMenu.find('li').show(); openContextMenu(e, $trashContextMenu); @@ -608,8 +606,7 @@ define([ // The data transferred is a stringified JSON containing the path of the dragged element var onDrag = function (ev, path) { var paths = []; - var $element = $(ev.target).closest('li'); - if ($element.find('>.element-row').length) { $element = $element.find('>.element-row'); } + var $element = findDataHolder($(ev.target)); if ($element.hasClass('selected')) { var $selected = $iframe.find('.selected'); $selected.each(function (idx, elmt) { @@ -665,7 +662,8 @@ define([ } }); - var newPath = $(ev.target).data('path') || $(ev.target).parent('.element-row').data('path') || $(ev.target).parent('li').data('path'); + var $el = findDataHolder($(ev.target)); + var newPath = $el.data('path'); if (!newPath) { return; } if (movedPaths && movedPaths.length) { moveElements(movedPaths, newPath, null, refresh); @@ -796,7 +794,8 @@ define([ $icon = filesOp.isFolderEmpty(root[key]) ? $folderEmptyIcon.clone() : $folderIcon.clone(); } var $element = $('
  • ', { - draggable: true + draggable: true, + 'class': 'element-row' }); if (isFolder) { addFolderData(element, key, $element); @@ -1261,7 +1260,7 @@ define([ var idx = files[rootName].indexOf(href); var $icon = getFileIcon(href); var $element = $('
  • ', { - 'class': 'file-element element', + 'class': 'file-element element element-row', draggable: draggable }); addFileData(href, file.title, $element, false); @@ -1293,7 +1292,7 @@ define([ var sortedFiles = sortElements(false, [FILES_DATA], keys, Cryptpad.getLSAttribute(SORT_FILE_BY), !getSortFileDesc(), false, true); sortedFiles.forEach(function (file) { var $icon = getFileIcon(file.href); - var $element = $('
  • ', { 'class': 'file-element element' }); + var $element = $('
  • ', { 'class': 'file-element element element-row' }); addFileData(file.href, file.title, $element, false); $element.data('path', [FILES_DATA, allfiles.indexOf(file)]); $element.data('element', file.href); @@ -1415,7 +1414,7 @@ define([ e.stopPropagation(); var $li = $content.find('.selected'); if ($li.length !== 1) { - $li = $tree.find('.element.active').closest('li'); + $li = findDataHolder($tree.find('.element.active')); } // Close if already opened if ($iframe.find('.contextMenu:visible').length) { @@ -1474,7 +1473,7 @@ define([ }; var refreshFilesData = function () { - $content.find('li').each(function (i, e) { + $content.find('.element-row').each(function (i, e) { var $el = $(e); if ($el.data('path')) { var path = $el.data('path'); From 8bdc8415ab2cab2185d87cdf8f09a63bc3e770d5 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 2 Mar 2017 10:15:13 +0100 Subject: [PATCH 07/84] Find a pad in the drive --- customize.dist/fsStore.js | 4 ++ www/common/cryptpad-common.js | 2 + www/common/fileObject.js | 120 ++++++++++++++++++++++++++++++++++ www/drive/file.css | 1 + www/drive/file.less | 1 + www/drive/main.js | 2 +- 6 files changed, 129 insertions(+), 1 deletion(-) diff --git a/customize.dist/fsStore.js b/customize.dist/fsStore.js index fbf7a5719..7ccde1947 100644 --- a/customize.dist/fsStore.js +++ b/customize.dist/fsStore.js @@ -119,6 +119,10 @@ define([ return filesOp.getStructure(); }; + ret.replaceHref = function (o, n) { + return filesOp.replaceHref(o, n); + }; + var changeHandlers = ret.changeHandlers = []; ret.change = function (f) {}; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index c78f938d2..222c658c4 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -423,6 +423,8 @@ define([ var ret = {}; + if (!href) { return ret; } + if (!/^https*:\/\//.test(href)) { var idx = href.indexOf('/#'); ret.type = href.slice(1, idx); diff --git a/www/common/fileObject.js b/www/common/fileObject.js index d8f10ced4..822035583 100644 --- a/www/common/fileObject.js +++ b/www/common/fileObject.js @@ -242,6 +242,90 @@ define([ return ret; }; + var _findFileInRoot = function (path, href) { + if (path[0] !== ROOT) { return []; } + var paths = []; + var root = exp.findElement(files, path); + + var addPaths = function (p) { + if (paths.indexOf(p) === -1) { + paths.push(p); + } + }; + + if (isFile(root)) { + if (compareFiles(href, root[e])) { + if (paths.indexOf(path) === -1) { + paths.push(path); + } + } + return paths; + } + for (var e in root) { + if (!isFile(root[e])) { + var nPath = path.slice(); + nPath.push(e); + _findFileInRoot(nPath, href).forEach(addPaths); + } + } + + return paths; + }; + var _findFileInArray = function (rootName, href) { + var unsorted = files[rootName].slice(); + var ret = []; + var i = -1; + while ((i = unsorted.indexOf(href, i+1)) != -1){ + ret.push([rootName, i]); + } + return ret; + }; + var _findFileInTrash = function (path, href) { + var root = exp.findElement(files, path); + var paths = []; + var addPaths = function (p) { + if (paths.indexOf(p) === -1) { + paths.push(p); + } + }; + if (path.length === 1) { + Object.keys(root).forEach(function (key) { + var arr = root[key]; + if (!Array.isArray(arr)) { return; } + var nPath = path.slice(); + nPath.push(key); + _findFileInTrash(nPath, href).forEach(addPaths); + }); + } + if (path.length === 2) { + if (!Array.isArray(root)) { return []; } + root.forEach(function (el, i) { + var nPath = path.slice(); + nPath.push(i); + nPath.push('element'); + if (isFile(el.element)) { + if (compareFiles(href, el.element)) { + addPaths(nPath); + } + return; + } + _findFileInTrash(nPath, href).forEach(addPaths); + }); + } + if (path.length >= 4) { + _findFileInRoot(path, href).forEach(addPaths); + } + return paths; + }; + var findFile = exp.findFile = function (href) { + var rootpaths = _findFileInRoot([ROOT], href); + var unsortedpaths = _findFileInHrefArray(UNSORTED, href); + var templatepaths = _findFileInHrefArray(TEMPLATE, href); + var trashpaths = _findFileInTrash([TRASH], href); + // TODO return concat all + }; + + // Remove the selected 'href' from the tree located at 'path', and push its locations to the 'paths' array var removeFileFromRoot = function (path, href) { var paths = []; @@ -802,6 +886,42 @@ define([ } }; + var replaceFile = function (path, o, n) { + var root = exp.findElement(files, path); + + if (isFile(root)) { return; } + for (var e in root) { + if (isFile(root[e])) { + if (compareFiles(o, root[e])) { + root[e] = n; + } + } else { + var nPath = path.slice(); + nPath.push(e); + replaceFile(nPath, o, n); + } + } + }; + + // Replace a href by a stronger one everywhere in the drive (except FILES_DATA) + var replaceHref = exp.replaceHref = function (o, n) { + replaceFile([ROOT], o, n); + var i = files[UNSORTED].indexOf(o); + if (i !== -1) { + files[UNSORTED].splice(i, 1); + files[UNSORTED].push(n); + } + var j = files[TEMPLATE].indexOf(o); + if (j !== -1) { + files[TEMPLATE].splice(j, 1); + files[TEMPLATE].push(n); + } + var k = getTrashFiles().indexOf(o); + if (k !== -1) { + // TODO? + } + }; + // addTemplate is called when we want to add a new pad, never visited, to the templates list // first, we must add it to FILES_DATA, so the input has to be an fileDAta object var addTemplate = exp.addTemplate = function (fileData) { diff --git a/www/drive/file.css b/www/drive/file.css index e80d6f98a..5f25a8957 100644 --- a/www/drive/file.css +++ b/www/drive/file.css @@ -112,6 +112,7 @@ span.fa-folder-open { #tree li > span.element-row { width: 100%; display: inline-block; + cursor: pointer; } #tree li > span.element-row:not(.selected):hover { background-color: #eee; diff --git a/www/drive/file.less b/www/drive/file.less index d5a7c1d73..930d82ec1 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -146,6 +146,7 @@ span { & > span.element-row { width: 100%; display: inline-block; + cursor: pointer; } & > span.element-row:not(.selected):hover { background-color: @drive-hover; diff --git a/www/drive/main.js b/www/drive/main.js index 1b6dd4a79..e53f1c94d 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -1164,7 +1164,7 @@ define([ var e = useData ? element : filesOp.getFileData(element); if (!e) { e = { - href : el, + href : element, title : Messages.fm_noname, atime : 0, ctime : 0 From d26d8f53d9bee8bd8ebfe9dcf22a67b947378f2b Mon Sep 17 00:00:00 2001 From: Pierre Bondoerffer Date: Thu, 2 Mar 2017 15:50:03 +0100 Subject: [PATCH 08/84] (CSS) Fixed textarea being too large --- www/poll/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/www/poll/index.html b/www/poll/index.html index cdaf574f3..a6de75ade 100644 --- a/www/poll/index.html +++ b/www/poll/index.html @@ -92,6 +92,7 @@ margin: auto; min-width: 80%; + width: 80%; min-height: 5em; font-size: 20px; font-weight: bold; From c5f983ecd7c581d9383cc6d75a05ce9b20531507 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 2 Mar 2017 16:01:34 +0100 Subject: [PATCH 09/84] Convert read-only link to editing link in the drive --- www/common/cryptpad-common.js | 14 ++++++++ www/common/fileObject.js | 64 +++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 222c658c4..b07adc422 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -630,6 +630,7 @@ define([ return; } + var updateWeaker = []; var contains; var renamed = recent.map(function (pad) { var p = parsePadUrl(pad.href); @@ -663,6 +664,14 @@ define([ // set the name pad.title = name; + + // If we now have a stronger version of a stored href, replace the weaker one by the strong one + if (pad && pad.href && href !== pad.href) { + updateWeaker.push({ + o: pad.href, + n: href + }); + } pad.href = href; } return pad; @@ -677,6 +686,11 @@ define([ } setRecentPads(renamed, function (err, data) { + if (updateWeaker.length > 0) { + updateWeaker.forEach(function (obj) { + getStore().replaceHref(obj.o, obj.n); + }); + } cb(err, data); }); }); diff --git a/www/common/fileObject.js b/www/common/fileObject.js index 822035583..158f664ff 100644 --- a/www/common/fileObject.js +++ b/www/common/fileObject.js @@ -243,10 +243,9 @@ define([ }; var _findFileInRoot = function (path, href) { - if (path[0] !== ROOT) { return []; } + if (path[0] !== ROOT && path[0] !== TRASH) { return []; } var paths = []; var root = exp.findElement(files, path); - var addPaths = function (p) { if (paths.indexOf(p) === -1) { paths.push(p); @@ -254,7 +253,7 @@ define([ }; if (isFile(root)) { - if (compareFiles(href, root[e])) { + if (compareFiles(href, root)) { if (paths.indexOf(path) === -1) { paths.push(path); } @@ -262,16 +261,14 @@ define([ return paths; } for (var e in root) { - if (!isFile(root[e])) { - var nPath = path.slice(); - nPath.push(e); - _findFileInRoot(nPath, href).forEach(addPaths); - } + var nPath = path.slice(); + nPath.push(e); + _findFileInRoot(nPath, href).forEach(addPaths); } return paths; }; - var _findFileInArray = function (rootName, href) { + var _findFileInHrefArray = function (rootName, href) { var unsorted = files[rootName].slice(); var ret = []; var i = -1; @@ -322,10 +319,9 @@ define([ var unsortedpaths = _findFileInHrefArray(UNSORTED, href); var templatepaths = _findFileInHrefArray(TEMPLATE, href); var trashpaths = _findFileInTrash([TRASH], href); - // TODO return concat all + return rootpaths.concat(unsortedpaths, templatepaths, trashpaths); }; - // Remove the selected 'href' from the tree located at 'path', and push its locations to the 'paths' array var removeFileFromRoot = function (path, href) { var paths = []; @@ -458,7 +454,6 @@ define([ var parentEl = exp.findElement(files, parentPath); // Trash root: we have array here, we can't just splice with the path otherwise we might break the path // of another element in the loop - console.log(path); if (path.length === 4) { trashRoot.push({ name: path[1], @@ -657,7 +652,6 @@ define([ // Import elements in the file manager var importElements = exp.importElements = function (elements, path, cb) { if (!elements || elements.length === 0) { return; } - console.log(elements); var newParent = findElement(files, path); if (!newParent) { debug("Trying to import elements into a non-existing folder"); return; } elements.forEach(function (e) { @@ -754,7 +748,7 @@ define([ }; // Delete permanently (remove from the trash root and from filesData) - var removeFromTrash = exp.removeFromTrash = function (path, cb) { + var removeFromTrash = exp.removeFromTrash = function (path, cb, nocheck) { if (!path || path.length < 4 || path[0] !== TRASH) { return; } // Remove the last element from the path to get the parent path and the element name var parentPath = path.slice(); @@ -775,7 +769,9 @@ define([ parentEl[name] = undefined; delete parentEl[name]; } - checkDeletedFiles(); + if (!nocheck) { + checkDeletedFiles(); + } if(cb) { cb(); } }; @@ -857,7 +853,7 @@ define([ pushToTrash(key, href, path); }; - var addUnsortedPad = exp.addPad = function (href, path, name) { + var addPad = exp.addPad = function (href, path, name) { if (workgroup) { return; } if (!href) { return; } var unsortedFiles = getUnsortedFiles(); @@ -882,6 +878,7 @@ define([ } } if (unsortedFiles.indexOf(href) === -1 && rootFiles.indexOf(href) === -1 && templateFiles.indexOf(href) === -1 && trashFiles.indexOf(href) === -1) { + console.log('push', href); files[UNSORTED].push(href); } }; @@ -905,20 +902,27 @@ define([ // Replace a href by a stronger one everywhere in the drive (except FILES_DATA) var replaceHref = exp.replaceHref = function (o, n) { - replaceFile([ROOT], o, n); - var i = files[UNSORTED].indexOf(o); - if (i !== -1) { - files[UNSORTED].splice(i, 1); - files[UNSORTED].push(n); - } - var j = files[TEMPLATE].indexOf(o); - if (j !== -1) { - files[TEMPLATE].splice(j, 1); - files[TEMPLATE].push(n); - } - var k = getTrashFiles().indexOf(o); - if (k !== -1) { - // TODO? + if (!isFile(o) || !isFile(n)) { return; } + var paths = findFile(o); + + // Remove all the occurences in the trash + // Replace all the occurences not in the trash + // If all the occurences are in the trash or no occurence, add the pad to unsorted + var allInTrash = true; + paths.forEach(function (p) { + if (p[0] === TRASH) { + removeFromTrash(p, null, true); // 3rd parameter means skip "checkDeletedFiles" + return; + } else { + allInTrash = false; + var parentPath = p.slice(); + var key = parentPath.pop(); + var parentEl = findElement(files, parentPath); + parentEl[key] = n; + } + }); + if (allInTrash) { + addPad(n); } }; From e0d972674fa4f50be4217e6ae85a8d62b2d9bb9d Mon Sep 17 00:00:00 2001 From: Pierre Bondoerffer Date: Thu, 2 Mar 2017 16:22:32 +0100 Subject: [PATCH 10/84] Fix context menu in drive and rename textbox styling --- www/drive/file.css | 2 ++ www/drive/file.less | 2 ++ www/drive/main.js | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/www/drive/file.css b/www/drive/file.css index e80d6f98a..9f41d3839 100644 --- a/www/drive/file.css +++ b/www/drive/file.css @@ -66,6 +66,7 @@ li { .contextMenu { display: none; position: absolute; + z-index: 50; } .contextMenu li { padding: 0; @@ -247,6 +248,7 @@ span.fa-folder-open { } #content div.grid li input { width: 100%; + margin-top: 5px; } #content div.grid li .fa { display: block; diff --git a/www/drive/file.less b/www/drive/file.less index d5a7c1d73..cf874dad7 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -95,6 +95,7 @@ li { .contextMenu { display: none; position: absolute; + z-index: 50; li { padding: 0; font-size: 16px; @@ -292,6 +293,7 @@ span { } input { width: 100%; + margin-top: 5px; } .fa { display: block; diff --git a/www/drive/main.js b/www/drive/main.js index 1b6dd4a79..4836fe51c 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -1424,7 +1424,8 @@ define([ // Open the menu $iframe.find('.contextMenu').css({ top: ($context.offset().top + 32) + 'px', - right: '0px' + right: '0px', + left: '' }); $li.contextmenu(); }); From 370ae8110672fb0a9f712cabf37db587fd7b4821 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 2 Mar 2017 16:29:17 +0100 Subject: [PATCH 11/84] Use the display name in the backup file name if not logged in --- www/settings/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/settings/main.js b/www/settings/main.js index 70cf938dc..bbb7d4524 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -124,7 +124,8 @@ define([ var exportFile = function () { var sjson = JSON.stringify(obj); - var suggestion = obj.login_name + '-' + new Date().toDateString(); + var name = obj.login_name || obj[USERNAME_KEY] || Messages.anonymous; + var suggestion = name + '-' + new Date().toDateString(); Cryptpad.prompt(Cryptpad.Messages.exportPrompt, Cryptpad.fixFileName(suggestion) + '.json', function (filename) { if (!(typeof(filename) === 'string' && filename)) { return; } From fa59f1000e7ea7c9404bb50a2b8bf2932b5d962b Mon Sep 17 00:00:00 2001 From: Pierre Bondoerffer Date: Thu, 2 Mar 2017 16:33:17 +0100 Subject: [PATCH 12/84] (CSS) Fix title input in pads --- customize.dist/src/less/toolbar.less | 3 +-- customize.dist/toolbar.css | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/customize.dist/src/less/toolbar.less b/customize.dist/src/less/toolbar.less index 73cce9923..2a5b3b0d8 100644 --- a/customize.dist/src/less/toolbar.less +++ b/customize.dist/src/less/toolbar.less @@ -253,13 +253,12 @@ input { font-size: 1.5em; vertical-align: middle; - height: 100%; box-sizing: border-box; border: 1px solid black; background: #fff; cursor: auto; width: 300px; - padding: 0px 5px; + padding: 5px 5px; } } .cryptpad-link { diff --git a/customize.dist/toolbar.css b/customize.dist/toolbar.css index de846b7bd..2ede62a9d 100644 --- a/customize.dist/toolbar.css +++ b/customize.dist/toolbar.css @@ -324,13 +324,12 @@ .cryptpad-toolbar-top .cryptpad-title input { font-size: 1.5em; vertical-align: middle; - height: 100%; box-sizing: border-box; border: 1px solid black; background: #fff; cursor: auto; width: 300px; - padding: 0px 5px; + padding: 5px 5px; } .cryptpad-toolbar-top .cryptpad-link { position: absolute; From e8a82c4c1004e10a98b70f5569f7d942d3449d56 Mon Sep 17 00:00:00 2001 From: Pierre Bondoerffer Date: Thu, 2 Mar 2017 16:35:30 +0100 Subject: [PATCH 13/84] (CSS) Toolbar buttons are now always black on white independent of system theme --- customize.dist/src/less/toolbar.less | 1 + customize.dist/toolbar.css | 1 + 2 files changed, 2 insertions(+) diff --git a/customize.dist/src/less/toolbar.less b/customize.dist/src/less/toolbar.less index 2a5b3b0d8..3936b13f5 100644 --- a/customize.dist/src/less/toolbar.less +++ b/customize.dist/src/less/toolbar.less @@ -95,6 +95,7 @@ } button { + color: #000; background-color: inherit; background-image: linear-gradient(to bottom,#fff,#e4e4e4); border: 1px solid #A6A6A6; diff --git a/customize.dist/toolbar.css b/customize.dist/toolbar.css index 2ede62a9d..5d81a1123 100644 --- a/customize.dist/toolbar.css +++ b/customize.dist/toolbar.css @@ -164,6 +164,7 @@ margin-right: 2px; } .cryptpad-toolbar button { + color: #000; background-color: inherit; background-image: linear-gradient(to bottom, #fff, #e4e4e4); border: 1px solid #A6A6A6; From 9a7c2dd5e2f437c168bc1603ea81bbb16ba5d124 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 2 Mar 2017 16:38:22 +0100 Subject: [PATCH 14/84] Add a 'settings' link to the user menu in static pages --- www/common/cryptpad-common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index b07adc422..6660cac5b 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1199,7 +1199,7 @@ define([ content: Messages.user_rename }); } - if (parsed && parsed.type && parsed.type !== 'settings') { + if (parsed && (!parsed.type || parsed.type !== 'settings')) { options.push({ tag: 'a', attributes: {'class': 'settings'}, From 2b6e44189d9a71099d7aeebffdac8b8cad63e37a Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 2 Mar 2017 17:01:27 +0100 Subject: [PATCH 15/84] When trying to reset the drive, tell the user if the input text is invalid --- customize.dist/translations/messages.fr.js | 1 + customize.dist/translations/messages.js | 1 + www/settings/main.js | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 3bcd145de..e31bd5a9b 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -250,6 +250,7 @@ define(function () { "Êtes-vous sûr de vouloir continuer ?
    " + "Tapez “I love CryptPad” pour confirmer."; out.settings_resetDone = "Votre drive est désormais vide!"; + out.settings_resetError = "Texte de vérification incorrect. Votre CryptDrive n'a pas été modifié."; out.settings_resetTips = "Astuces et informations dans CryptDrive"; out.settings_resetTipsButton = "Réinitialiser les astuces visibles dans CryptDrive"; out.settings_resetTipsDone = "Toutes les astuces sont de nouveau visibles."; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 479cde75f..c32f346eb 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -252,6 +252,7 @@ define(function () { "Are you sure you want to continue?
    " + "Type “I love CryptPad” to confirm."; out.settings_resetDone = "Your drive is now empty!"; + out.settings_resetError = "Incorrect verification text. Your CryptDrive has not been changed."; out.settings_resetTips = "Tips in CryptDrive"; out.settings_resetTipsButton = "Reset the available tips in CryptDrive"; out.settings_resetTipsDone = "All the tips are now visible again."; diff --git a/www/settings/main.js b/www/settings/main.js index bbb7d4524..ab3330ccd 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -165,7 +165,10 @@ define([ $button.click(function () { Cryptpad.prompt(Messages.settings_resetPrompt, "", function (val) { - if (val !== "I love CryptPad") { return; } + if (val !== "I love CryptPad") { + Cryptpad.alert(Messages.settings_resetError); + return; + } obj.proxy.drive = Cryptpad.getStore().getEmptyObject(); Cryptpad.alert(Messages.settings_resetDone); }); From c884782d57af20737020808d5900b9af93aec88a Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 2 Mar 2017 17:08:50 +0100 Subject: [PATCH 16/84] here are some changes --- customize.dist/translations/messages.js | 11 +---------- www/common/cryptpad-common.js | 10 +++++----- www/slide/main.js | 4 ++-- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 172371032..c28a8e32a 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -50,10 +50,8 @@ define(function () { out.orangeLight = "Your slow connection may impact your experience"; out.redLight = "You are disconnected from the session"; - out.importButton = 'IMPORT'; out.importButtonTitle = 'Import a pad from a local file'; - out.exportButton = 'EXPORT'; out.exportButtonTitle = 'Export this pad to a local file'; out.exportPrompt = 'What would you like to name your file?'; @@ -64,7 +62,6 @@ define(function () { out.clickToEdit = "Click to edit"; - out.forgetButton = 'FORGET'; out.forgetButtonTitle = 'Move this pad to the trash'; out.forgetPrompt = 'Clicking OK will move this pad to your trash. Are you sure?'; out.movedToTrash = 'That pad has been moved to the trash.
    Access my Drive'; @@ -75,19 +72,14 @@ define(function () { out.newButton = 'New'; out.newButtonTitle = 'Create a new pad'; - out.presentButton = 'PRESENT'; out.presentButtonTitle = "Enter presentation mode"; out.presentSuccess = 'Hit ESC to exit presentation mode'; - out.sourceButton = 'VIEW SOURCE'; //TODO remove? hidden behind the present mode - out.sourceButtonTitle = "Leave presentation mode"; - out.backgroundButton = 'BACKGROUND COLOR'; out.backgroundButtonTitle = 'Change the background color in the presentation'; - out.colorButton = 'TEXT COLOR'; out.colorButtonTitle = 'Change the text color in presentation mode'; out.editShare = "Editing link"; - out.editShareTitle = "Copy the edit link to clipboard"; + out.editShareTitle = "Copy the editing link to clipboard"; out.viewShare = "Read-only link"; out.viewShareTitle = "Copy the read-only link to clipboard"; out.viewOpen = "Open read-only link in new tab"; @@ -110,7 +102,6 @@ define(function () { out.poll_p_save = "Your settings are updated instantly, so you never need to save."; out.poll_p_encryption = "All your input is encrypted so only people who have the link can access it. Even the server cannot see what you change."; - out.wizardButton = 'WIZARD'; out.wizardLog = "Click the button in the top left to return to your poll"; out.wizardTitle = "Use the wizard to create your poll"; out.wizardConfirm = "Are you really ready to add these options to your poll?"; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 907d9f612..dc50462a7 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -912,7 +912,7 @@ define([ switch (type) { case 'export': button = $('