diff --git a/src/pretix/presale/templates/pretixpresale/widget_dummy.v1.html b/src/pretix/presale/templates/pretixpresale/widget_dummy.v1.html deleted file mode 100644 index 72f58a9066..0000000000 --- a/src/pretix/presale/templates/pretixpresale/widget_dummy.v1.html +++ /dev/null @@ -1,5 +0,0 @@ -{% load compress %} -{% load static %} -{% compress css %} - -{% endcompress %} diff --git a/src/pretix/presale/views/widget.py b/src/pretix/presale/views/widget.py index d95624acf0..f99e83527b 100644 --- a/src/pretix/presale/views/widget.py +++ b/src/pretix/presale/views/widget.py @@ -83,7 +83,7 @@ logger = logging.getLogger(__name__) # we never change static source without restart, so we can cache this thread-wise _source_cache_key = None -version_min = 1 +version_min = 2 version_max = 2 version_default = 2 # used for output in widget-embed-code @@ -109,6 +109,8 @@ def indent(s): def widget_css_etag(request, version, **kwargs): + if version < version_min: + version = version_min # This makes sure a new version of the theme is loaded whenever settings or the source files have changed if hasattr(request, 'event'): return (f'{_get_source_cache_key(version)}-' @@ -130,11 +132,7 @@ def widget_css(request, version, **kwargs): if version > version_max: raise Http404() if version < version_min: - return redirect(reverse('presale:event.widget.css' if hasattr(request, 'event') else 'organizer.widget.css', kwargs={ - 'version': version_min, - 'organizer': request.organizer.slug, - 'event': request.event.slug if hasattr(request, 'event') else None, - })) + version = version_min o = getattr(request, 'event', request.organizer) template_path = 'pretixpresale/widget_dummy.html' if version == version_max else 'pretixpresale/widget_dummy.v{}.html'.format(version) @@ -145,7 +143,7 @@ def widget_css(request, version, **kwargs): widget_css = f.read() theme_css = get_theme_vars_css(o, widget=True) - css = theme_css + widget_css + css = f"/* v{version} */\n" + theme_css + widget_css resp = FileResponse(css, content_type='text/css') resp._csp_ignore = True @@ -202,7 +200,7 @@ def generate_widget_js(version, lang): code.append('})({});\n') code = ''.join(code) code = rJSMinFilter(content=code).output() - return code + return f"/* v{version} */\n" + code @gzip_page @@ -212,10 +210,7 @@ def widget_js(request, version, lang, **kwargs): raise Http404() if version < version_min: - return redirect(reverse('presale:widget.js', kwargs={ - 'version': version_min, - 'lang': lang, - })) + version = version_min cached_js = cache.get('widget_js_data_v{}_{}'.format(version, lang)) if cached_js and not settings.DEBUG: diff --git a/src/pretix/static/pretixpresale/js/widget/widget.v1.js b/src/pretix/static/pretixpresale/js/widget/widget.v1.js deleted file mode 100644 index 260606e946..0000000000 --- a/src/pretix/static/pretixpresale/js/widget/widget.v1.js +++ /dev/null @@ -1,2504 +0,0 @@ -/*global siteglobals, module, lang, django*/ -/* PRETIX WIDGET BEGINS HERE */ -/* This is embedded in an isolation wrapper that exposes siteglobals as the global - scope. */ - -window.PretixWidget = { - 'build_widgets': true, - 'widget_data': { - 'referer': location.href - } -}; - -var Vue = module.exports; - -var strings = { - 'quantity': django.pgettext('widget', 'Quantity'), - 'quantity_dec': django.pgettext('widget', 'Decrease quantity'), - 'quantity_inc': django.pgettext('widget', 'Increase quantity'), - 'price': django.pgettext('widget', 'Price'), - 'original_price': django.pgettext('widget', 'Original price: %s'), - 'new_price': django.pgettext('widget', 'New price: %s'), - 'select': django.pgettext('widget', 'Select'), - 'select_item': django.pgettext('widget', 'Select %s'), - 'select_variant': django.pgettext('widget', 'Select variant %s'), - 'sold_out': django.pgettext('widget', 'Sold out'), - 'buy': django.pgettext('widget', 'Buy'), - 'register': django.pgettext('widget', 'Register'), - 'reserved': django.pgettext('widget', 'Reserved'), - 'free': django.pgettext('widget', 'FREE'), - 'price_from': django.pgettext('widget', 'from %(currency)s %(price)s'), - 'image_of': django.pgettext('widget', 'Image of %s'), - 'tax_incl': django.pgettext('widget', 'incl. %(rate)s% %(taxname)s'), - 'tax_plus': django.pgettext('widget', 'plus %(rate)s% %(taxname)s'), - 'tax_incl_mixed': django.pgettext('widget', 'incl. taxes'), - 'tax_plus_mixed': django.pgettext('widget', 'plus taxes'), - 'quota_left': django.pgettext('widget', 'currently available: %s'), - 'unavailable_require_voucher': django.pgettext('widget', 'Only available with a voucher'), - 'unavailable_available_from': django.pgettext('widget', 'Not yet available'), - 'unavailable_available_until': django.pgettext('widget', 'Not available anymore'), - 'unavailable_active': django.pgettext('widget', 'Currently not available'), - 'unavailable_hidden_if_item_available': django.pgettext('widget', 'Not yet available'), - 'order_min': django.pgettext('widget', 'minimum amount to order: %s'), - 'exit': django.pgettext('widget', 'Close ticket shop'), - 'loading_error': django.pgettext('widget', 'The ticket shop could not be loaded.'), - 'loading_error_429': django.pgettext('widget', 'There are currently a lot of users in this ticket shop. Please ' + - 'open the shop in a new tab to continue.'), - 'open_new_tab': django.pgettext('widget', 'Open ticket shop'), - 'checkout': django.pgettext('widget', 'Checkout'), - 'cart_error': django.pgettext('widget', 'The cart could not be created. Please try again later'), - 'cart_error_429': django.pgettext('widget', 'We could not create your cart, since there are currently too many ' + - 'users in this ticket shop. Please click "Continue" to retry in a new tab.'), - 'waiting_list': django.pgettext('widget', 'Waiting list'), - 'cart_exists': django.pgettext('widget', 'You currently have an active cart for this event. If you select more' + - ' products, they will be added to your existing cart.'), - 'resume_checkout': django.pgettext('widget', 'Resume checkout'), - 'redeem_voucher': django.pgettext('widget', 'Redeem a voucher'), - 'redeem': django.pgettext('widget', 'Redeem'), - 'voucher_code': django.pgettext('widget', 'Voucher code'), - 'close': django.pgettext('widget', 'Close'), - 'continue': django.pgettext('widget', 'Continue'), - 'variations': django.pgettext('widget', 'Show variants'), - 'hide_variations': django.pgettext('widget', 'Hide variants'), - 'back_to_list': django.pgettext('widget', 'Choose a different event'), - 'back_to_dates': django.pgettext('widget', 'Choose a different date'), - 'back': django.pgettext('widget', 'Back'), - 'next_month': django.pgettext('widget', 'Next month'), - 'previous_month': django.pgettext('widget', 'Previous month'), - 'next_week': django.pgettext('widget', 'Next week'), - 'previous_week': django.pgettext('widget', 'Previous week'), - 'show_seating': django.pgettext('widget', 'Open seat selection'), - 'seating_plan_waiting_list': django.pgettext('widget', 'Some or all ticket categories are currently sold out. If you want, you can add yourself to the waiting list. We will then notify if seats are available again.'), - 'load_more': django.pgettext('widget', 'Load more'), - 'days': { - 'MO': django.gettext('Mo'), - 'TU': django.gettext('Tu'), - 'WE': django.gettext('We'), - 'TH': django.gettext('Th'), - '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'), - '02': django.gettext('February'), - '03': django.gettext('March'), - '04': django.gettext('April'), - '05': django.gettext('May'), - '06': django.gettext('June'), - '07': django.gettext('July'), - '08': django.gettext('August'), - '09': django.gettext('September'), - '10': django.gettext('October'), - '11': django.gettext('November'), - '12': django.gettext('December'), - } -}; - -var setCookie = function (cname, cvalue, exdays) { - var d = new Date(); - d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); - var expires = "expires=" + d.toUTCString(); - document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; -}; -var getCookie = function (name) { - var value = "; " + document.cookie; - var parts = value.split("; " + name + "="); - if (parts.length == 2) return parts.pop().split(";").shift() || null; - else return null; -}; - -var padNumber = function(number, size) { - var s = String(number); - while (s.length < (size || 2)) {s = "0" + s;} - return s; -}; - -var getISOWeeks = function (y) { - var d, isLeap; - - d = new Date(y, 0, 1); - isLeap = new Date(y, 1, 29).getMonth() === 1; - - //check for a Jan 1 that's a Thursday or a leap year that has a - //Wednesday jan 1. Otherwise it's 52 - return d.getDay() === 4 || isLeap && d.getDay() === 3 ? 53 : 52 -}; - -/* HTTP API Call helpers */ -var api = { - '_getJSON': function (endpoint, callback, err_callback) { - var xhr = new window.XMLHttpRequest(); - xhr.open("GET", endpoint, true); - xhr.onload = function (e) { - if (xhr.readyState === 4) { - if (xhr.status === 200) { - callback(JSON.parse(xhr.responseText), xhr); - } else { - err_callback(xhr, e); - } - } - }; - xhr.onerror = function (e) { - console.error(xhr.statusText); - err_callback(xhr, e); - }; - xhr.send(null); - }, - - '_postFormJSON': function (endpoint, form, callback, err_callback) { - var params = [].filter.call(form.elements, function (el) { - return (el.type !== 'checkbox' && el.type !== 'radio') || el.checked; - }) - .filter(function (el) { - return !!el.name && !!el.value; - }) - .filter(function (el) { - return !el.disabled; - }) - .map(function (el) { - return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value); - }).join('&'); - - var xhr = new window.XMLHttpRequest(); - xhr.open("POST", endpoint, true); - xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - xhr.onload = function (e) { - if (xhr.readyState === 4) { - if (xhr.status === 200) { - callback(JSON.parse(xhr.responseText)); - } else { - err_callback(xhr, e); - } - } - }; - xhr.onerror = function (e) { - err_callback(xhr, e); - }; - xhr.send(params); - } -}; - -var makeid = function (length) { - var text = ""; - var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - - for (var i = 0; i < length; i++) { - text += possible.charAt(Math.floor(Math.random() * possible.length)); - } - - return text; -}; - -var site_is_secure = function () { - return /https.*/.test(document.location.protocol) -}; - -var widget_id = makeid(16); - -/* Vue Components */ -Vue.component('availbox', { - template: ('
' - + '
' - + '{{unavailability_reason_message}}' - + '
' - + '
' - + '{{unavailability_reason_message}}' - + '
' - + '
' - + strings.reserved - + '
' - + '
' - + strings.sold_out - + '
' - + '' - + '
' - + '' - + '' - + '
' - + '' - + '' - + '' - + '
' - + '
' - + '
'), - props: { - item: Object, - variation: Object - }, - mounted: function() { - if (this.item.has_variations) { - this.$set(this.variation, 'amount_selected', 0); - } else { - // Automatically set the only available item to be selected. - this.$set(this.item, 'amount_selected', this.$root.itemnum === 1 && !this.$root.has_seating_plan ? 1 : 0); - } - this.$root.$emit('amounts_changed') - }, - computed: { - aria_labelledby: function () { - return this.$root.html_id + '-item-label-' + this.item.id; - }, - dec_label: function () { - return '- ' + (this.item.has_variations ? this.variation.value : this.item.name) + ': ' + strings.quantity_dec; - }, - inc_label: function () { - return '+ ' + (this.item.has_variations ? this.variation.value : this.item.name) + ': ' + strings.quantity_inc; - }, - count_group_classes: function () { - return { - 'pretix-widget-item-count-group': !this.$root.use_native_spinners - } - }, - unavailability_reason_message: function () { - var reason = this.item.current_unavailability_reason || this.variation?.current_unavailability_reason; - if (reason) { - return strings["unavailable_" + reason] || reason; - } - return ""; - }, - amount_selected: { - cache: false, - get: function () { - var selected = this.item.has_variations ? this.variation.amount_selected : this.item.amount_selected - if (selected === 0) return undefined; - return selected - }, - set: function (value) { - // Unary operator to force boolean to integer conversion, as the HTML form submission - // needs the value to be integer for all products. - value = (+value); - if (this.item.has_variations) { - this.variation.amount_selected = value; - } else { - this.item.amount_selected = value; - } - if (this.$refs.quantity) { - // manually set value on quantity as on reload somehow v-model binding breaks - this.$refs.quantity.value = value; - } - this.$root.$emit("amounts_changed") - } - }, - label_select_item: function () { - return this.item.has_variations - ? strings.select_variant.replace("%s", this.variation.value) - : strings.select_item.replace("%s", this.item.name) - }, - input_name: function () { - if (this.item.has_variations) { - return 'variation_' + this.item.id + '_' + this.variation.id; - } else { - return 'item_' + this.item.id; - } - }, - order_max: function () { - return this.item.has_variations ? this.variation.order_max : this.item.order_max; - }, - avail: function () { - return this.item.has_variations ? this.variation.avail : this.item.avail; - }, - waiting_list_show: function () { - return this.avail[0] < 100 && this.$root.waiting_list_enabled && this.item.allow_waitinglist; - }, - waiting_list_url: function () { - var u - if (this.item.has_variations) { - u = this.$root.target_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id + '&var=' + this.variation.id + '&widget_data=' + encodeURIComponent(this.$root.widget_data_json) + this.$root.consent_parameter; - } else { - u = this.$root.target_url + 'w/' + widget_id + '/waitinglist/?item=' + this.item.id + '&widget_data=' + encodeURIComponent(this.$root.widget_data_json) + this.$root.consent_parameter; - } - if (this.$root.subevent) { - u += '&subevent=' + this.$root.subevent - } - return u - } - }, - methods: { - focus_voucher_field: function () { - this.$root.$emit('focus_voucher_field') - }, - on_step: function (e) { - var t = e.target.tagName == 'BUTTON' ? e.target : e.target.closest('button'); - var step = parseFloat(t.getAttribute("data-step")); - var controls = document.getElementById(t.getAttribute("data-controls")); - this.amount_selected = Math.max(controls.min, Math.min(controls.max || Number.MAX_SAFE_INTEGER, (this.amount_selected || 0) + step)); - } - } -}); -Vue.component('pricebox', { - template: ('
' - + '' - + '' - + ' ' - + '' - + '
' - + '{{ $root.currency }} ' - + '' - + '
' - + '' - + '{{ taxline }}' - + '' - + '
'), - props: { - price: Object, - free_price: Boolean, - field_name: String, - suggested_price: Object, - original_price: String, - mandatory_priced_addons: Boolean, - item_id: Number, - }, - methods: { - stripHTML: function (s) { - var div = document.createElement('div'); - div.innerHTML = s; - return div.textContent || div.innerText || ''; - }, - }, - computed: { - aria_labelledby: function () { - return [ - this.$root.html_id + '-item-label-' + this.item_id, - this.price_box_id - ].join(" "); - }, - price_box_id: function () { - return this.$root.html_id + '-item-pricebox-' + this.item_id; - }, - price_desc_id: function () { - return this.$root.html_id + '-item-pricedesc-' + this.item_id; - }, - display_price: function () { - if (this.$root.display_net_prices) { - return floatformat(parseFloat(this.price.net), 2); - } else { - return floatformat(parseFloat(this.price.gross), 2); - } - }, - display_price_nonlocalized: function () { - if (this.$root.display_net_prices) { - return parseFloat(this.price.net).toFixed(2); - } else { - return parseFloat(this.price.gross).toFixed(2); - } - }, - suggested_price_nonlocalized: function () { - var price = this.suggested_price; - if (price === null) { - price = this.price; - } - if (this.$root.display_net_prices) { - return parseFloat(price.net).toFixed(2); - } else { - return parseFloat(price.gross).toFixed(2); - } - }, - original_price_aria_label: function () { - return django.interpolate(strings.original_price, [this.stripHTML(this.original_line)]); - }, - new_price_aria_label: function () { - return django.interpolate(strings.new_price, [this.stripHTML(this.priceline)]); - }, - original_line: function () { - return '' + this.$root.currency + " " + floatformat(parseFloat(this.original_price), 2); - }, - priceline: function () { - if (this.price.gross === "0.00") { - if (this.mandatory_priced_addons && !this.original_price) { - return "\xA0"; // nbsp, because an empty string would cause the HTML element to collapse - } - return strings.free; - } else { - return '' + this.$root.currency + " " + this.display_price; - } - }, - taxline: function () { - if (this.$root.display_net_prices) { - if (this.price.includes_mixed_tax_rate) { - return strings.tax_plus_mixed; - } else { - return django.interpolate(strings.tax_plus, { - 'rate': autofloatformat(this.price.rate, 2), - 'taxname': this.price.name - }, true); - } - } else { - if (this.price.includes_mixed_tax_rate) { - return strings.tax_incl_mixed; - } else { - return django.interpolate(strings.tax_incl, { - 'rate': autofloatformat(this.price.rate, 2), - 'taxname': this.price.name - }, true); - } - } - } - } -}); -Vue.component('variation', { - template: ('
' - + '
' - - // Variation description - + '
' - + '
' - + '{{ variation.value }}' - + '
' - + '

