diff --git a/Makefile b/Makefile index 09d3f22..124ddc9 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ release: npm-build translations test -d releases/$$VERSION && rm -fr releases/$$VERSION mkdir -p releases/$$VERSION/side_menu - cp -r README.md CHANGELOG.md appinfo css lib img l10n js src templates screenshots releases/$$VERSION/side_menu + cp -r README.md CHANGELOG.md appinfo css lib img l10n js src templates screenshots vendor releases/$$VERSION/side_menu cd releases/$$VERSION zip -r side_menu_v$$VERSION.zip side_menu tar cvzf side_menu_v$$VERSION.tar.gz side_menu diff --git a/css/admin.css b/css/admin.css index 41d9ec1..a15aa64 100644 --- a/css/admin.css +++ b/css/admin.css @@ -20,7 +20,7 @@ margin: 10px 0 10px 0; } -#side-menu-section input[type="checkbox"] { +#-dropside-menu-section input[type="checkbox"] { vertical-align: middle; } @@ -81,6 +81,12 @@ cursor: pointer; } +.side-menu-setting-list-drop { + background: yellow; + border-color: yellow; + height: 34px; +} + .side-menu-setting.arrow { color: #ccc; padding-right: 5px; diff --git a/src/SideMenu.js b/src/SideMenu.js index 441d0a4..a9848c4 100644 --- a/src/SideMenu.js +++ b/src/SideMenu.js @@ -41,7 +41,7 @@ const mountSideMenuComponent = () => { sideMenu.$mount('#side-menu') - $('body').trigger('side-menu.ready') + document.querySelector('body').dispatchEvent(new CustomEvent('side-menu.ready')) } else { window.setTimeout(mountSideMenuComponent, 50) } diff --git a/src/SideMenu.vue b/src/SideMenu.vue index 68fcccb..7ab3cab 100644 --- a/src/SideMenu.vue +++ b/src/SideMenu.vue @@ -122,13 +122,15 @@ export default { name: trim(element.querySelector('span').innerHTML), icon: svg, active: element.classList.contains('active') - }); + }) } } (function(apps) { window.setTimeout(function() { - jQuery('body').trigger('side-menu.apps', [apps]) + document.querySelector('body').dispatchEvent(new CustomEvent('side-menu.apps', { + detail: {apps: apps}, + })) }, 1000) })(this.apps) }, @@ -147,7 +149,7 @@ export default { that.logo = config['logo'] that.logoLink = config['logo-link'] that.settings = config['settings'] - }); + }) }, }, mounted() { diff --git a/src/SideMenuBig.vue b/src/SideMenuBig.vue index 9f6d8f2..72e6321 100644 --- a/src/SideMenuBig.vue +++ b/src/SideMenuBig.vue @@ -97,8 +97,10 @@ export default { } } - jQuery('body').trigger('side-menu.apps', [apps]) - }); + document.querySelector('body').dispatchEvent(new CustomEvent('side-menu.apps', { + detail: {apps: apps}, + })) + }) }, retrieveActiveApp() { @@ -116,7 +118,7 @@ export default { that.targetBlankApps = config['target-blank-apps'] that.settings = config['settings'] - }); + }) }, }, mounted() { diff --git a/src/SideMenuWithCategories.vue b/src/SideMenuWithCategories.vue index 6b63689..7accbf0 100644 --- a/src/SideMenuWithCategories.vue +++ b/src/SideMenuWithCategories.vue @@ -95,8 +95,10 @@ export default { } } - jQuery('body').trigger('side-menu.apps', [apps]) - }); + document.querySelector('body').dispatchEvent(new CustomEvent('side-menu.apps', { + detail: {apps: apps}, + })) + }) }, retrieveActiveApp() { @@ -114,7 +116,7 @@ export default { that.targetBlankApps = config['target-blank-apps'] that.settings = config['settings'] - }); + }) }, }, mounted() { diff --git a/src/admin.js b/src/admin.js index c9b3c4d..3058e24 100644 --- a/src/admin.js +++ b/src/admin.js @@ -17,13 +17,23 @@ let elements = [] -const selector = '#side-menu-message'; +const selector = '#side-menu-message' const userConfig = (name, value, callbacks) => { const url = OC.generateUrl('/apps/side_menu/personalSetting/valueSet') + const formData = new FormData() + formData.append('name', name) + formData.append('value', value) - $.post(url, {name: name, value: value}, callbacks.success) - .fail(callbacks.error) + fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: formData + }) + .then(callbacks.success) + .catch(callbacks.error) } const appConfig = (name, value, callbacks) => { @@ -31,23 +41,29 @@ const appConfig = (name, value, callbacks) => { } const saveSettings = (key) => { - const element = elements.get(key) + const element = elements[key] + + if (!element) { + return + } + let value let name - if (jQuery(element).is('[data-checkbox]')) { - name = jQuery(element).attr('data-name') - const inputs = jQuery('input[name="' + name + '[]"]:checked') + if (element.hasAttribute('data-checkbox')) { + name = element.getAttribute('data-name') value = [] - inputs.each((i, v) => { - value.push(v.value) - }) + const inputs = document.querySelectorAll('input[name="' + name + '[]"]:checked') + + for (let input of inputs) { + value.push(input.value) + } value = JSON.stringify(value) } else { - name = jQuery(element).attr('name') - value = jQuery(element).val() + name = element.getAttribute('name') + value = element.value } const size = elements.length @@ -63,8 +79,8 @@ const saveSettings = (key) => { t('side_menu', (key + 1) + '/' + size) ) - if (key < size - 1) { - saveSettings(++key) + if (key < size) { + saveSettings(key + 1) } else { OC.msg.finishedSuccess(selector, t('side_menu', 'Saved')) } @@ -74,7 +90,7 @@ const saveSettings = (key) => { } } - if (jQuery(element).is('[data-personal]')) { + if (element.hasAttribute('data-personal')) { userConfig(name, value, callbacks) } else { appConfig(name, value, callbacks) @@ -82,84 +98,105 @@ const saveSettings = (key) => { } const elementToggler = (element) => { - jQuery(element).toggle() + let display = 'none' + + if (window.getComputedStyle(element).display === 'none') { + display = 'block' + } + + element.style.display = display } -jQuery(document).ready(() => { - elements = jQuery('.side-menu-setting') +document.addEventListener('DOMContentLoaded', () => { + elements = document.querySelectorAll('.side-menu-setting') - jQuery('#side-menu-save').on('click', (event) => { + document.querySelector('#side-menu-save').addEventListener('click', (event) => { event.preventDefault() OC.msg.startSaving(selector) saveSettings(0) - }); - - jQuery('.side-menu-display').on('click', (event) => { - var target = jQuery(event.target) - - jQuery('.side-menu-display').removeClass('is-active') - target.addClass('is-active') - - jQuery('#side-menu-always-displayed').val(target.attr('data-alwaysdiplayed')) - jQuery('#side-menu-big-menu').val(target.attr('data-bigmenu')) - jQuery('#side-menu-side-with-categories').val(target.attr('data-sidewithcategories')) }) - jQuery('.side-menu-setting-live').on('change', (event) => { - var target = jQuery(event.target) - var name = target.attr('name') - var value = target.val() + const displays = document.querySelectorAll('.side-menu-display') - if ('background-color-opacity' === name) { - return $('#side-menu-background-color, #side-menu-background-color-to').trigger('change'); - } else if ('dark-mode-background-color-opacity' === name) { - return $('#side-menu-dark-mode-background-color, #side-menu-dark-mode-background-color-to').trigger('change'); - } + for (let display of displays) { + display.addEventListener('click', (event) => { + const target = event.target - if (name === 'opener') { - var url = OC.generateUrl(`/apps/side_menu/img/${value}.svg`).replace('/index.php', '') + for (let d of displays) { + d.classList.toggle('is-active', d === display) + } - value = `url(${url})`; - } + document.querySelector('#side-menu-always-displayed').value = target.getAttribute('data-alwaysdiplayed') + document.querySelector('#side-menu-big-menu').value = target.getAttribute('data-bigmenu') + document.querySelector('#side-menu-side-with-categories').value = target.getAttribute('data-sidewithcategories') + }) + } - if (name === 'icon-invert-filter' || name === 'icon-opacity') { - value/=100; - } + for (let item of document.querySelectorAll('.side-menu-setting-live')) { + item.addEventListener('change', (event) => { + const target = event.target + const name = target.getAttribute('name') - if (['dark-mode-background-color', 'dark-mode-background-color-to'].indexOf(name) > -1) { - var opacity = parseInt($('#side-menu-dark-mode-background-color-opacity').val() * 255 / 100); + let value = target.value + let id = null - value = [value, opacity.toString(16)].join(''); - } else if (['background-color', 'background-color-to'].indexOf(name) > -1) { - var opacity = parseInt($('#side-menu-background-color-opacity').val() * 255 / 100); + if (name === 'background-color-opacity') { + id = '#side-menu-background-color, #side-menu-background-color-to' + } else if (name === 'dark-mode-background-color-opacity') { + id = '#side-menu-dark-mode-background-color, #side-menu-dark-mode-background-color-to' + } - value = [value, opacity.toString(16)].join(''); - } + if (id) { + document.querySelector(id).dispatchEvent(new CustomEvent('change')) - document.documentElement.style.setProperty('--side-menu-' + name, value) + return + } + + if (name === 'opener') { + const url = OC.generateUrl(`/apps/side_menu/img/${value}.svg`).replace('/index.php', '') + + value = `url(${url})` + } + + if (name === 'icon-invert-filter' || name === 'icon-opacity') { + value/=100 + } + + if (['dark-mode-background-color', 'dark-mode-background-color-to'].indexOf(name) > -1) { + const opacity = parseInt(document.querySelector('#side-menu-dark-mode-background-color-opacity').value * 255 / 100) + + value = [value, opacity.toString(16)].join('') + } else if (['background-color', 'background-color-to'].indexOf(name) > -1) { + const opacity = parseInt(document.querySelector('#side-menu-background-color-opacity').value * 255 / 100) + + value = [value, opacity.toString(16)].join('') + } + + document.documentElement.style.setProperty('--side-menu-' + name, value) + }) + } + + for (let toggler of document.querySelectorAll('.side-menu-toggler')) { + toggler.addEventListener('click', (event) => { + const target = event.target + const element = document.querySelector(target.getAttribute('data-target')) + + elementToggler(element) + }) + } + + sortable('#categories-list .side-menu-setting-list', { + placeholderClass: 'side-menu-setting-list-drop' }) - jQuery('.side-menu-toggler').on('click', (event) => { - var target = jQuery(event.target) - var element = target.attr('data-target') + sortable('#categories-list .side-menu-setting-list')[0].addEventListener('sortstop', (e) => { + let value = [] - elementToggler(element) + for (let item of document.querySelectorAll('#categories-list .side-menu-setting-list-item')) { + value.push(item.getAttribute('data-id')) + } + + document.querySelector('input[name="categories-order"]').value = JSON.stringify(value) }) - - jQuery("#categories-list .side-menu-setting-list").sortable({ - forcePlaceholderSize: true, - placeholder: 'placeholder', - stop: function (event, ui) { - let value = [] - - jQuery('#categories-list .side-menu-setting-list-item').each(function() { - value.push(jQuery(this).attr('data-id')) - }); - - value = JSON.stringify(value) - - jQuery('input[name="categories-order"]').val(value) - } - }); -}); +}) diff --git a/templates/js/_alwaysDisplayed.js b/templates/js/_alwaysDisplayed.js index 2b58bc7..e37230a 100644 --- a/templates/js/_alwaysDisplayed.js +++ b/templates/js/_alwaysDisplayed.js @@ -1,21 +1,19 @@ -var alwaysDisplayed = function() { - var elements = document.querySelectorAll('*'); - var fixedElements = [] - - for (var i in elements) { - var element = elements[i] +const alwaysDisplayed = function() { + const elements = querySelectorAll('*') + const fixedElements = [] + for (var element of elements) { if (typeof element !== 'object') { continue } - var position = window.getComputedStyle(element, null).getPropertyValue('position'); + const position = window.getComputedStyle(element, null).getPropertyValue('position') if (position !== 'fixed') { continue } - var id = element.getAttribute('id') + const id = element.getAttribute('id') if (id === 'header' || id === 'side-menu' || id === 'side-menu-loader') { continue @@ -25,7 +23,21 @@ var alwaysDisplayed = function() { continue } - if (jQuery(element).parents('#side-menu').length) { + let elementIsInSideMenu = false + let parent = element.parentNode + + while (parent && !elementIsInSideMenu) { + try { + if (parent.getAttribute('id') === 'side-menu') { + elementIsInSideMenu = true + } + } catch (e) { + } + + parent = parent.parentNode + } + + if (elementIsInSideMenu) { continue } @@ -33,19 +45,19 @@ var alwaysDisplayed = function() { } for (var i in fixedElements) { - var element = fixedElements[i] - var computedStyle = window.getComputedStyle(element, null) - var left = computedStyle.getPropertyValue('left') - var right = computedStyle.getPropertyValue('right') + const element = fixedElements[i] + const computedStyle = window.getComputedStyle(element, null) + const left = computedStyle.getPropertyValue('left') + const right = computedStyle.getPropertyValue('right') if (right !== '0px') { - var intValue = parseInt(left.replace('px', '')) - element.style.setProperty('transform', 'translateX(' + (intValue + 50) + 'px)') + const intValue = parseInt(left.replace('px', '')) + 50 + element.style.setProperty('transform', 'translateX(' + intValue.toString() + 'px)') } } } -let content = document.getElementById('content') +const content = querySelector('#content') if (content && content.classList.contains('app-settings')) { let loaded = false @@ -56,7 +68,7 @@ if (content && content.classList.contains('app-settings')) { } const observer = new MutationObserver(() => { if (loaded) { - return; + return } const element = content.querySelector('#app-category-your-apps') || content.querySelector('#app-navigation ul') diff --git a/templates/js/_loaderEnabled.js b/templates/js/_loaderEnabled.js index b391e4b..1d5ff4e 100644 --- a/templates/js/_loaderEnabled.js +++ b/templates/js/_loaderEnabled.js @@ -1,15 +1,14 @@ -var pageLoader = jQuery('