@angular/upgrade
Version:
Angular - the library for easing update from v1 to v2
1,069 lines (1,057 loc) • 114 kB
JavaScript
/**
* @license Angular v11.2.4
* (c) 2010-2021 Google LLC. https://angular.io/
* License: MIT
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/platform-browser-dynamic')) :
typeof define === 'function' && define.amd ? define('@angular/upgrade', ['exports', '@angular/core', '@angular/platform-browser-dynamic'], factory) :
(global = global || self, factory((global.ng = global.ng || {}, global.ng.upgrade = {}), global.ng.core, global.ng.platformBrowserDynamic));
}(this, (function (exports, core, platformBrowserDynamic) { 'use strict';
/**
* @license
* Copyright Google LLC 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
*/
/**
* @publicApi
*/
var VERSION = new core.Version('11.2.4');
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b)
if (b.hasOwnProperty(p))
d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
r = Reflect.decorate(decorators, target, key, desc);
else
for (var i = decorators.length - 1; i >= 0; i--)
if (d = decorators[i])
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); };
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try {
step(generator.next(value));
}
catch (e) {
reject(e);
} }
function rejected(value) { try {
step(generator["throw"](value));
}
catch (e) {
reject(e);
} }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function () { if (t[0] & 1)
throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f)
throw new TypeError("Generator is already executing.");
while (_)
try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
return t;
if (y = 0, t)
op = [op[0] & 2, t.value];
switch (op[0]) {
case 0:
case 1:
t = op;
break;
case 4:
_.label++;
return { value: op[1], done: false };
case 5:
_.label++;
y = op[1];
op = [0];
continue;
case 7:
op = _.ops.pop();
_.trys.pop();
continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
_ = 0;
continue;
}
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
_.label = op[1];
break;
}
if (op[0] === 6 && _.label < t[1]) {
_.label = t[1];
t = op;
break;
}
if (t && _.label < t[2]) {
_.label = t[2];
_.ops.push(op);
break;
}
if (t[2])
_.ops.pop();
_.trys.pop();
continue;
}
op = body.call(thisArg, _);
}
catch (e) {
op = [6, e];
y = 0;
}
finally {
f = t = 0;
}
if (op[0] & 5)
throw op[1];
return { value: op[0] ? op[1] : void 0, done: true };
}
}
var __createBinding = Object.create ? (function (o, m, k, k2) {
if (k2 === undefined)
k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
}) : (function (o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
function __exportStar(m, exports) {
for (var p in m)
if (p !== "default" && !exports.hasOwnProperty(p))
__createBinding(exports, m, p);
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m)
return m.call(o);
if (o && typeof o.length === "number")
return {
next: function () {
if (o && i >= o.length)
o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m)
return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
ar.push(r.value);
}
catch (error) {
e = { error: error };
}
finally {
try {
if (r && !r.done && (m = i["return"]))
m.call(i);
}
finally {
if (e)
throw e.error;
}
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++)
s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
}
;
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n])
i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try {
step(g[n](v));
}
catch (e) {
settle(q[0][3], e);
} }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length)
resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) {
Object.defineProperty(cooked, "raw", { value: raw });
}
else {
cooked.raw = raw;
}
return cooked;
}
;
var __setModuleDefault = Object.create ? (function (o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function (o, v) {
o["default"] = v;
};
function __importStar(mod) {
if (mod && mod.__esModule)
return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (Object.hasOwnProperty.call(mod, k))
__createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
function __classPrivateFieldGet(receiver, privateMap) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
}
function __classPrivateFieldSet(receiver, privateMap, value) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to set private field on non-instance");
}
privateMap.set(receiver, value);
return value;
}
/**
* @license
* Copyright Google LLC 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
*/
function noNg() {
throw new Error('AngularJS v1.x is not loaded!');
}
var noNgElement = (function () { return noNg(); });
noNgElement.cleanData = noNg;
var angular = {
bootstrap: noNg,
module: noNg,
element: noNgElement,
injector: noNg,
version: undefined,
resumeBootstrap: noNg,
getTestability: noNg
};
try {
if (window.hasOwnProperty('angular')) {
angular = window.angular;
}
}
catch (_a) {
// ignore in CJS mode.
}
/**
* @deprecated Use `setAngularJSGlobal` instead.
*
* @publicApi
*/
function setAngularLib(ng) {
setAngularJSGlobal(ng);
}
/**
* @deprecated Use `getAngularJSGlobal` instead.
*
* @publicApi
*/
function getAngularLib() {
return getAngularJSGlobal();
}
/**
* Resets the AngularJS global.
*
* Used when AngularJS is loaded lazily, and not available on `window`.
*
* @publicApi
*/
function setAngularJSGlobal(ng) {
angular = ng;
}
/**
* Returns the current AngularJS global.
*
* @publicApi
*/
function getAngularJSGlobal() {
return angular;
}
var bootstrap = function (e, modules, config) { return angular.bootstrap(e, modules, config); };
// Do not declare as `module` to avoid webpack bug
// (see https://github.com/angular/angular/issues/30050).
var module_ = function (prefix, dependencies) { return angular.module(prefix, dependencies); };
var element = (function (e) { return angular.element(e); });
element.cleanData = function (nodes) { return angular.element.cleanData(nodes); };
var injector = function (modules, strictDi) { return angular.injector(modules, strictDi); };
var resumeBootstrap = function () { return angular.resumeBootstrap(); };
var getTestability = function (e) { return angular.getTestability(e); };
/**
* @license
* Copyright Google LLC 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
*/
var $COMPILE = '$compile';
var $CONTROLLER = '$controller';
var $DELEGATE = '$delegate';
var $EXCEPTION_HANDLER = '$exceptionHandler';
var $HTTP_BACKEND = '$httpBackend';
var $INJECTOR = '$injector';
var $INTERVAL = '$interval';
var $PARSE = '$parse';
var $PROVIDE = '$provide';
var $ROOT_ELEMENT = '$rootElement';
var $ROOT_SCOPE = '$rootScope';
var $SCOPE = '$scope';
var $TEMPLATE_CACHE = '$templateCache';
var $TEMPLATE_REQUEST = '$templateRequest';
var $$TESTABILITY = '$$testability';
var COMPILER_KEY = '$$angularCompiler';
var DOWNGRADED_MODULE_COUNT_KEY = '$$angularDowngradedModuleCount';
var GROUP_PROJECTABLE_NODES_KEY = '$$angularGroupProjectableNodes';
var INJECTOR_KEY = '$$angularInjector';
var LAZY_MODULE_REF = '$$angularLazyModuleRef';
var NG_ZONE_KEY = '$$angularNgZone';
var UPGRADE_APP_TYPE_KEY = '$$angularUpgradeAppType';
var REQUIRE_INJECTOR = '?^^' + INJECTOR_KEY;
var REQUIRE_NG_MODEL = '?ngModel';
var UPGRADE_MODULE_NAME = '$$UpgradeModule';
/**
* @license
* Copyright Google LLC 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
*/
/**
* A `PropertyBinding` represents a mapping between a property name
* and an attribute name. It is parsed from a string of the form
* `"prop: attr"`; or simply `"propAndAttr" where the property
* and attribute have the same identifier.
*/
var PropertyBinding = /** @class */ (function () {
function PropertyBinding(prop, attr) {
this.prop = prop;
this.attr = attr;
this.parseBinding();
}
PropertyBinding.prototype.parseBinding = function () {
this.bracketAttr = "[" + this.attr + "]";
this.parenAttr = "(" + this.attr + ")";
this.bracketParenAttr = "[(" + this.attr + ")]";
var capitalAttr = this.attr.charAt(0).toUpperCase() + this.attr.substr(1);
this.onAttr = "on" + capitalAttr;
this.bindAttr = "bind" + capitalAttr;
this.bindonAttr = "bindon" + capitalAttr;
};
return PropertyBinding;
}());
/**
* @license
* Copyright Google LLC 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
*/
var DIRECTIVE_PREFIX_REGEXP = /^(?:x|data)[:\-_]/i;
var DIRECTIVE_SPECIAL_CHARS_REGEXP = /[:\-_]+(.)/g;
function onError(e) {
// TODO: (misko): We seem to not have a stack trace here!
if (console.error) {
console.error(e, e.stack);
}
else {
// tslint:disable-next-line:no-console
console.log(e, e.stack);
}
throw e;
}
/**
* Clean the jqLite/jQuery data on the element and all its descendants.
* Equivalent to how jqLite/jQuery invoke `cleanData()` on an Element when removed:
* https://github.com/angular/angular.js/blob/2e72ea13fa98bebf6ed4b5e3c45eaf5f990ed16f/src/jqLite.js#L349-L355
* https://github.com/jquery/jquery/blob/6984d1747623dbc5e87fd6c261a5b6b1628c107c/src/manipulation.js#L182
*
* NOTE:
* `cleanData()` will also invoke the AngularJS `$destroy` DOM event on the element:
* https://github.com/angular/angular.js/blob/2e72ea13fa98bebf6ed4b5e3c45eaf5f990ed16f/src/Angular.js#L1932-L1945
*
* @param node The DOM node whose data needs to be cleaned.
*/
function cleanData(node) {
element.cleanData([node]);
if (isParentNode(node)) {
element.cleanData(node.querySelectorAll('*'));
}
}
function controllerKey(name) {
return '$' + name + 'Controller';
}
/**
* Destroy an AngularJS app given the app `$injector`.
*
* NOTE: Destroying an app is not officially supported by AngularJS, but try to do our best by
* destroying `$rootScope` and clean the jqLite/jQuery data on `$rootElement` and all
* descendants.
*
* @param $injector The `$injector` of the AngularJS app to destroy.
*/
function destroyApp($injector) {
var $rootElement = $injector.get($ROOT_ELEMENT);
var $rootScope = $injector.get($ROOT_SCOPE);
$rootScope.$destroy();
cleanData($rootElement[0]);
}
function directiveNormalize(name) {
return name.replace(DIRECTIVE_PREFIX_REGEXP, '')
.replace(DIRECTIVE_SPECIAL_CHARS_REGEXP, function (_, letter) { return letter.toUpperCase(); });
}
function getTypeName(type) {
// Return the name of the type or the first line of its stringified version.
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 /* None */;
}
function isFunction(value) {
return typeof value === 'function';
}
function isParentNode(node) {
return isFunction(node.querySelectorAll);
}
function validateInjectionKey($injector, downgradedModule, injectionKey, attemptedAction) {
var upgradeAppType = getUpgradeAppType($injector);
var downgradedModuleCount = getDowngradedModuleCount($injector);
// Check for common errors.
switch (upgradeAppType) {
case 1 /* Dynamic */:
case 2 /* Static */:
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 /* Lite */:
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?');
}
}
var Deferred = /** @class */ (function () {
function Deferred() {
var _this = this;
this.promise = new Promise(function (res, rej) {
_this.resolve = res;
_this.reject = rej;
});
}
return Deferred;
}());
/**
* @return Whether the passed-in component implements the subset of the
* `ControlValueAccessor` interface needed for AngularJS `ng-model`
* compatibility.
*/
function supportsNgModel(component) {
return typeof component.writeValue === 'function' &&
typeof component.registerOnChange === 'function';
}
/**
* Glue the AngularJS `NgModelController` (if it exists) to the component
* (if it implements the needed subset of the `ControlValueAccessor` interface).
*/
function hookupNgModel(ngModel, component) {
if (ngModel && supportsNgModel(component)) {
ngModel.$render = function () {
component.writeValue(ngModel.$viewValue);
};
component.registerOnChange(ngModel.$setViewValue.bind(ngModel));
if (typeof component.registerOnTouched === 'function') {
component.registerOnTouched(ngModel.$setTouched.bind(ngModel));
}
}
}
/**
* Test two values for strict equality, accounting for the fact that `NaN !== NaN`.
*/
function strictEquals(val1, val2) {
return val1 === val2 || (val1 !== val1 && val2 !== val2);
}
/**
* @license
* Copyright Google LLC 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
*/
var INITIAL_VALUE = {
__UNINITIALIZED__: true
};
var DowngradeComponentAdapter = /** @class */ (function () {
function DowngradeComponentAdapter(element, attrs, scope, ngModel, parentInjector, $compile, $parse, componentFactory, wrapCallback) {
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.implementsOnChanges = false;
this.inputChangeCount = 0;
this.inputChanges = {};
this.componentScope = scope.$new();
}
DowngradeComponentAdapter.prototype.compileContents = function () {
var _this = this;
var compiledProjectableNodes = [];
var projectableNodes = this.groupProjectableNodes();
var linkFns = projectableNodes.map(function (nodes) { return _this.$compile(nodes); });
this.element.empty();
linkFns.forEach(function (linkFn) {
linkFn(_this.scope, function (clone) {
compiledProjectableNodes.push(clone);
_this.element.append(clone);
});
});
return compiledProjectableNodes;
};
DowngradeComponentAdapter.prototype.createComponent = function (projectableNodes) {
var providers = [{ provide: $SCOPE, useValue: this.componentScope }];
var childInjector = core.Injector.create({ providers: providers, parent: this.parentInjector, name: 'DowngradeComponentAdapter' });
this.componentRef =
this.componentFactory.create(childInjector, projectableNodes, this.element[0]);
this.viewChangeDetector = this.componentRef.injector.get(core.ChangeDetectorRef);
this.changeDetector = this.componentRef.changeDetectorRef;
this.component = this.componentRef.instance;
// testability hook is commonly added during component bootstrap in
// packages/core/src/application_ref.bootstrap()
// in downgraded application, component creation will take place here as well as adding the
// testability hook.
var testability = this.componentRef.injector.get(core.Testability, null);
if (testability) {
this.componentRef.injector.get(core.TestabilityRegistry)
.registerApplication(this.componentRef.location.nativeElement, testability);
}
hookupNgModel(this.ngModel, this.component);
};
DowngradeComponentAdapter.prototype.setupInputs = function (manuallyAttachView, propagateDigest) {
var _this = this;
if (propagateDigest === void 0) { propagateDigest = true; }
var attrs = this.attrs;
var inputs = this.componentFactory.inputs || [];
var _loop_1 = function (i) {
var input = new PropertyBinding(inputs[i].propName, inputs[i].templateName);
var expr = null;
if (attrs.hasOwnProperty(input.attr)) {
var observeFn_1 = (function (prop) {
var prevValue = INITIAL_VALUE;
return function (currValue) {
// Initially, both `$observe()` and `$watch()` will call this function.
if (!strictEquals(prevValue, currValue)) {
if (prevValue === INITIAL_VALUE) {
prevValue = currValue;
}
_this.updateInput(prop, prevValue, currValue);
prevValue = currValue;
}
};
})(input.prop);
attrs.$observe(input.attr, observeFn_1);
// Use `$watch()` (in addition to `$observe()`) in order to initialize the input in time
// for `ngOnChanges()`. This is necessary if we are already in a `$digest`, which means that
// `ngOnChanges()` (which is called by a watcher) will run before the `$observe()` callback.
var unwatch_1 = this_1.componentScope.$watch(function () {
unwatch_1();
unwatch_1 = null;
observeFn_1(attrs[input.attr]);
});
}
else if (attrs.hasOwnProperty(input.bindAttr)) {
expr = attrs[input.bindAttr];
}
else if (attrs.hasOwnProperty(input.bracketAttr)) {
expr = attrs[input.bracketAttr];
}
else if (attrs.hasOwnProperty(input.bindonAttr)) {
expr = attrs[input.bindonAttr];
}
else if (attrs.hasOwnProperty(input.bracketParenAttr)) {
expr = attrs[input.bracketParenAttr];
}
if (expr != null) {
var watchFn = (function (prop) { return function (currValue, prevValue) { return _this.updateInput(prop, prevValue, currValue); }; })(input.prop);
this_1.componentScope.$watch(expr, watchFn);
}
};
var this_1 = this;
for (var i = 0; i < inputs.length; i++) {
_loop_1(i);
}
// Invoke `ngOnChanges()` and Change Detection (when necessary)
var detectChanges = function () { return _this.changeDetector.detectChanges(); };
var prototype = this.componentFactory.componentType.prototype;
this.implementsOnChanges = !!(prototype && prototype.ngOnChanges);
this.componentScope.$watch(function () { return _this.inputChangeCount; }, this.wrapCallback(function () {
// Invoke `ngOnChanges()`
if (_this.implementsOnChanges) {
var inputChanges = _this.inputChanges;
_this.inputChanges = {};
_this.component.ngOnChanges(inputChanges);
}
_this.viewChangeDetector.markForCheck();
// If opted out of propagating digests, invoke change detection when inputs change.
if (!propagateDigest) {
detectChanges();
}
}));
// If not opted out of propagating digests, invoke change detection on every digest
if (propagateDigest) {
this.componentScope.$watch(this.wrapCallback(detectChanges));
}
// If necessary, attach the view so that it will be dirty-checked.
// (Allow time for the initial input values to be set and `ngOnChanges()` to be called.)
if (manuallyAttachView || !propagateDigest) {
var unwatch_2 = this.componentScope.$watch(function () {
unwatch_2();
unwatch_2 = null;
var appRef = _this.parentInjector.get(core.ApplicationRef);
appRef.attachView(_this.componentRef.hostView);
});
}
};
DowngradeComponentAdapter.prototype.setupOutputs = function () {
var attrs = this.attrs;
var outputs = this.componentFactory.outputs || [];
for (var j = 0; j < outputs.length; j++) {
var output = new PropertyBinding(outputs[j].propName, outputs[j].templateName);
var bindonAttr = output.bindonAttr.substring(0, output.bindonAttr.length - 6);
var bracketParenAttr = "[(" + output.bracketParenAttr.substring(2, output.bracketParenAttr.length - 8) + ")]";
// order below is important - first update bindings then evaluate expressions
if (attrs.hasOwnProperty(bindonAttr)) {
this.subscribeToOutput(output, attrs[bindonAttr], true);
}
if (attrs.hasOwnProperty(bracketParenAttr)) {
this.subscribeToOutput(output, attrs[bracketParenAttr], true);
}
if (attrs.hasOwnProperty(output.onAttr)) {
this.subscribeToOutput(output, attrs[output.onAttr]);
}
if (attrs.hasOwnProperty(output.parenAttr)) {
this.subscribeToOutput(output, attrs[output.parenAttr]);
}
}
};
DowngradeComponentAdapter.prototype.subscribeToOutput = function (output, expr, isAssignment) {
var _this = this;
if (isAssignment === void 0) { isAssignment = false; }
var getter = this.$parse(expr);
var setter = getter.assign;
if (isAssignment && !setter) {
throw new Error("Expression '" + expr + "' is not assignable!");
}
var emitter = this.component[output.prop];
if (emitter) {
emitter.subscribe({
next: isAssignment ? function (v) { return setter(_this.scope, v); } :
function (v) { return getter(_this.scope, { '$event': v }); }
});
}
else {
throw new Error("Missing emitter '" + output.prop + "' on component '" + getTypeName(this.componentFactory.componentType) + "'!");
}
};
DowngradeComponentAdapter.prototype.registerCleanup = function () {
var _this = this;
var testabilityRegistry = this.componentRef.injector.get(core.TestabilityRegistry);
var destroyComponentRef = this.wrapCallback(function () { return _this.componentRef.destroy(); });
var destroyed = false;
this.element.on('$destroy', function () {
// The `$destroy` event may have been triggered by the `cleanData()` call in the
// `componentScope` `$destroy` handler below. In that case, we don't want to call
// `componentScope.$destroy()` again.
if (!destroyed)
_this.componentScope.$destroy();
});
this.componentScope.$on('$destroy', function () {
if (!destroyed) {
destroyed = true;
testabilityRegistry.unregisterApplication(_this.componentRef.location.nativeElement);
// The `componentScope` might be getting destroyed, because an ancestor element is being
// removed/destroyed. If that is the case, jqLite/jQuery would normally invoke `cleanData()`
// on the removed element and all descendants.
// https://github.com/angular/angular.js/blob/2e72ea13fa98bebf6ed4b5e3c45eaf5f990ed16f/src/jqLite.js#L349-L355
// https://github.com/jquery/jquery/blob/6984d1747623dbc5e87fd6c261a5b6b1628c107c/src/manipulation.js#L182
//
// Here, however, `destroyComponentRef()` may under some circumstances remove the element
// from the DOM and therefore it will no longer be a descendant of the removed element when
// `cleanData()` is called. This would result in a memory leak, because the element's data
// and event handlers (and all objects directly or indirectly referenced by them) would be
// retained.
//
// To ensure the element is always properly cleaned up, we manually call `cleanData()` on
// this element and its descendants before destroying the `ComponentRef`.
cleanData(_this.element[0]);
destroyComponentRef();
}
});
};
DowngradeComponentAdapter.prototype.getInjector = function () {
return this.componentRef.injector;
};
DowngradeComponentAdapter.prototype.updateInput = function (prop, prevValue, currValue) {
if (this.implementsOnChanges) {
this.inputChanges[prop] = new core.SimpleChange(prevValue, currValue, prevValue === currValue);
}
this.inputChangeCount++;
this.component[prop] = currValue;
};
DowngradeComponentAdapter.prototype.groupProjectableNodes = function () {
var ngContentSelectors = this.componentFactory.ngContentSelectors;
return groupNodesBySelector(ngContentSelectors, this.element.contents());
};
return DowngradeComponentAdapter;
}());
/**
* Group a set of DOM nodes into `ngContent` groups, based on the given content selectors.
*/
function groupNodesBySelector(ngContentSelectors, nodes) {
var projectableNodes = [];
for (var i = 0, ii = ngContentSelectors.length; i < ii; ++i) {
projectableNodes[i] = [];
}
for (var j = 0, jj = nodes.length; j < jj; ++j) {
var node = nodes[j];
var ngContentIndex = findMatchingNgContentIndex(node, ngContentSelectors);
if (ngContentIndex != null) {
projectableNodes[ngContentIndex].push(node);
}
}
return projectableNodes;
}
function findMatchingNgContentIndex(element, ngContentSelectors) {
var ngContentIndices = [];
var wildcardNgContentIndex = -1;
for (var i = 0; i < ngContentSelectors.length; i++) {
var 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;
}
var _matches;
function matchesSelector(el, selector) {
if (!_matches) {
var elProto = Element.prototype;
_matches = elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector ||
elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector;
}
return el.nodeType === Node.ELEMENT_NODE ? _matches.call(el, selector) : false;
}
/**
* @license
* Copyright Google LLC 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
*/
function isThenable(obj) {
return !!obj && isFunction(obj.then);
}
/**
* Synchronous, promise-like object.
*/
var SyncPromise = /** @class */ (function () {
function SyncPromise() {
this.resolved = false;
this.callbacks = [];
}
SyncPromise.all = function (valuesOrPromises) {
var aggrPromise = new SyncPromise();
var resolvedCount = 0;
var results = [];
var resolve = function (idx, value) {
results[idx] = value;
if (++resolvedCount === valuesOrPromises.length)
aggrPromise.resolve(results);
};
valuesOrPromises.forEach(function (p, idx) {
if (isThenable(p)) {
p.then(function (v) { return resolve(idx, v); });
}
else {
resolve(idx, p);
}
});
return aggrPromise;
};
SyncPromise.prototype.resolve = function (value) {
// Do nothing, if already resolved.
if (this.resolved)
return;
this.value = value;
this.resolved = true;
// Run the queued callbacks.
this.callbacks.forEach(function (callback) { return callback(value); });
this.callbacks.length = 0;
};
SyncPromise.prototype.then = function (callback) {
if (this.resolved) {
callback(this.value);
}
else {
this.callbacks.push(callback);
}
};
return SyncPromise;
}());
/**
* @description
*
* A helper function that allows an Angular component to be used from AngularJS.
*
* *Part of the [upgrade/static](api?query=upgrade%2Fstatic)
* library for hybrid upgrade apps that support AOT compilation*
*
* This helper function returns a factory function to be used for registering
* an AngularJS wrapper directive for "downgrading" an Angular component.
*
* @usageNotes
* ### Examples
*
* Let's assume that you have an Angular component called `ng2Heroes` that needs
* to be made available in AngularJS templates.
*
* {@example upgrade/static/ts/full/module.ts region="ng2-heroes"}
*
* We must create an AngularJS [directive](https://docs.angularjs.org/guide/directive)
* that will make this Angular component available inside AngularJS templates.
* The `downgradeComponent()` function returns a factory function that we
* can use to define the AngularJS directive that wraps the "downgraded" component.
*
* {@example upgrade/static/ts/full/module.ts region="ng2-heroes-wrapper"}
*
* For more details and examples on downgrading Angular components to AngularJS components please
* visit the [Upgrade guide](guide/upgrade#using-angular-components-from-angularjs-code).
*
* @param info contains information about the Component that is being downgraded:
*
* - `component: Type<any>`: The type of the Component that will be downgraded
* - `downgradedModule?: string`: The name of the downgraded module (if any) that the component
* "belongs to", as returned by a call to `downgradeModule()`. It is the module, whose
* corresponding Angular module will be bootstrapped, when the component needs to be instantiated.
* <br />
* (This option is only necessary when using `downgradeModule()` to downgrade more than one
* Angular module.)
* - `propagateDigest?: boolean`: Whether to perform {@link ChangeDetectorRef#detectChanges
* change detection} on the component on every
* [$digest](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest). If set to `false`,
* change detection will still be performed when any of the component's inputs changes.
* (Default: true)
*
* @returns a factory function that can be used to register the component in an
* AngularJS module.
*
* @publicApi
*/
function downgradeComponent(info) {
var directiveFactory = function ($compile, $injector, $parse) {
// When using `downgradeModule()`, we need to handle certain things specially. For example:
// - We always need to attach the component view to the `ApplicationRef` for it to be
// dirty-checked.
// - We need to ensure callbacks to Angular APIs (e.g. change detection) are run inside the
// Angular zone.
// NOTE: This is not needed, when using `UpgradeModule`, because `$digest()` will be run
// inside the Angular zone (except if explicitly escaped, in which case we shouldn't
// force it back in).
var isNgUpgradeLite = getUpgradeAppType($injector) === 3 /* Lite */;
var wrapCallback = !isNgUpgradeLite ? function (cb) { return cb; } : function (cb) { return function () { return core.NgZone.isInAngularZone() ? cb() : ngZone.run(cb); }; };
var ngZone;
// When downgrading multiple modules, special handling is needed wrt injectors.
var hasMultipleDowngradedModules = isNgUpgradeLite && (getDowngradedModuleCount($injector) > 1);
return {
restrict: 'E',
terminal: true,
require: [REQUIRE_INJECTOR, REQUIRE_NG_MODEL],
link: function (scope, element, attrs, required) {
// We might have to compile the contents asynchronously, because this might have been
// triggered by `UpgradeNg1ComponentAdapterBuilder`, before the Angular templates have
// been compiled.
var ngModel = required[1];
var parentInjector = required[0];
var moduleInjector = undefined;
var ranAsync = false;
if (!parentInjector || hasMultipleDowngradedModules) {
var downgradedModule = info.downgradedModule || '';
var lazyModuleRefKey = "" + LAZY_MODULE_REF + downgradedModule;
var attemptedAction = "instantiating component '" + getTypeName(info.component) + "'";
validateInjectionKey($injector, downgradedModule, lazyModuleRefKey, attemptedAction);
var lazyModuleRef = $injector.get(lazyModuleRefKey);
moduleInjector = lazyModuleRef.injector || lazyModuleRef.promise;
}
// Notes:
//
// There are two injectors: `finalModuleInjector` and `finalParentInjector` (they might be
// the same instance, but that is irrelevant):
// - `finalModuleInjector` is used to retrieve `ComponentFactoryResolver`, thus it must be
// on the same tree as the `NgModule` that declares this downgraded component.
// - `finalParentInjector` is used for all other injection purposes.
// (Note that Angular knows to only traverse the component-tree part of that injector,
// when looking for an injectable and then switch to the module injector.)
//
// There are basically three cases:
// - If there is no parent component (thus no `parentInjector`), we bootstrap the downgraded
// `NgModule` and use its injector as both `finalModuleInjector` and
// `finalParentInjector`.
// - If there is a parent component (and thus a `parentInjector`) and we are sure that it
// belongs to the same `NgModule` as this downgraded component (e.g. because there is only
// one downgraded module, we use that `parentInjector` as both `finalModuleInjector` and
// `finalParentInjector`.
// - If there is a parent component, but it may belong to a different `NgModule`, then we
// use the `parentInjector` as `finalParentInjector` and this downgraded component's
// declaring `NgModule`'s injector as `finalModuleInjector`.
// Note 1: If the `NgModule` is already bootstrapped, we just get its injector (we don't
// bootstrap again).
// Note 2: It is possible that (while there are multiple downgraded modules) this
// downgraded component and its parent component both belong to the same NgModule.
// In that case, we could have used the `parentInjector` as both
// `finalModuleInjector` and `finalParentInjector`, but (for simplicity) we are
// treating this case as if they belong to different `NgModule`s. That doesn't
// really affect anything, since `parentInjector` has `moduleInjector` as ancestor
// and trying to resolve `ComponentFactoryResolver` from either one will return
// the same instance.
// If there is a parent component, use its injector as parent injector