' - + '{{ quota_left_str }}' - + '

' - + '
' - + '
' - - // Price - + '
' - + '' - + '' - + ' ' - + '
' - - // Availability - + '
' - + '' - + '
' - - + '
' - + '
' - + '
'), - props: { - variation: Object, - item: Object, - category: Object, - }, - computed: { - orig_price: function () { - if (this.variation.original_price) { - return this.variation.original_price; - } - return this.item.original_price; - }, - quota_left_str: function () { - return django.interpolate(strings["quota_left"], [this.variation.avail[1]]); - }, - variation_label_id: function () { - return this.$root.html_id + '-variation-label-' + this.item.id + '-' + this.variation.id; - }, - variation_desc_id: function () { - return this.$root.html_id + '-variation-desc-' + this.item.id + '-' + this.variation.id; - }, - variation_price_id: function () { - return this.$root.html_id + '-variation-price-' + this.item.id + '-' + this.variation.id; - }, - aria_labelledby: function () { - return [this.variation_label_id, this.variation_price_id].join(" "); - }, - headingLevel: function () { - return this.category.name ? '5' : '4'; - }, - } -}); -Vue.component('item', { - template: ('
' - + '
' - - // Product description - + '
' - + '' - + '
' - + '' - + '{{ item.name }}' - + '' - + '{{ item.name }}' - + '
' - + '

' - + '{{ min_order_str }}' - + '

' - + '

' - + '{{ quota_left_str }}' - + '

' - + '
' - + '
' - - // Price - + '
' - + '' - + '' - + '
' - + ' ' - + '
' - - // Availability - + '
' - + '{{ variationsToggleLabel }}' - + '' - + '
' - - + '
' - + '
' - - // Variations - + '
' - + '' - + '' - + '
' - - + '
'), - props: { - item: Object, - category: Object, - }, - data: function () { - return { - expanded: this.$root.show_variations_expanded - }; - }, - mounted: function () { - if (this.$refs.variations) { - if (!this.expanded) { - var $this = this; - this.$refs.variations.hidden = true; - this.$refs.variations.addEventListener('transitionend', function (event) { - if (event.target == this) { - this.hidden = !$this.expanded; - this.style.maxHeight = 'none'; - } - }); - this.$watch('expanded', function (newValue) { - var v = this.$refs.variations; - v.hidden = false; - v.style.maxHeight = (newValue ? 0 : v.scrollHeight) + 'px'; - // Vue.nextTick does not work here - window.setTimeout(function () { - v.style.maxHeight = (!newValue ? 0 : v.scrollHeight) + 'px'; - }, 50); - }) - } - } - }, - methods: { - expand: function () { - this.expanded = !this.expanded; - }, - lightbox: function () { - this.$root.overlay.lightbox = { - image: this.item.picture_fullsize, - description: this.item.name, - } - } - }, - computed: { - classObject: function () { - return { - 'pretix-widget-item': true, - 'pretix-widget-item-with-picture': !!this.item.picture, - 'pretix-widget-item-with-variations': this.item.has_variations - } - }, - varClasses: function () { - return { - 'pretix-widget-item-variations': true, - 'pretix-widget-item-variations-expanded': this.expanded, - } - }, - picture_alt_text: function () { - return django.interpolate(strings["image_of"], [this.item.name]); - }, - headingLevel: function () { - return this.category.name ? '4' : '3'; - }, - item_label_id: function () { - return this.$root.html_id + '-item-label-' + this.item.id; - }, - item_desc_id: function () { - return this.$root.html_id + '-item-desc-' + this.item.id; - }, - item_price_id: function () { - return this.$root.html_id + '-item-price-' + this.item.id; - }, - aria_labelledby: function () { - return [this.item_label_id, this.item_price_id].join(" "); - }, - min_order_str: function () { - return django.interpolate(strings["order_min"], [this.item.order_min]); - }, - quota_left_str: function () { - return django.interpolate(strings["quota_left"], [this.item.avail[1]]); - }, - show_toggle: function () { - return this.item.has_variations && !this.$root.show_variations_expanded; - }, - pricerange: function () { - if (this.item.free_price) { - return django.interpolate(strings.price_from, { - 'currency': this.$root.currency, - 'price': floatformat(this.item.min_price, 2) - }, true).replace(this.$root.currency, '' + this.$root.currency + ''); - } else if (this.item.min_price !== this.item.max_price) { - return '' + this.$root.currency + " " - + floatformat(this.item.min_price, 2) + " – " - + floatformat(this.item.max_price, 2); - } else if (this.item.min_price === "0.00" && this.item.max_price === "0.00") { - if (this.item.mandatory_priced_addons) { - return "\xA0"; // nbsp, because an empty string would cause the HTML element to collapse - } - return strings.free; - } else { - return '' + this.$root.currency + " " + floatformat(this.item.min_price, 2); - } - }, - variationsToggleLabel: function () { - return this.expanded ? strings.hide_variations : strings.variations; - }, - } -}); -Vue.component('category', { - template: ('
' - + '

{{ category.name }}

' - + '
' - + '
' - + '
' - + '' - + '
' - + '
'), - props: { - category: Object - } -}); - -var shared_methods = { - buy: function (event) { - if (this.$root.useIframe) { - if (event) { - event.preventDefault(); - } - } else { - return; - } - if (this.$root.is_button && this.$root.items.length === 0) { - if (this.$root.voucher_code) { - this.voucher_open(this.$root.voucher_code); - } else { - this.resume(); - } - } else { - var url = this.$root.formAction + "&locale=" + lang + "&ajax=1"; - this.$root.overlay.frame_loading = true; - - this.async_task_interval = 100; - var form = this.$refs.form; - if (form === undefined) { - form = this.$refs.formcomp.$refs.form; - } - api._postFormJSON(url, form, this.buy_callback, this.buy_error_callback); - } - }, - buy_error_callback: function (xhr, data) { - if (xhr.status === 429 && typeof xhr.responseURL !== "undefined") { - this.$root.overlay.error_message = strings['cart_error_429']; - this.$root.overlay.frame_loading = false; - this.$root.overlay.error_url_after = this.$root.newTabTarget; - this.$root.overlay.error_url_after_new_tab = true; - return; - } - if (xhr.status === 405 && typeof xhr.responseURL !== "undefined") { - // Likely a redirect! - this.$root.target_url = xhr.responseURL.substr(0, xhr.responseURL.indexOf("/cart/add") - 18); - this.$root.overlay.frame_loading = false; - this.buy(); - return; - } - this.$root.overlay.error_message = strings['cart_error']; - this.$root.overlay.frame_loading = false; - }, - buy_check_error_callback: function (xhr, data) { - if (xhr.status == 200 || (xhr.status >= 400 && xhr.status < 500)) { - this.$root.overlay.error_message = strings['cart_error']; - this.$root.overlay.frame_loading = false; - } else { - this.async_task_timeout = window.setTimeout(this.buy_check, 1000); - } - }, - buy_callback: function (data) { - if (data.redirect) { - if (data.cart_id) { - this.$root.cart_id = data.cart_id; - setCookie(this.$root.cookieName, data.cart_id, 30); - } - if (data.redirect.substr(0, 1) === '/') { - data.redirect = this.$root.target_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.redirect; - } - var url = data.redirect; - if (url.indexOf('?')) { - url = url + '&iframe=1&locale=' + lang + '&take_cart_id=' + this.$root.cart_id; - } else { - url = url + '?iframe=1&locale=' + lang + '&take_cart_id=' + this.$root.cart_id; - } - url += this.$root.consent_parameter; - if (this.$root.additionalURLParams) { - url += '&' + this.$root.additionalURLParams; - } - if (data.success === false) { - url = url.replace(/checkout\/start/g, ""); - this.$root.overlay.error_message = data.message; - if (data.has_cart) { - this.$root.overlay.error_url_after = url; - } - this.$root.overlay.frame_loading = false; - } else { - this.$root.overlay.frame_src = url; - } - } else { - this.async_task_id = data.async_id; - if (data.check_url) { - this.async_task_check_url = this.$root.target_url.replace(/^([^\/]+:\/\/[^\/]+)\/.*$/, "$1") + data.check_url; - } - this.async_task_timeout = window.setTimeout(this.buy_check, this.async_task_interval); - this.async_task_interval = 250; - } - }, - buy_check: function () { - api._getJSON(this.async_task_check_url, this.buy_callback, this.buy_check_error_callback); - }, - redeem: function (event) { - if (this.$root.useIframe) { - event.preventDefault(); - this.voucher_open(this.voucher); - } - }, - voucher_open: function (voucher) { - var redirect_url = this.$root.voucherFormTarget + '&voucher=' + encodeURIComponent(voucher); - if (this.$root.useIframe) { - this.$root.overlay.frame_src = redirect_url; - } else { - window.open(redirect_url); - } - }, - resume: function () { - var redirect_url; - redirect_url = this.$root.target_url + 'w/' + widget_id + '/'; - if (this.$root.subevent && !this.$root.cart_id) { - // button with subevent but no items - redirect_url += this.$root.subevent + '/'; - } - redirect_url += '?iframe=1&locale=' + lang; - if (this.$root.cart_id) { - redirect_url += '&take_cart_id=' + this.$root.cart_id; - } - if (this.$root.widget_data) { - redirect_url += '&widget_data=' + encodeURIComponent(this.$root.widget_data_json); - } - redirect_url += this.$root.consent_parameter; - if (this.$root.additionalURLParams) { - redirect_url += '&' + this.$root.additionalURLParams; - } - if (this.$root.useIframe) { - this.$root.overlay.frame_src = redirect_url; - } else { - window.open(redirect_url); - } - }, -}; - -var shared_widget_data = function () { - return { - async_task_id: null, - async_task_check_url: null, - async_task_timeout: null, - async_task_interval: 100, - voucher: null, - mobile: false, - } -}; - -var shared_loading_fragment = ( - '
' - + '' - + '
' -); - -var shared_iframe_fragment = ( - '
' - + '
' - + '' - + '
' - + '
' - + '' - + '' - + '
' - + '
' -); - -var shared_alert_fragment = ( - '
' - + '' - + '
' - + '

{{ $root.error_message }}

' - + '

' - + '

' - + '
' - + '
' - + '' - + '
' -); - -var shared_lightbox_fragment = ( - '
' - + '
' - + '' - + '
' - + '
' - + '
' - + '' - + '
{{$root.lightbox.description}}
' - + '
' - + '' - + '
' - + '
' -); - -Vue.component('pretix-overlay', { - template: ('
' - + shared_iframe_fragment - + shared_alert_fragment - + shared_lightbox_fragment - + '
' - ), - watch: { - '$root.lightbox': function (newValue, oldValue) { - if (newValue) { - if (newValue.image != oldValue?.image) { - this.$set(newValue, "loading", true); - } - if (!oldValue) { - window.addEventListener('keyup', this.lightboxCloseOnKeyup); - } - } else { - window.removeEventListener('keyup', this.lightboxCloseOnKeyup); - } - } - }, - computed: { - frameClasses: function () { - return { - 'pretix-widget-frame-holder': true, - 'pretix-widget-frame-shown': this.$root.frame_shown || this.$root.frame_loading, - }; - }, - alertClasses: function () { - return { - 'pretix-widget-alert-holder': true, - 'pretix-widget-alert-shown': this.$root.error_message, - }; - }, - lightboxClasses: function () { - return { - 'pretix-widget-lightbox-holder': true, - 'pretix-widget-lightbox-shown': this.$root.lightbox, - 'pretix-widget-lightbox-isloading': this.$root.lightbox?.loading, - }; - }, - }, - methods: { - lightboxCloseOnKeyup: function (event) { - if (event.keyCode === 27) { - // abort on ESC-key - this.lightboxClose(); - } - }, - lightboxClose: function () { - this.$root.lightbox = null; - }, - lightboxLoaded: function () { - this.$root.lightbox.loading = false; - }, - errorClose: function () { - this.$root.error_message = null; - this.$root.error_url_after = null; - this.$root.error_url_after_new_tab = false; - }, - errorContinue: function () { - if (this.$root.error_url_after_new_tab) { - window.open(this.$root.error_url_after); - return; - } - this.$root.overlay.frame_src = this.$root.error_url_after; - this.$root.frame_loading = true; - this.$root.error_message = null; - this.$root.error_url_after = null; - }, - close: function () { - this.$root.frame_shown = false; - this.$root.parent.frame_dismissed = true; - this.$root.frame_src = ""; - this.$root.parent.reload(); - this.$root.parent.trigger_close_callback(); - }, - iframeLoaded: function () { - if (this.$root.frame_loading) { - this.$root.frame_loading = false; - if (this.$root.frame_src) { - this.$root.frame_shown = true; - } - } - }, - focusButton: function () { - this.$el.querySelector(".pretix-widget-alert-box button").focus(); - }, - - } -}); - -Vue.component('pretix-widget-event-form', { - template: ('
' - // Back navigation - + '
' - + '‹ ' - + strings['back_to_list'] - + '' - + '‹ ' - + strings['back_to_dates'] - + '' - + '
' - - // Event name - + '
' - + '{{ $root.name }}' - + '
' - - // Date range - + '
' - + '{{ $root.date_range }}' - + '
' - - // Location - + '
' - - // Form start - + '
' - + '
' - + '' - + '' - + '' - + '' - - // Error message - + '
{{ $root.error }}
' - - // Resume cart - + '
' - + '' - + '' + strings['cart_exists'] + '' - + '
' - + '
' - - // Seating plan - + '' - - // Waiting list for seating plan - + '
' - + '
' - + strings['seating_plan_waiting_list'] - + '
' - + '
' - + '' - + '
' - + '
' - + '
' - - // Actual product list - + '' - - // Buy button - + '
' - + '' - + '
' - - + '
' - - // Voucher form - + '
' - + '
' - + '

'+ strings['redeem_voucher'] +'

' - + '
' - + '
' - + '' - + '
' - + '' - + '
' - + '' - + '
' - + '
' - + '
' - + '
' - - + '
' - ), - mounted: function() { - this.$root.$on('focus_voucher_field', this.focus_voucher_field) - }, - beforeDestroy: function() { - this.$root.$off('focus_voucher_field', this.focus_voucher_field) - }, - computed: { - aria_labelledby: function() { - return this.$root.html_id + '-voucher-headline'; - }, - display_event_info: function () { - return this.$root.display_event_info || (this.$root.display_event_info === null && (this.$root.events || this.$root.weeks || this.$root.days)); - }, - id_cart_exists_msg: function () { - return this.$root.html_id + '-cart-exists'; - }, - buy_label: function () { - var i, j, k, all_free = true; - for (i = 0; i < this.$root.categories.length; i++) { - var cat = this.$root.categories[i]; - for (j = 0; j < cat.items.length; j++) { - var item = cat.items[j]; - for (k = 0; k < item.variations.length; k++) { - var v = item.variations[k]; - if (v.price.gross !== "0.00") { - all_free = false; - break; - } - } - if ((item.variations.length === 0 && item.price.gross !== "0.00") || item.mandatory_priced_addons) { - all_free = false; - break; - } - } - if (!all_free) { - break; - } - } - if (all_free) { - return strings.register; - } else { - return strings.buy; - } - }, - hiddenParams: function () { - var params = new URL(this.$root.voucherFormTarget).searchParams; - params.delete("iframe"); - params.delete("take_cart_id"); - return [...params.entries()]; - }, - }, - methods: { - focus_voucher_field: function() { - this.$refs.voucherinput.scrollIntoView(false) - this.$refs.voucherinput.focus() - }, - 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; - this.$root.trigger_load_callback(); - if (this.$root.events !== undefined && this.$root.events !== null) { - this.$root.view = "events"; - } else if (this.$root.days !== undefined && this.$root.days !== null) { - this.$root.view = "days"; - } 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(); - }); - }, - } -}); - -Vue.component('pretix-widget-event-list-filter-field', { - template: ('
' - + '' - + '' - + '
'), - props: { - field: Object - }, - methods: { - onChange: function(event) { - var filterParams = new URLSearchParams(this.$root.filter); - if (event.target.value) { - filterParams.set(this.field.key, event.target.value); - } else { - filterParams.delete(this.field.key); - } - this.$root.filter = filterParams.toString(); - this.$root.loading++; - this.$root.reload(); - }, - }, - computed: { - id: function () { - return widget_id + "_" + this.field.key; - }, - currentValue: function () { - var filterParams = new URLSearchParams(this.$root.filter); - return filterParams.get(this.field.key) || ""; - }, - }, -}); - -Vue.component('pretix-widget-event-list-filter-form', { - template: ('
' - + '' - + '
'), -}); - -Vue.component('pretix-widget-event-list-entry', { - template: ('' - + '
{{ event.name }}
' - + '
{{ event.date_range }}
' - + '
{{ location }}
' // hidden by css for now, but - // used by a few people - + '
{{ event.availability.text }}
' - + '
'), - props: { - event: Object - }, - computed: { - classObject: function () { - var o = { - 'pretix-widget-event-list-entry': true - }; - o['pretix-widget-event-availability-' + this.event.availability.color] = true; - if (this.event.availability.reason) { - o['pretix-widget-event-availability-' + this.event.availability.reason] = true; - } - return o - }, - location: function () { - return this.event.location.replace(/\s*\n\s*/g, ', '); - } - }, - methods: { - select: function () { - this.$root.parent_stack.push(this.$root.target_url); - this.$root.target_url = this.event.event_url; - this.$root.error = null; - this.$root.subevent = this.event.subevent; - this.$root.loading++; - this.$root.reload(); - } - } -}); - -Vue.component('pretix-widget-event-list', { - template: ('
' - + '
' - + '' - + '
' - + '
' - + '{{ $root.name }}' - + '
' - + '
' - + '' - + '' - + '

