mirror of
https://github.com/nextcloud/server.git
synced 2026-04-05 09:06:35 -04:00
Merge pull request #32231 from nextcloud/feat/theming-scheme-meta
This commit is contained in:
parent
cdf7840d00
commit
6364e53e5a
7 changed files with 84 additions and 23 deletions
|
|
@ -71,6 +71,14 @@ interface ITheme {
|
|||
*/
|
||||
public function getDescription(): string;
|
||||
|
||||
/**
|
||||
* Get the meta attribute matching the theme
|
||||
* e.g. https://html.spec.whatwg.org/multipage/semantics.html#meta-color-scheme
|
||||
* @return array{name?: string, content?: string}[]
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getMeta(): array;
|
||||
|
||||
/**
|
||||
* Get the media query triggering this theme
|
||||
* Optional, ignored if falsy
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
namespace OCA\Theming\Service;
|
||||
|
||||
use OCA\Theming\ITheme;
|
||||
use OCA\Theming\Themes\DefaultTheme;
|
||||
use OCA\Theming\Util;
|
||||
use OCP\IConfig;
|
||||
|
|
@ -48,6 +49,7 @@ class ThemeInjectionService {
|
|||
$this->defaultTheme = $defaultTheme;
|
||||
$this->util = $util;
|
||||
$this->config = $config;
|
||||
|
||||
if ($userSession->getUser() !== null) {
|
||||
$this->userId = $userSession->getUser()->getUID();
|
||||
} else {
|
||||
|
|
@ -55,7 +57,7 @@ class ThemeInjectionService {
|
|||
}
|
||||
}
|
||||
|
||||
public function injectHeaders() {
|
||||
public function injectHeaders(): void {
|
||||
$themes = $this->themesService->getThemes();
|
||||
$defaultTheme = $themes[$this->defaultTheme->getId()];
|
||||
$mediaThemes = array_filter($themes, function ($theme) {
|
||||
|
|
@ -64,11 +66,11 @@ class ThemeInjectionService {
|
|||
});
|
||||
|
||||
// Default theme fallback
|
||||
$this->addThemeHeader($defaultTheme->getId());
|
||||
$this->addThemeHeaders($defaultTheme);
|
||||
|
||||
// Themes applied by media queries
|
||||
foreach($mediaThemes as $theme) {
|
||||
$this->addThemeHeader($theme->getId(), true, $theme->getMediaQuery());
|
||||
$this->addThemeHeaders($theme, true, $theme->getMediaQuery());
|
||||
}
|
||||
|
||||
// Themes
|
||||
|
|
@ -77,20 +79,23 @@ class ThemeInjectionService {
|
|||
if ($theme->getId() === $this->defaultTheme->getId()) {
|
||||
continue;
|
||||
}
|
||||
$this->addThemeHeader($theme->getId(), false);
|
||||
$this->addThemeHeaders($theme, false);
|
||||
}
|
||||
|
||||
// Meta headers
|
||||
$this->addThemeMetaHeaders($themes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject theme header into rendered page
|
||||
*
|
||||
* @param string $themeId the theme ID
|
||||
* @param ITheme $theme the theme
|
||||
* @param bool $plain request the :root syntax
|
||||
* @param string $media media query to use in the <link> element
|
||||
*/
|
||||
private function addThemeHeader(string $themeId, bool $plain = true, string $media = null) {
|
||||
private function addThemeHeaders(ITheme $theme, bool $plain = true, string $media = null): void {
|
||||
$linkToCSS = $this->urlGenerator->linkToRoute('theming.Theming.getThemeStylesheet', [
|
||||
'themeId' => $themeId,
|
||||
'themeId' => $theme->getId(),
|
||||
'plain' => $plain,
|
||||
'v' => $this->util->getCacheBuster(),
|
||||
]);
|
||||
|
|
@ -101,4 +106,36 @@ class ThemeInjectionService {
|
|||
'class' => 'theme'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject meta headers into rendered page
|
||||
*
|
||||
* @param ITheme[] $themes the theme
|
||||
*/
|
||||
private function addThemeMetaHeaders(array $themes): void {
|
||||
$metaHeaders = [];
|
||||
|
||||
// Meta headers
|
||||
foreach($this->themesService->getThemes() as $theme) {
|
||||
if (!empty($theme->getMeta())) {
|
||||
foreach($theme->getMeta() as $meta) {
|
||||
if (!isset($meta['name']) || !isset($meta['content'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($metaHeaders[$meta['name']])) {
|
||||
$metaHeaders[$meta['name']] = [];
|
||||
}
|
||||
$metaHeaders[$meta['name']][] = $meta['content'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($metaHeaders as $name => $content) {
|
||||
\OCP\Util::addHeader('meta', [
|
||||
'name' => $name,
|
||||
'content' => join(' ', array_unique($content)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ class DarkHighContrastTheme extends DarkTheme implements ITheme {
|
|||
return 'dark-highcontrast';
|
||||
}
|
||||
|
||||
public function getMediaQuery(): string {
|
||||
return '(prefers-color-scheme: dark) and (prefers-contrast: more)';
|
||||
}
|
||||
|
||||
public function getTitle(): string {
|
||||
return $this->l->t('Dark theme with high contrast mode');
|
||||
}
|
||||
|
|
@ -49,6 +45,10 @@ class DarkHighContrastTheme extends DarkTheme implements ITheme {
|
|||
return $this->l->t('Similar to the high contrast mode, but with dark colours.');
|
||||
}
|
||||
|
||||
public function getMediaQuery(): string {
|
||||
return '(prefers-color-scheme: dark) and (prefers-contrast: more)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep this consistent with other HighContrast Themes
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ class DarkTheme extends DefaultTheme implements ITheme {
|
|||
return 'dark';
|
||||
}
|
||||
|
||||
public function getMediaQuery(): string {
|
||||
return '(prefers-color-scheme: dark)';
|
||||
}
|
||||
|
||||
public function getTitle(): string {
|
||||
return $this->l->t('Dark theme');
|
||||
}
|
||||
|
|
@ -49,6 +45,18 @@ class DarkTheme extends DefaultTheme implements ITheme {
|
|||
return $this->l->t('A dark theme to ease your eyes by reducing the overall luminosity and brightness.');
|
||||
}
|
||||
|
||||
public function getMediaQuery(): string {
|
||||
return '(prefers-color-scheme: dark)';
|
||||
}
|
||||
|
||||
public function getMeta(): array {
|
||||
// https://html.spec.whatwg.org/multipage/semantics.html#meta-color-scheme
|
||||
return [[
|
||||
'name' => 'color-scheme',
|
||||
'content' => 'dark',
|
||||
]];
|
||||
}
|
||||
|
||||
public function getCSSVariables(): array {
|
||||
$defaultVariables = parent::getCSSVariables();
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,10 @@ class DefaultTheme implements ITheme {
|
|||
return '';
|
||||
}
|
||||
|
||||
public function getMeta(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getCSSVariables(): array {
|
||||
$colorMainText = '#222222';
|
||||
$colorMainTextRgb = join(',', $this->util->hexToRGB($colorMainText));
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ class HighContrastTheme extends DefaultTheme implements ITheme {
|
|||
return 'light-highcontrast';
|
||||
}
|
||||
|
||||
public function getMediaQuery(): string {
|
||||
return '(prefers-contrast: more)';
|
||||
}
|
||||
|
||||
public function getTitle(): string {
|
||||
return $this->l->t('High contrast mode');
|
||||
}
|
||||
|
|
@ -49,6 +45,10 @@ class HighContrastTheme extends DefaultTheme implements ITheme {
|
|||
return $this->l->t('A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased.');
|
||||
}
|
||||
|
||||
public function getMediaQuery(): string {
|
||||
return '(prefers-contrast: more)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep this consistent with other HighContrast Themes
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ class LightTheme extends DefaultTheme implements ITheme {
|
|||
return 'light';
|
||||
}
|
||||
|
||||
public function getType(): int {
|
||||
return ITheme::TYPE_THEME;
|
||||
}
|
||||
|
||||
public function getTitle(): string {
|
||||
return $this->l->t('Light theme');
|
||||
}
|
||||
|
|
@ -52,4 +48,12 @@ class LightTheme extends DefaultTheme implements ITheme {
|
|||
public function getMediaQuery(): string {
|
||||
return '(prefers-color-scheme: light)';
|
||||
}
|
||||
|
||||
public function getMeta(): array {
|
||||
// https://html.spec.whatwg.org/multipage/semantics.html#meta-color-scheme
|
||||
return [[
|
||||
'name' => 'color-scheme',
|
||||
'content' => 'light',
|
||||
]];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue