diff options
-rw-r--r-- | apps/theming/css/settings-admin.scss | 14 | ||||
-rw-r--r-- | apps/theming/js/settings-admin.js | 26 | ||||
-rw-r--r-- | apps/theming/lib/Controller/ThemingController.php | 11 | ||||
-rw-r--r-- | apps/theming/lib/Settings/Admin.php | 1 | ||||
-rw-r--r-- | apps/theming/lib/ThemingDefaults.php | 14 | ||||
-rw-r--r-- | apps/theming/templates/settings-admin.php | 11 | ||||
-rw-r--r-- | apps/theming/tests/Controller/ThemingControllerTest.php | 2 | ||||
-rw-r--r-- | apps/theming/tests/Settings/AdminTest.php | 10 | ||||
-rw-r--r-- | apps/theming/tests/ThemingDefaultsTest.php | 71 | ||||
-rw-r--r-- | core/css/guest.css | 4 |
10 files changed, 144 insertions, 20 deletions
diff --git a/apps/theming/css/settings-admin.scss b/apps/theming/css/settings-admin.scss index ceb560f0f02..7753540ccd2 100644 --- a/apps/theming/css/settings-admin.scss +++ b/apps/theming/css/settings-admin.scss @@ -28,7 +28,7 @@ visibility: hidden; } form.uploadButton { - width: 356px; + width: 411px; } form .theme-undo, .theme-remove-bg { @@ -46,13 +46,17 @@ input[type='text']:hover + .theme-undo, input[type='text'] + .theme-undo:hover, input[type='text']:focus + .theme-undo, - input[type='text']:active + .theme-undo { + input[type='text']:active + .theme-undo, + input[type='url']:hover + .theme-undo, + input[type='url'] + .theme-undo:hover, + input[type='url']:focus + .theme-undo, + input[type='url']:active + .theme-undo{ visibility: visible; } label span { display: inline-block; - min-width: 120px; + min-width: 175px; padding: 8px 0px; vertical-align: top; } @@ -88,7 +92,7 @@ background-size: cover; background-position: center center; text-align: center; - margin-left: 123px; + margin-left: 178px; margin-top: 10px; margin-bottom: 20px; cursor: pointer; @@ -117,4 +121,4 @@ background-repeat: no-repeat; background-size: contain; } -}
\ No newline at end of file +} diff --git a/apps/theming/js/settings-admin.js b/apps/theming/js/settings-admin.js index 25ac092a964..76d9fb965ca 100644 --- a/apps/theming/js/settings-admin.js +++ b/apps/theming/js/settings-admin.js @@ -83,7 +83,8 @@ function hideUndoButton(setting, value) { url: 'https://nextcloud.com', color: '#0082c9', logoMime: '', - backgroundMime: '' + backgroundMime: '', + imprintUrl: '' }; if (value === themingDefaults[setting] || value === '') { @@ -175,7 +176,7 @@ $(document).ready(function () { var el = $(this); }); - $('#theming input[type=text]').change(function(e) { + function onChange(e) { var el = $(this); var setting = el.parent().find('div[data-setting]').data('setting'); var value = $(this).val(); @@ -186,14 +187,14 @@ $(document).ready(function () { } } if(setting === 'name') { - if(checkName()){ - $.when(el.focusout()).then(function() { - setThemingValue('name', value); - }); - if (e.keyCode == 13) { - setThemingValue('name', value); - } - } + if(checkName()){ + $.when(el.focusout()).then(function() { + setThemingValue('name', value); + }); + if (e.keyCode == 13) { + setThemingValue('name', value); + } + } } $.when(el.focusout()).then(function() { @@ -202,7 +203,10 @@ $(document).ready(function () { if (e.keyCode == 13) { setThemingValue(setting, value); } - }); + }; + + $('#theming input[type="text"]').change(onChange); + $('#theming input[type="url"]').change(onChange); $('.theme-undo').click(function (e) { var setting = $(this).data('setting'); diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php index e4a8f0b5036..dd7bf4bb04d 100644 --- a/apps/theming/lib/Controller/ThemingController.php +++ b/apps/theming/lib/Controller/ThemingController.php @@ -161,6 +161,16 @@ class ThemingController extends Controller { ]); } break; + case 'imprintUrl': + if (strlen($value) > 500) { + return new DataResponse([ + 'data' => [ + 'message' => $this->l10n->t('The given legal notice address is too long'), + ], + 'status' => 'error' + ]); + } + break; case 'slogan': if (strlen($value) > 500) { return new DataResponse([ @@ -408,6 +418,7 @@ class ThemingController extends Controller { url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ', slogan: ' . json_encode($this->themingDefaults->getSlogan()) . ', color: ' . json_encode($this->themingDefaults->getColorPrimary()) . ', + imprintUrl: ' . json_encode($this->themingDefaults->getImprintUrl()) . ', inverted: ' . json_encode($this->util->invertTextColor($this->themingDefaults->getColorPrimary())) . ', cacheBuster: ' . json_encode($cacheBusterValue) . ' }; diff --git a/apps/theming/lib/Settings/Admin.php b/apps/theming/lib/Settings/Admin.php index 7c937f19790..ef296688ed2 100644 --- a/apps/theming/lib/Settings/Admin.php +++ b/apps/theming/lib/Settings/Admin.php @@ -84,6 +84,7 @@ class Admin implements ISettings { 'canThemeIcons' => $this->themingDefaults->shouldReplaceIcons(), 'iconDocs' => $this->urlGenerator->linkToDocs('admin-theming-icons'), 'images' => $this->imageManager->getCustomImages(), + 'imprintUrl' => $this->themingDefaults->getImprintUrl(), ]; return new TemplateResponse('theming', 'settings-admin', $parameters, ''); diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php index 2e6b667b1f6..d2f57471242 100644 --- a/apps/theming/lib/ThemingDefaults.php +++ b/apps/theming/lib/ThemingDefaults.php @@ -141,12 +141,26 @@ class ThemingDefaults extends \OC_Defaults { return \OCP\Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', $this->slogan)); } + public function getImprintUrl() { + return $this->config->getAppValue('theming', 'imprintUrl', ''); + } + public function getShortFooter() { $slogan = $this->getSlogan(); $footer = '<a href="'. $this->getBaseUrl() . '" target="_blank"' . ' rel="noreferrer noopener">' .$this->getEntity() . '</a>'. ($slogan !== '' ? ' – ' . $slogan : ''); + $imprintUrl = (string)$this->getImprintUrl(); + if($imprintUrl !== '' + && filter_var($imprintUrl, FILTER_VALIDATE_URL, [ + 'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED + ]) + ) { + $footer .= '<br/><a href="' . $imprintUrl . '" class="legal" target="_blank"' . + ' rel="noreferrer noopener">' . $this->l->t('Legal notice') . '</a>'; + } + return $footer; } diff --git a/apps/theming/templates/settings-admin.php b/apps/theming/templates/settings-admin.php index ea9925f3a64..26ab78637c9 100644 --- a/apps/theming/templates/settings-admin.php +++ b/apps/theming/templates/settings-admin.php @@ -47,8 +47,8 @@ style('theming', 'settings-admin'); </div> <div> <label> - <span><?php p($l->t('Web address')) ?></span> - <input id="theming-url" type="url" placeholder="<?php p($l->t('Web address https://…')); ?>" value="<?php p($_['url']) ?>" maxlength="500" /> + <span><?php p($l->t('Web link')) ?></span> + <input id="theming-url" type="url" placeholder="<?php p($l->t('https://…')); ?>" value="<?php p($_['url']) ?>" maxlength="500" /> <div data-setting="url" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div> </label> </div> @@ -94,6 +94,13 @@ style('theming', 'settings-admin'); <h2 class="inlineblock"><?php p($l->t('Advanced options')); ?></h2> <div class="advanced-options"> + <div> + <label> + <span><?php p($l->t('Legal notice link')) ?></span> + <input id="theming-imprintUrl" type="url" placeholder="<?php p($l->t('https://…')); ?>" value="<?php p($_['imprintUrl']) ?>" maxlength="500" /> + <div data-setting="imprintUrl" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div> + </label> + </div> <div class="advanced-option-logoheader"> <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>" data-image-key="logoheader"> <input type="hidden" id="theming-logoheaderMime" value="<?php p($_['images']['logoheader']['mime']); ?>" /> diff --git a/apps/theming/tests/Controller/ThemingControllerTest.php b/apps/theming/tests/Controller/ThemingControllerTest.php index eddf5bc56dc..f196541d371 100644 --- a/apps/theming/tests/Controller/ThemingControllerTest.php +++ b/apps/theming/tests/Controller/ThemingControllerTest.php @@ -817,6 +817,7 @@ class ThemingControllerTest extends TestCase { url: "", slogan: "", color: "#000", + imprintUrl: null, inverted: false, cacheBuster: null }; @@ -851,6 +852,7 @@ class ThemingControllerTest extends TestCase { url: "nextcloudurl", slogan: "awesome", color: "#ffffff", + imprintUrl: null, inverted: true, cacheBuster: null }; diff --git a/apps/theming/tests/Settings/AdminTest.php b/apps/theming/tests/Settings/AdminTest.php index 4eac689fb3f..f7361677d77 100644 --- a/apps/theming/tests/Settings/AdminTest.php +++ b/apps/theming/tests/Settings/AdminTest.php @@ -83,6 +83,10 @@ class AdminTest extends TestCase { ->willReturn('https://example.com'); $this->themingDefaults ->expects($this->once()) + ->method('getImprintUrl') + ->willReturn(''); + $this->themingDefaults + ->expects($this->once()) ->method('getSlogan') ->willReturn('MySlogan'); $this->themingDefaults @@ -105,6 +109,7 @@ class AdminTest extends TestCase { 'canThemeIcons' => null, 'iconDocs' => null, 'images' => [], + 'imprintUrl' => '', ]; $expected = new TemplateResponse('theming', 'settings-admin', $params, ''); @@ -132,6 +137,10 @@ class AdminTest extends TestCase { ->willReturn('https://example.com'); $this->themingDefaults ->expects($this->once()) + ->method('getImprintUrl') + ->willReturn(''); + $this->themingDefaults + ->expects($this->once()) ->method('getSlogan') ->willReturn('MySlogan'); $this->themingDefaults @@ -154,6 +163,7 @@ class AdminTest extends TestCase { 'canThemeIcons' => null, 'iconDocs' => '', 'images' => [], + 'imprintUrl' => '', ]; $expected = new TemplateResponse('theming', 'settings-admin', $params, ''); diff --git a/apps/theming/tests/ThemingDefaultsTest.php b/apps/theming/tests/ThemingDefaultsTest.php index c943af01c6c..b454b21f840 100644 --- a/apps/theming/tests/ThemingDefaultsTest.php +++ b/apps/theming/tests/ThemingDefaultsTest.php @@ -195,6 +195,27 @@ class ThemingDefaultsTest extends TestCase { $this->assertEquals('https://example.com/', $this->template->getBaseUrl()); } + public function imprintUrlProvider() { + return [ + [ '' ], + [ 'https://example.com/imprint.html'] + ]; + } + + /** + * @param $imprintUrl + * @dataProvider imprintUrlProvider + */ + public function testGetImprintURL($imprintUrl) { + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('theming', 'imprintUrl', '') + ->willReturn($imprintUrl); + + $this->assertEquals($imprintUrl, $this->template->getImprintUrl()); + } + public function testGetSloganWithDefault() { $this->config ->expects($this->once()) @@ -217,12 +238,13 @@ class ThemingDefaultsTest extends TestCase { public function testGetShortFooter() { $this->config - ->expects($this->exactly(3)) + ->expects($this->exactly(4)) ->method('getAppValue') ->willReturnMap([ ['theming', 'url', $this->defaults->getBaseUrl(), 'url'], ['theming', 'name', 'Nextcloud', 'Name'], ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'], + ['theming', 'imprintUrl', '', ''], ]); $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> – Slogan', $this->template->getShortFooter()); @@ -230,17 +252,62 @@ class ThemingDefaultsTest extends TestCase { public function testGetShortFooterEmptySlogan() { $this->config - ->expects($this->exactly(3)) + ->expects($this->exactly(4)) ->method('getAppValue') ->willReturnMap([ ['theming', 'url', $this->defaults->getBaseUrl(), 'url'], ['theming', 'name', 'Nextcloud', 'Name'], ['theming', 'slogan', $this->defaults->getSlogan(), ''], + ['theming', 'imprintUrl', '', ''], ]); $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a>', $this->template->getShortFooter()); } + public function testGetShortFooterImprint() { + $this->config + ->expects($this->exactly(4)) + ->method('getAppValue') + ->willReturnMap([ + ['theming', 'url', $this->defaults->getBaseUrl(), 'url'], + ['theming', 'name', 'Nextcloud', 'Name'], + ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'], + ['theming', 'imprintUrl', '', 'https://example.com/imprint'], + ]); + + $this->l10n + ->expects($this->any()) + ->method('t') + ->willReturnArgument(0); + + $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> – Slogan<br/><a href="https://example.com/imprint" class="legal" target="_blank" rel="noreferrer noopener">Legal notice</a>', $this->template->getShortFooter()); + } + + public function invalidImprintUrlProvider() { + return [ + ['example.com/imprint'], # missing scheme + ['https:///imprint'], # missing host + ]; + } + + /** + * @param $invalidImprintUrl + * @dataProvider invalidImprintUrlProvider + */ + public function testGetShortFooterInvalidImprint($invalidImprintUrl) { + $this->config + ->expects($this->exactly(4)) + ->method('getAppValue') + ->willReturnMap([ + ['theming', 'url', $this->defaults->getBaseUrl(), 'url'], + ['theming', 'name', 'Nextcloud', 'Name'], + ['theming', 'slogan', $this->defaults->getSlogan(), 'Slogan'], + ['theming', 'imprintUrl', '', $invalidImprintUrl], + ]); + + $this->assertEquals('<a href="url" target="_blank" rel="noreferrer noopener">Name</a> – Slogan', $this->template->getShortFooter()); + } + public function testgetColorPrimaryWithDefault() { $this->config ->expects($this->once()) diff --git a/core/css/guest.css b/core/css/guest.css index e0e639252ee..88341fb903a 100644 --- a/core/css/guest.css +++ b/core/css/guest.css @@ -744,6 +744,10 @@ footer .info a { overflow: hidden; } +a.legal { + font-size: smaller; +} + /* for low-res screens, use Regular font-weight instead of Light */ @media (-webkit-max-device-pixel-ratio: 1.3), (max-resolution: 124.8dpi) { @font-face { |