Skip to content

Commit bfaadfb

Browse files
committed
MOBILE-4362 modicon: Properly check if icon should be filtered
1 parent 16046c1 commit bfaadfb

File tree

5 files changed

+76
-43
lines changed

5 files changed

+76
-43
lines changed

src/addons/mod/lti/services/handlers/module.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { AddonModLtiHelper } from '../lti-helper';
2222
import { AddonModLtiIndexComponent } from '../../components/index';
2323
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
2424
import { CoreCourse } from '@features/course/services/course';
25-
import { CoreSites } from '@services/sites';
2625

2726
/**
2827
* Handler to support LTI modules.
@@ -87,19 +86,6 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
8786
return module?.modicon ?? modicon ?? CoreCourse.getModuleIconSrc(this.modName);
8887
}
8988

90-
/**
91-
* @inheritdoc
92-
*/
93-
iconIsShape(module?: CoreCourseModuleData | undefined, modicon?: string | undefined): boolean | undefined {
94-
const iconUrl = module?.modicon ?? modicon;
95-
96-
if (!iconUrl) {
97-
return true;
98-
}
99-
100-
return iconUrl.startsWith(CoreSites.getRequiredCurrentSite().siteUrl);
101-
}
102-
10389
}
10490

10591
export const AddonModLtiModuleHandler = makeSingleton(AddonModLtiModuleHandlerService);

src/addons/mod/resource/services/handlers/module.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,5 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
170170
return AddonModResourceIndexComponent;
171171
}
172172

173-
/**
174-
* @inheritdoc
175-
*/
176-
iconIsShape(module?: CoreCourseModuleData | undefined, modicon?: string | undefined): boolean | undefined {
177-
const iconUrl = module?.modicon ?? modicon;
178-
179-
return !iconUrl?.startsWith('assets/img/files_legacy/') && !iconUrl?.endsWith('.png');
180-
}
181-
182173
}
183174
export const AddonModResourceModuleHandler = makeSingleton(AddonModResourceModuleHandlerService);

src/addons/mod/url/services/handlers/module.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,6 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
218218
return this.shouldOpenLink(module);
219219
}
220220

221-
/**
222-
* @inheritdoc
223-
*/
224-
iconIsShape(module?: CoreCourseModuleData | undefined, modicon?: string | undefined): boolean | undefined {
225-
const iconUrl = module?.modicon ?? modicon;
226-
227-
return !iconUrl?.startsWith('assets/img/files_legacy/') && !iconUrl?.endsWith('.png');
228-
}
229-
230221
/**
231222
* Log module viewed.
232223
*/

src/core/components/mod-icon/mod-icon.ts

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChange } from '@
1717
import { CoreCourse } from '@features/course/services/course';
1818
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
1919
import { CoreSites } from '@services/sites';
20+
import { CoreUrlUtils } from '@services/utils/url';
2021

