From ef6a4ed7f4aa5276ce15cc50ba665147e4b42ff1 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 15 Sep 2022 13:14:22 +0200 Subject: [PATCH] MOBILE-4127 theme: Move mode classes to html tag --- .../activitymodules/activitymodules.scss | 2 +- .../components/calendar/calendar.scss | 2 +- .../components/submission/submission.scss | 2 +- .../attempt-results/attempt-results.scss | 2 +- .../mod/lesson/pages/player/player.scss | 2 +- .../mod/quiz/components/index/index.scss | 2 +- .../mod/survey/components/index/index.scss | 2 +- .../mod/wiki/components/index/index.scss | 2 +- src/app/app.component.ts | 36 ++++++++----------- .../module-navigation/module-navigation.scss | 2 +- .../course-list-item/course-list-item.scss | 2 +- .../rich-text-editor/rich-text-editor.scss | 2 +- .../features/grades/pages/course/course.scss | 2 +- src/core/features/login/login.scss | 2 +- .../settings/services/settings-helper.ts | 5 +-- .../components/user-tour/user-tour.scss | 2 +- src/core/services/utils/dom.ts | 32 +++++++++++++++++ src/theme/components/format-text.scss | 6 ++-- src/theme/helpers/custom.mixins.scss | 18 +++++----- src/theme/theme.custom.scss | 4 +-- src/theme/theme.dark.scss | 6 +++- src/theme/theme.light.scss | 4 +-- 22 files changed, 84 insertions(+), 55 deletions(-) diff --git a/src/addons/block/activitymodules/components/activitymodules/activitymodules.scss b/src/addons/block/activitymodules/components/activitymodules/activitymodules.scss index 21ce02313..6f1f7df99 100644 --- a/src/addons/block/activitymodules/components/activitymodules/activitymodules.scss +++ b/src/addons/block/activitymodules/components/activitymodules/activitymodules.scss @@ -8,6 +8,6 @@ } } -:host-context(body.dark) { +:host-context(html.dark) { --mod-icon-filter: brightness(0) invert(1); } diff --git a/src/addons/calendar/components/calendar/calendar.scss b/src/addons/calendar/components/calendar/calendar.scss index 1fe5598cc..7f6833c23 100644 --- a/src/addons/calendar/components/calendar/calendar.scss +++ b/src/addons/calendar/components/calendar/calendar.scss @@ -152,6 +152,6 @@ } } -:host-context(body.dark) { +:host-context(html.dark) { --addon-calendar-blank-day-background-color: var(--gray-900); } diff --git a/src/addons/mod/assign/components/submission/submission.scss b/src/addons/mod/assign/components/submission/submission.scss index eb68d7add..2ae6d827b 100644 --- a/src/addons/mod/assign/components/submission/submission.scss +++ b/src/addons/mod/assign/components/submission/submission.scss @@ -40,7 +40,7 @@ } } -:host-context(body.dark) ::ng-deep { +:host-context(html.dark) ::ng-deep { ion-item.submissioneditable p { color: var(--danger-tint); } diff --git a/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss b/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss index ef4832daf..09e782178 100644 --- a/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss +++ b/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss @@ -35,7 +35,7 @@ } } -:host-context(body.dark) { +:host-context(html.dark) { .addon-mod_h5pactivity-result-table-row.item:nth-child(even) { --background: var(--gray-900); } diff --git a/src/addons/mod/lesson/pages/player/player.scss b/src/addons/mod/lesson/pages/player/player.scss index 011192f4c..2090c01ed 100644 --- a/src/addons/mod/lesson/pages/player/player.scss +++ b/src/addons/mod/lesson/pages/player/player.scss @@ -2,7 +2,7 @@ --background-odd: var(--light); } -:host-context(body.dark) { +:host-context(html.dark) { --background-odd: var(--medium); } diff --git a/src/addons/mod/quiz/components/index/index.scss b/src/addons/mod/quiz/components/index/index.scss index b7cdadf28..c153eae1b 100644 --- a/src/addons/mod/quiz/components/index/index.scss +++ b/src/addons/mod/quiz/components/index/index.scss @@ -20,7 +20,7 @@ } } -:host-context(body.dark) { +:host-context(html.dark) { .addon-mod_quiz-table { .addon-mod_quiz-highlighted, .item.addon-mod_quiz-highlighted, diff --git a/src/addons/mod/survey/components/index/index.scss b/src/addons/mod/survey/components/index/index.scss index bdb061e94..bb262ac5b 100644 --- a/src/addons/mod/survey/components/index/index.scss +++ b/src/addons/mod/survey/components/index/index.scss @@ -25,7 +25,7 @@ } } -:host-context(body.dark) { +:host-context(html.dark) { --grid-background: var(--gray-900); --even-background: var(--medium); } diff --git a/src/addons/mod/wiki/components/index/index.scss b/src/addons/mod/wiki/components/index/index.scss index 64a882770..9bbc1c0ed 100644 --- a/src/addons/mod/wiki/components/index/index.scss +++ b/src/addons/mod/wiki/components/index/index.scss @@ -56,7 +56,7 @@ $addon-mod-wiki-toc-level-padding: 12px !default; } } -:host-context(body.dark) { +:host-context(html.dark) { --addon-mod-wiki-newentry-link-color: var(--danger-tint); --addon-mod-wiki-toc-background-color: var(--medium); } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index ef704dd51..fc46daea6 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -54,7 +54,7 @@ export class AppComponent implements OnInit, AfterViewInit { ngOnInit(): void { // eslint-disable-next-line @typescript-eslint/no-explicit-any const win = window; - document.body.classList.add('ionic5'); + CoreDomUtils.toggleModeClass('ionic5', true); this.addVersionClass(MOODLEAPP_VERSION_PREFIX, CoreConstants.CONFIG.versionname.replace('-dev', '')); CoreEvents.on(CoreEvents.LOGOUT, async () => { @@ -255,24 +255,24 @@ export class AppComponent implements OnInit, AfterViewInit { // Execute the callback in the Angular zone, so change detection doesn't stop working. NgZone.run(() => { const isOnline = CoreNetwork.isOnline(); - const hadOfflineMessage = document.body.classList.contains('core-offline'); + const hadOfflineMessage = CoreDomUtils.hasModeClass('core-offline'); - document.body.classList.toggle('core-offline', !isOnline); + CoreDomUtils.toggleModeClass('core-offline', !isOnline); if (isOnline && hadOfflineMessage) { - document.body.classList.add('core-online'); + CoreDomUtils.toggleModeClass('core-online', true); setTimeout(() => { - document.body.classList.remove('core-online'); + CoreDomUtils.toggleModeClass('core-online', false); }, 3000); } else if (!isOnline) { - document.body.classList.remove('core-online'); + CoreDomUtils.toggleModeClass('core-online', false); } }); }); const isOnline = CoreNetwork.isOnline(); - document.body.classList.toggle('core-offline', !isOnline); + CoreDomUtils.toggleModeClass('core-offline', !isOnline); // Set StatusBar properties. CoreApp.setStatusBarColor(); @@ -301,11 +301,9 @@ export class AppComponent implements OnInit, AfterViewInit { parts[1] = parts[1] || '0'; parts[2] = parts[2] || '0'; - document.body.classList.add( - prefix + parts[0], - prefix + parts[0] + '-' + parts[1], - prefix + parts[0] + '-' + parts[1] + '-' + parts[2], - ); + CoreDomUtils.toggleModeClass(prefix + parts[0], true); + CoreDomUtils.toggleModeClass(prefix + parts[0] + '-' + parts[1], true); + CoreDomUtils.toggleModeClass(prefix + parts[0] + '-' + parts[1] + '-' + parts[2], true); } /** @@ -314,17 +312,13 @@ export class AppComponent implements OnInit, AfterViewInit { * @param prefix Prefix of to the class. */ protected removeVersionClass(prefix: string): void { - const remove: string[] = []; - - Array.from(document.body.classList).forEach((tempClass) => { - if (tempClass.substring(0, 8) == prefix) { - remove.push(tempClass); + for (const versionClass of CoreDomUtils.getModeClasses()) { + if (!versionClass.startsWith(prefix)) { + continue; } - }); - remove.forEach((tempClass) => { - document.body.classList.remove(tempClass); - }); + CoreDomUtils.toggleModeClass(versionClass, false); + } } } diff --git a/src/core/features/course/components/module-navigation/module-navigation.scss b/src/core/features/course/components/module-navigation/module-navigation.scss index 6b8ce25f6..95d039bfb 100644 --- a/src/core/features/course/components/module-navigation/module-navigation.scss +++ b/src/core/features/course/components/module-navigation/module-navigation.scss @@ -52,6 +52,6 @@ height: 0 !important; } -:host-context(body.dark) { +:host-context(html.dark) { --button-color: var(--gray-100); } diff --git a/src/core/features/courses/components/course-list-item/course-list-item.scss b/src/core/features/courses/components/course-list-item/course-list-item.scss index 7d1bb34dc..6ec6ee1a3 100644 --- a/src/core/features/courses/components/course-list-item/course-list-item.scss +++ b/src/core/features/courses/components/course-list-item/course-list-item.scss @@ -29,7 +29,7 @@ } -:host-context(body.dark) { +:host-context(html.dark) { --button-background: rgba(0, 0, 0, 0.3); } diff --git a/src/core/features/editor/components/rich-text-editor/rich-text-editor.scss b/src/core/features/editor/components/rich-text-editor/rich-text-editor.scss index d990a190e..7d8a645d0 100644 --- a/src/core/features/editor/components/rich-text-editor/rich-text-editor.scss +++ b/src/core/features/editor/components/rich-text-editor/rich-text-editor.scss @@ -7,7 +7,7 @@ --background: var(--ion-item-background); } -:host-context(body.dark) { +:host-context(html.dark) { --background: var(--medium); --color: var(--white); --button-color: var(--gray-200); diff --git a/src/core/features/grades/pages/course/course.scss b/src/core/features/grades/pages/course/course.scss index fff8ae719..5358730a6 100644 --- a/src/core/features/grades/pages/course/course.scss +++ b/src/core/features/grades/pages/course/course.scss @@ -22,7 +22,7 @@ } -:host-context(body.dark) { +:host-context(html.dark) { --header-background: var(--gray-900); --odd-cell-background: var(--gray-800); --odd-cell-hover: var(--gray-600); diff --git a/src/core/features/login/login.scss b/src/core/features/login/login.scss index 165ba96e3..590cc5f2b 100644 --- a/src/core/features/login/login.scss +++ b/src/core/features/login/login.scss @@ -103,7 +103,7 @@ } } -:host-context(body.dark) { +:host-context(html.dark) { @if ($core-login-button-outline-dark) { form ion-button { --background: white; diff --git a/src/core/features/settings/services/settings-helper.ts b/src/core/features/settings/services/settings-helper.ts index 18e754265..16404feae 100644 --- a/src/core/features/settings/services/settings-helper.ts +++ b/src/core/features/settings/services/settings-helper.ts @@ -459,9 +459,10 @@ export class CoreSettingsHelperProvider { * @param enable True to enable dark mode, false to disable. */ protected toggleDarkMode(enable: boolean = false): void { - const isDark = document.body.classList.contains('dark'); + const isDark = CoreDomUtils.hasModeClass('dark'); + if (isDark !== enable) { - document.body.classList.toggle('dark', enable); + CoreDomUtils.toggleModeClass('dark', enable); this.darkModeObservable.next(enable); CoreApp.setStatusBarColor(); diff --git a/src/core/features/usertours/components/user-tour/user-tour.scss b/src/core/features/usertours/components/user-tour/user-tour.scss index 812b509bc..50e03506d 100644 --- a/src/core/features/usertours/components/user-tour/user-tour.scss +++ b/src/core/features/usertours/components/user-tour/user-tour.scss @@ -57,6 +57,6 @@ } -:host-context(body.dark) { +:host-context(html.dark) { --popover-background: var(--gray-700); } diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index 9cf705339..1f64c5323 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -1945,6 +1945,38 @@ export class CoreDomUtilsProvider { return this.waitForResizeDone(windowWidth, windowHeight, retries+1); } + /** + * Check whether a CSS class indicating an app mode is set. + * + * @param className Class name. + * @return Whether the CSS class is set. + */ + hasModeClass(className: string): boolean { + return document.documentElement.classList.contains(className); + } + + /** + * Get active mode CSS classes. + * + * @return Mode classes. + */ + getModeClasses(): string[] { + return Array.from(document.documentElement.classList); + } + + /** + * Toggle a CSS class in the root element used to indicate app modes. + * + * @param className Class name. + * @param enable Whether to add or remove the class. + */ + toggleModeClass(className: string, enable?: boolean): void { + document.documentElement.classList.toggle(className, enable); + + // @deprecated since 4.1 + document.body.classList.toggle(className, enable); + } + } /** diff --git a/src/theme/components/format-text.scss b/src/theme/components/format-text.scss index fa6dbe4a0..2aa721cf1 100644 --- a/src/theme/components/format-text.scss +++ b/src/theme/components/format-text.scss @@ -7,7 +7,7 @@ core-format-text { --core-format-text-viewer-icon-background: rgba(255, 255, 255, .5); } -body.dark core-format-text { +html.dark core-format-text { --core-format-text-viewer-icon-background: rgba(0, 0, 0, .5); } @@ -633,7 +633,7 @@ ion-header.ios h1 core-format-text { } } -body.dark core-format-text select, -body.dark core-rich-text-editor .core-rte-editor select { +html.dark core-format-text select, +html.dark core-rich-text-editor .core-rte-editor select { background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23FFFFFF%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'); } diff --git a/src/theme/helpers/custom.mixins.scss b/src/theme/helpers/custom.mixins.scss index d2f4c3085..c3cb6504d 100644 --- a/src/theme/helpers/custom.mixins.scss +++ b/src/theme/helpers/custom.mixins.scss @@ -25,17 +25,15 @@ // Generates the color classes and variables based on the // colors map - @mixin generate-color($color-name, $colors) { - $base: map-get($colors, $color-name); - $light: map-get($base, 'light'); + @mixin generate-color($color-name, $colors, $theme) { + $color-themes: map-get($colors, $color-name); + $base: map-get($color-themes, $theme); - @include generate-color-variants($color-name, $light); - - body.dark { - $dark: map-get($base, 'dark'); - $dark: mix($light, white, 80%) !default; - @include generate-color-variants($color-name, $dark); + @if $theme == 'dark' { + $base: mix(map-get($color-themes, 'light'), white, 80%) !default; } + + @include generate-color-variants($color-name, $base); } @mixin generate-color-variants($color-name, $base) { @@ -210,7 +208,7 @@ @mixin darkmode() { $root: #{&}; - @at-root #{add-root-selector($root, "body.dark")} { + @at-root #{add-root-selector($root, "html.dark")} { @content; } } diff --git a/src/theme/theme.custom.scss b/src/theme/theme.custom.scss index 68b7b64d7..282ff6aaf 100644 --- a/src/theme/theme.custom.scss +++ b/src/theme/theme.custom.scss @@ -8,7 +8,7 @@ * Light Theme * ------------------------------------------- */ -:root { +html { } @@ -16,6 +16,6 @@ * Dark Theme * ------------------------------------------- */ -:root body.dark { +html.dark { } diff --git a/src/theme/theme.dark.scss b/src/theme/theme.dark.scss index a526f82ea..81f9b0543 100644 --- a/src/theme/theme.dark.scss +++ b/src/theme/theme.dark.scss @@ -5,7 +5,7 @@ * http://ionicframework.com/docs/theming/ */ -:root body.dark { +html.dark { // Ionic shades, defined for ionic internal use. --ion-color-step-0: var(--black); @@ -30,6 +30,10 @@ --ion-color-step-950: var(--gray-100); --ion-color-step-1000: var(--white); + @each $color-name, $unused in $colors { + @include generate-color($color-name, $colors, 'dark'); + } + --ion-background-color: #{$background-color-dark}; --ion-background-color-rgb: #{$background-color-dark-rgb}; diff --git a/src/theme/theme.light.scss b/src/theme/theme.light.scss index 780297398..90e2f10bf 100644 --- a/src/theme/theme.light.scss +++ b/src/theme/theme.light.scss @@ -5,7 +5,7 @@ * http://ionicframework.com/docs/theming/ */ -:root { +html { // Color palette --black: #{$black}; @@ -44,7 +44,7 @@ --ion-color-step-1000: var(--black); @each $color-name, $unused in $colors { - @include generate-color($color-name, $colors); + @include generate-color($color-name, $colors, 'light'); } // Accessibility vars.