Skip to content

Instantly share code, notes, and snippets.

@bmeurer
Last active January 28, 2019 10:55
Show Gist options
  • Save bmeurer/5b9480ef1a74c5187180193abc73dcd4 to your computer and use it in GitHub Desktop.
Save bmeurer/5b9480ef1a74c5187180193abc73dcd4 to your computer and use it in GitHub Desktop.
Angular Universal Prerendering test case
--- dist/prerender_ORIG.js 2019-01-28 11:32:34.000000000 +0100
+++ dist/prerender.js 2019-01-28 11:33:58.000000000 +0100
@@ -88604,66 +88604,7 @@
serialize: { value: function() {
var s = '';
for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {
- s += kid._serializeOne(this);
- }
- return s;
- }},
- _serializeOne: { value: function(parent) {
- var kid = this, s = '';
- switch(kid.nodeType) {
- case 1: //ELEMENT_NODE
- var ns = kid.namespaceURI;
- var html = ns === NAMESPACE.HTML;
- var tagname = (html || ns === NAMESPACE.SVG || ns === NAMESPACE.MATHML) ? kid.localName : kid.tagName;
-
- s += '<' + tagname;
-
- for(var j = 0, k = kid._numattrs; j < k; j++) {
- var a = kid._attr(j);
- s += ' ' + attrname(a);
- if (a.value !== undefined) s += '="' + escapeAttr(a.value) + '"';
- }
- s += '>';
-
- if (!(html && emptyElements[tagname])) {
- var ss = kid.serialize();
- if (html && extraNewLine[tagname] && ss.charAt(0)==='\n') s += '\n';
- // Serialize children and add end tag for all others
- s += ss;
- s += '</' + tagname + '>';
- }
- break;
- case 3: //TEXT_NODE
- case 4: //CDATA_SECTION_NODE
- var parenttag;
- if (parent.nodeType === ELEMENT_NODE &&
- parent.namespaceURI === NAMESPACE.HTML)
- parenttag = parent.tagName;
- else
- parenttag = '';
-
- if (hasRawContent[parenttag] ||
- (parenttag==='NOSCRIPT' && parent.ownerDocument._scripting_enabled)) {
- s += kid.data;
- } else {
- s += escape(kid.data);
- }
- break;
- case 8: //COMMENT_NODE
- s += '<!--' + kid.data + '-->';
- break;
- case 7: //PROCESSING_INSTRUCTION_NODE
- s += '<?' + kid.target + ' ' + kid.data + '?>';
- break;
- case 10: //DOCUMENT_TYPE_NODE
- s += '<!DOCTYPE ' + kid.name;
-
- if (false) {}
-
- s += '>';
- break;
- default:
- utils.InvalidState();
+ s += _serializeOne(kid, this);
}
return s;
}},
@@ -88671,7 +88612,7 @@
// Non-standard, but often useful for debugging.
outerHTML: {
get: function() {
- return this._serializeOne({ nodeType: 0 });
+ return _serializeOne(this, { nodeType: 0 });
},
set: utils.nyi,
},
@@ -88699,6 +88640,66 @@
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: { value: DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC },
});
+function _serializeOne(kid, parent) {
+ var s = '';
+ switch(kid.nodeType) {
+ case 1: //ELEMENT_NODE
+ var ns = kid.namespaceURI;
+ var html = ns === NAMESPACE.HTML;
+ var tagname = (html || ns === NAMESPACE.SVG || ns === NAMESPACE.MATHML) ? kid.localName : kid.tagName;
+
+ s += '<' + tagname;
+
+ for(var j = 0, k = kid._numattrs; j < k; j++) {
+ var a = kid._attr(j);
+ s += ' ' + attrname(a);
+ if (a.value !== undefined) s += '="' + escapeAttr(a.value) + '"';
+ }
+ s += '>';
+
+ if (!(html && emptyElements[tagname])) {
+ var ss = kid.serialize();
+ if (html && extraNewLine[tagname] && ss.charAt(0)==='\n') s += '\n';
+ // Serialize children and add end tag for all others
+ s += ss;
+ s += '</' + tagname + '>';
+ }
+ break;
+ case 3: //TEXT_NODE
+ case 4: //CDATA_SECTION_NODE
+ var parenttag;
+ if (parent.nodeType === ELEMENT_NODE &&
+ parent.namespaceURI === NAMESPACE.HTML)
+ parenttag = parent.tagName;
+ else
+ parenttag = '';
+
+ if (hasRawContent[parenttag] ||
+ (parenttag==='NOSCRIPT' && parent.ownerDocument._scripting_enabled)) {
+ s += kid.data;
+ } else {
+ s += escape(kid.data);
+ }
+ break;
+ case 8: //COMMENT_NODE
+ s += '<!--' + kid.data + '-->';
+ break;
+ case 7: //PROCESSING_INSTRUCTION_NODE
+ s += '<?' + kid.target + ' ' + kid.data + '?>';
+ break;
+ case 10: //DOCUMENT_TYPE_NODE
+ s += '<!DOCTYPE ' + kid.name;
+
+ if (false) {}
+
+ s += '>';
+ break;
+ default:
+ utils.InvalidState();
+ }
+ return s;
+}
+
function escape(s) {
return s.replace(/[&<>\u00A0]/g, function(c) {
switch(c) {
@@ -89701,6 +89702,66 @@
}
}
+function _serializeOne(kid, parent) {
+ var s = '';
+ switch(kid.nodeType) {
+ case 1: //ELEMENT_NODE
+ var ns = kid.namespaceURI;
+ var html = ns === NAMESPACE.HTML;
+ var tagname = (html || ns === NAMESPACE.SVG || ns === NAMESPACE.MATHML) ? kid.localName : kid.tagName;
+
+ s += '<' + tagname;
+
+ for(var j = 0, k = kid._numattrs; j < k; j++) {
+ var a = kid._attr(j);
+ s += ' ' + attrname(a);
+ if (a.value !== undefined) s += '="' + escapeAttr(a.value) + '"';
+ }
+ s += '>';
+
+ if (!(html && emptyElements[tagname])) {
+ var ss = kid.serialize();
+ if (html && extraNewLine[tagname] && ss.charAt(0)==='\n') s += '\n';
+ // Serialize children and add end tag for all others
+ s += ss;
+ s += '</' + tagname + '>';
+ }
+ break;
+ case 3: //TEXT_NODE
+ case 4: //CDATA_SECTION_NODE
+ var parenttag;
+ if (parent.nodeType === ELEMENT_NODE &&
+ parent.namespaceURI === NAMESPACE.HTML)
+ parenttag = parent.tagName;
+ else
+ parenttag = '';
+
+ if (hasRawContent[parenttag] ||
+ (parenttag==='NOSCRIPT' && parent.ownerDocument._scripting_enabled)) {
+ s += kid.data;
+ } else {
+ s += escape(kid.data);
+ }
+ break;
+ case 8: //COMMENT_NODE
+ s += '<!--' + kid.data + '-->';
+ break;
+ case 7: //PROCESSING_INSTRUCTION_NODE
+ s += '<?' + kid.target + ' ' + kid.data + '?>';
+ break;
+ case 10: //DOCUMENT_TYPE_NODE
+ s += '<!DOCTYPE ' + kid.name;
+
+ if (false) {}
+
+ s += '>';
+ break;
+ default:
+ utils.InvalidState();
+ }
+ return s;
+}
+
Element.prototype = Object.create(ContainerNode.prototype, {
isHTML: { get: function isHTML() {
return this.namespaceURI === NAMESPACE.HTML && this.ownerDocument.isHTML;
@@ -89756,7 +89817,7 @@
// "the attribute must return the result of running the HTML fragment
// serialization algorithm on a fictional node whose only child is
// the context object"
- return this._serializeOne({ nodeType: 0 });
+ return _serializeOne(this, { nodeType: 0 });
},
set: function(v) {
var document = this.ownerDocument;
This file has been truncated, but you can view the full file.
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var zone_js_dist_zone_node__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var zone_js_dist_zone_node__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(zone_js_dist_zone_node__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
/* harmony import */ var _angular_platform_server__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(208);
/* harmony import */ var _dist_prerender_main__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(276);
/* harmony import */ var _dist_prerender_main__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_dist_prerender_main__WEBPACK_IMPORTED_MODULE_3__);
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (undefined && undefined.__generator) || function (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 };
}
};
Object(_angular_core__WEBPACK_IMPORTED_MODULE_1__["enableProdMode"])();
var document = __webpack_require__(285);
var routes = ['/dashboard', '/heroes', '/detail/12'];
function driver(n, urls) {
return __awaiter(this, void 0, void 0, function () {
var startTime, i, _i, urls_1, url;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
startTime = Date.now();
i = 0;
_a.label = 1;
case 1:
if (!(i < n)) return [3 /*break*/, 6];
_i = 0, urls_1 = urls;
_a.label = 2;
case 2:
if (!(_i < urls_1.length)) return [3 /*break*/, 5];
url = urls_1[_i];
return [4 /*yield*/, Object(_angular_platform_server__WEBPACK_IMPORTED_MODULE_2__["renderModuleFactory"])(_dist_prerender_main__WEBPACK_IMPORTED_MODULE_3__["AppPrerenderModuleNgFactory"], { url: url, document: document })];
case 3:
_a.sent();
_a.label = 4;
case 4:
_i++;
return [3 /*break*/, 2];
case 5:
++i;
return [3 /*break*/, 1];
case 6: return [2 /*return*/, Date.now() - startTime];
}
});
});
}
function main() {
return __awaiter(this, void 0, void 0, function () {
var time;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
// Warmup
console.log('Warming up...');
return [4 /*yield*/, driver(1, routes)];
case 1:
_a.sent();
return [4 /*yield*/, driver(10, routes)];
case 2:
_a.sent();
return [4 /*yield*/, driver(100, routes)];
case 3:
_a.sent();
console.log('Warmed up...');
return [4 /*yield*/, driver(1000, routes)];
case 4:
time = _a.sent();
console.log("Time: " + time + " ms.");
return [2 /*return*/];
}
});
});
}
main().catch(console.error);
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
(function (global, factory) {
true ? factory() :
undefined;
}(this, (function () { 'use strict';
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var Zone$1 = (function (global) {
var performance = global['performance'];
function mark(name) {
performance && performance['mark'] && performance['mark'](name);
}
function performanceMeasure(name, label) {
performance && performance['measure'] && performance['measure'](name, label);
}
mark('Zone');
var checkDuplicate = global[('__zone_symbol__forceDuplicateZoneCheck')] === true;
if (global['Zone']) {
// if global['Zone'] already exists (maybe zone.js was already loaded or
// some other lib also registered a global object named Zone), we may need
// to throw an error, but sometimes user may not want this error.
// For example,
// we have two web pages, page1 includes zone.js, page2 doesn't.
// and the 1st time user load page1 and page2, everything work fine,
// but when user load page2 again, error occurs because global['Zone'] already exists.
// so we add a flag to let user choose whether to throw this error or not.
// By default, if existing Zone is from zone.js, we will not throw the error.
if (checkDuplicate || typeof global['Zone'].__symbol__ !== 'function') {
throw new Error('Zone already loaded.');
}
else {
return global['Zone'];
}
}
var Zone = /** @class */ (function () {
function Zone(parent, zoneSpec) {
this._parent = parent;
this._name = zoneSpec ? zoneSpec.name || 'unnamed' : '<root>';
this._properties = zoneSpec && zoneSpec.properties || {};
this._zoneDelegate =
new ZoneDelegate(this, this._parent && this._parent._zoneDelegate, zoneSpec);
}
Zone.assertZonePatched = function () {
if (global['Promise'] !== patches['ZoneAwarePromise']) {
throw new Error('Zone.js has detected that ZoneAwarePromise `(window|global).Promise` ' +
'has been overwritten.\n' +
'Most likely cause is that a Promise polyfill has been loaded ' +
'after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. ' +
'If you must load one, do so before loading zone.js.)');
}
};
Object.defineProperty(Zone, "root", {
get: function () {
var zone = Zone.current;
while (zone.parent) {
zone = zone.parent;
}
return zone;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Zone, "current", {
get: function () {
return _currentZoneFrame.zone;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Zone, "currentTask", {
get: function () {
return _currentTask;
},
enumerable: true,
configurable: true
});
Zone.__load_patch = function (name, fn) {
if (patches.hasOwnProperty(name)) {
if (checkDuplicate) {
throw Error('Already loaded patch: ' + name);
}
}
else if (!global['__Zone_disable_' + name]) {
var perfName = 'Zone:' + name;
mark(perfName);
patches[name] = fn(global, Zone, _api);
performanceMeasure(perfName, perfName);
}
};
Object.defineProperty(Zone.prototype, "parent", {
get: function () {
return this._parent;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Zone.prototype, "name", {
get: function () {
return this._name;
},
enumerable: true,
configurable: true
});
Zone.prototype.get = function (key) {
var zone = this.getZoneWith(key);
if (zone)
return zone._properties[key];
};
Zone.prototype.getZoneWith = function (key) {
var current = this;
while (current) {
if (current._properties.hasOwnProperty(key)) {
return current;
}
current = current._parent;
}
return null;
};
Zone.prototype.fork = function (zoneSpec) {
if (!zoneSpec)
throw new Error('ZoneSpec required!');
return this._zoneDelegate.fork(this, zoneSpec);
};
Zone.prototype.wrap = function (callback, source) {
if (typeof callback !== 'function') {
throw new Error('Expecting function got: ' + callback);
}
var _callback = this._zoneDelegate.intercept(this, callback, source);
var zone = this;
return function () {
return zone.runGuarded(_callback, this, arguments, source);
};
};
Zone.prototype.run = function (callback, applyThis, applyArgs, source) {
_currentZoneFrame = { parent: _currentZoneFrame, zone: this };
try {
return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);
}
finally {
_currentZoneFrame = _currentZoneFrame.parent;
}
};
Zone.prototype.runGuarded = function (callback, applyThis, applyArgs, source) {
if (applyThis === void 0) { applyThis = null; }
_currentZoneFrame = { parent: _currentZoneFrame, zone: this };
try {
try {
return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);
}
catch (error) {
if (this._zoneDelegate.handleError(this, error)) {
throw error;
}
}
}
finally {
_currentZoneFrame = _currentZoneFrame.parent;
}
};
Zone.prototype.runTask = function (task, applyThis, applyArgs) {
if (task.zone != this) {
throw new Error('A task can only be run in the zone of creation! (Creation: ' +
(task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');
}
// https://github.com/angular/zone.js/issues/778, sometimes eventTask
// will run in notScheduled(canceled) state, we should not try to
// run such kind of task but just return
if (task.state === notScheduled && (task.type === eventTask || task.type === macroTask)) {
return;
}
var reEntryGuard = task.state != running;
reEntryGuard && task._transitionTo(running, scheduled);
task.runCount++;
var previousTask = _currentTask;
_currentTask = task;
_currentZoneFrame = { parent: _currentZoneFrame, zone: this };
try {
if (task.type == macroTask && task.data && !task.data.isPeriodic) {
task.cancelFn = undefined;
}
try {
return this._zoneDelegate.invokeTask(this, task, applyThis, applyArgs);
}
catch (error) {
if (this._zoneDelegate.handleError(this, error)) {
throw error;
}
}
}
finally {
// if the task's state is notScheduled or unknown, then it has already been cancelled
// we should not reset the state to scheduled
if (task.state !== notScheduled && task.state !== unknown) {
if (task.type == eventTask || (task.data && task.data.isPeriodic)) {
reEntryGuard && task._transitionTo(scheduled, running);
}
else {
task.runCount = 0;
this._updateTaskCount(task, -1);
reEntryGuard &&
task._transitionTo(notScheduled, running, notScheduled);
}
}
_currentZoneFrame = _currentZoneFrame.parent;
_currentTask = previousTask;
}
};
Zone.prototype.scheduleTask = function (task) {
if (task.zone && task.zone !== this) {
// check if the task was rescheduled, the newZone
// should not be the children of the original zone
var newZone = this;
while (newZone) {
if (newZone === task.zone) {
throw Error("can not reschedule task to " + this.name + " which is descendants of the original zone " + task.zone.name);
}
newZone = newZone.parent;
}
}
task._transitionTo(scheduling, notScheduled);
var zoneDelegates = [];
task._zoneDelegates = zoneDelegates;
task._zone = this;
try {
task = this._zoneDelegate.scheduleTask(this, task);
}
catch (err) {
// should set task's state to unknown when scheduleTask throw error
// because the err may from reschedule, so the fromState maybe notScheduled
task._transitionTo(unknown, scheduling, notScheduled);
// TODO: @JiaLiPassion, should we check the result from handleError?
this._zoneDelegate.handleError(this, err);
throw err;
}
if (task._zoneDelegates === zoneDelegates) {
// we have to check because internally the delegate can reschedule the task.
this._updateTaskCount(task, 1);
}
if (task.state == scheduling) {
task._transitionTo(scheduled, scheduling);
}
return task;
};
Zone.prototype.scheduleMicroTask = function (source, callback, data, customSchedule) {
return this.scheduleTask(new ZoneTask(microTask, source, callback, data, customSchedule, undefined));
};
Zone.prototype.scheduleMacroTask = function (source, callback, data, customSchedule, customCancel) {
return this.scheduleTask(new ZoneTask(macroTask, source, callback, data, customSchedule, customCancel));
};
Zone.prototype.scheduleEventTask = function (source, callback, data, customSchedule, customCancel) {
return this.scheduleTask(new ZoneTask(eventTask, source, callback, data, customSchedule, customCancel));
};
Zone.prototype.cancelTask = function (task) {
if (task.zone != this)
throw new Error('A task can only be cancelled in the zone of creation! (Creation: ' +
(task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');
task._transitionTo(canceling, scheduled, running);
try {
this._zoneDelegate.cancelTask(this, task);
}
catch (err) {
// if error occurs when cancelTask, transit the state to unknown
task._transitionTo(unknown, canceling);
this._zoneDelegate.handleError(this, err);
throw err;
}
this._updateTaskCount(task, -1);
task._transitionTo(notScheduled, canceling);
task.runCount = 0;
return task;
};
Zone.prototype._updateTaskCount = function (task, count) {
var zoneDelegates = task._zoneDelegates;
if (count == -1) {
task._zoneDelegates = null;
}
for (var i = 0; i < zoneDelegates.length; i++) {
zoneDelegates[i]._updateTaskCount(task.type, count);
}
};
Zone.__symbol__ = __symbol__;
return Zone;
}());
var DELEGATE_ZS = {
name: '',
onHasTask: function (delegate, _, target, hasTaskState) { return delegate.hasTask(target, hasTaskState); },
onScheduleTask: function (delegate, _, target, task) {
return delegate.scheduleTask(target, task);
},
onInvokeTask: function (delegate, _, target, task, applyThis, applyArgs) {
return delegate.invokeTask(target, task, applyThis, applyArgs);
},
onCancelTask: function (delegate, _, target, task) { return delegate.cancelTask(target, task); }
};
var ZoneDelegate = /** @class */ (function () {
function ZoneDelegate(zone, parentDelegate, zoneSpec) {
this._taskCounts = { 'microTask': 0, 'macroTask': 0, 'eventTask': 0 };
this.zone = zone;
this._parentDelegate = parentDelegate;
this._forkZS = zoneSpec && (zoneSpec && zoneSpec.onFork ? zoneSpec : parentDelegate._forkZS);
this._forkDlgt = zoneSpec && (zoneSpec.onFork ? parentDelegate : parentDelegate._forkDlgt);
this._forkCurrZone = zoneSpec && (zoneSpec.onFork ? this.zone : parentDelegate.zone);
this._interceptZS =
zoneSpec && (zoneSpec.onIntercept ? zoneSpec : parentDelegate._interceptZS);
this._interceptDlgt =
zoneSpec && (zoneSpec.onIntercept ? parentDelegate : parentDelegate._interceptDlgt);
this._interceptCurrZone =
zoneSpec && (zoneSpec.onIntercept ? this.zone : parentDelegate.zone);
this._invokeZS = zoneSpec && (zoneSpec.onInvoke ? zoneSpec : parentDelegate._invokeZS);
this._invokeDlgt =
zoneSpec && (zoneSpec.onInvoke ? parentDelegate : parentDelegate._invokeDlgt);
this._invokeCurrZone = zoneSpec && (zoneSpec.onInvoke ? this.zone : parentDelegate.zone);
this._handleErrorZS =
zoneSpec && (zoneSpec.onHandleError ? zoneSpec : parentDelegate._handleErrorZS);
this._handleErrorDlgt =
zoneSpec && (zoneSpec.onHandleError ? parentDelegate : parentDelegate._handleErrorDlgt);
this._handleErrorCurrZone =
zoneSpec && (zoneSpec.onHandleError ? this.zone : parentDelegate.zone);
this._scheduleTaskZS =
zoneSpec && (zoneSpec.onScheduleTask ? zoneSpec : parentDelegate._scheduleTaskZS);
this._scheduleTaskDlgt = zoneSpec &&
(zoneSpec.onScheduleTask ? parentDelegate : parentDelegate._scheduleTaskDlgt);
this._scheduleTaskCurrZone =
zoneSpec && (zoneSpec.onScheduleTask ? this.zone : parentDelegate.zone);
this._invokeTaskZS =
zoneSpec && (zoneSpec.onInvokeTask ? zoneSpec : parentDelegate._invokeTaskZS);
this._invokeTaskDlgt =
zoneSpec && (zoneSpec.onInvokeTask ? parentDelegate : parentDelegate._invokeTaskDlgt);
this._invokeTaskCurrZone =
zoneSpec && (zoneSpec.onInvokeTask ? this.zone : parentDelegate.zone);
this._cancelTaskZS =
zoneSpec && (zoneSpec.onCancelTask ? zoneSpec : parentDelegate._cancelTaskZS);
this._cancelTaskDlgt =
zoneSpec && (zoneSpec.onCancelTask ? parentDelegate : parentDelegate._cancelTaskDlgt);
this._cancelTaskCurrZone =
zoneSpec && (zoneSpec.onCancelTask ? this.zone : parentDelegate.zone);
this._hasTaskZS = null;
this._hasTaskDlgt = null;
this._hasTaskDlgtOwner = null;
this._hasTaskCurrZone = null;
var zoneSpecHasTask = zoneSpec && zoneSpec.onHasTask;
var parentHasTask = parentDelegate && parentDelegate._hasTaskZS;
if (zoneSpecHasTask || parentHasTask) {
// If we need to report hasTask, than this ZS needs to do ref counting on tasks. In such
// a case all task related interceptors must go through this ZD. We can't short circuit it.
this._hasTaskZS = zoneSpecHasTask ? zoneSpec : DELEGATE_ZS;
this._hasTaskDlgt = parentDelegate;
this._hasTaskDlgtOwner = this;
this._hasTaskCurrZone = zone;
if (!zoneSpec.onScheduleTask) {
this._scheduleTaskZS = DELEGATE_ZS;
this._scheduleTaskDlgt = parentDelegate;
this._scheduleTaskCurrZone = this.zone;
}
if (!zoneSpec.onInvokeTask) {
this._invokeTaskZS = DELEGATE_ZS;
this._invokeTaskDlgt = parentDelegate;
this._invokeTaskCurrZone = this.zone;
}
if (!zoneSpec.onCancelTask) {
this._cancelTaskZS = DELEGATE_ZS;
this._cancelTaskDlgt = parentDelegate;
this._cancelTaskCurrZone = this.zone;
}
}
}
ZoneDelegate.prototype.fork = function (targetZone, zoneSpec) {
return this._forkZS ? this._forkZS.onFork(this._forkDlgt, this.zone, targetZone, zoneSpec) :
new Zone(targetZone, zoneSpec);
};
ZoneDelegate.prototype.intercept = function (targetZone, callback, source) {
return this._interceptZS ?
this._interceptZS.onIntercept(this._interceptDlgt, this._interceptCurrZone, targetZone, callback, source) :
callback;
};
ZoneDelegate.prototype.invoke = function (targetZone, callback, applyThis, applyArgs, source) {
return this._invokeZS ? this._invokeZS.onInvoke(this._invokeDlgt, this._invokeCurrZone, targetZone, callback, applyThis, applyArgs, source) :
callback.apply(applyThis, applyArgs);
};
ZoneDelegate.prototype.handleError = function (targetZone, error) {
return this._handleErrorZS ?
this._handleErrorZS.onHandleError(this._handleErrorDlgt, this._handleErrorCurrZone, targetZone, error) :
true;
};
ZoneDelegate.prototype.scheduleTask = function (targetZone, task) {
var returnTask = task;
if (this._scheduleTaskZS) {
if (this._hasTaskZS) {
returnTask._zoneDelegates.push(this._hasTaskDlgtOwner);
}
returnTask = this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt, this._scheduleTaskCurrZone, targetZone, task);
if (!returnTask)
returnTask = task;
}
else {
if (task.scheduleFn) {
task.scheduleFn(task);
}
else if (task.type == microTask) {
scheduleMicroTask(task);
}
else {
throw new Error('Task is missing scheduleFn.');
}
}
return returnTask;
};
ZoneDelegate.prototype.invokeTask = function (targetZone, task, applyThis, applyArgs) {
return this._invokeTaskZS ? this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt, this._invokeTaskCurrZone, targetZone, task, applyThis, applyArgs) :
task.callback.apply(applyThis, applyArgs);
};
ZoneDelegate.prototype.cancelTask = function (targetZone, task) {
var value;
if (this._cancelTaskZS) {
value = this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt, this._cancelTaskCurrZone, targetZone, task);
}
else {
if (!task.cancelFn) {
throw Error('Task is not cancelable');
}
value = task.cancelFn(task);
}
return value;
};
ZoneDelegate.prototype.hasTask = function (targetZone, isEmpty) {
// hasTask should not throw error so other ZoneDelegate
// can still trigger hasTask callback
try {
this._hasTaskZS &&
this._hasTaskZS.onHasTask(this._hasTaskDlgt, this._hasTaskCurrZone, targetZone, isEmpty);
}
catch (err) {
this.handleError(targetZone, err);
}
};
ZoneDelegate.prototype._updateTaskCount = function (type, count) {
var counts = this._taskCounts;
var prev = counts[type];
var next = counts[type] = prev + count;
if (next < 0) {
throw new Error('More tasks executed then were scheduled.');
}
if (prev == 0 || next == 0) {
var isEmpty = {
microTask: counts['microTask'] > 0,
macroTask: counts['macroTask'] > 0,
eventTask: counts['eventTask'] > 0,
change: type
};
this.hasTask(this.zone, isEmpty);
}
};
return ZoneDelegate;
}());
var ZoneTask = /** @class */ (function () {
function ZoneTask(type, source, callback, options, scheduleFn, cancelFn) {
this._zone = null;
this.runCount = 0;
this._zoneDelegates = null;
this._state = 'notScheduled';
this.type = type;
this.source = source;
this.data = options;
this.scheduleFn = scheduleFn;
this.cancelFn = cancelFn;
this.callback = callback;
var self = this;
// TODO: @JiaLiPassion options should have interface
if (type === eventTask && options && options.useG) {
this.invoke = ZoneTask.invokeTask;
}
else {
this.invoke = function () {
return ZoneTask.invokeTask.call(global, self, this, arguments);
};
}
}
ZoneTask.invokeTask = function (task, target, args) {
if (!task) {
task = this;
}
_numberOfNestedTaskFrames++;
try {
task.runCount++;
return task.zone.runTask(task, target, args);
}
finally {
if (_numberOfNestedTaskFrames == 1) {
drainMicroTaskQueue();
}
_numberOfNestedTaskFrames--;
}
};
Object.defineProperty(ZoneTask.prototype, "zone", {
get: function () {
return this._zone;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ZoneTask.prototype, "state", {
get: function () {
return this._state;
},
enumerable: true,
configurable: true
});
ZoneTask.prototype.cancelScheduleRequest = function () {
this._transitionTo(notScheduled, scheduling);
};
ZoneTask.prototype._transitionTo = function (toState, fromState1, fromState2) {
if (this._state === fromState1 || this._state === fromState2) {
this._state = toState;
if (toState == notScheduled) {
this._zoneDelegates = null;
}
}
else {
throw new Error(this.type + " '" + this.source + "': can not transition to '" + toState + "', expecting state '" + fromState1 + "'" + (fromState2 ? ' or \'' + fromState2 + '\'' : '') + ", was '" + this._state + "'.");
}
};
ZoneTask.prototype.toString = function () {
if (this.data && typeof this.data.handleId !== 'undefined') {
return this.data.handleId.toString();
}
else {
return Object.prototype.toString.call(this);
}
};
// add toJSON method to prevent cyclic error when
// call JSON.stringify(zoneTask)
ZoneTask.prototype.toJSON = function () {
return {
type: this.type,
state: this.state,
source: this.source,
zone: this.zone.name,
runCount: this.runCount
};
};
return ZoneTask;
}());
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
/// MICROTASK QUEUE
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
var symbolSetTimeout = __symbol__('setTimeout');
var symbolPromise = __symbol__('Promise');
var symbolThen = __symbol__('then');
var _microTaskQueue = [];
var _isDrainingMicrotaskQueue = false;
var nativeMicroTaskQueuePromise;
function scheduleMicroTask(task) {
// if we are not running in any task, and there has not been anything scheduled
// we must bootstrap the initial task creation by manually scheduling the drain
if (_numberOfNestedTaskFrames === 0 && _microTaskQueue.length === 0) {
// We are not running in Task, so we need to kickstart the microtask queue.
if (!nativeMicroTaskQueuePromise) {
if (global[symbolPromise]) {
nativeMicroTaskQueuePromise = global[symbolPromise].resolve(0);
}
}
if (nativeMicroTaskQueuePromise) {
var nativeThen = nativeMicroTaskQueuePromise[symbolThen];
if (!nativeThen) {
// native Promise is not patchable, we need to use `then` directly
// issue 1078
nativeThen = nativeMicroTaskQueuePromise['then'];
}
nativeThen.call(nativeMicroTaskQueuePromise, drainMicroTaskQueue);
}
else {
global[symbolSetTimeout](drainMicroTaskQueue, 0);
}
}
task && _microTaskQueue.push(task);
}
function drainMicroTaskQueue() {
if (!_isDrainingMicrotaskQueue) {
_isDrainingMicrotaskQueue = true;
while (_microTaskQueue.length) {
var queue = _microTaskQueue;
_microTaskQueue = [];
for (var i = 0; i < queue.length; i++) {
var task = queue[i];
try {
task.zone.runTask(task, null, null);
}
catch (error) {
_api.onUnhandledError(error);
}
}
}
_api.microtaskDrainDone();
_isDrainingMicrotaskQueue = false;
}
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
/// BOOTSTRAP
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
var NO_ZONE = { name: 'NO ZONE' };
var notScheduled = 'notScheduled', scheduling = 'scheduling', scheduled = 'scheduled', running = 'running', canceling = 'canceling', unknown = 'unknown';
var microTask = 'microTask', macroTask = 'macroTask', eventTask = 'eventTask';
var patches = {};
var _api = {
symbol: __symbol__,
currentZoneFrame: function () { return _currentZoneFrame; },
onUnhandledError: noop,
microtaskDrainDone: noop,
scheduleMicroTask: scheduleMicroTask,
showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; },
patchEventTarget: function () { return []; },
patchOnProperties: noop,
patchMethod: function () { return noop; },
bindArguments: function () { return []; },
patchThen: function () { return noop; },
setNativePromise: function (NativePromise) {
// sometimes NativePromise.resolve static function
// is not ready yet, (such as core-js/es6.promise)
// so we need to check here.
if (NativePromise && typeof NativePromise.resolve === 'function') {
nativeMicroTaskQueuePromise = NativePromise.resolve(0);
}
},
};
var _currentZoneFrame = { parent: null, zone: new Zone(null, null) };
var _currentTask = null;
var _numberOfNestedTaskFrames = 0;
function noop() { }
function __symbol__(name) {
return '__zone_symbol__' + name;
}
performanceMeasure('Zone', 'Zone');
return global['Zone'] = Zone;
})(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global);
var __values = (undefined && undefined.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Zone.__load_patch('ZoneAwarePromise', function (global, Zone, api) {
var ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var ObjectDefineProperty = Object.defineProperty;
function readableObjectToString(obj) {
if (obj && obj.toString === Object.prototype.toString) {
var className = obj.constructor && obj.constructor.name;
return (className ? className : '') + ': ' + JSON.stringify(obj);
}
return obj ? obj.toString() : Object.prototype.toString.call(obj);
}
var __symbol__ = api.symbol;
var _uncaughtPromiseErrors = [];
var symbolPromise = __symbol__('Promise');
var symbolThen = __symbol__('then');
var creationTrace = '__creationTrace__';
api.onUnhandledError = function (e) {
if (api.showUncaughtError()) {
var rejection = e && e.rejection;
if (rejection) {
console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined);
}
else {
console.error(e);
}
}
};
api.microtaskDrainDone = function () {
while (_uncaughtPromiseErrors.length) {
var _loop_1 = function () {
var uncaughtPromiseError = _uncaughtPromiseErrors.shift();
try {
uncaughtPromiseError.zone.runGuarded(function () {
throw uncaughtPromiseError;
});
}
catch (error) {
handleUnhandledRejection(error);
}
};
while (_uncaughtPromiseErrors.length) {
_loop_1();
}
}
};
var UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL = __symbol__('unhandledPromiseRejectionHandler');
function handleUnhandledRejection(e) {
api.onUnhandledError(e);
try {
var handler = Zone[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL];
if (handler && typeof handler === 'function') {
handler.call(this, e);
}
}
catch (err) {
}
}
function isThenable(value) {
return value && value.then;
}
function forwardResolution(value) {
return value;
}
function forwardRejection(rejection) {
return ZoneAwarePromise.reject(rejection);
}
var symbolState = __symbol__('state');
var symbolValue = __symbol__('value');
var symbolFinally = __symbol__('finally');
var symbolParentPromiseValue = __symbol__('parentPromiseValue');
var symbolParentPromiseState = __symbol__('parentPromiseState');
var source = 'Promise.then';
var UNRESOLVED = null;
var RESOLVED = true;
var REJECTED = false;
var REJECTED_NO_CATCH = 0;
function makeResolver(promise, state) {
return function (v) {
try {
resolvePromise(promise, state, v);
}
catch (err) {
resolvePromise(promise, false, err);
}
// Do not return value or you will break the Promise spec.
};
}
var once = function () {
var wasCalled = false;
return function wrapper(wrappedFunction) {
return function () {
if (wasCalled) {
return;
}
wasCalled = true;
wrappedFunction.apply(null, arguments);
};
};
};
var TYPE_ERROR = 'Promise resolved with itself';
var CURRENT_TASK_TRACE_SYMBOL = __symbol__('currentTaskTrace');
// Promise Resolution
function resolvePromise(promise, state, value) {
var onceWrapper = once();
if (promise === value) {
throw new TypeError(TYPE_ERROR);
}
if (promise[symbolState] === UNRESOLVED) {
// should only get value.then once based on promise spec.
var then = null;
try {
if (typeof value === 'object' || typeof value === 'function') {
then = value && value.then;
}
}
catch (err) {
onceWrapper(function () {
resolvePromise(promise, false, err);
})();
return promise;
}
// if (value instanceof ZoneAwarePromise) {
if (state !== REJECTED && value instanceof ZoneAwarePromise &&
value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) &&
value[symbolState] !== UNRESOLVED) {
clearRejectedNoCatch(value);
resolvePromise(promise, value[symbolState], value[symbolValue]);
}
else if (state !== REJECTED && typeof then === 'function') {
try {
then.call(value, onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)));
}
catch (err) {
onceWrapper(function () {
resolvePromise(promise, false, err);
})();
}
}
else {
promise[symbolState] = state;
var queue = promise[symbolValue];
promise[symbolValue] = value;
if (promise[symbolFinally] === symbolFinally) {
// the promise is generated by Promise.prototype.finally
if (state === RESOLVED) {
// the state is resolved, should ignore the value
// and use parent promise value
promise[symbolState] = promise[symbolParentPromiseState];
promise[symbolValue] = promise[symbolParentPromiseValue];
}
}
// record task information in value when error occurs, so we can
// do some additional work such as render longStackTrace
if (state === REJECTED && value instanceof Error) {
// check if longStackTraceZone is here
var trace = Zone.currentTask && Zone.currentTask.data &&
Zone.currentTask.data[creationTrace];
if (trace) {
// only keep the long stack trace into error when in longStackTraceZone
ObjectDefineProperty(value, CURRENT_TASK_TRACE_SYMBOL, { configurable: true, enumerable: false, writable: true, value: trace });
}
}
for (var i = 0; i < queue.length;) {
scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);
}
if (queue.length == 0 && state == REJECTED) {
promise[symbolState] = REJECTED_NO_CATCH;
try {
// try to print more readable error log
throw new Error('Uncaught (in promise): ' + readableObjectToString(value) +
(value && value.stack ? '\n' + value.stack : ''));
}
catch (err) {
var error_1 = err;
error_1.rejection = value;
error_1.promise = promise;
error_1.zone = Zone.current;
error_1.task = Zone.currentTask;
_uncaughtPromiseErrors.push(error_1);
api.scheduleMicroTask(); // to make sure that it is running
}
}
}
}
// Resolving an already resolved promise is a noop.
return promise;
}
var REJECTION_HANDLED_HANDLER = __symbol__('rejectionHandledHandler');
function clearRejectedNoCatch(promise) {
if (promise[symbolState] === REJECTED_NO_CATCH) {
// if the promise is rejected no catch status
// and queue.length > 0, means there is a error handler
// here to handle the rejected promise, we should trigger
// windows.rejectionhandled eventHandler or nodejs rejectionHandled
// eventHandler
try {
var handler = Zone[REJECTION_HANDLED_HANDLER];
if (handler && typeof handler === 'function') {
handler.call(this, { rejection: promise[symbolValue], promise: promise });
}
}
catch (err) {
}
promise[symbolState] = REJECTED;
for (var i = 0; i < _uncaughtPromiseErrors.length; i++) {
if (promise === _uncaughtPromiseErrors[i].promise) {
_uncaughtPromiseErrors.splice(i, 1);
}
}
}
}
function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) {
clearRejectedNoCatch(promise);
var promiseState = promise[symbolState];
var delegate = promiseState ?
(typeof onFulfilled === 'function') ? onFulfilled : forwardResolution :
(typeof onRejected === 'function') ? onRejected : forwardRejection;
zone.scheduleMicroTask(source, function () {
try {
var parentPromiseValue = promise[symbolValue];
var isFinallyPromise = chainPromise && symbolFinally === chainPromise[symbolFinally];
if (isFinallyPromise) {
// if the promise is generated from finally call, keep parent promise's state and value
chainPromise[symbolParentPromiseValue] = parentPromiseValue;
chainPromise[symbolParentPromiseState] = promiseState;
}
// should not pass value to finally callback
var value = zone.run(delegate, undefined, isFinallyPromise && delegate !== forwardRejection && delegate !== forwardResolution ?
[] :
[parentPromiseValue]);
resolvePromise(chainPromise, true, value);
}
catch (error) {
// if error occurs, should always return this error
resolvePromise(chainPromise, false, error);
}
}, chainPromise);
}
var ZONE_AWARE_PROMISE_TO_STRING = 'function ZoneAwarePromise() { [native code] }';
var ZoneAwarePromise = /** @class */ (function () {
function ZoneAwarePromise(executor) {
var promise = this;
if (!(promise instanceof ZoneAwarePromise)) {
throw new Error('Must be an instanceof Promise.');
}
promise[symbolState] = UNRESOLVED;
promise[symbolValue] = []; // queue;
try {
executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED));
}
catch (error) {
resolvePromise(promise, false, error);
}
}
ZoneAwarePromise.toString = function () {
return ZONE_AWARE_PROMISE_TO_STRING;
};
ZoneAwarePromise.resolve = function (value) {
return resolvePromise(new this(null), RESOLVED, value);
};
ZoneAwarePromise.reject = function (error) {
return resolvePromise(new this(null), REJECTED, error);
};
ZoneAwarePromise.race = function (values) {
var e_1, _a;
var resolve;
var reject;
var promise = new this(function (res, rej) {
resolve = res;
reject = rej;
});
function onResolve(value) {
promise && (promise = false || resolve(value));
}
function onReject(error) {
promise && (promise = false || reject(error));
}
try {
for (var values_1 = __values(values), values_1_1 = values_1.next(); !values_1_1.done; values_1_1 = values_1.next()) {
var value = values_1_1.value;
if (!isThenable(value)) {
value = this.resolve(value);
}
value.then(onResolve, onReject);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (values_1_1 && !values_1_1.done && (_a = values_1.return)) _a.call(values_1);
}
finally { if (e_1) throw e_1.error; }
}
return promise;
};
ZoneAwarePromise.all = function (values) {
var e_2, _a;
var resolve;
var reject;
var promise = new this(function (res, rej) {
resolve = res;
reject = rej;
});
// Start at 2 to prevent prematurely resolving if .then is called immediately.
var unresolvedCount = 2;
var valueIndex = 0;
var resolvedValues = [];
var _loop_2 = function (value) {
if (!isThenable(value)) {
value = this_1.resolve(value);
}
var curValueIndex = valueIndex;
value.then(function (value) {
resolvedValues[curValueIndex] = value;
unresolvedCount--;
if (unresolvedCount === 0) {
resolve(resolvedValues);
}
}, reject);
unresolvedCount++;
valueIndex++;
};
var this_1 = this;
try {
for (var values_2 = __values(values), values_2_1 = values_2.next(); !values_2_1.done; values_2_1 = values_2.next()) {
var value = values_2_1.value;
_loop_2(value);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (values_2_1 && !values_2_1.done && (_a = values_2.return)) _a.call(values_2);
}
finally { if (e_2) throw e_2.error; }
}
// Make the unresolvedCount zero-based again.
unresolvedCount -= 2;
if (unresolvedCount === 0) {
resolve(resolvedValues);
}
return promise;
};
ZoneAwarePromise.prototype.then = function (onFulfilled, onRejected) {
var chainPromise = new this.constructor(null);
var zone = Zone.current;
if (this[symbolState] == UNRESOLVED) {
this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected);
}
else {
scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected);
}
return chainPromise;
};
ZoneAwarePromise.prototype.catch = function (onRejected) {
return this.then(null, onRejected);
};
ZoneAwarePromise.prototype.finally = function (onFinally) {
var chainPromise = new this.constructor(null);
chainPromise[symbolFinally] = symbolFinally;
var zone = Zone.current;
if (this[symbolState] == UNRESOLVED) {
this[symbolValue].push(zone, chainPromise, onFinally, onFinally);
}
else {
scheduleResolveOrReject(this, zone, chainPromise, onFinally, onFinally);
}
return chainPromise;
};
return ZoneAwarePromise;
}());
// Protect against aggressive optimizers dropping seemingly unused properties.
// E.g. Closure Compiler in advanced mode.
ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve;
ZoneAwarePromise['reject'] = ZoneAwarePromise.reject;
ZoneAwarePromise['race'] = ZoneAwarePromise.race;
ZoneAwarePromise['all'] = ZoneAwarePromise.all;
var NativePromise = global[symbolPromise] = global['Promise'];
var ZONE_AWARE_PROMISE = Zone.__symbol__('ZoneAwarePromise');
var desc = ObjectGetOwnPropertyDescriptor(global, 'Promise');
if (!desc || desc.configurable) {
desc && delete desc.writable;
desc && delete desc.value;
if (!desc) {
desc = { configurable: true, enumerable: true };
}
desc.get = function () {
// if we already set ZoneAwarePromise, use patched one
// otherwise return native one.
return global[ZONE_AWARE_PROMISE] ? global[ZONE_AWARE_PROMISE] : global[symbolPromise];
};
desc.set = function (NewNativePromise) {
if (NewNativePromise === ZoneAwarePromise) {
// if the NewNativePromise is ZoneAwarePromise
// save to global
global[ZONE_AWARE_PROMISE] = NewNativePromise;
}
else {
// if the NewNativePromise is not ZoneAwarePromise
// for example: after load zone.js, some library just
// set es6-promise to global, if we set it to global
// directly, assertZonePatched will fail and angular
// will not loaded, so we just set the NewNativePromise
// to global[symbolPromise], so the result is just like
// we load ES6 Promise before zone.js
global[symbolPromise] = NewNativePromise;
if (!NewNativePromise.prototype[symbolThen]) {
patchThen(NewNativePromise);
}
api.setNativePromise(NewNativePromise);
}
};
ObjectDefineProperty(global, 'Promise', desc);
}
global['Promise'] = ZoneAwarePromise;
var symbolThenPatched = __symbol__('thenPatched');
function patchThen(Ctor) {
var proto = Ctor.prototype;
var prop = ObjectGetOwnPropertyDescriptor(proto, 'then');
if (prop && (prop.writable === false || !prop.configurable)) {
// check Ctor.prototype.then propertyDescriptor is writable or not
// in meteor env, writable is false, we should ignore such case
return;
}
var originalThen = proto.then;
// Keep a reference to the original method.
proto[symbolThen] = originalThen;
Ctor.prototype.then = function (onResolve, onReject) {
var _this = this;
var wrapped = new ZoneAwarePromise(function (resolve, reject) {
originalThen.call(_this, resolve, reject);
});
return wrapped.then(onResolve, onReject);
};
Ctor[symbolThenPatched] = true;
}
api.patchThen = patchThen;
if (NativePromise) {
patchThen(NativePromise);
}
// This is not part of public API, but it is useful for tests, so we expose it.
Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;
return ZoneAwarePromise;
});
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Suppress closure compiler errors about unknown 'Zone' variable
* @fileoverview
* @suppress {undefinedVars,globalThis,missingRequire}
*/
// issue #989, to reduce bundle size, use short name
/** Object.getOwnPropertyDescriptor */
var ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
/** Object.defineProperty */
var ObjectDefineProperty = Object.defineProperty;
/** Object.getPrototypeOf */
var ObjectGetPrototypeOf = Object.getPrototypeOf;
/** Object.create */
/** Array.prototype.slice */
var ArraySlice = Array.prototype.slice;
/** addEventListener string const */
var ADD_EVENT_LISTENER_STR = 'addEventListener';
/** removeEventListener string const */
var REMOVE_EVENT_LISTENER_STR = 'removeEventListener';
/** zoneSymbol addEventListener */
var ZONE_SYMBOL_ADD_EVENT_LISTENER = Zone.__symbol__(ADD_EVENT_LISTENER_STR);
/** zoneSymbol removeEventListener */
var ZONE_SYMBOL_REMOVE_EVENT_LISTENER = Zone.__symbol__(REMOVE_EVENT_LISTENER_STR);
/** true string const */
var TRUE_STR = 'true';
/** false string const */
var FALSE_STR = 'false';
/** __zone_symbol__ string const */
var ZONE_SYMBOL_PREFIX = '__zone_symbol__';
function wrapWithCurrentZone(callback, source) {
return Zone.current.wrap(callback, source);
}
function scheduleMacroTaskWithCurrentZone(source, callback, data, customSchedule, customCancel) {
return Zone.current.scheduleMacroTask(source, callback, data, customSchedule, customCancel);
}
var zoneSymbol = Zone.__symbol__;
var isWindowExists = typeof window !== 'undefined';
var internalWindow = isWindowExists ? window : undefined;
var _global = isWindowExists && internalWindow || typeof self === 'object' && self || global;
var REMOVE_ATTRIBUTE = 'removeAttribute';
var NULL_ON_PROP_VALUE = [null];
function bindArguments(args, source) {
for (var i = args.length - 1; i >= 0; i--) {
if (typeof args[i] === 'function') {
args[i] = wrapWithCurrentZone(args[i], source + '_' + i);
}
}
return args;
}
function isPropertyWritable(propertyDesc) {
if (!propertyDesc) {
return true;
}
if (propertyDesc.writable === false) {
return false;
}
return !(typeof propertyDesc.get === 'function' && typeof propertyDesc.set === 'undefined');
}
var isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope);
// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify
// this code.
var isNode = (!('nw' in _global) && typeof _global.process !== 'undefined' &&
{}.toString.call(_global.process) === '[object process]');
var isBrowser = !isNode && !isWebWorker && !!(isWindowExists && internalWindow['HTMLElement']);
// we are in electron of nw, so we are both browser and nodejs
// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify
// this code.
var isMix = typeof _global.process !== 'undefined' &&
{}.toString.call(_global.process) === '[object process]' && !isWebWorker &&
!!(isWindowExists && internalWindow['HTMLElement']);
var zoneSymbolEventNames = {};
var wrapFn = function (event) {
// https://github.com/angular/zone.js/issues/911, in IE, sometimes
// event will be undefined, so we need to use window.event
event = event || _global.event;
if (!event) {
return;
}
var eventNameSymbol = zoneSymbolEventNames[event.type];
if (!eventNameSymbol) {
eventNameSymbol = zoneSymbolEventNames[event.type] = zoneSymbol('ON_PROPERTY' + event.type);
}
var target = this || event.target || _global;
var listener = target[eventNameSymbol];
var result;
if (isBrowser && target === internalWindow && event.type === 'error') {
// window.onerror have different signiture
// https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror#window.onerror
// and onerror callback will prevent default when callback return true
var errorEvent = event;
result = listener &&
listener.call(this, errorEvent.message, errorEvent.filename, errorEvent.lineno, errorEvent.colno, errorEvent.error);
if (result === true) {
event.preventDefault();
}
}
else {
result = listener && listener.apply(this, arguments);
if (result != undefined && !result) {
event.preventDefault();
}
}
return result;
};
function patchProperty(obj, prop, prototype) {
var desc = ObjectGetOwnPropertyDescriptor(obj, prop);
if (!desc && prototype) {
// when patch window object, use prototype to check prop exist or not
var prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, prop);
if (prototypeDesc) {
desc = { enumerable: true, configurable: true };
}
}
// if the descriptor not exists or is not configurable
// just return
if (!desc || !desc.configurable) {
return;
}
var onPropPatchedSymbol = zoneSymbol('on' + prop + 'patched');
if (obj.hasOwnProperty(onPropPatchedSymbol) && obj[onPropPatchedSymbol]) {
return;
}
// A property descriptor cannot have getter/setter and be writable
// deleting the writable and value properties avoids this error:
//
// TypeError: property descriptors must not specify a value or be writable when a
// getter or setter has been specified
delete desc.writable;
delete desc.value;
var originalDescGet = desc.get;
var originalDescSet = desc.set;
// substr(2) cuz 'onclick' -> 'click', etc
var eventName = prop.substr(2);
var eventNameSymbol = zoneSymbolEventNames[eventName];
if (!eventNameSymbol) {
eventNameSymbol = zoneSymbolEventNames[eventName] = zoneSymbol('ON_PROPERTY' + eventName);
}
desc.set = function (newValue) {
// in some of windows's onproperty callback, this is undefined
// so we need to check it
var target = this;
if (!target && obj === _global) {
target = _global;
}
if (!target) {
return;
}
var previousValue = target[eventNameSymbol];
if (previousValue) {
target.removeEventListener(eventName, wrapFn);
}
// issue #978, when onload handler was added before loading zone.js
// we should remove it with originalDescSet
if (originalDescSet) {
originalDescSet.apply(target, NULL_ON_PROP_VALUE);
}
if (typeof newValue === 'function') {
target[eventNameSymbol] = newValue;
target.addEventListener(eventName, wrapFn, false);
}
else {
target[eventNameSymbol] = null;
}
};
// The getter would return undefined for unassigned properties but the default value of an
// unassigned property is null
desc.get = function () {
// in some of windows's onproperty callback, this is undefined
// so we need to check it
var target = this;
if (!target && obj === _global) {
target = _global;
}
if (!target) {
return null;
}
var listener = target[eventNameSymbol];
if (listener) {
return listener;
}
else if (originalDescGet) {
// result will be null when use inline event attribute,
// such as <button onclick="func();">OK</button>
// because the onclick function is internal raw uncompiled handler
// the onclick will be evaluated when first time event was triggered or
// the property is accessed, https://github.com/angular/zone.js/issues/525
// so we should use original native get to retrieve the handler
var value = originalDescGet && originalDescGet.call(this);
if (value) {
desc.set.call(this, value);
if (typeof target[REMOVE_ATTRIBUTE] === 'function') {
target.removeAttribute(prop);
}
return value;
}
}
return null;
};
ObjectDefineProperty(obj, prop, desc);
obj[onPropPatchedSymbol] = true;
}
function patchOnProperties(obj, properties, prototype) {
if (properties) {
for (var i = 0; i < properties.length; i++) {
patchProperty(obj, 'on' + properties[i], prototype);
}
}
else {
var onProperties = [];
for (var prop in obj) {
if (prop.substr(0, 2) == 'on') {
onProperties.push(prop);
}
}
for (var j = 0; j < onProperties.length; j++) {
patchProperty(obj, onProperties[j], prototype);
}
}
}
var originalInstanceKey = zoneSymbol('originalInstance');
// wrap some native API on `window`
function copySymbolProperties(src, dest) {
if (typeof Object.getOwnPropertySymbols !== 'function') {
return;
}
var symbols = Object.getOwnPropertySymbols(src);
symbols.forEach(function (symbol) {
var desc = Object.getOwnPropertyDescriptor(src, symbol);
Object.defineProperty(dest, symbol, {
get: function () {
return src[symbol];
},
set: function (value) {
if (desc && (!desc.writable || typeof desc.set !== 'function')) {
// if src[symbol] is not writable or not have a setter, just return
return;
}
src[symbol] = value;
},
enumerable: desc ? desc.enumerable : true,
configurable: desc ? desc.configurable : true
});
});
}
var shouldCopySymbolProperties = false;
function setShouldCopySymbolProperties(flag) {
shouldCopySymbolProperties = flag;
}
function patchMethod(target, name, patchFn) {
var proto = target;
while (proto && !proto.hasOwnProperty(name)) {
proto = ObjectGetPrototypeOf(proto);
}
if (!proto && target[name]) {
// somehow we did not find it, but we can see it. This happens on IE for Window properties.
proto = target;
}
var delegateName = zoneSymbol(name);
var delegate = null;
if (proto && !(delegate = proto[delegateName])) {
delegate = proto[delegateName] = proto[name];
// check whether proto[name] is writable
// some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob
var desc = proto && ObjectGetOwnPropertyDescriptor(proto, name);
if (isPropertyWritable(desc)) {
var patchDelegate_1 = patchFn(delegate, delegateName, name);
proto[name] = function () {
return patchDelegate_1(this, arguments);
};
attachOriginToPatched(proto[name], delegate);
if (shouldCopySymbolProperties) {
copySymbolProperties(delegate, proto[name]);
}
}
}
return delegate;
}
// TODO: @JiaLiPassion, support cancel task later if necessary
function patchMacroTask(obj, funcName, metaCreator) {
var setNative = null;
function scheduleTask(task) {
var data = task.data;
data.args[data.cbIdx] = function () {
task.invoke.apply(this, arguments);
};
setNative.apply(data.target, data.args);
return task;
}
setNative = patchMethod(obj, funcName, function (delegate) { return function (self, args) {
var meta = metaCreator(self, args);
if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') {
return scheduleMacroTaskWithCurrentZone(meta.name, args[meta.cbIdx], meta, scheduleTask);
}
else {
// cause an error by calling it directly.
return delegate.apply(self, args);
}
}; });
}
function patchMicroTask(obj, funcName, metaCreator) {
var setNative = null;
function scheduleTask(task) {
var data = task.data;
data.args[data.cbIdx] = function () {
task.invoke.apply(this, arguments);
};
setNative.apply(data.target, data.args);
return task;
}
setNative = patchMethod(obj, funcName, function (delegate) { return function (self, args) {
var meta = metaCreator(self, args);
if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') {
return Zone.current.scheduleMicroTask(meta.name, args[meta.cbIdx], meta, scheduleTask);
}
else {
// cause an error by calling it directly.
return delegate.apply(self, args);
}
}; });
}
function attachOriginToPatched(patched, original) {
patched[zoneSymbol('OriginalDelegate')] = original;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// override Function.prototype.toString to make zone.js patched function
// look like native function
Zone.__load_patch('toString', function (global) {
// patch Func.prototype.toString to let them look like native
var originalFunctionToString = Function.prototype.toString;
var ORIGINAL_DELEGATE_SYMBOL = zoneSymbol('OriginalDelegate');
var PROMISE_SYMBOL = zoneSymbol('Promise');
var ERROR_SYMBOL = zoneSymbol('Error');
var newFunctionToString = function toString() {
if (typeof this === 'function') {
var originalDelegate = this[ORIGINAL_DELEGATE_SYMBOL];
if (originalDelegate) {
if (typeof originalDelegate === 'function') {
return originalFunctionToString.apply(this[ORIGINAL_DELEGATE_SYMBOL], arguments);
}
else {
return Object.prototype.toString.call(originalDelegate);
}
}
if (this === Promise) {
var nativePromise = global[PROMISE_SYMBOL];
if (nativePromise) {
return originalFunctionToString.apply(nativePromise, arguments);
}
}
if (this === Error) {
var nativeError = global[ERROR_SYMBOL];
if (nativeError) {
return originalFunctionToString.apply(nativeError, arguments);
}
}
}
return originalFunctionToString.apply(this, arguments);
};
newFunctionToString[ORIGINAL_DELEGATE_SYMBOL] = originalFunctionToString;
Function.prototype.toString = newFunctionToString;
// patch Object.prototype.toString to let them look like native
var originalObjectToString = Object.prototype.toString;
var PROMISE_OBJECT_TO_STRING = '[object Promise]';
Object.prototype.toString = function () {
if (this instanceof Promise) {
return PROMISE_OBJECT_TO_STRING;
}
return originalObjectToString.apply(this, arguments);
};
});
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Zone.__load_patch('node_util', function (global, Zone, api) {
api.patchOnProperties = patchOnProperties;
api.patchMethod = patchMethod;
api.bindArguments = bindArguments;
setShouldCopySymbolProperties(true);
});
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @fileoverview
* @suppress {missingRequire}
*/
var passiveSupported = false;
if (typeof window !== 'undefined') {
try {
var options = Object.defineProperty({}, 'passive', {
get: function () {
passiveSupported = true;
}
});
window.addEventListener('test', options, options);
window.removeEventListener('test', options, options);
}
catch (err) {
passiveSupported = false;
}
}
// an identifier to tell ZoneTask do not create a new invoke closure
var OPTIMIZED_ZONE_EVENT_TASK_DATA = {
useG: true
};
var zoneSymbolEventNames$1 = {};
var globalSources = {};
var EVENT_NAME_SYMBOL_REGX = /^__zone_symbol__(\w+)(true|false)$/;
var IMMEDIATE_PROPAGATION_SYMBOL = ('__zone_symbol__propagationStopped');
function patchEventTarget(_global, apis, patchOptions) {
var ADD_EVENT_LISTENER = (patchOptions && patchOptions.add) || ADD_EVENT_LISTENER_STR;
var REMOVE_EVENT_LISTENER = (patchOptions && patchOptions.rm) || REMOVE_EVENT_LISTENER_STR;
var LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.listeners) || 'eventListeners';
var REMOVE_ALL_LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.rmAll) || 'removeAllListeners';
var zoneSymbolAddEventListener = zoneSymbol(ADD_EVENT_LISTENER);
var ADD_EVENT_LISTENER_SOURCE = '.' + ADD_EVENT_LISTENER + ':';
var PREPEND_EVENT_LISTENER = 'prependListener';
var PREPEND_EVENT_LISTENER_SOURCE = '.' + PREPEND_EVENT_LISTENER + ':';
var invokeTask = function (task, target, event) {
// for better performance, check isRemoved which is set
// by removeEventListener
if (task.isRemoved) {
return;
}
var delegate = task.callback;
if (typeof delegate === 'object' && delegate.handleEvent) {
// create the bind version of handleEvent when invoke
task.callback = function (event) { return delegate.handleEvent(event); };
task.originalDelegate = delegate;
}
// invoke static task.invoke
task.invoke(task, target, [event]);
var options = task.options;
if (options && typeof options === 'object' && options.once) {
// if options.once is true, after invoke once remove listener here
// only browser need to do this, nodejs eventEmitter will cal removeListener
// inside EventEmitter.once
var delegate_1 = task.originalDelegate ? task.originalDelegate : task.callback;
target[REMOVE_EVENT_LISTENER].call(target, event.type, delegate_1, options);
}
};
// global shared zoneAwareCallback to handle all event callback with capture = false
var globalZoneAwareCallback = function (event) {
// https://github.com/angular/zone.js/issues/911, in IE, sometimes
// event will be undefined, so we need to use window.event
event = event || _global.event;
if (!event) {
return;
}
// event.target is needed for Samsung TV and SourceBuffer
// || global is needed https://github.com/angular/zone.js/issues/190
var target = this || event.target || _global;
var tasks = target[zoneSymbolEventNames$1[event.type][FALSE_STR]];
if (tasks) {
// invoke all tasks which attached to current target with given event.type and capture = false
// for performance concern, if task.length === 1, just invoke
if (tasks.length === 1) {
invokeTask(tasks[0], target, event);
}
else {
// https://github.com/angular/zone.js/issues/836
// copy the tasks array before invoke, to avoid
// the callback will remove itself or other listener
var copyTasks = tasks.slice();
for (var i = 0; i < copyTasks.length; i++) {
if (event && event[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
break;
}
invokeTask(copyTasks[i], target, event);
}
}
}
};
// global shared zoneAwareCallback to handle all event callback with capture = true
var globalZoneAwareCaptureCallback = function (event) {
// https://github.com/angular/zone.js/issues/911, in IE, sometimes
// event will be undefined, so we need to use window.event
event = event || _global.event;
if (!event) {
return;
}
// event.target is needed for Samsung TV and SourceBuffer
// || global is needed https://github.com/angular/zone.js/issues/190
var target = this || event.target || _global;
var tasks = target[zoneSymbolEventNames$1[event.type][TRUE_STR]];
if (tasks) {
// invoke all tasks which attached to current target with given event.type and capture = false
// for performance concern, if task.length === 1, just invoke
if (tasks.length === 1) {
invokeTask(tasks[0], target, event);
}
else {
// https://github.com/angular/zone.js/issues/836
// copy the tasks array before invoke, to avoid
// the callback will remove itself or other listener
var copyTasks = tasks.slice();
for (var i = 0; i < copyTasks.length; i++) {
if (event && event[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
break;
}
invokeTask(copyTasks[i], target, event);
}
}
}
};
function patchEventTargetMethods(obj, patchOptions) {
if (!obj) {
return false;
}
var useGlobalCallback = true;
if (patchOptions && patchOptions.useG !== undefined) {
useGlobalCallback = patchOptions.useG;
}
var validateHandler = patchOptions && patchOptions.vh;
var checkDuplicate = true;
if (patchOptions && patchOptions.chkDup !== undefined) {
checkDuplicate = patchOptions.chkDup;
}
var returnTarget = false;
if (patchOptions && patchOptions.rt !== undefined) {
returnTarget = patchOptions.rt;
}
var proto = obj;
while (proto && !proto.hasOwnProperty(ADD_EVENT_LISTENER)) {
proto = ObjectGetPrototypeOf(proto);
}
if (!proto && obj[ADD_EVENT_LISTENER]) {
// somehow we did not find it, but we can see it. This happens on IE for Window properties.
proto = obj;
}
if (!proto) {
return false;
}
if (proto[zoneSymbolAddEventListener]) {
return false;
}
var eventNameToString = patchOptions && patchOptions.eventNameToString;
// a shared global taskData to pass data for scheduleEventTask
// so we do not need to create a new object just for pass some data
var taskData = {};
var nativeAddEventListener = proto[zoneSymbolAddEventListener] = proto[ADD_EVENT_LISTENER];
var nativeRemoveEventListener = proto[zoneSymbol(REMOVE_EVENT_LISTENER)] =
proto[REMOVE_EVENT_LISTENER];
var nativeListeners = proto[zoneSymbol(LISTENERS_EVENT_LISTENER)] =
proto[LISTENERS_EVENT_LISTENER];
var nativeRemoveAllListeners = proto[zoneSymbol(REMOVE_ALL_LISTENERS_EVENT_LISTENER)] =
proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER];
var nativePrependEventListener;
if (patchOptions && patchOptions.prepend) {
nativePrependEventListener = proto[zoneSymbol(patchOptions.prepend)] =
proto[patchOptions.prepend];
}
function checkIsPassive(task) {
if (!passiveSupported && typeof taskData.options !== 'boolean' &&
typeof taskData.options !== 'undefined' && taskData.options !== null) {
// options is a non-null non-undefined object
// passive is not supported
// don't pass options as object
// just pass capture as a boolean
task.options = !!taskData.options.capture;
taskData.options = task.options;
}
}
var customScheduleGlobal = function (task) {
// if there is already a task for the eventName + capture,
// just return, because we use the shared globalZoneAwareCallback here.
if (taskData.isExisting) {
return;
}
checkIsPassive(task);
return nativeAddEventListener.call(taskData.target, taskData.eventName, taskData.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, taskData.options);
};
var customCancelGlobal = function (task) {
// if task is not marked as isRemoved, this call is directly
// from Zone.prototype.cancelTask, we should remove the task
// from tasksList of target first
if (!task.isRemoved) {
var symbolEventNames = zoneSymbolEventNames$1[task.eventName];
var symbolEventName = void 0;
if (symbolEventNames) {
symbolEventName = symbolEventNames[task.capture ? TRUE_STR : FALSE_STR];
}
var existingTasks = symbolEventName && task.target[symbolEventName];
if (existingTasks) {
for (var i = 0; i < existingTasks.length; i++) {
var existingTask = existingTasks[i];
if (existingTask === task) {
existingTasks.splice(i, 1);
// set isRemoved to data for faster invokeTask check
task.isRemoved = true;
if (existingTasks.length === 0) {
// all tasks for the eventName + capture have gone,
// remove globalZoneAwareCallback and remove the task cache from target
task.allRemoved = true;
task.target[symbolEventName] = null;
}
break;
}
}
}
}
// if all tasks for the eventName + capture have gone,
// we will really remove the global event callback,
// if not, return
if (!task.allRemoved) {
return;
}
return nativeRemoveEventListener.call(task.target, task.eventName, task.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, task.options);
};
var customScheduleNonGlobal = function (task) {
checkIsPassive(task);
return nativeAddEventListener.call(taskData.target, taskData.eventName, task.invoke, taskData.options);
};
var customSchedulePrepend = function (task) {
return nativePrependEventListener.call(taskData.target, taskData.eventName, task.invoke, taskData.options);
};
var customCancelNonGlobal = function (task) {
return nativeRemoveEventListener.call(task.target, task.eventName, task.invoke, task.options);
};
var customSchedule = useGlobalCallback ? customScheduleGlobal : customScheduleNonGlobal;
var customCancel = useGlobalCallback ? customCancelGlobal : customCancelNonGlobal;
var compareTaskCallbackVsDelegate = function (task, delegate) {
var typeOfDelegate = typeof delegate;
return (typeOfDelegate === 'function' && task.callback === delegate) ||
(typeOfDelegate === 'object' && task.originalDelegate === delegate);
};
var compare = (patchOptions && patchOptions.diff) ? patchOptions.diff : compareTaskCallbackVsDelegate;
var blackListedEvents = Zone[Zone.__symbol__('BLACK_LISTED_EVENTS')];
var makeAddListener = function (nativeListener, addSource, customScheduleFn, customCancelFn, returnTarget, prepend) {
if (returnTarget === void 0) { returnTarget = false; }
if (prepend === void 0) { prepend = false; }
return function () {
var target = this || _global;
var eventName = arguments[0];
var delegate = arguments[1];
if (!delegate) {
return nativeListener.apply(this, arguments);
}
if (isNode && eventName === 'uncaughtException') {
// don't patch uncaughtException of nodejs to prevent endless loop
return nativeListener.apply(this, arguments);
}
// don't create the bind delegate function for handleEvent
// case here to improve addEventListener performance
// we will create the bind delegate when invoke
var isHandleEvent = false;
if (typeof delegate !== 'function') {
if (!delegate.handleEvent) {
return nativeListener.apply(this, arguments);
}
isHandleEvent = true;
}
if (validateHandler && !validateHandler(nativeListener, delegate, target, arguments)) {
return;
}
var options = arguments[2];
if (blackListedEvents) {
// check black list
for (var i = 0; i < blackListedEvents.length; i++) {
if (eventName === blackListedEvents[i]) {
return nativeListener.apply(this, arguments);
}
}
}
var capture;
var once = false;
if (options === undefined) {
capture = false;
}
else if (options === true) {
capture = true;
}
else if (options === false) {
capture = false;
}
else {
capture = options ? !!options.capture : false;
once = options ? !!options.once : false;
}
var zone = Zone.current;
var symbolEventNames = zoneSymbolEventNames$1[eventName];
var symbolEventName;
if (!symbolEventNames) {
// the code is duplicate, but I just want to get some better performance
var falseEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + FALSE_STR;
var trueEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + TRUE_STR;
var symbol = ZONE_SYMBOL_PREFIX + falseEventName;
var symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
zoneSymbolEventNames$1[eventName] = {};
zoneSymbolEventNames$1[eventName][FALSE_STR] = symbol;
zoneSymbolEventNames$1[eventName][TRUE_STR] = symbolCapture;
symbolEventName = capture ? symbolCapture : symbol;
}
else {
symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
}
var existingTasks = target[symbolEventName];
var isExisting = false;
if (existingTasks) {
// already have task registered
isExisting = true;
if (checkDuplicate) {
for (var i = 0; i < existingTasks.length; i++) {
if (compare(existingTasks[i], delegate)) {
// same callback, same capture, same event name, just return
return;
}
}
}
}
else {
existingTasks = target[symbolEventName] = [];
}
var source;
var constructorName = target.constructor['name'];
var targetSource = globalSources[constructorName];
if (targetSource) {
source = targetSource[eventName];
}
if (!source) {
source = constructorName + addSource +
(eventNameToString ? eventNameToString(eventName) : eventName);
}
// do not create a new object as task.data to pass those things
// just use the global shared one
taskData.options = options;
if (once) {
// if addEventListener with once options, we don't pass it to
// native addEventListener, instead we keep the once setting
// and handle ourselves.
taskData.options.once = false;
}
taskData.target = target;
taskData.capture = capture;
taskData.eventName = eventName;
taskData.isExisting = isExisting;
var data = useGlobalCallback ? OPTIMIZED_ZONE_EVENT_TASK_DATA : undefined;
// keep taskData into data to allow onScheduleEventTask to access the task information
if (data) {
data.taskData = taskData;
}
var task = zone.scheduleEventTask(source, delegate, data, customScheduleFn, customCancelFn);
// should clear taskData.target to avoid memory leak
// issue, https://github.com/angular/angular/issues/20442
taskData.target = null;
// need to clear up taskData because it is a global object
if (data) {
data.taskData = null;
}
// have to save those information to task in case
// application may call task.zone.cancelTask() directly
if (once) {
options.once = true;
}
if (!(!passiveSupported && typeof task.options === 'boolean')) {
// if not support passive, and we pass an option object
// to addEventListener, we should save the options to task
task.options = options;
}
task.target = target;
task.capture = capture;
task.eventName = eventName;
if (isHandleEvent) {
// save original delegate for compare to check duplicate
task.originalDelegate = delegate;
}
if (!prepend) {
existingTasks.push(task);
}
else {
existingTasks.unshift(task);
}
if (returnTarget) {
return target;
}
};
};
proto[ADD_EVENT_LISTENER] = makeAddListener(nativeAddEventListener, ADD_EVENT_LISTENER_SOURCE, customSchedule, customCancel, returnTarget);
if (nativePrependEventListener) {
proto[PREPEND_EVENT_LISTENER] = makeAddListener(nativePrependEventListener, PREPEND_EVENT_LISTENER_SOURCE, customSchedulePrepend, customCancel, returnTarget, true);
}
proto[REMOVE_EVENT_LISTENER] = function () {
var target = this || _global;
var eventName = arguments[0];
var options = arguments[2];
var capture;
if (options === undefined) {
capture = false;
}
else if (options === true) {
capture = true;
}
else if (options === false) {
capture = false;
}
else {
capture = options ? !!options.capture : false;
}
var delegate = arguments[1];
if (!delegate) {
return nativeRemoveEventListener.apply(this, arguments);
}
if (validateHandler &&
!validateHandler(nativeRemoveEventListener, delegate, target, arguments)) {
return;
}
var symbolEventNames = zoneSymbolEventNames$1[eventName];
var symbolEventName;
if (symbolEventNames) {
symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
}
var existingTasks = symbolEventName && target[symbolEventName];
if (existingTasks) {
for (var i = 0; i < existingTasks.length; i++) {
var existingTask = existingTasks[i];
if (compare(existingTask, delegate)) {
existingTasks.splice(i, 1);
// set isRemoved to data for faster invokeTask check
existingTask.isRemoved = true;
if (existingTasks.length === 0) {
// all tasks for the eventName + capture have gone,
// remove globalZoneAwareCallback and remove the task cache from target
existingTask.allRemoved = true;
target[symbolEventName] = null;
}
existingTask.zone.cancelTask(existingTask);
if (returnTarget) {
return target;
}
return;
}
}
}
// issue 930, didn't find the event name or callback
// from zone kept existingTasks, the callback maybe
// added outside of zone, we need to call native removeEventListener
// to try to remove it.
return nativeRemoveEventListener.apply(this, arguments);
};
proto[LISTENERS_EVENT_LISTENER] = function () {
var target = this || _global;
var eventName = arguments[0];
var listeners = [];
var tasks = findEventTasks(target, eventNameToString ? eventNameToString(eventName) : eventName);
for (var i = 0; i < tasks.length; i++) {
var task = tasks[i];
var delegate = task.originalDelegate ? task.originalDelegate : task.callback;
listeners.push(delegate);
}
return listeners;
};
proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER] = function () {
var target = this || _global;
var eventName = arguments[0];
if (!eventName) {
var keys = Object.keys(target);
for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var match = EVENT_NAME_SYMBOL_REGX.exec(prop);
var evtName = match && match[1];
// in nodejs EventEmitter, removeListener event is
// used for monitoring the removeListener call,
// so just keep removeListener eventListener until
// all other eventListeners are removed
if (evtName && evtName !== 'removeListener') {
this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName);
}
}
// remove removeListener listener finally
this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener');
}
else {
var symbolEventNames = zoneSymbolEventNames$1[eventName];
if (symbolEventNames) {
var symbolEventName = symbolEventNames[FALSE_STR];
var symbolCaptureEventName = symbolEventNames[TRUE_STR];
var tasks = target[symbolEventName];
var captureTasks = target[symbolCaptureEventName];
if (tasks) {
var removeTasks = tasks.slice();
for (var i = 0; i < removeTasks.length; i++) {
var task = removeTasks[i];
var delegate = task.originalDelegate ? task.originalDelegate : task.callback;
this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
}
}
if (captureTasks) {
var removeTasks = captureTasks.slice();
for (var i = 0; i < removeTasks.length; i++) {
var task = removeTasks[i];
var delegate = task.originalDelegate ? task.originalDelegate : task.callback;
this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
}
}
}
}
if (returnTarget) {
return this;
}
};
// for native toString patch
attachOriginToPatched(proto[ADD_EVENT_LISTENER], nativeAddEventListener);
attachOriginToPatched(proto[REMOVE_EVENT_LISTENER], nativeRemoveEventListener);
if (nativeRemoveAllListeners) {
attachOriginToPatched(proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER], nativeRemoveAllListeners);
}
if (nativeListeners) {
attachOriginToPatched(proto[LISTENERS_EVENT_LISTENER], nativeListeners);
}
return true;
}
var results = [];
for (var i = 0; i < apis.length; i++) {
results[i] = patchEventTargetMethods(apis[i], patchOptions);
}
return results;
}
function findEventTasks(target, eventName) {
var foundTasks = [];
for (var prop in target) {
var match = EVENT_NAME_SYMBOL_REGX.exec(prop);
var evtName = match && match[1];
if (evtName && (!eventName || evtName === eventName)) {
var tasks = target[prop];
if (tasks) {
for (var i = 0; i < tasks.length; i++) {
foundTasks.push(tasks[i]);
}
}
}
}
return foundTasks;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Zone.__load_patch('EventEmitter', function (global) {
// For EventEmitter
var EE_ADD_LISTENER = 'addListener';
var EE_PREPEND_LISTENER = 'prependListener';
var EE_REMOVE_LISTENER = 'removeListener';
var EE_REMOVE_ALL_LISTENER = 'removeAllListeners';
var EE_LISTENERS = 'listeners';
var EE_ON = 'on';
var compareTaskCallbackVsDelegate = function (task, delegate) {
// same callback, same capture, same event name, just return
return task.callback === delegate || task.callback.listener === delegate;
};
var eventNameToString = function (eventName) {
if (typeof eventName === 'string') {
return eventName;
}
if (!eventName) {
return '';
}
return eventName.toString().replace('(', '_').replace(')', '_');
};
function patchEventEmitterMethods(obj) {
var result = patchEventTarget(global, [obj], {
useG: false,
add: EE_ADD_LISTENER,
rm: EE_REMOVE_LISTENER,
prepend: EE_PREPEND_LISTENER,
rmAll: EE_REMOVE_ALL_LISTENER,
listeners: EE_LISTENERS,
chkDup: false,
rt: true,
diff: compareTaskCallbackVsDelegate,
eventNameToString: eventNameToString
});
if (result && result[0]) {
obj[EE_ON] = obj[EE_ADD_LISTENER];
}
}
// EventEmitter
var events;
try {
events = __webpack_require__(2);
}
catch (err) {
}
if (events && events.EventEmitter) {
patchEventEmitterMethods(events.EventEmitter.prototype);
}
});
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
Zone.__load_patch('fs', function () {
var fs;
try {
fs = __webpack_require__(3);
}
catch (err) {
}
// watch, watchFile, unwatchFile has been patched
// because EventEmitter has been patched
var TO_PATCH_MACROTASK_METHODS = [
'access', 'appendFile', 'chmod', 'chown', 'close', 'exists', 'fchmod',
'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod',
'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'read',
'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rmdir', 'stat',
'symlink', 'truncate', 'unlink', 'utimes', 'write', 'writeFile',
];
if (fs) {
TO_PATCH_MACROTASK_METHODS.filter(function (name) { return !!fs[name] && typeof fs[name] === 'function'; })
.forEach(function (name) {
patchMacroTask(fs, name, function (self, args) {
return {
name: 'fs.' + name,
args: args,
cbIdx: args.length > 0 ? args.length - 1 : -1,
target: self
};
});
});
}
});
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @fileoverview
* @suppress {missingRequire}
*/
var taskSymbol = zoneSymbol('zoneTask');
function patchTimer(window, setName, cancelName, nameSuffix) {
var setNative = null;
var clearNative = null;
setName += nameSuffix;
cancelName += nameSuffix;
var tasksByHandleId = {};
function scheduleTask(task) {
var data = task.data;
function timer() {
try {
task.invoke.apply(this, arguments);
}
finally {
// issue-934, task will be cancelled
// even it is a periodic task such as
// setInterval
if (!(task.data && task.data.isPeriodic)) {
if (typeof data.handleId === 'number') {
// in non-nodejs env, we remove timerId
// from local cache
delete tasksByHandleId[data.handleId];
}
else if (data.handleId) {
// Node returns complex objects as handleIds
// we remove task reference from timer object
data.handleId[taskSymbol] = null;
}
}
}
}
data.args[0] = timer;
data.handleId = setNative.apply(window, data.args);
return task;
}
function clearTask(task) {
return clearNative(task.data.handleId);
}
setNative =
patchMethod(window, setName, function (delegate) { return function (self, args) {
if (typeof args[0] === 'function') {
var options = {
isPeriodic: nameSuffix === 'Interval',
delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 :
undefined,
args: args
};
var task = scheduleMacroTaskWithCurrentZone(setName, args[0], options, scheduleTask, clearTask);
if (!task) {
return task;
}
// Node.js must additionally support the ref and unref functions.
var handle = task.data.handleId;
if (typeof handle === 'number') {
// for non nodejs env, we save handleId: task
// mapping in local cache for clearTimeout
tasksByHandleId[handle] = task;
}
else if (handle) {
// for nodejs env, we save task
// reference in timerId Object for clearTimeout
handle[taskSymbol] = task;
}
// check whether handle is null, because some polyfill or browser
// may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame
if (handle && handle.ref && handle.unref && typeof handle.ref === 'function' &&
typeof handle.unref === 'function') {
task.ref = handle.ref.bind(handle);
task.unref = handle.unref.bind(handle);
}
if (typeof handle === 'number' || handle) {
return handle;
}
return task;
}
else {
// cause an error by calling it directly.
return delegate.apply(window, args);
}
}; });
clearNative =
patchMethod(window, cancelName, function (delegate) { return function (self, args) {
var id = args[0];
var task;
if (typeof id === 'number') {
// non nodejs env.
task = tasksByHandleId[id];
}
else {
// nodejs env.
task = id && id[taskSymbol];
// other environments.
if (!task) {
task = id;
}
}
if (task && typeof task.type === 'string') {
if (task.state !== 'notScheduled' &&
(task.cancelFn && task.data.isPeriodic || task.runCount === 0)) {
if (typeof id === 'number') {
delete tasksByHandleId[id];
}
else if (id) {
id[taskSymbol] = null;
}
// Do not cancel already canceled functions
task.zone.cancelTask(task);
}
}
else {
// cause an error by calling it directly.
delegate.apply(window, args);
}
}; });
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var set = 'set';
var clear = 'clear';
Zone.__load_patch('node_timers', function (global, Zone) {
// Timers
var globalUseTimeoutFromTimer = false;
try {
var timers = __webpack_require__(4);
var globalEqualTimersTimeout = global.setTimeout === timers.setTimeout;
if (!globalEqualTimersTimeout && !isMix) {
// 1. if isMix, then we are in mix environment such as Electron
// we should only patch timers.setTimeout because global.setTimeout
// have been patched
// 2. if global.setTimeout not equal timers.setTimeout, check
// whether global.setTimeout use timers.setTimeout or not
var originSetTimeout_1 = timers.setTimeout;
timers.setTimeout = function () {
globalUseTimeoutFromTimer = true;
return originSetTimeout_1.apply(this, arguments);
};
var detectTimeout = global.setTimeout(function () { }, 100);
clearTimeout(detectTimeout);
timers.setTimeout = originSetTimeout_1;
}
patchTimer(timers, set, clear, 'Timeout');
patchTimer(timers, set, clear, 'Interval');
patchTimer(timers, set, clear, 'Immediate');
}
catch (error) {
// timers module not exists, for example, when we using nativeScript
// timers is not available
}
if (isMix) {
// if we are in mix environment, such as Electron,
// the global.setTimeout has already been patched,
// so we just patch timers.setTimeout
return;
}
if (!globalUseTimeoutFromTimer) {
// 1. global setTimeout equals timers setTimeout
// 2. or global don't use timers setTimeout(maybe some other library patch setTimeout)
// 3. or load timers module error happens, we should patch global setTimeout
patchTimer(global, set, clear, 'Timeout');
patchTimer(global, set, clear, 'Interval');
patchTimer(global, set, clear, 'Immediate');
}
else {
// global use timers setTimeout, but not equals
// this happens when use nodejs v0.10.x, global setTimeout will
// use a lazy load version of timers setTimeout
// we should not double patch timer's setTimeout
// so we only store the __symbol__ for consistency
global[Zone.__symbol__('setTimeout')] = global.setTimeout;
global[Zone.__symbol__('setInterval')] = global.setInterval;
global[Zone.__symbol__('setImmediate')] = global.setImmediate;
}
});
// patch process related methods
Zone.__load_patch('nextTick', function () {
// patch nextTick as microTask
patchMicroTask(process, 'nextTick', function (self, args) {
return {
name: 'process.nextTick',
args: args,
cbIdx: (args.length > 0 && typeof args[0] === 'function') ? 0 : -1,
target: process
};
});
});
Zone.__load_patch('handleUnhandledPromiseRejection', function (global, Zone, api) {
Zone[api.symbol('unhandledPromiseRejectionHandler')] =
findProcessPromiseRejectionHandler('unhandledRejection');
Zone[api.symbol('rejectionHandledHandler')] =
findProcessPromiseRejectionHandler('rejectionHandled');
// handle unhandled promise rejection
function findProcessPromiseRejectionHandler(evtName) {
return function (e) {
var eventTasks = findEventTasks(process, evtName);
eventTasks.forEach(function (eventTask) {
// process has added unhandledrejection event listener
// trigger the event listener
if (evtName === 'unhandledRejection') {
eventTask.invoke(e.rejection, e.promise);
}
else if (evtName === 'rejectionHandled') {
eventTask.invoke(e.promise);
}
});
};
}
});
// Crypto
Zone.__load_patch('crypto', function () {
var crypto;
try {
crypto = __webpack_require__(5);
}
catch (err) {
}
// use the generic patchMacroTask to patch crypto
if (crypto) {
var methodNames = ['randomBytes', 'pbkdf2'];
methodNames.forEach(function (name) {
patchMacroTask(crypto, name, function (self, args) {
return {
name: 'crypto.' + name,
args: args,
cbIdx: (args.length > 0 && typeof args[args.length - 1] === 'function') ?
args.length - 1 :
-1,
target: crypto
};
});
});
}
});
Zone.__load_patch('console', function (global, Zone) {
var consoleMethods = ['dir', 'log', 'info', 'error', 'warn', 'assert', 'debug', 'timeEnd', 'trace'];
consoleMethods.forEach(function (m) {
var originalMethod = console[Zone.__symbol__(m)] = console[m];
if (originalMethod) {
console[m] = function () {
var args = ArraySlice.call(arguments);
if (Zone.current === Zone.root) {
return originalMethod.apply(this, args);
}
else {
return Zone.root.run(originalMethod, this, args);
}
};
}
});
});
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
})));
/***/ }),
/* 2 */
/***/ (function(module, exports) {
module.exports = require("events");
/***/ }),
/* 3 */
/***/ (function(module, exports) {
module.exports = require("fs");
/***/ }),
/* 4 */
/***/ (function(module, exports) {
module.exports = require("timers");
/***/ }),
/* 5 */
/***/ (function(module, exports) {
module.exports = require("crypto");
/***/ }),
/* 6 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_s", function() { return APPLICATION_MODULE_PROVIDERS; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_p", function() { return _iterableDiffersFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_q", function() { return _keyValueDiffersFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_r", function() { return _localeFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_g", function() { return _appIdRandomProviderFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_n", function() { return DefaultIterableDifferFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_o", function() { return DefaultKeyValueDifferFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_m", function() { return DebugElement__PRE_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_l", function() { return DebugNode__PRE_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_c", function() { return injectInjectorOnly; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_d", function() { return ReflectiveInjector_; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_e", function() { return ReflectiveDependency; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_f", function() { return resolveReflectiveProviders; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_k", function() { return getModuleFactory__PRE_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_t", function() { return wtfEnabled; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_v", function() { return createScope; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_u", function() { return detectWTF; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_y", function() { return endTimeRange; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_w", function() { return leave; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_x", function() { return startTimeRange; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_bb", function() { return injectAttributeImpl; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_bi", function() { return NG_INJECTABLE_DEF; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_bc", function() { return getLView; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_bd", function() { return getPreviousOrParentTNode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_be", function() { return nextContextImpl; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_bh", function() { return BoundPlayerFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_bl", function() { return loadInternal; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_h", function() { return createElementRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_i", function() { return createTemplateRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_j", function() { return createViewRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_a", function() { return makeParamDecorator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_b", function() { return makePropDecorator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_bj", function() { return getClosureSafeProperty; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_z", function() { return _def; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵangular_packages_core_core_ba", function() { return DebugContext; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createPlatform", function() { return createPlatform; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "assertPlatform", function() { return assertPlatform; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "destroyPlatform", function() { return destroyPlatform; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPlatform", function() { return getPlatform; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlatformRef", function() { return PlatformRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ApplicationRef", function() { return ApplicationRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createPlatformFactory", function() { return createPlatformFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NgProbeToken", function() { return NgProbeToken; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableProdMode", function() { return enableProdMode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDevMode", function() { return isDevMode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "APP_ID", function() { return APP_ID; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PACKAGE_ROOT_URL", function() { return PACKAGE_ROOT_URL; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PLATFORM_INITIALIZER", function() { return PLATFORM_INITIALIZER; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PLATFORM_ID", function() { return PLATFORM_ID; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "APP_BOOTSTRAP_LISTENER", function() { return APP_BOOTSTRAP_LISTENER; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "APP_INITIALIZER", function() { return APP_INITIALIZER; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ApplicationInitStatus", function() { return ApplicationInitStatus; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DebugElement", function() { return DebugElement; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DebugNode", function() { return DebugNode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asNativeElements", function() { return asNativeElements; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getDebugNode", function() { return getDebugNode; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Testability", function() { return Testability; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TestabilityRegistry", function() { return TestabilityRegistry; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setTestabilityGetter", function() { return setTestabilityGetter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TRANSLATIONS", function() { return TRANSLATIONS; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TRANSLATIONS_FORMAT", function() { return TRANSLATIONS_FORMAT; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LOCALE_ID", function() { return LOCALE_ID; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MissingTranslationStrategy", function() { return MissingTranslationStrategy; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ApplicationModule", function() { return ApplicationModule; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wtfCreateScope", function() { return wtfCreateScope; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wtfLeave", function() { return wtfLeave; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wtfStartTimeRange", function() { return wtfStartTimeRange; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wtfEndTimeRange", function() { return wtfEndTimeRange; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Type", function() { return Type; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EventEmitter", function() { return EventEmitter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorHandler", function() { return ErrorHandler; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sanitizer", function() { return Sanitizer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SecurityContext", function() { return SecurityContext; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ANALYZE_FOR_ENTRY_COMPONENTS", function() { return ANALYZE_FOR_ENTRY_COMPONENTS; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Attribute", function() { return Attribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ContentChild", function() { return ContentChild; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ContentChildren", function() { return ContentChildren; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Query", function() { return Query; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ViewChild", function() { return ViewChild; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ViewChildren", function() { return ViewChildren; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Component", function() { return Component; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Directive", function() { return Directive; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HostBinding", function() { return HostBinding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HostListener", function() { return HostListener; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Input", function() { return Input; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Output", function() { return Output; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Pipe", function() { return Pipe; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CUSTOM_ELEMENTS_SCHEMA", function() { return CUSTOM_ELEMENTS_SCHEMA; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NO_ERRORS_SCHEMA", function() { return NO_ERRORS_SCHEMA; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NgModule", function() { return NgModule; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ViewEncapsulation", function() { return ViewEncapsulation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Version", function() { return Version; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VERSION", function() { return VERSION; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defineInjectable", function() { return defineInjectable; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defineInjector", function() { return defineInjector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forwardRef", function() { return forwardRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveForwardRef", function() { return resolveForwardRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Injectable", function() { return Injectable; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "INJECTOR", function() { return INJECTOR$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Injector", function() { return Injector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "inject", function() { return inject; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinject", function() { return inject; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InjectFlags", function() { return InjectFlags; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReflectiveInjector", function() { return ReflectiveInjector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createInjector", function() { return createInjector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ResolvedReflectiveFactory", function() { return ResolvedReflectiveFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReflectiveKey", function() { return ReflectiveKey; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InjectionToken", function() { return InjectionToken; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Inject", function() { return Inject; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Optional", function() { return Optional; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Self", function() { return Self; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SkipSelf", function() { return SkipSelf; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Host", function() { return Host; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NgZone", function() { return NgZone; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵNoopNgZone", function() { return NoopNgZone; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenderComponentType", function() { return RenderComponentType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Renderer", function() { return Renderer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Renderer2", function() { return Renderer2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RendererFactory2", function() { return RendererFactory2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RendererStyleFlags2", function() { return RendererStyleFlags2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RootRenderer", function() { return RootRenderer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "COMPILER_OPTIONS", function() { return COMPILER_OPTIONS; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Compiler", function() { return Compiler; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CompilerFactory", function() { return CompilerFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ModuleWithComponentFactories", function() { return ModuleWithComponentFactories; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ComponentFactory", function() { return ComponentFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵComponentFactory", function() { return ComponentFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ComponentRef", function() { return ComponentRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ComponentFactoryResolver", function() { return ComponentFactoryResolver; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ElementRef", function() { return ElementRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NgModuleFactory", function() { return NgModuleFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NgModuleRef", function() { return NgModuleRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NgModuleFactoryLoader", function() { return NgModuleFactoryLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getModuleFactory", function() { return getModuleFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QueryList", function() { return QueryList$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SystemJsNgModuleLoader", function() { return SystemJsNgModuleLoader; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SystemJsNgModuleLoaderConfig", function() { return SystemJsNgModuleLoaderConfig; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TemplateRef", function() { return TemplateRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ViewContainerRef", function() { return ViewContainerRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EmbeddedViewRef", function() { return EmbeddedViewRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ViewRef", function() { return ViewRef$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ChangeDetectionStrategy", function() { return ChangeDetectionStrategy; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ChangeDetectorRef", function() { return ChangeDetectorRef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DefaultIterableDiffer", function() { return DefaultIterableDiffer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IterableDiffers", function() { return IterableDiffers; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyValueDiffers", function() { return KeyValueDiffers; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleChange", function() { return SimpleChange; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WrappedValue", function() { return WrappedValue; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "platformCore", function() { return platformCore; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵALLOW_MULTIPLE_PLATFORMS", function() { return ALLOW_MULTIPLE_PLATFORMS; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵAPP_ID_RANDOM_PROVIDER", function() { return APP_ID_RANDOM_PROVIDER; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdefaultIterableDiffers", function() { return defaultIterableDiffers; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdefaultKeyValueDiffers", function() { return defaultKeyValueDiffers; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdevModeEqual", function() { return devModeEqual; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵisListLikeIterable", function() { return isListLikeIterable; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵChangeDetectorStatus", function() { return ChangeDetectorStatus; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵisDefaultChangeDetectionStrategy", function() { return isDefaultChangeDetectionStrategy; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵConsole", function() { return Console; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetInjectableDef", function() { return getInjectableDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵsetCurrentInjector", function() { return setCurrentInjector; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵAPP_ROOT", function() { return APP_ROOT; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵivyEnabled", function() { return ivyEnabled; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵCodegenComponentFactoryResolver", function() { return CodegenComponentFactoryResolver; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵresolveComponentResources", function() { return resolveComponentResources; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵReflectionCapabilities", function() { return ReflectionCapabilities; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵRenderDebugInfo", function() { return RenderDebugInfo; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵ_sanitizeHtml", function() { return _sanitizeHtml; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵ_sanitizeStyle", function() { return _sanitizeStyle; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵ_sanitizeUrl", function() { return _sanitizeUrl; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵglobal", function() { return _global; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵlooseIdentical", function() { return looseIdentical; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵstringify", function() { return stringify; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵmakeDecorator", function() { return makeDecorator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵisObservable", function() { return isObservable; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵisPromise", function() { return isPromise; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵclearOverrides", function() { return clearOverrides; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinitServicesIfNeeded", function() { return initServicesIfNeeded; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵoverrideComponentView", function() { return overrideComponentView; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵoverrideProvider", function() { return overrideProvider; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR", function() { return NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdefineBase", function() { return defineBase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdefineComponent", function() { return defineComponent; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdefineDirective", function() { return defineDirective; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdefinePipe", function() { return definePipe; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdefineNgModule", function() { return defineNgModule; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdetectChanges", function() { return detectChanges; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵrenderComponent", function() { return renderComponent; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵRender3ComponentFactory", function() { return ComponentFactory$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵRender3ComponentRef", function() { return ComponentRef$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdirectiveInject", function() { return directiveInject; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinjectAttribute", function() { return injectAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetFactoryOf", function() { return getFactoryOf; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetInheritedFactory", function() { return getInheritedFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵtemplateRefExtractor", function() { return templateRefExtractor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵProvidersFeature", function() { return ProvidersFeature; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵInheritDefinitionFeature", function() { return InheritDefinitionFeature; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵNgOnChangesFeature", function() { return NgOnChangesFeature; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵLifecycleHooksFeature", function() { return LifecycleHooksFeature; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵRender3NgModuleRef", function() { return NgModuleRef$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵmarkDirty", function() { return markDirty; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵNgModuleFactory", function() { return NgModuleFactory$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵNO_CHANGE", function() { return NO_CHANGE; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcontainer", function() { return container; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵnextContext", function() { return nextContext; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementStart", function() { return elementStart; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵnamespaceHTML", function() { return namespaceHTML; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵnamespaceMathML", function() { return namespaceMathML; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵnamespaceSVG", function() { return namespaceSVG; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelement", function() { return element; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵlistener", function() { return listener; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵtext", function() { return text; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵembeddedViewStart", function() { return embeddedViewStart; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵquery", function() { return query; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵregisterContentQuery", function() { return registerContentQuery; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵprojection", function() { return projection; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵbind", function() { return bind; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation1", function() { return interpolation1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation2", function() { return interpolation2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation3", function() { return interpolation3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation4", function() { return interpolation4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation5", function() { return interpolation5; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation6", function() { return interpolation6; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation7", function() { return interpolation7; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolation8", function() { return interpolation8; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolationV", function() { return interpolationV; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpipeBind1", function() { return pipeBind1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpipeBind2", function() { return pipeBind2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpipeBind3", function() { return pipeBind3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpipeBind4", function() { return pipeBind4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpipeBindV", function() { return pipeBindV; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction0", function() { return pureFunction0; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction1", function() { return pureFunction1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction2", function() { return pureFunction2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction3", function() { return pureFunction3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction4", function() { return pureFunction4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction5", function() { return pureFunction5; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction6", function() { return pureFunction6; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction7", function() { return pureFunction7; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunction8", function() { return pureFunction8; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpureFunctionV", function() { return pureFunctionV; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetCurrentView", function() { return getCurrentView; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetHostElement", function() { return getHostElement; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵrestoreView", function() { return restoreView; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcontainerRefreshStart", function() { return containerRefreshStart; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcontainerRefreshEnd", function() { return containerRefreshEnd; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵqueryRefresh", function() { return queryRefresh; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵloadQueryList", function() { return loadQueryList; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementEnd", function() { return elementEnd; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementProperty", function() { return elementProperty; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcomponentHostSyntheticProperty", function() { return componentHostSyntheticProperty; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵprojectionDef", function() { return projectionDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵreference", function() { return reference; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵenableBindings", function() { return enableBindings; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdisableBindings", function() { return disableBindings; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵallocHostVars", function() { return allocHostVars; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementAttribute", function() { return elementAttribute; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementContainerStart", function() { return elementContainerStart; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementContainerEnd", function() { return elementContainerEnd; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementStyling", function() { return elementStyling; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementHostAttrs", function() { return elementHostAttrs; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementStylingMap", function() { return elementStylingMap; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementStyleProp", function() { return elementStyleProp; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementStylingApply", function() { return elementStylingApply; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementClassProp", function() { return elementClassProp; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵtextBinding", function() { return textBinding; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵtemplate", function() { return template; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵembeddedViewEnd", function() { return embeddedViewEnd; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵstore", function() { return store; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵload", function() { return load; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpipe", function() { return pipe; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵwhenRendered", function() { return whenRendered; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵi18n", function() { return i18n; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵi18nAttributes", function() { return i18nAttributes; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵi18nExp", function() { return i18nExp; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵi18nStart", function() { return i18nStart; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵi18nEnd", function() { return i18nEnd; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵi18nApply", function() { return i18nApply; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵi18nPostprocess", function() { return i18nPostprocess; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵsetClassMetadata", function() { return setClassMetadata; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcompileComponent", function() { return compileComponent; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcompileDirective", function() { return compileDirective; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcompileNgModule", function() { return compileNgModule; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcompileNgModuleDefs", function() { return compileNgModuleDefs; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpatchComponentDefWithScope", function() { return patchComponentDefWithScope; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵresetCompiledComponents", function() { return resetCompiledComponents; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcompilePipe", function() { return compilePipe; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵsanitizeHtml", function() { return sanitizeHtml; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵsanitizeStyle", function() { return sanitizeStyle; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵsanitizeUrl", function() { return sanitizeUrl; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵsanitizeResourceUrl", function() { return sanitizeResourceUrl; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵbypassSanitizationTrustHtml", function() { return bypassSanitizationTrustHtml; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵbypassSanitizationTrustStyle", function() { return bypassSanitizationTrustStyle; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵbypassSanitizationTrustScript", function() { return bypassSanitizationTrustScript; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵbypassSanitizationTrustUrl", function() { return bypassSanitizationTrustUrl; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵbypassSanitizationTrustResourceUrl", function() { return bypassSanitizationTrustResourceUrl; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetLContext", function() { return getLContext; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵbindPlayerFactory", function() { return bindPlayerFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵaddPlayer", function() { return addPlayer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetPlayers", function() { return getPlayers; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcompileNgModuleFactory__POST_R3__", function() { return compileNgModuleFactory__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_COMPILE_COMPONENT__POST_R3__", function() { return SWITCH_COMPILE_COMPONENT__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_COMPILE_DIRECTIVE__POST_R3__", function() { return SWITCH_COMPILE_DIRECTIVE__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_COMPILE_PIPE__POST_R3__", function() { return SWITCH_COMPILE_PIPE__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_COMPILE_NGMODULE__POST_R3__", function() { return SWITCH_COMPILE_NGMODULE__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetDebugNode__POST_R3__", function() { return getDebugNode__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_COMPILE_INJECTABLE__POST_R3__", function() { return SWITCH_COMPILE_INJECTABLE__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_IVY_ENABLED__POST_R3__", function() { return SWITCH_IVY_ENABLED__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__", function() { return SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵCompiler_compileModuleSync__POST_R3__", function() { return Compiler_compileModuleSync__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵCompiler_compileModuleAsync__POST_R3__", function() { return Compiler_compileModuleAsync__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵCompiler_compileModuleAndAllComponentsSync__POST_R3__", function() { return Compiler_compileModuleAndAllComponentsSync__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵCompiler_compileModuleAndAllComponentsAsync__POST_R3__", function() { return Compiler_compileModuleAndAllComponentsAsync__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_ELEMENT_REF_FACTORY__POST_R3__", function() { return SWITCH_ELEMENT_REF_FACTORY__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_TEMPLATE_REF_FACTORY__POST_R3__", function() { return SWITCH_TEMPLATE_REF_FACTORY__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__", function() { return SWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_RENDERER2_FACTORY__POST_R3__", function() { return SWITCH_RENDERER2_FACTORY__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetModuleFactory__POST_R3__", function() { return getModuleFactory__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpublishGlobalUtil", function() { return publishGlobalUtil; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpublishDefaultGlobalUtils", function() { return publishDefaultGlobalUtils; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵSWITCH_INJECTOR_FACTORY__POST_R3__", function() { return SWITCH_INJECTOR_FACTORY__POST_R3__; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵregisterModuleFactory", function() { return registerModuleFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵEMPTY_ARRAY", function() { return EMPTY_ARRAY$4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵEMPTY_MAP", function() { return EMPTY_MAP; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵand", function() { return anchorDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵccf", function() { return createComponentFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcmf", function() { return createNgModuleFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵcrt", function() { return createRendererType2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵdid", function() { return directiveDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵeld", function() { return elementDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵelementEventFullName", function() { return elementEventFullName; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵgetComponentViewDefinitionFactory", function() { return getComponentViewDefinitionFactory; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinlineInterpolate", function() { return inlineInterpolate; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵinterpolate", function() { return interpolate; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵmod", function() { return moduleDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵmpd", function() { return moduleProvideDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵncd", function() { return ngContentDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵnov", function() { return nodeValue; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpid", function() { return pipeDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵprd", function() { return providerDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpad", function() { return pureArrayDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵpod", function() { return pureObjectDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵppd", function() { return purePipeDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵqud", function() { return queryDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵted", function() { return textDef; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵunv", function() { return unwrapValue$1; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ɵvid", function() { return viewDef; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(107);
/**
* @license Angular v7.2.2
* (c) 2010-2018 Google, Inc. https://angular.io/
* License: MIT
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function getClosureSafeProperty(objWithPropertyToExtract) {
for (var key in objWithPropertyToExtract) {
if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
return key;
}
}
throw Error('Could not find renamed property on target object.');
}
/**
* Sets properties on a target object from a source object, but only if
* the property doesn't already exist on the target object.
* @param target The target to set properties on
* @param source The source of the property keys and values to set
*/
function fillProperties(target, source) {
for (var key in source) {
if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) {
target[key] = source[key];
}
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var NG_COMPONENT_DEF = getClosureSafeProperty({ ngComponentDef: getClosureSafeProperty });
var NG_DIRECTIVE_DEF = getClosureSafeProperty({ ngDirectiveDef: getClosureSafeProperty });
var NG_INJECTABLE_DEF = getClosureSafeProperty({ ngInjectableDef: getClosureSafeProperty });
var NG_INJECTOR_DEF = getClosureSafeProperty({ ngInjectorDef: getClosureSafeProperty });
var NG_PIPE_DEF = getClosureSafeProperty({ ngPipeDef: getClosureSafeProperty });
var NG_MODULE_DEF = getClosureSafeProperty({ ngModuleDef: getClosureSafeProperty });
var NG_BASE_DEF = getClosureSafeProperty({ ngBaseDef: getClosureSafeProperty });
/**
* If a directive is diPublic, bloomAdd sets a property on the type with this constant as
* the key and the directive's unique ID as the value. This allows us to map directives to their
* bloom filter bit for DI.
*/
var NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafeProperty });
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Construct an `InjectableDef` which defines how a token will be constructed by the DI system, and
* in which injectors (if any) it will be available.
*
* This should be assigned to a static `ngInjectableDef` field on a type, which will then be an
* `InjectableType`.
*
* Options:
* * `providedIn` determines which injectors will include the injectable, by either associating it
* with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
* provided in the `'root'` injector, which will be the application-level injector in most apps.
* * `factory` gives the zero argument function which will create an instance of the injectable.
* The factory can call `inject` to access the `Injector` and request injection of dependencies.
*
* @publicApi
*/
function defineInjectable(opts) {
return {
providedIn: opts.providedIn || null, factory: opts.factory, value: undefined,
};
}
/**
* Construct an `InjectorDef` which configures an injector.
*
* This should be assigned to a static `ngInjectorDef` field on a type, which will then be an
* `InjectorType`.
*
* Options:
*
* * `factory`: an `InjectorType` is an instantiable type, so a zero argument `factory` function to
* create the type must be provided. If that factory function needs to inject arguments, it can
* use the `inject` function.
* * `providers`: an optional array of providers to add to the injector. Each provider must
* either have a factory or point to a type which has an `ngInjectableDef` static property (the
* type must be an `InjectableType`).
* * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
* whose providers will also be added to the injector. Locally provided types will override
* providers from imports.
*
* @publicApi
*/
function defineInjector(options) {
return {
factory: options.factory, providers: options.providers || [], imports: options.imports || [],
};
}
/**
* Read the `ngInjectableDef` type in a way which is immune to accidentally reading inherited value.
*
* @param type type which may have `ngInjectableDef`
*/
function getInjectableDef(type) {
return type && type.hasOwnProperty(NG_INJECTABLE_DEF) ? type[NG_INJECTABLE_DEF] : null;
}
/**
* Read the `ngInjectorDef` type in a way which is immune to accidentally reading inherited value.
*
* @param type type which may have `ngInjectorDef`
*/
function getInjectorDef(type) {
return type && type.hasOwnProperty(NG_INJECTOR_DEF) ? type[NG_INJECTOR_DEF] : null;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Creates a token that can be used in a DI Provider.
*
* Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
* runtime representation) such as when injecting an interface, callable type, array or
* parameterized type.
*
* `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
* the `Injector`. This provides additional level of type safety.
*
* ```
* interface MyInterface {...}
* var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
* // myInterface is inferred to be MyInterface.
* ```
*
* When creating an `InjectionToken`, you can optionally specify a factory function which returns
* (possibly by creating) a default value of the parameterized type `T`. This sets up the
* `InjectionToken` using this factory as a provider as if it was defined explicitly in the
* application's root injector. If the factory function, which takes zero arguments, needs to inject
* dependencies, it can do so using the `inject` function. See below for an example.
*
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
* overrides the above behavior and marks the token as belonging to a particular `@NgModule`. As
* mentioned above, `'root'` is the default value for `providedIn`.
*
* @usageNotes
* ### Basic Example
*
* ### Plain InjectionToken
*
* {@example core/di/ts/injector_spec.ts region='InjectionToken'}
*
* ### Tree-shakable InjectionToken
*
* {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
*
*
* @publicApi
*/
var InjectionToken = /** @class */ (function () {
function InjectionToken(_desc, options) {
this._desc = _desc;
/** @internal */
this.ngMetadataName = 'InjectionToken';
if (options !== undefined) {
this.ngInjectableDef = defineInjectable({
providedIn: options.providedIn || 'root',
factory: options.factory,
});
}
else {
this.ngInjectableDef = undefined;
}
}
InjectionToken.prototype.toString = function () { return "InjectionToken " + this._desc; };
return InjectionToken;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var ANNOTATIONS = '__annotations__';
var PARAMETERS = '__parameters__';
var PROP_METADATA = '__prop__metadata__';
/**
* @suppress {globalThis}
*/
function makeDecorator(name, props, parentClass, additionalProcessing, typeFn) {
var metaCtor = makeMetadataCtor(props);
function DecoratorFactory() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _a;
if (this instanceof DecoratorFactory) {
metaCtor.call.apply(metaCtor, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([this], args));
return this;
}
var annotationInstance = new ((_a = DecoratorFactory).bind.apply(_a, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], args)))();
return function TypeDecorator(cls) {
if (typeFn)
typeFn.apply(void 0, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([cls], args));
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
var annotations = cls.hasOwnProperty(ANNOTATIONS) ?
cls[ANNOTATIONS] :
Object.defineProperty(cls, ANNOTATIONS, { value: [] })[ANNOTATIONS];
annotations.push(annotationInstance);
if (additionalProcessing)
additionalProcessing(cls);
return cls;
};
}
if (parentClass) {
DecoratorFactory.prototype = Object.create(parentClass.prototype);
}
DecoratorFactory.prototype.ngMetadataName = name;
DecoratorFactory.annotationCls = DecoratorFactory;
return DecoratorFactory;
}
function makeMetadataCtor(props) {
return function ctor() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (props) {
var values = props.apply(void 0, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(args));
for (var propName in values) {
this[propName] = values[propName];
}
}
};
}
function makeParamDecorator(name, props, parentClass) {
var metaCtor = makeMetadataCtor(props);
function ParamDecoratorFactory() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _a;
if (this instanceof ParamDecoratorFactory) {
metaCtor.apply(this, args);
return this;
}
var annotationInstance = new ((_a = ParamDecoratorFactory).bind.apply(_a, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], args)))();
ParamDecorator.annotation = annotationInstance;
return ParamDecorator;
function ParamDecorator(cls, unusedKey, index) {
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
var parameters = cls.hasOwnProperty(PARAMETERS) ?
cls[PARAMETERS] :
Object.defineProperty(cls, PARAMETERS, { value: [] })[PARAMETERS];
// there might be gaps if some in between parameters do not have annotations.
// we pad with nulls.
while (parameters.length <= index) {
parameters.push(null);
}
(parameters[index] = parameters[index] || []).push(annotationInstance);
return cls;
}
}
if (parentClass) {
ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
}
ParamDecoratorFactory.prototype.ngMetadataName = name;
ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
return ParamDecoratorFactory;
}
function makePropDecorator(name, props, parentClass, additionalProcessing) {
var metaCtor = makeMetadataCtor(props);
function PropDecoratorFactory() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _a;
if (this instanceof PropDecoratorFactory) {
metaCtor.apply(this, args);
return this;
}
var decoratorInstance = new ((_a = PropDecoratorFactory).bind.apply(_a, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], args)))();
function PropDecorator(target, name) {
var constructor = target.constructor;
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
var meta = constructor.hasOwnProperty(PROP_METADATA) ?
constructor[PROP_METADATA] :
Object.defineProperty(constructor, PROP_METADATA, { value: {} })[PROP_METADATA];
meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
meta[name].unshift(decoratorInstance);
if (additionalProcessing)
additionalProcessing.apply(void 0, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([target, name], args));
}
return PropDecorator;
}
if (parentClass) {
PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
}
PropDecoratorFactory.prototype.ngMetadataName = name;
PropDecoratorFactory.annotationCls = PropDecoratorFactory;
return PropDecoratorFactory;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This token can be used to create a virtual provider that will populate the
* `entryComponents` fields of components and ng modules based on its `useValue`.
* All components that are referenced in the `useValue` value (either directly
* or in a nested array or map) will be added to the `entryComponents` property.
*
* @usageNotes
* ### Example
* The following example shows how the router can populate the `entryComponents`
* field of an NgModule based on the router configuration which refers
* to components.
*
* ```typescript
* // helper function inside the router
* function provideRoutes(routes) {
* return [
* {provide: ROUTES, useValue: routes},
* {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
* ];
* }
*
* // user code
* let routes = [
* {path: '/root', component: RootComp},
* {path: '/teams', component: TeamsComp}
* ];
*
* @NgModule({
* providers: [provideRoutes(routes)]
* })
* class ModuleWithRoutes {}
* ```
*
* @publicApi
*/
var ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents');
/**
* Attribute decorator and metadata.
*
* @Annotation
* @publicApi
*/
var Attribute = makeParamDecorator('Attribute', function (attributeName) { return ({ attributeName: attributeName }); });
/**
* Base class for query metadata.
*
* @see `ContentChildren`.
* @see `ContentChild`.
* @see `ViewChildren`.
* @see `ViewChild`.
*
* @publicApi
*/
var Query = /** @class */ (function () {
function Query() {
}
return Query;
}());
/**
* ContentChildren decorator and metadata.
*
*
* @Annotation
* @publicApi
*/
var ContentChildren = makePropDecorator('ContentChildren', function (selector, data) {
if (data === void 0) { data = {}; }
return (Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({ selector: selector, first: false, isViewQuery: false, descendants: false }, data));
}, Query);
/**
* ContentChild decorator and metadata.
*
*
* @Annotation
*
* @publicApi
*/
var ContentChild = makePropDecorator('ContentChild', function (selector, data) {
if (data === void 0) { data = {}; }
return (Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({ selector: selector, first: true, isViewQuery: false, descendants: true }, data));
}, Query);
/**
* ViewChildren decorator and metadata.
*
* @Annotation
* @publicApi
*/
var ViewChildren = makePropDecorator('ViewChildren', function (selector, data) {
if (data === void 0) { data = {}; }
return (Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({ selector: selector, first: false, isViewQuery: true, descendants: true }, data));
}, Query);
/**
* ViewChild decorator and metadata.
*
* @Annotation
* @publicApi
*/
var ViewChild = makePropDecorator('ViewChild', function (selector, data) {
return (Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({ selector: selector, first: true, isViewQuery: true, descendants: true }, data));
}, Query);
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* The strategy that the default change detector uses to detect changes.
* When set, takes effect the next time change detection is triggered.
*
* @publicApi
*/
var ChangeDetectionStrategy;
(function (ChangeDetectionStrategy) {
/**
* Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated
* until reactivated by setting the strategy to `Default` (`CheckAlways`).
* Change detection can still be explicitly invoked.
*/
ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
/**
* Use the default `CheckAlways` strategy, in which change detection is automatic until
* explicitly deactivated.
*/
ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
})(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));
/**
* Defines the possible states of the default change detector.
* @see `ChangeDetectorRef`
*/
var ChangeDetectorStatus;
(function (ChangeDetectorStatus) {
/**
* A state in which, after calling `detectChanges()`, the change detector
* state becomes `Checked`, and must be explicitly invoked or reactivated.
*/
ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
/**
* A state in which change detection is skipped until the change detector mode
* becomes `CheckOnce`.
*/
ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
/**
* A state in which change detection continues automatically until explicitly
* deactivated.
*/
ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
/**
* A state in which a change detector sub tree is not a part of the main tree and
* should be skipped.
*/
ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
/**
* Indicates that the change detector encountered an error checking a binding
* or calling a directive lifecycle method and is now in an inconsistent state. Change
* detectors in this state do not detect changes.
*/
ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
/**
* Indicates that the change detector has been destroyed.
*/
ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
})(ChangeDetectorStatus || (ChangeDetectorStatus = {}));
/**
* Reports whether a given strategy is currently the default for change detection.
* @param changeDetectionStrategy The strategy to check.
* @returns True if the given strategy is the current default, false otherwise.
* @see `ChangeDetectorStatus`
* @see `ChangeDetectorRef`
*/
function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
return changeDetectionStrategy == null ||
changeDetectionStrategy === ChangeDetectionStrategy.Default;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var __window = typeof window !== 'undefined' && window;
var __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
self instanceof WorkerGlobalScope && self;
var __global = typeof global !== 'undefined' && global;
// Check __global first, because in Node tests both __global and __window may be defined and _global
// should be __global in that case.
var _global = __global || __window || __self;
var promise = Promise.resolve(0);
var _symbolIterator = null;
function getSymbolIterator() {
if (!_symbolIterator) {
var Symbol_1 = _global['Symbol'];
if (Symbol_1 && Symbol_1.iterator) {
_symbolIterator = Symbol_1.iterator;
}
else {
// es6-shim specific logic
var keys = Object.getOwnPropertyNames(Map.prototype);
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
if (key !== 'entries' && key !== 'size' &&
Map.prototype[key] === Map.prototype['entries']) {
_symbolIterator = key;
}
}
}
}
return _symbolIterator;
}
function scheduleMicroTask(fn) {
if (typeof Zone === 'undefined') {
// use promise to schedule microTask instead of use Zone
promise.then(function () { fn && fn.apply(null, null); });
}
else {
Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
}
}
// JS has NaN !== NaN
function looseIdentical(a, b) {
return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
}
function stringify(token) {
if (typeof token === 'string') {
return token;
}
if (token instanceof Array) {
return '[' + token.map(stringify).join(', ') + ']';
}
if (token == null) {
return '' + token;
}
if (token.overriddenName) {
return "" + token.overriddenName;
}
if (token.name) {
return "" + token.name;
}
var res = token.toString();
if (res == null) {
return '' + res;
}
var newLineIndex = res.indexOf('\n');
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
}
/**
* Convince closure compiler that the wrapped function has no side-effects.
*
* Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
* allow us to execute a function but have closure compiler mark the call as no-side-effects.
* It is important that the return value for the `noSideEffects` function be assigned
* to something which is retained otherwise the call to `noSideEffects` will be removed by closure
* compiler.
*/
function noSideEffects(fn) {
return '' + { toString: fn };
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var __forward_ref__ = getClosureSafeProperty({ __forward_ref__: getClosureSafeProperty });
/**
* Allows to refer to references which are not yet defined.
*
* For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
* DI is declared, but not yet defined. It is also used when the `token` which we use when creating
* a query is not yet defined.
*
* @usageNotes
* ### Example
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
* @publicApi
*/
function forwardRef(forwardRefFn) {
forwardRefFn.__forward_ref__ = forwardRef;
forwardRefFn.toString = function () { return stringify(this()); };
return forwardRefFn;
}
/**
* Lazily retrieves the reference value from a forwardRef.
*
* Acts as the identity function when given a non-forward-ref value.
*
* @usageNotes
* ### Example
*
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
*
* @see `forwardRef`
* @publicApi
*/
function resolveForwardRef(type) {
var fn = type;
if (typeof fn === 'function' && fn.hasOwnProperty(__forward_ref__) &&
fn.__forward_ref__ === forwardRef) {
return fn();
}
else {
return type;
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Used to resolve resource URLs on `@Component` when used with JIT compilation.
*
* Example:
* ```
* @Component({
* selector: 'my-comp',
* templateUrl: 'my-comp.html', // This requires asynchronous resolution
* })
* class MyComponnent{
* }
*
* // Calling `renderComponent` will fail because `MyComponent`'s `@Compenent.templateUrl`
* // needs to be resolved because `renderComponent` is synchronous process.
* // renderComponent(MyComponent);
*
* // Calling `resolveComponentResources` will resolve `@Compenent.templateUrl` into
* // `@Compenent.template`, which would allow `renderComponent` to proceed in synchronous manner.
* // Use browser's `fetch` function as the default resource resolution strategy.
* resolveComponentResources(fetch).then(() => {
* // After resolution all URLs have been converted into strings.
* renderComponent(MyComponent);
* });
*
* ```
*
* NOTE: In AOT the resolution happens during compilation, and so there should be no need
* to call this method outside JIT mode.
*
* @param resourceResolver a function which is responsible to returning a `Promise` of the resolved
* URL. Browser's `fetch` method is a good default implementation.
*/
function resolveComponentResources(resourceResolver) {
// Store all promises which are fetching the resources.
var urlFetches = [];
// Cache so that we don't fetch the same resource more than once.
var urlMap = new Map();
function cachedResourceResolve(url) {
var promise = urlMap.get(url);
if (!promise) {
var resp = resourceResolver(url);
urlMap.set(url, promise = resp.then(unwrapResponse));
urlFetches.push(promise);
}
return promise;
}
componentResourceResolutionQueue.forEach(function (component) {
if (component.templateUrl) {
cachedResourceResolve(component.templateUrl).then(function (template) {
component.template = template;
component.templateUrl = undefined;
});
}
var styleUrls = component.styleUrls;
var styles = component.styles || (component.styles = []);
var styleOffset = component.styles.length;
styleUrls && styleUrls.forEach(function (styleUrl, index) {
styles.push(''); // pre-allocate array.
cachedResourceResolve(styleUrl).then(function (style) {
styles[styleOffset + index] = style;
styleUrls.splice(styleUrls.indexOf(styleUrl), 1);
if (styleUrls.length == 0) {
component.styleUrls = undefined;
}
});
});
});
componentResourceResolutionQueue.clear();
return Promise.all(urlFetches).then(function () { return null; });
}
var componentResourceResolutionQueue = new Set();
function maybeQueueResolutionOfComponentResources(metadata) {
if (componentNeedsResolution(metadata)) {
componentResourceResolutionQueue.add(metadata);
}
}
function componentNeedsResolution(component) {
return component.templateUrl || component.styleUrls && component.styleUrls.length;
}
function unwrapResponse(response) {
return typeof response == 'string' ? response : response.text();
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Defines template and style encapsulation options available for Component's {@link Component}.
*
* See {@link Component#encapsulation encapsulation}.
*
* @usageNotes
* ### Example
*
* {@example core/ts/metadata/encapsulation.ts region='longform'}
*
* @publicApi
*/
var ViewEncapsulation;
(function (ViewEncapsulation) {
/**
* Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
* Element and pre-processing the style rules provided via {@link Component#styles styles} or
* {@link Component#styleUrls styleUrls}, and adding the new Host Element attribute to all
* selectors.
*
* This is the default option.
*/
ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
/**
* @deprecated v6.1.0 - use {ViewEncapsulation.ShadowDom} instead.
* Use the native encapsulation mechanism of the renderer.
*
* For the DOM this means using the deprecated [Shadow DOM
* v0](https://w3c.github.io/webcomponents/spec/shadow/) and
* creating a ShadowRoot for Component's Host Element.
*/
ViewEncapsulation[ViewEncapsulation["Native"] = 1] = "Native";
/**
* Don't provide any template or style encapsulation.
*/
ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
/**
* Use Shadow DOM to encapsulate styles.
*
* For the DOM this means using modern [Shadow
* DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
* creating a ShadowRoot for Component's Host Element.
*/
ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
})(ViewEncapsulation || (ViewEncapsulation = {}));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function ngDevModeResetPerfCounters() {
var newCounters = {
firstTemplatePass: 0,
tNode: 0,
tView: 0,
rendererCreateTextNode: 0,
rendererSetText: 0,
rendererCreateElement: 0,
rendererAddEventListener: 0,
rendererSetAttribute: 0,
rendererRemoveAttribute: 0,
rendererSetProperty: 0,
rendererSetClassName: 0,
rendererAddClass: 0,
rendererRemoveClass: 0,
rendererSetStyle: 0,
rendererRemoveStyle: 0,
rendererDestroy: 0,
rendererDestroyNode: 0,
rendererMoveNode: 0,
rendererRemoveNode: 0,
rendererCreateComment: 0,
};
// NOTE: Under Ivy we may have both window & global defined in the Node
// environment since ensureDocument() in render3.ts sets global.window.
if (typeof window != 'undefined') {
// Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
window['ngDevMode'] = newCounters;
}
if (typeof global != 'undefined') {
// Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
global['ngDevMode'] = newCounters;
}
if (typeof self != 'undefined') {
// Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
self['ngDevMode'] = newCounters;
}
return newCounters;
}
/**
* This checks to see if the `ngDevMode` has been set. If yes,
* than we honor it, otherwise we default to dev mode with additional checks.
*
* The idea is that unless we are doing production build where we explicitly
* set `ngDevMode == false` we should be helping the developer by providing
* as much early warning and errors as possible.
*/
if (typeof ngDevMode === 'undefined' || ngDevMode) {
ngDevModeResetPerfCounters();
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This file contains reuseable "empty" symbols that can be used as default return values
* in different parts of the rendering code. Because the same symbols are returned, this
* allows for identity checks against these values to be consistently used by the framework
* code.
*/
var EMPTY_OBJ = {};
var EMPTY_ARRAY = [];
// freezing the values prevents any code from accidentally inserting new values in
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
Object.freeze(EMPTY_OBJ);
Object.freeze(EMPTY_ARRAY);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var _renderCompCount = 0;
/**
* Create a component definition object.
*
*
* # Example
* ```
* class MyDirective {
* // Generated by Angular Template Compiler
* // [Symbol] syntax will not be supported by TypeScript until v2.7
* static ngComponentDef = defineComponent({
* ...
* });
* }
* ```
*/
function defineComponent(componentDefinition) {
var type = componentDefinition.type;
var typePrototype = type.prototype;
var declaredInputs = {};
var def = {
type: type,
providersResolver: null,
consts: componentDefinition.consts,
vars: componentDefinition.vars,
factory: componentDefinition.factory,
template: componentDefinition.template || null,
hostBindings: componentDefinition.hostBindings || null,
contentQueries: componentDefinition.contentQueries || null,
contentQueriesRefresh: componentDefinition.contentQueriesRefresh || null,
attributes: componentDefinition.attributes || null,
declaredInputs: declaredInputs,
inputs: null,
outputs: null,
exportAs: componentDefinition.exportAs || null,
onInit: typePrototype.ngOnInit || null,
doCheck: typePrototype.ngDoCheck || null,
afterContentInit: typePrototype.ngAfterContentInit || null,
afterContentChecked: typePrototype.ngAfterContentChecked || null,
afterViewInit: typePrototype.ngAfterViewInit || null,
afterViewChecked: typePrototype.ngAfterViewChecked || null,
onDestroy: typePrototype.ngOnDestroy || null,
onPush: componentDefinition.changeDetection === ChangeDetectionStrategy.OnPush,
directiveDefs: null,
pipeDefs: null,
selectors: componentDefinition.selectors,
viewQuery: componentDefinition.viewQuery || null,
features: componentDefinition.features || null,
data: componentDefinition.data || {},
// TODO(misko): convert ViewEncapsulation into const enum so that it can be used directly in the
// next line. Also `None` should be 0 not 2.
encapsulation: componentDefinition.encapsulation || ViewEncapsulation.Emulated,
id: 'c',
styles: componentDefinition.styles || EMPTY_ARRAY,
_: null,
};
def._ = noSideEffects(function () {
var directiveTypes = componentDefinition.directives;
var feature = componentDefinition.features;
var pipeTypes = componentDefinition.pipes;
def.id += _renderCompCount++;
def.inputs = invertObject(componentDefinition.inputs, declaredInputs),
def.outputs = invertObject(componentDefinition.outputs),
feature && feature.forEach(function (fn) { return fn(def); });
def.directiveDefs = directiveTypes ?
function () { return (typeof directiveTypes === 'function' ? directiveTypes() : directiveTypes)
.map(extractDirectiveDef); } :
null;
def.pipeDefs = pipeTypes ?
function () { return (typeof pipeTypes === 'function' ? pipeTypes() : pipeTypes).map(extractPipeDef); } :
null;
});
return def;
}
function extractDirectiveDef(type) {
var def = getComponentDef(type) || getDirectiveDef(type);
if (ngDevMode && !def) {
throw new Error("'" + type.name + "' is neither 'ComponentType' or 'DirectiveType'.");
}
return def;
}
function extractPipeDef(type) {
var def = getPipeDef(type);
if (ngDevMode && !def) {
throw new Error("'" + type.name + "' is not a 'PipeType'.");
}
return def;
}
function defineNgModule(def) {
var res = {
type: def.type,
bootstrap: def.bootstrap || EMPTY_ARRAY,
declarations: def.declarations || EMPTY_ARRAY,
imports: def.imports || EMPTY_ARRAY,
exports: def.exports || EMPTY_ARRAY,
transitiveCompileScopes: null,
};
return res;
}
/**
* Inverts an inputs or outputs lookup such that the keys, which were the
* minified keys, are part of the values, and the values are parsed so that
* the publicName of the property is the new key
*
* e.g. for
*
* ```
* class Comp {
* @Input()
* propName1: string;
*
* @Input('publicName2')
* declaredPropName2: number;
* }
* ```
*
* will be serialized as
*
* ```
* {
* propName1: 'propName1',
* declaredPropName2: ['publicName2', 'declaredPropName2'],
* }
* ```
*
* which is than translated by the minifier as:
*
* ```
* {
* minifiedPropName1: 'propName1',
* minifiedPropName2: ['publicName2', 'declaredPropName2'],
* }
* ```
*
* becomes: (public name => minifiedName)
*
* ```
* {
* 'propName1': 'minifiedPropName1',
* 'publicName2': 'minifiedPropName2',
* }
* ```
*
* Optionally the function can take `secondary` which will result in: (public name => declared name)
*
* ```
* {
* 'propName1': 'propName1',
* 'publicName2': 'declaredPropName2',
* }
* ```
*
*/
function invertObject(obj, secondary) {
if (obj == null)
return EMPTY_OBJ;
var newLookup = {};
for (var minifiedKey in obj) {
if (obj.hasOwnProperty(minifiedKey)) {
var publicName = obj[minifiedKey];
var declaredName = publicName;
if (Array.isArray(publicName)) {
declaredName = publicName[1];
publicName = publicName[0];
}
newLookup[publicName] = minifiedKey;
if (secondary) {
(secondary[publicName] = declaredName);
}
}
}
return newLookup;
}
/**
* Create a base definition
*
* # Example
* ```
* class ShouldBeInherited {
* static ngBaseDef = defineBase({
* ...
* })
* }
* @param baseDefinition The base definition parameters
*/
function defineBase(baseDefinition) {
var declaredInputs = {};
return {
inputs: invertObject(baseDefinition.inputs, declaredInputs),
declaredInputs: declaredInputs,
outputs: invertObject(baseDefinition.outputs),
};
}
/**
* Create a directive definition object.
*
* # Example
* ```
* class MyDirective {
* // Generated by Angular Template Compiler
* // [Symbol] syntax will not be supported by TypeScript until v2.7
* static ngDirectiveDef = defineDirective({
* ...
* });
* }
* ```
*/
var defineDirective = defineComponent;
/**
* Create a pipe definition object.
*
* # Example
* ```
* class MyPipe implements PipeTransform {
* // Generated by Angular Template Compiler
* static ngPipeDef = definePipe({
* ...
* });
* }
* ```
* @param pipeDef Pipe definition generated by the compiler
*/
function definePipe(pipeDef) {
return {
name: pipeDef.name,
factory: pipeDef.factory,
pure: pipeDef.pure !== false,
onDestroy: pipeDef.type.prototype.ngOnDestroy || null
};
}
/**
* The following getter methods retrieve the definition form the type. Currently the retrieval
* honors inheritance, but in the future we may change the rule to require that definitions are
* explicit. This would require some sort of migration strategy.
*/
function getComponentDef(type) {
return type[NG_COMPONENT_DEF] || null;
}
function getDirectiveDef(type) {
return type[NG_DIRECTIVE_DEF] || null;
}
function getPipeDef(type) {
return type[NG_PIPE_DEF] || null;
}
function getNgModuleDef(type, throwNotFound) {
var ngModuleDef = type[NG_MODULE_DEF] || null;
if (!ngModuleDef && throwNotFound === true) {
throw new Error("Type " + stringify(type) + " does not have 'ngModuleDef' property.");
}
return ngModuleDef;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function assertEqual(actual, expected, msg) {
if (actual != expected) {
throwError(msg);
}
}
function assertNotEqual(actual, expected, msg) {
if (actual == expected) {
throwError(msg);
}
}
function assertLessThan(actual, expected, msg) {
if (actual >= expected) {
throwError(msg);
}
}
function assertGreaterThan(actual, expected, msg) {
if (actual <= expected) {
throwError(msg);
}
}
function assertDefined(actual, msg) {
if (actual == null) {
throwError(msg);
}
}
function assertComponentType(actual, msg) {
if (msg === void 0) { msg = 'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.'; }
if (!getComponentDef(actual)) {
throwError(msg);
}
}
function assertNgModuleType(actual, msg) {
if (msg === void 0) { msg = 'Type passed in is not NgModuleType, it does not have \'ngModuleDef\' property.'; }
if (!getNgModuleDef(actual)) {
throwError(msg);
}
}
function throwError(msg) {
// tslint:disable-next-line
debugger; // Left intentionally for better debugger experience.
throw new Error("ASSERTION ERROR: " + msg);
}
function assertDomNode(node) {
assertEqual(node instanceof Node, true, 'The provided value must be an instance of a DOM Node');
}
function assertPreviousIsParent(isParent) {
assertEqual(isParent, true, 'previousOrParentTNode should be a parent');
}
function assertHasParent(tNode) {
assertDefined(tNode.parent, 'previousOrParentTNode should have a parent');
}
function assertDataInRange(arr, index) {
assertLessThan(index, arr ? arr.length : 0, 'index expected to be a valid data index');
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// Below are constants for LView indices to help us look up LView members
// without having to remember the specific indices.
// Uglify will inline these when minifying so there shouldn't be a cost.
var TVIEW = 0;
var FLAGS = 1;
var PARENT = 2;
var NEXT = 3;
var QUERIES = 4;
var HOST = 5;
var HOST_NODE = 6; // Rename to `T_HOST`?
var BINDING_INDEX = 7;
var CLEANUP = 8;
var CONTEXT = 9;
var INJECTOR = 10;
var RENDERER_FACTORY = 11;
var RENDERER = 12;
var SANITIZER = 13;
var TAIL = 14;
var CONTAINER_INDEX = 15;
var CONTENT_QUERIES = 16;
var DECLARATION_VIEW = 17;
/** Size of LView's header. Necessary to adjust for it when setting slots. */
var HEADER_OFFSET = 18;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Below are constants for LContainer indices to help us look up LContainer members
* without having to remember the specific indices.
* Uglify will inline these when minifying so there shouldn't be a cost.
*/
var ACTIVE_INDEX = 0;
var VIEWS = 1;
// PARENT, NEXT, QUERIES, and HOST are indices 2, 3, 4, and 5.
// As we already have these constants in LView, we don't need to re-create them.
var NATIVE = 6;
var RENDER_PARENT = 7;
// Because interfaces in TS/JS cannot be instanceof-checked this means that we
// need to rely on predictable characteristics of data-structures to check if they
// are what we expect for them to be. The `LContainer` interface code below has a
// fixed length and the constant value below references that. Using the length value
// below we can predictably gaurantee that we are dealing with an `LContainer` array.
// This value MUST be kept up to date with the length of the `LContainer` array
// interface below so that runtime type checking can work.
var LCONTAINER_LENGTH = 8;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This property will be monkey-patched on elements, components and directives
*/
var MONKEY_PATCH_KEY_NAME = '__ngContext__';
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var TNODE = 8;
var PARENT_INJECTOR = 8;
var INJECTOR_BLOOM_PARENT_SIZE = 9;
var NO_PARENT_INJECTOR = -1;
/**
* Each injector is saved in 9 contiguous slots in `LView` and 9 contiguous slots in
* `TView.data`. This allows us to store information about the current node's tokens (which
* can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be
* shared, so they live in `LView`).
*
* Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter
* determines whether a directive is available on the associated node or not. This prevents us
* from searching the directives array at this level unless it's probable the directive is in it.
*
* See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
*
* Because all injectors have been flattened into `LView` and `TViewData`, they cannot typed
* using interfaces as they were previously. The start index of each `LInjector` and `TInjector`
* will differ based on where it is flattened into the main array, so it's not possible to know
* the indices ahead of time and save their types here. The interfaces are still included here
* for documentation purposes.
*
* export interface LInjector extends Array<any> {
*
* // Cumulative bloom for directive IDs 0-31 (IDs are % BLOOM_SIZE)
* [0]: number;
*
* // Cumulative bloom for directive IDs 32-63
* [1]: number;
*
* // Cumulative bloom for directive IDs 64-95
* [2]: number;
*
* // Cumulative bloom for directive IDs 96-127
* [3]: number;
*
* // Cumulative bloom for directive IDs 128-159
* [4]: number;
*
* // Cumulative bloom for directive IDs 160 - 191
* [5]: number;
*
* // Cumulative bloom for directive IDs 192 - 223
* [6]: number;
*
* // Cumulative bloom for directive IDs 224 - 255
* [7]: number;
*
* // We need to store a reference to the injector's parent so DI can keep looking up
* // the injector tree until it finds the dependency it's looking for.
* [PARENT_INJECTOR]: number;
* }
*
* export interface TInjector extends Array<any> {
*
* // Shared node bloom for directive IDs 0-31 (IDs are % BLOOM_SIZE)
* [0]: number;
*
* // Shared node bloom for directive IDs 32-63
* [1]: number;
*
* // Shared node bloom for directive IDs 64-95
* [2]: number;
*
* // Shared node bloom for directive IDs 96-127
* [3]: number;
*
* // Shared node bloom for directive IDs 128-159
* [4]: number;
*
* // Shared node bloom for directive IDs 160 - 191
* [5]: number;
*
* // Shared node bloom for directive IDs 192 - 223
* [6]: number;
*
* // Shared node bloom for directive IDs 224 - 255
* [7]: number;
*
* // Necessary to find directive indices for a particular node.
* [TNODE]: TElementNode|TElementContainerNode|TContainerNode;
* }
*/
/**
* Factory for creating instances of injectors in the NodeInjector.
*
* This factory is complicated by the fact that it can resolve `multi` factories as well.
*
* NOTE: Some of the fields are optional which means that this class has two hidden classes.
* - One without `multi` support (most common)
* - One with `multi` values, (rare).
*
* Since VMs can cache up to 4 inline hidden classes this is OK.
*
* - Single factory: Only `resolving` and `factory` is defined.
* - `providers` factory: `componentProviders` is a number and `index = -1`.
* - `viewProviders` factory: `componentProviders` is a number and `index` points to `providers`.
*/
var NodeInjectorFactory = /** @class */ (function () {
function NodeInjectorFactory(
/**
* Factory to invoke in order to create a new instance.
*/
factory,
/**
* Set to `true` if the token is declared in `viewProviders` (or if it is component).
*/
isViewProvider, injectImplementation) {
this.factory = factory;
/**
* Marker set to true during factory invocation to see if we get into recursive loop.
* Recursive loop causes an error to be displayed.
*/
this.resolving = false;
this.canSeeViewProviders = isViewProvider;
this.injectImpl = injectImplementation;
}
return NodeInjectorFactory;
}());
var FactoryPrototype = NodeInjectorFactory.prototype;
function isFactory(obj) {
// See: https://jsperf.com/instanceof-vs-getprototypeof
return obj != null && typeof obj == 'object' && Object.getPrototypeOf(obj) == FactoryPrototype;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Returns whether the values are different from a change detection stand point.
*
* Constraints are relaxed in checkNoChanges mode. See `devModeEqual` for details.
*/
function isDifferent(a, b) {
// NaN is the only value that is not equal to itself so the first
// test checks if both a and b are not NaN
return !(a !== a && b !== b) && a !== b;
}
function stringify$1(value) {
if (typeof value == 'function')
return value.name || value;
if (typeof value == 'string')
return value;
if (value == null)
return '';
if (typeof value == 'object' && typeof value.type == 'function')
return value.type.name || value.type;
return '' + value;
}
/**
* Flattens an array in non-recursive way. Input arrays are not modified.
*/
function flatten(list) {
var result = [];
var i = 0;
while (i < list.length) {
var item = list[i];
if (Array.isArray(item)) {
if (item.length > 0) {
list = item.concat(list.slice(i + 1));
i = 0;
}
else {
i++;
}
}
else {
result.push(item);
i++;
}
}
return result;
}
/** Retrieves a value from any `LView` or `TData`. */
function loadInternal(view, index) {
ngDevMode && assertDataInRange(view, index + HEADER_OFFSET);
return view[index + HEADER_OFFSET];
}
/**
* Takes the value of a slot in `LView` and returns the element node.
*
* Normally, element nodes are stored flat, but if the node has styles/classes on it,
* it might be wrapped in a styling context. Or if that node has a directive that injects
* ViewContainerRef, it may be wrapped in an LContainer. Or if that node is a component,
* it will be wrapped in LView. It could even have all three, so we keep looping
* until we find something that isn't an array.
*
* @param value The initial value in `LView`
*/
function readElementValue(value) {
while (Array.isArray(value)) {
value = value[HOST];
}
return value;
}
/**
* Retrieves an element value from the provided `viewData`, by unwrapping
* from any containers, component views, or style contexts.
*/
function getNativeByIndex(index, lView) {
return readElementValue(lView[index + HEADER_OFFSET]);
}
function getNativeByTNode(tNode, hostView) {
return readElementValue(hostView[tNode.index]);
}
function getTNode(index, view) {
ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
ngDevMode && assertLessThan(index, view[TVIEW].data.length, 'wrong index for TNode');
return view[TVIEW].data[index + HEADER_OFFSET];
}
function getComponentViewByIndex(nodeIndex, hostView) {
// Could be an LView or an LContainer. If LContainer, unwrap to find LView.
var slotValue = hostView[nodeIndex];
return slotValue.length >= HEADER_OFFSET ? slotValue : slotValue[HOST];
}
function isContentQueryHost(tNode) {
return (tNode.flags & 4 /* hasContentQuery */) !== 0;
}
function isComponent(tNode) {
return (tNode.flags & 1 /* isComponent */) === 1 /* isComponent */;
}
function isComponentDef(def) {
return def.template !== null;
}
function isLContainer(value) {
// Styling contexts are also arrays, but their first index contains an element node
return Array.isArray(value) && value.length === LCONTAINER_LENGTH;
}
function isRootView(target) {
return (target[FLAGS] & 128 /* IsRoot */) !== 0;
}
/**
* Retrieve the root view from any component by walking the parent `LView` until
* reaching the root `LView`.
*
* @param component any component
*/
function getRootView(target) {
ngDevMode && assertDefined(target, 'component');
var lView = Array.isArray(target) ? target : readPatchedLView(target);
while (lView && !(lView[FLAGS] & 128 /* IsRoot */)) {
lView = lView[PARENT];
}
return lView;
}
function getRootContext(viewOrComponent) {
var rootView = getRootView(viewOrComponent);
ngDevMode &&
assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
return rootView[CONTEXT];
}
/**
* Returns the monkey-patch value data present on the target (which could be
* a component, directive or a DOM node).
*/
function readPatchedData(target) {
ngDevMode && assertDefined(target, 'Target expected');
return target[MONKEY_PATCH_KEY_NAME];
}
function readPatchedLView(target) {
var value = readPatchedData(target);
if (value) {
return Array.isArray(value) ? value : value.lView;
}
return null;
}
function hasParentInjector(parentLocation) {
return parentLocation !== NO_PARENT_INJECTOR;
}
function getParentInjectorIndex(parentLocation) {
return parentLocation & 32767 /* InjectorIndexMask */;
}
function getParentInjectorViewOffset(parentLocation) {
return parentLocation >> 16 /* ViewOffsetShift */;
}
/**
* Unwraps a parent injector location number to find the view offset from the current injector,
* then walks up the declaration view tree until the view is found that contains the parent
* injector.
*
* @param location The location of the parent injector, which contains the view offset
* @param startView The LView instance from which to start walking up the view tree
* @returns The LView instance that contains the parent injector
*/
function getParentInjectorView(location, startView) {
var viewOffset = getParentInjectorViewOffset(location);
var parentView = startView;
// For most cases, the parent injector can be found on the host node (e.g. for component
// or container), but we must keep the loop here to support the rarer case of deeply nested
// <ng-template> tags or inline views, where the parent injector might live many views
// above the child injector.
while (viewOffset > 0) {
parentView = parentView[DECLARATION_VIEW];
viewOffset--;
}
return parentView;
}
/**
* Unwraps a parent injector location number to find the view offset from the current injector,
* then walks up the declaration view tree until the TNode of the parent injector is found.
*
* @param location The location of the parent injector, which contains the view offset
* @param startView The LView instance from which to start walking up the view tree
* @param startTNode The TNode instance of the starting element
* @returns The TNode of the parent injector
*/
function getParentInjectorTNode(location, startView, startTNode) {
if (startTNode.parent && startTNode.parent.injectorIndex !== -1) {
// view offset is 0
var injectorIndex = startTNode.parent.injectorIndex;
var parentTNode_1 = startTNode.parent;
while (parentTNode_1.parent != null && injectorIndex == parentTNode_1.injectorIndex) {
parentTNode_1 = parentTNode_1.parent;
}
return parentTNode_1;
}
var viewOffset = getParentInjectorViewOffset(location);
// view offset is 1
var parentView = startView;
var parentTNode = startView[HOST_NODE];
// view offset is superior to 1
while (viewOffset > 1) {
parentView = parentView[DECLARATION_VIEW];
parentTNode = parentView[HOST_NODE];
viewOffset--;
}
return parentTNode;
}
var defaultScheduler = (typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame || // browser only
setTimeout // everything else
).bind(_global);
/**
* Equivalent to ES6 spread, add each item to an array.
*
* @param items The items to add
* @param arr The array to which you want to add the items
*/
function addAllToArray(items, arr) {
for (var i = 0; i < items.length; i++) {
arr.push(items[i]);
}
}
/**
* Given a current view, finds the nearest component's host (LElement).
*
* @param lView LView for which we want a host element node
* @returns The host node
*/
function findComponentView(lView) {
var rootTNode = lView[HOST_NODE];
while (rootTNode && rootTNode.type === 2 /* View */) {
ngDevMode && assertDefined(lView[DECLARATION_VIEW], 'lView[DECLARATION_VIEW]');
lView = lView[DECLARATION_VIEW];
rootTNode = lView[HOST_NODE];
}
return lView;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var R3ResolvedDependencyType;
(function (R3ResolvedDependencyType) {
R3ResolvedDependencyType[R3ResolvedDependencyType["Token"] = 0] = "Token";
R3ResolvedDependencyType[R3ResolvedDependencyType["Attribute"] = 1] = "Attribute";
})(R3ResolvedDependencyType || (R3ResolvedDependencyType = {}));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function getCompilerFacade() {
var globalNg = _global.ng;
if (!globalNg || !globalNg.ɵcompilerFacade) {
throw new Error("Angular JIT compilation failed: '@angular/compiler' not loaded!\n" +
" - JIT compilation is discouraged for production use-cases! Consider AOT mode instead.\n" +
" - Did you bootstrap using '@angular/platform-browser-dynamic' or '@angular/platform-server'?\n" +
" - Alternatively provide the compiler with 'import \"@angular/compiler\";' before bootstrapping.");
}
return globalNg.ɵcompilerFacade;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Inject decorator and metadata.
*
* @Annotation
* @publicApi
*/
var Inject = makeParamDecorator('Inject', function (token) { return ({ token: token }); });
/**
* Optional decorator and metadata.
*
* @Annotation
* @publicApi
*/
var Optional = makeParamDecorator('Optional');
/**
* Self decorator and metadata.
*
* @Annotation
* @publicApi
*/
var Self = makeParamDecorator('Self');
/**
* SkipSelf decorator and metadata.
*
* @Annotation
* @publicApi
*/
var SkipSelf = makeParamDecorator('SkipSelf');
/**
* Host decorator and metadata.
*
* @Annotation
* @publicApi
*/
var Host = makeParamDecorator('Host');
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Injection flags for DI.
*
* @publicApi
*/
var InjectFlags;
(function (InjectFlags) {
// TODO(alxhub): make this 'const' when ngc no longer writes exports of it into ngfactory files.
InjectFlags[InjectFlags["Default"] = 0] = "Default";
/**
* Specifies that an injector should retrieve a dependency from any injector until reaching the
* host element of the current component. (Only used with Element Injector)
*/
InjectFlags[InjectFlags["Host"] = 1] = "Host";
/** Don't descend into ancestors of the node requesting injection. */
InjectFlags[InjectFlags["Self"] = 2] = "Self";
/** Skip the node that is requesting injection. */
InjectFlags[InjectFlags["SkipSelf"] = 4] = "SkipSelf";
/** Inject `defaultValue` instead if token not found. */
InjectFlags[InjectFlags["Optional"] = 8] = "Optional";
})(InjectFlags || (InjectFlags = {}));
/**
* Current injector value used by `inject`.
* - `undefined`: it is an error to call `inject`
* - `null`: `inject` can be called but there is no injector (limp-mode).
* - Injector instance: Use the injector for resolution.
*/
var _currentInjector = undefined;
function setCurrentInjector(injector) {
var former = _currentInjector;
_currentInjector = injector;
return former;
}
/**
* Current implementation of inject.
*
* By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
* to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
* way for two reasons:
* 1. `Injector` should not depend on ivy logic.
* 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
*/
var _injectImplementation;
/**
* Sets the current inject implementation.
*/
function setInjectImplementation(impl) {
var previous = _injectImplementation;
_injectImplementation = impl;
return previous;
}
function injectInjectorOnly(token, flags) {
if (flags === void 0) { flags = InjectFlags.Default; }
if (_currentInjector === undefined) {
throw new Error("inject() must be called from an injection context");
}
else if (_currentInjector === null) {
return injectRootLimpMode(token, undefined, flags);
}
else {
return _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
}
}
function inject(token, flags) {
if (flags === void 0) { flags = InjectFlags.Default; }
return (_injectImplementation || injectInjectorOnly)(token, flags);
}
/**
* Injects `root` tokens in limp mode.
*
* If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
* `"root"`. This is known as the limp mode injection. In such case the value is stored in the
* `InjectableDef`.
*/
function injectRootLimpMode(token, notFoundValue, flags) {
var injectableDef = getInjectableDef(token);
if (injectableDef && injectableDef.providedIn == 'root') {
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
injectableDef.value;
}
if (flags & InjectFlags.Optional)
return null;
if (notFoundValue !== undefined)
return notFoundValue;
throw new Error("Injector: NOT_FOUND [" + stringify(token) + "]");
}
function injectArgs(types) {
var args = [];
for (var i = 0; i < types.length; i++) {
var arg = types[i];
if (Array.isArray(arg)) {
if (arg.length === 0) {
throw new Error('Arguments array must have arguments.');
}
var type = undefined;
var flags = InjectFlags.Default;
for (var j = 0; j < arg.length; j++) {
var meta = arg[j];
if (meta instanceof Optional || meta.ngMetadataName === 'Optional') {
flags |= InjectFlags.Optional;
}
else if (meta instanceof SkipSelf || meta.ngMetadataName === 'SkipSelf') {
flags |= InjectFlags.SkipSelf;
}
else if (meta instanceof Self || meta.ngMetadataName === 'Self') {
flags |= InjectFlags.Self;
}
else if (meta instanceof Inject) {
type = meta.token;
}
else {
type = meta;
}
}
args.push(inject(type, flags));
}
else {
args.push(inject(arg));
}
}
return args;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function assertNodeType(tNode, type) {
assertDefined(tNode, 'should be called with a TNode');
assertEqual(tNode.type, type, "should be a " + typeName(type));
}
function assertNodeOfPossibleTypes(tNode) {
var types = [];
for (var _i = 1; _i < arguments.length; _i++) {
types[_i - 1] = arguments[_i];
}
assertDefined(tNode, 'should be called with a TNode');
var found = types.some(function (type) { return tNode.type === type; });
assertEqual(found, true, "Should be one of " + types.map(typeName).join(', ') + " but got " + typeName(tNode.type));
}
function typeName(type) {
if (type == 1 /* Projection */)
return 'Projection';
if (type == 0 /* Container */)
return 'Container';
if (type == 2 /* View */)
return 'View';
if (type == 3 /* Element */)
return 'Element';
if (type == 4 /* ElementContainer */)
return 'ElementContainer';
return '<unknown>';
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* If this is the first template pass, any ngOnInit or ngDoCheck hooks will be queued into
* TView.initHooks during directiveCreate.
*
* The directive index and hook type are encoded into one number (1st bit: type, remaining bits:
* directive index), then saved in the even indices of the initHooks array. The odd indices
* hold the hook functions themselves.
*
* @param index The index of the directive in LView
* @param hooks The static hooks map on the directive def
* @param tView The current TView
*/
function queueInitHooks(index, onInit, doCheck, tView) {
ngDevMode &&
assertEqual(tView.firstTemplatePass, true, 'Should only be called on first template pass');
if (onInit) {
(tView.initHooks || (tView.initHooks = [])).push(index, onInit);
}
if (doCheck) {
(tView.initHooks || (tView.initHooks = [])).push(index, doCheck);
(tView.checkHooks || (tView.checkHooks = [])).push(index, doCheck);
}
}
/**
* Loops through the directives on a node and queues all their hooks except ngOnInit
* and ngDoCheck, which are queued separately in directiveCreate.
*/
function queueLifecycleHooks(tView, tNode) {
if (tView.firstTemplatePass) {
// It's necessary to loop through the directives at elementEnd() (rather than processing in
// directiveCreate) so we can preserve the current hook order. Content, view, and destroy
// hooks for projected components and directives must be called *before* their hosts.
for (var i = tNode.directiveStart, end = tNode.directiveEnd; i < end; i++) {
var def = tView.data[i];
queueContentHooks(def, tView, i);
queueViewHooks(def, tView, i);
queueDestroyHooks(def, tView, i);
}
}
}
/** Queues afterContentInit and afterContentChecked hooks on TView */
function queueContentHooks(def, tView, i) {
if (def.afterContentInit) {
(tView.contentHooks || (tView.contentHooks = [])).push(i, def.afterContentInit);
}
if (def.afterContentChecked) {
(tView.contentHooks || (tView.contentHooks = [])).push(i, def.afterContentChecked);
(tView.contentCheckHooks || (tView.contentCheckHooks = [])).push(i, def.afterContentChecked);
}
}
/** Queues afterViewInit and afterViewChecked hooks on TView */
function queueViewHooks(def, tView, i) {
if (def.afterViewInit) {
(tView.viewHooks || (tView.viewHooks = [])).push(i, def.afterViewInit);
}
if (def.afterViewChecked) {
(tView.viewHooks || (tView.viewHooks = [])).push(i, def.afterViewChecked);
(tView.viewCheckHooks || (tView.viewCheckHooks = [])).push(i, def.afterViewChecked);
}
}
/** Queues onDestroy hooks on TView */
function queueDestroyHooks(def, tView, i) {
if (def.onDestroy != null) {
(tView.destroyHooks || (tView.destroyHooks = [])).push(i, def.onDestroy);
}
}
/**
* Calls onInit and doCheck calls if they haven't already been called.
*
* @param currentView The current view
*/
function executeInitHooks(currentView, tView, checkNoChangesMode) {
if (!checkNoChangesMode && currentView[FLAGS] & 32 /* RunInit */) {
executeHooks(currentView, tView.initHooks, tView.checkHooks, checkNoChangesMode);
currentView[FLAGS] &= ~32 /* RunInit */;
}
}
/**
* Iterates over afterViewInit and afterViewChecked functions and calls them.
*
* @param currentView The current view
*/
function executeHooks(currentView, allHooks, checkHooks, checkNoChangesMode) {
if (checkNoChangesMode)
return;
var hooksToCall = currentView[FLAGS] & 2 /* FirstLViewPass */ ? allHooks : checkHooks;
if (hooksToCall) {
callHooks(currentView, hooksToCall);
}
}
/**
* Calls lifecycle hooks with their contexts, skipping init hooks if it's not
* the first LView pass.
*
* @param currentView The current view
* @param arr The array in which the hooks are found
*/
function callHooks(currentView, arr) {
for (var i = 0; i < arr.length; i += 2) {
arr[i + 1].call(currentView[arr[i]]);
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Store the element depth count. This is used to identify the root elements of the template
* so that we can than attach `LView` to only those elements.
*/
var elementDepthCount;
function getElementDepthCount() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return elementDepthCount;
}
function increaseElementDepthCount() {
elementDepthCount++;
}
function decreaseElementDepthCount() {
elementDepthCount--;
}
var currentDirectiveDef = null;
function getCurrentDirectiveDef() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return currentDirectiveDef;
}
function setCurrentDirectiveDef(def) {
currentDirectiveDef = def;
}
/**
* Stores whether directives should be matched to elements.
*
* When template contains `ngNonBindable` than we need to prevent the runtime form matching
* directives on children of that element.
*
* Example:
* ```
* <my-comp my-directive>
* Should match component / directive.
* </my-comp>
* <div ngNonBindable>
* <my-comp my-directive>
* Should not match component / directive because we are in ngNonBindable.
* </my-comp>
* </div>
* ```
*/
var bindingsEnabled;
function getBindingsEnabled() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return bindingsEnabled;
}
/**
* Enables directive matching on elements.
*
* * Example:
* ```
* <my-comp my-directive>
* Should match component / directive.
* </my-comp>
* <div ngNonBindable>
* <!-- disabledBindings() -->
* <my-comp my-directive>
* Should not match component / directive because we are in ngNonBindable.
* </my-comp>
* <!-- enableBindings() -->
* </div>
* ```
*/
function enableBindings() {
bindingsEnabled = true;
}
/**
* Disables directive matching on element.
*
* * Example:
* ```
* <my-comp my-directive>
* Should match component / directive.
* </my-comp>
* <div ngNonBindable>
* <!-- disabledBindings() -->
* <my-comp my-directive>
* Should not match component / directive because we are in ngNonBindable.
* </my-comp>
* <!-- enableBindings() -->
* </div>
* ```
*/
function disableBindings() {
bindingsEnabled = false;
}
function getLView() {
return lView;
}
/**
* Restores `contextViewData` to the given OpaqueViewState instance.
*
* Used in conjunction with the getCurrentView() instruction to save a snapshot
* of the current view and restore it when listeners are invoked. This allows
* walking the declaration view tree in listeners to get vars from parent views.
*
* @param viewToRestore The OpaqueViewState instance to restore.
*/
function restoreView(viewToRestore) {
contextLView = viewToRestore;
}
/** Used to set the parent property when nodes are created and track query results. */
var previousOrParentTNode;
function getPreviousOrParentTNode() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return previousOrParentTNode;
}
function setPreviousOrParentTNode(tNode) {
previousOrParentTNode = tNode;
}
function setTNodeAndViewData(tNode, view) {
previousOrParentTNode = tNode;
lView = view;
}
/**
* If `isParent` is:
* - `true`: then `previousOrParentTNode` points to a parent node.
* - `false`: then `previousOrParentTNode` points to previous node (sibling).
*/
var isParent;
function getIsParent() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return isParent;
}
function setIsParent(value) {
isParent = value;
}
/**
* Query instructions can ask for "current queries" in 2 different cases:
* - when creating view queries (at the root of a component view, before any node is created - in
* this case currentQueries points to view queries)
* - when creating content queries (i.e. this previousOrParentTNode points to a node on which we
* create content queries).
*/
function getOrCreateCurrentQueries(QueryType) {
var lView = getLView();
var currentQueries = lView[QUERIES];
// if this is the first content query on a node, any existing LQueries needs to be cloned
// in subsequent template passes, the cloning occurs before directive instantiation.
if (previousOrParentTNode && previousOrParentTNode !== lView[HOST_NODE] &&
!isContentQueryHost(previousOrParentTNode)) {
currentQueries && (currentQueries = lView[QUERIES] = currentQueries.clone());
previousOrParentTNode.flags |= 4 /* hasContentQuery */;
}
return currentQueries || (lView[QUERIES] = new QueryType(null, null, null));
}
/** Checks whether a given view is in creation mode */
function isCreationMode(view) {
if (view === void 0) { view = lView; }
return (view[FLAGS] & 1 /* CreationMode */) === 1 /* CreationMode */;
}
/**
* State of the current view being processed.
*
* An array of nodes (text, element, container, etc), pipes, their bindings, and
* any local variables that need to be stored between invocations.
*/
var lView;
/**
* The last viewData retrieved by nextContext().
* Allows building nextContext() and reference() calls.
*
* e.g. const inner = x().$implicit; const outer = x().$implicit;
*/
var contextLView = null;
function getContextLView() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return contextLView;
}
/**
* In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
*
* Necessary to support ChangeDetectorRef.checkNoChanges().
*/
var checkNoChangesMode = false;
function getCheckNoChangesMode() {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return checkNoChangesMode;
}
function setCheckNoChangesMode(mode) {
checkNoChangesMode = mode;
}
/** Whether or not this is the first time the current view has been processed. */
var firstTemplatePass = true;
function getFirstTemplatePass() {
return firstTemplatePass;
}
function setFirstTemplatePass(value) {
firstTemplatePass = value;
}
/**
* The root index from which pure function instructions should calculate their binding
* indices. In component views, this is TView.bindingStartIndex. In a host binding
* context, this is the TView.expandoStartIndex + any dirs/hostVars before the given dir.
*/
var bindingRootIndex = -1;
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
function getBindingRoot() {
return bindingRootIndex;
}
function setBindingRoot(value) {
bindingRootIndex = value;
}
/**
* Swap the current state with a new state.
*
* For performance reasons we store the state in the top level of the module.
* This way we minimize the number of properties to read. Whenever a new view
* is entered we have to store the state for later, and when the view is
* exited the state has to be restored
*
* @param newView New state to become active
* @param host Element to which the View is a child of
* @returns the previous state;
*/
function enterView(newView, hostTNode) {
var oldView = lView;
if (newView) {
var tView = newView[TVIEW];
firstTemplatePass = tView.firstTemplatePass;
bindingRootIndex = tView.bindingStartIndex;
}
previousOrParentTNode = hostTNode;
isParent = true;
lView = contextLView = newView;
return oldView;
}
function nextContextImpl(level) {
if (level === void 0) { level = 1; }
contextLView = walkUpViews(level, contextLView);
return contextLView[CONTEXT];
}
function walkUpViews(nestingLevel, currentView) {
while (nestingLevel > 0) {
ngDevMode && assertDefined(currentView[DECLARATION_VIEW], 'Declaration view should be defined if nesting level is greater than 0.');
currentView = currentView[DECLARATION_VIEW];
nestingLevel--;
}
return currentView;
}
/**
* Resets the application state.
*/
function resetComponentState() {
isParent = false;
previousOrParentTNode = null;
elementDepthCount = 0;
bindingsEnabled = true;
}
/**
* Used in lieu of enterView to make it clear when we are exiting a child view. This makes
* the direction of traversal (up or down the view tree) a bit clearer.
*
* @param newView New state to become active
*/
function leaveView(newView) {
var tView = lView[TVIEW];
if (isCreationMode(lView)) {
lView[FLAGS] &= ~1 /* CreationMode */;
}
else {
executeHooks(lView, tView.viewHooks, tView.viewCheckHooks, checkNoChangesMode);
// Views are clean and in update mode after being checked, so these bits are cleared
lView[FLAGS] &= ~(8 /* Dirty */ | 2 /* FirstLViewPass */);
lView[FLAGS] |= 32 /* RunInit */;
lView[BINDING_INDEX] = tView.bindingStartIndex;
}
enterView(newView, null);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Defines if the call to `inject` should include `viewProviders` in its resolution.
*
* This is set to true when we try to instantiate a component. This value is reset in
* `getNodeInjectable` to a value which matches the declaration location of the token about to be
* instantiated. This is done so that if we are injecting a token which was declared outside of
* `viewProviders` we don't accidentally pull `viewProviders` in.
*
* Example:
*
* ```
* @Injectable()
* class MyService {
* constructor(public value: String) {}
* }
*
* @Component({
* providers: [
* MyService,
* {provide: String, value: 'providers' }
* ]
* viewProviders: [
* {provide: String, value: 'viewProviders'}
* ]
* })
* class MyComponent {
* constructor(myService: MyService, value: String) {
* // We expect that Component can see into `viewProviders`.
* expect(value).toEqual('viewProviders');
* // `MyService` was not declared in `viewProviders` hence it can't see it.
* expect(myService.value).toEqual('providers');
* }
* }
*
* ```
*/
var includeViewProviders = true;
function setIncludeViewProviders(v) {
var oldValue = includeViewProviders;
includeViewProviders = v;
return oldValue;
}
/**
* The number of slots in each bloom filter (used by DI). The larger this number, the fewer
* directives that will share slots, and thus, the fewer false positives when checking for
* the existence of a directive.
*/
var BLOOM_SIZE = 256;
var BLOOM_MASK = BLOOM_SIZE - 1;
/** Counter used to generate unique IDs for directives. */
var nextNgElementId = 0;
/**
* Registers this directive as present in its node's injector by flipping the directive's
* corresponding bit in the injector's bloom filter.
*
* @param injectorIndex The index of the node injector where this token should be registered
* @param tView The TView for the injector's bloom filters
* @param type The directive token to register
*/
function bloomAdd(injectorIndex, tView, type) {
ngDevMode && assertEqual(tView.firstTemplatePass, true, 'expected firstTemplatePass to be true');
var id = typeof type !== 'string' ? type[NG_ELEMENT_ID] : type.charCodeAt(0) || 0;
// Set a unique ID on the directive type, so if something tries to inject the directive,
// we can easily retrieve the ID and hash it into the bloom bit that should be checked.
if (id == null) {
id = type[NG_ELEMENT_ID] = nextNgElementId++;
}
// We only have BLOOM_SIZE (256) slots in our bloom filter (8 buckets * 32 bits each),
// so all unique IDs must be modulo-ed into a number from 0 - 255 to fit into the filter.
var bloomBit = id & BLOOM_MASK;
// Create a mask that targets the specific bit associated with the directive.
// JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
// to bit positions 0 - 31 in a 32 bit integer.
var mask = 1 << bloomBit;
// Use the raw bloomBit number to determine which bloom filter bucket we should check
// e.g: bf0 = [0 - 31], bf1 = [32 - 63], bf2 = [64 - 95], bf3 = [96 - 127], etc
var b7 = bloomBit & 0x80;
var b6 = bloomBit & 0x40;
var b5 = bloomBit & 0x20;
var tData = tView.data;
if (b7) {
b6 ? (b5 ? (tData[injectorIndex + 7] |= mask) : (tData[injectorIndex + 6] |= mask)) :
(b5 ? (tData[injectorIndex + 5] |= mask) : (tData[injectorIndex + 4] |= mask));
}
else {
b6 ? (b5 ? (tData[injectorIndex + 3] |= mask) : (tData[injectorIndex + 2] |= mask)) :
(b5 ? (tData[injectorIndex + 1] |= mask) : (tData[injectorIndex] |= mask));
}
}
/**
* Creates (or gets an existing) injector for a given element or container.
*
* @param tNode for which an injector should be retrieved / created.
* @param hostView View where the node is stored
* @returns Node injector
*/
function getOrCreateNodeInjectorForNode(tNode, hostView) {
var existingInjectorIndex = getInjectorIndex(tNode, hostView);
if (existingInjectorIndex !== -1) {
return existingInjectorIndex;
}
var tView = hostView[TVIEW];
if (tView.firstTemplatePass) {
tNode.injectorIndex = hostView.length;
insertBloom(tView.data, tNode); // foundation for node bloom
insertBloom(hostView, null); // foundation for cumulative bloom
insertBloom(tView.blueprint, null);
ngDevMode && assertEqual(tNode.flags === 0 || tNode.flags === 1 /* isComponent */, true, 'expected tNode.flags to not be initialized');
}
var parentLoc = getParentInjectorLocation(tNode, hostView);
var parentIndex = getParentInjectorIndex(parentLoc);
var parentLView = getParentInjectorView(parentLoc, hostView);
var injectorIndex = tNode.injectorIndex;
// If a parent injector can't be found, its location is set to -1.
// In that case, we don't need to set up a cumulative bloom
if (hasParentInjector(parentLoc)) {
var parentData = parentLView[TVIEW].data;
// Creates a cumulative bloom filter that merges the parent's bloom filter
// and its own cumulative bloom (which contains tokens for all ancestors)
for (var i = 0; i < 8; i++) {
hostView[injectorIndex + i] = parentLView[parentIndex + i] | parentData[parentIndex + i];
}
}
hostView[injectorIndex + PARENT_INJECTOR] = parentLoc;
return injectorIndex;
}
function insertBloom(arr, footer) {
arr.push(0, 0, 0, 0, 0, 0, 0, 0, footer);
}
function getInjectorIndex(tNode, hostView) {
if (tNode.injectorIndex === -1 ||
// If the injector index is the same as its parent's injector index, then the index has been
// copied down from the parent node. No injector has been created yet on this node.
(tNode.parent && tNode.parent.injectorIndex === tNode.injectorIndex) ||
// After the first template pass, the injector index might exist but the parent values
// might not have been calculated yet for this instance
hostView[tNode.injectorIndex + PARENT_INJECTOR] == null) {
return -1;
}
else {
return tNode.injectorIndex;
}
}
/**
* Finds the index of the parent injector, with a view offset if applicable. Used to set the
* parent injector initially.
*
* Returns a combination of number of `ViewData` we have to go up and index in that `Viewdata`
*/
function getParentInjectorLocation(tNode, view) {
if (tNode.parent && tNode.parent.injectorIndex !== -1) {
return tNode.parent.injectorIndex; // ViewOffset is 0
}
// For most cases, the parent injector index can be found on the host node (e.g. for component
// or container), so this loop will be skipped, but we must keep the loop here to support
// the rarer case of deeply nested <ng-template> tags or inline views.
var hostTNode = view[HOST_NODE];
var viewOffset = 1;
while (hostTNode && hostTNode.injectorIndex === -1) {
view = view[DECLARATION_VIEW];
hostTNode = view ? view[HOST_NODE] : null;
viewOffset++;
}
return hostTNode ?
hostTNode.injectorIndex | (viewOffset << 16 /* ViewOffsetShift */) :
-1;
}
/**
* Makes a type or an injection token public to the DI system by adding it to an
* injector's bloom filter.
*
* @param di The node injector in which a directive will be added
* @param token The type or the injection token to be made public
*/
function diPublicInInjector(injectorIndex, view, token) {
bloomAdd(injectorIndex, view[TVIEW], token);
}
/**
* Inject static attribute value into directive constructor.
*
* This method is used with `factory` functions which are generated as part of
* `defineDirective` or `defineComponent`. The method retrieves the static value
* of an attribute. (Dynamic attributes are not supported since they are not resolved
* at the time of injection and can change over time.)
*
* # Example
* Given:
* ```
* @Component(...)
* class MyComponent {
* constructor(@Attribute('title') title: string) { ... }
* }
* ```
* When instantiated with
* ```
* <my-component title="Hello"></my-component>
* ```
*
* Then factory method generated is:
* ```
* MyComponent.ngComponentDef = defineComponent({
* factory: () => new MyComponent(injectAttribute('title'))
* ...
* })
* ```
*
* @publicApi
*/
function injectAttributeImpl(tNode, attrNameToInject) {
ngDevMode && assertNodeOfPossibleTypes(tNode, 0 /* Container */, 3 /* Element */, 4 /* ElementContainer */);
ngDevMode && assertDefined(tNode, 'expecting tNode');
var attrs = tNode.attrs;
if (attrs) {
for (var i = 0; i < attrs.length; i = i + 2) {
var attrName = attrs[i];
if (attrName === 3 /* SelectOnly */)
break;
if (attrName == attrNameToInject) {
return attrs[i + 1];
}
}
}
return null;
}
/**
* Returns the value associated to the given token from the NodeInjectors => ModuleInjector.
*
* Look for the injector providing the token by walking up the node injector tree and then
* the module injector tree.
*
* @param tNode The Node where the search for the injector should start
* @param lView The `LView` that contains the `tNode`
* @param token The token to look for
* @param flags Injection flags
* @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
* @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
*/
function getOrCreateInjectable(tNode, lView, token, flags, notFoundValue) {
if (flags === void 0) { flags = InjectFlags.Default; }
if (tNode) {
var bloomHash = bloomHashBitOrFactory(token);
// If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
// so just call the factory function to create it.
if (typeof bloomHash === 'function') {
var savePreviousOrParentTNode = getPreviousOrParentTNode();
var saveLView = getLView();
setTNodeAndViewData(tNode, lView);
try {
var value = bloomHash();
if (value == null && !(flags & InjectFlags.Optional)) {
throw new Error("No provider for " + stringify$1(token) + "!");
}
else {
return value;
}
}
finally {
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
}
}
else if (typeof bloomHash == 'number') {
// If the token has a bloom hash, then it is a token which could be in NodeInjector.
// A reference to the previous injector TView that was found while climbing the element
// injector tree. This is used to know if viewProviders can be accessed on the current
// injector.
var previousTView = null;
var injectorIndex = getInjectorIndex(tNode, lView);
var parentLocation = NO_PARENT_INJECTOR;
var hostTElementNode = flags & InjectFlags.Host ? findComponentView(lView)[HOST_NODE] : null;
// If we should skip this injector, or if there is no injector on this node, start by
// searching
// the parent injector.
if (injectorIndex === -1 || flags & InjectFlags.SkipSelf) {
parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) :
lView[injectorIndex + PARENT_INJECTOR];
if (!shouldSearchParent(flags, false)) {
injectorIndex = -1;
}
else {
previousTView = lView[TVIEW];
injectorIndex = getParentInjectorIndex(parentLocation);
lView = getParentInjectorView(parentLocation, lView);
}
}
// Traverse up the injector tree until we find a potential match or until we know there
// *isn't* a match.
while (injectorIndex !== -1) {
parentLocation = lView[injectorIndex + PARENT_INJECTOR];
// Check the current injector. If it matches, see if it contains token.
var tView = lView[TVIEW];
if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {
// At this point, we have an injector which *may* contain the token, so we step through
// the providers and directives associated with the injector's corresponding node to get
// the instance.
var instance = searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode);
if (instance !== NOT_FOUND) {
return instance;
}
}
if (shouldSearchParent(flags, lView[TVIEW].data[injectorIndex + TNODE] === hostTElementNode) &&
bloomHasToken(bloomHash, injectorIndex, lView)) {
// The def wasn't found anywhere on this node, so it was a false positive.
// Traverse up the tree and continue searching.
previousTView = tView;
injectorIndex = getParentInjectorIndex(parentLocation);
lView = getParentInjectorView(parentLocation, lView);
}
else {
// If we should not search parent OR If the ancestor bloom filter value does not have the
// bit corresponding to the directive we can give up on traversing up to find the specific
// injector.
injectorIndex = -1;
}
}
}
}
if (flags & InjectFlags.Optional && notFoundValue === undefined) {
// This must be set or the NullInjector will throw for optional deps
notFoundValue = null;
}
if ((flags & (InjectFlags.Self | InjectFlags.Host)) === 0) {
var moduleInjector = lView[INJECTOR];
if (moduleInjector) {
return moduleInjector.get(token, notFoundValue, flags & InjectFlags.Optional);
}
else {
return injectRootLimpMode(token, notFoundValue, flags & InjectFlags.Optional);
}
}
if (flags & InjectFlags.Optional) {
return notFoundValue;
}
else {
throw new Error("NodeInjector: NOT_FOUND [" + stringify$1(token) + "]");
}
}
var NOT_FOUND = {};
function searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode) {
var currentTView = lView[TVIEW];
var tNode = currentTView.data[injectorIndex + TNODE];
// First, we need to determine if view providers can be accessed by the starting element.
// There are two possibities
var canAccessViewProviders = previousTView == null ?
// 1) This is the first invocation `previousTView == null` which means that we are at the
// `TNode` of where injector is starting to look. In such a case the only time we are allowed
// to look into the ViewProviders is if:
// - we are on a component
// - AND the injector set `includeViewProviders` to true (implying that the token can see
// ViewProviders because it is the Component or a Service which itself was declared in
// ViewProviders)
(isComponent(tNode) && includeViewProviders) :
// 2) `previousTView != null` which means that we are now walking across the parent nodes.
// In such a case we are only allowed to look into the ViewProviders if:
// - We just crossed from child View to Parent View `previousTView != currentTView`
// - AND the parent TNode is an Element.
// This means that we just came from the Component's View and therefore are allowed to see
// into the ViewProviders.
(previousTView != currentTView && (tNode.type === 3 /* Element */));
// This special case happens when there is a @host on the inject and when we are searching
// on the host element node.
var isHostSpecialCase = (flags & InjectFlags.Host) && hostTElementNode === tNode;
var injectableIdx = locateDirectiveOrProvider(tNode, lView, token, canAccessViewProviders, isHostSpecialCase);
if (injectableIdx !== null) {
return getNodeInjectable(currentTView.data, lView, injectableIdx, tNode);
}
else {
return NOT_FOUND;
}
}
/**
* Searches for the given token among the node's directives and providers.
*
* @param tNode TNode on which directives are present.
* @param lView The view we are currently processing
* @param token Provider token or type of a directive to look for.
* @param canAccessViewProviders Whether view providers should be considered.
* @param isHostSpecialCase Whether the host special case applies.
* @returns Index of a found directive or provider, or null when none found.
*/
function locateDirectiveOrProvider(tNode, lView, token, canAccessViewProviders, isHostSpecialCase) {
var tView = lView[TVIEW];
var nodeProviderIndexes = tNode.providerIndexes;
var tInjectables = tView.data;
var injectablesStart = nodeProviderIndexes & 65535 /* ProvidersStartIndexMask */;
var directivesStart = tNode.directiveStart;
var directiveEnd = tNode.directiveEnd;
var cptViewProvidersCount = nodeProviderIndexes >> 16 /* CptViewProvidersCountShift */;
var startingIndex = canAccessViewProviders ? injectablesStart : injectablesStart + cptViewProvidersCount;
// When the host special case applies, only the viewProviders and the component are visible
var endIndex = isHostSpecialCase ? injectablesStart + cptViewProvidersCount : directiveEnd;
for (var i = startingIndex; i < endIndex; i++) {
var providerTokenOrDef = tInjectables[i];
if (i < directivesStart && token === providerTokenOrDef ||
i >= directivesStart && providerTokenOrDef.type === token) {
return i;
}
}
if (isHostSpecialCase) {
var dirDef = tInjectables[directivesStart];
if (dirDef && isComponentDef(dirDef) && dirDef.type === token) {
return directivesStart;
}
}
return null;
}
/**
* Retrieve or instantiate the injectable from the `lData` at particular `index`.
*
* This function checks to see if the value has already been instantiated and if so returns the
* cached `injectable`. Otherwise if it detects that the value is still a factory it
* instantiates the `injectable` and caches the value.
*/
function getNodeInjectable(tData, lData, index, tNode) {
var value = lData[index];
if (isFactory(value)) {
var factory = value;
if (factory.resolving) {
throw new Error("Circular dep for " + stringify$1(tData[index]));
}
var previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);
factory.resolving = true;
var previousInjectImplementation = void 0;
if (factory.injectImpl) {
previousInjectImplementation = setInjectImplementation(factory.injectImpl);
}
var savePreviousOrParentTNode = getPreviousOrParentTNode();
var saveLView = getLView();
setTNodeAndViewData(tNode, lData);
try {
value = lData[index] = factory.factory(null, tData, lData, tNode);
}
finally {
if (factory.injectImpl)
setInjectImplementation(previousInjectImplementation);
setIncludeViewProviders(previousIncludeViewProviders);
factory.resolving = false;
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
}
}
return value;
}
/**
* Returns the bit in an injector's bloom filter that should be used to determine whether or not
* the directive might be provided by the injector.
*
* When a directive is public, it is added to the bloom filter and given a unique ID that can be
* retrieved on the Type. When the directive isn't public or the token is not a directive `null`
* is returned as the node injector can not possibly provide that token.
*
* @param token the injection token
* @returns the matching bit to check in the bloom filter or `null` if the token is not known.
*/
function bloomHashBitOrFactory(token) {
ngDevMode && assertDefined(token, 'token must be defined');
if (typeof token === 'string') {
return token.charCodeAt(0) || 0;
}
var tokenId = token[NG_ELEMENT_ID];
return typeof tokenId === 'number' ? tokenId & BLOOM_MASK : tokenId;
}
function bloomHasToken(bloomHash, injectorIndex, injectorView) {
// Create a mask that targets the specific bit associated with the directive we're looking for.
// JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
// to bit positions 0 - 31 in a 32 bit integer.
var mask = 1 << bloomHash;
var b7 = bloomHash & 0x80;
var b6 = bloomHash & 0x40;
var b5 = bloomHash & 0x20;
// Our bloom filter size is 256 bits, which is eight 32-bit bloom filter buckets:
// bf0 = [0 - 31], bf1 = [32 - 63], bf2 = [64 - 95], bf3 = [96 - 127], etc.
// Get the bloom filter value from the appropriate bucket based on the directive's bloomBit.
var value;
if (b7) {
value = b6 ? (b5 ? injectorView[injectorIndex + 7] : injectorView[injectorIndex + 6]) :
(b5 ? injectorView[injectorIndex + 5] : injectorView[injectorIndex + 4]);
}
else {
value = b6 ? (b5 ? injectorView[injectorIndex + 3] : injectorView[injectorIndex + 2]) :
(b5 ? injectorView[injectorIndex + 1] : injectorView[injectorIndex]);
}
// If the bloom filter value has the bit corresponding to the directive's bloomBit flipped on,
// this injector is a potential match.
return !!(value & mask);
}
/** Returns true if flags prevent parent injector from being searched for tokens */
function shouldSearchParent(flags, isFirstHostTNode) {
return !(flags & InjectFlags.Self) && !(flags & InjectFlags.Host && isFirstHostTNode);
}
function injectInjector() {
var tNode = getPreviousOrParentTNode();
return new NodeInjector(tNode, getLView());
}
var NodeInjector = /** @class */ (function () {
function NodeInjector(_tNode, _lView) {
this._tNode = _tNode;
this._lView = _lView;
}
NodeInjector.prototype.get = function (token, notFoundValue) {
return getOrCreateInjectable(this._tNode, this._lView, token, undefined, notFoundValue);
};
return NodeInjector;
}());
function getFactoryOf(type) {
var typeAny = type;
var def = getComponentDef(typeAny) || getDirectiveDef(typeAny) ||
getPipeDef(typeAny) || getInjectableDef(typeAny) || getInjectorDef(typeAny);
if (!def || def.factory === undefined) {
return null;
}
return def.factory;
}
function getInheritedFactory(type) {
var proto = Object.getPrototypeOf(type.prototype).constructor;
var factory = getFactoryOf(proto);
if (factory !== null) {
return factory;
}
else {
// There is no factory defined. Either this was improper usage of inheritance
// (no Angular decorator on the superclass) or there is no constructor at all
// in the inheritance chain. Since the two cases cannot be distinguished, the
// latter has to be assumed.
return function (t) { return new t(); };
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** Returns the matching `LContext` data for a given DOM node, directive or component instance.
*
* This function will examine the provided DOM element, component, or directive instance\'s
* monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
* value will be that of the newly created `LContext`.
*
* If the monkey-patched value is the `LView` instance then the context value for that
* target will be created and the monkey-patch reference will be updated. Therefore when this
* function is called it may mutate the provided element\'s, component\'s or any of the associated
* directive\'s monkey-patch values.
*
* If the monkey-patch value is not detected then the code will walk up the DOM until an element
* is found which contains a monkey-patch reference. When that occurs then the provided element
* will be updated with a new context (which is then returned). If the monkey-patch value is not
* detected for a component/directive instance then it will throw an error (all components and
* directives should be automatically monkey-patched by ivy).
*
* @param target Component, Directive or DOM Node.
*/
function getLContext(target) {
var mpValue = readPatchedData(target);
if (mpValue) {
// only when it's an array is it considered an LView instance
// ... otherwise it's an already constructed LContext instance
if (Array.isArray(mpValue)) {
var lView = mpValue;
var nodeIndex = void 0;
var component = undefined;
var directives = undefined;
if (isComponentInstance(target)) {
nodeIndex = findViaComponent(lView, target);
if (nodeIndex == -1) {
throw new Error('The provided component was not found in the application');
}
component = target;
}
else if (isDirectiveInstance(target)) {
nodeIndex = findViaDirective(lView, target);
if (nodeIndex == -1) {
throw new Error('The provided directive was not found in the application');
}
directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
}
else {
nodeIndex = findViaNativeElement(lView, target);
if (nodeIndex == -1) {
return null;
}
}
// the goal is not to fill the entire context full of data because the lookups
// are expensive. Instead, only the target data (the element, component, container, ICU
// expression or directive details) are filled into the context. If called multiple times
// with different target values then the missing target data will be filled in.
var native = readElementValue(lView[nodeIndex]);
var existingCtx = readPatchedData(native);
var context = (existingCtx && !Array.isArray(existingCtx)) ?
existingCtx :
createLContext(lView, nodeIndex, native);
// only when the component has been discovered then update the monkey-patch
if (component && context.component === undefined) {
context.component = component;
attachPatchData(context.component, context);
}
// only when the directives have been discovered then update the monkey-patch
if (directives && context.directives === undefined) {
context.directives = directives;
for (var i = 0; i < directives.length; i++) {
attachPatchData(directives[i], context);
}
}
attachPatchData(context.native, context);
mpValue = context;
}
}
else {
var rElement = target;
ngDevMode && assertDomNode(rElement);
// if the context is not found then we need to traverse upwards up the DOM
// to find the nearest element that has already been monkey patched with data
var parent_1 = rElement;
while (parent_1 = parent_1.parentNode) {
var parentContext = readPatchedData(parent_1);
if (parentContext) {
var lView = void 0;
if (Array.isArray(parentContext)) {
lView = parentContext;
}
else {
lView = parentContext.lView;
}
// the edge of the app was also reached here through another means
// (maybe because the DOM was changed manually).
if (!lView) {
return null;
}
var index = findViaNativeElement(lView, rElement);
if (index >= 0) {
var native = readElementValue(lView[index]);
var context = createLContext(lView, index, native);
attachPatchData(native, context);
mpValue = context;
break;
}
}
}
}
return mpValue || null;
}
/**
* Creates an empty instance of a `LContext` context
*/
function createLContext(lView, nodeIndex, native) {
return {
lView: lView,
nodeIndex: nodeIndex,
native: native,
component: undefined,
directives: undefined,
localRefs: undefined,
};
}
/**
* Takes a component instance and returns the view for that component.
*
* @param componentInstance
* @returns The component's view
*/
function getComponentViewByInstance(componentInstance) {
var lView = readPatchedData(componentInstance);
var view;
if (Array.isArray(lView)) {
var nodeIndex = findViaComponent(lView, componentInstance);
view = getComponentViewByIndex(nodeIndex, lView);
var context = createLContext(lView, nodeIndex, view[HOST]);
context.component = componentInstance;
attachPatchData(componentInstance, context);
attachPatchData(context.native, context);
}
else {
var context = lView;
view = getComponentViewByIndex(context.nodeIndex, context.lView);
}
return view;
}
/**
* Assigns the given data to the given target (which could be a component,
* directive or DOM node instance) using monkey-patching.
*/
function attachPatchData(target, data) {
target[MONKEY_PATCH_KEY_NAME] = data;
}
function isComponentInstance(instance) {
return instance && instance.constructor && instance.constructor.ngComponentDef;
}
function isDirectiveInstance(instance) {
return instance && instance.constructor && instance.constructor.ngDirectiveDef;
}
/**
* Locates the element within the given LView and returns the matching index
*/
function findViaNativeElement(lView, target) {
var tNode = lView[TVIEW].firstChild;
while (tNode) {
var native = getNativeByTNode(tNode, lView);
if (native === target) {
return tNode.index;
}
tNode = traverseNextElement(tNode);
}
return -1;
}
/**
* Locates the next tNode (child, sibling or parent).
*/
function traverseNextElement(tNode) {
if (tNode.child) {
return tNode.child;
}
else if (tNode.next) {
return tNode.next;
}
else {
// Let's take the following template: <div><span>text</span></div><component/>
// After checking the text node, we need to find the next parent that has a "next" TNode,
// in this case the parent `div`, so that we can find the component.
while (tNode.parent && !tNode.parent.next) {
tNode = tNode.parent;
}
return tNode.parent && tNode.parent.next;
}
}
/**
* Locates the component within the given LView and returns the matching index
*/
function findViaComponent(lView, componentInstance) {
var componentIndices = lView[TVIEW].components;
if (componentIndices) {
for (var i = 0; i < componentIndices.length; i++) {
var elementComponentIndex = componentIndices[i];
var componentView = getComponentViewByIndex(elementComponentIndex, lView);
if (componentView[CONTEXT] === componentInstance) {
return elementComponentIndex;
}
}
}
else {
var rootComponentView = getComponentViewByIndex(HEADER_OFFSET, lView);
var rootComponent = rootComponentView[CONTEXT];
if (rootComponent === componentInstance) {
// we are dealing with the root element here therefore we know that the
// element is the very first element after the HEADER data in the lView
return HEADER_OFFSET;
}
}
return -1;
}
/**
* Locates the directive within the given LView and returns the matching index
*/
function findViaDirective(lView, directiveInstance) {
// if a directive is monkey patched then it will (by default)
// have a reference to the LView of the current view. The
// element bound to the directive being search lives somewhere
// in the view data. We loop through the nodes and check their
// list of directives for the instance.
var tNode = lView[TVIEW].firstChild;
while (tNode) {
var directiveIndexStart = tNode.directiveStart;
var directiveIndexEnd = tNode.directiveEnd;
for (var i = directiveIndexStart; i < directiveIndexEnd; i++) {
if (lView[i] === directiveInstance) {
return tNode.index;
}
}
tNode = traverseNextElement(tNode);
}
return -1;
}
/**
* Returns a list of directives extracted from the given view based on the
* provided list of directive index values.
*
* @param nodeIndex The node index
* @param lView The target view data
* @param includeComponents Whether or not to include components in returned directives
*/
function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
var tNode = lView[TVIEW].data[nodeIndex];
var directiveStartIndex = tNode.directiveStart;
if (directiveStartIndex == 0)
return EMPTY_ARRAY;
var directiveEndIndex = tNode.directiveEnd;
if (!includeComponents && tNode.flags & 1 /* isComponent */)
directiveStartIndex++;
return lView.slice(directiveStartIndex, directiveEndIndex);
}
function getComponentAtNodeIndex(nodeIndex, lView) {
var tNode = lView[TVIEW].data[nodeIndex];
var directiveStartIndex = tNode.directiveStart;
return tNode.flags & 1 /* isComponent */ ? lView[directiveStartIndex] : null;
}
/**
* Returns a map of local references (local reference name => element or directive instance) that
* exist on a given element.
*/
function discoverLocalRefs(lView, nodeIndex) {
var tNode = lView[TVIEW].data[nodeIndex];
if (tNode && tNode.localNames) {
var result = {};
for (var i = 0; i < tNode.localNames.length; i += 2) {
var localRefName = tNode.localNames[i];
var directiveIndex = tNode.localNames[i + 1];
result[localRefName] =
directiveIndex === -1 ? getNativeByTNode(tNode, lView) : lView[directiveIndex];
}
return result;
}
return null;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Returns the component instance associated with a given DOM host element.
* Elements which don't represent components return `null`.
*
* @param element Host DOM element from which the component should be retrieved.
*
* ```
* <my-app>
* #VIEW
* <div>
* <child-comp></child-comp>
* </div>
* </mp-app>
*
* expect(getComponent(<child-comp>) instanceof ChildComponent).toBeTruthy();
* expect(getComponent(<my-app>) instanceof MyApp).toBeTruthy();
* ```
*
* @publicApi
*/
function getComponent(element) {
var context = loadLContextFromNode(element);
if (context.component === undefined) {
context.component = getComponentAtNodeIndex(context.nodeIndex, context.lView);
}
return context.component;
}
/**
* Returns the component instance associated with a given DOM host element.
* Elements which don't represent components return `null`.
*
* @param element Host DOM element from which the component should be retrieved.
*
* ```
* <my-app>
* #VIEW
* <div>
* <child-comp></child-comp>
* </div>
* </mp-app>
*
* expect(getComponent(<child-comp>) instanceof ChildComponent).toBeTruthy();
* expect(getComponent(<my-app>) instanceof MyApp).toBeTruthy();
* ```
*
* @publicApi
*/
function getContext(element) {
var context = loadLContextFromNode(element);
return context.lView[CONTEXT];
}
/**
* Returns the component instance associated with view which owns the DOM element (`null`
* otherwise).
*
* @param element DOM element which is owned by an existing component's view.
*
* ```
* <my-app>
* #VIEW
* <div>
* <child-comp></child-comp>
* </div>
* </mp-app>
*
* expect(getViewComponent(<child-comp>) instanceof MyApp).toBeTruthy();
* expect(getViewComponent(<my-app>)).toEqual(null);
* ```
*
* @publicApi
*/
function getViewComponent(element) {
var context = loadLContext(element);
var lView = context.lView;
while (lView[PARENT] && lView[HOST] === null) {
// As long as lView[HOST] is null we know we are part of sub-template such as `*ngIf`
lView = lView[PARENT];
}
return lView[FLAGS] & 128 /* IsRoot */ ? null : lView[CONTEXT];
}
/**
* Returns the `RootContext` instance that is associated with
* the application where the target is situated.
*
*/
function getRootContext$1(target) {
var lViewData = Array.isArray(target) ? target : loadLContext(target).lView;
var rootLView = getRootView$1(lViewData);
return rootLView[CONTEXT];
}
/**
* Retrieve all root components.
*
* Root components are those which have been bootstrapped by Angular.
*
* @param target A DOM element, component or directive instance.
*
* @publicApi
*/
function getRootComponents(target) {
return Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(getRootContext$1(target).components);
}
/**
* Retrieves an `Injector` associated with the element, component or directive.
*
* @param target A DOM element, component or directive instance.
*
* @publicApi
*/
function getInjector(target) {
var context = loadLContext(target);
var tNode = context.lView[TVIEW].data[context.nodeIndex];
return new NodeInjector(tNode, context.lView);
}
/**
* Retrieve a set of injection tokens at a given DOM node.
*
* @param element Element for which the injection tokens should be retrieved.
* @publicApi
*/
function getInjectionTokens(element) {
var context = loadLContext(element, false);
if (!context)
return [];
var lView = context.lView;
var tView = lView[TVIEW];
var tNode = tView.data[context.nodeIndex];
var providerTokens = [];
var startIndex = tNode.providerIndexes & 65535 /* ProvidersStartIndexMask */;
var endIndex = tNode.directiveEnd;
for (var i = startIndex; i < endIndex; i++) {
var value = tView.data[i];
if (isDirectiveDefHack(value)) {
// The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
// design flaw. We should always store same type so that we can be monomorphic. The issue
// is that for Components/Directives we store the def instead the type. The correct behavior
// is that we should always be storing injectable type in this location.
value = value.type;
}
providerTokens.push(value);
}
return providerTokens;
}
/**
* Retrieves directives associated with a given DOM host element.
*
* @param target A DOM element, component or directive instance.
*
* @publicApi
*/
function getDirectives(target) {
var context = loadLContext(target);
if (context.directives === undefined) {
context.directives = getDirectivesAtNodeIndex(context.nodeIndex, context.lView, false);
}
return context.directives || [];
}
function loadLContext(target, throwOnNotFound) {
if (throwOnNotFound === void 0) { throwOnNotFound = true; }
var context = getLContext(target);
if (!context && throwOnNotFound) {
throw new Error(ngDevMode ? "Unable to find context associated with " + stringify$1(target) :
'Invalid ng target');
}
return context;
}
/**
* Retrieve the root view from any component by walking the parent `LView` until
* reaching the root `LView`.
*
* @param componentOrView any component or view
*
*/
function getRootView$1(componentOrView) {
var lView;
if (Array.isArray(componentOrView)) {
ngDevMode && assertDefined(componentOrView, 'lView');
lView = componentOrView;
}
else {
ngDevMode && assertDefined(componentOrView, 'component');
lView = readPatchedLView(componentOrView);
}
while (lView && !(lView[FLAGS] & 128 /* IsRoot */)) {
lView = lView[PARENT];
}
return lView;
}
/**
* Retrieve map of local references.
*
* The references are retrieved as a map of local reference name to element or directive instance.
*
* @param target A DOM element, component or directive instance.
*
* @publicApi
*/
function getLocalRefs(target) {
var context = loadLContext(target);
if (context.localRefs === undefined) {
context.localRefs = discoverLocalRefs(context.lView, context.nodeIndex);
}
return context.localRefs || {};
}
/**
* Retrieve the host element of the component.
*
* Use this function to retrieve the host element of the component. The host
* element is the element which the component is associated with.
*
* @param directive Component or Directive for which the host element should be retrieved.
*
* @publicApi
*/
function getHostElement(directive) {
return getLContext(directive).native;
}
function loadLContextFromNode(node) {
if (!(node instanceof Node))
throw new Error('Expecting instance of DOM Node');
return loadLContext(node);
}
function isBrowserEvents(listener) {
// Browser events are those which don't have `useCapture` as boolean.
return typeof listener.useCapture === 'boolean';
}
/**
* Retrieves a list of DOM listeners.
*
* ```
* <my-app>
* #VIEW
* <div (click)="doSomething()">
* </div>
* </mp-app>
*
* expect(getListeners(<div>)).toEqual({
* name: 'click',
* element: <div>,
* callback: () => doSomething(),
* useCapture: false
* });
* ```
*
* @param element Element for which the DOM listeners should be retrieved.
* @publicApi
*/
function getListeners(element) {
var lContext = loadLContextFromNode(element);
var lView = lContext.lView;
var tView = lView[TVIEW];
var lCleanup = lView[CLEANUP];
var tCleanup = tView.cleanup;
var listeners = [];
if (tCleanup && lCleanup) {
for (var i = 0; i < tCleanup.length;) {
var firstParam = tCleanup[i++];
var secondParam = tCleanup[i++];
if (typeof firstParam === 'string') {
var name_1 = firstParam;
var listenerElement = readElementValue(lView[secondParam]);
var callback = lCleanup[tCleanup[i++]];
var useCaptureOrIndx = tCleanup[i++];
// if useCaptureOrIndx is boolean then report it as is.
// if useCaptureOrIndx is positive number then it in unsubscribe method
// if useCaptureOrIndx is negative number then it is a Subscription
var useCapture = typeof useCaptureOrIndx === 'boolean' ?
useCaptureOrIndx :
(useCaptureOrIndx >= 0 ? false : null);
if (element == listenerElement) {
listeners.push({ element: element, name: name_1, callback: callback, useCapture: useCapture });
}
}
}
}
listeners.sort(sortListeners);
return listeners;
}
function sortListeners(a, b) {
if (a.name == b.name)
return 0;
return a.name < b.name ? -1 : 1;
}
/**
* This function should not exist because it is megamorphic and only mostly correct.
*
* See call site for more info.
*/
function isDirectiveDefHack(obj) {
return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function normalizeDebugBindingName(name) {
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
return "ng-reflect-" + name;
}
var CAMEL_CASE_REGEXP = /([A-Z])/g;
function camelCaseToDashCase(input) {
return input.replace(CAMEL_CASE_REGEXP, function () {
var m = [];
for (var _i = 0; _i < arguments.length; _i++) {
m[_i] = arguments[_i];
}
return '-' + m[1].toLowerCase();
});
}
function normalizeDebugBindingValue(value) {
try {
// Limit the size of the value as otherwise the DOM just gets polluted.
return value != null ? value.toString().slice(0, 30) : value;
}
catch (e) {
return '[ERROR] Exception while trying to serialize the value';
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function devModeEqual(a, b) {
var isListLikeIterableA = isListLikeIterable(a);
var isListLikeIterableB = isListLikeIterable(b);
if (isListLikeIterableA && isListLikeIterableB) {
return areIterablesEqual(a, b, devModeEqual);
}
else {
var isAObject = a && (typeof a === 'object' || typeof a === 'function');
var isBObject = b && (typeof b === 'object' || typeof b === 'function');
if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
return true;
}
else {
return looseIdentical(a, b);
}
}
}
/**
* Indicates that the result of a {@link Pipe} transformation has changed even though the
* reference has not changed.
*
* Wrapped values are unwrapped automatically during the change detection, and the unwrapped value
* is stored.
*
* Example:
*
* ```
* if (this._latestValue === this._latestReturnedValue) {
* return this._latestReturnedValue;
* } else {
* this._latestReturnedValue = this._latestValue;
* return WrappedValue.wrap(this._latestValue); // this will force update
* }
* ```
*
* @publicApi
*/
var WrappedValue = /** @class */ (function () {
function WrappedValue(value) {
this.wrapped = value;
}
/** Creates a wrapped value. */
WrappedValue.wrap = function (value) { return new WrappedValue(value); };
/**
* Returns the underlying value of a wrapped value.
* Returns the given `value` when it is not wrapped.
**/
WrappedValue.unwrap = function (value) { return WrappedValue.isWrapped(value) ? value.wrapped : value; };
/** Returns true if `value` is a wrapped value. */
WrappedValue.isWrapped = function (value) { return value instanceof WrappedValue; };
return WrappedValue;
}());
/**
* Represents a basic change from a previous to a new value.
*
* @publicApi
*/
var SimpleChange = /** @class */ (function () {
function SimpleChange(previousValue, currentValue, firstChange) {
this.previousValue = previousValue;
this.currentValue = currentValue;
this.firstChange = firstChange;
}
/**
* Check whether the new value is the first value assigned.
*/
SimpleChange.prototype.isFirstChange = function () { return this.firstChange; };
return SimpleChange;
}());
function isListLikeIterable(obj) {
if (!isJsObject(obj))
return false;
return Array.isArray(obj) ||
(!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
}
function areIterablesEqual(a, b, comparator) {
var iterator1 = a[getSymbolIterator()]();
var iterator2 = b[getSymbolIterator()]();
while (true) {
var item1 = iterator1.next();
var item2 = iterator2.next();
if (item1.done && item2.done)
return true;
if (item1.done || item2.done)
return false;
if (!comparator(item1.value, item2.value))
return false;
}
}
function iterateListLike(obj, fn) {
if (Array.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
fn(obj[i]);
}
}
else {
var iterator = obj[getSymbolIterator()]();
var item = void 0;
while (!((item = iterator.next()).done)) {
fn(item.value);
}
}
}
function isJsObject(o) {
return o !== null && (typeof o === 'function' || typeof o === 'object');
}
/** Called when directives inject each other (creating a circular dependency) */
/** Called when there are multiple component selectors that match a given node */
function throwMultipleComponentError(tNode) {
throw new Error("Multiple components match node with tagname " + tNode.tagName);
}
/** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
function throwErrorIfNoChangesMode(creationMode, oldValue, currValue) {
var msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
if (creationMode) {
msg +=
" It seems like the view has been created after its parent and its children have been dirty checked." +
" Has it been created in a change detection hook ?";
}
// TODO: include debug context
throw new Error(msg);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** A special value which designates that a value has not changed. */
var NO_CHANGE = {};
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// TODO(misko): consider inlining
/** Updates binding and returns the value. */
function updateBinding(lView, bindingIndex, value) {
return lView[bindingIndex] = value;
}
/** Gets the current binding value. */
function getBinding(lView, bindingIndex) {
ngDevMode && assertDataInRange(lView, lView[bindingIndex]);
ngDevMode &&
assertNotEqual(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
return lView[bindingIndex];
}
/** Updates binding if changed, then returns whether it was updated. */
function bindingUpdated(lView, bindingIndex, value) {
ngDevMode && assertNotEqual(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
ngDevMode &&
assertLessThan(bindingIndex, lView.length, "Slot should have been initialized to NO_CHANGE");
if (lView[bindingIndex] === NO_CHANGE) {
// initial pass
lView[bindingIndex] = value;
}
else if (isDifferent(lView[bindingIndex], value)) {
if (ngDevMode && getCheckNoChangesMode()) {
if (!devModeEqual(lView[bindingIndex], value)) {
throwErrorIfNoChangesMode(isCreationMode(lView), lView[bindingIndex], value);
}
}
lView[bindingIndex] = value;
}
else {
return false;
}
return true;
}
/** Updates 2 bindings if changed, then returns whether either was updated. */
function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
var different = bindingUpdated(lView, bindingIndex, exp1);
return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
}
/** Updates 3 bindings if changed, then returns whether any was updated. */
function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
var different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
}
/** Updates 4 bindings if changed, then returns whether any was updated. */
function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
var different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var NG_PROJECT_AS_ATTR_NAME = 'ngProjectAs';
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// TODO: cleanup once the code is merged in angular/angular
var RendererStyleFlags3;
(function (RendererStyleFlags3) {
RendererStyleFlags3[RendererStyleFlags3["Important"] = 1] = "Important";
RendererStyleFlags3[RendererStyleFlags3["DashCase"] = 2] = "DashCase";
})(RendererStyleFlags3 || (RendererStyleFlags3 = {}));
/** Returns whether the `renderer` is a `ProceduralRenderer3` */
function isProceduralRenderer(renderer) {
return !!(renderer.listen);
}
var domRendererFactory3 = {
createRenderer: function (hostElement, rendererType) { return document; }
};
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** Retrieves the parent element of a given node. */
function getParentNative(tNode, currentView) {
if (tNode.parent == null) {
return getHostNative(currentView);
}
else {
var parentTNode = getFirstParentNative(tNode);
return getNativeByTNode(parentTNode, currentView);
}
}
/**
* Get the first parent of a node that isn't an IcuContainer TNode
*/
function getFirstParentNative(tNode) {
var parent = tNode.parent;
while (parent && parent.type === 5 /* IcuContainer */) {
parent = parent.parent;
}
return parent;
}
/**
* Gets the host element given a view. Will return null if the current view is an embedded view,
* which does not have a host element.
*/
function getHostNative(currentView) {
var hostTNode = currentView[HOST_NODE];
return hostTNode && hostTNode.type !== 2 /* View */ ?
getNativeByTNode(hostTNode, currentView[PARENT]) :
null;
}
function getLContainer(tNode, embeddedView) {
if (tNode.index === -1) {
// This is a dynamically created view inside a dynamic container.
// If the host index is -1, the view has not yet been inserted, so it has no parent.
var containerHostIndex = embeddedView[CONTAINER_INDEX];
return containerHostIndex > -1 ? embeddedView[PARENT][containerHostIndex] : null;
}
else {
// This is a inline view node (e.g. embeddedViewStart)
return embeddedView[PARENT][tNode.parent.index];
}
}
/**
* Retrieves render parent for a given view.
* Might be null if a view is not yet attached to any container.
*/
function getContainerRenderParent(tViewNode, view) {
var container = getLContainer(tViewNode, view);
return container ? container[RENDER_PARENT] : null;
}
/**
* Stack used to keep track of projection nodes in walkTNodeTree.
*
* This is deliberately created outside of walkTNodeTree to avoid allocating
* a new array each time the function is called. Instead the array will be
* re-used by each invocation. This works because the function is not reentrant.
*/
var projectionNodeStack = [];
/**
* Walks a tree of TNodes, applying a transformation on the element nodes, either only on the first
* one found, or on all of them.
*
* @param viewToWalk the view to walk
* @param action identifies the action to be performed on the elements
* @param renderer the current renderer.
* @param renderParent Optional the render parent node to be set in all LContainers found,
* required for action modes Insert and Destroy.
* @param beforeNode Optional the node before which elements should be added, required for action
* Insert.
*/
function walkTNodeTree(viewToWalk, action, renderer, renderParent, beforeNode) {
var rootTNode = viewToWalk[TVIEW].node;
var projectionNodeIndex = -1;
var currentView = viewToWalk;
var tNode = rootTNode.child;
while (tNode) {
var nextTNode = null;
if (tNode.type === 3 /* Element */) {
executeNodeAction(action, renderer, renderParent, getNativeByTNode(tNode, currentView), beforeNode);
var nodeOrContainer = currentView[tNode.index];
if (isLContainer(nodeOrContainer)) {
// This element has an LContainer, and its comment needs to be handled
executeNodeAction(action, renderer, renderParent, nodeOrContainer[NATIVE], beforeNode);
}
}
else if (tNode.type === 0 /* Container */) {
var lContainer = currentView[tNode.index];
executeNodeAction(action, renderer, renderParent, lContainer[NATIVE], beforeNode);
if (renderParent)
lContainer[RENDER_PARENT] = renderParent;
if (lContainer[VIEWS].length) {
currentView = lContainer[VIEWS][0];
nextTNode = currentView[TVIEW].node;
// When the walker enters a container, then the beforeNode has to become the local native
// comment node.
beforeNode = lContainer[NATIVE];
}
}
else if (tNode.type === 1 /* Projection */) {
var componentView = findComponentView(currentView);
var componentHost = componentView[HOST_NODE];
var head = componentHost.projection[tNode.projection];
// Must store both the TNode and the view because this projection node could be nested
// deeply inside embedded views, and we need to get back down to this particular nested view.
projectionNodeStack[++projectionNodeIndex] = tNode;
projectionNodeStack[++projectionNodeIndex] = currentView;
if (head) {
currentView = componentView[PARENT];
nextTNode = currentView[TVIEW].data[head.index];
}
}
else {
// Otherwise, this is a View or an ElementContainer
nextTNode = tNode.child;
}
if (nextTNode === null) {
// this last node was projected, we need to get back down to its projection node
if (tNode.next === null && (tNode.flags & 2 /* isProjected */)) {
currentView = projectionNodeStack[projectionNodeIndex--];
tNode = projectionNodeStack[projectionNodeIndex--];
}
nextTNode = tNode.next;
/**
* Find the next node in the TNode tree, taking into account the place where a node is
* projected (in the shadow DOM) rather than where it comes from (in the light DOM).
*
* If there is no sibling node, then it goes to the next sibling of the parent node...
* until it reaches rootNode (at which point null is returned).
*/
while (!nextTNode) {
// If parent is null, we're crossing the view boundary, so we should get the host TNode.
tNode = tNode.parent || currentView[TVIEW].node;
if (tNode === null || tNode === rootTNode)
return null;
// When exiting a container, the beforeNode must be restored to the previous value
if (tNode.type === 0 /* Container */) {
currentView = currentView[PARENT];
beforeNode = currentView[tNode.index][NATIVE];
}
if (tNode.type === 2 /* View */ && currentView[NEXT]) {
currentView = currentView[NEXT];
nextTNode = currentView[TVIEW].node;
}
else {
nextTNode = tNode.next;
}
}
}
tNode = nextTNode;
}
}
/**
* NOTE: for performance reasons, the possible actions are inlined within the function instead of
* being passed as an argument.
*/
function executeNodeAction(action, renderer, parent, node, beforeNode) {
if (action === 0 /* Insert */) {
isProceduralRenderer(renderer) ?
renderer.insertBefore(parent, node, beforeNode) :
parent.insertBefore(node, beforeNode, true);
}
else if (action === 1 /* Detach */) {
isProceduralRenderer(renderer) ?
renderer.removeChild(parent, node) :
parent.removeChild(node);
}
else if (action === 2 /* Destroy */) {
ngDevMode && ngDevMode.rendererDestroyNode++;
renderer.destroyNode(node);
}
}
function createTextNode(value, renderer) {
return isProceduralRenderer(renderer) ? renderer.createText(stringify$1(value)) :
renderer.createTextNode(stringify$1(value));
}
function addRemoveViewFromContainer(viewToWalk, insertMode, beforeNode) {
var renderParent = getContainerRenderParent(viewToWalk[TVIEW].node, viewToWalk);
ngDevMode && assertNodeType(viewToWalk[TVIEW].node, 2 /* View */);
if (renderParent) {
var renderer = viewToWalk[RENDERER];
walkTNodeTree(viewToWalk, insertMode ? 0 /* Insert */ : 1 /* Detach */, renderer, renderParent, beforeNode);
}
}
/**
* Traverses down and up the tree of views and containers to remove listeners and
* call onDestroy callbacks.
*
* Notes:
* - Because it's used for onDestroy calls, it needs to be bottom-up.
* - Must process containers instead of their views to avoid splicing
* when views are destroyed and re-added.
* - Using a while loop because it's faster than recursion
* - Destroy only called on movement to sibling or movement to parent (laterally or up)
*
* @param rootView The view to destroy
*/
function destroyViewTree(rootView) {
// If the view has no children, we can clean it up and return early.
if (rootView[TVIEW].childIndex === -1) {
return cleanUpView(rootView);
}
var viewOrContainer = getLViewChild(rootView);
while (viewOrContainer) {
var next = null;
if (viewOrContainer.length >= HEADER_OFFSET) {
// If LView, traverse down to child.
var view = viewOrContainer;
if (view[TVIEW].childIndex > -1)
next = getLViewChild(view);
}
else {
// If container, traverse down to its first LView.
var container = viewOrContainer;
if (container[VIEWS].length)
next = container[VIEWS][0];
}
if (next == null) {
// Only clean up view when moving to the side or up, as destroy hooks
// should be called in order from the bottom up.
while (viewOrContainer && !viewOrContainer[NEXT] && viewOrContainer !== rootView) {
cleanUpView(viewOrContainer);
viewOrContainer = getParentState(viewOrContainer, rootView);
}
cleanUpView(viewOrContainer || rootView);
next = viewOrContainer && viewOrContainer[NEXT];
}
viewOrContainer = next;
}
}
/**
* Inserts a view into a container.
*
* This adds the view to the container's array of active views in the correct
* position. It also adds the view's elements to the DOM if the container isn't a
* root node of another view (in that case, the view's elements will be added when
* the container's parent view is added later).
*
* @param lView The view to insert
* @param lContainer The container into which the view should be inserted
* @param parentView The new parent of the inserted view
* @param index The index at which to insert the view
* @param containerIndex The index of the container node, if dynamic
*/
function insertView(lView, lContainer, parentView, index, containerIndex) {
var views = lContainer[VIEWS];
if (index > 0) {
// This is a new view, we need to add it to the children.
views[index - 1][NEXT] = lView;
}
if (index < views.length) {
lView[NEXT] = views[index];
views.splice(index, 0, lView);
}
else {
views.push(lView);
lView[NEXT] = null;
}
// Dynamically inserted views need a reference to their parent container's host so it's
// possible to jump from a view to its container's next when walking the node tree.
if (containerIndex > -1) {
lView[CONTAINER_INDEX] = containerIndex;
lView[PARENT] = parentView;
}
// Notify query that a new view has been added
if (lView[QUERIES]) {
lView[QUERIES].insertView(index);
}
// Sets the attached flag
lView[FLAGS] |= 16 /* Attached */;
}
/**
* Detaches a view from a container.
*
* This method splices the view from the container's array of active views. It also
* removes the view's elements from the DOM.
*
* @param lContainer The container from which to detach a view
* @param removeIndex The index of the view to detach
* @param detached Whether or not this view is already detached.
* @returns Detached LView instance.
*/
function detachView(lContainer, removeIndex, detached) {
var views = lContainer[VIEWS];
var viewToDetach = views[removeIndex];
if (removeIndex > 0) {
views[removeIndex - 1][NEXT] = viewToDetach[NEXT];
}
views.splice(removeIndex, 1);
if (!detached) {
addRemoveViewFromContainer(viewToDetach, false);
}
if (viewToDetach[QUERIES]) {
viewToDetach[QUERIES].removeView();
}
viewToDetach[CONTAINER_INDEX] = -1;
viewToDetach[PARENT] = null;
// Unsets the attached flag
viewToDetach[FLAGS] &= ~16 /* Attached */;
return viewToDetach;
}
/**
* Removes a view from a container, i.e. detaches it and then destroys the underlying LView.
*
* @param lContainer The container from which to remove a view
* @param tContainer The TContainer node associated with the LContainer
* @param removeIndex The index of the view to remove
*/
function removeView(lContainer, containerHost, removeIndex) {
var view = lContainer[VIEWS][removeIndex];
detachView(lContainer, removeIndex, !!containerHost.detached);
destroyLView(view);
}
/** Gets the child of the given LView */
function getLViewChild(lView) {
var childIndex = lView[TVIEW].childIndex;
return childIndex === -1 ? null : lView[childIndex];
}
/**
* A standalone function which destroys an LView,
* conducting cleanup (e.g. removing listeners, calling onDestroys).
*
* @param view The view to be destroyed.
*/
function destroyLView(view) {
var renderer = view[RENDERER];
if (isProceduralRenderer(renderer) && renderer.destroyNode) {
walkTNodeTree(view, 2 /* Destroy */, renderer, null);
}
destroyViewTree(view);
// Sets the destroyed flag
view[FLAGS] |= 64 /* Destroyed */;
}
/**
* Determines which LViewOrLContainer to jump to when traversing back up the
* tree in destroyViewTree.
*
* Normally, the view's parent LView should be checked, but in the case of
* embedded views, the container (which is the view node's parent, but not the
* LView's parent) needs to be checked for a possible next property.
*
* @param state The LViewOrLContainer for which we need a parent state
* @param rootView The rootView, so we don't propagate too far up the view tree
* @returns The correct parent LViewOrLContainer
*/
function getParentState(state, rootView) {
var tNode;
if (state.length >= HEADER_OFFSET && (tNode = state[HOST_NODE]) &&
tNode.type === 2 /* View */) {
// if it's an embedded view, the state needs to go up to the container, in case the
// container has a next
return getLContainer(tNode, state);
}
else {
// otherwise, use parent view for containers or component views
return state[PARENT] === rootView ? null : state[PARENT];
}
}
/**
* Calls onDestroys hooks for all directives and pipes in a given view and then removes all
* listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
* can be propagated to @Output listeners.
*
* @param view The LView to clean up
*/
function cleanUpView(viewOrContainer) {
if (viewOrContainer.length >= HEADER_OFFSET) {
var view = viewOrContainer;
executeOnDestroys(view);
executePipeOnDestroys(view);
removeListeners(view);
var hostTNode = view[HOST_NODE];
// For component views only, the local renderer is destroyed as clean up time.
if (hostTNode && hostTNode.type === 3 /* Element */ && isProceduralRenderer(view[RENDERER])) {
ngDevMode && ngDevMode.rendererDestroy++;
view[RENDERER].destroy();
}
}
}
/** Removes listeners and unsubscribes from output subscriptions */
function removeListeners(lView) {
var tCleanup = lView[TVIEW].cleanup;
if (tCleanup != null) {
var lCleanup = lView[CLEANUP];
for (var i = 0; i < tCleanup.length - 1; i += 2) {
if (typeof tCleanup[i] === 'string') {
// This is a listener with the native renderer
var idx = tCleanup[i + 1];
var listener = lCleanup[tCleanup[i + 2]];
var native = readElementValue(lView[idx]);
var useCaptureOrSubIdx = tCleanup[i + 3];
if (typeof useCaptureOrSubIdx === 'boolean') {
// DOM listener
native.removeEventListener(tCleanup[i], listener, useCaptureOrSubIdx);
}
else {
if (useCaptureOrSubIdx >= 0) {
// unregister
lCleanup[useCaptureOrSubIdx]();
}
else {
// Subscription
lCleanup[-useCaptureOrSubIdx].unsubscribe();
}
}
i += 2;
}
else if (typeof tCleanup[i] === 'number') {
// This is a listener with renderer2 (cleanup fn can be found by index)
var cleanupFn = lCleanup[tCleanup[i]];
cleanupFn();
}
else {
// This is a cleanup function that is grouped with the index of its context
var context = lCleanup[tCleanup[i + 1]];
tCleanup[i].call(context);
}
}
lView[CLEANUP] = null;
}
}
/** Calls onDestroy hooks for this view */
function executeOnDestroys(view) {
var tView = view[TVIEW];
var destroyHooks;
if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
callHooks(view, destroyHooks);
}
}
/** Calls pipe destroy hooks for this view */
function executePipeOnDestroys(lView) {
var pipeDestroyHooks = lView[TVIEW] && lView[TVIEW].pipeDestroyHooks;
if (pipeDestroyHooks) {
callHooks(lView, pipeDestroyHooks);
}
}
function getRenderParent(tNode, currentView) {
if (canInsertNativeNode(tNode, currentView)) {
// If we are asked for a render parent of the root component we need to do low-level DOM
// operation as LTree doesn't exist above the topmost host node. We might need to find a render
// parent of the topmost host node if the root component injects ViewContainerRef.
if (isRootView(currentView)) {
return nativeParentNode(currentView[RENDERER], getNativeByTNode(tNode, currentView));
}
var hostTNode = currentView[HOST_NODE];
var tNodeParent = tNode.parent;
if (tNodeParent != null && tNodeParent.type === 4 /* ElementContainer */) {
tNode = getHighestElementContainer(tNodeParent);
}
return tNode.parent == null && hostTNode.type === 2 /* View */ ?
getContainerRenderParent(hostTNode, currentView) :
getParentNative(tNode, currentView);
}
return null;
}
function canInsertNativeChildOfElement(tNode) {
// If the parent is null, then we are inserting across views. This happens when we
// insert a root element of the component view into the component host element and it
// should always be eager.
if (tNode.parent == null ||
// We should also eagerly insert if the parent is a regular, non-component element
// since we know that this relationship will never be broken.
tNode.parent.type === 3 /* Element */ && !(tNode.parent.flags & 1 /* isComponent */)) {
return true;
}
// Parent is a Component. Component's content nodes are not inserted immediately
// because they will be projected, and so doing insert at this point would be wasteful.
// Since the projection would than move it to its final destination.
return false;
}
/**
* We might delay insertion of children for a given view if it is disconnected.
* This might happen for 2 main reasons:
* - view is not inserted into any container (view was created but not inserted yet)
* - view is inserted into a container but the container itself is not inserted into the DOM
* (container might be part of projection or child of a view that is not inserted yet).
*
* In other words we can insert children of a given view if this view was inserted into a container
* and
* the container itself has its render parent determined.
*/
function canInsertNativeChildOfView(viewTNode, view) {
// Because we are inserting into a `View` the `View` may be disconnected.
var container = getLContainer(viewTNode, view);
if (container == null || container[RENDER_PARENT] == null) {
// The `View` is not inserted into a `Container` or the parent `Container`
// itself is disconnected. So we have to delay.
return false;
}
// The parent `Container` is in inserted state, so we can eagerly insert into
// this location.
return true;
}
/**
* Returns whether a native element can be inserted into the given parent.
*
* There are two reasons why we may not be able to insert a element immediately.
* - Projection: When creating a child content element of a component, we have to skip the
* insertion because the content of a component will be projected.
* `<component><content>delayed due to projection</content></component>`
* - Parent container is disconnected: This can happen when we are inserting a view into
* parent container, which itself is disconnected. For example the parent container is part
* of a View which has not be inserted or is mare for projection but has not been inserted
* into destination.
*
*
* @param tNode The tNode of the node that we want to insert.
* @param currentView Current LView being processed.
* @return boolean Whether the node should be inserted now (or delayed until later).
*/
function canInsertNativeNode(tNode, currentView) {
var currentNode = tNode;
var parent = tNode.parent;
if (tNode.parent) {
if (tNode.parent.type === 4 /* ElementContainer */) {
currentNode = getHighestElementContainer(tNode);
parent = currentNode.parent;
}
else if (tNode.parent.type === 5 /* IcuContainer */) {
currentNode = getFirstParentNative(currentNode);
parent = currentNode.parent;
}
}
if (parent === null)
parent = currentView[HOST_NODE];
if (parent && parent.type === 2 /* View */) {
return canInsertNativeChildOfView(parent, currentView);
}
else {
// Parent is a regular element or a component
return canInsertNativeChildOfElement(currentNode);
}
}
/**
* Inserts a native node before another native node for a given parent using {@link Renderer3}.
* This is a utility function that can be used when native nodes were determined - it abstracts an
* actual renderer being used.
*/
function nativeInsertBefore(renderer, parent, child, beforeNode) {
if (isProceduralRenderer(renderer)) {
renderer.insertBefore(parent, child, beforeNode);
}
else {
parent.insertBefore(child, beforeNode, true);
}
}
/**
* Returns a native parent of a given native node.
*/
function nativeParentNode(renderer, node) {
return (isProceduralRenderer(renderer) ? renderer.parentNode(node) : node.parentNode);
}
/**
* Returns a native sibling of a given native node.
*/
function nativeNextSibling(renderer, node) {
return isProceduralRenderer(renderer) ? renderer.nextSibling(node) : node.nextSibling;
}
/**
* Appends the `child` element to the `parent`.
*
* The element insertion might be delayed {@link canInsertNativeNode}.
*
* @param childEl The child that should be appended
* @param childTNode The TNode of the child element
* @param currentView The current LView
* @returns Whether or not the child was appended
*/
function appendChild(childEl, childTNode, currentView) {
if (childEl === void 0) { childEl = null; }
if (childEl !== null && canInsertNativeNode(childTNode, currentView)) {
var renderer = currentView[RENDERER];
var parentEl = getParentNative(childTNode, currentView);
var parentTNode = childTNode.parent || currentView[HOST_NODE];
if (parentTNode.type === 2 /* View */) {
var lContainer = getLContainer(parentTNode, currentView);
var views = lContainer[VIEWS];
var index = views.indexOf(currentView);
nativeInsertBefore(renderer, lContainer[RENDER_PARENT], childEl, getBeforeNodeForView(index, views, lContainer[NATIVE]));
}
else if (parentTNode.type === 4 /* ElementContainer */) {
var renderParent = getRenderParent(childTNode, currentView);
nativeInsertBefore(renderer, renderParent, childEl, parentEl);
}
else if (parentTNode.type === 5 /* IcuContainer */) {
var icuAnchorNode = getNativeByTNode(childTNode.parent, currentView);
nativeInsertBefore(renderer, parentEl, childEl, icuAnchorNode);
}
else {
isProceduralRenderer(renderer) ? renderer.appendChild(parentEl, childEl) :
parentEl.appendChild(childEl);
}
return true;
}
return false;
}
/**
* Gets the top-level ng-container if ng-containers are nested.
*
* @param ngContainer The TNode of the starting ng-container
* @returns tNode The TNode of the highest level ng-container
*/
function getHighestElementContainer(ngContainer) {
while (ngContainer.parent != null && ngContainer.parent.type === 4 /* ElementContainer */) {
ngContainer = ngContainer.parent;
}
return ngContainer;
}
function getBeforeNodeForView(index, views, containerNative) {
if (index + 1 < views.length) {
var view = views[index + 1];
var viewTNode = view[HOST_NODE];
return viewTNode.child ? getNativeByTNode(viewTNode.child, view) : containerNative;
}
else {
return containerNative;
}
}
/**
* Removes the `child` element from the DOM if not in view and not projected.
*
* @param childTNode The TNode of the child to remove
* @param childEl The child that should be removed
* @param currentView The current LView
* @returns Whether or not the child was removed
*/
function removeChild(childTNode, childEl, currentView) {
// We only remove the element if not in View or not projected.
if (childEl !== null && canInsertNativeNode(childTNode, currentView)) {
var parentNative = getParentNative(childTNode, currentView);
var renderer = currentView[RENDERER];
isProceduralRenderer(renderer) ? renderer.removeChild(parentNative, childEl) :
parentNative.removeChild(childEl);
return true;
}
return false;
}
/**
* Appends a projected node to the DOM, or in the case of a projected container,
* appends the nodes from all of the container's active views to the DOM.
*
* @param projectedTNode The TNode to be projected
* @param tProjectionNode The projection (ng-content) TNode
* @param currentView Current LView
* @param projectionView Projection view (view above current)
*/
function appendProjectedNode(projectedTNode, tProjectionNode, currentView, projectionView) {
var native = getNativeByTNode(projectedTNode, projectionView);
appendChild(native, tProjectionNode, currentView);
// the projected contents are processed while in the shadow view (which is the currentView)
// therefore we need to extract the view where the host element lives since it's the
// logical container of the content projected views
attachPatchData(native, projectionView);
var renderParent = getRenderParent(tProjectionNode, currentView);
var nodeOrContainer = projectionView[projectedTNode.index];
if (projectedTNode.type === 0 /* Container */) {
// The node we are adding is a container and we are adding it to an element which
// is not a component (no more re-projection).
// Alternatively a container is projected at the root of a component's template
// and can't be re-projected (as not content of any component).
// Assign the final projection location in those cases.
nodeOrContainer[RENDER_PARENT] = renderParent;
var views = nodeOrContainer[VIEWS];
for (var i = 0; i < views.length; i++) {
addRemoveViewFromContainer(views[i], true, nodeOrContainer[NATIVE]);
}
}
else {
if (projectedTNode.type === 4 /* ElementContainer */) {
var ngContainerChildTNode = projectedTNode.child;
while (ngContainerChildTNode) {
appendProjectedNode(ngContainerChildTNode, tProjectionNode, currentView, projectionView);
ngContainerChildTNode = ngContainerChildTNode.next;
}
}
if (isLContainer(nodeOrContainer)) {
nodeOrContainer[RENDER_PARENT] = renderParent;
appendChild(nodeOrContainer[NATIVE], tProjectionNode, currentView);
}
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var NG_TEMPLATE_SELECTOR = 'ng-template';
function isCssClassMatching(nodeClassAttrVal, cssClassToMatch) {
var nodeClassesLen = nodeClassAttrVal.length;
var matchIndex = nodeClassAttrVal.indexOf(cssClassToMatch);
var matchEndIdx = matchIndex + cssClassToMatch.length;
if (matchIndex === -1 // no match
|| (matchIndex > 0 && nodeClassAttrVal[matchIndex - 1] !== ' ') // no space before
||
(matchEndIdx < nodeClassesLen && nodeClassAttrVal[matchEndIdx] !== ' ')) // no space after
{
return false;
}
return true;
}
/**
* Function that checks whether a given tNode matches tag-based selector and has a valid type.
*
* Matching can be perfomed in 2 modes: projection mode (when we project nodes) and regular
* directive matching mode. In "projection" mode, we do not need to check types, so if tag name
* matches selector, we declare a match. In "directive matching" mode, we also check whether tNode
* is of expected type:
* - whether tNode has either Element or ElementContainer type
* - or if we want to match "ng-template" tag, we check for Container type
*/
function hasTagAndTypeMatch(tNode, currentSelector, isProjectionMode) {
return currentSelector === tNode.tagName &&
(isProjectionMode ||
(tNode.type === 3 /* Element */ || tNode.type === 4 /* ElementContainer */) ||
(tNode.type === 0 /* Container */ && currentSelector === NG_TEMPLATE_SELECTOR));
}
/**
* A utility function to match an Ivy node static data against a simple CSS selector
*
* @param node static data to match
* @param selector
* @returns true if node matches the selector.
*/
function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
var mode = 4 /* ELEMENT */;
var nodeAttrs = tNode.attrs;
var selectOnlyMarkerIdx = nodeAttrs ? nodeAttrs.indexOf(3 /* SelectOnly */) : -1;
// When processing ":not" selectors, we skip to the next ":not" if the
// current one doesn't match
var skipToNextSelector = false;
for (var i = 0; i < selector.length; i++) {
var current = selector[i];
if (typeof current === 'number') {
// If we finish processing a :not selector and it hasn't failed, return false
if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {
return false;
}
// If we are skipping to the next :not() and this mode flag is positive,
// it's a part of the current :not() selector, and we should keep skipping
if (skipToNextSelector && isPositive(current))
continue;
skipToNextSelector = false;
mode = current | (mode & 1 /* NOT */);
continue;
}
if (skipToNextSelector)
continue;
if (mode & 4 /* ELEMENT */) {
mode = 2 /* ATTRIBUTE */ | mode & 1 /* NOT */;
if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) ||
current === '' && selector.length === 1) {
if (isPositive(mode))
return false;
skipToNextSelector = true;
}
}
else {
var attrName = mode & 8 /* CLASS */ ? 'class' : current;
var attrIndexInNode = findAttrIndexInNode(attrName, nodeAttrs);
if (attrIndexInNode === -1) {
if (isPositive(mode))
return false;
skipToNextSelector = true;
continue;
}
var selectorAttrValue = mode & 8 /* CLASS */ ? current : selector[++i];
if (selectorAttrValue !== '') {
var nodeAttrValue = void 0;
var maybeAttrName = nodeAttrs[attrIndexInNode];
if (selectOnlyMarkerIdx > -1 && attrIndexInNode > selectOnlyMarkerIdx) {
nodeAttrValue = '';
}
else {
ngDevMode && assertNotEqual(maybeAttrName, 0 /* NamespaceURI */, 'We do not match directives on namespaced attributes');
nodeAttrValue = nodeAttrs[attrIndexInNode + 1];
}
if (mode & 8 /* CLASS */ &&
!isCssClassMatching(nodeAttrValue, selectorAttrValue) ||
mode & 2 /* ATTRIBUTE */ && selectorAttrValue !== nodeAttrValue) {
if (isPositive(mode))
return false;
skipToNextSelector = true;
}
}
}
}
return isPositive(mode) || skipToNextSelector;
}
function isPositive(mode) {
return (mode & 1 /* NOT */) === 0;
}
/**
* Examines an attributes definition array from a node to find the index of the
* attribute with the specified name.
*
* NOTE: Will not find namespaced attributes.
*
* @param name the name of the attribute to find
* @param attrs the attribute array to examine
*/
function findAttrIndexInNode(name, attrs) {
if (attrs === null)
return -1;
var selectOnlyMode = false;
var i = 0;
while (i < attrs.length) {
var maybeAttrName = attrs[i];
if (maybeAttrName === name) {
return i;
}
else if (maybeAttrName === 0 /* NamespaceURI */) {
// NOTE(benlesh): will not find namespaced attributes. This is by design.
i += 4;
}
else {
if (maybeAttrName === 3 /* SelectOnly */) {
selectOnlyMode = true;
}
i += selectOnlyMode ? 1 : 2;
}
}
return -1;
}
function isNodeMatchingSelectorList(tNode, selector, isProjectionMode) {
if (isProjectionMode === void 0) { isProjectionMode = false; }
for (var i = 0; i < selector.length; i++) {
if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) {
return true;
}
}
return false;
}
function getProjectAsAttrValue(tNode) {
var nodeAttrs = tNode.attrs;
if (nodeAttrs != null) {
var ngProjectAsAttrIdx = nodeAttrs.indexOf(NG_PROJECT_AS_ATTR_NAME);
// only check for ngProjectAs in attribute names, don't accidentally match attribute's value
// (attribute names are stored at even indexes)
if ((ngProjectAsAttrIdx & 1) === 0) {
return nodeAttrs[ngProjectAsAttrIdx + 1];
}
}
return null;
}
/**
* Checks a given node against matching selectors and returns
* selector index (or 0 if none matched).
*
* This function takes into account the ngProjectAs attribute: if present its value will be compared
* to the raw (un-parsed) CSS selector instead of using standard selector matching logic.
*/
function matchingSelectorIndex(tNode, selectors, textSelectors) {
var ngProjectAsAttrVal = getProjectAsAttrValue(tNode);
for (var i = 0; i < selectors.length; i++) {
// if a node has the ngProjectAs attribute match it against unparsed selector
// match a node against a parsed selector only if ngProjectAs attribute is not present
if (ngProjectAsAttrVal === textSelectors[i] ||
ngProjectAsAttrVal === null &&
isNodeMatchingSelectorList(tNode, selectors[i], /* isProjectionMode */ true)) {
return i + 1; // first matching selector "captures" a given node
}
}
return 0;
}
/**
* Combines the binding value and a factory for an animation player.
*
* Used to bind a player to an element template binding (currently only
* `[style]`, `[style.prop]`, `[class]` and `[class.name]` bindings
* supported). The provided `factoryFn` function will be run once all
* the associated bindings have been evaluated on the element and is
* designed to return a player which will then be placed on the element.
*
* @param factoryFn The function that is used to create a player
* once all the rendering-related (styling values) have been
* processed for the element binding.
* @param value The raw value that will be exposed to the binding
* so that the binding can update its internal values when
* any changes are evaluated.
*/
function bindPlayerFactory(factoryFn, value) {
return new BoundPlayerFactory(factoryFn, value);
}
var BoundPlayerFactory = /** @class */ (function () {
function BoundPlayerFactory(fn, value) {
this.fn = fn;
this.value = value;
}
return BoundPlayerFactory;
}());
var CorePlayerHandler = /** @class */ (function () {
function CorePlayerHandler() {
this._players = [];
}
CorePlayerHandler.prototype.flushPlayers = function () {
for (var i = 0; i < this._players.length; i++) {
var player = this._players[i];
if (!player.parent && player.state === 0 /* Pending */) {
player.play();
}
}
this._players.length = 0;
};
CorePlayerHandler.prototype.queuePlayer = function (player) { this._players.push(player); };
return CorePlayerHandler;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var ANIMATION_PROP_PREFIX = '@';
function createEmptyStylingContext(element, sanitizer, initialStyles, initialClasses) {
return [
0,
[null, -1, false, sanitizer || null],
initialStyles || [null],
initialClasses || [null],
[0, 0],
element || null,
null,
null,
null,
];
}
/**
* Used clone a copy of a pre-computed template of a styling context.
*
* A pre-computed template is designed to be computed once for a given element
* (instructions.ts has logic for caching this).
*/
function allocStylingContext(element, templateStyleContext) {
// each instance gets a copy
var context = templateStyleContext.slice();
context[5 /* ElementPosition */] = element;
// this will prevent any other directives from extending the context
context[0 /* MasterFlagPosition */] |= 32 /* BindingAllocationLocked */;
return context;
}
/**
* Retrieve the `StylingContext` at a given index.
*
* This method lazily creates the `StylingContext`. This is because in most cases
* we have styling without any bindings. Creating `StylingContext` eagerly would mean that
* every style declaration such as `<div style="color: red">` would result `StyleContext`
* which would create unnecessary memory pressure.
*
* @param index Index of the style allocation. See: `elementStyling`.
* @param viewData The view to search for the styling context
*/
function getStylingContext(index, viewData) {
var storageIndex = index;
var slotValue = viewData[storageIndex];
var wrapper = viewData;
while (Array.isArray(slotValue)) {
wrapper = slotValue;
slotValue = slotValue[HOST];
}
if (isStylingContext(wrapper)) {
return wrapper;
}
else {
// This is an LView or an LContainer
var stylingTemplate = getTNode(index - HEADER_OFFSET, viewData).stylingTemplate;
if (wrapper !== viewData) {
storageIndex = HOST;
}
return wrapper[storageIndex] = stylingTemplate ?
allocStylingContext(slotValue, stylingTemplate) :
createEmptyStylingContext(slotValue);
}
}
function isStylingContext(value) {
// Not an LView or an LContainer
return Array.isArray(value) && typeof value[0 /* MasterFlagPosition */] === 'number' &&
Array.isArray(value[2 /* InitialStyleValuesPosition */]);
}
function isAnimationProp(name) {
return name[0] === ANIMATION_PROP_PREFIX;
}
function addPlayerInternal(playerContext, rootContext, element, player, playerContextIndex, ref) {
ref = ref || element;
if (playerContextIndex) {
playerContext[playerContextIndex] = player;
}
else {
playerContext.push(player);
}
if (player) {
player.addEventListener(200 /* Destroyed */, function () {
var index = playerContext.indexOf(player);
var nonFactoryPlayerIndex = playerContext[0 /* NonBuilderPlayersStart */];
// if the player is being removed from the factory side of the context
// (which is where the [style] and [class] bindings do their thing) then
// that side of the array cannot be resized since the respective bindings
// have pointer index values that point to the associated factory instance
if (index) {
if (index < nonFactoryPlayerIndex) {
playerContext[index] = null;
}
else {
playerContext.splice(index, 1);
}
}
player.destroy();
});
var playerHandler = rootContext.playerHandler || (rootContext.playerHandler = new CorePlayerHandler());
playerHandler.queuePlayer(player, ref);
return true;
}
return false;
}
function getPlayersInternal(playerContext) {
var players = [];
var nonFactoryPlayersStart = playerContext[0 /* NonBuilderPlayersStart */];
// add all factory-based players (which are apart of [style] and [class] bindings)
for (var i = 1 /* PlayerBuildersStartPosition */ + 1 /* PlayerOffsetPosition */; i < nonFactoryPlayersStart; i += 2 /* PlayerAndPlayerBuildersTupleSize */) {
var player = playerContext[i];
if (player) {
players.push(player);
}
}
// add all custom players (not apart of [style] and [class] bindings)
for (var i = nonFactoryPlayersStart; i < playerContext.length; i++) {
players.push(playerContext[i]);
}
return players;
}
function getOrCreatePlayerContext(target, context) {
context = context || getLContext(target);
if (!context) {
ngDevMode && throwInvalidRefError();
return null;
}
var lView = context.lView, nodeIndex = context.nodeIndex;
var stylingContext = getStylingContext(nodeIndex, lView);
return getPlayerContext(stylingContext) || allocPlayerContext(stylingContext);
}
function getPlayerContext(stylingContext) {
return stylingContext[8 /* PlayerContext */];
}
function allocPlayerContext(data) {
return data[8 /* PlayerContext */] =
[5 /* SinglePlayerBuildersStartPosition */, null, null, null, null];
}
function throwInvalidRefError() {
throw new Error('Only elements that exist in an Angular application can be used for animations');
}
function hasStyling(attrs) {
for (var i = 0; i < attrs.length; i++) {
var attr = attrs[i];
if (attr == 1 /* Classes */ || attr == 2 /* Styles */)
return true;
}
return false;
}
function hasClassInput(tNode) {
return tNode.flags & 8 /* hasClassInput */ ? true : false;
}
/**
* This file includes the code to power all styling-binding operations in Angular.
*
* These include:
* [style]="myStyleObj"
* [class]="myClassObj"
* [style.prop]="myPropValue"
* [class.name]="myClassValue"
*
* There are many different ways in which these functions below are called. Please see
* `interfaces/styles.ts` to get a better idea of how the styling algorithm works.
*/
/**
* Creates a new StylingContext an fills it with the provided static styling attribute values.
*/
function initializeStaticContext(attrs) {
var context = createEmptyStylingContext();
var initialClasses = context[3 /* InitialClassValuesPosition */] =
[null];
var initialStyles = context[2 /* InitialStyleValuesPosition */] =
[null];
// The attributes array has marker values (numbers) indicating what the subsequent
// values represent. When we encounter a number, we set the mode to that type of attribute.
var mode = -1;
for (var i = 0; i < attrs.length; i++) {
var attr = attrs[i];
if (typeof attr == 'number') {
mode = attr;
}
else if (mode === 2 /* Styles */) {
initialStyles.push(attr, attrs[++i]);
}
else if (mode === 1 /* Classes */) {
initialClasses.push(attr, true);
}
else if (mode === 3 /* SelectOnly */) {
break;
}
}
return context;
}
/**
* Designed to update an existing styling context with new static styling
* data (classes and styles).
*
* @param context the existing styling context
* @param attrs an array of new static styling attributes that will be
* assigned to the context
* @param directive the directive instance with which static data is associated with.
*/
function patchContextWithStaticAttrs(context, attrs, directive) {
// If the styling context has already been patched with the given directive's bindings,
// then there is no point in doing it again. The reason why this may happen (the directive
// styling being patched twice) is because the `stylingBinding` function is called each time
// an element is created (both within a template function and within directive host bindings).
var directives = context[1 /* DirectiveRegistryPosition */];
if (getDirectiveRegistryValuesIndexOf(directives, directive) == -1) {
// this is a new directive which we have not seen yet.
directives.push(directive, -1, false, null);
var initialClasses = null;
var initialStyles = null;
var mode = -1;
for (var i = 0; i < attrs.length; i++) {
var attr = attrs[i];
if (typeof attr == 'number') {
mode = attr;
}
else if (mode == 1 /* Classes */) {
initialClasses = initialClasses || context[3 /* InitialClassValuesPosition */];
patchInitialStylingValue(initialClasses, attr, true);
}
else if (mode == 2 /* Styles */) {
initialStyles = initialStyles || context[2 /* InitialStyleValuesPosition */];
patchInitialStylingValue(initialStyles, attr, attrs[++i]);
}
}
}
}
/**
* Designed to add a style or class value into the existing set of initial styles.
*
* The function will search and figure out if a style/class value is already present
* within the provided initial styling array. If and when a style/class value is not
* present (or if it's value is falsy) then it will be inserted/updated in the list
* of initial styling values.
*/
function patchInitialStylingValue(initialStyling, prop, value) {
// Even values are keys; Odd numbers are values; Search keys only
for (var i = 1 /* KeyValueStartPosition */; i < initialStyling.length;) {
var key = initialStyling[i];
if (key === prop) {
var existingValue = initialStyling[i + 1 /* ValueOffset */];
// If there is no previous style value (when `null`) or no previous class
// applied (when `false`) then we update the the newly given value.
if (existingValue == null || existingValue == false) {
initialStyling[i + 1 /* ValueOffset */] = value;
}
return;
}
i = i + 2 /* Size */;
}
// We did not find existing key, add a new one.
initialStyling.push(prop, value);
}
/**
* Runs through the initial styling data present in the context and renders
* them via the renderer on the element.
*/
function renderInitialStylesAndClasses(element, context, renderer) {
var initialClasses = context[3 /* InitialClassValuesPosition */];
renderInitialStylingValues(element, renderer, initialClasses, true);
var initialStyles = context[2 /* InitialStyleValuesPosition */];
renderInitialStylingValues(element, renderer, initialStyles, false);
}
/**
* This is a helper function designed to render each entry present within the
* provided list of initialStylingValues.
*/
function renderInitialStylingValues(element, renderer, initialStylingValues, isEntryClassBased) {
for (var i = 1 /* KeyValueStartPosition */; i < initialStylingValues.length; i += 2 /* Size */) {
var value = initialStylingValues[i + 1 /* ValueOffset */];
if (value) {
if (isEntryClassBased) {
setClass(element, initialStylingValues[i + 0 /* PropOffset */], true, renderer, null);
}
else {
setStyle(element, initialStylingValues[i + 0 /* PropOffset */], value, renderer, null);
}
}
}
}
/**
* Adds in new binding values to a styling context.
*
* If a directive value is provided then all provided class/style binding names will
* reference the provided directive.
*
* @param context the existing styling context
* @param directiveRef the directive that the new bindings will reference
* @param classBindingNames an array of class binding names that will be added to the context
* @param styleBindingNames an array of style binding names that will be added to the context
* @param styleSanitizer an optional sanitizer that handle all sanitization on for each of
* the bindings added to the context. Note that if a directive is provided then the sanitizer
* instance will only be active if and when the directive updates the bindings that it owns.
*/
function updateContextWithBindings(context, directiveRef, classBindingNames, styleBindingNames, styleSanitizer, onlyProcessSingleClasses) {
if (context[0 /* MasterFlagPosition */] & 32 /* BindingAllocationLocked */)
return;
// this means the context has already been patched with the directive's bindings
var directiveIndex = findOrPatchDirectiveIntoRegistry(context, directiveRef, styleSanitizer);
if (directiveIndex === -1) {
// this means the directive has already been patched in ... No point in doing anything
return;
}
// there are alot of variables being used below to track where in the context the new
// binding values will be placed. Because the context consists of multiple types of
// entries (single classes/styles and multi classes/styles) alot of the index positions
// need to be computed ahead of time and the context needs to be extended before the values
// are inserted in.
var singlePropOffsetValues = context[4 /* SinglePropOffsetPositions */];
var totalCurrentClassBindings = singlePropOffsetValues[1 /* ClassesCountPosition */];
var totalCurrentStyleBindings = singlePropOffsetValues[0 /* StylesCountPosition */];
var classesOffset = totalCurrentClassBindings * 4 /* Size */;
var stylesOffset = totalCurrentStyleBindings * 4 /* Size */;
var singleStylesStartIndex = 9 /* SingleStylesStartPosition */;
var singleClassesStartIndex = singleStylesStartIndex + stylesOffset;
var multiStylesStartIndex = singleClassesStartIndex + classesOffset;
var multiClassesStartIndex = multiStylesStartIndex + stylesOffset;
// because we're inserting more bindings into the context, this means that the
// binding values need to be referenced the singlePropOffsetValues array so that
// the template/directive can easily find them inside of the `elementStyleProp`
// and the `elementClassProp` functions without iterating through the entire context.
// The first step to setting up these reference points is to mark how many bindings
// are being added. Even if these bindings already exist in the context, the directive
// or template code will still call them unknowingly. Therefore the total values need
// to be registered so that we know how many bindings are assigned to each directive.
var currentSinglePropsLength = singlePropOffsetValues.length;
singlePropOffsetValues.push(styleBindingNames ? styleBindingNames.length : 0, classBindingNames ? classBindingNames.length : 0);
// the code below will check to see if a new style binding already exists in the context
// if so then there is no point in inserting it into the context again. Whether or not it
// exists the styling offset code will now know exactly where it is
var insertionOffset = 0;
var filteredStyleBindingNames = [];
if (styleBindingNames && styleBindingNames.length) {
for (var i_1 = 0; i_1 < styleBindingNames.length; i_1++) {
var name_1 = styleBindingNames[i_1];
var singlePropIndex = getMatchingBindingIndex(context, name_1, singleStylesStartIndex, singleClassesStartIndex);
if (singlePropIndex == -1) {
singlePropIndex = singleClassesStartIndex + insertionOffset;
insertionOffset += 4 /* Size */;
filteredStyleBindingNames.push(name_1);
}
singlePropOffsetValues.push(singlePropIndex);
}
}
// just like with the style binding loop above, the new class bindings get the same treatment...
var filteredClassBindingNames = [];
if (classBindingNames && classBindingNames.length) {
for (var i_2 = 0; i_2 < classBindingNames.length; i_2++) {
var name_2 = classBindingNames[i_2];
var singlePropIndex = getMatchingBindingIndex(context, name_2, singleClassesStartIndex, multiStylesStartIndex);
if (singlePropIndex == -1) {
singlePropIndex = multiStylesStartIndex + insertionOffset;
insertionOffset += 4 /* Size */;
filteredClassBindingNames.push(name_2);
}
else {
singlePropIndex += filteredStyleBindingNames.length * 4 /* Size */;
}
singlePropOffsetValues.push(singlePropIndex);
}
}
// because new styles are being inserted, this means the existing collection of style offset
// index values are incorrect (they point to the wrong values). The code below will run through
// the entire offset array and update the existing set of index values to point to their new
// locations while taking the new binding values into consideration.
var i = 2 /* ValueStartPosition */;
if (filteredStyleBindingNames.length) {
while (i < currentSinglePropsLength) {
var totalStyles = singlePropOffsetValues[i + 0 /* StylesCountPosition */];
var totalClasses = singlePropOffsetValues[i + 1 /* ClassesCountPosition */];
if (totalClasses) {
var start = i + 2 /* ValueStartPosition */ + totalStyles;
for (var j = start; j < start + totalClasses; j++) {
singlePropOffsetValues[j] += filteredStyleBindingNames.length * 4 /* Size */;
}
}
var total = totalStyles + totalClasses;
i += 2 /* ValueStartPosition */ + total;
}
}
var totalNewEntries = filteredClassBindingNames.length + filteredStyleBindingNames.length;
// in the event that there are new style values being inserted, all existing class and style
// bindings need to have their pointer values offsetted with the new amount of space that is
// used for the new style/class bindings.
for (var i_3 = singleStylesStartIndex; i_3 < context.length; i_3 += 4 /* Size */) {
var isMultiBased = i_3 >= multiStylesStartIndex;
var isClassBased = i_3 >= (isMultiBased ? multiClassesStartIndex : singleClassesStartIndex);
var flag = getPointers(context, i_3);
var staticIndex = getInitialIndex(flag);
var singleOrMultiIndex = getMultiOrSingleIndex(flag);
if (isMultiBased) {
singleOrMultiIndex +=
isClassBased ? (filteredStyleBindingNames.length * 4 /* Size */) : 0;
}
else {
singleOrMultiIndex += (totalNewEntries * 4 /* Size */) +
((isClassBased ? filteredStyleBindingNames.length : 0) * 4 /* Size */);
}
setFlag(context, i_3, pointers(flag, staticIndex, singleOrMultiIndex));
}
// this is where we make space in the context for the new style bindings
for (var i_4 = 0; i_4 < filteredStyleBindingNames.length * 4 /* Size */; i_4++) {
context.splice(multiClassesStartIndex, 0, null);
context.splice(singleClassesStartIndex, 0, null);
singleClassesStartIndex++;
multiStylesStartIndex++;
multiClassesStartIndex += 2; // both single + multi slots were inserted
}
// this is where we make space in the context for the new class bindings
for (var i_5 = 0; i_5 < filteredClassBindingNames.length * 4 /* Size */; i_5++) {
context.splice(multiStylesStartIndex, 0, null);
context.push(null);
multiStylesStartIndex++;
multiClassesStartIndex++;
}
var initialClasses = context[3 /* InitialClassValuesPosition */];
var initialStyles = context[2 /* InitialStyleValuesPosition */];
// the code below will insert each new entry into the context and assign the appropriate
// flags and index values to them. It's important this runs at the end of this function
// because the context, property offset and index values have all been computed just before.
for (var i_6 = 0; i_6 < totalNewEntries; i_6++) {
var entryIsClassBased = i_6 >= filteredStyleBindingNames.length;
var adjustedIndex = entryIsClassBased ? (i_6 - filteredStyleBindingNames.length) : i_6;
var propName = entryIsClassBased ? filteredClassBindingNames[adjustedIndex] :
filteredStyleBindingNames[adjustedIndex];
var multiIndex = void 0, singleIndex = void 0;
if (entryIsClassBased) {
multiIndex = multiClassesStartIndex +
((totalCurrentClassBindings + adjustedIndex) * 4 /* Size */);
singleIndex = singleClassesStartIndex +
((totalCurrentClassBindings + adjustedIndex) * 4 /* Size */);
}
else {
multiIndex =
multiStylesStartIndex + ((totalCurrentStyleBindings + adjustedIndex) * 4 /* Size */);
singleIndex = singleStylesStartIndex +
((totalCurrentStyleBindings + adjustedIndex) * 4 /* Size */);
}
// if a property is not found in the initial style values list then it
// is ALWAYS added incase a follow-up directive introduces the same initial
// style/class value later on.
var initialValuesToLookup = entryIsClassBased ? initialClasses : initialStyles;
var indexForInitial = getInitialStylingValuesIndexOf(initialValuesToLookup, propName);
if (indexForInitial === -1) {
indexForInitial = initialValuesToLookup.length + 1 /* ValueOffset */;
initialValuesToLookup.push(propName, entryIsClassBased ? false : null);
}
else {
indexForInitial += 1 /* ValueOffset */;
}
var initialFlag = prepareInitialFlag(context, propName, entryIsClassBased, styleSanitizer || null);
setFlag(context, singleIndex, pointers(initialFlag, indexForInitial, multiIndex));
setProp(context, singleIndex, propName);
setValue(context, singleIndex, null);
setPlayerBuilderIndex(context, singleIndex, 0, directiveIndex);
setFlag(context, multiIndex, pointers(initialFlag, indexForInitial, singleIndex));
setProp(context, multiIndex, propName);
setValue(context, multiIndex, null);
setPlayerBuilderIndex(context, multiIndex, 0, directiveIndex);
}
// the total classes/style values are updated so the next time the context is patched
// additional style/class bindings from another directive then it knows exactly where
// to insert them in the context
singlePropOffsetValues[1 /* ClassesCountPosition */] =
totalCurrentClassBindings + filteredClassBindingNames.length;
singlePropOffsetValues[0 /* StylesCountPosition */] =
totalCurrentStyleBindings + filteredStyleBindingNames.length;
// there is no initial value flag for the master index since it doesn't
// reference an initial style value
var masterFlag = pointers(0, 0, multiStylesStartIndex) |
(onlyProcessSingleClasses ? 16 /* OnlyProcessSingleClasses */ : 0);
setFlag(context, 0 /* MasterFlagPosition */, masterFlag);
}
/**
* Searches through the existing registry of directives
*/
function findOrPatchDirectiveIntoRegistry(context, directiveRef, styleSanitizer) {
var directiveRefs = context[1 /* DirectiveRegistryPosition */];
var nextOffsetInsertionIndex = context[4 /* SinglePropOffsetPositions */].length;
var directiveIndex;
var detectedIndex = getDirectiveRegistryValuesIndexOf(directiveRefs, directiveRef);
if (detectedIndex === -1) {
directiveIndex = directiveRefs.length / 4 /* Size */;
directiveRefs.push(directiveRef, nextOffsetInsertionIndex, false, styleSanitizer || null);
}
else {
var singlePropStartPosition = detectedIndex + 1 /* SinglePropValuesIndexOffset */;
if (directiveRefs[singlePropStartPosition] >= 0) {
// the directive has already been patched into the context
return -1;
}
directiveIndex = detectedIndex / 4 /* Size */;
// because the directive already existed this means that it was set during elementHostAttrs or
// elementStart which means that the binding values were not here. Therefore, the values below
// need to be applied so that single class and style properties can be assigned later.
var singlePropPositionIndex = detectedIndex + 1 /* SinglePropValuesIndexOffset */;
directiveRefs[singlePropPositionIndex] = nextOffsetInsertionIndex;
// the sanitizer is also apart of the binding process and will be used when bindings are
// applied.
var styleSanitizerIndex = detectedIndex + 3 /* StyleSanitizerOffset */;
directiveRefs[styleSanitizerIndex] = styleSanitizer || null;
}
return directiveIndex;
}
function getMatchingBindingIndex(context, bindingName, start, end) {
for (var j = start; j < end; j += 4 /* Size */) {
if (getProp(context, j) === bindingName)
return j;
}
return -1;
}
/**
* Sets and resolves all `multi` styling on an `StylingContext` so that they can be
* applied to the element once `renderStyling` is called.
*
* All missing styles/class (any values that are not provided in the new `styles`
* or `classes` params) will resolve to `null` within their respective positions
* in the context.
*
* @param context The styling context that will be updated with the
* newly provided style values.
* @param classesInput The key/value map of CSS class names that will be used for the update.
* @param stylesInput The key/value map of CSS styles that will be used for the update.
*/
function updateStylingMap(context, classesInput, stylesInput, directiveRef) {
stylesInput = stylesInput || null;
var directiveIndex = getDirectiveIndexFromRegistry(context, directiveRef || null);
var element = context[5 /* ElementPosition */];
var classesPlayerBuilder = classesInput instanceof BoundPlayerFactory ?
new ClassAndStylePlayerBuilder(classesInput, element, 1 /* Class */) :
null;
var stylesPlayerBuilder = stylesInput instanceof BoundPlayerFactory ?
new ClassAndStylePlayerBuilder(stylesInput, element, 2 /* Style */) :
null;
var classesValue = classesPlayerBuilder ?
classesInput.value :
classesInput;
var stylesValue = stylesPlayerBuilder ? stylesInput.value : stylesInput;
// early exit (this is what's done to avoid using ctx.bind() to cache the value)
var ignoreAllClassUpdates = limitToSingleClasses(context) || classesValue === NO_CHANGE ||
classesValue === context[6 /* CachedClassValueOrInitialClassString */];
var ignoreAllStyleUpdates = stylesValue === NO_CHANGE || stylesValue === context[7 /* CachedStyleValue */];
if (ignoreAllClassUpdates && ignoreAllStyleUpdates)
return;
context[6 /* CachedClassValueOrInitialClassString */] = classesValue;
context[7 /* CachedStyleValue */] = stylesValue;
var classNames = EMPTY_ARRAY;
var applyAllClasses = false;
var playerBuildersAreDirty = false;
var classesPlayerBuilderIndex = classesPlayerBuilder ? 1 /* ClassMapPlayerBuilderPosition */ : 0;
if (hasPlayerBuilderChanged(context, classesPlayerBuilder, 1 /* ClassMapPlayerBuilderPosition */)) {
setPlayerBuilder(context, classesPlayerBuilder, 1 /* ClassMapPlayerBuilderPosition */);
playerBuildersAreDirty = true;
}
var stylesPlayerBuilderIndex = stylesPlayerBuilder ? 3 /* StyleMapPlayerBuilderPosition */ : 0;
if (hasPlayerBuilderChanged(context, stylesPlayerBuilder, 3 /* StyleMapPlayerBuilderPosition */)) {
setPlayerBuilder(context, stylesPlayerBuilder, 3 /* StyleMapPlayerBuilderPosition */);
playerBuildersAreDirty = true;
}
// each time a string-based value pops up then it shouldn't require a deep
// check of what's changed.
if (!ignoreAllClassUpdates) {
if (typeof classesValue == 'string') {
classNames = classesValue.split(/\s+/);
// this boolean is used to avoid having to create a key/value map of `true` values
// since a classname string implies that all those classes are added
applyAllClasses = true;
}
else {
classNames = classesValue ? Object.keys(classesValue) : EMPTY_ARRAY;
}
}
var classes = (classesValue || EMPTY_OBJ);
var styleProps = stylesValue ? Object.keys(stylesValue) : EMPTY_ARRAY;
var styles = stylesValue || EMPTY_OBJ;
var classesStartIndex = styleProps.length;
var multiStartIndex = getMultiStartIndex(context);
var dirty = false;
var ctxIndex = multiStartIndex;
var propIndex = 0;
var propLimit = styleProps.length + classNames.length;
// the main loop here will try and figure out how the shape of the provided
// styles differ with respect to the context. Later if the context/styles/classes
// are off-balance then they will be dealt in another loop after this one
while (ctxIndex < context.length && propIndex < propLimit) {
var isClassBased = propIndex >= classesStartIndex;
var processValue = (!isClassBased && !ignoreAllStyleUpdates) || (isClassBased && !ignoreAllClassUpdates);
// when there is a cache-hit for a string-based class then we should
// avoid doing any work diffing any of the changes
if (processValue) {
var adjustedPropIndex = isClassBased ? propIndex - classesStartIndex : propIndex;
var newProp = isClassBased ? classNames[adjustedPropIndex] : styleProps[adjustedPropIndex];
var newValue = isClassBased ? (applyAllClasses ? true : classes[newProp]) : styles[newProp];
var playerBuilderIndex = isClassBased ? classesPlayerBuilderIndex : stylesPlayerBuilderIndex;
var prop = getProp(context, ctxIndex);
if (prop === newProp) {
var value = getValue(context, ctxIndex);
var flag = getPointers(context, ctxIndex);
setPlayerBuilderIndex(context, ctxIndex, playerBuilderIndex, directiveIndex);
if (hasValueChanged(flag, value, newValue)) {
setValue(context, ctxIndex, newValue);
playerBuildersAreDirty = playerBuildersAreDirty || !!playerBuilderIndex;
var initialValue = getInitialValue(context, flag);
// SKIP IF INITIAL CHECK
// If the former `value` is `null` then it means that an initial value
// could be being rendered on screen. If that is the case then there is
// no point in updating the value incase it matches. In other words if the
// new value is the exact same as the previously rendered value (which
// happens to be the initial value) then do nothing.
if (value != null || hasValueChanged(flag, initialValue, newValue)) {
setDirty(context, ctxIndex, true);
dirty = true;
}
}
}
else {
var indexOfEntry = findEntryPositionByProp(context, newProp, ctxIndex);
if (indexOfEntry > 0) {
// it was found at a later point ... just swap the values
var valueToCompare = getValue(context, indexOfEntry);
var flagToCompare = getPointers(context, indexOfEntry);
swapMultiContextEntries(context, ctxIndex, indexOfEntry);
if (hasValueChanged(flagToCompare, valueToCompare, newValue)) {
var initialValue = getInitialValue(context, flagToCompare);
setValue(context, ctxIndex, newValue);
// same if statement logic as above (look for SKIP IF INITIAL CHECK).
if (valueToCompare != null || hasValueChanged(flagToCompare, initialValue, newValue)) {
setDirty(context, ctxIndex, true);
playerBuildersAreDirty = playerBuildersAreDirty || !!playerBuilderIndex;
dirty = true;
}
}
}
else {
// we only care to do this if the insertion is in the middle
var newFlag = prepareInitialFlag(context, newProp, isClassBased, getStyleSanitizer(context, directiveIndex));
playerBuildersAreDirty = playerBuildersAreDirty || !!playerBuilderIndex;
insertNewMultiProperty(context, ctxIndex, isClassBased, newProp, newFlag, newValue, directiveIndex, playerBuilderIndex);
dirty = true;
}
}
}
ctxIndex += 4 /* Size */;
propIndex++;
}
// this means that there are left-over values in the context that
// were not included in the provided styles/classes and in this
// case the goal is to "remove" them from the context (by nullifying)
while (ctxIndex < context.length) {
var flag = getPointers(context, ctxIndex);
var isClassBased = (flag & 2 /* Class */) === 2 /* Class */;
var processValue = (!isClassBased && !ignoreAllStyleUpdates) || (isClassBased && !ignoreAllClassUpdates);
if (processValue) {
var value = getValue(context, ctxIndex);
var doRemoveValue = valueExists(value, isClassBased);
if (doRemoveValue) {
setDirty(context, ctxIndex, true);
setValue(context, ctxIndex, null);
// we keep the player factory the same so that the `nulled` value can
// be instructed into the player because removing a style and/or a class
// is a valid animation player instruction.
var playerBuilderIndex = isClassBased ? classesPlayerBuilderIndex : stylesPlayerBuilderIndex;
setPlayerBuilderIndex(context, ctxIndex, playerBuilderIndex, directiveIndex);
dirty = true;
}
}
ctxIndex += 4 /* Size */;
}
// this means that there are left-over properties in the context that
// were not detected in the context during the loop above. In that
// case we want to add the new entries into the list
var sanitizer = getStyleSanitizer(context, directiveIndex);
while (propIndex < propLimit) {
var isClassBased = propIndex >= classesStartIndex;
var processValue = (!isClassBased && !ignoreAllStyleUpdates) || (isClassBased && !ignoreAllClassUpdates);
if (processValue) {
var adjustedPropIndex = isClassBased ? propIndex - classesStartIndex : propIndex;
var prop = isClassBased ? classNames[adjustedPropIndex] : styleProps[adjustedPropIndex];
var value = isClassBased ? (applyAllClasses ? true : classes[prop]) : styles[prop];
var flag = prepareInitialFlag(context, prop, isClassBased, sanitizer) | 1 /* Dirty */;
var playerBuilderIndex = isClassBased ? classesPlayerBuilderIndex : stylesPlayerBuilderIndex;
var ctxIndex_1 = context.length;
context.push(flag, prop, value, 0);
setPlayerBuilderIndex(context, ctxIndex_1, playerBuilderIndex, directiveIndex);
dirty = true;
}
propIndex++;
}
if (dirty) {
setContextDirty(context, true);
setDirectiveDirty(context, directiveIndex, true);
}
if (playerBuildersAreDirty) {
setContextPlayersDirty(context, true);
}
}
/**
* This method will toggle the referenced CSS class (by the provided index)
* within the given context.
*
* @param context The styling context that will be updated with the
* newly provided class value.
* @param offset The index of the CSS class which is being updated.
* @param addOrRemove Whether or not to add or remove the CSS class
*/
function updateClassProp(context, offset, addOrRemove, directiveRef) {
_updateSingleStylingValue(context, offset, addOrRemove, true, directiveRef);
}
/**
* Sets and resolves a single style value on the provided `StylingContext` so
* that they can be applied to the element once `renderStyling` is called.
*
* Note that prop-level styling values are considered higher priority than any styling that
* has been applied using `updateStylingMap`, therefore, when styling values are rendered
* then any styles/classes that have been applied using this function will be considered first
* (then multi values second and then initial values as a backup).
*
* @param context The styling context that will be updated with the
* newly provided style value.
* @param offset The index of the property which is being updated.
* @param value The CSS style value that will be assigned
* @param directiveRef an optional reference to the directive responsible
* for this binding change. If present then style binding will only
* actualize if the directive has ownership over this binding
* (see styling.ts#directives for more information about the algorithm).
*/
function updateStyleProp(context, offset, input, directiveRef) {
_updateSingleStylingValue(context, offset, input, false, directiveRef);
}
function _updateSingleStylingValue(context, offset, input, isClassBased, directiveRef) {
var directiveIndex = getDirectiveIndexFromRegistry(context, directiveRef || null);
var singleIndex = getSinglePropIndexValue(context, directiveIndex, offset, isClassBased);
var currValue = getValue(context, singleIndex);
var currFlag = getPointers(context, singleIndex);
var currDirective = getDirectiveIndexFromEntry(context, singleIndex);
var value = (input instanceof BoundPlayerFactory) ? input.value : input;
if (hasValueChanged(currFlag, currValue, value) &&
allowValueChange(currValue, value, currDirective, directiveIndex)) {
var isClassBased_1 = (currFlag & 2 /* Class */) === 2 /* Class */;
var element = context[5 /* ElementPosition */];
var playerBuilder = input instanceof BoundPlayerFactory ?
new ClassAndStylePlayerBuilder(input, element, isClassBased_1 ? 1 /* Class */ : 2 /* Style */) :
null;
var value_1 = (playerBuilder ? input.value : input);
var currPlayerIndex = getPlayerBuilderIndex(context, singleIndex);
var playerBuildersAreDirty = false;
var playerBuilderIndex = playerBuilder ? currPlayerIndex : 0;
if (hasPlayerBuilderChanged(context, playerBuilder, currPlayerIndex)) {
var newIndex = setPlayerBuilder(context, playerBuilder, currPlayerIndex);
playerBuilderIndex = playerBuilder ? newIndex : 0;
playerBuildersAreDirty = true;
}
if (playerBuildersAreDirty || currDirective !== directiveIndex) {
setPlayerBuilderIndex(context, singleIndex, playerBuilderIndex, directiveIndex);
}
if (currDirective !== directiveIndex) {
var prop = getProp(context, singleIndex);
var sanitizer = getStyleSanitizer(context, directiveIndex);
setSanitizeFlag(context, singleIndex, (sanitizer && sanitizer(prop)) ? true : false);
}
// the value will always get updated (even if the dirty flag is skipped)
setValue(context, singleIndex, value_1);
var indexForMulti = getMultiOrSingleIndex(currFlag);
// if the value is the same in the multi-area then there's no point in re-assembling
var valueForMulti = getValue(context, indexForMulti);
if (!valueForMulti || hasValueChanged(currFlag, valueForMulti, value_1)) {
var multiDirty = false;
var singleDirty = true;
// only when the value is set to `null` should the multi-value get flagged
if (!valueExists(value_1, isClassBased_1) && valueExists(valueForMulti, isClassBased_1)) {
multiDirty = true;
singleDirty = false;
}
setDirty(context, indexForMulti, multiDirty);
setDirty(context, singleIndex, singleDirty);
setDirectiveDirty(context, directiveIndex, true);
setContextDirty(context, true);
}
if (playerBuildersAreDirty) {
setContextPlayersDirty(context, true);
}
}
}
/**
* Renders all queued styling using a renderer onto the given element.
*
* This function works by rendering any styles (that have been applied
* using `updateStylingMap`) and any classes (that have been applied using
* `updateStyleProp`) onto the provided element using the provided renderer.
* Just before the styles/classes are rendered a final key/value style map
* will be assembled (if `styleStore` or `classStore` are provided).
*
* @param lElement the element that the styles will be rendered on
* @param context The styling context that will be used to determine
* what styles will be rendered
* @param renderer the renderer that will be used to apply the styling
* @param classesStore if provided, the updated class values will be applied
* to this key/value map instead of being renderered via the renderer.
* @param stylesStore if provided, the updated style values will be applied
* to this key/value map instead of being renderered via the renderer.
* @param directiveRef an optional directive that will be used to target which
* styling values are rendered. If left empty, only the bindings that are
* registered on the template will be rendered.
* @returns number the total amount of players that got queued for animation (if any)
*/
function renderStyling(context, renderer, rootOrView, isFirstRender, classesStore, stylesStore, directiveRef) {
var totalPlayersQueued = 0;
var targetDirectiveIndex = getDirectiveIndexFromRegistry(context, directiveRef || null);
if (isContextDirty(context) && isDirectiveDirty(context, targetDirectiveIndex)) {
var flushPlayerBuilders = context[0 /* MasterFlagPosition */] & 8 /* PlayerBuildersDirty */;
var native = context[5 /* ElementPosition */];
var multiStartIndex = getMultiStartIndex(context);
var onlySingleClasses = limitToSingleClasses(context);
var stillDirty = false;
for (var i = 9 /* SingleStylesStartPosition */; i < context.length; i += 4 /* Size */) {
// there is no point in rendering styles that have not changed on screen
if (isDirty(context, i)) {
var flag = getPointers(context, i);
var directiveIndex = getDirectiveIndexFromEntry(context, i);
if (targetDirectiveIndex !== directiveIndex) {
stillDirty = true;
continue;
}
var prop = getProp(context, i);
var value = getValue(context, i);
var styleSanitizer = (flag & 4 /* Sanitize */) ? getStyleSanitizer(context, directiveIndex) : null;
var playerBuilder = getPlayerBuilder(context, i);
var isClassBased = flag & 2 /* Class */ ? true : false;
var isInSingleRegion = i < multiStartIndex;
var readInitialValue = !isClassBased || !onlySingleClasses;
var valueToApply = value;
// VALUE DEFER CASE 1: Use a multi value instead of a null single value
// this check implies that a single value was removed and we
// should now defer to a multi value and use that (if set).
if (isInSingleRegion && !valueExists(valueToApply, isClassBased)) {
// single values ALWAYS have a reference to a multi index
var multiIndex = getMultiOrSingleIndex(flag);
valueToApply = getValue(context, multiIndex);
}
// VALUE DEFER CASE 2: Use the initial value if all else fails (is falsy)
// the initial value will always be a string or null,
// therefore we can safely adopt it incase there's nothing else
// note that this should always be a falsy check since `false` is used
// for both class and style comparisons (styles can't be false and false
// classes are turned off and should therefore defer to their initial values)
// Note that we ignore class-based deferals because otherwise a class can never
// be removed in the case that it exists as true in the initial classes list...
if (!isClassBased && !valueExists(valueToApply, isClassBased) && readInitialValue) {
valueToApply = getInitialValue(context, flag);
}
// if the first render is true then we do not want to start applying falsy
// values to the DOM element's styling. Otherwise then we know there has
// been a change and even if it's falsy then it's removing something that
// was truthy before.
var doApplyValue = isFirstRender ? valueToApply : true;
if (doApplyValue) {
if (isClassBased) {
setClass(native, prop, valueToApply ? true : false, renderer, classesStore, playerBuilder);
}
else {
setStyle(native, prop, valueToApply, renderer, styleSanitizer, stylesStore, playerBuilder);
}
}
setDirty(context, i, false);
}
}
if (flushPlayerBuilders) {
var rootContext = Array.isArray(rootOrView) ? getRootContext(rootOrView) : rootOrView;
var playerContext = getPlayerContext(context);
var playersStartIndex = playerContext[0 /* NonBuilderPlayersStart */];
for (var i = 1 /* PlayerBuildersStartPosition */; i < playersStartIndex; i += 2 /* PlayerAndPlayerBuildersTupleSize */) {
var builder = playerContext[i];
var playerInsertionIndex = i + 1 /* PlayerOffsetPosition */;
var oldPlayer = playerContext[playerInsertionIndex];
if (builder) {
var player = builder.buildPlayer(oldPlayer, isFirstRender);
if (player !== undefined) {
if (player != null) {
var wasQueued = addPlayerInternal(playerContext, rootContext, native, player, playerInsertionIndex);
wasQueued && totalPlayersQueued++;
}
if (oldPlayer) {
oldPlayer.destroy();
}
}
}
else if (oldPlayer) {
// the player builder has been removed ... therefore we should delete the associated
// player
oldPlayer.destroy();
}
}
setContextPlayersDirty(context, false);
}
setDirectiveDirty(context, targetDirectiveIndex, false);
setContextDirty(context, stillDirty);
}
return totalPlayersQueued;
}
/**
* This function renders a given CSS prop/value entry using the
* provided renderer. If a `store` value is provided then
* that will be used a render context instead of the provided
* renderer.
*
* @param native the DOM Element
* @param prop the CSS style property that will be rendered
* @param value the CSS style value that will be rendered
* @param renderer
* @param store an optional key/value map that will be used as a context to render styles on
*/
function setStyle(native, prop, value, renderer, sanitizer, store, playerBuilder) {
value = sanitizer && value ? sanitizer(prop, value) : value;
if (store || playerBuilder) {
if (store) {
store.setValue(prop, value);
}
if (playerBuilder) {
playerBuilder.setValue(prop, value);
}
}
else if (value) {
value = value.toString(); // opacity, z-index and flexbox all have number values which may not
// assign as numbers
ngDevMode && ngDevMode.rendererSetStyle++;
isProceduralRenderer(renderer) ?
renderer.setStyle(native, prop, value, RendererStyleFlags3.DashCase) :
native['style'].setProperty(prop, value);
}
else {
ngDevMode && ngDevMode.rendererRemoveStyle++;
isProceduralRenderer(renderer) ?
renderer.removeStyle(native, prop, RendererStyleFlags3.DashCase) :
native['style'].removeProperty(prop);
}
}
/**
* This function renders a given CSS class value using the provided
* renderer (by adding or removing it from the provided element).
* If a `store` value is provided then that will be used a render
* context instead of the provided renderer.
*
* @param native the DOM Element
* @param prop the CSS style property that will be rendered
* @param value the CSS style value that will be rendered
* @param renderer
* @param store an optional key/value map that will be used as a context to render styles on
*/
function setClass(native, className, add, renderer, store, playerBuilder) {
if (store || playerBuilder) {
if (store) {
store.setValue(className, add);
}
if (playerBuilder) {
playerBuilder.setValue(className, add);
}
}
else if (add) {
ngDevMode && ngDevMode.rendererAddClass++;
isProceduralRenderer(renderer) ? renderer.addClass(native, className) :
native['classList'].add(className);
}
else {
ngDevMode && ngDevMode.rendererRemoveClass++;
isProceduralRenderer(renderer) ? renderer.removeClass(native, className) :
native['classList'].remove(className);
}
}
function setSanitizeFlag(context, index, sanitizeYes) {
if (sanitizeYes) {
context[index] |= 4 /* Sanitize */;
}
else {
context[index] &= ~4 /* Sanitize */;
}
}
function setDirty(context, index, isDirtyYes) {
var adjustedIndex = index >= 9 /* SingleStylesStartPosition */ ? (index + 0 /* FlagsOffset */) : index;
if (isDirtyYes) {
context[adjustedIndex] |= 1 /* Dirty */;
}
else {
context[adjustedIndex] &= ~1 /* Dirty */;
}
}
function isDirty(context, index) {
var adjustedIndex = index >= 9 /* SingleStylesStartPosition */ ? (index + 0 /* FlagsOffset */) : index;
return (context[adjustedIndex] & 1 /* Dirty */) == 1 /* Dirty */;
}
function isClassBasedValue(context, index) {
var adjustedIndex = index >= 9 /* SingleStylesStartPosition */ ? (index + 0 /* FlagsOffset */) : index;
return (context[adjustedIndex] & 2 /* Class */) == 2 /* Class */;
}
function isSanitizable(context, index) {
var adjustedIndex = index >= 9 /* SingleStylesStartPosition */ ? (index + 0 /* FlagsOffset */) : index;
return (context[adjustedIndex] & 4 /* Sanitize */) == 4 /* Sanitize */;
}
function pointers(configFlag, staticIndex, dynamicIndex) {
return (configFlag & 63 /* BitMask */) | (staticIndex << 6 /* BitCountSize */) |
(dynamicIndex << (14 /* BitCountSize */ + 6 /* BitCountSize */));
}
function getInitialValue(context, flag) {
var index = getInitialIndex(flag);
var entryIsClassBased = flag & 2 /* Class */;
var initialValues = entryIsClassBased ? context[3 /* InitialClassValuesPosition */] :
context[2 /* InitialStyleValuesPosition */];
return initialValues[index];
}
function getInitialIndex(flag) {
return (flag >> 6 /* BitCountSize */) & 16383 /* BitMask */;
}
function getMultiOrSingleIndex(flag) {
var index = (flag >> (14 /* BitCountSize */ + 6 /* BitCountSize */)) & 16383 /* BitMask */;
return index >= 9 /* SingleStylesStartPosition */ ? index : -1;
}
function getMultiStartIndex(context) {
return getMultiOrSingleIndex(context[0 /* MasterFlagPosition */]);
}
function setProp(context, index, prop) {
context[index + 1 /* PropertyOffset */] = prop;
}
function setValue(context, index, value) {
context[index + 2 /* ValueOffset */] = value;
}
function hasPlayerBuilderChanged(context, builder, index) {
var playerContext = context[8 /* PlayerContext */];
if (builder) {
if (!playerContext || index === 0) {
return true;
}
}
else if (!playerContext) {
return false;
}
return playerContext[index] !== builder;
}
function setPlayerBuilder(context, builder, insertionIndex) {
var playerContext = context[8 /* PlayerContext */] || allocPlayerContext(context);
if (insertionIndex > 0) {
playerContext[insertionIndex] = builder;
}
else {
insertionIndex = playerContext[0 /* NonBuilderPlayersStart */];
playerContext.splice(insertionIndex, 0, builder, null);
playerContext[0 /* NonBuilderPlayersStart */] +=
2 /* PlayerAndPlayerBuildersTupleSize */;
}
return insertionIndex;
}
function directiveOwnerPointers(directiveIndex, playerIndex) {
return (playerIndex << 16 /* BitCountSize */) | directiveIndex;
}
function setPlayerBuilderIndex(context, index, playerBuilderIndex, directiveIndex) {
var value = directiveOwnerPointers(directiveIndex, playerBuilderIndex);
context[index + 3 /* PlayerBuilderIndexOffset */] = value;
}
function getPlayerBuilderIndex(context, index) {
var flag = context[index + 3 /* PlayerBuilderIndexOffset */];
var playerBuilderIndex = (flag >> 16 /* BitCountSize */) &
65535 /* BitMask */;
return playerBuilderIndex;
}
function getPlayerBuilder(context, index) {
var playerBuilderIndex = getPlayerBuilderIndex(context, index);
if (playerBuilderIndex) {
var playerContext = context[8 /* PlayerContext */];
if (playerContext) {
return playerContext[playerBuilderIndex];
}
}
return null;
}
function setFlag(context, index, flag) {
var adjustedIndex = index === 0 /* MasterFlagPosition */ ? index : (index + 0 /* FlagsOffset */);
context[adjustedIndex] = flag;
}
function getPointers(context, index) {
var adjustedIndex = index === 0 /* MasterFlagPosition */ ? index : (index + 0 /* FlagsOffset */);
return context[adjustedIndex];
}
function getValue(context, index) {
return context[index + 2 /* ValueOffset */];
}
function getProp(context, index) {
return context[index + 1 /* PropertyOffset */];
}
function isContextDirty(context) {
return isDirty(context, 0 /* MasterFlagPosition */);
}
function limitToSingleClasses(context) {
return context[0 /* MasterFlagPosition */] & 16 /* OnlyProcessSingleClasses */;
}
function setContextDirty(context, isDirtyYes) {
setDirty(context, 0 /* MasterFlagPosition */, isDirtyYes);
}
function setContextPlayersDirty(context, isDirtyYes) {
if (isDirtyYes) {
context[0 /* MasterFlagPosition */] |= 8 /* PlayerBuildersDirty */;
}
else {
context[0 /* MasterFlagPosition */] &= ~8 /* PlayerBuildersDirty */;
}
}
function findEntryPositionByProp(context, prop, startIndex) {
for (var i = (startIndex || 0) + 1 /* PropertyOffset */; i < context.length; i += 4 /* Size */) {
var thisProp = context[i];
if (thisProp == prop) {
return i - 1 /* PropertyOffset */;
}
}
return -1;
}
function swapMultiContextEntries(context, indexA, indexB) {
var tmpValue = getValue(context, indexA);
var tmpProp = getProp(context, indexA);
var tmpFlag = getPointers(context, indexA);
var tmpPlayerBuilderIndex = getPlayerBuilderIndex(context, indexA);
var flagA = tmpFlag;
var flagB = getPointers(context, indexB);
var singleIndexA = getMultiOrSingleIndex(flagA);
if (singleIndexA >= 0) {
var _flag = getPointers(context, singleIndexA);
var _initial = getInitialIndex(_flag);
setFlag(context, singleIndexA, pointers(_flag, _initial, indexB));
}
var singleIndexB = getMultiOrSingleIndex(flagB);
if (singleIndexB >= 0) {
var _flag = getPointers(context, singleIndexB);
var _initial = getInitialIndex(_flag);
setFlag(context, singleIndexB, pointers(_flag, _initial, indexA));
}
setValue(context, indexA, getValue(context, indexB));
setProp(context, indexA, getProp(context, indexB));
setFlag(context, indexA, getPointers(context, indexB));
var playerIndexA = getPlayerBuilderIndex(context, indexB);
var directiveIndexA = 0;
setPlayerBuilderIndex(context, indexA, playerIndexA, directiveIndexA);
setValue(context, indexB, tmpValue);
setProp(context, indexB, tmpProp);
setFlag(context, indexB, tmpFlag);
setPlayerBuilderIndex(context, indexB, tmpPlayerBuilderIndex, directiveIndexA);
}
function updateSinglePointerValues(context, indexStartPosition) {
for (var i = indexStartPosition; i < context.length; i += 4 /* Size */) {
var multiFlag = getPointers(context, i);
var singleIndex = getMultiOrSingleIndex(multiFlag);
if (singleIndex > 0) {
var singleFlag = getPointers(context, singleIndex);
var initialIndexForSingle = getInitialIndex(singleFlag);
var flagValue = (isDirty(context, singleIndex) ? 1 /* Dirty */ : 0 /* None */) |
(isClassBasedValue(context, singleIndex) ? 2 /* Class */ : 0 /* None */) |
(isSanitizable(context, singleIndex) ? 4 /* Sanitize */ : 0 /* None */);
var updatedFlag = pointers(flagValue, initialIndexForSingle, i);
setFlag(context, singleIndex, updatedFlag);
}
}
}
function insertNewMultiProperty(context, index, classBased, name, flag, value, directiveIndex, playerIndex) {
var doShift = index < context.length;
// prop does not exist in the list, add it in
context.splice(index, 0, flag | 1 /* Dirty */ | (classBased ? 2 /* Class */ : 0 /* None */), name, value, 0);
setPlayerBuilderIndex(context, index, playerIndex, directiveIndex);
if (doShift) {
// because the value was inserted midway into the array then we
// need to update all the shifted multi values' single value
// pointers to point to the newly shifted location
updateSinglePointerValues(context, index + 4 /* Size */);
}
}
function valueExists(value, isClassBased) {
if (isClassBased) {
return value ? true : false;
}
return value !== null;
}
function prepareInitialFlag(context, prop, entryIsClassBased, sanitizer) {
var flag = (sanitizer && sanitizer(prop)) ? 4 /* Sanitize */ : 0 /* None */;
var initialIndex;
if (entryIsClassBased) {
flag |= 2 /* Class */;
initialIndex =
getInitialStylingValuesIndexOf(context[3 /* InitialClassValuesPosition */], prop);
}
else {
initialIndex =
getInitialStylingValuesIndexOf(context[2 /* InitialStyleValuesPosition */], prop);
}
initialIndex = initialIndex > 0 ? (initialIndex + 1 /* ValueOffset */) : 0;
return pointers(flag, initialIndex, 0);
}
function hasValueChanged(flag, a, b) {
var isClassBased = flag & 2 /* Class */;
var hasValues = a && b;
var usesSanitizer = flag & 4 /* Sanitize */;
// the toString() comparison ensures that a value is checked
// ... otherwise (during sanitization bypassing) the === comparsion
// would fail since a new String() instance is created
if (!isClassBased && hasValues && usesSanitizer) {
// we know for sure we're dealing with strings at this point
return a.toString() !== b.toString();
}
// everything else is safe to check with a normal equality check
return a !== b;
}
var ClassAndStylePlayerBuilder = /** @class */ (function () {
function ClassAndStylePlayerBuilder(factory, _element, _type) {
this._element = _element;
this._type = _type;
this._values = {};
this._dirty = false;
this._factory = factory;
}
ClassAndStylePlayerBuilder.prototype.setValue = function (prop, value) {
if (this._values[prop] !== value) {
this._values[prop] = value;
this._dirty = true;
}
};
ClassAndStylePlayerBuilder.prototype.buildPlayer = function (currentPlayer, isFirstRender) {
// if no values have been set here then this means the binding didn't
// change and therefore the binding values were not updated through
// `setValue` which means no new player will be provided.
if (this._dirty) {
var player = this._factory.fn(this._element, this._type, this._values, isFirstRender, currentPlayer || null);
this._values = {};
this._dirty = false;
return player;
}
return undefined;
};
return ClassAndStylePlayerBuilder;
}());
function getDirectiveIndexFromEntry(context, index) {
var value = context[index + 3 /* PlayerBuilderIndexOffset */];
return value & 65535 /* BitMask */;
}
function getDirectiveIndexFromRegistry(context, directive) {
var index = getDirectiveRegistryValuesIndexOf(context[1 /* DirectiveRegistryPosition */], directive);
ngDevMode &&
assertNotEqual(index, -1, "The provided directive " + directive + " has not been allocated to the element's style/class bindings");
return index > 0 ? index / 4 /* Size */ : 0;
// return index / DirectiveRegistryValuesIndex.Size;
}
function getDirectiveRegistryValuesIndexOf(directives, directive) {
for (var i = 0; i < directives.length; i += 4 /* Size */) {
if (directives[i] === directive) {
return i;
}
}
return -1;
}
function getInitialStylingValuesIndexOf(keyValues, key) {
for (var i = 1 /* KeyValueStartPosition */; i < keyValues.length; i += 2 /* Size */) {
if (keyValues[i] === key)
return i;
}
return -1;
}
function getSinglePropIndexValue(context, directiveIndex, offset, isClassBased) {
var singlePropOffsetRegistryIndex = context[1 /* DirectiveRegistryPosition */][(directiveIndex * 4 /* Size */) +
1 /* SinglePropValuesIndexOffset */];
var offsets = context[4 /* SinglePropOffsetPositions */];
var indexForOffset = singlePropOffsetRegistryIndex +
2 /* ValueStartPosition */ +
(isClassBased ?
offsets[singlePropOffsetRegistryIndex + 0 /* StylesCountPosition */] :
0) +
offset;
return offsets[indexForOffset];
}
function getStyleSanitizer(context, directiveIndex) {
var dirs = context[1 /* DirectiveRegistryPosition */];
var value = dirs[directiveIndex * 4 /* Size */ +
3 /* StyleSanitizerOffset */] ||
dirs[3 /* StyleSanitizerOffset */] || null;
return value;
}
function isDirectiveDirty(context, directiveIndex) {
var dirs = context[1 /* DirectiveRegistryPosition */];
return dirs[directiveIndex * 4 /* Size */ +
2 /* DirtyFlagOffset */];
}
function setDirectiveDirty(context, directiveIndex, dirtyYes) {
var dirs = context[1 /* DirectiveRegistryPosition */];
dirs[directiveIndex * 4 /* Size */ +
2 /* DirtyFlagOffset */] = dirtyYes;
}
function allowValueChange(currentValue, newValue, currentDirectiveOwner, newDirectiveOwner) {
// the code below relies the importance of directive's being tied to their
// index value. The index values for each directive are derived from being
// registered into the styling context directive registry. The most important
// directive is the parent component directive (the template) and each directive
// that is added after is considered less important than the previous entry. This
// prioritization of directives enables the styling algorithm to decide if a style
// or class should be allowed to be updated/replaced incase an earlier directive
// already wrote to the exact same style-property or className value. In other words
// ... this decides what to do if and when there is a collision.
if (currentValue) {
if (newValue) {
// if a directive index is lower than it always has priority over the
// previous directive's value...
return newDirectiveOwner <= currentDirectiveOwner;
}
else {
// only write a null value incase it's the same owner writing it.
// this avoids having a higher-priority directive write to null
// only to have a lesser-priority directive change right to a
// non-null value immediately afterwards.
return currentDirectiveOwner === newDirectiveOwner;
}
}
return true;
}
/**
* This function is only designed to be called for `[class]` bindings when
* `[ngClass]` (or something that uses `class` as an input) is present. Once
* directive host bindings fully work for `[class]` and `[style]` inputs
* then this can be deleted.
*/
function getInitialClassNameValue(context) {
var className = context[6 /* CachedClassValueOrInitialClassString */];
if (className == null) {
className = '';
var initialClassValues = context[3 /* InitialClassValuesPosition */];
for (var i = 1 /* KeyValueStartPosition */; i < initialClassValues.length; i += 2 /* Size */) {
var isPresent = initialClassValues[i + 1];
if (isPresent) {
className += (className.length ? ' ' : '') + initialClassValues[i];
}
}
context[6 /* CachedClassValueOrInitialClassString */] = className;
}
return className;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A permanent marker promise which signifies that the current CD tree is
* clean.
*/
var _CLEAN_PROMISE = Promise.resolve(null);
/**
* Refreshes the view, executing the following steps in that order:
* triggers init hooks, refreshes dynamic embedded views, triggers content hooks, sets host
* bindings, refreshes child components.
* Note: view hooks are triggered later when leaving the view.
*/
function refreshDescendantViews(lView) {
var tView = lView[TVIEW];
// This needs to be set before children are processed to support recursive components
tView.firstTemplatePass = false;
setFirstTemplatePass(false);
// If this is a creation pass, we should not call lifecycle hooks or evaluate bindings.
// This will be done in the update pass.
if (!isCreationMode(lView)) {
var checkNoChangesMode = getCheckNoChangesMode();
executeInitHooks(lView, tView, checkNoChangesMode);
refreshDynamicEmbeddedViews(lView);
// Content query results must be refreshed before content hooks are called.
refreshContentQueries(tView);
executeHooks(lView, tView.contentHooks, tView.contentCheckHooks, checkNoChangesMode);
setHostBindings(tView, lView);
}
refreshChildComponents(tView.components);
}
/** Sets the host bindings for the current view. */
function setHostBindings(tView, viewData) {
if (tView.expandoInstructions) {
var bindingRootIndex = viewData[BINDING_INDEX] = tView.expandoStartIndex;
setBindingRoot(bindingRootIndex);
var currentDirectiveIndex = -1;
var currentElementIndex = -1;
for (var i = 0; i < tView.expandoInstructions.length; i++) {
var instruction = tView.expandoInstructions[i];
if (typeof instruction === 'number') {
if (instruction <= 0) {
// Negative numbers mean that we are starting new EXPANDO block and need to update
// the current element and directive index.
currentElementIndex = -instruction;
// Injector block and providers are taken into account.
var providerCount = tView.expandoInstructions[++i];
bindingRootIndex += INJECTOR_BLOOM_PARENT_SIZE + providerCount;
currentDirectiveIndex = bindingRootIndex;
}
else {
// This is either the injector size (so the binding root can skip over directives
// and get to the first set of host bindings on this node) or the host var count
// (to get to the next set of host bindings on this node).
bindingRootIndex += instruction;
}
setBindingRoot(bindingRootIndex);
}
else {
// If it's not a number, it's a host binding function that needs to be executed.
if (instruction !== null) {
viewData[BINDING_INDEX] = bindingRootIndex;
instruction(2 /* Update */, readElementValue(viewData[currentDirectiveIndex]), currentElementIndex);
}
currentDirectiveIndex++;
}
}
}
}
/** Refreshes content queries for all directives in the given view. */
function refreshContentQueries(tView) {
if (tView.contentQueries != null) {
for (var i = 0; i < tView.contentQueries.length; i += 2) {
var directiveDefIdx = tView.contentQueries[i];
var directiveDef = tView.data[directiveDefIdx];
directiveDef.contentQueriesRefresh(directiveDefIdx - HEADER_OFFSET, tView.contentQueries[i + 1]);
}
}
}
/** Refreshes child components in the current view. */
function refreshChildComponents(components) {
if (components != null) {
for (var i = 0; i < components.length; i++) {
componentRefresh(components[i]);
}
}
}
function createLView(parentLView, tView, context, flags, rendererFactory, renderer, sanitizer, injector) {
var lView = tView.blueprint.slice();
lView[FLAGS] = flags | 1 /* CreationMode */ | 16 /* Attached */ | 32 /* RunInit */ |
2 /* FirstLViewPass */;
lView[PARENT] = lView[DECLARATION_VIEW] = parentLView;
lView[CONTEXT] = context;
lView[RENDERER_FACTORY] = (rendererFactory || parentLView && parentLView[RENDERER_FACTORY]);
ngDevMode && assertDefined(lView[RENDERER_FACTORY], 'RendererFactory is required');
lView[RENDERER] = (renderer || parentLView && parentLView[RENDERER]);
ngDevMode && assertDefined(lView[RENDERER], 'Renderer is required');
lView[SANITIZER] = sanitizer || parentLView && parentLView[SANITIZER] || null;
lView[INJECTOR] = injector || parentLView && parentLView[INJECTOR] || null;
return lView;
}
function createNodeAtIndex(index, type, native, name, attrs) {
var lView = getLView();
var tView = lView[TVIEW];
var adjustedIndex = index + HEADER_OFFSET;
ngDevMode &&
assertLessThan(adjustedIndex, lView.length, "Slot should have been initialized with null");
lView[adjustedIndex] = native;
var tNode = tView.data[adjustedIndex];
if (tNode == null) {
// TODO(misko): Refactor createTNode so that it does not depend on LView.
tNode = tView.data[adjustedIndex] = createTNode(lView, type, adjustedIndex, name, attrs, null);
}
// Now link ourselves into the tree.
// We need this even if tNode exists, otherwise we might end up pointing to unexisting tNodes when
// we use i18n (especially with ICU expressions that update the DOM during the update phase).
var previousOrParentTNode = getPreviousOrParentTNode();
var isParent = getIsParent();
if (previousOrParentTNode) {
if (isParent && previousOrParentTNode.child == null &&
(tNode.parent !== null || previousOrParentTNode.type === 2 /* View */)) {
// We are in the same view, which means we are adding content node to the parent view.
previousOrParentTNode.child = tNode;
}
else if (!isParent) {
previousOrParentTNode.next = tNode;
}
}
if (tView.firstChild == null) {
tView.firstChild = tNode;
}
setPreviousOrParentTNode(tNode);
setIsParent(true);
return tNode;
}
function createViewNode(index, view) {
// View nodes are not stored in data because they can be added / removed at runtime (which
// would cause indices to change). Their TNodes are instead stored in tView.node.
if (view[TVIEW].node == null) {
view[TVIEW].node = createTNode(view, 2 /* View */, index, null, null, null);
}
return view[HOST_NODE] = view[TVIEW].node;
}
/**
* When elements are created dynamically after a view blueprint is created (e.g. through
* i18nApply() or ComponentFactory.create), we need to adjust the blueprint for future
* template passes.
*/
function allocExpando(view) {
var tView = view[TVIEW];
if (tView.firstTemplatePass) {
tView.expandoStartIndex++;
tView.blueprint.push(null);
tView.data.push(null);
view.push(null);
}
}
/**
* Used for creating the LViewNode of a dynamic embedded view,
* either through ViewContainerRef.createEmbeddedView() or TemplateRef.createEmbeddedView().
* Such lViewNode will then be renderer with renderEmbeddedTemplate() (see below).
*/
function createEmbeddedViewAndNode(tView, context, declarationView, renderer, queries, injectorIndex) {
var _isParent = getIsParent();
var _previousOrParentTNode = getPreviousOrParentTNode();
setIsParent(true);
setPreviousOrParentTNode(null);
var lView = createLView(declarationView, tView, context, 4 /* CheckAlways */);
lView[DECLARATION_VIEW] = declarationView;
if (queries) {
lView[QUERIES] = queries.createView();
}
createViewNode(-1, lView);
if (tView.firstTemplatePass) {
tView.node.injectorIndex = injectorIndex;
}
setIsParent(_isParent);
setPreviousOrParentTNode(_previousOrParentTNode);
return lView;
}
/**
* Used for rendering embedded views (e.g. dynamically created views)
*
* Dynamically created views must store/retrieve their TViews differently from component views
* because their template functions are nested in the template functions of their hosts, creating
* closures. If their host template happens to be an embedded template in a loop (e.g. ngFor inside
* an ngFor), the nesting would mean we'd have multiple instances of the template function, so we
* can't store TViews in the template function itself (as we do for comps). Instead, we store the
* TView for dynamically created views on their host TNode, which only has one instance.
*/
function renderEmbeddedTemplate(viewToRender, tView, context) {
var _isParent = getIsParent();
var _previousOrParentTNode = getPreviousOrParentTNode();
setIsParent(true);
setPreviousOrParentTNode(null);
var oldView;
if (viewToRender[FLAGS] & 128 /* IsRoot */) {
// This is a root view inside the view tree
tickRootContext(getRootContext(viewToRender));
}
else {
try {
setIsParent(true);
setPreviousOrParentTNode(null);
oldView = enterView(viewToRender, viewToRender[HOST_NODE]);
namespaceHTML();
tView.template(getRenderFlags(viewToRender), context);
// This must be set to false immediately after the first creation run because in an
// ngFor loop, all the views will be created together before update mode runs and turns
// off firstTemplatePass. If we don't set it here, instances will perform directive
// matching, etc again and again.
viewToRender[TVIEW].firstTemplatePass = false;
setFirstTemplatePass(false);
refreshDescendantViews(viewToRender);
}
finally {
leaveView(oldView);
setIsParent(_isParent);
setPreviousOrParentTNode(_previousOrParentTNode);
}
}
}
/**
* Retrieves a context at the level specified and saves it as the global, contextViewData.
* Will get the next level up if level is not specified.
*
* This is used to save contexts of parent views so they can be bound in embedded views, or
* in conjunction with reference() to bind a ref from a parent view.
*
* @param level The relative level of the view from which to grab context compared to contextVewData
* @returns context
*/
function nextContext(level) {
if (level === void 0) { level = 1; }
return nextContextImpl(level);
}
function renderComponentOrTemplate(hostView, context, templateFn) {
var rendererFactory = hostView[RENDERER_FACTORY];
var oldView = enterView(hostView, hostView[HOST_NODE]);
var normalExecutionPath = !getCheckNoChangesMode();
try {
if (normalExecutionPath && rendererFactory.begin) {
rendererFactory.begin();
}
if (isCreationMode(hostView)) {
// creation mode pass
if (templateFn) {
namespaceHTML();
templateFn(1 /* Create */, context);
}
refreshDescendantViews(hostView);
hostView[FLAGS] &= ~1 /* CreationMode */;
}
// update mode pass
templateFn && templateFn(2 /* Update */, context);
refreshDescendantViews(hostView);
}
finally {
if (normalExecutionPath && rendererFactory.end) {
rendererFactory.end();
}
leaveView(oldView);
}
}
/**
* This function returns the default configuration of rendering flags depending on when the
* template is in creation mode or update mode. Update block and create block are
* always run separately.
*/
function getRenderFlags(view) {
return isCreationMode(view) ? 1 /* Create */ : 2 /* Update */;
}
//////////////////////////
//// Namespace
//////////////////////////
var _currentNamespace = null;
function namespaceSVG() {
_currentNamespace = 'http://www.w3.org/2000/svg';
}
function namespaceMathML() {
_currentNamespace = 'http://www.w3.org/1998/MathML/';
}
function namespaceHTML() {
_currentNamespace = null;
}
//////////////////////////
//// Element
//////////////////////////
/**
* Creates an empty element using {@link elementStart} and {@link elementEnd}
*
* @param index Index of the element in the data array
* @param name Name of the DOM Node
* @param attrs Statically bound set of attributes, classes, and styles to be written into the DOM
* element on creation. Use [AttributeMarker] to denote the meaning of this array.
* @param localRefs A set of local reference bindings on the element.
*/
function element(index, name, attrs, localRefs) {
elementStart(index, name, attrs, localRefs);
elementEnd();
}
/**
* Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
* The instruction must later be followed by `elementContainerEnd()` call.
*
* @param index Index of the element in the LView array
* @param attrs Set of attributes to be used when matching directives.
* @param localRefs A set of local reference bindings on the element.
*
* Even if this instruction accepts a set of attributes no actual attribute values are propagated to
* the DOM (as a comment node can't have attributes). Attributes are here only for directive
* matching purposes and setting initial inputs of directives.
*/
function elementContainerStart(index, attrs, localRefs) {
var lView = getLView();
var tView = lView[TVIEW];
var renderer = lView[RENDERER];
var tagName = 'ng-container';
ngDevMode && assertEqual(lView[BINDING_INDEX], tView.bindingStartIndex, 'element containers should be created before any bindings');
ngDevMode && ngDevMode.rendererCreateComment++;
var native = renderer.createComment(ngDevMode ? tagName : '');
ngDevMode && assertDataInRange(lView, index - 1);
var tNode = createNodeAtIndex(index, 4 /* ElementContainer */, native, tagName, attrs || null);
appendChild(native, tNode, lView);
createDirectivesAndLocals(tView, lView, localRefs);
attachPatchData(native, lView);
}
/** Mark the end of the <ng-container>. */
function elementContainerEnd() {
var previousOrParentTNode = getPreviousOrParentTNode();
var lView = getLView();
var tView = lView[TVIEW];
if (getIsParent()) {
setIsParent(false);
}
else {
ngDevMode && assertHasParent(getPreviousOrParentTNode());
previousOrParentTNode = previousOrParentTNode.parent;
setPreviousOrParentTNode(previousOrParentTNode);
}
ngDevMode && assertNodeType(previousOrParentTNode, 4 /* ElementContainer */);
var currentQueries = lView[QUERIES];
if (currentQueries) {
lView[QUERIES] = currentQueries.addNode(previousOrParentTNode);
}
queueLifecycleHooks(tView, previousOrParentTNode);
}
/**
* Create DOM element. The instruction must later be followed by `elementEnd()` call.
*
* @param index Index of the element in the LView array
* @param name Name of the DOM Node
* @param attrs Statically bound set of attributes, classes, and styles to be written into the DOM
* element on creation. Use [AttributeMarker] to denote the meaning of this array.
* @param localRefs A set of local reference bindings on the element.
*
* Attributes and localRefs are passed as an array of strings where elements with an even index
* hold an attribute name and elements with an odd index hold an attribute value, ex.:
* ['id', 'warning5', 'class', 'alert']
*/
function elementStart(index, name, attrs, localRefs) {
var lView = getLView();
var tView = lView[TVIEW];
ngDevMode && assertEqual(lView[BINDING_INDEX], tView.bindingStartIndex, 'elements should be created before any bindings ');
ngDevMode && ngDevMode.rendererCreateElement++;
var native = elementCreate(name);
ngDevMode && assertDataInRange(lView, index - 1);
var tNode = createNodeAtIndex(index, 3 /* Element */, native, name, attrs || null);
if (attrs) {
// it's important to only prepare styling-related datastructures once for a given
// tNode and not each time an element is created. Also, the styling code is designed
// to be patched and constructed at various points, but only up until the first element
// is created. Then the styling context is locked and can only be instantiated for each
// successive element that is created.
if (tView.firstTemplatePass && !tNode.stylingTemplate && hasStyling(attrs)) {
tNode.stylingTemplate = initializeStaticContext(attrs);
}
setUpAttributes(native, attrs);
}
appendChild(native, tNode, lView);
createDirectivesAndLocals(tView, lView, localRefs);
// any immediate children of a component or template container must be pre-emptively
// monkey-patched with the component view data so that the element can be inspected
// later on using any element discovery utility methods (see `element_discovery.ts`)
if (getElementDepthCount() === 0) {
attachPatchData(native, lView);
}
increaseElementDepthCount();
// if a directive contains a host binding for "class" then all class-based data will
// flow through that (except for `[class.prop]` bindings). This also includes initial
// static class values as well. (Note that this will be fixed once map-based `[style]`
// and `[class]` bindings work for multiple directives.)
if (tView.firstTemplatePass) {
var inputData = initializeTNodeInputs(tNode);
if (inputData && inputData.hasOwnProperty('class')) {
tNode.flags |= 8 /* hasClassInput */;
}
}
// There is no point in rendering styles when a class directive is present since
// it will take that over for us (this will be removed once #FW-882 is in).
if (tNode.stylingTemplate && (tNode.flags & 8 /* hasClassInput */) === 0) {
renderInitialStylesAndClasses(native, tNode.stylingTemplate, lView[RENDERER]);
}
}
/**
* Creates a native element from a tag name, using a renderer.
* @param name the tag name
* @param overriddenRenderer Optional A renderer to override the default one
* @returns the element created
*/
function elementCreate(name, overriddenRenderer) {
var native;
var rendererToUse = overriddenRenderer || getLView()[RENDERER];
if (isProceduralRenderer(rendererToUse)) {
native = rendererToUse.createElement(name, _currentNamespace);
}
else {
if (_currentNamespace === null) {
native = rendererToUse.createElement(name);
}
else {
native = rendererToUse.createElementNS(_currentNamespace, name);
}
}
return native;
}
/**
* Creates directive instances and populates local refs.
*
* @param localRefs Local refs of the node in question
* @param localRefExtractor mapping function that extracts local ref value from TNode
*/
function createDirectivesAndLocals(tView, viewData, localRefs, localRefExtractor) {
if (localRefExtractor === void 0) { localRefExtractor = getNativeByTNode; }
if (!getBindingsEnabled())
return;
var previousOrParentTNode = getPreviousOrParentTNode();
if (getFirstTemplatePass()) {
ngDevMode && ngDevMode.firstTemplatePass++;
resolveDirectives(tView, viewData, findDirectiveMatches(tView, viewData, previousOrParentTNode), previousOrParentTNode, localRefs || null);
}
instantiateAllDirectives(tView, viewData, previousOrParentTNode);
invokeDirectivesHostBindings(tView, viewData, previousOrParentTNode);
saveResolvedLocalsInData(viewData, previousOrParentTNode, localRefExtractor);
}
/**
* Takes a list of local names and indices and pushes the resolved local variable values
* to LView in the same order as they are loaded in the template with load().
*/
function saveResolvedLocalsInData(viewData, tNode, localRefExtractor) {
var localNames = tNode.localNames;
if (localNames) {
var localIndex = tNode.index + 1;
for (var i = 0; i < localNames.length; i += 2) {
var index = localNames[i + 1];
var value = index === -1 ?
localRefExtractor(tNode, viewData) :
viewData[index];
viewData[localIndex++] = value;
}
}
}
/**
* Gets TView from a template function or creates a new TView
* if it doesn't already exist.
*
* @param templateFn The template from which to get static data
* @param consts The number of nodes, local refs, and pipes in this view
* @param vars The number of bindings and pure function bindings in this view
* @param directives Directive defs that should be saved on TView
* @param pipes Pipe defs that should be saved on TView
* @returns TView
*/
function getOrCreateTView(templateFn, consts, vars, directives, pipes, viewQuery) {
// TODO(misko): reading `ngPrivateData` here is problematic for two reasons
// 1. It is a megamorphic call on each invocation.
// 2. For nested embedded views (ngFor inside ngFor) the template instance is per
// outer template invocation, which means that no such property will exist
// Correct solution is to only put `ngPrivateData` on the Component template
// and not on embedded templates.
return templateFn.ngPrivateData ||
(templateFn.ngPrivateData =
createTView(-1, templateFn, consts, vars, directives, pipes, viewQuery));
}
/**
* Creates a TView instance
*
* @param viewIndex The viewBlockId for inline views, or -1 if it's a component/dynamic
* @param templateFn Template function
* @param consts The number of nodes, local refs, and pipes in this template
* @param directives Registry of directives for this view
* @param pipes Registry of pipes for this view
*/
function createTView(viewIndex, templateFn, consts, vars, directives, pipes, viewQuery) {
ngDevMode && ngDevMode.tView++;
var bindingStartIndex = HEADER_OFFSET + consts;
// This length does not yet contain host bindings from child directives because at this point,
// we don't know which directives are active on this template. As soon as a directive is matched
// that has a host binding, we will update the blueprint with that def's hostVars count.
var initialViewLength = bindingStartIndex + vars;
var blueprint = createViewBlueprint(bindingStartIndex, initialViewLength);
return blueprint[TVIEW] = {
id: viewIndex,
blueprint: blueprint,
template: templateFn,
viewQuery: viewQuery,
node: null,
data: blueprint.slice(),
childIndex: -1,
bindingStartIndex: bindingStartIndex,
expandoStartIndex: initialViewLength,
expandoInstructions: null,
firstTemplatePass: true,
initHooks: null,
checkHooks: null,
contentHooks: null,
contentCheckHooks: null,
viewHooks: null,
viewCheckHooks: null,
destroyHooks: null,
pipeDestroyHooks: null,
cleanup: null,
contentQueries: null,
components: null,
directiveRegistry: typeof directives === 'function' ? directives() : directives,
pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
firstChild: null,
};
}
function createViewBlueprint(bindingStartIndex, initialViewLength) {
var blueprint = new Array(initialViewLength)
.fill(null, 0, bindingStartIndex)
.fill(NO_CHANGE, bindingStartIndex);
blueprint[CONTAINER_INDEX] = -1;
blueprint[BINDING_INDEX] = bindingStartIndex;
return blueprint;
}
function setUpAttributes(native, attrs) {
var renderer = getLView()[RENDERER];
var isProc = isProceduralRenderer(renderer);
var i = 0;
while (i < attrs.length) {
var attrName = attrs[i++];
if (typeof attrName == 'number') {
if (attrName === 0 /* NamespaceURI */) {
// Namespaced attributes
var namespaceURI = attrs[i++];
var attrName_1 = attrs[i++];
var attrVal = attrs[i++];
ngDevMode && ngDevMode.rendererSetAttribute++;
isProc ?
renderer
.setAttribute(native, attrName_1, attrVal, namespaceURI) :
native.setAttributeNS(namespaceURI, attrName_1, attrVal);
}
else {
// All other `AttributeMarker`s are ignored here.
break;
}
}
else {
/// attrName is string;
var attrVal = attrs[i++];
if (attrName !== NG_PROJECT_AS_ATTR_NAME) {
// Standard attributes
ngDevMode && ngDevMode.rendererSetAttribute++;
if (isAnimationProp(attrName)) {
if (isProc) {
renderer.setProperty(native, attrName, attrVal);
}
}
else {
isProc ?
renderer
.setAttribute(native, attrName, attrVal) :
native.setAttribute(attrName, attrVal);
}
}
}
}
}
function createError(text, token) {
return new Error("Renderer: " + text + " [" + stringify$1(token) + "]");
}
/**
* Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
*
* @param elementOrSelector Render element or CSS selector to locate the element.
*/
function locateHostElement(factory, elementOrSelector) {
var defaultRenderer = factory.createRenderer(null, null);
var rNode = typeof elementOrSelector === 'string' ?
(isProceduralRenderer(defaultRenderer) ?
defaultRenderer.selectRootElement(elementOrSelector) :
defaultRenderer.querySelector(elementOrSelector)) :
elementOrSelector;
if (ngDevMode && !rNode) {
if (typeof elementOrSelector === 'string') {
throw createError('Host node with selector not found:', elementOrSelector);
}
else {
throw createError('Host node is required:', elementOrSelector);
}
}
return rNode;
}
/**
* Adds an event listener to the current node.
*
* If an output exists on one of the node's directives, it also subscribes to the output
* and saves the subscription for later cleanup.
*
* @param eventName Name of the event
* @param listenerFn The function to be called when event emits
* @param useCapture Whether or not to use capture in event listener.
*/
function listener(eventName, listenerFn, useCapture) {
if (useCapture === void 0) { useCapture = false; }
var lView = getLView();
var tNode = getPreviousOrParentTNode();
var tView = lView[TVIEW];
var firstTemplatePass = tView.firstTemplatePass;
var tCleanup = firstTemplatePass && (tView.cleanup || (tView.cleanup = []));
ngDevMode && assertNodeOfPossibleTypes(tNode, 3 /* Element */, 0 /* Container */, 4 /* ElementContainer */);
// add native event listener - applicable to elements only
if (tNode.type === 3 /* Element */) {
var native = getNativeByTNode(tNode, lView);
ngDevMode && ngDevMode.rendererAddEventListener++;
var renderer = lView[RENDERER];
var lCleanup = getCleanup(lView);
var lCleanupIndex = lCleanup.length;
var useCaptureOrSubIdx = useCapture;
// In order to match current behavior, native DOM event listeners must be added for all
// events (including outputs).
if (isProceduralRenderer(renderer)) {
var cleanupFn = renderer.listen(native, eventName, listenerFn);
lCleanup.push(listenerFn, cleanupFn);
useCaptureOrSubIdx = lCleanupIndex + 1;
}
else {
var wrappedListener = wrapListenerWithPreventDefault(listenerFn);
native.addEventListener(eventName, wrappedListener, useCapture);
lCleanup.push(wrappedListener);
}
tCleanup && tCleanup.push(eventName, tNode.index, lCleanupIndex, useCaptureOrSubIdx);
}
// subscribe to directive outputs
if (tNode.outputs === undefined) {
// if we create TNode here, inputs must be undefined so we know they still need to be
// checked
tNode.outputs = generatePropertyAliases(tNode, 1 /* Output */);
}
var outputs = tNode.outputs;
var props;
if (outputs && (props = outputs[eventName])) {
var propsLength = props.length;
if (propsLength) {
var lCleanup = getCleanup(lView);
for (var i = 0; i < propsLength; i += 2) {
ngDevMode && assertDataInRange(lView, props[i]);
var subscription = lView[props[i]][props[i + 1]].subscribe(listenerFn);
var idx = lCleanup.length;
lCleanup.push(listenerFn, subscription);
tCleanup && tCleanup.push(eventName, tNode.index, idx, -(idx + 1));
}
}
}
}
/**
* Saves context for this cleanup function in LView.cleanupInstances.
*
* On the first template pass, saves in TView:
* - Cleanup function
* - Index of context we just saved in LView.cleanupInstances
*/
function storeCleanupWithContext(lView, context, cleanupFn) {
var lCleanup = getCleanup(lView);
lCleanup.push(context);
if (lView[TVIEW].firstTemplatePass) {
getTViewCleanup(lView).push(cleanupFn, lCleanup.length - 1);
}
}
/**
* Saves the cleanup function itself in LView.cleanupInstances.
*
* This is necessary for functions that are wrapped with their contexts, like in renderer2
* listeners.
*
* On the first template pass, the index of the cleanup function is saved in TView.
*/
function storeCleanupFn(view, cleanupFn) {
getCleanup(view).push(cleanupFn);
if (view[TVIEW].firstTemplatePass) {
getTViewCleanup(view).push(view[CLEANUP].length - 1, null);
}
}
/** Mark the end of the element. */
function elementEnd() {
var previousOrParentTNode = getPreviousOrParentTNode();
if (getIsParent()) {
setIsParent(false);
}
else {
ngDevMode && assertHasParent(getPreviousOrParentTNode());
previousOrParentTNode = previousOrParentTNode.parent;
setPreviousOrParentTNode(previousOrParentTNode);
}
ngDevMode && assertNodeType(previousOrParentTNode, 3 /* Element */);
var lView = getLView();
var currentQueries = lView[QUERIES];
if (currentQueries) {
lView[QUERIES] = currentQueries.addNode(previousOrParentTNode);
}
queueLifecycleHooks(getLView()[TVIEW], previousOrParentTNode);
decreaseElementDepthCount();
// this is fired at the end of elementEnd because ALL of the stylingBindings code
// (for directives and the template) have now executed which means the styling
// context can be instantiated properly.
if (hasClassInput(previousOrParentTNode)) {
var stylingContext = getStylingContext(previousOrParentTNode.index, lView);
setInputsForProperty(lView, previousOrParentTNode.inputs['class'], getInitialClassNameValue(stylingContext));
}
}
/**
* Updates the value of removes an attribute on an Element.
*
* @param number index The index of the element in the data array
* @param name name The name of the attribute.
* @param value value The attribute is removed when value is `null` or `undefined`.
* Otherwise the attribute value is set to the stringified value.
* @param sanitizer An optional function used to sanitize the value.
*/
function elementAttribute(index, name, value, sanitizer) {
if (value !== NO_CHANGE) {
var lView = getLView();
var renderer = lView[RENDERER];
var element_1 = getNativeByIndex(index, lView);
if (value == null) {
ngDevMode && ngDevMode.rendererRemoveAttribute++;
isProceduralRenderer(renderer) ? renderer.removeAttribute(element_1, name) :
element_1.removeAttribute(name);
}
else {
ngDevMode && ngDevMode.rendererSetAttribute++;
var strValue = sanitizer == null ? stringify$1(value) : sanitizer(value);
isProceduralRenderer(renderer) ? renderer.setAttribute(element_1, name, strValue) :
element_1.setAttribute(name, strValue);
}
}
}
/**
* Update a property on an element.
*
* If the property name also exists as an input property on one of the element's directives,
* the component property will be set instead of the element property. This check must
* be conducted at runtime so child components that add new @Inputs don't have to be re-compiled.
*
* @param index The index of the element to update in the data array
* @param propName Name of property. Because it is going to DOM, this is not subject to
* renaming as part of minification.
* @param value New value to write.
* @param sanitizer An optional function used to sanitize the value.
* @param nativeOnly Whether or not we should only set native properties and skip input check
* (this is necessary for host property bindings)
*/
function elementProperty(index, propName, value, sanitizer, nativeOnly) {
elementPropertyInternal(index, propName, value, sanitizer, nativeOnly);
}
/**
* Updates a synthetic host binding (e.g. `[@foo]`) on a component.
*
* This instruction is for compatibility purposes and is designed to ensure that a
* synthetic host binding (e.g. `@HostBinding('@foo')`) properly gets rendered in
* the component's renderer. Normally all host bindings are evaluated with the parent
* component's renderer, but, in the case of animation @triggers, they need to be
* evaluated with the sub components renderer (because that's where the animation
* triggers are defined).
*
* Do not use this instruction as a replacement for `elementProperty`. This instruction
* only exists to ensure compatibility with the ViewEngine's host binding behavior.
*
* @param index The index of the element to update in the data array
* @param propName Name of property. Because it is going to DOM, this is not subject to
* renaming as part of minification.
* @param value New value to write.
* @param sanitizer An optional function used to sanitize the value.
* @param nativeOnly Whether or not we should only set native properties and skip input check
* (this is necessary for host property bindings)
*/
function componentHostSyntheticProperty(index, propName, value, sanitizer, nativeOnly) {
elementPropertyInternal(index, propName, value, sanitizer, nativeOnly, loadComponentRenderer);
}
function loadComponentRenderer(tNode, lView) {
var componentLView = lView[tNode.index];
return componentLView[RENDERER];
}
function elementPropertyInternal(index, propName, value, sanitizer, nativeOnly, loadRendererFn) {
if (value === NO_CHANGE)
return;
var lView = getLView();
var element = getNativeByIndex(index, lView);
var tNode = getTNode(index, lView);
var inputData;
var dataValue;
if (!nativeOnly && (inputData = initializeTNodeInputs(tNode)) &&
(dataValue = inputData[propName])) {
setInputsForProperty(lView, dataValue, value);
if (isComponent(tNode))
markDirtyIfOnPush(lView, index + HEADER_OFFSET);
if (ngDevMode) {
if (tNode.type === 3 /* Element */ || tNode.type === 0 /* Container */) {
setNgReflectProperties(lView, element, tNode.type, dataValue, value);
}
}
}
else if (tNode.type === 3 /* Element */) {
var renderer = loadRendererFn ? loadRendererFn(tNode, lView) : lView[RENDERER];
// It is assumed that the sanitizer is only added when the compiler determines that the property
// is risky, so sanitization can be done without further checks.
value = sanitizer != null ? sanitizer(value) : value;
ngDevMode && ngDevMode.rendererSetProperty++;
if (isProceduralRenderer(renderer)) {
renderer.setProperty(element, propName, value);
}
else if (!isAnimationProp(propName)) {
element.setProperty ? element.setProperty(propName, value) :
element[propName] = value;
}
}
}
/**
* Constructs a TNode object from the arguments.
*
* @param type The type of the node
* @param adjustedIndex The index of the TNode in TView.data, adjusted for HEADER_OFFSET
* @param tagName The tag name of the node
* @param attrs The attributes defined on this node
* @param tViews Any TViews attached to this node
* @returns the TNode object
*/
function createTNode(lView, type, adjustedIndex, tagName, attrs, tViews) {
var previousOrParentTNode = getPreviousOrParentTNode();
ngDevMode && ngDevMode.tNode++;
var parent = getIsParent() ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent;
// Parents cannot cross component boundaries because components will be used in multiple places,
// so it's only set if the view is the same.
var parentInSameView = parent && lView && parent !== lView[HOST_NODE];
var tParent = parentInSameView ? parent : null;
return {
type: type,
index: adjustedIndex,
injectorIndex: tParent ? tParent.injectorIndex : -1,
directiveStart: -1,
directiveEnd: -1,
flags: 0,
providerIndexes: 0,
tagName: tagName,
attrs: attrs,
localNames: null,
initialInputs: undefined,
inputs: undefined,
outputs: undefined,
tViews: tViews,
next: null,
child: null,
parent: tParent,
detached: null,
stylingTemplate: null,
projection: null
};
}
/**
* Given a list of directive indices and minified input names, sets the
* input properties on the corresponding directives.
*/
function setInputsForProperty(lView, inputs, value) {
for (var i = 0; i < inputs.length; i += 2) {
ngDevMode && assertDataInRange(lView, inputs[i]);
lView[inputs[i]][inputs[i + 1]] = value;
}
}
function setNgReflectProperties(lView, element, type, inputs, value) {
var _a;
for (var i = 0; i < inputs.length; i += 2) {
var renderer = lView[RENDERER];
var attrName = normalizeDebugBindingName(inputs[i + 1]);
var debugValue = normalizeDebugBindingValue(value);
if (type === 3 /* Element */) {
isProceduralRenderer(renderer) ?
renderer.setAttribute(element, attrName, debugValue) :
element.setAttribute(attrName, debugValue);
}
else if (value !== undefined) {
var value_1 = "bindings=" + JSON.stringify((_a = {}, _a[attrName] = debugValue, _a), null, 2);
if (isProceduralRenderer(renderer)) {
renderer.setValue(element, value_1);
}
else {
element.textContent = value_1;
}
}
}
}
/**
* Consolidates all inputs or outputs of all directives on this logical node.
*
* @param tNodeFlags node flags
* @param direction whether to consider inputs or outputs
* @returns PropertyAliases|null aggregate of all properties if any, `null` otherwise
*/
function generatePropertyAliases(tNode, direction) {
var tView = getLView()[TVIEW];
var propStore = null;
var start = tNode.directiveStart;
var end = tNode.directiveEnd;
if (end > start) {
var isInput = direction === 0 /* Input */;
var defs = tView.data;
for (var i = start; i < end; i++) {
var directiveDef = defs[i];
var propertyAliasMap = isInput ? directiveDef.inputs : directiveDef.outputs;
for (var publicName in propertyAliasMap) {
if (propertyAliasMap.hasOwnProperty(publicName)) {
propStore = propStore || {};
var internalName = propertyAliasMap[publicName];
var hasProperty = propStore.hasOwnProperty(publicName);
hasProperty ? propStore[publicName].push(i, internalName) :
(propStore[publicName] = [i, internalName]);
}
}
}
}
return propStore;
}
/**
* Assign any inline style values to the element during creation mode.
*
* This instruction is meant to be called during creation mode to register all
* dynamic style and class bindings on the element. Note for static values (no binding)
* see `elementStart` and `elementHostAttrs`.
*
* @param classBindingNames An array containing bindable class names.
* The `elementClassProp` refers to the class name by index in this array.
* (i.e. `['foo', 'bar']` means `foo=0` and `bar=1`).
* @param styleBindingNames An array containing bindable style properties.
* The `elementStyleProp` refers to the class name by index in this array.
* (i.e. `['width', 'height']` means `width=0` and `height=1`).
* @param styleSanitizer An optional sanitizer function that will be used to sanitize any CSS
* property values that are applied to the element (during rendering).
* Note that the sanitizer instance itself is tied to the `directive` (if provided).
* @param directive A directive instance the styling is associated with. If not provided
* current view's controller instance is assumed.
*
* @publicApi
*/
function elementStyling(classBindingNames, styleBindingNames, styleSanitizer, directive) {
var tNode = getPreviousOrParentTNode();
if (!tNode.stylingTemplate) {
tNode.stylingTemplate = createEmptyStylingContext();
}
updateContextWithBindings(tNode.stylingTemplate, directive || null, classBindingNames, styleBindingNames, styleSanitizer, hasClassInput(tNode));
}
/**
* Assign static styling values to a host element.
*
* NOTE: This instruction is meant to used from `hostBindings` function only.
*
* @param directive A directive instance the styling is associated with.
* @param attrs An array containing class and styling information. The values must be marked with
* `AttributeMarker`.
*
* ```
* var attrs = [AttributeMarker.Classes, 'foo', 'bar',
* AttributeMarker.Styles, 'width', '100px', 'height, '200px']
* elementHostAttrs(directive, attrs);
* ```
*
* @publicApi
*/
function elementHostAttrs(directive, attrs) {
var tNode = getPreviousOrParentTNode();
if (!tNode.stylingTemplate) {
tNode.stylingTemplate = initializeStaticContext(attrs);
}
patchContextWithStaticAttrs(tNode.stylingTemplate, attrs, directive);
}
/**
* Apply styling binding to the element.
*
* This instruction is meant to be run after `elementStyle` and/or `elementStyleProp`.
* if any styling bindings have changed then the changes are flushed to the element.
*
*
* @param index Index of the element's with which styling is associated.
* @param directive Directive instance that is attempting to change styling. (Defaults to the
* component of the current view).
components
*
* @publicApi
*/
function elementStylingApply(index, directive) {
var lView = getLView();
var isFirstRender = (lView[FLAGS] & 2 /* FirstLViewPass */) !== 0;
var totalPlayersQueued = renderStyling(getStylingContext(index + HEADER_OFFSET, lView), lView[RENDERER], lView, isFirstRender, null, null, directive);
if (totalPlayersQueued > 0) {
var rootContext = getRootContext(lView);
scheduleTick(rootContext, 2 /* FlushPlayers */);
}
}
/**
* Update a style bindings value on an element.
*
* If the style value is `null` then it will be removed from the element
* (or assigned a different value depending if there are any styles placed
* on the element with `elementStyle` or any styles that are present
* from when the element was created (with `elementStyling`).
*
* (Note that the styling element is updated as part of `elementStylingApply`.)
*
* @param index Index of the element's with which styling is associated.
* @param styleIndex Index of style to update. This index value refers to the
* index of the style in the style bindings array that was passed into
* `elementStlyingBindings`.
* @param value New value to write (null to remove). Note that if a directive also
* attempts to write to the same binding value then it will only be able to
* do so if the template binding value is `null` (or doesn't exist at all).
* @param suffix Optional suffix. Used with scalar values to add unit such as `px`.
* Note that when a suffix is provided then the underlying sanitizer will
* be ignored.
* @param directive Directive instance that is attempting to change styling. (Defaults to the
* component of the current view).
components
*
* @publicApi
*/
function elementStyleProp(index, styleIndex, value, suffix, directive) {
var valueToAdd = null;
if (value !== null) {
if (suffix) {
// when a suffix is applied then it will bypass
// sanitization entirely (b/c a new string is created)
valueToAdd = stringify$1(value) + suffix;
}
else {
// sanitization happens by dealing with a String value
// this means that the string value will be passed through
// into the style rendering later (which is where the value
// will be sanitized before it is applied)
valueToAdd = value;
}
}
updateStyleProp(getStylingContext(index + HEADER_OFFSET, getLView()), styleIndex, valueToAdd, directive);
}
/**
* Add or remove a class via a class binding on a DOM element.
*
* This instruction is meant to handle the [class.foo]="exp" case and, therefore,
* the class itself must already be applied using `elementStyling` within
* the creation block.
*
* @param index Index of the element's with which styling is associated.
* @param classIndex Index of class to toggle. This index value refers to the
* index of the class in the class bindings array that was passed into
* `elementStlyingBindings` (which is meant to be called before this
* function is).
* @param value A true/false value which will turn the class on or off.
* @param directive Directive instance that is attempting to change styling. (Defaults to the
* component of the current view).
components
*
* @publicApi
*/
function elementClassProp(index, classIndex, value, directive) {
var onOrOffClassValue = (value instanceof BoundPlayerFactory) ? value : (!!value);
updateClassProp(getStylingContext(index + HEADER_OFFSET, getLView()), classIndex, onOrOffClassValue, directive);
}
/**
* Update style and/or class bindings using object literal.
*
* This instruction is meant apply styling via the `[style]="exp"` and `[class]="exp"` template
* bindings. When styles are applied to the Element they will then be placed with respect to
* any styles set with `elementStyleProp`. If any styles are set to `null` then they will be
* removed from the element.
*
* (Note that the styling instruction will not be applied until `elementStylingApply` is called.)
*
* @param index Index of the element's with which styling is associated.
* @param classes A key/value style map of CSS classes that will be added to the given element.
* Any missing classes (that have already been applied to the element beforehand) will be
* removed (unset) from the element's list of CSS classes.
* @param styles A key/value style map of the styles that will be applied to the given element.
* Any missing styles (that have already been applied to the element beforehand) will be
* removed (unset) from the element's styling.
* @param directive Directive instance that is attempting to change styling. (Defaults to the
* component of the current view).
*
* @publicApi
*/
function elementStylingMap(index, classes, styles, directive) {
if (directive != undefined)
return hackImplementationOfElementStylingMap(index, classes, styles, directive); // supported in next PR
var lView = getLView();
var tNode = getTNode(index, lView);
var stylingContext = getStylingContext(index + HEADER_OFFSET, lView);
if (hasClassInput(tNode) && classes !== NO_CHANGE) {
var initialClasses = getInitialClassNameValue(stylingContext);
var classInputVal = (initialClasses.length ? (initialClasses + ' ') : '') + classes;
setInputsForProperty(lView, tNode.inputs['class'], classInputVal);
}
else {
updateStylingMap(stylingContext, classes, styles);
}
}
/* START OF HACK BLOCK */
function hackImplementationOfElementStylingMap(index, classes, styles, directive) {
throw new Error('unimplemented. Should not be needed by ViewEngine compatibility');
}
/* END OF HACK BLOCK */
//////////////////////////
//// Text
//////////////////////////
/**
* Create static text node
*
* @param index Index of the node in the data array
* @param value Value to write. This value will be stringified.
*/
function text(index, value) {
var lView = getLView();
ngDevMode && assertEqual(lView[BINDING_INDEX], lView[TVIEW].bindingStartIndex, 'text nodes should be created before any bindings');
ngDevMode && ngDevMode.rendererCreateTextNode++;
var textNative = createTextNode(value, lView[RENDERER]);
var tNode = createNodeAtIndex(index, 3 /* Element */, textNative, null, null);
// Text nodes are self closing.
setIsParent(false);
appendChild(textNative, tNode, lView);
}
/**
* Create text node with binding
* Bindings should be handled externally with the proper interpolation(1-8) method
*
* @param index Index of the node in the data array.
* @param value Stringified value to write.
*/
function textBinding(index, value) {
if (value !== NO_CHANGE) {
var lView = getLView();
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
var element_2 = getNativeByIndex(index, lView);
ngDevMode && assertDefined(element_2, 'native element should exist');
ngDevMode && ngDevMode.rendererSetText++;
var renderer = lView[RENDERER];
isProceduralRenderer(renderer) ? renderer.setValue(element_2, stringify$1(value)) :
element_2.textContent = stringify$1(value);
}
}
//////////////////////////
//// Directive
//////////////////////////
/**
* Instantiate a root component.
*/
function instantiateRootComponent(tView, viewData, def) {
var rootTNode = getPreviousOrParentTNode();
if (tView.firstTemplatePass) {
if (def.providersResolver)
def.providersResolver(def);
generateExpandoInstructionBlock(tView, rootTNode, 1);
baseResolveDirective(tView, viewData, def, def.factory);
}
var directive = getNodeInjectable(tView.data, viewData, viewData.length - 1, rootTNode);
postProcessBaseDirective(viewData, rootTNode, directive, def);
return directive;
}
/**
* Resolve the matched directives on a node.
*/
function resolveDirectives(tView, viewData, directives, tNode, localRefs) {
// Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in tsickle.
ngDevMode && assertEqual(getFirstTemplatePass(), true, 'should run on first template pass only');
var exportsMap = localRefs ? { '': -1 } : null;
if (directives) {
initNodeFlags(tNode, tView.data.length, directives.length);
// When the same token is provided by several directives on the same node, some rules apply in
// the viewEngine:
// - viewProviders have priority over providers
// - the last directive in NgModule.declarations has priority over the previous one
// So to match these rules, the order in which providers are added in the arrays is very
// important.
for (var i = 0; i < directives.length; i++) {
var def = directives[i];
if (def.providersResolver)
def.providersResolver(def);
}
generateExpandoInstructionBlock(tView, tNode, directives.length);
for (var i = 0; i < directives.length; i++) {
var def = directives[i];
var directiveDefIdx = tView.data.length;
baseResolveDirective(tView, viewData, def, def.factory);
saveNameToExportMap(tView.data.length - 1, def, exportsMap);
// Init hooks are queued now so ngOnInit is called in host components before
// any projected components.
queueInitHooks(directiveDefIdx, def.onInit, def.doCheck, tView);
}
}
if (exportsMap)
cacheMatchingLocalNames(tNode, localRefs, exportsMap);
}
/**
* Instantiate all the directives that were previously resolved on the current node.
*/
function instantiateAllDirectives(tView, lView, tNode) {
var start = tNode.directiveStart;
var end = tNode.directiveEnd;
if (!getFirstTemplatePass() && start < end) {
getOrCreateNodeInjectorForNode(tNode, lView);
}
for (var i = start; i < end; i++) {
var def = tView.data[i];
if (isComponentDef(def)) {
addComponentLogic(lView, tNode, def);
}
var directive = getNodeInjectable(tView.data, lView, i, tNode);
postProcessDirective(lView, directive, def, i);
}
}
function invokeDirectivesHostBindings(tView, viewData, tNode) {
var start = tNode.directiveStart;
var end = tNode.directiveEnd;
var expando = tView.expandoInstructions;
var firstTemplatePass = getFirstTemplatePass();
for (var i = start; i < end; i++) {
var def = tView.data[i];
var directive = viewData[i];
if (def.hostBindings) {
var previousExpandoLength = expando.length;
setCurrentDirectiveDef(def);
def.hostBindings(1 /* Create */, directive, tNode.index - HEADER_OFFSET);
setCurrentDirectiveDef(null);
// `hostBindings` function may or may not contain `allocHostVars` call
// (e.g. it may not if it only contains host listeners), so we need to check whether
// `expandoInstructions` has changed and if not - we still push `hostBindings` to
// expando block, to make sure we execute it for DI cycle
if (previousExpandoLength === expando.length && firstTemplatePass) {
expando.push(def.hostBindings);
}
}
else if (firstTemplatePass) {
expando.push(null);
}
}
}
/**
* Generates a new block in TView.expandoInstructions for this node.
*
* Each expando block starts with the element index (turned negative so we can distinguish
* it from the hostVar count) and the directive count. See more in VIEW_DATA.md.
*/
function generateExpandoInstructionBlock(tView, tNode, directiveCount) {
ngDevMode && assertEqual(tView.firstTemplatePass, true, 'Expando block should only be generated on first template pass.');
var elementIndex = -(tNode.index - HEADER_OFFSET);
var providerStartIndex = tNode.providerIndexes & 65535 /* ProvidersStartIndexMask */;
var providerCount = tView.data.length - providerStartIndex;
(tView.expandoInstructions || (tView.expandoInstructions = [])).push(elementIndex, providerCount, directiveCount);
}
/**
* On the first template pass, we need to reserve space for host binding values
* after directives are matched (so all directives are saved, then bindings).
* Because we are updating the blueprint, we only need to do this once.
*/
function prefillHostVars(tView, lView, totalHostVars) {
ngDevMode &&
assertEqual(getFirstTemplatePass(), true, 'Should only be called in first template pass.');
for (var i = 0; i < totalHostVars; i++) {
lView.push(NO_CHANGE);
tView.blueprint.push(NO_CHANGE);
tView.data.push(null);
}
}
/**
* Process a directive on the current node after its creation.
*/
function postProcessDirective(viewData, directive, def, directiveDefIdx) {
var previousOrParentTNode = getPreviousOrParentTNode();
postProcessBaseDirective(viewData, previousOrParentTNode, directive, def);
ngDevMode && assertDefined(previousOrParentTNode, 'previousOrParentTNode');
if (previousOrParentTNode && previousOrParentTNode.attrs) {
setInputsFromAttrs(directiveDefIdx, directive, def.inputs, previousOrParentTNode);
}
if (def.contentQueries) {
def.contentQueries(directiveDefIdx);
}
if (isComponentDef(def)) {
var componentView = getComponentViewByIndex(previousOrParentTNode.index, viewData);
componentView[CONTEXT] = directive;
}
}
/**
* A lighter version of postProcessDirective() that is used for the root component.
*/
function postProcessBaseDirective(lView, previousOrParentTNode, directive, def) {
var native = getNativeByTNode(previousOrParentTNode, lView);
ngDevMode && assertEqual(lView[BINDING_INDEX], lView[TVIEW].bindingStartIndex, 'directives should be created before any bindings');
ngDevMode && assertPreviousIsParent(getIsParent());
attachPatchData(directive, lView);
if (native) {
attachPatchData(native, lView);
}
// TODO(misko): setUpAttributes should be a feature for better treeshakability.
if (def.attributes != null && previousOrParentTNode.type == 3 /* Element */) {
setUpAttributes(native, def.attributes);
}
}
/**
* Matches the current node against all available selectors.
* If a component is matched (at most one), it is returned in first position in the array.
*/
function findDirectiveMatches(tView, viewData, tNode) {
ngDevMode && assertEqual(getFirstTemplatePass(), true, 'should run on first template pass only');
var registry = tView.directiveRegistry;
var matches = null;
if (registry) {
for (var i = 0; i < registry.length; i++) {
var def = registry[i];
if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) {
matches || (matches = []);
diPublicInInjector(getOrCreateNodeInjectorForNode(getPreviousOrParentTNode(), viewData), viewData, def.type);
if (isComponentDef(def)) {
if (tNode.flags & 1 /* isComponent */)
throwMultipleComponentError(tNode);
tNode.flags = 1 /* isComponent */;
// The component is always stored first with directives after.
matches.unshift(def);
}
else {
matches.push(def);
}
}
}
}
return matches;
}
/** Stores index of component's host element so it will be queued for view refresh during CD. */
function queueComponentIndexForCheck(previousOrParentTNode) {
ngDevMode &&
assertEqual(getFirstTemplatePass(), true, 'Should only be called in first template pass.');
var tView = getLView()[TVIEW];
(tView.components || (tView.components = [])).push(previousOrParentTNode.index);
}
/**
* Stores host binding fn and number of host vars so it will be queued for binding refresh during
* CD.
*/
function queueHostBindingForCheck(tView, def, hostVars) {
ngDevMode &&
assertEqual(getFirstTemplatePass(), true, 'Should only be called in first template pass.');
var expando = tView.expandoInstructions;
var length = expando.length;
// Check whether a given `hostBindings` function already exists in expandoInstructions,
// which can happen in case directive definition was extended from base definition (as a part of
// the `InheritDefinitionFeature` logic). If we found the same `hostBindings` function in the
// list, we just increase the number of host vars associated with that function, but do not add it
// into the list again.
if (length >= 2 && expando[length - 2] === def.hostBindings) {
expando[length - 1] = expando[length - 1] + hostVars;
}
else {
expando.push(def.hostBindings, hostVars);
}
}
/** Caches local names and their matching directive indices for query and template lookups. */
function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
if (localRefs) {
var localNames = tNode.localNames = [];
// Local names must be stored in tNode in the same order that localRefs are defined
// in the template to ensure the data is loaded in the same slots as their refs
// in the template (for template queries).
for (var i = 0; i < localRefs.length; i += 2) {
var index = exportsMap[localRefs[i + 1]];
if (index == null)
throw new Error("Export of name '" + localRefs[i + 1] + "' not found!");
localNames.push(localRefs[i], index);
}
}
}
/**
* Builds up an export map as directives are created, so local refs can be quickly mapped
* to their directive instances.
*/
function saveNameToExportMap(index, def, exportsMap) {
if (exportsMap) {
if (def.exportAs)
exportsMap[def.exportAs] = index;
if (def.template)
exportsMap[''] = index;
}
}
/**
* Initializes the flags on the current node, setting all indices to the initial index,
* the directive count to 0, and adding the isComponent flag.
* @param index the initial index
*/
function initNodeFlags(tNode, index, numberOfDirectives) {
ngDevMode && assertEqual(getFirstTemplatePass(), true, 'expected firstTemplatePass to be true');
var flags = tNode.flags;
ngDevMode && assertEqual(flags === 0 || flags === 1 /* isComponent */, true, 'expected node flags to not be initialized');
ngDevMode && assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
// When the first directive is created on a node, save the index
tNode.flags = flags & 1 /* isComponent */;
tNode.directiveStart = index;
tNode.directiveEnd = index + numberOfDirectives;
tNode.providerIndexes = index;
}
function baseResolveDirective(tView, viewData, def, directiveFactory) {
tView.data.push(def);
var nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), null);
tView.blueprint.push(nodeInjectorFactory);
viewData.push(nodeInjectorFactory);
}
function addComponentLogic(lView, previousOrParentTNode, def) {
var native = getNativeByTNode(previousOrParentTNode, lView);
var tView = getOrCreateTView(def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery);
// Only component views should be added to the view tree directly. Embedded views are
// accessed through their containers because they may be removed / re-added later.
var rendererFactory = lView[RENDERER_FACTORY];
var componentView = addToViewTree(lView, previousOrParentTNode.index, createLView(lView, tView, null, def.onPush ? 8 /* Dirty */ : 4 /* CheckAlways */, rendererFactory, lView[RENDERER_FACTORY].createRenderer(native, def)));
componentView[HOST_NODE] = previousOrParentTNode;
// Component view will always be created before any injected LContainers,
// so this is a regular element, wrap it with the component view
componentView[HOST] = lView[previousOrParentTNode.index];
lView[previousOrParentTNode.index] = componentView;
if (getFirstTemplatePass()) {
queueComponentIndexForCheck(previousOrParentTNode);
}
}
/**
* Sets initial input properties on directive instances from attribute data
*
* @param directiveIndex Index of the directive in directives array
* @param instance Instance of the directive on which to set the initial inputs
* @param inputs The list of inputs from the directive def
* @param tNode The static data for this node
*/
function setInputsFromAttrs(directiveIndex, instance, inputs, tNode) {
var initialInputData = tNode.initialInputs;
if (initialInputData === undefined || directiveIndex >= initialInputData.length) {
initialInputData = generateInitialInputs(directiveIndex, inputs, tNode);
}
var initialInputs = initialInputData[directiveIndex];
if (initialInputs) {
for (var i = 0; i < initialInputs.length; i += 2) {
instance[initialInputs[i]] = initialInputs[i + 1];
}
}
}
/**
* Generates initialInputData for a node and stores it in the template's static storage
* so subsequent template invocations don't have to recalculate it.
*
* initialInputData is an array containing values that need to be set as input properties
* for directives on this node, but only once on creation. We need this array to support
* the case where you set an @Input property of a directive using attribute-like syntax.
* e.g. if you have a `name` @Input, you can set it once like this:
*
* <my-component name="Bess"></my-component>
*
* @param directiveIndex Index to store the initial input data
* @param inputs The list of inputs from the directive def
* @param tNode The static data on this node
*/
function generateInitialInputs(directiveIndex, inputs, tNode) {
var initialInputData = tNode.initialInputs || (tNode.initialInputs = []);
initialInputData[directiveIndex] = null;
var attrs = tNode.attrs;
var i = 0;
while (i < attrs.length) {
var attrName = attrs[i];
if (attrName === 3 /* SelectOnly */)
break;
if (attrName === 0 /* NamespaceURI */) {
// We do not allow inputs on namespaced attributes.
i += 4;
continue;
}
var minifiedInputName = inputs[attrName];
var attrValue = attrs[i + 1];
if (minifiedInputName !== undefined) {
var inputsToStore = initialInputData[directiveIndex] || (initialInputData[directiveIndex] = []);
inputsToStore.push(minifiedInputName, attrValue);
}
i += 2;
}
return initialInputData;
}
//////////////////////////
//// ViewContainer & View
//////////////////////////
/**
* Creates a LContainer, either from a container instruction, or for a ViewContainerRef.
*
* @param hostNative The host element for the LContainer
* @param hostTNode The host TNode for the LContainer
* @param currentView The parent view of the LContainer
* @param native The native comment element
* @param isForViewContainerRef Optional a flag indicating the ViewContainerRef case
* @returns LContainer
*/
function createLContainer(hostNative, hostTNode, currentView, native, isForViewContainerRef) {
return [
isForViewContainerRef ? -1 : 0,
[],
currentView,
null,
null,
hostNative,
native,
getRenderParent(hostTNode, currentView) // renderParent
];
}
/**
* Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
*
* <ng-template #foo>
* <div></div>
* </ng-template>
*
* @param index The index of the container in the data array
* @param templateFn Inline template
* @param consts The number of nodes, local refs, and pipes for this template
* @param vars The number of bindings for this template
* @param tagName The name of the container element, if applicable
* @param attrs The attrs attached to the container, if applicable
* @param localRefs A set of local reference bindings on the element.
* @param localRefExtractor A function which extracts local-refs values from the template.
* Defaults to the current element associated with the local-ref.
*/
function template(index, templateFn, consts, vars, tagName, attrs, localRefs, localRefExtractor) {
var lView = getLView();
var tView = lView[TVIEW];
// TODO: consider a separate node type for templates
var tNode = containerInternal(index, tagName || null, attrs || null);
if (getFirstTemplatePass()) {
tNode.tViews = createTView(-1, templateFn, consts, vars, tView.directiveRegistry, tView.pipeRegistry, null);
}
createDirectivesAndLocals(tView, lView, localRefs, localRefExtractor);
var currentQueries = lView[QUERIES];
var previousOrParentTNode = getPreviousOrParentTNode();
var native = getNativeByTNode(previousOrParentTNode, lView);
attachPatchData(native, lView);
if (currentQueries) {
lView[QUERIES] = currentQueries.addNode(previousOrParentTNode);
}
queueLifecycleHooks(tView, tNode);
setIsParent(false);
}
/**
* Creates an LContainer for inline views, e.g.
*
* % if (showing) {
* <div></div>
* % }
*
* @param index The index of the container in the data array
*/
function container(index) {
var tNode = containerInternal(index, null, null);
getFirstTemplatePass() && (tNode.tViews = []);
setIsParent(false);
}
function containerInternal(index, tagName, attrs) {
var lView = getLView();
ngDevMode && assertEqual(lView[BINDING_INDEX], lView[TVIEW].bindingStartIndex, 'container nodes should be created before any bindings');
var adjustedIndex = index + HEADER_OFFSET;
var comment = lView[RENDERER].createComment(ngDevMode ? 'container' : '');
ngDevMode && ngDevMode.rendererCreateComment++;
var tNode = createNodeAtIndex(index, 0 /* Container */, comment, tagName, attrs);
var lContainer = lView[adjustedIndex] =
createLContainer(lView[adjustedIndex], tNode, lView, comment);
appendChild(comment, tNode, lView);
// Containers are added to the current view tree instead of their embedded views
// because views can be removed and re-inserted.
addToViewTree(lView, index + HEADER_OFFSET, lContainer);
var currentQueries = lView[QUERIES];
if (currentQueries) {
// prepare place for matching nodes from views inserted into a given container
lContainer[QUERIES] = currentQueries.container();
}
ngDevMode && assertNodeType(getPreviousOrParentTNode(), 0 /* Container */);
return tNode;
}
/**
* Sets a container up to receive views.
*
* @param index The index of the container in the data array
*/
function containerRefreshStart(index) {
var lView = getLView();
var tView = lView[TVIEW];
var previousOrParentTNode = loadInternal(tView.data, index);
setPreviousOrParentTNode(previousOrParentTNode);
ngDevMode && assertNodeType(previousOrParentTNode, 0 /* Container */);
setIsParent(true);
lView[index + HEADER_OFFSET][ACTIVE_INDEX] = 0;
// We need to execute init hooks here so ngOnInit hooks are called in top level views
// before they are called in embedded views (for backwards compatibility).
executeInitHooks(lView, tView, getCheckNoChangesMode());
}
/**
* Marks the end of the LContainer.
*
* Marking the end of LContainer is the time when to child views get inserted or removed.
*/
function containerRefreshEnd() {
var previousOrParentTNode = getPreviousOrParentTNode();
if (getIsParent()) {
setIsParent(false);
}
else {
ngDevMode && assertNodeType(previousOrParentTNode, 2 /* View */);
ngDevMode && assertHasParent(previousOrParentTNode);
previousOrParentTNode = previousOrParentTNode.parent;
setPreviousOrParentTNode(previousOrParentTNode);
}
ngDevMode && assertNodeType(previousOrParentTNode, 0 /* Container */);
var lContainer = getLView()[previousOrParentTNode.index];
var nextIndex = lContainer[ACTIVE_INDEX];
// remove extra views at the end of the container
while (nextIndex < lContainer[VIEWS].length) {
removeView(lContainer, previousOrParentTNode, nextIndex);
}
}
/**
* Goes over dynamic embedded views (ones created through ViewContainerRef APIs) and refreshes them
* by executing an associated template function.
*/
function refreshDynamicEmbeddedViews(lView) {
for (var current = getLViewChild(lView); current !== null; current = current[NEXT]) {
// Note: current can be an LView or an LContainer instance, but here we are only interested
// in LContainer. We can tell it's an LContainer because its length is less than the LView
// header.
if (current.length < HEADER_OFFSET && current[ACTIVE_INDEX] === -1) {
var container_1 = current;
for (var i = 0; i < container_1[VIEWS].length; i++) {
var dynamicViewData = container_1[VIEWS][i];
// The directives and pipes are not needed here as an existing view is only being refreshed.
ngDevMode && assertDefined(dynamicViewData[TVIEW], 'TView must be allocated');
renderEmbeddedTemplate(dynamicViewData, dynamicViewData[TVIEW], dynamicViewData[CONTEXT]);
}
}
}
}
/**
* Looks for a view with a given view block id inside a provided LContainer.
* Removes views that need to be deleted in the process.
*
* @param lContainer to search for views
* @param tContainerNode to search for views
* @param startIdx starting index in the views array to search from
* @param viewBlockId exact view block id to look for
* @returns index of a found view or -1 if not found
*/
function scanForView(lContainer, tContainerNode, startIdx, viewBlockId) {
var views = lContainer[VIEWS];
for (var i = startIdx; i < views.length; i++) {
var viewAtPositionId = views[i][TVIEW].id;
if (viewAtPositionId === viewBlockId) {
return views[i];
}
else if (viewAtPositionId < viewBlockId) {
// found a view that should not be at this position - remove
removeView(lContainer, tContainerNode, i);
}
else {
// found a view with id greater than the one we are searching for
// which means that required view doesn't exist and can't be found at
// later positions in the views array - stop the searchdef.cont here
break;
}
}
return null;
}
/**
* Marks the start of an embedded view.
*
* @param viewBlockId The ID of this view
* @return boolean Whether or not this view is in creation mode
*/
function embeddedViewStart(viewBlockId, consts, vars) {
var lView = getLView();
var previousOrParentTNode = getPreviousOrParentTNode();
// The previous node can be a view node if we are processing an inline for loop
var containerTNode = previousOrParentTNode.type === 2 /* View */ ?
previousOrParentTNode.parent :
previousOrParentTNode;
var lContainer = lView[containerTNode.index];
ngDevMode && assertNodeType(containerTNode, 0 /* Container */);
var viewToRender = scanForView(lContainer, containerTNode, lContainer[ACTIVE_INDEX], viewBlockId);
if (viewToRender) {
setIsParent(true);
enterView(viewToRender, viewToRender[TVIEW].node);
}
else {
// When we create a new LView, we always reset the state of the instructions.
viewToRender = createLView(lView, getOrCreateEmbeddedTView(viewBlockId, consts, vars, containerTNode), null, 4 /* CheckAlways */);
if (lContainer[QUERIES]) {
viewToRender[QUERIES] = lContainer[QUERIES].createView();
}
createViewNode(viewBlockId, viewToRender);
enterView(viewToRender, viewToRender[TVIEW].node);
}
if (lContainer) {
if (isCreationMode(viewToRender)) {
// it is a new view, insert it into collection of views for a given container
insertView(viewToRender, lContainer, lView, lContainer[ACTIVE_INDEX], -1);
}
lContainer[ACTIVE_INDEX]++;
}
return isCreationMode(viewToRender) ? 1 /* Create */ | 2 /* Update */ :
2 /* Update */;
}
/**
* Initialize the TView (e.g. static data) for the active embedded view.
*
* Each embedded view block must create or retrieve its own TView. Otherwise, the embedded view's
* static data for a particular node would overwrite the static data for a node in the view above
* it with the same index (since it's in the same template).
*
* @param viewIndex The index of the TView in TNode.tViews
* @param consts The number of nodes, local refs, and pipes in this template
* @param vars The number of bindings and pure function bindings in this template
* @param container The parent container in which to look for the view's static data
* @returns TView
*/
function getOrCreateEmbeddedTView(viewIndex, consts, vars, parent) {
var tView = getLView()[TVIEW];
ngDevMode && assertNodeType(parent, 0 /* Container */);
var containerTViews = parent.tViews;
ngDevMode && assertDefined(containerTViews, 'TView expected');
ngDevMode && assertEqual(Array.isArray(containerTViews), true, 'TViews should be in an array');
if (viewIndex >= containerTViews.length || containerTViews[viewIndex] == null) {
containerTViews[viewIndex] = createTView(viewIndex, null, consts, vars, tView.directiveRegistry, tView.pipeRegistry, null);
}
return containerTViews[viewIndex];
}
/** Marks the end of an embedded view. */
function embeddedViewEnd() {
var lView = getLView();
var viewHost = lView[HOST_NODE];
if (isCreationMode(lView)) {
refreshDescendantViews(lView); // creation mode pass
lView[FLAGS] &= ~1 /* CreationMode */;
}
refreshDescendantViews(lView); // update mode pass
leaveView(lView[PARENT]);
setPreviousOrParentTNode(viewHost);
setIsParent(false);
}
/////////////
/**
* Refreshes components by entering the component view and processing its bindings, queries, etc.
*
* @param adjustedElementIndex Element index in LView[] (adjusted for HEADER_OFFSET)
*/
function componentRefresh(adjustedElementIndex) {
var lView = getLView();
ngDevMode && assertDataInRange(lView, adjustedElementIndex);
var hostView = getComponentViewByIndex(adjustedElementIndex, lView);
ngDevMode && assertNodeType(lView[TVIEW].data[adjustedElementIndex], 3 /* Element */);
// Only attached CheckAlways components or attached, dirty OnPush components should be checked
if (viewAttached(hostView) && hostView[FLAGS] & (4 /* CheckAlways */ | 8 /* Dirty */)) {
syncViewWithBlueprint(hostView);
checkView(hostView, hostView[CONTEXT]);
}
}
/**
* Syncs an LView instance with its blueprint if they have gotten out of sync.
*
* Typically, blueprints and their view instances should always be in sync, so the loop here
* will be skipped. However, consider this case of two components side-by-side:
*
* App template:
* ```
* <comp></comp>
* <comp></comp>
* ```
*
* The following will happen:
* 1. App template begins processing.
* 2. First <comp> is matched as a component and its LView is created.
* 3. Second <comp> is matched as a component and its LView is created.
* 4. App template completes processing, so it's time to check child templates.
* 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
* 6. Second <comp> template is checked. Its blueprint has been updated by the first
* <comp> template, but its LView was created before this update, so it is out of sync.
*
* Note that embedded views inside ngFor loops will never be out of sync because these views
* are processed as soon as they are created.
*
* @param componentView The view to sync
*/
function syncViewWithBlueprint(componentView) {
var componentTView = componentView[TVIEW];
for (var i = componentView.length; i < componentTView.blueprint.length; i++) {
componentView[i] = componentTView.blueprint[i];
}
}
/** Returns a boolean for whether the view is attached */
function viewAttached(view) {
return (view[FLAGS] & 16 /* Attached */) === 16 /* Attached */;
}
/**
* Instruction to distribute projectable nodes among <ng-content> occurrences in a given template.
* It takes all the selectors from the entire component's template and decides where
* each projected node belongs (it re-distributes nodes among "buckets" where each "bucket" is
* backed by a selector).
*
* This function requires CSS selectors to be provided in 2 forms: parsed (by a compiler) and text,
* un-parsed form.
*
* The parsed form is needed for efficient matching of a node against a given CSS selector.
* The un-parsed, textual form is needed for support of the ngProjectAs attribute.
*
* Having a CSS selector in 2 different formats is not ideal, but alternatives have even more
* drawbacks:
* - having only a textual form would require runtime parsing of CSS selectors;
* - we can't have only a parsed as we can't re-construct textual form from it (as entered by a
* template author).
*
* @param selectors A collection of parsed CSS selectors
* @param rawSelectors A collection of CSS selectors in the raw, un-parsed form
*/
function projectionDef(selectors, textSelectors) {
var componentNode = findComponentView(getLView())[HOST_NODE];
if (!componentNode.projection) {
var noOfNodeBuckets = selectors ? selectors.length + 1 : 1;
var pData = componentNode.projection =
new Array(noOfNodeBuckets).fill(null);
var tails = pData.slice();
var componentChild = componentNode.child;
while (componentChild !== null) {
var bucketIndex = selectors ? matchingSelectorIndex(componentChild, selectors, textSelectors) : 0;
var nextNode = componentChild.next;
if (tails[bucketIndex]) {
tails[bucketIndex].next = componentChild;
}
else {
pData[bucketIndex] = componentChild;
componentChild.next = null;
}
tails[bucketIndex] = componentChild;
componentChild = nextNode;
}
}
}
/**
* Stack used to keep track of projection nodes in projection() instruction.
*
* This is deliberately created outside of projection() to avoid allocating
* a new array each time the function is called. Instead the array will be
* re-used by each invocation. This works because the function is not reentrant.
*/
var projectionNodeStack$1 = [];
/**
* Inserts previously re-distributed projected nodes. This instruction must be preceded by a call
* to the projectionDef instruction.
*
* @param nodeIndex
* @param selectorIndex:
* - 0 when the selector is `*` (or unspecified as this is the default value),
* - 1 based index of the selector from the {@link projectionDef}
*/
function projection(nodeIndex, selectorIndex, attrs) {
if (selectorIndex === void 0) { selectorIndex = 0; }
var lView = getLView();
var tProjectionNode = createNodeAtIndex(nodeIndex, 1 /* Projection */, null, null, attrs || null);
// We can't use viewData[HOST_NODE] because projection nodes can be nested in embedded views.
if (tProjectionNode.projection === null)
tProjectionNode.projection = selectorIndex;
// `<ng-content>` has no content
setIsParent(false);
// re-distribution of projectable nodes is stored on a component's view level
var componentView = findComponentView(lView);
var componentNode = componentView[HOST_NODE];
var nodeToProject = componentNode.projection[selectorIndex];
var projectedView = componentView[PARENT];
var projectionNodeIndex = -1;
while (nodeToProject) {
if (nodeToProject.type === 1 /* Projection */) {
// This node is re-projected, so we must go up the tree to get its projected nodes.
var currentComponentView = findComponentView(projectedView);
var currentComponentHost = currentComponentView[HOST_NODE];
var firstProjectedNode = currentComponentHost.projection[nodeToProject.projection];
if (firstProjectedNode) {
projectionNodeStack$1[++projectionNodeIndex] = nodeToProject;
projectionNodeStack$1[++projectionNodeIndex] = projectedView;
nodeToProject = firstProjectedNode;
projectedView = currentComponentView[PARENT];
continue;
}
}
else {
// This flag must be set now or we won't know that this node is projected
// if the nodes are inserted into a container later.
nodeToProject.flags |= 2 /* isProjected */;
appendProjectedNode(nodeToProject, tProjectionNode, lView, projectedView);
}
// If we are finished with a list of re-projected nodes, we need to get
// back to the root projection node that was re-projected.
if (nodeToProject.next === null && projectedView !== componentView[PARENT]) {
projectedView = projectionNodeStack$1[projectionNodeIndex--];
nodeToProject = projectionNodeStack$1[projectionNodeIndex--];
}
nodeToProject = nodeToProject.next;
}
}
/**
* Adds LView or LContainer to the end of the current view tree.
*
* This structure will be used to traverse through nested views to remove listeners
* and call onDestroy callbacks.
*
* @param lView The view where LView or LContainer should be added
* @param adjustedHostIndex Index of the view's host node in LView[], adjusted for header
* @param state The LView or LContainer to add to the view tree
* @returns The state passed in
*/
function addToViewTree(lView, adjustedHostIndex, state) {
var tView = lView[TVIEW];
var firstTemplatePass = getFirstTemplatePass();
if (lView[TAIL]) {
lView[TAIL][NEXT] = state;
}
else if (firstTemplatePass) {
tView.childIndex = adjustedHostIndex;
}
lView[TAIL] = state;
return state;
}
///////////////////////////////
//// Change detection
///////////////////////////////
/** If node is an OnPush component, marks its LView dirty. */
function markDirtyIfOnPush(lView, viewIndex) {
var childComponentLView = getComponentViewByIndex(viewIndex, lView);
if (!(childComponentLView[FLAGS] & 4 /* CheckAlways */)) {
childComponentLView[FLAGS] |= 8 /* Dirty */;
}
}
/** Wraps an event listener with preventDefault behavior. */
function wrapListenerWithPreventDefault(listenerFn) {
return function wrapListenerIn_preventDefault(e) {
if (listenerFn(e) === false) {
e.preventDefault();
// Necessary for legacy browsers that don't support preventDefault (e.g. IE)
e.returnValue = false;
}
};
}
/** Marks current view and all ancestors dirty */
function markViewDirty(lView) {
while (lView && !(lView[FLAGS] & 128 /* IsRoot */)) {
lView[FLAGS] |= 8 /* Dirty */;
lView = lView[PARENT];
}
lView[FLAGS] |= 8 /* Dirty */;
ngDevMode && assertDefined(lView[CONTEXT], 'rootContext should be defined');
var rootContext = lView[CONTEXT];
scheduleTick(rootContext, 1 /* DetectChanges */);
}
/**
* Used to schedule change detection on the whole application.
*
* Unlike `tick`, `scheduleTick` coalesces multiple calls into one change detection run.
* It is usually called indirectly by calling `markDirty` when the view needs to be
* re-rendered.
*
* Typically `scheduleTick` uses `requestAnimationFrame` to coalesce multiple
* `scheduleTick` requests. The scheduling function can be overridden in
* `renderComponent`'s `scheduler` option.
*/
function scheduleTick(rootContext, flags) {
var nothingScheduled = rootContext.flags === 0 /* Empty */;
rootContext.flags |= flags;
if (nothingScheduled && rootContext.clean == _CLEAN_PROMISE) {
var res_1;
rootContext.clean = new Promise(function (r) { return res_1 = r; });
rootContext.scheduler(function () {
if (rootContext.flags & 1 /* DetectChanges */) {
rootContext.flags &= ~1 /* DetectChanges */;
tickRootContext(rootContext);
}
if (rootContext.flags & 2 /* FlushPlayers */) {
rootContext.flags &= ~2 /* FlushPlayers */;
var playerHandler = rootContext.playerHandler;
if (playerHandler) {
playerHandler.flushPlayers();
}
}
rootContext.clean = _CLEAN_PROMISE;
res_1(null);
});
}
}
function tickRootContext(rootContext) {
for (var i = 0; i < rootContext.components.length; i++) {
var rootComponent = rootContext.components[i];
renderComponentOrTemplate(readPatchedLView(rootComponent), rootComponent);
}
}
/**
* Synchronously perform change detection on a component (and possibly its sub-components).
*
* This function triggers change detection in a synchronous way on a component. There should
* be very little reason to call this function directly since a preferred way to do change
* detection is to {@link markDirty} the component and wait for the scheduler to call this method
* at some future point in time. This is because a single user action often results in many
* components being invalidated and calling change detection on each component synchronously
* would be inefficient. It is better to wait until all components are marked as dirty and
* then perform single change detection across all of the components
*
* @param component The component which the change detection should be performed on.
*/
function detectChanges(component) {
var view = getComponentViewByInstance(component);
detectChangesInternal(view, component);
}
function detectChangesInternal(view, context) {
var rendererFactory = view[RENDERER_FACTORY];
if (rendererFactory.begin)
rendererFactory.begin();
if (isCreationMode(view)) {
checkView(view, context); // creation mode pass
}
checkView(view, context); // update mode pass
if (rendererFactory.end)
rendererFactory.end();
}
/**
* Synchronously perform change detection on a root view and its components.
*
* @param lView The view which the change detection should be performed on.
*/
function detectChangesInRootView(lView) {
tickRootContext(lView[CONTEXT]);
}
/**
* Checks the change detector and its children, and throws if any changes are detected.
*
* This is used in development mode to verify that running change detection doesn't
* introduce other changes.
*/
function checkNoChanges(component) {
setCheckNoChangesMode(true);
try {
detectChanges(component);
}
finally {
setCheckNoChangesMode(false);
}
}
/**
* Checks the change detector on a root view and its components, and throws if any changes are
* detected.
*
* This is used in development mode to verify that running change detection doesn't
* introduce other changes.
*
* @param lView The view which the change detection should be checked on.
*/
function checkNoChangesInRootView(lView) {
setCheckNoChangesMode(true);
try {
detectChangesInRootView(lView);
}
finally {
setCheckNoChangesMode(false);
}
}
/** Checks the view of the component provided. Does not gate on dirty checks or execute doCheck. */
function checkView(hostView, component) {
var hostTView = hostView[TVIEW];
var oldView = enterView(hostView, hostView[HOST_NODE]);
var templateFn = hostTView.template;
var viewQuery = hostTView.viewQuery;
try {
namespaceHTML();
createViewQuery(viewQuery, hostView, component);
templateFn(getRenderFlags(hostView), component);
refreshDescendantViews(hostView);
updateViewQuery(viewQuery, hostView, component);
}
finally {
leaveView(oldView);
}
}
function createViewQuery(viewQuery, view, component) {
if (viewQuery && isCreationMode(view)) {
viewQuery(1 /* Create */, component);
}
}
function updateViewQuery(viewQuery, view, component) {
if (viewQuery && !isCreationMode(view)) {
viewQuery(2 /* Update */, component);
}
}
/**
* Mark the component as dirty (needing change detection).
*
* Marking a component dirty will schedule a change detection on this
* component at some point in the future. Marking an already dirty
* component as dirty is a noop. Only one outstanding change detection
* can be scheduled per component tree. (Two components bootstrapped with
* separate `renderComponent` will have separate schedulers)
*
* When the root component is bootstrapped with `renderComponent`, a scheduler
* can be provided.
*
* @param component Component to mark as dirty.
*
* @publicApi
*/
function markDirty(component) {
ngDevMode && assertDefined(component, 'component');
markViewDirty(getComponentViewByInstance(component));
}
///////////////////////////////
//// Bindings & interpolations
///////////////////////////////
/**
* Creates a single value binding.
*
* @param value Value to diff
*/
function bind(value) {
var lView = getLView();
return bindingUpdated(lView, lView[BINDING_INDEX]++, value) ? value : NO_CHANGE;
}
/**
* Allocates the necessary amount of slots for host vars.
*
* @param count Amount of vars to be allocated
*/
function allocHostVars(count) {
if (!getFirstTemplatePass())
return;
var lView = getLView();
var tView = lView[TVIEW];
queueHostBindingForCheck(tView, getCurrentDirectiveDef(), count);
prefillHostVars(tView, lView, count);
}
/**
* Create interpolation bindings with a variable number of expressions.
*
* If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
* Those are faster because there is no need to create an array of expressions and iterate over it.
*
* `values`:
* - has static text at even indexes,
* - has evaluated expressions at odd indexes.
*
* Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
*/
function interpolationV(values) {
ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
var different = false;
var lView = getLView();
var bindingIndex = lView[BINDING_INDEX];
for (var i = 1; i < values.length; i += 2) {
// Check if bindings (odd indexes) have changed
bindingUpdated(lView, bindingIndex++, values[i]) && (different = true);
}
lView[BINDING_INDEX] = bindingIndex;
if (!different) {
return NO_CHANGE;
}
// Build the updated content
var content = values[0];
for (var i = 1; i < values.length; i += 2) {
content += stringify$1(values[i]) + values[i + 1];
}
return content;
}
/**
* Creates an interpolation binding with 1 expression.
*
* @param prefix static value used for concatenation only.
* @param v0 value checked for change.
* @param suffix static value used for concatenation only.
*/
function interpolation1(prefix, v0, suffix) {
var lView = getLView();
var different = bindingUpdated(lView, lView[BINDING_INDEX], v0);
lView[BINDING_INDEX] += 1;
return different ? prefix + stringify$1(v0) + suffix : NO_CHANGE;
}
/** Creates an interpolation binding with 2 expressions. */
function interpolation2(prefix, v0, i0, v1, suffix) {
var lView = getLView();
var different = bindingUpdated2(lView, lView[BINDING_INDEX], v0, v1);
lView[BINDING_INDEX] += 2;
return different ? prefix + stringify$1(v0) + i0 + stringify$1(v1) + suffix : NO_CHANGE;
}
/** Creates an interpolation binding with 3 expressions. */
function interpolation3(prefix, v0, i0, v1, i1, v2, suffix) {
var lView = getLView();
var different = bindingUpdated3(lView, lView[BINDING_INDEX], v0, v1, v2);
lView[BINDING_INDEX] += 3;
return different ? prefix + stringify$1(v0) + i0 + stringify$1(v1) + i1 + stringify$1(v2) + suffix :
NO_CHANGE;
}
/** Create an interpolation binding with 4 expressions. */
function interpolation4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
var lView = getLView();
var different = bindingUpdated4(lView, lView[BINDING_INDEX], v0, v1, v2, v3);
lView[BINDING_INDEX] += 4;
return different ?
prefix + stringify$1(v0) + i0 + stringify$1(v1) + i1 + stringify$1(v2) + i2 + stringify$1(v3) +
suffix :
NO_CHANGE;
}
/** Creates an interpolation binding with 5 expressions. */
function interpolation5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
var lView = getLView();
var bindingIndex = lView[BINDING_INDEX];
var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
lView[BINDING_INDEX] += 5;
return different ?
prefix + stringify$1(v0) + i0 + stringify$1(v1) + i1 + stringify$1(v2) + i2 + stringify$1(v3) + i3 +
stringify$1(v4) + suffix :
NO_CHANGE;
}
/** Creates an interpolation binding with 6 expressions. */
function interpolation6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
var lView = getLView();
var bindingIndex = lView[BINDING_INDEX];
var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
lView[BINDING_INDEX] += 6;
return different ?
prefix + stringify$1(v0) + i0 + stringify$1(v1) + i1 + stringify$1(v2) + i2 + stringify$1(v3) + i3 +
stringify$1(v4) + i4 + stringify$1(v5) + suffix :
NO_CHANGE;
}
/** Creates an interpolation binding with 7 expressions. */
function interpolation7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
var lView = getLView();
var bindingIndex = lView[BINDING_INDEX];
var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
lView[BINDING_INDEX] += 7;
return different ?
prefix + stringify$1(v0) + i0 + stringify$1(v1) + i1 + stringify$1(v2) + i2 + stringify$1(v3) + i3 +
stringify$1(v4) + i4 + stringify$1(v5) + i5 + stringify$1(v6) + suffix :
NO_CHANGE;
}
/** Creates an interpolation binding with 8 expressions. */
function interpolation8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
var lView = getLView();
var bindingIndex = lView[BINDING_INDEX];
var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
lView[BINDING_INDEX] += 8;
return different ?
prefix + stringify$1(v0) + i0 + stringify$1(v1) + i1 + stringify$1(v2) + i2 + stringify$1(v3) + i3 +
stringify$1(v4) + i4 + stringify$1(v5) + i5 + stringify$1(v6) + i6 + stringify$1(v7) + suffix :
NO_CHANGE;
}
/** Store a value in the `data` at a given `index`. */
function store(index, value) {
var lView = getLView();
var tView = lView[TVIEW];
// We don't store any static data for local variables, so the first time
// we see the template, we should store as null to avoid a sparse array
var adjustedIndex = index + HEADER_OFFSET;
if (adjustedIndex >= tView.data.length) {
tView.data[adjustedIndex] = null;
}
lView[adjustedIndex] = value;
}
/**
* Retrieves a local reference from the current contextViewData.
*
* If the reference to retrieve is in a parent view, this instruction is used in conjunction
* with a nextContext() call, which walks up the tree and updates the contextViewData instance.
*
* @param index The index of the local ref in contextViewData.
*/
function reference(index) {
var contextLView = getContextLView();
return loadInternal(contextLView, index);
}
function loadQueryList(queryListIdx) {
var lView = getLView();
ngDevMode &&
assertDefined(lView[CONTENT_QUERIES], 'Content QueryList array should be defined if reading a query.');
ngDevMode && assertDataInRange(lView[CONTENT_QUERIES], queryListIdx);
return lView[CONTENT_QUERIES][queryListIdx];
}
/** Retrieves a value from current `viewData`. */
function load(index) {
return loadInternal(getLView(), index);
}
function directiveInject(token, flags) {
if (flags === void 0) { flags = InjectFlags.Default; }
token = resolveForwardRef(token);
return getOrCreateInjectable(getPreviousOrParentTNode(), getLView(), token, flags);
}
/**
* Facade for the attribute injection from DI.
*/
function injectAttribute(attrNameToInject) {
return injectAttributeImpl(getPreviousOrParentTNode(), attrNameToInject);
}
/**
* Registers a QueryList, associated with a content query, for later refresh (part of a view
* refresh).
*/
function registerContentQuery(queryList, currentDirectiveIndex) {
var viewData = getLView();
var tView = viewData[TVIEW];
var savedContentQueriesLength = (viewData[CONTENT_QUERIES] || (viewData[CONTENT_QUERIES] = [])).push(queryList);
if (getFirstTemplatePass()) {
var tViewContentQueries = tView.contentQueries || (tView.contentQueries = []);
var lastSavedDirectiveIndex = tView.contentQueries.length ? tView.contentQueries[tView.contentQueries.length - 2] : -1;
if (currentDirectiveIndex !== lastSavedDirectiveIndex) {
tViewContentQueries.push(currentDirectiveIndex, savedContentQueriesLength - 1);
}
}
}
var CLEAN_PROMISE = _CLEAN_PROMISE;
function initializeTNodeInputs(tNode) {
// If tNode.inputs is undefined, a listener has created outputs, but inputs haven't
// yet been checked.
if (tNode) {
if (tNode.inputs === undefined) {
// mark inputs as checked
tNode.inputs = generatePropertyAliases(tNode, 0 /* Input */);
}
return tNode.inputs;
}
return null;
}
/**
* Returns the current OpaqueViewState instance.
*
* Used in conjunction with the restoreView() instruction to save a snapshot
* of the current view and restore it when listeners are invoked. This allows
* walking the declaration view tree in listeners to get vars from parent views.
*/
function getCurrentView() {
return getLView();
}
function getCleanup(view) {
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
return view[CLEANUP] || (view[CLEANUP] = []);
}
function getTViewCleanup(view) {
return view[TVIEW].cleanup || (view[TVIEW].cleanup = []);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Adds a player to an element, directive or component instance that will later be
* animated once change detection has passed.
*
* When a player is added to a reference it will stay active until `player.destroy()`
* is called. Once called then the player will be removed from the active players
* present on the associated ref instance.
*
* To get a list of all the active players on an element see [getPlayers].
*
* @param ref The element, directive or component that the player will be placed on.
* @param player The player that will be triggered to play once change detection has run.
*/
function addPlayer(ref, player) {
var context = getLContext(ref);
if (!context) {
ngDevMode && throwInvalidRefError();
return;
}
var element$$1 = context.native;
var lView = context.lView;
var playerContext = getOrCreatePlayerContext(element$$1, context);
var rootContext = getRootContext$1(lView);
addPlayerInternal(playerContext, rootContext, element$$1, player, 0, ref);
scheduleTick(rootContext, 2 /* FlushPlayers */);
}
/**
* Returns a list of all the active players present on the provided ref instance (which can
* be an instance of a directive, component or element).
*
* This function will only return players that have been added to the ref instance using
* `addPlayer` or any players that are active through any template styling bindings
* (`[style]`, `[style.prop]`, `[class]` and `[class.name]`).
*
* @publicApi
*/
function getPlayers(ref) {
var context = getLContext(ref);
if (!context) {
ngDevMode && throwInvalidRefError();
return [];
}
var stylingContext = getStylingContext(context.nodeIndex, context.lView);
var playerContext = stylingContext ? getPlayerContext(stylingContext) : null;
return playerContext ? getPlayersInternal(playerContext) : [];
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This file introduces series of globally accessible debug tools
* to allow for the Angular debugging story to function.
*
* To see this in action run the following command:
*
* bazel run --define=compile=aot
* //packages/core/test/bundling/todo:devserver
*
* Then load `localhost:5432` and start using the console tools.
*/
/**
* This value reflects the property on the window where the dev
* tools are patched (window.ng).
* */
var GLOBAL_PUBLISH_EXPANDO_KEY = 'ng';
/*
* Publishes a collection of default debug tools onto `window._ng_`.
*
* These functions are available globally when Angular is in development
* mode and are automatically stripped away from prod mode is on.
*/
var _published = false;
function publishDefaultGlobalUtils() {
if (!_published) {
_published = true;
publishGlobalUtil('getComponent', getComponent);
publishGlobalUtil('getContext', getContext);
publishGlobalUtil('getListeners', getListeners);
publishGlobalUtil('getViewComponent', getViewComponent);
publishGlobalUtil('getHostElement', getHostElement);
publishGlobalUtil('getInjector', getInjector);
publishGlobalUtil('getRootComponents', getRootComponents);
publishGlobalUtil('getDirectives', getDirectives);
publishGlobalUtil('getPlayers', getPlayers);
publishGlobalUtil('markDirty', markDirty);
}
}
/**
* Publishes the given function to `window.ngDevMode` so that it can be
* used from the browser console when an application is not in production.
*/
function publishGlobalUtil(name, fn) {
var w = _global;
ngDevMode && assertDefined(fn, 'function not defined');
if (w) {
var container = w[GLOBAL_PUBLISH_EXPANDO_KEY];
if (!container) {
container = w[GLOBAL_PUBLISH_EXPANDO_KEY] = {};
}
container[name] = fn;
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Bootstraps a Component into an existing host element and returns an instance
* of the component.
*
* Use this function to bootstrap a component into the DOM tree. Each invocation
* of this function will create a separate tree of components, injectors and
* change detection cycles and lifetimes. To dynamically insert a new component
* into an existing tree such that it shares the same injection, change detection
* and object lifetime, use {@link ViewContainer#createComponent}.
*
* @param componentType Component to bootstrap
* @param options Optional parameters which control bootstrapping
*/
function renderComponent(componentType /* Type as workaround for: Microsoft/TypeScript/issues/4881 */, opts) {
if (opts === void 0) { opts = {}; }
ngDevMode && publishDefaultGlobalUtils();
ngDevMode && assertComponentType(componentType);
var rendererFactory = opts.rendererFactory || domRendererFactory3;
var sanitizer = opts.sanitizer || null;
var componentDef = getComponentDef(componentType);
if (componentDef.type != componentType)
componentDef.type = componentType;
// The first index of the first selector is the tag name.
var componentTag = componentDef.selectors[0][0];
var hostRNode = locateHostElement(rendererFactory, opts.host || componentTag);
var rootFlags = componentDef.onPush ? 8 /* Dirty */ | 128 /* IsRoot */ :
4 /* CheckAlways */ | 128 /* IsRoot */;
var rootContext = createRootContext(opts.scheduler, opts.playerHandler);
var renderer = rendererFactory.createRenderer(hostRNode, componentDef);
var rootView = createLView(null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, rendererFactory, renderer, undefined, opts.injector || null);
var oldView = enterView(rootView, null);
var component;
try {
if (rendererFactory.begin)
rendererFactory.begin();
var componentView = createRootComponentView(hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
component = createRootComponent(componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
refreshDescendantViews(rootView); // creation mode pass
rootView[FLAGS] &= ~1 /* CreationMode */;
refreshDescendantViews(rootView); // update mode pass
}
finally {
leaveView(oldView);
if (rendererFactory.end)
rendererFactory.end();
}
return component;
}
/**
* Creates the root component view and the root component node.
*
* @param rNode Render host element.
* @param def ComponentDef
* @param rootView The parent view where the host node is stored
* @param renderer The current renderer
* @param sanitizer The sanitizer, if provided
*
* @returns Component view created
*/
function createRootComponentView(rNode, def, rootView, rendererFactory, renderer, sanitizer) {
resetComponentState();
var tView = rootView[TVIEW];
var componentView = createLView(rootView, getOrCreateTView(def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery), null, def.onPush ? 8 /* Dirty */ : 4 /* CheckAlways */, rendererFactory, renderer, sanitizer);
var tNode = createNodeAtIndex(0, 3 /* Element */, rNode, null, null);
if (tView.firstTemplatePass) {
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), rootView, def.type);
tNode.flags = 1 /* isComponent */;
initNodeFlags(tNode, rootView.length, 1);
queueComponentIndexForCheck(tNode);
}
// Store component view at node index, with node as the HOST
componentView[HOST] = rootView[HEADER_OFFSET];
componentView[HOST_NODE] = tNode;
return rootView[HEADER_OFFSET] = componentView;
}
/**
* Creates a root component and sets it up with features and host bindings. Shared by
* renderComponent() and ViewContainerRef.createComponent().
*/
function createRootComponent(componentView, componentDef, rootView, rootContext, hostFeatures) {
var tView = rootView[TVIEW];
// Create directive instance with factory() and store at next index in viewData
var component = instantiateRootComponent(tView, rootView, componentDef);
rootContext.components.push(component);
componentView[CONTEXT] = component;
hostFeatures && hostFeatures.forEach(function (feature) { return feature(component, componentDef); });
if (tView.firstTemplatePass && componentDef.hostBindings) {
var rootTNode = getPreviousOrParentTNode();
setCurrentDirectiveDef(componentDef);
componentDef.hostBindings(1 /* Create */, component, rootTNode.index - HEADER_OFFSET);
setCurrentDirectiveDef(null);
}
return component;
}
function createRootContext(scheduler, playerHandler) {
return {
components: [],
scheduler: scheduler || defaultScheduler,
clean: CLEAN_PROMISE,
playerHandler: playerHandler || null,
flags: 0 /* Empty */
};
}
/**
* Used to enable lifecycle hooks on the root component.
*
* Include this feature when calling `renderComponent` if the root component
* you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
* be called properly.
*
* Example:
*
* ```
* renderComponent(AppComponent, {features: [RootLifecycleHooks]});
* ```
*/
function LifecycleHooksFeature(component, def) {
var rootTView = readPatchedLView(component)[TVIEW];
var dirIndex = rootTView.data.length - 1;
queueInitHooks(dirIndex, def.onInit, def.doCheck, rootTView);
// TODO(misko): replace `as TNode` with createTNode call. (needs refactoring to lose dep on
// LNode).
queueLifecycleHooks(rootTView, { directiveStart: dirIndex, directiveEnd: dirIndex + 1 });
}
/**
* Retrieve the root context for any component by walking the parent `LView` until
* reaching the root `LView`.
*
* @param component any component
*/
function getRootContext$2(component) {
var rootContext = getRootView(component)[CONTEXT];
ngDevMode && assertDefined(rootContext, 'rootContext');
return rootContext;
}
/**
* Wait on component until it is rendered.
*
* This function returns a `Promise` which is resolved when the component's
* change detection is executed. This is determined by finding the scheduler
* associated with the `component`'s render tree and waiting until the scheduler
* flushes. If nothing is scheduled, the function returns a resolved promise.
*
* Example:
* ```
* await whenRendered(myComponent);
* ```
*
* @param component Component to wait upon
* @returns Promise which resolves when the component is rendered.
*/
function whenRendered(component) {
return getRootContext$2(component).clean;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Determines if a definition is a {@link ComponentDef} or a {@link DirectiveDef}
* @param definition The definition to examine
*/
function isComponentDef$1(definition) {
var def = definition;
return typeof def.template === 'function';
}
function getSuperType(type) {
return Object.getPrototypeOf(type.prototype).constructor;
}
/**
* Merges the definition from a super class to a sub class.
* @param definition The definition that is a SubClass of another directive of component
*/
function InheritDefinitionFeature(definition) {
var superType = getSuperType(definition.type);
var _loop_1 = function () {
var e_1, _a;
var superDef = undefined;
if (isComponentDef$1(definition)) {
// Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
superDef = superType.ngComponentDef || superType.ngDirectiveDef;
}
else {
if (superType.ngComponentDef) {
throw new Error('Directives cannot inherit Components');
}
// Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
superDef = superType.ngDirectiveDef;
}
var baseDef = superType.ngBaseDef;
// Some fields in the definition may be empty, if there were no values to put in them that
// would've justified object creation. Unwrap them if necessary.
if (baseDef || superDef) {
var writeableDef = definition;
writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
}
if (baseDef) {
// Merge inputs and outputs
fillProperties(definition.inputs, baseDef.inputs);
fillProperties(definition.declaredInputs, baseDef.declaredInputs);
fillProperties(definition.outputs, baseDef.outputs);
}
if (superDef) {
// Merge hostBindings
var prevHostBindings_1 = definition.hostBindings;
var superHostBindings_1 = superDef.hostBindings;
if (superHostBindings_1) {
if (prevHostBindings_1) {
definition.hostBindings = function (rf, ctx, elementIndex) {
superHostBindings_1(rf, ctx, elementIndex);
prevHostBindings_1(rf, ctx, elementIndex);
};
}
else {
definition.hostBindings = superHostBindings_1;
}
}
// Merge View Queries
if (isComponentDef$1(definition) && isComponentDef$1(superDef)) {
var prevViewQuery_1 = definition.viewQuery;
var superViewQuery_1 = superDef.viewQuery;
if (superViewQuery_1) {
if (prevViewQuery_1) {
definition.viewQuery = function (rf, ctx) {
superViewQuery_1(rf, ctx);
prevViewQuery_1(rf, ctx);
};
}
else {
definition.viewQuery = superViewQuery_1;
}
}
}
// Merge Content Queries
var prevContentQueries_1 = definition.contentQueries;
var superContentQueries_1 = superDef.contentQueries;
if (superContentQueries_1) {
if (prevContentQueries_1) {
definition.contentQueries = function (dirIndex) {
superContentQueries_1(dirIndex);
prevContentQueries_1(dirIndex);
};
}
else {
definition.contentQueries = superContentQueries_1;
}
}
// Merge Content Queries Refresh
var prevContentQueriesRefresh_1 = definition.contentQueriesRefresh;
var superContentQueriesRefresh_1 = superDef.contentQueriesRefresh;
if (superContentQueriesRefresh_1) {
if (prevContentQueriesRefresh_1) {
definition.contentQueriesRefresh = function (directiveIndex, queryIndex) {
superContentQueriesRefresh_1(directiveIndex, queryIndex);
prevContentQueriesRefresh_1(directiveIndex, queryIndex);
};
}
else {
definition.contentQueriesRefresh = superContentQueriesRefresh_1;
}
}
// Merge inputs and outputs
fillProperties(definition.inputs, superDef.inputs);
fillProperties(definition.declaredInputs, superDef.declaredInputs);
fillProperties(definition.outputs, superDef.outputs);
// Inherit hooks
// Assume super class inheritance feature has already run.
definition.afterContentChecked =
definition.afterContentChecked || superDef.afterContentChecked;
definition.afterContentInit = definition.afterContentInit || superDef.afterContentInit;
definition.afterViewChecked = definition.afterViewChecked || superDef.afterViewChecked;
definition.afterViewInit = definition.afterViewInit || superDef.afterViewInit;
definition.doCheck = definition.doCheck || superDef.doCheck;
definition.onDestroy = definition.onDestroy || superDef.onDestroy;
definition.onInit = definition.onInit || superDef.onInit;
// Run parent features
var features = superDef.features;
if (features) {
try {
for (var features_1 = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__values"])(features), features_1_1 = features_1.next(); !features_1_1.done; features_1_1 = features_1.next()) {
var feature = features_1_1.value;
if (feature && feature.ngInherit) {
feature(definition);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (features_1_1 && !features_1_1.done && (_a = features_1.return)) _a.call(features_1);
}
finally { if (e_1) throw e_1.error; }
}
}
return "break";
}
else {
// Even if we don't have a definition, check the type for the hooks and use those if need be
var superPrototype = superType.prototype;
if (superPrototype) {
definition.afterContentChecked =
definition.afterContentChecked || superPrototype.afterContentChecked;
definition.afterContentInit =
definition.afterContentInit || superPrototype.afterContentInit;
definition.afterViewChecked =
definition.afterViewChecked || superPrototype.afterViewChecked;
definition.afterViewInit = definition.afterViewInit || superPrototype.afterViewInit;
definition.doCheck = definition.doCheck || superPrototype.doCheck;
definition.onDestroy = definition.onDestroy || superPrototype.onDestroy;
definition.onInit = definition.onInit || superPrototype.onInit;
}
}
superType = Object.getPrototypeOf(superType);
};
while (superType) {
var state_1 = _loop_1();
if (state_1 === "break")
break;
}
}
function maybeUnwrapEmpty(value) {
if (value === EMPTY_OBJ) {
return {};
}
else if (value === EMPTY_ARRAY) {
return [];
}
else {
return value;
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var PRIVATE_PREFIX = '__ngOnChanges_';
/**
* The NgOnChangesFeature decorates a component with support for the ngOnChanges
* lifecycle hook, so it should be included in any component that implements
* that hook.
*
* If the component or directive uses inheritance, the NgOnChangesFeature MUST
* be included as a feature AFTER {@link InheritDefinitionFeature}, otherwise
* inherited properties will not be propagated to the ngOnChanges lifecycle
* hook.
*
* Example usage:
*
* ```
* static ngComponentDef = defineComponent({
* ...
* inputs: {name: 'publicName'},
* features: [NgOnChangesFeature]
* });
* ```
*/
function NgOnChangesFeature(definition) {
var publicToDeclaredInputs = definition.declaredInputs;
var publicToMinifiedInputs = definition.inputs;
var proto = definition.type.prototype;
var _loop_1 = function (publicName) {
if (publicToDeclaredInputs.hasOwnProperty(publicName)) {
var minifiedKey = publicToMinifiedInputs[publicName];
var declaredKey_1 = publicToDeclaredInputs[publicName];
var privateMinKey_1 = PRIVATE_PREFIX + minifiedKey;
// Walk the prototype chain to see if we find a property descriptor
// That way we can honor setters and getters that were inherited.
var originalProperty = undefined;
var checkProto = proto;
while (!originalProperty && checkProto &&
Object.getPrototypeOf(checkProto) !== Object.getPrototypeOf(Object.prototype)) {
originalProperty = Object.getOwnPropertyDescriptor(checkProto, minifiedKey);
checkProto = Object.getPrototypeOf(checkProto);
}
var getter = originalProperty && originalProperty.get;
var setter_1 = originalProperty && originalProperty.set;
// create a getter and setter for property
Object.defineProperty(proto, minifiedKey, {
get: getter ||
(setter_1 ? undefined : function () { return this[privateMinKey_1]; }),
set: function (value) {
var simpleChanges = this[PRIVATE_PREFIX];
if (!simpleChanges) {
simpleChanges = {};
// Place where we will store SimpleChanges if there is a change
Object.defineProperty(this, PRIVATE_PREFIX, { value: simpleChanges, writable: true });
}
var isFirstChange = !this.hasOwnProperty(privateMinKey_1);
var currentChange = simpleChanges[declaredKey_1];
if (currentChange) {
currentChange.currentValue = value;
}
else {
simpleChanges[declaredKey_1] =
new SimpleChange(this[privateMinKey_1], value, isFirstChange);
}
if (isFirstChange) {
// Create a place where the actual value will be stored and make it non-enumerable
Object.defineProperty(this, privateMinKey_1, { value: value, writable: true });
}
else {
this[privateMinKey_1] = value;
}
if (setter_1)
setter_1.call(this, value);
},
// Make the property configurable in dev mode to allow overriding in tests
configurable: !!ngDevMode
});
}
};
for (var publicName in publicToDeclaredInputs) {
_loop_1(publicName);
}
// If an onInit hook is defined, it will need to wrap the ngOnChanges call
// so the call order is changes-init-check in creation mode. In subsequent
// change detection runs, only the check wrapper will be called.
if (definition.onInit != null) {
definition.onInit = onChangesWrapper(definition.onInit);
}
definition.doCheck = onChangesWrapper(definition.doCheck);
}
// This option ensures that the ngOnChanges lifecycle hook will be inherited
// from superclasses (in InheritDefinitionFeature).
NgOnChangesFeature.ngInherit = true;
function onChangesWrapper(delegateHook) {
return function () {
var simpleChanges = this[PRIVATE_PREFIX];
if (simpleChanges != null) {
this.ngOnChanges(simpleChanges);
this[PRIVATE_PREFIX] = null;
}
if (delegateHook)
delegateHook.apply(this);
};
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function noop() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
// Do nothing.
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var SOURCE = '__source';
var _THROW_IF_NOT_FOUND = new Object();
var THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
/**
* An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
*
* Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
* project.
*
* @publicApi
*/
var INJECTOR$1 = new InjectionToken('INJECTOR');
var NullInjector = /** @class */ (function () {
function NullInjector() {
}
NullInjector.prototype.get = function (token, notFoundValue) {
if (notFoundValue === void 0) { notFoundValue = _THROW_IF_NOT_FOUND; }
if (notFoundValue === _THROW_IF_NOT_FOUND) {
// Intentionally left behind: With dev tools open the debugger will stop here. There is no
// reason why correctly written application should cause this exception.
// TODO(misko): uncomment the next line once `ngDevMode` works with closure.
// if(ngDevMode) debugger;
throw new Error("NullInjectorError: No provider for " + stringify(token) + "!");
}
return notFoundValue;
};
return NullInjector;
}());
/**
* Concrete injectors implement this interface.
*
* For more details, see the ["Dependency Injection Guide"](guide/dependency-injection).
*
* @usageNotes
* ### Example
*
* {@example core/di/ts/injector_spec.ts region='Injector'}
*
* `Injector` returns itself when given `Injector` as a token:
*
* {@example core/di/ts/injector_spec.ts region='injectInjector'}
*
* @publicApi
*/
var Injector = /** @class */ (function () {
function Injector() {
}
/**
* Create a new Injector which is configure using `StaticProvider`s.
*
* @usageNotes
* ### Example
*
* {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
*/
Injector.create = function (options, parent) {
if (Array.isArray(options)) {
return new StaticInjector(options, parent);
}
else {
return new StaticInjector(options.providers, options.parent, options.name || null);
}
};
Injector.THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
Injector.NULL = new NullInjector();
/** @nocollapse */
Injector.ngInjectableDef = defineInjectable({
providedIn: 'any',
factory: function () { return inject(INJECTOR$1); },
});
/** @internal */
Injector.__NG_ELEMENT_ID__ = function () { return SWITCH_INJECTOR_FACTORY(); };
return Injector;
}());
var SWITCH_INJECTOR_FACTORY__POST_R3__ = function () {
return injectInjector();
};
var SWITCH_INJECTOR_FACTORY__PRE_R3__ = noop;
var SWITCH_INJECTOR_FACTORY = SWITCH_INJECTOR_FACTORY__PRE_R3__;
var IDENT = function (value) {
return value;
};
var EMPTY = [];
var CIRCULAR = IDENT;
var MULTI_PROVIDER_FN = function () {
return Array.prototype.slice.call(arguments);
};
var USE_VALUE = getClosureSafeProperty({ provide: String, useValue: getClosureSafeProperty });
var NG_TOKEN_PATH = 'ngTokenPath';
var NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
var NULL_INJECTOR$1 = Injector.NULL;
var NEW_LINE = /\n/gm;
var NO_NEW_LINE = 'ɵ';
var StaticInjector = /** @class */ (function () {
function StaticInjector(providers, parent, source) {
if (parent === void 0) { parent = NULL_INJECTOR$1; }
if (source === void 0) { source = null; }
this.parent = parent;
this.source = source;
var records = this._records = new Map();
records.set(Injector, { token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false });
records.set(INJECTOR$1, { token: INJECTOR$1, fn: IDENT, deps: EMPTY, value: this, useNew: false });
recursivelyProcessProviders(records, providers);
}
StaticInjector.prototype.get = function (token, notFoundValue, flags) {
if (flags === void 0) { flags = InjectFlags.Default; }
var record = this._records.get(token);
try {
return tryResolveToken(token, record, this._records, this.parent, notFoundValue, flags);
}
catch (e) {
var tokenPath = e[NG_TEMP_TOKEN_PATH];
if (token[SOURCE]) {
tokenPath.unshift(token[SOURCE]);
}
e.message = formatError('\n' + e.message, tokenPath, this.source);
e[NG_TOKEN_PATH] = tokenPath;
e[NG_TEMP_TOKEN_PATH] = null;
throw e;
}
};
StaticInjector.prototype.toString = function () {
var tokens = [], records = this._records;
records.forEach(function (v, token) { return tokens.push(stringify(token)); });
return "StaticInjector[" + tokens.join(', ') + "]";
};
return StaticInjector;
}());
function resolveProvider(provider) {
var deps = computeDeps(provider);
var fn = IDENT;
var value = EMPTY;
var useNew = false;
var provide = resolveForwardRef(provider.provide);
if (USE_VALUE in provider) {
// We need to use USE_VALUE in provider since provider.useValue could be defined as undefined.
value = provider.useValue;
}
else if (provider.useFactory) {
fn = provider.useFactory;
}
else if (provider.useExisting) ;
else if (provider.useClass) {
useNew = true;
fn = resolveForwardRef(provider.useClass);
}
else if (typeof provide == 'function') {
useNew = true;
fn = provide;
}
else {
throw staticError('StaticProvider does not have [useValue|useFactory|useExisting|useClass] or [provide] is not newable', provider);
}
return { deps: deps, fn: fn, useNew: useNew, value: value };
}
function multiProviderMixError(token) {
return staticError('Cannot mix multi providers and regular providers', token);
}
function recursivelyProcessProviders(records, provider) {
if (provider) {
provider = resolveForwardRef(provider);
if (provider instanceof Array) {
// if we have an array recurse into the array
for (var i = 0; i < provider.length; i++) {
recursivelyProcessProviders(records, provider[i]);
}
}
else if (typeof provider === 'function') {
// Functions were supported in ReflectiveInjector, but are not here. For safety give useful
// error messages
throw staticError('Function/Class not supported', provider);
}
else if (provider && typeof provider === 'object' && provider.provide) {
// At this point we have what looks like a provider: {provide: ?, ....}
var token = resolveForwardRef(provider.provide);
var resolvedProvider = resolveProvider(provider);
if (provider.multi === true) {
// This is a multi provider.
var multiProvider = records.get(token);
if (multiProvider) {
if (multiProvider.fn !== MULTI_PROVIDER_FN) {
throw multiProviderMixError(token);
}
}
else {
// Create a placeholder factory which will look up the constituents of the multi provider.
records.set(token, multiProvider = {
token: provider.provide,
deps: [],
useNew: false,
fn: MULTI_PROVIDER_FN,
value: EMPTY
});
}
// Treat the provider as the token.
token = provider;
multiProvider.deps.push({ token: token, options: 6 /* Default */ });
}
var record = records.get(token);
if (record && record.fn == MULTI_PROVIDER_FN) {
throw multiProviderMixError(token);
}
records.set(token, resolvedProvider);
}
else {
throw staticError('Unexpected provider', provider);
}
}
}
function tryResolveToken(token, record, records, parent, notFoundValue, flags) {
try {
return resolveToken(token, record, records, parent, notFoundValue, flags);
}
catch (e) {
// ensure that 'e' is of type Error.
if (!(e instanceof Error)) {
e = new Error(e);
}
var path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
path.unshift(token);
if (record && record.value == CIRCULAR) {
// Reset the Circular flag.
record.value = EMPTY;
}
throw e;
}
}
function resolveToken(token, record, records, parent, notFoundValue, flags) {
var _a;
var value;
if (record && !(flags & InjectFlags.SkipSelf)) {
// If we don't have a record, this implies that we don't own the provider hence don't know how
// to resolve it.
value = record.value;
if (value == CIRCULAR) {
throw Error(NO_NEW_LINE + 'Circular dependency');
}
else if (value === EMPTY) {
record.value = CIRCULAR;
var obj = undefined;
var useNew = record.useNew;
var fn = record.fn;
var depRecords = record.deps;
var deps = EMPTY;
if (depRecords.length) {
deps = [];
for (var i = 0; i < depRecords.length; i++) {
var depRecord = depRecords[i];
var options = depRecord.options;
var childRecord = options & 2 /* CheckSelf */ ? records.get(depRecord.token) : undefined;
deps.push(tryResolveToken(
// Current Token to resolve
depRecord.token,
// A record which describes how to resolve the token.
// If undefined, this means we don't have such a record
childRecord,
// Other records we know about.
records,
// If we don't know how to resolve dependency and we should not check parent for it,
// than pass in Null injector.
!childRecord && !(options & 4 /* CheckParent */) ? NULL_INJECTOR$1 : parent, options & 1 /* Optional */ ? null : Injector.THROW_IF_NOT_FOUND, InjectFlags.Default));
}
}
record.value = value = useNew ? new ((_a = fn).bind.apply(_a, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], deps)))() : fn.apply(obj, deps);
}
}
else if (!(flags & InjectFlags.Self)) {
value = parent.get(token, notFoundValue, InjectFlags.Default);
}
return value;
}
function computeDeps(provider) {
var deps = EMPTY;
var providerDeps = provider.deps;
if (providerDeps && providerDeps.length) {
deps = [];
for (var i = 0; i < providerDeps.length; i++) {
var options = 6 /* Default */;
var token = resolveForwardRef(providerDeps[i]);
if (token instanceof Array) {
for (var j = 0, annotations = token; j < annotations.length; j++) {
var annotation = annotations[j];
if (annotation instanceof Optional || annotation == Optional) {
options = options | 1 /* Optional */;
}
else if (annotation instanceof SkipSelf || annotation == SkipSelf) {
options = options & ~2 /* CheckSelf */;
}
else if (annotation instanceof Self || annotation == Self) {
options = options & ~4 /* CheckParent */;
}
else if (annotation instanceof Inject) {
token = annotation.token;
}
else {
token = resolveForwardRef(annotation);
}
}
}
deps.push({ token: token, options: options });
}
}
else if (provider.useExisting) {
var token = resolveForwardRef(provider.useExisting);
deps = [{ token: token, options: 6 /* Default */ }];
}
else if (!providerDeps && !(USE_VALUE in provider)) {
// useValue & useExisting are the only ones which are exempt from deps all others need it.
throw staticError('\'deps\' required', provider);
}
return deps;
}
function formatError(text, obj, source) {
if (source === void 0) { source = null; }
text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.substr(2) : text;
var context = stringify(obj);
if (obj instanceof Array) {
context = obj.map(stringify).join(' -> ');
}
else if (typeof obj === 'object') {
var parts = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var value = obj[key];
parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
}
}
context = "{" + parts.join(', ') + "}";
}
return "StaticInjectorError" + (source ? '(' + source + ')' : '') + "[" + context + "]: " + text.replace(NEW_LINE, '\n ');
}
function staticError(text, obj) {
return new Error(formatError(text, obj));
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* An internal token whose presence in an injector indicates that the injector should treat itself
* as a root scoped injector when processing requests for unknown tokens which may indicate
* they are provided in the root scope.
*/
var APP_ROOT = new InjectionToken('The presence of this token marks an injector as being the root injector.');
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Marker which indicates that a value has not yet been created from the factory function.
*/
var NOT_YET = {};
/**
* Marker which indicates that the factory function for a token is in the process of being called.
*
* If the injector is asked to inject a token with its value set to CIRCULAR, that indicates
* injection of a dependency has recursively attempted to inject the original token, and there is
* a circular dependency among the providers.
*/
var CIRCULAR$1 = {};
var EMPTY_ARRAY$1 = [];
/**
* A lazily initialized NullInjector.
*/
var NULL_INJECTOR$2 = undefined;
function getNullInjector() {
if (NULL_INJECTOR$2 === undefined) {
NULL_INJECTOR$2 = new NullInjector();
}
return NULL_INJECTOR$2;
}
/**
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
*
* @publicApi
*/
function createInjector(defType, parent, additionalProviders) {
if (parent === void 0) { parent = null; }
if (additionalProviders === void 0) { additionalProviders = null; }
parent = parent || getNullInjector();
return new R3Injector(defType, additionalProviders, parent);
}
var R3Injector = /** @class */ (function () {
function R3Injector(def, additionalProviders, parent) {
var _this = this;
this.parent = parent;
/**
* Map of tokens to records which contain the instances of those tokens.
*/
this.records = new Map();
/**
* The transitive set of `InjectorType`s which define this injector.
*/
this.injectorDefTypes = new Set();
/**
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
*/
this.onDestroy = new Set();
/**
* Flag indicating that this injector was previously destroyed.
*/
this.destroyed = false;
// Start off by creating Records for every provider declared in every InjectorType
// included transitively in `def`.
var dedupStack = [];
deepForEach([def], function (injectorDef) { return _this.processInjectorType(injectorDef, [], dedupStack); });
additionalProviders && deepForEach(additionalProviders, function (provider) { return _this.processProvider(provider, def, additionalProviders); });
// Make sure the INJECTOR token provides this injector.
this.records.set(INJECTOR$1, makeRecord(undefined, this));
// Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide
// any injectable scoped to APP_ROOT_SCOPE.
this.isRootInjector = this.records.has(APP_ROOT);
// Eagerly instantiate the InjectorType classes themselves.
this.injectorDefTypes.forEach(function (defType) { return _this.get(defType); });
}
/**
* Destroy the injector and release references to every instance or provider associated with it.
*
* Also calls the `OnDestroy` lifecycle hooks of every instance that was created for which a
* hook was found.
*/
R3Injector.prototype.destroy = function () {
this.assertNotDestroyed();
// Set destroyed = true first, in case lifecycle hooks re-enter destroy().
this.destroyed = true;
try {
// Call all the lifecycle hooks.
this.onDestroy.forEach(function (service) { return service.ngOnDestroy(); });
}
finally {
// Release all references.
this.records.clear();
this.onDestroy.clear();
this.injectorDefTypes.clear();
}
};
R3Injector.prototype.get = function (token, notFoundValue, flags) {
if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
if (flags === void 0) { flags = InjectFlags.Default; }
this.assertNotDestroyed();
// Set the injection context.
var previousInjector = setCurrentInjector(this);
try {
// Check for the SkipSelf flag.
if (!(flags & InjectFlags.SkipSelf)) {
// SkipSelf isn't set, check if the record belongs to this injector.
var record = this.records.get(token);
if (record === undefined) {
// No record, but maybe the token is scoped to this injector. Look for an ngInjectableDef
// with a scope matching this injector.
var def = couldBeInjectableType(token) && getInjectableDef(token);
if (def && this.injectableDefInScope(def)) {
// Found an ngInjectableDef and it's scoped to this injector. Pretend as if it was here
// all along.
record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
this.records.set(token, record);
}
}
// If a record was found, get the instance for it and return it.
if (record !== undefined) {
return this.hydrate(token, record);
}
}
// Select the next injector based on the Self flag - if self is set, the next injector is
// the NullInjector, otherwise it's the parent.
var nextInjector = !(flags & InjectFlags.Self) ? this.parent : getNullInjector();
return nextInjector.get(token, notFoundValue);
}
finally {
// Lastly, clean up the state by restoring the previous injector.
setCurrentInjector(previousInjector);
}
};
R3Injector.prototype.assertNotDestroyed = function () {
if (this.destroyed) {
throw new Error('Injector has already been destroyed.');
}
};
/**
* Add an `InjectorType` or `InjectorDefTypeWithProviders` and all of its transitive providers
* to this injector.
*/
R3Injector.prototype.processInjectorType = function (defOrWrappedDef, parents, dedupStack) {
var _this = this;
defOrWrappedDef = resolveForwardRef(defOrWrappedDef);
if (!defOrWrappedDef)
return;
// Either the defOrWrappedDef is an InjectorType (with ngInjectorDef) or an
// InjectorDefTypeWithProviders (aka ModuleWithProviders). Detecting either is a megamorphic
// read, so care is taken to only do the read once.
// First attempt to read the ngInjectorDef.
var def = getInjectorDef(defOrWrappedDef);
// If that's not present, then attempt to read ngModule from the InjectorDefTypeWithProviders.
var ngModule = (def == null) && defOrWrappedDef.ngModule || undefined;
// Determine the InjectorType. In the case where `defOrWrappedDef` is an `InjectorType`,
// then this is easy. In the case of an InjectorDefTypeWithProviders, then the definition type
// is the `ngModule`.
var defType = (ngModule === undefined) ? defOrWrappedDef : ngModule;
// Check for circular dependencies.
if (ngDevMode && parents.indexOf(defType) !== -1) {
var defName = stringify(defType);
throw new Error("Circular dependency in DI detected for type " + defName + ". Dependency path: " + parents.map(function (defType) { return stringify(defType); }).join(' > ') + " > " + defName + ".");
}
// Check for multiple imports of the same module
var isDuplicate = dedupStack.indexOf(defType) !== -1;
// If defOrWrappedType was an InjectorDefTypeWithProviders, then .providers may hold some
// extra providers.
var providers = (ngModule !== undefined) && defOrWrappedDef.providers ||
EMPTY_ARRAY$1;
// Finally, if defOrWrappedType was an `InjectorDefTypeWithProviders`, then the actual
// `InjectorDef` is on its `ngModule`.
if (ngModule !== undefined) {
def = getInjectorDef(ngModule);
}
// If no definition was found, it might be from exports. Remove it.
if (def == null) {
return;
}
// Track the InjectorType and add a provider for it.
this.injectorDefTypes.add(defType);
this.records.set(defType, makeRecord(def.factory, NOT_YET));
// Add providers in the same way that @NgModule resolution did:
// First, include providers from any imports.
if (def.imports != null && !isDuplicate) {
// Before processing defType's imports, add it to the set of parents. This way, if it ends
// up deeply importing itself, this can be detected.
ngDevMode && parents.push(defType);
// Add it to the set of dedups. This way we can detect multiple imports of the same module
dedupStack.push(defType);
try {
deepForEach(def.imports, function (imported) { return _this.processInjectorType(imported, parents, dedupStack); });
}
finally {
// Remove it from the parents set when finished.
ngDevMode && parents.pop();
}
}
// Next, include providers listed on the definition itself.
var defProviders = def.providers;
if (defProviders != null && !isDuplicate) {
var injectorType_1 = defOrWrappedDef;
deepForEach(defProviders, function (provider) { return _this.processProvider(provider, injectorType_1, defProviders); });
}
// Finally, include providers from an InjectorDefTypeWithProviders if there was one.
var ngModuleType = defOrWrappedDef.ngModule;
deepForEach(providers, function (provider) { return _this.processProvider(provider, ngModuleType, providers); });
};
/**
* Process a `SingleProvider` and add it.
*/
R3Injector.prototype.processProvider = function (provider, ngModuleType, providers) {
// Determine the token from the provider. Either it's its own token, or has a {provide: ...}
// property.
provider = resolveForwardRef(provider);
var token = isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide);
// Construct a `Record` for the provider.
var record = providerToRecord(provider, ngModuleType, providers);
if (!isTypeProvider(provider) && provider.multi === true) {
// If the provider indicates that it's a multi-provider, process it specially.
// First check whether it's been defined already.
var multiRecord_1 = this.records.get(token);
if (multiRecord_1) {
// It has. Throw a nice error if
if (multiRecord_1.multi === undefined) {
throw new Error("Mixed multi-provider for " + token + ".");
}
}
else {
multiRecord_1 = makeRecord(undefined, NOT_YET, true);
multiRecord_1.factory = function () { return injectArgs(multiRecord_1.multi); };
this.records.set(token, multiRecord_1);
}
token = provider;
multiRecord_1.multi.push(provider);
}
else {
var existing = this.records.get(token);
if (existing && existing.multi !== undefined) {
throw new Error("Mixed multi-provider for " + stringify(token));
}
}
this.records.set(token, record);
};
R3Injector.prototype.hydrate = function (token, record) {
if (record.value === CIRCULAR$1) {
throw new Error("Cannot instantiate cyclic dependency! " + stringify(token));
}
else if (record.value === NOT_YET) {
record.value = CIRCULAR$1;
record.value = record.factory();
}
if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {
this.onDestroy.add(record.value);
}
return record.value;
};
R3Injector.prototype.injectableDefInScope = function (def) {
if (!def.providedIn) {
return false;
}
else if (typeof def.providedIn === 'string') {
return def.providedIn === 'any' || (def.providedIn === 'root' && this.isRootInjector);
}
else {
return this.injectorDefTypes.has(def.providedIn);
}
};
return R3Injector;
}());
function injectableDefOrInjectorDefFactory(token) {
var injectableDef = getInjectableDef(token);
if (injectableDef === null) {
var injectorDef = getInjectorDef(token);
if (injectorDef !== null) {
return injectorDef.factory;
}
else if (token instanceof InjectionToken) {
throw new Error("Token " + stringify(token) + " is missing an ngInjectableDef definition.");
}
else if (token instanceof Function) {
var paramLength = token.length;
if (paramLength > 0) {
var args = new Array(paramLength).fill('?');
throw new Error("Can't resolve all parameters for " + stringify(token) + ": (" + args.join(', ') + ").");
}
return function () { return new token(); };
}
throw new Error('unreachable');
}
return injectableDef.factory;
}
function providerToRecord(provider, ngModuleType, providers) {
var factory = providerToFactory(provider, ngModuleType, providers);
if (isValueProvider(provider)) {
return makeRecord(undefined, provider.useValue);
}
else {
return makeRecord(factory, NOT_YET);
}
}
/**
* Converts a `SingleProvider` into a factory function.
*
* @param provider provider to convert to factory
*/
function providerToFactory(provider, ngModuleType, providers) {
var factory = undefined;
if (isTypeProvider(provider)) {
return injectableDefOrInjectorDefFactory(resolveForwardRef(provider));
}
else {
if (isValueProvider(provider)) {
factory = function () { return resolveForwardRef(provider.useValue); };
}
else if (isExistingProvider(provider)) {
factory = function () { return inject(resolveForwardRef(provider.useExisting)); };
}
else if (isFactoryProvider(provider)) {
factory = function () { return provider.useFactory.apply(provider, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(injectArgs(provider.deps || []))); };
}
else {
var classRef_1 = resolveForwardRef(provider &&
(provider.useClass || provider.provide));
if (!classRef_1) {
var ngModuleDetail = '';
if (ngModuleType && providers) {
var providerDetail = providers.map(function (v) { return v == provider ? '?' + provider + '?' : '...'; });
ngModuleDetail =
" - only instances of Provider and Type are allowed, got: [" + providerDetail.join(', ') + "]";
}
throw new Error("Invalid provider for the NgModule '" + stringify(ngModuleType) + "'" + ngModuleDetail);
}
if (hasDeps(provider)) {
factory = function () { return new ((classRef_1).bind.apply((classRef_1), Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], injectArgs(provider.deps))))(); };
}
else {
return injectableDefOrInjectorDefFactory(classRef_1);
}
}
}
return factory;
}
function makeRecord(factory, value, multi) {
if (multi === void 0) { multi = false; }
return {
factory: factory,
value: value,
multi: multi ? [] : undefined,
};
}
function deepForEach(input, fn) {
input.forEach(function (value) { return Array.isArray(value) ? deepForEach(value, fn) : fn(value); });
}
function isValueProvider(value) {
return value && typeof value == 'object' && USE_VALUE in value;
}
function isExistingProvider(value) {
return !!(value && value.useExisting);
}
function isFactoryProvider(value) {
return !!(value && value.useFactory);
}
function isTypeProvider(value) {
return typeof value === 'function';
}
function hasDeps(value) {
return !!value.deps;
}
function hasOnDestroy(value) {
return typeof value === 'object' && value != null && value.ngOnDestroy &&
typeof value.ngOnDestroy === 'function';
}
function couldBeInjectableType(value) {
return (typeof value === 'function') ||
(typeof value === 'object' && value instanceof InjectionToken);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Resolves the providers which are defined in the DirectiveDef.
*
* When inserting the tokens and the factories in their respective arrays, we can assume that
* this method is called first for the component (if any), and then for other directives on the same
* node.
* As a consequence,the providers are always processed in that order:
* 1) The view providers of the component
* 2) The providers of the component
* 3) The providers of the other directives
* This matches the structure of the injectables arrays of a view (for each node).
* So the tokens and the factories can be pushed at the end of the arrays, except
* in one case for multi providers.
*
* @param def the directive definition
* @param providers: Array of `providers`.
* @param viewProviders: Array of `viewProviders`.
*/
function providersResolver(def, providers, viewProviders) {
var lView = getLView();
var tView = lView[TVIEW];
if (tView.firstTemplatePass) {
var isComponent$$1 = isComponentDef(def);
// The list of view providers is processed first, and the flags are updated
resolveProvider$1(viewProviders, tView.data, tView.blueprint, isComponent$$1, true);
// Then, the list of providers is processed, and the flags are updated
resolveProvider$1(providers, tView.data, tView.blueprint, isComponent$$1, false);
}
}
/**
* Resolves a provider and publishes it to the DI system.
*/
function resolveProvider$1(provider, tInjectables, lInjectablesBlueprint, isComponent$$1, isViewProvider) {
provider = resolveForwardRef(provider);
if (Array.isArray(provider)) {
// Recursively call `resolveProvider`
// Recursion is OK in this case because this code will not be in hot-path once we implement
// cloning of the initial state.
for (var i = 0; i < provider.length; i++) {
resolveProvider$1(provider[i], tInjectables, lInjectablesBlueprint, isComponent$$1, isViewProvider);
}
}
else {
var lView = getLView();
var token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
var providerFactory = providerToFactory(provider);
var tNode = getPreviousOrParentTNode();
var beginIndex = tNode.providerIndexes & 65535 /* ProvidersStartIndexMask */;
var endIndex = tNode.directiveStart;
var cptViewProvidersCount = tNode.providerIndexes >> 16 /* CptViewProvidersCountShift */;
if (isTypeProvider(provider) || !provider.multi) {
// Single provider case: the factory is created and pushed immediately
var factory = new NodeInjectorFactory(providerFactory, isViewProvider, directiveInject);
var existingFactoryIndex = indexOf(token, tInjectables, isViewProvider ? beginIndex : beginIndex + cptViewProvidersCount, endIndex);
if (existingFactoryIndex == -1) {
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), lView, token);
tInjectables.push(token);
tNode.directiveStart++;
tNode.directiveEnd++;
if (isViewProvider) {
tNode.providerIndexes += 65536 /* CptViewProvidersCountShifter */;
}
lInjectablesBlueprint.push(factory);
lView.push(factory);
}
else {
lInjectablesBlueprint[existingFactoryIndex] = factory;
lView[existingFactoryIndex] = factory;
}
}
else {
// Multi provider case:
// We create a multi factory which is going to aggregate all the values.
// Since the output of such a factory depends on content or view injection,
// we create two of them, which are linked together.
//
// The first one (for view providers) is always in the first block of the injectables array,
// and the second one (for providers) is always in the second block.
// This is important because view providers have higher priority. When a multi token
// is being looked up, the view providers should be found first.
// Note that it is not possible to have a multi factory in the third block (directive block).
//
// The algorithm to process multi providers is as follows:
// 1) If the multi provider comes from the `viewProviders` of the component:
// a) If the special view providers factory doesn't exist, it is created and pushed.
// b) Else, the multi provider is added to the existing multi factory.
// 2) If the multi provider comes from the `providers` of the component or of another
// directive:
// a) If the multi factory doesn't exist, it is created and provider pushed into it.
// It is also linked to the multi factory for view providers, if it exists.
// b) Else, the multi provider is added to the existing multi factory.
var existingProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex + cptViewProvidersCount, endIndex);
var existingViewProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex, beginIndex + cptViewProvidersCount);
var doesProvidersFactoryExist = existingProvidersFactoryIndex >= 0 &&
lInjectablesBlueprint[existingProvidersFactoryIndex];
var doesViewProvidersFactoryExist = existingViewProvidersFactoryIndex >= 0 &&
lInjectablesBlueprint[existingViewProvidersFactoryIndex];
if (isViewProvider && !doesViewProvidersFactoryExist ||
!isViewProvider && !doesProvidersFactoryExist) {
// Cases 1.a and 2.a
diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), lView, token);
var factory = multiFactory(isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver, lInjectablesBlueprint.length, isViewProvider, isComponent$$1, providerFactory);
if (!isViewProvider && doesViewProvidersFactoryExist) {
lInjectablesBlueprint[existingViewProvidersFactoryIndex].providerFactory = factory;
}
tInjectables.push(token);
tNode.directiveStart++;
tNode.directiveEnd++;
if (isViewProvider) {
tNode.providerIndexes += 65536 /* CptViewProvidersCountShifter */;
}
lInjectablesBlueprint.push(factory);
lView.push(factory);
}
else {
// Cases 1.b and 2.b
multiFactoryAdd(lInjectablesBlueprint[isViewProvider ? existingViewProvidersFactoryIndex : existingProvidersFactoryIndex], providerFactory, !isViewProvider && isComponent$$1);
}
if (!isViewProvider && isComponent$$1 && doesViewProvidersFactoryExist) {
lInjectablesBlueprint[existingViewProvidersFactoryIndex].componentProviders++;
}
}
}
}
/**
* Add a factory in a multi factory.
*/
function multiFactoryAdd(multiFactory, factory, isComponentProvider) {
multiFactory.multi.push(factory);
if (isComponentProvider) {
multiFactory.componentProviders++;
}
}
/**
* Returns the index of item in the array, but only in the begin to end range.
*/
function indexOf(item, arr, begin, end) {
for (var i = begin; i < end; i++) {
if (arr[i] === item)
return i;
}
return -1;
}
/**
* Use this with `multi` `providers`.
*/
function multiProvidersFactoryResolver(_, tData, lData, tNode) {
return multiResolve(this.multi, []);
}
/**
* Use this with `multi` `viewProviders`.
*
* This factory knows how to concatenate itself with the existing `multi` `providers`.
*/
function multiViewProvidersFactoryResolver(_, tData, lData, tNode) {
var factories = this.multi;
var result;
if (this.providerFactory) {
var componentCount = this.providerFactory.componentProviders;
var multiProviders = getNodeInjectable(tData, lData, this.providerFactory.index, tNode);
// Copy the section of the array which contains `multi` `providers` from the component
result = multiProviders.slice(0, componentCount);
// Insert the `viewProvider` instances.
multiResolve(factories, result);
// Copy the section of the array which contains `multi` `providers` from other directives
for (var i = componentCount; i < multiProviders.length; i++) {
result.push(multiProviders[i]);
}
}
else {
result = [];
// Insert the `viewProvider` instances.
multiResolve(factories, result);
}
return result;
}
/**
* Maps an array of factories into an array of values.
*/
function multiResolve(factories, result) {
for (var i = 0; i < factories.length; i++) {
var factory = factories[i];
result.push(factory());
}
return result;
}
/**
* Creates a multi factory.
*/
function multiFactory(factoryFn, index, isViewProvider, isComponent$$1, f) {
var factory = new NodeInjectorFactory(factoryFn, isViewProvider, directiveInject);
factory.multi = [];
factory.index = index;
factory.componentProviders = 0;
multiFactoryAdd(factory, f, isComponent$$1 && !isViewProvider);
return factory;
}
/**
* This feature resolves the providers of a directive (or component),
* and publish them into the DI system, making it visible to others for injection.
*
* For example:
* class ComponentWithProviders {
* constructor(private greeter: GreeterDE) {}
*
* static ngComponentDef = defineComponent({
* type: ComponentWithProviders,
* selectors: [['component-with-providers']],
* factory: () => new ComponentWithProviders(directiveInject(GreeterDE as any)),
* consts: 1,
* vars: 1,
* template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
* if (fs & RenderFlags.Create) {
* text(0);
* }
* if (fs & RenderFlags.Update) {
* textBinding(0, bind(ctx.greeter.greet()));
* }
* },
* features: [ProvidersFeature([GreeterDE])]
* });
* }
*
* @param definition
*/
function ProvidersFeature(providers, viewProviders) {
if (viewProviders === void 0) { viewProviders = []; }
return function (definition) {
definition.providersResolver = function (def) {
return providersResolver(def, providers, viewProviders);
};
};
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Represents a component created by a `ComponentFactory`.
* Provides access to the component instance and related objects,
* and provides the means of destroying the instance.
*
* @publicApi
*/
var ComponentRef = /** @class */ (function () {
function ComponentRef() {
}
return ComponentRef;
}());
/**
* @publicApi
*/
var ComponentFactory = /** @class */ (function () {
function ComponentFactory() {
}
return ComponentFactory;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function noComponentFactoryError(component) {
var error = Error("No component factory found for " + stringify(component) + ". Did you add it to @NgModule.entryComponents?");
error[ERROR_COMPONENT] = component;
return error;
}
var ERROR_COMPONENT = 'ngComponent';
var _NullComponentFactoryResolver = /** @class */ (function () {
function _NullComponentFactoryResolver() {
}
_NullComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
throw noComponentFactoryError(component);
};
return _NullComponentFactoryResolver;
}());
/**
* @publicApi
*/
var ComponentFactoryResolver = /** @class */ (function () {
function ComponentFactoryResolver() {
}
ComponentFactoryResolver.NULL = new _NullComponentFactoryResolver();
return ComponentFactoryResolver;
}());
var CodegenComponentFactoryResolver = /** @class */ (function () {
function CodegenComponentFactoryResolver(factories, _parent, _ngModule) {
this._parent = _parent;
this._ngModule = _ngModule;
this._factories = new Map();
for (var i = 0; i < factories.length; i++) {
var factory = factories[i];
this._factories.set(factory.componentType, factory);
}
}
CodegenComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
var factory = this._factories.get(component);
if (!factory && this._parent) {
factory = this._parent.resolveComponentFactory(component);
}
if (!factory) {
throw noComponentFactoryError(component);
}
return new ComponentFactoryBoundToModule(factory, this._ngModule);
};
return CodegenComponentFactoryResolver;
}());
var ComponentFactoryBoundToModule = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(ComponentFactoryBoundToModule, _super);
function ComponentFactoryBoundToModule(factory, ngModule) {
var _this = _super.call(this) || this;
_this.factory = factory;
_this.ngModule = ngModule;
_this.selector = factory.selector;
_this.componentType = factory.componentType;
_this.ngContentSelectors = factory.ngContentSelectors;
_this.inputs = factory.inputs;
_this.outputs = factory.outputs;
return _this;
}
ComponentFactoryBoundToModule.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
return this.factory.create(injector, projectableNodes, rootSelectorOrNode, ngModule || this.ngModule);
};
return ComponentFactoryBoundToModule;
}(ComponentFactory));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Represents an instance of an NgModule created via a {@link NgModuleFactory}.
*
* `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
* NgModule Instance.
*
* @publicApi
*/
var NgModuleRef = /** @class */ (function () {
function NgModuleRef() {
}
return NgModuleRef;
}());
/**
* @publicApi
*/
var NgModuleFactory = /** @class */ (function () {
function NgModuleFactory() {
}
return NgModuleFactory;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var ViewRef = /** @class */ (function () {
function ViewRef(_lView, _context, _componentIndex) {
this._context = _context;
this._componentIndex = _componentIndex;
this._appRef = null;
this._viewContainerRef = null;
/**
* @internal
*/
this._tViewNode = null;
this._lView = _lView;
}
Object.defineProperty(ViewRef.prototype, "rootNodes", {
get: function () {
if (this._lView[HOST] == null) {
var tView = this._lView[HOST_NODE];
return collectNativeNodes(this._lView, tView, []);
}
return [];
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewRef.prototype, "context", {
get: function () { return this._context ? this._context : this._lookUpContext(); },
enumerable: true,
configurable: true
});
Object.defineProperty(ViewRef.prototype, "destroyed", {
get: function () {
return (this._lView[FLAGS] & 64 /* Destroyed */) === 64 /* Destroyed */;
},
enumerable: true,
configurable: true
});
ViewRef.prototype.destroy = function () {
if (this._appRef) {
this._appRef.detachView(this);
}
else if (this._viewContainerRef) {
var index = this._viewContainerRef.indexOf(this);
if (index > -1) {
this._viewContainerRef.detach(index);
}
this._viewContainerRef = null;
}
destroyLView(this._lView);
};
ViewRef.prototype.onDestroy = function (callback) { storeCleanupFn(this._lView, callback); };
/**
* Marks a view and all of its ancestors dirty.
*
* It also triggers change detection by calling `scheduleTick` internally, which coalesces
* multiple `markForCheck` calls to into one change detection run.
*
* This can be used to ensure an {@link ChangeDetectionStrategy#OnPush OnPush} component is
* checked when it needs to be re-rendered but the two normal triggers haven't marked it
* dirty (i.e. inputs haven't changed and events haven't fired in the view).
*
* <!-- TODO: Add a link to a chapter on OnPush components -->
*
* @usageNotes
* ### Example
*
* ```typescript
* @Component({
* selector: 'my-app',
* template: `Number of ticks: {{numberOfTicks}}`
* changeDetection: ChangeDetectionStrategy.OnPush,
* })
* class AppComponent {
* numberOfTicks = 0;
*
* constructor(private ref: ChangeDetectorRef) {
* setInterval(() => {
* this.numberOfTicks++;
* // the following is required, otherwise the view will not be updated
* this.ref.markForCheck();
* }, 1000);
* }
* }
* ```
*/
ViewRef.prototype.markForCheck = function () { markViewDirty(this._lView); };
/**
* Detaches the view from the change detection tree.
*
* Detached views will not be checked during change detection runs until they are
* re-attached, even if they are dirty. `detach` can be used in combination with
* {@link ChangeDetectorRef#detectChanges detectChanges} to implement local change
* detection checks.
*
* <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
* <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
*
* @usageNotes
* ### Example
*
* The following example defines a component with a large list of readonly data.
* Imagine the data changes constantly, many times per second. For performance reasons,
* we want to check and update the list every five seconds. We can do that by detaching
* the component's change detector and doing a local check every five seconds.
*
* ```typescript
* class DataProvider {
* // in a real application the returned data will be different every time
* get data() {
* return [1,2,3,4,5];
* }
* }
*
* @Component({
* selector: 'giant-list',
* template: `
* <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
* `,
* })
* class GiantList {
* constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {
* ref.detach();
* setInterval(() => {
* this.ref.detectChanges();
* }, 5000);
* }
* }
*
* @Component({
* selector: 'app',
* providers: [DataProvider],
* template: `
* <giant-list><giant-list>
* `,
* })
* class App {
* }
* ```
*/
ViewRef.prototype.detach = function () { this._lView[FLAGS] &= ~16 /* Attached */; };
/**
* Re-attaches a view to the change detection tree.
*
* This can be used to re-attach views that were previously detached from the tree
* using {@link ChangeDetectorRef#detach detach}. Views are attached to the tree by default.
*
* <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
*
* @usageNotes
* ### Example
*
* The following example creates a component displaying `live` data. The component will detach
* its change detector from the main change detector tree when the component's live property
* is set to false.
*
* ```typescript
* class DataProvider {
* data = 1;
*
* constructor() {
* setInterval(() => {
* this.data = this.data * 2;
* }, 500);
* }
* }
*
* @Component({
* selector: 'live-data',
* inputs: ['live'],
* template: 'Data: {{dataProvider.data}}'
* })
* class LiveData {
* constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
*
* set live(value) {
* if (value) {
* this.ref.reattach();
* } else {
* this.ref.detach();
* }
* }
* }
*
* @Component({
* selector: 'my-app',
* providers: [DataProvider],
* template: `
* Live Update: <input type="checkbox" [(ngModel)]="live">
* <live-data [live]="live"><live-data>
* `,
* })
* class AppComponent {
* live = true;
* }
* ```
*/
ViewRef.prototype.reattach = function () { this._lView[FLAGS] |= 16 /* Attached */; };
/**
* Checks the view and its children.
*
* This can also be used in combination with {@link ChangeDetectorRef#detach detach} to implement
* local change detection checks.
*
* <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
* <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
*
* @usageNotes
* ### Example
*
* The following example defines a component with a large list of readonly data.
* Imagine, the data changes constantly, many times per second. For performance reasons,
* we want to check and update the list every five seconds.
*
* We can do that by detaching the component's change detector and doing a local change detection
* check every five seconds.
*
* See {@link ChangeDetectorRef#detach detach} for more information.
*/
ViewRef.prototype.detectChanges = function () { detectChangesInternal(this._lView, this.context); };
/**
* Checks the change detector and its children, and throws if any changes are detected.
*
* This is used in development mode to verify that running change detection doesn't
* introduce other changes.
*/
ViewRef.prototype.checkNoChanges = function () { checkNoChanges(this.context); };
ViewRef.prototype.attachToViewContainerRef = function (vcRef) {
if (this._appRef) {
throw new Error('This view is already attached directly to the ApplicationRef!');
}
this._viewContainerRef = vcRef;
};
ViewRef.prototype.detachFromAppRef = function () { this._appRef = null; };
ViewRef.prototype.attachToAppRef = function (appRef) {
if (this._viewContainerRef) {
throw new Error('This view is already attached to a ViewContainer!');
}
this._appRef = appRef;
};
ViewRef.prototype._lookUpContext = function () {
return this._context = this._lView[PARENT][this._componentIndex];
};
return ViewRef;
}());
/** @internal */
var RootViewRef = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(RootViewRef, _super);
function RootViewRef(_view) {
var _this = _super.call(this, _view, null, -1) || this;
_this._view = _view;
return _this;
}
RootViewRef.prototype.detectChanges = function () { detectChangesInRootView(this._view); };
RootViewRef.prototype.checkNoChanges = function () { checkNoChangesInRootView(this._view); };
Object.defineProperty(RootViewRef.prototype, "context", {
get: function () { return null; },
enumerable: true,
configurable: true
});
return RootViewRef;
}(ViewRef));
function collectNativeNodes(lView, parentTNode, result) {
var tNodeChild = parentTNode.child;
while (tNodeChild) {
result.push(getNativeByTNode(tNodeChild, lView));
if (tNodeChild.type === 4 /* ElementContainer */) {
collectNativeNodes(lView, tNodeChild, result);
}
tNodeChild = tNodeChild.next;
}
return result;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Creates an ElementRef from the most recent node.
*
* @returns The ElementRef instance to use
*/
function injectElementRef(ElementRefToken) {
return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getLView());
}
var R3ElementRef;
/**
* Creates an ElementRef given a node.
*
* @param ElementRefToken The ElementRef type
* @param tNode The node for which you'd like an ElementRef
* @param view The view to which the node belongs
* @returns The ElementRef instance to use
*/
function createElementRef(ElementRefToken, tNode, view) {
if (!R3ElementRef) {
// TODO: Fix class name, should be ElementRef, but there appears to be a rollup bug
R3ElementRef = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(ElementRef_, _super);
function ElementRef_() {
return _super !== null && _super.apply(this, arguments) || this;
}
return ElementRef_;
}(ElementRefToken));
}
return new R3ElementRef(getNativeByTNode(tNode, view));
}
var R3TemplateRef;
/**
* Creates a TemplateRef given a node.
*
* @returns The TemplateRef instance to use
*/
function injectTemplateRef(TemplateRefToken, ElementRefToken) {
return createTemplateRef(TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getLView());
}
/**
* Creates a TemplateRef and stores it on the injector.
*
* @param TemplateRefToken The TemplateRef type
* @param ElementRefToken The ElementRef type
* @param hostTNode The node that is requesting a TemplateRef
* @param hostView The view to which the node belongs
* @returns The TemplateRef instance to use
*/
function createTemplateRef(TemplateRefToken, ElementRefToken, hostTNode, hostView) {
if (!R3TemplateRef) {
// TODO: Fix class name, should be TemplateRef, but there appears to be a rollup bug
R3TemplateRef = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(TemplateRef_, _super);
function TemplateRef_(_declarationParentView, elementRef, _tView, _renderer, _queries, _injectorIndex) {
var _this = _super.call(this) || this;
_this._declarationParentView = _declarationParentView;
_this.elementRef = elementRef;
_this._tView = _tView;
_this._renderer = _renderer;
_this._queries = _queries;
_this._injectorIndex = _injectorIndex;
return _this;
}
TemplateRef_.prototype.createEmbeddedView = function (context, container$$1, hostTNode, hostView, index) {
var lView = createEmbeddedViewAndNode(this._tView, context, this._declarationParentView, this._renderer, this._queries, this._injectorIndex);
if (container$$1) {
insertView(lView, container$$1, hostView, index, hostTNode.index);
}
renderEmbeddedTemplate(lView, this._tView, context);
var viewRef = new ViewRef(lView, context, -1);
viewRef._tViewNode = lView[HOST_NODE];
return viewRef;
};
return TemplateRef_;
}(TemplateRefToken));
}
if (hostTNode.type === 0 /* Container */) {
var hostContainer = hostView[hostTNode.index];
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
return new R3TemplateRef(hostView, createElementRef(ElementRefToken, hostTNode, hostView), hostTNode.tViews, getLView()[RENDERER], hostContainer[QUERIES], hostTNode.injectorIndex);
}
else {
return null;
}
}
var R3ViewContainerRef;
/**
* Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
* already exists, retrieves the existing ViewContainerRef.
*
* @returns The ViewContainerRef instance to use
*/
function injectViewContainerRef(ViewContainerRefToken, ElementRefToken) {
var previousTNode = getPreviousOrParentTNode();
return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getLView());
}
/**
* Creates a ViewContainerRef and stores it on the injector.
*
* @param ViewContainerRefToken The ViewContainerRef type
* @param ElementRefToken The ElementRef type
* @param hostTNode The node that is requesting a ViewContainerRef
* @param hostView The view to which the node belongs
* @returns The ViewContainerRef instance to use
*/
function createContainerRef(ViewContainerRefToken, ElementRefToken, hostTNode, hostView) {
if (!R3ViewContainerRef) {
// TODO: Fix class name, should be ViewContainerRef, but there appears to be a rollup bug
R3ViewContainerRef = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(ViewContainerRef_, _super);
function ViewContainerRef_(_lContainer, _hostTNode, _hostView) {
var _this = _super.call(this) || this;
_this._lContainer = _lContainer;
_this._hostTNode = _hostTNode;
_this._hostView = _hostView;
_this._viewRefs = [];
return _this;
}
Object.defineProperty(ViewContainerRef_.prototype, "element", {
get: function () {
return createElementRef(ElementRefToken, this._hostTNode, this._hostView);
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewContainerRef_.prototype, "injector", {
get: function () { return new NodeInjector(this._hostTNode, this._hostView); },
enumerable: true,
configurable: true
});
Object.defineProperty(ViewContainerRef_.prototype, "parentInjector", {
/** @deprecated No replacement */
get: function () {
var parentLocation = getParentInjectorLocation(this._hostTNode, this._hostView);
var parentView = getParentInjectorView(parentLocation, this._hostView);
var parentTNode = getParentInjectorTNode(parentLocation, this._hostView, this._hostTNode);
return !hasParentInjector(parentLocation) || parentTNode == null ?
new NodeInjector(null, this._hostView) :
new NodeInjector(parentTNode, parentView);
},
enumerable: true,
configurable: true
});
ViewContainerRef_.prototype.clear = function () {
while (this._lContainer[VIEWS].length) {
this.remove(0);
}
};
ViewContainerRef_.prototype.get = function (index) { return this._viewRefs[index] || null; };
Object.defineProperty(ViewContainerRef_.prototype, "length", {
get: function () { return this._lContainer[VIEWS].length; },
enumerable: true,
configurable: true
});
ViewContainerRef_.prototype.createEmbeddedView = function (templateRef, context, index) {
var adjustedIdx = this._adjustIndex(index);
var viewRef = templateRef
.createEmbeddedView(context || {}, this._lContainer, this._hostTNode, this._hostView, adjustedIdx);
viewRef.attachToViewContainerRef(this);
this._viewRefs.splice(adjustedIdx, 0, viewRef);
return viewRef;
};
ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
var contextInjector = injector || this.parentInjector;
if (!ngModuleRef && componentFactory.ngModule == null && contextInjector) {
ngModuleRef = contextInjector.get(NgModuleRef, null);
}
var componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
this.insert(componentRef.hostView, index);
return componentRef;
};
ViewContainerRef_.prototype.insert = function (viewRef, index) {
if (viewRef.destroyed) {
throw new Error('Cannot insert a destroyed View in a ViewContainer!');
}
var lView = viewRef._lView;
var adjustedIdx = this._adjustIndex(index);
insertView(lView, this._lContainer, this._hostView, adjustedIdx, this._hostTNode.index);
var beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer[VIEWS], this._lContainer[NATIVE]);
addRemoveViewFromContainer(lView, true, beforeNode);
viewRef.attachToViewContainerRef(this);
this._viewRefs.splice(adjustedIdx, 0, viewRef);
return viewRef;
};
ViewContainerRef_.prototype.move = function (viewRef, newIndex) {
if (viewRef.destroyed) {
throw new Error('Cannot move a destroyed View in a ViewContainer!');
}
var index = this.indexOf(viewRef);
this.detach(index);
this.insert(viewRef, this._adjustIndex(newIndex));
return viewRef;
};
ViewContainerRef_.prototype.indexOf = function (viewRef) { return this._viewRefs.indexOf(viewRef); };
ViewContainerRef_.prototype.remove = function (index) {
var adjustedIdx = this._adjustIndex(index, -1);
removeView(this._lContainer, this._hostTNode, adjustedIdx);
this._viewRefs.splice(adjustedIdx, 1);
};
ViewContainerRef_.prototype.detach = function (index) {
var adjustedIdx = this._adjustIndex(index, -1);
var view = detachView(this._lContainer, adjustedIdx, !!this._hostTNode.detached);
var wasDetached = this._viewRefs.splice(adjustedIdx, 1)[0] != null;
return wasDetached ? new ViewRef(view, view[CONTEXT], view[CONTAINER_INDEX]) : null;
};
ViewContainerRef_.prototype._adjustIndex = function (index, shift) {
if (shift === void 0) { shift = 0; }
if (index == null) {
return this._lContainer[VIEWS].length + shift;
}
if (ngDevMode) {
assertGreaterThan(index, -1, 'index must be positive');
// +1 because it's legal to insert at the end.
assertLessThan(index, this._lContainer[VIEWS].length + 1 + shift, 'index');
}
return index;
};
return ViewContainerRef_;
}(ViewContainerRefToken));
}
ngDevMode && assertNodeOfPossibleTypes(hostTNode, 0 /* Container */, 3 /* Element */, 4 /* ElementContainer */);
var lContainer;
var slotValue = hostView[hostTNode.index];
if (isLContainer(slotValue)) {
// If the host is a container, we don't need to create a new LContainer
lContainer = slotValue;
lContainer[ACTIVE_INDEX] = -1;
}
else {
var commentNode = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
ngDevMode && ngDevMode.rendererCreateComment++;
// A container can be created on the root (topmost / bootstrapped) component and in this case we
// can't use LTree to insert container's marker node (both parent of a comment node and the
// commend node itself is located outside of elements hold by LTree). In this specific case we
// use low-level DOM manipulation to insert container's marker (comment) node.
if (isRootView(hostView)) {
var renderer = hostView[RENDERER];
var hostNative = getNativeByTNode(hostTNode, hostView);
var parentOfHostNative = nativeParentNode(renderer, hostNative);
nativeInsertBefore(renderer, parentOfHostNative, commentNode, nativeNextSibling(renderer, hostNative));
}
else {
appendChild(commentNode, hostTNode, hostView);
}
hostView[hostTNode.index] = lContainer =
createLContainer(slotValue, hostTNode, hostView, commentNode, true);
addToViewTree(hostView, hostTNode.index, lContainer);
}
return new R3ViewContainerRef(lContainer, hostTNode, hostView);
}
/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
function injectChangeDetectorRef() {
return createViewRef(getPreviousOrParentTNode(), getLView(), null);
}
/**
* Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
*
* @param hostTNode The node that is requesting a ChangeDetectorRef
* @param hostView The view to which the node belongs
* @param context The context for this change detector ref
* @returns The ChangeDetectorRef to use
*/
function createViewRef(hostTNode, hostView, context) {
if (isComponent(hostTNode)) {
var componentIndex = hostTNode.directiveStart;
var componentView = getComponentViewByIndex(hostTNode.index, hostView);
return new ViewRef(componentView, context, componentIndex);
}
else if (hostTNode.type === 3 /* Element */) {
var hostComponentView = findComponentView(hostView);
return new ViewRef(hostComponentView, hostComponentView[CONTEXT], -1);
}
return null;
}
function getOrCreateRenderer2(view) {
var renderer = view[RENDERER];
if (isProceduralRenderer(renderer)) {
return renderer;
}
else {
throw new Error('Cannot inject Renderer2 when the application uses Renderer3!');
}
}
/** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */
function injectRenderer2() {
return getOrCreateRenderer2(getLView());
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A wrapper around a native element inside of a View.
*
* An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
* element.
*
* @security Permitting direct access to the DOM can make your application more vulnerable to
* XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the
* [Security Guide](http://g.co/ng/security).
*
* @publicApi
*/
// Note: We don't expose things like `Injector`, `ViewContainer`, ... here,
// i.e. users have to ask for what they need. With that, we can build better analysis tools
// and could do better codegen in the future.
var ElementRef = /** @class */ (function () {
function ElementRef(nativeElement) {
this.nativeElement = nativeElement;
}
/** @internal */
ElementRef.__NG_ELEMENT_ID__ = function () { return SWITCH_ELEMENT_REF_FACTORY(ElementRef); };
return ElementRef;
}());
var SWITCH_ELEMENT_REF_FACTORY__POST_R3__ = injectElementRef;
var SWITCH_ELEMENT_REF_FACTORY__PRE_R3__ = noop;
var SWITCH_ELEMENT_REF_FACTORY = SWITCH_ELEMENT_REF_FACTORY__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @deprecated Use `RendererType2` (and `Renderer2`) instead.
* @publicApi
*/
var RenderComponentType = /** @class */ (function () {
function RenderComponentType(id, templateUrl, slotCount, encapsulation, styles, animations) {
this.id = id;
this.templateUrl = templateUrl;
this.slotCount = slotCount;
this.encapsulation = encapsulation;
this.styles = styles;
this.animations = animations;
}
return RenderComponentType;
}());
/**
* @deprecated Debug info is handled internally in the view engine now.
*/
var RenderDebugInfo = /** @class */ (function () {
function RenderDebugInfo() {
}
return RenderDebugInfo;
}());
/**
* @deprecated Use the `Renderer2` instead.
* @publicApi
*/
var Renderer = /** @class */ (function () {
function Renderer() {
}
return Renderer;
}());
var Renderer2Interceptor = new InjectionToken('Renderer2Interceptor');
/**
* Injectable service that provides a low-level interface for modifying the UI.
*
* Use this service to bypass Angular's templating and make custom UI changes that can't be
* expressed declaratively. For example if you need to set a property or an attribute whose name is
* not statically known, use {@link Renderer#setElementProperty setElementProperty} or
* {@link Renderer#setElementAttribute setElementAttribute} respectively.
*
* If you are implementing a custom renderer, you must implement this interface.
*
* The default Renderer implementation is `DomRenderer`. Also available is `WebWorkerRenderer`.
*
* @deprecated Use `RendererFactory2` instead.
* @publicApi
*/
var RootRenderer = /** @class */ (function () {
function RootRenderer() {
}
return RootRenderer;
}());
/**
* Creates and initializes a custom renderer that implements the `Renderer2` base class.
*
* @publicApi
*/
var RendererFactory2 = /** @class */ (function () {
function RendererFactory2() {
}
return RendererFactory2;
}());
/**
* Flags for renderer-specific style modifiers.
* @publicApi
*/
var RendererStyleFlags2;
(function (RendererStyleFlags2) {
/**
* Marks a style as important.
*/
RendererStyleFlags2[RendererStyleFlags2["Important"] = 1] = "Important";
/**
* Marks a style as using dash case naming (this-is-dash-case).
*/
RendererStyleFlags2[RendererStyleFlags2["DashCase"] = 2] = "DashCase";
})(RendererStyleFlags2 || (RendererStyleFlags2 = {}));
/**
* Extend this base class to implement custom rendering. By default, Angular
* renders a template into DOM. You can use custom rendering to intercept
* rendering calls, or to render to something other than DOM.
*
* Create your custom renderer using `RendererFactory2`.
*
* Use a custom renderer to bypass Angular's templating and
* make custom UI changes that can't be expressed declaratively.
* For example if you need to set a property or an attribute whose name is
* not statically known, use the `setProperty()` or
* `setAttribute()` method.
*
* @publicApi
*/
var Renderer2 = /** @class */ (function () {
function Renderer2() {
}
/** @internal */
Renderer2.__NG_ELEMENT_ID__ = function () { return SWITCH_RENDERER2_FACTORY(); };
return Renderer2;
}());
var SWITCH_RENDERER2_FACTORY__POST_R3__ = injectRenderer2;
var SWITCH_RENDERER2_FACTORY__PRE_R3__ = noop;
var SWITCH_RENDERER2_FACTORY = SWITCH_RENDERER2_FACTORY__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A SecurityContext marks a location that has dangerous security implications, e.g. a DOM property
* like `innerHTML` that could cause Cross Site Scripting (XSS) security bugs when improperly
* handled.
*
* See DomSanitizer for more details on security in Angular applications.
*
* @publicApi
*/
var SecurityContext;
(function (SecurityContext) {
SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
SecurityContext[SecurityContext["URL"] = 4] = "URL";
SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
})(SecurityContext || (SecurityContext = {}));
/**
* Sanitizer is used by the views to sanitize potentially dangerous values.
*
* @publicApi
*/
var Sanitizer = /** @class */ (function () {
function Sanitizer() {
}
return Sanitizer;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @description Represents the version of Angular
*
* @publicApi
*/
var Version = /** @class */ (function () {
function Version(full) {
this.full = full;
this.major = full.split('.')[0];
this.minor = full.split('.')[1];
this.patch = full.split('.').slice(2).join('.');
}
return Version;
}());
/**
* @publicApi
*/
var VERSION = new Version('7.2.2');
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var ComponentFactoryResolver$1 = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(ComponentFactoryResolver$$1, _super);
/**
* @param ngModule The NgModuleRef to which all resolved factories are bound.
*/
function ComponentFactoryResolver$$1(ngModule) {
var _this = _super.call(this) || this;
_this.ngModule = ngModule;
return _this;
}
ComponentFactoryResolver$$1.prototype.resolveComponentFactory = function (component) {
ngDevMode && assertComponentType(component);
var componentDef = getComponentDef(component);
return new ComponentFactory$1(componentDef, this.ngModule);
};
return ComponentFactoryResolver$$1;
}(ComponentFactoryResolver));
function toRefArray(map) {
var array = [];
for (var nonMinified in map) {
if (map.hasOwnProperty(nonMinified)) {
var minified = map[nonMinified];
array.push({ propName: minified, templateName: nonMinified });
}
}
return array;
}
/**
* Default {@link RootContext} for all components rendered with {@link renderComponent}.
*/
var ROOT_CONTEXT = new InjectionToken('ROOT_CONTEXT_TOKEN', { providedIn: 'root', factory: function () { return createRootContext(inject(SCHEDULER)); } });
/**
* A change detection scheduler token for {@link RootContext}. This token is the default value used
* for the default `RootContext` found in the {@link ROOT_CONTEXT} token.
*/
var SCHEDULER = new InjectionToken('SCHEDULER_TOKEN', {
providedIn: 'root',
factory: function () { return defaultScheduler; },
});
var NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
function createChainedInjector(rootViewInjector, moduleInjector) {
return {
get: function (token, notFoundValue) {
var value = rootViewInjector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);
if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
// Return the value from the root element injector when
// - it provides it
// (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
// - the module injector should not be checked
// (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
return value;
}
return moduleInjector.get(token, notFoundValue);
}
};
}
/**
* Render3 implementation of {@link viewEngine_ComponentFactory}.
*/
var ComponentFactory$1 = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(ComponentFactory$$1, _super);
/**
* @param componentDef The component definition.
* @param ngModule The NgModuleRef to which the factory is bound.
*/
function ComponentFactory$$1(componentDef, ngModule) {
var _this = _super.call(this) || this;
_this.componentDef = componentDef;
_this.ngModule = ngModule;
_this.componentType = componentDef.type;
_this.selector = componentDef.selectors[0][0];
_this.ngContentSelectors = [];
return _this;
}
Object.defineProperty(ComponentFactory$$1.prototype, "inputs", {
get: function () {
return toRefArray(this.componentDef.inputs);
},
enumerable: true,
configurable: true
});
Object.defineProperty(ComponentFactory$$1.prototype, "outputs", {
get: function () {
return toRefArray(this.componentDef.outputs);
},
enumerable: true,
configurable: true
});
ComponentFactory$$1.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
var isInternalRootView = rootSelectorOrNode === undefined;
ngModule = ngModule || this.ngModule;
var rootViewInjector = ngModule ? createChainedInjector(injector, ngModule.injector) : injector;
var rendererFactory = rootViewInjector.get(RendererFactory2, domRendererFactory3);
var sanitizer = rootViewInjector.get(Sanitizer, null);
var hostRNode = isInternalRootView ?
elementCreate(this.selector, rendererFactory.createRenderer(null, this.componentDef)) :
locateHostElement(rendererFactory, rootSelectorOrNode);
var rootFlags = this.componentDef.onPush ? 8 /* Dirty */ | 128 /* IsRoot */ :
4 /* CheckAlways */ | 128 /* IsRoot */;
var rootContext = !isInternalRootView ? rootViewInjector.get(ROOT_CONTEXT) : createRootContext();
var renderer = rendererFactory.createRenderer(hostRNode, this.componentDef);
if (rootSelectorOrNode && hostRNode) {
ngDevMode && ngDevMode.rendererSetAttribute++;
isProceduralRenderer(renderer) ?
renderer.setAttribute(hostRNode, 'ng-version', VERSION.full) :
hostRNode.setAttribute('ng-version', VERSION.full);
}
// Create the root view. Uses empty TView and ContentTemplate.
var rootLView = createLView(null, createTView(-1, null, 1, 0, null, null, null), rootContext, rootFlags, rendererFactory, renderer, sanitizer, rootViewInjector);
// rootView is the parent when bootstrapping
var oldLView = enterView(rootLView, null);
var component;
var tElementNode;
try {
if (rendererFactory.begin)
rendererFactory.begin();
var componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, renderer);
tElementNode = getTNode(0, rootLView);
// Transform the arrays of native nodes into a structure that can be consumed by the
// projection instruction. This is needed to support the reprojection of these nodes.
if (projectableNodes) {
var index = 0;
var tView = rootLView[TVIEW];
var projection$$1 = tElementNode.projection = [];
for (var i = 0; i < projectableNodes.length; i++) {
var nodeList = projectableNodes[i];
var firstTNode = null;
var previousTNode = null;
for (var j = 0; j < nodeList.length; j++) {
if (tView.firstTemplatePass) {
// For dynamically created components such as ComponentRef, we create a new TView for
// each insert. This is not ideal since we should be sharing the TViews.
// Also the logic here should be shared with `component.ts`'s `renderComponent`
// method.
tView.expandoStartIndex++;
tView.blueprint.splice(++index + HEADER_OFFSET, 0, null);
tView.data.splice(index + HEADER_OFFSET, 0, null);
rootLView.splice(index + HEADER_OFFSET, 0, null);
}
var tNode = createNodeAtIndex(index, 3 /* Element */, nodeList[j], null, null);
previousTNode ? (previousTNode.next = tNode) : (firstTNode = tNode);
previousTNode = tNode;
}
projection$$1.push(firstTNode);
}
}
// TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
// executed here?
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
addToViewTree(rootLView, HEADER_OFFSET, componentView);
refreshDescendantViews(rootLView);
}
finally {
leaveView(oldLView);
if (rendererFactory.end)
rendererFactory.end();
}
var componentRef = new ComponentRef$1(this.componentType, component, createElementRef(ElementRef, tElementNode, rootLView), rootLView, tElementNode);
if (isInternalRootView) {
// The host element of the internal root view is attached to the component's host view node
componentRef.hostView._tViewNode.child = tElementNode;
}
return componentRef;
};
return ComponentFactory$$1;
}(ComponentFactory));
var componentFactoryResolver = new ComponentFactoryResolver$1();
/**
* Represents an instance of a Component created via a {@link ComponentFactory}.
*
* `ComponentRef` provides access to the Component Instance as well other objects related to this
* Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
* method.
*
*/
var ComponentRef$1 = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(ComponentRef$$1, _super);
function ComponentRef$$1(componentType, instance, location, _rootLView, _tNode) {
var _this = _super.call(this) || this;
_this.location = location;
_this._rootLView = _rootLView;
_this._tNode = _tNode;
_this.destroyCbs = [];
_this.instance = instance;
_this.hostView = _this.changeDetectorRef = new RootViewRef(_rootLView);
_this.hostView._tViewNode = createViewNode(-1, _rootLView);
_this.componentType = componentType;
return _this;
}
Object.defineProperty(ComponentRef$$1.prototype, "injector", {
get: function () { return new NodeInjector(this._tNode, this._rootLView); },
enumerable: true,
configurable: true
});
ComponentRef$$1.prototype.destroy = function () {
ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
this.destroyCbs.forEach(function (fn) { return fn(); });
this.destroyCbs = null;
this.hostView.destroy();
};
ComponentRef$$1.prototype.onDestroy = function (callback) {
ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
this.destroyCbs.push(callback);
};
return ComponentRef$$1;
}(ComponentRef));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This file is used to control if the default rendering pipeline should be `ViewEngine` or `Ivy`.
*
* For more information on how to run and debug tests with either Ivy or View Engine (legacy),
* please see [BAZEL.md](./docs/BAZEL.md).
*/
var _devMode = true;
var _runModeLocked = false;
/**
* Returns whether Angular is in development mode. After called once,
* the value is locked and won't change any more.
*
* By default, this is true, unless a user calls `enableProdMode` before calling this.
*
* @publicApi
*/
function isDevMode() {
_runModeLocked = true;
return _devMode;
}
/**
* Disable Angular's development mode, which turns off assertions and other
* checks within the framework.
*
* One important assertion this disables verifies that a change detection pass
* does not result in additional changes to any bindings (also known as
* unidirectional data flow).
*
* @publicApi
*/
function enableProdMode() {
if (_runModeLocked) {
throw new Error('Cannot enable prod mode after platform setup.');
}
_devMode = false;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This helper class is used to get hold of an inert tree of DOM elements containing dirty HTML
* that needs sanitizing.
* Depending upon browser support we must use one of three strategies for doing this.
* Support: Safari 10.x -> XHR strategy
* Support: Firefox -> DomParser strategy
* Default: InertDocument strategy
*/
var InertBodyHelper = /** @class */ (function () {
function InertBodyHelper(defaultDoc) {
this.defaultDoc = defaultDoc;
this.inertDocument = this.defaultDoc.implementation.createHTMLDocument('sanitization-inert');
this.inertBodyElement = this.inertDocument.body;
if (this.inertBodyElement == null) {
// usually there should be only one body element in the document, but IE doesn't have any, so
// we need to create one.
var inertHtml = this.inertDocument.createElement('html');
this.inertDocument.appendChild(inertHtml);
this.inertBodyElement = this.inertDocument.createElement('body');
inertHtml.appendChild(this.inertBodyElement);
}
this.inertBodyElement.innerHTML = '<svg><g onload="this.parentNode.remove()"></g></svg>';
if (this.inertBodyElement.querySelector && !this.inertBodyElement.querySelector('svg')) {
// We just hit the Safari 10.1 bug - which allows JS to run inside the SVG G element
// so use the XHR strategy.
this.getInertBodyElement = this.getInertBodyElement_XHR;
return;
}
this.inertBodyElement.innerHTML =
'<svg><p><style><img src="</style><img src=x onerror=alert(1)//">';
if (this.inertBodyElement.querySelector && this.inertBodyElement.querySelector('svg img')) {
// We just hit the Firefox bug - which prevents the inner img JS from being sanitized
// so use the DOMParser strategy, if it is available.
// If the DOMParser is not available then we are not in Firefox (Server/WebWorker?) so we
// fall through to the default strategy below.
if (isDOMParserAvailable()) {
this.getInertBodyElement = this.getInertBodyElement_DOMParser;
return;
}
}
// None of the bugs were hit so it is safe for us to use the default InertDocument strategy
this.getInertBodyElement = this.getInertBodyElement_InertDocument;
}
/**
* Use XHR to create and fill an inert body element (on Safari 10.1)
* See
* https://github.com/cure53/DOMPurify/blob/a992d3a75031cb8bb032e5ea8399ba972bdf9a65/src/purify.js#L439-L449
*/
InertBodyHelper.prototype.getInertBodyElement_XHR = function (html) {
// We add these extra elements to ensure that the rest of the content is parsed as expected
// e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
// `<head>` tag.
html = '<body><remove></remove>' + html + '</body>';
try {
html = encodeURI(html);
}
catch (_a) {
return null;
}
var xhr = new XMLHttpRequest();
xhr.responseType = 'document';
xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false);
xhr.send(undefined);
var body = xhr.response.body;
body.removeChild(body.firstChild);
return body;
};
/**
* Use DOMParser to create and fill an inert body element (on Firefox)
* See https://github.com/cure53/DOMPurify/releases/tag/0.6.7
*
*/
InertBodyHelper.prototype.getInertBodyElement_DOMParser = function (html) {
// We add these extra elements to ensure that the rest of the content is parsed as expected
// e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
// `<head>` tag.
html = '<body><remove></remove>' + html + '</body>';
try {
var body = new window
.DOMParser()
.parseFromString(html, 'text/html')
.body;
body.removeChild(body.firstChild);
return body;
}
catch (_a) {
return null;
}
};
/**
* Use an HTML5 `template` element, if supported, or an inert body element created via
* `createHtmlDocument` to create and fill an inert DOM element.
* This is the default sane strategy to use if the browser does not require one of the specialised
* strategies above.
*/
InertBodyHelper.prototype.getInertBodyElement_InertDocument = function (html) {
// Prefer using <template> element if supported.
var templateEl = this.inertDocument.createElement('template');
if ('content' in templateEl) {
templateEl.innerHTML = html;
return templateEl;
}
this.inertBodyElement.innerHTML = html;
// Support: IE 9-11 only
// strip custom-namespaced attributes on IE<=11
if (this.defaultDoc.documentMode) {
this.stripCustomNsAttrs(this.inertBodyElement);
}
return this.inertBodyElement;
};
/**
* When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
* attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g.
* 'ns1:xlink:foo').
*
* This is undesirable since we don't want to allow any of these custom attributes. This method
* strips them all.
*/
InertBodyHelper.prototype.stripCustomNsAttrs = function (el) {
var elAttrs = el.attributes;
// loop backwards so that we can support removals.
for (var i = elAttrs.length - 1; 0 < i; i--) {
var attrib = elAttrs.item(i);
var attrName = attrib.name;
if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
el.removeAttribute(attrName);
}
}
var childNode = el.firstChild;
while (childNode) {
if (childNode.nodeType === Node.ELEMENT_NODE)
this.stripCustomNsAttrs(childNode);
childNode = childNode.nextSibling;
}
};
return InertBodyHelper;
}());
/**
* We need to determine whether the DOMParser exists in the global context.
* The try-catch is because, on some browsers, trying to access this property
* on window can actually throw an error.
*
* @suppress {uselessCode}
*/
function isDOMParserAvailable() {
try {
return !!window.DOMParser;
}
catch (_a) {
return false;
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
*
* This regular expression matches a subset of URLs that will not cause script
* execution if used in URL context within a HTML document. Specifically, this
* regular expression matches if (comment from here on and regex copied from
* Soy's EscapingConventions):
* (1) Either a protocol in a whitelist (http, https, mailto or ftp).
* (2) or no protocol. A protocol must be followed by a colon. The below
* allows that by allowing colons only after one of the characters [/?#].
* A colon after a hash (#) must be in the fragment.
* Otherwise, a colon after a (?) must be in a query.
* Otherwise, a colon after a single solidus (/) must be in a path.
* Otherwise, a colon after a double solidus (//) must be in the authority
* (before port).
*
* The pattern disallows &, used in HTML entity declarations before
* one of the characters in [/?#]. This disallows HTML entities used in the
* protocol name, which should never happen, e.g. "h&#116;tp" for "http".
* It also disallows HTML entities in the first path part of a relative path,
* e.g. "foo&lt;bar/baz". Our existing escaping functions should not produce
* that. More importantly, it disallows masking of a colon,
* e.g. "javascript&#58;...".
*
* This regular expression was taken from the Closure sanitization library.
*/
var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
/** A pattern that matches safe data URLs. Only matches image, video and audio types. */
var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;
function _sanitizeUrl(url) {
url = String(url);
if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN))
return url;
if (isDevMode()) {
console.warn("WARNING: sanitizing unsafe URL value " + url + " (see http://g.co/ng/security#xss)");
}
return 'unsafe:' + url;
}
function sanitizeSrcset(srcset) {
srcset = String(srcset);
return srcset.split(',').map(function (srcset) { return _sanitizeUrl(srcset.trim()); }).join(', ');
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function tagSet(tags) {
var e_1, _a;
var res = {};
try {
for (var _b = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__values"])(tags.split(',')), _c = _b.next(); !_c.done; _c = _b.next()) {
var t = _c.value;
res[t] = true;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return res;
}
function merge$1() {
var sets = [];
for (var _i = 0; _i < arguments.length; _i++) {
sets[_i] = arguments[_i];
}
var e_2, _a;
var res = {};
try {
for (var sets_1 = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__values"])(sets), sets_1_1 = sets_1.next(); !sets_1_1.done; sets_1_1 = sets_1.next()) {
var s = sets_1_1.value;
for (var v in s) {
if (s.hasOwnProperty(v))
res[v] = true;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (sets_1_1 && !sets_1_1.done && (_a = sets_1.return)) _a.call(sets_1);
}
finally { if (e_2) throw e_2.error; }
}
return res;
}
// Good source of info about elements and attributes
// http://dev.w3.org/html5/spec/Overview.html#semantics
// http://simon.html5.org/html-elements
// Safe Void Elements - HTML5
// http://dev.w3.org/html5/spec/Overview.html#void-elements
var VOID_ELEMENTS = tagSet('area,br,col,hr,img,wbr');
// Elements that you can, intentionally, leave open (and which close themselves)
// http://dev.w3.org/html5/spec/Overview.html#optional-tags
var OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr');
var OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet('rp,rt');
var OPTIONAL_END_TAG_ELEMENTS = merge$1(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS);
// Safe Block Elements - HTML5
var BLOCK_ELEMENTS = merge$1(OPTIONAL_END_TAG_BLOCK_ELEMENTS, tagSet('address,article,' +
'aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
'h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul'));
// Inline Elements - HTML5
var INLINE_ELEMENTS = merge$1(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,acronym,audio,b,' +
'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' +
'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video'));
var VALID_ELEMENTS = merge$1(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
// Attributes that have href and hence need to be sanitized
var URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
// Attributes that have special href set hence need to be sanitized
var SRCSET_ATTRS = tagSet('srcset');
var HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' +
'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' +
'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' +
'scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,' +
'valign,value,vspace,width');
// NB: This currently consciously doesn't support SVG. SVG sanitization has had several security
// issues in the past, so it seems safer to leave it out if possible. If support for binding SVG via
// innerHTML is required, SVG attributes should be added here.
// NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
// can be sanitized, but they increase security surface area without a legitimate use case, so they
// are left out here.
var VALID_ATTRS = merge$1(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS);
/**
* SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
* attributes.
*/
var SanitizingHtmlSerializer = /** @class */ (function () {
function SanitizingHtmlSerializer() {
// Explicitly track if something was stripped, to avoid accidentally warning of sanitization just
// because characters were re-encoded.
this.sanitizedSomething = false;
this.buf = [];
}
SanitizingHtmlSerializer.prototype.sanitizeChildren = function (el) {
// This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
// However this code never accesses properties off of `document` before deleting its contents
// again, so it shouldn't be vulnerable to DOM clobbering.
var current = el.firstChild;
var elementValid = true;
while (current) {
if (current.nodeType === Node.ELEMENT_NODE) {
elementValid = this.startElement(current);
}
else if (current.nodeType === Node.TEXT_NODE) {
this.chars(current.nodeValue);
}
else {
// Strip non-element, non-text nodes.
this.sanitizedSomething = true;
}
if (elementValid && current.firstChild) {
current = current.firstChild;
continue;
}
while (current) {
// Leaving the element. Walk up and to the right, closing tags as we go.
if (current.nodeType === Node.ELEMENT_NODE) {
this.endElement(current);
}
var next = this.checkClobberedElement(current, current.nextSibling);
if (next) {
current = next;
break;
}
current = this.checkClobberedElement(current, current.parentNode);
}
}
return this.buf.join('');
};
/**
* Outputs only valid Elements.
*
* Invalid elements are skipped.
*
* @param element element to sanitize
* Returns true if the element is valid.
*/
SanitizingHtmlSerializer.prototype.startElement = function (element) {
var tagName = element.nodeName.toLowerCase();
if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
this.sanitizedSomething = true;
return false;
}
this.buf.push('<');
this.buf.push(tagName);
var elAttrs = element.attributes;
for (var i = 0; i < elAttrs.length; i++) {
var elAttr = elAttrs.item(i);
var attrName = elAttr.name;
var lower = attrName.toLowerCase();
if (!VALID_ATTRS.hasOwnProperty(lower)) {
this.sanitizedSomething = true;
continue;
}
var value = elAttr.value;
// TODO(martinprobst): Special case image URIs for data:image/...
if (URI_ATTRS[lower])
value = _sanitizeUrl(value);
if (SRCSET_ATTRS[lower])
value = sanitizeSrcset(value);
this.buf.push(' ', attrName, '="', encodeEntities(value), '"');
}
this.buf.push('>');
return true;
};
SanitizingHtmlSerializer.prototype.endElement = function (current) {
var tagName = current.nodeName.toLowerCase();
if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
this.buf.push('</');
this.buf.push(tagName);
this.buf.push('>');
}
};
SanitizingHtmlSerializer.prototype.chars = function (chars) { this.buf.push(encodeEntities(chars)); };
SanitizingHtmlSerializer.prototype.checkClobberedElement = function (node, nextNode) {
if (nextNode &&
(node.compareDocumentPosition(nextNode) &
Node.DOCUMENT_POSITION_CONTAINED_BY) === Node.DOCUMENT_POSITION_CONTAINED_BY) {
throw new Error("Failed to sanitize html because the element is clobbered: " + node.outerHTML);
}
return nextNode;
};
return SanitizingHtmlSerializer;
}());
// Regular Expressions for parsing tags and attributes
var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
// ! to ~ is the ASCII range.
var NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
/**
* Escapes all potentially dangerous characters, so that the
* resulting string can be safely inserted into attribute or
* element text.
* @param value
*/
function encodeEntities(value) {
return value.replace(/&/g, '&amp;')
.replace(SURROGATE_PAIR_REGEXP, function (match) {
var hi = match.charCodeAt(0);
var low = match.charCodeAt(1);
return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
})
.replace(NON_ALPHANUMERIC_REGEXP, function (match) { return '&#' + match.charCodeAt(0) + ';'; })
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
var inertBodyHelper;
/**
* Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
* the DOM in a browser environment.
*/
function _sanitizeHtml(defaultDoc, unsafeHtmlInput) {
var inertBodyElement = null;
try {
inertBodyHelper = inertBodyHelper || new InertBodyHelper(defaultDoc);
// Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
var unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
// mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
// trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
var mXSSAttempts = 5;
var parsedHtml = unsafeHtml;
do {
if (mXSSAttempts === 0) {
throw new Error('Failed to sanitize html because the input is unstable');
}
mXSSAttempts--;
unsafeHtml = parsedHtml;
parsedHtml = inertBodyElement.innerHTML;
inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
} while (unsafeHtml !== parsedHtml);
var sanitizer = new SanitizingHtmlSerializer();
var safeHtml = sanitizer.sanitizeChildren(getTemplateContent(inertBodyElement) || inertBodyElement);
if (isDevMode() && sanitizer.sanitizedSomething) {
console.warn('WARNING: sanitizing HTML stripped some content, see http://g.co/ng/security#xss');
}
return safeHtml;
}
finally {
// In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
if (inertBodyElement) {
var parent_1 = getTemplateContent(inertBodyElement) || inertBodyElement;
while (parent_1.firstChild) {
parent_1.removeChild(parent_1.firstChild);
}
}
}
}
function getTemplateContent(el) {
return 'content' in el /** Microsoft/TypeScript#21517 */ && isTemplateElement(el) ?
el.content :
null;
}
function isTemplateElement(el) {
return el.nodeType === Node.ELEMENT_NODE && el.nodeName === 'TEMPLATE';
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Marks that the next string is for element.
*
* See `I18nMutateOpCodes` documentation.
*/
var ELEMENT_MARKER = {
marker: 'element'
};
/**
* Marks that the next string is for comment.
*
* See `I18nMutateOpCodes` documentation.
*/
var COMMENT_MARKER = {
marker: 'comment'
};
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var MARKER = "\uFFFD";
var ICU_BLOCK_REGEX = /^\s*(�\d+:?\d*�)\s*,\s*(select|plural)\s*,/;
var SUBTEMPLATE_REGEXP = /�\/?\*(\d+:\d+)�/gi;
var PH_REGEXP = /�(\/?[#*]\d+):?\d*�/gi;
var BINDING_REGEXP = /�(\d+):?\d*�/gi;
var ICU_REGEXP = /({\s*�\d+:?\d*�\s*,\s*\S{6}\s*,[\s\S]*})/gi;
// i18nPostproocess regexps
var PP_PLACEHOLDERS = /\[(�.+?�?)\]/g;
var PP_ICU_VARS = /({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g;
var PP_ICUS = /�I18N_EXP_(ICU(_\d+)?)�/g;
/**
* Breaks pattern into strings and top level {...} blocks.
* Can be used to break a message into text and ICU expressions, or to break an ICU expression into
* keys and cases.
* Original code from closure library, modified for Angular.
*
* @param pattern (sub)Pattern to be broken.
*
*/
function extractParts(pattern) {
if (!pattern) {
return [];
}
var prevPos = 0;
var braceStack = [];
var results = [];
var braces = /[{}]/g;
// lastIndex doesn't get set to 0 so we have to.
braces.lastIndex = 0;
var match;
while (match = braces.exec(pattern)) {
var pos = match.index;
if (match[0] == '}') {
braceStack.pop();
if (braceStack.length == 0) {
// End of the block.
var block = pattern.substring(prevPos, pos);
if (ICU_BLOCK_REGEX.test(block)) {
results.push(parseICUBlock(block));
}
else if (block) { // Don't push empty strings
results.push(block);
}
prevPos = pos + 1;
}
}
else {
if (braceStack.length == 0) {
var substring_1 = pattern.substring(prevPos, pos);
results.push(substring_1);
prevPos = pos + 1;
}
braceStack.push('{');
}
}
var substring = pattern.substring(prevPos);
if (substring != '') {
results.push(substring);
}
return results;
}
/**
* Parses text containing an ICU expression and produces a JSON object for it.
* Original code from closure library, modified for Angular.
*
* @param pattern Text containing an ICU expression that needs to be parsed.
*
*/
function parseICUBlock(pattern) {
var cases = [];
var values = [];
var icuType = 1 /* plural */;
var mainBinding = 0;
pattern = pattern.replace(ICU_BLOCK_REGEX, function (str, binding, type) {
if (type === 'select') {
icuType = 0 /* select */;
}
else {
icuType = 1 /* plural */;
}
mainBinding = parseInt(binding.substr(1), 10);
return '';
});
var parts = extractParts(pattern);
// Looking for (key block)+ sequence. One of the keys has to be "other".
for (var pos = 0; pos < parts.length;) {
var key = parts[pos++].trim();
if (icuType === 1 /* plural */) {
// Key can be "=x", we just want "x"
key = key.replace(/\s*(?:=)?(\w+)\s*/, '$1');
}
if (key.length) {
cases.push(key);
}
var blocks = extractParts(parts[pos++]);
if (blocks.length) {
values.push(blocks);
}
}
assertGreaterThan(cases.indexOf('other'), -1, 'Missing key "other" in ICU statement.');
// TODO(ocombe): support ICU expressions in attributes, see #21615
return { type: icuType, mainBinding: mainBinding, cases: cases, values: values };
}
/**
* Removes everything inside the sub-templates of a message.
*/
function removeInnerTemplateTranslation(message) {
var match;
var res = '';
var index = 0;
var inTemplate = false;
var tagMatched;
while ((match = SUBTEMPLATE_REGEXP.exec(message)) !== null) {
if (!inTemplate) {
res += message.substring(index, match.index + match[0].length);
tagMatched = match[1];
inTemplate = true;
}
else {
if (match[0] === MARKER + "/*" + tagMatched + MARKER) {
index = match.index;
inTemplate = false;
}
}
}
ngDevMode &&
assertEqual(inTemplate, false, "Tag mismatch: unable to find the end of the sub-template in the translation \"" + message + "\"");
res += message.substr(index);
return res;
}
/**
* Extracts a part of a message and removes the rest.
*
* This method is used for extracting a part of the message associated with a template. A translated
* message can span multiple templates.
*
* Example:
* ```
* <div i18n>Translate <span *ngIf>me</span>!</div>
* ```
*
* @param message The message to crop
* @param subTemplateIndex Index of the sub-template to extract. If undefined it returns the
* external template and removes all sub-templates.
*/
function getTranslationForTemplate(message, subTemplateIndex) {
if (typeof subTemplateIndex !== 'number') {
// We want the root template message, ignore all sub-templates
return removeInnerTemplateTranslation(message);
}
else {
// We want a specific sub-template
var start = message.indexOf(":" + subTemplateIndex + MARKER) + 2 + subTemplateIndex.toString().length;
var end = message.search(new RegExp(MARKER + "\\/\\*\\d+:" + subTemplateIndex + MARKER));
return removeInnerTemplateTranslation(message.substring(start, end));
}
}
/**
* Generate the OpCodes to update the bindings of a string.
*
* @param str The string containing the bindings.
* @param destinationNode Index of the destination node which will receive the binding.
* @param attrName Name of the attribute, if the string belongs to an attribute.
* @param sanitizeFn Sanitization function used to sanitize the string after update, if necessary.
*/
function generateBindingUpdateOpCodes(str, destinationNode, attrName, sanitizeFn) {
if (sanitizeFn === void 0) { sanitizeFn = null; }
var updateOpCodes = [null, null]; // Alloc space for mask and size
var textParts = str.split(BINDING_REGEXP);
var mask = 0;
for (var j = 0; j < textParts.length; j++) {
var textValue = textParts[j];
if (j & 1) {
// Odd indexes are bindings
var bindingIndex = parseInt(textValue, 10);
updateOpCodes.push(-1 - bindingIndex);
mask = mask | toMaskBit(bindingIndex);
}
else if (textValue !== '') {
// Even indexes are text
updateOpCodes.push(textValue);
}
}
updateOpCodes.push(destinationNode << 2 /* SHIFT_REF */ |
(attrName ? 1 /* Attr */ : 0 /* Text */));
if (attrName) {
updateOpCodes.push(attrName, sanitizeFn);
}
updateOpCodes[0] = mask;
updateOpCodes[1] = updateOpCodes.length - 2;
return updateOpCodes;
}
function getBindingMask(icuExpression, mask) {
if (mask === void 0) { mask = 0; }
mask = mask | toMaskBit(icuExpression.mainBinding);
var match;
for (var i = 0; i < icuExpression.values.length; i++) {
var valueArr = icuExpression.values[i];
for (var j = 0; j < valueArr.length; j++) {
var value = valueArr[j];
if (typeof value === 'string') {
while (match = BINDING_REGEXP.exec(value)) {
mask = mask | toMaskBit(parseInt(match[1], 10));
}
}
else {
mask = getBindingMask(value, mask);
}
}
}
return mask;
}
var i18nIndexStack = [];
var i18nIndexStackPointer = -1;
/**
* Convert binding index to mask bit.
*
* Each index represents a single bit on the bit-mask. Because bit-mask only has 32 bits, we make
* the 32nd bit share all masks for all bindings higher than 32. Since it is extremely rare to have
* more than 32 bindings this will be hit very rarely. The downside of hitting this corner case is
* that we will execute binding code more often than necessary. (penalty of performance)
*/
function toMaskBit(bindingIndex) {
return 1 << Math.min(bindingIndex, 31);
}
var parentIndexStack = [];
/**
* Marks a block of text as translatable.
*
* The instructions `i18nStart` and `i18nEnd` mark the translation block in the template.
* The translation `message` is the value which is locale specific. The translation string may
* contain placeholders which associate inner elements and sub-templates within the translation.
*
* The translation `message` placeholders are:
* - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
* interpolated into. The placeholder `index` points to the expression binding index. An optional
* `block` that matches the sub-template in which it was declared.
* - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*: Marks the beginning
* and end of DOM element that were embedded in the original translation block. The placeholder
* `index` points to the element index in the template instructions set. An optional `block` that
* matches the sub-template in which it was declared.
* - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
* split up and translated separately in each angular template function. The `index` points to the
* `template` instruction index. A `block` that matches the sub-template in which it was declared.
*
* @param index A unique index of the translation in the static block.
* @param message The translation message.
* @param subTemplateIndex Optional sub-template index in the `message`.
*/
function i18nStart(index, message, subTemplateIndex) {
var tView = getLView()[TVIEW];
ngDevMode && assertDefined(tView, "tView should be defined");
i18nIndexStack[++i18nIndexStackPointer] = index;
if (tView.firstTemplatePass && tView.data[index + HEADER_OFFSET] === null) {
i18nStartFirstPass(tView, index, message, subTemplateIndex);
}
}
/**
* See `i18nStart` above.
*/
function i18nStartFirstPass(tView, index, message, subTemplateIndex) {
var viewData = getLView();
var expandoStartIndex = tView.blueprint.length - HEADER_OFFSET;
var previousOrParentTNode = getPreviousOrParentTNode();
var parentTNode = getIsParent() ? getPreviousOrParentTNode() :
previousOrParentTNode && previousOrParentTNode.parent;
var parentIndex = parentTNode && parentTNode !== viewData[HOST_NODE] ?
parentTNode.index - HEADER_OFFSET :
index;
var parentIndexPointer = 0;
parentIndexStack[parentIndexPointer] = parentIndex;
var createOpCodes = [];
// If the previous node wasn't the direct parent then we have a translation without top level
// element and we need to keep a reference of the previous element if there is one
if (index > 0 && previousOrParentTNode !== parentTNode) {
// Create an OpCode to select the previous TNode
createOpCodes.push(previousOrParentTNode.index << 3 /* SHIFT_REF */ | 0 /* Select */);
}
var updateOpCodes = [];
var icuExpressions = [];
var templateTranslation = getTranslationForTemplate(message, subTemplateIndex);
var msgParts = templateTranslation.split(PH_REGEXP);
for (var i = 0; i < msgParts.length; i++) {
var value = msgParts[i];
if (i & 1) {
// Odd indexes are placeholders (elements and sub-templates)
if (value.charAt(0) === '/') {
// It is a closing tag
if (value.charAt(1) === '#') {
var phIndex = parseInt(value.substr(2), 10);
parentIndex = parentIndexStack[--parentIndexPointer];
createOpCodes.push(phIndex << 3 /* SHIFT_REF */ | 5 /* ElementEnd */);
}
}
else {
var phIndex = parseInt(value.substr(1), 10);
// The value represents a placeholder that we move to the designated index
createOpCodes.push(phIndex << 3 /* SHIFT_REF */ | 0 /* Select */, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
if (value.charAt(0) === '#') {
parentIndexStack[++parentIndexPointer] = parentIndex = phIndex;
}
}
}
else {
// Even indexes are text (including bindings & ICU expressions)
var parts = value.split(ICU_REGEXP);
for (var j = 0; j < parts.length; j++) {
value = parts[j];
if (j & 1) {
// Odd indexes are ICU expressions
// Create the comment node that will anchor the ICU expression
allocExpando(viewData);
var icuNodeIndex = tView.blueprint.length - 1 - HEADER_OFFSET;
createOpCodes.push(COMMENT_MARKER, ngDevMode ? "ICU " + icuNodeIndex : '', parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
// Update codes for the ICU expression
var icuExpression = parseICUBlock(value.substr(1, value.length - 2));
var mask = getBindingMask(icuExpression);
icuStart(icuExpressions, icuExpression, icuNodeIndex, icuNodeIndex);
// Since this is recursive, the last TIcu that was pushed is the one we want
var tIcuIndex = icuExpressions.length - 1;
updateOpCodes.push(toMaskBit(icuExpression.mainBinding), // mask of the main binding
3, // skip 3 opCodes if not changed
-1 - icuExpression.mainBinding, icuNodeIndex << 2 /* SHIFT_REF */ | 2 /* IcuSwitch */, tIcuIndex, mask, // mask of all the bindings of this ICU expression
2, // skip 2 opCodes if not changed
icuNodeIndex << 2 /* SHIFT_REF */ | 3 /* IcuUpdate */, tIcuIndex);
}
else if (value !== '') {
// Even indexes are text (including bindings)
var hasBinding = value.match(BINDING_REGEXP);
// Create text nodes
allocExpando(viewData);
createOpCodes.push(
// If there is a binding, the value will be set during update
hasBinding ? '' : value, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
if (hasBinding) {
addAllToArray(generateBindingUpdateOpCodes(value, tView.blueprint.length - 1 - HEADER_OFFSET), updateOpCodes);
}
}
}
}
}
// NOTE: local var needed to properly assert the type of `TI18n`.
var tI18n = {
vars: tView.blueprint.length - HEADER_OFFSET - expandoStartIndex,
expandoStartIndex: expandoStartIndex,
create: createOpCodes,
update: updateOpCodes,
icus: icuExpressions.length ? icuExpressions : null,
};
tView.data[index + HEADER_OFFSET] = tI18n;
}
function appendI18nNode(tNode, parentTNode, previousTNode) {
ngDevMode && ngDevMode.rendererMoveNode++;
var viewData = getLView();
if (!previousTNode) {
previousTNode = parentTNode;
}
// re-organize node tree to put this node in the correct position.
if (previousTNode === parentTNode && tNode !== parentTNode.child) {
tNode.next = parentTNode.child;
parentTNode.child = tNode;
}
else if (previousTNode !== parentTNode && tNode !== previousTNode.next) {
tNode.next = previousTNode.next;
previousTNode.next = tNode;
}
else {
tNode.next = null;
}
if (parentTNode !== viewData[HOST_NODE]) {
tNode.parent = parentTNode;
}
appendChild(getNativeByTNode(tNode, viewData), tNode, viewData);
var slotValue = viewData[tNode.index];
if (tNode.type !== 0 /* Container */ && isLContainer(slotValue)) {
// Nodes that inject ViewContainerRef also have a comment node that should be moved
appendChild(slotValue[NATIVE], tNode, viewData);
}
return tNode;
}
/**
* Handles message string post-processing for internationalization.
*
* Handles message string post-processing by transforming it from intermediate
* format (that might contain some markers that we need to replace) to the final
* form, consumable by i18nStart instruction. Post processing steps include:
*
* 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
* 2. Replace all ICU vars (like "VAR_PLURAL")
* 3. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
* in case multiple ICUs have the same placeholder name
*
* @param message Raw translation string for post processing
* @param replacements Set of replacements that should be applied
*
* @returns Transformed string that can be consumed by i18nStart instruction
*
* @publicAPI
*/
function i18nPostprocess(message, replacements) {
//
// Step 1: resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
//
var matches = {};
var result = message.replace(PP_PLACEHOLDERS, function (_match, content) {
if (!matches[content]) {
matches[content] = content.split('|');
}
if (!matches[content].length) {
throw new Error("i18n postprocess: unmatched placeholder - " + content);
}
return matches[content].shift();
});
// verify that we injected all values
var hasUnmatchedValues = Object.keys(matches).some(function (key) { return !!matches[key].length; });
if (hasUnmatchedValues) {
throw new Error("i18n postprocess: unmatched values - " + JSON.stringify(matches));
}
// return current result if no replacements specified
if (!Object.keys(replacements).length) {
return result;
}
//
// Step 2: replace all ICU vars (like "VAR_PLURAL")
//
result = result.replace(PP_ICU_VARS, function (match, start, key, _type, _idx, end) {
return replacements.hasOwnProperty(key) ? "" + start + replacements[key] + end : match;
});
//
// Step 3: replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
// in case multiple ICUs have the same placeholder name
//
result = result.replace(PP_ICUS, function (match, key) {
if (replacements.hasOwnProperty(key)) {
var list = replacements[key];
if (!list.length) {
throw new Error("i18n postprocess: unmatched ICU - " + match + " with key: " + key);
}
return list.shift();
}
return match;
});
return result;
}
/**
* Translates a translation block marked by `i18nStart` and `i18nEnd`. It inserts the text/ICU nodes
* into the render tree, moves the placeholder nodes and removes the deleted nodes.
*/
function i18nEnd() {
var tView = getLView()[TVIEW];
ngDevMode && assertDefined(tView, "tView should be defined");
i18nEndFirstPass(tView);
}
/**
* See `i18nEnd` above.
*/
function i18nEndFirstPass(tView) {
var viewData = getLView();
ngDevMode && assertEqual(viewData[BINDING_INDEX], viewData[TVIEW].bindingStartIndex, 'i18nEnd should be called before any binding');
var rootIndex = i18nIndexStack[i18nIndexStackPointer--];
var tI18n = tView.data[rootIndex + HEADER_OFFSET];
ngDevMode && assertDefined(tI18n, "You should call i18nStart before i18nEnd");
// The last placeholder that was added before `i18nEnd`
var previousOrParentTNode = getPreviousOrParentTNode();
var visitedPlaceholders = readCreateOpCodes(rootIndex, tI18n.create, tI18n.expandoStartIndex, viewData);
// Remove deleted placeholders
// The last placeholder that was added before `i18nEnd` is `previousOrParentTNode`
for (var i = rootIndex + 1; i <= previousOrParentTNode.index - HEADER_OFFSET; i++) {
if (visitedPlaceholders.indexOf(i) === -1) {
removeNode(i, viewData);
}
}
}
function readCreateOpCodes(index, createOpCodes, expandoStartIndex, viewData) {
var renderer = getLView()[RENDERER];
var currentTNode = null;
var previousTNode = null;
var visitedPlaceholders = [];
for (var i = 0; i < createOpCodes.length; i++) {
var opCode = createOpCodes[i];
if (typeof opCode == 'string') {
var textRNode = createTextNode(opCode, renderer);
ngDevMode && ngDevMode.rendererCreateTextNode++;
previousTNode = currentTNode;
currentTNode =
createNodeAtIndex(expandoStartIndex++, 3 /* Element */, textRNode, null, null);
setIsParent(false);
}
else if (typeof opCode == 'number') {
switch (opCode & 7 /* MASK_OPCODE */) {
case 1 /* AppendChild */:
var destinationNodeIndex = opCode >>> 17 /* SHIFT_PARENT */;
var destinationTNode = void 0;
if (destinationNodeIndex === index) {
// If the destination node is `i18nStart`, we don't have a
// top-level node and we should use the host node instead
destinationTNode = viewData[HOST_NODE];
}
else {
destinationTNode = getTNode(destinationNodeIndex, viewData);
}
ngDevMode &&
assertDefined(currentTNode, "You need to create or select a node before you can insert it into the DOM");
previousTNode = appendI18nNode(currentTNode, destinationTNode, previousTNode);
destinationTNode.next = null;
break;
case 0 /* Select */:
var nodeIndex = opCode >>> 3 /* SHIFT_REF */;
visitedPlaceholders.push(nodeIndex);
previousTNode = currentTNode;
currentTNode = getTNode(nodeIndex, viewData);
if (currentTNode) {
setPreviousOrParentTNode(currentTNode);
if (currentTNode.type === 3 /* Element */) {
setIsParent(true);
}
}
break;
case 5 /* ElementEnd */:
var elementIndex = opCode >>> 3 /* SHIFT_REF */;
previousTNode = currentTNode = getTNode(elementIndex, viewData);
setPreviousOrParentTNode(currentTNode);
setIsParent(false);
break;
case 4 /* Attr */:
var elementNodeIndex = opCode >>> 3 /* SHIFT_REF */;
var attrName = createOpCodes[++i];
var attrValue = createOpCodes[++i];
elementAttribute(elementNodeIndex, attrName, attrValue);
break;
default:
throw new Error("Unable to determine the type of mutate operation for \"" + opCode + "\"");
}
}
else {
switch (opCode) {
case COMMENT_MARKER:
var commentValue = createOpCodes[++i];
ngDevMode && assertEqual(typeof commentValue, 'string', "Expected \"" + commentValue + "\" to be a comment node value");
var commentRNode = renderer.createComment(commentValue);
ngDevMode && ngDevMode.rendererCreateComment++;
previousTNode = currentTNode;
currentTNode = createNodeAtIndex(expandoStartIndex++, 5 /* IcuContainer */, commentRNode, null, null);
attachPatchData(commentRNode, viewData);
currentTNode.activeCaseIndex = null;
// We will add the case nodes later, during the update phase
setIsParent(false);
break;
case ELEMENT_MARKER:
var tagNameValue = createOpCodes[++i];
ngDevMode && assertEqual(typeof tagNameValue, 'string', "Expected \"" + tagNameValue + "\" to be an element node tag name");
var elementRNode = renderer.createElement(tagNameValue);
ngDevMode && ngDevMode.rendererCreateElement++;
previousTNode = currentTNode;
currentTNode = createNodeAtIndex(expandoStartIndex++, 3 /* Element */, elementRNode, tagNameValue, null);
break;
default:
throw new Error("Unable to determine the type of mutate operation for \"" + opCode + "\"");
}
}
}
setIsParent(false);
return visitedPlaceholders;
}
function readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, viewData, bypassCheckBit) {
if (bypassCheckBit === void 0) { bypassCheckBit = false; }
var caseCreated = false;
for (var i = 0; i < updateOpCodes.length; i++) {
// bit code to check if we should apply the next update
var checkBit = updateOpCodes[i];
// Number of opCodes to skip until next set of update codes
var skipCodes = updateOpCodes[++i];
if (bypassCheckBit || (checkBit & changeMask)) {
// The value has been updated since last checked
var value = '';
for (var j = i + 1; j <= (i + skipCodes); j++) {
var opCode = updateOpCodes[j];
if (typeof opCode == 'string') {
value += opCode;
}
else if (typeof opCode == 'number') {
if (opCode < 0) {
// It's a binding index whose value is negative
value += stringify$1(viewData[bindingsStartIndex - opCode]);
}
else {
var nodeIndex = opCode >>> 2 /* SHIFT_REF */;
switch (opCode & 3 /* MASK_OPCODE */) {
case 1 /* Attr */:
var attrName = updateOpCodes[++j];
var sanitizeFn = updateOpCodes[++j];
elementAttribute(nodeIndex, attrName, value, sanitizeFn);
break;
case 0 /* Text */:
textBinding(nodeIndex, value);
break;
case 2 /* IcuSwitch */:
var tIcuIndex = updateOpCodes[++j];
var tIcu = icus[tIcuIndex];
var icuTNode = getTNode(nodeIndex, viewData);
// If there is an active case, delete the old nodes
if (icuTNode.activeCaseIndex !== null) {
var removeCodes = tIcu.remove[icuTNode.activeCaseIndex];
for (var k = 0; k < removeCodes.length; k++) {
var removeOpCode = removeCodes[k];
switch (removeOpCode & 7 /* MASK_OPCODE */) {
case 3 /* Remove */:
var nodeIndex_1 = removeOpCode >>> 3 /* SHIFT_REF */;
removeNode(nodeIndex_1, viewData);
break;
case 6 /* RemoveNestedIcu */:
var nestedIcuNodeIndex = removeCodes[k + 1] >>> 3 /* SHIFT_REF */;
var nestedIcuTNode = getTNode(nestedIcuNodeIndex, viewData);
var activeIndex = nestedIcuTNode.activeCaseIndex;
if (activeIndex !== null) {
var nestedIcuTIndex = removeOpCode >>> 3 /* SHIFT_REF */;
var nestedTIcu = icus[nestedIcuTIndex];
addAllToArray(nestedTIcu.remove[activeIndex], removeCodes);
}
break;
}
}
}
// Update the active caseIndex
var caseIndex = getCaseIndex(tIcu, value);
icuTNode.activeCaseIndex = caseIndex !== -1 ? caseIndex : null;
// Add the nodes for the new case
readCreateOpCodes(-1, tIcu.create[caseIndex], tIcu.expandoStartIndex, viewData);
caseCreated = true;
break;
case 3 /* IcuUpdate */:
tIcuIndex = updateOpCodes[++j];
tIcu = icus[tIcuIndex];
icuTNode = getTNode(nodeIndex, viewData);
readUpdateOpCodes(tIcu.update[icuTNode.activeCaseIndex], icus, bindingsStartIndex, changeMask, viewData, caseCreated);
break;
}
}
}
}
}
i += skipCodes;
}
}
function removeNode(index, viewData) {
var removedPhTNode = getTNode(index, viewData);
var removedPhRNode = getNativeByIndex(index, viewData);
removeChild(removedPhTNode, removedPhRNode || null, viewData);
removedPhTNode.detached = true;
ngDevMode && ngDevMode.rendererRemoveNode++;
var slotValue = load(index);
if (isLContainer(slotValue)) {
var lContainer = slotValue;
if (removedPhTNode.type !== 0 /* Container */) {
removeChild(removedPhTNode, lContainer[NATIVE] || null, viewData);
}
lContainer[RENDER_PARENT] = null;
}
}
/**
*
* Use this instruction to create a translation block that doesn't contain any placeholder.
* It calls both {@link i18nStart} and {@link i18nEnd} in one instruction.
*
* The translation `message` is the value which is locale specific. The translation string may
* contain placeholders which associate inner elements and sub-templates within the translation.
*
* The translation `message` placeholders are:
* - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
* interpolated into. The placeholder `index` points to the expression binding index. An optional
* `block` that matches the sub-template in which it was declared.
* - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*: Marks the beginning
* and end of DOM element that were embedded in the original translation block. The placeholder
* `index` points to the element index in the template instructions set. An optional `block` that
* matches the sub-template in which it was declared.
* - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
* split up and translated separately in each angular template function. The `index` points to the
* `template` instruction index. A `block` that matches the sub-template in which it was declared.
*
* @param index A unique index of the translation in the static block.
* @param message The translation message.
* @param subTemplateIndex Optional sub-template index in the `message`.
*/
function i18n(index, message, subTemplateIndex) {
i18nStart(index, message, subTemplateIndex);
i18nEnd();
}
/**
* Marks a list of attributes as translatable.
*
* @param index A unique index in the static block
* @param values
*/
function i18nAttributes(index, values) {
var tView = getLView()[TVIEW];
ngDevMode && assertDefined(tView, "tView should be defined");
ngDevMode &&
assertEqual(tView.firstTemplatePass, true, "You should only call i18nEnd on first template pass");
if (tView.firstTemplatePass && tView.data[index + HEADER_OFFSET] === null) {
i18nAttributesFirstPass(tView, index, values);
}
}
/**
* See `i18nAttributes` above.
*/
function i18nAttributesFirstPass(tView, index, values) {
var previousElement = getPreviousOrParentTNode();
var previousElementIndex = previousElement.index - HEADER_OFFSET;
var updateOpCodes = [];
for (var i = 0; i < values.length; i += 2) {
var attrName = values[i];
var message = values[i + 1];
var parts = message.split(ICU_REGEXP);
for (var j = 0; j < parts.length; j++) {
var value = parts[j];
if (j & 1) ;
else if (value !== '') {
// Even indexes are text (including bindings)
var hasBinding = !!value.match(BINDING_REGEXP);
if (hasBinding) {
addAllToArray(generateBindingUpdateOpCodes(value, previousElementIndex, attrName), updateOpCodes);
}
else {
elementAttribute(previousElementIndex, attrName, value);
}
}
}
}
tView.data[index + HEADER_OFFSET] = updateOpCodes;
}
var changeMask = 0;
var shiftsCounter = 0;
/**
* Stores the values of the bindings during each update cycle in order to determine if we need to
* update the translated nodes.
*
* @param expression The binding's new value or NO_CHANGE
*/
function i18nExp(expression) {
if (expression !== NO_CHANGE) {
changeMask = changeMask | (1 << shiftsCounter);
}
shiftsCounter++;
}
/**
* Updates a translation block or an i18n attribute when the bindings have changed.
*
* @param index Index of either {@link i18nStart} (translation block) or {@link i18nAttributes}
* (i18n attribute) on which it should update the content.
*/
function i18nApply(index) {
if (shiftsCounter) {
var lView = getLView();
var tView = lView[TVIEW];
ngDevMode && assertDefined(tView, "tView should be defined");
var tI18n = tView.data[index + HEADER_OFFSET];
var updateOpCodes = void 0;
var icus = null;
if (Array.isArray(tI18n)) {
updateOpCodes = tI18n;
}
else {
updateOpCodes = tI18n.update;
icus = tI18n.icus;
}
var bindingsStartIndex = lView[BINDING_INDEX] - shiftsCounter - 1;
readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, lView);
// Reset changeMask & maskBit to default for the next update cycle
changeMask = 0;
shiftsCounter = 0;
}
}
var Plural;
(function (Plural) {
Plural[Plural["Zero"] = 0] = "Zero";
Plural[Plural["One"] = 1] = "One";
Plural[Plural["Two"] = 2] = "Two";
Plural[Plural["Few"] = 3] = "Few";
Plural[Plural["Many"] = 4] = "Many";
Plural[Plural["Other"] = 5] = "Other";
})(Plural || (Plural = {}));
/**
* Returns the plural case based on the locale.
* This is a copy of the deprecated function that we used in Angular v4.
* // TODO(ocombe): remove this once we can the real getPluralCase function
*
* @deprecated from v5 the plural case function is in locale data files common/locales/*.ts
*/
function getPluralCase(locale, nLike) {
if (typeof nLike === 'string') {
nLike = parseInt(nLike, 10);
}
var n = nLike;
var nDecimal = n.toString().replace(/^[^.]*\.?/, '');
var i = Math.floor(Math.abs(n));
var v = nDecimal.length;
var f = parseInt(nDecimal, 10);
var t = parseInt(n.toString().replace(/^[^.]*\.?|0+$/g, ''), 10) || 0;
var lang = locale.split('-')[0].toLowerCase();
switch (lang) {
case 'af':
case 'asa':
case 'az':
case 'bem':
case 'bez':
case 'bg':
case 'brx':
case 'ce':
case 'cgg':
case 'chr':
case 'ckb':
case 'ee':
case 'el':
case 'eo':
case 'es':
case 'eu':
case 'fo':
case 'fur':
case 'gsw':
case 'ha':
case 'haw':
case 'hu':
case 'jgo':
case 'jmc':
case 'ka':
case 'kk':
case 'kkj':
case 'kl':
case 'ks':
case 'ksb':
case 'ky':
case 'lb':
case 'lg':
case 'mas':
case 'mgo':
case 'ml':
case 'mn':
case 'nb':
case 'nd':
case 'ne':
case 'nn':
case 'nnh':
case 'nyn':
case 'om':
case 'or':
case 'os':
case 'ps':
case 'rm':
case 'rof':
case 'rwk':
case 'saq':
case 'seh':
case 'sn':
case 'so':
case 'sq':
case 'ta':
case 'te':
case 'teo':
case 'tk':
case 'tr':
case 'ug':
case 'uz':
case 'vo':
case 'vun':
case 'wae':
case 'xog':
if (n === 1)
return Plural.One;
return Plural.Other;
case 'ak':
case 'ln':
case 'mg':
case 'pa':
case 'ti':
if (n === Math.floor(n) && n >= 0 && n <= 1)
return Plural.One;
return Plural.Other;
case 'am':
case 'as':
case 'bn':
case 'fa':
case 'gu':
case 'hi':
case 'kn':
case 'mr':
case 'zu':
if (i === 0 || n === 1)
return Plural.One;
return Plural.Other;
case 'ar':
if (n === 0)
return Plural.Zero;
if (n === 1)
return Plural.One;
if (n === 2)
return Plural.Two;
if (n % 100 === Math.floor(n % 100) && n % 100 >= 3 && n % 100 <= 10)
return Plural.Few;
if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 99)
return Plural.Many;
return Plural.Other;
case 'ast':
case 'ca':
case 'de':
case 'en':
case 'et':
case 'fi':
case 'fy':
case 'gl':
case 'it':
case 'nl':
case 'sv':
case 'sw':
case 'ur':
case 'yi':
if (i === 1 && v === 0)
return Plural.One;
return Plural.Other;
case 'be':
if (n % 10 === 1 && !(n % 100 === 11))
return Plural.One;
if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 4 &&
!(n % 100 >= 12 && n % 100 <= 14))
return Plural.Few;
if (n % 10 === 0 || n % 10 === Math.floor(n % 10) && n % 10 >= 5 && n % 10 <= 9 ||
n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 14)
return Plural.Many;
return Plural.Other;
case 'br':
if (n % 10 === 1 && !(n % 100 === 11 || n % 100 === 71 || n % 100 === 91))
return Plural.One;
if (n % 10 === 2 && !(n % 100 === 12 || n % 100 === 72 || n % 100 === 92))
return Plural.Two;
if (n % 10 === Math.floor(n % 10) && (n % 10 >= 3 && n % 10 <= 4 || n % 10 === 9) &&
!(n % 100 >= 10 && n % 100 <= 19 || n % 100 >= 70 && n % 100 <= 79 ||
n % 100 >= 90 && n % 100 <= 99))
return Plural.Few;
if (!(n === 0) && n % 1e6 === 0)
return Plural.Many;
return Plural.Other;
case 'bs':
case 'hr':
case 'sr':
if (v === 0 && i % 10 === 1 && !(i % 100 === 11) || f % 10 === 1 && !(f % 100 === 11))
return Plural.One;
if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
!(i % 100 >= 12 && i % 100 <= 14) ||
f % 10 === Math.floor(f % 10) && f % 10 >= 2 && f % 10 <= 4 &&
!(f % 100 >= 12 && f % 100 <= 14))
return Plural.Few;
return Plural.Other;
case 'cs':
case 'sk':
if (i === 1 && v === 0)
return Plural.One;
if (i === Math.floor(i) && i >= 2 && i <= 4 && v === 0)
return Plural.Few;
if (!(v === 0))
return Plural.Many;
return Plural.Other;
case 'cy':
if (n === 0)
return Plural.Zero;
if (n === 1)
return Plural.One;
if (n === 2)
return Plural.Two;
if (n === 3)
return Plural.Few;
if (n === 6)
return Plural.Many;
return Plural.Other;
case 'da':
if (n === 1 || !(t === 0) && (i === 0 || i === 1))
return Plural.One;
return Plural.Other;
case 'dsb':
case 'hsb':
if (v === 0 && i % 100 === 1 || f % 100 === 1)
return Plural.One;
if (v === 0 && i % 100 === 2 || f % 100 === 2)
return Plural.Two;
if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 ||
f % 100 === Math.floor(f % 100) && f % 100 >= 3 && f % 100 <= 4)
return Plural.Few;
return Plural.Other;
case 'ff':
case 'fr':
case 'hy':
case 'kab':
if (i === 0 || i === 1)
return Plural.One;
return Plural.Other;
case 'fil':
if (v === 0 && (i === 1 || i === 2 || i === 3) ||
v === 0 && !(i % 10 === 4 || i % 10 === 6 || i % 10 === 9) ||
!(v === 0) && !(f % 10 === 4 || f % 10 === 6 || f % 10 === 9))
return Plural.One;
return Plural.Other;
case 'ga':
if (n === 1)
return Plural.One;
if (n === 2)
return Plural.Two;
if (n === Math.floor(n) && n >= 3 && n <= 6)
return Plural.Few;
if (n === Math.floor(n) && n >= 7 && n <= 10)
return Plural.Many;
return Plural.Other;
case 'gd':
if (n === 1 || n === 11)
return Plural.One;
if (n === 2 || n === 12)
return Plural.Two;
if (n === Math.floor(n) && (n >= 3 && n <= 10 || n >= 13 && n <= 19))
return Plural.Few;
return Plural.Other;
case 'gv':
if (v === 0 && i % 10 === 1)
return Plural.One;
if (v === 0 && i % 10 === 2)
return Plural.Two;
if (v === 0 &&
(i % 100 === 0 || i % 100 === 20 || i % 100 === 40 || i % 100 === 60 || i % 100 === 80))
return Plural.Few;
if (!(v === 0))
return Plural.Many;
return Plural.Other;
case 'he':
if (i === 1 && v === 0)
return Plural.One;
if (i === 2 && v === 0)
return Plural.Two;
if (v === 0 && !(n >= 0 && n <= 10) && n % 10 === 0)
return Plural.Many;
return Plural.Other;
case 'is':
if (t === 0 && i % 10 === 1 && !(i % 100 === 11) || !(t === 0))
return Plural.One;
return Plural.Other;
case 'ksh':
if (n === 0)
return Plural.Zero;
if (n === 1)
return Plural.One;
return Plural.Other;
case 'kw':
case 'naq':
case 'se':
case 'smn':
if (n === 1)
return Plural.One;
if (n === 2)
return Plural.Two;
return Plural.Other;
case 'lag':
if (n === 0)
return Plural.Zero;
if ((i === 0 || i === 1) && !(n === 0))
return Plural.One;
return Plural.Other;
case 'lt':
if (n % 10 === 1 && !(n % 100 >= 11 && n % 100 <= 19))
return Plural.One;
if (n % 10 === Math.floor(n % 10) && n % 10 >= 2 && n % 10 <= 9 &&
!(n % 100 >= 11 && n % 100 <= 19))
return Plural.Few;
if (!(f === 0))
return Plural.Many;
return Plural.Other;
case 'lv':
case 'prg':
if (n % 10 === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19 ||
v === 2 && f % 100 === Math.floor(f % 100) && f % 100 >= 11 && f % 100 <= 19)
return Plural.Zero;
if (n % 10 === 1 && !(n % 100 === 11) || v === 2 && f % 10 === 1 && !(f % 100 === 11) ||
!(v === 2) && f % 10 === 1)
return Plural.One;
return Plural.Other;
case 'mk':
if (v === 0 && i % 10 === 1 || f % 10 === 1)
return Plural.One;
return Plural.Other;
case 'mt':
if (n === 1)
return Plural.One;
if (n === 0 || n % 100 === Math.floor(n % 100) && n % 100 >= 2 && n % 100 <= 10)
return Plural.Few;
if (n % 100 === Math.floor(n % 100) && n % 100 >= 11 && n % 100 <= 19)
return Plural.Many;
return Plural.Other;
case 'pl':
if (i === 1 && v === 0)
return Plural.One;
if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
!(i % 100 >= 12 && i % 100 <= 14))
return Plural.Few;
if (v === 0 && !(i === 1) && i % 10 === Math.floor(i % 10) && i % 10 >= 0 && i % 10 <= 1 ||
v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 ||
v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 12 && i % 100 <= 14)
return Plural.Many;
return Plural.Other;
case 'pt':
if (n === Math.floor(n) && n >= 0 && n <= 2 && !(n === 2))
return Plural.One;
return Plural.Other;
case 'ro':
if (i === 1 && v === 0)
return Plural.One;
if (!(v === 0) || n === 0 ||
!(n === 1) && n % 100 === Math.floor(n % 100) && n % 100 >= 1 && n % 100 <= 19)
return Plural.Few;
return Plural.Other;
case 'ru':
case 'uk':
if (v === 0 && i % 10 === 1 && !(i % 100 === 11))
return Plural.One;
if (v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 2 && i % 10 <= 4 &&
!(i % 100 >= 12 && i % 100 <= 14))
return Plural.Few;
if (v === 0 && i % 10 === 0 ||
v === 0 && i % 10 === Math.floor(i % 10) && i % 10 >= 5 && i % 10 <= 9 ||
v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 11 && i % 100 <= 14)
return Plural.Many;
return Plural.Other;
case 'shi':
if (i === 0 || n === 1)
return Plural.One;
if (n === Math.floor(n) && n >= 2 && n <= 10)
return Plural.Few;
return Plural.Other;
case 'si':
if (n === 0 || n === 1 || i === 0 && f === 1)
return Plural.One;
return Plural.Other;
case 'sl':
if (v === 0 && i % 100 === 1)
return Plural.One;
if (v === 0 && i % 100 === 2)
return Plural.Two;
if (v === 0 && i % 100 === Math.floor(i % 100) && i % 100 >= 3 && i % 100 <= 4 || !(v === 0))
return Plural.Few;
return Plural.Other;
case 'tzm':
if (n === Math.floor(n) && n >= 0 && n <= 1 || n === Math.floor(n) && n >= 11 && n <= 99)
return Plural.One;
return Plural.Other;
// When there is no specification, the default is always "other"
// Spec: http://cldr.unicode.org/index/cldr-spec/plural-rules
// > other (required—general plural form — also used if the language only has a single form)
default:
return Plural.Other;
}
}
function getPluralCategory(value, locale) {
var plural = getPluralCase(locale, value);
switch (plural) {
case Plural.Zero:
return 'zero';
case Plural.One:
return 'one';
case Plural.Two:
return 'two';
case Plural.Few:
return 'few';
case Plural.Many:
return 'many';
default:
return 'other';
}
}
/**
* Returns the index of the current case of an ICU expression depending on the main binding value
*
* @param icuExpression
* @param bindingValue The value of the main binding used by this ICU expression
*/
function getCaseIndex(icuExpression, bindingValue) {
var index = icuExpression.cases.indexOf(bindingValue);
if (index === -1) {
switch (icuExpression.type) {
case 1 /* plural */: {
// TODO(ocombe): replace this hard-coded value by the real LOCALE_ID value
var locale = 'en-US';
var resolvedCase = getPluralCategory(bindingValue, locale);
index = icuExpression.cases.indexOf(resolvedCase);
if (index === -1 && resolvedCase !== 'other') {
index = icuExpression.cases.indexOf('other');
}
break;
}
case 0 /* select */: {
index = icuExpression.cases.indexOf('other');
break;
}
}
}
return index;
}
/**
* Generate the OpCodes for ICU expressions.
*
* @param tIcus
* @param icuExpression
* @param startIndex
* @param expandoStartIndex
*/
function icuStart(tIcus, icuExpression, startIndex, expandoStartIndex) {
var createCodes = [];
var removeCodes = [];
var updateCodes = [];
var vars = [];
var childIcus = [];
for (var i = 0; i < icuExpression.values.length; i++) {
// Each value is an array of strings & other ICU expressions
var valueArr = icuExpression.values[i];
var nestedIcus = [];
for (var j = 0; j < valueArr.length; j++) {
var value = valueArr[j];
if (typeof value !== 'string') {
// It is an nested ICU expression
var icuIndex = nestedIcus.push(value) - 1;
// Replace nested ICU expression by a comment node
valueArr[j] = "<!--\uFFFD" + icuIndex + "\uFFFD-->";
}
}
var icuCase = parseIcuCase(valueArr.join(''), startIndex, nestedIcus, tIcus, expandoStartIndex);
createCodes.push(icuCase.create);
removeCodes.push(icuCase.remove);
updateCodes.push(icuCase.update);
vars.push(icuCase.vars);
childIcus.push(icuCase.childIcus);
}
var tIcu = {
type: icuExpression.type,
vars: vars,
expandoStartIndex: expandoStartIndex + 1, childIcus: childIcus,
cases: icuExpression.cases,
create: createCodes,
remove: removeCodes,
update: updateCodes
};
tIcus.push(tIcu);
var lView = getLView();
var worstCaseSize = Math.max.apply(Math, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(vars));
for (var i = 0; i < worstCaseSize; i++) {
allocExpando(lView);
}
}
/**
* Transforms a string template into an HTML template and a list of instructions used to update
* attributes or nodes that contain bindings.
*
* @param unsafeHtml The string to parse
* @param parentIndex
* @param nestedIcus
* @param tIcus
* @param expandoStartIndex
*/
function parseIcuCase(unsafeHtml, parentIndex, nestedIcus, tIcus, expandoStartIndex) {
var inertBodyHelper = new InertBodyHelper(document);
var inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
if (!inertBodyElement) {
throw new Error('Unable to generate inert body element');
}
var wrapper = getTemplateContent(inertBodyElement) || inertBodyElement;
var opCodes = { vars: 0, childIcus: [], create: [], remove: [], update: [] };
parseNodes(wrapper.firstChild, opCodes, parentIndex, nestedIcus, tIcus, expandoStartIndex);
return opCodes;
}
var NESTED_ICU = /�(\d+)�/;
/**
* Parses a node, its children and its siblings, and generates the mutate & update OpCodes.
*
* @param currentNode The first node to parse
* @param icuCase The data for the ICU expression case that contains those nodes
* @param parentIndex Index of the current node's parent
* @param nestedIcus Data for the nested ICU expressions that this case contains
* @param tIcus Data for all ICU expressions of the current message
* @param expandoStartIndex Expando start index for the current ICU expression
*/
function parseNodes(currentNode, icuCase, parentIndex, nestedIcus, tIcus, expandoStartIndex) {
if (currentNode) {
var nestedIcusToCreate = [];
while (currentNode) {
var nextNode = currentNode.nextSibling;
var newIndex = expandoStartIndex + ++icuCase.vars;
switch (currentNode.nodeType) {
case Node.ELEMENT_NODE:
var element$$1 = currentNode;
var tagName = element$$1.tagName.toLowerCase();
if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
// This isn't a valid element, we won't create an element for it
icuCase.vars--;
}
else {
icuCase.create.push(ELEMENT_MARKER, tagName, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
var elAttrs = element$$1.attributes;
for (var i = 0; i < elAttrs.length; i++) {
var attr = elAttrs.item(i);
var lowerAttrName = attr.name.toLowerCase();
var hasBinding_1 = !!attr.value.match(BINDING_REGEXP);
// we assume the input string is safe, unless it's using a binding
if (hasBinding_1) {
if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
if (URI_ATTRS[lowerAttrName]) {
addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name, _sanitizeUrl), icuCase.update);
}
else if (SRCSET_ATTRS[lowerAttrName]) {
addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name, sanitizeSrcset), icuCase.update);
}
else {
addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name), icuCase.update);
}
}
else {
ngDevMode &&
console.warn("WARNING: ignoring unsafe attribute value " + lowerAttrName + " on element " + tagName + " (see http://g.co/ng/security#xss)");
}
}
else {
icuCase.create.push(newIndex << 3 /* SHIFT_REF */ | 4 /* Attr */, attr.name, attr.value);
}
}
// Parse the children of this node (if any)
parseNodes(currentNode.firstChild, icuCase, newIndex, nestedIcus, tIcus, expandoStartIndex);
// Remove the parent node after the children
icuCase.remove.push(newIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
}
break;
case Node.TEXT_NODE:
var value = currentNode.textContent || '';
var hasBinding = value.match(BINDING_REGEXP);
icuCase.create.push(hasBinding ? '' : value, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
icuCase.remove.push(newIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
if (hasBinding) {
addAllToArray(generateBindingUpdateOpCodes(value, newIndex), icuCase.update);
}
break;
case Node.COMMENT_NODE:
// Check if the comment node is a placeholder for a nested ICU
var match = NESTED_ICU.exec(currentNode.textContent || '');
if (match) {
var nestedIcuIndex = parseInt(match[1], 10);
var newLocal = ngDevMode ? "nested ICU " + nestedIcuIndex : '';
// Create the comment node that will anchor the ICU expression
icuCase.create.push(COMMENT_MARKER, newLocal, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
var nestedIcu = nestedIcus[nestedIcuIndex];
nestedIcusToCreate.push([nestedIcu, newIndex]);
}
else {
// We do not handle any other type of comment
icuCase.vars--;
}
break;
default:
// We do not handle any other type of element
icuCase.vars--;
}
currentNode = nextNode;
}
for (var i = 0; i < nestedIcusToCreate.length; i++) {
var nestedIcu = nestedIcusToCreate[i][0];
var nestedIcuNodeIndex = nestedIcusToCreate[i][1];
icuStart(tIcus, nestedIcu, nestedIcuNodeIndex, expandoStartIndex + icuCase.vars);
// Since this is recursive, the last TIcu that was pushed is the one we want
var nestTIcuIndex = tIcus.length - 1;
icuCase.vars += Math.max.apply(Math, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(tIcus[nestTIcuIndex].vars));
icuCase.childIcus.push(nestTIcuIndex);
var mask = getBindingMask(nestedIcu);
icuCase.update.push(toMaskBit(nestedIcu.mainBinding), // mask of the main binding
3, // skip 3 opCodes if not changed
-1 - nestedIcu.mainBinding, nestedIcuNodeIndex << 2 /* SHIFT_REF */ | 2 /* IcuSwitch */, nestTIcuIndex, mask, // mask of all the bindings of this ICU expression
2, // skip 2 opCodes if not changed
nestedIcuNodeIndex << 2 /* SHIFT_REF */ | 3 /* IcuUpdate */, nestTIcuIndex);
icuCase.remove.push(nestTIcuIndex << 3 /* SHIFT_REF */ | 6 /* RemoveNestedIcu */, nestedIcuNodeIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
}
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var COMPONENT_FACTORY_RESOLVER = {
provide: ComponentFactoryResolver,
useClass: ComponentFactoryResolver$1,
deps: [NgModuleRef],
};
var NgModuleRef$1 = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(NgModuleRef$$1, _super);
function NgModuleRef$$1(ngModuleType, _parent) {
var _this = _super.call(this) || this;
_this._parent = _parent;
// tslint:disable-next-line:require-internal-with-underscore
_this._bootstrapComponents = [];
_this.injector = _this;
_this.destroyCbs = [];
var ngModuleDef = getNgModuleDef(ngModuleType);
ngDevMode && assertDefined(ngModuleDef, "NgModule '" + stringify(ngModuleType) + "' is not a subtype of 'NgModuleType'.");
_this._bootstrapComponents = ngModuleDef.bootstrap;
var additionalProviders = [
{
provide: NgModuleRef,
useValue: _this,
},
COMPONENT_FACTORY_RESOLVER
];
_this._r3Injector = createInjector(ngModuleType, _parent, additionalProviders);
_this.instance = _this.get(ngModuleType);
return _this;
}
NgModuleRef$$1.prototype.get = function (token, notFoundValue, injectFlags) {
if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
if (injectFlags === void 0) { injectFlags = InjectFlags.Default; }
if (token === Injector || token === NgModuleRef || token === INJECTOR$1) {
return this;
}
return this._r3Injector.get(token, notFoundValue, injectFlags);
};
Object.defineProperty(NgModuleRef$$1.prototype, "componentFactoryResolver", {
get: function () {
return this.get(ComponentFactoryResolver);
},
enumerable: true,
configurable: true
});
NgModuleRef$$1.prototype.destroy = function () {
ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
this.destroyCbs.forEach(function (fn) { return fn(); });
this.destroyCbs = null;
};
NgModuleRef$$1.prototype.onDestroy = function (callback) {
ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
this.destroyCbs.push(callback);
};
return NgModuleRef$$1;
}(NgModuleRef));
var NgModuleFactory$1 = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(NgModuleFactory$$1, _super);
function NgModuleFactory$$1(moduleType) {
var _this = _super.call(this) || this;
_this.moduleType = moduleType;
return _this;
}
NgModuleFactory$$1.prototype.create = function (parentInjector) {
return new NgModuleRef$1(this.moduleType, parentInjector);
};
return NgModuleFactory$$1;
}(NgModuleFactory));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Adds decorator, constructor, and property metadata to a given type via static metadata fields
* on the type.
*
* These metadata fields can later be read with Angular's `ReflectionCapabilities` API.
*
* Calls to `setClassMetadata` can be marked as pure, resulting in the metadata assignments being
* tree-shaken away during production builds.
*/
function setClassMetadata(type, decorators, ctorParameters, propDecorators) {
var _a;
var clazz = type;
if (decorators !== null) {
if (clazz.decorators !== undefined) {
(_a = clazz.decorators).push.apply(_a, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(decorators));
}
else {
clazz.decorators = decorators;
}
}
if (ctorParameters !== null) {
// Rather than merging, clobber the existing parameters. If other projects exist which use
// tsickle-style annotations and reflect over them in the same way, this could cause issues,
// but that is vanishingly unlikely.
clazz.ctorParameters = ctorParameters;
}
if (propDecorators !== null) {
// The property decorator objects are merged as it is possible different fields have different
// decorator types. Decorators on individual fields are not merged, as it's also incredibly
// unlikely that a field will be decorated both with an Angular decorator and a non-Angular
// decorator that's also been downleveled.
if (clazz.propDecorators !== undefined) {
clazz.propDecorators = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({}, clazz.propDecorators, propDecorators);
}
else {
clazz.propDecorators = propDecorators;
}
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Bindings for pure functions are stored after regular bindings.
*
* |------consts------|---------vars---------| |----- hostVars (dir1) ------|
* ------------------------------------------------------------------------------------------
* | nodes/refs/pipes | bindings | fn slots | injector | dir1 | host bindings | host slots |
* ------------------------------------------------------------------------------------------
* ^ ^
* TView.bindingStartIndex TView.expandoStartIndex
*
* Pure function instructions are given an offset from the binding root. Adding the offset to the
* binding root gives the first index where the bindings are stored. In component views, the binding
* root is the bindingStartIndex. In host bindings, the binding root is the expandoStartIndex +
* any directive instances + any hostVars in directives evaluated before it.
*
* See VIEW_DATA.md for more information about host binding resolution.
*/
/**
* If the value hasn't been saved, calls the pure function to store and return the
* value. If it has been saved, returns the saved value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn Function that returns a value
* @param thisArg Optional calling context of pureFn
* @returns value
*/
function pureFunction0(slotOffset, pureFn, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
return isCreationMode() ?
updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
getBinding(lView, bindingIndex);
}
/**
* If the value of the provided exp has changed, calls the pure function to return
* an updated value. Or if the value has not changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn Function that returns an updated value
* @param exp Updated expression value
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction1(slotOffset, pureFn, exp, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var lView = getLView();
var bindingIndex = getBindingRoot() + slotOffset;
return bindingUpdated(lView, bindingIndex, exp) ?
updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
getBinding(lView, bindingIndex + 1);
}
/**
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn
* @param exp1
* @param exp2
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction2(slotOffset, pureFn, exp1, exp2, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
updateBinding(lView, bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
getBinding(lView, bindingIndex + 2);
}
/**
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn
* @param exp1
* @param exp2
* @param exp3
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction3(slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
updateBinding(lView, bindingIndex + 3, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
getBinding(lView, bindingIndex + 3);
}
/**
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn
* @param exp1
* @param exp2
* @param exp3
* @param exp4
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction4(slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
updateBinding(lView, bindingIndex + 4, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
getBinding(lView, bindingIndex + 4);
}
/**
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn
* @param exp1
* @param exp2
* @param exp3
* @param exp4
* @param exp5
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction5(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated(lView, bindingIndex + 4, exp5) || different ?
updateBinding(lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
pureFn(exp1, exp2, exp3, exp4, exp5)) :
getBinding(lView, bindingIndex + 5);
}
/**
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn
* @param exp1
* @param exp2
* @param exp3
* @param exp4
* @param exp5
* @param exp6
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction6(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ?
updateBinding(lView, bindingIndex + 6, thisArg ?
pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) :
getBinding(lView, bindingIndex + 6);
}
/**
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn
* @param exp1
* @param exp2
* @param exp3
* @param exp4
* @param exp5
* @param exp6
* @param exp7
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction7(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ?
updateBinding(lView, bindingIndex + 7, thisArg ?
pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) :
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) :
getBinding(lView, bindingIndex + 7);
}
/**
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn
* @param exp1
* @param exp2
* @param exp3
* @param exp4
* @param exp5
* @param exp6
* @param exp7
* @param exp8
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunction8(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var lView = getLView();
var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
updateBinding(lView, bindingIndex + 8, thisArg ?
pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) :
pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) :
getBinding(lView, bindingIndex + 8);
}
/**
* pureFunction instruction that can support any number of bindings.
*
* If the value of any provided exp has changed, calls the pure function to return
* an updated value. Or if no values have changed, returns cached value.
*
* @param slotOffset the offset from binding root to the reserved slot
* @param pureFn A pure function that takes binding values and builds an object or array
* containing those values.
* @param exps An array of binding values
* @param thisArg Optional calling context of pureFn
* @returns Updated or cached value
*/
function pureFunctionV(slotOffset, pureFn, exps, thisArg) {
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
var bindingIndex = getBindingRoot() + slotOffset;
var different = false;
var lView = getLView();
for (var i = 0; i < exps.length; i++) {
bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
}
return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) :
getBinding(lView, bindingIndex);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Create a pipe.
*
* @param index Pipe index where the pipe will be stored.
* @param pipeName The name of the pipe
* @returns T the instance of the pipe.
*/
function pipe(index, pipeName) {
var tView = getLView()[TVIEW];
var pipeDef;
var adjustedIndex = index + HEADER_OFFSET;
if (tView.firstTemplatePass) {
pipeDef = getPipeDef$1(pipeName, tView.pipeRegistry);
tView.data[adjustedIndex] = pipeDef;
if (pipeDef.onDestroy) {
(tView.pipeDestroyHooks || (tView.pipeDestroyHooks = [])).push(adjustedIndex, pipeDef.onDestroy);
}
}
else {
pipeDef = tView.data[adjustedIndex];
}
var pipeInstance = pipeDef.factory(null);
store(index, pipeInstance);
return pipeInstance;
}
/**
* Searches the pipe registry for a pipe with the given name. If one is found,
* returns the pipe. Otherwise, an error is thrown because the pipe cannot be resolved.
*
* @param name Name of pipe to resolve
* @param registry Full list of available pipes
* @returns Matching PipeDef
*/
function getPipeDef$1(name, registry) {
if (registry) {
for (var i = registry.length - 1; i >= 0; i--) {
var pipeDef = registry[i];
if (name === pipeDef.name) {
return pipeDef;
}
}
}
throw new Error("The pipe '" + name + "' could not be found!");
}
/**
* Invokes a pipe with 1 arguments.
*
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
* the pipe only when an input to the pipe changes.
*
* @param index Pipe index where the pipe was stored on creation.
* @param slotOffset the offset in the reserved slot space
* @param v1 1st argument to {@link PipeTransform#transform}.
*/
function pipeBind1(index, slotOffset, v1) {
var pipeInstance = load(index);
return unwrapValue(isPure(index) ? pureFunction1(slotOffset, pipeInstance.transform, v1, pipeInstance) :
pipeInstance.transform(v1));
}
/**
* Invokes a pipe with 2 arguments.
*
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
* the pipe only when an input to the pipe changes.
*
* @param index Pipe index where the pipe was stored on creation.
* @param slotOffset the offset in the reserved slot space
* @param v1 1st argument to {@link PipeTransform#transform}.
* @param v2 2nd argument to {@link PipeTransform#transform}.
*/
function pipeBind2(index, slotOffset, v1, v2) {
var pipeInstance = load(index);
return unwrapValue(isPure(index) ? pureFunction2(slotOffset, pipeInstance.transform, v1, v2, pipeInstance) :
pipeInstance.transform(v1, v2));
}
/**
* Invokes a pipe with 3 arguments.
*
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
* the pipe only when an input to the pipe changes.
*
* @param index Pipe index where the pipe was stored on creation.
* @param slotOffset the offset in the reserved slot space
* @param v1 1st argument to {@link PipeTransform#transform}.
* @param v2 2nd argument to {@link PipeTransform#transform}.
* @param v3 4rd argument to {@link PipeTransform#transform}.
*/
function pipeBind3(index, slotOffset, v1, v2, v3) {
var pipeInstance = load(index);
return unwrapValue(isPure(index) ? pureFunction3(slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) :
pipeInstance.transform(v1, v2, v3));
}
/**
* Invokes a pipe with 4 arguments.
*
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
* the pipe only when an input to the pipe changes.
*
* @param index Pipe index where the pipe was stored on creation.
* @param slotOffset the offset in the reserved slot space
* @param v1 1st argument to {@link PipeTransform#transform}.
* @param v2 2nd argument to {@link PipeTransform#transform}.
* @param v3 3rd argument to {@link PipeTransform#transform}.
* @param v4 4th argument to {@link PipeTransform#transform}.
*/
function pipeBind4(index, slotOffset, v1, v2, v3, v4) {
var pipeInstance = load(index);
return unwrapValue(isPure(index) ?
pureFunction4(slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) :
pipeInstance.transform(v1, v2, v3, v4));
}
/**
* Invokes a pipe with variable number of arguments.
*
* This instruction acts as a guard to {@link PipeTransform#transform} invoking
* the pipe only when an input to the pipe changes.
*
* @param index Pipe index where the pipe was stored on creation.
* @param slotOffset the offset in the reserved slot space
* @param values Array of arguments to pass to {@link PipeTransform#transform} method.
*/
function pipeBindV(index, slotOffset, values) {
var pipeInstance = load(index);
return unwrapValue(isPure(index) ? pureFunctionV(slotOffset, pipeInstance.transform, values, pipeInstance) :
pipeInstance.transform.apply(pipeInstance, values));
}
function isPure(index) {
return getLView()[TVIEW].data[index + HEADER_OFFSET].pure;
}
/**
* Unwrap the output of a pipe transformation.
* In order to trick change detection into considering that the new value is always different from
* the old one, the old value is overwritten by NO_CHANGE.
*
* @param newValue the pipe transformation output.
*/
function unwrapValue(newValue) {
if (WrappedValue.isWrapped(newValue)) {
newValue = WrappedValue.unwrap(newValue);
getLView()[getBindingRoot()] = NO_CHANGE;
}
return newValue;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Use in directives and components to emit custom events synchronously
* or asynchronously, and register handlers for those events by subscribing
* to an instance.
*
* @usageNotes
*
* In the following example, a component defines two output properties
* that create event emitters. When the title is clicked, the emitter
* emits an open or close event to toggle the current visibility state.
*
* ```
* @Component({
* selector: 'zippy',
* template: `
* <div class="zippy">
* <div (click)="toggle()">Toggle</div>
* <div [hidden]="!visible">
* <ng-content></ng-content>
* </div>
* </div>`})
* export class Zippy {
* visible: boolean = true;
* @Output() open: EventEmitter<any> = new EventEmitter();
* @Output() close: EventEmitter<any> = new EventEmitter();
*
* toggle() {
* this.visible = !this.visible;
* if (this.visible) {
* this.open.emit(null);
* } else {
* this.close.emit(null);
* }
* }
* }
* ```
*
* Access the event object with the `$event` argument passed to the output event
* handler:
*
* ```
* <zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>
* ```
*
* ### Notes
*
* Uses Rx.Observable but provides an adapter to make it work as specified here:
* https://github.com/jhusain/observable-spec
*
* Once a reference implementation of the spec is available, switch to it.
*
* @publicApi
*/
var EventEmitter = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(EventEmitter, _super);
/**
* Creates an instance of this class that can
* deliver events synchronously or asynchronously.
*
* @param isAsync When true, deliver events asynchronously.
*
*/
function EventEmitter(isAsync) {
if (isAsync === void 0) { isAsync = false; }
var _this = _super.call(this) || this;
_this.__isAsync = isAsync;
return _this;
}
/**
* Emits an event containing a given value.
* @param value The value to emit.
*/
EventEmitter.prototype.emit = function (value) { _super.prototype.next.call(this, value); };
/**
* Registers handlers for events emitted by this instance.
* @param generatorOrNext When supplied, a custom handler for emitted events.
* @param error When supplied, a custom handler for an error notification
* from this emitter.
* @param complete When supplied, a custom handler for a completion
* notification from this emitter.
*/
EventEmitter.prototype.subscribe = function (generatorOrNext, error, complete) {
var schedulerFn;
var errorFn = function (err) { return null; };
var completeFn = function () { return null; };
if (generatorOrNext && typeof generatorOrNext === 'object') {
schedulerFn = this.__isAsync ? function (value) {
setTimeout(function () { return generatorOrNext.next(value); });
} : function (value) { generatorOrNext.next(value); };
if (generatorOrNext.error) {
errorFn = this.__isAsync ? function (err) { setTimeout(function () { return generatorOrNext.error(err); }); } :
function (err) { generatorOrNext.error(err); };
}
if (generatorOrNext.complete) {
completeFn = this.__isAsync ? function () { setTimeout(function () { return generatorOrNext.complete(); }); } :
function () { generatorOrNext.complete(); };
}
}
else {
schedulerFn = this.__isAsync ? function (value) { setTimeout(function () { return generatorOrNext(value); }); } :
function (value) { generatorOrNext(value); };
if (error) {
errorFn =
this.__isAsync ? function (err) { setTimeout(function () { return error(err); }); } : function (err) { error(err); };
}
if (complete) {
completeFn =
this.__isAsync ? function () { setTimeout(function () { return complete(); }); } : function () { complete(); };
}
}
var sink = _super.prototype.subscribe.call(this, schedulerFn, errorFn, completeFn);
if (generatorOrNext instanceof rxjs__WEBPACK_IMPORTED_MODULE_1__["Subscription"]) {
generatorOrNext.add(sink);
}
return sink;
};
return EventEmitter;
}(rxjs__WEBPACK_IMPORTED_MODULE_1__["Subject"]));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Represents an embedded template that can be used to instantiate embedded views.
* To instantiate embedded views based on a template, use the `ViewContainerRef`
* method `createEmbeddedView()`.
*
* Access a `TemplateRef` instance by placing a directive on an `<ng-template>`
* element (or directive prefixed with `*`). The `TemplateRef` for the embedded view
* is injected into the constructor of the directive,
* using the `TemplateRef` token.
*
* You can also use a `Query` to find a `TemplateRef` associated with
* a component or a directive.
*
* @see `ViewContainerRef`
* @see [Navigate the Component Tree with DI](guide/dependency-injection-navtree)
*
* @publicApi
*/
var TemplateRef = /** @class */ (function () {
function TemplateRef() {
}
/** @internal */
TemplateRef.__NG_ELEMENT_ID__ = function () { return SWITCH_TEMPLATE_REF_FACTORY(TemplateRef, ElementRef); };
return TemplateRef;
}());
var SWITCH_TEMPLATE_REF_FACTORY__POST_R3__ = injectTemplateRef;
var SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__ = noop;
var SWITCH_TEMPLATE_REF_FACTORY = SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var LQueries_ = /** @class */ (function () {
function LQueries_(parent, shallow, deep) {
this.parent = parent;
this.shallow = shallow;
this.deep = deep;
}
LQueries_.prototype.track = function (queryList, predicate, descend, read) {
if (descend) {
this.deep = createQuery(this.deep, queryList, predicate, read != null ? read : null);
}
else {
this.shallow = createQuery(this.shallow, queryList, predicate, read != null ? read : null);
}
};
LQueries_.prototype.clone = function () { return new LQueries_(this, null, this.deep); };
LQueries_.prototype.container = function () {
var shallowResults = copyQueriesToContainer(this.shallow);
var deepResults = copyQueriesToContainer(this.deep);
return shallowResults || deepResults ? new LQueries_(this, shallowResults, deepResults) : null;
};
LQueries_.prototype.createView = function () {
var shallowResults = copyQueriesToView(this.shallow);
var deepResults = copyQueriesToView(this.deep);
return shallowResults || deepResults ? new LQueries_(this, shallowResults, deepResults) : null;
};
LQueries_.prototype.insertView = function (index) {
insertView$1(index, this.shallow);
insertView$1(index, this.deep);
};
LQueries_.prototype.addNode = function (tNode) {
add(this.deep, tNode);
if (isContentQueryHost(tNode)) {
add(this.shallow, tNode);
if (tNode.parent && isContentQueryHost(tNode.parent)) {
// if node has a content query and parent also has a content query
// both queries need to check this node for shallow matches
add(this.parent.shallow, tNode);
}
return this.parent;
}
isRootNodeOfQuery(tNode) && add(this.shallow, tNode);
return this;
};
LQueries_.prototype.removeView = function () {
removeView$1(this.shallow);
removeView$1(this.deep);
};
return LQueries_;
}());
function isRootNodeOfQuery(tNode) {
return tNode.parent === null || isContentQueryHost(tNode.parent);
}
function copyQueriesToContainer(query) {
var result = null;
while (query) {
var containerValues = []; // prepare room for views
query.values.push(containerValues);
var clonedQuery = {
next: result,
list: query.list,
predicate: query.predicate,
values: containerValues,
containerValues: null
};
result = clonedQuery;
query = query.next;
}
return result;
}
function copyQueriesToView(query) {
var result = null;
while (query) {
var clonedQuery = {
next: result,
list: query.list,
predicate: query.predicate,
values: [],
containerValues: query.values
};
result = clonedQuery;
query = query.next;
}
return result;
}
function insertView$1(index, query) {
while (query) {
ngDevMode &&
assertDefined(query.containerValues, 'View queries need to have a pointer to container values.');
query.containerValues.splice(index, 0, query.values);
query = query.next;
}
}
function removeView$1(query) {
while (query) {
ngDevMode &&
assertDefined(query.containerValues, 'View queries need to have a pointer to container values.');
var containerValues = query.containerValues;
var viewValuesIdx = containerValues.indexOf(query.values);
var removed = containerValues.splice(viewValuesIdx, 1);
// mark a query as dirty only when removed view had matching modes
ngDevMode && assertEqual(removed.length, 1, 'removed.length');
if (removed[0].length) {
query.list.setDirty();
}
query = query.next;
}
}
/**
* Iterates over local names for a given node and returns directive index
* (or -1 if a local name points to an element).
*
* @param tNode static data of a node to check
* @param selector selector to match
* @returns directive index, -1 or null if a selector didn't match any of the local names
*/
function getIdxOfMatchingSelector(tNode, selector) {
var localNames = tNode.localNames;
if (localNames) {
for (var i = 0; i < localNames.length; i += 2) {
if (localNames[i] === selector) {
return localNames[i + 1];
}
}
}
return null;
}
// TODO: "read" should be an AbstractType (FW-486)
function queryByReadToken(read, tNode, currentView) {
var factoryFn = read[NG_ELEMENT_ID];
if (typeof factoryFn === 'function') {
return factoryFn();
}
else {
var matchingIdx = locateDirectiveOrProvider(tNode, currentView, read, false, false);
if (matchingIdx !== null) {
return getNodeInjectable(currentView[TVIEW].data, currentView, matchingIdx, tNode);
}
}
return null;
}
function queryByTNodeType(tNode, currentView) {
if (tNode.type === 3 /* Element */ || tNode.type === 4 /* ElementContainer */) {
return createElementRef(ElementRef, tNode, currentView);
}
if (tNode.type === 0 /* Container */) {
return createTemplateRef(TemplateRef, ElementRef, tNode, currentView);
}
return null;
}
function queryByTemplateRef(templateRefToken, tNode, currentView, read) {
var templateRefResult = templateRefToken[NG_ELEMENT_ID]();
if (read) {
return templateRefResult ? queryByReadToken(read, tNode, currentView) : null;
}
return templateRefResult;
}
function queryRead(tNode, currentView, read, matchingIdx) {
if (read) {
return queryByReadToken(read, tNode, currentView);
}
if (matchingIdx > -1) {
return getNodeInjectable(currentView[TVIEW].data, currentView, matchingIdx, tNode);
}
// if read token and / or strategy is not specified,
// detect it using appropriate tNode type
return queryByTNodeType(tNode, currentView);
}
function add(query, tNode) {
var currentView = getLView();
while (query) {
var predicate = query.predicate;
var type = predicate.type;
if (type) {
var result = null;
if (type === TemplateRef) {
result = queryByTemplateRef(type, tNode, currentView, predicate.read);
}
else {
var matchingIdx = locateDirectiveOrProvider(tNode, currentView, type, false, false);
if (matchingIdx !== null) {
result = queryRead(tNode, currentView, predicate.read, matchingIdx);
}
}
if (result !== null) {
addMatch(query, result);
}
}
else {
var selector = predicate.selector;
for (var i = 0; i < selector.length; i++) {
var matchingIdx = getIdxOfMatchingSelector(tNode, selector[i]);
if (matchingIdx !== null) {
var result = queryRead(tNode, currentView, predicate.read, matchingIdx);
if (result !== null) {
addMatch(query, result);
}
}
}
}
query = query.next;
}
}
function addMatch(query, matchingValue) {
query.values.push(matchingValue);
query.list.setDirty();
}
function createPredicate(predicate, read) {
var isArray = Array.isArray(predicate);
return {
type: isArray ? null : predicate,
selector: isArray ? predicate : null,
read: read
};
}
function createQuery(previous, queryList, predicate, read) {
return {
next: previous,
list: queryList,
predicate: createPredicate(predicate, read),
values: queryList._valuesTree,
containerValues: null
};
}
var QueryList_ = /** @class */ (function () {
function QueryList_() {
this.dirty = true;
this.changes = new EventEmitter();
this._values = [];
/** @internal */
this._valuesTree = [];
}
Object.defineProperty(QueryList_.prototype, "length", {
get: function () { return this._values.length; },
enumerable: true,
configurable: true
});
Object.defineProperty(QueryList_.prototype, "first", {
get: function () {
var values = this._values;
return values.length ? values[0] : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(QueryList_.prototype, "last", {
get: function () {
var values = this._values;
return values.length ? values[values.length - 1] : null;
},
enumerable: true,
configurable: true
});
/**
* See
* [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
*/
QueryList_.prototype.map = function (fn) { return this._values.map(fn); };
/**
* See
* [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
*/
QueryList_.prototype.filter = function (fn) {
return this._values.filter(fn);
};
/**
* See
* [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
*/
QueryList_.prototype.find = function (fn) {
return this._values.find(fn);
};
/**
* See
* [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
*/
QueryList_.prototype.reduce = function (fn, init) {
return this._values.reduce(fn, init);
};
/**
* See
* [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
*/
QueryList_.prototype.forEach = function (fn) { this._values.forEach(fn); };
/**
* See
* [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
*/
QueryList_.prototype.some = function (fn) {
return this._values.some(fn);
};
QueryList_.prototype.toArray = function () { return this._values.slice(0); };
QueryList_.prototype[getSymbolIterator()] = function () { return this._values[getSymbolIterator()](); };
QueryList_.prototype.toString = function () { return this._values.toString(); };
QueryList_.prototype.reset = function (res) {
this._values = flatten(res);
this.dirty = false;
};
QueryList_.prototype.notifyOnChanges = function () { this.changes.emit(this); };
QueryList_.prototype.setDirty = function () { this.dirty = true; };
QueryList_.prototype.destroy = function () {
this.changes.complete();
this.changes.unsubscribe();
};
return QueryList_;
}());
var QueryList = QueryList_;
/**
* Creates and returns a QueryList.
*
* @param memoryIndex The index in memory where the QueryList should be saved. If null,
* this is is a content query and the QueryList will be saved later through directiveCreate.
* @param predicate The type for which the query will search
* @param descend Whether or not to descend into children
* @param read What to save in the query
* @returns QueryList<T>
*/
function query(memoryIndex, predicate, descend,
// TODO: "read" should be an AbstractType (FW-486)
read) {
ngDevMode && assertPreviousIsParent(getIsParent());
var queryList = new QueryList();
var queries = getOrCreateCurrentQueries(LQueries_);
queries.track(queryList, predicate, descend, read);
storeCleanupWithContext(getLView(), queryList, queryList.destroy);
if (memoryIndex != null) {
store(memoryIndex, queryList);
}
return queryList;
}
/**
* Refreshes a query by combining matches from all active views and removing matches from deleted
* views.
* Returns true if a query got dirty during change detection, false otherwise.
*/
function queryRefresh(queryList) {
var queryListImpl = queryList;
if (queryList.dirty) {
queryList.reset(queryListImpl._valuesTree);
queryList.notifyOnChanges();
return true;
}
return false;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
* `<ng-template>` element.
*/
function templateRefExtractor(tNode, currentView) {
return createTemplateRef(TemplateRef, ElementRef, tNode, currentView);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var BRAND = '__SANITIZER_TRUSTED_BRAND__';
function allowSanitizationBypass(value, type) {
return (value instanceof String && value[BRAND] === type);
}
/**
* Mark `html` string as trusted.
*
* This function wraps the trusted string in `String` and brands it in a way which makes it
* recognizable to {@link htmlSanitizer} to be trusted implicitly.
*
* @param trustedHtml `html` string which needs to be implicitly trusted.
* @returns a `html` `String` which has been branded to be implicitly trusted.
*/
function bypassSanitizationTrustHtml(trustedHtml) {
return bypassSanitizationTrustString(trustedHtml, "Html" /* Html */);
}
/**
* Mark `style` string as trusted.
*
* This function wraps the trusted string in `String` and brands it in a way which makes it
* recognizable to {@link styleSanitizer} to be trusted implicitly.
*
* @param trustedStyle `style` string which needs to be implicitly trusted.
* @returns a `style` `String` which has been branded to be implicitly trusted.
*/
function bypassSanitizationTrustStyle(trustedStyle) {
return bypassSanitizationTrustString(trustedStyle, "Style" /* Style */);
}
/**
* Mark `script` string as trusted.
*
* This function wraps the trusted string in `String` and brands it in a way which makes it
* recognizable to {@link scriptSanitizer} to be trusted implicitly.
*
* @param trustedScript `script` string which needs to be implicitly trusted.
* @returns a `script` `String` which has been branded to be implicitly trusted.
*/
function bypassSanitizationTrustScript(trustedScript) {
return bypassSanitizationTrustString(trustedScript, "Script" /* Script */);
}
/**
* Mark `url` string as trusted.
*
* This function wraps the trusted string in `String` and brands it in a way which makes it
* recognizable to {@link urlSanitizer} to be trusted implicitly.
*
* @param trustedUrl `url` string which needs to be implicitly trusted.
* @returns a `url` `String` which has been branded to be implicitly trusted.
*/
function bypassSanitizationTrustUrl(trustedUrl) {
return bypassSanitizationTrustString(trustedUrl, "Url" /* Url */);
}
/**
* Mark `url` string as trusted.
*
* This function wraps the trusted string in `String` and brands it in a way which makes it
* recognizable to {@link resourceUrlSanitizer} to be trusted implicitly.
*
* @param trustedResourceUrl `url` string which needs to be implicitly trusted.
* @returns a `url` `String` which has been branded to be implicitly trusted.
*/
function bypassSanitizationTrustResourceUrl(trustedResourceUrl) {
return bypassSanitizationTrustString(trustedResourceUrl, "ResourceUrl" /* ResourceUrl */);
}
function bypassSanitizationTrustString(trustedString, mode) {
var trusted = new String(trustedString);
trusted[BRAND] = mode;
return trusted;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Regular expression for safe style values.
*
* Quotes (" and ') are allowed, but a check must be done elsewhere to ensure they're balanced.
*
* ',' allows multiple values to be assigned to the same property (e.g. background-attachment or
* font-family) and hence could allow multiple values to get injected, but that should pose no risk
* of XSS.
*
* The function expression checks only for XSS safety, not for CSS validity.
*
* This regular expression was taken from the Closure sanitization library, and augmented for
* transformation values.
*/
var VALUES = '[-,."\'%_!# a-zA-Z0-9]+';
var TRANSFORMATION_FNS = '(?:matrix|translate|scale|rotate|skew|perspective)(?:X|Y|3d)?';
var COLOR_FNS = '(?:rgb|hsl)a?';
var GRADIENTS = '(?:repeating-)?(?:linear|radial)-gradient';
var CSS3_FNS = '(?:calc|attr)';
var FN_ARGS = '\\([-0-9.%, #a-zA-Z]+\\)';
var SAFE_STYLE_VALUE = new RegExp("^(" + VALUES + "|" +
("(?:" + TRANSFORMATION_FNS + "|" + COLOR_FNS + "|" + GRADIENTS + "|" + CSS3_FNS + ")") +
(FN_ARGS + ")$"), 'g');
/**
* Matches a `url(...)` value with an arbitrary argument as long as it does
* not contain parentheses.
*
* The URL value still needs to be sanitized separately.
*
* `url(...)` values are a very common use case, e.g. for `background-image`. With carefully crafted
* CSS style rules, it is possible to construct an information leak with `url` values in CSS, e.g.
* by observing whether scroll bars are displayed, or character ranges used by a font face
* definition.
*
* Angular only allows binding CSS values (as opposed to entire CSS rules), so it is unlikely that
* binding a URL value without further cooperation from the page will cause an information leak, and
* if so, it is just a leak, not a full blown XSS vulnerability.
*
* Given the common use case, low likelihood of attack vector, and low impact of an attack, this
* code is permissive and allows URLs that sanitize otherwise.
*/
var URL_RE = /^url\(([^)]+)\)$/;
/**
* Checks that quotes (" and ') are properly balanced inside a string. Assumes
* that neither escape (\) nor any other character that could result in
* breaking out of a string parsing context are allowed;
* see http://www.w3.org/TR/css3-syntax/#string-token-diagram.
*
* This code was taken from the Closure sanitization library.
*/
function hasBalancedQuotes(value) {
var outsideSingle = true;
var outsideDouble = true;
for (var i = 0; i < value.length; i++) {
var c = value.charAt(i);
if (c === '\'' && outsideDouble) {
outsideSingle = !outsideSingle;
}
else if (c === '"' && outsideSingle) {
outsideDouble = !outsideDouble;
}
}
return outsideSingle && outsideDouble;
}
/**
* Sanitizes the given untrusted CSS style property value (i.e. not an entire object, just a single
* value) and returns a value that is safe to use in a browser environment.
*/
function _sanitizeStyle(value) {
value = String(value).trim(); // Make sure it's actually a string.
if (!value)
return '';
// Single url(...) values are supported, but only for URLs that sanitize cleanly. See above for
// reasoning behind this.
var urlMatch = value.match(URL_RE);
if ((urlMatch && _sanitizeUrl(urlMatch[1]) === urlMatch[1]) ||
value.match(SAFE_STYLE_VALUE) && hasBalancedQuotes(value)) {
return value; // Safe style values.
}
if (isDevMode()) {
console.warn("WARNING: sanitizing unsafe style value " + value + " (see http://g.co/ng/security#xss).");
}
return 'unsafe';
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
* dangerous content.
*
* This method parses the `html` and locates potentially dangerous content (such as urls and
* javascript) and removes it.
*
* It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustHtml}.
*
* @param unsafeHtml untrusted `html`, typically from the user.
* @returns `html` string which is safe to display to user, because all of the dangerous javascript
* and urls have been removed.
*/
function sanitizeHtml(unsafeHtml) {
var sanitizer = getSanitizer();
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.HTML, unsafeHtml) || '';
}
if (allowSanitizationBypass(unsafeHtml, "Html" /* Html */)) {
return unsafeHtml.toString();
}
return _sanitizeHtml(document, stringify$1(unsafeHtml));
}
/**
* A `style` sanitizer which converts untrusted `style` **string** into trusted string by removing
* dangerous content.
*
* This method parses the `style` and locates potentially dangerous content (such as urls and
* javascript) and removes it.
*
* It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustStyle}.
*
* @param unsafeStyle untrusted `style`, typically from the user.
* @returns `style` string which is safe to bind to the `style` properties, because all of the
* dangerous javascript and urls have been removed.
*/
function sanitizeStyle(unsafeStyle) {
var sanitizer = getSanitizer();
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.STYLE, unsafeStyle) || '';
}
if (allowSanitizationBypass(unsafeStyle, "Style" /* Style */)) {
return unsafeStyle.toString();
}
return _sanitizeStyle(stringify$1(unsafeStyle));
}
/**
* A `url` sanitizer which converts untrusted `url` **string** into trusted string by removing
* dangerous
* content.
*
* This method parses the `url` and locates potentially dangerous content (such as javascript) and
* removes it.
*
* It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustUrl}.
*
* @param unsafeUrl untrusted `url`, typically from the user.
* @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
* all of the dangerous javascript has been removed.
*/
function sanitizeUrl(unsafeUrl) {
var sanitizer = getSanitizer();
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.URL, unsafeUrl) || '';
}
if (allowSanitizationBypass(unsafeUrl, "Url" /* Url */)) {
return unsafeUrl.toString();
}
return _sanitizeUrl(stringify$1(unsafeUrl));
}
/**
* A `url` sanitizer which only lets trusted `url`s through.
*
* This passes only `url`s marked trusted by calling {@link bypassSanitizationTrustResourceUrl}.
*
* @param unsafeResourceUrl untrusted `url`, typically from the user.
* @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
* only trusted `url`s have been allowed to pass.
*/
function sanitizeResourceUrl(unsafeResourceUrl) {
var sanitizer = getSanitizer();
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '';
}
if (allowSanitizationBypass(unsafeResourceUrl, "ResourceUrl" /* ResourceUrl */)) {
return unsafeResourceUrl.toString();
}
throw new Error('unsafe value used in a resource URL context (see http://g.co/ng/security#xss)');
}
/**
* A `script` sanitizer which only lets trusted javascript through.
*
* This passes only `script`s marked trusted by calling {@link
* bypassSanitizationTrustScript}.
*
* @param unsafeScript untrusted `script`, typically from the user.
* @returns `url` string which is safe to bind to the `<script>` element such as `<img src>`,
* because only trusted `scripts` have been allowed to pass.
*/
function sanitizeScript(unsafeScript) {
var sanitizer = getSanitizer();
if (sanitizer) {
return sanitizer.sanitize(SecurityContext.SCRIPT, unsafeScript) || '';
}
if (allowSanitizationBypass(unsafeScript, "Script" /* Script */)) {
return unsafeScript.toString();
}
throw new Error('unsafe value used in a script context');
}
/**
* The default style sanitizer will handle sanitization for style properties by
* sanitizing any CSS property that can include a `url` value (usually image-based properties)
*/
var defaultStyleSanitizer = function (prop, value) {
if (value === undefined) {
return prop === 'background-image' || prop === 'background' || prop === 'border-image' ||
prop === 'filter' || prop === 'filter' || prop === 'list-style' ||
prop === 'list-style-image';
}
return sanitizeStyle(value);
};
function getSanitizer() {
var lView = getLView();
return lView && lView[SANITIZER];
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
*
* This should be kept up to date with the public exports of @angular/core.
*/
var angularCoreEnv = {
'ɵdefineBase': defineBase,
'ɵdefineComponent': defineComponent,
'ɵdefineDirective': defineDirective,
'defineInjectable': defineInjectable,
'defineInjector': defineInjector,
'ɵdefineNgModule': defineNgModule,
'ɵdefinePipe': definePipe,
'ɵdirectiveInject': directiveInject,
'ɵgetFactoryOf': getFactoryOf,
'ɵgetInheritedFactory': getInheritedFactory,
'inject': inject,
'ɵinjectAttribute': injectAttribute,
'ɵtemplateRefExtractor': templateRefExtractor,
'ɵNgOnChangesFeature': NgOnChangesFeature,
'ɵProvidersFeature': ProvidersFeature,
'ɵInheritDefinitionFeature': InheritDefinitionFeature,
'ɵelementAttribute': elementAttribute,
'ɵbind': bind,
'ɵcontainer': container,
'ɵnextContext': nextContext,
'ɵcontainerRefreshStart': containerRefreshStart,
'ɵcontainerRefreshEnd': containerRefreshEnd,
'ɵloadQueryList': loadQueryList,
'ɵnamespaceHTML': namespaceHTML,
'ɵnamespaceMathML': namespaceMathML,
'ɵnamespaceSVG': namespaceSVG,
'ɵenableBindings': enableBindings,
'ɵdisableBindings': disableBindings,
'ɵallocHostVars': allocHostVars,
'ɵelementStart': elementStart,
'ɵelementEnd': elementEnd,
'ɵelement': element,
'ɵelementContainerStart': elementContainerStart,
'ɵelementContainerEnd': elementContainerEnd,
'ɵpureFunction0': pureFunction0,
'ɵpureFunction1': pureFunction1,
'ɵpureFunction2': pureFunction2,
'ɵpureFunction3': pureFunction3,
'ɵpureFunction4': pureFunction4,
'ɵpureFunction5': pureFunction5,
'ɵpureFunction6': pureFunction6,
'ɵpureFunction7': pureFunction7,
'ɵpureFunction8': pureFunction8,
'ɵpureFunctionV': pureFunctionV,
'ɵgetCurrentView': getCurrentView,
'ɵrestoreView': restoreView,
'ɵinterpolation1': interpolation1,
'ɵinterpolation2': interpolation2,
'ɵinterpolation3': interpolation3,
'ɵinterpolation4': interpolation4,
'ɵinterpolation5': interpolation5,
'ɵinterpolation6': interpolation6,
'ɵinterpolation7': interpolation7,
'ɵinterpolation8': interpolation8,
'ɵinterpolationV': interpolationV,
'ɵelementClassProp': elementClassProp,
'ɵlistener': listener,
'ɵload': load,
'ɵprojection': projection,
'ɵelementProperty': elementProperty,
'ɵcomponentHostSyntheticProperty': componentHostSyntheticProperty,
'ɵpipeBind1': pipeBind1,
'ɵpipeBind2': pipeBind2,
'ɵpipeBind3': pipeBind3,
'ɵpipeBind4': pipeBind4,
'ɵpipeBindV': pipeBindV,
'ɵprojectionDef': projectionDef,
'ɵpipe': pipe,
'ɵquery': query,
'ɵqueryRefresh': queryRefresh,
'ɵregisterContentQuery': registerContentQuery,
'ɵreference': reference,
'ɵelementStyling': elementStyling,
'ɵelementHostAttrs': elementHostAttrs,
'ɵelementStylingMap': elementStylingMap,
'ɵelementStyleProp': elementStyleProp,
'ɵelementStylingApply': elementStylingApply,
'ɵtemplate': template,
'ɵtext': text,
'ɵtextBinding': textBinding,
'ɵembeddedViewStart': embeddedViewStart,
'ɵembeddedViewEnd': embeddedViewEnd,
'ɵi18n': i18n,
'ɵi18nAttributes': i18nAttributes,
'ɵi18nExp': i18nExp,
'ɵi18nStart': i18nStart,
'ɵi18nEnd': i18nEnd,
'ɵi18nApply': i18nApply,
'ɵi18nPostprocess': i18nPostprocess,
'ɵsanitizeHtml': sanitizeHtml,
'ɵsanitizeStyle': sanitizeStyle,
'ɵdefaultStyleSanitizer': defaultStyleSanitizer,
'ɵsanitizeResourceUrl': sanitizeResourceUrl,
'ɵsanitizeScript': sanitizeScript,
'ɵsanitizeUrl': sanitizeUrl
};
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Used to load ng module factories.
*
* @publicApi
*/
var NgModuleFactoryLoader = /** @class */ (function () {
function NgModuleFactoryLoader() {
}
return NgModuleFactoryLoader;
}());
/**
* Map of module-id to the corresponding NgModule.
* - In pre Ivy we track NgModuleFactory,
* - In post Ivy we track the NgModuleType
*/
var modules = new Map();
/**
* Registers a loaded module. Should only be called from generated NgModuleFactory code.
* @publicApi
*/
function registerModuleFactory(id, factory) {
var existing = modules.get(id);
assertNotExisting(id, existing && existing.moduleType);
modules.set(id, factory);
}
function assertNotExisting(id, type) {
if (type) {
throw new Error("Duplicate module registered for " + id + " - " + stringify(type) + " vs " + stringify(type.name));
}
}
function registerNgModuleType(id, ngModuleType) {
var existing = modules.get(id);
assertNotExisting(id, existing);
modules.set(id, ngModuleType);
}
function getModuleFactory__PRE_R3__(id) {
var factory = modules.get(id);
if (!factory)
throw noModuleError(id);
return factory;
}
function getModuleFactory__POST_R3__(id) {
var type = modules.get(id);
if (!type)
throw noModuleError(id);
return new NgModuleFactory$1(type);
}
/**
* Returns the NgModuleFactory with the given id, if it exists and has been loaded.
* Factories for modules that do not specify an `id` cannot be retrieved. Throws if the module
* cannot be found.
* @publicApi
*/
var getModuleFactory = getModuleFactory__PRE_R3__;
function noModuleError(id) {
return new Error("No module with ID " + id + " loaded");
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @description
*
* Represents a type that a Component or other object is instances of.
*
* An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
* the `MyCustomComponent` constructor function.
*
* @publicApi
*/
var Type = Function;
function isType(v) {
return typeof v === 'function';
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Attention: These regex has to hold even if the code is minified!
*/
var DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
var INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{/;
var INHERITED_CLASS_WITH_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(/;
var ReflectionCapabilities = /** @class */ (function () {
function ReflectionCapabilities(reflect) {
this._reflect = reflect || _global['Reflect'];
}
ReflectionCapabilities.prototype.isReflectionEnabled = function () { return true; };
ReflectionCapabilities.prototype.factory = function (t) { return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return new (t.bind.apply(t, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], args)))();
}; };
/** @internal */
ReflectionCapabilities.prototype._zipTypesAndAnnotations = function (paramTypes, paramAnnotations) {
var result;
if (typeof paramTypes === 'undefined') {
result = new Array(paramAnnotations.length);
}
else {
result = new Array(paramTypes.length);
}
for (var i = 0; i < result.length; i++) {
// TS outputs Object for parameters without types, while Traceur omits
// the annotations. For now we preserve the Traceur behavior to aid
// migration, but this can be revisited.
if (typeof paramTypes === 'undefined') {
result[i] = [];
}
else if (paramTypes[i] != Object) {
result[i] = [paramTypes[i]];
}
else {
result[i] = [];
}
if (paramAnnotations && paramAnnotations[i] != null) {
result[i] = result[i].concat(paramAnnotations[i]);
}
}
return result;
};
ReflectionCapabilities.prototype._ownParameters = function (type, parentCtor) {
var typeStr = type.toString();
// If we have no decorators, we only have function.length as metadata.
// In that case, to detect whether a child class declared an own constructor or not,
// we need to look inside of that constructor to check whether it is
// just calling the parent.
// This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
// that sets 'design:paramtypes' to []
// if a class inherits from another class but has no ctor declared itself.
if (DELEGATE_CTOR.exec(typeStr) ||
(INHERITED_CLASS.exec(typeStr) && !INHERITED_CLASS_WITH_CTOR.exec(typeStr))) {
return null;
}
// Prefer the direct API.
if (type.parameters && type.parameters !== parentCtor.parameters) {
return type.parameters;
}
// API of tsickle for lowering decorators to properties on the class.
var tsickleCtorParams = type.ctorParameters;
if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
// Newer tsickle uses a function closure
// Retain the non-function case for compatibility with older tsickle
var ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
var paramTypes_1 = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
var paramAnnotations_1 = ctorParameters.map(function (ctorParam) {
return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators);
});
return this._zipTypesAndAnnotations(paramTypes_1, paramAnnotations_1);
}
// API for metadata created by invoking the decorators.
var paramAnnotations = type.hasOwnProperty(PARAMETERS) && type[PARAMETERS];
var paramTypes = this._reflect && this._reflect.getOwnMetadata &&
this._reflect.getOwnMetadata('design:paramtypes', type);
if (paramTypes || paramAnnotations) {
return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
}
// If a class has no decorators, at least create metadata
// based on function.length.
// Note: We know that this is a real constructor as we checked
// the content of the constructor above.
return new Array(type.length).fill(undefined);
};
ReflectionCapabilities.prototype.parameters = function (type) {
// Note: only report metadata if we have at least one class decorator
// to stay in sync with the static reflector.
if (!isType(type)) {
return [];
}
var parentCtor = getParentCtor(type);
var parameters = this._ownParameters(type, parentCtor);
if (!parameters && parentCtor !== Object) {
parameters = this.parameters(parentCtor);
}
return parameters || [];
};
ReflectionCapabilities.prototype._ownAnnotations = function (typeOrFunc, parentCtor) {
// Prefer the direct API.
if (typeOrFunc.annotations && typeOrFunc.annotations !== parentCtor.annotations) {
var annotations = typeOrFunc.annotations;
if (typeof annotations === 'function' && annotations.annotations) {
annotations = annotations.annotations;
}
return annotations;
}
// API of tsickle for lowering decorators to properties on the class.
if (typeOrFunc.decorators && typeOrFunc.decorators !== parentCtor.decorators) {
return convertTsickleDecoratorIntoMetadata(typeOrFunc.decorators);
}
// API for metadata created by invoking the decorators.
if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
return typeOrFunc[ANNOTATIONS];
}
return null;
};
ReflectionCapabilities.prototype.annotations = function (typeOrFunc) {
if (!isType(typeOrFunc)) {
return [];
}
var parentCtor = getParentCtor(typeOrFunc);
var ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
var parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
return parentAnnotations.concat(ownAnnotations);
};
ReflectionCapabilities.prototype._ownPropMetadata = function (typeOrFunc, parentCtor) {
// Prefer the direct API.
if (typeOrFunc.propMetadata &&
typeOrFunc.propMetadata !== parentCtor.propMetadata) {
var propMetadata = typeOrFunc.propMetadata;
if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
propMetadata = propMetadata.propMetadata;
}
return propMetadata;
}
// API of tsickle for lowering decorators to properties on the class.
if (typeOrFunc.propDecorators &&
typeOrFunc.propDecorators !== parentCtor.propDecorators) {
var propDecorators_1 = typeOrFunc.propDecorators;
var propMetadata_1 = {};
Object.keys(propDecorators_1).forEach(function (prop) {
propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
});
return propMetadata_1;
}
// API for metadata created by invoking the decorators.
if (typeOrFunc.hasOwnProperty(PROP_METADATA)) {
return typeOrFunc[PROP_METADATA];
}
return null;
};
ReflectionCapabilities.prototype.propMetadata = function (typeOrFunc) {
if (!isType(typeOrFunc)) {
return {};
}
var parentCtor = getParentCtor(typeOrFunc);
var propMetadata = {};
if (parentCtor !== Object) {
var parentPropMetadata_1 = this.propMetadata(parentCtor);
Object.keys(parentPropMetadata_1).forEach(function (propName) {
propMetadata[propName] = parentPropMetadata_1[propName];
});
}
var ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
if (ownPropMetadata) {
Object.keys(ownPropMetadata).forEach(function (propName) {
var decorators = [];
if (propMetadata.hasOwnProperty(propName)) {
decorators.push.apply(decorators, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(propMetadata[propName]));
}
decorators.push.apply(decorators, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(ownPropMetadata[propName]));
propMetadata[propName] = decorators;
});
}
return propMetadata;
};
ReflectionCapabilities.prototype.hasLifecycleHook = function (type, lcProperty) {
return type instanceof Type && lcProperty in type.prototype;
};
ReflectionCapabilities.prototype.guards = function (type) { return {}; };
ReflectionCapabilities.prototype.getter = function (name) { return new Function('o', 'return o.' + name + ';'); };
ReflectionCapabilities.prototype.setter = function (name) {
return new Function('o', 'v', 'return o.' + name + ' = v;');
};
ReflectionCapabilities.prototype.method = function (name) {
var functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n return o." + name + ".apply(o, args);";
return new Function('o', 'args', functionBody);
};
// There is not a concept of import uri in Js, but this is useful in developing Dart applications.
ReflectionCapabilities.prototype.importUri = function (type) {
// StaticSymbol
if (typeof type === 'object' && type['filePath']) {
return type['filePath'];
}
// Runtime type
return "./" + stringify(type);
};
ReflectionCapabilities.prototype.resourceUri = function (type) { return "./" + stringify(type); };
ReflectionCapabilities.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
return runtime;
};
ReflectionCapabilities.prototype.resolveEnum = function (enumIdentifier, name) { return enumIdentifier[name]; };
return ReflectionCapabilities;
}());
function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
if (!decoratorInvocations) {
return [];
}
return decoratorInvocations.map(function (decoratorInvocation) {
var decoratorType = decoratorInvocation.type;
var annotationCls = decoratorType.annotationCls;
var annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
return new (annotationCls.bind.apply(annotationCls, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], annotationArgs)))();
});
}
function getParentCtor(ctor) {
var parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
var parentCtor = parentProto ? parentProto.constructor : null;
// Note: We always use `Object` as the null value
// to simplify checking later on.
return parentCtor || Object;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var _reflect = null;
function getReflect() {
return (_reflect = _reflect || new ReflectionCapabilities());
}
function reflectDependencies(type) {
return convertDependencies(getReflect().parameters(type));
}
function convertDependencies(deps) {
var compiler = getCompilerFacade();
return deps.map(function (dep) { return reflectDependency(compiler, dep); });
}
function reflectDependency(compiler, dep) {
var meta = {
token: null,
host: false,
optional: false,
resolved: compiler.R3ResolvedDependencyType.Token,
self: false,
skipSelf: false,
};
function setTokenAndResolvedType(token) {
meta.resolved = compiler.R3ResolvedDependencyType.Token;
meta.token = token;
}
if (Array.isArray(dep)) {
if (dep.length === 0) {
throw new Error('Dependency array must have arguments.');
}
for (var j = 0; j < dep.length; j++) {
var param = dep[j];
if (param === undefined) {
// param may be undefined if type of dep is not set by ngtsc
continue;
}
else if (param instanceof Optional || param.__proto__.ngMetadataName === 'Optional') {
meta.optional = true;
}
else if (param instanceof SkipSelf || param.__proto__.ngMetadataName === 'SkipSelf') {
meta.skipSelf = true;
}
else if (param instanceof Self || param.__proto__.ngMetadataName === 'Self') {
meta.self = true;
}
else if (param instanceof Host || param.__proto__.ngMetadataName === 'Host') {
meta.host = true;
}
else if (param instanceof Inject) {
meta.token = param.token;
}
else if (param instanceof Attribute) {
if (param.attributeName === undefined) {
throw new Error("Attribute name must be defined.");
}
meta.token = param.attributeName;
meta.resolved = compiler.R3ResolvedDependencyType.Attribute;
}
else {
setTokenAndResolvedType(param);
}
}
}
else {
setTokenAndResolvedType(dep);
}
return meta;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var EMPTY_ARRAY$2 = [];
var moduleQueue = [];
/**
* Enqueues moduleDef to be checked later to see if scope can be set on its
* component declarations.
*/
function enqueueModuleForDelayedScoping(moduleType, ngModule) {
moduleQueue.push({ moduleType: moduleType, ngModule: ngModule });
}
var flushingModuleQueue = false;
/**
* Loops over queued module definitions, if a given module definition has all of its
* declarations resolved, it dequeues that module definition and sets the scope on
* its declarations.
*/
function flushModuleScopingQueueAsMuchAsPossible() {
if (!flushingModuleQueue) {
flushingModuleQueue = true;
try {
for (var i = moduleQueue.length - 1; i >= 0; i--) {
var _a = moduleQueue[i], moduleType = _a.moduleType, ngModule = _a.ngModule;
if (ngModule.declarations && ngModule.declarations.every(isResolvedDeclaration)) {
// dequeue
moduleQueue.splice(i, 1);
setScopeOnDeclaredComponents(moduleType, ngModule);
}
}
}
finally {
flushingModuleQueue = false;
}
}
}
/**
* Returns truthy if a declaration has resolved. If the declaration happens to be
* an array of declarations, it will recurse to check each declaration in that array
* (which may also be arrays).
*/
function isResolvedDeclaration(declaration) {
if (Array.isArray(declaration)) {
return declaration.every(isResolvedDeclaration);
}
return !!resolveForwardRef(declaration);
}
/**
* Compiles a module in JIT mode.
*
* This function automatically gets called when a class has a `@NgModule` decorator.
*/
function compileNgModule(moduleType, ngModule) {
if (ngModule === void 0) { ngModule = {}; }
compileNgModuleDefs(moduleType, ngModule);
// Because we don't know if all declarations have resolved yet at the moment the
// NgModule decorator is executing, we're enqueueing the setting of module scope
// on its declarations to be run at a later time when all declarations for the module,
// including forward refs, have resolved.
enqueueModuleForDelayedScoping(moduleType, ngModule);
}
/**
* Compiles and adds the `ngModuleDef` and `ngInjectorDef` properties to the module class.
*/
function compileNgModuleDefs(moduleType, ngModule) {
ngDevMode && assertDefined(moduleType, 'Required value moduleType');
ngDevMode && assertDefined(ngModule, 'Required value ngModule');
var declarations = flatten$1(ngModule.declarations || EMPTY_ARRAY$2);
var ngModuleDef = null;
Object.defineProperty(moduleType, NG_MODULE_DEF, {
configurable: true,
get: function () {
if (ngModuleDef === null) {
ngModuleDef = getCompilerFacade().compileNgModule(angularCoreEnv, "ng://" + moduleType.name + "/ngModuleDef.js", {
type: moduleType,
bootstrap: flatten$1(ngModule.bootstrap || EMPTY_ARRAY$2, resolveForwardRef),
declarations: declarations.map(resolveForwardRef),
imports: flatten$1(ngModule.imports || EMPTY_ARRAY$2, resolveForwardRef)
.map(expandModuleWithProviders),
exports: flatten$1(ngModule.exports || EMPTY_ARRAY$2, resolveForwardRef)
.map(expandModuleWithProviders),
emitInline: true,
});
}
return ngModuleDef;
}
});
if (ngModule.id) {
registerNgModuleType(ngModule.id, moduleType);
}
var ngInjectorDef = null;
Object.defineProperty(moduleType, NG_INJECTOR_DEF, {
get: function () {
if (ngInjectorDef === null) {
ngDevMode && verifySemanticsOfNgModuleDef(moduleType);
var meta = {
name: moduleType.name,
type: moduleType,
deps: reflectDependencies(moduleType),
providers: ngModule.providers || EMPTY_ARRAY$2,
imports: [
(ngModule.imports || EMPTY_ARRAY$2).map(resolveForwardRef),
(ngModule.exports || EMPTY_ARRAY$2).map(resolveForwardRef),
],
};
ngInjectorDef = getCompilerFacade().compileInjector(angularCoreEnv, "ng://" + moduleType.name + "/ngInjectorDef.js", meta);
}
return ngInjectorDef;
},
// Make the property configurable in dev mode to allow overriding in tests
configurable: !!ngDevMode,
});
}
function verifySemanticsOfNgModuleDef(moduleType) {
if (verifiedNgModule.get(moduleType))
return;
verifiedNgModule.set(moduleType, true);
moduleType = resolveForwardRef(moduleType);
var ngModuleDef = getNgModuleDef(moduleType, true);
var errors = [];
ngModuleDef.declarations.forEach(verifyDeclarationsHaveDefinitions);
var combinedDeclarations = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(ngModuleDef.declarations.map(resolveForwardRef), flatten$1(ngModuleDef.imports.map(computeCombinedExports), resolveForwardRef));
ngModuleDef.exports.forEach(verifyExportsAreDeclaredOrReExported);
ngModuleDef.declarations.forEach(verifyDeclarationIsUnique);
ngModuleDef.declarations.forEach(verifyComponentEntryComponentsIsPartOfNgModule);
var ngModule = getAnnotation(moduleType, 'NgModule');
if (ngModule) {
ngModule.imports &&
flatten$1(ngModule.imports, unwrapModuleWithProvidersImports)
.forEach(verifySemanticsOfNgModuleDef);
ngModule.bootstrap && ngModule.bootstrap.forEach(verifyComponentIsPartOfNgModule);
ngModule.entryComponents && ngModule.entryComponents.forEach(verifyComponentIsPartOfNgModule);
}
// Throw Error if any errors were detected.
if (errors.length) {
throw new Error(errors.join('\n'));
}
////////////////////////////////////////////////////////////////////////////////////////////////
function verifyDeclarationsHaveDefinitions(type) {
type = resolveForwardRef(type);
var def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef(type);
if (!def) {
errors.push("Unexpected value '" + stringify$1(type) + "' declared by the module '" + stringify$1(moduleType) + "'. Please add a @Pipe/@Directive/@Component annotation.");
}
}
function verifyExportsAreDeclaredOrReExported(type) {
type = resolveForwardRef(type);
var kind = getComponentDef(type) && 'component' || getDirectiveDef(type) && 'directive' ||
getPipeDef(type) && 'pipe';
if (kind) {
// only checked if we are declared as Component, Directive, or Pipe
// Modules don't need to be declared or imported.
if (combinedDeclarations.lastIndexOf(type) === -1) {
// We are exporting something which we don't explicitly declare or import.
errors.push("Can't export " + kind + " " + stringify$1(type) + " from " + stringify$1(moduleType) + " as it was neither declared nor imported!");
}
}
}
function verifyDeclarationIsUnique(type) {
type = resolveForwardRef(type);
var existingModule = ownerNgModule.get(type);
if (existingModule && existingModule !== moduleType) {
var modules = [existingModule, moduleType].map(stringify$1).sort();
errors.push("Type " + stringify$1(type) + " is part of the declarations of 2 modules: " + modules[0] + " and " + modules[1] + "! " +
("Please consider moving " + stringify$1(type) + " to a higher module that imports " + modules[0] + " and " + modules[1] + ". ") +
("You can also create a new NgModule that exports and includes " + stringify$1(type) + " then import that NgModule in " + modules[0] + " and " + modules[1] + "."));
}
else {
// Mark type as having owner.
ownerNgModule.set(type, moduleType);
}
}
function verifyComponentIsPartOfNgModule(type) {
type = resolveForwardRef(type);
var existingModule = ownerNgModule.get(type);
if (!existingModule) {
errors.push("Component " + stringify$1(type) + " is not part of any NgModule or the module has not been imported into your module.");
}
}
function verifyComponentEntryComponentsIsPartOfNgModule(type) {
type = resolveForwardRef(type);
if (getComponentDef(type)) {
// We know we are component
var component = getAnnotation(type, 'Component');
if (component && component.entryComponents) {
component.entryComponents.forEach(verifyComponentIsPartOfNgModule);
}
}
}
}
function unwrapModuleWithProvidersImports(typeOrWithProviders) {
typeOrWithProviders = resolveForwardRef(typeOrWithProviders);
return typeOrWithProviders.ngModule || typeOrWithProviders;
}
function getAnnotation(type, name) {
var annotation = null;
collect(type.__annotations__);
collect(type.decorators);
return annotation;
function collect(annotations) {
if (annotations) {
annotations.forEach(readAnnotation);
}
}
function readAnnotation(decorator) {
if (!annotation) {
var proto = Object.getPrototypeOf(decorator);
if (proto.ngMetadataName == name) {
annotation = decorator;
}
else if (decorator.type) {
var proto_1 = Object.getPrototypeOf(decorator.type);
if (proto_1.ngMetadataName == name) {
annotation = decorator.args[0];
}
}
}
}
}
/**
* Keep track of compiled components. This is needed because in tests we often want to compile the
* same component with more than one NgModule. This would cause an error unless we reset which
* NgModule the component belongs to. We keep the list of compiled components here so that the
* TestBed can reset it later.
*/
var ownerNgModule = new Map();
var verifiedNgModule = new Map();
function resetCompiledComponents() {
ownerNgModule = new Map();
verifiedNgModule = new Map();
moduleQueue.length = 0;
}
/**
* Computes the combined declarations of explicit declarations, as well as declarations inherited
* by
* traversing the exports of imported modules.
* @param type
*/
function computeCombinedExports(type) {
type = resolveForwardRef(type);
var ngModuleDef = getNgModuleDef(type, true);
return Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(flatten$1(ngModuleDef.exports.map(function (type) {
var ngModuleDef = getNgModuleDef(type);
if (ngModuleDef) {
verifySemanticsOfNgModuleDef(type);
return computeCombinedExports(type);
}
else {
return type;
}
})));
}
/**
* Some declared components may be compiled asynchronously, and thus may not have their
* ngComponentDef set yet. If this is the case, then a reference to the module is written into
* the `ngSelectorScope` property of the declared type.
*/
function setScopeOnDeclaredComponents(moduleType, ngModule) {
var declarations = flatten$1(ngModule.declarations || EMPTY_ARRAY$2);
var transitiveScopes = transitiveScopesFor(moduleType);
declarations.forEach(function (declaration) {
if (declaration.hasOwnProperty(NG_COMPONENT_DEF)) {
// An `ngComponentDef` field exists - go ahead and patch the component directly.
var component = declaration;
var componentDef = getComponentDef(component);
patchComponentDefWithScope(componentDef, transitiveScopes);
}
else if (!declaration.hasOwnProperty(NG_DIRECTIVE_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
// Set `ngSelectorScope` for future reference when the component compilation finishes.
declaration.ngSelectorScope = moduleType;
}
});
}
/**
* Patch the definition of a component with directives and pipes from the compilation scope of
* a given module.
*/
function patchComponentDefWithScope(componentDef, transitiveScopes) {
componentDef.directiveDefs = function () { return Array.from(transitiveScopes.compilation.directives)
.map(function (dir) { return getDirectiveDef(dir) || getComponentDef(dir); })
.filter(function (def) { return !!def; }); };
componentDef.pipeDefs = function () {
return Array.from(transitiveScopes.compilation.pipes).map(function (pipe) { return getPipeDef(pipe); });
};
}
/**
* Compute the pair of transitive scopes (compilation scope and exported scope) for a given module.
*
* This operation is memoized and the result is cached on the module's definition. It can be called
* on modules with components that have not fully compiled yet, but the result should not be used
* until they have.
*/
function transitiveScopesFor(moduleType) {
if (!isNgModule(moduleType)) {
throw new Error(moduleType.name + " does not have an ngModuleDef");
}
var def = getNgModuleDef(moduleType);
if (def.transitiveCompileScopes !== null) {
return def.transitiveCompileScopes;
}
var scopes = {
compilation: {
directives: new Set(),
pipes: new Set(),
},
exported: {
directives: new Set(),
pipes: new Set(),
},
};
def.declarations.forEach(function (declared) {
var declaredWithDefs = declared;
if (getPipeDef(declaredWithDefs)) {
scopes.compilation.pipes.add(declared);
}
else {
// Either declared has an ngComponentDef or ngDirectiveDef, or it's a component which hasn't
// had its template compiled yet. In either case, it gets added to the compilation's
// directives.
scopes.compilation.directives.add(declared);
}
});
def.imports.forEach(function (imported) {
var importedTyped = imported;
if (!isNgModule(importedTyped)) {
throw new Error("Importing " + importedTyped.name + " which does not have an ngModuleDef");
}
// When this module imports another, the imported module's exported directives and pipes are
// added to the compilation scope of this module.
var importedScope = transitiveScopesFor(importedTyped);
importedScope.exported.directives.forEach(function (entry) { return scopes.compilation.directives.add(entry); });
importedScope.exported.pipes.forEach(function (entry) { return scopes.compilation.pipes.add(entry); });
});
def.exports.forEach(function (exported) {
var exportedTyped = exported;
// Either the type is a module, a pipe, or a component/directive (which may not have an
// ngComponentDef as it might be compiled asynchronously).
if (isNgModule(exportedTyped)) {
// When this module exports another, the exported module's exported directives and pipes are
// added to both the compilation and exported scopes of this module.
var exportedScope = transitiveScopesFor(exportedTyped);
exportedScope.exported.directives.forEach(function (entry) {
scopes.compilation.directives.add(entry);
scopes.exported.directives.add(entry);
});
exportedScope.exported.pipes.forEach(function (entry) {
scopes.compilation.pipes.add(entry);
scopes.exported.pipes.add(entry);
});
}
else if (getPipeDef(exportedTyped)) {
scopes.exported.pipes.add(exportedTyped);
}
else {
scopes.exported.directives.add(exportedTyped);
}
});
def.transitiveCompileScopes = scopes;
return scopes;
}
function flatten$1(values, mapFn) {
var out = [];
values.forEach(function (value) {
if (Array.isArray(value)) {
out.push.apply(out, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(flatten$1(value, mapFn)));
}
else {
out.push(mapFn ? mapFn(value) : value);
}
});
return out;
}
function expandModuleWithProviders(value) {
if (isModuleWithProviders(value)) {
return value.ngModule;
}
return value;
}
function isModuleWithProviders(value) {
return value.ngModule !== undefined;
}
function isNgModule(value) {
return !!getNgModuleDef(value);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Compile an Angular component according to its decorator metadata, and patch the resulting
* ngComponentDef onto the component type.
*
* Compilation may be asynchronous (due to the need to resolve URLs for the component template or
* other resources, for example). In the event that compilation is not immediate, `compileComponent`
* will enqueue resource resolution into a global queue and will fail to return the `ngComponentDef`
* until the global queue has been resolved with a call to `resolveComponentResources`.
*/
function compileComponent(type, metadata) {
var ngComponentDef = null;
// Metadata may have resources which need to be resolved.
maybeQueueResolutionOfComponentResources(metadata);
Object.defineProperty(type, NG_COMPONENT_DEF, {
get: function () {
var compiler = getCompilerFacade();
if (ngComponentDef === null) {
if (componentNeedsResolution(metadata)) {
var error = ["Component '" + stringify$1(type) + "' is not resolved:"];
if (metadata.templateUrl) {
error.push(" - templateUrl: " + stringify$1(metadata.templateUrl));
}
if (metadata.styleUrls && metadata.styleUrls.length) {
error.push(" - styleUrls: " + JSON.stringify(metadata.styleUrls));
}
error.push("Did you run and wait for 'resolveComponentResources()'?");
throw new Error(error.join('\n'));
}
var meta = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({}, directiveMetadata(type, metadata), { template: metadata.template || '', preserveWhitespaces: metadata.preserveWhitespaces || false, styles: metadata.styles || EMPTY_ARRAY, animations: metadata.animations, viewQueries: extractQueriesMetadata(type, getReflect().propMetadata(type), isViewQuery), directives: [], changeDetection: metadata.changeDetection, pipes: new Map(), encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated, interpolation: metadata.interpolation, viewProviders: metadata.viewProviders || null });
ngComponentDef = compiler.compileComponent(angularCoreEnv, "ng://" + stringify$1(type) + "/template.html", meta);
// When NgModule decorator executed, we enqueued the module definition such that
// it would only dequeue and add itself as module scope to all of its declarations,
// but only if if all of its declarations had resolved. This call runs the check
// to see if any modules that are in the queue can be dequeued and add scope to
// their declarations.
flushModuleScopingQueueAsMuchAsPossible();
// If component compilation is async, then the @NgModule annotation which declares the
// component may execute and set an ngSelectorScope property on the component type. This
// allows the component to patch itself with directiveDefs from the module after it
// finishes compiling.
if (hasSelectorScope(type)) {
var scopes = transitiveScopesFor(type.ngSelectorScope);
patchComponentDefWithScope(ngComponentDef, scopes);
}
}
return ngComponentDef;
},
// Make the property configurable in dev mode to allow overriding in tests
configurable: !!ngDevMode,
});
}
function hasSelectorScope(component) {
return component.ngSelectorScope !== undefined;
}
/**
* Compile an Angular directive according to its decorator metadata, and patch the resulting
* ngDirectiveDef onto the component type.
*
* In the event that compilation is not immediate, `compileDirective` will return a `Promise` which
* will resolve when compilation completes and the directive becomes usable.
*/
function compileDirective(type, directive) {
var ngDirectiveDef = null;
Object.defineProperty(type, NG_DIRECTIVE_DEF, {
get: function () {
if (ngDirectiveDef === null) {
var facade = directiveMetadata(type, directive);
ngDirectiveDef = getCompilerFacade().compileDirective(angularCoreEnv, "ng://" + (type && type.name) + "/ngDirectiveDef.js", facade);
}
return ngDirectiveDef;
},
// Make the property configurable in dev mode to allow overriding in tests
configurable: !!ngDevMode,
});
}
function extendsDirectlyFromObject(type) {
return Object.getPrototypeOf(type.prototype) === Object.prototype;
}
/**
* Extract the `R3DirectiveMetadata` for a particular directive (either a `Directive` or a
* `Component`).
*/
function directiveMetadata(type, metadata) {
// Reflect inputs and outputs.
var propMetadata = getReflect().propMetadata(type);
return {
name: type.name,
type: type,
typeArgumentCount: 0,
selector: metadata.selector,
deps: reflectDependencies(type),
host: metadata.host || EMPTY_OBJ,
propMetadata: propMetadata,
inputs: metadata.inputs || EMPTY_ARRAY,
outputs: metadata.outputs || EMPTY_ARRAY,
queries: extractQueriesMetadata(type, propMetadata, isContentQuery),
lifecycle: {
usesOnChanges: type.prototype.ngOnChanges !== undefined,
},
typeSourceSpan: null,
usesInheritance: !extendsDirectlyFromObject(type),
exportAs: metadata.exportAs || null,
providers: metadata.providers || null,
};
}
function convertToR3QueryPredicate(selector) {
return typeof selector === 'string' ? splitByComma(selector) : resolveForwardRef(selector);
}
function convertToR3QueryMetadata(propertyName, ann) {
return {
propertyName: propertyName,
predicate: convertToR3QueryPredicate(ann.selector),
descendants: ann.descendants,
first: ann.first,
read: ann.read ? ann.read : null
};
}
function extractQueriesMetadata(type, propMetadata, isQueryAnn) {
var queriesMeta = [];
var _loop_1 = function (field) {
if (propMetadata.hasOwnProperty(field)) {
propMetadata[field].forEach(function (ann) {
if (isQueryAnn(ann)) {
if (!ann.selector) {
throw new Error("Can't construct a query for the property \"" + field + "\" of " +
("\"" + stringify$1(type) + "\" since the query selector wasn't defined."));
}
queriesMeta.push(convertToR3QueryMetadata(field, ann));
}
});
}
};
for (var field in propMetadata) {
_loop_1(field);
}
return queriesMeta;
}
function isContentQuery(value) {
var name = value.ngMetadataName;
return name === 'ContentChild' || name === 'ContentChildren';
}
function isViewQuery(value) {
var name = value.ngMetadataName;
return name === 'ViewChild' || name === 'ViewChildren';
}
function splitByComma(value) {
return value.split(',').map(function (piece) { return piece.trim(); });
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function compilePipe(type, meta) {
var ngPipeDef = null;
Object.defineProperty(type, NG_PIPE_DEF, {
get: function () {
if (ngPipeDef === null) {
ngPipeDef = getCompilerFacade().compilePipe(angularCoreEnv, "ng://" + stringify$1(type) + "/ngPipeDef.js", {
type: type,
name: type.name,
deps: reflectDependencies(type),
pipeName: meta.name,
pure: meta.pure !== undefined ? meta.pure : true
});
}
return ngPipeDef;
},
// Make the property configurable in dev mode to allow overriding in tests
configurable: !!ngDevMode,
});
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Type of the Directive metadata.
*
* @publicApi
*/
var Directive = makeDecorator('Directive', function (dir) {
if (dir === void 0) { dir = {}; }
return dir;
}, undefined, undefined, function (type, meta) { return SWITCH_COMPILE_DIRECTIVE(type, meta); });
/**
* Component decorator and metadata.
*
* @Annotation
* @publicApi
*/
var Component = makeDecorator('Component', function (c) {
if (c === void 0) { c = {}; }
return (Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({ changeDetection: ChangeDetectionStrategy.Default }, c));
}, Directive, undefined, function (type, meta) { return SWITCH_COMPILE_COMPONENT(type, meta); });
/**
* @Annotation
* @publicApi
*/
var Pipe = makeDecorator('Pipe', function (p) { return (Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({ pure: true }, p)); }, undefined, undefined, function (type, meta) { return SWITCH_COMPILE_PIPE(type, meta); });
var initializeBaseDef = function (target) {
var constructor = target.constructor;
var inheritedBaseDef = constructor.ngBaseDef;
var baseDef = constructor.ngBaseDef = {
inputs: {},
outputs: {},
declaredInputs: {},
};
if (inheritedBaseDef) {
fillProperties(baseDef.inputs, inheritedBaseDef.inputs);
fillProperties(baseDef.outputs, inheritedBaseDef.outputs);
fillProperties(baseDef.declaredInputs, inheritedBaseDef.declaredInputs);
}
};
/**
* Does the work of creating the `ngBaseDef` property for the @Input and @Output decorators.
* @param key "inputs" or "outputs"
*/
var updateBaseDefFromIOProp = function (getProp) {
return function (target, name) {
var args = [];
for (var _i = 2; _i < arguments.length; _i++) {
args[_i - 2] = arguments[_i];
}
var constructor = target.constructor;
if (!constructor.hasOwnProperty(NG_BASE_DEF)) {
initializeBaseDef(target);
}
var baseDef = constructor.ngBaseDef;
var defProp = getProp(baseDef);
defProp[name] = args[0];
};
};
/**
* @Annotation
* @publicApi
*/
var Input = makePropDecorator('Input', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); }, undefined, updateBaseDefFromIOProp(function (baseDef) { return baseDef.inputs || {}; }));
/**
* @Annotation
* @publicApi
*/
var Output = makePropDecorator('Output', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); }, undefined, updateBaseDefFromIOProp(function (baseDef) { return baseDef.outputs || {}; }));
/**
* @Annotation
* @publicApi
*/
var HostBinding = makePropDecorator('HostBinding', function (hostPropertyName) { return ({ hostPropertyName: hostPropertyName }); });
/**
* Binds a CSS event to a host listener and supplies configuration metadata.
* Angular invokes the supplied handler method when the host element emits the specified event,
* and updates the bound element with the result.
* If the handler method returns false, applies `preventDefault` on the bound element.
*
* @usageNotes
*
* The following example declares a directive
* that attaches a click listener to a button and counts clicks.
*
* ```
* @Directive({selector: 'button[counting]'})
* class CountClicks {
* numberOfClicks = 0;
*
* @HostListener('click', ['$event.target'])
* onClick(btn) {
* console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
* }
* }
*
* @Component({
* selector: 'app',
* template: '<button counting>Increment</button>',
* })
* class App {}
* ```
*
* @Annotation
* @publicApi
*/
var HostListener = makePropDecorator('HostListener', function (eventName, args) { return ({ eventName: eventName, args: args }); });
var SWITCH_COMPILE_COMPONENT__POST_R3__ = compileComponent;
var SWITCH_COMPILE_DIRECTIVE__POST_R3__ = compileDirective;
var SWITCH_COMPILE_PIPE__POST_R3__ = compilePipe;
var SWITCH_COMPILE_COMPONENT__PRE_R3__ = noop;
var SWITCH_COMPILE_DIRECTIVE__PRE_R3__ = noop;
var SWITCH_COMPILE_PIPE__PRE_R3__ = noop;
var SWITCH_COMPILE_COMPONENT = SWITCH_COMPILE_COMPONENT__PRE_R3__;
var SWITCH_COMPILE_DIRECTIVE = SWITCH_COMPILE_DIRECTIVE__PRE_R3__;
var SWITCH_COMPILE_PIPE = SWITCH_COMPILE_PIPE__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var ɵ0$2 = getClosureSafeProperty;
var USE_VALUE$1 = getClosureSafeProperty({ provide: String, useValue: ɵ0$2 });
var EMPTY_ARRAY$3 = [];
function convertInjectableProviderToFactory(type, provider) {
if (!provider) {
var reflectionCapabilities = new ReflectionCapabilities();
var deps_1 = reflectionCapabilities.parameters(type);
// TODO - convert to flags.
return function () { return new (type.bind.apply(type, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], injectArgs(deps_1))))(); };
}
if (USE_VALUE$1 in provider) {
var valueProvider_1 = provider;
return function () { return valueProvider_1.useValue; };
}
else if (provider.useExisting) {
var existingProvider_1 = provider;
return function () { return inject(existingProvider_1.useExisting); };
}
else if (provider.useFactory) {
var factoryProvider_1 = provider;
return function () { return factoryProvider_1.useFactory.apply(factoryProvider_1, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(injectArgs(factoryProvider_1.deps || EMPTY_ARRAY$3))); };
}
else if (provider.useClass) {
var classProvider_1 = provider;
var deps_2 = provider.deps;
if (!deps_2) {
var reflectionCapabilities = new ReflectionCapabilities();
deps_2 = reflectionCapabilities.parameters(type);
}
return function () {
var _a;
return new ((_a = classProvider_1.useClass).bind.apply(_a, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], injectArgs(deps_2))))();
};
}
else {
var deps_3 = provider.deps;
if (!deps_3) {
var reflectionCapabilities = new ReflectionCapabilities();
deps_3 = reflectionCapabilities.parameters(type);
}
return function () { return new (type.bind.apply(type, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([void 0], injectArgs(deps_3))))(); };
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Defines a schema that allows an NgModule to contain the following:
* - Non-Angular elements named with dash case (`-`).
* - Element properties named with dash case (`-`).
* Dash case is the naming convention for custom elements.
*
* @publicApi
*/
var CUSTOM_ELEMENTS_SCHEMA = {
name: 'custom-elements'
};
/**
* Defines a schema that allows any property on any element.
*
* @publicApi
*/
var NO_ERRORS_SCHEMA = {
name: 'no-errors-schema'
};
/**
* @Annotation
* @publicApi
*/
var NgModule = makeDecorator('NgModule', function (ngModule) { return ngModule; }, undefined, undefined,
/**
* Decorator that marks the following class as an NgModule, and supplies
* configuration metadata for it.
*
* * The `declarations` and `entryComponents` options configure the compiler
* with information about what belongs to the NgModule.
* * The `providers` options configures the NgModule's injector to provide
* dependencies the NgModule members.
* * The `imports` and `exports` options bring in members from other modules, and make
* this module's members available to others.
*/
function (type, meta) { return SWITCH_COMPILE_NGMODULE(type, meta); });
function preR3NgModuleCompile(moduleType, metadata) {
var imports = (metadata && metadata.imports) || [];
if (metadata && metadata.exports) {
imports = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(imports, [metadata.exports]);
}
moduleType.ngInjectorDef = defineInjector({
factory: convertInjectableProviderToFactory(moduleType, { useClass: moduleType }),
providers: metadata && metadata.providers,
imports: imports,
});
}
var SWITCH_COMPILE_NGMODULE__POST_R3__ = compileNgModule;
var SWITCH_COMPILE_NGMODULE__PRE_R3__ = preR3NgModuleCompile;
var SWITCH_COMPILE_NGMODULE = SWITCH_COMPILE_NGMODULE__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
* `ngInjectableDef` onto the injectable type.
*/
function compileInjectable(type, srcMeta) {
var def = null;
// if NG_INJECTABLE_DEF is already defined on this class then don't overwrite it
if (type.hasOwnProperty(NG_INJECTABLE_DEF))
return;
Object.defineProperty(type, NG_INJECTABLE_DEF, {
get: function () {
if (def === null) {
// Allow the compilation of a class with a `@Injectable()` decorator without parameters
var meta = srcMeta || { providedIn: null };
var hasAProvider = isUseClassProvider(meta) || isUseFactoryProvider(meta) ||
isUseValueProvider(meta) || isUseExistingProvider(meta);
var compilerMeta = {
name: type.name,
type: type,
typeArgumentCount: 0,
providedIn: meta.providedIn,
ctorDeps: reflectDependencies(type),
userDeps: undefined
};
if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
compilerMeta.userDeps = convertDependencies(meta.deps);
}
if (!hasAProvider) {
// In the case the user specifies a type provider, treat it as {provide: X, useClass: X}.
// The deps will have been reflected above, causing the factory to create the class by
// calling
// its constructor with injected deps.
compilerMeta.useClass = type;
}
else if (isUseClassProvider(meta)) {
// The user explicitly specified useClass, and may or may not have provided deps.
compilerMeta.useClass = meta.useClass;
}
else if (isUseValueProvider(meta)) {
// The user explicitly specified useValue.
compilerMeta.useValue = meta.useValue;
}
else if (isUseFactoryProvider(meta)) {
// The user explicitly specified useFactory.
compilerMeta.useFactory = meta.useFactory;
}
else if (isUseExistingProvider(meta)) {
// The user explicitly specified useExisting.
compilerMeta.useExisting = meta.useExisting;
}
else {
// Can't happen - either hasAProvider will be false, or one of the providers will be set.
throw new Error("Unreachable state.");
}
def = getCompilerFacade().compileInjectable(angularCoreEnv, "ng://" + type.name + "/ngInjectableDef.js", compilerMeta);
}
return def;
},
});
}
var ɵ0$3 = getClosureSafeProperty;
var USE_VALUE$2 = getClosureSafeProperty({ provide: String, useValue: ɵ0$3 });
function isUseClassProvider(meta) {
return meta.useClass !== undefined;
}
function isUseValueProvider(meta) {
return USE_VALUE$2 in meta;
}
function isUseFactoryProvider(meta) {
return meta.useFactory !== undefined;
}
function isUseExistingProvider(meta) {
return meta.useExisting !== undefined;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Injectable decorator and metadata.
*
* @Annotation
* @publicApi
*/
var Injectable = makeDecorator('Injectable', undefined, undefined, undefined, function (type, meta) { return SWITCH_COMPILE_INJECTABLE(type, meta); });
/**
* Supports @Injectable() in JIT mode for Render2.
*/
function render2CompileInjectable(injectableType, options) {
if (options && options.providedIn !== undefined && !getInjectableDef(injectableType)) {
injectableType.ngInjectableDef = defineInjectable({
providedIn: options.providedIn,
factory: convertInjectableProviderToFactory(injectableType, options),
});
}
}
var SWITCH_COMPILE_INJECTABLE__POST_R3__ = compileInjectable;
var SWITCH_COMPILE_INJECTABLE__PRE_R3__ = render2CompileInjectable;
var SWITCH_COMPILE_INJECTABLE = SWITCH_COMPILE_INJECTABLE__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var ERROR_DEBUG_CONTEXT = 'ngDebugContext';
var ERROR_ORIGINAL_ERROR = 'ngOriginalError';
var ERROR_LOGGER = 'ngErrorLogger';
function getDebugContext(error) {
return error[ERROR_DEBUG_CONTEXT];
}
function getOriginalError(error) {
return error[ERROR_ORIGINAL_ERROR];
}
function getErrorLogger(error) {
return error[ERROR_LOGGER] || defaultErrorLogger;
}
function defaultErrorLogger(console) {
var values = [];
for (var _i = 1; _i < arguments.length; _i++) {
values[_i - 1] = arguments[_i];
}
console.error.apply(console, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(values));
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Provides a hook for centralized exception handling.
*
* The default implementation of `ErrorHandler` prints error messages to the `console`. To
* intercept error handling, write a custom exception handler that replaces this default as
* appropriate for your app.
*
* @usageNotes
* ### Example
*
* ```
* class MyErrorHandler implements ErrorHandler {
* handleError(error) {
* // do something with the exception
* }
* }
*
* @NgModule({
* providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
* })
* class MyModule {}
* ```
*
* @publicApi
*/
var ErrorHandler = /** @class */ (function () {
function ErrorHandler() {
/**
* @internal
*/
this._console = console;
}
ErrorHandler.prototype.handleError = function (error) {
var originalError = this._findOriginalError(error);
var context = this._findContext(error);
// Note: Browser consoles show the place from where console.error was called.
// We can use this to give users additional information about the error.
var errorLogger = getErrorLogger(error);
errorLogger(this._console, "ERROR", error);
if (originalError) {
errorLogger(this._console, "ORIGINAL ERROR", originalError);
}
if (context) {
errorLogger(this._console, 'ERROR CONTEXT', context);
}
};
/** @internal */
ErrorHandler.prototype._findContext = function (error) {
if (error) {
return getDebugContext(error) ? getDebugContext(error) :
this._findContext(getOriginalError(error));
}
return null;
};
/** @internal */
ErrorHandler.prototype._findOriginalError = function (error) {
var e = getOriginalError(error);
while (e && getOriginalError(e)) {
e = getOriginalError(e);
}
return e;
};
return ErrorHandler;
}());
function wrappedError(message, originalError) {
var msg = message + " caused by: " + (originalError instanceof Error ? originalError.message : originalError);
var error = Error(msg);
error[ERROR_ORIGINAL_ERROR] = originalError;
return error;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function findFirstClosedCycle(keys) {
var res = [];
for (var i = 0; i < keys.length; ++i) {
if (res.indexOf(keys[i]) > -1) {
res.push(keys[i]);
return res;
}
res.push(keys[i]);
}
return res;
}
function constructResolvingPath(keys) {
if (keys.length > 1) {
var reversed = findFirstClosedCycle(keys.slice().reverse());
var tokenStrs = reversed.map(function (k) { return stringify(k.token); });
return ' (' + tokenStrs.join(' -> ') + ')';
}
return '';
}
function injectionError(injector, key, constructResolvingMessage, originalError) {
var keys = [key];
var errMsg = constructResolvingMessage(keys);
var error = (originalError ? wrappedError(errMsg, originalError) : Error(errMsg));
error.addKey = addKey;
error.keys = keys;
error.injectors = [injector];
error.constructResolvingMessage = constructResolvingMessage;
error[ERROR_ORIGINAL_ERROR] = originalError;
return error;
}
function addKey(injector, key) {
this.injectors.push(injector);
this.keys.push(key);
// Note: This updated message won't be reflected in the `.stack` property
this.message = this.constructResolvingMessage(this.keys);
}
/**
* Thrown when trying to retrieve a dependency by key from {@link Injector}, but the
* {@link Injector} does not have a {@link Provider} for the given key.
*
* @usageNotes
* ### Example
*
* ```typescript
* class A {
* constructor(b:B) {}
* }
*
* expect(() => Injector.resolveAndCreate([A])).toThrowError();
* ```
*/
function noProviderError(injector, key) {
return injectionError(injector, key, function (keys) {
var first = stringify(keys[0].token);
return "No provider for " + first + "!" + constructResolvingPath(keys);
});
}
/**
* Thrown when dependencies form a cycle.
*
* @usageNotes
* ### Example
*
* ```typescript
* var injector = Injector.resolveAndCreate([
* {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
* {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
* ]);
*
* expect(() => injector.get("one")).toThrowError();
* ```
*
* Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
*/
function cyclicDependencyError(injector, key) {
return injectionError(injector, key, function (keys) {
return "Cannot instantiate cyclic dependency!" + constructResolvingPath(keys);
});
}
/**
* Thrown when a constructing type returns with an Error.
*
* The `InstantiationError` class contains the original error plus the dependency graph which caused
* this object to be instantiated.
*
* @usageNotes
* ### Example
*
* ```typescript
* class A {
* constructor() {
* throw new Error('message');
* }
* }
*
* var injector = Injector.resolveAndCreate([A]);
* try {
* injector.get(A);
* } catch (e) {
* expect(e instanceof InstantiationError).toBe(true);
* expect(e.originalException.message).toEqual("message");
* expect(e.originalStack).toBeDefined();
* }
* ```
*/
function instantiationError(injector, originalException, originalStack, key) {
return injectionError(injector, key, function (keys) {
var first = stringify(keys[0].token);
return originalException.message + ": Error during instantiation of " + first + "!" + constructResolvingPath(keys) + ".";
}, originalException);
}
/**
* Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
* creation.
*
* @usageNotes
* ### Example
*
* ```typescript
* expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
* ```
*/
function invalidProviderError(provider) {
return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
}
/**
* Thrown when the class has no annotation information.
*
* Lack of annotation information prevents the {@link Injector} from determining which dependencies
* need to be injected into the constructor.
*
* @usageNotes
* ### Example
*
* ```typescript
* class A {
* constructor(b) {}
* }
*
* expect(() => Injector.resolveAndCreate([A])).toThrowError();
* ```
*
* This error is also thrown when the class not marked with {@link Injectable} has parameter types.
*
* ```typescript
* class B {}
*
* class A {
* constructor(b:B) {} // no information about the parameter types of A is available at runtime.
* }
*
* expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
* ```
*
*/
function noAnnotationError(typeOrFunc, params) {
var signature = [];
for (var i = 0, ii = params.length; i < ii; i++) {
var parameter = params[i];
if (!parameter || parameter.length == 0) {
signature.push('?');
}
else {
signature.push(parameter.map(stringify).join(' '));
}
}
return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' +
signature.join(', ') + '). ' +
'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' +
stringify(typeOrFunc) + '\' is decorated with Injectable.');
}
/**
* Thrown when getting an object by index.
*
* @usageNotes
* ### Example
*
* ```typescript
* class A {}
*
* var injector = Injector.resolveAndCreate([A]);
*
* expect(() => injector.getAt(100)).toThrowError();
* ```
*
*/
function outOfBoundsError(index) {
return Error("Index " + index + " is out-of-bounds.");
}
// TODO: add a working example after alpha38 is released
/**
* Thrown when a multi provider and a regular provider are bound to the same token.
*
* @usageNotes
* ### Example
*
* ```typescript
* expect(() => Injector.resolveAndCreate([
* { provide: "Strings", useValue: "string1", multi: true},
* { provide: "Strings", useValue: "string2", multi: false}
* ])).toThrowError();
* ```
*/
function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A unique object used for retrieving items from the {@link ReflectiveInjector}.
*
* Keys have:
* - a system-wide unique `id`.
* - a `token`.
*
* `Key` is used internally by {@link ReflectiveInjector} because its system-wide unique `id` allows
* the
* injector to store created objects in a more efficient way.
*
* `Key` should not be created directly. {@link ReflectiveInjector} creates keys automatically when
* resolving
* providers.
*
* @deprecated No replacement
* @publicApi
*/
var ReflectiveKey = /** @class */ (function () {
/**
* Private
*/
function ReflectiveKey(token, id) {
this.token = token;
this.id = id;
if (!token) {
throw new Error('Token must be defined!');
}
this.displayName = stringify(this.token);
}
/**
* Retrieves a `Key` for a token.
*/
ReflectiveKey.get = function (token) {
return _globalKeyRegistry.get(resolveForwardRef(token));
};
Object.defineProperty(ReflectiveKey, "numberOfKeys", {
/**
* @returns the number of keys registered in the system.
*/
get: function () { return _globalKeyRegistry.numberOfKeys; },
enumerable: true,
configurable: true
});
return ReflectiveKey;
}());
var KeyRegistry = /** @class */ (function () {
function KeyRegistry() {
this._allKeys = new Map();
}
KeyRegistry.prototype.get = function (token) {
if (token instanceof ReflectiveKey)
return token;
if (this._allKeys.has(token)) {
return this._allKeys.get(token);
}
var newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
this._allKeys.set(token, newKey);
return newKey;
};
Object.defineProperty(KeyRegistry.prototype, "numberOfKeys", {
get: function () { return this._allKeys.size; },
enumerable: true,
configurable: true
});
return KeyRegistry;
}());
var _globalKeyRegistry = new KeyRegistry();
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Provides access to reflection data about symbols. Used internally by Angular
* to power dependency injection and compilation.
*/
var Reflector = /** @class */ (function () {
function Reflector(reflectionCapabilities) {
this.reflectionCapabilities = reflectionCapabilities;
}
Reflector.prototype.updateCapabilities = function (caps) { this.reflectionCapabilities = caps; };
Reflector.prototype.factory = function (type) { return this.reflectionCapabilities.factory(type); };
Reflector.prototype.parameters = function (typeOrFunc) {
return this.reflectionCapabilities.parameters(typeOrFunc);
};
Reflector.prototype.annotations = function (typeOrFunc) {
return this.reflectionCapabilities.annotations(typeOrFunc);
};
Reflector.prototype.propMetadata = function (typeOrFunc) {
return this.reflectionCapabilities.propMetadata(typeOrFunc);
};
Reflector.prototype.hasLifecycleHook = function (type, lcProperty) {
return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
};
Reflector.prototype.getter = function (name) { return this.reflectionCapabilities.getter(name); };
Reflector.prototype.setter = function (name) { return this.reflectionCapabilities.setter(name); };
Reflector.prototype.method = function (name) { return this.reflectionCapabilities.method(name); };
Reflector.prototype.importUri = function (type) { return this.reflectionCapabilities.importUri(type); };
Reflector.prototype.resourceUri = function (type) { return this.reflectionCapabilities.resourceUri(type); };
Reflector.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
};
Reflector.prototype.resolveEnum = function (identifier, name) {
return this.reflectionCapabilities.resolveEnum(identifier, name);
};
return Reflector;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* The {@link Reflector} used internally in Angular to access metadata
* about symbols.
*/
var reflector = new Reflector(new ReflectionCapabilities());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* `Dependency` is used by the framework to extend DI.
* This is internal to Angular and should not be used directly.
*/
var ReflectiveDependency = /** @class */ (function () {
function ReflectiveDependency(key, optional, visibility) {
this.key = key;
this.optional = optional;
this.visibility = visibility;
}
ReflectiveDependency.fromKey = function (key) {
return new ReflectiveDependency(key, false, null);
};
return ReflectiveDependency;
}());
var _EMPTY_LIST = [];
var ResolvedReflectiveProvider_ = /** @class */ (function () {
function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
this.key = key;
this.resolvedFactories = resolvedFactories;
this.multiProvider = multiProvider;
this.resolvedFactory = this.resolvedFactories[0];
}
return ResolvedReflectiveProvider_;
}());
/**
* An internal resolved representation of a factory function created by resolving `Provider`.
* @publicApi
*/
var ResolvedReflectiveFactory = /** @class */ (function () {
function ResolvedReflectiveFactory(
/**
* Factory function which can return an instance of an object represented by a key.
*/
factory,
/**
* Arguments (dependencies) to the `factory` function.
*/
dependencies) {
this.factory = factory;
this.dependencies = dependencies;
}
return ResolvedReflectiveFactory;
}());
/**
* Resolve a single provider.
*/
function resolveReflectiveFactory(provider) {
var factoryFn;
var resolvedDeps;
if (provider.useClass) {
var useClass = resolveForwardRef(provider.useClass);
factoryFn = reflector.factory(useClass);
resolvedDeps = _dependenciesFor(useClass);
}
else if (provider.useExisting) {
factoryFn = function (aliasInstance) { return aliasInstance; };
resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
}
else if (provider.useFactory) {
factoryFn = provider.useFactory;
resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
}
else {
factoryFn = function () { return provider.useValue; };
resolvedDeps = _EMPTY_LIST;
}
return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
}
/**
* Converts the `Provider` into `ResolvedProvider`.
*
* `Injector` internally only uses `ResolvedProvider`, `Provider` contains convenience provider
* syntax.
*/
function resolveReflectiveProvider(provider) {
return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
}
/**
* Resolve a list of Providers.
*/
function resolveReflectiveProviders(providers) {
var normalized = _normalizeProviders(providers, []);
var resolved = normalized.map(resolveReflectiveProvider);
var resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
return Array.from(resolvedProviderMap.values());
}
/**
* Merges a list of ResolvedProviders into a list where each key is contained exactly once and
* multi providers have been merged.
*/
function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
for (var i = 0; i < providers.length; i++) {
var provider = providers[i];
var existing = normalizedProvidersMap.get(provider.key.id);
if (existing) {
if (provider.multiProvider !== existing.multiProvider) {
throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
}
if (provider.multiProvider) {
for (var j = 0; j < provider.resolvedFactories.length; j++) {
existing.resolvedFactories.push(provider.resolvedFactories[j]);
}
}
else {
normalizedProvidersMap.set(provider.key.id, provider);
}
}
else {
var resolvedProvider = void 0;
if (provider.multiProvider) {
resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
}
else {
resolvedProvider = provider;
}
normalizedProvidersMap.set(provider.key.id, resolvedProvider);
}
}
return normalizedProvidersMap;
}
function _normalizeProviders(providers, res) {
providers.forEach(function (b) {
if (b instanceof Type) {
res.push({ provide: b, useClass: b });
}
else if (b && typeof b == 'object' && b.provide !== undefined) {
res.push(b);
}
else if (b instanceof Array) {
_normalizeProviders(b, res);
}
else {
throw invalidProviderError(b);
}
});
return res;
}
function constructDependencies(typeOrFunc, dependencies) {
if (!dependencies) {
return _dependenciesFor(typeOrFunc);
}
else {
var params_1 = dependencies.map(function (t) { return [t]; });
return dependencies.map(function (t) { return _extractToken(typeOrFunc, t, params_1); });
}
}
function _dependenciesFor(typeOrFunc) {
var params = reflector.parameters(typeOrFunc);
if (!params)
return [];
if (params.some(function (p) { return p == null; })) {
throw noAnnotationError(typeOrFunc, params);
}
return params.map(function (p) { return _extractToken(typeOrFunc, p, params); });
}
function _extractToken(typeOrFunc, metadata, params) {
var token = null;
var optional = false;
if (!Array.isArray(metadata)) {
if (metadata instanceof Inject) {
return _createDependency(metadata.token, optional, null);
}
else {
return _createDependency(metadata, optional, null);
}
}
var visibility = null;
for (var i = 0; i < metadata.length; ++i) {
var paramMetadata = metadata[i];
if (paramMetadata instanceof Type) {
token = paramMetadata;
}
else if (paramMetadata instanceof Inject) {
token = paramMetadata.token;
}
else if (paramMetadata instanceof Optional) {
optional = true;
}
else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
visibility = paramMetadata;
}
else if (paramMetadata instanceof InjectionToken) {
token = paramMetadata;
}
}
token = resolveForwardRef(token);
if (token != null) {
return _createDependency(token, optional, visibility);
}
else {
throw noAnnotationError(typeOrFunc, params);
}
}
function _createDependency(token, optional, visibility) {
return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// Threshold for the dynamic version
var UNDEFINED = new Object();
/**
* A ReflectiveDependency injection container used for instantiating objects and resolving
* dependencies.
*
* An `Injector` is a replacement for a `new` operator, which can automatically resolve the
* constructor dependencies.
*
* In typical use, application code asks for the dependencies in the constructor and they are
* resolved by the `Injector`.
*
* @usageNotes
* ### Example
*
* The following example creates an `Injector` configured to create `Engine` and `Car`.
*
* ```typescript
* @Injectable()
* class Engine {
* }
*
* @Injectable()
* class Car {
* constructor(public engine:Engine) {}
* }
*
* var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
* var car = injector.get(Car);
* expect(car instanceof Car).toBe(true);
* expect(car.engine instanceof Engine).toBe(true);
* ```
*
* Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
* resolve all of the object's dependencies automatically.
*
* @deprecated from v5 - slow and brings in a lot of code, Use `Injector.create` instead.
* @publicApi
*/
var ReflectiveInjector = /** @class */ (function () {
function ReflectiveInjector() {
}
/**
* Turns an array of provider definitions into an array of resolved providers.
*
* A resolution is a process of flattening multiple nested arrays and converting individual
* providers into an array of `ResolvedReflectiveProvider`s.
*
* @usageNotes
* ### Example
*
* ```typescript
* @Injectable()
* class Engine {
* }
*
* @Injectable()
* class Car {
* constructor(public engine:Engine) {}
* }
*
* var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
*
* expect(providers.length).toEqual(2);
*
* expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
* expect(providers[0].key.displayName).toBe("Car");
* expect(providers[0].dependencies.length).toEqual(1);
* expect(providers[0].factory).toBeDefined();
*
* expect(providers[1].key.displayName).toBe("Engine");
* });
* ```
*
*/
ReflectiveInjector.resolve = function (providers) {
return resolveReflectiveProviders(providers);
};
/**
* Resolves an array of providers and creates an injector from those providers.
*
* The passed-in providers can be an array of `Type`, `Provider`,
* or a recursive array of more providers.
*
* @usageNotes
* ### Example
*
* ```typescript
* @Injectable()
* class Engine {
* }
*
* @Injectable()
* class Car {
* constructor(public engine:Engine) {}
* }
*
* var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
* expect(injector.get(Car) instanceof Car).toBe(true);
* ```
*/
ReflectiveInjector.resolveAndCreate = function (providers, parent) {
var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
};
/**
* Creates an injector from previously resolved providers.
*
* This API is the recommended way to construct injectors in performance-sensitive parts.
*
* @usageNotes
* ### Example
*
* ```typescript
* @Injectable()
* class Engine {
* }
*
* @Injectable()
* class Car {
* constructor(public engine:Engine) {}
* }
*
* var providers = ReflectiveInjector.resolve([Car, Engine]);
* var injector = ReflectiveInjector.fromResolvedProviders(providers);
* expect(injector.get(Car) instanceof Car).toBe(true);
* ```
*/
ReflectiveInjector.fromResolvedProviders = function (providers, parent) {
return new ReflectiveInjector_(providers, parent);
};
return ReflectiveInjector;
}());
var ReflectiveInjector_ = /** @class */ (function () {
/**
* Private
*/
function ReflectiveInjector_(_providers, _parent) {
/** @internal */
this._constructionCounter = 0;
this._providers = _providers;
this.parent = _parent || null;
var len = _providers.length;
this.keyIds = new Array(len);
this.objs = new Array(len);
for (var i = 0; i < len; i++) {
this.keyIds[i] = _providers[i].key.id;
this.objs[i] = UNDEFINED;
}
}
ReflectiveInjector_.prototype.get = function (token, notFoundValue) {
if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);
};
ReflectiveInjector_.prototype.resolveAndCreateChild = function (providers) {
var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
return this.createChildFromResolved(ResolvedReflectiveProviders);
};
ReflectiveInjector_.prototype.createChildFromResolved = function (providers) {
var inj = new ReflectiveInjector_(providers);
inj.parent = this;
return inj;
};
ReflectiveInjector_.prototype.resolveAndInstantiate = function (provider) {
return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
};
ReflectiveInjector_.prototype.instantiateResolved = function (provider) {
return this._instantiateProvider(provider);
};
ReflectiveInjector_.prototype.getProviderAtIndex = function (index) {
if (index < 0 || index >= this._providers.length) {
throw outOfBoundsError(index);
}
return this._providers[index];
};
/** @internal */
ReflectiveInjector_.prototype._new = function (provider) {
if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
throw cyclicDependencyError(this, provider.key);
}
return this._instantiateProvider(provider);
};
ReflectiveInjector_.prototype._getMaxNumberOfObjects = function () { return this.objs.length; };
ReflectiveInjector_.prototype._instantiateProvider = function (provider) {
if (provider.multiProvider) {
var res = new Array(provider.resolvedFactories.length);
for (var i = 0; i < provider.resolvedFactories.length; ++i) {
res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
}
return res;
}
else {
return this._instantiate(provider, provider.resolvedFactories[0]);
}
};
ReflectiveInjector_.prototype._instantiate = function (provider, ResolvedReflectiveFactory$$1) {
var _this = this;
var factory = ResolvedReflectiveFactory$$1.factory;
var deps;
try {
deps =
ResolvedReflectiveFactory$$1.dependencies.map(function (dep) { return _this._getByReflectiveDependency(dep); });
}
catch (e) {
if (e.addKey) {
e.addKey(this, provider.key);
}
throw e;
}
var obj;
try {
obj = factory.apply(void 0, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])(deps));
}
catch (e) {
throw instantiationError(this, e, e.stack, provider.key);
}
return obj;
};
ReflectiveInjector_.prototype._getByReflectiveDependency = function (dep) {
return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
};
ReflectiveInjector_.prototype._getByKey = function (key, visibility, notFoundValue) {
if (key === ReflectiveInjector_.INJECTOR_KEY) {
return this;
}
if (visibility instanceof Self) {
return this._getByKeySelf(key, notFoundValue);
}
else {
return this._getByKeyDefault(key, notFoundValue, visibility);
}
};
ReflectiveInjector_.prototype._getObjByKeyId = function (keyId) {
for (var i = 0; i < this.keyIds.length; i++) {
if (this.keyIds[i] === keyId) {
if (this.objs[i] === UNDEFINED) {
this.objs[i] = this._new(this._providers[i]);
}
return this.objs[i];
}
}
return UNDEFINED;
};
/** @internal */
ReflectiveInjector_.prototype._throwOrNull = function (key, notFoundValue) {
if (notFoundValue !== THROW_IF_NOT_FOUND) {
return notFoundValue;
}
else {
throw noProviderError(this, key);
}
};
/** @internal */
ReflectiveInjector_.prototype._getByKeySelf = function (key, notFoundValue) {
var obj = this._getObjByKeyId(key.id);
return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
};
/** @internal */
ReflectiveInjector_.prototype._getByKeyDefault = function (key, notFoundValue, visibility) {
var inj;
if (visibility instanceof SkipSelf) {
inj = this.parent;
}
else {
inj = this;
}
while (inj instanceof ReflectiveInjector_) {
var inj_ = inj;
var obj = inj_._getObjByKeyId(key.id);
if (obj !== UNDEFINED)
return obj;
inj = inj_.parent;
}
if (inj !== null) {
return inj.get(key.token, notFoundValue);
}
else {
return this._throwOrNull(key, notFoundValue);
}
};
Object.defineProperty(ReflectiveInjector_.prototype, "displayName", {
get: function () {
var providers = _mapProviders(this, function (b) { return ' "' + b.key.displayName + '" '; })
.join(', ');
return "ReflectiveInjector(providers: [" + providers + "])";
},
enumerable: true,
configurable: true
});
ReflectiveInjector_.prototype.toString = function () { return this.displayName; };
ReflectiveInjector_.INJECTOR_KEY = ReflectiveKey.get(Injector);
return ReflectiveInjector_;
}());
function _mapProviders(injector, fn) {
var res = new Array(injector._providers.length);
for (var i = 0; i < injector._providers.length; ++i) {
res[i] = fn(injector.getProviderAtIndex(i));
}
return res;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Determine if the argument is shaped like a Promise
*/
function isPromise(obj) {
// allow any Promise/A+ compliant thenable.
// It's up to the caller to ensure that obj.then conforms to the spec
return !!obj && typeof obj.then === 'function';
}
/**
* Determine if the argument is an Observable
*/
function isObservable(obj) {
// TODO: use isObservable once we update pass rxjs 6.1
// https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md#610-2018-05-03
return !!obj && typeof obj.subscribe === 'function';
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A function that will be executed when an application is initialized.
*
* @publicApi
*/
var APP_INITIALIZER = new InjectionToken('Application Initializer');
/**
* A class that reflects the state of running {@link APP_INITIALIZER}s.
*
* @publicApi
*/
var ApplicationInitStatus = /** @class */ (function () {
function ApplicationInitStatus(appInits) {
var _this = this;
this.appInits = appInits;
this.initialized = false;
this.done = false;
this.donePromise = new Promise(function (res, rej) {
_this.resolve = res;
_this.reject = rej;
});
}
/** @internal */
ApplicationInitStatus.prototype.runInitializers = function () {
var _this = this;
if (this.initialized) {
return;
}
var asyncInitPromises = [];
var complete = function () {
_this.done = true;
_this.resolve();
};
if (this.appInits) {
for (var i = 0; i < this.appInits.length; i++) {
var initResult = this.appInits[i]();
if (isPromise(initResult)) {
asyncInitPromises.push(initResult);
}
}
}
Promise.all(asyncInitPromises).then(function () { complete(); }).catch(function (e) { _this.reject(e); });
if (asyncInitPromises.length === 0) {
complete();
}
this.initialized = true;
};
ApplicationInitStatus = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable(),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__param"])(0, Inject(APP_INITIALIZER)), Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__param"])(0, Optional()),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [Array])
], ApplicationInitStatus);
return ApplicationInitStatus;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* A DI Token representing a unique string id assigned to the application by Angular and used
* primarily for prefixing application attributes and CSS styles when
* {@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
*
* If you need to avoid randomly generated value to be used as an application id, you can provide
* a custom value via a DI provider <!-- TODO: provider --> configuring the root {@link Injector}
* using this token.
* @publicApi
*/
var APP_ID = new InjectionToken('AppId');
function _appIdRandomProviderFactory() {
return "" + _randomChar() + _randomChar() + _randomChar();
}
/**
* Providers that will generate a random APP_ID_TOKEN.
* @publicApi
*/
var APP_ID_RANDOM_PROVIDER = {
provide: APP_ID,
useFactory: _appIdRandomProviderFactory,
deps: [],
};
function _randomChar() {
return String.fromCharCode(97 + Math.floor(Math.random() * 25));
}
/**
* A function that will be executed when a platform is initialized.
* @publicApi
*/
var PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
/**
* A token that indicates an opaque platform id.
* @publicApi
*/
var PLATFORM_ID = new InjectionToken('Platform ID');
/**
* All callbacks provided via this token will be called for every component that is bootstrapped.
* Signature of the callback:
*
* `(componentRef: ComponentRef) => void`.
*
* @publicApi
*/
var APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
/**
* A token which indicates the root directory of the application
* @publicApi
*/
var PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var Console = /** @class */ (function () {
function Console() {
}
Console.prototype.log = function (message) {
// tslint:disable-next-line:no-console
console.log(message);
};
// Note: for reporting errors use `DOM.logError()` as it is platform specific
Console.prototype.warn = function (message) {
// tslint:disable-next-line:no-console
console.warn(message);
};
Console = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable()
], Console);
return Console;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Combination of NgModuleFactory and ComponentFactorys.
*
* @publicApi
*/
var ModuleWithComponentFactories = /** @class */ (function () {
function ModuleWithComponentFactories(ngModuleFactory, componentFactories) {
this.ngModuleFactory = ngModuleFactory;
this.componentFactories = componentFactories;
}
return ModuleWithComponentFactories;
}());
function _throwError() {
throw new Error("Runtime compiler is not loaded");
}
var Compiler_compileModuleSync__PRE_R3__ = _throwError;
var Compiler_compileModuleSync__POST_R3__ = function (moduleType) {
return new NgModuleFactory$1(moduleType);
};
var Compiler_compileModuleSync = Compiler_compileModuleSync__PRE_R3__;
var Compiler_compileModuleAsync__PRE_R3__ = _throwError;
var Compiler_compileModuleAsync__POST_R3__ = function (moduleType) {
return Promise.resolve(Compiler_compileModuleSync__POST_R3__(moduleType));
};
var Compiler_compileModuleAsync = Compiler_compileModuleAsync__PRE_R3__;
var Compiler_compileModuleAndAllComponentsSync__PRE_R3__ = _throwError;
var Compiler_compileModuleAndAllComponentsSync__POST_R3__ = function (moduleType) {
return new ModuleWithComponentFactories(Compiler_compileModuleSync__POST_R3__(moduleType), []);
};
var Compiler_compileModuleAndAllComponentsSync = Compiler_compileModuleAndAllComponentsSync__PRE_R3__;
var Compiler_compileModuleAndAllComponentsAsync__PRE_R3__ = _throwError;
var Compiler_compileModuleAndAllComponentsAsync__POST_R3__ = function (moduleType) {
return Promise.resolve(Compiler_compileModuleAndAllComponentsSync__POST_R3__(moduleType));
};
var Compiler_compileModuleAndAllComponentsAsync = Compiler_compileModuleAndAllComponentsAsync__PRE_R3__;
/**
* Low-level service for running the angular compiler during runtime
* to create {@link ComponentFactory}s, which
* can later be used to create and render a Component instance.
*
* Each `@NgModule` provides an own `Compiler` to its injector,
* that will use the directives/pipes of the ng module for compilation
* of components.
*
* @publicApi
*/
var Compiler = /** @class */ (function () {
function Compiler() {
/**
* Compiles the given NgModule and all of its components. All templates of the components listed
* in `entryComponents` have to be inlined.
*/
this.compileModuleSync = Compiler_compileModuleSync;
/**
* Compiles the given NgModule and all of its components
*/
this.compileModuleAsync = Compiler_compileModuleAsync;
/**
* Same as {@link #compileModuleSync} but also creates ComponentFactories for all components.
*/
this.compileModuleAndAllComponentsSync = Compiler_compileModuleAndAllComponentsSync;
/**
* Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components.
*/
this.compileModuleAndAllComponentsAsync = Compiler_compileModuleAndAllComponentsAsync;
}
/**
* Clears all caches.
*/
Compiler.prototype.clearCache = function () { };
/**
* Clears the cache for the given component/ngModule.
*/
Compiler.prototype.clearCacheFor = function (type) { };
/**
* Returns the id for a given NgModule, if one is defined and known to the compiler.
*/
Compiler.prototype.getModuleId = function (moduleType) { return undefined; };
Compiler = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable()
], Compiler);
return Compiler;
}());
/**
* Token to provide CompilerOptions in the platform injector.
*
* @publicApi
*/
var COMPILER_OPTIONS = new InjectionToken('compilerOptions');
/**
* A factory for creating a Compiler
*
* @publicApi
*/
var CompilerFactory = /** @class */ (function () {
function CompilerFactory() {
}
return CompilerFactory;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var trace;
var events;
function detectWTF() {
var wtf = _global /** TODO #9100 */['wtf'];
if (wtf) {
trace = wtf['trace'];
if (trace) {
events = trace['events'];
return true;
}
}
return false;
}
function createScope(signature, flags) {
if (flags === void 0) { flags = null; }
return events.createScope(signature, flags);
}
function leave(scope, returnValue) {
trace.leaveScope(scope, returnValue);
return returnValue;
}
function startTimeRange(rangeType, action) {
return trace.beginTimeRange(rangeType, action);
}
function endTimeRange(range) {
trace.endTimeRange(range);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* True if WTF is enabled.
*/
var wtfEnabled = detectWTF();
function noopScope(arg0, arg1) {
return null;
}
/**
* Create trace scope.
*
* Scopes must be strictly nested and are analogous to stack frames, but
* do not have to follow the stack frames. Instead it is recommended that they follow logical
* nesting. You may want to use
* [Event
* Signatures](http://google.github.io/tracing-framework/instrumenting-code.html#custom-events)
* as they are defined in WTF.
*
* Used to mark scope entry. The return value is used to leave the scope.
*
* var myScope = wtfCreateScope('MyClass#myMethod(ascii someVal)');
*
* someMethod() {
* var s = myScope('Foo'); // 'Foo' gets stored in tracing UI
* // DO SOME WORK HERE
* return wtfLeave(s, 123); // Return value 123
* }
*
* Note, adding try-finally block around the work to ensure that `wtfLeave` gets called can
* negatively impact the performance of your application. For this reason we recommend that
* you don't add them to ensure that `wtfLeave` gets called. In production `wtfLeave` is a noop and
* so try-finally block has no value. When debugging perf issues, skipping `wtfLeave`, do to
* exception, will produce incorrect trace, but presence of exception signifies logic error which
* needs to be fixed before the app should be profiled. Add try-finally only when you expect that
* an exception is expected during normal execution while profiling.
*
* @publicApi
*/
var wtfCreateScope = wtfEnabled ? createScope : function (signature, flags) { return noopScope; };
/**
* Used to mark end of Scope.
*
* - `scope` to end.
* - `returnValue` (optional) to be passed to the WTF.
*
* Returns the `returnValue for easy chaining.
* @publicApi
*/
var wtfLeave = wtfEnabled ? leave : function (s, r) { return r; };
/**
* Used to mark Async start. Async are similar to scope but they don't have to be strictly nested.
* The return value is used in the call to [endAsync]. Async ranges only work if WTF has been
* enabled.
*
* someMethod() {
* var s = wtfStartTimeRange('HTTP:GET', 'some.url');
* var future = new Future.delay(5).then((_) {
* wtfEndTimeRange(s);
* });
* }
* @publicApi
*/
var wtfStartTimeRange = wtfEnabled ? startTimeRange : function (rangeType, action) { return null; };
/**
* Ends a async time range operation.
* [range] is the return value from [wtfStartTimeRange] Async ranges only work if WTF has been
* enabled.
* @publicApi
*/
var wtfEndTimeRange = wtfEnabled ? endTimeRange : function (r) { return null; };
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* An injectable service for executing work inside or outside of the Angular zone.
*
* The most common use of this service is to optimize performance when starting a work consisting of
* one or more asynchronous tasks that don't require UI updates or error handling to be handled by
* Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
* can reenter the Angular zone via {@link #run}.
*
* <!-- TODO: add/fix links to:
* - docs explaining zones and the use of zones in Angular and change-detection
* - link to runOutsideAngular/run (throughout this file!)
* -->
*
* @usageNotes
* ### Example
*
* ```
* import {Component, NgZone} from '@angular/core';
* import {NgIf} from '@angular/common';
*
* @Component({
* selector: 'ng-zone-demo',
* template: `
* <h2>Demo: NgZone</h2>
*
* <p>Progress: {{progress}}%</p>
* <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
*
* <button (click)="processWithinAngularZone()">Process within Angular zone</button>
* <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
* `,
* })
* export class NgZoneDemo {
* progress: number = 0;
* label: string;
*
* constructor(private _ngZone: NgZone) {}
*
* // Loop inside the Angular zone
* // so the UI DOES refresh after each setTimeout cycle
* processWithinAngularZone() {
* this.label = 'inside';
* this.progress = 0;
* this._increaseProgress(() => console.log('Inside Done!'));
* }
*
* // Loop outside of the Angular zone
* // so the UI DOES NOT refresh after each setTimeout cycle
* processOutsideOfAngularZone() {
* this.label = 'outside';
* this.progress = 0;
* this._ngZone.runOutsideAngular(() => {
* this._increaseProgress(() => {
* // reenter the Angular zone and display done
* this._ngZone.run(() => { console.log('Outside Done!'); });
* });
* });
* }
*
* _increaseProgress(doneCallback: () => void) {
* this.progress += 1;
* console.log(`Current progress: ${this.progress}%`);
*
* if (this.progress < 100) {
* window.setTimeout(() => this._increaseProgress(doneCallback), 10);
* } else {
* doneCallback();
* }
* }
* }
* ```
*
* @publicApi
*/
var NgZone = /** @class */ (function () {
function NgZone(_a) {
var _b = _a.enableLongStackTrace, enableLongStackTrace = _b === void 0 ? false : _b;
this.hasPendingMicrotasks = false;
this.hasPendingMacrotasks = false;
/**
* Whether there are no outstanding microtasks or macrotasks.
*/
this.isStable = true;
/**
* Notifies when code enters Angular Zone. This gets fired first on VM Turn.
*/
this.onUnstable = new EventEmitter(false);
/**
* Notifies when there is no more microtasks enqueued in the current VM Turn.
* This is a hint for Angular to do change detection, which may enqueue more microtasks.
* For this reason this event can fire multiple times per VM Turn.
*/
this.onMicrotaskEmpty = new EventEmitter(false);
/**
* Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
* implies we are about to relinquish VM turn.
* This event gets called just once.
*/
this.onStable = new EventEmitter(false);
/**
* Notifies that an error has been delivered.
*/
this.onError = new EventEmitter(false);
if (typeof Zone == 'undefined') {
throw new Error("In this configuration Angular requires Zone.js");
}
Zone.assertZonePatched();
var self = this;
self._nesting = 0;
self._outer = self._inner = Zone.current;
if (Zone['wtfZoneSpec']) {
self._inner = self._inner.fork(Zone['wtfZoneSpec']);
}
if (Zone['TaskTrackingZoneSpec']) {
self._inner = self._inner.fork(new Zone['TaskTrackingZoneSpec']);
}
if (enableLongStackTrace && Zone['longStackTraceZoneSpec']) {
self._inner = self._inner.fork(Zone['longStackTraceZoneSpec']);
}
forkInnerZoneWithAngularBehavior(self);
}
NgZone.isInAngularZone = function () { return Zone.current.get('isAngularZone') === true; };
NgZone.assertInAngularZone = function () {
if (!NgZone.isInAngularZone()) {
throw new Error('Expected to be in Angular Zone, but it is not!');
}
};
NgZone.assertNotInAngularZone = function () {
if (NgZone.isInAngularZone()) {
throw new Error('Expected to not be in Angular Zone, but it is!');
}
};
/**
* Executes the `fn` function synchronously within the Angular zone and returns value returned by
* the function.
*
* Running functions via `run` allows you to reenter Angular zone from a task that was executed
* outside of the Angular zone (typically started via {@link #runOutsideAngular}).
*
* Any future tasks or microtasks scheduled from within this function will continue executing from
* within the Angular zone.
*
* If a synchronous error happens it will be rethrown and not reported via `onError`.
*/
NgZone.prototype.run = function (fn, applyThis, applyArgs) {
return this._inner.run(fn, applyThis, applyArgs);
};
/**
* Executes the `fn` function synchronously within the Angular zone as a task and returns value
* returned by the function.
*
* Running functions via `run` allows you to reenter Angular zone from a task that was executed
* outside of the Angular zone (typically started via {@link #runOutsideAngular}).
*
* Any future tasks or microtasks scheduled from within this function will continue executing from
* within the Angular zone.
*
* If a synchronous error happens it will be rethrown and not reported via `onError`.
*/
NgZone.prototype.runTask = function (fn, applyThis, applyArgs, name) {
var zone = this._inner;
var task = zone.scheduleEventTask('NgZoneEvent: ' + name, fn, EMPTY_PAYLOAD, noop$1, noop$1);
try {
return zone.runTask(task, applyThis, applyArgs);
}
finally {
zone.cancelTask(task);
}
};
/**
* Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
* rethrown.
*/
NgZone.prototype.runGuarded = function (fn, applyThis, applyArgs) {
return this._inner.runGuarded(fn, applyThis, applyArgs);
};
/**
* Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
* the function.
*
* Running functions via {@link #runOutsideAngular} allows you to escape Angular's zone and do
* work that
* doesn't trigger Angular change-detection or is subject to Angular's error handling.
*
* Any future tasks or microtasks scheduled from within this function will continue executing from
* outside of the Angular zone.
*
* Use {@link #run} to reenter the Angular zone and do work that updates the application model.
*/
NgZone.prototype.runOutsideAngular = function (fn) {
return this._outer.run(fn);
};
return NgZone;
}());
function noop$1() { }
var EMPTY_PAYLOAD = {};
function checkStable(zone) {
if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
try {
zone._nesting++;
zone.onMicrotaskEmpty.emit(null);
}
finally {
zone._nesting--;
if (!zone.hasPendingMicrotasks) {
try {
zone.runOutsideAngular(function () { return zone.onStable.emit(null); });
}
finally {
zone.isStable = true;
}
}
}
}
}
function forkInnerZoneWithAngularBehavior(zone) {
zone._inner = zone._inner.fork({
name: 'angular',
properties: { 'isAngularZone': true },
onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
try {
onEnter(zone);
return delegate.invokeTask(target, task, applyThis, applyArgs);
}
finally {
onLeave(zone);
}
},
onInvoke: function (delegate, current, target, callback, applyThis, applyArgs, source) {
try {
onEnter(zone);
return delegate.invoke(target, callback, applyThis, applyArgs, source);
}
finally {
onLeave(zone);
}
},
onHasTask: function (delegate, current, target, hasTaskState) {
delegate.hasTask(target, hasTaskState);
if (current === target) {
// We are only interested in hasTask events which originate from our zone
// (A child hasTask event is not interesting to us)
if (hasTaskState.change == 'microTask') {
zone.hasPendingMicrotasks = hasTaskState.microTask;
checkStable(zone);
}
else if (hasTaskState.change == 'macroTask') {
zone.hasPendingMacrotasks = hasTaskState.macroTask;
}
}
},
onHandleError: function (delegate, current, target, error) {
delegate.handleError(target, error);
zone.runOutsideAngular(function () { return zone.onError.emit(error); });
return false;
}
});
}
function onEnter(zone) {
zone._nesting++;
if (zone.isStable) {
zone.isStable = false;
zone.onUnstable.emit(null);
}
}
function onLeave(zone) {
zone._nesting--;
checkStable(zone);
}
/**
* Provides a noop implementation of `NgZone` which does nothing. This zone requires explicit calls
* to framework to perform rendering.
*/
var NoopNgZone = /** @class */ (function () {
function NoopNgZone() {
this.hasPendingMicrotasks = false;
this.hasPendingMacrotasks = false;
this.isStable = true;
this.onUnstable = new EventEmitter();
this.onMicrotaskEmpty = new EventEmitter();
this.onStable = new EventEmitter();
this.onError = new EventEmitter();
}
NoopNgZone.prototype.run = function (fn) { return fn(); };
NoopNgZone.prototype.runGuarded = function (fn) { return fn(); };
NoopNgZone.prototype.runOutsideAngular = function (fn) { return fn(); };
NoopNgZone.prototype.runTask = function (fn) { return fn(); };
return NoopNgZone;
}());
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* The Testability service provides testing hooks that can be accessed from
* the browser and by services such as Protractor. Each bootstrapped Angular
* application on the page will have an instance of Testability.
* @publicApi
*/
var Testability = /** @class */ (function () {
function Testability(_ngZone) {
var _this = this;
this._ngZone = _ngZone;
this._pendingCount = 0;
this._isZoneStable = true;
/**
* Whether any work was done since the last 'whenStable' callback. This is
* useful to detect if this could have potentially destabilized another
* component while it is stabilizing.
* @internal
*/
this._didWork = false;
this._callbacks = [];
this.taskTrackingZone = null;
this._watchAngularEvents();
_ngZone.run(function () {
_this.taskTrackingZone =
typeof Zone == 'undefined' ? null : Zone.current.get('TaskTrackingZone');
});
}
Testability.prototype._watchAngularEvents = function () {
var _this = this;
this._ngZone.onUnstable.subscribe({
next: function () {
_this._didWork = true;
_this._isZoneStable = false;
}
});
this._ngZone.runOutsideAngular(function () {
_this._ngZone.onStable.subscribe({
next: function () {
NgZone.assertNotInAngularZone();
scheduleMicroTask(function () {
_this._isZoneStable = true;
_this._runCallbacksIfReady();
});
}
});
});
};
/**
* Increases the number of pending request
* @deprecated pending requests are now tracked with zones.
*/
Testability.prototype.increasePendingRequestCount = function () {
this._pendingCount += 1;
this._didWork = true;
return this._pendingCount;
};
/**
* Decreases the number of pending request
* @deprecated pending requests are now tracked with zones
*/
Testability.prototype.decreasePendingRequestCount = function () {
this._pendingCount -= 1;
if (this._pendingCount < 0) {
throw new Error('pending async requests below zero');
}
this._runCallbacksIfReady();
return this._pendingCount;
};
/**
* Whether an associated application is stable
*/
Testability.prototype.isStable = function () {
return this._isZoneStable && this._pendingCount === 0 && !this._ngZone.hasPendingMacrotasks;
};
Testability.prototype._runCallbacksIfReady = function () {
var _this = this;
if (this.isStable()) {
// Schedules the call backs in a new frame so that it is always async.
scheduleMicroTask(function () {
while (_this._callbacks.length !== 0) {
var cb = _this._callbacks.pop();
clearTimeout(cb.timeoutId);
cb.doneCb(_this._didWork);
}
_this._didWork = false;
});
}
else {
// Still not stable, send updates.
var pending_1 = this.getPendingTasks();
this._callbacks = this._callbacks.filter(function (cb) {
if (cb.updateCb && cb.updateCb(pending_1)) {
clearTimeout(cb.timeoutId);
return false;
}
return true;
});
this._didWork = true;
}
};
Testability.prototype.getPendingTasks = function () {
if (!this.taskTrackingZone) {
return [];
}
// Copy the tasks data so that we don't leak tasks.
return this.taskTrackingZone.macroTasks.map(function (t) {
return {
source: t.source,
// From TaskTrackingZone:
// https://github.com/angular/zone.js/blob/master/lib/zone-spec/task-tracking.ts#L40
creationLocation: t.creationLocation,
data: t.data
};
});
};
Testability.prototype.addCallback = function (cb, timeout, updateCb) {
var _this = this;
var timeoutId = -1;
if (timeout && timeout > 0) {
timeoutId = setTimeout(function () {
_this._callbacks = _this._callbacks.filter(function (cb) { return cb.timeoutId !== timeoutId; });
cb(_this._didWork, _this.getPendingTasks());
}, timeout);
}
this._callbacks.push({ doneCb: cb, timeoutId: timeoutId, updateCb: updateCb });
};
/**
* Wait for the application to be stable with a timeout. If the timeout is reached before that
* happens, the callback receives a list of the macro tasks that were pending, otherwise null.
*
* @param doneCb The callback to invoke when Angular is stable or the timeout expires
* whichever comes first.
* @param timeout Optional. The maximum time to wait for Angular to become stable. If not
* specified, whenStable() will wait forever.
* @param updateCb Optional. If specified, this callback will be invoked whenever the set of
* pending macrotasks changes. If this callback returns true doneCb will not be invoked
* and no further updates will be issued.
*/
Testability.prototype.whenStable = function (doneCb, timeout, updateCb) {
if (updateCb && !this.taskTrackingZone) {
throw new Error('Task tracking zone is required when passing an update callback to ' +
'whenStable(). Is "zone.js/dist/task-tracking.js" loaded?');
}
// These arguments are 'Function' above to keep the public API simple.
this.addCallback(doneCb, timeout, updateCb);
this._runCallbacksIfReady();
};
/**
* Get the number of pending requests
* @deprecated pending requests are now tracked with zones
*/
Testability.prototype.getPendingRequestCount = function () { return this._pendingCount; };
/**
* Find providers by name
* @param using The root element to search from
* @param provider The name of binding variable
* @param exactMatch Whether using exactMatch
*/
Testability.prototype.findProviders = function (using, provider, exactMatch) {
// TODO(juliemr): implement.
return [];
};
Testability = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable(),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [NgZone])
], Testability);
return Testability;
}());
/**
* A global registry of {@link Testability} instances for specific elements.
* @publicApi
*/
var TestabilityRegistry = /** @class */ (function () {
function TestabilityRegistry() {
/** @internal */
this._applications = new Map();
_testabilityGetter.addToWindow(this);
}
/**
* Registers an application with a testability hook so that it can be tracked
* @param token token of application, root element
* @param testability Testability hook
*/
TestabilityRegistry.prototype.registerApplication = function (token, testability) {
this._applications.set(token, testability);
};
/**
* Unregisters an application.
* @param token token of application, root element
*/
TestabilityRegistry.prototype.unregisterApplication = function (token) { this._applications.delete(token); };
/**
* Unregisters all applications
*/
TestabilityRegistry.prototype.unregisterAllApplications = function () { this._applications.clear(); };
/**
* Get a testability hook associated with the application
* @param elem root element
*/
TestabilityRegistry.prototype.getTestability = function (elem) { return this._applications.get(elem) || null; };
/**
* Get all registered testabilities
*/
TestabilityRegistry.prototype.getAllTestabilities = function () { return Array.from(this._applications.values()); };
/**
* Get all registered applications(root elements)
*/
TestabilityRegistry.prototype.getAllRootElements = function () { return Array.from(this._applications.keys()); };
/**
* Find testability of a node in the Tree
* @param elem node
* @param findInAncestors whether finding testability in ancestors if testability was not found in
* current node
*/
TestabilityRegistry.prototype.findTestabilityInTree = function (elem, findInAncestors) {
if (findInAncestors === void 0) { findInAncestors = true; }
return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors);
};
TestabilityRegistry = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable(),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [])
], TestabilityRegistry);
return TestabilityRegistry;
}());
var _NoopGetTestability = /** @class */ (function () {
function _NoopGetTestability() {
}
_NoopGetTestability.prototype.addToWindow = function (registry) { };
_NoopGetTestability.prototype.findTestabilityInTree = function (registry, elem, findInAncestors) {
return null;
};
return _NoopGetTestability;
}());
/**
* Set the {@link GetTestability} implementation used by the Angular testing framework.
* @publicApi
*/
function setTestabilityGetter(getter) {
_testabilityGetter = getter;
}
var _testabilityGetter = new _NoopGetTestability();
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var _platform;
var compileNgModuleFactory = compileNgModuleFactory__PRE_R3__;
function compileNgModuleFactory__PRE_R3__(injector, options, moduleType) {
var compilerFactory = injector.get(CompilerFactory);
var compiler = compilerFactory.createCompiler([options]);
return compiler.compileModuleAsync(moduleType);
}
function compileNgModuleFactory__POST_R3__(injector, options, moduleType) {
ngDevMode && assertNgModuleType(moduleType);
return Promise.resolve(new NgModuleFactory$1(moduleType));
}
var ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
/**
* A token for third-party components that can register themselves with NgProbe.
*
* @publicApi
*/
var NgProbeToken = /** @class */ (function () {
function NgProbeToken(name, token) {
this.name = name;
this.token = token;
}
return NgProbeToken;
}());
/**
* Creates a platform.
* Platforms have to be eagerly created via this function.
*
* @publicApi
*/
function createPlatform(injector) {
if (_platform && !_platform.destroyed &&
!_platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
throw new Error('There can be only one platform. Destroy the previous one to create a new one.');
}
_platform = injector.get(PlatformRef);
var inits = injector.get(PLATFORM_INITIALIZER, null);
if (inits)
inits.forEach(function (init) { return init(); });
return _platform;
}
/**
* Creates a factory for a platform
*
* @publicApi
*/
function createPlatformFactory(parentPlatformFactory, name, providers) {
if (providers === void 0) { providers = []; }
var desc = "Platform: " + name;
var marker = new InjectionToken(desc);
return function (extraProviders) {
if (extraProviders === void 0) { extraProviders = []; }
var platform = getPlatform();
if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
if (parentPlatformFactory) {
parentPlatformFactory(providers.concat(extraProviders).concat({ provide: marker, useValue: true }));
}
else {
var injectedProviders = providers.concat(extraProviders).concat({ provide: marker, useValue: true });
createPlatform(Injector.create({ providers: injectedProviders, name: desc }));
}
}
return assertPlatform(marker);
};
}
/**
* Checks that there currently is a platform which contains the given token as a provider.
*
* @publicApi
*/
function assertPlatform(requiredToken) {
var platform = getPlatform();
if (!platform) {
throw new Error('No platform exists!');
}
if (!platform.injector.get(requiredToken, null)) {
throw new Error('A platform with a different configuration has been created. Please destroy it first.');
}
return platform;
}
/**
* Destroy the existing platform.
*
* @publicApi
*/
function destroyPlatform() {
if (_platform && !_platform.destroyed) {
_platform.destroy();
}
}
/**
* Returns the current platform.
*
* @publicApi
*/
function getPlatform() {
return _platform && !_platform.destroyed ? _platform : null;
}
/**
* The Angular platform is the entry point for Angular on a web page. Each page
* has exactly one platform, and services (such as reflection) which are common
* to every Angular application running on the page are bound in its scope.
*
* A page's platform is initialized implicitly when a platform is created via a platform factory
* (e.g. {@link platformBrowser}), or explicitly by calling the {@link createPlatform} function.
*
* @publicApi
*/
var PlatformRef = /** @class */ (function () {
/** @internal */
function PlatformRef(_injector) {
this._injector = _injector;
this._modules = [];
this._destroyListeners = [];
this._destroyed = false;
}
/**
* Creates an instance of an `@NgModule` for the given platform
* for offline compilation.
*
* @usageNotes
* ### Simple Example
*
* ```typescript
* my_module.ts:
*
* @NgModule({
* imports: [BrowserModule]
* })
* class MyModule {}
*
* main.ts:
* import {MyModuleNgFactory} from './my_module.ngfactory';
* import {platformBrowser} from '@angular/platform-browser';
*
* let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
* ```
*/
PlatformRef.prototype.bootstrapModuleFactory = function (moduleFactory, options) {
var _this = this;
// Note: We need to create the NgZone _before_ we instantiate the module,
// as instantiating the module creates some providers eagerly.
// So we create a mini parent injector that just contains the new NgZone and
// pass that as parent to the NgModuleFactory.
var ngZoneOption = options ? options.ngZone : undefined;
var ngZone = getNgZone(ngZoneOption);
var providers = [{ provide: NgZone, useValue: ngZone }];
// Attention: Don't use ApplicationRef.run here,
// as we want to be sure that all possible constructor calls are inside `ngZone.run`!
return ngZone.run(function () {
var ngZoneInjector = Injector.create({ providers: providers, parent: _this.injector, name: moduleFactory.moduleType.name });
var moduleRef = moduleFactory.create(ngZoneInjector);
var exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
if (!exceptionHandler) {
throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
}
moduleRef.onDestroy(function () { return remove(_this._modules, moduleRef); });
ngZone.runOutsideAngular(function () { return ngZone.onError.subscribe({ next: function (error) { exceptionHandler.handleError(error); } }); });
return _callAndReportToErrorHandler(exceptionHandler, ngZone, function () {
var initStatus = moduleRef.injector.get(ApplicationInitStatus);
initStatus.runInitializers();
return initStatus.donePromise.then(function () {
_this._moduleDoBootstrap(moduleRef);
return moduleRef;
});
});
});
};
/**
* Creates an instance of an `@NgModule` for a given platform using the given runtime compiler.
*
* @usageNotes
* ### Simple Example
*
* ```typescript
* @NgModule({
* imports: [BrowserModule]
* })
* class MyModule {}
*
* let moduleRef = platformBrowser().bootstrapModule(MyModule);
* ```
*
*/
PlatformRef.prototype.bootstrapModule = function (moduleType, compilerOptions) {
var _this = this;
if (compilerOptions === void 0) { compilerOptions = []; }
var options = optionsReducer({}, compilerOptions);
return compileNgModuleFactory(this.injector, options, moduleType)
.then(function (moduleFactory) { return _this.bootstrapModuleFactory(moduleFactory, options); });
};
PlatformRef.prototype._moduleDoBootstrap = function (moduleRef) {
var appRef = moduleRef.injector.get(ApplicationRef);
if (moduleRef._bootstrapComponents.length > 0) {
moduleRef._bootstrapComponents.forEach(function (f) { return appRef.bootstrap(f); });
}
else if (moduleRef.instance.ngDoBootstrap) {
moduleRef.instance.ngDoBootstrap(appRef);
}
else {
throw new Error("The module " + stringify(moduleRef.instance.constructor) + " was bootstrapped, but it does not declare \"@NgModule.bootstrap\" components nor a \"ngDoBootstrap\" method. " +
"Please define one of these.");
}
this._modules.push(moduleRef);
};
/**
* Register a listener to be called when the platform is disposed.
*/
PlatformRef.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
Object.defineProperty(PlatformRef.prototype, "injector", {
/**
* Retrieve the platform {@link Injector}, which is the parent injector for
* every Angular application on the page and provides singleton providers.
*/
get: function () { return this._injector; },
enumerable: true,
configurable: true
});
/**
* Destroy the Angular platform and all Angular applications on the page.
*/
PlatformRef.prototype.destroy = function () {
if (this._destroyed) {
throw new Error('The platform has already been destroyed!');
}
this._modules.slice().forEach(function (module) { return module.destroy(); });
this._destroyListeners.forEach(function (listener) { return listener(); });
this._destroyed = true;
};
Object.defineProperty(PlatformRef.prototype, "destroyed", {
get: function () { return this._destroyed; },
enumerable: true,
configurable: true
});
PlatformRef = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable(),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [Injector])
], PlatformRef);
return PlatformRef;
}());
function getNgZone(ngZoneOption) {
var ngZone;
if (ngZoneOption === 'noop') {
ngZone = new NoopNgZone();
}
else {
ngZone = (ngZoneOption === 'zone.js' ? undefined : ngZoneOption) ||
new NgZone({ enableLongStackTrace: isDevMode() });
}
return ngZone;
}
function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
try {
var result = callback();
if (isPromise(result)) {
return result.catch(function (e) {
ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
// rethrow as the exception handler might not do it
throw e;
});
}
return result;
}
catch (e) {
ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
// rethrow as the exception handler might not do it
throw e;
}
}
function optionsReducer(dst, objs) {
if (Array.isArray(objs)) {
dst = objs.reduce(optionsReducer, dst);
}
else {
dst = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({}, dst, objs);
}
return dst;
}
/**
* A reference to an Angular application running on a page.
*
* @publicApi
*/
var ApplicationRef = /** @class */ (function () {
/** @internal */
function ApplicationRef(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus) {
var _this = this;
this._zone = _zone;
this._console = _console;
this._injector = _injector;
this._exceptionHandler = _exceptionHandler;
this._componentFactoryResolver = _componentFactoryResolver;
this._initStatus = _initStatus;
this._bootstrapListeners = [];
this._views = [];
this._runningTick = false;
this._enforceNoNewChanges = false;
this._stable = true;
/**
* Get a list of component types registered to this application.
* This list is populated even before the component is created.
*/
this.componentTypes = [];
/**
* Get a list of components registered to this application.
*/
this.components = [];
this._enforceNoNewChanges = isDevMode();
this._zone.onMicrotaskEmpty.subscribe({ next: function () { _this._zone.run(function () { _this.tick(); }); } });
var isCurrentlyStable = new rxjs__WEBPACK_IMPORTED_MODULE_1__["Observable"](function (observer) {
_this._stable = _this._zone.isStable && !_this._zone.hasPendingMacrotasks &&
!_this._zone.hasPendingMicrotasks;
_this._zone.runOutsideAngular(function () {
observer.next(_this._stable);
observer.complete();
});
});
var isStable = new rxjs__WEBPACK_IMPORTED_MODULE_1__["Observable"](function (observer) {
// Create the subscription to onStable outside the Angular Zone so that
// the callback is run outside the Angular Zone.
var stableSub;
_this._zone.runOutsideAngular(function () {
stableSub = _this._zone.onStable.subscribe(function () {
NgZone.assertNotInAngularZone();
// Check whether there are no pending macro/micro tasks in the next tick
// to allow for NgZone to update the state.
scheduleMicroTask(function () {
if (!_this._stable && !_this._zone.hasPendingMacrotasks &&
!_this._zone.hasPendingMicrotasks) {
_this._stable = true;
observer.next(true);
}
});
});
});
var unstableSub = _this._zone.onUnstable.subscribe(function () {
NgZone.assertInAngularZone();
if (_this._stable) {
_this._stable = false;
_this._zone.runOutsideAngular(function () { observer.next(false); });
}
});
return function () {
stableSub.unsubscribe();
unstableSub.unsubscribe();
};
});
this.isStable =
Object(rxjs__WEBPACK_IMPORTED_MODULE_1__["merge"])(isCurrentlyStable, isStable.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_2__["share"])()));
}
ApplicationRef_1 = ApplicationRef;
/**
* Bootstrap a new component at the root level of the application.
*
* @usageNotes
* ### Bootstrap process
*
* When bootstrapping a new root component into an application, Angular mounts the
* specified application component onto DOM elements identified by the componentType's
* selector and kicks off automatic change detection to finish initializing the component.
*
* Optionally, a component can be mounted onto a DOM element that does not match the
* componentType's selector.
*
* ### Example
* {@example core/ts/platform/platform.ts region='longform'}
*/
ApplicationRef.prototype.bootstrap = function (componentOrFactory, rootSelectorOrNode) {
var _this = this;
if (!this._initStatus.done) {
throw new Error('Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
}
var componentFactory;
if (componentOrFactory instanceof ComponentFactory) {
componentFactory = componentOrFactory;
}
else {
componentFactory =
this._componentFactoryResolver.resolveComponentFactory(componentOrFactory);
}
this.componentTypes.push(componentFactory.componentType);
// Create a factory associated with the current module if it's not bound to some other
var ngModule = componentFactory instanceof ComponentFactoryBoundToModule ?
null :
this._injector.get(NgModuleRef);
var selectorOrNode = rootSelectorOrNode || componentFactory.selector;
var compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
compRef.onDestroy(function () { _this._unloadComponent(compRef); });
var testability = compRef.injector.get(Testability, null);
if (testability) {
compRef.injector.get(TestabilityRegistry)
.registerApplication(compRef.location.nativeElement, testability);
}
this._loadComponent(compRef);
if (isDevMode()) {
this._console.log("Angular is running in the development mode. Call enableProdMode() to enable the production mode.");
}
return compRef;
};
/**
* Invoke this method to explicitly process change detection and its side-effects.
*
* In development mode, `tick()` also performs a second change detection cycle to ensure that no
* further changes are detected. If additional changes are picked up during this second cycle,
* bindings in the app have side-effects that cannot be resolved in a single change detection
* pass.
* In this case, Angular throws an error, since an Angular application can only have one change
* detection pass during which all change detection must complete.
*/
ApplicationRef.prototype.tick = function () {
var _this = this;
if (this._runningTick) {
throw new Error('ApplicationRef.tick is called recursively');
}
var scope = ApplicationRef_1._tickScope();
try {
this._runningTick = true;
this._views.forEach(function (view) { return view.detectChanges(); });
if (this._enforceNoNewChanges) {
this._views.forEach(function (view) { return view.checkNoChanges(); });
}
}
catch (e) {
// Attention: Don't rethrow as it could cancel subscriptions to Observables!
this._zone.runOutsideAngular(function () { return _this._exceptionHandler.handleError(e); });
}
finally {
this._runningTick = false;
wtfLeave(scope);
}
};
/**
* Attaches a view so that it will be dirty checked.
* The view will be automatically detached when it is destroyed.
* This will throw if the view is already attached to a ViewContainer.
*/
ApplicationRef.prototype.attachView = function (viewRef) {
var view = viewRef;
this._views.push(view);
view.attachToAppRef(this);
};
/**
* Detaches a view from dirty checking again.
*/
ApplicationRef.prototype.detachView = function (viewRef) {
var view = viewRef;
remove(this._views, view);
view.detachFromAppRef();
};
ApplicationRef.prototype._loadComponent = function (componentRef) {
this.attachView(componentRef.hostView);
this.tick();
this.components.push(componentRef);
// Get the listeners lazily to prevent DI cycles.
var listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
listeners.forEach(function (listener) { return listener(componentRef); });
};
ApplicationRef.prototype._unloadComponent = function (componentRef) {
this.detachView(componentRef.hostView);
remove(this.components, componentRef);
};
/** @internal */
ApplicationRef.prototype.ngOnDestroy = function () {
// TODO(alxhub): Dispose of the NgZone.
this._views.slice().forEach(function (view) { return view.destroy(); });
};
Object.defineProperty(ApplicationRef.prototype, "viewCount", {
/**
* Returns the number of attached views.
*/
get: function () { return this._views.length; },
enumerable: true,
configurable: true
});
var ApplicationRef_1;
/** @internal */
ApplicationRef._tickScope = wtfCreateScope('ApplicationRef#tick()');
ApplicationRef = ApplicationRef_1 = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable(),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [NgZone, Console, Injector,
ErrorHandler,
ComponentFactoryResolver,
ApplicationInitStatus])
], ApplicationRef);
return ApplicationRef;
}());
function remove(list, el) {
var index = list.indexOf(el);
if (index > -1) {
list.splice(index, 1);
}
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* An unmodifiable list of items that Angular keeps up to date when the state
* of the application changes.
*
* The type of object that {@link ViewChildren}, {@link ContentChildren}, and {@link QueryList}
* provide.
*
* Implements an iterable interface, therefore it can be used in both ES6
* javascript `for (var i of items)` loops as well as in Angular templates with
* `*ngFor="let i of myList"`.
*
* Changes can be observed by subscribing to the changes `Observable`.
*
* NOTE: In the future this class will implement an `Observable` interface.
*
* @usageNotes
* ### Example
* ```typescript
* @Component({...})
* class Container {
* @ViewChildren(Item) items:QueryList<Item>;
* }
* ```
*
* @publicApi
*/
var QueryList$1 = /** @class */ (function () {
function QueryList() {
this.dirty = true;
this._results = [];
this.changes = new EventEmitter();
this.length = 0;
}
/**
* See
* [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
*/
QueryList.prototype.map = function (fn) { return this._results.map(fn); };
/**
* See
* [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
*/
QueryList.prototype.filter = function (fn) {
return this._results.filter(fn);
};
/**
* See
* [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
*/
QueryList.prototype.find = function (fn) {
return this._results.find(fn);
};
/**
* See
* [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
*/
QueryList.prototype.reduce = function (fn, init) {
return this._results.reduce(fn, init);
};
/**
* See
* [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
*/
QueryList.prototype.forEach = function (fn) { this._results.forEach(fn); };
/**
* See
* [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
*/
QueryList.prototype.some = function (fn) {
return this._results.some(fn);
};
QueryList.prototype.toArray = function () { return this._results.slice(); };
QueryList.prototype[getSymbolIterator()] = function () { return this._results[getSymbolIterator()](); };
QueryList.prototype.toString = function () { return this._results.toString(); };
QueryList.prototype.reset = function (res) {
this._results = flatten$2(res);
this.dirty = false;
this.length = this._results.length;
this.last = this._results[this.length - 1];
this.first = this._results[0];
};
QueryList.prototype.notifyOnChanges = function () { this.changes.emit(this); };
/** internal */
QueryList.prototype.setDirty = function () { this.dirty = true; };
/** internal */
QueryList.prototype.destroy = function () {
this.changes.complete();
this.changes.unsubscribe();
};
return QueryList;
}());
function flatten$2(list) {
return list.reduce(function (flat, item) {
var flatItem = Array.isArray(item) ? flatten$2(item) : item;
return flat.concat(flatItem);
}, []);
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var _SEPARATOR = '#';
var FACTORY_CLASS_SUFFIX = 'NgFactory';
/**
* Configuration for SystemJsNgModuleLoader.
* token.
*
* @publicApi
*/
var SystemJsNgModuleLoaderConfig = /** @class */ (function () {
function SystemJsNgModuleLoaderConfig() {
}
return SystemJsNgModuleLoaderConfig;
}());
var DEFAULT_CONFIG = {
factoryPathPrefix: '',
factoryPathSuffix: '.ngfactory',
};
/**
* NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
* @publicApi
*/
var SystemJsNgModuleLoader = /** @class */ (function () {
function SystemJsNgModuleLoader(_compiler, config) {
this._compiler = _compiler;
this._config = config || DEFAULT_CONFIG;
}
SystemJsNgModuleLoader.prototype.load = function (path) {
var offlineMode = this._compiler instanceof Compiler;
return offlineMode ? this.loadFactory(path) : this.loadAndCompile(path);
};
SystemJsNgModuleLoader.prototype.loadAndCompile = function (path) {
var _this = this;
var _a = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__read"])(path.split(_SEPARATOR), 2), module = _a[0], exportName = _a[1];
if (exportName === undefined) {
exportName = 'default';
}
return __webpack_require__(207)(module)
.then(function (module) { return module[exportName]; })
.then(function (type) { return checkNotEmpty(type, module, exportName); })
.then(function (type) { return _this._compiler.compileModuleAsync(type); });
};
SystemJsNgModuleLoader.prototype.loadFactory = function (path) {
var _a = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__read"])(path.split(_SEPARATOR), 2), module = _a[0], exportName = _a[1];
var factoryClassSuffix = FACTORY_CLASS_SUFFIX;
if (exportName === undefined) {
exportName = 'default';
factoryClassSuffix = '';
}
return __webpack_require__(207)(this._config.factoryPathPrefix + module + this._config.factoryPathSuffix)
.then(function (module) { return module[exportName + factoryClassSuffix]; })
.then(function (factory) { return checkNotEmpty(factory, module, exportName); });
};
SystemJsNgModuleLoader = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
Injectable(),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__param"])(1, Optional()),
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__metadata"])("design:paramtypes", [Compiler, SystemJsNgModuleLoaderConfig])
], SystemJsNgModuleLoader);
return SystemJsNgModuleLoader;
}());
function checkNotEmpty(value, modulePath, exportName) {
if (!value) {
throw new Error("Cannot find '" + exportName + "' in '" + modulePath + "'");
}
return value;
}
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Represents a container where one or more views can be attached to a component.
*
* Can contain *host views* (created by instantiating a
* component with the `createComponent()` method), and *embedded views*
* (created by instantiating a `TemplateRef` with the `createEmbeddedView()` method).
*
* A view container instance can contain other view containers,
* creating a [view hierarchy](guide/glossary#view-tree).
*
* @see `ComponentRef`
* @see `EmbeddedViewRef`
*
* @publicApi
*/
var ViewContainerRef = /** @class */ (function () {
function ViewContainerRef() {
}
/** @internal */
ViewContainerRef.__NG_ELEMENT_ID__ = function () { return SWITCH_VIEW_CONTAINER_REF_FACTORY(ViewContainerRef, ElementRef); };
return ViewContainerRef;
}());
var SWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__ = injectViewContainerRef;
var SWITCH_VIEW_CONTAINER_REF_FACTORY__PRE_R3__ = noop;
var SWITCH_VIEW_CONTAINER_REF_FACTORY = SWITCH_VIEW_CONTAINER_REF_FACTORY__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Base class for Angular Views, provides change detection functionality.
* A change-detection tree collects all views that are to be checked for changes.
* Use the methods to add and remove views from the tree, initiate change-detection,
* and explicitly mark views as _dirty_, meaning that they have changed and need to be rerendered.
*
* @usageNotes
*
* The following examples demonstrate how to modify default change-detection behavior
* to perform explicit detection when needed.
*
* ### Use `markForCheck()` with `CheckOnce` strategy
*
* The following example sets the `OnPush` change-detection strategy for a component
* (`CheckOnce`, rather than the default `CheckAlways`), then forces a second check
* after an interval. See [live demo](http://plnkr.co/edit/GC512b?p=preview).
*
* <code-example path="core/ts/change_detect/change-detection.ts"
* region="mark-for-check"></code-example>
*
* ### Detach change detector to limit how often check occurs
*
* The following example defines a component with a large list of read-only data
* that is expected to change constantly, many times per second.
* To improve performance, we want to check and update the list
* less often than the changes actually occur. To do that, we detach
* the component's change detector and perform an explicit local check every five seconds.
*
* <code-example path="core/ts/change_detect/change-detection.ts" region="detach"></code-example>
*
*
* ### Reattaching a detached component
*
* The following example creates a component displaying live data.
* The component detaches its change detector from the main change detector tree
* when the `live` property is set to false, and reattaches it when the property
* becomes true.
*
* <code-example path="core/ts/change_detect/change-detection.ts" region="reattach"></code-example>
*
* @publicApi
*/
var ChangeDetectorRef = /** @class */ (function () {
function ChangeDetectorRef() {
}
/** @internal */
ChangeDetectorRef.__NG_ELEMENT_ID__ = function () { return SWITCH_CHANGE_DETECTOR_REF_FACTORY(); };
return ChangeDetectorRef;
}());
var SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__ = injectChangeDetectorRef;
var SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__ = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
};
var SWITCH_CHANGE_DETECTOR_REF_FACTORY = SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__;
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Represents an Angular [view](guide/glossary#view),
* specifically the [host view](guide/glossary#view-tree) that is defined by a component.
* Also serves as the base class
* that adds destroy methods for [embedded views](guide/glossary#view-tree).
*
* @see `EmbeddedViewRef`
*
* @publicApi
*/
var ViewRef$1 = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(ViewRef, _super);
function ViewRef() {
return _super !== null && _super.apply(this, arguments) || this;
}
return ViewRef;
}(ChangeDetectorRef));
/**
* Represents an Angular [view](guide/glossary#view) in a view container.
* An [embedded view](guide/glossary#view-tree) can be referenced from a component
* other than the hosting component whose template defines it, or it can be defined
* independently by a `TemplateRef`.
*
* Properties of elements in a view can change, but the structure (number and order) of elements in
* a view cannot. Change the structure of elements by inserting, moving, or
* removing nested views in a view container.
*
* @see `ViewContainerRef`
*
* @usageNotes
*
* The following template breaks down into two separate `TemplateRef` instances,
* an outer one and an inner one.
*
* ```
* Count: {{items.length}}
* <ul>
* <li *ngFor="let item of items">{{item}}</li>
* </ul>
* ```
*
* This is the outer `TemplateRef`:
*
* ```
* Count: {{items.length}}
* <ul>
* <ng-template ngFor let-item [ngForOf]="items"></ng-template>
* </ul>
* ```
*
* This is the inner `TemplateRef`:
*
* ```
* <li>{{item}}</li>
* ```
*
* The outer and inner `TemplateRef` instances are assembled into views as follows:
*
* ```
* <!-- ViewRef: outer-0 -->
* Count: 2
* <ul>
* <ng-template view-container-ref></ng-template>
* <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
* <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
* </ul>
* <!-- /ViewRef: outer-0 -->
* ```
* @publicApi
*/
var EmbeddedViewRef = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(EmbeddedViewRef, _super);
function EmbeddedViewRef() {
return _super !== null && _super.apply(this, arguments) || this;
}
return EmbeddedViewRef;
}(ViewRef$1));
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var EventListener = /** @class */ (function () {
function EventListener(name, callback) {
this.name = name;
this.callback = callback;
}
return EventListener;
}());
var DebugNode__PRE_R3__ = /** @class */ (function () {
function DebugNode__PRE_R3__(nativeNode, parent, _debugContext) {
this.listeners = [];
this.parent = null;
this._debugContext = _debugContext;
this.nativeNode = nativeNode;
if (parent && parent instanceof DebugElement__PRE_R3__) {
parent.addChild(this);
}
}
Object.defineProperty(DebugNode__PRE_R3__.prototype, "injector", {
get: function () { return this._debugContext.injector; },
enumerable: true,
configurable: true
});
Object.defineProperty(DebugNode__PRE_R3__.prototype, "componentInstance", {
get: function () { return this._debugContext.component; },
enumerable: true,
configurable: true
});
Object.defineProperty(DebugNode__PRE_R3__.prototype, "context", {
get: function () { return this._debugContext.context; },
enumerable: true,
configurable: true
});
Object.defineProperty(DebugNode__PRE_R3__.prototype, "references", {
get: function () { return this._debugContext.references; },
enumerable: true,
configurable: true
});
Object.defineProperty(DebugNode__PRE_R3__.prototype, "providerTokens", {
get: function () { return this._debugContext.providerTokens; },
enumerable: true,
configurable: true
});
return DebugNode__PRE_R3__;
}());
var DebugElement__PRE_R3__ = /** @class */ (function (_super) {
Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(DebugElement__PRE_R3__, _super);
function DebugElement__PRE_R3__(nativeNode, parent, _debugContext) {
var _this = _super.call(this, nativeNode, parent, _debugContext) || this;
_this.properties = {};
_this.attributes = {};
_this.classes = {};
_this.styles = {};
_this.childNodes = [];
_this.nativeElement = nativeNode;
return _this;
}
DebugElement__PRE_R3__.prototype.addChild = function (child) {
if (child) {
this.childNodes.push(child);
child.parent = this;
}
};
DebugElement__PRE_R3__.prototype.removeChild = function (child) {
var childIndex = this.childNodes.indexOf(child);
if (childIndex !== -1) {
child.parent = null;
this.childNodes.splice(childIndex, 1);
}
};
DebugElement__PRE_R3__.prototype.insertChildrenAfter = function (child, newChildren) {
var _this = this;
var _a;
var siblingIndex = this.childNodes.indexOf(child);
if (siblingIndex !== -1) {
(_a = this.childNodes).splice.apply(_a, Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spread"])([siblingIndex + 1, 0], newChildren));
newChildren.forEach(function (c) {
if (c.parent) {
c.parent.removeChild(c);
}
child.parent = _this;
});
}
};
DebugElement__PRE_R3__.prototype.insertBefore = function (refChild, newChild) {
var refIndex = this.childNodes.indexOf(refChild);
if (refIndex === -1) {
this.addChild(newChild);
}
else {
if (newChild.parent) {
newChild.parent.removeChild(newChild);
}
newChild.parent = this;
this.childNodes.splice(refIndex, 0, newChild);
}
};
DebugElement__PRE_R3__.prototype.query = function (predicate) {
var results = this.queryAll(predicate);
return results[0] || null;
};
DebugElement__PRE_R3__.prototype.queryAll = function (predicate) {
var matches = [];
_queryElementChildren(this, predicate, matches);
return matches;
};
DebugElement__PRE_R3__.prototype.queryAllNodes = function (predicate) {
var matches = [];
_queryNodeChildren(this, predicate, matches);
return matches;
};
Object.defineProperty(DebugElement__PRE_R3__.prototype, "children", {
get: function () {
return this
.childNodes //
.filter(function (node) { return node instanceof DebugElement__PRE_R3__; });
},
enumerable: true,
configurable: true
});
DebugElement__PRE_R3__.prototype.triggerEventHandler = function (eventName, eventObj) {
this.listeners.forEach(function (listener) {
if (listener.name == eventName) {
listener.callback(eventObj);
}
});
};
return DebugElement__PRE_R3__;
}(DebugNode__PRE_R3__));
/**
* @publicApi
*/
function asNativeElements(debugEls) {
return debugEls.map(function (el) { return el.nativeElement; });
}
function _queryElementChildren(element, predicate, matches) {
element.childNodes.forEach(function (node) {
if (node instanceof DebugElement__PRE_R3__) {
if (predicate(node)) {
matches.push(node);
}
_queryElementChildren(node, predicate, matches);
}
});
}
function _queryNodeChildren(parentNode, predicate, matches) {
if (parentNode instanceof DebugElement__PRE_R3__) {
parentNode.childNodes.forEach(function (node) {
if (predicate(node)) {
matches.push(node);
}
if (node instanceof DebugElement__PRE_R3__) {
_queryNodeChildren(node, predicate, matches);
}
});
}
}
var DebugNode__POST_R3__ = /** @class */ (function () {
function DebugNode__POST_R3__(nativeNode) {
this.nativeNode = nativeNode;
}
Object.defineProperty(DebugNode__POST_R3__.prototype, "parent", {
get: function () {
var parent = this.nativeNode.parentNode;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment