Skip to content

Commit 6364e53

Browse files
skjnldsvartonge
authored andcommitted
Merge pull request #32231 from nextcloud/feat/theming-scheme-meta
1 parent cdf7840 commit 6364e53

File tree

7 files changed

+84
-23
lines changed

7 files changed

+84
-23
lines changed

apps/theming/lib/ITheme.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ public function getEnableLabel(): string;
7171
*/
7272
public function getDescription(): string;
7373

74+
/**
75+
* Get the meta attribute matching the theme
76+
* e.g. https://html.spec.whatwg.org/multipage/semantics.html#meta-color-scheme
77+
* @return array{name?: string, content?: string}[]
78+
* @since 29.0.0
79+
*/
80+
public function getMeta(): array;
81+
7482
/**
7583
* Get the media query triggering this theme
7684
* Optional, ignored if falsy

apps/theming/lib/Service/ThemeInjectionService.php

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323
namespace OCA\Theming\Service;
2424

25+
use OCA\Theming\ITheme;
2526
use OCA\Theming\Themes\DefaultTheme;
2627
use OCA\Theming\Util;
2728
use OCP\IConfig;
@@ -48,14 +49,15 @@ public function __construct(IURLGenerator $urlGenerator,
4849
$this->defaultTheme = $defaultTheme;
4950
$this->util = $util;
5051
$this->config = $config;
52+
5153
if ($userSession->getUser() !== null) {
5254
$this->userId = $userSession->getUser()->getUID();
5355
} else {
5456
$this->userId = null;
5557
}
5658
}
5759

58-
public function injectHeaders() {
60+
public function injectHeaders(): void {
5961
$themes = $this->themesService->getThemes();
6062
$defaultTheme = $themes[$this->defaultTheme->getId()];
6163
$mediaThemes = array_filter($themes, function ($theme) {
@@ -64,11 +66,11 @@ public function injectHeaders() {
6466
});
6567

6668
// Default theme fallback
67-
$this->addThemeHeader($defaultTheme->getId());
69+
$this->addThemeHeaders($defaultTheme);
6870

6971
// Themes applied by media queries
7072
foreach($mediaThemes as $theme) {
71-
$this->addThemeHeader($theme->getId(), true, $theme->getMediaQuery());
73+
$this->addThemeHeaders($theme, true, $theme->getMediaQuery());
7274
}
7375

7476
// Themes
@@ -77,20 +79,23 @@ public function injectHeaders() {
7779
if ($theme->getId() === $this->defaultTheme->getId()) {
7880
continue;
7981
}
80-
$this->addThemeHeader($theme->getId(), false);
82+
$this->addThemeHeaders($theme, false);
8183
}
84+
85+
// Meta headers
86+
$this->addThemeMetaHeaders($themes);
8287
}
8388

8489
/**
8590
* Inject theme header into rendered page
8691
*
87-
* @param string $themeId the theme ID
92+
* @param ITheme $theme the theme
8893
* @param bool $plain request the :root syntax
8994
* @param string $media media query to use in the <link> element
9095
*/
91-
private function addThemeHeader(string $themeId, bool $plain = true, string $media = null) {
96+
private function addThemeHeaders(ITheme $theme, bool $plain = true, string $media = null): void {
9297
$linkToCSS = $this->urlGenerator->linkToRoute('theming.Theming.getThemeStylesheet', [
93-
'themeId' => $themeId,
98+
'themeId' => $theme->getId(),
9499
'plain' => $plain,
95100
'v' => $this->util->getCacheBuster(),
96101
]);
@@ -101,4 +106,36 @@ private function addThemeHeader(string $themeId, bool $plain = true, string $med
101106
'class' => 'theme'
102107
]);
103108
}
109+
110+
/**
111+
* Inject meta headers into rendered page
112+
*
113+
* @param ITheme[] $themes the theme
114+
*/
115+
private function addThemeMetaHeaders(array $themes): void {
116+
$metaHeaders = [];
117+
118+
// Meta headers
119+
foreach($this->themesService->getThemes() as $theme) {
120+
if (!empty($theme->getMeta())) {
121+
foreach($theme->getMeta() as $meta) {
122+
if (!isset($meta['name']) || !isset($meta['content'])) {
123+
continue;
124+
}
125+
126+
if (!isset($metaHeaders[$meta['name']])) {
127+
$metaHeaders[$meta['name']] = [];
128+
}
129+
$metaHeaders[$meta['name']][] = $meta['content'];
130+
}
131+
}
132+
}
133+
134+
foreach($metaHeaders as $name => $content) {
135+
\OCP\Util::addHeader('meta', [
136+
'name' => $name,
137+
'content' => join(' ', array_unique($content)),
138+
]);
139+
}
140+
}
104141
}

apps/theming/lib/Themes/DarkHighContrastTheme.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ public function getId(): string {
3333
return 'dark-highcontrast';
3434
}
3535

36-
public function getMediaQuery(): string {
37-
return '(prefers-color-scheme: dark) and (prefers-contrast: more)';
38-
}
39-
4036
public function getTitle(): string {
4137
return $this->l->t('Dark theme with high contrast mode');
4238
}
@@ -49,6 +45,10 @@ public function getDescription(): string {
4945
return $this->l->t('Similar to the high contrast mode, but with dark colours.');
5046
}
5147

48+
public function getMediaQuery(): string {
49+
return '(prefers-color-scheme: dark) and (prefers-contrast: more)';
50+
}
51+
5252
/**
5353
* Keep this consistent with other HighContrast Themes
5454
*/

apps/theming/lib/Themes/DarkTheme.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ public function getId(): string {
3333
return 'dark';
3434
}
3535

36-
public function getMediaQuery(): string {
37-
return '(prefers-color-scheme: dark)';
38-
}
39-
4036
public function getTitle(): string {
4137
return $this->l->t('Dark theme');
4238
}
@@ -49,6 +45,18 @@ public function getDescription(): string {
4945
return $this->l->t('A dark theme to ease your eyes by reducing the overall luminosity and brightness.');
5046
}
5147

48+
public function getMediaQuery(): string {
49+
return '(prefers-color-scheme: dark)';
50+
}
51+
52+
public function getMeta(): array {
53+
// https://html.spec.whatwg.org/multipage/semantics.html#meta-color-scheme
54+
return [[
55+
'name' => 'color-scheme',
56+
'content' => 'dark',
57+
]];
58+
}
59+
5260
public function getCSSVariables(): array {
5361
$defaultVariables = parent::getCSSVariables();
5462

apps/theming/lib/Themes/DefaultTheme.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ public function getMediaQuery(): string {
101101
return '';
102102
}
103103

104+
public function getMeta(): array {
105+
return [];
106+
}
107+
104108
public function getCSSVariables(): array {
105109
$colorMainText = '#222222';
106110
$colorMainTextRgb = join(',', $this->util->hexToRGB($colorMainText));

apps/theming/lib/Themes/HighContrastTheme.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ public function getId(): string {
3333
return 'light-highcontrast';
3434
}
3535

36-
public function getMediaQuery(): string {
37-
return '(prefers-contrast: more)';
38-
}
39-
4036
public function getTitle(): string {
4137
return $this->l->t('High contrast mode');
4238
}
@@ -49,6 +45,10 @@ public function getDescription(): string {
4945
return $this->l->t('A high contrast mode to ease your navigation. Visual quality will be reduced but clarity will be increased.');
5046
}
5147

48+
public function getMediaQuery(): string {
49+
return '(prefers-contrast: more)';
50+
}
51+
5252
/**
5353
* Keep this consistent with other HighContrast Themes
5454
*/

apps/theming/lib/Themes/LightTheme.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ public function getId(): string {
3333
return 'light';
3434
}
3535

36-
public function getType(): int {
37-
return ITheme::TYPE_THEME;
38-
}
39-
4036
public function getTitle(): string {
4137
return $this->l->t('Light theme');
4238
}
@@ -52,4 +48,12 @@ public function getDescription(): string {
5248
public function getMediaQuery(): string {
5349
return '(prefers-color-scheme: light)';
5450
}
51+
52+
public function getMeta(): array {
53+
// https://html.spec.whatwg.org/multipage/semantics.html#meta-color-scheme
54+
return [[
55+
'name' => 'color-scheme',
56+
'content' => 'light',
57+
]];
58+
}
5559
}

0 commit comments

Comments
 (0)