diff --git a/package-lock.json b/package-lock.json index f94e3ecd..089cbb46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4819,6 +4819,11 @@ "picomatch": "^2.2.3" } }, + "microtip": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/microtip/-/microtip-0.2.2.tgz", + "integrity": "sha512-oah38eH5vSHVFP6yXjbKWOYt92mav++0j3zh844h1vhOscqEg7Rf4agDEIwUTFCcAPPdlhYUQMe6eZfHgD+4oQ==" + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -7004,6 +7009,12 @@ "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==" }, + "smoothscroll-polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz", + "integrity": "sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==", + "dev": true + }, "sockjs": { "version": "0.3.21", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", diff --git a/package.json b/package.json index 65b2eb5e..c55f57b7 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "jquery": "^1.12.4", "lazysizes": "^4.1.8", "leaflet": "^1.7.1", + "microtip": "^0.2.2", "normalize.css": "^7.0.0", "picturefill": "^3.0.3", "sass-mq": "^3.3.2", @@ -39,9 +40,9 @@ }, "devDependencies": { "@babel/plugin-proposal-object-rest-spread": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/preset-env": "^7.14.5", "@symfony/webpack-encore": "^1.5.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", "autoprefixer": "^9.4.6", "core-js": "^3.15.0", "file-loader": "^6.2.0", @@ -49,6 +50,7 @@ "postcss": "^8.3.5", "postcss-loader": "^5.3.0", "sass-loader": "^9.0.3", + "smoothscroll-polyfill": "^0.4.4", "vue-loader": "^15.9.7", "vue-template-compiler": "^2.6.14" }, diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js index e58f7bf7..2d6bcbc3 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js @@ -6,6 +6,51 @@ const application = Application.start() const context = require.context('./controllers', true, /\.js$/) application.load(definitionsFromContext(context)) +// Polyfills +import smoothscroll from 'smoothscroll-polyfill' +smoothscroll.polyfill() + +// Function to parse config values from JSON data in HTML source +const parseAppConfig = () => { + const configElement = document.getElementById('appconfig'); + if (null === configElement) { + return {} + } + return JSON.parse(configElement.innerHTML); +} + +// Function to append pacode parameter to urls specified in config by domain +const appendPaCode = appConfig => { + const paCode = appConfig.paCode + const externalDomains = appConfig.externalDomains + if (!paCode) { + return + } + document.querySelectorAll('a').forEach(element => { + if (element.hostname === location.hostname) { + return + } + if (externalDomains.indexOf(element.hostname) === -1) { + return + } + let url = element.href + if (!url) { + return + } + if (url.indexOf('agenturcode=') !== -1) { + return + } + const separator = url.indexOf('?') === -1 ? '?' : '&' + url += separator + 'agenturcode=' + paCode + element.href = url + }) +} + +// Executed on document ready +document.addEventListener('DOMContentLoaded', () => { + const appConfig = parseAppConfig() + appendPaCode(appConfig) +}) @@ -16,12 +61,10 @@ import $ from 'jquery' import dayjs from 'dayjs' import 'dayjs/locale/de' import '@fancyapps/fancybox' -import axios from 'axios' global.$ = global.jQuery = $; require('cookieconsent'); -require('slick-carousel'); require('lazysizes'); require('lazysizes/plugins/unveilhooks/ls.unveilhooks'); require('bootstrap-sass/assets/javascripts/bootstrap'); @@ -44,9 +87,6 @@ import HotelList from './components/HotelList.vue' // Define global constants const $window = $(window); -const sliderPrevArrow = ''; -const sliderNextArrow = ''; -const sliderDot = ''; // Configure fancybox $.fancybox.defaults.iframe.css.width = '800px'; @@ -82,8 +122,6 @@ new Vue({ data () { return { maxWindowWidth: 991, - lastScrollPosition: 0, - scrollTopVisible: false, searchBoxVisible: false, navbarLocked: false, searchbarFixed: false, @@ -105,28 +143,16 @@ new Vue({ this.scroll(0); }, scrollTo (anchorId) { - const top = $(anchorId).offset().top - this.getHeaderOffset(); + const top = $(anchorId).offset().top; this.scroll(top); }, scroll (top) { this.navbarLocked = true; - $('html, body').stop().animate( - { scrollTop: top }, - 650, - () => { - this.navbarLocked = false; - } - ); - }, - getHeaderOffset () { - return $('.searchbar').hasClass('affix') ? 260 : 120; + window.scrollTo({ top: top, behavior: 'smooth' }) }, toggleSearchbox () { this.searchBoxVisible = !this.searchBoxVisible; }, - hideSearchbox () { - this.searchBoxVisible = false; - }, toggleMobileNavigation () { $('[data-mobile-menu]').collapse('toggle'); }, @@ -145,103 +171,6 @@ new Vue({ $(this).css('backgroundImage', 'url(' + imageSource + ')'); }); }, - lazyLoadBackgroundImages () { - document.addEventListener('lazybeforeunveil', e => { - const bg = e.target.getAttribute('data-bg'); - if (bg) { - e.target.style.backgroundImage = 'url(' + bg + ')'; - } - }); - }, - initCarousels () { - // let $carouselItemWrappers = $('.slider--teasers > .slider__items').not('.slick-initialized'); - // let initCallback = this.initTeaserSlider; - // $.each($carouselItemWrappers, function () { - // initCallback($(this)); - // }); - // $carouselItemWrappers = $('.slider--thirds > .slider__items').not('.slick-initialized'); - // $.each($carouselItemWrappers, function () { - // let numberOfSlides = $(this).children().length; - // $(this).slick({ - // accessibility: false, // This is a hack to avoid a slick carousel bug. see: https://github.com/kenwheeler/slick/issues/1407#issuecomment-325228683 - // mobileFirst: true, - // infinite: false, - // slidesToShow: 1.15, - // slidesToScroll: 1, - // arrows: false, - // dots: false, - // responsive: [ - // { - // breakpoint: 1200, - // settings: { - // slidesToShow: 3, - // arrows: numberOfSlides > 3, - // prevArrow: sliderPrevArrow, - // nextArrow: sliderNextArrow - // } - // }, - // { - // breakpoint: 992, - // settings: { - // slidesToShow: 2.75, - // } - // }, - // { - // breakpoint: 640, - // settings: { - // slidesToShow: 2.5, - // } - // }, - // { - // breakpoint: 384, - // settings: { - // slidesToShow: 1.75, - // } - // } - // ] - // }); - // }); - }, - initTeaserSlider ($element) { - let maxNumberOfSlides = $element.parent('.slider').hasClass('in-column') ? 3 : 4; - $element.slick({ - accessibility: false, // This is a hack to avoid a slick carousel bug. see: https://github.com/kenwheeler/slick/issues/1407#issuecomment-325228683 - mobileFirst: true, - infinite: false, - slidesToShow: 1.15, - slidesToScroll: 1, - arrows: false, - responsive: [ - { - breakpoint: 1200, - settings: { - slidesToShow: maxNumberOfSlides, - arrows: true, - prevArrow: sliderPrevArrow, - nextArrow: sliderNextArrow - } - }, - { - breakpoint: 992, - settings: { - slidesToShow: maxNumberOfSlides - 0.5, - } - }, - { - breakpoint: 640, - settings: { - slidesToShow: 2.5, - } - }, - { - breakpoint: 384, - settings: { - slidesToShow: 1.75, - } - } - ] - }); - }, initDropdownMenuBehavior () { const $dropdownLinks = $('.navbar-main').find('a.dropdown-toggle'); if (this.mobileMode) { @@ -254,11 +183,6 @@ new Vue({ }); } }, - initTooltips () { - if (!this.mobileMode) { - $('.tooltiptoggle').tooltip(); - } - }, initFilterpanel () { const $filterPanel = $('#filterpanel'); if (this.mobileMode) { @@ -267,33 +191,9 @@ new Vue({ $filterPanel.addClass('in'); } }, - initPartnerIdSelect () { - $('[data-force-partnerid-select]').on('click', '.booking-link', function (e) { - e.preventDefault(); - }); - }, - initFaqFilter () { - const $entries = $('[data-faq-entry]'); - $('[data-faqfilter]').on('keyup', function () { - const query = $(this).val(); - if (query.length < 3) { - $entries.fadeIn(); - } else { - const pattern = new RegExp(query, 'i'); - $entries.each(function () { - const question = $(this).children('[data-faq-question]').text(); - const answer = $(this).children('[data-faq-answer]').text(); - if (!question.match(pattern) && !answer.match(pattern)) { - $(this).fadeOut(); - } - }); - } - }); - }, initListeners () { $window.on('resize', () => { this.setMobileMode(); - this.initCarousels(); this.initDropdownMenuBehavior(); let newBackgroundImageMode = this.getBackgroundImageMode(); if (this.backgroundImageMode !== newBackgroundImageMode) { @@ -301,12 +201,6 @@ new Vue({ this.setResponsiveBackgroundImages(); } }); - $window.on('scroll', () => { - this.scrollTopVisible = $window.scrollTop() > $window.height()/3; - if ($window.scrollTop() >= 0) { - this.lastScrollPosition = $window.scrollTop(); - } - }); $(document).on('click', event => { const $clickedElement = $(event.target); const isNavExpanded = $('#ep-navbar-burger-menu').hasClass('collapse in'); @@ -322,48 +216,16 @@ new Vue({ this.searchbarFixed = false; }); }, - appendPaCode () { - const paCode = this.$store.state.config.paCode; - const externalDomains = this.$store.state.config.externalDomains; - if (!paCode) { - return; - } - $('a').each(function () { - if (this.hostname === location.hostname) { - return; - } - if (externalDomains.indexOf(this.hostname) === -1) { - return; - } - let url = $(this).attr('href'); - if (!url) { - return; - } - if (url.indexOf('agenturcode=') !== -1) { - return; - } - const separator = url.indexOf('?') === -1 ? '?' : '&'; - url += separator + 'agenturcode=' + paCode; - $(this).attr('href', url); - }); - }, }, created () { this.$store.dispatch('init'); EventBus.$on('ajaxContentLoaded', () => { Vue.nextTick(() => { - this.initTooltips(); this.initFilterpanel(); - this.appendPaCode(); - }); - }); - EventBus.$on('tableLoaded', () => { - Vue.nextTick(() => { - this.initTooltips(); }); }); EventBus.$on('scrollTo', (anchorId, offset) => { - this.scrollTo(anchorId, offset); + document.getElementById(anchorId).scrollIntoView({ behavior: 'smooth' }) }); }, mounted () { @@ -371,15 +233,9 @@ new Vue({ this.setMobileMode(); this.setBackgroundImageMode(); this.setResponsiveBackgroundImages(); - this.lazyLoadBackgroundImages(); this.initListeners(); this.initFilterpanel(); - this.initCarousels(); - this.initTooltips(); this.initDropdownMenuBehavior(); - this.initPartnerIdSelect(); - this.initFaqFilter(); - this.appendPaCode(); }); } }); diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue index 86c2b48f..efc3dc7d 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue @@ -26,17 +26,17 @@