@angular/upgrade
Version:
Angular - the library for easing update from v1 to v2
1,190 lines (1,172 loc) • 44.1 kB
JavaScript
/**
* @license Angular v21.0.3
* (c) 2010-2025 Google LLC. https://angular.dev/
* License: MIT
*/
import { element, $ROOT_ELEMENT, $ROOT_SCOPE, DOWNGRADED_MODULE_COUNT_KEY, UPGRADE_APP_TYPE_KEY, $SCOPE, $COMPILE, $INJECTOR, $PARSE, REQUIRE_INJECTOR, REQUIRE_NG_MODEL, LAZY_MODULE_REF, INJECTOR_KEY, $CONTROLLER, $TEMPLATE_CACHE, $HTTP_BACKEND, module_, $PROVIDE, UPGRADE_MODULE_NAME, $$TESTABILITY, $DELEGATE, $INTERVAL, bootstrap } from './_constants-chunk.mjs';
export { getAngularJSGlobal, getAngularLib, setAngularJSGlobal, setAngularLib, angular1 as ɵangular1, constants as ɵconstants } from './_constants-chunk.mjs';
import * as i0 from '@angular/core';
import { ɵNG_MOD_DEF as _NG_MOD_DEF, Injector, ChangeDetectorRef, Testability, TestabilityRegistry, ApplicationRef, SimpleChange, ɵSIGNAL as _SIGNAL, NgZone, ComponentFactoryResolver, ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as _NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, PlatformRef, ɵinternalProvideZoneChangeDetection as _internalProvideZoneChangeDetection, EventEmitter, Directive, ɵNoopNgZone as _NoopNgZone, NgModule } from '@angular/core';
export { VERSION } from './upgrade.mjs';
import { platformBrowser } from '@angular/platform-browser';
class PropertyBinding {
prop;
attr;
bracketAttr;
bracketParenAttr;
parenAttr;
onAttr;
bindAttr;
bindonAttr;
constructor(prop, attr) {
this.prop = prop;
this.attr = attr;
this.bracketAttr = `[${this.attr}]`;
this.parenAttr = `(${this.attr})`;
this.bracketParenAttr = `[(${this.attr})]`;
const capitalAttr = this.attr.charAt(0).toUpperCase() + this.attr.slice(1);
this.onAttr = `on${capitalAttr}`;
this.bindAttr = `bind${capitalAttr}`;
this.bindonAttr = `bindon${capitalAttr}`;
}
}
const DIRECTIVE_PREFIX_REGEXP = /^(?:x|data)[:\-_]/i;
const DIRECTIVE_SPECIAL_CHARS_REGEXP = /[:\-_]+(.)/g;
function onError(e) {
console.error(e, e.stack);
throw e;
}
function cleanData(node) {
element.cleanData([node]);
if (isParentNode(node)) {
element.cleanData(node.querySelectorAll('*'));
}
}
function controllerKey(name) {
return '$' + name + 'Controller';
}
function destroyApp($injector) {
const $rootElement = $injector.get($ROOT_ELEMENT);
const $rootScope = $injector.get($ROOT_SCOPE);
$rootScope.$destroy();
cleanData($rootElement[0]);
}
function directiveNormalize(name) {
return name.replace(DIRECTIVE_PREFIX_REGEXP, '').replace(DIRECTIVE_SPECIAL_CHARS_REGEXP, (_, letter) => letter.toUpperCase());
}
function getTypeName(type) {
return type.overriddenName || type.name || type.toString().split('\n')[0];
}
function getDowngradedModuleCount($injector) {
return $injector.has(DOWNGRADED_MODULE_COUNT_KEY) ? $injector.get(DOWNGRADED_MODULE_COUNT_KEY) : 0;
}
function getUpgradeAppType($injector) {
return $injector.has(UPGRADE_APP_TYPE_KEY) ? $injector.get(UPGRADE_APP_TYPE_KEY) : 0;
}
function isFunction(value) {
return typeof value === 'function';
}
function isNgModuleType(value) {
return isFunction(value) && !!value[_NG_MOD_DEF];
}
function isParentNode(node) {
return isFunction(node.querySelectorAll);
}
function validateInjectionKey($injector, downgradedModule, injectionKey, attemptedAction) {
const upgradeAppType = getUpgradeAppType($injector);
const downgradedModuleCount = getDowngradedModuleCount($injector);
switch (upgradeAppType) {
case 1:
case 2:
if (downgradedModule) {
throw new Error(`Error while ${attemptedAction}: 'downgradedModule' unexpectedly specified.\n` + "You should not specify a value for 'downgradedModule', unless you are downgrading " + "more than one Angular module (via 'downgradeModule()').");
}
break;
case 3:
if (!downgradedModule && downgradedModuleCount >= 2) {
throw new Error(`Error while ${attemptedAction}: 'downgradedModule' not specified.\n` + 'This application contains more than one downgraded Angular module, thus you need to ' + "always specify 'downgradedModule' when downgrading components and injectables.");
}
if (!$injector.has(injectionKey)) {
throw new Error(`Error while ${attemptedAction}: Unable to find the specified downgraded module.\n` + 'Did you forget to downgrade an Angular module or include it in the AngularJS ' + 'application?');
}
break;
default:
throw new Error(`Error while ${attemptedAction}: Not a valid '@angular/upgrade' application.\n` + 'Did you forget to downgrade an Angular module or include it in the AngularJS ' + 'application?');
}
}
class Deferred {
promise;
resolve;
reject;
constructor() {
this.promise = new Promise((res, rej) => {
this.resolve = res;
this.reject = rej;
});
}
}
function supportsNgModel(component) {
return typeof component.writeValue === 'function' && typeof component.registerOnChange === 'function';
}
function hookupNgModel(ngModel, component) {
if (ngModel && supportsNgModel(component)) {
ngModel.$render = () => {
component.writeValue(ngModel.$viewValue);
};
component.registerOnChange(ngModel.$setViewValue.bind(ngModel));
if (typeof component.registerOnTouched === 'function') {
component.registerOnTouched(ngModel.$setTouched.bind(ngModel));
}
}
}
function strictEquals(val1, val2) {
return val1 === val2 || val1 !== val1 && val2 !== val2;
}
var util = /*#__PURE__*/Object.freeze({
__proto__: null,
Deferred: Deferred,
cleanData: cleanData,
controllerKey: controllerKey,
destroyApp: destroyApp,
directiveNormalize: directiveNormalize,
getDowngradedModuleCount: getDowngradedModuleCount,
getTypeName: getTypeName,
getUpgradeAppType: getUpgradeAppType,
hookupNgModel: hookupNgModel,
isFunction: isFunction,
isNgModuleType: isNgModuleType,
onError: onError,
strictEquals: strictEquals,
validateInjectionKey: validateInjectionKey
});
const INITIAL_VALUE$1 = {
__UNINITIALIZED__: true
};
class DowngradeComponentAdapter {
element;
attrs;
scope;
ngModel;
parentInjector;
$compile;
$parse;
componentFactory;
wrapCallback;
unsafelyOverwriteSignalInputs;
implementsOnChanges = false;
inputChangeCount = 0;
inputChanges = {};
componentScope;
constructor(element, attrs, scope, ngModel, parentInjector, $compile, $parse, componentFactory, wrapCallback, unsafelyOverwriteSignalInputs) {
this.element = element;
this.attrs = attrs;
this.scope = scope;
this.ngModel = ngModel;
this.parentInjector = parentInjector;
this.$compile = $compile;
this.$parse = $parse;
this.componentFactory = componentFactory;
this.wrapCallback = wrapCallback;
this.unsafelyOverwriteSignalInputs = unsafelyOverwriteSignalInputs;
this.componentScope = scope.$new();
}
compileContents() {
const compiledProjectableNodes = [];
const projectableNodes = this.groupProjectableNodes();
const linkFns = projectableNodes.map(nodes => this.$compile(nodes));
this.element.empty();
linkFns.forEach(linkFn => {
linkFn(this.scope, clone => {
compiledProjectableNodes.push(clone);
this.element.append(clone);
});
});
return compiledProjectableNodes;
}
createComponentAndSetup(projectableNodes, manuallyAttachView = false, propagateDigest = true) {
const component = this.createComponent(projectableNodes);
this.setupInputs(manuallyAttachView, propagateDigest, component);
this.setupOutputs(component.componentRef);
this.registerCleanup(component.componentRef);
return component.componentRef;
}
createComponent(projectableNodes) {
const providers = [{
provide: $SCOPE,
useValue: this.componentScope
}];
const childInjector = Injector.create({
providers: providers,
parent: this.parentInjector,
name: 'DowngradeComponentAdapter'
});
const componentRef = this.componentFactory.create(childInjector, projectableNodes, this.element[0]);
const viewChangeDetector = componentRef.injector.get(ChangeDetectorRef);
const changeDetector = componentRef.changeDetectorRef;
const testability = componentRef.injector.get(Testability, null);
if (testability) {
componentRef.injector.get(TestabilityRegistry).registerApplication(componentRef.location.nativeElement, testability);
}
hookupNgModel(this.ngModel, componentRef.instance);
return {
viewChangeDetector,
componentRef,
changeDetector
};
}
setupInputs(manuallyAttachView, propagateDigest = true, {
componentRef,
changeDetector,
viewChangeDetector
}) {
const attrs = this.attrs;
const inputs = this.componentFactory.inputs || [];
for (const input of inputs) {
const inputBinding = new PropertyBinding(input.propName, input.templateName);
let expr = null;
if (attrs.hasOwnProperty(inputBinding.attr)) {
const observeFn = ((prop, isSignal) => {
let prevValue = INITIAL_VALUE$1;
return currValue => {
if (!strictEquals(prevValue, currValue)) {
if (prevValue === INITIAL_VALUE$1) {
prevValue = currValue;
}
this.updateInput(componentRef, prop, prevValue, currValue, isSignal);
prevValue = currValue;
}
};
})(inputBinding.prop, input.isSignal);
attrs.$observe(inputBinding.attr, observeFn);
let unwatch = this.componentScope.$watch(() => {
unwatch();
unwatch = null;
observeFn(attrs[inputBinding.attr]);
});
} else if (attrs.hasOwnProperty(inputBinding.bindAttr)) {
expr = attrs[inputBinding.bindAttr];
} else if (attrs.hasOwnProperty(inputBinding.bracketAttr)) {
expr = attrs[inputBinding.bracketAttr];
} else if (attrs.hasOwnProperty(inputBinding.bindonAttr)) {
expr = attrs[inputBinding.bindonAttr];
} else if (attrs.hasOwnProperty(inputBinding.bracketParenAttr)) {
expr = attrs[inputBinding.bracketParenAttr];
}
if (expr != null) {
const watchFn = ((prop, isSignal) => (currValue, prevValue) => this.updateInput(componentRef, prop, prevValue, currValue, isSignal))(inputBinding.prop, input.isSignal);
this.componentScope.$watch(expr, watchFn);
}
}
const detectChanges = () => changeDetector.detectChanges();
const prototype = this.componentFactory.componentType.prototype;
this.implementsOnChanges = !!(prototype && prototype.ngOnChanges);
this.componentScope.$watch(() => this.inputChangeCount, this.wrapCallback(() => {
if (this.implementsOnChanges) {
const inputChanges = this.inputChanges;
this.inputChanges = {};
componentRef.instance.ngOnChanges(inputChanges);
}
viewChangeDetector.markForCheck();
if (!propagateDigest) {
detectChanges();
}
}));
if (propagateDigest) {
this.componentScope.$watch(this.wrapCallback(detectChanges));
}
if (manuallyAttachView || !propagateDigest) {
let unwatch = this.componentScope.$watch(() => {
unwatch();
unwatch = null;
const appRef = this.parentInjector.get(ApplicationRef);
appRef.attachView(componentRef.hostView);
});
}
}
setupOutputs(componentRef) {
const attrs = this.attrs;
const outputs = this.componentFactory.outputs || [];
for (const output of outputs) {
const outputBindings = new PropertyBinding(output.propName, output.templateName);
const bindonAttr = outputBindings.bindonAttr.substring(0, outputBindings.bindonAttr.length - 6);
const bracketParenAttr = `[(${outputBindings.bracketParenAttr.substring(2, outputBindings.bracketParenAttr.length - 8)})]`;
if (attrs.hasOwnProperty(bindonAttr)) {
this.subscribeToOutput(componentRef, outputBindings, attrs[bindonAttr], true);
}
if (attrs.hasOwnProperty(bracketParenAttr)) {
this.subscribeToOutput(componentRef, outputBindings, attrs[bracketParenAttr], true);
}
if (attrs.hasOwnProperty(outputBindings.onAttr)) {
this.subscribeToOutput(componentRef, outputBindings, attrs[outputBindings.onAttr]);
}
if (attrs.hasOwnProperty(outputBindings.parenAttr)) {
this.subscribeToOutput(componentRef, outputBindings, attrs[outputBindings.parenAttr]);
}
}
}
subscribeToOutput(componentRef, output, expr, isAssignment = false) {
const getter = this.$parse(expr);
const setter = getter.assign;
if (isAssignment && !setter) {
throw new Error(`Expression '${expr}' is not assignable!`);
}
const emitter = componentRef.instance[output.prop];
if (emitter) {
const subscription = emitter.subscribe(isAssignment ? v => setter(this.scope, v) : v => getter(this.scope, {
'$event': v
}));
componentRef.onDestroy(() => subscription.unsubscribe());
} else {
throw new Error(`Missing emitter '${output.prop}' on component '${getTypeName(this.componentFactory.componentType)}'!`);
}
}
registerCleanup(componentRef) {
const testabilityRegistry = componentRef.injector.get(TestabilityRegistry);
const destroyComponentRef = this.wrapCallback(() => componentRef.destroy());
let destroyed = false;
this.element.on('$destroy', () => {
if (!destroyed) this.componentScope.$destroy();
});
this.componentScope.$on('$destroy', () => {
if (!destroyed) {
destroyed = true;
testabilityRegistry.unregisterApplication(componentRef.location.nativeElement);
cleanData(this.element[0]);
destroyComponentRef();
}
});
}
updateInput(componentRef, prop, prevValue, currValue, isSignal) {
if (this.implementsOnChanges) {
this.inputChanges[prop] = new SimpleChange(prevValue, currValue, prevValue === currValue);
}
this.inputChangeCount++;
if (isSignal && !this.unsafelyOverwriteSignalInputs) {
const node = componentRef.instance[prop][_SIGNAL];
node.applyValueToInputSignal(node, currValue);
} else {
componentRef.instance[prop] = currValue;
}
}
groupProjectableNodes() {
let ngContentSelectors = this.componentFactory.ngContentSelectors;
return groupNodesBySelector(ngContentSelectors, this.element.contents());
}
}
function groupNodesBySelector(ngContentSelectors, nodes) {
const projectableNodes = [];
for (let i = 0, ii = ngContentSelectors.length; i < ii; ++i) {
projectableNodes[i] = [];
}
for (let j = 0, jj = nodes.length; j < jj; ++j) {
const node = nodes[j];
const ngContentIndex = findMatchingNgContentIndex(node, ngContentSelectors);
if (ngContentIndex != null) {
projectableNodes[ngContentIndex].push(node);
}
}
return projectableNodes;
}
function findMatchingNgContentIndex(element, ngContentSelectors) {
const ngContentIndices = [];
let wildcardNgContentIndex = -1;
for (let i = 0; i < ngContentSelectors.length; i++) {
const selector = ngContentSelectors[i];
if (selector === '*') {
wildcardNgContentIndex = i;
} else {
if (matchesSelector(element, selector)) {
ngContentIndices.push(i);
}
}
}
ngContentIndices.sort();
if (wildcardNgContentIndex !== -1) {
ngContentIndices.push(wildcardNgContentIndex);
}
return ngContentIndices.length ? ngContentIndices[0] : null;
}
function matchesSelector(el, selector) {
const elProto = Element.prototype;
return el.nodeType === Node.ELEMENT_NODE ? (elProto.matches ?? elProto.msMatchesSelector).call(el, selector) : false;
}
function isThenable(obj) {
return !!obj && isFunction(obj.then);
}
class SyncPromise {
value;
resolved = false;
callbacks = [];
static all(valuesOrPromises) {
const aggrPromise = new SyncPromise();
let resolvedCount = 0;
const results = [];
const resolve = (idx, value) => {
results[idx] = value;
if (++resolvedCount === valuesOrPromises.length) aggrPromise.resolve(results);
};
valuesOrPromises.forEach((p, idx) => {
if (isThenable(p)) {
p.then(v => resolve(idx, v));
} else {
resolve(idx, p);
}
});
return aggrPromise;
}
resolve(value) {
if (this.resolved) return;
this.value = value;
this.resolved = true;
this.callbacks.forEach(callback => callback(value));
this.callbacks.length = 0;
}
then(callback) {
if (this.resolved) {
callback(this.value);
} else {
this.callbacks.push(callback);
}
}
}
function downgradeComponent(info) {
const directiveFactory = function ($compile, $injector, $parse) {
const unsafelyOverwriteSignalInputs = info.unsafelyOverwriteSignalInputs ?? false;
const isNgUpgradeLite = getUpgradeAppType($injector) === 3;
const wrapCallback = !isNgUpgradeLite ? cb => cb : cb => () => NgZone.isInAngularZone() ? cb() : ngZone.run(cb);
let ngZone;
const hasMultipleDowngradedModules = isNgUpgradeLite && getDowngradedModuleCount($injector) > 1;
return {
restrict: 'E',
terminal: true,
require: [REQUIRE_INJECTOR, REQUIRE_NG_MODEL],
controller: function () {},
link: (scope, element, attrs, required) => {
const ngModel = required[1];
const parentInjector = required[0];
let moduleInjector = undefined;
let ranAsync = false;
if (!parentInjector || hasMultipleDowngradedModules) {
const downgradedModule = info.downgradedModule || '';
const lazyModuleRefKey = `${LAZY_MODULE_REF}${downgradedModule}`;
const attemptedAction = `instantiating component '${getTypeName(info.component)}'`;
validateInjectionKey($injector, downgradedModule, lazyModuleRefKey, attemptedAction);
const lazyModuleRef = $injector.get(lazyModuleRefKey);
moduleInjector = lazyModuleRef.injector ?? lazyModuleRef.promise;
}
const finalParentInjector = parentInjector || moduleInjector;
const finalModuleInjector = moduleInjector || parentInjector;
const doDowngrade = (injector, moduleInjector) => {
const componentFactoryResolver = moduleInjector.get(ComponentFactoryResolver);
const componentFactory = componentFactoryResolver.resolveComponentFactory(info.component);
if (!componentFactory) {
throw new Error(`Expecting ComponentFactory for: ${getTypeName(info.component)}`);
}
const injectorPromise = new ParentInjectorPromise(element);
const facade = new DowngradeComponentAdapter(element, attrs, scope, ngModel, injector, $compile, $parse, componentFactory, wrapCallback, unsafelyOverwriteSignalInputs);
const projectableNodes = facade.compileContents();
const componentRef = facade.createComponentAndSetup(projectableNodes, isNgUpgradeLite, info.propagateDigest);
injectorPromise.resolve(componentRef.injector);
if (ranAsync) {
scope.$evalAsync(() => {});
}
};
const downgradeFn = !isNgUpgradeLite ? doDowngrade : (pInjector, mInjector) => {
if (!ngZone) {
ngZone = pInjector.get(NgZone);
}
wrapCallback(() => doDowngrade(pInjector, mInjector))();
};
SyncPromise.all([finalParentInjector, finalModuleInjector]).then(([pInjector, mInjector]) => downgradeFn(pInjector, mInjector));
ranAsync = true;
}
};
};
directiveFactory['$inject'] = [$COMPILE, $INJECTOR, $PARSE];
return directiveFactory;
}
class ParentInjectorPromise extends SyncPromise {
element;
injectorKey = controllerKey(INJECTOR_KEY);
constructor(element) {
super();
this.element = element;
element.data(this.injectorKey, this);
}
resolve(injector) {
this.element.data(this.injectorKey, injector);
this.element = null;
super.resolve(injector);
}
}
function downgradeInjectable(token, downgradedModule = '') {
const factory = function ($injector) {
const injectorKey = `${INJECTOR_KEY}${downgradedModule}`;
const injectableName = isFunction(token) ? getTypeName(token) : String(token);
const attemptedAction = `instantiating injectable '${injectableName}'`;
validateInjectionKey($injector, downgradedModule, injectorKey, attemptedAction);
try {
const injector = $injector.get(injectorKey);
return injector.get(token);
} catch (err) {
throw new Error(`Error while ${attemptedAction}: ${err.message || err}`);
}
};
factory['$inject'] = [$INJECTOR];
return factory;
}
let policy;
function getPolicy() {
if (policy === undefined) {
policy = null;
const windowWithTrustedTypes = window;
if (windowWithTrustedTypes.trustedTypes) {
try {
policy = windowWithTrustedTypes.trustedTypes.createPolicy('angular#unsafe-upgrade', {
createHTML: s => s
});
} catch {}
}
}
return policy;
}
function trustedHTMLFromLegacyTemplate(html) {
return getPolicy()?.createHTML(html) || html;
}
const REQUIRE_PREFIX_RE = /^(\^\^?)?(\?)?(\^\^?)?/;
class UpgradeHelper {
name;
$injector;
element;
$element;
directive;
$compile;
$controller;
constructor(injector, name, elementRef, directive) {
this.name = name;
this.$injector = injector.get($INJECTOR);
this.$compile = this.$injector.get($COMPILE);
this.$controller = this.$injector.get($CONTROLLER);
this.element = elementRef.nativeElement;
this.$element = element(this.element);
this.directive = directive ?? UpgradeHelper.getDirective(this.$injector, name);
}
static getDirective($injector, name) {
const directives = $injector.get(name + 'Directive');
if (directives.length > 1) {
throw new Error(`Only support single directive definition for: ${name}`);
}
const directive = directives[0];
if (directive.compile && !directive.link) notSupported(name, 'compile');
if (directive.replace) notSupported(name, 'replace');
if (directive.terminal) notSupported(name, 'terminal');
return directive;
}
static getTemplate($injector, directive, fetchRemoteTemplate = false, $element) {
if (directive.template !== undefined) {
return trustedHTMLFromLegacyTemplate(getOrCall(directive.template, $element));
} else if (directive.templateUrl) {
const $templateCache = $injector.get($TEMPLATE_CACHE);
const url = getOrCall(directive.templateUrl, $element);
const template = $templateCache.get(url);
if (template !== undefined) {
return trustedHTMLFromLegacyTemplate(template);
} else if (!fetchRemoteTemplate) {
throw new Error('loading directive templates asynchronously is not supported');
}
return new Promise((resolve, reject) => {
const $httpBackend = $injector.get($HTTP_BACKEND);
$httpBackend('GET', url, null, (status, response) => {
if (status === 200) {
resolve(trustedHTMLFromLegacyTemplate($templateCache.put(url, response)));
} else {
reject(`GET component template from '${url}' returned '${status}: ${response}'`);
}
});
});
} else {
throw new Error(`Directive '${directive.name}' is not a component, it is missing template.`);
}
}
buildController(controllerType, $scope) {
const locals = {
'$scope': $scope,
'$element': this.$element
};
const controller = this.$controller(controllerType, locals, null, this.directive.controllerAs);
this.$element.data?.(controllerKey(this.directive.name), controller);
return controller;
}
compileTemplate(template) {
if (template === undefined) {
template = UpgradeHelper.getTemplate(this.$injector, this.directive, false, this.$element);
}
return this.compileHtml(template);
}
onDestroy($scope, controllerInstance) {
if (controllerInstance && isFunction(controllerInstance.$onDestroy)) {
controllerInstance.$onDestroy();
}
$scope.$destroy();
cleanData(this.element);
}
prepareTransclusion() {
const transclude = this.directive.transclude;
const contentChildNodes = this.extractChildNodes();
const attachChildrenFn = (scope, cloneAttachFn) => {
scope = scope || {
$destroy: () => undefined
};
return cloneAttachFn($template, scope);
};
let $template = contentChildNodes;
if (transclude) {
const slots = Object.create(null);
if (typeof transclude === 'object') {
$template = [];
const slotMap = Object.create(null);
const filledSlots = Object.create(null);
Object.keys(transclude).forEach(slotName => {
let selector = transclude[slotName];
const optional = selector.charAt(0) === '?';
selector = optional ? selector.substring(1) : selector;
slotMap[selector] = slotName;
slots[slotName] = null;
filledSlots[slotName] = optional;
});
contentChildNodes.forEach(node => {
const slotName = slotMap[directiveNormalize(node.nodeName.toLowerCase())];
if (slotName) {
filledSlots[slotName] = true;
slots[slotName] = slots[slotName] || [];
slots[slotName].push(node);
} else {
$template.push(node);
}
});
Object.keys(filledSlots).forEach(slotName => {
if (!filledSlots[slotName]) {
throw new Error(`Required transclusion slot '${slotName}' on directive: ${this.name}`);
}
});
Object.keys(slots).filter(slotName => slots[slotName]).forEach(slotName => {
const nodes = slots[slotName];
slots[slotName] = (scope, cloneAttach) => {
return cloneAttach(nodes, scope);
};
});
}
attachChildrenFn.$$slots = slots;
$template.forEach(node => {
if (node.nodeType === Node.TEXT_NODE && !node.nodeValue) {
node.nodeValue = '\u200C';
}
});
}
return attachChildrenFn;
}
resolveAndBindRequiredControllers(controllerInstance) {
const directiveRequire = this.getDirectiveRequire();
const requiredControllers = this.resolveRequire(directiveRequire);
if (controllerInstance && this.directive.bindToController && isMap(directiveRequire)) {
const requiredControllersMap = requiredControllers;
Object.keys(requiredControllersMap).forEach(key => {
controllerInstance[key] = requiredControllersMap[key];
});
}
return requiredControllers;
}
compileHtml(html) {
this.element.innerHTML = html;
return this.$compile(this.element.childNodes);
}
extractChildNodes() {
const childNodes = [];
let childNode;
while (childNode = this.element.firstChild) {
childNode.remove();
childNodes.push(childNode);
}
return childNodes;
}
getDirectiveRequire() {
const require = this.directive.require || this.directive.controller && this.directive.name;
if (isMap(require)) {
Object.entries(require).forEach(([key, value]) => {
const match = value.match(REQUIRE_PREFIX_RE);
const name = value.substring(match[0].length);
if (!name) {
require[key] = match[0] + key;
}
});
}
return require;
}
resolveRequire(require) {
if (!require) {
return null;
} else if (Array.isArray(require)) {
return require.map(req => this.resolveRequire(req));
} else if (typeof require === 'object') {
const value = {};
Object.keys(require).forEach(key => value[key] = this.resolveRequire(require[key]));
return value;
} else if (typeof require === 'string') {
const match = require.match(REQUIRE_PREFIX_RE);
const inheritType = match[1] || match[3];
const name = require.substring(match[0].length);
const isOptional = !!match[2];
const searchParents = !!inheritType;
const startOnParent = inheritType === '^^';
const ctrlKey = controllerKey(name);
const elem = startOnParent ? this.$element.parent() : this.$element;
const value = searchParents ? elem.inheritedData(ctrlKey) : elem.data(ctrlKey);
if (!value && !isOptional) {
throw new Error(`Unable to find required '${require}' in upgraded directive '${this.name}'.`);
}
return value;
} else {
throw new Error(`Unrecognized 'require' syntax on upgraded directive '${this.name}': ${require}`);
}
}
}
function getOrCall(property, ...args) {
return isFunction(property) ? property(...args) : property;
}
function isMap(value) {
return value && !Array.isArray(value) && typeof value === 'object';
}
function notSupported(name, feature) {
throw new Error(`Upgraded directive '${name}' contains unsupported feature: '${feature}'.`);
}
var upgrade_helper = /*#__PURE__*/Object.freeze({
__proto__: null,
UpgradeHelper: UpgradeHelper
});
let tempInjectorRef = null;
function setTempInjectorRef(injector) {
tempInjectorRef = injector;
}
function injectorFactory() {
if (!tempInjectorRef) {
throw new Error('Trying to get the AngularJS injector before it being set.');
}
const injector = tempInjectorRef;
tempInjectorRef = null;
return injector;
}
function rootScopeFactory(i) {
return i.get('$rootScope');
}
function compileFactory(i) {
return i.get('$compile');
}
function parseFactory(i) {
return i.get('$parse');
}
const angular1Providers = [{
provide: '$injector',
useFactory: injectorFactory,
deps: []
}, {
provide: '$rootScope',
useFactory: rootScopeFactory,
deps: ['$injector']
}, {
provide: '$compile',
useFactory: compileFactory,
deps: ['$injector']
}, {
provide: '$parse',
useFactory: parseFactory,
deps: ['$injector']
}];
class NgAdapterInjector {
modInjector;
constructor(modInjector) {
this.modInjector = modInjector;
}
get(token, notFoundValue) {
if (notFoundValue === _NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
return notFoundValue;
}
return this.modInjector.get(token, notFoundValue);
}
}
let moduleUid = 0;
function downgradeModule(moduleOrBootstrapFn) {
const lazyModuleName = `${UPGRADE_MODULE_NAME}.lazy${++moduleUid}`;
const lazyModuleRefKey = `${LAZY_MODULE_REF}${lazyModuleName}`;
const lazyInjectorKey = `${INJECTOR_KEY}${lazyModuleName}`;
let bootstrapFn;
if (isNgModuleType(moduleOrBootstrapFn)) {
bootstrapFn = extraProviders => platformBrowser(extraProviders).bootstrapModule(moduleOrBootstrapFn, {
applicationProviders: [_internalProvideZoneChangeDetection({})]
});
} else if (!isFunction(moduleOrBootstrapFn)) {
bootstrapFn = extraProviders => platformBrowser(extraProviders).bootstrapModuleFactory(moduleOrBootstrapFn, {
applicationProviders: [_internalProvideZoneChangeDetection({})]
});
} else {
bootstrapFn = moduleOrBootstrapFn;
}
let injector;
module_(lazyModuleName, []).constant(UPGRADE_APP_TYPE_KEY, 3).factory(INJECTOR_KEY, [lazyInjectorKey, identity]).factory(lazyInjectorKey, () => {
if (!injector) {
throw new Error('Trying to get the Angular injector before bootstrapping the corresponding ' + 'Angular module.');
}
return injector;
}).factory(LAZY_MODULE_REF, [lazyModuleRefKey, identity]).factory(lazyModuleRefKey, [$INJECTOR, $injector => {
setTempInjectorRef($injector);
const result = {
promise: bootstrapFn(angular1Providers).then(ref => {
injector = result.injector = new NgAdapterInjector(ref.injector);
injector.get($INJECTOR);
injector.get(PlatformRef).onDestroy(() => destroyApp($injector));
return injector;
})
};
return result;
}]).config([$INJECTOR, $PROVIDE, ($injector, $provide) => {
$provide.constant(DOWNGRADED_MODULE_COUNT_KEY, getDowngradedModuleCount($injector) + 1);
}]);
return lazyModuleName;
}
function identity(x) {
return x;
}
const NOT_SUPPORTED = 'NOT_SUPPORTED';
const INITIAL_VALUE = {
__UNINITIALIZED__: true
};
class Bindings {
twoWayBoundProperties = [];
twoWayBoundLastValues = [];
expressionBoundProperties = [];
propertyToOutputMap = {};
}
class UpgradeComponent {
helper;
$element;
$componentScope;
directive;
bindings;
controllerInstance;
bindingDestination;
pendingChanges = null;
unregisterDoCheckWatcher;
constructor(name, elementRef, injector) {
this.helper = new UpgradeHelper(injector, name, elementRef);
this.$element = this.helper.$element;
this.directive = this.helper.directive;
this.bindings = this.initializeBindings(this.directive, name);
const $parentScope = injector.get($SCOPE);
this.$componentScope = $parentScope.$new(!!this.directive.scope);
this.initializeOutputs();
}
ngOnInit() {
const attachChildNodes = this.helper.prepareTransclusion();
const linkFn = this.helper.compileTemplate();
const controllerType = this.directive.controller;
const bindToController = this.directive.bindToController;
let controllerInstance = controllerType ? this.helper.buildController(controllerType, this.$componentScope) : undefined;
let bindingDestination;
if (!bindToController) {
bindingDestination = this.$componentScope;
} else if (controllerType && controllerInstance) {
bindingDestination = controllerInstance;
} else {
throw new Error(`Upgraded directive '${this.directive.name}' specifies 'bindToController' but no controller.`);
}
this.controllerInstance = controllerInstance;
this.bindingDestination = bindingDestination;
this.bindOutputs(bindingDestination);
const requiredControllers = this.helper.resolveAndBindRequiredControllers(controllerInstance);
if (this.pendingChanges) {
this.forwardChanges(this.pendingChanges, bindingDestination);
this.pendingChanges = null;
}
if (this.controllerInstance && isFunction(this.controllerInstance.$onInit)) {
this.controllerInstance.$onInit();
}
if (controllerInstance && isFunction(controllerInstance.$doCheck)) {
const callDoCheck = () => controllerInstance?.$doCheck?.();
this.unregisterDoCheckWatcher = this.$componentScope.$parent.$watch(callDoCheck);
callDoCheck();
}
const link = this.directive.link;
const preLink = typeof link == 'object' && link.pre;
const postLink = typeof link == 'object' ? link.post : link;
const attrs = NOT_SUPPORTED;
const transcludeFn = NOT_SUPPORTED;
if (preLink) {
preLink(this.$componentScope, this.$element, attrs, requiredControllers, transcludeFn);
}
linkFn(this.$componentScope, null, {
parentBoundTranscludeFn: attachChildNodes
});
if (postLink) {
postLink(this.$componentScope, this.$element, attrs, requiredControllers, transcludeFn);
}
if (this.controllerInstance && isFunction(this.controllerInstance.$postLink)) {
this.controllerInstance.$postLink();
}
}
ngOnChanges(changes) {
if (!this.bindingDestination) {
this.pendingChanges = changes;
} else {
this.forwardChanges(changes, this.bindingDestination);
}
}
ngDoCheck() {
const twoWayBoundProperties = this.bindings.twoWayBoundProperties;
const twoWayBoundLastValues = this.bindings.twoWayBoundLastValues;
const propertyToOutputMap = this.bindings.propertyToOutputMap;
twoWayBoundProperties.forEach((propName, idx) => {
const newValue = this.bindingDestination?.[propName];
const oldValue = twoWayBoundLastValues[idx];
if (!Object.is(newValue, oldValue)) {
const outputName = propertyToOutputMap[propName];
const eventEmitter = this[outputName];
eventEmitter.emit(newValue);
twoWayBoundLastValues[idx] = newValue;
}
});
}
ngOnDestroy() {
if (isFunction(this.unregisterDoCheckWatcher)) {
this.unregisterDoCheckWatcher();
}
this.helper.onDestroy(this.$componentScope, this.controllerInstance);
}
initializeBindings(directive, name) {
const btcIsObject = typeof directive.bindToController === 'object';
if (btcIsObject && Object.keys(directive.scope).length) {
throw new Error(`Binding definitions on scope and controller at the same time is not supported.`);
}
const context = btcIsObject ? directive.bindToController : directive.scope;
const bindings = new Bindings();
if (typeof context == 'object') {
Object.keys(context).forEach(propName => {
const definition = context[propName];
const bindingType = definition.charAt(0);
switch (bindingType) {
case '@':
case '<':
break;
case '=':
bindings.twoWayBoundProperties.push(propName);
bindings.twoWayBoundLastValues.push(INITIAL_VALUE);
bindings.propertyToOutputMap[propName] = propName + 'Change';
break;
case '&':
bindings.expressionBoundProperties.push(propName);
bindings.propertyToOutputMap[propName] = propName;
break;
default:
let json = JSON.stringify(context);
throw new Error(`Unexpected mapping '${bindingType}' in '${json}' in '${name}' directive.`);
}
});
}
return bindings;
}
initializeOutputs() {
this.bindings.twoWayBoundProperties.concat(this.bindings.expressionBoundProperties).forEach(propName => {
const outputName = this.bindings.propertyToOutputMap[propName];
this[outputName] = new EventEmitter();
});
}
bindOutputs(bindingDestination) {
this.bindings.expressionBoundProperties.forEach(propName => {
const outputName = this.bindings.propertyToOutputMap[propName];
const emitter = this[outputName];
bindingDestination[propName] = value => emitter.emit(value);
});
}
forwardChanges(changes, bindingDestination) {
Object.keys(changes).forEach(propName => bindingDestination[propName] = changes[propName].currentValue);
if (isFunction(bindingDestination.$onChanges)) {
bindingDestination.$onChanges(changes);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: UpgradeComponent,
deps: "invalid",
target: i0.ɵɵFactoryTarget.Directive
});
static ɵdir = i0.ɵɵngDeclareDirective({
minVersion: "14.0.0",
version: "21.0.3",
type: UpgradeComponent,
isStandalone: true,
usesOnChanges: true,
ngImport: i0
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: UpgradeComponent,
decorators: [{
type: Directive
}],
ctorParameters: () => [{
type: undefined
}, {
type: i0.ElementRef
}, {
type: i0.Injector
}]
});
class UpgradeModule {
ngZone;
platformRef;
$injector;
injector;
applicationRef;
constructor(injector, ngZone, platformRef) {
this.ngZone = ngZone;
this.platformRef = platformRef;
this.injector = new NgAdapterInjector(injector);
this.applicationRef = this.injector.get(ApplicationRef);
}
bootstrap(element$1, modules = [], config) {
const INIT_MODULE_NAME = UPGRADE_MODULE_NAME + '.init';
module_(INIT_MODULE_NAME, []).constant(UPGRADE_APP_TYPE_KEY, 2).value(INJECTOR_KEY, this.injector).factory(LAZY_MODULE_REF, [INJECTOR_KEY, injector => ({
injector
})]).config([$PROVIDE, $INJECTOR, ($provide, $injector) => {
if ($injector.has($$TESTABILITY)) {
$provide.decorator($$TESTABILITY, [$DELEGATE, testabilityDelegate => {
const originalWhenStable = testabilityDelegate.whenStable;
const injector = this.injector;
const newWhenStable = function (callback) {
originalWhenStable.call(testabilityDelegate, function () {
const ng2Testability = injector.get(Testability);
if (ng2Testability.isStable()) {
callback();
} else {
ng2Testability.whenStable(newWhenStable.bind(testabilityDelegate, callback));
}
});
};
testabilityDelegate.whenStable = newWhenStable;
return testabilityDelegate;
}]);
}
if ($injector.has($INTERVAL)) {
$provide.decorator($INTERVAL, [$DELEGATE, intervalDelegate => {
let wrappedInterval = (fn, delay, count, invokeApply, ...pass) => {
return this.ngZone.runOutsideAngular(() => {
return intervalDelegate((...args) => {
setTimeout(() => {
this.ngZone.run(() => fn(...args));
});
}, delay, count, invokeApply, ...pass);
});
};
Object.keys(intervalDelegate).forEach(prop => wrappedInterval[prop] = intervalDelegate[prop]);
if (intervalDelegate.hasOwnProperty('flush')) {
wrappedInterval['flush'] = () => {
intervalDelegate['flush']();
return wrappedInterval;
};
}
return wrappedInterval;
}]);
}
}]).run([$INJECTOR, $injector => {
this.$injector = $injector;
const $rootScope = $injector.get('$rootScope');
setTempInjectorRef($injector);
this.injector.get($INJECTOR);
element(element$1).data(controllerKey(INJECTOR_KEY), this.injector);
this.platformRef.onDestroy(() => destroyApp($injector));
setTimeout(() => {
const synchronize = () => {
this.ngZone.run(() => {
if ($rootScope.$$phase) {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
console.warn('A digest was triggered while one was already in progress. This may mean that something is triggering digests outside the Angular zone.');
}
$rootScope.$evalAsync();
} else {
$rootScope.$digest();
}
});
};
const subscription = this.ngZone instanceof _NoopNgZone ? this.applicationRef.afterTick.subscribe(() => synchronize()) : this.ngZone.onMicrotaskEmpty.subscribe(() => synchronize());
$rootScope.$on('$destroy', () => {
subscription.unsubscribe();
});
}, 0);
}]);
const upgradeModule = module_(UPGRADE_MODULE_NAME, [INIT_MODULE_NAME].concat(modules));
const windowAngular = window['angular'];
windowAngular.resumeBootstrap = undefined;
const returnValue = this.ngZone.run(() => bootstrap(element$1, [upgradeModule.name], config));
if (windowAngular.resumeBootstrap) {
const originalResumeBootstrap = windowAngular.resumeBootstrap;
const ngZone = this.ngZone;
windowAngular.resumeBootstrap = function () {
let args = arguments;
windowAngular.resumeBootstrap = originalResumeBootstrap;
return ngZone.run(() => windowAngular.resumeBootstrap.apply(this, args));
};
}
return returnValue;
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: UpgradeModule,
deps: [{
token: i0.Injector
}, {
token: i0.NgZone
}, {
token: i0.PlatformRef
}],
target: i0.ɵɵFactoryTarget.NgModule
});
static ɵmod = i0.ɵɵngDeclareNgModule({
minVersion: "14.0.0",
version: "21.0.3",
ngImport: i0,
type: UpgradeModule
});
static ɵinj = i0.ɵɵngDeclareInjector({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: UpgradeModule,
providers: [angular1Providers, _internalProvideZoneChangeDetection({})]
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: UpgradeModule,
decorators: [{
type: NgModule,
args: [{
providers: [angular1Providers, _internalProvideZoneChangeDetection({})]
}]
}],
ctorParameters: () => [{
type: i0.Injector
}, {
type: i0.NgZone
}, {
type: i0.PlatformRef
}]
});
export { UpgradeComponent, UpgradeModule, downgradeComponent, downgradeInjectable, downgradeModule, upgrade_helper as ɵupgradeHelper, util as ɵutil };
//# sourceMappingURL=static.mjs.map