diff --git a/templates/js/_topMenuApps.js b/templates/js/_topMenuApps.js index 57b7088..589c464 100644 --- a/templates/js/_topMenuApps.js +++ b/templates/js/_topMenuApps.js @@ -1,32 +1,55 @@ -var menuCache = null +let menuCache = null -var updateTopMenu = function() { - var breakpointMobileWidth = 1024 - var menu = jQuery('#appmenu') - var apps = menu.find('li') - var minAppsDesktop = 8 - var usePercentualAppMenuLimit = 0.8 - var isMobile = jQuery(window).width() < breakpointMobileWidth - var lastShownApp = null - var appShown = [] - var moreApps = jQuery('#more-apps') - var navigation = jQuery('#navigation') - var navigationApps = jQuery('#apps ul') - var appCount = null +const breakpointMobileWidth = 1024 +const usePercentualAppMenuLimit = 0.8 +const minAppsDesktop = 8 - var currentMenuCache = menu.html() + menu.next().html() +const handleMenuClick = (e, icon) => { + let element = e.target - if (currentMenuCache === menuCache) { + while (element.tagName !== 'LI') { + element = element.parentNode + } + + const a = querySelector('a', element) + + if (a.getAttribute('target') !== '_blank' && e.which === 1 && !e.ctrlKey && !e.metaKey) { + for (let tag of ['svg', 'div']) { + let el = querySelector(tag, element) + + if (el) { + el.remove() + } + } + + const loader = createElement('div', {'class': icon}) + + a.insertBefore(loader, querySelector('span', a)) + } +} + +const updateTopMenu = function() { + const isMobile = window.innerWidth < breakpointMobileWidth + const menu = querySelector('#appmenu') + const moreApps = querySelector('#more-apps') + const navigation = querySelector('#navigation') + const navigationApps = querySelector('#apps ul') + + let apps = querySelectorAll('li', menu) + let lastShownApp = null + let appShown = [] + + if ((menu.innerHTML + menu.nextSibling.innerHTML) === menuCache) { return } - navigationApps.html('') + navigationAppsHtml = '' - apps.each(function(i, app) { - var dataId = app.getAttribute('data-id') + for (let app of apps) { + const dataId = app.getAttribute('data-id') if (dataId === null) { - return + continue } if (topMenuApps.indexOf(dataId) === -1) { @@ -36,25 +59,28 @@ var updateTopMenu = function() { app.classList.remove('hidden') app.classList.add('app-external-site') appShown.push(app) - navigationApps.append(app.outerHTML) + + navigationAppsHtml = navigationAppsHtml + app.outerHTML } if (targetBlankApps.indexOf(dataId) !== -1) { - jQuery(app).children('a').attr('target', '_blank'); + querySelector('a', app).setAttribute('target', '_blank') } - }) - - var rightHeaderWidth = jQuery('.header-right').outerWidth() - var headerWidth = jQuery('header').outerWidth() - var availableWidth = headerWidth - jQuery('#nextcloud').outerWidth() - - jQuery('#header .side-menu-opener').outerWidth() - - (rightHeaderWidth > 230 ? rightHeaderWidth : 230) - - if (!isMobile) { - availableWidth = availableWidth * usePercentualAppMenuLimit } - appCount = Math.floor(availableWidth / jQuery('#appmenu li').width()) + navigationApps.innerHTML = navigationAppsHtml + + const rightHeaderWidth = querySelector('.header-right').offsetWidth + const headerWidth = querySelector('header').offsetWidth + + let availableWidth = headerWidth + + availableWidth -= nextcloud.offsetWidth + availableWidth -= querySelector('#header .side-menu-opener').offsetWidth + availableWidth -= rightHeaderWidth > 230 ? rightHeaderWidth : 230 + availableWidth *= isMobile ? usePercentualAppMenuLimit : 1 + + let appCount = Math.floor(availableWidth / querySelector('#appmenu li:not(.hidden)').offsetWidth) if (isMobile && appCount > minAppsDesktop) { appCount = minAppsDesktop @@ -63,110 +89,117 @@ var updateTopMenu = function() { } if (appCount === 0) { - menu.addClass('hidden') + menu.classList.add('hidden') + } else { + menu.classList.remove('hidden') } - menu.removeClass('hidden') - menu.css('opacity', 1) + menu.style.opacity = 1 if (appShown.length - 1 - appCount >= 1) { appCount-- } - moreApps.find('a').removeClass('active') + for (let item of querySelectorAll('a', moreApps)) { + item.classList.remove('active') + } - var k = 0 - var notInHeader = 0 - var name + let k = 0 + let notInHeader = 0 - jQuery(appShown).each(function(i, app) { - app = jQuery(app) - name = app.data('id') + for (let app of appShown) { + const name = app.getAttribute('data-id') + const item = querySelector('#apps li[data-id=' + name + '].app-external-site') if (k < appCount && appCount > 0) { - app.removeClass('hidden') + app.classList.remove('hidden') lastShownApp = app - jQuery('#apps li[data-id=' + name + '].app-external-site').addClass('in-header') + item.classList.add('in-header') } else { - app.addClass('hidden') + app.classList.add('hidden') notInHeader++ - jQuery('#apps li[data-id=' + name + '].app-external-site').removeClass('in-header') + item.classList.remove('in-header') - if (appCount > 0 && app.children('a').hasClass('active')) { - lastShownApp.addClass('hidden') - app.removeClass('hidden') + const a = querySelector('a', app) + + if (appCount > 0 && a.classList.contains('active')) { + lastShownApp.classList.add('hidden') + app.classList.remove('hidden') notInHeader++ - jQuery('#apps li[data-id=' + name + '].app-external-site') - .removeClass('in-header') - .addClass('in-header') + item.classList.add('in-header') } } k++ - }) + } - // Hack for https://github.com/nextcloud/server/blob/23b0b63c213f5b31eecae817ffd4a9e26f6624d0/core/src/components/MainMenu.js#L74-L96 - menu.undelegate('li:not(#more-apps) > a', 'click') - menu.delegate('li:not(#more-apps) > a', 'click', function(e) { - var a = $(e.target) + // Hack for: + // - https://github.com/nextcloud/server/blob/master/core/src/components/MainMenu.js#L97-L119 + // - https://github.com/nextcloud/server/blob/master/core/src/components/MainMenu.js#L97-L119 + jQuery(menu).undelegate('li:not(#more-apps) > a', 'click') + jQuery(navigation).undelegate('a', 'click') - if (!a.is('a')) { - a = a.closest('a') + const confs = [ + { + items: querySelectorAll('#navigation li'), + icon: 'icon-loading-small' + }, + { + items: querySelectorAll('li:not(#more-apps)', menu), + icon: OCA.Theming && OCA.Theming.inverted ? 'icon-loading-small' : 'icon-loading-small-dark' + }, + ] + + for (let conf of confs) { + for (let item of conf.items) { + item.addEventListener('click', (e) => { + handleMenuClick(e, conf.icon) + }) } + } - if (a.attr('target') !== '_blank' && e.which === 1 && !e.ctrlKey && !e.metaKey && a.parent('#more-apps').length === 0) { - a.find('svg').remove() - a.find('div').remove() - a.prepend(jQuery('
').addClass( - OCA.Theming && OCA.Theming.inverted - ? 'icon-loading-small' - : 'icon-loading-small-dark' - )) + for (let app of querySelectorAll('#apps li.app-external-site')) { + const appId = app.getAttribute('data-id') - window.location.href = a.attr('href') - } - }) - - jQuery('#apps li.app-external-site').each(function(i, app) { - app = jQuery(app) - var appId = app.attr('data-id') - - if (app.hasClass('in-header')) { - app.find('svg').find('defs').remove() + if (app.classList.contains('in-header')) { + for (let defs of querySelectorAll('svg defs', app)) { + defs.remove() + } } else { - var svg = app.find('svg'); + const svg = querySelector('svg', app) - if (svg.find('defs').length > 0) { + if (querySelectorAll('svg defs', app).length > 0) { return; } - var defs = ` + const defs = `