remove most of jquery from top menu
This commit is contained in:
parent
cc7c9f6ed5
commit
a074d747c1
|
@ -1,32 +1,55 @@
|
||||||
var menuCache = null
|
let menuCache = null
|
||||||
|
|
||||||
var updateTopMenu = function() {
|
const breakpointMobileWidth = 1024
|
||||||
var breakpointMobileWidth = 1024
|
const usePercentualAppMenuLimit = 0.8
|
||||||
var menu = jQuery('#appmenu')
|
const minAppsDesktop = 8
|
||||||
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
|
|
||||||
|
|
||||||
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationApps.html('')
|
navigationAppsHtml = ''
|
||||||
|
|
||||||
apps.each(function(i, app) {
|
for (let app of apps) {
|
||||||
var dataId = app.getAttribute('data-id')
|
const dataId = app.getAttribute('data-id')
|
||||||
|
|
||||||
if (dataId === null) {
|
if (dataId === null) {
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topMenuApps.indexOf(dataId) === -1) {
|
if (topMenuApps.indexOf(dataId) === -1) {
|
||||||
|
@ -36,25 +59,28 @@ var updateTopMenu = function() {
|
||||||
app.classList.remove('hidden')
|
app.classList.remove('hidden')
|
||||||
app.classList.add('app-external-site')
|
app.classList.add('app-external-site')
|
||||||
appShown.push(app)
|
appShown.push(app)
|
||||||
navigationApps.append(app.outerHTML)
|
|
||||||
|
navigationAppsHtml = navigationAppsHtml + app.outerHTML
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetBlankApps.indexOf(dataId) !== -1) {
|
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) {
|
if (isMobile && appCount > minAppsDesktop) {
|
||||||
appCount = minAppsDesktop
|
appCount = minAppsDesktop
|
||||||
|
@ -63,110 +89,117 @@ var updateTopMenu = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appCount === 0) {
|
if (appCount === 0) {
|
||||||
menu.addClass('hidden')
|
menu.classList.add('hidden')
|
||||||
|
} else {
|
||||||
|
menu.classList.remove('hidden')
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.removeClass('hidden')
|
menu.style.opacity = 1
|
||||||
menu.css('opacity', 1)
|
|
||||||
|
|
||||||
if (appShown.length - 1 - appCount >= 1) {
|
if (appShown.length - 1 - appCount >= 1) {
|
||||||
appCount--
|
appCount--
|
||||||
}
|
}
|
||||||
|
|
||||||
moreApps.find('a').removeClass('active')
|
for (let item of querySelectorAll('a', moreApps)) {
|
||||||
|
item.classList.remove('active')
|
||||||
|
}
|
||||||
|
|
||||||
var k = 0
|
let k = 0
|
||||||
var notInHeader = 0
|
let notInHeader = 0
|
||||||
var name
|
|
||||||
|
|
||||||
jQuery(appShown).each(function(i, app) {
|
for (let app of appShown) {
|
||||||
app = jQuery(app)
|
const name = app.getAttribute('data-id')
|
||||||
name = app.data('id')
|
const item = querySelector('#apps li[data-id=' + name + '].app-external-site')
|
||||||
|
|
||||||
if (k < appCount && appCount > 0) {
|
if (k < appCount && appCount > 0) {
|
||||||
app.removeClass('hidden')
|
app.classList.remove('hidden')
|
||||||
lastShownApp = app
|
lastShownApp = app
|
||||||
|
|
||||||
jQuery('#apps li[data-id=' + name + '].app-external-site').addClass('in-header')
|
item.classList.add('in-header')
|
||||||
} else {
|
} else {
|
||||||
app.addClass('hidden')
|
app.classList.add('hidden')
|
||||||
notInHeader++
|
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')) {
|
const a = querySelector('a', app)
|
||||||
lastShownApp.addClass('hidden')
|
|
||||||
app.removeClass('hidden')
|
if (appCount > 0 && a.classList.contains('active')) {
|
||||||
|
lastShownApp.classList.add('hidden')
|
||||||
|
app.classList.remove('hidden')
|
||||||
notInHeader++
|
notInHeader++
|
||||||
|
|
||||||
jQuery('#apps li[data-id=' + name + '].app-external-site')
|
item.classList.add('in-header')
|
||||||
.removeClass('in-header')
|
|
||||||
.addClass('in-header')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
k++
|
k++
|
||||||
})
|
}
|
||||||
|
|
||||||
// Hack for https://github.com/nextcloud/server/blob/23b0b63c213f5b31eecae817ffd4a9e26f6624d0/core/src/components/MainMenu.js#L74-L96
|
// Hack for:
|
||||||
menu.undelegate('li:not(#more-apps) > a', 'click')
|
// - https://github.com/nextcloud/server/blob/master/core/src/components/MainMenu.js#L97-L119
|
||||||
menu.delegate('li:not(#more-apps) > a', 'click', function(e) {
|
// - https://github.com/nextcloud/server/blob/master/core/src/components/MainMenu.js#L97-L119
|
||||||
var a = $(e.target)
|
jQuery(menu).undelegate('li:not(#more-apps) > a', 'click')
|
||||||
|
jQuery(navigation).undelegate('a', 'click')
|
||||||
|
|
||||||
if (!a.is('a')) {
|
const confs = [
|
||||||
a = a.closest('a')
|
{
|
||||||
|
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) {
|
for (let app of querySelectorAll('#apps li.app-external-site')) {
|
||||||
a.find('svg').remove()
|
const appId = app.getAttribute('data-id')
|
||||||
a.find('div').remove()
|
|
||||||
a.prepend(jQuery('<div/>').addClass(
|
|
||||||
OCA.Theming && OCA.Theming.inverted
|
|
||||||
? 'icon-loading-small'
|
|
||||||
: 'icon-loading-small-dark'
|
|
||||||
))
|
|
||||||
|
|
||||||
window.location.href = a.attr('href')
|
if (app.classList.contains('in-header')) {
|
||||||
}
|
for (let defs of querySelectorAll('svg defs', app)) {
|
||||||
})
|
defs.remove()
|
||||||
|
}
|
||||||
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()
|
|
||||||
} else {
|
} 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var defs = `
|
const defs = `
|
||||||
<defs>
|
<defs>
|
||||||
<filter id="invertMenuMore-${appId}">
|
<filter id="invertMenuMore-${appId}">
|
||||||
<feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"></feColorMatrix>
|
<feColorMatrix in="SourceGraphic" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"></feColorMatrix>
|
||||||
</filter>
|
</filter>
|
||||||
</defs>`
|
</defs>`
|
||||||
|
|
||||||
svg.prepend(defs)
|
svg.innerHTML = defs + svg.innerHTML
|
||||||
svg.find('image').attr('filter', `url(#invertMenuMore-${appId})`)
|
|
||||||
|
|
||||||
var html = svg.get(0).innerHTML.replace(/fecolormatrix/g, 'feColorMatrix');
|
for (let image of querySelectorAll('image', svg)) {
|
||||||
|
image.setAttribute('filter', `url(#invertMenuMore-${appId})`)
|
||||||
|
}
|
||||||
|
|
||||||
svg.html(html)
|
svg.innerHTML = svg.innerHTML.replace(/fecolormatrix/g, 'feColorMatrix')
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
if (notInHeader === 0) {
|
|
||||||
moreApps.hide()
|
|
||||||
navigation.hide()
|
|
||||||
} else {
|
|
||||||
moreApps.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
menuCache = menu.html() + menu.next().html()
|
if (notInHeader === 0) {
|
||||||
|
moreApps.style.display = 'none'
|
||||||
|
navigation.style.display = 'none'
|
||||||
|
} else {
|
||||||
|
moreApps.style.display = 'flex'
|
||||||
|
}
|
||||||
|
|
||||||
|
menuCache = menu.innerHTML + menu.nextSibling.innerHTML
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(updateTopMenu, 50)
|
setInterval(updateTopMenu, 1000)
|
||||||
|
|
|
@ -94,11 +94,15 @@ if ($_['always-displayed']) {
|
||||||
body.addEventListener('side-menu.ready', () => {
|
body.addEventListener('side-menu.ready', () => {
|
||||||
const sideMenu = querySelector('#side-menu')
|
const sideMenu = querySelector('#side-menu')
|
||||||
const headerMenuOpener = querySelector('#header .side-menu-opener')
|
const headerMenuOpener = querySelector('#header .side-menu-opener')
|
||||||
const sideMenuOpener = querySelector('#side-menu .side-menu-opener')
|
const sideMenuOpener = querySelectorAll('#side-menu .side-menu-opener')
|
||||||
|
|
||||||
sideMenuFocus = () => {
|
sideMenuFocus = () => {
|
||||||
let a = querySelector('.side-menu-app.active a', sideMenu)
|
let a = querySelector('.side-menu-app.active a', sideMenu)
|
||||||
|
|
||||||
|
if (!a) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (a.length === 0) {
|
if (a.length === 0) {
|
||||||
a = querySelector('.side-menu-app:first-child a', sideMenu)
|
a = querySelector('.side-menu-app:first-child a', sideMenu)
|
||||||
}
|
}
|
||||||
|
@ -108,7 +112,7 @@ if ($_['always-displayed']) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<?php if ($_['opener-hover'] || $display === 'always-displayed'): ?>
|
<?php if ($_['opener-hover']): ?>
|
||||||
const sideMenuMouseLeave = () => {
|
const sideMenuMouseLeave = () => {
|
||||||
sideMenu.classList.remove('open')
|
sideMenu.classList.remove('open')
|
||||||
sideMenu.removeEventListener('mouseleave', sideMenuMouseLeave)
|
sideMenu.removeEventListener('mouseleave', sideMenuMouseLeave)
|
||||||
|
@ -142,20 +146,20 @@ if ($_['always-displayed']) {
|
||||||
|
|
||||||
const a = querySelector('.side-menu-app.active a', sideMenu)
|
const a = querySelector('.side-menu-app.active a', sideMenu)
|
||||||
|
|
||||||
if (a.length) {
|
if (a !== null) {
|
||||||
a.focus()
|
a.focus()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
<?php if ($display === 'always-displayed'): ?>
|
for (let opener of sideMenuOpener) {
|
||||||
sideMenuOpener.addEventListener('click', () => {
|
opener.addEventListener('click', () => {
|
||||||
sideMenu.classList.toggle('open')
|
<?php if ($display === 'always-displayed'): ?>
|
||||||
|
sideMenu.classList.toggle('open')
|
||||||
|
<?php else: ?>
|
||||||
|
sideMenu.classList.remove('open')
|
||||||
|
<?php endif; ?>
|
||||||
})
|
})
|
||||||
<?php else: ?>
|
}
|
||||||
sideMenuOpener.addEventListener('click', () => {
|
|
||||||
sideMenu.classList.remove('open')
|
|
||||||
})
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
document.addEventListener('keydown', (e) => {
|
document.addEventListener('keydown', (e) => {
|
||||||
var key = e.key || e.keyCode
|
var key = e.key || e.keyCode
|
||||||
|
|
Loading…
Reference in a new issue