' - + '
'), - computed: { - display_event_info: function () { - return this.$root.display_event_info || (this.$root.display_event_info === null && this.$root.parent_stack.length > 0); - }, - }, - 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) { - this.$root.events = undefined; - this.$root.view = "weeks"; - this.$root.name = null; - this.$root.frontpage_text = null; - } else { - this.$root.loading++; - this.$root.target_url = this.$root.parent_stack.pop(); - this.$root.error = null; - this.$root.reload(); - } - }, - load_more: function () { - this.$root.append_events = true; - this.$root.offset += 50; - this.$root.loading++; - this.$root.reload(); - } - } -}); - -Vue.component('pretix-widget-event-calendar-event', { - template: ('' - + '' - + '{{ event.name }}' - + '' - + '
{{ event.time }}
' - + '
{{ event.availability.text }}
' - + '
'), - props: { - event: Object, - describedby: String, - }, - computed: { - classObject: function () { - var o = { - 'pretix-widget-event-calendar-event': true - }; - o['pretix-widget-event-availability-' + this.event.availability.color] = true; - if (this.event.availability.reason) { - o['pretix-widget-event-availability-' + this.event.availability.reason] = true; - } - return o - } - }, - methods: { - select: function () { - this.$root.parent_stack.push(this.$root.target_url); - this.$root.target_url = this.event.event_url; - this.$root.error = null; - this.$root.subevent = this.event.subevent; - this.$root.loading++; - this.$root.reload(); - } - } -}); - -Vue.component('pretix-widget-event-week-cell', { - template: ('
' - + '
' - + '{{ dayhead }}' - + '
' - + '
' - + '' - + '
' - + '
'), - props: { - day: Object, - }, - methods: { - selectDay: function () { - if (!this.day || !this.day.events.length || !this.$parent.$parent.$parent.mobile) { - return; - } - if (this.day.events.length === 1) { - var ev = this.day.events[0]; - this.$root.parent_stack.push(this.$root.target_url); - this.$root.target_url = ev.event_url; - this.$root.error = null; - this.$root.subevent = ev.subevent; - this.$root.loading++; - this.$root.reload(); - } else { - this.$root.events = this.day.events; - this.$root.view = "events"; - } - } - }, - computed: { - id: function () { - return this.day ? this.$root.html_id + '-' + this.day.date : ''; - }, - dayhead: function () { - if (!this.day) { - return; - } - return this.day.day_formatted; - }, - classObject: function () { - var o = {}; - if (this.day && this.day.events.length > 0) { - o['pretix-widget-has-events'] = true; - var best = 'red'; - var all_low = true; - for (var i = 0; i < this.day.events.length; i++) { - var ev = this.day.events[i]; - if (ev.availability.color === 'green') { - best = 'green'; - if (ev.availability.reason !== 'low') { - all_low = false; - } - } else if (ev.availability.color === 'orange' && best !== 'green') { - best = 'orange' - } - } - o['pretix-widget-day-availability-' + best] = true; - if (best === 'green' && all_low) { - o['pretix-widget-day-availability-low'] = true; - } - } - return o - } - } -}); - -Vue.component('pretix-widget-event-calendar-cell', { - template: ('' - + '
' - + '{{ daynum }}' - + '
' - + '
' - + '' - + '
' - + ''), - props: { - day: Object, - }, - methods: { - selectDay: function (e) { - if (!this.day || !this.day.events.length || !this.$parent.$parent.$parent.mobile) { - return; - } - e.preventDefault(); - e.stopPropagation(); - if (this.day.events.length === 1) { - var ev = this.day.events[0]; - this.$root.parent_stack.push(this.$root.target_url); - this.$root.target_url = ev.event_url; - this.$root.error = null; - this.$root.subevent = ev.subevent; - this.$root.loading++; - this.$root.reload(); - } else { - this.$root.events = this.day.events; - this.$root.view = "events"; - } - }, - onKeyDown: function (e) { - var keyDown = e.key !== undefined ? e.key : e.keyCode; - if ( (keyDown === 'Enter' || keyDown === 13) || (['Spacebar', ' '].indexOf(keyDown) >= 0 || keyDown === 32)) { - // (prevent default so the page doesn't scroll when pressing space) - e.preventDefault(); - this.selectDay(e); - } - }, - }, - mounted: function () { - if (this.role == 'button') { - this.$el.addEventListener("click", this.selectDay); - this.$el.addEventListener("keydown", this.onKeyDown); - } - }, - watch: { - role: function (newValue) { - if (newValue == 'button') { - this.$el.addEventListener("click", this.selectDay); - this.$el.addEventListener("keydown", this.onKeyDown); - } else { - this.$el.removeEventListener("click", this.selectDay); - this.$el.removeEventListener("keydown", this.onKeyDown); - } - } - }, - computed: { - role: function () { - return (!this.day || !this.day.events.length || !this.$parent.$parent.$parent.mobile) ? 'cell' : 'button'; - }, - tabindex: function () { - return this.role == 'button' ? '0' : '-1'; - }, - daynum: function () { - if (!this.day) { - return; - } - 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) { - o['pretix-widget-has-events'] = true; - var best = 'red'; - var all_low = true; - for (var i = 0; i < this.day.events.length; i++) { - var ev = this.day.events[i]; - if (ev.availability.color === 'green') { - best = 'green'; - if (ev.availability.reason !== 'low') { - all_low = false; - } - } else if (ev.availability.color === 'orange' && best !== 'green') { - best = 'orange' - } - } - o['pretix-widget-day-availability-' + best] = true; - if (best === 'green' && all_low) { - o['pretix-widget-day-availability-low'] = true; - } - } - return o - } - } -}); - -Vue.component('pretix-widget-event-calendar-row', { - template: ('' - + '' - + ''), - props: { - week: Array - }, -}); - -Vue.component('pretix-widget-event-calendar', { - template: ('
' - - // Back navigation - + '
' - + '‹ ' - + strings['back'] - + '' - + '
' - - // Headline - + '
' - + '{{ $root.name }}' - + '
' - + '
' - - // Filter - + '' - - // Calendar navigation - + '
' - + '« ' - + strings['previous_month'] - + ' ' - + '{{ monthname }} ' - + '' - + strings['next_month'] - + ' »' - + '
' - - // Calendar - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '
' + strings['days']['MO'] + '' + strings['days']['TU'] + '' + strings['days']['WE'] + '' + strings['days']['TH'] + '' + strings['days']['FR'] + '' + strings['days']['SA'] + '' + strings['days']['SU'] + '
' - + '
'), - computed: { - display_event_info: function () { - return this.$root.display_event_info || (this.$root.display_event_info === null && this.$root.parent_stack.length > 0); - }, - 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 () { - this.$root.weeks = undefined; - this.$root.view = "events"; - this.$root.name = null; - this.$root.frontpage_text = null; - }, - prevmonth: function () { - var curMonth = parseInt(this.$root.date.substr(5, 2)); - var curYear = parseInt(this.$root.date.substr(0, 4)); - curMonth--; - if (curMonth < 1) { - curMonth = 12; - curYear--; - } - this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01"; - this.$root.loading++; - this.$root.reload({focus: '#'+this.id}); - }, - nextmonth: function () { - var curMonth = parseInt(this.$root.date.substr(5, 2)); - var curYear = parseInt(this.$root.date.substr(0, 4)); - curMonth++; - if (curMonth > 12) { - curMonth = 1; - curYear++; - } - this.$root.date = String(curYear) + "-" + padNumber(curMonth, 2) + "-01"; - this.$root.loading++; - this.$root.reload({focus: '#'+this.id}); - } - }, -}); - -Vue.component('pretix-widget-event-week-calendar', { - template: ('
' - // Back navigation - + '
' - + '‹ ' - + strings['back'] - + '' - + '
' - - // Event header - + '
' - + '{{ $root.name }}' - + '
' - - // Filter - + '' - - // Calendar navigation - + '
' - + '
' - + '« ' - + strings['previous_week'] - + ' ' - + '{{ weekname }} ' - + '' - + strings['next_week'] - + ' »' - + '
' - - // Actual calendar - + '
' - + '
' - + '' - + '' - + '
' - + '
' - - + '
' - + ''), - computed: { - display_event_info: function () { - return this.$root.display_event_info || (this.$root.display_event_info === null && this.$root.parent_stack.length > 0); - }, - weekname: function () { - var curWeek = this.$root.week[1]; - var curYear = this.$root.week[0]; - return curWeek + ' / ' + curYear; - }, - id: function () { - return this.$root.html_id + "-event-week-table"; - }, - }, - methods: { - back_to_list: function () { - this.$root.weeks = undefined; - this.$root.name = null; - this.$root.frontpage_text = null; - this.$root.view = "events"; - }, - prevweek: function () { - var curWeek = this.$root.week[1]; - var curYear = this.$root.week[0]; - curWeek--; - if (curWeek < 1) { - curYear--; - curWeek = getISOWeeks(curYear); - } - this.$root.week = [curYear, curWeek]; - this.$root.loading++; - this.$root.reload({focus: '#'+this.id}); - }, - nextweek: function () { - var curWeek = this.$root.week[1]; - var curYear = this.$root.week[0]; - curWeek++; - if (curWeek > getISOWeeks(curYear)) { - curWeek = 1; - curYear++; - } - this.$root.week = [curYear, curWeek]; - this.$root.loading++; - this.$root.reload({focus: '#'+this.id}); - } - }, -}); - -Vue.component('pretix-widget', { - template: ('
' - + '
' - + shared_loading_fragment - + '
{{ $root.error }}
' - + '' - + '' - + '' - + '' - + '' - + '
' - + '
' - + '
' - + '
' - + '
' - + '' - ), - data: shared_widget_data, - methods: shared_methods, - mounted: function () { - var thisObj = this; - if ("ResizeObserver" in window) { - var resizeObserver = new ResizeObserver(function(entries) { - thisObj.mobile = entries[0].contentRect.width <= 800; - }); - resizeObserver.observe(this.$refs.wrapper); - } else { - this.mobile = this.$refs.wrapper.clientWidth <= 800; - var debounce; - window.addEventListener("resize", function() { - if (debounce) clearTimeout(debounce); - debounce = setTimeout(function () { - thisObj.mobile = thisObj.$refs.wrapper.clientWidth <= 800; - }, 100); - }); - } - }, - computed: { - classObject: function () { - return { - 'pretix-widget': true, - 'pretix-widget-mobile': this.mobile, - 'pretix-widget-use-custom-spinners': !this.$root.use_native_spinners - }; - } - } -}); - -Vue.component('pretix-button', { - template: ('
' - + '
' - + '
' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '' - + '
' - + '
' - + '
' - + '
' - + '' - ), - data: shared_widget_data, - methods: shared_methods, -}); - -/* Function to create the actual Vue instances */ - -var shared_root_methods = { - open_link_in_frame: function (event) { - var url = event.target.attributes.href.value; - if (this.$root.additionalURLParams) { - if (url.indexOf('?')) { - url += '&' + this.$root.additionalURLParams; - } else { - url += '?' + this.$root.additionalURLParams; - } - } - if (this.$root.useIframe) { - event.preventDefault(); - if (url.indexOf('?')) { - url += '&iframe=1'; - } else { - url += '?iframe=1'; - } - this.$root.overlay.frame_src = url; - } else { - event.target.href = url; - return; - } - }, - trigger_load_callback: function () { - this.$nextTick(function () { - for (var i = 0; i < window.PretixWidget._loaded.length; i++) { - window.PretixWidget._loaded[i]() - } - }); - }, - trigger_close_callback: function () { - this.$nextTick(function () { - for (var i = 0; i < window.PretixWidget._closed.length; i++) { - window.PretixWidget._closed[i]() - } - }); - }, - reload: function (opt = {}) { - var url; - if (this.$root.is_button) { - return; - } - if (this.$root.subevent) { - url = this.$root.target_url + this.$root.subevent + '/widget/product_list?lang=' + lang; - } else { - url = this.$root.target_url + 'widget/product_list?lang=' + lang; - } - if (this.$root.offset) { - url += '&offset=' + this.$root.offset; - } - if (this.$root.filter) { - url += '&' + this.$root.filter; - } - if (this.$root.item_filter) { - url += '&items=' + encodeURIComponent(this.$root.item_filter); - } - if (this.$root.category_filter) { - url += '&categories=' + encodeURIComponent(this.$root.category_filter); - } - if (this.$root.variation_filter) { - url += '&variations=' + encodeURIComponent(this.$root.variation_filter); - } - var cart_id = getCookie(this.cookieName); - if (this.$root.voucher_code) { - url += '&voucher=' + encodeURIComponent(this.$root.voucher_code); - } - if (cart_id) { - url += "&cart_id=" + encodeURIComponent(cart_id); - } - if (this.$root.date !== null) { - url += "&date=" + this.$root.date.substr(0, 7); - } else if (this.$root.week !== null) { - url += "&date=" + this.$root.week[0] + "-W" + this.$root.week[1]; - } - if (this.$root.style !== null) { - url = url + '&style=' + encodeURIComponent(this.$root.style); - } - var root = this.$root; - api._getJSON(url, function (data, xhr) { - if (typeof xhr.responseURL !== "undefined") { - var new_url = xhr.responseURL.substr(0, xhr.responseURL.indexOf("/widget/product_list?") + 1); - var old_url = url.substr(0, url.indexOf("/widget/product_list?") + 1); - if (new_url !== old_url) { - if (root.subevent) { - new_url = new_url.substr(0, new_url.lastIndexOf("/", new_url.length - 1) + 1); - } - root.target_url = new_url; - root.reload(); - return; - } - } - root.connection_error = false; - if (data.weeks !== undefined) { - root.weeks = data.weeks; - root.date = data.date; - root.week = null; - root.events = undefined; - root.view = "weeks"; - root.name = data.name; - root.frontpage_text = data.frontpage_text; - root.meta_filter_fields = data.meta_filter_fields; - } else if (data.days !== undefined) { - root.days = data.days; - root.date = null; - root.week = data.week; - root.events = undefined; - root.view = "days"; - root.name = data.name; - root.frontpage_text = data.frontpage_text; - root.meta_filter_fields = data.meta_filter_fields; - } else if (data.events !== undefined) { - root.events = root.append_events && root.events ? root.events.concat(data.events) : data.events; - root.append_events = false; - root.weeks = undefined; - root.view = "events"; - root.name = data.name; - root.frontpage_text = data.frontpage_text; - root.has_more_events = data.has_more_events; - root.meta_filter_fields = data.meta_filter_fields; - } else { - root.view = "event"; - // Replace target_url and subevent with canonical values in case they were slightly wrong - root.target_url = data.target_url; - root.subevent = data.subevent; - // Event data - root.name = data.name; - root.frontpage_text = data.frontpage_text; - root.date_range = data.date_range; - root.location = data.location; - root.categories = data.items_by_category; - root.currency = data.currency; - root.display_net_prices = data.display_net_prices; - root.use_native_spinners = data.use_native_spinners; - root.voucher_explanation_text = data.voucher_explanation_text; - root.error = data.error; - root.display_add_to_cart = data.display_add_to_cart; - root.waiting_list_enabled = data.waiting_list_enabled; - root.show_variations_expanded = data.show_variations_expanded || !!root.variation_filter; - root.cart_id = cart_id; - root.cart_exists = data.cart_exists; - root.vouchers_exist = data.vouchers_exist; - root.has_seating_plan = data.has_seating_plan; - root.has_seating_plan_waitinglist = data.has_seating_plan_waitinglist; - root.itemnum = data.itemnum; - } - root.poweredby = data.poweredby; - if (root.loading > 0) { - root.loading--; - root.trigger_load_callback(); - } - if (root.parent_stack.length > 0 && root.has_seating_plan && root.categories.length === 0 && !root.frame_dismissed && root.useIframe && !root.error && !root.has_seating_plan_waitinglist) { - // 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 = []; - root.currency = ''; - if (error.status === 429) { - root.error = strings['loading_error_429']; - root.connection_error = true; - } else { - root.error = strings['loading_error']; - root.connection_error = true; - } - if (root.loading > 0) { - root.loading--; - root.trigger_load_callback(); - } - }); - }, - startwaiting: function () { - var redirect_url = this.$root.target_url + 'w/' + widget_id + '/waitinglist/?iframe=1&locale=' + lang; - if (this.$root.subevent){ - redirect_url += '&subevent=' + this.$root.subevent; - } - if (this.$root.additionalURLParams) { - redirect_url += '&' + this.$root.additionalURLParams; - } - if (this.$root.useIframe) { - this.$root.overlay.frame_src = redirect_url; - } else { - window.open(redirect_url); - } - }, - startseating: function () { - var redirect_url = this.$root.target_url + 'w/' + widget_id; - if (this.$root.subevent){ - redirect_url += '/' + this.$root.subevent; - } - redirect_url += '/seatingframe/?iframe=1&locale=' + lang; - if (this.$root.voucher_code) { - redirect_url += '&voucher=' + encodeURIComponent(this.$root.voucher_code); - } - if (this.$root.cart_id) { - redirect_url += '&take_cart_id=' + this.$root.cart_id; - } - if (this.$root.widget_data) { - redirect_url += '&widget_data=' + encodeURIComponent(this.$root.widget_data_json); - } - if (this.$root.additionalURLParams) { - redirect_url += '&' + this.$root.additionalURLParams; - } - redirect_url += this.$root.consent_parameter; - if (this.$root.useIframe) { - this.$root.overlay.frame_src = redirect_url; - } else { - window.open(redirect_url); - } - }, - choose_event: function (event) { - this.$root.target_url = event.event_url; - this.$root.error = null; - this.$root.connection_error = false; - this.$root.subevent = event.subevent; - this.$root.loading++; - this.$root.reload(); - } -}; - -var shared_root_computed = { - cookieName: function () { - return "pretix_widget_" + this.target_url.replace(/[^a-zA-Z0-9]+/g, "_"); - }, - formTarget: function () { - var is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; - var is_android = navigator.userAgent.toLowerCase().indexOf("android") > -1; - if (is_android && is_firefox) { - // Opening a POST form in a new browser fails in Firefox. This is supposed to be fixed since FF 76 - // but for some reason, it is still the case in FF for Android. - // https://bugzilla.mozilla.org/show_bug.cgi?id=1629441 - // https://github.com/pretix/pretix/issues/1040 - return "_top"; - } else { - return "_blank"; - } - }, - voucherFormTarget: function () { - var form_target = this.target_url + 'w/' + widget_id + '/redeem?iframe=1&locale=' + lang; - var cookie = getCookie(this.cookieName); - if (cookie) { - form_target += "&take_cart_id=" + cookie; - } - if (this.subevent) { - form_target += "&subevent=" + this.subevent; - } - if (this.$root.widget_data) { - form_target += '&widget_data=' + encodeURIComponent(this.$root.widget_data_json); - } - form_target += this.$root.consent_parameter; - if (this.$root.additionalURLParams) { - form_target += '&' + this.$root.additionalURLParams; - } - return form_target; - }, - formMethod: function () { - if (!this.useIframe && this.is_button && this.items.length === 0) { - return 'get'; - } - return 'post'; - }, - formAction: function () { - if (!this.useIframe && this.is_button && this.items.length === 0) { - var target; - if (this.voucher_code) { - target = this.target_url + 'redeem'; - } else if (this.subevent) { - target = this.target_url + this.subevent + '/'; - } else { - target = this.target_url; - } - return target; - } - var checkout_url = "/" + this.target_url.replace(/^[^\/]+:\/\/([^\/]+)\//, "") + "w/" + widget_id + "/"; - if (!this.$root.cart_exists) { - checkout_url += "checkout/start"; - } - if (this.$root.additionalURLParams) { - checkout_url += '?' + this.$root.additionalURLParams; - } - var form_target = this.target_url + 'w/' + widget_id + '/cart/add?iframe=1&next=' + encodeURIComponent(checkout_url); - var cookie = getCookie(this.cookieName); - if (cookie) { - form_target += "&take_cart_id=" + cookie; - } - form_target += this.$root.consent_parameter - return form_target - }, - newTabTarget: function () { - var target = this.target_url; - if (this.subevent) { - target = this.target_url + this.subevent + '/'; - } - return target; - }, - useIframe: function () { - if (window.crossOriginIsolated === true) { - console.warn("pretix Widget cannot use iframe due to Cross-Origin-Embed-Policy") - return false; - } - return !this.disable_iframe && (this.skip_ssl || site_is_secure()); - }, - showPrices: function () { - var has_priced = false; - var cnt_items = 0; - for (var i = 0; i < this.categories.length; i++) { - for (var j = 0; j < this.categories[i].items.length; j++) { - var item = this.categories[i].items[j]; - if (item.has_variations) { - cnt_items += item.variations.length; - has_priced = true; - } else { - cnt_items++; - has_priced = has_priced || item.price.gross != "0.00" || item.free_price; - } - } - } - return has_priced || cnt_items > 1; - }, - consent_parameter_value: function () { - if (typeof this.widget_data["consent"] !== "undefined") { - return encodeURIComponent(this.widget_data["consent"]); - } - return ""; - }, - consent_parameter: function () { - if (typeof this.widget_data["consent"] !== "undefined") { - return "&consent=" + encodeURIComponent(this.widget_data["consent"]); - } - return ""; - }, - widget_data_json: function () { - var cloned_data = Object.assign({}, this.widget_data); - if (typeof cloned_data["consent"] !== "undefined") { - // Remove consent as we pass it differently. We still keep it as widget_data in the input to avoid breaking - // the JS API of the widget. - delete cloned_data["consent"]; - } - return JSON.stringify(cloned_data); - }, - additionalURLParams: function () { - if (!window.location.search.indexOf('utm_')) { - return ''; - } - var params = new URLSearchParams(window.location.search); - for (var [key, value] of params.entries()) { - if (!key.startsWith('utm_')) { - params.delete(key); - } - } - return params.toString(); - }, -}; - -var create_overlay = function (app) { - var elem = document.createElement('pretix-overlay'); - document.body.appendChild(elem); - - var framechild = new Vue({ - el: elem, - data: function () { - return { - parent: app, - frame_loading: false, - frame_shown: false, - error_url_after: null, - error_url_after_new_tab: true, - error_message: null, - lightbox: null, - prevActiveElement: null, - } - }, - props: { - frame_src: String, - }, - methods: { - }, - watch: { - frame_src: function (newValue, oldValue) { - // show loading spinner only when previously no frame_src was set - if (newValue && !oldValue) { - this.frame_loading = true; - } - // to close and unload the iframe, frame_src can be empty -> make it valid HTML with about:blank - this.$el.querySelector("iframe").src = newValue || "about:blank"; - }, - frame_shown: function (newValue) { - if (newValue) { - this.prevActiveElement = document.activeElement; - var btn = this.$el?.querySelector(".pretix-widget-frame-close a"); - this.$nextTick(function () { - btn?.focus(); - }); - } else { - this.prevActiveElement?.focus(); - } - }, - error_message: function (newValue) { - if (newValue) { - this.prevActiveElement = document.activeElement; - } else { - this.prevActiveElement?.focus(); - } - }, - } - }); - app.$root.overlay = framechild; -}; - -function get_ga_client_id(tracking_id) { - if (typeof ga === "undefined") { - return null; - } - try { - var trackers = ga.getAll(); - var i, len; - for (i = 0, len = trackers.length; i < len; i += 1) { - if (trackers[i].get('trackingId') === tracking_id) { - return trackers[i].get('clientId'); - } - } - } catch (e) { - } - return null; -} - -var create_widget = function (element, html_id=null) { - var target_url = element.attributes.event.value; - if (!target_url.match(/\/$/)) { - target_url += "/"; - } - var voucher = element.attributes.voucher ? element.attributes.voucher.value : null; - var subevent = element.attributes.subevent ? element.attributes.subevent.value : null; - var style = element.attributes["list-type"] ? element.attributes["list-type"].value : (element.attributes.style ? element.attributes.style.value : null); - var skip_ssl = element.attributes["skip-ssl-check"] ? true : false; - var disable_iframe = element.attributes["disable-iframe"] ? true : false; - var disable_vouchers = element.attributes["disable-vouchers"] ? true : false; - var disable_filters = element.attributes["disable-filters"] ? true : false; - var display_event_info = element.getAttribute("display-event-info"); // null means "auto" (as before), everything other than "false" is true - if (display_event_info !== null && display_event_info !== "auto") { - display_event_info = display_event_info !== "false"; - } else { - display_event_info = null; - } - var widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data)); - var filter = element.attributes.filter ? element.attributes.filter.value : null; - var items = element.attributes.items ? element.attributes.items.value : null; - var variations = element.attributes.variations ? element.attributes.variations.value : null; - var categories = element.attributes.categories ? element.attributes.categories.value : null; - var single_item_select = element.getAttribute("single-item-select") || "checkbox"; - for (var i = 0; i < element.attributes.length; i++) { - var attrib = element.attributes[i]; - if (attrib.name.match(/^data-.*$/)) { - widget_data[attrib.name.replace(/^data-/, '')] = attrib.value; - } - } - html_id = html_id || element.id || makeid(16); - - var observer = new MutationObserver((mutationList) => { - mutationList.forEach((mutation) => { - if (mutation.type == "attributes" && mutation.attributeName.startsWith("data-")) { - Vue.set(app.widget_data, mutation.attributeName.substring(5), mutation.target.getAttribute(mutation.attributeName)); - } - }); - }); - var observerOptions = { attributes: true }; - - if (element.tagName !== "pretix-widget") { - element.innerHTML = ""; - // we need to watch the container as well as the replaced root-node (see mounted()) - observer.observe(element, observerOptions); - } - - var app = new Vue({ - el: element, - data: function () { - return { - target_url: target_url, - parent_stack: [], - subevent: subevent, - is_button: false, - categories: null, - currency: null, - name: null, - date_range: null, - location: null, - offset: 0, - has_more_events: false, - append_events: false, - frontpage_text: null, - filter: filter, - item_filter: items, - category_filter: categories, - variation_filter: variations, - voucher_code: voucher, - display_net_prices: false, - use_native_spinners: false, - single_item_select: single_item_select, - voucher_explanation_text: null, - show_variations_expanded: !!variations, - skip_ssl: skip_ssl, - disable_iframe: disable_iframe, - style: style, - connection_error: false, - error: null, - weeks: null, - days: null, - date: null, - week: null, - frame_dismissed: false, - events: null, - view: null, - display_add_to_cart: false, - widget_data: widget_data, - loading: 1, - widget_id: 'pretix-widget-' + widget_id, - html_id: html_id, - vouchers_exist: false, - disable_vouchers: disable_vouchers, - disable_filters: disable_filters, - display_event_info: display_event_info, - cart_exists: false, - itemcount: 0, - overlay: null, - poweredby: "", - has_seating_plan: false, - has_seating_plan_waitinglist: false, - meta_filter_fields: [], - } - }, - created: function () { - this.reload(); - }, - mounted: function () { - observer.observe(this.$el, observerOptions); - }, - computed: shared_root_computed, - methods: shared_root_methods, - watch: { - 'view': function (newValue, oldValue) { - if (oldValue) { - // always make sure the widget is scrolled to the top - // as we only check top, we do not need to wait for a redraw - var rect = this.$el.getBoundingClientRect(); - if (rect.top < 0) { - this.$el.scrollIntoView(); - } - } - } - } - }); - create_overlay(app); - return app; -}; - -var create_button = function (element, html_id=null) { - var target_url = element.attributes.event.value; - if (!target_url.match(/\/$/)) { - target_url += "/"; - } - var voucher = element.attributes.voucher ? element.attributes.voucher.value : null; - var subevent = element.attributes.subevent ? element.attributes.subevent.value : null; - var raw_items = element.attributes.items ? element.attributes.items.value : ""; - var skip_ssl = element.attributes["skip-ssl-check"] ? true : false; - var disable_iframe = element.attributes["disable-iframe"] ? true : false; - var button_text = element.innerHTML; - var widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data)); - for (var i = 0; i < element.attributes.length; i++) { - var attrib = element.attributes[i]; - if (attrib.name.match(/^data-.*$/)) { - widget_data[attrib.name.replace(/^data-/, '')] = attrib.value; - } - } - html_id = html_id || element.id || makeid(16); - - var observer = new MutationObserver((mutationList) => { - mutationList.forEach((mutation) => { - if (mutation.type == "attributes" && mutation.attributeName.startsWith("data-")) { - Vue.set(app.widget_data, mutation.attributeName.substring(5), mutation.target.getAttribute(mutation.attributeName)); - } - }); - }); - var observerOptions = { attributes: true }; - - if (element.tagName !== "pretix-button") { - element.innerHTML = "" + element.innerHTML + ""; - // Vue does not replace the container, so watch container as well - observer.observe(element, observerOptions); - } - - var itemsplit = raw_items.split(","); - var items = []; - for (var i = 0; i < itemsplit.length; i++) { - if (itemsplit[i].indexOf("=") > 0 ) { - var splitthis = itemsplit[i].split("="); - items.push({'item': splitthis[0], 'count': splitthis[1]}) - } - } - - var app = new Vue({ - el: element, - data: function () { - return { - target_url: target_url, - subevent: subevent, - is_button: true, - skip_ssl: skip_ssl, - disable_iframe: disable_iframe, - voucher_code: voucher, - items: items, - error: null, - filter: null, - frame_dismissed: false, - widget_data: widget_data, - widget_id: 'pretix-widget-' + widget_id, - html_id: html_id, - button_text: button_text - } - }, - created: function () { - }, - mounted: function () { - observer.observe(this.$el, observerOptions); - }, - computed: shared_root_computed, - methods: shared_root_methods - }); - create_overlay(app); - return app; -}; - -/* Find all widgets on the page and render them */ -widgetlist = []; -buttonlist = []; -window.PretixWidget._loaded = []; -window.PretixWidget._closed = []; -window.PretixWidget.addLoadListener = function (f) { - window.PretixWidget._loaded.push(f); -} -window.PretixWidget.addCloseListener = function (f) { - window.PretixWidget._closed.push(f); -} -window.PretixWidget.buildWidgets = function () { - document.createElement("pretix-widget"); - document.createElement("pretix-button"); - docReady(function () { - var widgets = document.querySelectorAll("pretix-widget, div.pretix-widget-compat"); - var wlength = widgets.length; - for (var i = 0; i < wlength; i++) { - var widget = widgets[i]; - widgetlist.push(create_widget(widget, widget.id || "pretix-widget-"+i)); - } - - var buttons = document.querySelectorAll("pretix-button, div.pretix-button-compat"); - var blength = buttons.length; - for (var i = 0; i < blength; i++) { - var button = buttons[i]; - buttonlist.push(create_button(button, button.id || "pretix-button-"+i)); - } - }); -}; - -window.PretixWidget.open = function (target_url, voucher, subevent, items, widget_data, skip_ssl_check, disable_iframe) { - if (!target_url.match(/\/$/)) { - target_url += "/"; - } - - var all_widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data)); - if (widget_data) { - Object.keys(widget_data).forEach(function(key) { all_widget_data[key] = widget_data[key]; }); - } - var root = document.createElement("div"); - document.body.appendChild(root); - root.classList.add("pretix-widget-hidden"); - root.innerHTML = ""; - var app = new Vue({ - el: root, - data: function () { - return { - target_url: target_url, - subevent: subevent || null, - is_button: true, - skip_ssl: skip_ssl_check || false, - disable_iframe: disable_iframe || false, - voucher_code: voucher || null, - items: items || [], - error: null, - filter: null, - frame_dismissed: false, - widget_data: all_widget_data, - widget_id: 'pretix-widget-' + widget_id, - button_text: "" - } - }, - created: function () { - }, - computed: shared_root_computed, - methods: shared_root_methods - }); - create_overlay(app); - app.$nextTick(function () { - if (this.$root.useIframe) { - this.$refs.btn.buy(); - } else { - this.$refs.btn.$refs.form.submit(); - } - }) -}; - -if (typeof window.pretixWidgetCallback !== "undefined") { - window.pretixWidgetCallback(); -} -if (window.PretixWidget.build_widgets) { - window.PretixWidget.buildWidgets(); -} - -/* Set a global variable for debugging. In DEBUG mode, siteglobals will be window, otherwise it will be something - unnamed. */ -siteglobals.pretixwidget_debug = { - 'Vue': Vue, - 'widgets': widgetlist, - 'buttons': buttonlist -}; diff --git a/src/pretix/static/pretixpresale/scss/widget.v1.scss b/src/pretix/static/pretixpresale/scss/widget.v1.scss deleted file mode 100644 index 900b153691..0000000000 --- a/src/pretix/static/pretixpresale/scss/widget.v1.scss +++ /dev/null @@ -1,1088 +0,0 @@ -// not included, will be dynamically prepended @import "../../pretixbase/scss/_theme_variables.scss"; -@import "../../pretixbase/scss/_bootstrap_vars.scss"; -@import "../../bootstrap/scss/bootstrap/variables"; -@import "../../bootstrap/scss/bootstrap/mixins"; - -.pretix-widget-hidden { - display: none; -} -.pretix-widget, .pretix-widget-alert-box { - a { - color: $link-color; - text-decoration: none; - - &:hover, - &:focus { - color: $link-hover-color; - text-decoration: $link-hover-decoration; - } - &:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } - } - img { - border: 0; - } - b, strong { - font-weight: bold; - } - h3 { - font-size: $font-size-h3; - font-weight: bold; - padding: 0 15px; - } - button, input[type="button"], a.pretix-widget-button { - overflow: visible; - text-transform: none; - cursor: pointer; - display: inline-block; - margin-bottom: 0; - text-align: center; - vertical-align: middle; - touch-action: manipulation; - background-image: none; - border: 1px solid transparent; - white-space: nowrap; - text-decoration: none; - @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base); - @include user-select(none); - @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border, $btn-primary-background-active, $btn-primary-border-active, $btn-primary-border-hover); - - &, - &:active, - &.active { - &:focus, - &.focus { - text-decoration: none; - @include tab-focus; - } - } - &.disabled, - &[disabled], - fieldset[disabled] & { - cursor: $cursor-disabled; - @include opacity(.65); - @include box-shadow(none); - } - &.pretix-widget-btn-default { - @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border, darken($btn-default-bg, 10%), darken($btn-default-border, 25%), darken($btn-default-border, 12%)); - } - } - label.pretix-widget-btn-checkbox { - @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border, darken($btn-default-bg, 10%), darken($btn-default-border, 25%), darken($btn-default-border, 12%)); - border-width: 1px; - border-style: solid; - position: relative; - cursor: pointer; - padding: 6px 24px; - min-height: 32px; - box-sizing: border-box; - color: #333; - input { - position: absolute; - left: 10px; - } - &:has(input:checked) { - background-color: #e6e6e6; - border-color: #adadad; - } - } - .pretix-widget-icon-cart { - display: inline-block; - width: 1em; - height: 1em; - vertical-align: text-bottom; - fill: #333; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.267 6.756c0-.312-.202-.563-.453-.563-.252 0-.454.251-.454.563 0 .312.202.563.454.563.251 0 .453-.251.453-.563Zm3.174 0c0-.312-.202-.563-.454-.563-.251 0-.453.251-.453.563 0 .312.202.563.453.563.252 0 .454-.251.454-.563Zm.453-4.785c0-.154-.103-.282-.227-.282H1.413c-.035-.211-.039-.563-.28-.563H.227c-.124 0-.227.128-.227.282 0 .153.103.281.227.281h.722l.627 3.62c-.049.127-.216.466-.216.603 0 .153.103.281.227.281h3.627c.124 0 .227-.128.227-.281 0-.154-.103-.282-.227-.282H1.955c.036-.088.085-.18.085-.281 0-.102-.032-.212-.046-.308l3.698-.537c.117-.018.202-.141.202-.281V1.971Z' transform='matrix(2.52069 0 0 2.02994 -.035 -.523)'/%3E%3C/svg%3E%0A"); - } - input:checked + .pretix-widget-icon-cart { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.534 3.097a.317.317 0 0 1-.067.197L3.56 4.42a.207.207 0 0 1-.16.084.207.207 0 0 1-.159-.084l-.907-1.126a.317.317 0 0 1-.067-.197c0-.154.103-.282.227-.282.06 0 .117.031.159.084l.521.642V2.252c0-.154.102-.281.226-.281.124 0 .227.127.227.281v1.289l.521-.642a.205.205 0 0 1 .159-.084c.124 0 .227.128.227.282ZM2.267 6.756c0-.312-.202-.563-.453-.563-.252 0-.454.251-.454.563 0 .312.202.563.454.563.251 0 .453-.251.453-.563Zm3.174 0c0-.312-.202-.563-.454-.563-.251 0-.453.251-.453.563 0 .312.202.563.453.563.252 0 .454-.251.454-.563Zm.453-4.785c0-.154-.103-.282-.227-.282H1.413c-.035-.211-.039-.563-.28-.563H.227c-.124 0-.227.128-.227.282 0 .153.103.281.227.281h.722l.627 3.62c-.049.127-.216.466-.216.603 0 .153.103.281.227.281h3.627c.124 0 .227-.128.227-.281 0-.154-.103-.282-.227-.282H1.955c.036-.088.085-.18.085-.281 0-.102-.032-.212-.046-.308l3.698-.537c.117-.018.202-.141.202-.281V1.971Z' transform='matrix(2.52069 0 0 2.02994 -.035 -.523)'/%3E%3C/svg%3E%0A"); - } - input[type="text"], input[type="number"], select { - line-height: normal; - border: 1px solid $input-border; - border-radius: $input-border-radius; - height: $input-height-base; - padding: $padding-base-vertical $padding-base-horizontal; - color: $input-color; - background-color: $input-bg; - @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075)); - @include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s); - @include placeholder; - $color-rgba: rgba(red($input-border-focus), green($input-border-focus), blue($input-border-focus), .6); - - &:focus { - border-color: $input-border-focus; - outline: 0; - @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px $color-rgba); - } - } - input[type=number] { - padding-right: 0; // Setting the padding-right to zero, as some versions Firefox render the arrow-buttons on number inputs useless. - } - input[type="checkbox"], - input[type="radio"] { - box-sizing: border-box; // 1 - padding: 0; // 2 - &:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; - } - } -} -.pretix-widget-use-custom-spinners input[type=number] { - padding-right: $padding-base-horizontal; - -moz-appearance: textfield; -} -.pretix-widget-use-custom-spinners input[type=number]::-webkit-outer-spin-button, -.pretix-widget-use-custom-spinners input[type=number]::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; -} -.pretix-widget { - margin: 10px 0; - padding: 0 10px; - border: 1px solid #ccc; - position: relative; - min-height: 208px; - border-radius: $input-border-radius; - - .pretix-widget-resume-button { - float: right; - margin-left: 10px; - } - - .pretix-widget-clickable { - cursor: pointer; - } - - .pretix-widget-info-message { - padding: 10px; - text-align: left; - margin: 10px 0; - background-color: white; - border: 2px solid $brand-info; - color: $state-info-text; - border-radius: $alert-border-radius; - } - - .pretix-widget-error-message { - padding: 10px; - text-align: center; - margin: 10px 0; - background-color: white; - border: 2px solid $brand-danger; - color: $state-danger-text; - border-radius: $alert-border-radius; - } - - .pretix-widget-error-action { - padding: 10px; - text-align: center; - } - - .pretix-widget-loading { - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, .8); - text-align: center; - } - - @-moz-keyframes pretix-widget-spin { - 100% { - -moz-transform: rotate(360deg); - } - } - - @-webkit-keyframes pretix-widget-spin { - 100% { - -webkit-transform: rotate(360deg); - } - } - - @keyframes pretix-widget-spin { - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - .pretix-widget-loading svg { - margin: 40px; - /*Fallback*/ - position: absolute; - top: 50%; - margin-top: -64px; - /*Sticky*/ - position: -webkit-sticky; - position: sticky; - top: Min(50vh, 50%);/* use uppercase M to use CSS-min and not SASS-min*/ - - -webkit-animation: pretix-widget-spin 6s linear infinite; - -moz-animation: pretix-widget-spin 6s linear infinite; - animation: pretix-widget-spin 6s linear infinite; - } - - .pretix-widget-item-row, .pretix-widget-category { - clear: both; - } - - .pretix-widget-item-title { - font-weight: bold; - } - - .pretix-widget-item-row { - padding: 10px 0; - } - - .pretix-widget-category { - margin: 10px 0; - } - - .pretix-widget-category-description { - padding: 0 15px; - } - - .pretix-widget-category-name { - margin: 10px 0 0 0; - } - - .pretix-widget-item-info-col { - width: 50%; - float: left; - padding: 0 15px; - box-sizing: border-box; - } - - .pretix-widget-item-price-col, .pretix-widget-item-availability-col { - width: 25%; - float: left; - padding: 0 15px; - box-sizing: border-box; - } - - .pretix-widget-item-description p, .pretix-widget-item-meta { - margin: 0; - } - - .pretix-widget-item-price-col { - text-align: right; - } - - del.pretix-widget-pricebox-original-price { - color: $text-muted; - } - - ins.pretix-widget-pricebox-new-price { - font-size: 120%; - font-weight: bold; - text-decoration: none; - } - - .pretix-widget-clear { - clear: both; - } - - .pretix-widget-category-description p { - margin: 0 0 10px; - } - - .pretix-widget-pricebox-tax { - display: block; - } - - .pretix-widget-item-count-group { - display: flex; - } - - .pretix-widget-item-count-group input { - border-radius: 0; - border-left: none; - border-right: none; - } - - .pretix-widget-item-count-group button span { - vertical-align: 25%; - line-height: 0.5; - } - - .pretix-widget-item-count-dec { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - width: 2.5em; - z-index: 2; - } - - .pretix-widget-item-count-inc { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - width: 2.5em; - } - - .pretix-widget-item-count-multiple { - display: block; - width: 100%; - box-sizing: border-box; - padding: 5px; - text-align: center; - } - - .pretix-widget-pricebox-price-input { - display: inline; - width: 100px; - box-sizing: border-box; - text-align: right; - } - - .pretix-widget-item-count-single-label { - display: block; - text-align: center; - width: 100%; - } - - .pretix-widget-attribution { - padding: 10px 15px; - text-align: center; - font-size: 12px; - } - - .pretix-widget-item-picture { - width: 60px; - height: 60px; - margin-right: 10px; - float: left; - } - - .pretix-widget-action { - margin-left: 75%; - width: 25%; - padding: 0 15px; - box-sizing: border-box; - } - - .pretix-widget-action button { - width: 100%; - } - - .pretix-widget-voucher-text { - margin: 10px 0; - padding: 0 15px; - } - - .pretix-widget-voucher-headline { - margin: 10px 0 0 0; - } - - .pretix-widget-voucher-input-wrap { - padding: 0 15px; - width: 75%; - box-sizing: border-box; - float: left; - } - - .pretix-widget-voucher input { - width: 100%; - box-sizing: border-box; - } - - .pretix-widget-voucher-button-wrap { - padding: 0 15px; - width: 25%; - box-sizing: border-box; - float: left; - } - - .pretix-widget-voucher button { - width: 100%; - } - - .pretix-widget-seating-waitinglist { - margin: 15px 0; - } - - .pretix-widget-seating-waitinglist-text { - padding: 0 15px; - width: 75%; - box-sizing: border-box; - float: left; - } - - .pretix-widget-seating-waitinglist-button-wrap { - padding: 0 15px; - width: 25%; - box-sizing: border-box; - float: left; - } - - .pretix-widget-seating-waitinglist-button { - width: 100%; - } - - .pretix-widget-item-with-picture .pretix-widget-main-item-row .pretix-widget-item-title-and-description { - margin-left: 70px; - } - - .pretix-widget-item-availability-col { - text-align: center; - - .pretix-widget-collapse-indicator::before { - content: ""; - display: inline-block; - width: $font-size-base; - height: $font-size-base; - background: url("data:image/svg+xml,%3Csvg viewBox='0 0 14 14' xmlns='http://www.w3.org/2000/svg' xml:space='preserve'%3E%3Cpath fill='#{url-friendly-colour($link-color)}' d='M6.395 4.151a.268.268 0 0 0-.177.077l-.386.386a.259.259 0 0 0-.077.177c.002.067.029.13.077.179l3.033 3.031-3.033 3.032a.255.255 0 0 0-.077.177.253.253 0 0 0 .077.178l.386.385a.268.268 0 0 0 .177.077.27.27 0 0 0 .178-.077l3.595-3.595a.259.259 0 0 0 .077-.177.255.255 0 0 0-.077-.176L6.573 4.228a.257.257 0 0 0-.178-.077Z'/%3E%3C/svg%3E"); - transition: transform .5s; - } - - .pretix-widget-collapse-indicator[aria-expanded=true]::before { - transform: rotate(90deg); - } - } - - .pretix-widget-availability-gone { - font-weight: bold; - color: $brand-danger; - text-transform: uppercase; - } - - .pretix-widget-availability-unavailable { - color: $brand-danger; - } - - .pretix-widget-item-variations { - overflow: hidden; - padding-top: 0; - padding-bottom: 0; - margin-top: 0; - margin-bottom: 0; - -moz-transition-duration: 0.5s; - -webkit-transition-duration: 0.5s; - -o-transition-duration: 0.5s; - transition-duration: 0.5s; - -moz-transition-timing-function: ease-in-out; - -webkit-transition-timing-function: ease-in-out; - -o-transition-timing-function: ease-in-out; - transition-timing-function: ease-in-out; - } - .pretix-widget-event-header { - padding-top: 10px; - text-align: center; - } - .pretix-widget-event-details { - padding-top: 10px; - text-align: center; - } - .pretix-widget-event-location { - display: none; - padding-top: 10px; - text-align: center; - } - .pretix-widget-event-description { - padding: 0 15px; - } - .pretix-widget-event-list-back { - padding-top: 10px; - text-align: center; - display: block; - a { - display: block; - } - } - .pretix-widget-back { - padding-bottom: 10px; - text-align: center; - display: block; - a { - display: block; - } - } - - .pretix-widget-event-list { - padding: 10px 0; - cursor: pointer; - } - .pretix-widget-event-list-entry { - display: flex; - flex-direction: row; - padding: 5px 0; - flex-wrap: wrap; - color: $text-color; - - &:hover, &:active, &:focus { - background: $gray-lighter; - text-decoration: none; - } - - .pretix-widget-event-list-entry-name { - width: 50%; - padding: 5px; - box-sizing: border-box; - } - .pretix-widget-event-list-entry-location { - padding: 5px; - box-sizing: border-box; - display: none; - } - .pretix-widget-event-list-entry-date { - width: 25%; - padding: 5px; - box-sizing: border-box; - } - .pretix-widget-event-list-entry-availability { - width: 25%; - text-align: right; - padding: 7px 5px 3px; - box-sizing: border-box; - span { - display: inline; - padding: 2px 6px 3px; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #fff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: 4px; - } - } - } - - .pretix-widget-event-availability-orange .pretix-widget-event-list-entry-availability span, - .pretix-widget-event-availability-orange.pretix-widget-event-calendar-event { - background-color: $brand-warning; - } - .pretix-widget-event-availability-none .pretix-widget-event-list-entry-availability span, - .pretix-widget-event-availability-none.pretix-widget-event-calendar-event { - background-color: $brand-primary; - } - .pretix-widget-event-availability-green .pretix-widget-event-list-entry-availability span, - .pretix-widget-event-availability-green.pretix-widget-event-calendar-event { - background-color: $brand-success; - } - .pretix-widget-event-availability-red .pretix-widget-event-list-entry-availability span, - .pretix-widget-event-availability-red.pretix-widget-event-calendar-event { - background-color: $brand-danger; - } - .pretix-widget-event-availability-low .pretix-widget-event-list-entry-availability span { - border-left: 10px solid $brand-warning; - } - .pretix-widget-event-availability-low.pretix-widget-event-calendar-event { - border-right: 10px solid $brand-warning; - } - - .pretix-widget-event-calendar { - padding-top: 10px; - word-break: break-word; - - .pretix-widget-event-week-table { - display: flex; - flex-direction: row; - - .pretix-widget-event-week-col { - flex: 1; - margin: 0 5px; - - &:first-child { - margin-left: 0; - } - &:last-child { - margin-right: 0; - } - } - } - - .pretix-widget-event-calendar-head { - display: flex; - flex-direction: row; - - strong { - width: 50%; - text-align: center; - display: block; - } - .pretix-widget-event-calendar-next-month, .pretix-widget-event-calendar-previous-month { - display: block; - width: 25%; - } - .pretix-widget-event-calendar-next-month { - text-align: right; - } - } - .pretix-widget-event-calendar-event { - display: block; - border-radius: 4px; - padding: 5px; - color: white; - cursor: pointer; - margin-bottom: 5px; - &:last-child { - margin-bottom: 0; - } - &:hover { - text-decoration: none; - } - } - - .pretix-widget-event-calendar-table { - width: 100%; - - th, td { - width: 14.285714285714286%; - vertical-align: top; - padding: 10px 5px; - } - } - .pretix-widget-event-calendar-day { - font-weight: bold; - } - } - - .pretix-widget-seating-link-wrapper { - padding: 0 15px; - margin: 15px 0 10px; - } - .pretix-widget-seating-link { - display: block; - width: 100%; - } -} - - -.pretix-widget-event-list-filter-form { - display: flex; - flex-direction: row; - align-items: end; - margin-bottom: 15px; - - .pretix-widget-event-list-filter-field { - display: block; - width: 100%; - margin: 0 15px 0 0; - - label { - display: inline-block; - font-weight: bold; - margin-bottom: 5px; - } - - select { - display: block; - width: 100%; - } - } - .pretix-widget-event-list-filter-field:last-child { - margin: 0; - } -} -.pretix-widget.pretix-widget-mobile .pretix-widget-event-list-filter-form { - display: block; - - .pretix-widget-event-list-filter-field { - display: block; - margin: 0 0 5px; - } -} - -@keyframes pretix-widget-bounce-in { - 0% { - transform: scale(0); - } - 50% { - transform: scale(1.5); - } - 100% { - transform: scale(1); - } -} -.pretix-widget-alert-holder { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, 0.8); - z-index: 16777271; - visibility: hidden; - opacity: 0; - transition: opacity 0.5s; /* do not animate visibility or we'll have a flashing thing on load */ - - &.pretix-widget-alert-shown { - visibility: visible; - opacity: 1; - transition: opacity 0.5s, visibility 0.5s; - } - - .bounce-enter-active { - animation: pretix-widget-bounce-in .5s; - } - .bounce-leave-active { - animation: pretix-widget-bounce-in .5s reverse; - } - - .pretix-widget-alert-box { - position: fixed; - left: 50%; - width: 600px; - margin-left: -300px; - top: 100px; - background: white; - border-radius: 5px 5px 5px 5px; - -moz-border-radius: 5px 5px 5px 5px; - -webkit-border-radius: 5px 5px 5px 5px; - box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - -webkit-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - -moz-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - box-sizing: border-box; - padding: 42px 20px 20px 20px; - text-align: center; - font-size: 20px; - - p:first-child { - margin-top: 0; - } - p:last-child { - margin-bottom: 0; - } - } - .pretix-widget-alert-icon { - position: fixed; - left: 50%; - width: 64px; - margin-left: -32px; - top: 68px; - } -} -.pretix-widget-frame-holder { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, 0.8); - z-index: 16777271; - visibility: hidden; - opacity: 0; - transition: opacity 0.5s, visibility 0.5s; - - .pretix-widget-frame-loading { - text-align: center; - display: flex; - align-items: center; - justify-content: center; - height: 100%; - width: 100%; - position: fixed; - left: 0; - top: 0; - } - - .pretix-widget-frame-loading svg { - margin: 40px; - -webkit-animation: pretix-widget-spin 6s linear infinite; - -moz-animation: pretix-widget-spin 6s linear infinite; - animation: pretix-widget-spin 6s linear infinite; - } - - &.pretix-widget-frame-shown { - visibility: visible; - opacity: 1; - transition: opacity 0.5s, visibility 0.5s; - } - - .pretix-widget-frame-inner { - position: fixed; - left: 10%; - width: 80%; - height: 80%; - top: 10%; - background: white; - border-radius: 5px 5px 5px 5px; - -moz-border-radius: 5px 5px 5px 5px; - -webkit-border-radius: 5px 5px 5px 5px; - box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - -webkit-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - -moz-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - box-sizing: border-box; - padding: 10px; - } - - .pretix-widget-frame-close { - position: fixed; - right: 10%; - top: 10%; - width: 24px; - height: 24px; - background: $brand-primary; - margin: -12px -12px 0 0; - border-radius: 12px; - -moz-border-radius: 12px; - -webkit-border-radius: 12px; - text-align: center; - } - - .pretix-widget-frame-close a { - color: white; - font-weight: bold; - font-family: sans-serif; - text-decoration: none; - padding: 4px 0; - display: inline-block; - line-height: 16px; - } - - .pretix-widget-frame-close svg { - display: inline-block; - border: none; - } - - .pretix-widget-frame-inner iframe { - width: 100% !important; - height: 100% !important; - } -} - -.pretix-widget-lightbox-holder { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, 0.8); - z-index: 16777271; - visibility: hidden; - opacity: 0; - transition: opacity 0.5s, visibility 0.5s; - display: flex; - align-items: center; - justify-content: center; - - .pretix-widget-lightbox-loading svg { - margin: 40px; - -webkit-animation: pretix-widget-spin 6s linear infinite; - -moz-animation: pretix-widget-spin 6s linear infinite; - animation: pretix-widget-spin 6s linear infinite; - } - - &.pretix-widget-lightbox-shown { - visibility: visible; - opacity: 1; - transition: opacity 0.5s, visibility 0.5s; - } - - .pretix-widget-lightbox-inner { - position: relative; - background: white; - border-radius: 5px 5px 5px 5px; - -moz-border-radius: 5px 5px 5px 5px; - -webkit-border-radius: 5px 5px 5px 5px; - box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - -webkit-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - -moz-box-shadow: 0 4px 18px 0 rgba(0, 0, 0, 0.1), 0 6px 20px 0 rgba(0, 0, 0, 0.09); - box-sizing: border-box; - padding: 10px; - max-width: 90%; - max-height: 90%; - } - &.pretix-widget-lightbox-isloading .pretix-widget-lightbox-inner { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0,0,0,0); - border: 0; - } - - .pretix-widget-lightbox-image { - margin: 0; - padding: 0; - text-align: center; - } - .pretix-widget-lightbox-image img { - max-width: 80vw; - max-height: 80vh; - object-fit: scale-down; - } - .pretix-widget-lightbox-image figcaption { - margin: 0.5em 0 0; - } - - .pretix-widget-lightbox-close { - position: absolute; - right: -12px; - top: -12px; - width: 24px; - height: 24px; - background: $brand-primary; - margin: 0; - border: none; - border-radius: 12px; - -moz-border-radius: 12px; - -webkit-border-radius: 12px; - text-align: center; - color: white; - font-weight: bold; - font-family: sans-serif; - text-decoration: none; - padding: 4px 0; - display: inline-block; - line-height: 16px; - cursor: pointer; - } - - .pretix-widget-lightbox-close svg { - display: inline-block; - border: none; - } -} - -.pretix-widget-primary-color { - /* in SVG */ - fill: $brand-primary; -} - -.pretix-widget-event-list-load-more { - text-align: center; -} - -.pretix-widget.pretix-widget-mobile { - .pretix-widget-event-week-table { - display: block; - - .pretix-widget-event-week-col { - flex: 1; - margin: 10px 0; - } - } - - .pretix-widget-item-info-col { - width: 100%; - float: none; - margin-bottom: 5px; - } - .pretix-widget-item-info-col:after { - display: block; - content: ""; - clear: both; - } - .pretix-widget-item-price-col, .pretix-widget-item-availability-col { - width: 50%; - min-width: 140px; - } - .pretix-widget-action { - width: 100%; - margin-left: 0; - } - .pretix-widget-voucher-input-wrap { - width: 100%; - float: none; - } - .pretix-widget-voucher-button-wrap { - width: 100%; - float: none; - margin-top: 10px; - } - - .pretix-widget-event-list-entry { - .pretix-widget-event-list-entry-name { - width: 100%; - } - .pretix-widget-event-list-entry-location { - width: 100%; - } - .pretix-widget-event-list-entry-date { - width: 50%; - } - .pretix-widget-event-list-entry-availability { - width: 50%; - } - } - - .pretix-widget-event-calendar { - .pretix-widget-event-calendar-events { - display: none; - } - .pretix-widget-event-week-table { - .pretix-widget-event-calendar-events { - display: block; - } - } - td.pretix-widget-has-events { - background: $brand-primary; - color: white; - cursor: pointer; - &.pretix-widget-day-availability-red { - background: $brand-danger; - } - &.pretix-widget-day-availability-green { - background: $brand-success; - } - &.pretix-widget-day-availability-low { - border-right: 5px solid $brand-warning; - } - &.pretix-widget-day-availability-orange { - background: $brand-warning; - } - } - - .pretix-widget-event-calendar-head { - display: block; - strong { - width: 100%; - display: block; - } - .pretix-widget-event-calendar-next-month, .pretix-widget-event-calendar-previous-month { - display: block; - width: 100%; - text-align: center; - } - } - } -} - -@media (min-width: 1200px) { - .pretix-widget-frame-holder { - .pretix-widget-frame-inner { - left: 50%; - margin-left: -540px; - width: 1080px; - } - .pretix-widget-frame-close { - left: 50%; - margin-left: 528px; - } - } -} - -@media (max-width: 800px) { - .pretix-widget-frame-holder .pretix-widget-frame-inner { - left: 0; - width: 100%; - height: 100%; - top: 0; - background: $brand-primary; - border-radius: 0; - -moz-border-radius: 0; - -webkit-border-radius: 0; - box-shadow: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - padding: 40px 0 0 0; - } - .pretix-widget-frame-holder .pretix-widget-frame-close { - right: 20px; - top: 20px; - background: white; - svg path { - fill: $brand-primary; - } - } -} diff --git a/src/tests/presale/test_widget.py b/src/tests/presale/test_widget.py index ac606dacca..a11b3c9099 100644 --- a/src/tests/presale/test_widget.py +++ b/src/tests/presale/test_widget.py @@ -542,7 +542,7 @@ class WidgetCartTest(CartTestMixin, TestCase): @override_settings(COMPRESS_PRECOMPILERS=settings.COMPRESS_PRECOMPILERS_ORIGINAL) def test_css_customized(self): - response = self.client.get('/%s/%s/widget/v1.css' % (self.orga.slug, self.event.slug)) + response = self.client.get('/%s/%s/widget/v2.css' % (self.orga.slug, self.event.slug)) c = b"".join(response.streaming_content).decode() assert '#8E44B3' in c assert '#33c33c' not in c @@ -550,7 +550,7 @@ class WidgetCartTest(CartTestMixin, TestCase): self.orga.settings.primary_color = "#33c33c" self.orga.cache.clear() - response = self.client.get('/%s/%s/widget/v1.css' % (self.orga.slug, self.event.slug)) + response = self.client.get('/%s/%s/widget/v2.css' % (self.orga.slug, self.event.slug)) c = b"".join(response.streaming_content).decode() assert '#8E44B3' not in c assert '#33c33c' in c @@ -558,18 +558,18 @@ class WidgetCartTest(CartTestMixin, TestCase): self.event.settings.primary_color = "#34c34c" self.event.cache.clear() - response = self.client.get('/%s/%s/widget/v1.css' % (self.orga.slug, self.event.slug)) + response = self.client.get('/%s/%s/widget/v2.css' % (self.orga.slug, self.event.slug)) c = b"".join(response.streaming_content).decode() assert '#8E44B3' not in c assert '#33c33c' not in c assert '#34c34c' in c def test_js_localized(self): - response = self.client.get('/widget/v1.en.js') + response = self.client.get('/widget/v2.en.js') c = response.content.decode() assert '%m/%d/%Y' in c assert '%d.%m.%Y' not in c - response = self.client.get('/widget/v1.de.js') + response = self.client.get('/widget/v2.de.js') c = response.content.decode() assert '%m/%d/%Y' not in c assert '%d.%m.%Y' in c