diff --git a/src/core/components/mod-icon/mod-icon.html b/src/core/components/mod-icon/mod-icon.html
index 0a58c0b76..e4266da4a 100644
--- a/src/core/components/mod-icon/mod-icon.html
+++ b/src/core/components/mod-icon/mod-icon.html
@@ -1,6 +1,3 @@
-
-
-
-
-
+
+
diff --git a/src/core/components/mod-icon/mod-icon.scss b/src/core/components/mod-icon/mod-icon.scss
index d10806744..7d79dd7f3 100644
--- a/src/core/components/mod-icon/mod-icon.scss
+++ b/src/core/components/mod-icon/mod-icon.scss
@@ -23,13 +23,13 @@
background-color: transparent;
line-height: var(--size);
- --color: var(--activity-base-icon-color);
-
&.colorize {
&.version_current {
- @each $type, $value in $activity-icon-colors {
- &.#{$type} {
- --color: var(--activity#{$type});
+ @each $type, $value in $activity-icon-color-filters {
+ &.#{$type}:not(.branded) {
+ img {
+ filter: var(--activity#{$type});
+ }
}
}
}
@@ -40,7 +40,7 @@
@each $type, $value in $activity-icon-background-colors {
&.#{$type}:not(.branded) {
background-color: var(--activity-40-#{$type});
- ::ng-deep svg, img {
+ img {
filter: brightness(0) invert(1);
}
}
@@ -57,15 +57,7 @@
--padding-bottom: var(--module-legacy-icon-padding, 8px);
}
- &.colorize.version_current:not(.branded) {
- ::ng-deep svg,
- ::ng-deep svg * {
- fill: var(--color) !important;
- }
- }
-
- img,
- ::ng-deep svg {
+ img {
width: var(--size);
height: var(--size);
max-width: var(--size);
diff --git a/src/core/components/mod-icon/mod-icon.ts b/src/core/components/mod-icon/mod-icon.ts
index 6be57523b..0bb66e0b0 100644
--- a/src/core/components/mod-icon/mod-icon.ts
+++ b/src/core/components/mod-icon/mod-icon.ts
@@ -24,17 +24,11 @@ import {
SimpleChange,
signal,
} from '@angular/core';
-import { SafeHtml } from '@angular/platform-browser';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
-import { CoreFile } from '@services/file';
-import { CoreFileHelper } from '@services/file-helper';
import { CoreSites } from '@services/sites';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUrlUtils } from '@services/utils/url';
-import { CoreUtils } from '@services/utils/utils';
-import { DomSanitizer, Http } from '@singletons';
-import { firstValueFrom } from 'rxjs';
const assetsPath = 'assets/img/';
const fallbackModName = 'external-tool';
@@ -80,9 +74,7 @@ export class CoreModIconComponent implements OnInit, OnChanges {
iconUrl = signal('');
modNameTranslated = signal('');
isLocalUrl = signal(false);
- svgIcon = signal('');
linkIconWithComponent = signal(false);
- loaded = signal(false);
protected iconVersion: IconVersion = IconVersion.LEGACY_VERSION;
protected purposeClass = '';
@@ -208,8 +200,6 @@ export class CoreModIconComponent implements OnInit, OnChanges {
);
this.setBrandedClass();
-
- await this.setSVGIcon();
}
/**
@@ -230,8 +220,6 @@ export class CoreModIconComponent implements OnInit, OnChanges {
const path = CoreCourse.getModuleIconsPath();
this.iconUrl.set(path + moduleName + '.svg');
-
- await this.setSVGIcon();
}
/**
@@ -306,141 +294,4 @@ export class CoreModIconComponent implements OnInit, OnChanges {
return IconVersion.CURRENT_VERSION;
}
- /**
- * Sets SVG markup for the icon (if the URL is an SVG).
- *
- * @returns Promise resolved when done.
- */
- protected async setSVGIcon(): Promise {
- if (this.iconVersion === IconVersion.LEGACY_VERSION) {
- this.loaded.set(true);
- this.svgIcon.set('');
-
- return;
- }
-
- this.loaded.set(false);
-
- let mimetype = '';
- let fileContents = '';
-
- // Download the icon if it's not local to cache it.
- if (!this.isLocalUrl()) {
- try {
- const iconUrl = await CoreFileHelper.downloadFile(
- this.iconUrl(),
- this.linkIconWithComponent() ? this.modname : undefined,
- this.linkIconWithComponent() ? this.componentId : undefined,
- );
- if (iconUrl) {
- mimetype = await CoreUtils.getMimeTypeFromUrl(iconUrl);
- fileContents = await CoreFile.readFile(iconUrl);
- }
- } catch {
- // Ignore errors.
- }
- }
-
- try {
-
- if (!fileContents) {
- // Try to download the icon directly (also for local files).
- const response = await firstValueFrom(Http.get(
- this.iconUrl(),
- {
- observe: 'response',
- responseType: 'text',
- },
- ));
- mimetype = response.headers.get('content-type') || mimetype;
- fileContents = response.body || '';
- }
-
- if (mimetype !== 'image/svg+xml' || !fileContents) {
- this.svgIcon.set('');
-
- return;
- }
-
- // Clean the DOM to avoid security issues.
- const parser = new DOMParser();
- const doc = parser.parseFromString(fileContents, 'image/svg+xml');
-
- // Safety check.
- if (doc.documentElement.nodeName !== 'svg') {
- this.svgIcon.set('');
-
- return;
- }
-
- // Remove scripts tags.
- const scripts = doc.documentElement.getElementsByTagName('script');
- for (let i = scripts.length - 1; i >= 0; i--) {
- scripts[i].parentNode?.removeChild(scripts[i]);
- }
-
- // Has own styles, do not apply colors.
- if (doc.documentElement.getElementsByTagName('style').length > 0) {
- this.brandedClass = true;
- }
-
- // Recursively remove attributes starting with on.
- const removeAttributes = (element: Element): void => {
- Array.from(element.attributes).forEach((attr) => {
- if (attr.name.startsWith('on')) {
- element.removeAttribute(attr.name);
- }
- });
-
- Array.from(element.children).forEach((child) => {
- removeAttributes(child);
- });
- };
- removeAttributes(doc.documentElement);
-
- // Add viewBox to avoid scaling issues.
- if (!doc.documentElement.getAttribute('viewBox')) {
- const width = doc.documentElement.getAttribute('width');
- const height = doc.documentElement.getAttribute('height');
- if (width && height) {
- doc.documentElement.setAttribute('viewBox', '0 0 '+ width + ' ' + height);
- }
- }
-
- // Prefix id's on svg DOM to avoid conflicts.
- const uniqueId = 'modicon' + CoreUtils.getUniqueId('modicon') + '_';
- const styleTags = Array.from(doc.documentElement.getElementsByTagName('style'));
- const styleAttrs = Array.from(doc.documentElement.querySelectorAll('[style]'));
- const idTags = Array.from(doc.documentElement.querySelectorAll('[id]'));
- idTags.forEach((element) => {
- if (!element.id) {
- return;
- }
- const newId = uniqueId + element.id;
- // Regexp to replace all ocurrences of the id with workd bondaries.
- const oldIdFinder = new RegExp(`#${element.id}\\b`, 'g');
-
- element.id = newId;
-
- // Prefix the elementId on style Tags.
- styleTags.forEach((style) => {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- style.textContent = style.textContent!.replace(oldIdFinder, `#${newId}`);
- });
-
- // Also change ids on style attributes.
- styleAttrs.forEach((attr) => {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- attr.setAttribute('style', attr.getAttribute('style')!.replace(oldIdFinder, `#${newId}`));
- });
- });
-
- this.svgIcon.set(DomSanitizer.bypassSecurityTrustHtml(doc.documentElement.outerHTML));
- } catch {
- this.svgIcon.set('');
- } finally {
- this.loaded.set(true);
- }
- }
-
}
diff --git a/src/theme/globals.variables.scss b/src/theme/globals.variables.scss
index 815179140..3cebbc93b 100644
--- a/src/theme/globals.variables.scss
+++ b/src/theme/globals.variables.scss
@@ -136,6 +136,15 @@ $activity-icon-colors: (
interactivecontent: #8d3d1b
) !default;
+$activity-icon-color-filters: (
+ administration: brightness(0%) invert(45%) sepia(46%) saturate(3819%) hue-rotate(260deg) brightness(101%) contrast(87%),
+ assessment: brightness(0%) invert(36%) sepia(98%) saturate(6969%) hue-rotate(315deg) brightness(90%) contrast(119%),
+ collaboration: brightness(0%) invert(25%) sepia(54%) saturate(6226%) hue-rotate(245deg) brightness(100%) contrast(102%),
+ communication: brightness(0%) invert(48%) sepia(74%) saturate(4887%) hue-rotate(11deg) brightness(102%) contrast(101%),
+ content: brightness(0%) invert(49%) sepia(52%) saturate(4675%) hue-rotate(156deg) brightness(89%) contrast(102%),
+ interactivecontent: brightness(0%) invert(25%) sepia(63%) saturate(1152%) hue-rotate(344deg) brightness(94%) contrast(91%)
+) !default;
+
$calendar-event-category-category: #8e24aa !default;
$calendar-event-category-course: $red !default;
$calendar-event-category-group: $yellow !default;
diff --git a/src/theme/theme.dark.scss b/src/theme/theme.dark.scss
index 95d463e6e..f2836b6b9 100644
--- a/src/theme/theme.dark.scss
+++ b/src/theme/theme.dark.scss
@@ -172,5 +172,4 @@ html.dark {
--core-table-even-cell-background: var(--gray-900);
--core-table-even-cell-hover: var(--gray-700);
- --activity-base-icon-color: var(--white);
}
diff --git a/src/theme/theme.light.scss b/src/theme/theme.light.scss
index 74bb7b704..919eb588d 100644
--- a/src/theme/theme.light.scss
+++ b/src/theme/theme.light.scss
@@ -201,9 +201,8 @@ html {
--core-dd-question-color-#{$i + 1}-contrast: #{get_contrast_color(nth($core-dd-question-colors, $i + 1))};
}
- --activity-base-icon-color: var(--gray-900);
// Make activtity colours available for custom modules.
- @each $type, $value in $activity-icon-colors {
+ @each $type, $value in $activity-icon-color-filters {
--activity#{$type}: #{$value};
}