From 0dd343f2d40939900d12f8c42c5c7d4d6be97f63 Mon Sep 17 00:00:00 2001 From: Brian Underwood Date: Tue, 7 Feb 2023 21:48:57 +0100 Subject: [PATCH 001/378] Specs for the gallery component --- test/unit/specs/components/gallery.spec.js | 276 +++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 test/unit/specs/components/gallery.spec.js diff --git a/test/unit/specs/components/gallery.spec.js b/test/unit/specs/components/gallery.spec.js new file mode 100644 index 000000000..108e2b6bf --- /dev/null +++ b/test/unit/specs/components/gallery.spec.js @@ -0,0 +1,276 @@ +import Gallery from 'src/components/gallery/gallery.vue' + +describe.only('Gallery', () => { + let local + + it('attachments is falsey', () => { + local = { attachments: false } + expect(Gallery.computed.rows.call(local)).to.eql([]) + + local = { attachments: null } + expect(Gallery.computed.rows.call(local)).to.eql([]) + + local = { attachments: undefined } + expect(Gallery.computed.rows.call(local)).to.eql([]) + }) + + it('no attachments', () => { + local = { attachments: [] } + expect(Gallery.computed.rows.call(local)).to.eql([]) + }) + + it('one audio attachment', () => { + local = { + attachments: [ + { mimetype: 'audio/mpeg' } + ] + } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { audio: true, items: [{ mimetype: 'audio/mpeg' }] } + ]) + }) + + it('one image attachment', () => { + local = { + attachments: [ + { mimetype: 'image/png' } + ] + } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { items: [{ mimetype: 'image/png' }] } + ]) + }) + + it('one audio attachment and one image attachment', () => { + local = { + attachments: [ + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/png' } + ] + } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { audio: true, items: [{ mimetype: 'audio/mpeg' }] }, + { items: [{ mimetype: 'image/png' }] } + ]) + }) + + it('has "size" key set to "hide"', () => { + let local + local = { + attachments: [ + { mimetype: 'audio/mpeg' } + ], + size: 'hide' + } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { minimal: true, items: [{ mimetype: 'audio/mpeg' }] } + ]) + + local = { + attachments: [ + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/png' }, + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' } + ], + size: 'hide' + } + + // When defining `size: hide`, the `items` aren't + // grouped and `audio` isn't set + expect(Gallery.computed.rows.call(local)).to.eql([ + { minimal: true, items: [{ mimetype: 'image/jpg' }] }, + { minimal: true, items: [{ mimetype: 'image/png' }] }, + { minimal: true, items: [{ mimetype: 'image/jpg' }] }, + { minimal: true, items: [{ mimetype: 'audio/mpeg' }] }, + { minimal: true, items: [{ mimetype: 'image/png' }] }, + { minimal: true, items: [{ mimetype: 'audio/mpeg' }] }, + { minimal: true, items: [{ mimetype: 'image/jpg' }] }, + { minimal: true, items: [{ mimetype: 'image/png' }] }, + { minimal: true, items: [{ mimetype: 'image/jpg' }] } + ]) + }) + + // types other than image or audio should be `minimal` + it('non-image/audio', () => { + let local + local = { + attachments: [ + { mimetype: 'plain/text' } + ] + } + expect(Gallery.computed.rows.call(local)).to.eql([ + { minimal: true, items: [{ mimetype: 'plain/text' }] } + ]) + + // No grouping of non-image/audio items + local = { + attachments: [ + { mimetype: 'plain/text' }, + { mimetype: 'plain/text' }, + { mimetype: 'plain/text' } + ] + } + expect(Gallery.computed.rows.call(local)).to.eql([ + { minimal: true, items: [{ mimetype: 'plain/text' }] }, + { minimal: true, items: [{ mimetype: 'plain/text' }] }, + { minimal: true, items: [{ mimetype: 'plain/text' }] } + ]) + + local = { + attachments: [ + { mimetype: 'image/png' }, + { mimetype: 'plain/text' }, + { mimetype: 'image/jpg' }, + { mimetype: 'audio/mpeg' } + ] + } + // NOTE / TODO: When defining `size: hide`, the `items` aren't + // grouped and `audio` isn't set + expect(Gallery.computed.rows.call(local)).to.eql([ + { items: [{ mimetype: 'image/png' }] }, + { minimal: true, items: [{ mimetype: 'plain/text' }] }, + { items: [{ mimetype: 'image/jpg' }] }, + { audio: true, items: [{ mimetype: 'audio/mpeg' }] } + ]) + }) + + it('mixed attachments', () => { + local = { + attachments: [ + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/png' }, + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/jpg' } + ] + } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { audio: true, items: [{ mimetype: 'audio/mpeg' }] }, + { items: [{ mimetype: 'image/png' }] }, + { audio: true, items: [{ mimetype: 'audio/mpeg' }] }, + { items: [{ mimetype: 'image/jpg' }, { mimetype: 'image/png' }, { mimetype: 'image/jpg' }, { mimetype: 'image/jpg' }] } + ]) + + local = { + attachments: [ + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/jpg' }, + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/png' }, + { mimetype: 'audio/mpeg' } + ] + } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { items: [{ mimetype: 'image/jpg' }, { mimetype: 'image/png' }, { mimetype: 'image/jpg' }] }, + { items: [{ mimetype: 'image/jpg' }] }, + { audio: true, items: [{ mimetype: 'audio/mpeg' }] }, + { items: [{ mimetype: 'image/png' }] }, + { audio: true, items: [{ mimetype: 'audio/mpeg' }] } + ]) + + local = { + attachments: [ + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' } + ] + } + + // Group by three-per-row, unless there's one dangling, then stick it on the end of the last row + // https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1785#note_98514 + expect(Gallery.computed.rows.call(local)).to.eql([ + { items: [{ mimetype: 'image/jpg' }, { mimetype: 'image/png' }, { mimetype: 'image/jpg' }] }, + { items: [{ mimetype: 'image/jpg' }, { mimetype: 'image/png' }, { mimetype: 'image/png' }, { mimetype: 'image/jpg' }] } + ]) + + local = { + attachments: [ + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' } + ] + } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { items: [{ mimetype: 'image/jpg' }, { mimetype: 'image/png' }, { mimetype: 'image/jpg' }] }, + { items: [{ mimetype: 'image/jpg' }, { mimetype: 'image/png' }, { mimetype: 'image/png' }] }, + { items: [{ mimetype: 'image/jpg' }, { mimetype: 'image/png' }] } + ]) + }) + + it('does not do grouping when grid is set', () => { + const attachments = [ + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/png' }, + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'image/jpg' } + ] + + local = { grid: true, attachments } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { grid: true, items: attachments } + ]) + }) + + it('limit is set', () => { + const attachments = [ + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/png' }, + { mimetype: 'image/jpg' }, + { mimetype: 'audio/mpeg' }, + { mimetype: 'image/jpg' } + ] + + let local + local = { attachments, limit: 2 } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { audio: true, items: [{ mimetype: 'audio/mpeg' }] }, + { items: [{ mimetype: 'image/png' }] } + ]) + + local = { attachments, limit: 3 } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { audio: true, items: [{ mimetype: 'audio/mpeg' }] }, + { items: [{ mimetype: 'image/png' }, { mimetype: 'image/jpg' }] } + ]) + + local = { attachments, limit: 4 } + + expect(Gallery.computed.rows.call(local)).to.eql([ + { audio: true, items: [{ mimetype: 'audio/mpeg' }] }, + { items: [{ mimetype: 'image/png' }, { mimetype: 'image/jpg' }] }, + { audio: true, items: [{ mimetype: 'audio/mpeg' }] } + ]) + }) +}) From 22fd3afd160d27c9ab43fcc8d1270db455403f8e Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 30 Mar 2023 15:30:03 -0600 Subject: [PATCH 002/378] Change selenium server path to use require instead of hardcoding it --- test/e2e/nightwatch.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/nightwatch.conf.js b/test/e2e/nightwatch.conf.js index 4041c6989..fdd2fda29 100644 --- a/test/e2e/nightwatch.conf.js +++ b/test/e2e/nightwatch.conf.js @@ -9,7 +9,7 @@ module.exports = { selenium: { start_process: true, - server_path: 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar', + server_path: require('selenium-server').path, host: '127.0.0.1', port: 4444, cli_args: { From 8e64b1791bca4b34ec1988dda3fea99eb1715c1f Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 30 Mar 2023 15:30:30 -0600 Subject: [PATCH 003/378] Add selenium server logs path to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4df5ec838..0d5befd28 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ selenium-debug.log .idea/ config/local.json static/emoji.json +logs/ From 829ab46fdcebceac78a00151361ce1755455c643 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Wed, 12 Apr 2023 09:11:09 +0000 Subject: [PATCH 004/378] Update dependency @ungap/event-target to v0.2.4 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index db45f210d..d832517ce 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@babel/preset-env": "7.21.4", "@babel/register": "7.21.0", "@intlify/vue-i18n-loader": "5.0.1", - "@ungap/event-target": "0.2.3", + "@ungap/event-target": "0.2.4", "@vue/babel-helper-vue-jsx-merge-props": "1.4.0", "@vue/babel-plugin-jsx": "1.1.1", "@vue/compiler-sfc": "3.2.45", diff --git a/yarn.lock b/yarn.lock index 4b407fd58..52f9d2aea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2152,10 +2152,10 @@ dependencies: "@types/node" "*" -"@ungap/event-target@0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@ungap/event-target/-/event-target-0.2.3.tgz#be682c681126dca2371c4e1a1721f8e8bb400905" - integrity sha512-7Bz0qdvxNGV9n0f+xcMKU7wsEfK6PNzo8IdAcOiBgMNyCuU0Mk9dv0Hbd/Kgr+MFFfn4xLHFbuOt820egT5qEA== +"@ungap/event-target@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ungap/event-target/-/event-target-0.2.4.tgz#8b083a62ee665228bac08013fa516a3488528bb8" + integrity sha512-u9Fd3k2qfMtn+0dxbCn/y0pzQ9Ucw6lWR984CrHcbxc+WzcMkJE4VjWHWSb9At40MjwMyHCkJNXroS55Osshhw== "@ungap/promise-all-settled@1.1.2": version "1.1.2" From e1ef3811624717559b2b3ed02eaadd71ab93a872 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Wed, 3 May 2023 09:07:55 +0000 Subject: [PATCH 005/378] Update dependency js-cookie to v3.0.5 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 169dd609c..3daae1eb1 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "click-outside-vue3": "4.0.1", "cropperjs": "1.5.13", "escape-html": "1.0.3", - "js-cookie": "3.0.1", + "js-cookie": "3.0.5", "localforage": "1.10.0", "parse-link-header": "2.0.0", "phoenix": "1.6.2", diff --git a/yarn.lock b/yarn.lock index 1ccc9b058..4bef251f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5661,10 +5661,10 @@ js-beautify@1.14.6: glob "^8.0.3" nopt "^6.0.0" -js-cookie@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414" - integrity sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw== +js-cookie@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc" + integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== js-sdsl@^4.1.4: version "4.1.5" From 4beb29918a7cc33c72a404df6a724a5bd244e685 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Fri, 6 Oct 2023 09:10:07 +0000 Subject: [PATCH 006/378] Update dependency @vuelidate/core to v2.0.3 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 873f04ff1..a6a0f3304 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@kazvmoe-infra/pinch-zoom-element": "1.2.0", "@kazvmoe-infra/unicode-emoji-json": "0.4.0", "@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12", - "@vuelidate/core": "2.0.2", + "@vuelidate/core": "2.0.3", "@vuelidate/validators": "2.0.0", "body-scroll-lock": "3.1.5", "chromatism": "3.0.0", diff --git a/yarn.lock b/yarn.lock index 2eb513a59..2febc2165 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2345,10 +2345,10 @@ dependencies: js-beautify "1.14.6" -"@vuelidate/core@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@vuelidate/core/-/core-2.0.2.tgz#e874afc830ccc5295e83a0c0a0f0621e084348c9" - integrity sha512-aG1OZWv6xVws3ljyKy/pyxq1rdZZ2ryj+FEREcC9d4GP4qOvNHHZUl/NQxa0Bck3Ooc0RfXU8vwCA9piRoWy6w== +"@vuelidate/core@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@vuelidate/core/-/core-2.0.3.tgz#40468c5ed15b72bde880a026b0699c2f0f1ecede" + integrity sha512-AN6l7KF7+mEfyWG0doT96z+47ljwPpZfi9/JrNMkOGLFv27XVZvKzRLXlmDPQjPl/wOB1GNnHuc54jlCLRNqGA== dependencies: vue-demi "^0.13.11" From 9ccd01352290759575cd65b521eeba149c5cb3b7 Mon Sep 17 00:00:00 2001 From: HJ <30-hj@users.noreply.git.pleroma.social> Date: Sun, 12 Nov 2023 10:38:13 +0000 Subject: [PATCH 007/378] Merge branch 'tusooa/fix-admin-crash-when-no-primary-fe-set' into 'develop' fix admin crash when no primary fe set See merge request pleroma/pleroma-fe!1867 (cherry picked from commit faef2767cd7ba5961445e9c38e8ebf52d3610259) 661d5b6d Fix frontend admin tab crashing when no primary frontend is set b2c5520d Add changelog for frontend tab crash fix --- changelog.d/fix-admin-crash-when-no-primary-fe-set.fix | 1 + src/components/settings_modal/admin_tabs/frontends_tab.vue | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog.d/fix-admin-crash-when-no-primary-fe-set.fix diff --git a/changelog.d/fix-admin-crash-when-no-primary-fe-set.fix b/changelog.d/fix-admin-crash-when-no-primary-fe-set.fix new file mode 100644 index 000000000..78eae3be9 --- /dev/null +++ b/changelog.d/fix-admin-crash-when-no-primary-fe-set.fix @@ -0,0 +1 @@ +Fix frontend admin tab crashing when no primary frontend is set diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.vue b/src/components/settings_modal/admin_tabs/frontends_tab.vue index 13b8fa6b6..25b08eb70 100644 --- a/src/components/settings_modal/admin_tabs/frontends_tab.vue +++ b/src/components/settings_modal/admin_tabs/frontends_tab.vue @@ -33,9 +33,9 @@ > {{ frontend.name }} {{ ' ' }} - + Date: Sun, 12 Nov 2023 23:06:14 +0000 Subject: [PATCH 008/378] Merge branch 'tusooa/react-more-actions-fix' into 'develop' Accessibility for react & extra buttons See merge request pleroma/pleroma-fe!1869 (cherry picked from commit 18c0cf1845a95db2d0e894d2455cdd4dc545aaf7) 0026b35f Add alt text for react and extra-buttons popup 82063f34 Add aria-controls to extra-buttons trigger 5ff14837 Add changelog --- changelog.d/react-more-actions-fix.fix | 1 + src/components/emoji_input/emoji_input.js | 3 ++- src/components/emoji_picker/emoji_picker.vue | 2 +- src/components/extra_buttons/extra_buttons.js | 13 ++++++++++++- .../extra_buttons/extra_buttons.vue | 19 ++++++++++++++++++- src/components/poll/poll.js | 3 ++- .../post_status_form/post_status_form.js | 3 ++- src/components/react_button/react_button.vue | 2 ++ src/i18n/en.json | 3 ++- .../random_seed/random_seed.service.js | 3 +++ 10 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 changelog.d/react-more-actions-fix.fix create mode 100644 src/services/random_seed/random_seed.service.js diff --git a/changelog.d/react-more-actions-fix.fix b/changelog.d/react-more-actions-fix.fix new file mode 100644 index 000000000..9ab41de23 --- /dev/null +++ b/changelog.d/react-more-actions-fix.fix @@ -0,0 +1 @@ +Add aria attributes to react and extra buttons diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index 68654f693..9baf63f22 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -1,4 +1,5 @@ import Completion from '../../services/completion/completion.js' +import genRandomSeed from '../../services/random_seed/random_seed.service.js' import EmojiPicker from '../emoji_picker/emoji_picker.vue' import Popover from 'src/components/popover/popover.vue' import ScreenReaderNotice from 'src/components/screen_reader_notice/screen_reader_notice.vue' @@ -110,7 +111,7 @@ const EmojiInput = { }, data () { return { - randomSeed: `${Math.random()}`.replace('.', '-'), + randomSeed: genRandomSeed(), input: undefined, caretEl: undefined, highlighted: -1, diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index b8d333097..0788f34ca 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -3,7 +3,7 @@ ref="popover" trigger="click" popover-class="emoji-picker popover-default" - :trigger-attrs="{ 'aria-hidden': true }" + :trigger-attrs="{ 'aria-hidden': true, tabindex: -1 }" @show="onPopoverShown" @close="onPopoverClosed" > diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js index 48b960b2b..e2c88cebb 100644 --- a/src/components/extra_buttons/extra_buttons.js +++ b/src/components/extra_buttons/extra_buttons.js @@ -1,4 +1,5 @@ import Popover from '../popover/popover.vue' +import genRandomSeed from '../../services/random_seed/random_seed.service.js' import ConfirmModal from '../confirm_modal/confirm_modal.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -40,7 +41,8 @@ const ExtraButtons = { data () { return { expanded: false, - showingDeleteDialog: false + showingDeleteDialog: false, + randomSeed: genRandomSeed() } }, methods: { @@ -152,6 +154,15 @@ const ExtraButtons = { editingAvailable () { return this.$store.state.instance.editingAvailable }, shouldConfirmDelete () { return this.$store.getters.mergedConfig.modalOnDelete + }, + triggerAttrs () { + return { + title: this.$t('status.more_actions'), + id: `popup-trigger-${this.randomSeed}`, + 'aria-controls': `popup-menu-${this.randomSeed}`, + 'aria-expanded': this.expanded, + 'aria-haspopup': 'menu' + } } } } diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue index c1c15c0fb..b7d3b1d3a 100644 --- a/src/components/extra_buttons/extra_buttons.vue +++ b/src/components/extra_buttons/extra_buttons.vue @@ -2,6 +2,7 @@