MOBILE-3320 DX: Allow abstract service singletons
This commit is contained in:
		
							parent
							
								
									75cedafa33
								
							
						
					
					
						commit
						a5accde64a
					
				| @ -16,11 +16,12 @@ import { AddonModDataFieldPluginComponent } from '@addons/mod/data/classes/field | ||||
| import { AddonModDataEntryField } from '@addons/mod/data/services/data'; | ||||
| import { Component } from '@angular/core'; | ||||
| import { FormBuilder } from '@angular/forms'; | ||||
| import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; | ||||
| import { SafeUrl } from '@angular/platform-browser'; | ||||
| import { CoreAnyError } from '@classes/errors/error'; | ||||
| import { CoreApp } from '@services/app'; | ||||
| import { CoreGeolocation, CoreGeolocationError, CoreGeolocationErrorReason } from '@services/geolocation'; | ||||
| import { CoreDomUtils } from '@services/utils/dom'; | ||||
| import { DomSanitizer } from '@singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Component to render data latlong field. | ||||
| @ -35,10 +36,7 @@ export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginCo | ||||
|     east?: number; | ||||
|     locationServicesEnabled = false; | ||||
| 
 | ||||
|     constructor( | ||||
|         fb: FormBuilder, | ||||
|         protected sanitizer: DomSanitizer, | ||||
|     ) { | ||||
|     constructor(fb: FormBuilder) { | ||||
|         super(fb); | ||||
|     } | ||||
| 
 | ||||
| @ -82,7 +80,7 @@ export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginCo | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return this.sanitizer.bypassSecurityTrustUrl(url); | ||||
|         return DomSanitizer.bypassSecurityTrustUrl(url); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -13,7 +13,6 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Injectable, Type } from '@angular/core'; | ||||
| import { DomSanitizer } from '@angular/platform-browser'; | ||||
| 
 | ||||
| import { CoreConstants } from '@/core/constants'; | ||||
| import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; | ||||
| @ -24,7 +23,7 @@ import { CoreFilepool } from '@services/filepool'; | ||||
| import { CoreNavigationOptions, CoreNavigator } from '@services/navigator'; | ||||
| import { CoreSites } from '@services/sites'; | ||||
| import { CoreUtils } from '@services/utils/utils'; | ||||
| import { makeSingleton } from '@singletons'; | ||||
| import { DomSanitizer, makeSingleton } from '@singletons'; | ||||
| import { AddonModLtiHelper } from '../lti-helper'; | ||||
| import { AddonModLti, AddonModLtiProvider } from '../lti'; | ||||
| import { AddonModLtiIndexComponent } from '../../components/index'; | ||||
| @ -51,8 +50,6 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler | ||||
|         [CoreConstants.FEATURE_SHOW_DESCRIPTION]: true, | ||||
|     }; | ||||
| 
 | ||||
|     constructor(protected sanitizer: DomSanitizer) {} | ||||
| 
 | ||||
|     /** | ||||
|      * @inheritdoc | ||||
|      */ | ||||
| @ -124,11 +121,11 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler | ||||
|             // Get the internal URL.
 | ||||
|             const url = await CoreFilepool.getSrcByUrl(siteId, icon, AddonModLtiProvider.COMPONENT, module.id); | ||||
| 
 | ||||
