From 6df790dbba238b2b60eb2575a063adb84deedaa5 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 8 Jul 2021 17:55:25 +0530 Subject: [PATCH 01/49] some minor fixes for anon drives * don't show the collapse tree button in the toolbar * display the bread crumb when viewing shared folders --- www/common/drive-ui.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index e079ad2b9..b2489c22b 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -2289,7 +2289,8 @@ define([ var createTitle = function ($container, path, noStyle) { if (!path || path.length === 0) { return; } var isTrash = manager.isPathIn(path, [TRASH]); - if (APP.mobile() && !noStyle) { // noStyle means title in search result + // we assume that users viewing shared folders may want to see the "bread-crumb" + if (!APP.newSharedFolder && APP.mobile() && !noStyle) { // noStyle means title in search result return $container; } var isVirtual = virtualCategories.indexOf(path[0]) !== -1; @@ -3147,7 +3148,8 @@ define([ if (APP.$burnThisDrive) { APP.toolbar.$bottomR.append(APP.$burnThisDrive); } - collapseTreeButton(); + // this button is not useful for unregistered users who do not have a tree worth looking at + if (APP.loggedIn) { collapseTreeButton(); } return $toolbar; }; From f46a820ad83684894dfc32a89531d6d29552a227 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 9 Jul 2021 11:41:08 +0200 Subject: [PATCH 02/49] Don't sort 'sorted lists' in forms by default --- www/form/inner.js | 5 ++++- www/form/main.js | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/www/form/inner.js b/www/form/inner.js index 2a1501ecb..f9427024f 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -1470,6 +1470,7 @@ define([ if (!Array.isArray(opts.values)) { return; } var map = {}; var invMap = {}; + var sorted = false; var els = opts.values.map(function (data, i) { var uid = Util.uid(); map[uid] = data; @@ -1479,7 +1480,7 @@ define([ h('i.fa.fa-ellipsis-v'), h('i.fa.fa-ellipsis-v'), ]), - h('span.cp-form-sort-order', (i+1)), + h('span.cp-form-sort-order', '?'), h('span', data) ]); $(div).data('val', data); @@ -1494,6 +1495,7 @@ define([ $tag.find('.cp-form-type-sort').each(function (i, el) { $(el).find('.cp-form-sort-order').text(i+1); }); + sorted = true; }; var cursorGetter; var setCursorGetter = function (f) { cursorGetter = f; }; @@ -1516,6 +1518,7 @@ define([ return { tag: tag, getValue: function () { + if (!sorted) { return; } return sortable.toArray().map(function (id) { return map[id]; }); diff --git a/www/form/main.js b/www/form/main.js index 9ccac3d00..112b548db 100644 --- a/www/form/main.js +++ b/www/form/main.js @@ -265,6 +265,7 @@ define([ }, function (obj) { if (obj && obj.error) { return void cb(obj); } var messages = obj.messages; + if (!messages.length) { return void cb(); } var res = Utils.Crypto.Mailbox.openOwnSecretLetter(messages[0].msg, { validateKey: data.validateKey, ephemeral_private: Nacl.util.decodeBase64(answer.curvePrivate), From ed28b5ec7b76b0bd509c7c8ef3245f0594e8ee56 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 9 Jul 2021 11:45:48 +0200 Subject: [PATCH 03/49] Randomize 'ordered list' initial state in forms --- www/common/common-util.js | 9 +++++++++ www/form/inner.js | 1 + 2 files changed, 10 insertions(+) diff --git a/www/common/common-util.js b/www/common/common-util.js index 51540a660..1fd78cec1 100644 --- a/www/common/common-util.js +++ b/www/common/common-util.js @@ -9,6 +9,15 @@ return Array.prototype.slice.call(A, start, end); }; + Util.shuffleArray = function (a) { + for (var i = a.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var tmp = a[i]; + a[i] = a[j]; + a[j] = tmp; + } + }; + Util.bake = function (f, args) { if (typeof(args) === 'undefined') { args = []; } if (!Array.isArray(args)) { args = [args]; } diff --git a/www/form/inner.js b/www/form/inner.js index f9427024f..ce6379908 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -1471,6 +1471,7 @@ define([ var map = {}; var invMap = {}; var sorted = false; + Util.shuffleArray(opts.values); var els = opts.values.map(function (data, i) { var uid = Util.uid(); map[uid] = data; From 1b081c52df90a3feee824f3fe6ace9e29dcd99a2 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 9 Jul 2021 11:46:29 +0200 Subject: [PATCH 04/49] lint compliance --- www/form/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/form/inner.js b/www/form/inner.js index ce6379908..a1c7f4c93 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -1472,7 +1472,7 @@ define([ var invMap = {}; var sorted = false; Util.shuffleArray(opts.values); - var els = opts.values.map(function (data, i) { + var els = opts.values.map(function (data) { var uid = Util.uid(); map[uid] = data; invMap[data] = uid; From 1b0a0fe14fd13ec5815f2bae852bf9544ff406af Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 9 Jul 2021 11:56:53 +0200 Subject: [PATCH 05/49] Improve reset button in forms --- www/form/inner.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index a1c7f4c93..c49910411 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -1492,11 +1492,11 @@ define([ els ]); var $tag = $(tag); - var reorder = function () { + var reorder = function (reset) { $tag.find('.cp-form-type-sort').each(function (i, el) { - $(el).find('.cp-form-sort-order').text(i+1); + $(el).find('.cp-form-sort-order').text(reset ? '?' : i+1); }); - sorted = true; + sorted = !reset; }; var cursorGetter; var setCursorGetter = function (f) { cursorGetter = f; }; @@ -1525,11 +1525,12 @@ define([ }); }, reset: function () { + Util.shuffleArray(opts.values); var toSort = (opts.values).map(function (val) { return invMap[val]; }); sortable.sort(toSort); - reorder(); + reorder(true); }, edit: function (cb, tmp) { var v = Util.clone(opts); @@ -1889,12 +1890,13 @@ define([ } var send = h('button.cp-open.btn.btn-primary', update ? Messages.form_update : Messages.form_submit); - var reset = h('button.cp-open.btn.btn-danger-alt', Messages.form_reset); + var reset = h('button.cp-open.cp-reset-button.btn.btn-danger-alt', Messages.form_reset); $(reset).click(function () { if (!Array.isArray(APP.formBlocks)) { return; } APP.formBlocks.forEach(function (data) { if (typeof(data.reset) === "function") { data.reset(); } }); + $(reset).attr('disabled', 'disabled'); }); var $send = $(send).click(function () { $send.attr('disabled', 'disabled'); @@ -2008,6 +2010,7 @@ define([ delete _answers._userdata; evOnChange.reg(function (noBeforeUnload, isSave) { if (noBeforeUnload) { return; } + $container.find('.cp-reset-button').removeAttr('disabled'); var results = getFormResults(); if (isSave) { answers = Util.clone(results || {}); @@ -2360,6 +2363,9 @@ define([ // In view mode, add "Submit" and "reset" buttons $container.append(makeFormControls(framework, content, Boolean(answers), evOnChange)); + if (!answers) { + $container.find('.cp-reset-button').attr('disabled', 'disabled'); + } }; var getTempFields = function () { From 5b3dcde28cb0a6f71bc09cc8ccb69939d206ec95 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 9 Jul 2021 16:43:17 +0530 Subject: [PATCH 06/49] disable cache usage for form results --- www/common/outer/cache-store.js | 2 +- www/form/main.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/www/common/outer/cache-store.js b/www/common/outer/cache-store.js index fdb1f7668..514e18ab7 100644 --- a/www/common/outer/cache-store.js +++ b/www/common/outer/cache-store.js @@ -97,7 +97,7 @@ define([ var checkCheckpoints = function (array) { if (!Array.isArray(array)) { return; } // Keep the last 100 messages - if (array.length > 100) { + if (array.length > 100) { // XXX array.splice(0, array.length - 100); } // Remove every message before the first checkpoint diff --git a/www/form/main.js b/www/form/main.js index 9ccac3d00..3b2c160a4 100644 --- a/www/form/main.js +++ b/www/form/main.js @@ -176,7 +176,7 @@ define([ validateKey: keys.secondaryValidateKey, owners: [myKeys.edPublic], crypto: crypto, - Cache: Utils.Cache + //Cache: Utils.Cache // XXX }; var results = {}; config.onError = function (info) { From 32e79d323df4a7e7a114637be0e8054202ea3725 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 9 Jul 2021 18:53:27 +0530 Subject: [PATCH 07/49] add support for tabs in ckeditor and leave a note about the challenges of accessibility here --- www/pad/inner.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/www/pad/inner.js b/www/pad/inner.js index 304e9abe4..95e7c1bff 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -1326,6 +1326,11 @@ define([ })); $(waitFor()); }).nThen(function(waitFor) { + // TODO this breaks users' ability to tab out of the editor + // but that's a problem in other editors and nobody has complained so far + // so we'll include this as-is for now while we search for a good pattern + // addresses this issue more generally + Ckeditor.config.tabSpaces = 4; Ckeditor.config.toolbarCanCollapse = true; Ckeditor.config.language = Messages._getLanguage(); if (screen.height < 800) { From 0929b5db472f5db99ab2ca6e246792c674fd106e Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 12 Jul 2021 15:36:55 +0200 Subject: [PATCH 08/49] Form improvements --- www/form/app-form.less | 29 +++++++++ www/form/inner.js | 130 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 150 insertions(+), 9 deletions(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index 95802e18b..b0e38f27c 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -464,6 +464,16 @@ display: flex; flex-flow: column; position: relative; + + #cp-form-response-msg { + background: @cp_form-bg1; + margin-bottom: 20px; + padding: 10px; + p:last-child { + margin-bottom: 0; + } + } + .cp-form-creator-results-controls { margin-bottom: 20px; //background: @cp_form-bg1; @@ -677,6 +687,16 @@ -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } + .cp-form-poll-option, .cp-poll-time-day { + flex-flow: column; + text-align: center; + .cp-form-weekday-separator { + display: none; + } + } + .cp-poll-time-day { + height: 50px; + } } &.cp-form-poll-switch { display: flex; @@ -706,12 +726,21 @@ } .cp-form-poll-option, .cp-poll-switch { width: 200px; + .cp-form-weekday-separator { + margin-right: 5px; + margin-left: 5px; + } } .cp-poll-time-day { flex-basis: 40px; border-right: none; border-right: 1px solid @cryptpad_text_col; border-bottom: 0px; + flex-flow: column; + text-align: center; + .cp-form-weekday-separator { + display: none; + } } } .cp-form-poll-choice, .cp-form-poll-answer { diff --git a/www/form/inner.js b/www/form/inner.js index c49910411..f8dfe5ab8 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -575,6 +575,19 @@ define([ ]; }; + var getWeekDays = function (large) { + var baseDate = new Date(2017, 0, 1); // just a Sunday + var weekDays = []; + for(var i = 0; i < 7; i++) { + weekDays.push(baseDate.toLocaleDateString(undefined, { weekday: 'long' })); + baseDate.setDate(baseDate.getDate() + 1); + } + if (!large) { + weekDays = weekDays.map(function (day) { return day.slice(0,3); }); + } + return weekDays.map(function (day) { return day.replace(/^./, function (str) { return str.toUpperCase(); }); }); + }; + var makePollTable = function (answers, opts) { // Sort date values if (opts.type !== "text") { @@ -583,18 +596,25 @@ define([ }); } // Create first line with options + var allDays = getWeekDays(true); var els = opts.values.map(function (data) { + var _date; if (opts.type === "day") { - var _date = new Date(data); + _date = new Date(data); data = _date.toLocaleDateString(); } if (opts.type === "time") { - var _dateT = new Date(data); - data = Flatpickr.formatDate(_dateT, timeFormat); + _date = new Date(data); + data = Flatpickr.formatDate(_date, timeFormat); } + var day = allDays[_date.getDay()]; return h('div.cp-poll-cell.cp-form-poll-option', { title: Util.fixHTML(data) - }, data); + }, [ + opts.type === 'day' ? h('span.cp-form-weekday', day) : undefined, + opts.type === 'day' ? h('span.cp-form-weekday-separator', ' - ') : undefined, + h('span', data) + ]); }); // Insert axis switch button var switchAxis = h('button.btn.btn-default', [ @@ -611,13 +631,20 @@ define([ opts.values.forEach(function (d) { var date = new Date(d); var day = date.toLocaleDateString(); - _days[day] = _days[day] || 0; - _days[day]++; + _days[day] = { + n: (_days[day] && _days[day].n) || 0, + name: allDays[date.getDay()] + }; + _days[day].n++; }); Object.keys(_days).forEach(function (day) { days.push(h('div.cp-poll-cell.cp-poll-time-day', { - style: 'flex-grow:'+(_days[day]-1)+';' - }, day)); + style: 'flex-grow:'+(_days[day].n - 1)+';' + }, [ + h('span.cp-form-weekday', _days[day].name), + h('span.cp-form-weekday-separator', ' - '), + h('span', day) + ])); }); lines.unshift(h('div', days)); } @@ -1704,6 +1731,12 @@ define([ return; } + if (content.answers.msg) { + var description = h('div.cp-form-creator-results-description#cp-form-response-msg'); + var $desc = $(description).appendTo($container); + DiffMd.apply(DiffMd.render(content.answers.msg), $desc, APP.common); + } + var controls = h('div.cp-form-creator-results-controls'); var $controls = $(controls).appendTo($container); var exportButton = h('button.btn.btn-secondary', Messages.exportButton); // XXX form_exportCSV; @@ -1835,7 +1868,7 @@ define([ }; var addResultsButton = function (framework, content) { - var $res = $(h('button.cp-toolbar-appmenu', [ + var $res = $(h('button.cp-toolbar-appmenu.cp-toolbar-form-button', [ h('i.fa.fa-bar-chart'), h('span.cp-button-name', Messages.form_results) ])); @@ -2003,6 +2036,18 @@ define([ APP.formBlocks = []; + if (APP.isClosed && content.answers.privateKey && !APP.isEditor) { + var sframeChan = framework._.sfCommon.getSframeChannel(); + sframeChan.query("Q_FORM_FETCH_ANSWERS", content.answers, function (err, obj) { + var answers = obj && obj.results; + if (answers) { APP.answers = answers; } + $('body').addClass('cp-app-form-results'); + $('.cp-toolbar-form-button').remove(); + renderResults(content, answers); + }); + return; + } + var evOnChange = Util.mkEvent(); if (!APP.isEditor) { var _answers = Util.clone(answers || {}); @@ -2453,6 +2498,71 @@ define([ }; refreshPublic(); + var responseMsg = h('div.cp-form-response-msg-container'); + var $responseMsg = $(responseMsg); + var refreshResponse = function () { + $responseMsg.empty(); + Messages.form_updateMsg = "Update response message"; // XXX + Messages.form_addMsg = "Add response message"; + Messages.form_responseMsg = "Add a message that will be displayed in the response page."; + var text = content.answers.msg ? Messages.form_updateMsg : Messages.form_addMsg; + var btn = h('button.btn.btn-secondary', text); + $(btn).click(function () { + var editor; + if (!APP.responseModal) { + var t = h('textarea'); + var div = h('div', [ + h('p', Messages.form_responseMsg), + t + ]); + var cm = SFCodeMirror.create("gfm", CMeditor, t); + editor = APP.responseEditor = cm.editor; + editor.setOption('lineNumbers', true); + editor.setOption('lineWrapping', true); + editor.setOption('styleActiveLine', true); + editor.setOption('readOnly', false); + setTimeout(function () { + editor.setValue(content.answers.msg || ''); + editor.refresh(); + editor.save(); + editor.focus(); + }); + + var buttons = [{ + className: 'primary', + name: Messages.settings_save, + onClick: function () { + var v = editor.getValue(); + content.answers.msg = v.trim(0, 2000); // XXX max length? + framework.localChange(); + framework._.cpNfInner.chainpad.onSettle(function () { + UI.log(Messages.saved); + refreshResponse(); + }); + }, + //keys: [] + }, { + className: 'cancel', + name: Messages.cancel, + onClick: function () {}, + keys: [27] + }]; + APP.responseModal = UI.dialog.customModal(div, { buttons: buttons }); + } else { + editor = APP.responseEditor; + setTimeout(function () { + editor.setValue(content.answers.msg || ''); + editor.refresh(); + editor.save(); + editor.focus(); + }); + } + UI.openCustomModal(APP.responseModal); + }); + $responseMsg.append(btn); + }; + refreshResponse(); + // Allow anonymous answers var privacyContainer = h('div.cp-form-privacy-container'); var $privacy = $(privacyContainer); @@ -2548,11 +2658,13 @@ define([ evOnChange.reg(refreshPublic); evOnChange.reg(refreshPrivacy); evOnChange.reg(refreshEndDate); + evOnChange.reg(refreshResponse); return [ endDateContainer, privacyContainer, resultsType, + responseMsg ]; }; From a4092e888b76a7d6d172f2ad312922e49cd5d4e4 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 19 Jul 2021 19:14:47 +0530 Subject: [PATCH 09/49] remove unused images --- customize.dist/images/YannFlory.jpg | Bin 33940 -> 0 bytes customize.dist/images/logo_white.png | Bin 9730 -> 0 bytes customize.dist/images/logo_white.svg | 1 - .../old_logos/CryptPad-white-logo.svg | 1 - .../old_logos/CryptPad_logo_color.svg | 1 - customize.dist/old_logos/CryptPadlogo_op5.svg | 1 - customize.dist/old_logos/cryptofist_mini.png | Bin 36726 -> 0 bytes customize.dist/old_logos/cryptofist_small.png | Bin 91507 -> 0 bytes .../cryptpad-new-logo-colors-logoonly.png | Bin 10031 -> 0 bytes 9 files changed, 4 deletions(-) delete mode 100644 customize.dist/images/YannFlory.jpg delete mode 100644 customize.dist/images/logo_white.png delete mode 100644 customize.dist/images/logo_white.svg delete mode 100644 customize.dist/old_logos/CryptPad-white-logo.svg delete mode 100644 customize.dist/old_logos/CryptPad_logo_color.svg delete mode 100644 customize.dist/old_logos/CryptPadlogo_op5.svg delete mode 100644 customize.dist/old_logos/cryptofist_mini.png delete mode 100644 customize.dist/old_logos/cryptofist_small.png delete mode 100644 customize.dist/old_logos/cryptpad-new-logo-colors-logoonly.png diff --git a/customize.dist/images/YannFlory.jpg b/customize.dist/images/YannFlory.jpg deleted file mode 100644 index 9c358d1a622777fbcd79b5b1aea46e962e501fbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33940 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 \ No newline at end of file diff --git a/customize.dist/old_logos/CryptPad-white-logo.svg b/customize.dist/old_logos/CryptPad-white-logo.svg deleted file mode 100644 index 26131b502..000000000 --- a/customize.dist/old_logos/CryptPad-white-logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/customize.dist/old_logos/CryptPad_logo_color.svg b/customize.dist/old_logos/CryptPad_logo_color.svg deleted file mode 100644 index 64fc86682..000000000 --- a/customize.dist/old_logos/CryptPad_logo_color.svg +++ /dev/null @@ -1 +0,0 @@ -CryptPad_logo_color \ No newline at end of file diff --git a/customize.dist/old_logos/CryptPadlogo_op5.svg b/customize.dist/old_logos/CryptPadlogo_op5.svg deleted file mode 100644 index aa5acb201..000000000 --- a/customize.dist/old_logos/CryptPadlogo_op5.svg +++ /dev/null @@ -1 +0,0 @@ -CryptPadlogo \ No newline at end of file diff --git a/customize.dist/old_logos/cryptofist_mini.png b/customize.dist/old_logos/cryptofist_mini.png deleted file mode 100644 index 73845e455cc3684150091ff4612659019b3625ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36726 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.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

YB7keL3{gO`k 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

_HrCcCYX)s#3*K6W`0eXPXCRp42W+6*3w%LcS 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 From 621941b9337f37f83c31c030979115320cf19426 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 19 Jul 2021 19:49:20 +0530 Subject: [PATCH 10/49] comments about possible form improvements --- www/form/inner.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index f8dfe5ab8..9f05f80dd 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -721,7 +721,7 @@ define([ var answer = answerObj.results; if (!answer || !answer.values) { return; } var values = answer.values || {}; - var res = Number(values[data]) || 0; + var res = Number(values[data]) || 0; // XXX inc function ? if (res === 1) { y++; } else if (res === 2) { m++; } }); @@ -768,7 +768,7 @@ define([ }; refreshBest(); - if (myLine && evOnChange) { + if (myLine && evOnChange) { // XXX var updateValues = function () { totalEls.forEach(function (cell) { var $c = $(cell); @@ -776,7 +776,7 @@ define([ if (!data) { return; } var y = totals[data].y + ((myTotals[data] || {}).y || 0); var m = totals[data].m + ((myTotals[data] || {}).m || 0); - $c.find('.cp-form-total-yes').text(y); + $c.find('.cp-form-total-yes').text(y); // XXX inc function $c.find('.cp-form-total-maybe').text('('+m+')'); }); }; @@ -977,7 +977,7 @@ define([ printResults: function (answers, uid) { var results = []; var empty = 0; - Object.keys(answers).forEach(function (author) { + Object.keys(answers).forEach(function (author) { // XXX deduplicate these? var obj = answers[author]; var answer = obj.msg[uid]; if (!answer || !answer.trim()) { return empty++; } @@ -989,7 +989,7 @@ define([ }, icon: h('i.cptools.cptools-form-text') }, - textarea: { + textarea: { // XXX defaultOpts: { maxLength: 1000 }, @@ -1043,7 +1043,7 @@ define([ printResults: function (answers, uid) { var results = []; var empty = 0; - Object.keys(answers).forEach(function (author) { + Object.keys(answers).forEach(function (author) { // XXX deduplicate these var obj = answers[author]; var answer = obj.msg[uid]; if (!answer || !answer.trim()) { return empty++; } @@ -1117,7 +1117,7 @@ define([ var obj = answers[author]; var answer = obj.msg[uid]; if (!answer || !answer.trim()) { return empty++; } - count[answer] = count[answer] || 0; + count[answer] = count[answer] || 0; // XXX inc function count[answer]++; }); Object.keys(count).forEach(function (value) { @@ -1220,7 +1220,7 @@ define([ var c = count[q_uid] = count[q_uid] || {}; var res = answer[q_uid]; if (!res || !res.trim()) { return; } - c[res] = c[res] || 0; + c[res] = c[res] || 0; // XXX inc function c[res]++; }); }); @@ -1331,7 +1331,7 @@ define([ var answer = obj.msg[uid]; if (!Array.isArray(answer) || !answer.length) { return empty++; } answer.forEach(function (val) { - count[val] = count[val] || 0; + count[val] = count[val] || 0; // XXX inc function count[val]++; }); }); @@ -1446,7 +1446,7 @@ define([ var c = count[q_uid] = count[q_uid] || {}; var res = answer[q_uid]; if (!Array.isArray(res) || !res.length) { return; } - res.forEach(function (v) { + res.forEach(function (v) { // XXX increment function? c[v] = c[v] || 0; c[v]++; }); @@ -1586,7 +1586,7 @@ define([ if (!Array.isArray(answer) || !answer.length) { return empty++; } answer.forEach(function (el, i) { var score = l - i; - count[el] = (count[el] || 0) + score; + count[el] = (count[el] || 0) + score; // XXX inc function? }); }); var sorted = Object.keys(count).sort(function (a, b) { From 0fc2269a3a6d54e047837a720023f7a52cc16cb8 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 20 Jul 2021 10:40:40 +0200 Subject: [PATCH 11/49] Create links in the drive --- www/code/inner.js | 4 +- www/common/application_config_internal.js | 1 + www/common/common-interface.js | 2 + www/common/common-ui-elements.js | 68 ++++++++++- www/common/drive-ui.js | 140 +++++++++++++++++++++- www/common/inner/share.js | 52 ++++++-- www/common/notifications.js | 14 +++ www/common/outer/async-store.js | 9 +- www/common/outer/mailbox-handlers.js | 2 +- www/common/outer/userObject.js | 43 ++++++- www/common/proxy-manager.js | 62 +++++++++- www/common/sframe-app-framework.js | 11 +- www/common/userObject.js | 27 ++++- www/secureiframe/inner.js | 8 +- www/teams/main.js | 3 +- 15 files changed, 416 insertions(+), 30 deletions(-) diff --git a/www/code/inner.js b/www/code/inner.js index 785e82788..19ffdb285 100644 --- a/www/code/inner.js +++ b/www/code/inner.js @@ -368,8 +368,8 @@ define([ var mkFilePicker = function (framework, editor, evModeChange) { evModeChange.reg(function (mode) { if (MEDIA_TAG_MODES.indexOf(mode) !== -1) { - // Embedding is endabled - framework.setMediaTagEmbedder(function (mt) { + // Embedding is enabled + framework.setMediaTagEmbedder(function (mt, data) { editor.focus(); editor.replaceSelection($(mt)[0].outerHTML); }); diff --git a/www/common/application_config_internal.js b/www/common/application_config_internal.js index 15e5b5e34..3be979f17 100644 --- a/www/common/application_config_internal.js +++ b/www/common/application_config_internal.js @@ -119,6 +119,7 @@ define(function() { file: 'cptools-file', fileupload: 'cptools-file-upload', folderupload: 'cptools-folder-upload', + link: 'fa-link', pad: 'cptools-richtext', code: 'cptools-code', slide: 'cptools-slide', diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 4d3520426..5aea35c78 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -1050,6 +1050,7 @@ define([ var font = icon.indexOf('cptools') === 0 ? 'cptools' : 'fa'; if (type === 'fileupload') { type = 'file'; } if (type === 'folderupload') { type = 'file'; } + if (type === 'link') { type = 'drive'; } var appClass = ' cp-icon cp-icon-color-'+type; $icon = $('', {'class': font + ' ' + icon + appClass}); } @@ -1061,6 +1062,7 @@ define([ if (!data) { return $icon; } var href = data.href || data.roHref; var type = data.type; + if (data.static) { type = 'link'; } if (!href && !type) { return $icon; } if (!type) { type = Hash.parsePadUrl(href).type; } diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 0ab010cb5..6114884b2 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -1032,10 +1032,19 @@ define([ icon: 'fa-picture-o', action: function () { var _cfg = { - types: ['file'], + types: ['file', 'link'], where: ['root'] }; common.openFilePicker(_cfg, function (data) { + // Embed links + if (data.static) { + var a = h('a', { + href: data.href + }, data.name); + cfg.embed(a, data); + return; + } + // Embed files if (data.type !== 'file') { console.log("Unexpected data type picked " + data.type); return; @@ -3021,6 +3030,63 @@ define([ UI.proposal(content, todo); }; + UIElements.displayOpenLinkModal = function (common, data, dismiss) { + var name = Util.fixHTML(data.title); + var url = data.href; + var user = data.name; + Messages.notification_openLink = "You've received a link {0} from {1}:"; // XXX + Messages.link_open = "Open URL"; + Messages.link_store = "Store link in drive"; + + var content = h('div', [ + UI.setHTML(h('p'), Messages._getKey('notification_openLink', [name, user])), + h('pre', url), + UIElements.getVerifiedFriend(common, data.curve, user) + ]); + var clicked = false; + var modal; + var buttons = [{ + name: Messages.friendRequest_later, + onClick: function () { + if (clicked) { return true; } + clicked = true; + }, + keys: [27] + }, { + className: 'primary', + name: Messages.link_open, + onClick: function () { + if (clicked) { return true; } + clicked = true; + common.openUnsafeURL(url); + }, + keys: [13] + }, { + className: 'primary', + name: Messages.link_store, + onClick: function () { + if (clicked) { return; } + clicked = true; + common.getSframeChannel().query("Q_DRIVE_USEROBJECT", { + cmd: "addLink", + data: { + name: name, + href: url, + path: ['root'] + } + }, function () { + modal.closeModal(); + dismiss(); + }); + return true; + }, + keys: [[13, 'ctrl']] + }]; + var _modal = UI.dialog.customModal(content, {buttons: buttons}); + modal = UI.openCustomModal(_modal); + return modal; + }; + UIElements.displayAddOwnerModal = function (common, data) { var priv = common.getMetadataMgr().getPrivateData(); var sframeChan = common.getSframeChannel(); diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index b2489c22b..28ac531e2 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -42,6 +42,8 @@ define([ Pages) { + Messages.fm_link = "Link"; // XXX + var APP = window.APP = { editable: false, online: false, @@ -443,6 +445,11 @@ define([ 'data-icon': AppConfig.applicationsIcon.poll, 'data-type': 'poll' }, Messages.button_newpoll)), + h('li', h('a.cp-app-drive-context-newdoc.dropdown-item.cp-app-drive-context-editable', { + 'tabindex': '-1', + 'data-icon': AppConfig.applicationsIcon.link, + 'data-type': 'link' + }, Messages.fm_link)), ]), ]), $separator.clone()[0], @@ -1111,6 +1118,15 @@ define([ var defaultInApp = ['application/pdf']; var openFile = function (el, isRo, app) { var data = manager.getFileData(el); + + if (data.static) { + if (data.href) { + common.openUnsafeURL(data.href); + manager.updateStaticAccess(el, refresh); + } + return; + } + if (!data || (!data.href && !data.roHref)) { return void logError("Missing data for the file", el, data); } @@ -1263,6 +1279,9 @@ define([ if ($element.is('.cp-border-color-sheet')) { hide.push('download'); } + if ($element.is('.cp-app-drive-static')) { + hide.push('access', 'hashtag', 'properties', 'download'); + } if ($element.is('.cp-app-drive-element-file')) { // No folder in files hide.push('color'); @@ -1899,6 +1918,27 @@ define([ // In list mode, display metadata from the filesData object + var addStaticData = function (element, $element, data) { + $element.addClass('cp-border-color-drive'); + var name = data.name; + var $name = $('', {'class': 'cp-app-drive-element-name'}).text(name); + $element.append($name); + if (getViewMode() === 'grid') { + $element.attr('title', name); + } + + var type = Messages.fm_link; + var $type = $('', { + 'class': 'cp-app-drive-element-type cp-app-drive-element-list' + }).text(type); + var $adate = $('', { + 'class': 'cp-app-drive-element-atime cp-app-drive-element-list' + }).text(getDate(data.atime)); + var $cdate = $('', { + 'class': 'cp-app-drive-element-ctime cp-app-drive-element-list' + }).text(getDate(data.ctime)); + $element.append($type).append($adate).append($cdate); + } var _addOwnership = function ($span, $state, data) { if (data && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1) { var $owned = $ownedIcon.clone().appendTo($state); @@ -1914,6 +1954,9 @@ define([ if (!manager.isFile(element)) { return; } var data = manager.getFileData(element); + if (data.static) { + return addStaticData(element, $element, data); + } if (!Object.keys(data).length) { return true; @@ -2124,7 +2167,9 @@ define([ $icon = manager.isFolderEmpty(root[key]) ? $folderEmptyIcon.clone() : $folderIcon.clone(); $icon.css("color", getFolderColor(path.concat(elPath))); } - var classes = restrictedClass + roClass + liClass; + + var staticClass = manager.isStaticFile(element) ? '.cp-app-drive-static' : ''; + var classes = restrictedClass + roClass + liClass + staticClass; var $element = $(h('li.cp-app-drive-element.cp-app-drive-element-row' + classes, { draggable: true })); @@ -2460,7 +2505,6 @@ define([ showMode(viewMode); $button.click(function (e) { - console.error(e); var viewMode = getViewMode(); var newViewMode = getOppositeViewMode(viewMode); setViewMode(newViewMode); @@ -2686,6 +2730,63 @@ define([ }); $input.click(); }; + var showLinkModal = function () { + Messages.fm_link_name = "Link name"; // XXX + Messages.fm_link_url = "URL"; + Messages.fm_link_warning = "Warning: URL size..."; + var name, url; + var warning = h('div.alert.alert-warning', [ + h('i.fa.fa-exclamation-triangle'), + h('span', Messages.fm_link_warning) + ]); + var content = h('p', [ + warning, + h('label', {for: 'cp-app-drive-link-name'}, Messages.fm_link_name), + name = h('input#cp-app-drive-link-name', { autocomplete: 'off' }), + h('label', {for: 'cp-app-drive-link-url'}, Messages.fm_link_url), + url = h('input#cp-app-drive-link-url', { type: 'url', autocomplete: 'off' }) + ]); + var $warning = $(warning).hide(); + var $url = $(url).on('change keypress keyup keydown', function () { + var v = $url.val().trim(); + if (v.length > 200) { + $warning.show(); + return; + } + $warning.hide(); + }); + var buttons = [{ + className: 'cancel', + name: Messages.cancelButton, + onClick: function () {}, + keys: [27] + }]; + buttons.push({ + className: 'primary', + // We may want to use a new key here + iconClass: '.fa.fa-plus', + name: Messages.tag_add, + onClick: function () { + var n = $(name).val().trim(); + var u = $url.val().trim(); + if (!n || !u) { return true; } + if (!Util.isValidURL(u)) { + // XXX add style for invalid input? input:invalid + UI.warn(Messages.error); + return true; + } + manager.addLink(currentPath, { + name: n, + url: u + }, refresh); + }, + keys: [13] + }); + var m = UI.dialog.customModal(content, { + buttons: buttons + }); + UI.openCustomModal(m); + }; var addNewPadHandlers = function ($block, isInRoot) { // Handlers if (isInRoot) { @@ -2714,6 +2815,7 @@ define([ } $block.find('a.cp-app-drive-new-fileupload, li.cp-app-drive-new-fileupload').click(showUploadFilesModal); $block.find('a.cp-app-drive-new-folderupload, li.cp-app-drive-new-folderupload').click(showUploadFolderModal); + $block.find('a.cp-app-drive-new-link, li.cp-app-drive-new-link').click(showLinkModal); } $block.find('a.cp-app-drive-new-doc, li.cp-app-drive-new-doc') .click(function () { @@ -2757,6 +2859,12 @@ define([ }); } options.push({tag: 'hr'}); + options.push({ + tag: 'a', + attributes: {'class': 'cp-app-drive-new-link'}, + content: $('

').append(getIcon('link')).html() + Messages.fm_link + }); + options.push({tag: 'hr'}); } getNewPadTypes().forEach(function (type) { var attributes = { @@ -3073,6 +3181,13 @@ define([ $elementFolderUpload.append($('', {'class': 'cp-app-drive-new-name'}) .text(Messages.uploadFolderButton)); } + // Link + var $elementFileUpload = $('
  • ', { + 'class': 'cp-app-drive-new-link cp-app-drive-element-row ' + + 'cp-app-drive-element-grid' + }).prepend(getIcon('link')).appendTo($container); + $elementFileUpload.append($('', {'class': 'cp-app-drive-new-name'}) + .text(Messages.fm_link)); } // Pads getNewPadTypes().forEach(function (type) { @@ -3479,6 +3594,7 @@ define([ var path = paths[0]; if (manager.isPathIn(path, [TRASH])) { return; } + if (!file.channel) { file.channel = id; } if (channels.indexOf(file.channel) !== -1) { return; } channels.push(file.channel); @@ -4482,8 +4598,9 @@ define([ password: data.password }, isTemplate: paths[0].path[0] === 'template', - title: data.title, + title: data.title || data.name, sharedFolder: sf, + static: data.static ? data.href : undefined, common: common }; if (padType === 'file') { @@ -4501,6 +4618,20 @@ define([ data = manager.getSharedFolderData(el); } if (!data) { return; } + if (data.static) { + sframeChan.query("Q_DRIVE_USEROBJECT", { + cmd: "addLink", + teamId: -1, + data: { + name: data.name, + href: data.href, + path: ['root'] + } + }, function () { + UI.log(Messages.saved); + }); + return; + } sframeChan.query('Q_STORE_IN_TEAM', { href: data.href || data.rohref, password: data.password, @@ -4539,6 +4670,9 @@ define([ } else if ($this.hasClass("cp-app-drive-context-newdoc")) { var ntype = $this.data('type') || 'pad'; + if (ntype === 'link') { + return void showLinkModal(); + } var path2 = manager.isPathIn(currentPath, [TRASH]) ? '' : currentPath; openIn(ntype, path2, APP.team); } diff --git a/www/common/inner/share.js b/www/common/inner/share.js index 9ba75f867..5225ea818 100644 --- a/www/common/inner/share.js +++ b/www/common/inner/share.js @@ -90,7 +90,11 @@ define([ setTimeout(w); }); if (res && /^http/.test(res)) { - href = Hash.getRelativeHref(res); + var _href = Hash.getRelativeHref(res); + if (_href) { href = _href; } + else { + href = res; + } setTimeout(w); return; } @@ -109,6 +113,7 @@ define([ if (mailbox.notifications && mailbox.curvePublic) { common.mailbox.sendTo("SHARE_PAD", { href: href, + isStatic: Boolean(config.static), password: config.password, isTemplate: config.isTemplate, name: myName, @@ -137,6 +142,20 @@ define([ }); return; } + if (config.static) { + common.getSframeChannel().query("Q_DRIVE_USEROBJECT", { + cmd: "addLink", + teamId: team.id, + data: { + name: title, + href: href, + path: ['root'] + } + }, function () { + UI.log(Messages.saved); + }); + return; + } sframeChan.query('Q_STORE_IN_TEAM', { href: href, password: config.password, @@ -346,6 +365,9 @@ define([ ] : [ UI.createCheckbox('cp-share-embed', Messages.share_linkEmbed, false, { mark: {tabindex:1} }), ]; + + if (opts.static) { linkContent = []; } + linkContent.push(h('div.cp-spacer')); linkContent.push(UI.dialog.selectableArea('', { id: 'cp-share-link-preview', tabindex: 1, rows:3})); @@ -361,7 +383,7 @@ define([ // warning about sharing links // when sharing a version hash, there is a similar warning and we want // to avoid alert fatigue - if (!opts.versionHash) { + if (!opts.versionHash && !opts.static) { var localStore = window.cryptpadStore; var dismissButton = h('span.fa.fa-times'); var shareLinkWarning = h('div.alert.alert-warning.dismissable', @@ -405,6 +427,10 @@ define([ var v = opts.getLinkValue({ embed: Util.isChecked($link.find('#cp-share-embed')) }); + if (opts.static) { + common.openUnsafeURL(v); + return true; + } window.open(v); return true; }, @@ -562,6 +588,7 @@ define([ }); }; opts.getLinkValue = function (initValue, cb) { + if (opts.static) { return opts.static; } var val = initValue || {}; var edit = val.edit !== undefined ? val.edit : Util.isChecked($rights.find('#cp-share-editable-true')); var embed = val.embed; @@ -686,7 +713,7 @@ define([ opts.access = true; // Allow the use of the modal even if the pad is not stored var hashes = opts.hashes; - if (!hashes || (!hashes.editHash && !hashes.viewHash)) { return; } + if (!hashes || (!hashes.editHash && !hashes.viewHash && !opts.static)) { return; } var teams = getEditableTeams(common, opts); opts.teams = teams; @@ -705,19 +732,23 @@ define([ var $rights = opts.$rights = getRightsHeader(common, opts); var resetTab = function () { + if (opts.static) { return; } $rights.show(); $rights.find('label.cp-radio').show(); }; var onShowEmbed = function () { + if (opts.static) { return; } $rights.find('#cp-share-bar').closest('label').hide(); $rights.find('input[type="radio"]:enabled').first().prop('checked', 'checked'); $rights.find('input[type="radio"]').trigger('change'); }; var onShowContacts = function () { + if (opts.static) { return; } if (!hasFriends || priv.offline) { $rights.hide(); } }; + if (opts.static) { $rights.hide(); } var contactsActive = hasFriends && !priv.offline; var tabs = [{ @@ -732,13 +763,16 @@ define([ title: Messages.share_linkCategory, icon: "fa fa-link", active: !contactsActive, - }, { - getTab: getEmbedTab, - title: Messages.share_embedCategory, - icon: "fa fa-code", - onShow: onShowEmbed, - onHide: resetTab }]; + if (!opts.static) { + tabs.push({ + getTab: getEmbedTab, + title: Messages.share_embedCategory, + icon: "fa fa-code", + onShow: onShowEmbed, + onHide: resetTab + }); + } Modal.getModal(common, opts, tabs, function (err, modal) { // Hide the burn-after-reading option by default var $modal = $(modal); diff --git a/www/common/notifications.js b/www/common/notifications.js index 20738e237..24458420e 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -92,6 +92,11 @@ define([ (type === 'file' ? 'notification_fileShared' : // Msg.notification_fileSharedTeam 'notification_padShared'); // Msg.notification_padSharedTeam + Messages.notification_linkShared = "{0} has shared a link with you: {1}"; // XXX + if (msg.content.isStatic) { + key = 'notification_linkShared'; // Msg.notification_linkShared; + } + var teamNotification = /^team-/.test(data.type) && Number(data.type.slice(5)); var teamName = ''; if (teamNotification) { @@ -109,6 +114,15 @@ define([ return Messages._getKey(key, [name, title, teamName]); }; content.handler = function() { + if (msg.content.isStatic) { + UIElements.displayOpenLinkModal(common, { + curve: msg.author, + href: msg.content.href, + name: name, + title: title + }, defaultDismiss(common, data)); + return; + } var obj = { p: msg.content.isTemplate ? ['template'] : undefined, t: teamNotification || undefined, diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 9f779a0a8..6aacd4a1b 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1306,9 +1306,14 @@ define([ getAllStores().forEach(function (s) { s.manager.getSecureFilesList(where).forEach(function (obj) { var data = obj.data; - if (channels.indexOf(data.channel) !== -1) { return; } + if (channels.indexOf(data.channel || data.id) !== -1) { return; } var id = obj.id; - if (data.channel) { channels.push(data.channel); } + if (data.channel) { channels.push(data.channel || data.id); } + // Only include static links if "link" is requested + if (data.static) { + if (types.indexOf('link') !== -1) { list[id] = data; } + return; + } var parsed = Hash.parsePadUrl(data.href || data.roHref); if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) && !isFiltered(parsed.type, data)) { diff --git a/www/common/outer/mailbox-handlers.js b/www/common/outer/mailbox-handlers.js index 7f7e20d2a..bb19d2d91 100644 --- a/www/common/outer/mailbox-handlers.js +++ b/www/common/outer/mailbox-handlers.js @@ -239,7 +239,7 @@ define([ if (isMuted(ctx, data)) { return void cb(true); } - var channel = Hash.hrefToHexChannelId(content.href, content.password); + var channel = content.isStatic ? content.href : Hash.hrefToHexChannelId(content.href, content.password); var parsed = Hash.parsePadUrl(content.href); var mode = parsed.hashData && parsed.hashData.mode || 'n/a'; diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index e7c55da67..a12beacf9 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -20,6 +20,7 @@ define([ var ROOT = exp.ROOT; var FILES_DATA = exp.FILES_DATA; + var STATIC_DATA = exp.STATIC_DATA; var OLD_FILES_DATA = exp.OLD_FILES_DATA; var UNSORTED = exp.UNSORTED; var TRASH = exp.TRASH; @@ -78,6 +79,14 @@ define([ files[FILES_DATA][id] = data; cb(null, id); }; + exp.pushLink = function (_data, cb) { + if (typeof cb !== "function") { cb = function () {}; } + if (readOnly) { return void cb('EFORBIDDEN'); } + var id = Util.createRandomInteger(); + var data = clone(_data); + files[STATIC_DATA][id] = data; + cb(null, id); + }; exp.pushSharedFolder = function (_data, cb) { if (typeof cb !== "function") { cb = function () {}; } @@ -136,7 +145,7 @@ define([ var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]); var toClean = []; - exp.getFiles([FILES_DATA, SHARED_FOLDERS]).forEach(function (id) { + exp.getFiles([FILES_DATA, SHARED_FOLDERS, STATIC_DATA]).forEach(function (id) { if (filesList.indexOf(id) === -1) { var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id); var channelId = fd.channel; @@ -146,6 +155,8 @@ define([ if (exp.isSharedFolder(id)) { delete files[SHARED_FOLDERS][id]; if (config.removeProxy) { config.removeProxy(id); } + } else if (files[STATIC_DATA][id]) { + delete files[STATIC_DATA][id]; } else { spliceFileData(id); } @@ -398,7 +409,7 @@ define([ if (!loggedIn && !config.testMode) { return; } id = Number(id); - var data = files[FILES_DATA][id] || files[SHARED_FOLDERS][id]; + var data = files[FILES_DATA][id] || files[STATIC_DATA][id] || files[SHARED_FOLDERS][id]; if (!data || typeof(data) !== "object") { return; } var newPath = path, parentEl; if (path && !Array.isArray(path)) { @@ -634,7 +645,7 @@ define([ delete element[el]; } if (typeof element[el] === "number") { - var data = files[FILES_DATA][element[el]]; + var data = files[FILES_DATA][element[el]] || files[STATIC_DATA][element[el]]; if (!data) { debug("An element in ROOT doesn't have associated data", element[el], el); delete element[el]; @@ -845,6 +856,25 @@ define([ toClean.forEach(function (id) { spliceFileData(id); }); + var sd = files[STATIC_DATA]; + var toCleanSD = []; + for (var id in sd) { + id = Number(id); + var el2 = sd[id]; + if (!el2 || typeof(el2) !== "object" || !el2.href) { + toCleanSD.push(id); + continue; + } + if ((loggedIn || config.testMode) && rootFiles.indexOf(id) === -1) { + toCleanSD.push(id); + continue; + } + } + var spliceSD = function (id) { + if (readOnly) { return; } + delete files[STATIC_DATA][id]; + }; + toCleanSD.forEach(spliceSD); }; var fixSharedFolders = function () { if (sharedFolder) { return; } @@ -892,6 +922,12 @@ define([ } } }; + var fixStaticData = function () { + if (typeof(files[STATIC_DATA]) !== "object") { + debug("STATIC_DATA was not an object"); + files[STATIC_DATA] = {}; + } + }; var fixDrive = function () { @@ -900,6 +936,7 @@ define([ }); }; + fixStaticData(); fixRoot(); fixTrashRoot(); fixTemplate(); diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 0e799de56..fc42f8aae 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -584,6 +584,24 @@ define([ }); }); }; + // Add a link + var _addLink = function (Env, data, cb) { + data = data || {}; + var resolved = _resolvePath(Env, data.path); + if (!resolved || !resolved.userObject) { return void cb({error: 'E_NOTFOUND'}); } + var uo = resolved.userObject; + var now = +new Date(); + uo.pushLink({ + name: data.name, + href: data.href, + atime: now, + ctime: now + }, function (e, id) { + if (e) { return void cb({error: e}); } + uo.add(id, resolved.path); + Env.onSync(cb); + }); + }; var _restoreSharedFolder = function (Env, _data, cb) { var fId = _data.id; @@ -1019,6 +1037,14 @@ define([ }); }; + + var _updateStaticAccess = function (Env, id, cb) { + var uo = _getUserObjectFromId(Env, id); + var sd = uo.getFileData(id, true); + sd.atime = +new Date(); + Env.onSync(cb); + }; + var onCommand = function (Env, cmdData, cb) { var cmd = cmdData.cmd; var data = cmdData.data || {}; @@ -1031,6 +1057,8 @@ define([ _addFolder(Env, data, cb); break; case 'addSharedFolder': _addSharedFolder(Env, data, cb); break; + case 'addLink': + _addLink(Env, data, cb); break; case 'restoreSharedFolder': _restoreSharedFolder(Env, data, cb); break; case 'convertFolderToSharedFolder': @@ -1045,6 +1073,8 @@ define([ _rename(Env, data, cb); break; case 'setFolderData': _setFolderData(Env, data, cb); break; + case 'updateStaticAccess': + _updateStaticAccess(Env, data, cb); break; default: cb(); } @@ -1129,8 +1159,8 @@ define([ data: uo.getFileData(id) }; }).filter(function (d) { - if (channels.indexOf(d.data.channel) === -1) { - channels.push(d.data.channel); + if (channels.indexOf(d.data.channel || d.id) === -1) { + channels.push(d.data.channel || d.id); return true; } }); @@ -1383,6 +1413,16 @@ define([ } }, cb); }; + var addLinkInner = function (Env, path, data, cb) { + return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { + cmd: "addLink", + data: { + path: path, + name: data.name, + href: data.url + } + }, cb); + }; var restoreSharedFolderInner = function (Env, fId, password, cb) { return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { cmd: "restoreSharedFolder", @@ -1433,6 +1473,14 @@ define([ }, cb); }; + var updateStaticAccessInner = function (Env, id, cb) { + return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { + cmd: "updateStaticAccess", + data: id + }, cb); + + }; + /* Tools */ var findChannels = _findChannels; @@ -1450,6 +1498,11 @@ define([ return String(uo.getTitle(id, type)); }; + var isStaticFile = function (Env, id) { + var uo = _getUserObjectFromId(Env, id); + return uo.isStaticFile(id); + }; + var isReadOnlyFile = function (Env, id) { var uo = _getUserObjectFromId(Env, id); return uo.isReadOnlyFile(id); @@ -1491,7 +1544,7 @@ define([ var files = []; var userObjects = _getUserObjects(Env); userObjects.forEach(function (uo) { - var data = uo.getFiles([UserObject.FILES_DATA]).map(function (id) { + var data = uo.getFiles([UserObject.FILES_DATA, UserObject.STATIC_DATA]).map(function (id) { return [Number(id), uo.getFileData(id)]; }); Array.prototype.push.apply(files, data); @@ -1608,17 +1661,20 @@ define([ emptyTrash: callWithEnv(emptyTrashInner), addFolder: callWithEnv(addFolderInner), addSharedFolder: callWithEnv(addSharedFolderInner), + addLink: callWithEnv(addLinkInner), restoreSharedFolder: callWithEnv(restoreSharedFolderInner), convertFolderToSharedFolder: callWithEnv(convertFolderToSharedFolderInner), delete: callWithEnv(deleteInner), deleteOwned: callWithEnv(deleteOwnedInner), restore: callWithEnv(restoreInner), setFolderData: callWithEnv(setFolderDataInner), + updateStaticAccess: callWithEnv(updateStaticAccessInner), // Tools getFileData: callWithEnv(getFileData), find: callWithEnv(find), getTitle: callWithEnv(getTitle), isReadOnlyFile: callWithEnv(isReadOnlyFile), + isStaticFile: callWithEnv(isStaticFile), getFiles: callWithEnv(getFiles), search: callWithEnv(search), getRecentPads: callWithEnv(getRecentPads), diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 0fd250f80..96997cd06 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -733,11 +733,20 @@ define([ if (!common.isLoggedIn()) { return; } $embedButton = common.createButton('mediatag', true).click(function () { var cfg = { - types: ['file'], + types: ['file', 'link'], where: ['root'] }; if ($embedButton.data('filter')) { cfg.filter = $embedButton.data('filter'); } common.openFilePicker(cfg, function (data) { + // Embed links + if (data.static) { + var a = h('a', { + href: data.href + }, data.name); + mediaTagEmbedder($(a), data); + return; + } + // Embed files if (data.type !== 'file') { console.log("Unexpected data type picked " + data.type); return; diff --git a/www/common/userObject.js b/www/common/userObject.js index ca716f25f..9de3ea918 100644 --- a/www/common/userObject.js +++ b/www/common/userObject.js @@ -17,6 +17,7 @@ define([ var SHARED_FOLDERS_TEMP = module.SHARED_FOLDERS_TEMP = "sharedFoldersTemp"; // Maybe deleted or new password var FILES_DATA = module.FILES_DATA = Constants.storageKey; var OLD_FILES_DATA = module.OLD_FILES_DATA = Constants.oldStorageKey; + var STATIC_DATA = module.STATIC_DATA = 'static'; // Create untitled documents when no name is given var getLocaleDate = function () { @@ -138,6 +139,7 @@ define([ var NEW_FILE_NAME = Messages.fm_newFile || 'New file'; exp.ROOT = ROOT; + exp.STATIC_DATA = STATIC_DATA; exp.UNSORTED = UNSORTED; exp.TRASH = TRASH; exp.TEMPLATE = TEMPLATE; @@ -236,6 +238,10 @@ define([ return Boolean(data.roHref && !data.href); }; + exp.isStaticFile = function (element) { + return Boolean(files[STATIC_DATA] && files[STATIC_DATA][element]); + }; + var isFolder = exp.isFolder = function (element) { if (isFolderData(element)) { return false; } return typeof(element) === "object" || isSharedFolder(element); @@ -310,6 +316,12 @@ define([ // Get data from AllFiles (Cryptpad_RECENTPADS) var getFileData = exp.getFileData = function (file, editable) { if (!file) { return; } + var link = (files[STATIC_DATA] || {})[file]; + if (link) { + var _link = editable ? link : Util.clone(link); + if (!editable) { _link.static = true; } + return _link; + } var data = files[FILES_DATA][file] || {}; if (!editable) { data = JSON.parse(JSON.stringify(data)); @@ -344,6 +356,7 @@ define([ return '??'; } var data = getFileData(file); + if (data.static) { return data.name; } if (!file || !data || !(data.href || data.roHref)) { error("getTitle called with a non-existing file id: ", file, data); return; @@ -475,6 +488,11 @@ define([ }); return ret; }; + _getFiles[STATIC_DATA] = function () { + var ret = []; + if (!files[STATIC_DATA]) { return ret; } + return Object.keys(files[STATIC_DATA]).map(Number).filter(Boolean); + }; _getFiles[FILES_DATA] = function () { var ret = []; if (!files[FILES_DATA]) { return ret; } @@ -854,6 +872,7 @@ define([ // RENAME exp.rename = function (path, newName, cb) { + cb = cb || function () {}; if (sframeChan) { return void sframeChan.query("Q_DRIVE_USEROBJECT", { cmd: "rename", @@ -891,9 +910,15 @@ define([ if (isSharedFolder(element)) { data = files[SHARED_FOLDERS][element]; } else { - data = files[FILES_DATA][element]; + data = files[FILES_DATA][element] || files[STATIC_DATA][element]; } if (!data) { return; } + if (files[STATIC_DATA][element]) { + if (!newName || !newName.trim()) { return void cb(); } + data.name = newName; + cb(); + return; + } if (!newName || newName.trim() === "") { delete data.filename; if (typeof cb === "function") { cb(); } diff --git a/www/secureiframe/inner.js b/www/secureiframe/inner.js index 4226c7f82..18970c47b 100644 --- a/www/secureiframe/inner.js +++ b/www/secureiframe/inner.js @@ -127,6 +127,7 @@ define([ sframeChan.event("EV_SECURE_ACTION", { type: parsed.type, password: data.password, + static: data.static, href: data.url, name: data.name }); @@ -214,20 +215,21 @@ define([ $container.html(''); Object.keys(list).forEach(function (id) { var data = list[id]; - var name = data.filename || data.title || '?'; + var name = data.filename || data.title || data.name || '?'; if (filter && name.toLowerCase().indexOf(filter.toLowerCase()) === -1) { return; } var $span = $('', { 'class': 'cp-filepicker-content-element', - 'title': name, + 'title': Util.fixHTML(name), }).appendTo($container); $span.append(UI.getFileIcon(data)); $('', {'class': 'cp-filepicker-content-element-name'}).text(name) .appendTo($span); + if (data.static) { $span.attr('title', Util.fixHTML(data.href)); } $span.click(function () { if (typeof onFilePicked === "function") { - onFilePicked({url: data.href, name: name, password: data.password}); + onFilePicked({url: data.href, name: name, static: data.static, password: data.password}); } }); diff --git a/www/teams/main.js b/www/teams/main.js index ea48f72a1..4bf00e105 100644 --- a/www/teams/main.js +++ b/www/teams/main.js @@ -24,7 +24,8 @@ define([ sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) { if (!teamId) { return void cb({error: 'EINVAL'}); } - data.teamId = teamId; + if (data.teamId !== -1) { data.teamId = teamId; } + else { delete data.teamId; } Cryptpad.userObjectCommand(data, cb); }); sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) { From e38206ffb34775081d5e2d8f616c86b6fb638636 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 20 Jul 2021 10:46:40 +0200 Subject: [PATCH 12/49] Fix premium tickets --- www/support/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index 90fd43fa5..db51e1221 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -345,7 +345,7 @@ define([ var senderKey = content.sender && content.sender.edPublic; var fromMe = senderKey === privateData.edPublic; var fromAdmin = ctx.adminKeys.indexOf(senderKey) !== -1; - var fromPremium = Boolean(content.sender.plan); + var fromPremium = Boolean(content.sender.plan || Util.find(content, ['sender', 'quota', 'plan']); var userData = h('div.cp-support-showdata', [ Messages.support_showData, From 1a88baf9c367bb41edb579df694fc67dd17c9a07 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 20 Jul 2021 10:48:25 +0200 Subject: [PATCH 13/49] lint compliance --- www/support/ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/support/ui.js b/www/support/ui.js index db51e1221..f61ddac4b 100644 --- a/www/support/ui.js +++ b/www/support/ui.js @@ -345,7 +345,7 @@ define([ var senderKey = content.sender && content.sender.edPublic; var fromMe = senderKey === privateData.edPublic; var fromAdmin = ctx.adminKeys.indexOf(senderKey) !== -1; - var fromPremium = Boolean(content.sender.plan || Util.find(content, ['sender', 'quota', 'plan']); + var fromPremium = Boolean(content.sender.plan || Util.find(content, ['sender', 'quota', 'plan'])); var userData = h('div.cp-support-showdata', [ Messages.support_showData, From d530a51f99facde8c496142f46615bc85c941542 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 20 Jul 2021 10:51:12 +0200 Subject: [PATCH 14/49] Fix premium ticket category in admin panel --- www/admin/inner.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/admin/inner.js b/www/admin/inner.js index 61cf05896..b35059df0 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -833,7 +833,8 @@ define([ var premium = t.some(function (msg) { var _ed = Util.find(msg, ['content', 'msg', 'content', 'sender', 'edPublic']); if (ed !== _ed) { return; } - return Util.find(msg, ['content', 'msg', 'content', 'sender', 'plan']); + return Util.find(msg, ['content', 'msg', 'content', 'sender', 'plan']) || + Util.find(msg, ['content', 'msg', 'content', 'sender', 'quota', 'plan']); }); var lastMsg = t[t.length - 1]; var lastMsgEd = Util.find(lastMsg, ['content', 'msg', 'content', 'sender', 'edPublic']); From 0a5614b79f20c841da7172f5e7d5603bdffa8a50 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 21 Jul 2021 11:37:44 +0200 Subject: [PATCH 15/49] Fix team invitation link #774 --- www/common/outer/team.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 4184b8482..94f91c807 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -195,7 +195,7 @@ define([ Pinpad.create(ctx.store.network, data, function (e, call) { if (e) { return void cb(e); } team.rpc = call; - team.onRpcReadyEvt.fire(); + if (team && team.onRpcReadyEvt) { team.onRpcReadyEvt.fire(); } cb(); }, Cache); }); From 667bef2a840951e7226a8cb2147734ba9ca5eb3c Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 21 Jul 2021 17:19:35 +0200 Subject: [PATCH 16/49] Fix links in shared folders --- www/common/outer/userObject.js | 6 ++++++ www/common/proxy-manager.js | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index a12beacf9..257fa5001 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -253,6 +253,12 @@ define([ id = Number(id); // Find and maybe update existing pads with the same channel id var d = data[id]; + // If we were given a static link, copy to STATIC_DATA + if (d.static) { + delete d.static; + files[STATIC_DATA][id] = d; + return; + } // If we were given an edit link, encrypt its value if needed if (d.href) { d.href = exp.cryptor.encrypt(d.href); } var found = false; diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index fc42f8aae..01c22812c 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -22,11 +22,11 @@ define([ // a cached version if (Env.folders[id].offline && !lm.cache) { Env.folders[id].offline = false; + if (Env.folders[id].userObject.fixFiles) { Env.folders[id].userObject.fixFiles(); } Env.Store.refreshDriveUI(); } return; } - if (Env.folders[id]) { console.warn(Env.folders[id]); } var cfg = getConfig(Env); cfg.sharedFolder = true; cfg.id = id; From 6faaec5042f8442463f481b1267212022eafc94e Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 22 Jul 2021 12:06:48 +0200 Subject: [PATCH 17/49] lint compliance --- www/code/inner.js | 2 +- www/common/drive-ui.js | 16 ++++++++-------- www/common/outer/userObject.js | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/www/code/inner.js b/www/code/inner.js index 19ffdb285..4f6c0308e 100644 --- a/www/code/inner.js +++ b/www/code/inner.js @@ -369,7 +369,7 @@ define([ evModeChange.reg(function (mode) { if (MEDIA_TAG_MODES.indexOf(mode) !== -1) { // Embedding is enabled - framework.setMediaTagEmbedder(function (mt, data) { + framework.setMediaTagEmbedder(function (mt) { editor.focus(); editor.replaceSelection($(mt)[0].outerHTML); }); diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 28ac531e2..9c0a37f42 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1113,6 +1113,10 @@ define([ common.getMediaTagPreview(mts, idx); }; + var refresh = APP.refresh = function () { + APP.displayDirectory(currentPath); + }; + // `app`: true (force open wiht the app), false (force open in preview), // falsy (open in preview if default is not using the app) var defaultInApp = ['application/pdf']; @@ -1163,10 +1167,6 @@ define([ common.openURL(Hash.getNewPadURL(href, obj)); }; - var refresh = APP.refresh = function () { - APP.displayDirectory(currentPath); - }; - var pickFolderColor = function ($element, currentColor, cb) { var colors = ["", "#f23c38", "#ff0073", "#da0eba", "#9d00ac", "#6c19b3", "#4a42b1", "#3d8af0", "#30a0f1", "#1fb9d1", "#009686", "#45b354", "#84c750", "#c6e144", "#faf147", "#fbc423", "#fc9819", "#fd5227", "#775549", "#9c9c9c", "#607a89"]; @@ -1938,7 +1938,7 @@ define([ 'class': 'cp-app-drive-element-ctime cp-app-drive-element-list' }).text(getDate(data.ctime)); $element.append($type).append($adate).append($cdate); - } + }; var _addOwnership = function ($span, $state, data) { if (data && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1) { var $owned = $ownedIcon.clone().appendTo($state); @@ -2504,7 +2504,7 @@ define([ setViewMode(viewMode || 'grid'); showMode(viewMode); - $button.click(function (e) { + $button.click(function () { var viewMode = getViewMode(); var newViewMode = getOppositeViewMode(viewMode); setViewMode(newViewMode); @@ -3182,11 +3182,11 @@ define([ .text(Messages.uploadFolderButton)); } // Link - var $elementFileUpload = $('
  • ', { + var $elementLink = $('
  • ', { 'class': 'cp-app-drive-new-link cp-app-drive-element-row ' + 'cp-app-drive-element-grid' }).prepend(getIcon('link')).appendTo($container); - $elementFileUpload.append($('', {'class': 'cp-app-drive-new-name'}) + $elementLink.append($('', {'class': 'cp-app-drive-new-name'}) .text(Messages.fm_link)); } // Pads diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 257fa5001..97c2207e0 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -864,15 +864,15 @@ define([ }); var sd = files[STATIC_DATA]; var toCleanSD = []; - for (var id in sd) { - id = Number(id); - var el2 = sd[id]; + for (var id2 in sd) { + id2 = Number(id2); + var el2 = sd[id2]; if (!el2 || typeof(el2) !== "object" || !el2.href) { - toCleanSD.push(id); + toCleanSD.push(id2); continue; } - if ((loggedIn || config.testMode) && rootFiles.indexOf(id) === -1) { - toCleanSD.push(id); + if ((loggedIn || config.testMode) && rootFiles.indexOf(id2) === -1) { + toCleanSD.push(id2); continue; } } From 6c720ce9d1881f5dacabe5e15877edad91b6781a Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 23 Jul 2021 10:18:42 +0200 Subject: [PATCH 18/49] Fix type error --- www/form/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/form/inner.js b/www/form/inner.js index 9f05f80dd..e30f0775a 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -607,7 +607,7 @@ define([ _date = new Date(data); data = Flatpickr.formatDate(_date, timeFormat); } - var day = allDays[_date.getDay()]; + var day = _date && allDays[_date.getDay()]; return h('div.cp-poll-cell.cp-form-poll-option', { title: Util.fixHTML(data) }, [ From 212b3d48845b9ad17408f18ea920bdd3f4305f78 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 23 Jul 2021 14:47:30 +0200 Subject: [PATCH 19/49] Form fixes and improvements --- www/common/sframe-common-outer.js | 1 - www/form/app-form.less | 14 ++++++ www/form/inner.js | 71 ++++++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index b0759b5ec..a532863a2 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -1925,7 +1925,6 @@ define([ var cryptputCfg = $.extend(true, {}, rtConfig, {password: password}); if (data.templateContent) { Cryptget.put(currentPad.hash, JSON.stringify(data.templateContent), function () { - console.error(arguments); startRealtime(); cb(); }, cryptputCfg); diff --git a/www/form/app-form.less b/www/form/app-form.less index b0e38f27c..b037efac2 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -247,6 +247,14 @@ .cp-form-anon-answer { text-align: center; margin: 20px 0 30px 0; + .cp-form-anon-answer-input { + display: flex; + white-space: nowrap; + align-items: center; + input { + margin-left: 10px; + } + } } } @@ -669,6 +677,12 @@ .avatar_main(30px); margin-right: 10px; } + &.cp-clickable { + cursor: pointer; + &:hover { + transform: scale(1.1); + } + } } .cp-poll-time-day { flex-basis: 100px; diff --git a/www/form/inner.js b/www/form/inner.js index 9f05f80dd..773740701 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -588,7 +588,9 @@ define([ return weekDays.map(function (day) { return day.replace(/^./, function (str) { return str.toUpperCase(); }); }); }; - var makePollTable = function (answers, opts) { + // "resultsPageObj" is an object with "content" and "answers" + // only available when viewing the Responses page + var makePollTable = function (answers, opts, resultsPageObj) { // Sort date values if (opts.type !== "text") { opts.values.sort(function (a, b) { @@ -607,7 +609,7 @@ define([ _date = new Date(data); data = Flatpickr.formatDate(_date, timeFormat); } - var day = allDays[_date.getDay()]; + var day = _date && allDays[_date.getDay()]; return h('div.cp-poll-cell.cp-form-poll-option', { title: Util.fixHTML(data) }, [ @@ -667,13 +669,19 @@ define([ }, v); return cell; }); - els.unshift(h('div.cp-poll-cell.cp-poll-answer-name', { + var nameCell; + els.unshift(nameCell = h('div.cp-poll-cell.cp-poll-answer-name', { title: Util.fixHTML(name) }, [ avatar, h('span', name) ])); bodyEls.push(h('div', els)); + if (resultsPageObj && (APP.isEditor || APP.isAuditor)) { + $(nameCell).addClass('cp-clickable').click(function () { + APP.renderResults(resultsPageObj.content, resultsPageObj.answers, answerObj.curve); + }); + } }); } var body = h('div.cp-form-poll-body', bodyEls); @@ -815,6 +823,7 @@ define([ if (filterCurve && user === filterCurve) { return; } try { return { + curve: user, user: answers[user].msg._userdata, results: answers[user].msg[uid] }; @@ -1615,7 +1624,7 @@ define([ if (!opts) { opts = TYPES.poll.defaultOpts; } if (!Array.isArray(opts.values)) { return; } - var lines = makePollTable(answers, opts); + var lines = makePollTable(answers, opts, false); // Add form var addLine = opts.values.map(function (data) { @@ -1699,10 +1708,16 @@ define([ }; }, - printResults: function (answers, uid, form) { + printResults: function (answers, uid, form, content) { var opts = form[uid].opts || TYPES.poll.defaultOpts; var _answers = getBlockAnswers(answers, uid); - var lines = makePollTable(_answers, opts); + + // If content is defined, we'll be able to click on a row to display + // all the answers of this user + var lines = makePollTable(_answers, opts, content && { + content: content, + answers: answers + }); var total = makePollTotal(_answers, opts); if (total) { lines.push(h('div', total)); } @@ -1723,7 +1738,7 @@ define([ }, }; - var renderResults = function (content, answers) { + var renderResults = APP.renderResults = function (content, answers, showUser) { var $container = $('div.cp-form-creator-results').empty(); if (!Object.keys(answers || {}).length) { @@ -1767,7 +1782,9 @@ define([ var type = block.type; var model = TYPES[type]; if (!model || !model.printResults) { return; } - var print = model.printResults(answers, uid, form); + + // Only use content if we're not viewing individual answers + var print = model.printResults(answers, uid, form, !header && content); var q = h('div.cp-form-block-question', block.q || Messages.form_default); @@ -1861,10 +1878,19 @@ define([ e.preventDefault(); APP.common.openURL(Hash.hashToHref(ud.profile, 'profile')); }); + if (showUser === curve) { + setTimeout(function () { + showUser = undefined; + $(viewButton).click(); + }); + } return div; }); $results.append(els); }); + if (showUser) { + $s.click(); + } }; var addResultsButton = function (framework, content) { @@ -1910,16 +1936,34 @@ define([ var makeFormControls = function (framework, content, update, evOnChange) { var loggedIn = framework._.sfCommon.isLoggedIn(); var metadataMgr = framework._.cpNfInner.metadataMgr; + var user = metadataMgr.getUserData(); if (!loggedIn && !content.answers.anonymous) { return; } var cbox; + var anonName, $anonName; cbox = UI.createCheckbox('cp-form-anonymous', Messages.form_anonymousBox, true, { mark: { tabindex:1 } }); + var $anonBox = $(cbox).find('input'); if (loggedIn) { if (!content.answers.anonymous || APP.cantAnon) { $(cbox).hide().find('input').attr('disabled', 'disabled').prop('checked', false); } + } else { + Messages.form_anonName = "Your username"; // XXX + Messages.form_answerAs = "Answer as"; // XXX + anonName = h('div.cp-form-anon-answer-input', [ + Messages.form_answerAs, + h('input', { + value: user.name || '', + placeholder: Messages.form_anonName + }) + ]) + $anonName = $(anonName).hide(); + $anonBox.on('change', function () { + if (Util.isChecked($anonBox)) { $anonName.hide(); } + else { $anonName.show(); } + }); } var send = h('button.cp-open.btn.btn-primary', update ? Messages.form_update : Messages.form_submit); @@ -1937,14 +1981,16 @@ define([ if (!results) { return; } var user = metadataMgr.getUserData(); - if (!Util.isChecked($(cbox).find('input'))) { + if (!Util.isChecked($anonBox)) { results._userdata = loggedIn ? { avatar: user.avatar, name: user.name, notifications: user.notifications, curvePublic: user.curvePublic, profile: user.profile - } : { name: user.name }; + } : { + name: $anonName ? $anonName.find('input').val() : user.name + }; } var sframeChan = framework._.sfCommon.getSframeChannel(); @@ -2024,7 +2070,10 @@ define([ return h('div.cp-form-send-container', [ invalid, - cbox ? h('div.cp-form-anon-answer', cbox) : undefined, + cbox ? h('div.cp-form-anon-answer', [ + cbox, + anonName + ]) : undefined, reset, send ]); }; From a93a9f14d3f8cd252ab29e6a5330a588f6251b16 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 23 Jul 2021 17:51:42 +0200 Subject: [PATCH 20/49] Fix initial title with forms templates --- www/common/sframe-common-title.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/www/common/sframe-common-title.js b/www/common/sframe-common-title.js index 2539d1542..d1b06df73 100644 --- a/www/common/sframe-common-title.js +++ b/www/common/sframe-common-title.js @@ -23,6 +23,12 @@ define([ var $title; exp.setToolbar = function (toolbar) { $title = toolbar && (toolbar.title || toolbar.pageTitle); + if ($title && exp.defaultTitle) { + var md = metadataMgr.getMetadata(); + $title.find('input').prop('placeholder', md.defaultTitle); + $title.find('span.cp-toolbar-title-value').text(md.title || md.defaultTitle); + $title.find('input').val(md.title || md.defaultTitle); + } }; exp.getTitle = function () { return exp.title; }; From f5fc4f28bffd7815635d0cae57a84c25f8809f13 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 23 Jul 2021 17:51:56 +0200 Subject: [PATCH 21/49] Improve forms CSV export with polls --- www/form/inner.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 773740701..8db1f8e16 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -1724,15 +1724,31 @@ define([ return h('div.cp-form-type-poll', lines); }, - exportCSV: function (answer) { - if (answer === false) { return; } - if (!answer || !answer.values) { return ['']; } + exportCSV: function (answer, form) { + var opts = form.opts || TYPES.poll.defaultOpts; + var q = form.q || Messages.form_default; + if (answer === false) { + var cols = opts.values.map(function (key) { + return q + ' | ' + key; + }); + cols.unshift(q); + return cols; + } + if (!answer || !answer.values) { + var empty = opts.values.map(function () { return ''; }); + empty.unshift(''); + return empty; + } var str = ''; Object.keys(answer.values).sort().forEach(function (k, i) { if (i !== 0) { str += ';'; } str += k.replace(';', '').replace(':', '') + ':' + answer.values[k]; }); - return [str]; + var res = opts.values.map(function (key) { + return answer.values[key] || ''; + }); + res.unshift(str); + return res; }, icon: h('i.cptools.cptools-form-poll') }, From 2019e1d70a75dd8c36c8b5b1459e34f3f59d3b41 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 13:05:47 +0530 Subject: [PATCH 22/49] implement minor fixes and add comments following code review --- www/common/drive-ui.js | 7 +++--- www/common/outer/mailbox-handlers.js | 3 ++- www/common/outer/userObject.js | 32 +++++++++++++++++----------- www/teams/main.js | 2 ++ 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 9c0a37f42..cd456fd41 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -42,7 +42,8 @@ define([ Pages) { - Messages.fm_link = "Link"; // XXX + Messages.fm_link = "Link"; // XXX "New Link" ? + // XXX check for all occurrences of `fm_link` before changing it var APP = window.APP = { editable: false, @@ -1924,10 +1925,10 @@ define([ var $name = $('', {'class': 'cp-app-drive-element-name'}).text(name); $element.append($name); if (getViewMode() === 'grid') { - $element.attr('title', name); + $element.attr('title', name); // XXX Util.fixHTML } - var type = Messages.fm_link; + var type = Messages.fm_link; // XXX new translation key ("Link") var $type = $('', { 'class': 'cp-app-drive-element-type cp-app-drive-element-list' }).text(type); diff --git a/www/common/outer/mailbox-handlers.js b/www/common/outer/mailbox-handlers.js index bb19d2d91..88e43352b 100644 --- a/www/common/outer/mailbox-handlers.js +++ b/www/common/outer/mailbox-handlers.js @@ -238,7 +238,8 @@ define([ // content.name, content.title, content.href, content.password if (isMuted(ctx, data)) { return void cb(true); } - + // if the shared content is a 'link' then we can't use the channel to deduplicate notifications + // use href instead. var channel = content.isStatic ? content.href : Hash.hrefToHexChannelId(content.href, content.password); var parsed = Hash.parsePadUrl(content.href); var mode = parsed.hashData && parsed.hashData.mode || 'n/a'; diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 97c2207e0..4051c79c1 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -616,13 +616,18 @@ define([ var element = elem || files[ROOT]; if (!element) { return console.error("Invalid element in root"); } var nbMetadataFolders = 0; + // caching this variables saves a lot of hashmap lookups in this loop + var static_data = files[STATIC_DATA]; + var files_data = files[FILES_DATA]; + var element_el; for (var el in element) { - if (element[el] === null) { + element_el = element[el]; + if (element_el === null) { console.error('element[%s] is null', el); delete element[el]; continue; } - if (exp.isFolderData(element[el])) { + if (exp.isFolderData(element_el)) { if (nbMetadataFolders !== 0) { debug("Multiple metadata files in folder"); delete element[el]; @@ -630,30 +635,30 @@ define([ nbMetadataFolders++; continue; } - if (!exp.isFile(element[el], true) && !exp.isFolder(element[el])) { - debug("An element in ROOT was not a folder nor a file. ", element[el]); + if (!exp.isFile(element_el, true) && !exp.isFolder(element_el)) { + debug("An element in ROOT was not a folder nor a file. ", element_el); delete element[el]; continue; } - if (exp.isFolder(element[el])) { - fixRoot(element[el]); + if (exp.isFolder(element_el)) { + fixRoot(element_el); continue; } - if (typeof element[el] === "string") { + if (typeof element_el === "string") { // We have an old file (href) which is not in filesData: add it var id = Util.createRandomInteger(); var key = Hash.createChannelId(); - files[FILES_DATA][id] = { - href: exp.cryptor.encrypt(element[el]), + files_data[id] = { + href: exp.cryptor.encrypt(element_el), filename: el }; element[key] = id; delete element[el]; } - if (typeof element[el] === "number") { - var data = files[FILES_DATA][element[el]] || files[STATIC_DATA][element[el]]; + if (typeof element_el === "number") { + var data = files_data[element_el] || static_data[element_el]; if (!data) { - debug("An element in ROOT doesn't have associated data", element[el], el); + debug("An element in ROOT doesn't have associated data", element_el, el); delete element[el]; } } @@ -862,6 +867,7 @@ define([ toClean.forEach(function (id) { spliceFileData(id); }); + // make sure that links are displayed at least once in your drive if you are going to keep them var sd = files[STATIC_DATA]; var toCleanSD = []; for (var id2 in sd) { @@ -929,7 +935,7 @@ define([ } }; var fixStaticData = function () { - if (typeof(files[STATIC_DATA]) !== "object") { + if (Util.isObject(files[STATIC_DATA])) { debug("STATIC_DATA was not an object"); files[STATIC_DATA] = {}; } diff --git a/www/teams/main.js b/www/teams/main.js index 4bf00e105..7d12126eb 100644 --- a/www/teams/main.js +++ b/www/teams/main.js @@ -24,6 +24,8 @@ define([ sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) { if (!teamId) { return void cb({error: 'EINVAL'}); } + // a teamId of -1 bypasses guards against modifying your drive + // from the team app if (data.teamId !== -1) { data.teamId = teamId; } else { delete data.teamId; } Cryptpad.userObjectCommand(data, cb); From 6578b66ba6b6b665eb4b440f4e74b65811dcfed5 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 13:07:23 +0530 Subject: [PATCH 23/49] convert a warning to an error --- www/checkup/main.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/www/checkup/main.js b/www/checkup/main.js index f4a40d11e..93ead1bbc 100644 --- a/www/checkup/main.js +++ b/www/checkup/main.js @@ -714,8 +714,6 @@ define([ if (isOnion(trimmedUnsafe) && isOnion(trimmedSafe)) { return void cb(true); } // otherwise expect that both inner and outer domains use HTTPS - setWarningClass(msg); - msg.appendChild(h('span', [ "Both ", code('httpUnsafeOrigin'), From 9ca3682df95dac85084d912bb5742707f56df35e Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 14:10:32 +0530 Subject: [PATCH 24/49] fix an accidentally flipped boolean --- www/common/outer/userObject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 4051c79c1..7108da936 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -935,7 +935,7 @@ define([ } }; var fixStaticData = function () { - if (Util.isObject(files[STATIC_DATA])) { + if (!Util.isObject(files[STATIC_DATA])) { debug("STATIC_DATA was not an object"); files[STATIC_DATA] = {}; } From 99c11f032e3cb131011e2bf584412f1105526358 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 14:53:04 +0530 Subject: [PATCH 25/49] tally form votes with an increment function --- www/common/common-util.js | 4 ++++ www/form/inner.js | 22 +++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/www/common/common-util.js b/www/common/common-util.js index 1fd78cec1..ac50a1f24 100644 --- a/www/common/common-util.js +++ b/www/common/common-util.js @@ -161,6 +161,10 @@ }; }; + Util.inc = function (map, key, val) { + map[key] = (map[key] || 0) + (typeof(val) === 'number'? val: 1); + }; + Util.find = function (map, path) { var l = path.length; for (var i = 0; i < l; i++) { diff --git a/www/form/inner.js b/www/form/inner.js index 8db1f8e16..266be125b 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -729,7 +729,7 @@ define([ var answer = answerObj.results; if (!answer || !answer.values) { return; } var values = answer.values || {}; - var res = Number(values[data]) || 0; // XXX inc function ? + var res = Number(values[data]) || 0; if (res === 1) { y++; } else if (res === 2) { m++; } }); @@ -784,7 +784,7 @@ define([ if (!data) { return; } var y = totals[data].y + ((myTotals[data] || {}).y || 0); var m = totals[data].m + ((myTotals[data] || {}).m || 0); - $c.find('.cp-form-total-yes').text(y); // XXX inc function + $c.find('.cp-form-total-yes').text(y); $c.find('.cp-form-total-maybe').text('('+m+')'); }); }; @@ -1126,8 +1126,7 @@ define([ var obj = answers[author]; var answer = obj.msg[uid]; if (!answer || !answer.trim()) { return empty++; } - count[answer] = count[answer] || 0; // XXX inc function - count[answer]++; + Util.inc(count, answer); }); Object.keys(count).forEach(function (value) { results.push(h('div.cp-form-results-type-radio-data', [ @@ -1229,8 +1228,7 @@ define([ var c = count[q_uid] = count[q_uid] || {}; var res = answer[q_uid]; if (!res || !res.trim()) { return; } - c[res] = c[res] || 0; // XXX inc function - c[res]++; + Util.inc(c, res); }); }); Object.keys(count).forEach(function (q_uid) { @@ -1340,8 +1338,7 @@ define([ var answer = obj.msg[uid]; if (!Array.isArray(answer) || !answer.length) { return empty++; } answer.forEach(function (val) { - count[val] = count[val] || 0; // XXX inc function - count[val]++; + Util.inc(count, val); }); }); Object.keys(count).forEach(function (value) { @@ -1455,9 +1452,8 @@ define([ var c = count[q_uid] = count[q_uid] || {}; var res = answer[q_uid]; if (!Array.isArray(res) || !res.length) { return; } - res.forEach(function (v) { // XXX increment function? - c[v] = c[v] || 0; - c[v]++; + res.forEach(function (v) { + Util.inc(c, v); }); }); }); @@ -1595,7 +1591,7 @@ define([ if (!Array.isArray(answer) || !answer.length) { return empty++; } answer.forEach(function (el, i) { var score = l - i; - count[el] = (count[el] || 0) + score; // XXX inc function? + Util.inc(count, el, score); }); }); var sorted = Object.keys(count).sort(function (a, b) { @@ -1974,7 +1970,7 @@ define([ value: user.name || '', placeholder: Messages.form_anonName }) - ]) + ]); $anonName = $(anonName).hide(); $anonBox.on('change', function () { if (Util.isChecked($anonBox)) { $anonName.hide(); } From 7bc6ed17b9aee94e23c422d26edb61a51c35f590 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 14:57:28 +0530 Subject: [PATCH 26/49] update max choices input in forms ...when the maximum exceeds the number of choices --- www/form/inner.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 266be125b..210d8bd68 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -298,6 +298,7 @@ define([ del ]); $(del).click(function () { + var $block = $(el).closest('.cp-form-edit-block'); $(el).remove(); // We've just deleted an item/option so we should be under the MAX limit and // we can show the "add" button again @@ -306,6 +307,13 @@ define([ $add.show(); if (v.type === "time") { $(addMultiple).show(); } } + // decrement the max choices input when there are fewer options than the current maximum + if (maxInput) { + var inputs = $block.find('input').length; + var $maxInput = $(maxInput); + var currentMax = Number($maxInput.val()); + $maxInput.val(Math.min(inputs, currentMax)); + } }); return el; }; @@ -776,7 +784,7 @@ define([ }; refreshBest(); - if (myLine && evOnChange) { // XXX + if (myLine && evOnChange) { var updateValues = function () { totalEls.forEach(function (cell) { var $c = $(cell); @@ -2564,8 +2572,8 @@ define([ var refreshResponse = function () { $responseMsg.empty(); Messages.form_updateMsg = "Update response message"; // XXX - Messages.form_addMsg = "Add response message"; - Messages.form_responseMsg = "Add a message that will be displayed in the response page."; + Messages.form_addMsg = "Add response message"; // XXX + Messages.form_responseMsg = "Add a message that will be displayed in the response page."; // XXX var text = content.answers.msg ? Messages.form_updateMsg : Messages.form_addMsg; var btn = h('button.btn.btn-secondary', text); $(btn).click(function () { From e5558b516c16a847d911ddba7378d806511dd778 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 15:02:48 +0530 Subject: [PATCH 27/49] guard against a typeError when drive-less users try to send a pad-burned notification --- www/common/outer/async-store.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 6aacd4a1b..30b71f1bd 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -2058,8 +2058,15 @@ define([ } catch (e) { console.error(e); } + // Tell all the owners that the pad was deleted from the server - var curvePublic = store.proxy.curvePublic; + var curvePublic; + try { + curvePublic = store.proxy.curvePublic; + } catch (err) { + console.error(err); + return; // XXX anons can't send notifications... + } m.forEach(function (obj) { var mb = JSON.parse(obj); if (mb.curvePublic === curvePublic) { return; } From 513f1531e3dc514876b811ce43ad1104bee33830 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 15:03:02 +0530 Subject: [PATCH 28/49] remove some dead code --- www/common/toolbar.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/www/common/toolbar.js b/www/common/toolbar.js index 785d1bc7e..5b53aa9a1 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -867,10 +867,6 @@ MessengerUI, Messages, Pages) { 'class': "cp-toolbar-link-logo" }).append(UIElements.getSvgLogo()); - /*.append($('', { - //src: '/customize/images/logo_white.png?' + ApiConfig.requireConf.urlArgs - src: '/customize/favicon/main-favicon.png?' + ApiConfig.requireConf.urlArgs - }));*/ var onClick = function (e) { e.preventDefault(); if (e.ctrlKey) { From d21e79733e6ff64862d496ff5151e11b8e4daa04 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 15:24:08 +0530 Subject: [PATCH 29/49] send feedback when self-destructing pads explode --- www/common/sframe-common-outer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index a532863a2..575971368 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -2003,6 +2003,8 @@ define([ sframeChan.on('EV_BURN_AFTER_READING', function () { startRealtime(); + // feedback fails for users in noDrive mode + Utils.Feedback.send("BURN_AFTER_READING", Boolean(cfg.noDrive)); }); sframeChan.ready(); From ec928334d898d21f3e746ddd52376b220c0254ee Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 15:26:23 +0530 Subject: [PATCH 30/49] don't try to pin channels with invalid lengths --- www/common/proxy-manager.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 01c22812c..78196cf7c 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -1263,7 +1263,10 @@ define([ Array.prototype.push.apply(result, sfChannels); } - return result; + return result.filter(function (channel) { + if (typeof(channel) !== 'string') { return; } + return [32, 48].indexOf(channel.length) !== -1; + }); }; var addPad = function (Env, path, pad, cb) { From 52d5bb5ae865dddf962f61012a0e7b2f8cb97262 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 15:28:20 +0530 Subject: [PATCH 31/49] add notes to gather feedback about the new link feature --- www/common/common-ui-elements.js | 3 +++ www/common/drive-ui.js | 2 ++ www/common/inner/share.js | 1 + www/common/notifications.js | 1 + 4 files changed, 7 insertions(+) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 6114884b2..8b01ad652 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -3048,6 +3048,7 @@ define([ var buttons = [{ name: Messages.friendRequest_later, onClick: function () { + // XXX feedback if (clicked) { return true; } clicked = true; }, @@ -3056,6 +3057,7 @@ define([ className: 'primary', name: Messages.link_open, onClick: function () { + // XXX feedback if (clicked) { return true; } clicked = true; common.openUnsafeURL(url); @@ -3067,6 +3069,7 @@ define([ onClick: function () { if (clicked) { return; } clicked = true; + // XXX feedback common.getSframeChannel().query("Q_DRIVE_USEROBJECT", { cmd: "addLink", data: { diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index cd456fd41..0e3b340a4 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1939,6 +1939,7 @@ define([ 'class': 'cp-app-drive-element-ctime cp-app-drive-element-list' }).text(getDate(data.ctime)); $element.append($type).append($adate).append($cdate); + // XXX feedback }; var _addOwnership = function ($span, $state, data) { if (data && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1) { @@ -2780,6 +2781,7 @@ define([ name: n, url: u }, refresh); + // XXX feedback }, keys: [13] }); diff --git a/www/common/inner/share.js b/www/common/inner/share.js index 5225ea818..125dcb5e2 100644 --- a/www/common/inner/share.js +++ b/www/common/inner/share.js @@ -111,6 +111,7 @@ define([ if (mailbox) { // Friend if (friends[curve] && !mailbox.notifications) { return; } if (mailbox.notifications && mailbox.curvePublic) { + // XXX feedback common.mailbox.sendTo("SHARE_PAD", { href: href, isStatic: Boolean(config.static), diff --git a/www/common/notifications.js b/www/common/notifications.js index 24458420e..78c29b90f 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -115,6 +115,7 @@ define([ }; content.handler = function() { if (msg.content.isStatic) { + // XXX feedback UIElements.displayOpenLinkModal(common, { curve: msg.author, href: msg.content.href, From f178d4bebc949bae5bda3a230cf70b0c2b582f45 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 15:51:15 +0530 Subject: [PATCH 32/49] update pending changelog --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f98c1ea68..7dd823202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +# WIP + +* links + * create links in your drive or a team drive + * share with contacts + * when you receive a link, you can "open", "store", "decide later" or dismiss from the notification dropdown + * share with a team (the link is instantly added to the team) + * store in your own drive from your team drive + * embed a link into a pad + * And you can have multiple links to the same target in one drive +* tabs in ckeditor +* fix recognition of premium user tickets in the admin support panel +* forms + * disable usage of the indexedDB cache for form results + * handle empty messages + * fix initial title with form templates + * style improvements + * guard against a typeError with dates + * in the responses page you can click on a user in the polls to get this user's answers to the other questions + * unregistered users can set their username when they don't want to answer anonymously + * improve CSV export with polls + * decrement max choices when it exceeds the number of available options +* remove unused images +* drive + * show the bread-crumb and disable the tree in anon drives + # 4.8.0 ## Goals From 403d922ddd4ceb86cbeecce9a92096824342c77b Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 16:30:49 +0530 Subject: [PATCH 33/49] replace two XXX notes with comments --- www/common/drive-ui.js | 6 +++++- www/common/outer/async-store.js | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 0e3b340a4..feec8543e 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1925,7 +1925,11 @@ define([ var $name = $('', {'class': 'cp-app-drive-element-name'}).text(name); $element.append($name); if (getViewMode() === 'grid') { - $element.attr('title', name); // XXX Util.fixHTML + //console.error(name, Util.fixHTML(name)); + // this is only safe because our build of tippy sets titles as + // 'textContent' instead of innerHTML, otherwise + // we would need to use Util.fixHTML + $element.attr('title', name); } var type = Messages.fm_link; // XXX new translation key ("Link") diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 30b71f1bd..d8e558dad 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -2062,10 +2062,12 @@ define([ // Tell all the owners that the pad was deleted from the server var curvePublic; try { + // users in noDrive mode don't have a proxy and + // unregistered users don't have a curvePublic curvePublic = store.proxy.curvePublic; } catch (err) { console.error(err); - return; // XXX anons can't send notifications... + return; } m.forEach(function (obj) { var mb = JSON.parse(obj); From 812d5f7146b48a72928fd172c4e8c11168277f69 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 18:11:45 +0530 Subject: [PATCH 34/49] disable form response message UI until it's been reviewed more --- www/form/inner.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 210d8bd68..8de8eb2c3 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2570,10 +2570,11 @@ define([ var responseMsg = h('div.cp-form-response-msg-container'); var $responseMsg = $(responseMsg); var refreshResponse = function () { + if (true) { return; } // XXX 4.10.0 $responseMsg.empty(); - Messages.form_updateMsg = "Update response message"; // XXX - Messages.form_addMsg = "Add response message"; // XXX - Messages.form_responseMsg = "Add a message that will be displayed in the response page."; // XXX + Messages.form_updateMsg = "Update response message"; // XXX 4.10.0 + Messages.form_addMsg = "Add response message"; // XXX 4.10.0 + Messages.form_responseMsg = "Add a message that will be displayed in the response page."; // XXX 4.10.0 var text = content.answers.msg ? Messages.form_updateMsg : Messages.form_addMsg; var btn = h('button.btn.btn-secondary', text); $(btn).click(function () { @@ -2602,7 +2603,7 @@ define([ name: Messages.settings_save, onClick: function () { var v = editor.getValue(); - content.answers.msg = v.trim(0, 2000); // XXX max length? + content.answers.msg = v.trim(0, 2000); // XXX 4.10.0 max length? framework.localChange(); framework._.cpNfInner.chainpad.onSettle(function () { UI.log(Messages.saved); @@ -2628,9 +2629,9 @@ define([ } UI.openCustomModal(APP.responseModal); }); - $responseMsg.append(btn); + // $responseMsg.append(btn); // XXX 4.10.0 }; - refreshResponse(); + //refreshResponse(); // Allow anonymous answers var privacyContainer = h('div.cp-form-privacy-container'); @@ -2727,7 +2728,7 @@ define([ evOnChange.reg(refreshPublic); evOnChange.reg(refreshPrivacy); evOnChange.reg(refreshEndDate); - evOnChange.reg(refreshResponse); + //evOnChange.reg(refreshResponse); return [ endDateContainer, From 987fb696ed7e904413210f1378944fc602516f39 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 18:12:31 +0530 Subject: [PATCH 35/49] downgrade urgency of unhandled form notes --- www/form/inner.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 8de8eb2c3..b3db8ce79 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -994,7 +994,7 @@ define([ printResults: function (answers, uid) { var results = []; var empty = 0; - Object.keys(answers).forEach(function (author) { // XXX deduplicate these? + Object.keys(answers).forEach(function (author) { // TODO deduplicate these? var obj = answers[author]; var answer = obj.msg[uid]; if (!answer || !answer.trim()) { return empty++; } @@ -1006,7 +1006,7 @@ define([ }, icon: h('i.cptools.cptools-form-text') }, - textarea: { // XXX + textarea: { defaultOpts: { maxLength: 1000 }, @@ -1060,7 +1060,7 @@ define([ printResults: function (answers, uid) { var results = []; var empty = 0; - Object.keys(answers).forEach(function (author) { // XXX deduplicate these + Object.keys(answers).forEach(function (author) { // TODO deduplicate these var obj = answers[author]; var answer = obj.msg[uid]; if (!answer || !answer.trim()) { return empty++; } From 4862e9b0ccd2f6ba78be452193c07984e4e0cb37 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 18:14:01 +0530 Subject: [PATCH 36/49] use two translation keys for 'Link' UI in different contexts --- www/common/drive-ui.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index feec8543e..12c4431c8 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -42,8 +42,8 @@ define([ Pages) { - Messages.fm_link = "Link"; // XXX "New Link" ? - // XXX check for all occurrences of `fm_link` before changing it + Messages.fm_link_new = "New Link"; // XXX + Messages.fm_link_type = "Link"; // XXX var APP = window.APP = { editable: false, @@ -450,7 +450,7 @@ define([ 'tabindex': '-1', 'data-icon': AppConfig.applicationsIcon.link, 'data-type': 'link' - }, Messages.fm_link)), + }, Messages.fm_link_new)), ]), ]), $separator.clone()[0], @@ -1932,7 +1932,7 @@ define([ $element.attr('title', name); } - var type = Messages.fm_link; // XXX new translation key ("Link") + var type = Messages.fm_link_type; var $type = $('', { 'class': 'cp-app-drive-element-type cp-app-drive-element-list' }).text(type); @@ -2738,8 +2738,8 @@ define([ }; var showLinkModal = function () { Messages.fm_link_name = "Link name"; // XXX - Messages.fm_link_url = "URL"; - Messages.fm_link_warning = "Warning: URL size..."; + Messages.fm_link_url = "URL"; // XXX + Messages.fm_link_warning = "Warning: URL size..."; // XXX var name, url; var warning = h('div.alert.alert-warning', [ h('i.fa.fa-exclamation-triangle'), @@ -2869,7 +2869,7 @@ define([ options.push({ tag: 'a', attributes: {'class': 'cp-app-drive-new-link'}, - content: $('
    ').append(getIcon('link')).html() + Messages.fm_link + content: $('
    ').append(getIcon('link')).html() + Messages.fm_link_new }); options.push({tag: 'hr'}); } @@ -3194,7 +3194,7 @@ define([ 'cp-app-drive-element-grid' }).prepend(getIcon('link')).appendTo($container); $elementLink.append($('', {'class': 'cp-app-drive-new-name'}) - .text(Messages.fm_link)); + .text(Messages.fm_link_type)); } // Pads getNewPadTypes().forEach(function (type) { From e3150f12848ded2c83990b30c76bddecba8d030f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Benqu=C3=A9?= Date: Mon, 26 Jul 2021 14:28:55 +0100 Subject: [PATCH 37/49] Add margin above anonymous name field --- www/form/app-form.less | 1 + 1 file changed, 1 insertion(+) diff --git a/www/form/app-form.less b/www/form/app-form.less index b037efac2..41ef8ba98 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -248,6 +248,7 @@ text-align: center; margin: 20px 0 30px 0; .cp-form-anon-answer-input { + margin-top: 20px; display: flex; white-space: nowrap; align-items: center; From 126a3fff46fe690b71eddba5c58f22b5a3eade1e Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 19:56:11 +0530 Subject: [PATCH 38/49] remove hardcoded translations and rework link name placeholder behaviour --- www/common/drive-ui.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 12c4431c8..21a2337a7 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -42,9 +42,6 @@ define([ Pages) { - Messages.fm_link_new = "New Link"; // XXX - Messages.fm_link_type = "Link"; // XXX - var APP = window.APP = { editable: false, online: false, @@ -2737,21 +2734,23 @@ define([ $input.click(); }; var showLinkModal = function () { - Messages.fm_link_name = "Link name"; // XXX - Messages.fm_link_url = "URL"; // XXX - Messages.fm_link_warning = "Warning: URL size..."; // XXX var name, url; var warning = h('div.alert.alert-warning', [ h('i.fa.fa-exclamation-triangle'), h('span', Messages.fm_link_warning) ]); var content = h('p', [ - warning, h('label', {for: 'cp-app-drive-link-name'}, Messages.fm_link_name), - name = h('input#cp-app-drive-link-name', { autocomplete: 'off' }), + name = h('input#cp-app-drive-link-name', { autocomplete: 'off', placeholder: Messages.fm_link_name_placeholder }), h('label', {for: 'cp-app-drive-link-url'}, Messages.fm_link_url), - url = h('input#cp-app-drive-link-url', { type: 'url', autocomplete: 'off' }) + url = h('input#cp-app-drive-link-url', { type: 'url', autocomplete: 'off', placeholder: Messages.form_input_ph_url }), + warning, ]); + var setNamePlaceholder = function (val) { + val = val.replace(/https*:\/\//, '').replace(/#.*$/, '').slice(0, 16); + name.setAttribute('placeholder', val) + }; + var $warning = $(warning).hide(); var $url = $(url).on('change keypress keyup keydown', function () { var v = $url.val().trim(); @@ -2759,6 +2758,7 @@ define([ $warning.show(); return; } + setNamePlaceholder(v); $warning.hide(); }); var buttons = [{ @@ -2773,7 +2773,8 @@ define([ iconClass: '.fa.fa-plus', name: Messages.tag_add, onClick: function () { - var n = $(name).val().trim(); + var $name = $(name); + var n = $name.val().trim() || $name.attr('placeholder'); var u = $url.val().trim(); if (!n || !u) { return true; } if (!Util.isValidURL(u)) { From 4e900b18cf5c57060ea8ae996161690d7d1ab25d Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 26 Jul 2021 19:56:49 +0530 Subject: [PATCH 39/49] use more specific 'export to CSV' translation in forms --- www/form/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/form/inner.js b/www/form/inner.js index b3db8ce79..2a04eedd2 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -1774,7 +1774,7 @@ define([ var controls = h('div.cp-form-creator-results-controls'); var $controls = $(controls).appendTo($container); - var exportButton = h('button.btn.btn-secondary', Messages.exportButton); // XXX form_exportCSV; + var exportButton = h('button.btn.btn-secondary', Messages.form_exportCSV); var exportCSV = h('div.cp-form-creator-results-export', exportButton); $(exportCSV).appendTo($container); var results = h('div.cp-form-creator-results-content'); From 4f5a04101050e43a9a7c167805a72eabddc1158d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Benqu=C3=A9?= Date: Mon, 26 Jul 2021 15:26:51 +0100 Subject: [PATCH 40/49] Style username in poll results table --- www/form/app-form.less | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index 41ef8ba98..1354cacca 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -681,7 +681,11 @@ &.cp-clickable { cursor: pointer; &:hover { - transform: scale(1.1); + color: @cryptpad_color_link; + &::after { + font-family: FontAwesome; + content: "\00a0\f06e"; + } } } } From 04a616f87d43f85e7cd1347565476a770446f158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Benqu=C3=A9?= Date: Mon, 26 Jul 2021 15:38:21 +0100 Subject: [PATCH 41/49] Add margin to individual response list - prevents response title to be mixed up with first question --- www/form/app-form.less | 1 + 1 file changed, 1 insertion(+) diff --git a/www/form/app-form.less b/www/form/app-form.less index 1354cacca..60da1daff 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -548,6 +548,7 @@ .cp-form-individual { background: @cp_form-bg1; padding: 10px; + margin-bottom: 20px; & > *:not(:last-child) { margin-right: 10px; } From 854a635c5f8abda45b415828d42888bdb6b929f7 Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 03:40:03 +0530 Subject: [PATCH 42/49] remove hardcoded translations and defer non-blocking issues till the next release --- lib/env.js | 2 +- www/common/common-ui-elements.js | 16 ++++++++++++---- www/common/drive-ui.js | 3 +-- www/common/inner/share.js | 1 - www/common/notifications.js | 2 -- www/common/outer/cache-store.js | 2 +- www/convert/inner.js | 4 ++-- www/form/inner.js | 2 -- www/form/main.js | 2 +- 9 files changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/env.js b/lib/env.js index 3d58f11f7..4db282d77 100644 --- a/lib/env.js +++ b/lib/env.js @@ -123,7 +123,7 @@ module.exports.create = function (config) { maxWorkers: config.maxWorkers, disableIntegratedTasks: config.disableIntegratedTasks || false, - disableIntegratedEviction: typeof(config.disableIntegratedEviction) === 'undefined'? true: config.disableIntegratedEviction, // XXX false, + disableIntegratedEviction: typeof(config.disableIntegratedEviction) === 'undefined'? true: config.disableIntegratedEviction, // XXX 4.10.0 false, lastEviction: +new Date(), evictionReport: {}, commandTimers: {}, diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 8b01ad652..eba151551 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -3034,9 +3034,18 @@ define([ var name = Util.fixHTML(data.title); var url = data.href; var user = data.name; - Messages.notification_openLink = "You've received a link {0} from {1}:"; // XXX - Messages.link_open = "Open URL"; - Messages.link_store = "Store link in drive"; + //Messages.link_open = "Open URL"; + // openLinkInNewTab ("Open Link in New Tab") + // fc_open ("Open") + // share_linkOpen ("Preview") + // resources_openInNewTab ("Open it in a new tab") + Messages.link_open = Messages.fc_open; // XXX 4.10.0 + + //Messages.link_store = "Store link in drive"; + // toolbar_storeInDrive ? ("Store in CryptDrive") + // autostore_store ? ("Store") + Messages.link_store = Messages.toolbar_storeInDrive; // XXX 4.10.0 + var content = h('div', [ UI.setHTML(h('p'), Messages._getKey('notification_openLink', [name, user])), @@ -3069,7 +3078,6 @@ define([ onClick: function () { if (clicked) { return; } clicked = true; - // XXX feedback common.getSframeChannel().query("Q_DRIVE_USEROBJECT", { cmd: "addLink", data: { diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 21a2337a7..78618f7ed 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1940,7 +1940,6 @@ define([ 'class': 'cp-app-drive-element-ctime cp-app-drive-element-list' }).text(getDate(data.ctime)); $element.append($type).append($adate).append($cdate); - // XXX feedback }; var _addOwnership = function ($span, $state, data) { if (data && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1) { @@ -2778,7 +2777,7 @@ define([ var u = $url.val().trim(); if (!n || !u) { return true; } if (!Util.isValidURL(u)) { - // XXX add style for invalid input? input:invalid + // XXX 4.10.0 add style for invalid input? input:invalid UI.warn(Messages.error); return true; } diff --git a/www/common/inner/share.js b/www/common/inner/share.js index 125dcb5e2..5225ea818 100644 --- a/www/common/inner/share.js +++ b/www/common/inner/share.js @@ -111,7 +111,6 @@ define([ if (mailbox) { // Friend if (friends[curve] && !mailbox.notifications) { return; } if (mailbox.notifications && mailbox.curvePublic) { - // XXX feedback common.mailbox.sendTo("SHARE_PAD", { href: href, isStatic: Boolean(config.static), diff --git a/www/common/notifications.js b/www/common/notifications.js index 78c29b90f..83052ff68 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -92,7 +92,6 @@ define([ (type === 'file' ? 'notification_fileShared' : // Msg.notification_fileSharedTeam 'notification_padShared'); // Msg.notification_padSharedTeam - Messages.notification_linkShared = "{0} has shared a link with you: {1}"; // XXX if (msg.content.isStatic) { key = 'notification_linkShared'; // Msg.notification_linkShared; } @@ -115,7 +114,6 @@ define([ }; content.handler = function() { if (msg.content.isStatic) { - // XXX feedback UIElements.displayOpenLinkModal(common, { curve: msg.author, href: msg.content.href, diff --git a/www/common/outer/cache-store.js b/www/common/outer/cache-store.js index 514e18ab7..93bc0d0c6 100644 --- a/www/common/outer/cache-store.js +++ b/www/common/outer/cache-store.js @@ -97,7 +97,7 @@ define([ var checkCheckpoints = function (array) { if (!Array.isArray(array)) { return; } // Keep the last 100 messages - if (array.length > 100) { // XXX + if (array.length > 100) { // XXX 4.10.0 array.splice(0, array.length - 100); } // Remove every message before the first checkpoint diff --git a/www/convert/inner.js b/www/convert/inner.js index cdcf745ca..ba9870ccf 100644 --- a/www/convert/inner.js +++ b/www/convert/inner.js @@ -192,8 +192,8 @@ define([ }, }; - Messages.convertPage = "Convert"; // XXX - Messages.convert_hint = "Pick the file you want to convert. The list of output format will be visible afterward."; // XXX + Messages.convertPage = "Convert"; // XXX 4.10.0 + Messages.convert_hint = "Pick the file you want to convert. The list of output format will be visible afterward."; // XXX 4.10.0 var createToolbar = function () { var displayed = ['useradmin', 'newpad', 'limit', 'pageTitle', 'notifications']; diff --git a/www/form/inner.js b/www/form/inner.js index 2a04eedd2..1b555be5d 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -1970,8 +1970,6 @@ define([ $(cbox).hide().find('input').attr('disabled', 'disabled').prop('checked', false); } } else { - Messages.form_anonName = "Your username"; // XXX - Messages.form_answerAs = "Answer as"; // XXX anonName = h('div.cp-form-anon-answer-input', [ Messages.form_answerAs, h('input', { diff --git a/www/form/main.js b/www/form/main.js index b25a4b21a..de2c311ef 100644 --- a/www/form/main.js +++ b/www/form/main.js @@ -176,7 +176,7 @@ define([ validateKey: keys.secondaryValidateKey, owners: [myKeys.edPublic], crypto: crypto, - //Cache: Utils.Cache // XXX + //Cache: Utils.Cache // XXX 4.10.0 }; var results = {}; config.onError = function (info) { From 9c373377cfa44fe428c8a4f351930166475afcb8 Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 03:40:48 +0530 Subject: [PATCH 43/49] send feedback for UI related to the new link functionality --- www/common/common-ui-elements.js | 5 +++-- www/common/drive-ui.js | 2 +- www/common/inner/share.js | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index eba151551..99d506347 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -3057,19 +3057,19 @@ define([ var buttons = [{ name: Messages.friendRequest_later, onClick: function () { - // XXX feedback if (clicked) { return true; } clicked = true; + Feedback.send('LINK_RECEIVED_LATER'); }, keys: [27] }, { className: 'primary', name: Messages.link_open, onClick: function () { - // XXX feedback if (clicked) { return true; } clicked = true; common.openUnsafeURL(url); + Feedback.send("LINK_RECEIVED_OPEN"); }, keys: [13] }, { @@ -3088,6 +3088,7 @@ define([ }, function () { modal.closeModal(); dismiss(); + Feedback.send("LINK_RECEIVED_STORE"); }); return true; }, diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 78618f7ed..82cabec8f 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -2785,7 +2785,7 @@ define([ name: n, url: u }, refresh); - // XXX feedback + Feedback.send("LINK_CREATED"); }, keys: [13] }); diff --git a/www/common/inner/share.js b/www/common/inner/share.js index 5225ea818..4bcf0d621 100644 --- a/www/common/inner/share.js +++ b/www/common/inner/share.js @@ -124,6 +124,9 @@ define([ channel: mailbox.notifications, curvePublic: mailbox.curvePublic }); + if (config.static) { + Feedback.send("LINK_SHARED_WITH_CONTACT"); + } return; } } @@ -154,6 +157,7 @@ define([ }, function () { UI.log(Messages.saved); }); + Feedback.send("LINK_ADDED_TO_DRIVE"); return; } sframeChan.query('Q_STORE_IN_TEAM', { From 3eb2e77ed8f72e2b870f8e9a1f00c573650a15b5 Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 05:16:52 +0530 Subject: [PATCH 44/49] update changelog --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dd823202..3c5ca97fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,9 +20,28 @@ * unregistered users can set their username when they don't want to answer anonymously * improve CSV export with polls * decrement max choices when it exceeds the number of available options + * render form results if possible when the form is closed and you have answered + * shuffle form options to limit bias in results * remove unused images * drive * show the bread-crumb and disable the tree in anon drives +* checkup + * http:// for safe/unsafe origin is now an error unless used for an onion or localhost + * and only if you are accessing the test via localhost.. to catch all those instances using localhost on prod config +* feedback keys + * `LINK_RECEIVED_LATER` + * `LINK_RECEIVED_OPEN` + * `LINK_RECEIVED_STORE` + * `LINK_CREATED` + * `LINK_SHARED_WITH_CONTACT` + * `LINK_ADDED_TO_DRIVE` + * `BURN_AFTER_READING` +* teams + * guard against a typeError when initializing +* general + * don't try to pin channels with invalid lengths + * slight optimization when initializing your drive + * Lithuanian translation in progress # 4.8.0 From 921da962d0d22b0dd3280afa92ad324b45a33b65 Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 05:18:39 +0530 Subject: [PATCH 45/49] narrow exceptions for use of localhost in checkup --- www/checkup/main.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/checkup/main.js b/www/checkup/main.js index 93ead1bbc..90c16a29a 100644 --- a/www/checkup/main.js +++ b/www/checkup/main.js @@ -705,9 +705,13 @@ define([ var isOnion = function (host) { return /\.onion$/.test(host); }; + var isLocalhost = function (host) { + return /^http:\/\/localhost/.test(host); + }; + assert(function (cb, msg) { // provide an exception for development instances - if (/http:\/\/localhost/.test(trimmedUnsafe)) { return void cb(true); } + if (isLocalhost(trimmedUnsafe) && isLocalhost(window.location.href)) { return void cb(true); } // if both the main and sandbox domains are onion addresses // then the HTTPS requirement is unnecessary From 45b58d622d47b60b8787a10d8be83716ae97e09a Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 05:19:35 +0530 Subject: [PATCH 46/49] rewrite a switch statement as a concise lookup table --- www/common/proxy-manager.js | 51 ++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 78196cf7c..d6492c68c 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -1045,39 +1045,32 @@ define([ Env.onSync(cb); }; + var COMMANDS = { + move: _move, + restore: _restore, + addFolder: _addFolder, + addSharedFolder: _addSharedFolder, + addLink: _addLink, + restoreSharedFolder: _restoreSharedFolder, + convertFolderToSharedFolder: _convertFolderToSharedFolder, + delete: _delete, + deleteOwned: _deleteOwned, + emptyTrash: _emptyTrash, + rename: _rename, + setFolderData: _setFolderData, + updateStaticAccess: _updateStaticAccess, + }; + var onCommand = function (Env, cmdData, cb) { var cmd = cmdData.cmd; var data = cmdData.data || {}; - switch (cmd) { - case 'move': - _move(Env, data, cb); break; - case 'restore': - _restore(Env, data, cb); break; - case 'addFolder': - _addFolder(Env, data, cb); break; - case 'addSharedFolder': - _addSharedFolder(Env, data, cb); break; - case 'addLink': - _addLink(Env, data, cb); break; - case 'restoreSharedFolder': - _restoreSharedFolder(Env, data, cb); break; - case 'convertFolderToSharedFolder': - _convertFolderToSharedFolder(Env, data, cb); break; - case 'delete': - _delete(Env, data, cb); break; - case 'deleteOwned': - _deleteOwned(Env, data, cb); break; - case 'emptyTrash': - _emptyTrash(Env, data, cb); break; - case 'rename': - _rename(Env, data, cb); break; - case 'setFolderData': - _setFolderData(Env, data, cb); break; - case 'updateStaticAccess': - _updateStaticAccess(Env, data, cb); break; - default: - cb(); + var method = COMMANDS[cmd]; + + if (typeof(method) === 'function') { + return void method(Env, data, cb); } + // if the command was not handled then call back + cb(); }; // Set the value everywhere the given pad is stored (main and shared folders) From 32027f09d6c4b89398ea6d965cda5906255b2703 Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 05:21:05 +0530 Subject: [PATCH 47/49] refine link name placeholder suggestion and provide a more descriptive error message --- www/common/drive-ui.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 82cabec8f..15558cf18 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -2745,9 +2745,15 @@ define([ url = h('input#cp-app-drive-link-url', { type: 'url', autocomplete: 'off', placeholder: Messages.form_input_ph_url }), warning, ]); + + var protocolPattern = /https*:\/\//; + var fragmentPattern = /#.*$/; var setNamePlaceholder = function (val) { - val = val.replace(/https*:\/\//, '').replace(/#.*$/, '').slice(0, 16); - name.setAttribute('placeholder', val) + var temp = val.replace(protocolPattern, '').replace(fragmentPattern, '').trim().slice(0, 48); + if (!protocolPattern.test(val) || !temp) { + temp = Messages.fm_link_name_placeholder; + } + name.setAttribute('placeholder', temp); }; var $warning = $(warning).hide(); @@ -2778,7 +2784,7 @@ define([ if (!n || !u) { return true; } if (!Util.isValidURL(u)) { // XXX 4.10.0 add style for invalid input? input:invalid - UI.warn(Messages.error); + UI.warn(Messages.fm_link_invalid); return true; } manager.addLink(currentPath, { From 7916f36007e1079846a503fc0da63626b64294a5 Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 05:27:05 +0530 Subject: [PATCH 48/49] update version string to 4.9.0 --- customize.dist/pages.js | 2 +- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/customize.dist/pages.js b/customize.dist/pages.js index 18632f6ea..18d65c680 100644 --- a/customize.dist/pages.js +++ b/customize.dist/pages.js @@ -105,7 +105,7 @@ define([ var imprintUrl = AppConfig.imprint && (typeof(AppConfig.imprint) === "boolean" ? '/imprint.html' : AppConfig.imprint); - Pages.versionString = "v4.8.0"; + Pages.versionString = "v4.9.0"; // used for the about menu diff --git a/package-lock.json b/package-lock.json index 4d7992f82..42136e238 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cryptpad", - "version": "4.8.0", + "version": "4.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9e18f05f0..68a315891 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cryptpad", "description": "realtime collaborative visual editor with zero knowlege server", - "version": "4.8.0", + "version": "4.9.0", "license": "AGPL-3.0+", "repository": { "type": "git", From 673ed629d662b5f6ed6628e3ace140e99bddb866 Mon Sep 17 00:00:00 2001 From: ansuz Date: Tue, 27 Jul 2021 17:14:53 +0530 Subject: [PATCH 49/49] update changelog for 4.9.0 --- CHANGELOG.md | 84 +++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c5ca97fa..26dc534d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,47 +1,45 @@ -# WIP +# 4.9.0 -* links - * create links in your drive or a team drive - * share with contacts - * when you receive a link, you can "open", "store", "decide later" or dismiss from the notification dropdown - * share with a team (the link is instantly added to the team) - * store in your own drive from your team drive - * embed a link into a pad - * And you can have multiple links to the same target in one drive -* tabs in ckeditor -* fix recognition of premium user tickets in the admin support panel -* forms - * disable usage of the indexedDB cache for form results - * handle empty messages - * fix initial title with form templates - * style improvements - * guard against a typeError with dates - * in the responses page you can click on a user in the polls to get this user's answers to the other questions - * unregistered users can set their username when they don't want to answer anonymously - * improve CSV export with polls - * decrement max choices when it exceeds the number of available options - * render form results if possible when the form is closed and you have answered - * shuffle form options to limit bias in results -* remove unused images -* drive - * show the bread-crumb and disable the tree in anon drives -* checkup - * http:// for safe/unsafe origin is now an error unless used for an onion or localhost - * and only if you are accessing the test via localhost.. to catch all those instances using localhost on prod config -* feedback keys - * `LINK_RECEIVED_LATER` - * `LINK_RECEIVED_OPEN` - * `LINK_RECEIVED_STORE` - * `LINK_CREATED` - * `LINK_SHARED_WITH_CONTACT` - * `LINK_ADDED_TO_DRIVE` - * `BURN_AFTER_READING` -* teams - * guard against a typeError when initializing -* general - * don't try to pin channels with invalid lengths - * slight optimization when initializing your drive - * Lithuanian translation in progress +## Goals and announcements + +We allocated most of this release cycle towards a schedule of one-on-one user interviews and some broad usage studies leveraging our new Form app. The remainder of our time was spent on some minor improvements. We'll continue at a slightly slower pace of implementation for the coming weeks while we complete our scheduled interviews and take some much-needed vacations. + +## Update notes + +It appears our promotion of the checkup page through our recent release notes and the inclusion of a link to it from the instance admin have been moderately successful. We've observed that more instance admins are noticing and fixing some common configuration issues. + +This release features some minor changes to one instance configuration test which incorrectly provided an exemption for the use of `http://localhost:3000` as an `httpUnsafeOrigin` value. This exemption was provided because it's valid for local development, however, it suppressed errors when this configuration was used for production instances where it could cause a variety of problems. As usual, we recommend checking your instance's admin page after updating to confirm that you are passing the latest tests. Information about the checkup page is included in [our documentation](https://docs.cryptpad.fr/en/admin_guide/admin_panel.html#network). + +To update from 4.8.0 to 4.9.0: + +1. Stop your server +2. Get the latest code with git +3. Install the latest dependencies with `bower update` and `npm i` +4. Restart your server +5. Confirm that your instance is passing all the tests included on the `/checkup/` page + +## Features + +* We've added the ability to store URLs in user and team drives as requested in a private support ticket and [this issue](https://github.com/xwiki-labs/cryptpad/issues/732). Links can be shared directly with contacts. Unlike pads, links are not collaborative objects, so updating a link's name will not update the entry in another user's drive if you've already shared it with them. Links are integrated into our apps' _insert_ menu to facilitate quick insertion of links you've stored into your documents. We're interested in measuring how this functionality is used in practice so we can decide whether it's worth spending more time on it, so we've added some telemetry to measure (in aggregate) how often its components are used. We anonymize IP addresses in the logs for CryptPad.fr, but as always, you can disable telemetry via your settings panel. +* Our rich text editor now supports indentation with the tab key, as per [this ticket](https://github.com/xwiki-labs/cryptpad/issues/634). +* Forms received another round of improvements to styles, workflows, and some basic survey functionality to yield more accurate results. + * Ordered lists are now shuffled for each survey participant so that their initial order has less effect on the final results. + * CSV export now uses a layout that makes poll options easier to read. + * Unregistered users can now add a name to their response. + * Form results are displayed automatically (when available) to those who have answered. + * Authors and auditors can now click on some types of answers to jump directly to other answers from the same user. +* Users with very large drives might notice that their account loads slightly faster now, due to some minor optimizations in an integrity check that the client performs when loading accounts. + +## Bugs + +* We've added a guard against a type error that could be triggered when loading teams under certain rare conditions. +* Unregistered users' drives now show the "bread-crumb" UI for navigating between folders when viewing a shared folder in read-only mode. We've also suppressed the "Files" button for displaying the tree view which was non-functional for such users. +* A change in the format of support tickets caused tickets recently created by premium users to not be recognized as such. We've fixed the categorization in the admin panel's support ticket view. +* We've fixed a number of minor issues with forms: + * The maximum number of selectable choices for checkbox questions can no longer exceed the number of available choices. + * We guard against a type error that could occur when parsing dates. + * Forms imported from templates now have their initial title corrected. + * We've disabled the use of our indexedDB caching system for form results, since it was quietly dropping older responses when more than 100 responses had been submitted. We plan to re-enable caching for results once we've updated the eviction metric to better handle the response format. # 4.8.0