In VE the `Sanitizer` is always available in `BrowserModule` because the VE retrieves it using injection. In Ivy the injection is optional and we have instructions instead of component definition arrays. The implication of this is that in Ivy the instructions can pull in the sanitizer only when they are working with a property which is known to be unsafe. Because the Injection is optional this works even if no Sanitizer is present. So in Ivy we first use the sanitizer which is pulled in by the instruction, unless one is available through the `Injector` then we use that one instead. This PR does few things: 1) It makes `Sanitizer` optional in Ivy. 2) It makes `DomSanitizer` tree shakable. 3) It aligns the semantics of Ivy `Sanitizer` with that of the Ivy sanitization rules. 4) It refactors `DomSanitizer` to use same functions as Ivy sanitization for consistency. PR Close #31934
137 lines
5.5 KiB
TypeScript
137 lines
5.5 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {CommonModule, DOCUMENT, PlatformLocation, ɵPLATFORM_BROWSER_ID as PLATFORM_BROWSER_ID} from '@angular/common';
|
|
import {APP_ID, ApplicationModule, ErrorHandler, Inject, ModuleWithProviders, NgModule, NgZone, Optional, PLATFORM_ID, PLATFORM_INITIALIZER, PlatformRef, RendererFactory2, Sanitizer, SkipSelf, StaticProvider, Testability, createPlatformFactory, platformCore, ɵAPP_ROOT as APP_ROOT, ɵConsole as Console} from '@angular/core';
|
|
|
|
import {BrowserDomAdapter} from './browser/browser_adapter';
|
|
import {BrowserPlatformLocation} from './browser/location/browser_platform_location';
|
|
import {SERVER_TRANSITION_PROVIDERS, TRANSITION_ID} from './browser/server-transition';
|
|
import {BrowserGetTestability} from './browser/testability';
|
|
import {ELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
|
|
import {DomRendererFactory2} from './dom/dom_renderer';
|
|
import {DomEventsPlugin} from './dom/events/dom_events';
|
|
import {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
|
|
import {HAMMER_GESTURE_CONFIG, HAMMER_LOADER, HammerGestureConfig, HammerGesturesPlugin} from './dom/events/hammer_gestures';
|
|
import {KeyEventsPlugin} from './dom/events/key_events';
|
|
import {DomSharedStylesHost, SharedStylesHost} from './dom/shared_styles_host';
|
|
import {DomSanitizer, DomSanitizerImpl} from './security/dom_sanitization_service';
|
|
|
|
export const INTERNAL_BROWSER_PLATFORM_PROVIDERS: StaticProvider[] = [
|
|
{provide: PLATFORM_ID, useValue: PLATFORM_BROWSER_ID},
|
|
{provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true},
|
|
{provide: PlatformLocation, useClass: BrowserPlatformLocation, deps: [DOCUMENT]},
|
|
{provide: DOCUMENT, useFactory: _document, deps: []},
|
|
];
|
|
|
|
const BROWSER_SANITIZATION_PROVIDERS__PRE_R3__: StaticProvider[] = [
|
|
{provide: Sanitizer, useExisting: DomSanitizer},
|
|
{provide: DomSanitizer, useClass: DomSanitizerImpl, deps: [DOCUMENT]},
|
|
];
|
|
|
|
/**
|
|
* @codeGenApi
|
|
*/
|
|
export const BROWSER_SANITIZATION_PROVIDERS__POST_R3__ = [];
|
|
|
|
/**
|
|
* @security Replacing built-in sanitization providers exposes the application to XSS risks.
|
|
* Attacker-controlled data introduced by an unsanitized provider could expose your
|
|
* application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
|
|
* @publicApi
|
|
*/
|
|
export const BROWSER_SANITIZATION_PROVIDERS = BROWSER_SANITIZATION_PROVIDERS__PRE_R3__;
|
|
|
|
/**
|
|
* @publicApi
|
|
*/
|
|
export const platformBrowser: (extraProviders?: StaticProvider[]) => PlatformRef =
|
|
createPlatformFactory(platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);
|
|
|
|
export function initDomAdapter() {
|
|
BrowserDomAdapter.makeCurrent();
|
|
BrowserGetTestability.init();
|
|
}
|
|
|
|
export function errorHandler(): ErrorHandler {
|
|
return new ErrorHandler();
|
|
}
|
|
|
|
export function _document(): any {
|
|
return document;
|
|
}
|
|
|
|
export const BROWSER_MODULE_PROVIDERS: StaticProvider[] = [
|
|
BROWSER_SANITIZATION_PROVIDERS,
|
|
{provide: APP_ROOT, useValue: true},
|
|
{provide: ErrorHandler, useFactory: errorHandler, deps: []},
|
|
{
|
|
provide: EVENT_MANAGER_PLUGINS,
|
|
useClass: DomEventsPlugin,
|
|
multi: true,
|
|
deps: [DOCUMENT, NgZone, PLATFORM_ID]
|
|
},
|
|
{provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true, deps: [DOCUMENT]},
|
|
{
|
|
provide: EVENT_MANAGER_PLUGINS,
|
|
useClass: HammerGesturesPlugin,
|
|
multi: true,
|
|
deps: [DOCUMENT, HAMMER_GESTURE_CONFIG, Console, [new Optional(), HAMMER_LOADER]]
|
|
},
|
|
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig, deps: []},
|
|
{
|
|
provide: DomRendererFactory2,
|
|
useClass: DomRendererFactory2,
|
|
deps: [EventManager, DomSharedStylesHost, APP_ID]
|
|
},
|
|
{provide: RendererFactory2, useExisting: DomRendererFactory2},
|
|
{provide: SharedStylesHost, useExisting: DomSharedStylesHost},
|
|
{provide: DomSharedStylesHost, useClass: DomSharedStylesHost, deps: [DOCUMENT]},
|
|
{provide: Testability, useClass: Testability, deps: [NgZone]},
|
|
{provide: EventManager, useClass: EventManager, deps: [EVENT_MANAGER_PLUGINS, NgZone]},
|
|
ELEMENT_PROBE_PROVIDERS,
|
|
];
|
|
|
|
/**
|
|
* Exports required infrastructure for all Angular apps.
|
|
* Included by default in all Angular apps created with the CLI
|
|
* `new` command.
|
|
* Re-exports `CommonModule` and `ApplicationModule`, making their
|
|
* exports and providers available to all apps.
|
|
*
|
|
* @publicApi
|
|
*/
|
|
@NgModule({providers: BROWSER_MODULE_PROVIDERS, exports: [CommonModule, ApplicationModule]})
|
|
export class BrowserModule {
|
|
constructor(@Optional() @SkipSelf() @Inject(BrowserModule) parentModule: BrowserModule|null) {
|
|
if (parentModule) {
|
|
throw new Error(
|
|
`BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Configures a browser-based app to transition from a server-rendered app, if
|
|
* one is present on the page.
|
|
*
|
|
* @param params An object containing an identifier for the app to transition.
|
|
* The ID must match between the client and server versions of the app.
|
|
* @returns The reconfigured `BrowserModule` to import into the app's root `AppModule`.
|
|
*/
|
|
static withServerTransition(params: {appId: string}): ModuleWithProviders<BrowserModule> {
|
|
return {
|
|
ngModule: BrowserModule,
|
|
providers: [
|
|
{provide: APP_ID, useValue: params.appId},
|
|
{provide: TRANSITION_ID, useExisting: APP_ID},
|
|
SERVER_TRANSITION_PROVIDERS,
|
|
],
|
|
};
|
|
}
|
|
}
|