UNPKG

82.6 kBJavaScriptView Raw
1/**
2 * @license Angular v10.0.5
3 * (c) 2010-2020 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { Injector, ChangeDetectorRef, Testability, TestabilityRegistry, ApplicationRef, SimpleChange, NgZone, ComponentFactoryResolver, Version, ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, EventEmitter, Directive, ElementRef, isDevMode, NgModule } from '@angular/core';
8import { platformBrowser } from '@angular/platform-browser';
9
10/**
11 * @license
12 * Copyright Google LLC All Rights Reserved.
13 *
14 * Use of this source code is governed by an MIT-style license that can be
15 * found in the LICENSE file at https://angular.io/license
16 */
17function noNg() {
18 throw new Error('AngularJS v1.x is not loaded!');
19}
20const noNgElement = (() => noNg());
21noNgElement.cleanData = noNg;
22let angular = {
23 bootstrap: noNg,
24 module: noNg,
25 element: noNgElement,
26 injector: noNg,
27 version: undefined,
28 resumeBootstrap: noNg,
29 getTestability: noNg
30};
31try {
32 if (window.hasOwnProperty('angular')) {
33 angular = window.angular;
34 }
35}
36catch (_a) {
37 // ignore in CJS mode.
38}
39/**
40 * @deprecated Use `setAngularJSGlobal` instead.
41 *
42 * @publicApi
43 */
44function setAngularLib(ng) {
45 setAngularJSGlobal(ng);
46}
47/**
48 * @deprecated Use `getAngularJSGlobal` instead.
49 *
50 * @publicApi
51 */
52function getAngularLib() {
53 return getAngularJSGlobal();
54}
55/**
56 * Resets the AngularJS global.
57 *
58 * Used when AngularJS is loaded lazily, and not available on `window`.
59 *
60 * @publicApi
61 */
62function setAngularJSGlobal(ng) {
63 angular = ng;
64}
65/**
66 * Returns the current AngularJS global.
67 *
68 * @publicApi
69 */
70function getAngularJSGlobal() {
71 return angular;
72}
73const bootstrap = (e, modules, config) => angular.bootstrap(e, modules, config);
74// Do not declare as `module` to avoid webpack bug
75// (see https://github.com/angular/angular/issues/30050).
76const module_ = (prefix, dependencies) => angular.module(prefix, dependencies);
77const element = (e => angular.element(e));
78element.cleanData = nodes => angular.element.cleanData(nodes);
79const injector = (modules, strictDi) => angular.injector(modules, strictDi);
80const resumeBootstrap = () => angular.resumeBootstrap();
81const getTestability = e => angular.getTestability(e);
82
83/**
84 * @license
85 * Copyright Google LLC All Rights Reserved.
86 *
87 * Use of this source code is governed by an MIT-style license that can be
88 * found in the LICENSE file at https://angular.io/license
89 */
90const $COMPILE = '$compile';
91const $CONTROLLER = '$controller';
92const $DELEGATE = '$delegate';
93const $EXCEPTION_HANDLER = '$exceptionHandler';
94const $HTTP_BACKEND = '$httpBackend';
95const $INJECTOR = '$injector';
96const $INTERVAL = '$interval';
97const $PARSE = '$parse';
98const $PROVIDE = '$provide';
99const $ROOT_SCOPE = '$rootScope';
100const $SCOPE = '$scope';
101const $TEMPLATE_CACHE = '$templateCache';
102const $TEMPLATE_REQUEST = '$templateRequest';
103const $$TESTABILITY = '$$testability';
104const COMPILER_KEY = '$$angularCompiler';
105const DOWNGRADED_MODULE_COUNT_KEY = '$$angularDowngradedModuleCount';
106const GROUP_PROJECTABLE_NODES_KEY = '$$angularGroupProjectableNodes';
107const INJECTOR_KEY = '$$angularInjector';
108const LAZY_MODULE_REF = '$$angularLazyModuleRef';
109const NG_ZONE_KEY = '$$angularNgZone';
110const UPGRADE_APP_TYPE_KEY = '$$angularUpgradeAppType';
111const REQUIRE_INJECTOR = '?^^' + INJECTOR_KEY;
112const REQUIRE_NG_MODEL = '?ngModel';
113const UPGRADE_MODULE_NAME = '$$UpgradeModule';
114
115/**
116 * @license
117 * Copyright Google LLC All Rights Reserved.
118 *
119 * Use of this source code is governed by an MIT-style license that can be
120 * found in the LICENSE file at https://angular.io/license
121 */
122/**
123 * A `PropertyBinding` represents a mapping between a property name
124 * and an attribute name. It is parsed from a string of the form
125 * `"prop: attr"`; or simply `"propAndAttr" where the property
126 * and attribute have the same identifier.
127 */
128class PropertyBinding {
129 constructor(prop, attr) {
130 this.prop = prop;
131 this.attr = attr;
132 this.parseBinding();
133 }
134 parseBinding() {
135 this.bracketAttr = `[${this.attr}]`;
136 this.parenAttr = `(${this.attr})`;
137 this.bracketParenAttr = `[(${this.attr})]`;
138 const capitalAttr = this.attr.charAt(0).toUpperCase() + this.attr.substr(1);
139 this.onAttr = `on${capitalAttr}`;
140 this.bindAttr = `bind${capitalAttr}`;
141 this.bindonAttr = `bindon${capitalAttr}`;
142 }
143}
144
145/**
146 * @license
147 * Copyright Google LLC All Rights Reserved.
148 *
149 * Use of this source code is governed by an MIT-style license that can be
150 * found in the LICENSE file at https://angular.io/license
151 */
152const DIRECTIVE_PREFIX_REGEXP = /^(?:x|data)[:\-_]/i;
153const DIRECTIVE_SPECIAL_CHARS_REGEXP = /[:\-_]+(.)/g;
154function onError(e) {
155 // TODO: (misko): We seem to not have a stack trace here!
156 if (console.error) {
157 console.error(e, e.stack);
158 }
159 else {
160 // tslint:disable-next-line:no-console
161 console.log(e, e.stack);
162 }
163 throw e;
164}
165function controllerKey(name) {
166 return '$' + name + 'Controller';
167}
168function directiveNormalize(name) {
169 return name.replace(DIRECTIVE_PREFIX_REGEXP, '')
170 .replace(DIRECTIVE_SPECIAL_CHARS_REGEXP, (_, letter) => letter.toUpperCase());
171}
172function getTypeName(type) {
173 // Return the name of the type or the first line of its stringified version.
174 return type.overriddenName || type.name || type.toString().split('\n')[0];
175}
176function getDowngradedModuleCount($injector) {
177 return $injector.has(DOWNGRADED_MODULE_COUNT_KEY) ? $injector.get(DOWNGRADED_MODULE_COUNT_KEY) :
178 0;
179}
180function getUpgradeAppType($injector) {
181 return $injector.has(UPGRADE_APP_TYPE_KEY) ? $injector.get(UPGRADE_APP_TYPE_KEY) :
182 0 /* None */;
183}
184function isFunction(value) {
185 return typeof value === 'function';
186}
187function validateInjectionKey($injector, downgradedModule, injectionKey, attemptedAction) {
188 const upgradeAppType = getUpgradeAppType($injector);
189 const downgradedModuleCount = getDowngradedModuleCount($injector);
190 // Check for common errors.
191 switch (upgradeAppType) {
192 case 1 /* Dynamic */:
193 case 2 /* Static */:
194 if (downgradedModule) {
195 throw new Error(`Error while ${attemptedAction}: 'downgradedModule' unexpectedly specified.\n` +
196 'You should not specify a value for \'downgradedModule\', unless you are downgrading ' +
197 'more than one Angular module (via \'downgradeModule()\').');
198 }
199 break;
200 case 3 /* Lite */:
201 if (!downgradedModule && (downgradedModuleCount >= 2)) {
202 throw new Error(`Error while ${attemptedAction}: 'downgradedModule' not specified.\n` +
203 'This application contains more than one downgraded Angular module, thus you need to ' +
204 'always specify \'downgradedModule\' when downgrading components and injectables.');
205 }
206 if (!$injector.has(injectionKey)) {
207 throw new Error(`Error while ${attemptedAction}: Unable to find the specified downgraded module.\n` +
208 'Did you forget to downgrade an Angular module or include it in the AngularJS ' +
209 'application?');
210 }
211 break;
212 default:
213 throw new Error(`Error while ${attemptedAction}: Not a valid '@angular/upgrade' application.\n` +
214 'Did you forget to downgrade an Angular module or include it in the AngularJS ' +
215 'application?');
216 }
217}
218class Deferred {
219 constructor() {
220 this.promise = new Promise((res, rej) => {
221 this.resolve = res;
222 this.reject = rej;
223 });
224 }
225}
226/**
227 * @return Whether the passed-in component implements the subset of the
228 * `ControlValueAccessor` interface needed for AngularJS `ng-model`
229 * compatibility.
230 */
231function supportsNgModel(component) {
232 return typeof component.writeValue === 'function' &&
233 typeof component.registerOnChange === 'function';
234}
235/**
236 * Glue the AngularJS `NgModelController` (if it exists) to the component
237 * (if it implements the needed subset of the `ControlValueAccessor` interface).
238 */
239function hookupNgModel(ngModel, component) {
240 if (ngModel && supportsNgModel(component)) {
241 ngModel.$render = () => {
242 component.writeValue(ngModel.$viewValue);
243 };
244 component.registerOnChange(ngModel.$setViewValue.bind(ngModel));
245 if (typeof component.registerOnTouched === 'function') {
246 component.registerOnTouched(ngModel.$setTouched.bind(ngModel));
247 }
248 }
249}
250/**
251 * Test two values for strict equality, accounting for the fact that `NaN !== NaN`.
252 */
253function strictEquals(val1, val2) {
254 return val1 === val2 || (val1 !== val1 && val2 !== val2);
255}
256
257/**
258 * @license
259 * Copyright Google LLC All Rights Reserved.
260 *
261 * Use of this source code is governed by an MIT-style license that can be
262 * found in the LICENSE file at https://angular.io/license
263 */
264const INITIAL_VALUE = {
265 __UNINITIALIZED__: true
266};
267class DowngradeComponentAdapter {
268 constructor(element, attrs, scope, ngModel, parentInjector, $injector, $compile, $parse, componentFactory, wrapCallback) {
269 this.element = element;
270 this.attrs = attrs;
271 this.scope = scope;
272 this.ngModel = ngModel;
273 this.parentInjector = parentInjector;
274 this.$injector = $injector;
275 this.$compile = $compile;
276 this.$parse = $parse;
277 this.componentFactory = componentFactory;
278 this.wrapCallback = wrapCallback;
279 this.implementsOnChanges = false;
280 this.inputChangeCount = 0;
281 this.inputChanges = {};
282 this.componentScope = scope.$new();
283 }
284 compileContents() {
285 const compiledProjectableNodes = [];
286 const projectableNodes = this.groupProjectableNodes();
287 const linkFns = projectableNodes.map(nodes => this.$compile(nodes));
288 this.element.empty();
289 linkFns.forEach(linkFn => {
290 linkFn(this.scope, (clone) => {
291 compiledProjectableNodes.push(clone);
292 this.element.append(clone);
293 });
294 });
295 return compiledProjectableNodes;
296 }
297 createComponent(projectableNodes) {
298 const providers = [{ provide: $SCOPE, useValue: this.componentScope }];
299 const childInjector = Injector.create({ providers: providers, parent: this.parentInjector, name: 'DowngradeComponentAdapter' });
300 this.componentRef =
301 this.componentFactory.create(childInjector, projectableNodes, this.element[0]);
302 this.viewChangeDetector = this.componentRef.injector.get(ChangeDetectorRef);
303 this.changeDetector = this.componentRef.changeDetectorRef;
304 this.component = this.componentRef.instance;
305 // testability hook is commonly added during component bootstrap in
306 // packages/core/src/application_ref.bootstrap()
307 // in downgraded application, component creation will take place here as well as adding the
308 // testability hook.
309 const testability = this.componentRef.injector.get(Testability, null);
310 if (testability) {
311 this.componentRef.injector.get(TestabilityRegistry)
312 .registerApplication(this.componentRef.location.nativeElement, testability);
313 }
314 hookupNgModel(this.ngModel, this.component);
315 }
316 setupInputs(manuallyAttachView, propagateDigest = true) {
317 const attrs = this.attrs;
318 const inputs = this.componentFactory.inputs || [];
319 for (let i = 0; i < inputs.length; i++) {
320 const input = new PropertyBinding(inputs[i].propName, inputs[i].templateName);
321 let expr = null;
322 if (attrs.hasOwnProperty(input.attr)) {
323 const observeFn = (prop => {
324 let prevValue = INITIAL_VALUE;
325 return (currValue) => {
326 // Initially, both `$observe()` and `$watch()` will call this function.
327 if (!strictEquals(prevValue, currValue)) {
328 if (prevValue === INITIAL_VALUE) {
329 prevValue = currValue;
330 }
331 this.updateInput(prop, prevValue, currValue);
332 prevValue = currValue;
333 }
334 };
335 })(input.prop);
336 attrs.$observe(input.attr, observeFn);
337 // Use `$watch()` (in addition to `$observe()`) in order to initialize the input in time
338 // for `ngOnChanges()`. This is necessary if we are already in a `$digest`, which means that
339 // `ngOnChanges()` (which is called by a watcher) will run before the `$observe()` callback.
340 let unwatch = this.componentScope.$watch(() => {
341 unwatch();
342 unwatch = null;
343 observeFn(attrs[input.attr]);
344 });
345 }
346 else if (attrs.hasOwnProperty(input.bindAttr)) {
347 expr = attrs[input.bindAttr];
348 }
349 else if (attrs.hasOwnProperty(input.bracketAttr)) {
350 expr = attrs[input.bracketAttr];
351 }
352 else if (attrs.hasOwnProperty(input.bindonAttr)) {
353 expr = attrs[input.bindonAttr];
354 }
355 else if (attrs.hasOwnProperty(input.bracketParenAttr)) {
356 expr = attrs[input.bracketParenAttr];
357 }
358 if (expr != null) {
359 const watchFn = (prop => (currValue, prevValue) => this.updateInput(prop, prevValue, currValue))(input.prop);
360 this.componentScope.$watch(expr, watchFn);
361 }
362 }
363 // Invoke `ngOnChanges()` and Change Detection (when necessary)
364 const detectChanges = () => this.changeDetector.detectChanges();
365 const prototype = this.componentFactory.componentType.prototype;
366 this.implementsOnChanges = !!(prototype && prototype.ngOnChanges);
367 this.componentScope.$watch(() => this.inputChangeCount, this.wrapCallback(() => {
368 // Invoke `ngOnChanges()`
369 if (this.implementsOnChanges) {
370 const inputChanges = this.inputChanges;
371 this.inputChanges = {};
372 this.component.ngOnChanges(inputChanges);
373 }
374 this.viewChangeDetector.markForCheck();
375 // If opted out of propagating digests, invoke change detection when inputs change.
376 if (!propagateDigest) {
377 detectChanges();
378 }
379 }));
380 // If not opted out of propagating digests, invoke change detection on every digest
381 if (propagateDigest) {
382 this.componentScope.$watch(this.wrapCallback(detectChanges));
383 }
384 // If necessary, attach the view so that it will be dirty-checked.
385 // (Allow time for the initial input values to be set and `ngOnChanges()` to be called.)
386 if (manuallyAttachView || !propagateDigest) {
387 let unwatch = this.componentScope.$watch(() => {
388 unwatch();
389 unwatch = null;
390 const appRef = this.parentInjector.get(ApplicationRef);
391 appRef.attachView(this.componentRef.hostView);
392 });
393 }
394 }
395 setupOutputs() {
396 const attrs = this.attrs;
397 const outputs = this.componentFactory.outputs || [];
398 for (let j = 0; j < outputs.length; j++) {
399 const output = new PropertyBinding(outputs[j].propName, outputs[j].templateName);
400 const bindonAttr = output.bindonAttr.substring(0, output.bindonAttr.length - 6);
401 const bracketParenAttr = `[(${output.bracketParenAttr.substring(2, output.bracketParenAttr.length - 8)})]`;
402 // order below is important - first update bindings then evaluate expressions
403 if (attrs.hasOwnProperty(bindonAttr)) {
404 this.subscribeToOutput(output, attrs[bindonAttr], true);
405 }
406 if (attrs.hasOwnProperty(bracketParenAttr)) {
407 this.subscribeToOutput(output, attrs[bracketParenAttr], true);
408 }
409 if (attrs.hasOwnProperty(output.onAttr)) {
410 this.subscribeToOutput(output, attrs[output.onAttr]);
411 }
412 if (attrs.hasOwnProperty(output.parenAttr)) {
413 this.subscribeToOutput(output, attrs[output.parenAttr]);
414 }
415 }
416 }
417 subscribeToOutput(output, expr, isAssignment = false) {
418 const getter = this.$parse(expr);
419 const setter = getter.assign;
420 if (isAssignment && !setter) {
421 throw new Error(`Expression '${expr}' is not assignable!`);
422 }
423 const emitter = this.component[output.prop];
424 if (emitter) {
425 emitter.subscribe({
426 next: isAssignment ? (v) => setter(this.scope, v) :
427 (v) => getter(this.scope, { '$event': v })
428 });
429 }
430 else {
431 throw new Error(`Missing emitter '${output.prop}' on component '${getTypeName(this.componentFactory.componentType)}'!`);
432 }
433 }
434 registerCleanup() {
435 const testabilityRegistry = this.componentRef.injector.get(TestabilityRegistry);
436 const destroyComponentRef = this.wrapCallback(() => this.componentRef.destroy());
437 let destroyed = false;
438 this.element.on('$destroy', () => this.componentScope.$destroy());
439 this.componentScope.$on('$destroy', () => {
440 if (!destroyed) {
441 destroyed = true;
442 testabilityRegistry.unregisterApplication(this.componentRef.location.nativeElement);
443 destroyComponentRef();
444 }
445 });
446 }
447 getInjector() {
448 return this.componentRef.injector;
449 }
450 updateInput(prop, prevValue, currValue) {
451 if (this.implementsOnChanges) {
452 this.inputChanges[prop] = new SimpleChange(prevValue, currValue, prevValue === currValue);
453 }
454 this.inputChangeCount++;
455 this.component[prop] = currValue;
456 }
457 groupProjectableNodes() {
458 let ngContentSelectors = this.componentFactory.ngContentSelectors;
459 return groupNodesBySelector(ngContentSelectors, this.element.contents());
460 }
461}
462/**
463 * Group a set of DOM nodes into `ngContent` groups, based on the given content selectors.
464 */
465function groupNodesBySelector(ngContentSelectors, nodes) {
466 const projectableNodes = [];
467 let wildcardNgContentIndex;
468 for (let i = 0, ii = ngContentSelectors.length; i < ii; ++i) {
469 projectableNodes[i] = [];
470 }
471 for (let j = 0, jj = nodes.length; j < jj; ++j) {
472 const node = nodes[j];
473 const ngContentIndex = findMatchingNgContentIndex(node, ngContentSelectors);
474 if (ngContentIndex != null) {
475 projectableNodes[ngContentIndex].push(node);
476 }
477 }
478 return projectableNodes;
479}
480function findMatchingNgContentIndex(element, ngContentSelectors) {
481 const ngContentIndices = [];
482 let wildcardNgContentIndex = -1;
483 for (let i = 0; i < ngContentSelectors.length; i++) {
484 const selector = ngContentSelectors[i];
485 if (selector === '*') {
486 wildcardNgContentIndex = i;
487 }
488 else {
489 if (matchesSelector(element, selector)) {
490 ngContentIndices.push(i);
491 }
492 }
493 }
494 ngContentIndices.sort();
495 if (wildcardNgContentIndex !== -1) {
496 ngContentIndices.push(wildcardNgContentIndex);
497 }
498 return ngContentIndices.length ? ngContentIndices[0] : null;
499}
500let _matches;
501function matchesSelector(el, selector) {
502 if (!_matches) {
503 const elProto = Element.prototype;
504 _matches = elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector ||
505 elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector;
506 }
507 return el.nodeType === Node.ELEMENT_NODE ? _matches.call(el, selector) : false;
508}
509
510/**
511 * @license
512 * Copyright Google LLC All Rights Reserved.
513 *
514 * Use of this source code is governed by an MIT-style license that can be
515 * found in the LICENSE file at https://angular.io/license
516 */
517function isThenable(obj) {
518 return !!obj && isFunction(obj.then);
519}
520/**
521 * Synchronous, promise-like object.
522 */
523class SyncPromise {
524 constructor() {
525 this.resolved = false;
526 this.callbacks = [];
527 }
528 static all(valuesOrPromises) {
529 const aggrPromise = new SyncPromise();
530 let resolvedCount = 0;
531 const results = [];
532 const resolve = (idx, value) => {
533 results[idx] = value;
534 if (++resolvedCount === valuesOrPromises.length)
535 aggrPromise.resolve(results);
536 };
537 valuesOrPromises.forEach((p, idx) => {
538 if (isThenable(p)) {
539 p.then(v => resolve(idx, v));
540 }
541 else {
542 resolve(idx, p);
543 }
544 });
545 return aggrPromise;
546 }
547 resolve(value) {
548 // Do nothing, if already resolved.
549 if (this.resolved)
550 return;
551 this.value = value;
552 this.resolved = true;
553 // Run the queued callbacks.
554 this.callbacks.forEach(callback => callback(value));
555 this.callbacks.length = 0;
556 }
557 then(callback) {
558 if (this.resolved) {
559 callback(this.value);
560 }
561 else {
562 this.callbacks.push(callback);
563 }
564 }
565}
566
567/**
568 * @license
569 * Copyright Google LLC All Rights Reserved.
570 *
571 * Use of this source code is governed by an MIT-style license that can be
572 * found in the LICENSE file at https://angular.io/license
573 */
574/**
575 * @description
576 *
577 * A helper function that allows an Angular component to be used from AngularJS.
578 *
579 * *Part of the [upgrade/static](api?query=upgrade%2Fstatic)
580 * library for hybrid upgrade apps that support AOT compilation*
581 *
582 * This helper function returns a factory function to be used for registering
583 * an AngularJS wrapper directive for "downgrading" an Angular component.
584 *
585 * @usageNotes
586 * ### Examples
587 *
588 * Let's assume that you have an Angular component called `ng2Heroes` that needs
589 * to be made available in AngularJS templates.
590 *
591 * {@example upgrade/static/ts/full/module.ts region="ng2-heroes"}
592 *
593 * We must create an AngularJS [directive](https://docs.angularjs.org/guide/directive)
594 * that will make this Angular component available inside AngularJS templates.
595 * The `downgradeComponent()` function returns a factory function that we
596 * can use to define the AngularJS directive that wraps the "downgraded" component.
597 *
598 * {@example upgrade/static/ts/full/module.ts region="ng2-heroes-wrapper"}
599 *
600 * For more details and examples on downgrading Angular components to AngularJS components please
601 * visit the [Upgrade guide](guide/upgrade#using-angular-components-from-angularjs-code).
602 *
603 * @param info contains information about the Component that is being downgraded:
604 *
605 * - `component: Type<any>`: The type of the Component that will be downgraded
606 * - `downgradedModule?: string`: The name of the downgraded module (if any) that the component
607 * "belongs to", as returned by a call to `downgradeModule()`. It is the module, whose
608 * corresponding Angular module will be bootstrapped, when the component needs to be instantiated.
609 * <br />
610 * (This option is only necessary when using `downgradeModule()` to downgrade more than one
611 * Angular module.)
612 * - `propagateDigest?: boolean`: Whether to perform {@link ChangeDetectorRef#detectChanges
613 * change detection} on the component on every
614 * [$digest](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest). If set to `false`,
615 * change detection will still be performed when any of the component's inputs changes.
616 * (Default: true)
617 *
618 * @returns a factory function that can be used to register the component in an
619 * AngularJS module.
620 *
621 * @publicApi
622 */
623function downgradeComponent(info) {
624 const directiveFactory = function ($compile, $injector, $parse) {
625 // When using `downgradeModule()`, we need to handle certain things specially. For example:
626 // - We always need to attach the component view to the `ApplicationRef` for it to be
627 // dirty-checked.
628 // - We need to ensure callbacks to Angular APIs (e.g. change detection) are run inside the
629 // Angular zone.
630 // NOTE: This is not needed, when using `UpgradeModule`, because `$digest()` will be run
631 // inside the Angular zone (except if explicitly escaped, in which case we shouldn't
632 // force it back in).
633 const isNgUpgradeLite = getUpgradeAppType($injector) === 3 /* Lite */;
634 const wrapCallback = !isNgUpgradeLite ? cb => cb : cb => () => NgZone.isInAngularZone() ? cb() : ngZone.run(cb);
635 let ngZone;
636 // When downgrading multiple modules, special handling is needed wrt injectors.
637 const hasMultipleDowngradedModules = isNgUpgradeLite && (getDowngradedModuleCount($injector) > 1);
638 return {
639 restrict: 'E',
640 terminal: true,
641 require: [REQUIRE_INJECTOR, REQUIRE_NG_MODEL],
642 link: (scope, element, attrs, required) => {
643 // We might have to compile the contents asynchronously, because this might have been
644 // triggered by `UpgradeNg1ComponentAdapterBuilder`, before the Angular templates have
645 // been compiled.
646 const ngModel = required[1];
647 const parentInjector = required[0];
648 let moduleInjector = undefined;
649 let ranAsync = false;
650 if (!parentInjector || hasMultipleDowngradedModules) {
651 const downgradedModule = info.downgradedModule || '';
652 const lazyModuleRefKey = `${LAZY_MODULE_REF}${downgradedModule}`;
653 const attemptedAction = `instantiating component '${getTypeName(info.component)}'`;
654 validateInjectionKey($injector, downgradedModule, lazyModuleRefKey, attemptedAction);
655 const lazyModuleRef = $injector.get(lazyModuleRefKey);
656 moduleInjector = lazyModuleRef.injector || lazyModuleRef.promise;
657 }
658 // Notes:
659 //
660 // There are two injectors: `finalModuleInjector` and `finalParentInjector` (they might be
661 // the same instance, but that is irrelevant):
662 // - `finalModuleInjector` is used to retrieve `ComponentFactoryResolver`, thus it must be
663 // on the same tree as the `NgModule` that declares this downgraded component.
664 // - `finalParentInjector` is used for all other injection purposes.
665 // (Note that Angular knows to only traverse the component-tree part of that injector,
666 // when looking for an injectable and then switch to the module injector.)
667 //
668 // There are basically three cases:
669 // - If there is no parent component (thus no `parentInjector`), we bootstrap the downgraded
670 // `NgModule` and use its injector as both `finalModuleInjector` and
671 // `finalParentInjector`.
672 // - If there is a parent component (and thus a `parentInjector`) and we are sure that it
673 // belongs to the same `NgModule` as this downgraded component (e.g. because there is only
674 // one downgraded module, we use that `parentInjector` as both `finalModuleInjector` and
675 // `finalParentInjector`.
676 // - If there is a parent component, but it may belong to a different `NgModule`, then we
677 // use the `parentInjector` as `finalParentInjector` and this downgraded component's
678 // declaring `NgModule`'s injector as `finalModuleInjector`.
679 // Note 1: If the `NgModule` is already bootstrapped, we just get its injector (we don't
680 // bootstrap again).
681 // Note 2: It is possible that (while there are multiple downgraded modules) this
682 // downgraded component and its parent component both belong to the same NgModule.
683 // In that case, we could have used the `parentInjector` as both
684 // `finalModuleInjector` and `finalParentInjector`, but (for simplicity) we are
685 // treating this case as if they belong to different `NgModule`s. That doesn't
686 // really affect anything, since `parentInjector` has `moduleInjector` as ancestor
687 // and trying to resolve `ComponentFactoryResolver` from either one will return
688 // the same instance.
689 // If there is a parent component, use its injector as parent injector.
690 // If this is a "top-level" Angular component, use the module injector.
691 const finalParentInjector = parentInjector || moduleInjector;
692 // If this is a "top-level" Angular component or the parent component may belong to a
693 // different `NgModule`, use the module injector for module-specific dependencies.
694 // If there is a parent component that belongs to the same `NgModule`, use its injector.
695 const finalModuleInjector = moduleInjector || parentInjector;
696 const doDowngrade = (injector, moduleInjector) => {
697 // Retrieve `ComponentFactoryResolver` from the injector tied to the `NgModule` this
698 // component belongs to.
699 const componentFactoryResolver = moduleInjector.get(ComponentFactoryResolver);
700 const componentFactory = componentFactoryResolver.resolveComponentFactory(info.component);
701 if (!componentFactory) {
702 throw new Error(`Expecting ComponentFactory for: ${getTypeName(info.component)}`);
703 }
704 const injectorPromise = new ParentInjectorPromise(element);
705 const facade = new DowngradeComponentAdapter(element, attrs, scope, ngModel, injector, $injector, $compile, $parse, componentFactory, wrapCallback);
706 const projectableNodes = facade.compileContents();
707 facade.createComponent(projectableNodes);
708 facade.setupInputs(isNgUpgradeLite, info.propagateDigest);
709 facade.setupOutputs();
710 facade.registerCleanup();
711 injectorPromise.resolve(facade.getInjector());
712 if (ranAsync) {
713 // If this is run async, it is possible that it is not run inside a
714 // digest and initial input values will not be detected.
715 scope.$evalAsync(() => { });
716 }
717 };
718 const downgradeFn = !isNgUpgradeLite ? doDowngrade : (pInjector, mInjector) => {
719 if (!ngZone) {
720 ngZone = pInjector.get(NgZone);
721 }
722 wrapCallback(() => doDowngrade(pInjector, mInjector))();
723 };
724 // NOTE:
725 // Not using `ParentInjectorPromise.all()` (which is inherited from `SyncPromise`), because
726 // Closure Compiler (or some related tool) complains:
727 // `TypeError: ...$src$downgrade_component_ParentInjectorPromise.all is not a function`
728 SyncPromise.all([finalParentInjector, finalModuleInjector])
729 .then(([pInjector, mInjector]) => downgradeFn(pInjector, mInjector));
730 ranAsync = true;
731 }
732 };
733 };
734 // bracket-notation because of closure - see #14441
735 directiveFactory['$inject'] = [$COMPILE, $INJECTOR, $PARSE];
736 return directiveFactory;
737}
738/**
739 * Synchronous promise-like object to wrap parent injectors,
740 * to preserve the synchronous nature of AngularJS's `$compile`.
741 */
742class ParentInjectorPromise extends SyncPromise {
743 constructor(element) {
744 super();
745 this.element = element;
746 this.injectorKey = controllerKey(INJECTOR_KEY);
747 // Store the promise on the element.
748 element.data(this.injectorKey, this);
749 }
750 resolve(injector) {
751 // Store the real injector on the element.
752 this.element.data(this.injectorKey, injector);
753 // Release the element to prevent memory leaks.
754 this.element = null;
755 // Resolve the promise.
756 super.resolve(injector);
757 }
758}
759
760/**
761 * @license
762 * Copyright Google LLC All Rights Reserved.
763 *
764 * Use of this source code is governed by an MIT-style license that can be
765 * found in the LICENSE file at https://angular.io/license
766 */
767/**
768 * @description
769 *
770 * A helper function to allow an Angular service to be accessible from AngularJS.
771 *
772 * *Part of the [upgrade/static](api?query=upgrade%2Fstatic)
773 * library for hybrid upgrade apps that support AOT compilation*
774 *
775 * This helper function returns a factory function that provides access to the Angular
776 * service identified by the `token` parameter.
777 *
778 * @usageNotes
779 * ### Examples
780 *
781 * First ensure that the service to be downgraded is provided in an `NgModule`
782 * that will be part of the upgrade application. For example, let's assume we have
783 * defined `HeroesService`
784 *
785 * {@example upgrade/static/ts/full/module.ts region="ng2-heroes-service"}
786 *
787 * and that we have included this in our upgrade app `NgModule`
788 *
789 * {@example upgrade/static/ts/full/module.ts region="ng2-module"}
790 *
791 * Now we can register the `downgradeInjectable` factory function for the service
792 * on an AngularJS module.
793 *
794 * {@example upgrade/static/ts/full/module.ts region="downgrade-ng2-heroes-service"}
795 *
796 * Inside an AngularJS component's controller we can get hold of the
797 * downgraded service via the name we gave when downgrading.
798 *
799 * {@example upgrade/static/ts/full/module.ts region="example-app"}
800 *
801 * <div class="alert is-important">
802 *
803 * When using `downgradeModule()`, downgraded injectables will not be available until the Angular
804 * module that provides them is instantiated. In order to be safe, you need to ensure that the
805 * downgraded injectables are not used anywhere _outside_ the part of the app where it is
806 * guaranteed that their module has been instantiated.
807 *
808 * For example, it is _OK_ to use a downgraded service in an upgraded component that is only used
809 * from a downgraded Angular component provided by the same Angular module as the injectable, but
810 * it is _not OK_ to use it in an AngularJS component that may be used independently of Angular or
811 * use it in a downgraded Angular component from a different module.
812 *
813 * </div>
814 *
815 * @param token an `InjectionToken` that identifies a service provided from Angular.
816 * @param downgradedModule the name of the downgraded module (if any) that the injectable
817 * "belongs to", as returned by a call to `downgradeModule()`. It is the module, whose injector will
818 * be used for instantiating the injectable.<br />
819 * (This option is only necessary when using `downgradeModule()` to downgrade more than one Angular
820 * module.)
821 *
822 * @returns a [factory function](https://docs.angularjs.org/guide/di) that can be
823 * used to register the service on an AngularJS module.
824 *
825 * @publicApi
826 */
827function downgradeInjectable(token, downgradedModule = '') {
828 const factory = function ($injector) {
829 const injectorKey = `${INJECTOR_KEY}${downgradedModule}`;
830 const injectableName = isFunction(token) ? getTypeName(token) : String(token);
831 const attemptedAction = `instantiating injectable '${injectableName}'`;
832 validateInjectionKey($injector, downgradedModule, injectorKey, attemptedAction);
833 const injector = $injector.get(injectorKey);
834 return injector.get(token);
835 };
836 factory['$inject'] = [$INJECTOR];
837 return factory;
838}
839
840/**
841 * @license
842 * Copyright Google LLC All Rights Reserved.
843 *
844 * Use of this source code is governed by an MIT-style license that can be
845 * found in the LICENSE file at https://angular.io/license
846 */
847/**
848 * @publicApi
849 */
850const VERSION = new Version('10.0.5');
851
852/**
853 * @license
854 * Copyright Google LLC All Rights Reserved.
855 *
856 * Use of this source code is governed by an MIT-style license that can be
857 * found in the LICENSE file at https://angular.io/license
858 */
859// We have to do a little dance to get the ng1 injector into the module injector.
860// We store the ng1 injector so that the provider in the module injector can access it
861// Then we "get" the ng1 injector from the module injector, which triggers the provider to read
862// the stored injector and release the reference to it.
863let tempInjectorRef = null;
864function setTempInjectorRef(injector) {
865 tempInjectorRef = injector;
866}
867function injectorFactory() {
868 if (!tempInjectorRef) {
869 throw new Error('Trying to get the AngularJS injector before it being set.');
870 }
871 const injector = tempInjectorRef;
872 tempInjectorRef = null; // clear the value to prevent memory leaks
873 return injector;
874}
875function rootScopeFactory(i) {
876 return i.get('$rootScope');
877}
878function compileFactory(i) {
879 return i.get('$compile');
880}
881function parseFactory(i) {
882 return i.get('$parse');
883}
884const angular1Providers = [
885 // We must use exported named functions for the ng2 factories to keep the compiler happy:
886 // > Metadata collected contains an error that will be reported at runtime:
887 // > Function calls are not supported.
888 // > Consider replacing the function or lambda with a reference to an exported function
889 { provide: '$injector', useFactory: injectorFactory, deps: [] },
890 { provide: '$rootScope', useFactory: rootScopeFactory, deps: ['$injector'] },
891 { provide: '$compile', useFactory: compileFactory, deps: ['$injector'] },
892 { provide: '$parse', useFactory: parseFactory, deps: ['$injector'] }
893];
894
895/**
896 * @license
897 * Copyright Google LLC All Rights Reserved.
898 *
899 * Use of this source code is governed by an MIT-style license that can be
900 * found in the LICENSE file at https://angular.io/license
901 */
902class NgAdapterInjector {
903 constructor(modInjector) {
904 this.modInjector = modInjector;
905 }
906 // When Angular locate a service in the component injector tree, the not found value is set to
907 // `NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR`. In such a case we should not walk up to the module
908 // injector.
909 // AngularJS only supports a single tree and should always check the module injector.
910 get(token, notFoundValue) {
911 if (notFoundValue === ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
912 return notFoundValue;
913 }
914 return this.modInjector.get(token, notFoundValue);
915 }
916}
917
918/**
919 * @license
920 * Copyright Google LLC All Rights Reserved.
921 *
922 * Use of this source code is governed by an MIT-style license that can be
923 * found in the LICENSE file at https://angular.io/license
924 */
925let moduleUid = 0;
926/**
927 * @description
928 *
929 * A helper function for creating an AngularJS module that can bootstrap an Angular module
930 * "on-demand" (possibly lazily) when a {@link downgradeComponent downgraded component} needs to be
931 * instantiated.
932 *
933 * *Part of the [upgrade/static](api?query=upgrade/static) library for hybrid upgrade apps that
934 * support AOT compilation.*
935 *
936 * It allows loading/bootstrapping the Angular part of a hybrid application lazily and not having to
937 * pay the cost up-front. For example, you can have an AngularJS application that uses Angular for
938 * specific routes and only instantiate the Angular modules if/when the user visits one of these
939 * routes.
940 *
941 * The Angular module will be bootstrapped once (when requested for the first time) and the same
942 * reference will be used from that point onwards.
943 *
944 * `downgradeModule()` requires either an `NgModuleFactory` or a function:
945 * - `NgModuleFactory`: If you pass an `NgModuleFactory`, it will be used to instantiate a module
946 * using `platformBrowser`'s {@link PlatformRef#bootstrapModuleFactory bootstrapModuleFactory()}.
947 * - `Function`: If you pass a function, it is expected to return a promise resolving to an
948 * `NgModuleRef`. The function is called with an array of extra {@link StaticProvider Providers}
949 * that are expected to be available from the returned `NgModuleRef`'s `Injector`.
950 *
951 * `downgradeModule()` returns the name of the created AngularJS wrapper module. You can use it to
952 * declare a dependency in your main AngularJS module.
953 *
954 * {@example upgrade/static/ts/lite/module.ts region="basic-how-to"}
955 *
956 * For more details on how to use `downgradeModule()` see
957 * [Upgrading for Performance](guide/upgrade-performance).
958 *
959 * @usageNotes
960 *
961 * Apart from `UpgradeModule`, you can use the rest of the `upgrade/static` helpers as usual to
962 * build a hybrid application. Note that the Angular pieces (e.g. downgraded services) will not be
963 * available until the downgraded module has been bootstrapped, i.e. by instantiating a downgraded
964 * component.
965 *
966 * <div class="alert is-important">
967 *
968 * You cannot use `downgradeModule()` and `UpgradeModule` in the same hybrid application.<br />
969 * Use one or the other.
970 *
971 * </div>
972 *
973 * ### Differences with `UpgradeModule`
974 *
975 * Besides their different API, there are two important internal differences between
976 * `downgradeModule()` and `UpgradeModule` that affect the behavior of hybrid applications:
977 *
978 * 1. Unlike `UpgradeModule`, `downgradeModule()` does not bootstrap the main AngularJS module
979 * inside the {@link NgZone Angular zone}.
980 * 2. Unlike `UpgradeModule`, `downgradeModule()` does not automatically run a
981 * [$digest()](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest) when changes are
982 * detected in the Angular part of the application.
983 *
984 * What this means is that applications using `UpgradeModule` will run change detection more
985 * frequently in order to ensure that both frameworks are properly notified about possible changes.
986 * This will inevitably result in more change detection runs than necessary.
987 *
988 * `downgradeModule()`, on the other side, does not try to tie the two change detection systems as
989 * tightly, restricting the explicit change detection runs only to cases where it knows it is
990 * necessary (e.g. when the inputs of a downgraded component change). This improves performance,
991 * especially in change-detection-heavy applications, but leaves it up to the developer to manually
992 * notify each framework as needed.
993 *
994 * For a more detailed discussion of the differences and their implications, see
995 * [Upgrading for Performance](guide/upgrade-performance).
996 *
997 * <div class="alert is-helpful">
998 *
999 * You can manually trigger a change detection run in AngularJS using
1000 * [scope.$apply(...)](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply) or
1001 * [$rootScope.$digest()](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest).
1002 *
1003 * You can manually trigger a change detection run in Angular using {@link NgZone#run
1004 * ngZone.run(...)}.
1005 *
1006 * </div>
1007 *
1008 * ### Downgrading multiple modules
1009 *
1010 * It is possible to downgrade multiple modules and include them in an AngularJS application. In
1011 * that case, each downgraded module will be bootstrapped when an associated downgraded component or
1012 * injectable needs to be instantiated.
1013 *
1014 * Things to keep in mind, when downgrading multiple modules:
1015 *
1016 * - Each downgraded component/injectable needs to be explicitly associated with a downgraded
1017 * module. See `downgradeComponent()` and `downgradeInjectable()` for more details.
1018 *
1019 * - If you want some injectables to be shared among all downgraded modules, you can provide them as
1020 * `StaticProvider`s, when creating the `PlatformRef` (e.g. via `platformBrowser` or
1021 * `platformBrowserDynamic`).
1022 *
1023 * - When using {@link PlatformRef#bootstrapmodule `bootstrapModule()`} or
1024 * {@link PlatformRef#bootstrapmodulefactory `bootstrapModuleFactory()`} to bootstrap the
1025 * downgraded modules, each one is considered a "root" module. As a consequence, a new instance
1026 * will be created for every injectable provided in `"root"` (via
1027 * {@link Injectable#providedIn `providedIn`}).
1028 * If this is not your intention, you can have a shared module (that will act as act as the "root"
1029 * module) and create all downgraded modules using that module's injector:
1030 *
1031 * {@example upgrade/static/ts/lite-multi-shared/module.ts region="shared-root-module"}
1032 *
1033 * @publicApi
1034 */
1035function downgradeModule(moduleFactoryOrBootstrapFn) {
1036 const lazyModuleName = `${UPGRADE_MODULE_NAME}.lazy${++moduleUid}`;
1037 const lazyModuleRefKey = `${LAZY_MODULE_REF}${lazyModuleName}`;
1038 const lazyInjectorKey = `${INJECTOR_KEY}${lazyModuleName}`;
1039 const bootstrapFn = isFunction(moduleFactoryOrBootstrapFn) ?
1040 moduleFactoryOrBootstrapFn :
1041 (extraProviders) => platformBrowser(extraProviders).bootstrapModuleFactory(moduleFactoryOrBootstrapFn);
1042 let injector;
1043 // Create an ng1 module to bootstrap.
1044 module_(lazyModuleName, [])
1045 .constant(UPGRADE_APP_TYPE_KEY, 3 /* Lite */)
1046 .factory(INJECTOR_KEY, [lazyInjectorKey, identity])
1047 .factory(lazyInjectorKey, () => {
1048 if (!injector) {
1049 throw new Error('Trying to get the Angular injector before bootstrapping the corresponding ' +
1050 'Angular module.');
1051 }
1052 return injector;
1053 })
1054 .factory(LAZY_MODULE_REF, [lazyModuleRefKey, identity])
1055 .factory(lazyModuleRefKey, [
1056 $INJECTOR,
1057 ($injector) => {
1058 setTempInjectorRef($injector);
1059 const result = {
1060 promise: bootstrapFn(angular1Providers).then(ref => {
1061 injector = result.injector = new NgAdapterInjector(ref.injector);
1062 injector.get($INJECTOR);
1063 return injector;
1064 })
1065 };
1066 return result;
1067 }
1068 ])
1069 .config([
1070 $INJECTOR, $PROVIDE,
1071 ($injector, $provide) => {
1072 $provide.constant(DOWNGRADED_MODULE_COUNT_KEY, getDowngradedModuleCount($injector) + 1);
1073 }
1074 ]);
1075 return lazyModuleName;
1076}
1077function identity(x) {
1078 return x;
1079}
1080
1081/**
1082 * @license
1083 * Copyright Google LLC All Rights Reserved.
1084 *
1085 * Use of this source code is governed by an MIT-style license that can be
1086 * found in the LICENSE file at https://angular.io/license
1087 */
1088// Constants
1089const REQUIRE_PREFIX_RE = /^(\^\^?)?(\?)?(\^\^?)?/;
1090// Classes
1091class UpgradeHelper {
1092 constructor(injector, name, elementRef, directive) {
1093 this.injector = injector;
1094 this.name = name;
1095 this.$injector = injector.get($INJECTOR);
1096 this.$compile = this.$injector.get($COMPILE);
1097 this.$controller = this.$injector.get($CONTROLLER);
1098 this.element = elementRef.nativeElement;
1099 this.$element = element(this.element);
1100 this.directive = directive || UpgradeHelper.getDirective(this.$injector, name);
1101 }
1102 static getDirective($injector, name) {
1103 const directives = $injector.get(name + 'Directive');
1104 if (directives.length > 1) {
1105 throw new Error(`Only support single directive definition for: ${name}`);
1106 }
1107 const directive = directives[0];
1108 // AngularJS will transform `link: xyz` to `compile: () => xyz`. So we can only tell there was a
1109 // user-defined `compile` if there is no `link`. In other cases, we will just ignore `compile`.
1110 if (directive.compile && !directive.link)
1111 notSupported(name, 'compile');
1112 if (directive.replace)
1113 notSupported(name, 'replace');
1114 if (directive.terminal)
1115 notSupported(name, 'terminal');
1116 return directive;
1117 }
1118 static getTemplate($injector, directive, fetchRemoteTemplate = false, $element) {
1119 if (directive.template !== undefined) {
1120 return getOrCall(directive.template, $element);
1121 }
1122 else if (directive.templateUrl) {
1123 const $templateCache = $injector.get($TEMPLATE_CACHE);
1124 const url = getOrCall(directive.templateUrl, $element);
1125 const template = $templateCache.get(url);
1126 if (template !== undefined) {
1127 return template;
1128 }
1129 else if (!fetchRemoteTemplate) {
1130 throw new Error('loading directive templates asynchronously is not supported');
1131 }
1132 return new Promise((resolve, reject) => {
1133 const $httpBackend = $injector.get($HTTP_BACKEND);
1134 $httpBackend('GET', url, null, (status, response) => {
1135 if (status === 200) {
1136 resolve($templateCache.put(url, response));
1137 }
1138 else {
1139 reject(`GET component template from '${url}' returned '${status}: ${response}'`);
1140 }
1141 });
1142 });
1143 }
1144 else {
1145 throw new Error(`Directive '${directive.name}' is not a component, it is missing template.`);
1146 }
1147 }
1148 buildController(controllerType, $scope) {
1149 // TODO: Document that we do not pre-assign bindings on the controller instance.
1150 // Quoted properties below so that this code can be optimized with Closure Compiler.
1151 const locals = { '$scope': $scope, '$element': this.$element };
1152 const controller = this.$controller(controllerType, locals, null, this.directive.controllerAs);
1153 this.$element.data(controllerKey(this.directive.name), controller);
1154 return controller;
1155 }
1156 compileTemplate(template) {
1157 if (template === undefined) {
1158 template =
1159 UpgradeHelper.getTemplate(this.$injector, this.directive, false, this.$element);
1160 }
1161 return this.compileHtml(template);
1162 }
1163 onDestroy($scope, controllerInstance) {
1164 if (controllerInstance && isFunction(controllerInstance.$onDestroy)) {
1165 controllerInstance.$onDestroy();
1166 }
1167 $scope.$destroy();
1168 // Clean the jQuery/jqLite data on the component+child elements.
1169 // Equivelent to how jQuery/jqLite invoke `cleanData` on an Element (this.element)
1170 // https://github.com/jquery/jquery/blob/e743cbd28553267f955f71ea7248377915613fd9/src/manipulation.js#L223
1171 // https://github.com/angular/angular.js/blob/26ddc5f830f902a3d22f4b2aab70d86d4d688c82/src/jqLite.js#L306-L312
1172 // `cleanData` will invoke the AngularJS `$destroy` DOM event
1173 // https://github.com/angular/angular.js/blob/26ddc5f830f902a3d22f4b2aab70d86d4d688c82/src/Angular.js#L1911-L1924
1174 element.cleanData([this.element]);
1175 element.cleanData(this.element.querySelectorAll('*'));
1176 }
1177 prepareTransclusion() {
1178 const transclude = this.directive.transclude;
1179 const contentChildNodes = this.extractChildNodes();
1180 const attachChildrenFn = (scope, cloneAttachFn) => {
1181 // Since AngularJS v1.5.8, `cloneAttachFn` will try to destroy the transclusion scope if
1182 // `$template` is empty. Since the transcluded content comes from Angular, not AngularJS,
1183 // there will be no transclusion scope here.
1184 // Provide a dummy `scope.$destroy()` method to prevent `cloneAttachFn` from throwing.
1185 scope = scope || { $destroy: () => undefined };
1186 return cloneAttachFn($template, scope);
1187 };
1188 let $template = contentChildNodes;
1189 if (transclude) {
1190 const slots = Object.create(null);
1191 if (typeof transclude === 'object') {
1192 $template = [];
1193 const slotMap = Object.create(null);
1194 const filledSlots = Object.create(null);
1195 // Parse the element selectors.
1196 Object.keys(transclude).forEach(slotName => {
1197 let selector = transclude[slotName];
1198 const optional = selector.charAt(0) === '?';
1199 selector = optional ? selector.substring(1) : selector;
1200 slotMap[selector] = slotName;
1201 slots[slotName] = null; // `null`: Defined but not yet filled.
1202 filledSlots[slotName] = optional; // Consider optional slots as filled.
1203 });
1204 // Add the matching elements into their slot.
1205 contentChildNodes.forEach(node => {
1206 const slotName = slotMap[directiveNormalize(node.nodeName.toLowerCase())];
1207 if (slotName) {
1208 filledSlots[slotName] = true;
1209 slots[slotName] = slots[slotName] || [];
1210 slots[slotName].push(node);
1211 }
1212 else {
1213 $template.push(node);
1214 }
1215 });
1216 // Check for required slots that were not filled.
1217 Object.keys(filledSlots).forEach(slotName => {
1218 if (!filledSlots[slotName]) {
1219 throw new Error(`Required transclusion slot '${slotName}' on directive: ${this.name}`);
1220 }
1221 });
1222 Object.keys(slots).filter(slotName => slots[slotName]).forEach(slotName => {
1223 const nodes = slots[slotName];
1224 slots[slotName] = (scope, cloneAttach) => {
1225 return cloneAttach(nodes, scope);
1226 };
1227 });
1228 }
1229 // Attach `$$slots` to default slot transclude fn.
1230 attachChildrenFn.$$slots = slots;
1231 // AngularJS v1.6+ ignores empty or whitespace-only transcluded text nodes. But Angular
1232 // removes all text content after the first interpolation and updates it later, after
1233 // evaluating the expressions. This would result in AngularJS failing to recognize text
1234 // nodes that start with an interpolation as transcluded content and use the fallback
1235 // content instead.
1236 // To avoid this issue, we add a
1237 // [zero-width non-joiner character](https://en.wikipedia.org/wiki/Zero-width_non-joiner)
1238 // to empty text nodes (which can only be a result of Angular removing their initial content).
1239 // NOTE: Transcluded text content that starts with whitespace followed by an interpolation
1240 // will still fail to be detected by AngularJS v1.6+
1241 $template.forEach(node => {
1242 if (node.nodeType === Node.TEXT_NODE && !node.nodeValue) {
1243 node.nodeValue = '\u200C';
1244 }
1245 });
1246 }
1247 return attachChildrenFn;
1248 }
1249 resolveAndBindRequiredControllers(controllerInstance) {
1250 const directiveRequire = this.getDirectiveRequire();
1251 const requiredControllers = this.resolveRequire(directiveRequire);
1252 if (controllerInstance && this.directive.bindToController && isMap(directiveRequire)) {
1253 const requiredControllersMap = requiredControllers;
1254 Object.keys(requiredControllersMap).forEach(key => {
1255 controllerInstance[key] = requiredControllersMap[key];
1256 });
1257 }
1258 return requiredControllers;
1259 }
1260 compileHtml(html) {
1261 this.element.innerHTML = html;
1262 return this.$compile(this.element.childNodes);
1263 }
1264 extractChildNodes() {
1265 const childNodes = [];
1266 let childNode;
1267 while (childNode = this.element.firstChild) {
1268 this.element.removeChild(childNode);
1269 childNodes.push(childNode);
1270 }
1271 return childNodes;
1272 }
1273 getDirectiveRequire() {
1274 const require = this.directive.require || (this.directive.controller && this.directive.name);
1275 if (isMap(require)) {
1276 Object.keys(require).forEach(key => {
1277 const value = require[key];
1278 const match = value.match(REQUIRE_PREFIX_RE);
1279 const name = value.substring(match[0].length);
1280 if (!name) {
1281 require[key] = match[0] + key;
1282 }
1283 });
1284 }
1285 return require;
1286 }
1287 resolveRequire(require, controllerInstance) {
1288 if (!require) {
1289 return null;
1290 }
1291 else if (Array.isArray(require)) {
1292 return require.map(req => this.resolveRequire(req));
1293 }
1294 else if (typeof require === 'object') {
1295 const value = {};
1296 Object.keys(require).forEach(key => value[key] = this.resolveRequire(require[key]));
1297 return value;
1298 }
1299 else if (typeof require === 'string') {
1300 const match = require.match(REQUIRE_PREFIX_RE);
1301 const inheritType = match[1] || match[3];
1302 const name = require.substring(match[0].length);
1303 const isOptional = !!match[2];
1304 const searchParents = !!inheritType;
1305 const startOnParent = inheritType === '^^';
1306 const ctrlKey = controllerKey(name);
1307 const elem = startOnParent ? this.$element.parent() : this.$element;
1308 const value = searchParents ? elem.inheritedData(ctrlKey) : elem.data(ctrlKey);
1309 if (!value && !isOptional) {
1310 throw new Error(`Unable to find required '${require}' in upgraded directive '${this.name}'.`);
1311 }
1312 return value;
1313 }
1314 else {
1315 throw new Error(`Unrecognized 'require' syntax on upgraded directive '${this.name}': ${require}`);
1316 }
1317 }
1318}
1319function getOrCall(property, ...args) {
1320 return isFunction(property) ? property(...args) : property;
1321}
1322// NOTE: Only works for `typeof T !== 'object'`.
1323function isMap(value) {
1324 return value && !Array.isArray(value) && typeof value === 'object';
1325}
1326function notSupported(name, feature) {
1327 throw new Error(`Upgraded directive '${name}' contains unsupported feature: '${feature}'.`);
1328}
1329
1330/**
1331 * @license
1332 * Copyright Google LLC All Rights Reserved.
1333 *
1334 * Use of this source code is governed by an MIT-style license that can be
1335 * found in the LICENSE file at https://angular.io/license
1336 */
1337const NOT_SUPPORTED = 'NOT_SUPPORTED';
1338const INITIAL_VALUE$1 = {
1339 __UNINITIALIZED__: true
1340};
1341class Bindings {
1342 constructor() {
1343 this.twoWayBoundProperties = [];
1344 this.twoWayBoundLastValues = [];
1345 this.expressionBoundProperties = [];
1346 this.propertyToOutputMap = {};
1347 }
1348}
1349/**
1350 * @description
1351 *
1352 * A helper class that allows an AngularJS component to be used from Angular.
1353 *
1354 * *Part of the [upgrade/static](api?query=upgrade%2Fstatic)
1355 * library for hybrid upgrade apps that support AOT compilation.*
1356 *
1357 * This helper class should be used as a base class for creating Angular directives
1358 * that wrap AngularJS components that need to be "upgraded".
1359 *
1360 * @usageNotes
1361 * ### Examples
1362 *
1363 * Let's assume that you have an AngularJS component called `ng1Hero` that needs
1364 * to be made available in Angular templates.
1365 *
1366 * {@example upgrade/static/ts/full/module.ts region="ng1-hero"}
1367 *
1368 * We must create a `Directive` that will make this AngularJS component
1369 * available inside Angular templates.
1370 *
1371 * {@example upgrade/static/ts/full/module.ts region="ng1-hero-wrapper"}
1372 *
1373 * In this example you can see that we must derive from the `UpgradeComponent`
1374 * base class but also provide an {@link Directive `@Directive`} decorator. This is
1375 * because the AOT compiler requires that this information is statically available at
1376 * compile time.
1377 *
1378 * Note that we must do the following:
1379 * * specify the directive's selector (`ng1-hero`)
1380 * * specify all inputs and outputs that the AngularJS component expects
1381 * * derive from `UpgradeComponent`
1382 * * call the base class from the constructor, passing
1383 * * the AngularJS name of the component (`ng1Hero`)
1384 * * the `ElementRef` and `Injector` for the component wrapper
1385 *
1386 * @publicApi
1387 */
1388class UpgradeComponent {
1389 /**
1390 * Create a new `UpgradeComponent` instance. You should not normally need to do this.
1391 * Instead you should derive a new class from this one and call the super constructor
1392 * from the base class.
1393 *
1394 * {@example upgrade/static/ts/full/module.ts region="ng1-hero-wrapper" }
1395 *
1396 * * The `name` parameter should be the name of the AngularJS directive.
1397 * * The `elementRef` and `injector` parameters should be acquired from Angular by dependency
1398 * injection into the base class constructor.
1399 */
1400 constructor(name, elementRef, injector) {
1401 this.name = name;
1402 this.elementRef = elementRef;
1403 this.injector = injector;
1404 this.helper = new UpgradeHelper(injector, name, elementRef);
1405 this.$injector = this.helper.$injector;
1406 this.element = this.helper.element;
1407 this.$element = this.helper.$element;
1408 this.directive = this.helper.directive;
1409 this.bindings = this.initializeBindings(this.directive);
1410 // We ask for the AngularJS scope from the Angular injector, since
1411 // we will put the new component scope onto the new injector for each component
1412 const $parentScope = injector.get($SCOPE);
1413 // QUESTION 1: Should we create an isolated scope if the scope is only true?
1414 // QUESTION 2: Should we make the scope accessible through `$element.scope()/isolateScope()`?
1415 this.$componentScope = $parentScope.$new(!!this.directive.scope);
1416 this.initializeOutputs();
1417 }
1418 ngOnInit() {
1419 // Collect contents, insert and compile template
1420 const attachChildNodes = this.helper.prepareTransclusion();
1421 const linkFn = this.helper.compileTemplate();
1422 // Instantiate controller
1423 const controllerType = this.directive.controller;
1424 const bindToController = this.directive.bindToController;
1425 if (controllerType) {
1426 this.controllerInstance = this.helper.buildController(controllerType, this.$componentScope);
1427 }
1428 else if (bindToController) {
1429 throw new Error(`Upgraded directive '${this.directive.name}' specifies 'bindToController' but no controller.`);
1430 }
1431 // Set up outputs
1432 this.bindingDestination = bindToController ? this.controllerInstance : this.$componentScope;
1433 this.bindOutputs();
1434 // Require other controllers
1435 const requiredControllers = this.helper.resolveAndBindRequiredControllers(this.controllerInstance);
1436 // Hook: $onChanges
1437 if (this.pendingChanges) {
1438 this.forwardChanges(this.pendingChanges);
1439 this.pendingChanges = null;
1440 }
1441 // Hook: $onInit
1442 if (this.controllerInstance && isFunction(this.controllerInstance.$onInit)) {
1443 this.controllerInstance.$onInit();
1444 }
1445 // Hook: $doCheck
1446 if (this.controllerInstance && isFunction(this.controllerInstance.$doCheck)) {
1447 const callDoCheck = () => this.controllerInstance.$doCheck();
1448 this.unregisterDoCheckWatcher = this.$componentScope.$parent.$watch(callDoCheck);
1449 callDoCheck();
1450 }
1451 // Linking
1452 const link = this.directive.link;
1453 const preLink = typeof link == 'object' && link.pre;
1454 const postLink = typeof link == 'object' ? link.post : link;
1455 const attrs = NOT_SUPPORTED;
1456 const transcludeFn = NOT_SUPPORTED;
1457 if (preLink) {
1458 preLink(this.$componentScope, this.$element, attrs, requiredControllers, transcludeFn);
1459 }
1460 linkFn(this.$componentScope, null, { parentBoundTranscludeFn: attachChildNodes });
1461 if (postLink) {
1462 postLink(this.$componentScope, this.$element, attrs, requiredControllers, transcludeFn);
1463 }
1464 // Hook: $postLink
1465 if (this.controllerInstance && isFunction(this.controllerInstance.$postLink)) {
1466 this.controllerInstance.$postLink();
1467 }
1468 }
1469 ngOnChanges(changes) {
1470 if (!this.bindingDestination) {
1471 this.pendingChanges = changes;
1472 }
1473 else {
1474 this.forwardChanges(changes);
1475 }
1476 }
1477 ngDoCheck() {
1478 const twoWayBoundProperties = this.bindings.twoWayBoundProperties;
1479 const twoWayBoundLastValues = this.bindings.twoWayBoundLastValues;
1480 const propertyToOutputMap = this.bindings.propertyToOutputMap;
1481 twoWayBoundProperties.forEach((propName, idx) => {
1482 const newValue = this.bindingDestination[propName];
1483 const oldValue = twoWayBoundLastValues[idx];
1484 if (!Object.is(newValue, oldValue)) {
1485 const outputName = propertyToOutputMap[propName];
1486 const eventEmitter = this[outputName];
1487 eventEmitter.emit(newValue);
1488 twoWayBoundLastValues[idx] = newValue;
1489 }
1490 });
1491 }
1492 ngOnDestroy() {
1493 if (isFunction(this.unregisterDoCheckWatcher)) {
1494 this.unregisterDoCheckWatcher();
1495 }
1496 this.helper.onDestroy(this.$componentScope, this.controllerInstance);
1497 }
1498 initializeBindings(directive) {
1499 const btcIsObject = typeof directive.bindToController === 'object';
1500 if (btcIsObject && Object.keys(directive.scope).length) {
1501 throw new Error(`Binding definitions on scope and controller at the same time is not supported.`);
1502 }
1503 const context = btcIsObject ? directive.bindToController : directive.scope;
1504 const bindings = new Bindings();
1505 if (typeof context == 'object') {
1506 Object.keys(context).forEach(propName => {
1507 const definition = context[propName];
1508 const bindingType = definition.charAt(0);
1509 // QUESTION: What about `=*`? Ignore? Throw? Support?
1510 switch (bindingType) {
1511 case '@':
1512 case '<':
1513 // We don't need to do anything special. They will be defined as inputs on the
1514 // upgraded component facade and the change propagation will be handled by
1515 // `ngOnChanges()`.
1516 break;
1517 case '=':
1518 bindings.twoWayBoundProperties.push(propName);
1519 bindings.twoWayBoundLastValues.push(INITIAL_VALUE$1);
1520 bindings.propertyToOutputMap[propName] = propName + 'Change';
1521 break;
1522 case '&':
1523 bindings.expressionBoundProperties.push(propName);
1524 bindings.propertyToOutputMap[propName] = propName;
1525 break;
1526 default:
1527 let json = JSON.stringify(context);
1528 throw new Error(`Unexpected mapping '${bindingType}' in '${json}' in '${this.name}' directive.`);
1529 }
1530 });
1531 }
1532 return bindings;
1533 }
1534 initializeOutputs() {
1535 // Initialize the outputs for `=` and `&` bindings
1536 this.bindings.twoWayBoundProperties.concat(this.bindings.expressionBoundProperties)
1537 .forEach(propName => {
1538 const outputName = this.bindings.propertyToOutputMap[propName];
1539 this[outputName] = new EventEmitter();
1540 });
1541 }
1542 bindOutputs() {
1543 // Bind `&` bindings to the corresponding outputs
1544 this.bindings.expressionBoundProperties.forEach(propName => {
1545 const outputName = this.bindings.propertyToOutputMap[propName];
1546 const emitter = this[outputName];
1547 this.bindingDestination[propName] = (value) => emitter.emit(value);
1548 });
1549 }
1550 forwardChanges(changes) {
1551 // Forward input changes to `bindingDestination`
1552 Object.keys(changes).forEach(propName => this.bindingDestination[propName] = changes[propName].currentValue);
1553 if (isFunction(this.bindingDestination.$onChanges)) {
1554 this.bindingDestination.$onChanges(changes);
1555 }
1556 }
1557}
1558UpgradeComponent.decorators = [
1559 { type: Directive }
1560];
1561UpgradeComponent.ctorParameters = () => [
1562 { type: String },
1563 { type: ElementRef },
1564 { type: Injector }
1565];
1566
1567/**
1568 * @license
1569 * Copyright Google LLC All Rights Reserved.
1570 *
1571 * Use of this source code is governed by an MIT-style license that can be
1572 * found in the LICENSE file at https://angular.io/license
1573 */
1574/**
1575 * @description
1576 *
1577 * An `NgModule`, which you import to provide AngularJS core services,
1578 * and has an instance method used to bootstrap the hybrid upgrade application.
1579 *
1580 * *Part of the [upgrade/static](api?query=upgrade/static)
1581 * library for hybrid upgrade apps that support AOT compilation*
1582 *
1583 * The `upgrade/static` package contains helpers that allow AngularJS and Angular components
1584 * to be used together inside a hybrid upgrade application, which supports AOT compilation.
1585 *
1586 * Specifically, the classes and functions in the `upgrade/static` module allow the following:
1587 *
1588 * 1. Creation of an Angular directive that wraps and exposes an AngularJS component so
1589 * that it can be used in an Angular template. See `UpgradeComponent`.
1590 * 2. Creation of an AngularJS directive that wraps and exposes an Angular component so
1591 * that it can be used in an AngularJS template. See `downgradeComponent`.
1592 * 3. Creation of an Angular root injector provider that wraps and exposes an AngularJS
1593 * service so that it can be injected into an Angular context. See
1594 * {@link UpgradeModule#upgrading-an-angular-1-service Upgrading an AngularJS service} below.
1595 * 4. Creation of an AngularJS service that wraps and exposes an Angular injectable
1596 * so that it can be injected into an AngularJS context. See `downgradeInjectable`.
1597 * 3. Bootstrapping of a hybrid Angular application which contains both of the frameworks
1598 * coexisting in a single application.
1599 *
1600 * @usageNotes
1601 *
1602 * ```ts
1603 * import {UpgradeModule} from '@angular/upgrade/static';
1604 * ```
1605 *
1606 * See also the {@link UpgradeModule#examples examples} below.
1607 *
1608 * ### Mental Model
1609 *
1610 * When reasoning about how a hybrid application works it is useful to have a mental model which
1611 * describes what is happening and explains what is happening at the lowest level.
1612 *
1613 * 1. There are two independent frameworks running in a single application, each framework treats
1614 * the other as a black box.
1615 * 2. Each DOM element on the page is owned exactly by one framework. Whichever framework
1616 * instantiated the element is the owner. Each framework only updates/interacts with its own
1617 * DOM elements and ignores others.
1618 * 3. AngularJS directives always execute inside the AngularJS framework codebase regardless of
1619 * where they are instantiated.
1620 * 4. Angular components always execute inside the Angular framework codebase regardless of
1621 * where they are instantiated.
1622 * 5. An AngularJS component can be "upgraded"" to an Angular component. This is achieved by
1623 * defining an Angular directive, which bootstraps the AngularJS component at its location
1624 * in the DOM. See `UpgradeComponent`.
1625 * 6. An Angular component can be "downgraded" to an AngularJS component. This is achieved by
1626 * defining an AngularJS directive, which bootstraps the Angular component at its location
1627 * in the DOM. See `downgradeComponent`.
1628 * 7. Whenever an "upgraded"/"downgraded" component is instantiated the host element is owned by
1629 * the framework doing the instantiation. The other framework then instantiates and owns the
1630 * view for that component.
1631 * 1. This implies that the component bindings will always follow the semantics of the
1632 * instantiation framework.
1633 * 2. The DOM attributes are parsed by the framework that owns the current template. So
1634 * attributes in AngularJS templates must use kebab-case, while AngularJS templates must use
1635 * camelCase.
1636 * 3. However the template binding syntax will always use the Angular style, e.g. square
1637 * brackets (`[...]`) for property binding.
1638 * 8. Angular is bootstrapped first; AngularJS is bootstrapped second. AngularJS always owns the
1639 * root component of the application.
1640 * 9. The new application is running in an Angular zone, and therefore it no longer needs calls to
1641 * `$apply()`.
1642 *
1643 * ### The `UpgradeModule` class
1644 *
1645 * This class is an `NgModule`, which you import to provide AngularJS core services,
1646 * and has an instance method used to bootstrap the hybrid upgrade application.
1647 *
1648 * * Core AngularJS services
1649 * Importing this `NgModule` will add providers for the core
1650 * [AngularJS services](https://docs.angularjs.org/api/ng/service) to the root injector.
1651 *
1652 * * Bootstrap
1653 * The runtime instance of this class contains a {@link UpgradeModule#bootstrap `bootstrap()`}
1654 * method, which you use to bootstrap the top level AngularJS module onto an element in the
1655 * DOM for the hybrid upgrade app.
1656 *
1657 * It also contains properties to access the {@link UpgradeModule#injector root injector}, the
1658 * bootstrap `NgZone` and the
1659 * [AngularJS $injector](https://docs.angularjs.org/api/auto/service/$injector).
1660 *
1661 * ### Examples
1662 *
1663 * Import the `UpgradeModule` into your top level {@link NgModule Angular `NgModule`}.
1664 *
1665 * {@example upgrade/static/ts/full/module.ts region='ng2-module'}
1666 *
1667 * Then inject `UpgradeModule` into your Angular `NgModule` and use it to bootstrap the top level
1668 * [AngularJS module](https://docs.angularjs.org/api/ng/type/angular.Module) in the
1669 * `ngDoBootstrap()` method.
1670 *
1671 * {@example upgrade/static/ts/full/module.ts region='bootstrap-ng1'}
1672 *
1673 * Finally, kick off the whole process, by bootstraping your top level Angular `NgModule`.
1674 *
1675 * {@example upgrade/static/ts/full/module.ts region='bootstrap-ng2'}
1676 *
1677 * {@a upgrading-an-angular-1-service}
1678 * ### Upgrading an AngularJS service
1679 *
1680 * There is no specific API for upgrading an AngularJS service. Instead you should just follow the
1681 * following recipe:
1682 *
1683 * Let's say you have an AngularJS service:
1684 *
1685 * {@example upgrade/static/ts/full/module.ts region="ng1-text-formatter-service"}
1686 *
1687 * Then you should define an Angular provider to be included in your `NgModule` `providers`
1688 * property.
1689 *
1690 * {@example upgrade/static/ts/full/module.ts region="upgrade-ng1-service"}
1691 *
1692 * Then you can use the "upgraded" AngularJS service by injecting it into an Angular component
1693 * or service.
1694 *
1695 * {@example upgrade/static/ts/full/module.ts region="use-ng1-upgraded-service"}
1696 *
1697 * @publicApi
1698 */
1699class UpgradeModule {
1700 constructor(
1701 /** The root `Injector` for the upgrade application. */
1702 injector,
1703 /** The bootstrap zone for the upgrade application */
1704 ngZone) {
1705 this.ngZone = ngZone;
1706 this.injector = new NgAdapterInjector(injector);
1707 }
1708 /**
1709 * Bootstrap an AngularJS application from this NgModule
1710 * @param element the element on which to bootstrap the AngularJS application
1711 * @param [modules] the AngularJS modules to bootstrap for this application
1712 * @param [config] optional extra AngularJS bootstrap configuration
1713 */
1714 bootstrap(element$1, modules = [], config /*angular.IAngularBootstrapConfig*/) {
1715 const INIT_MODULE_NAME = UPGRADE_MODULE_NAME + '.init';
1716 // Create an ng1 module to bootstrap
1717 const initModule = module_(INIT_MODULE_NAME, [])
1718 .constant(UPGRADE_APP_TYPE_KEY, 2 /* Static */)
1719 .value(INJECTOR_KEY, this.injector)
1720 .factory(LAZY_MODULE_REF, [INJECTOR_KEY, (injector) => ({ injector })])
1721 .config([
1722 $PROVIDE, $INJECTOR,
1723 ($provide, $injector) => {
1724 if ($injector.has($$TESTABILITY)) {
1725 $provide.decorator($$TESTABILITY, [
1726 $DELEGATE,
1727 (testabilityDelegate) => {
1728 const originalWhenStable = testabilityDelegate.whenStable;
1729 const injector = this.injector;
1730 // Cannot use arrow function below because we need the context
1731 const newWhenStable = function (callback) {
1732 originalWhenStable.call(testabilityDelegate, function () {
1733 const ng2Testability = injector.get(Testability);
1734 if (ng2Testability.isStable()) {
1735 callback();
1736 }
1737 else {
1738 ng2Testability.whenStable(newWhenStable.bind(testabilityDelegate, callback));
1739 }
1740 });
1741 };
1742 testabilityDelegate.whenStable = newWhenStable;
1743 return testabilityDelegate;
1744 }
1745 ]);
1746 }
1747 if ($injector.has($INTERVAL)) {
1748 $provide.decorator($INTERVAL, [
1749 $DELEGATE,
1750 (intervalDelegate) => {
1751 // Wrap the $interval service so that setInterval is called outside NgZone,
1752 // but the callback is still invoked within it. This is so that $interval
1753 // won't block stability, which preserves the behavior from AngularJS.
1754 let wrappedInterval = (fn, delay, count, invokeApply, ...pass) => {
1755 return this.ngZone.runOutsideAngular(() => {
1756 return intervalDelegate((...args) => {
1757 // Run callback in the next VM turn - $interval calls
1758 // $rootScope.$apply, and running the callback in NgZone will
1759 // cause a '$digest already in progress' error if it's in the
1760 // same vm turn.
1761 setTimeout(() => {
1762 this.ngZone.run(() => fn(...args));
1763 });
1764 }, delay, count, invokeApply, ...pass);
1765 });
1766 };
1767 wrappedInterval['cancel'] = intervalDelegate.cancel;
1768 return wrappedInterval;
1769 }
1770 ]);
1771 }
1772 }
1773 ])
1774 .run([
1775 $INJECTOR,
1776 ($injector) => {
1777 this.$injector = $injector;
1778 // Initialize the ng1 $injector provider
1779 setTempInjectorRef($injector);
1780 this.injector.get($INJECTOR);
1781 // Put the injector on the DOM, so that it can be "required"
1782 element(element$1).data(controllerKey(INJECTOR_KEY), this.injector);
1783 // Wire up the ng1 rootScope to run a digest cycle whenever the zone settles
1784 // We need to do this in the next tick so that we don't prevent the bootup
1785 // stabilizing
1786 setTimeout(() => {
1787 const $rootScope = $injector.get('$rootScope');
1788 const subscription = this.ngZone.onMicrotaskEmpty.subscribe(() => {
1789 if ($rootScope.$$phase) {
1790 if (isDevMode()) {
1791 console.warn('A digest was triggered while one was already in progress. This may mean that something is triggering digests outside the Angular zone.');
1792 }
1793 return $rootScope.$evalAsync();
1794 }
1795 return $rootScope.$digest();
1796 });
1797 $rootScope.$on('$destroy', () => {
1798 subscription.unsubscribe();
1799 });
1800 }, 0);
1801 }
1802 ]);
1803 const upgradeModule = module_(UPGRADE_MODULE_NAME, [INIT_MODULE_NAME].concat(modules));
1804 // Make sure resumeBootstrap() only exists if the current bootstrap is deferred
1805 const windowAngular = window['angular'];
1806 windowAngular.resumeBootstrap = undefined;
1807 // Bootstrap the AngularJS application inside our zone
1808 this.ngZone.run(() => {
1809 bootstrap(element$1, [upgradeModule.name], config);
1810 });
1811 // Patch resumeBootstrap() to run inside the ngZone
1812 if (windowAngular.resumeBootstrap) {
1813 const originalResumeBootstrap = windowAngular.resumeBootstrap;
1814 const ngZone = this.ngZone;
1815 windowAngular.resumeBootstrap = function () {
1816 let args = arguments;
1817 windowAngular.resumeBootstrap = originalResumeBootstrap;
1818 return ngZone.run(() => windowAngular.resumeBootstrap.apply(this, args));
1819 };
1820 }
1821 }
1822}
1823UpgradeModule.decorators = [
1824 { type: NgModule, args: [{ providers: [angular1Providers] },] }
1825];
1826UpgradeModule.ctorParameters = () => [
1827 { type: Injector },
1828 { type: NgZone }
1829];
1830
1831/**
1832 * @license
1833 * Copyright Google LLC All Rights Reserved.
1834 *
1835 * Use of this source code is governed by an MIT-style license that can be
1836 * found in the LICENSE file at https://angular.io/license
1837 */
1838// This file only re-exports items to appear in the public api. Keep it that way.
1839
1840/**
1841 * @license
1842 * Copyright Google LLC All Rights Reserved.
1843 *
1844 * Use of this source code is governed by an MIT-style license that can be
1845 * found in the LICENSE file at https://angular.io/license
1846 */
1847
1848/**
1849 * Generated bundle index. Do not edit.
1850 */
1851
1852export { UpgradeComponent, UpgradeModule, VERSION, downgradeComponent, downgradeInjectable, downgradeModule, getAngularJSGlobal, getAngularLib, setAngularJSGlobal, setAngularLib, injectorFactory as ɵangular_packages_upgrade_static_static_a, rootScopeFactory as ɵangular_packages_upgrade_static_static_b, compileFactory as ɵangular_packages_upgrade_static_static_c, parseFactory as ɵangular_packages_upgrade_static_static_d, angular1Providers as ɵangular_packages_upgrade_static_static_e };
1853//# sourceMappingURL=static.js.map