diff --git a/front/src/components/Queue.vue b/front/src/components/Queue.vue index 8966c889c6f982243f10512d18dd5e186dfc3b9a..ae4a447fe6d763ced97b2a340ad410e7080a7184 100644 --- a/front/src/components/Queue.vue +++ b/front/src/components/Queue.vue @@ -194,7 +194,7 @@ <i class="feed icon"></i> <translate translate-context="Sidebar/Player/Title">You have a radio playing</translate> </h3> <p><translate translate-context="Sidebar/Player/Paragraph">New tracks will be appended here automatically.</translate></p> - <div @click="$store.dispatch('radios/stop')" class="ui basic primary button"><translate translate-context="*/Player/Button.Label/Short, Verb">Stop radio</translate></div> + <button @click="$store.dispatch('radios/stop')" class="ui basic primary button"><translate translate-context="*/Player/Button.Label/Short, Verb">Stop radio</translate></button> </div> </div> </div> diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue index 9aa382c1dc9bd47a1d3e34148f0b531a8d5bcaf3..08e114a432b1a6fa81424ef7a57da60e71678706 100644 --- a/front/src/components/audio/PlayButton.vue +++ b/front/src/components/audio/PlayButton.vue @@ -9,10 +9,9 @@ <i :class="[playIconClass, 'icon']"></i> <template v-if="!discrete && !iconOnly"> <slot><translate translate-context="*/Queue/Button.Label/Short, Verb">Play</translate></slot></template> </button> - <div + <button v-if="!discrete && !iconOnly" @click.prevent="clicked = true" - role="button" :class="['ui', {disabled: !playable && !filterableArtist}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]"> <i :class="dropdownIconClasses.concat(['icon'])" :title="title" ></i> <div class="menu" v-if="clicked"> @@ -29,18 +28,19 @@ <i class="feed icon"></i><translate translate-context="*/Queue/Button.Label/Short, Verb">Start radio</translate> </button> <div class="divider"></div> - <button v-if="filterableArtist" class="item basic" :disabled="!filterableArtist" @click.stop.prevent="filterArtist" :title="labels.hideArtist"> + <button v-if="filterableArtist" ref="filterArtist" data-ref="filterArtist" class="item basic" :disabled="!filterableArtist" @click.stop.prevent="filterArtist" :title="labels.hideArtist"> <i class="eye slash outline icon"></i><translate translate-context="*/Queue/Dropdown/Button/Label/Short">Hide content from this artist</translate> </button> <button v-for="obj in getReportableObjs({track, album, artist, playlist, account, channel})" :key="obj.target.type + obj.target.id" class="item basic" + :ref="`report${obj.target.type}${obj.target.id}`" :data-ref="`report${obj.target.type}${obj.target.id}`" @click.stop.prevent="$store.dispatch('moderation/report', obj.target)"> <i class="share icon" /> {{ obj.label }} </button> </div> - </div> + </button> </span> </template> @@ -270,9 +270,14 @@ export default { jQuery(this.$el).find('.ui.dropdown').dropdown({ selectOnKeydown: false, action: function (text, value, $el) { - // used ton ensure focusing the dropdown and clicking via keyboard + // used to ensure focusing the dropdown and clicking via keyboard // works as expected - self.$refs[$el.data('ref')].click() + let button = self.$refs[$el.data('ref')] + if (Array.isArray(button)) { + button[0].click() + } else { + button.click() + } jQuery(self.$el).find('.ui.dropdown').dropdown('hide') }, }) diff --git a/front/src/components/audio/Player.vue b/front/src/components/audio/Player.vue index 8766b5e9c1ab1c50a013f1dbcca2bdafe2b54a36..c2091141f333b5d532e4bd200152df10a57f8234 100644 --- a/front/src/components/audio/Player.vue +++ b/front/src/components/audio/Player.vue @@ -11,7 +11,7 @@ <div class="controls track-controls queue-not-focused desktop-and-up"> <div class="ui tiny image" @click.stop.prevent="$router.push({name: 'library.tracks.detail', params: {id: currentTrack.id }})"> <img alt="" ref="cover" v-if="currentTrack.cover && currentTrack.cover.urls.original" :src="$store.getters['instance/absoluteUrl'](currentTrack.cover.urls.medium_square_crop)"> - <img alt="" ref="cover" v-else-if="currentTrack.album && currentTrack.album.cover.urls && currentTrack.album.cover.urls.original" :src="$store.getters['instance/absoluteUrl'](currentTrack.album.cover.urls.medium_square_crop)"> + <img alt="" ref="cover" v-else-if="currentTrack.album && currentTrack.album.cover && currentTrack.album.cover.urls && currentTrack.album.cover.urls.original" :src="$store.getters['instance/absoluteUrl'](currentTrack.album.cover.urls.medium_square_crop)"> <img alt="" v-else src="../../assets/audio/default-cover.png"> </div> <div @click.stop.prevent="" class="middle aligned content ellipsis"> @@ -59,48 +59,44 @@ </button> </div> <div class="player-controls controls queue-not-focused"> - <span - role="button" + <button :title="labels.previous" :aria-label="labels.previous" - class="control tablet-and-up" + class="circular button control tablet-and-up" @click.prevent.stop="$store.dispatch('queue/previous')" :disabled="!hasPrevious"> <i :class="['ui', 'large', {'disabled': !hasPrevious}, 'backward step', 'icon']" ></i> - </span> - <span - role="button" + </button> + <button v-if="!playing" :title="labels.play" :aria-label="labels.play" @click.prevent.stop="togglePlay" - class="control"> + class="circular button control"> <i :class="['ui', 'big', 'play', {'disabled': !currentTrack}, 'icon']"></i> - </span> - <span - role="button" + </button> + <button v-else :title="labels.pause" :aria-label="labels.pause" @click.prevent.stop="togglePlay" - class="control"> + class="circular button control"> <i :class="['ui', 'big', 'pause', {'disabled': !currentTrack}, 'icon']"></i> - </span> - <span - role="button" + </button> + <button :title="labels.next" :aria-label="labels.next" - class="control" + class="circular button control" @click.prevent.stop="$store.dispatch('queue/next')" :disabled="!hasNext"> <i :class="['ui', 'large', {'disabled': !hasNext}, 'forward step', 'icon']" ></i> - </span> + </button> </div> <div class="controls progress-controls queue-not-focused tablet-and-up small align-left"> <div class="timer"> <template v-if="!isLoadingAudio"> - <span role="button" class="start" @click.stop.prevent="setCurrentTime(0)">{{currentTimeFormatted}}</span> + <span class="start" @click.stop.prevent="setCurrentTime(0)">{{currentTimeFormatted}}</span> | <span class="total">{{durationFormatted}}</span> </template> <template v-else> @@ -111,102 +107,101 @@ <div class="controls queue-controls when-queue-focused align-right"> <div class="group"> <volume-control class="expandable" /> - <span - role="button" + <button + class="circular control button" v-if="looping === 0" :title="labels.loopingDisabled" :aria-label="labels.loopingDisabled" @click.prevent.stop="$store.commit('player/looping', 1)" :disabled="!currentTrack"> <i :class="['ui', {'disabled': !currentTrack}, 'step', 'repeat', 'icon']"></i> - </span> - <span - role="button" + </button> + <button + class="looping circular control button" @click.prevent.stop="$store.commit('player/looping', 2)" :title="labels.loopingSingle" :aria-label="labels.loopingSingle" v-if="looping === 1" - class="looping" :disabled="!currentTrack"> <i class="repeat icon"> <span class="ui circular tiny vibrant label">1</span> </i> - </span> - <span - role="button" + </button> + <button + class="looping circular control button" :title="labels.loopingWhole" :aria-label="labels.loopingWhole" v-if="looping === 2" :disabled="!currentTrack" - class="looping" @click.prevent.stop="$store.commit('player/looping', 0)"> <i class="repeat icon"> <span class="ui circular tiny vibrant label">∞</span> </i> - </span> - <span - role="button" + </button> + <button + class="circular control button" :disabled="queue.tracks.length === 0" :title="labels.shuffle" :aria-label="labels.shuffle" @click.prevent.stop="shuffle()"> <div v-if="isShuffling" class="ui inline shuffling inverted tiny active loader"></div> <i v-else :class="['ui', 'random', {'disabled': queue.tracks.length === 0}, 'icon']" ></i> - </span> + </button> </div> <div class="group"> <div class="fake-dropdown"> - <span class="position control desktop-and-up" role="button" @click.stop="toggleMobilePlayer" aria-expanded="true"> + <button class="position circular control button desktop-and-up" @click.stop="toggleMobilePlayer" aria-expanded="true"> <i class="stream icon"></i> <translate translate-context="Sidebar/Queue/Text" :translate-params="{index: queue.currentIndex + 1, length: queue.tracks.length}"> %{ index } of %{ length } </translate> - </span> - <span class="position control tablet-and-below" role="button" @click.stop="switchTab"> + </button> + <button class="position circular control button tablet-and-below" @click.stop="switchTab"> <i class="stream icon"></i> <translate translate-context="Sidebar/Queue/Text" :translate-params="{index: queue.currentIndex + 1, length: queue.tracks.length}"> %{ index } of %{ length } </translate> - </span> + </button> - <span - class="control close-control desktop-and-up" + <button + class="circular control button close-control desktop-and-up" v-if="$store.state.ui.queueFocused" @click.stop="toggleMobilePlayer"> <i class="large down angle icon"></i> - </span> - <span - class="control desktop-and-up" + </button> + <button + class="circular control button desktop-and-up" v-else @click.stop="toggleMobilePlayer"> <i class="large up angle icon"></i> - </span> - <span - class="control close-control tablet-and-below" + </button> + <button + class="circular control button close-control tablet-and-below" v-if="$store.state.ui.queueFocused === 'player'" @click.stop="switchTab"> <i class="large up angle icon"></i> - </span> - <span - class="control tablet-and-below" + </button> + <button + class="circular control button tablet-and-below" v-if="$store.state.ui.queueFocused === 'queue'" @click.stop="switchTab"> <i class="large down angle icon"></i> - </span> + </button> </div> - <span - class="control close-control tablet-and-below" + <button + class="circular control button close-control tablet-and-below" @click.stop="$store.commit('ui/queueFocused', null)"> <i class="x icon"></i> - </span> + </button> </div> </div> </div> </div> <GlobalEvents @keydown.p.prevent.exact="togglePlay" + @keydown.esc.prevent.exact="$store.commit('ui/queueFocused', null)" @keydown.ctrl.shift.left.prevent.exact="previous" @keydown.ctrl.shift.right.prevent.exact="next" @keydown.shift.down.prevent.exact="$store.commit('player/incrementVolume', -0.1)" @@ -732,7 +727,7 @@ export default { title: this.currentTrack.title, artist: this.currentTrack.artist.name, } - if (this.currentTrack.album) { + if (this.currentTrack.album && this.currentTrack.album.cover) { metadata.album = this.currentTrack.album.title metadata.artwork = [ { src: this.currentTrack.album.cover.urls.original, sizes: '96x96', type: 'image/png' }, diff --git a/front/src/components/audio/VolumeControl.vue b/front/src/components/audio/VolumeControl.vue index dbbb2c46fe3b64fb7e309c72b5e07f3cf760c15d..4635d9763930554a3245abdfc6c38e8e33d0a3e7 100644 --- a/front/src/components/audio/VolumeControl.vue +++ b/front/src/components/audio/VolumeControl.vue @@ -1,5 +1,5 @@ <template> - <span :class="['component-volume-control', {'expanded': expanded}]" @click.prevent.stop="" @mouseover="handleOver" @mouseleave="handleLeave"> + <button class="circular control button" :class="['component-volume-control', {'expanded': expanded}]" @click.prevent.stop="" @mouseover="handleOver" @mouseleave="handleLeave"> <span role="button" v-if="sliderVolume === 0" @@ -34,7 +34,7 @@ max="1" v-model="sliderVolume" /> </div> - </span> + </button class="circular control"> </template> <script> import { mapState, mapGetters, mapActions } from "vuex" diff --git a/front/src/components/common/AttachmentInput.vue b/front/src/components/common/AttachmentInput.vue index 710990d7fb6542f0ee3df79706ed279dff4cc9b6..cab78c85e8f546b0a68ba2d2c061d2c970ba3a3a 100644 --- a/front/src/components/common/AttachmentInput.vue +++ b/front/src/components/common/AttachmentInput.vue @@ -18,16 +18,16 @@ </div> <div class="eleven wide column"> <div class="file-input"> - <label class="ui basic button" :for="attachmentId"> + <label :for="attachmentId"> <translate translate-context="*/*/*">Upload New Picture…</translate> </label> - <input class="ui hidden input" ref="attachment" type="file" :id="attachmentId" accept="image/x-png,image/jpeg" @change="submit" /> + <input class="ui input" ref="attachment" type="file" :id="attachmentId" accept="image/x-png,image/jpeg" @change="submit" /> </div> <div class="ui very small hidden divider"></div> <p><translate translate-context="Content/*/Paragraph">PNG or JPG. Dimensions should be between 1400x1400px and 3000x3000px. Maximum file size allowed is 5MB.</translate></p> - <div class="ui basic tiny button" v-if="value" @click.stop.prevent="remove(value)"> + <button class="ui basic tiny button" v-if="value" @click.stop.prevent="remove(value)"> <translate translate-context="Content/Radio/Button.Label/Verb">Remove</translate> - </div> + </button> <div v-if="isLoading" class="ui active inverted dimmer"> <div class="ui indeterminate text loader"> <translate translate-context="Content/*/*/Noun">Uploading file…</translate> diff --git a/front/src/components/common/DangerousButton.vue b/front/src/components/common/DangerousButton.vue index 763f3fa98bcdd10160f7499266b03addcffdf871..4ffe35c6fbbe26c824757805962359984c182f7d 100644 --- a/front/src/components/common/DangerousButton.vue +++ b/front/src/components/common/DangerousButton.vue @@ -1,5 +1,5 @@ <template> - <div @click="showModal = true" :class="[{disabled: disabled}]" role="button" :disabled="disabled"> + <button @click="showModal = true" :class="[{disabled: disabled}]" :disabled="disabled"> <slot></slot> <modal class="small" :show.sync="showModal"> @@ -24,7 +24,7 @@ </button> </div> </modal> - </div> + </button> </template> <script> diff --git a/front/src/components/federation/FetchButton.vue b/front/src/components/federation/FetchButton.vue index af323a89a2578cf01646172d08a261d66f61f637..c1266095e6017195204baac3945f91c2cae44d74 100644 --- a/front/src/components/federation/FetchButton.vue +++ b/front/src/components/federation/FetchButton.vue @@ -82,12 +82,11 @@ </div> </div> <div class="actions"> - <div role="button" class="ui basic cancel button"> + <button class="ui basic cancel button"> <translate translate-context="*/*/Button.Label/Verb">Close</translate> - </div> - <div role="button" @click="showModal = false; $emit('refresh')" class="ui confirm success button" v-if="fetch && fetch.status === 'finished'"> + </button @click.prevent="showModal = false; $emit('refresh')" class="ui confirm success button" v-if="fetch && fetch.status === 'finished'"> <translate translate-context="*/*/Button.Label/Verb">Close and reload page</translate> - </div> + </button> </div> </modal> </div> diff --git a/front/src/components/forms/PasswordInput.vue b/front/src/components/forms/PasswordInput.vue index 98c1097f6d26f119d9ae18b50c1976d495a5e6e0..5cac90f21158fb47f51d14c44618d199bd486bcd 100644 --- a/front/src/components/forms/PasswordInput.vue +++ b/front/src/components/forms/PasswordInput.vue @@ -7,9 +7,9 @@ @input="$emit('input', $event.target.value)" :id="fieldId" :value="value"> - <span @click="showPassword = !showPassword" :title="labels.title" class="ui icon button"> + <button @click.prevent="showPassword = !showPassword" :title="labels.title" class="ui icon button"> <i class="eye icon"></i> - </span> + </button> <button v-if="copyButton" @click.prevent="copy" class="ui icon button" :title="labels.copy"> <i class="copy icon"></i> </button> diff --git a/front/src/components/library/AlbumDropdown.vue b/front/src/components/library/AlbumDropdown.vue index 3c4fc00d56572635db71d715297309c59eb8f6a5..07b7b5a7674fe67243424916b4c79dfbd077f6f9 100644 --- a/front/src/components/library/AlbumDropdown.vue +++ b/front/src/components/library/AlbumDropdown.vue @@ -12,12 +12,12 @@ </div> </div> <div class="actions"> - <div class="ui basic deny button"> + <button class="ui basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> </div> </modal> - <div role="button" class="ui floating dropdown circular icon basic button" :title="labels.more" v-dropdown="{direction: 'downward'}"> + <button class="ui floating dropdown circular icon basic button" :title="labels.more" v-dropdown="{direction: 'downward'}"> <i class="ellipsis vertical icon"></i> <div class="menu"> <div @@ -78,7 +78,7 @@ <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate> </a> </div> - </div> + </button> </span> </template> <script> diff --git a/front/src/components/library/ArtistBase.vue b/front/src/components/library/ArtistBase.vue index 22038a88845f73f871e09d8e38e20d671a59fb77..35b0eb02f662bf4d59efe78c984a0e326ae6e15a 100644 --- a/front/src/components/library/ArtistBase.vue +++ b/front/src/components/library/ArtistBase.vue @@ -45,26 +45,26 @@ </div> </div> <div class="actions"> - <div class="ui deny button"> + <button class="ui deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> </div> </modal> <div class="ui buttons"> <button class="ui button" @click="$refs.dropdown.click()"> <translate translate-context="*/*/Button.Label/Noun">More…</translate> </button> - <div class="ui floating dropdown icon button" ref="dropdown" v-dropdown> + <button class="ui floating dropdown icon button" ref="dropdown" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> - <div + <button role="button" v-if="publicLibraries.length > 0" - @click="showEmbedModal = !showEmbedModal" + @click.prevent="showEmbedModal = !showEmbedModal" class="basic item"> <i class="code icon"></i> <translate translate-context="Content/*/Button.Label/Verb">Embed</translate> - </div> + </button> <a :href="wikipediaUrl" target="_blank" rel="noreferrer noopener" class="basic item"> <i class="wikipedia w icon"></i> <translate translate-context="Content/*/Button.Label/Verb">Search on Wikipedia</translate> @@ -108,7 +108,7 @@ <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate> </a> </div> - </div> + </button> </div> </div> </div> diff --git a/front/src/components/library/ImportStatusModal.vue b/front/src/components/library/ImportStatusModal.vue index f49c6d183b352e4bbcf59398c564cf679f57cc0a..782e8f292bddfffafcf1d0bedb1cdc651b0b4972 100644 --- a/front/src/components/library/ImportStatusModal.vue +++ b/front/src/components/library/ImportStatusModal.vue @@ -77,9 +77,9 @@ </div> </div> <div class="actions"> - <div class="ui deny button"> + <button class="ui deny button"> <translate translate-context="*/*/Button.Label/Verb">Close</translate> - </div> + </button> </div> </modal> </template> diff --git a/front/src/components/library/TrackBase.vue b/front/src/components/library/TrackBase.vue index 48637abad369d25cfedf02a5bcbf6043fd48159a..cf9a93659845098b60d37c7441876b916f970372 100644 --- a/front/src/components/library/TrackBase.vue +++ b/front/src/components/library/TrackBase.vue @@ -36,12 +36,12 @@ </div> </div> <div class="actions"> - <div class="ui basic deny button"> + <button class="ui basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> </div> </modal> - <div class="ui floating dropdown circular icon basic button" :title="labels.more" v-dropdown="{direction: 'downward'}"> + <button class="ui floating dropdown circular icon basic button" :title="labels.more" v-dropdown="{direction: 'downward'}"> <i class="ellipsis vertical icon"></i> <div class="menu" style="right: 0; left: auto"> <div @@ -102,7 +102,7 @@ <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate> </a> </div> - </div> + </button> </div> </div> </div> diff --git a/front/src/components/library/radios/Filter.vue b/front/src/components/library/radios/Filter.vue index 1a70c084710ff9229d00412d2f3b79aff3948a99..2a9c86b0588299243b6fac4d2922360cf935509a 100644 --- a/front/src/components/library/radios/Filter.vue +++ b/front/src/components/library/radios/Filter.vue @@ -51,9 +51,9 @@ </div> </div> <div class="actions"> - <div class="ui deny button"> + <button class="ui deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> </div> </modal> </td> diff --git a/front/src/components/manage/moderation/InstancePolicyModal.vue b/front/src/components/manage/moderation/InstancePolicyModal.vue index 44780042dac37d088c66f92b2e38552510b82eb5..b09d0d32218e6fd310ea7c1ceb3b6d19723dac34 100644 --- a/front/src/components/manage/moderation/InstancePolicyModal.vue +++ b/front/src/components/manage/moderation/InstancePolicyModal.vue @@ -31,9 +31,9 @@ <div class="ui hidden divider"></div> </div> <div class="actions"> - <div class="ui deny button"> + <button class="ui deny button"> <translate translate-context="*/*/Button.Label/Verb">Close</translate> - </div> + </button> </div> </modal> diff --git a/front/src/components/notifications/NotificationRow.vue b/front/src/components/notifications/NotificationRow.vue index 9c6b635f299a18307818220569ab2140907a381b..3a014241cf85a59e4f39186f67c4211640d0cdfb 100644 --- a/front/src/components/notifications/NotificationRow.vue +++ b/front/src/components/notifications/NotificationRow.vue @@ -9,14 +9,14 @@ </router-link> <template v-else v-html="notificationData.message"></template> <template v-if="notificationData.acceptFollow"> - <div @click="handleAction(notificationData.acceptFollow.handler)" :class="['ui', 'basic', 'tiny', notificationData.acceptFollow.buttonClass || '', 'button']"> + <button @click="handleAction(notificationData.acceptFollow.handler)" :class="['ui', 'basic', 'tiny', notificationData.acceptFollow.buttonClass || '', 'button']"> <i v-if="notificationData.acceptFollow.icon" :class="[notificationData.acceptFollow.icon, 'icon']" /> {{ notificationData.acceptFollow.label }} - </div> - <div @click="handleAction(notificationData.rejectFollow.handler)" :class="['ui', 'basic', 'tiny', notificationData.rejectFollow.buttonClass || '', 'button']"> + </button> + <button @click="handleAction(notificationData.rejectFollow.handler)" :class="['ui', 'basic', 'tiny', notificationData.rejectFollow.buttonClass || '', 'button']"> <i v-if="notificationData.rejectFollow.icon" :class="[notificationData.rejectFollow.icon, 'icon']" /> {{ notificationData.rejectFollow.label }} - </div> + </button> </template> </td> <td><human-date :date="item.activity.creation_date" /></td> diff --git a/front/src/components/playlists/Editor.vue b/front/src/components/playlists/Editor.vue index acde6f4d2244dcd958efbfe83f7ce2dd5cc66139..43d080dfa8a28b9ce29ddbee5017f44001682615 100644 --- a/front/src/components/playlists/Editor.vue +++ b/front/src/components/playlists/Editor.vue @@ -33,7 +33,7 @@ </template> </div> <div class="ui bottom attached segment"> - <div + <button @click="insertMany(queueTracks, false)" :disabled="queueTracks.length === 0" :class="['ui', {disabled: queueTracks.length === 0}, 'labeled', 'icon', 'button']" @@ -45,7 +45,7 @@ :translate-params="{count: queueTracks.length}"> Insert from queue (%{ count } track) </translate> - </div> + </button> <dangerous-button :disabled="plts.length === 0" class="ui labeled right floated danger icon button" :action="clearPlaylist"> <i class="eraser icon"></i> <translate translate-context="*/Playlist/Button.Label/Verb">Clear playlist</translate> @@ -64,7 +64,7 @@ <tr v-for="(plt, index) in plts" :key="`${index}-${plt.track.id}`"> <td class="left aligned">{{ plt.index + 1}}</td> <td class="center aligned"> - <img alt="" class="ui mini image" v-if="plt.track.album && plt.track.album.cover.urls.original" v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.urls.medium_square_crop)"> + <img alt="" class="ui mini image" v-if="plt.track.album && plt.track.album.cover && plt.track.album.cover.urls.original" v-lazy="$store.getters['instance/absoluteUrl'](plt.track.album.cover.urls.medium_square_crop)"> <img alt="" class="ui mini image" v-else src="../../assets/audio/default-cover.png"> </td> <td colspan="4"> @@ -72,7 +72,9 @@ {{ plt.track.artist.name }} </td> <td class="right aligned"> - <i @click.stop="removePlt(index)" class="circular danger trash icon"></i> + <button class="ui circular danger basic icon button"> + <i @click.stop="removePlt(index)" class="trash icon"></i> + </button> </td> </tr> </draggable> diff --git a/front/src/components/playlists/PlaylistModal.vue b/front/src/components/playlists/PlaylistModal.vue index 9a66d76bb1dfa06277a086378296cbff190c4d33..79e49a92ab405a7e0e8c3c22db45944da14e350d 100644 --- a/front/src/components/playlists/PlaylistModal.vue +++ b/front/src/components/playlists/PlaylistModal.vue @@ -100,7 +100,7 @@ </div> </div> <div class="actions"> - <div class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></div> + <button class="ui basic cancel button"><translate translate-context="*/*/Button.Label/Verb">Cancel</translate></button> </div> </modal> </template> diff --git a/front/src/main.js b/front/src/main.js index 514a5539a206698af9381f9f72321b4b4c081606..79505a707f47e2c1af27e6e58ab013b782a032a7 100644 --- a/front/src/main.js +++ b/front/src/main.js @@ -66,6 +66,13 @@ Vue.directive('title', function (el, binding) { Vue.directive('dropdown', function (el, binding) { jQuery(el).dropdown({ selectOnKeydown: false, + action: function (text, value, $el) { + // used to ensure focusing the dropdown and clicking via keyboard + // works as expected + let button = $el[0] + button.click() + jQuery(el).find('.ui.dropdown').dropdown('hide') + }, ...(binding.value || {}) }) }) diff --git a/front/src/style/components/_play_button.scss b/front/src/style/components/_play_button.scss index 2ec68d5e257f0d30da8a8fdcfc930fc2c277ca3f..3fc5390cad68ec04ac059a23a9a674dbf5437f83 100644 --- a/front/src/style/components/_play_button.scss +++ b/front/src/style/components/_play_button.scss @@ -2,4 +2,9 @@ button.item { width: 100%; } + > .floating.dropdown { + background: transparent; + padding: 0; + border: none; + } } diff --git a/front/src/style/components/_player.scss b/front/src/style/components/_player.scss index f18de598572a45fe919ddd8e8a6861bacaa746a5..edaa982774292071be8c88be272b4a980fb7465a 100644 --- a/front/src/style/components/_player.scss +++ b/front/src/style/components/_player.scss @@ -192,9 +192,6 @@ border: none; background-color: transparent; color: inherit; - &:focus { - box-shadow: none; - } } .fake-dropdown { @@ -204,13 +201,19 @@ align-items: center; justify-content: space-between; min-width: 10em; - > * { + > .control.button { padding: 0.5em; } .position.control { padding-right: 1em; flex-grow: 1; + padding-left: 0; + i.stream.icon { + position: relative; + top: -2px; + left: -2px; + } } .angle.icon { margin-right: 0; diff --git a/front/src/style/components/_volume_control.scss b/front/src/style/components/_volume_control.scss index d034e80ca6e98ae0eba693a1cedd425cb47ff576..c08b1a00f7f77b55e5bba3fe40c63e20a9b251bc 100644 --- a/front/src/style/components/_volume_control.scss +++ b/front/src/style/components/_volume_control.scss @@ -4,6 +4,7 @@ align-items: center; position: relative; overflow: visible; + top: 3px; input { max-width: 5.5em; height: 4px; diff --git a/front/src/views/admin/ChannelDetail.vue b/front/src/views/admin/ChannelDetail.vue index 55009075e85ab8d9df3d2b2070fad8fda918ab5f..3b923478587af8ddae754fecf355253697efdec5 100644 --- a/front/src/views/admin/ChannelDetail.vue +++ b/front/src/views/admin/ChannelDetail.vue @@ -36,7 +36,7 @@ <i class="info icon"></i> <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate> </router-link> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a @@ -56,7 +56,7 @@ <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate> </a> </div> - </div> + </button> </div> <div class="ui buttons"> <dangerous-button diff --git a/front/src/views/admin/library/AlbumDetail.vue b/front/src/views/admin/library/AlbumDetail.vue index dda46e24f2ec533cfb45622a1a6b1d3aaedccdaf..9a076221c90043f06d4eaf234737271512844055 100644 --- a/front/src/views/admin/library/AlbumDetail.vue +++ b/front/src/views/admin/library/AlbumDetail.vue @@ -37,7 +37,7 @@ <i class="info icon"></i> <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate> </router-link> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a @@ -61,7 +61,7 @@ <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate> </a> </div> - </div> + </button> </div> <div class="ui buttons"> <router-link diff --git a/front/src/views/admin/library/ArtistDetail.vue b/front/src/views/admin/library/ArtistDetail.vue index d9cfe5f6e932a40ba059257fafe3e8e784484881..e3e11c5178dd0bafe512acd29f79f43d0c87d74e 100644 --- a/front/src/views/admin/library/ArtistDetail.vue +++ b/front/src/views/admin/library/ArtistDetail.vue @@ -36,7 +36,7 @@ <i class="info icon"></i> <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate> </router-link> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a @@ -60,7 +60,7 @@ <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate> </a> </div> - </div> + </button> </div> <div class="ui buttons"> <router-link diff --git a/front/src/views/admin/library/LibraryDetail.vue b/front/src/views/admin/library/LibraryDetail.vue index 82f5e80b80a3e0686ca792f62fe84c74c938a364..6076063df908427fa1841d1f6e3c1314a750ac35 100644 --- a/front/src/views/admin/library/LibraryDetail.vue +++ b/front/src/views/admin/library/LibraryDetail.vue @@ -34,7 +34,7 @@ <i class="wrench icon"></i> <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate> </a> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a @@ -50,7 +50,7 @@ <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate> </a> </div> - </div> + </button> </div> <div class="ui buttons"> <dangerous-button diff --git a/front/src/views/admin/library/TagDetail.vue b/front/src/views/admin/library/TagDetail.vue index bb896036eaac5700e80ee2679e3b2f803981c0d6..856478d79db03fededeaf865f2ff35bf224d7c10 100644 --- a/front/src/views/admin/library/TagDetail.vue +++ b/front/src/views/admin/library/TagDetail.vue @@ -21,7 +21,7 @@ <i class="info icon"></i> <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate> </router-link> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a @@ -33,7 +33,7 @@ <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate> </a> </div> - </div> + </button> </div> <div class="ui buttons"> <dangerous-button diff --git a/front/src/views/admin/library/TrackDetail.vue b/front/src/views/admin/library/TrackDetail.vue index 1cf51953eb794736fc1f64a4ea09e39cea0ac685..822942598ff6ab4172baa54d230ac416ca978a4b 100644 --- a/front/src/views/admin/library/TrackDetail.vue +++ b/front/src/views/admin/library/TrackDetail.vue @@ -37,7 +37,7 @@ <i class="info icon"></i> <translate translate-context="Content/Moderation/Link/Verb">Open local profile</translate> </router-link> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a @@ -61,7 +61,7 @@ <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate> </a> </div> - </div> + </button> </div> <div class="ui buttons"> <router-link diff --git a/front/src/views/admin/library/UploadDetail.vue b/front/src/views/admin/library/UploadDetail.vue index e10f29acd98ef055e767bdd4593cf61f959eac5c..b5a8c522b9d65b2a340d799aa23446c9afb0df09 100644 --- a/front/src/views/admin/library/UploadDetail.vue +++ b/front/src/views/admin/library/UploadDetail.vue @@ -35,7 +35,7 @@ <i class="wrench icon"></i> <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate> </a> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a @@ -51,7 +51,7 @@ <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate> </a> </div> - </div> + </button> </div> <div class="ui buttons"> <a class="ui labeled icon button" v-if="object.audio_file" :href="$store.getters['instance/absoluteUrl'](object.audio_file)" target="_blank" rel="noopener noreferrer"> diff --git a/front/src/views/admin/moderation/AccountsDetail.vue b/front/src/views/admin/moderation/AccountsDetail.vue index caf02f2292f8c58e9f59726eb2337b65260831ea..0a78f345adbf061efdb14c8779a321a44423ef74 100644 --- a/front/src/views/admin/moderation/AccountsDetail.vue +++ b/front/src/views/admin/moderation/AccountsDetail.vue @@ -45,7 +45,7 @@ <i class="wrench icon"></i> <translate translate-context="Content/Moderation/Link/Verb">View in Django's admin</translate> </a> - <div class="ui floating dropdown icon button" v-dropdown> + <button class="ui floating dropdown icon button" v-dropdown> <i class="dropdown icon"></i> <div class="menu"> <a class="basic item" :href="object.url || object.fid" target="_blank" rel="noopener noreferrer"> @@ -53,7 +53,7 @@ <translate translate-context="Content/Moderation/Link/Verb">Open remote profile</translate> </a> </div> - </div> + </button> </div> </div> </div> diff --git a/front/src/views/auth/ProfileBase.vue b/front/src/views/auth/ProfileBase.vue index ece6c1c3dbcb0bf9cb47feda8745e4fb62edcf85..353ab1581c5f7bc5a474b659d5671ece13218730 100644 --- a/front/src/views/auth/ProfileBase.vue +++ b/front/src/views/auth/ProfileBase.vue @@ -6,7 +6,7 @@ <div class="ui head vertical stripe segment container"> <div class="ui stackable grid" v-if="object"> <div class="ui five wide column"> - <div class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em;"> + <button class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em;"> <i class="ellipsis vertical icon"></i> <div class="menu"> <div @@ -24,7 +24,7 @@ <translate translate-context="Content/Moderation/Link">Open in moderation interface</translate> </router-link> </div> - </div> + </button> <h1 class="ui center aligned icon header"> <i v-if="!object.icon" class="circular inverted user success icon"></i> <img alt="" class="ui big circular image" v-else v-lazy="$store.getters['instance/absoluteUrl'](object.icon.urls.medium_square_crop)" /> diff --git a/front/src/views/auth/ProfileOverview.vue b/front/src/views/auth/ProfileOverview.vue index 7bd38bbf84a98a7423e5dc30f1832f3c43df6b60..3ed7dde817ea8440b748c42ec3b70baea8dd3a4d 100644 --- a/front/src/views/auth/ProfileOverview.vue +++ b/front/src/views/auth/ProfileOverview.vue @@ -13,7 +13,7 @@ <h2 class="ui with-actions header"> <translate translate-context="*/*/*">Channels</translate> <div class="actions" v-if="$store.state.auth.authenticated && object.full_username === $store.state.auth.fullUsername"> - <a @click.stop.prevent="showCreateModal = true"> + <a @click.stop.prevent="showCreateModal = true" href=""> <i class="plus icon"></i> <translate translate-context="Content/Profile/Button">Add new</translate> </a> @@ -53,9 +53,9 @@ <div class="ui hidden divider"></div> </div> <div class="actions"> - <div v-if="step === 1" class="ui basic deny button"> + <button v-if="step === 1" class="ui basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> <button v-if="step > 1" class="ui basic button" @click.stop.prevent="step -= 1"> <translate translate-context="*/*/Button.Label/Verb">Previous step</translate> </button> diff --git a/front/src/views/channels/DetailBase.vue b/front/src/views/channels/DetailBase.vue index 6ab5395cd46117407be2a0e17672f6025e93a290..a6385488da4b757485e67c89ce2e5af0ce4ec895 100644 --- a/front/src/views/channels/DetailBase.vue +++ b/front/src/views/channels/DetailBase.vue @@ -68,12 +68,12 @@ </div> </div> <div class="actions"> - <div class="ui basic deny button"> + <button class="ui basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> </div> </modal> - <div class="ui right floated pointing dropdown icon small basic button" ref="dropdown" v-dropdown="{direction: 'downward'}"> + <button class="ui right floated pointing dropdown icon small basic button" ref="dropdown" v-dropdown="{direction: 'downward'}"> <i class="ellipsis vertical icon"></i> <div class="menu"> <div @@ -122,7 +122,7 @@ </router-link> </template> </div> - </div> + </button> </div> </div> <h1 class="ui header"> @@ -166,9 +166,9 @@ </div> </div> <div class="actions"> - <div class="ui basic deny button"> + <button class="ui basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> </div> </modal> <modal :show.sync="showEditModal" v-if="isOwner"> @@ -187,9 +187,9 @@ <div class="ui hidden divider"></div> </div> <div class="actions"> - <div class="ui left floated basic deny button"> + <button class="ui left floated basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> <button @click.stop="$refs.editForm.submit" :class="['ui', 'primary', 'confirm', {loading: edit.isLoading}, 'button']" :disabled="!edit.submittable"> <translate translate-context="*/Channels/Button.Label">Update channel</translate> </button> diff --git a/front/src/views/channels/SubscriptionsList.vue b/front/src/views/channels/SubscriptionsList.vue index f3b3ff796c69800fa56a43707c8f5632751a16f2..27f92ca1fce51ce85462b0a6ee903906270de2cb 100644 --- a/front/src/views/channels/SubscriptionsList.vue +++ b/front/src/views/channels/SubscriptionsList.vue @@ -23,9 +23,9 @@ :redirect="false"></remote-search-form> </div> <div class="actions"> - <div class="ui basic deny button"> + <button class="ui basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> <button form="remote-search" type="submit" class="ui primary button"> <i class="bookmark icon"></i> <translate translate-context="*/*/*/Verb">Subscribe</translate> diff --git a/front/src/views/content/libraries/Home.vue b/front/src/views/content/libraries/Home.vue index 59e720cdfe88a5e5ce77d1ddf47b3802ad0e6c61..f3089b5dc92159af46d18d6689934721583225e2 100644 --- a/front/src/views/content/libraries/Home.vue +++ b/front/src/views/content/libraries/Home.vue @@ -9,7 +9,7 @@ <p v-if="libraries.length == 0"> <translate translate-context="Content/Library/Paragraph">Looks like you don't have a library, it's time to create one.</translate> </p> - <a :aria-expanded="!hiddenForm" @click="hiddenForm = !hiddenForm"> + <a :aria-expanded="!hiddenForm" @click="hiddenForm = !hiddenForm" href=""> <i class="plus icon" v-if="hiddenForm" /> <i class="minus icon" v-else /> <translate translate-context="Content/Library/Link/Verb">Create a new library</translate> diff --git a/front/src/views/content/remote/Card.vue b/front/src/views/content/remote/Card.vue index f1836c726d27cc7253ce12c8d2bef19781cd35d9..8be7463d45a160ff3a7b94dfb064367617409b17 100644 --- a/front/src/views/content/remote/Card.vue +++ b/front/src/views/content/remote/Card.vue @@ -5,17 +5,16 @@ <router-link :to="{name: 'library.detail', params: {id: library.uuid}}"> {{ library.name }} </router-link> - <div class="ui right floated dropdown"> + <div class="ui right floated dropdown" v-dropdown> <i class="ellipsis vertical large icon nomargin"></i> <div class="menu"> - <div - role="button" + <button v-for="obj in getReportableObjs({library, account: library.actor})" :key="obj.target.type + obj.target.id" class="item basic" @click.stop.prevent="$store.dispatch('moderation/report', obj.target)"> <i class="share icon" /> {{ obj.label }} - </div> + </button> </div> </div> <span @@ -156,18 +155,6 @@ export default { latestScan: this.library.latest_scan, } }, - mounted () { - let self = this - jQuery(this.$el).find('.ui.dropdown').dropdown({ - selectOnKeydown: false, - action: function (text, value, $el) { - // used ton ensure focusing the dropdown and clicking via keyboard - // works as expected - self.$refs[$el.data('ref')].click() - jQuery(self.$el).find('.ui.dropdown').dropdown('hide') - } - }) - }, computed: { labels () { let me = this.$pgettext('Content/Library/Card.Help text', 'This library is private and your approval from its owner is needed to access its content') diff --git a/front/src/views/library/DetailBase.vue b/front/src/views/library/DetailBase.vue index 7f82ee61e34c5ca60d70e6f11bf8b92342a80200..a58a179be6a402687806b46fc3a8045736267755 100644 --- a/front/src/views/library/DetailBase.vue +++ b/front/src/views/library/DetailBase.vue @@ -4,7 +4,7 @@ <div v-if="isLoading" class="ui centered active inline loader"></div> <div class="ui stackable grid" v-else-if="object"> <div class="ui five wide column"> - <div class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em;"> + <button class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em;"> <i class="ellipsis vertical icon"></i> <div class="menu"> <div @@ -22,7 +22,7 @@ <translate translate-context="Content/Moderation/Link">Open in moderation interface</translate> </router-link> </div> - </div> + </button> <h1 class="ui header"> <div class="ui hidden divider"></div> <div class="ellipsis content"> diff --git a/front/src/views/library/Edit.vue b/front/src/views/library/Edit.vue index fb44dab21b29f3f7baf44b22a9abc4b995ad15dd..998e364c19835284bb4a1e3e6e744c1de5c0e255 100644 --- a/front/src/views/library/Edit.vue +++ b/front/src/views/library/Edit.vue @@ -38,12 +38,12 @@ </span> </td> <td> - <div @click="updateApproved(follow, true)" :class="['ui', 'mini', 'icon', 'labeled', 'success', 'button']" v-if="follow.approved === null || follow.approved === false"> + <button @click="updateApproved(follow, true)" :class="['ui', 'mini', 'icon', 'labeled', 'success', 'button']" v-if="follow.approved === null || follow.approved === false"> <i class="ui check icon"></i> <translate translate-context="Content/Library/Button.Label">Accept</translate> - </div> - <div @click="updateApproved(follow, false)" :class="['ui', 'mini', 'icon', 'labeled', 'danger', 'button']" v-if="follow.approved === null || follow.approved === true"> + </button> + <button @click="updateApproved(follow, false)" :class="['ui', 'mini', 'icon', 'labeled', 'danger', 'button']" v-if="follow.approved === null || follow.approved === true"> <i class="ui x icon"></i> <translate translate-context="Content/Library/Button.Label">Reject</translate> - </div> + </button> </td> </tr> diff --git a/front/src/views/playlists/Detail.vue b/front/src/views/playlists/Detail.vue index 31f30e2441cd85855cbeb98a48760e20c3b774b5..1af68e7c939ff56eec7de6b16844e4d39b986242 100644 --- a/front/src/views/playlists/Detail.vue +++ b/front/src/views/playlists/Detail.vue @@ -58,9 +58,9 @@ </div> </div> <div class="actions"> - <div class="ui basic deny button"> + <button class="ui basic deny button"> <translate translate-context="*/*/Button.Label/Verb">Cancel</translate> - </div> + </button> </div> </modal> </section>