From 7970f5026bac74817cd6b1f2246e716ae9045d83 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 14 May 2020 18:53:14 -0400 Subject: [PATCH 01/28] add support for displaying languages that administrators understand on the support panel --- customize.dist/application_config.js | 2 ++ www/support/inner.js | 29 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/customize.dist/application_config.js b/customize.dist/application_config.js index a7ad90f11..0187cf74b 100644 --- a/customize.dist/application_config.js +++ b/customize.dist/application_config.js @@ -9,5 +9,7 @@ define(['/common/application_config_internal.js'], function (AppConfig) { // Example: If you want to remove the survey link in the menu: // AppConfig.surveyURL = ""; + AppConfig.supportLanguages = [ 'en', 'fr' ]; // XXX + return AppConfig; }); diff --git a/www/support/inner.js b/www/support/inner.js index 701d01817..48bb1c4ef 100644 --- a/www/support/inner.js +++ b/www/support/inner.js @@ -11,6 +11,7 @@ define([ '/common/hyperscript.js', '/support/ui.js', '/api/config', + '/customize/application_config.js', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css', @@ -27,7 +28,8 @@ define([ Messages, h, Support, - ApiConfig + ApiConfig, + AppConfig ) { var APP = window.APP = {}; @@ -41,6 +43,7 @@ define([ 'cp-support-list', ], 'new': [ + 'cp-support-language', 'cp-support-form', ], }; @@ -132,6 +135,30 @@ define([ return $div; }; + create['language'] = function () { + if (!Array.isArray(AppConfig.supportLanguages)) { return $(h('div')); } + var languages = AppConfig.supportLanguages; + + var list = h('li', languages + .map(function (lang) { + return Messages._languages[lang]; + }) + .filter(Boolean) + .map(function (lang) { + return h('li', lang); + }) + ); + + var preamble = "This server's administrators speak the following languages:"; // XXX + var $div = $( + h('div.cp-support-language', [ + preamble, + list, + ]) + ); + return $div; + }; + // Create a new tickets create['form'] = function () { var key = 'form'; From 21d3108ad5ba0524466d786c5817596e22c78227 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 3 Jun 2020 16:26:59 +0200 Subject: [PATCH 02/28] Add missing tippy --- www/common/common-ui-elements.js | 1 + www/drive/inner.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 0caa39c92..278e8dda8 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -1658,6 +1658,7 @@ define([ var drawerCls = data.drawer === false ? '' : '.cp-toolbar-drawer-element'; var icon = data.icon || "fa-question"; button = $(h('button', { + title: data.tippy || '' //title: data.title || '', }, [ h('i.fa.' + icon), diff --git a/www/drive/inner.js b/www/drive/inner.js index a3caf7e84..5a7b86687 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -255,7 +255,7 @@ define([ text: '', name: 'burn-anon-drive', icon: 'fa-ban', - title: Messages.fm_burnThisDriveButton, + tippy: Messages.fm_burnThisDriveButton, drawer: false }).click(function () { UI.confirm(Messages.fm_burnThisDrive, function (yes) { From 33818cdc933f3cb44454bd6e8a08d9c3ebd48d85 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 3 Jun 2020 16:41:53 +0200 Subject: [PATCH 03/28] Fix 'empty drive' button in anon drives --- www/drive/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/drive/inner.js b/www/drive/inner.js index 5a7b86687..d5380b8d0 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -257,7 +257,7 @@ define([ icon: 'fa-ban', tippy: Messages.fm_burnThisDriveButton, drawer: false - }).click(function () { + }, function () { UI.confirm(Messages.fm_burnThisDrive, function (yes) { if (!yes) { return; } common.getSframeChannel().event('EV_BURN_ANON_DRIVE'); From 4dbcff2578ef9cae52b462b23dda01d3c3e124eb Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 3 Jun 2020 13:30:41 -0400 Subject: [PATCH 04/28] redirect anon users to login from support --- www/common/application_config_internal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/application_config_internal.js b/www/common/application_config_internal.js index 61a114a68..50249baa8 100644 --- a/www/common/application_config_internal.js +++ b/www/common/application_config_internal.js @@ -20,7 +20,7 @@ define(function() { * users and these users will be redirected to the login page if they still try to access * the app */ - config.registeredOnlyTypes = ['file', 'contacts', 'oodoc', 'ooslide', 'notifications']; + config.registeredOnlyTypes = ['file', 'contacts', 'oodoc', 'ooslide', 'notifications', 'support']; /* CryptPad is available is multiple languages, but only English and French are maintained * by the developers. The other languages may be outdated, and any missing string for a langauge From ad8c57031beb9f75cc1c475a5fa7dac1f11108e3 Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 3 Jun 2020 15:08:51 -0400 Subject: [PATCH 05/28] update markedjs from 0.5.0 to 1.1.0 --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 3ad7d88d2..9fd787c20 100644 --- a/bower.json +++ b/bower.json @@ -24,7 +24,7 @@ "ckeditor": "4.14.0", "codemirror": "^5.19.0", "requirejs": "2.3.5", - "marked": "0.5.0", + "marked": "1.1.0", "rangy": "rangy-release#~1.3.0", "json.sortify": "~2.1.0", "secure-fabric.js": "secure-v1.7.9", From fa16ce209454fc1dd160e0d18044335684210e2d Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 3 Jun 2020 15:42:16 -0400 Subject: [PATCH 06/28] disallow changing media-tag's attributes while in read-only mode --- www/pad/mediatag-plugin-dialog.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/www/pad/mediatag-plugin-dialog.js b/www/pad/mediatag-plugin-dialog.js index 472525edd..44503af9b 100644 --- a/www/pad/mediatag-plugin-dialog.js +++ b/www/pad/mediatag-plugin-dialog.js @@ -1,5 +1,19 @@ CKEDITOR.dialog.add('mediatag', function (editor) { var Messages = CKEDITOR._mediatagTranslations; + var isReadOnly = function (el) { + if (!el) { return; } + var parent = el; + while (parent) { + if (parent.nodeName.toUpperCase() === 'BODY') { + // I'm not sure why "false" is a string and not a boolean here + // but that's how it is and I'm scared to touch it + // --ansuz + return parent.getAttribute("contenteditable") === 'false'; + } + parent = parent.parentElement; + } + }; + return { title: Messages.title, minWidth: 400, @@ -118,6 +132,14 @@ CKEDITOR.dialog.add('mediatag', function (editor) { update(); }); + // disable all of the dialog's inputs if it is opened while in read-only mode + if (isReadOnly(element && element.$)) { + Array.prototype.slice.call(inputs).forEach(function (node) { + node.setAttribute('disabled', true); + }); + return; + } + setTimeout(update); }, onOk: function() { From 04fe289bf82665875b5f0229cbc0e040c49a4f87 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 4 Jun 2020 11:13:08 +0200 Subject: [PATCH 07/28] Fix some mermaid graphs and update default colors --- www/slide/app-slide.less | 8 ++++++++ www/slide/inner.js | 12 ++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/www/slide/app-slide.less b/www/slide/app-slide.less index 9fe6f7ebb..6cf4915ab 100644 --- a/www/slide/app-slide.less +++ b/www/slide/app-slide.less @@ -331,6 +331,14 @@ line-height: 1em; } } + svg { + * { + max-width: unset; + max-height: unset; + font-size: unset; + line-height: unset; + } + } ul, ol { ul, ol { margin: 0; diff --git a/www/slide/inner.js b/www/slide/inner.js index ad4308af2..8dcbe0654 100644 --- a/www/slide/inner.js +++ b/www/slide/inner.js @@ -403,6 +403,10 @@ define([ updateLocalColors(md.color, md.backColor); } }); + + return { + updateLocalColors: updateLocalColors + }; }; var mkFilePicker = function (framework, editor) { @@ -473,7 +477,7 @@ define([ mkThemeButton(framework); mkPrintButton(framework, editor, $content, $print); mkSlideOptionsButton(framework, slideOptions, $toolbarDrawer); - mkColorConfiguration(framework, $modal); + var colors = mkColorConfiguration(framework, $modal); mkFilePicker(framework, editor); mkSlidePreviewPane(framework, $contentContainer); @@ -518,9 +522,13 @@ define([ return CodeMirror.getHeadingText(); }); - framework.onReady(function (/*newPad*/) { + framework.onReady(function (newPad) { editor.focus(); + if (newPad) { + colors.updateLocalColors('#000', '#FFF'); + } + CodeMirror.setMode('markdown', function () { }); Slide.onChange(function (o, n, l) { var slideNumber = ''; From 03e6c8dacc91098f181c19f3a9778c941ddc0971 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 4 Jun 2020 11:47:15 +0200 Subject: [PATCH 08/28] Fix background image in slides --- www/common/inner/common-mediatag.js | 11 +++++++++++ www/common/sframe-common.js | 1 + www/slide/app-slide.less | 5 +++-- www/slide/inner.js | 25 +++++++++++-------------- www/slide/slide.js | 6 +++++- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/www/common/inner/common-mediatag.js b/www/common/inner/common-mediatag.js index 295d8b6b5..3c1f340af 100644 --- a/www/common/inner/common-mediatag.js +++ b/www/common/inner/common-mediatag.js @@ -26,6 +26,17 @@ define([ // Cache of the avatars outer html (including ) var avatars = {}; + MT.getMediaTag = function (common, data) { + var metadataMgr = common.getMetadataMgr(); + var privateDat = metadataMgr.getPrivateData(); + var origin = privateDat.fileHost || privateDat.origin; + var src = data.src = data.src.slice(0,1) === '/' ? origin + data.src : data.src; + return h('media-tag', { + src: src, + 'data-crypto-key': 'cryptpad:'+data.key + }); + }; + MT.getCursorAvatar = function (cursor) { var html = ''; html += (cursor.avatar && avatars[cursor.avatar]) || ''; diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 3d5df4f03..48e6782ef 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -106,6 +106,7 @@ define([ funcs.addMentions = callWithCommon(UIElements.addMentions); funcs.importMediaTagMenu = callWithCommon(MT.importMediaTagMenu); funcs.getMediaTagPreview = callWithCommon(MT.getMediaTagPreview); + funcs.getMediaTag = callWithCommon(MT.getMediaTag); // Thumb funcs.displayThumbnail = callWithCommon(Thumb.displayThumbnail); diff --git a/www/slide/app-slide.less b/www/slide/app-slide.less index 6cf4915ab..09abe9fb2 100644 --- a/www/slide/app-slide.less +++ b/www/slide/app-slide.less @@ -12,12 +12,13 @@ @color: @colortheme_slide-color ); + @slide-default-bg: #e3e3e3; + // body font-size: unset; display: flex; flex-flow: column; - @slide-default-bg: #000; .size (@n) { // font-size: @n * 1vmin; // line-height: @n * 1.1vmin; @@ -124,7 +125,7 @@ &> img { width: 50vw; height: 28.125vw; - max-height: ~"calc(100vh - 96px)"; + max-height: ~"calc(100vh - 96px)" !important; max-width: ~"calc(16 / 9 * (100vh - 96px))"; position: absolute; left: 0; diff --git a/www/slide/inner.js b/www/slide/inner.js index 8dcbe0654..f071ef2b9 100644 --- a/www/slide/inner.js +++ b/www/slide/inner.js @@ -130,7 +130,6 @@ define([ // Flag to check if a file from the filepicker is a mediatag for the slides or a background image var Background = { - isBackground: false }; var mkSlideOptionsButton = function (framework, slideOptions) { @@ -208,7 +207,6 @@ define([ style: 'font-size: 17px', id: 'cp-app-slide-options-bg' }).click(function () { - Background.isBackground = true; var pickerCfg = { types: ['file'], where: ['root'], @@ -216,7 +214,12 @@ define([ fileType: ['image/'] } }; - common.openFilePicker(pickerCfg); + common.openFilePicker(pickerCfg, function (data) { + if (data.type === 'file') { + data.mt = common.getMediaTag(data).outerHTML; + Background.todo(data); + } + }); }).text(Messages.printBackgroundButton).appendTo($p); } $p.append($('
')); @@ -330,7 +333,7 @@ define([ }); }; - var mkColorConfiguration = function (framework, $modal) { + var mkColorConfiguration = function (framework, $modal, slideOptions) { var textColor; var backColor; var metadataMgr = framework._.cpNfInner.metadataMgr; @@ -341,11 +344,13 @@ define([ $modal.css('color', text); $modal.css('border-color', text); $('#' + SLIDE_COLOR_ID).find('i').css('color', text); + slideOptions.textColor = text; } if (back) { backColor = back; - $modal.css('background-color', back); + //$modal.css('background-color', back); $('#' + SLIDE_BACKCOLOR_ID).find('i').css('color', back); + slideOptions.bgColor = back; } }; var updateLocalColors = function (text, back) { @@ -411,14 +416,6 @@ define([ var mkFilePicker = function (framework, editor) { framework.setMediaTagEmbedder(function (mt, data) { - if (Background.isBackground) { - if (data.type === 'file') { - data.mt = mt[0].outerHTML; - Background.todo(data); - } - Background.isBackground = false; - return; - } editor.replaceSelection($(mt)[0].outerHTML); }); }; @@ -477,7 +474,7 @@ define([ mkThemeButton(framework); mkPrintButton(framework, editor, $content, $print); mkSlideOptionsButton(framework, slideOptions, $toolbarDrawer); - var colors = mkColorConfiguration(framework, $modal); + var colors = mkColorConfiguration(framework, $modal, slideOptions); mkFilePicker(framework, editor); mkSlidePreviewPane(framework, $contentContainer); diff --git a/www/slide/slide.js b/www/slide/slide.js index 88ef757ac..64c0910d2 100644 --- a/www/slide/slide.js +++ b/www/slide/slide.js @@ -93,7 +93,11 @@ define([ if (options.background && options.background.mt) { mediatagBg = options.background.mt; } - var m = '' + mediatagBg + ''+DiffMd.render(c).replace(separatorReg, '' + mediatagBg + '')+''; + var bgColor = ''; + if (options.bgColor && !mediatagBg) { + bgColor = 'style="background-color:'+options.bgColor+';"'; + } + var m = '' + mediatagBg + ''+DiffMd.render(c).replace(separatorReg, '' + mediatagBg + '')+''; try { DiffMd.apply(m, $content, Common); } catch (e) { return console.error(e); } From 55c4345e9ecdf3c19cd24cc537c0468284a5fde9 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 4 Jun 2020 11:49:46 +0200 Subject: [PATCH 09/28] lint compliance --- www/slide/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/slide/inner.js b/www/slide/inner.js index f071ef2b9..b051724e2 100644 --- a/www/slide/inner.js +++ b/www/slide/inner.js @@ -415,7 +415,7 @@ define([ }; var mkFilePicker = function (framework, editor) { - framework.setMediaTagEmbedder(function (mt, data) { + framework.setMediaTagEmbedder(function (mt) { editor.replaceSelection($(mt)[0].outerHTML); }); }; From da400929a9090ddc699002c1e8a99a2d641b7c7d Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 4 Jun 2020 13:37:22 +0200 Subject: [PATCH 10/28] Fix print slides with mermaid --- customize.dist/src/less2/include/app-print.less | 1 - www/slide/app-slide.less | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/customize.dist/src/less2/include/app-print.less b/customize.dist/src/less2/include/app-print.less index 6ff8964eb..e4c344b20 100644 --- a/customize.dist/src/less2/include/app-print.less +++ b/customize.dist/src/less2/include/app-print.less @@ -21,7 +21,6 @@ } * { visibility: hidden; - height: auto; max-height: none; } .cp-app-slide-viewer #cp-app-slide-print { diff --git a/www/slide/app-slide.less b/www/slide/app-slide.less index 09abe9fb2..a1a27a7b0 100644 --- a/www/slide/app-slide.less +++ b/www/slide/app-slide.less @@ -164,6 +164,14 @@ #cp-app-slide-editor-container { display: none; } + #cp-app-slide-print { + .cp-app-slide-frame { + pre.mermaid > svg { + height: 100%; + width: 100%; + } + } + } } #cp-app-slide-print { position: relative; @@ -336,8 +344,8 @@ * { max-width: unset; max-height: unset; - font-size: unset; line-height: unset; + font-size: 87.5%; } } ul, ol { From a62ea391223e5d1b5e347899a0632b0b082c884c Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 5 Jun 2020 13:49:18 +0200 Subject: [PATCH 11/28] Fix colors and reload bugs in slides --- www/common/sframe-common-outer.js | 6 ++++++ www/slide/inner.js | 34 +++++++++++++++---------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 4c240a2ec..b5baf6301 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -1115,7 +1115,13 @@ define([ if (parsed.hashData) { currentPad.hash = parsed.hashData.getHash(opts); } // Rendered (maybe hidden) hash var hiddenParsed = Utils.Hash.parsePadUrl(window.location.href); + + // Update the hash in the address bar + var ohc = window.onhashchange; + window.onhashchange = function () {}; window.location.href = hiddenParsed.getUrl(opts); + window.onhashchange = ohc; + ohc({reset: true}); }); diff --git a/www/slide/inner.js b/www/slide/inner.js index b051724e2..71f25f4e7 100644 --- a/www/slide/inner.js +++ b/www/slide/inner.js @@ -348,7 +348,7 @@ define([ } if (back) { backColor = back; - //$modal.css('background-color', back); + $modal.find('.cp-app-slide-frame').css('background-color', back); $('#' + SLIDE_BACKCOLOR_ID).find('i').css('color', back); slideOptions.bgColor = back; } @@ -362,6 +362,10 @@ define([ framework.localChange(); }; + var $check = $("#cp-app-slide-colorpicker"); + var $backgroundPicker = $('', { type: 'color', value: backColor }) + .css({ display: 'none', }) + .on('change', function() { updateLocalColors(undefined, this.value); }); var $back = framework._.sfCommon.createButton(null, true, { icon: 'fa-square', text: Messages.slide_backCol, @@ -369,7 +373,14 @@ define([ hiddenReadOnly: true, name: 'background', id: SLIDE_BACKCOLOR_ID + }, function () { + $backgroundPicker.val(backColor); + $backgroundPicker.click(); }); + + var $foregroundPicker = $('', { type: 'color', value: textColor }) + .css({ display: 'none', }) + .on('change', function() { updateLocalColors(this.value, undefined); }); var $text = framework._.sfCommon.createButton(null, true, { icon: 'fa-i-cursor', text: Messages.slide_textCol, @@ -377,28 +388,15 @@ define([ hiddenReadOnly: true, name: 'color', id: SLIDE_COLOR_ID + }, function () { + $foregroundPicker.val(textColor); + $foregroundPicker.click(); }); var $testColor = $('', { type: 'color', value: '!' }); - var $check = $("#cp-app-slide-colorpicker"); if ($testColor.attr('type') !== "color" || $testColor.val() === '!') { return; } - var $backgroundPicker = $('', { type: 'color', value: backColor }) - .css({ display: 'none', }) - .on('change', function() { updateLocalColors(undefined, this.value); }); $check.append($backgroundPicker); - $back.on('click', function() { - $backgroundPicker.val(backColor); - $backgroundPicker.click(); - }); - - var $foregroundPicker = $('', { type: 'color', value: textColor }) - .css({ display: 'none', }) - .on('change', function() { updateLocalColors(this.value, undefined); }); $check.append($foregroundPicker); - $text.on('click', function() { - $foregroundPicker.val(textColor); - $foregroundPicker.click(); - }); framework._.toolbar.$theme.append($text).append($back); @@ -524,6 +522,8 @@ define([ if (newPad) { colors.updateLocalColors('#000', '#FFF'); + } else { + colors.updateLocalColors('#FFF', '#000'); } CodeMirror.setMode('markdown', function () { }); From 5d111c623755dca34251a8794dd11abf959ab719 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 5 Jun 2020 15:14:26 +0200 Subject: [PATCH 12/28] Update tags for multiple pads at once --- www/common/common-ui-elements.js | 63 ++++++++++++++++++++++++++------ www/common/drive-ui.js | 13 +++---- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 278e8dda8..70b0d25ed 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -46,28 +46,69 @@ define([ return mB + Messages.MB; }; - UIElements.updateTags = function (common, href) { + UIElements.updateTags = function (common, hrefs) { var existing, tags; + var allTags = {}; + if (!hrefs || typeof (hrefs) === "string") { + hrefs = [hrefs]; + } NThen(function(waitFor) { common.getSframeChannel().query("Q_GET_ALL_TAGS", null, waitFor(function(err, res) { if (err || res.error) { return void console.error(err || res.error); } existing = Object.keys(res.tags).sort(); })); }).nThen(function (waitFor) { - common.getPadAttribute('tags', waitFor(function (err, res) { - if (err) { - if (err === 'NO_ENTRY') { - UI.alert(Messages.tags_noentry); + var _err; + hrefs.forEach(function (href) { + common.getPadAttribute('tags', waitFor(function (err, res) { + if (err) { + if (err === 'NO_ENTRY') { + UI.alert(Messages.tags_noentry); + } + waitFor.abort(); + _err = err; + return void console.error(err); } - waitFor.abort(); - return void console.error(err); - } - tags = res || []; - }), href); + allTags[href] = res || []; + + if (tags) { + // Intersect with tags from previous pads + tags = (res || []).filter(function (tag) { + return tags.indexOf(tag) !== -1; + }); + } else { + tags = res || []; + } + }), href); + }); }).nThen(function () { UI.dialog.tagPrompt(tags, existing, function (newTags) { if (!Array.isArray(newTags)) { return; } - common.setPadAttribute('tags', newTags, null, href); + var added = []; + var removed = []; + newTags.forEach(function (tag) { + if (tags.indexOf(tag) === -1) { + added.push(tag); + } + }); + tags.forEach(function (tag) { + if (newTags.indexOf(tag) === -1) { + removed.push(tag); + } + }); + var update = function (oldTags) { + Array.prototype.push.apply(oldTags, added); + removed.forEach(function (tag) { + var idx = oldTags.indexOf(tag); + oldTags.splice(idx, 1); + }); + }; + + hrefs.forEach(function (href) { + var oldTags = allTags[href] || []; + update(oldTags); + common.setPadAttribute('tags', Util.deduplicateString(oldTags), null, href); + }); }); }); }; diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index a92e383d1..413b2624f 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1294,7 +1294,6 @@ define([ hide.push('properties', 'access'); hide.push('rename'); hide.push('openparent'); - hide.push('hashtag'); hide.push('download'); hide.push('share'); hide.push('savelocal'); @@ -4370,12 +4369,12 @@ define([ }); } else if ($this.hasClass("cp-app-drive-context-hashtag")) { - if (paths.length !== 1) { return; } - el = manager.find(paths[0].path); - data = manager.getFileData(el); - if (!data) { return void console.error("Expected to find a file"); } - var href = data.href || data.roHref; - common.updateTags(href); + var hrefs = paths.map(function (p) { + var el = manager.find(p.path); + var data = manager.getFileData(el); + return data.href || data.roHref; + }).filter(Boolean); + common.updateTags(hrefs); } else if ($this.hasClass("cp-app-drive-context-empty")) { if (paths.length !== 1 || !paths[0].element From c8f7c96cfc1527386d54a9dd1d2caf513edfc7da Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 5 Jun 2020 13:25:22 -0400 Subject: [PATCH 13/28] preserve formatting when displaying multi-line team invite messages --- www/teams/app-team.less | 1 + 1 file changed, 1 insertion(+) diff --git a/www/teams/app-team.less b/www/teams/app-team.less index eb49ec21f..c59d0dcb9 100644 --- a/www/teams/app-team.less +++ b/www/teams/app-team.less @@ -220,6 +220,7 @@ width: 100%; padding: 12px; margin-bottom: 20px; + white-space: pre; } .cp-teams-invite-password { margin-bottom: 20px; From 154a0b1e6e8ff0c6d4e82745df368a3f212815e8 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 5 Jun 2020 13:32:56 -0400 Subject: [PATCH 14/28] hide the drive's contextmenu when you hit escape --- www/common/drive-ui.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 413b2624f..8c8d7f5f1 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -526,6 +526,8 @@ define([ } }); }); + + return $(menu); }; @@ -919,6 +921,11 @@ define([ if (e.ctrlKey) { ev.ctrlKey = true; } if (e.shiftKey) { ev.shiftKey = true; } + // ESC + if (e.which === 27) { + return void APP.hideMenu(); + } + // Enter if (e.which === 13) { var $allSelected = $content.find('.cp-app-drive-element.cp-app-drive-element-selected'); From b419ead7fefdb2891f99dc915be19f3220041457 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 5 Jun 2020 14:25:24 -0400 Subject: [PATCH 15/28] implement more intuitive keyboard controls for the tag prompt --- www/common/common-interface.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 79951c3c5..6ddf0a320 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -377,6 +377,14 @@ define([ field.focus(); }); + var $field = field.tokenfield.closest('.tokenfield').find('.token-input'); + $field.on('keypress', function (e) { + if (!$field.val() && e.which === 13) { return void $ok.click(); } + }); + $field.on('keydown', function (e) { + if (!$field.val() && e.which === 27) { return void $cancel.click(); } + }); + return tagger; }; From 1ef79d44b4312f76148ec29d3e31b4b4e75f3d35 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 8 Jun 2020 11:47:09 -0400 Subject: [PATCH 16/28] display a disabled upload button to logged out users in the filepicker modal --- www/secureiframe/inner.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/www/secureiframe/inner.js b/www/secureiframe/inner.js index a42cd5e7a..1aa94d9cd 100644 --- a/www/secureiframe/inner.js +++ b/www/secureiframe/inner.js @@ -177,7 +177,7 @@ define([ }); // If file, display the upload button - if (types.indexOf('file') !== -1 && common.isLoggedIn()) { + if (types.indexOf('file') !== -1) { var f = (filters && filters.filter) || {}; delete data.accept; if (Array.isArray(f.fileType)) { @@ -188,7 +188,13 @@ define([ return val; }); } - $filter.append(common.createButton('upload', false, data)); + } + + var $uploadButton = common.createButton('upload', false, data); + $filter.append($uploadButton); + if (!common.isLoggedIn()) { + $uploadButton.prop('disabled', true) + .prop('title', Messages.upload_mustLogin); } var $container = $(h('span.cp-filepicker-content', [ From ce5bcc0022bc840fecb6e33d0b9c5275725f68cd Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 8 Jun 2020 11:57:05 -0400 Subject: [PATCH 17/28] add an XXX for the upload button's tooltip --- www/common/common-ui-elements.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 70b0d25ed..3a032b36f 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -1364,6 +1364,7 @@ define([ case 'import': button = $('