Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Haertl <jus@bitgrid.net>2017-02-17 18:42:07 +0300
committerJoas Schilling <coding@schilljs.com>2017-04-25 12:39:45 +0300
commit68a63ad3f33c683d726219a508bb31de7b9ab1d0 (patch)
tree910932971b761689c8ca843860119a1df6e29573 /apps/theming/lib/Controller
parent133f3fdc9aec28383dba323d58569eddd160b0df (diff)
Implement scss variable injection by OC_Defaults
Signed-off-by: Julius Haertl <jus@bitgrid.net> Add Scss variables to example theme and theming app Signed-off-by: Julius Haertl <jus@bitgrid.net> Use SCSSCacher to build theming css Signed-off-by: Julius Härtl <jus@bitgrid.net> Update theming.scss Signed-off-by: Julius Härtl <jus@bitgrid.net> Code cleanup Signed-off-by: Julius Härtl <jus@bitgrid.net> Fix tests Signed-off-by: Julius Härtl <jus@bitgrid.net> Inject SCSSCacher for easier testing Signed-off-by: Julius Härtl <jus@bitgrid.net> Fix typehint Signed-off-by: Lukas Reschke <lukas@statuscode.ch> Generate absolute URLs Signed-off-by: Lukas Reschke <lukas@statuscode.ch> Fix tests to always use absolute urls for theming images Signed-off-by: Julius Härtl <jus@bitgrid.net> MailheaderColor -> ColorPrimary Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'apps/theming/lib/Controller')
-rw-r--r--apps/theming/lib/Controller/ThemingController.php209
1 files changed, 62 insertions, 147 deletions
diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php
index 093134e6c5e..b2d603bb68a 100644
--- a/apps/theming/lib/Controller/ThemingController.php
+++ b/apps/theming/lib/Controller/ThemingController.php
@@ -27,6 +27,8 @@
namespace OCA\Theming\Controller;
+use OC\Files\AppData\Factory;
+use OC\Template\SCSSCacher;
use OCA\Theming\ThemingDefaults;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
@@ -40,9 +42,11 @@ use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\IConfig;
use OCP\IL10N;
+use OCP\ILogger;
use OCP\IRequest;
use OCA\Theming\Util;
use OCP\ITempManager;
+use OCP\IURLGenerator;
/**
* Class ThemingController
@@ -53,19 +57,21 @@ use OCP\ITempManager;
*/
class ThemingController extends Controller {
/** @var ThemingDefaults */
- private $template;
+ private $themingDefaults;
/** @var Util */
private $util;
/** @var ITimeFactory */
private $timeFactory;
/** @var IL10N */
- private $l;
+ private $l10n;
/** @var IConfig */
private $config;
/** @var ITempManager */
private $tempManager;
/** @var IAppData */
private $appData;
+ /** @var SCSSCacher */
+ private $scssCacher;
/**
* ThemingController constructor.
@@ -73,33 +79,36 @@ class ThemingController extends Controller {
* @param string $appName
* @param IRequest $request
* @param IConfig $config
- * @param ThemingDefaults $template
+ * @param ThemingDefaults $themingDefaults
* @param Util $util
* @param ITimeFactory $timeFactory
* @param IL10N $l
* @param ITempManager $tempManager
* @param IAppData $appData
+ * @param SCSSCacher $scssCacher
*/
public function __construct(
$appName,
IRequest $request,
IConfig $config,
- ThemingDefaults $template,
+ ThemingDefaults $themingDefaults,
Util $util,
ITimeFactory $timeFactory,
IL10N $l,
ITempManager $tempManager,
- IAppData $appData
+ IAppData $appData,
+ SCSSCacher $scssCacher
) {
parent::__construct($appName, $request);
- $this->template = $template;
+ $this->themingDefaults = $themingDefaults;
$this->util = $util;
$this->timeFactory = $timeFactory;
- $this->l = $l;
+ $this->l10n = $l;
$this->config = $config;
$this->tempManager = $tempManager;
$this->appData = $appData;
+ $this->scssCacher = $scssCacher;
}
/**
@@ -115,7 +124,7 @@ class ThemingController extends Controller {
if (strlen($value) > 250) {
return new DataResponse([
'data' => [
- 'message' => $this->l->t('The given name is too long'),
+ 'message' => $this->l10n->t('The given name is too long'),
],
'status' => 'error'
]);
@@ -125,7 +134,7 @@ class ThemingController extends Controller {
if (strlen($value) > 500) {
return new DataResponse([
'data' => [
- 'message' => $this->l->t('The given web address is too long'),
+ 'message' => $this->l10n->t('The given web address is too long'),
],
'status' => 'error'
]);
@@ -135,7 +144,7 @@ class ThemingController extends Controller {
if (strlen($value) > 500) {
return new DataResponse([
'data' => [
- 'message' => $this->l->t('The given slogan is too long'),
+ 'message' => $this->l10n->t('The given slogan is too long'),
],
'status' => 'error'
]);
@@ -145,7 +154,7 @@ class ThemingController extends Controller {
if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $value)) {
return new DataResponse([
'data' => [
- 'message' => $this->l->t('The given color is invalid'),
+ 'message' => $this->l10n->t('The given color is invalid'),
],
'status' => 'error'
]);
@@ -153,12 +162,12 @@ class ThemingController extends Controller {
break;
}
- $this->template->set($setting, $value);
+ $this->themingDefaults->set($setting, $value);
return new DataResponse(
[
'data' =>
[
- 'message' => $this->l->t('Saved')
+ 'message' => $this->l10n->t('Saved')
],
'status' => 'success'
]
@@ -177,7 +186,7 @@ class ThemingController extends Controller {
return new DataResponse(
[
'data' => [
- 'message' => $this->l->t('No file uploaded')
+ 'message' => $this->l10n->t('No file uploaded')
]
],
Http::STATUS_UNPROCESSABLE_ENTITY
@@ -191,20 +200,20 @@ class ThemingController extends Controller {
$folder = $this->appData->newFolder('images');
}
- if(!empty($newLogo)) {
+ if (!empty($newLogo)) {
$target = $folder->newFile('logo');
$target->putContent(file_get_contents($newLogo['tmp_name'], 'r'));
- $this->template->set('logoMime', $newLogo['type']);
+ $this->themingDefaults->set('logoMime', $newLogo['type']);
$name = $newLogo['name'];
}
- if(!empty($newBackgroundLogo)) {
+ if (!empty($newBackgroundLogo)) {
$target = $folder->newFile('background');
$image = @imagecreatefromstring(file_get_contents($newBackgroundLogo['tmp_name'], 'r'));
- if($image === false) {
+ if ($image === false) {
return new DataResponse(
[
'data' => [
- 'message' => $this->l->t('Unsupported image type'),
+ 'message' => $this->l10n->t('Unsupported image type'),
],
'status' => 'failure',
],
@@ -215,10 +224,10 @@ class ThemingController extends Controller {
// Optimize the image since some people may upload images that will be
// either to big or are not progressive rendering.
$tmpFile = $this->tempManager->getTemporaryFile();
- if(function_exists('imagescale')) {
+ if (function_exists('imagescale')) {
// FIXME: Once PHP 5.5.0 is a requirement the above check can be removed
// Workaround for https://bugs.php.net/bug.php?id=65171
- $newHeight = imagesy($image)/(imagesx($image)/1920);
+ $newHeight = imagesy($image) / (imagesx($image) / 1920);
$image = imagescale($image, 1920, $newHeight);
}
imageinterlace($image, 1);
@@ -226,7 +235,7 @@ class ThemingController extends Controller {
imagedestroy($image);
$target->putContent(file_get_contents($tmpFile, 'r'));
- $this->template->set('backgroundMime', $newBackgroundLogo['type']);
+ $this->themingDefaults->set('backgroundMime', $newBackgroundLogo['type']);
$name = $newBackgroundLogo['name'];
}
@@ -235,7 +244,7 @@ class ThemingController extends Controller {
'data' =>
[
'name' => $name,
- 'message' => $this->l->t('Saved')
+ 'message' => $this->l10n->t('Saved')
],
'status' => 'success'
]
@@ -249,13 +258,13 @@ class ThemingController extends Controller {
* @return DataResponse
*/
public function undo($setting) {
- $value = $this->template->undo($setting);
+ $value = $this->themingDefaults->undo($setting);
return new DataResponse(
[
'data' =>
[
'value' => $value,
- 'message' => $this->l->t('Saved')
+ 'message' => $this->l10n->t('Saved')
],
'status' => 'success'
]
@@ -316,128 +325,34 @@ class ThemingController extends Controller {
* @NoCSRFRequired
* @PublicPage
*
- * @return DataDownloadResponse
+ * @return FileDisplayResponse|NotFoundResponse
*/
public function getStylesheet() {
- $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
- $responseCss = '';
- $color = $this->config->getAppValue($this->appName, 'color');
- $elementColor = $this->util->elementColor($color);
-
- if($this->util->invertTextColor($color)) {
- $textColor = '#000000';
- } else {
- $textColor = '#ffffff';
- }
-
- if($color !== '') {
- $responseCss .= sprintf(
- '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n",
- $color
- );
- $responseCss .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
- 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
- 'background-color: %s; background-position: center center; background-size:contain;' .
- 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
- "}\n",
- \OC::$WEBROOT,
- $elementColor
- );
- $responseCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
- 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($elementColor).'\');' .
- "}\n";
- $responseCss .= '.primary, input[type="submit"].primary, input[type="button"].primary, button.primary, .button.primary,' .
- '.primary:active, input[type="submit"].primary:active, input[type="button"].primary:active, button.primary:active, .button.primary:active {' .
- 'border: 1px solid '.$elementColor.';'.
- 'background-color: '.$elementColor.';'.
- 'color: ' . $textColor . ';'.
- "}\n" .
- '.primary:hover, input[type="submit"].primary:hover, input[type="button"].primary:hover, button.primary:hover, .button.primary:hover,' .
- '.primary:focus, input[type="submit"].primary:focus, input[type="button"].primary:focus, button.primary:focus, .button.primary:focus {' .
- 'border: 1px solid '.$elementColor.';'.
- 'background-color: '.$elementColor.';'.
- 'color: ' . $textColor . ';'.
- "}\n" .
- '.primary:disabled, input[type="submit"].primary:disabled, input[type="button"].primary:disabled, button.primary:disabled, .button.primary:disabled,' .
- '.primary:disabled:hover, input[type="submit"].primary:disabled:hover, input[type="button"].primary:disabled:hover, button.primary:disabled:hover, .button.primary:disabled:hover,' .
- '.primary:disabled:focus, input[type="submit"].primary:disabled:focus, input[type="button"].primary:disabled:focus, button.primary:disabled:focus, .button.primary:disabled:focus {' .
- 'border: 1px solid '.$elementColor.';'.
- 'background-color: '.$elementColor.';'.
- 'opacity: 0.4;' .
- 'color: '.$textColor.';'.
- "}\n";
- $responseCss .= '.ui-widget-header { border: 1px solid ' . $color . '; background: '. $color . '; color: #ffffff;' . "}\n";
- $responseCss .= '.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {' .
- 'border: 1px solid ' . $color . ';' .
- 'color: ' . $elementColor . ';' .
- "}\n";
- $responseCss .= '.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited {' .
- 'color: ' . $elementColor . ';' .
- "}\n";
- $responseCss .= '
- #firstrunwizard .firstrunwizard-header {
- background-color: ' . $color . ';
- }
- #firstrunwizard p a {
- color: ' . $color . ';
- }
- ';
- $responseCss .= sprintf('.nc-theming-main-background {background-color: %s}' . "\n", $color);
- $responseCss .= sprintf('.nc-theming-main-text {color: %s}' . "\n", $color);
- $responseCss .= sprintf('#app-navigation li:hover > a, #app-navigation li:focus > a, #app-navigation a:focus, #app-navigation .selected, #app-navigation .selected a, #app-navigation .active, #app-navigation .active a {box-shadow: inset 2px 0 %s}' . "\n", $color);
-
- }
- $logo = $this->config->getAppValue($this->appName, 'logoMime');
- if($logo !== '') {
- $responseCss .= sprintf(
- '#header .logo {' .
- 'background-image: url(\'./logo?v='.$cacheBusterValue.'\');' .
- 'background-size: contain;' .
- '}' . "\n" .
- '#header .logo-icon {' .
- 'background-image: url(\'./logo?v='.$cacheBusterValue.'\');' .
- 'background-size: contain;' .
- '}' . "\n" .
- '#firstrunwizard .firstrunwizard-header .logo {' .
- 'background-image: url(\'./logo?v='.$cacheBusterValue.'\');' .
- 'background-size: contain;' .
- '}' . "\n"
- );
- }
- $backgroundLogo = $this->config->getAppValue($this->appName, 'backgroundMime');
- if($backgroundLogo !== '') {
- $responseCss .= '#body-login {background-image: url(\'./loginbackground?v='.$cacheBusterValue.'\');}' . "\n";
- $responseCss .= '#firstrunwizard .firstrunwizard-header {' .
- 'background-image: url(\'./loginbackground?v='.$cacheBusterValue.'\');' .
- '}' . "\n";
- }
- if($this->util->invertTextColor($color)) {
- $responseCss .= '#header .header-appname, #expandDisplayName { color: #000000; }' . "\n";
- $responseCss .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); }' . "\n";
- $responseCss .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n";
- $responseCss .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n";
- $responseCss .= '#body-login input.login { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/confirm.svg?v=2\'); }' . "\n";
- $responseCss .= '.nc-theming-contrast {color: #000000}' . "\n";
- $responseCss .= '.ui-widget-header { color: #000000; }' . "\n";
- } else {
- $responseCss .= '.nc-theming-contrast {color: #ffffff}' . "\n";
+ $appPath = substr(\OC::$server->getAppManager()->getAppPath('theming'), strlen(\OC::$SERVERROOT) + 1);
+ /* SCSSCacher is required here
+ * We cannot rely on automatic caching done by \OC_Util::addStyle,
+ * since we need to add the cacheBuster value to the url
+ */
+ $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, $appPath . '/css/theming.scss', 'theming');
+ if(!$cssCached) {
+ return new NotFoundResponse();
}
- if($logo !== '' or $color !== '') {
- $responseCss .= '.icon-file,.icon-filetype-text {' .
- 'background-image: url(\'./img/core/filetypes/text.svg?v='.$cacheBusterValue.'\');' . "}\n" .
- '.icon-folder, .icon-filetype-folder {' .
- 'background-image: url(\'./img/core/filetypes/folder.svg?v='.$cacheBusterValue.'\');' . "}\n" .
- '.icon-filetype-folder-drag-accept {' .
- 'background-image: url(\'./img/core/filetypes/folder-drag-accept.svg?v='.$cacheBusterValue.'\')!important;' . "}\n";
+ try {
+ $cssFile = $this->scssCacher->getCachedCSS('theming', 'theming.css');
+ $response = new FileDisplayResponse($cssFile, Http::STATUS_OK, ['Content-Type' => 'text/css']);
+ $response->cacheFor(86400);
+ $expires = new \DateTime();
+ $expires->setTimestamp($this->timeFactory->getTime());
+ $expires->add(new \DateInterval('PT24H'));
+ $response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
+ $response->addHeader('Pragma', 'cache');
+ return $response;
+ } catch (NotFoundException $e) {
+ return new NotFoundResponse();
}
-
- $response = new DataDownloadResponse($responseCss, 'style', 'text/css');
- $response->addHeader('Expires', date(\DateTime::RFC2822, $this->timeFactory->getTime()));
- $response->addHeader('Pragma', 'cache');
- $response->cacheFor(3600);
- return $response;
}
+
/**
* @NoCSRFRequired
* @PublicPage
@@ -448,12 +363,12 @@ class ThemingController extends Controller {
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
$responseJS = '(function() {
OCA.Theming = {
- name: ' . json_encode($this->template->getName()) . ',
- url: ' . json_encode($this->template->getBaseUrl()) . ',
- slogan: ' . json_encode($this->template->getSlogan()) . ',
- color: ' . json_encode($this->template->getColorPrimary()) . ',
- inverted: ' . json_encode($this->util->invertTextColor($this->template->getColorPrimary())) . ',
- cacheBuster: ' . json_encode($cacheBusterValue). '
+ name: ' . json_encode($this->themingDefaults->getName()) . ',
+ url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ',
+ slogan: ' . json_encode($this->themingDefaults->getSlogan()) . ',
+ color: ' . json_encode($this->themingDefaults->getColorPrimary()) . ',
+ inverted: ' . json_encode($this->util->invertTextColor($this->themingDefaults->getColorPrimary())) . ',
+ cacheBuster: ' . json_encode($cacheBusterValue) . '
};
})();';
$response = new DataDownloadResponse($responseJS, 'javascript', 'text/javascript');