diff --git a/appinfo/app.php b/appinfo/app.php index 6a27b9d..3f2b281 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -24,6 +24,11 @@ use OCP\Util; $config = \OC::$server->getConfig(); $cspnm = \OC::$server->getContentSecurityPolicyNonceManager(); + + +Util::addScript('side_menu', 'sideMenu'); +Util::addStyle('side_menu', 'sideMenu'); + $stylesheet = \OC::$server->getURLGenerator()->linkToRoute( 'side_menu.Css.stylesheet', [ @@ -31,6 +36,13 @@ $stylesheet = \OC::$server->getURLGenerator()->linkToRoute( ] ); +$script = \OC::$server->getURLGenerator()->linkToRoute( + 'side_menu.Js.script', + [ + 'v' => $config->getAppValue('side_menu', 'cache', '0'), + ] +); + Util::addHeader( 'link', [ @@ -40,13 +52,11 @@ Util::addHeader( '' ); -Util::addScript('side_menu', 'main'); -Util::addScript('side_menu', 'sideMenu'); -Util::addStyle('side_menu', 'sideMenu'); -// whitelist the URL to allow loading JS from this external domain -// $CSPManager = \OC::$server->getContentSecurityPolicyManager(); -// $policy = new ContentSecurityPolicy(); -// $policy->addAllowedScriptDomain($url); -// $policy->addAllowedImageDomain($url); -// $policy->addAllowedConnectDomain($url); -// $CSPManager->addDefaultPolicy($policy); +Util::addHeader( + 'script', + [ + 'src' => $script, + 'nonce' => $cspnm->getNonce(), + ], + '' +); diff --git a/appinfo/routes.php b/appinfo/routes.php index cdbcf44..1ab6780 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -20,5 +20,6 @@ return [ 'routes' => [ ['name' => 'Css#stylesheet', 'url' => '/css/stylesheet.css', 'verb' => 'GET'], + ['name' => 'Js#script', 'url' => '/js/script.js', 'verb' => 'GET'], ], ]; diff --git a/lib/Controller/JsController.php b/lib/Controller/JsController.php new file mode 100644 index 0000000..f6ed7b2 --- /dev/null +++ b/lib/Controller/JsController.php @@ -0,0 +1,63 @@ +. + */ + +namespace OCA\SideMenu\Controller; + +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\Response; +use OCP\IConfig; +use OCP\IRequest; + +class JsController extends Controller +{ + + /** @var \OCP\IConfig */ + protected $config; + + /** + * @param string $appName + * @param IRequest $request + * @param IConfig $config + */ + public function __construct($appName, IRequest $request, IConfig $config) + { + parent::__construct($appName, $request); + + $this->config = $config; + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @PublicPage + * + * @return Response + */ + public function script() + { + $parameters = [ + 'opener-hover' => (bool) $this->config->getAppValue('side_menu', 'opener-hover', '0'), + ]; + + $response = new TemplateResponse('side_menu', 'js/script', $parameters, 'blank'); + $response->addHeader('Content-Type', 'text/javascript'); + + return $response; + } +} diff --git a/src/main.js b/src/main.js deleted file mode 100644 index d0d5846..0000000 --- a/src/main.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -const sideMenuContainer = $('
') -const sideMenuOpener = $('') -const sideMenu = $('
') - -sideMenuContainer.append(sideMenu); - -$('body').append(sideMenuContainer); - -sideMenuOpener.insertBefore('#nextcloud'); - -$('body').on('click', '.side-menu-opener', () => { - $('#side-menu').toggleClass('open'); -}) diff --git a/templates/js/script.php b/templates/js/script.php new file mode 100644 index 0000000..6ceaff9 --- /dev/null +++ b/templates/js/script.php @@ -0,0 +1,52 @@ +(function() { + var sideMenuContainer = $('
') + var sideMenuOpener = $('') + var sideMenu = $('
') + var body = $('body') + + body.append(sideMenuContainer) + + sideMenuContainer.append(sideMenu) + sideMenuOpener.insertBefore('#nextcloud') + + var isTouchDevice = window.matchMedia("(pointer: coarse)").matches + + body.on('side-menu.ready', function() { + sideMenu = $('#side-menu') + + var headerMenuOpener = $('#header .side-menu-opener') + var sideMenuOpener = $('#side-menu .side-menu-opener') + + + var sideMenuMouseLeave = function() { + sideMenu + .removeClass('open') + .off('mouseleave', sideMenuMouseLeave) + } + + var sideMenuMouseEnter = function() { + sideMenu.on('mouseleave', sideMenuMouseLeave) + } + + var sideMenuOpenerMouseEnter = function() { + sideMenu + .addClass('open') + .on('mouseenter', sideMenuMouseEnter) + } + + if (!isTouchDevice) { + headerMenuOpener.on('mouseenter', sideMenuOpenerMouseEnter) + + sideMenu.addClass('hide-opener') + } + + + headerMenuOpener.on('click', function() { + sideMenu.addClass('open'); + }) + + sideMenuOpener.on('click', function() { + sideMenu.removeClass('open'); + }) + }) +})();