|             handlerData.icon = this.sanitizer.bypassSecurityTrustUrl(url); | ||||
|             handlerData.icon = DomSanitizer.bypassSecurityTrustUrl(url); | ||||
|         } catch { | ||||
|             // Error downloading. If we're online we'll set the online url.
 | ||||
|             if (CoreApp.isOnline()) { | ||||
|                 handlerData.icon = this.sanitizer.bypassSecurityTrustUrl(icon); | ||||
|                 handlerData.icon = DomSanitizer.bypassSecurityTrustUrl(icon); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -15,7 +15,7 @@ | ||||
| import { | ||||
|     Component, Input, Output, ViewChild, ElementRef, EventEmitter, OnChanges, SimpleChange, | ||||
| } from '@angular/core'; | ||||
| import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; | ||||
| import { SafeResourceUrl } from '@angular/platform-browser'; | ||||
| 
 | ||||
| import { CoreFile } from '@services/file'; | ||||
| import { CoreDomUtils } from '@services/utils/dom'; | ||||
| @ -23,6 +23,7 @@ import { CoreUrlUtils } from '@services/utils/url'; | ||||
| import { CoreIframeUtils } from '@services/utils/iframe'; | ||||
| import { CoreUtils } from '@services/utils/utils'; | ||||
| import { CoreLogger } from '@singletons/logger'; | ||||
| import { DomSanitizer } from '@singletons'; | ||||
| 
 | ||||
| @Component({ | ||||
|     selector: 'core-iframe', | ||||
| @ -46,10 +47,7 @@ export class CoreIframeComponent implements OnChanges { | ||||
|     protected logger: CoreLogger; | ||||
|     protected initialized = false; | ||||
| 
 | ||||
|     constructor( | ||||
|         protected sanitizer: DomSanitizer, | ||||
|     ) { | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.logger = CoreLogger.getInstance('CoreIframe'); | ||||
|         this.loaded = new EventEmitter<HTMLIFrameElement>(); | ||||
|     } | ||||
| @ -105,7 +103,7 @@ export class CoreIframeComponent implements OnChanges { | ||||
| 
 | ||||
|             await CoreIframeUtils.fixIframeCookies(url); | ||||
| 
 | ||||
|             this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(CoreFile.convertFileSrc(url)); | ||||
|             this.safeUrl = DomSanitizer.bypassSecurityTrustResourceUrl(CoreFile.convertFileSrc(url)); | ||||
| 
 | ||||
|             // Now that the URL has been set, initialize the iframe. Wait for the iframe to the added to the DOM.
 | ||||
|             setTimeout(() => { | ||||
|  | ||||
| @ -13,8 +13,8 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, Input, OnChanges, SimpleChange, ChangeDetectionStrategy } from '@angular/core'; | ||||
| import { DomSanitizer, SafeStyle } from '@angular/platform-browser'; | ||||
| import { Translate } from '@singletons'; | ||||
| import { SafeStyle } from '@angular/platform-browser'; | ||||
| import { DomSanitizer, Translate } from '@singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Component to show a progress bar and its value. | ||||
| @ -40,8 +40,6 @@ export class CoreProgressBarComponent implements OnChanges { | ||||
| 
 | ||||
|     protected textSupplied = false; | ||||
| 
 | ||||
|     constructor(private sanitizer: DomSanitizer) { } | ||||
| 
 | ||||
|     /** | ||||
|      * Detect changes on input properties. | ||||
|      */ | ||||
| @ -69,7 +67,7 @@ export class CoreProgressBarComponent implements OnChanges { | ||||
|                     this.text = String(this.progress); | ||||
|                 } | ||||
| 
 | ||||
|                 this.width = this.sanitizer.bypassSecurityTrustStyle(this.progress + '%'); | ||||
|                 this.width = DomSanitizer.bypassSecurityTrustStyle(this.progress + '%'); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -23,7 +23,6 @@ import { | ||||
|     Optional, | ||||
|     ViewContainerRef, | ||||
| } from '@angular/core'; | ||||
| import { DomSanitizer } from '@angular/platform-browser'; | ||||
| import { IonContent } from '@ionic/angular'; | ||||
| 
 | ||||
| import { CoreEventLoadingChangedData, CoreEventObserver, CoreEvents } from '@singletons/events'; | ||||
| @ -94,7 +93,6 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|         element: ElementRef, | ||||
|         @Optional() protected content: IonContent, | ||||
|         protected viewContainerRef: ViewContainerRef, | ||||
|         protected sanitizer: DomSanitizer, | ||||
|     ) { | ||||
|         this.element = element.nativeElement; | ||||
|         this.element.classList.add('core-format-text-loading'); // Hide contents until they're treated.
 | ||||
| @ -520,7 +518,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|         // Important: We need to look for links first because in 'img' we add new links without core-link.
 | ||||
|         anchors.forEach((anchor) => { | ||||
|             // Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
 | ||||
|             const linkDir = new CoreLinkDirective(new ElementRef(anchor), this.content, this.sanitizer); | ||||
|             const linkDir = new CoreLinkDirective(new ElementRef(anchor), this.content); | ||||
|             linkDir.capture = this.captureLinks ?? true; | ||||
|             linkDir.inApp = this.openLinksInApp; | ||||
|             linkDir.ngOnInit(); | ||||
|  | ||||
| @ -13,7 +13,7 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Directive, Input, OnInit, ElementRef, Optional, SecurityContext } from '@angular/core'; | ||||
| import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; | ||||
| import { SafeUrl } from '@angular/platform-browser'; | ||||
| import { IonContent } from '@ionic/angular'; | ||||
| 
 | ||||
| import { CoreFileHelper } from '@services/file-helper'; | ||||
| @ -25,6 +25,7 @@ import { CoreTextUtils } from '@services/utils/text'; | ||||
| import { CoreConstants } from '@/core/constants'; | ||||
| import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; | ||||
| import { CoreCustomURLSchemes } from '@services/urlschemes'; | ||||
| import { DomSanitizer } from '@singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Directive to open a link in external browser or in the app. | ||||
| @ -48,7 +49,6 @@ export class CoreLinkDirective implements OnInit { | ||||
|     constructor( | ||||
|         element: ElementRef, | ||||
|         @Optional() protected content: IonContent, | ||||
|         protected sanitizer: DomSanitizer, | ||||
|     ) { | ||||
|         this.element = element.nativeElement; | ||||
|     } | ||||
| @ -96,7 +96,7 @@ export class CoreLinkDirective implements OnInit { | ||||
|         let href: string | null = null; | ||||
|         if (this.href) { | ||||
|             // Convert the URL back to string if needed.
 | ||||
|             href = typeof this.href === 'string' ? this.href : this.sanitizer.sanitize(SecurityContext.URL, this.href); | ||||
|             href = typeof this.href === 'string' ? this.href : DomSanitizer.sanitize(SecurityContext.URL, this.href); | ||||
|         } | ||||
| 
 | ||||
|         href = href || this.element.getAttribute('href') || this.element.getAttribute('xlink:href'); | ||||
|  | ||||
| @ -12,7 +12,6 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { DomSanitizer } from '@angular/platform-browser'; | ||||
| import { IonContent } from '@ionic/angular'; | ||||
| import { NgZone } from '@angular/core'; | ||||
| import Faker from 'faker'; | ||||
| @ -39,7 +38,7 @@ describe('CoreFormatTextDirective', () => { | ||||
|         mockSingleton(Platform, { ready: () => Promise.resolve() }); | ||||
|         mockSingleton(CoreConfig, { get: (_, defaultValue) => defaultValue }); | ||||
| 
 | ||||
|         CoreDomUtils.setInstance(new CoreDomUtilsProvider(mock<DomSanitizer>())); | ||||
|         CoreDomUtils.setInstance(new CoreDomUtilsProvider()); | ||||
|         CoreUrlUtils.setInstance(new CoreUrlUtilsProvider()); | ||||
|         CoreUtils.setInstance(new CoreUtilsProvider(mock<NgZone>())); | ||||
| 
 | ||||
|  | ||||
| @ -44,7 +44,7 @@ describe('CoreNavigator', () => { | ||||
|         mockSingleton(Router, router); | ||||
|         mockSingleton(CoreUtils, new CoreUtilsProvider(mock())); | ||||
|         mockSingleton(CoreUrlUtils, new CoreUrlUtilsProvider()); | ||||
|         mockSingleton(CoreTextUtils, new CoreTextUtilsProvider(mock())); | ||||
|         mockSingleton(CoreTextUtils, new CoreTextUtilsProvider()); | ||||
|         mockSingleton(CoreSites, { getCurrentSiteId: () => 42, isLoggedIn: () => true }); | ||||
|         mockSingleton(CoreMainMenu, { isMainMenuTab: path => Promise.resolve(currentMainMenuHandlers.includes(path)) }); | ||||
|     }); | ||||
|  | ||||
| @ -12,24 +12,22 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { DomSanitizer } from '@angular/platform-browser'; | ||||
| 
 | ||||
| import { CoreApp } from '@services/app'; | ||||
| import { CoreTextUtilsProvider } from '@services/utils/text'; | ||||
| import { DomSanitizer } from '@singletons'; | ||||
| 
 | ||||
| import { mock, mockSingleton } from '@/testing/utils'; | ||||
| import { mockSingleton } from '@/testing/utils'; | ||||
| 
 | ||||
| describe('CoreTextUtilsProvider', () => { | ||||
| 
 | ||||
|     const config = { platform: 'android' }; | ||||
|     let sanitizer: DomSanitizer; | ||||
|     let textUtils: CoreTextUtilsProvider; | ||||
| 
 | ||||
|     beforeEach(() => { | ||||
|         mockSingleton(CoreApp, [], { isAndroid: () => config.platform === 'android' }); | ||||
|         mockSingleton(DomSanitizer, [], { bypassSecurityTrustUrl: url => url }); | ||||
| 
 | ||||
|         sanitizer = mock<DomSanitizer>([], { bypassSecurityTrustUrl: url => url }); | ||||
|         textUtils = new CoreTextUtilsProvider(sanitizer); | ||||
|         textUtils = new CoreTextUtilsProvider(); | ||||
|     }); | ||||
| 
 | ||||
|     it('adds ending slashes', () => { | ||||
| @ -58,7 +56,7 @@ describe('CoreTextUtilsProvider', () => { | ||||
|         // Assert
 | ||||
|         expect(url).toEqual('geo:0,0?q=Moodle%20Spain%20HQ'); | ||||
| 
 | ||||
|         expect(sanitizer.bypassSecurityTrustUrl).toHaveBeenCalled(); | ||||
|         expect(DomSanitizer.bypassSecurityTrustUrl).toHaveBeenCalled(); | ||||
|         expect(CoreApp.isAndroid).toHaveBeenCalled(); | ||||
|     }); | ||||
| 
 | ||||
| @ -74,7 +72,7 @@ describe('CoreTextUtilsProvider', () => { | ||||
|         // Assert
 | ||||
|         expect(url).toEqual('http://maps.google.com?q=Moodle%20Spain%20HQ'); | ||||
| 
 | ||||
|         expect(sanitizer.bypassSecurityTrustUrl).toHaveBeenCalled(); | ||||
|         expect(DomSanitizer.bypassSecurityTrustUrl).toHaveBeenCalled(); | ||||
|         expect(CoreApp.isAndroid).toHaveBeenCalled(); | ||||
|     }); | ||||
| 
 | ||||
|  | ||||
| @ -13,7 +13,6 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Injectable, SimpleChange, ElementRef, KeyValueChanges } from '@angular/core'; | ||||
| import { DomSanitizer } from '@angular/platform-browser'; | ||||
| import { IonContent } from '@ionic/angular'; | ||||
| import { ModalOptions, PopoverOptions, AlertOptions, AlertButton, TextFieldTypes } from '@ionic/core'; | ||||
| import { Md5 } from 'ts-md5'; | ||||
| @ -62,7 +61,7 @@ export class CoreDomUtilsProvider { | ||||
|     protected activeLoadingModals: CoreIonLoadingElement[] = []; | ||||
|     protected logger: CoreLogger; | ||||
| 
 | ||||
|     constructor(protected domSanitizer: DomSanitizer) { | ||||
|     constructor() { | ||||
|         this.logger = CoreLogger.getInstance('CoreDomUtilsProvider'); | ||||
| 
 | ||||
|         this.init(); | ||||
|  | ||||
| @ -13,13 +13,13 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; | ||||
| import { SafeUrl } from '@angular/platform-browser'; | ||||
| import { ModalOptions } from '@ionic/core'; | ||||
| 
 | ||||
| import { CoreApp } from '@services/app'; | ||||
| import { CoreLang } from '@services/lang'; | ||||
| import { CoreAnyError, CoreError } from '@classes/errors/error'; | ||||
| import { makeSingleton, Translate } from '@singletons'; | ||||
| import { DomSanitizer, makeSingleton, Translate } from '@singletons'; | ||||
| import { CoreWSFile } from '@services/ws'; | ||||
| import { Locutus } from '@singletons/locutus'; | ||||
| import { CoreViewerTextComponent } from '@features/viewer/components/text/text'; | ||||
| @ -94,8 +94,6 @@ export class CoreTextUtilsProvider { | ||||
| 
 | ||||
|     protected template: HTMLTemplateElement = document.createElement('template'); // A template element to convert HTML to element.
 | ||||
| 
 | ||||
|     constructor(private sanitizer: DomSanitizer) { } | ||||
| 
 | ||||
|     /** | ||||
|      * Add ending slash from a path or URL. | ||||
|      * | ||||
| @ -156,7 +154,7 @@ export class CoreTextUtilsProvider { | ||||
|      * @return URL to view the address. | ||||
|      */ | ||||
|     buildAddressURL(address: string): SafeUrl { | ||||
|         return this.sanitizer.bypassSecurityTrustUrl((CoreApp.isAndroid() ? 'geo:0,0?q=' : 'http://maps.google.com?q=') + | ||||
|         return DomSanitizer.bypassSecurityTrustUrl((CoreApp.isAndroid() ? 'geo:0,0?q=' : 'http://maps.google.com?q=') + | ||||
|                 encodeURIComponent(address)); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -12,9 +12,10 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { ApplicationRef, ApplicationInitStatus, Injector, NgZone as NgZoneService, Type } from '@angular/core'; | ||||
| import { AbstractType, ApplicationInitStatus, ApplicationRef, Injector, NgZone as NgZoneService, Type } from '@angular/core'; | ||||
| import { Router as RouterService } from '@angular/router'; | ||||
| import { HttpClient } from '@angular/common/http'; | ||||
| import { DomSanitizer as DomSanitizerService } from '@angular/platform-browser'; | ||||
| 
 | ||||
| import { | ||||
|     Platform as PlatformService, | ||||
| @ -109,7 +110,7 @@ export function setCreateSingletonMethodProxy(method: typeof createSingletonMeth | ||||
|  * @return Singleton proxy. | ||||
|  */ | ||||
| export function makeSingleton<Service extends object = object>( // eslint-disable-line @typescript-eslint/ban-types
 | ||||
|     injectionToken: Type<Service> | Type<unknown> | string, | ||||
|     injectionToken: Type<Service> | AbstractType<Service> | Type<unknown> | string, | ||||
| ): CoreSingletonProxy<Service> { | ||||
|     const singleton = { | ||||
|         setInstance(instance: Service) { | ||||
| @ -199,6 +200,7 @@ export const ApplicationInit = makeSingleton(ApplicationInitStatus); | ||||
| export const Application = makeSingleton(ApplicationRef); | ||||
| export const NavController = makeSingleton(NavControllerService); | ||||
| export const Router = makeSingleton(RouterService); | ||||
| export const DomSanitizer = makeSingleton(DomSanitizerService); | ||||
| 
 | ||||
| // Convert external libraries injectables.
 | ||||
| export const Translate = makeSingleton(TranslateService); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user