@angular/platform-browser
Version:
Angular - library for using Angular in a web browser
425 lines (417 loc) • 12.6 kB
JavaScript
/**
* @license Angular v21.0.5
* (c) 2010-2025 Google LLC. https://angular.dev/
* License: MIT
*/
import { ɵDomAdapter as _DomAdapter, ɵsetRootDomAdapter as _setRootDomAdapter, ɵparseCookieValue as _parseCookieValue, ɵgetDOM as _getDOM, DOCUMENT, ɵPLATFORM_BROWSER_ID as _PLATFORM_BROWSER_ID, XhrFactory, CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { ɵglobal as _global, ɵRuntimeError as _RuntimeError, Injectable, Inject, ɵresolveComponentResources as _resolveComponentResources, ɵinternalCreateApplication as _internalCreateApplication, PLATFORM_ID, PLATFORM_INITIALIZER, createPlatformFactory, platformCore, InjectionToken, ɵTESTABILITY_GETTER as _TESTABILITY_GETTER, ɵTESTABILITY as _TESTABILITY, Testability, ɵINJECTOR_SCOPE as _INJECTOR_SCOPE, ErrorHandler, RendererFactory2, inject, ApplicationModule, NgModule, ɵsetDocument as _setDocument } from '@angular/core';
import { EventManagerPlugin, EVENT_MANAGER_PLUGINS, DomEventsPlugin, DomRendererFactory2, SharedStylesHost, EventManager } from './_dom_renderer-chunk.mjs';
class BrowserDomAdapter extends _DomAdapter {
supportsDOMEvents = true;
static makeCurrent() {
_setRootDomAdapter(new BrowserDomAdapter());
}
onAndCancel(el, evt, listener, options) {
el.addEventListener(evt, listener, options);
return () => {
el.removeEventListener(evt, listener, options);
};
}
dispatchEvent(el, evt) {
el.dispatchEvent(evt);
}
remove(node) {
node.remove();
}
createElement(tagName, doc) {
doc = doc || this.getDefaultDocument();
return doc.createElement(tagName);
}
createHtmlDocument() {
return document.implementation.createHTMLDocument('fakeTitle');
}
getDefaultDocument() {
return document;
}
isElementNode(node) {
return node.nodeType === Node.ELEMENT_NODE;
}
isShadowRoot(node) {
return node instanceof DocumentFragment;
}
getGlobalEventTarget(doc, target) {
if (target === 'window') {
return window;
}
if (target === 'document') {
return doc;
}
if (target === 'body') {
return doc.body;
}
return null;
}
getBaseHref(doc) {
const href = getBaseElementHref();
return href == null ? null : relativePath(href);
}
resetBaseElement() {
baseElement = null;
}
getUserAgent() {
return window.navigator.userAgent;
}
getCookie(name) {
return _parseCookieValue(document.cookie, name);
}
}
let baseElement = null;
function getBaseElementHref() {
baseElement = baseElement || document.head.querySelector('base');
return baseElement ? baseElement.getAttribute('href') : null;
}
function relativePath(url) {
return new URL(url, document.baseURI).pathname;
}
class BrowserGetTestability {
addToWindow(registry) {
_global['getAngularTestability'] = (elem, findInAncestors = true) => {
const testability = registry.findTestabilityInTree(elem, findInAncestors);
if (testability == null) {
throw new _RuntimeError(5103, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Could not find testability for element.');
}
return testability;
};
_global['getAllAngularTestabilities'] = () => registry.getAllTestabilities();
_global['getAllAngularRootElements'] = () => registry.getAllRootElements();
const whenAllStable = callback => {
const testabilities = _global['getAllAngularTestabilities']();
let count = testabilities.length;
const decrement = function () {
count--;
if (count == 0) {
callback();
}
};
testabilities.forEach(testability => {
testability.whenStable(decrement);
});
};
if (!_global['frameworkStabilizers']) {
_global['frameworkStabilizers'] = [];
}
_global['frameworkStabilizers'].push(whenAllStable);
}
findTestabilityInTree(registry, elem, findInAncestors) {
if (elem == null) {
return null;
}
const t = registry.getTestability(elem);
if (t != null) {
return t;
} else if (!findInAncestors) {
return null;
}
if (_getDOM().isShadowRoot(elem)) {
return this.findTestabilityInTree(registry, elem.host, true);
}
return this.findTestabilityInTree(registry, elem.parentElement, true);
}
}
class BrowserXhr {
build() {
return new XMLHttpRequest();
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: BrowserXhr,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: BrowserXhr
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: BrowserXhr,
decorators: [{
type: Injectable
}]
});
const MODIFIER_KEYS = ['alt', 'control', 'meta', 'shift'];
const _keyMap = {
'\b': 'Backspace',
'\t': 'Tab',
'\x7F': 'Delete',
'\x1B': 'Escape',
'Del': 'Delete',
'Esc': 'Escape',
'Left': 'ArrowLeft',
'Right': 'ArrowRight',
'Up': 'ArrowUp',
'Down': 'ArrowDown',
'Menu': 'ContextMenu',
'Scroll': 'ScrollLock',
'Win': 'OS'
};
const MODIFIER_KEY_GETTERS = {
'alt': event => event.altKey,
'control': event => event.ctrlKey,
'meta': event => event.metaKey,
'shift': event => event.shiftKey
};
class KeyEventsPlugin extends EventManagerPlugin {
constructor(doc) {
super(doc);
}
supports(eventName) {
return KeyEventsPlugin.parseEventName(eventName) != null;
}
addEventListener(element, eventName, handler, options) {
const parsedEvent = KeyEventsPlugin.parseEventName(eventName);
const outsideHandler = KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());
return this.manager.getZone().runOutsideAngular(() => {
return _getDOM().onAndCancel(element, parsedEvent['domEventName'], outsideHandler, options);
});
}
static parseEventName(eventName) {
const parts = eventName.toLowerCase().split('.');
const domEventName = parts.shift();
if (parts.length === 0 || !(domEventName === 'keydown' || domEventName === 'keyup')) {
return null;
}
const key = KeyEventsPlugin._normalizeKey(parts.pop());
let fullKey = '';
let codeIX = parts.indexOf('code');
if (codeIX > -1) {
parts.splice(codeIX, 1);
fullKey = 'code.';
}
MODIFIER_KEYS.forEach(modifierName => {
const index = parts.indexOf(modifierName);
if (index > -1) {
parts.splice(index, 1);
fullKey += modifierName + '.';
}
});
fullKey += key;
if (parts.length != 0 || key.length === 0) {
return null;
}
const result = {};
result['domEventName'] = domEventName;
result['fullKey'] = fullKey;
return result;
}
static matchEventFullKeyCode(event, fullKeyCode) {
let keycode = _keyMap[event.key] || event.key;
let key = '';
if (fullKeyCode.indexOf('code.') > -1) {
keycode = event.code;
key = 'code.';
}
if (keycode == null || !keycode) return false;
keycode = keycode.toLowerCase();
if (keycode === ' ') {
keycode = 'space';
} else if (keycode === '.') {
keycode = 'dot';
}
MODIFIER_KEYS.forEach(modifierName => {
if (modifierName !== keycode) {
const modifierGetter = MODIFIER_KEY_GETTERS[modifierName];
if (modifierGetter(event)) {
key += modifierName + '.';
}
}
});
key += keycode;
return key === fullKeyCode;
}
static eventCallback(fullKey, handler, zone) {
return event => {
if (KeyEventsPlugin.matchEventFullKeyCode(event, fullKey)) {
zone.runGuarded(() => handler(event));
}
};
}
static _normalizeKey(keyName) {
return keyName === 'esc' ? 'escape' : keyName;
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: KeyEventsPlugin,
deps: [{
token: DOCUMENT
}],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: KeyEventsPlugin
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: KeyEventsPlugin,
decorators: [{
type: Injectable
}],
ctorParameters: () => [{
type: undefined,
decorators: [{
type: Inject,
args: [DOCUMENT]
}]
}]
});
function bootstrapApplication(rootComponent, options, context) {
const config = {
rootComponent,
platformRef: context?.platformRef,
...createProvidersConfig(options)
};
if ((typeof ngJitMode === 'undefined' || ngJitMode) && typeof fetch === 'function') {
return _resolveComponentResources(fetch).catch(error => {
console.error(error);
return Promise.resolve();
}).then(() => _internalCreateApplication(config));
}
return _internalCreateApplication(config);
}
function createApplication(options) {
return _internalCreateApplication(createProvidersConfig(options));
}
function createProvidersConfig(options) {
return {
appProviders: [...BROWSER_MODULE_PROVIDERS, ...(options?.providers ?? [])],
platformProviders: INTERNAL_BROWSER_PLATFORM_PROVIDERS
};
}
function provideProtractorTestingSupport() {
return [...TESTABILITY_PROVIDERS];
}
function initDomAdapter() {
BrowserDomAdapter.makeCurrent();
}
function errorHandler() {
return new ErrorHandler();
}
function _document() {
_setDocument(document);
return document;
}
const INTERNAL_BROWSER_PLATFORM_PROVIDERS = [{
provide: PLATFORM_ID,
useValue: _PLATFORM_BROWSER_ID
}, {
provide: PLATFORM_INITIALIZER,
useValue: initDomAdapter,
multi: true
}, {
provide: DOCUMENT,
useFactory: _document
}];
const platformBrowser = createPlatformFactory(platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);
const BROWSER_MODULE_PROVIDERS_MARKER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'BrowserModule Providers Marker' : '');
const TESTABILITY_PROVIDERS = [{
provide: _TESTABILITY_GETTER,
useClass: BrowserGetTestability
}, {
provide: _TESTABILITY,
useClass: Testability
}, {
provide: Testability,
useClass: Testability
}];
const BROWSER_MODULE_PROVIDERS = [{
provide: _INJECTOR_SCOPE,
useValue: 'root'
}, {
provide: ErrorHandler,
useFactory: errorHandler
}, {
provide: EVENT_MANAGER_PLUGINS,
useClass: DomEventsPlugin,
multi: true
}, {
provide: EVENT_MANAGER_PLUGINS,
useClass: KeyEventsPlugin,
multi: true
}, DomRendererFactory2, SharedStylesHost, EventManager, {
provide: RendererFactory2,
useExisting: DomRendererFactory2
}, {
provide: XhrFactory,
useClass: BrowserXhr
}, typeof ngDevMode === 'undefined' || ngDevMode ? {
provide: BROWSER_MODULE_PROVIDERS_MARKER,
useValue: true
} : []];
class BrowserModule {
constructor() {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
const providersAlreadyPresent = inject(BROWSER_MODULE_PROVIDERS_MARKER, {
optional: true,
skipSelf: true
});
if (providersAlreadyPresent) {
throw new _RuntimeError(5100, `Providers from the \`BrowserModule\` have already been loaded. If you need access ` + `to common directives such as NgIf and NgFor, import the \`CommonModule\` instead.`);
}
}
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: BrowserModule,
deps: [],
target: i0.ɵɵFactoryTarget.NgModule
});
static ɵmod = i0.ɵɵngDeclareNgModule({
minVersion: "14.0.0",
version: "21.0.5",
ngImport: i0,
type: BrowserModule,
exports: [CommonModule, ApplicationModule]
});
static ɵinj = i0.ɵɵngDeclareInjector({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: BrowserModule,
providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],
imports: [CommonModule, ApplicationModule]
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.5",
ngImport: i0,
type: BrowserModule,
decorators: [{
type: NgModule,
args: [{
providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],
exports: [CommonModule, ApplicationModule]
}]
}],
ctorParameters: () => []
});
export { BrowserDomAdapter, BrowserGetTestability, BrowserModule, KeyEventsPlugin, bootstrapApplication, createApplication, platformBrowser, provideProtractorTestingSupport };
//# sourceMappingURL=_browser-chunk.mjs.map