A bit more elegant. Plus it will allow us to also write a proper @nextcloud/theming package. To make life easier down the line for all. Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl> Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>tags/v20.0.0beta1
@@ -46,16 +46,4 @@ $linkToCSS = \OC::$server->getURLGenerator()->linkToRoute( | |||
] | |||
); | |||
$linkToJs = \OC::$server->getURLGenerator()->linkToRoute( | |||
'theming.Theming.getJavascript', | |||
[ | |||
'v' => \OC::$server->getConfig()->getAppValue('theming', 'cachebuster', '0'), | |||
] | |||
); | |||
\OCP\Util::addHeader( | |||
'script', | |||
[ | |||
'src' => $linkToJs, | |||
'nonce' => \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() | |||
], '' | |||
); | |||
\OCP\Util::addScript('theming', 'theming'); |
@@ -54,11 +54,6 @@ return ['routes' => [ | |||
'url' => '/image/{key}', | |||
'verb' => 'GET', | |||
], | |||
[ | |||
'name' => 'Theming#getJavascript', | |||
'url' => '/js/theming', | |||
'verb' => 'GET', | |||
], | |||
[ | |||
'name' => 'Theming#getManifest', | |||
'url' => '/manifest/{app}', |
@@ -0,0 +1 @@ | |||
OCA.Theming = OCP.InitialState.loadState('theming', 'data') |
@@ -24,8 +24,28 @@ | |||
namespace OCA\Theming\AppInfo; | |||
use OCA\Theming\Service\JSDataService; | |||
use OCP\AppFramework\IAppContainer; | |||
use OCP\IInitialStateService; | |||
class Application extends \OCP\AppFramework\App { | |||
public const APP_ID = 'theming'; | |||
public function __construct() { | |||
parent::__construct('theming', []); | |||
parent::__construct(self::APP_ID); | |||
$container = $this->getContainer(); | |||
$this->registerInitialState($container); | |||
} | |||
private function registerInitialState(IAppContainer $container) { | |||
/** @var IInitialStateService $initialState */ | |||
$initialState = $container->query(IInitialStateService::class); | |||
$initialState->provideLazyInitialState(self::APP_ID, 'data', function () use ($container) { | |||
/** @var JSDataService $data */ | |||
$data = $container->query(JSDataService::class); | |||
return $data; | |||
}); | |||
} | |||
} |
@@ -42,11 +42,9 @@ namespace OCA\Theming\Controller; | |||
use OC\Template\SCSSCacher; | |||
use OCA\Theming\ImageManager; | |||
use OCA\Theming\ThemingDefaults; | |||
use OCA\Theming\Util; | |||
use OCP\App\IAppManager; | |||
use OCP\AppFramework\Controller; | |||
use OCP\AppFramework\Http; | |||
use OCP\AppFramework\Http\DataDownloadResponse; | |||
use OCP\AppFramework\Http\DataResponse; | |||
use OCP\AppFramework\Http\FileDisplayResponse; | |||
use OCP\AppFramework\Http\NotFoundResponse; | |||
@@ -69,8 +67,6 @@ use OCP\IURLGenerator; | |||
class ThemingController extends Controller { | |||
/** @var ThemingDefaults */ | |||
private $themingDefaults; | |||
/** @var Util */ | |||
private $util; | |||
/** @var IL10N */ | |||
private $l10n; | |||
/** @var IConfig */ | |||
@@ -95,7 +91,6 @@ class ThemingController extends Controller { | |||
* @param IRequest $request | |||
* @param IConfig $config | |||
* @param ThemingDefaults $themingDefaults | |||
* @param Util $util | |||
* @param IL10N $l | |||
* @param ITempManager $tempManager | |||
* @param IAppData $appData | |||
@@ -109,7 +104,6 @@ class ThemingController extends Controller { | |||
IRequest $request, | |||
IConfig $config, | |||
ThemingDefaults $themingDefaults, | |||
Util $util, | |||
IL10N $l, | |||
ITempManager $tempManager, | |||
IAppData $appData, | |||
@@ -121,7 +115,6 @@ class ThemingController extends Controller { | |||
parent::__construct($appName, $request); | |||
$this->themingDefaults = $themingDefaults; | |||
$this->util = $util; | |||
$this->l10n = $l; | |||
$this->config = $config; | |||
$this->tempManager = $tempManager; | |||
@@ -429,32 +422,6 @@ class ThemingController extends Controller { | |||
} | |||
} | |||
/** | |||
* @NoCSRFRequired | |||
* @PublicPage | |||
* @NoSameSiteCookieRequired | |||
* | |||
* @return DataDownloadResponse | |||
*/ | |||
public function getJavascript() { | |||
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0'); | |||
$responseJS = '(function() { | |||
OCA.Theming = { | |||
name: ' . json_encode($this->themingDefaults->getName()) . ', | |||
url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ', | |||
slogan: ' . json_encode($this->themingDefaults->getSlogan()) . ', | |||
color: ' . json_encode($this->themingDefaults->getColorPrimary()) . ', | |||
imprintUrl: ' . json_encode($this->themingDefaults->getImprintUrl()) . ', | |||
privacyUrl: ' . json_encode($this->themingDefaults->getPrivacyUrl()) . ', | |||
inverted: ' . json_encode($this->util->invertTextColor($this->themingDefaults->getColorPrimary())) . ', | |||
cacheBuster: ' . json_encode($cacheBusterValue) . ' | |||
}; | |||
})();'; | |||
$response = new DataDownloadResponse($responseJS, 'javascript', 'text/javascript'); | |||
$response->cacheFor(3600); | |||
return $response; | |||
} | |||
/** | |||
* @NoCSRFRequired | |||
* @PublicPage |
@@ -0,0 +1,64 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> | |||
* | |||
* @author Roeland Jago Douma <roeland@famdouma.nl> | |||
* | |||
* @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 <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace OCA\Theming\Service; | |||
use OCA\Theming\AppInfo\Application; | |||
use OCA\Theming\ThemingDefaults; | |||
use OCA\Theming\Util; | |||
use OCP\IConfig; | |||
class JSDataService implements \JsonSerializable { | |||
/** @var ThemingDefaults */ | |||
private $themingDefaults; | |||
/** @var Util */ | |||
private $util; | |||
/** @var IConfig */ | |||
private $appConfig; | |||
public function __construct( | |||
ThemingDefaults $themingDefaults, | |||
Util $util, | |||
IConfig $appConfig | |||
) { | |||
$this->themingDefaults = $themingDefaults; | |||
$this->util = $util; | |||
$this->appConfig = $appConfig; | |||
} | |||
public function jsonSerialize() { | |||
return [ | |||
'name' => $this->themingDefaults->getName(), | |||
'url' => $this->themingDefaults->getBaseUrl(), | |||
'slogan' => $this->themingDefaults->getSlogan(), | |||
'color' => $this->themingDefaults->getColorPrimary(), | |||
'imprintUrl' => $this->themingDefaults->getImprintUrl(), | |||
'privacyUrl' => $this->themingDefaults->getPrivacyUrl(), | |||
'inverted' => $this->util->invertTextColor($this->themingDefaults->getColorPrimary()), | |||
'cacheBuster' => $this->appConfig->getAppValue(Application::class, 'cachebuster', '0'), | |||
]; | |||
} | |||
} |
@@ -41,7 +41,6 @@ use OC\Template\SCSSCacher; | |||
use OCA\Theming\Controller\ThemingController; | |||
use OCA\Theming\ImageManager; | |||
use OCA\Theming\ThemingDefaults; | |||
use OCA\Theming\Util; | |||
use OCP\App\IAppManager; | |||
use OCP\AppFramework\Http; | |||
use OCP\AppFramework\Http\DataResponse; | |||
@@ -64,8 +63,6 @@ class ThemingControllerTest extends TestCase { | |||
private $config; | |||
/** @var ThemingDefaults|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $themingDefaults; | |||
/** @var Util */ | |||
private $util; | |||
/** @var \OCP\AppFramework\Utility\ITimeFactory */ | |||
private $timeFactory; | |||
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ | |||
@@ -92,7 +89,6 @@ class ThemingControllerTest extends TestCase { | |||
$this->l10n = $this->createMock(L10N::class); | |||
$this->appData = $this->createMock(IAppData::class); | |||
$this->appManager = $this->createMock(IAppManager::class); | |||
$this->util = new Util($this->config, $this->appManager, $this->appData); | |||
$this->tempManager = \OC::$server->getTempManager(); | |||
$this->scssCacher = $this->createMock(SCSSCacher::class); | |||
$this->urlGenerator = $this->createMock(IURLGenerator::class); | |||
@@ -110,7 +106,6 @@ class ThemingControllerTest extends TestCase { | |||
$this->request, | |||
$this->config, | |||
$this->themingDefaults, | |||
$this->util, | |||
$this->l10n, | |||
$this->tempManager, | |||
$this->appData, | |||
@@ -848,76 +843,6 @@ class ThemingControllerTest extends TestCase { | |||
$this->assertEquals($response, $actual); | |||
} | |||
public function testGetJavascript() { | |||
$this->themingDefaults | |||
->expects($this->at(0)) | |||
->method('getName') | |||
->willReturn(""); | |||
$this->themingDefaults | |||
->expects($this->at(1)) | |||
->method('getBaseUrl') | |||
->willReturn(""); | |||
$this->themingDefaults | |||
->expects($this->at(2)) | |||
->method('getSlogan') | |||
->willReturn(""); | |||
$this->themingDefaults | |||
->expects($this->at(3)) | |||
->method('getColorPrimary') | |||
->willReturn("#000"); | |||
$expectedResponse = '(function() { | |||
OCA.Theming = { | |||
name: "", | |||
url: "", | |||
slogan: "", | |||
color: "#000", | |||
imprintUrl: null, | |||
privacyUrl: null, | |||
inverted: false, | |||
cacheBuster: null | |||
}; | |||
})();'; | |||
$expected = new Http\DataDownloadResponse($expectedResponse, 'javascript', 'text/javascript'); | |||
$expected->cacheFor(3600); | |||
@$this->assertEquals($expected, $this->themingController->getJavascript()); | |||
} | |||
public function testGetJavascriptInverted() { | |||
$this->themingDefaults | |||
->expects($this->at(0)) | |||
->method('getName') | |||
->willReturn("Nextcloud"); | |||
$this->themingDefaults | |||
->expects($this->at(1)) | |||
->method('getBaseUrl') | |||
->willReturn("nextcloudurl"); | |||
$this->themingDefaults | |||
->expects($this->at(2)) | |||
->method('getSlogan') | |||
->willReturn("awesome"); | |||
$this->themingDefaults | |||
->expects($this->any()) | |||
->method('getColorPrimary') | |||
->willReturn("#ffffff"); | |||
$expectedResponse = '(function() { | |||
OCA.Theming = { | |||
name: "Nextcloud", | |||
url: "nextcloudurl", | |||
slogan: "awesome", | |||
color: "#ffffff", | |||
imprintUrl: null, | |||
privacyUrl: null, | |||
inverted: true, | |||
cacheBuster: null | |||
}; | |||
})();'; | |||
$expected = new Http\DataDownloadResponse($expectedResponse, 'javascript', 'text/javascript'); | |||
$expected->cacheFor(3600); | |||
@$this->assertEquals($expected, $this->themingController->getJavascript()); | |||
} | |||
public function testGetManifest() { | |||
$this->config | |||
->expects($this->once()) |