diff --git a/src/pretix/static/pretixpresale/js/widget/widget.js b/src/pretix/static/pretixpresale/js/widget/widget.js index ce984b5ab0..4ca8b3aa38 100644 --- a/src/pretix/static/pretixpresale/js/widget/widget.js +++ b/src/pretix/static/pretixpresale/js/widget/widget.js @@ -77,6 +77,13 @@ var strings = { 'FR': django.gettext('Fr'), 'SA': django.gettext('Sa'), 'SU': django.gettext('Su'), + 'MONDAY': django.gettext('Monday'), + 'TUESDAY': django.gettext('Tuesday'), + 'WEDNESDAY': django.gettext('Wednesday'), + 'THURSDAY': django.gettext('Thursday'), + 'FRIDAY': django.gettext('Friday'), + 'SATURDAY': django.gettext('Saturday'), + 'SUNDAY': django.gettext('Sunday'), }, 'months': { '01': django.gettext('January'), @@ -964,10 +971,10 @@ Vue.component('pretix-widget-event-form', { template: ('
' // Back navigation + '
' - + '‹ ' + + '‹ ' + strings['back_to_list'] + '' - + '‹ ' + + '‹ ' + strings['back_to_dates'] + '' + '
' @@ -1119,6 +1126,11 @@ Vue.component('pretix-widget-event-form', { back_to_list: function() { this.$root.target_url = this.$root.parent_stack.pop(); this.$root.error = null; + if (!this.$root.subevent) { + // reset if we are not in a series + this.$root.name = null; + this.$root.frontpage_text = null; + } this.$root.subevent = null; this.$root.offset = 0; this.$root.append_events = false; @@ -1130,6 +1142,12 @@ Vue.component('pretix-widget-event-form', { } else { this.$root.view = "weeks"; } + + var $el = this.$root.$el; + this.$root.$nextTick(function() { + // wait for redraw, then focus content element for better a11y + $el.focus(); + }); }, calculate_buy_disabled: function() { var i, j, k; @@ -1197,7 +1215,7 @@ Vue.component('pretix-widget-event-list-filter-form', { }); Vue.component('pretix-widget-event-list-entry', { - template: ('' + template: ('' + '
{{ event.name }}
' + '' + '
{{ location }}
' // hidden by css for now, but @@ -1237,7 +1255,7 @@ Vue.component('pretix-widget-event-list-entry', { Vue.component('pretix-widget-event-list', { template: ('
' + '' @@ -1256,6 +1274,10 @@ Vue.component('pretix-widget-event-list', { }, methods: { back_to_calendar: function () { + // make sure to always focus content element + this.$nextTick(function () { + this.$root.$el.focus(); + }); this.$root.offset = 0; this.$root.append_events = false; if (this.$root.weeks) { @@ -1280,7 +1302,7 @@ Vue.component('pretix-widget-event-list', { }); Vue.component('pretix-widget-event-calendar-event', { - template: ('' + template: ('' + '' + '{{ event.name }}' + '' @@ -1288,7 +1310,8 @@ Vue.component('pretix-widget-event-calendar-event', { + '
{{ event.availability.text }}
' + '
'), props: { - event: Object + event: Object, + describedby: String, }, computed: { classObject: function () { @@ -1316,11 +1339,11 @@ Vue.component('pretix-widget-event-calendar-event', { Vue.component('pretix-widget-event-week-cell', { template: ('
' - + '
' + + '
' + '{{ dayhead }}' + '
' + '
' - + '' + + '' + '
' + '
'), props: { @@ -1346,6 +1369,9 @@ Vue.component('pretix-widget-event-week-cell', { } }, computed: { + id: function () { + return this.day ? this.$root.html_id + '-' + this.day.date : ''; + }, dayhead: function () { if (!this.day) { return; @@ -1381,7 +1407,7 @@ Vue.component('pretix-widget-event-week-cell', { Vue.component('pretix-widget-event-calendar-cell', { template: ('' - + '
' + + '
' + '{{ daynum }}' + '
' + '
' @@ -1417,6 +1443,9 @@ Vue.component('pretix-widget-event-calendar-cell', { } return this.day.date.substr(8); }, + date: function () { + return this.day ? (new Date(this.day.date)).toLocaleDateString() : ''; + }, classObject: function () { var o = {}; if (this.day && this.day.events.length > 0) { @@ -1474,26 +1503,26 @@ Vue.component('pretix-widget-event-calendar', { // Calendar navigation + '' // Calendar - + '' + + '
' + '' + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + '' + '' + '' @@ -1507,7 +1536,10 @@ Vue.component('pretix-widget-event-calendar', { }, monthname: function () { return strings['months'][this.$root.date.substr(5, 2)] + ' ' + this.$root.date.substr(0, 4); - } + }, + id: function () { + return this.$root.html_id + "-event-calendar-table"; + }, }, methods: { back_to_list: function () { @@ -1526,7 +1558,7 @@ Vue.component('pretix-widget-event-calendar', { } this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01"; this.$root.loading++; - this.$root.reload(); + this.$root.reload({focus: '#'+this.id}); }, nextmonth: function () { var curMonth = parseInt(this.$root.date.substr(5, 2)); @@ -1538,7 +1570,7 @@ Vue.component('pretix-widget-event-calendar', { } this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01"; this.$root.loading++; - this.$root.reload(); + this.$root.reload({focus: '#'+this.id}); } }, }); @@ -1573,7 +1605,7 @@ Vue.component('pretix-widget-event-week-calendar', { + '' // Actual calendar - + '
' + + '
' + '
' + '' + '' @@ -1591,6 +1623,9 @@ Vue.component('pretix-widget-event-week-calendar', { var curYear = this.$root.week[0]; return curWeek + ' / ' + curYear; }, + id: function () { + return this.$root.html_id + "-event-week-table"; + }, }, methods: { back_to_list: function () { @@ -1609,7 +1644,7 @@ Vue.component('pretix-widget-event-week-calendar', { } this.$root.week = [curYear, curWeek]; this.$root.loading++; - this.$root.reload(); + this.$root.reload({focus: '#'+this.id}); }, nextweek: function () { var curWeek = this.$root.week[1]; @@ -1621,13 +1656,13 @@ Vue.component('pretix-widget-event-week-calendar', { } this.$root.week = [curYear, curWeek]; this.$root.loading++; - this.$root.reload(); + this.$root.reload({focus: '#'+this.id}); } }, }); Vue.component('pretix-widget', { - template: ('
' + template: ('
' + '
' + shared_loading_fragment + '
{{ $root.error }}
' @@ -1737,7 +1772,7 @@ var shared_root_methods = { } }); }, - reload: function () { + reload: function (opt = {}) { var url; if (this.$root.is_button) { return; @@ -1854,6 +1889,15 @@ var shared_root_methods = { // If we're on desktop and someone selects a seating-only event in a calendar, let's open it right away, // but only if the person didn't close it before. root.startseating() + } else { + // make sure to only move focus to content element when it had focus before the reload/click + // this is needed because reload is also called on initial load and we do not want to move focus on initial load + if (root.$el.contains(document.activeElement)) { + root.$nextTick(function() { + // wait for redraw, then focus content element for better a11y + (opt.focus ? document.querySelector(opt.focus) : root.$el).focus(); + }); + } } }, function (error) { root.categories = [];
' + strings['days']['MO'] + '' + strings['days']['TU'] + '' + strings['days']['WE'] + '' + strings['days']['TH'] + '' + strings['days']['FR'] + '' + strings['days']['SA'] + '' + strings['days']['SU'] + '' + strings['days']['MO'] + '' + strings['days']['TU'] + '' + strings['days']['WE'] + '' + strings['days']['TH'] + '' + strings['days']['FR'] + '' + strings['days']['SA'] + '' + strings['days']['SU'] + '