2122
const assetsPath = 'assets/img/';
2223
const fallbackModName = 'external-tool';
@@ -54,12 +55,7 @@ export class CoreModIconComponent implements OnInit, OnChanges {
5455
async ngOnInit(): Promise<void> {
5556
if (!this.modname && this.modicon) {
5657
// Guess module from the icon url.
57-
const matches = this.modicon.match('/theme/image.php/[^/]+/([^/]+)/[-0-9]*/');
58-
this.modname = (matches && matches[1]) || '';
59-
60-
if (this.modname.startsWith('mod_')) {
61-
this.modname = this.modname.substring(4);
62-
}
58+
this.modname = this.getComponentNameFromIconUrl(this.modicon);
6359
}
6460

6561
this.modNameTranslated = CoreCourse.translateModuleName(this.modname, this.fallbackTranslation);
@@ -105,16 +101,15 @@ export class CoreModIconComponent implements OnInit, OnChanges {
105101
!!this.modname &&
106102
!!this.componentId &&
107103
!this.isLocalUrl &&
108-
!this.icon.match('/theme/image.php/[^/]+/' + this.modname + '/[-0-9]*/');
104+
this.getComponentNameFromIconUrl(this.icon) != this.modname;
109105

110-
const iconIsShape = await CoreCourseModuleDelegate.moduleIconIsShape(this.modname, this.icon);
111-
this.noFilter = iconIsShape === false;
106+
this.noFilter = await this.getIconNoFilter();
112107
}
113108

114109
/**
115110
* Icon to load on error.
116111
*/
117-
loadFallbackIcon(): void {
112+
async loadFallbackIcon(): Promise<void> {
118113
this.isLocalUrl = true;
119114
const moduleName = !this.modname || CoreCourse.CORE_MODULES.indexOf(this.modname) < 0
120115
? fallbackModName
@@ -127,7 +122,75 @@ export class CoreModIconComponent implements OnInit, OnChanges {
127122
}
128123

129124
this.icon = path + moduleName + '.svg';
130-
this.noFilter = false;
125+
this.noFilter = await this.getIconNoFilter();
126+
}
127+
128+
/**
129+
* Returns if the icon does not need to be filtered.
130+
*
131+
* @returns wether the icon does not need to be filtered.
132+
*/
133+
protected async getIconNoFilter(): Promise<boolean> {
134+
// Earlier 4.0, icons were never filtered.
135+
if (this.legacyIcon) {
136+
return true;
137+
}
138+
139+
// No icon or local icon (not legacy), filter it.
140+
if (!this.icon || this.isLocalUrl) {
141+
return false;
142+
}
143+
144+
// If it's an Moodle Theme icon, check if filtericon is set and use it.
145+
if (this.icon && CoreUrlUtils.isThemeImageUrl(this.icon)) {
146+
const iconParams = CoreUrlUtils.extractUrlParams(this.icon);
147+
if (iconParams['filtericon'] === '1') {
148+
return false;
149+
}
150+
151+
// filtericon was introduced in 4.2 and backported to 4.1.3 and 4.0.8.
152+
if (this.modname && !CoreSites.getCurrentSite()?.isVersionGreaterEqualThan(['4.0.8', '4.1.3', '4.2'])) {
153+
// If version is prior to that, check if the url is a module icon and filter it.
154+
if (this.getComponentNameFromIconUrl(this.icon) === this.modname) {
155+
return false;
156+
}
157+
}
158+
}
159+
160+
// External icons, or non monologo, do not filter.
161+
return true;
162+
}
163+
164+
/**
165+
* Guesses the mod name form the url.
166+
*
167+
* @param iconUrl Icon url.
168+
* @returns Guessed modname.
169+
*/
170+
protected getComponentNameFromIconUrl(iconUrl: string): string {
171+
if (!CoreUrlUtils.isThemeImageUrl(this.icon)) {
172+
// Cannot be guessed.
173+
return '';
174+
}
175+
176+
const iconParams = CoreUrlUtils.extractUrlParams(iconUrl);
177+
let component = iconParams['component'];
178+
179+
if (!component) {
180+
const matches = iconUrl.match('/theme/image.php/[^/]+/([^/]+)/[-0-9]*/');
181+
component = (matches && matches[1]) || '';
182+
}
183+
184+
// Some invalid components (others may be added later on).
185+
if (component === 'core' || component === 'theme') {
186+
return '';
187+
}
188+
189+
if (component.startsWith('mod_')) {
190+
component = component.substring(4);
191+
}
192+
193+
return component;
131194
}
132195

133196
}

src/core/features/course/services/module-delegate.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
9393
* @param module Module to get the icon from.
9494
* @param modicon The mod icon string.
9595
* @returns Whether the icon should be treated as a shape.
96+
* @deprecated since 4.3. Now it uses platform information. This function is not used anymore.
9697
*/
9798
iconIsShape?(module?: CoreCourseModuleData, modicon?: string): Promise<boolean | undefined> | boolean | undefined;
9899

@@ -415,6 +416,7 @@ export class CoreCourseModuleDelegateService extends CoreDelegate<CoreCourseModu
415416
* @param modicon The mod icon string.
416417
* @param module The module to use.
417418
* @returns Whether the icon should be treated as a shape.
419+
* @deprecated since 4.3. Now it uses platform information. This function is not used anymore.
418420
*/
419421
async moduleIconIsShape(modname: string, modicon?: string, module?: CoreCourseModuleData): Promise<boolean | undefined> {
420422
return await this.executeFunctionOnEnabled<Promise<boolean>>(modname, 'iconIsShape', [module, modicon]);

0 commit comments

Comments
 (0)