| /** |
| * @license Angular v11.2.14 |
| * (c) 2010-2021 Google LLC. https://angular.io/ |
| * License: MIT |
| */ |
| |
| (function (global, factory) { |
| typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : |
| typeof define === 'function' && define.amd ? define('@angular/compiler', ['exports'], factory) : |
| (global = global || self, factory((global.ng = global.ng || {}, global.ng.compiler = {}))); |
| }(this, (function (exports) { 'use strict'; |
| |
| /*! ***************************************************************************** |
| Copyright (c) Microsoft Corporation. |
| |
| Permission to use, copy, modify, and/or distribute this software for any |
| purpose with or without fee is hereby granted. |
| |
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH |
| REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
| AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, |
| INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
| LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR |
| OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| PERFORMANCE OF THIS SOFTWARE. |
| ***************************************************************************** */ |
| /* global Reflect, Promise */ |
| var extendStatics = function (d, b) { |
| extendStatics = Object.setPrototypeOf || |
| ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || |
| function (d, b) { for (var p in b) |
| if (b.hasOwnProperty(p)) |
| d[p] = b[p]; }; |
| return extendStatics(d, b); |
| }; |
| function __extends(d, b) { |
| extendStatics(d, b); |
| function __() { this.constructor = d; } |
| d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); |
| } |
| var __assign = function () { |
| __assign = Object.assign || function __assign(t) { |
| for (var s, i = 1, n = arguments.length; i < n; i++) { |
| s = arguments[i]; |
| for (var p in s) |
| if (Object.prototype.hasOwnProperty.call(s, p)) |
| t[p] = s[p]; |
| } |
| return t; |
| }; |
| return __assign.apply(this, arguments); |
| }; |
| function __rest(s, e) { |
| var t = {}; |
| for (var p in s) |
| if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) |
| t[p] = s[p]; |
| if (s != null && typeof Object.getOwnPropertySymbols === "function") |
| for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { |
| if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) |
| t[p[i]] = s[p[i]]; |
| } |
| return t; |
| } |
| function __decorate(decorators, target, key, desc) { |
| var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; |
| if (typeof Reflect === "object" && typeof Reflect.decorate === "function") |
| r = Reflect.decorate(decorators, target, key, desc); |
| else |
| for (var i = decorators.length - 1; i >= 0; i--) |
| if (d = decorators[i]) |
| r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; |
| return c > 3 && r && Object.defineProperty(target, key, r), r; |
| } |
| function __param(paramIndex, decorator) { |
| return function (target, key) { decorator(target, key, paramIndex); }; |
| } |
| function __metadata(metadataKey, metadataValue) { |
| if (typeof Reflect === "object" && typeof Reflect.metadata === "function") |
| return Reflect.metadata(metadataKey, metadataValue); |
| } |
| function __awaiter(thisArg, _arguments, P, generator) { |
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } |
| return new (P || (P = Promise))(function (resolve, reject) { |
| function fulfilled(value) { try { |
| step(generator.next(value)); |
| } |
| catch (e) { |
| reject(e); |
| } } |
| function rejected(value) { try { |
| step(generator["throw"](value)); |
| } |
| catch (e) { |
| reject(e); |
| } } |
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } |
| step((generator = generator.apply(thisArg, _arguments || [])).next()); |
| }); |
| } |
| function __generator(thisArg, body) { |
| var _ = { label: 0, sent: function () { if (t[0] & 1) |
| throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; |
| return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; |
| function verb(n) { return function (v) { return step([n, v]); }; } |
| function step(op) { |
| if (f) |
| throw new TypeError("Generator is already executing."); |
| while (_) |
| try { |
| if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) |
| return t; |
| if (y = 0, t) |
| op = [op[0] & 2, t.value]; |
| switch (op[0]) { |
| case 0: |
| case 1: |
| t = op; |
| break; |
| case 4: |
| _.label++; |
| return { value: op[1], done: false }; |
| case 5: |
| _.label++; |
| y = op[1]; |
| op = [0]; |
| continue; |
| case 7: |
| op = _.ops.pop(); |
| _.trys.pop(); |
| continue; |
| default: |
| if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { |
| _ = 0; |
| continue; |
| } |
| if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { |
| _.label = op[1]; |
| break; |
| } |
| if (op[0] === 6 && _.label < t[1]) { |
| _.label = t[1]; |
| t = op; |
| break; |
| } |
| if (t && _.label < t[2]) { |
| _.label = t[2]; |
| _.ops.push(op); |
| break; |
| } |
| if (t[2]) |
| _.ops.pop(); |
| _.trys.pop(); |
| continue; |
| } |
| op = body.call(thisArg, _); |
| } |
| catch (e) { |
| op = [6, e]; |
| y = 0; |
| } |
| finally { |
| f = t = 0; |
| } |
| if (op[0] & 5) |
| throw op[1]; |
| return { value: op[0] ? op[1] : void 0, done: true }; |
| } |
| } |
| var __createBinding = Object.create ? (function (o, m, k, k2) { |
| if (k2 === undefined) |
| k2 = k; |
| Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } }); |
| }) : (function (o, m, k, k2) { |
| if (k2 === undefined) |
| k2 = k; |
| o[k2] = m[k]; |
| }); |
| function __exportStar(m, exports) { |
| for (var p in m) |
| if (p !== "default" && !exports.hasOwnProperty(p)) |
| __createBinding(exports, m, p); |
| } |
| function __values(o) { |
| var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; |
| if (m) |
| return m.call(o); |
| if (o && typeof o.length === "number") |
| return { |
| next: function () { |
| if (o && i >= o.length) |
| o = void 0; |
| return { value: o && o[i++], done: !o }; |
| } |
| }; |
| throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); |
| } |
| function __read(o, n) { |
| var m = typeof Symbol === "function" && o[Symbol.iterator]; |
| if (!m) |
| return o; |
| var i = m.call(o), r, ar = [], e; |
| try { |
| while ((n === void 0 || n-- > 0) && !(r = i.next()).done) |
| ar.push(r.value); |
| } |
| catch (error) { |
| e = { error: error }; |
| } |
| finally { |
| try { |
| if (r && !r.done && (m = i["return"])) |
| m.call(i); |
| } |
| finally { |
| if (e) |
| throw e.error; |
| } |
| } |
| return ar; |
| } |
| function __spread() { |
| for (var ar = [], i = 0; i < arguments.length; i++) |
| ar = ar.concat(__read(arguments[i])); |
| return ar; |
| } |
| function __spreadArrays() { |
| for (var s = 0, i = 0, il = arguments.length; i < il; i++) |
| s += arguments[i].length; |
| for (var r = Array(s), k = 0, i = 0; i < il; i++) |
| for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) |
| r[k] = a[j]; |
| return r; |
| } |
| ; |
| function __await(v) { |
| return this instanceof __await ? (this.v = v, this) : new __await(v); |
| } |
| function __asyncGenerator(thisArg, _arguments, generator) { |
| if (!Symbol.asyncIterator) |
| throw new TypeError("Symbol.asyncIterator is not defined."); |
| var g = generator.apply(thisArg, _arguments || []), i, q = []; |
| return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; |
| function verb(n) { if (g[n]) |
| i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } |
| function resume(n, v) { try { |
| step(g[n](v)); |
| } |
| catch (e) { |
| settle(q[0][3], e); |
| } } |
| function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } |
| function fulfill(value) { resume("next", value); } |
| function reject(value) { resume("throw", value); } |
| function settle(f, v) { if (f(v), q.shift(), q.length) |
| resume(q[0][0], q[0][1]); } |
| } |
| function __asyncDelegator(o) { |
| var i, p; |
| return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; |
| function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } |
| } |
| function __asyncValues(o) { |
| if (!Symbol.asyncIterator) |
| throw new TypeError("Symbol.asyncIterator is not defined."); |
| var m = o[Symbol.asyncIterator], i; |
| return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); |
| function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } |
| function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); } |
| } |
| function __makeTemplateObject(cooked, raw) { |
| if (Object.defineProperty) { |
| Object.defineProperty(cooked, "raw", { value: raw }); |
| } |
| else { |
| cooked.raw = raw; |
| } |
| return cooked; |
| } |
| ; |
| var __setModuleDefault = Object.create ? (function (o, v) { |
| Object.defineProperty(o, "default", { enumerable: true, value: v }); |
| }) : function (o, v) { |
| o["default"] = v; |
| }; |
| function __importStar(mod) { |
| if (mod && mod.__esModule) |
| return mod; |
| var result = {}; |
| if (mod != null) |
| for (var k in mod) |
| if (Object.hasOwnProperty.call(mod, k)) |
| __createBinding(result, mod, k); |
| __setModuleDefault(result, mod); |
| return result; |
| } |
| function __importDefault(mod) { |
| return (mod && mod.__esModule) ? mod : { default: mod }; |
| } |
| function __classPrivateFieldGet(receiver, privateMap) { |
| if (!privateMap.has(receiver)) { |
| throw new TypeError("attempted to get private field on non-instance"); |
| } |
| return privateMap.get(receiver); |
| } |
| function __classPrivateFieldSet(receiver, privateMap, value) { |
| if (!privateMap.has(receiver)) { |
| throw new TypeError("attempted to set private field on non-instance"); |
| } |
| privateMap.set(receiver, value); |
| return value; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| (function (TagContentType) { |
| TagContentType[TagContentType["RAW_TEXT"] = 0] = "RAW_TEXT"; |
| TagContentType[TagContentType["ESCAPABLE_RAW_TEXT"] = 1] = "ESCAPABLE_RAW_TEXT"; |
| TagContentType[TagContentType["PARSABLE_DATA"] = 2] = "PARSABLE_DATA"; |
| })(exports.TagContentType || (exports.TagContentType = {})); |
| function splitNsName(elementName) { |
| if (elementName[0] != ':') { |
| return [null, elementName]; |
| } |
| var colonIndex = elementName.indexOf(':', 1); |
| if (colonIndex == -1) { |
| throw new Error("Unsupported format \"" + elementName + "\" expecting \":namespace:name\""); |
| } |
| return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)]; |
| } |
| // `<ng-container>` tags work the same regardless the namespace |
| function isNgContainer(tagName) { |
| return splitNsName(tagName)[1] === 'ng-container'; |
| } |
| // `<ng-content>` tags work the same regardless the namespace |
| function isNgContent(tagName) { |
| return splitNsName(tagName)[1] === 'ng-content'; |
| } |
| // `<ng-template>` tags work the same regardless the namespace |
| function isNgTemplate(tagName) { |
| return splitNsName(tagName)[1] === 'ng-template'; |
| } |
| function getNsPrefix(fullName) { |
| return fullName === null ? null : splitNsName(fullName)[0]; |
| } |
| function mergeNsAndName(prefix, localName) { |
| return prefix ? ":" + prefix + ":" + localName : localName; |
| } |
| // see https://www.w3.org/TR/html51/syntax.html#named-character-references |
| // see https://html.spec.whatwg.org/multipage/entities.json |
| // This list is not exhaustive to keep the compiler footprint low. |
| // The `{` / `ƫ` syntax should be used when the named character reference does not |
| // exist. |
| var NAMED_ENTITIES = { |
| 'Aacute': '\u00C1', |
| 'aacute': '\u00E1', |
| 'Acirc': '\u00C2', |
| 'acirc': '\u00E2', |
| 'acute': '\u00B4', |
| 'AElig': '\u00C6', |
| 'aelig': '\u00E6', |
| 'Agrave': '\u00C0', |
| 'agrave': '\u00E0', |
| 'alefsym': '\u2135', |
| 'Alpha': '\u0391', |
| 'alpha': '\u03B1', |
| 'amp': '&', |
| 'and': '\u2227', |
| 'ang': '\u2220', |
| 'apos': '\u0027', |
| 'Aring': '\u00C5', |
| 'aring': '\u00E5', |
| 'asymp': '\u2248', |
| 'Atilde': '\u00C3', |
| 'atilde': '\u00E3', |
| 'Auml': '\u00C4', |
| 'auml': '\u00E4', |
| 'bdquo': '\u201E', |
| 'Beta': '\u0392', |
| 'beta': '\u03B2', |
| 'brvbar': '\u00A6', |
| 'bull': '\u2022', |
| 'cap': '\u2229', |
| 'Ccedil': '\u00C7', |
| 'ccedil': '\u00E7', |
| 'cedil': '\u00B8', |
| 'cent': '\u00A2', |
| 'Chi': '\u03A7', |
| 'chi': '\u03C7', |
| 'circ': '\u02C6', |
| 'clubs': '\u2663', |
| 'cong': '\u2245', |
| 'copy': '\u00A9', |
| 'crarr': '\u21B5', |
| 'cup': '\u222A', |
| 'curren': '\u00A4', |
| 'dagger': '\u2020', |
| 'Dagger': '\u2021', |
| 'darr': '\u2193', |
| 'dArr': '\u21D3', |
| 'deg': '\u00B0', |
| 'Delta': '\u0394', |
| 'delta': '\u03B4', |
| 'diams': '\u2666', |
| 'divide': '\u00F7', |
| 'Eacute': '\u00C9', |
| 'eacute': '\u00E9', |
| 'Ecirc': '\u00CA', |
| 'ecirc': '\u00EA', |
| 'Egrave': '\u00C8', |
| 'egrave': '\u00E8', |
| 'empty': '\u2205', |
| 'emsp': '\u2003', |
| 'ensp': '\u2002', |
| 'Epsilon': '\u0395', |
| 'epsilon': '\u03B5', |
| 'equiv': '\u2261', |
| 'Eta': '\u0397', |
| 'eta': '\u03B7', |
| 'ETH': '\u00D0', |
| 'eth': '\u00F0', |
| 'Euml': '\u00CB', |
| 'euml': '\u00EB', |
| 'euro': '\u20AC', |
| 'exist': '\u2203', |
| 'fnof': '\u0192', |
| 'forall': '\u2200', |
| 'frac12': '\u00BD', |
| 'frac14': '\u00BC', |
| 'frac34': '\u00BE', |
| 'frasl': '\u2044', |
| 'Gamma': '\u0393', |
| 'gamma': '\u03B3', |
| 'ge': '\u2265', |
| 'gt': '>', |
| 'harr': '\u2194', |
| 'hArr': '\u21D4', |
| 'hearts': '\u2665', |
| 'hellip': '\u2026', |
| 'Iacute': '\u00CD', |
| 'iacute': '\u00ED', |
| 'Icirc': '\u00CE', |
| 'icirc': '\u00EE', |
| 'iexcl': '\u00A1', |
| 'Igrave': '\u00CC', |
| 'igrave': '\u00EC', |
| 'image': '\u2111', |
| 'infin': '\u221E', |
| 'int': '\u222B', |
| 'Iota': '\u0399', |
| 'iota': '\u03B9', |
| 'iquest': '\u00BF', |
| 'isin': '\u2208', |
| 'Iuml': '\u00CF', |
| 'iuml': '\u00EF', |
| 'Kappa': '\u039A', |
| 'kappa': '\u03BA', |
| 'Lambda': '\u039B', |
| 'lambda': '\u03BB', |
| 'lang': '\u27E8', |
| 'laquo': '\u00AB', |
| 'larr': '\u2190', |
| 'lArr': '\u21D0', |
| 'lceil': '\u2308', |
| 'ldquo': '\u201C', |
| 'le': '\u2264', |
| 'lfloor': '\u230A', |
| 'lowast': '\u2217', |
| 'loz': '\u25CA', |
| 'lrm': '\u200E', |
| 'lsaquo': '\u2039', |
| 'lsquo': '\u2018', |
| 'lt': '<', |
| 'macr': '\u00AF', |
| 'mdash': '\u2014', |
| 'micro': '\u00B5', |
| 'middot': '\u00B7', |
| 'minus': '\u2212', |
| 'Mu': '\u039C', |
| 'mu': '\u03BC', |
| 'nabla': '\u2207', |
| 'nbsp': '\u00A0', |
| 'ndash': '\u2013', |
| 'ne': '\u2260', |
| 'ni': '\u220B', |
| 'not': '\u00AC', |
| 'notin': '\u2209', |
| 'nsub': '\u2284', |
| 'Ntilde': '\u00D1', |
| 'ntilde': '\u00F1', |
| 'Nu': '\u039D', |
| 'nu': '\u03BD', |
| 'Oacute': '\u00D3', |
| 'oacute': '\u00F3', |
| 'Ocirc': '\u00D4', |
| 'ocirc': '\u00F4', |
| 'OElig': '\u0152', |
| 'oelig': '\u0153', |
| 'Ograve': '\u00D2', |
| 'ograve': '\u00F2', |
| 'oline': '\u203E', |
| 'Omega': '\u03A9', |
| 'omega': '\u03C9', |
| 'Omicron': '\u039F', |
| 'omicron': '\u03BF', |
| 'oplus': '\u2295', |
| 'or': '\u2228', |
| 'ordf': '\u00AA', |
| 'ordm': '\u00BA', |
| 'Oslash': '\u00D8', |
| 'oslash': '\u00F8', |
| 'Otilde': '\u00D5', |
| 'otilde': '\u00F5', |
| 'otimes': '\u2297', |
| 'Ouml': '\u00D6', |
| 'ouml': '\u00F6', |
| 'para': '\u00B6', |
| 'permil': '\u2030', |
| 'perp': '\u22A5', |
| 'Phi': '\u03A6', |
| 'phi': '\u03C6', |
| 'Pi': '\u03A0', |
| 'pi': '\u03C0', |
| 'piv': '\u03D6', |
| 'plusmn': '\u00B1', |
| 'pound': '\u00A3', |
| 'prime': '\u2032', |
| 'Prime': '\u2033', |
| 'prod': '\u220F', |
| 'prop': '\u221D', |
| 'Psi': '\u03A8', |
| 'psi': '\u03C8', |
| 'quot': '\u0022', |
| 'radic': '\u221A', |
| 'rang': '\u27E9', |
| 'raquo': '\u00BB', |
| 'rarr': '\u2192', |
| 'rArr': '\u21D2', |
| 'rceil': '\u2309', |
| 'rdquo': '\u201D', |
| 'real': '\u211C', |
| 'reg': '\u00AE', |
| 'rfloor': '\u230B', |
| 'Rho': '\u03A1', |
| 'rho': '\u03C1', |
| 'rlm': '\u200F', |
| 'rsaquo': '\u203A', |
| 'rsquo': '\u2019', |
| 'sbquo': '\u201A', |
| 'Scaron': '\u0160', |
| 'scaron': '\u0161', |
| 'sdot': '\u22C5', |
| 'sect': '\u00A7', |
| 'shy': '\u00AD', |
| 'Sigma': '\u03A3', |
| 'sigma': '\u03C3', |
| 'sigmaf': '\u03C2', |
| 'sim': '\u223C', |
| 'spades': '\u2660', |
| 'sub': '\u2282', |
| 'sube': '\u2286', |
| 'sum': '\u2211', |
| 'sup': '\u2283', |
| 'sup1': '\u00B9', |
| 'sup2': '\u00B2', |
| 'sup3': '\u00B3', |
| 'supe': '\u2287', |
| 'szlig': '\u00DF', |
| 'Tau': '\u03A4', |
| 'tau': '\u03C4', |
| 'there4': '\u2234', |
| 'Theta': '\u0398', |
| 'theta': '\u03B8', |
| 'thetasym': '\u03D1', |
| 'thinsp': '\u2009', |
| 'THORN': '\u00DE', |
| 'thorn': '\u00FE', |
| 'tilde': '\u02DC', |
| 'times': '\u00D7', |
| 'trade': '\u2122', |
| 'Uacute': '\u00DA', |
| 'uacute': '\u00FA', |
| 'uarr': '\u2191', |
| 'uArr': '\u21D1', |
| 'Ucirc': '\u00DB', |
| 'ucirc': '\u00FB', |
| 'Ugrave': '\u00D9', |
| 'ugrave': '\u00F9', |
| 'uml': '\u00A8', |
| 'upsih': '\u03D2', |
| 'Upsilon': '\u03A5', |
| 'upsilon': '\u03C5', |
| 'Uuml': '\u00DC', |
| 'uuml': '\u00FC', |
| 'weierp': '\u2118', |
| 'Xi': '\u039E', |
| 'xi': '\u03BE', |
| 'Yacute': '\u00DD', |
| 'yacute': '\u00FD', |
| 'yen': '\u00A5', |
| 'yuml': '\u00FF', |
| 'Yuml': '\u0178', |
| 'Zeta': '\u0396', |
| 'zeta': '\u03B6', |
| 'zwj': '\u200D', |
| 'zwnj': '\u200C', |
| }; |
| // The &ngsp; pseudo-entity is denoting a space. see: |
| // https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart |
| var NGSP_UNICODE = '\uE500'; |
| NAMED_ENTITIES['ngsp'] = NGSP_UNICODE; |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var HtmlTagDefinition = /** @class */ (function () { |
| function HtmlTagDefinition(_c) { |
| var _this = this; |
| var _d = _c === void 0 ? {} : _c, closedByChildren = _d.closedByChildren, implicitNamespacePrefix = _d.implicitNamespacePrefix, _e = _d.contentType, contentType = _e === void 0 ? exports.TagContentType.PARSABLE_DATA : _e, _f = _d.closedByParent, closedByParent = _f === void 0 ? false : _f, _g = _d.isVoid, isVoid = _g === void 0 ? false : _g, _h = _d.ignoreFirstLf, ignoreFirstLf = _h === void 0 ? false : _h, _j = _d.preventNamespaceInheritance, preventNamespaceInheritance = _j === void 0 ? false : _j; |
| this.closedByChildren = {}; |
| this.closedByParent = false; |
| this.canSelfClose = false; |
| if (closedByChildren && closedByChildren.length > 0) { |
| closedByChildren.forEach(function (tagName) { return _this.closedByChildren[tagName] = true; }); |
| } |
| this.isVoid = isVoid; |
| this.closedByParent = closedByParent || isVoid; |
| this.implicitNamespacePrefix = implicitNamespacePrefix || null; |
| this.contentType = contentType; |
| this.ignoreFirstLf = ignoreFirstLf; |
| this.preventNamespaceInheritance = preventNamespaceInheritance; |
| } |
| HtmlTagDefinition.prototype.isClosedByChild = function (name) { |
| return this.isVoid || name.toLowerCase() in this.closedByChildren; |
| }; |
| HtmlTagDefinition.prototype.getContentType = function (prefix) { |
| if (typeof this.contentType === 'object') { |
| var overrideType = prefix == null ? undefined : this.contentType[prefix]; |
| return overrideType !== null && overrideType !== void 0 ? overrideType : this.contentType.default; |
| } |
| return this.contentType; |
| }; |
| return HtmlTagDefinition; |
| }()); |
| var _DEFAULT_TAG_DEFINITION; |
| // see https://www.w3.org/TR/html51/syntax.html#optional-tags |
| // This implementation does not fully conform to the HTML5 spec. |
| var TAG_DEFINITIONS; |
| function getHtmlTagDefinition(tagName) { |
| var _a, _b; |
| if (!TAG_DEFINITIONS) { |
| _DEFAULT_TAG_DEFINITION = new HtmlTagDefinition(); |
| TAG_DEFINITIONS = { |
| 'base': new HtmlTagDefinition({ isVoid: true }), |
| 'meta': new HtmlTagDefinition({ isVoid: true }), |
| 'area': new HtmlTagDefinition({ isVoid: true }), |
| 'embed': new HtmlTagDefinition({ isVoid: true }), |
| 'link': new HtmlTagDefinition({ isVoid: true }), |
| 'img': new HtmlTagDefinition({ isVoid: true }), |
| 'input': new HtmlTagDefinition({ isVoid: true }), |
| 'param': new HtmlTagDefinition({ isVoid: true }), |
| 'hr': new HtmlTagDefinition({ isVoid: true }), |
| 'br': new HtmlTagDefinition({ isVoid: true }), |
| 'source': new HtmlTagDefinition({ isVoid: true }), |
| 'track': new HtmlTagDefinition({ isVoid: true }), |
| 'wbr': new HtmlTagDefinition({ isVoid: true }), |
| 'p': new HtmlTagDefinition({ |
| closedByChildren: [ |
| 'address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', |
| 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', |
| 'h6', 'header', 'hgroup', 'hr', 'main', 'nav', 'ol', |
| 'p', 'pre', 'section', 'table', 'ul' |
| ], |
| closedByParent: true |
| }), |
| 'thead': new HtmlTagDefinition({ closedByChildren: ['tbody', 'tfoot'] }), |
| 'tbody': new HtmlTagDefinition({ closedByChildren: ['tbody', 'tfoot'], closedByParent: true }), |
| 'tfoot': new HtmlTagDefinition({ closedByChildren: ['tbody'], closedByParent: true }), |
| 'tr': new HtmlTagDefinition({ closedByChildren: ['tr'], closedByParent: true }), |
| 'td': new HtmlTagDefinition({ closedByChildren: ['td', 'th'], closedByParent: true }), |
| 'th': new HtmlTagDefinition({ closedByChildren: ['td', 'th'], closedByParent: true }), |
| 'col': new HtmlTagDefinition({ isVoid: true }), |
| 'svg': new HtmlTagDefinition({ implicitNamespacePrefix: 'svg' }), |
| 'foreignObject': new HtmlTagDefinition({ |
| // Usually the implicit namespace here would be redundant since it will be inherited from |
| // the parent `svg`, but we have to do it for `foreignObject`, because the way the parser |
| // works is that the parent node of an end tag is its own start tag which means that |
| // the `preventNamespaceInheritance` on `foreignObject` would have it default to the |
| // implicit namespace which is `html`, unless specified otherwise. |
| implicitNamespacePrefix: 'svg', |
| // We want to prevent children of foreignObject from inheriting its namespace, because |
| // the point of the element is to allow nodes from other namespaces to be inserted. |
| preventNamespaceInheritance: true, |
| }), |
| 'math': new HtmlTagDefinition({ implicitNamespacePrefix: 'math' }), |
| 'li': new HtmlTagDefinition({ closedByChildren: ['li'], closedByParent: true }), |
| 'dt': new HtmlTagDefinition({ closedByChildren: ['dt', 'dd'] }), |
| 'dd': new HtmlTagDefinition({ closedByChildren: ['dt', 'dd'], closedByParent: true }), |
| 'rb': new HtmlTagDefinition({ closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true }), |
| 'rt': new HtmlTagDefinition({ closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true }), |
| 'rtc': new HtmlTagDefinition({ closedByChildren: ['rb', 'rtc', 'rp'], closedByParent: true }), |
| 'rp': new HtmlTagDefinition({ closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true }), |
| 'optgroup': new HtmlTagDefinition({ closedByChildren: ['optgroup'], closedByParent: true }), |
| 'option': new HtmlTagDefinition({ closedByChildren: ['option', 'optgroup'], closedByParent: true }), |
| 'pre': new HtmlTagDefinition({ ignoreFirstLf: true }), |
| 'listing': new HtmlTagDefinition({ ignoreFirstLf: true }), |
| 'style': new HtmlTagDefinition({ contentType: exports.TagContentType.RAW_TEXT }), |
| 'script': new HtmlTagDefinition({ contentType: exports.TagContentType.RAW_TEXT }), |
| 'title': new HtmlTagDefinition({ |
| // The browser supports two separate `title` tags which have to use |
| // a different content type: `HTMLTitleElement` and `SVGTitleElement` |
| contentType: { default: exports.TagContentType.ESCAPABLE_RAW_TEXT, svg: exports.TagContentType.PARSABLE_DATA } |
| }), |
| 'textarea': new HtmlTagDefinition({ contentType: exports.TagContentType.ESCAPABLE_RAW_TEXT, ignoreFirstLf: true }), |
| }; |
| } |
| // We have to make both a case-sensitive and a case-insesitive lookup, because |
| // HTML tag names are case insensitive, whereas some SVG tags are case sensitive. |
| return (_b = (_a = TAG_DEFINITIONS[tagName]) !== null && _a !== void 0 ? _a : TAG_DEFINITIONS[tagName.toLowerCase()]) !== null && _b !== void 0 ? _b : _DEFAULT_TAG_DEFINITION; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var _SELECTOR_REGEXP = new RegExp('(\\:not\\()|' + // 1: ":not(" |
| '(([\\.\\#]?)[-\\w]+)|' + // 2: "tag"; 3: "."/"#"; |
| // "-" should appear first in the regexp below as FF31 parses "[.-\w]" as a range |
| // 4: attribute; 5: attribute_string; 6: attribute_value |
| '(?:\\[([-.\\w*]+)(?:=([\"\']?)([^\\]\"\']*)\\5)?\\])|' + // "[name]", "[name=value]", |
| // "[name="value"]", |
| // "[name='value']" |
| '(\\))|' + // 7: ")" |
| '(\\s*,\\s*)', // 8: "," |
| 'g'); |
| /** |
| * A css selector contains an element name, |
| * css classes and attribute/value pairs with the purpose |
| * of selecting subsets out of them. |
| */ |
| var CssSelector = /** @class */ (function () { |
| function CssSelector() { |
| this.element = null; |
| this.classNames = []; |
| /** |
| * The selectors are encoded in pairs where: |
| * - even locations are attribute names |
| * - odd locations are attribute values. |
| * |
| * Example: |
| * Selector: `[key1=value1][key2]` would parse to: |
| * ``` |
| * ['key1', 'value1', 'key2', ''] |
| * ``` |
| */ |
| this.attrs = []; |
| this.notSelectors = []; |
| } |
| CssSelector.parse = function (selector) { |
| var results = []; |
| var _addResult = function (res, cssSel) { |
| if (cssSel.notSelectors.length > 0 && !cssSel.element && cssSel.classNames.length == 0 && |
| cssSel.attrs.length == 0) { |
| cssSel.element = '*'; |
| } |
| res.push(cssSel); |
| }; |
| var cssSelector = new CssSelector(); |
| var match; |
| var current = cssSelector; |
| var inNot = false; |
| _SELECTOR_REGEXP.lastIndex = 0; |
| while (match = _SELECTOR_REGEXP.exec(selector)) { |
| if (match[1 /* NOT */]) { |
| if (inNot) { |
| throw new Error('Nesting :not in a selector is not allowed'); |
| } |
| inNot = true; |
| current = new CssSelector(); |
| cssSelector.notSelectors.push(current); |
| } |
| var tag = match[2 /* TAG */]; |
| if (tag) { |
| var prefix = match[3 /* PREFIX */]; |
| if (prefix === '#') { |
| // #hash |
| current.addAttribute('id', tag.substr(1)); |
| } |
| else if (prefix === '.') { |
| // Class |
| current.addClassName(tag.substr(1)); |
| } |
| else { |
| // Element |
| current.setElement(tag); |
| } |
| } |
| var attribute = match[4 /* ATTRIBUTE */]; |
| if (attribute) { |
| current.addAttribute(attribute, match[6 /* ATTRIBUTE_VALUE */]); |
| } |
| if (match[7 /* NOT_END */]) { |
| inNot = false; |
| current = cssSelector; |
| } |
| if (match[8 /* SEPARATOR */]) { |
| if (inNot) { |
| throw new Error('Multiple selectors in :not are not supported'); |
| } |
| _addResult(results, cssSelector); |
| cssSelector = current = new CssSelector(); |
| } |
| } |
| _addResult(results, cssSelector); |
| return results; |
| }; |
| CssSelector.prototype.isElementSelector = function () { |
| return this.hasElementSelector() && this.classNames.length == 0 && this.attrs.length == 0 && |
| this.notSelectors.length === 0; |
| }; |
| CssSelector.prototype.hasElementSelector = function () { |
| return !!this.element; |
| }; |
| CssSelector.prototype.setElement = function (element) { |
| if (element === void 0) { element = null; } |
| this.element = element; |
| }; |
| /** Gets a template string for an element that matches the selector. */ |
| CssSelector.prototype.getMatchingElementTemplate = function () { |
| var tagName = this.element || 'div'; |
| var classAttr = this.classNames.length > 0 ? " class=\"" + this.classNames.join(' ') + "\"" : ''; |
| var attrs = ''; |
| for (var i = 0; i < this.attrs.length; i += 2) { |
| var attrName = this.attrs[i]; |
| var attrValue = this.attrs[i + 1] !== '' ? "=\"" + this.attrs[i + 1] + "\"" : ''; |
| attrs += " " + attrName + attrValue; |
| } |
| return getHtmlTagDefinition(tagName).isVoid ? "<" + tagName + classAttr + attrs + "/>" : |
| "<" + tagName + classAttr + attrs + "></" + tagName + ">"; |
| }; |
| CssSelector.prototype.getAttrs = function () { |
| var result = []; |
| if (this.classNames.length > 0) { |
| result.push('class', this.classNames.join(' ')); |
| } |
| return result.concat(this.attrs); |
| }; |
| CssSelector.prototype.addAttribute = function (name, value) { |
| if (value === void 0) { value = ''; } |
| this.attrs.push(name, value && value.toLowerCase() || ''); |
| }; |
| CssSelector.prototype.addClassName = function (name) { |
| this.classNames.push(name.toLowerCase()); |
| }; |
| CssSelector.prototype.toString = function () { |
| var res = this.element || ''; |
| if (this.classNames) { |
| this.classNames.forEach(function (klass) { return res += "." + klass; }); |
| } |
| if (this.attrs) { |
| for (var i = 0; i < this.attrs.length; i += 2) { |
| var name = this.attrs[i]; |
| var value = this.attrs[i + 1]; |
| res += "[" + name + (value ? '=' + value : '') + "]"; |
| } |
| } |
| this.notSelectors.forEach(function (notSelector) { return res += ":not(" + notSelector + ")"; }); |
| return res; |
| }; |
| return CssSelector; |
| }()); |
| /** |
| * Reads a list of CssSelectors and allows to calculate which ones |
| * are contained in a given CssSelector. |
| */ |
| var SelectorMatcher = /** @class */ (function () { |
| function SelectorMatcher() { |
| this._elementMap = new Map(); |
| this._elementPartialMap = new Map(); |
| this._classMap = new Map(); |
| this._classPartialMap = new Map(); |
| this._attrValueMap = new Map(); |
| this._attrValuePartialMap = new Map(); |
| this._listContexts = []; |
| } |
| SelectorMatcher.createNotMatcher = function (notSelectors) { |
| var notMatcher = new SelectorMatcher(); |
| notMatcher.addSelectables(notSelectors, null); |
| return notMatcher; |
| }; |
| SelectorMatcher.prototype.addSelectables = function (cssSelectors, callbackCtxt) { |
| var listContext = null; |
| if (cssSelectors.length > 1) { |
| listContext = new SelectorListContext(cssSelectors); |
| this._listContexts.push(listContext); |
| } |
| for (var i = 0; i < cssSelectors.length; i++) { |
| this._addSelectable(cssSelectors[i], callbackCtxt, listContext); |
| } |
| }; |
| /** |
| * Add an object that can be found later on by calling `match`. |
| * @param cssSelector A css selector |
| * @param callbackCtxt An opaque object that will be given to the callback of the `match` function |
| */ |
| SelectorMatcher.prototype._addSelectable = function (cssSelector, callbackCtxt, listContext) { |
| var matcher = this; |
| var element = cssSelector.element; |
| var classNames = cssSelector.classNames; |
| var attrs = cssSelector.attrs; |
| var selectable = new SelectorContext(cssSelector, callbackCtxt, listContext); |
| if (element) { |
| var isTerminal = attrs.length === 0 && classNames.length === 0; |
| if (isTerminal) { |
| this._addTerminal(matcher._elementMap, element, selectable); |
| } |
| else { |
| matcher = this._addPartial(matcher._elementPartialMap, element); |
| } |
| } |
| if (classNames) { |
| for (var i = 0; i < classNames.length; i++) { |
| var isTerminal = attrs.length === 0 && i === classNames.length - 1; |
| var className = classNames[i]; |
| if (isTerminal) { |
| this._addTerminal(matcher._classMap, className, selectable); |
| } |
| else { |
| matcher = this._addPartial(matcher._classPartialMap, className); |
| } |
| } |
| } |
| if (attrs) { |
| for (var i = 0; i < attrs.length; i += 2) { |
| var isTerminal = i === attrs.length - 2; |
| var name = attrs[i]; |
| var value = attrs[i + 1]; |
| if (isTerminal) { |
| var terminalMap = matcher._attrValueMap; |
| var terminalValuesMap = terminalMap.get(name); |
| if (!terminalValuesMap) { |
| terminalValuesMap = new Map(); |
| terminalMap.set(name, terminalValuesMap); |
| } |
| this._addTerminal(terminalValuesMap, value, selectable); |
| } |
| else { |
| var partialMap = matcher._attrValuePartialMap; |
| var partialValuesMap = partialMap.get(name); |
| if (!partialValuesMap) { |
| partialValuesMap = new Map(); |
| partialMap.set(name, partialValuesMap); |
| } |
| matcher = this._addPartial(partialValuesMap, value); |
| } |
| } |
| } |
| }; |
| SelectorMatcher.prototype._addTerminal = function (map, name, selectable) { |
| var terminalList = map.get(name); |
| if (!terminalList) { |
| terminalList = []; |
| map.set(name, terminalList); |
| } |
| terminalList.push(selectable); |
| }; |
| SelectorMatcher.prototype._addPartial = function (map, name) { |
| var matcher = map.get(name); |
| if (!matcher) { |
| matcher = new SelectorMatcher(); |
| map.set(name, matcher); |
| } |
| return matcher; |
| }; |
| /** |
| * Find the objects that have been added via `addSelectable` |
| * whose css selector is contained in the given css selector. |
| * @param cssSelector A css selector |
| * @param matchedCallback This callback will be called with the object handed into `addSelectable` |
| * @return boolean true if a match was found |
| */ |
| SelectorMatcher.prototype.match = function (cssSelector, matchedCallback) { |
| var result = false; |
| var element = cssSelector.element; |
| var classNames = cssSelector.classNames; |
| var attrs = cssSelector.attrs; |
| for (var i = 0; i < this._listContexts.length; i++) { |
| this._listContexts[i].alreadyMatched = false; |
| } |
| result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result; |
| result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) || |
| result; |
| if (classNames) { |
| for (var i = 0; i < classNames.length; i++) { |
| var className = classNames[i]; |
| result = |
| this._matchTerminal(this._classMap, className, cssSelector, matchedCallback) || result; |
| result = |
| this._matchPartial(this._classPartialMap, className, cssSelector, matchedCallback) || |
| result; |
| } |
| } |
| if (attrs) { |
| for (var i = 0; i < attrs.length; i += 2) { |
| var name = attrs[i]; |
| var value = attrs[i + 1]; |
| var terminalValuesMap = this._attrValueMap.get(name); |
| if (value) { |
| result = |
| this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result; |
| } |
| result = |
| this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result; |
| var partialValuesMap = this._attrValuePartialMap.get(name); |
| if (value) { |
| result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result; |
| } |
| result = |
| this._matchPartial(partialValuesMap, value, cssSelector, matchedCallback) || result; |
| } |
| } |
| return result; |
| }; |
| /** @internal */ |
| SelectorMatcher.prototype._matchTerminal = function (map, name, cssSelector, matchedCallback) { |
| if (!map || typeof name !== 'string') { |
| return false; |
| } |
| var selectables = map.get(name) || []; |
| var starSelectables = map.get('*'); |
| if (starSelectables) { |
| selectables = selectables.concat(starSelectables); |
| } |
| if (selectables.length === 0) { |
| return false; |
| } |
| var selectable; |
| var result = false; |
| for (var i = 0; i < selectables.length; i++) { |
| selectable = selectables[i]; |
| result = selectable.finalize(cssSelector, matchedCallback) || result; |
| } |
| return result; |
| }; |
| /** @internal */ |
| SelectorMatcher.prototype._matchPartial = function (map, name, cssSelector, matchedCallback) { |
| if (!map || typeof name !== 'string') { |
| return false; |
| } |
| var nestedSelector = map.get(name); |
| if (!nestedSelector) { |
| return false; |
| } |
| // TODO(perf): get rid of recursion and measure again |
| // TODO(perf): don't pass the whole selector into the recursion, |
| // but only the not processed parts |
| return nestedSelector.match(cssSelector, matchedCallback); |
| }; |
| return SelectorMatcher; |
| }()); |
| var SelectorListContext = /** @class */ (function () { |
| function SelectorListContext(selectors) { |
| this.selectors = selectors; |
| this.alreadyMatched = false; |
| } |
| return SelectorListContext; |
| }()); |
| // Store context to pass back selector and context when a selector is matched |
| var SelectorContext = /** @class */ (function () { |
| function SelectorContext(selector, cbContext, listContext) { |
| this.selector = selector; |
| this.cbContext = cbContext; |
| this.listContext = listContext; |
| this.notSelectors = selector.notSelectors; |
| } |
| SelectorContext.prototype.finalize = function (cssSelector, callback) { |
| var result = true; |
| if (this.notSelectors.length > 0 && (!this.listContext || !this.listContext.alreadyMatched)) { |
| var notMatcher = SelectorMatcher.createNotMatcher(this.notSelectors); |
| result = !notMatcher.match(cssSelector, null); |
| } |
| if (result && callback && (!this.listContext || !this.listContext.alreadyMatched)) { |
| if (this.listContext) { |
| this.listContext.alreadyMatched = true; |
| } |
| callback(this.selector, this.cbContext); |
| } |
| return result; |
| }; |
| return SelectorContext; |
| }()); |
| |
| var createInject = makeMetadataFactory('Inject', function (token) { return ({ token: token }); }); |
| var createInjectionToken = makeMetadataFactory('InjectionToken', function (desc) { return ({ _desc: desc, ɵprov: undefined }); }); |
| var createAttribute = makeMetadataFactory('Attribute', function (attributeName) { return ({ attributeName: attributeName }); }); |
| // Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not |
| // explicitly set. This value will be changed to `true` in v12. |
| // TODO(misko): switch the default in v12 to `true`. See: packages/core/src/metadata/di.ts |
| var emitDistinctChangesOnlyDefaultValue = false; |
| var createContentChildren = makeMetadataFactory('ContentChildren', function (selector, data) { |
| if (data === void 0) { data = {}; } |
| return (Object.assign({ selector: selector, first: false, isViewQuery: false, descendants: false, emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue }, data)); |
| }); |
| var createContentChild = makeMetadataFactory('ContentChild', function (selector, data) { |
| if (data === void 0) { data = {}; } |
| return (Object.assign({ selector: selector, first: true, isViewQuery: false, descendants: true }, data)); |
| }); |
| var createViewChildren = makeMetadataFactory('ViewChildren', function (selector, data) { |
| if (data === void 0) { data = {}; } |
| return (Object.assign({ selector: selector, first: false, isViewQuery: true, descendants: true, emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue }, data)); |
| }); |
| var createViewChild = makeMetadataFactory('ViewChild', function (selector, data) { return (Object.assign({ selector: selector, first: true, isViewQuery: true, descendants: true }, data)); }); |
| var createDirective = makeMetadataFactory('Directive', function (dir) { |
| if (dir === void 0) { dir = {}; } |
| return dir; |
| }); |
| var ViewEncapsulation; |
| (function (ViewEncapsulation) { |
| ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated"; |
| // Historically the 1 value was for `Native` encapsulation which has been removed as of v11. |
| ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None"; |
| ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom"; |
| })(ViewEncapsulation || (ViewEncapsulation = {})); |
| var ChangeDetectionStrategy; |
| (function (ChangeDetectionStrategy) { |
| ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush"; |
| ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default"; |
| })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {})); |
| var createComponent = makeMetadataFactory('Component', function (c) { |
| if (c === void 0) { c = {}; } |
| return (Object.assign({ changeDetection: ChangeDetectionStrategy.Default }, c)); |
| }); |
| var createPipe = makeMetadataFactory('Pipe', function (p) { return (Object.assign({ pure: true }, p)); }); |
| var createInput = makeMetadataFactory('Input', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); }); |
| var createOutput = makeMetadataFactory('Output', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); }); |
| var createHostBinding = makeMetadataFactory('HostBinding', function (hostPropertyName) { return ({ hostPropertyName: hostPropertyName }); }); |
| var createHostListener = makeMetadataFactory('HostListener', function (eventName, args) { return ({ eventName: eventName, args: args }); }); |
| var createNgModule = makeMetadataFactory('NgModule', function (ngModule) { return ngModule; }); |
| var createInjectable = makeMetadataFactory('Injectable', function (injectable) { |
| if (injectable === void 0) { injectable = {}; } |
| return injectable; |
| }); |
| var CUSTOM_ELEMENTS_SCHEMA = { |
| name: 'custom-elements' |
| }; |
| var NO_ERRORS_SCHEMA = { |
| name: 'no-errors-schema' |
| }; |
| var createOptional = makeMetadataFactory('Optional'); |
| var createSelf = makeMetadataFactory('Self'); |
| var createSkipSelf = makeMetadataFactory('SkipSelf'); |
| var createHost = makeMetadataFactory('Host'); |
| var Type = Function; |
| 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 = {})); |
| var MissingTranslationStrategy; |
| (function (MissingTranslationStrategy) { |
| MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error"; |
| MissingTranslationStrategy[MissingTranslationStrategy["Warning"] = 1] = "Warning"; |
| MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore"; |
| })(MissingTranslationStrategy || (MissingTranslationStrategy = {})); |
| function makeMetadataFactory(name, props) { |
| // This must be declared as a function, not a fat arrow, so that ES2015 devmode produces code |
| // that works with the static_reflector.ts in the ViewEngine compiler. |
| // In particular, `_registerDecoratorOrConstructor` assumes that the value returned here can be |
| // new'ed. |
| function factory() { |
| var args = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| args[_i] = arguments[_i]; |
| } |
| var values = props ? props.apply(void 0, __spread(args)) : {}; |
| return Object.assign({ ngMetadataName: name }, values); |
| } |
| factory.isTypeOf = function (obj) { return obj && obj.ngMetadataName === name; }; |
| factory.ngMetadataName = name; |
| return factory; |
| } |
| function parserSelectorToSimpleSelector(selector) { |
| var classes = selector.classNames && selector.classNames.length ? __spread([8 /* CLASS */], selector.classNames) : |
| []; |
| var elementName = selector.element && selector.element !== '*' ? selector.element : ''; |
| return __spread([elementName], selector.attrs, classes); |
| } |
| function parserSelectorToNegativeSelector(selector) { |
| var classes = selector.classNames && selector.classNames.length ? __spread([8 /* CLASS */], selector.classNames) : |
| []; |
| if (selector.element) { |
| return __spread([ |
| 1 /* NOT */ | 4 /* ELEMENT */, selector.element |
| ], selector.attrs, classes); |
| } |
| else if (selector.attrs.length) { |
| return __spread([1 /* NOT */ | 2 /* ATTRIBUTE */], selector.attrs, classes); |
| } |
| else { |
| return selector.classNames && selector.classNames.length ? __spread([1 /* NOT */ | 8 /* CLASS */], selector.classNames) : |
| []; |
| } |
| } |
| function parserSelectorToR3Selector(selector) { |
| var positive = parserSelectorToSimpleSelector(selector); |
| var negative = selector.notSelectors && selector.notSelectors.length ? |
| selector.notSelectors.map(function (notSelector) { return parserSelectorToNegativeSelector(notSelector); }) : |
| []; |
| return positive.concat.apply(positive, __spread(negative)); |
| } |
| function parseSelectorToR3Selector(selector) { |
| return selector ? CssSelector.parse(selector).map(parserSelectorToR3Selector) : []; |
| } |
| |
| var core = /*#__PURE__*/Object.freeze({ |
| __proto__: null, |
| createInject: createInject, |
| createInjectionToken: createInjectionToken, |
| createAttribute: createAttribute, |
| emitDistinctChangesOnlyDefaultValue: emitDistinctChangesOnlyDefaultValue, |
| createContentChildren: createContentChildren, |
| createContentChild: createContentChild, |
| createViewChildren: createViewChildren, |
| createViewChild: createViewChild, |
| createDirective: createDirective, |
| get ViewEncapsulation () { return ViewEncapsulation; }, |
| get ChangeDetectionStrategy () { return ChangeDetectionStrategy; }, |
| createComponent: createComponent, |
| createPipe: createPipe, |
| createInput: createInput, |
| createOutput: createOutput, |
| createHostBinding: createHostBinding, |
| createHostListener: createHostListener, |
| createNgModule: createNgModule, |
| createInjectable: createInjectable, |
| CUSTOM_ELEMENTS_SCHEMA: CUSTOM_ELEMENTS_SCHEMA, |
| NO_ERRORS_SCHEMA: NO_ERRORS_SCHEMA, |
| createOptional: createOptional, |
| createSelf: createSelf, |
| createSkipSelf: createSkipSelf, |
| createHost: createHost, |
| Type: Type, |
| get SecurityContext () { return SecurityContext; }, |
| get MissingTranslationStrategy () { return MissingTranslationStrategy; }, |
| parseSelectorToR3Selector: parseSelectorToR3Selector |
| }); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| //// Types |
| var TypeModifier; |
| (function (TypeModifier) { |
| TypeModifier[TypeModifier["Const"] = 0] = "Const"; |
| })(TypeModifier || (TypeModifier = {})); |
| var Type$1 = /** @class */ (function () { |
| function Type(modifiers) { |
| if (modifiers === void 0) { modifiers = []; } |
| this.modifiers = modifiers; |
| } |
| Type.prototype.hasModifier = function (modifier) { |
| return this.modifiers.indexOf(modifier) !== -1; |
| }; |
| return Type; |
| }()); |
| (function (BuiltinTypeName) { |
| BuiltinTypeName[BuiltinTypeName["Dynamic"] = 0] = "Dynamic"; |
| BuiltinTypeName[BuiltinTypeName["Bool"] = 1] = "Bool"; |
| BuiltinTypeName[BuiltinTypeName["String"] = 2] = "String"; |
| BuiltinTypeName[BuiltinTypeName["Int"] = 3] = "Int"; |
| BuiltinTypeName[BuiltinTypeName["Number"] = 4] = "Number"; |
| BuiltinTypeName[BuiltinTypeName["Function"] = 5] = "Function"; |
| BuiltinTypeName[BuiltinTypeName["Inferred"] = 6] = "Inferred"; |
| BuiltinTypeName[BuiltinTypeName["None"] = 7] = "None"; |
| })(exports.BuiltinTypeName || (exports.BuiltinTypeName = {})); |
| var BuiltinType = /** @class */ (function (_super) { |
| __extends(BuiltinType, _super); |
| function BuiltinType(name, modifiers) { |
| var _this = _super.call(this, modifiers) || this; |
| _this.name = name; |
| return _this; |
| } |
| BuiltinType.prototype.visitType = function (visitor, context) { |
| return visitor.visitBuiltinType(this, context); |
| }; |
| return BuiltinType; |
| }(Type$1)); |
| var ExpressionType = /** @class */ (function (_super) { |
| __extends(ExpressionType, _super); |
| function ExpressionType(value, modifiers, typeParams) { |
| if (typeParams === void 0) { typeParams = null; } |
| var _this = _super.call(this, modifiers) || this; |
| _this.value = value; |
| _this.typeParams = typeParams; |
| return _this; |
| } |
| ExpressionType.prototype.visitType = function (visitor, context) { |
| return visitor.visitExpressionType(this, context); |
| }; |
| return ExpressionType; |
| }(Type$1)); |
| var ArrayType = /** @class */ (function (_super) { |
| __extends(ArrayType, _super); |
| function ArrayType(of, modifiers) { |
| var _this = _super.call(this, modifiers) || this; |
| _this.of = of; |
| return _this; |
| } |
| ArrayType.prototype.visitType = function (visitor, context) { |
| return visitor.visitArrayType(this, context); |
| }; |
| return ArrayType; |
| }(Type$1)); |
| var MapType = /** @class */ (function (_super) { |
| __extends(MapType, _super); |
| function MapType(valueType, modifiers) { |
| var _this = _super.call(this, modifiers) || this; |
| _this.valueType = valueType || null; |
| return _this; |
| } |
| MapType.prototype.visitType = function (visitor, context) { |
| return visitor.visitMapType(this, context); |
| }; |
| return MapType; |
| }(Type$1)); |
| var DYNAMIC_TYPE = new BuiltinType(exports.BuiltinTypeName.Dynamic); |
| var INFERRED_TYPE = new BuiltinType(exports.BuiltinTypeName.Inferred); |
| var BOOL_TYPE = new BuiltinType(exports.BuiltinTypeName.Bool); |
| var INT_TYPE = new BuiltinType(exports.BuiltinTypeName.Int); |
| var NUMBER_TYPE = new BuiltinType(exports.BuiltinTypeName.Number); |
| var STRING_TYPE = new BuiltinType(exports.BuiltinTypeName.String); |
| var FUNCTION_TYPE = new BuiltinType(exports.BuiltinTypeName.Function); |
| var NONE_TYPE = new BuiltinType(exports.BuiltinTypeName.None); |
| (function (UnaryOperator) { |
| UnaryOperator[UnaryOperator["Minus"] = 0] = "Minus"; |
| UnaryOperator[UnaryOperator["Plus"] = 1] = "Plus"; |
| })(exports.UnaryOperator || (exports.UnaryOperator = {})); |
| (function (BinaryOperator) { |
| BinaryOperator[BinaryOperator["Equals"] = 0] = "Equals"; |
| BinaryOperator[BinaryOperator["NotEquals"] = 1] = "NotEquals"; |
| BinaryOperator[BinaryOperator["Identical"] = 2] = "Identical"; |
| BinaryOperator[BinaryOperator["NotIdentical"] = 3] = "NotIdentical"; |
| BinaryOperator[BinaryOperator["Minus"] = 4] = "Minus"; |
| BinaryOperator[BinaryOperator["Plus"] = 5] = "Plus"; |
| BinaryOperator[BinaryOperator["Divide"] = 6] = "Divide"; |
| BinaryOperator[BinaryOperator["Multiply"] = 7] = "Multiply"; |
| BinaryOperator[BinaryOperator["Modulo"] = 8] = "Modulo"; |
| BinaryOperator[BinaryOperator["And"] = 9] = "And"; |
| BinaryOperator[BinaryOperator["Or"] = 10] = "Or"; |
| BinaryOperator[BinaryOperator["BitwiseAnd"] = 11] = "BitwiseAnd"; |
| BinaryOperator[BinaryOperator["Lower"] = 12] = "Lower"; |
| BinaryOperator[BinaryOperator["LowerEquals"] = 13] = "LowerEquals"; |
| BinaryOperator[BinaryOperator["Bigger"] = 14] = "Bigger"; |
| BinaryOperator[BinaryOperator["BiggerEquals"] = 15] = "BiggerEquals"; |
| })(exports.BinaryOperator || (exports.BinaryOperator = {})); |
| function nullSafeIsEquivalent(base, other) { |
| if (base == null || other == null) { |
| return base == other; |
| } |
| return base.isEquivalent(other); |
| } |
| function areAllEquivalentPredicate(base, other, equivalentPredicate) { |
| var len = base.length; |
| if (len !== other.length) { |
| return false; |
| } |
| for (var i = 0; i < len; i++) { |
| if (!equivalentPredicate(base[i], other[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| function areAllEquivalent(base, other) { |
| return areAllEquivalentPredicate(base, other, function (baseElement, otherElement) { return baseElement.isEquivalent(otherElement); }); |
| } |
| var Expression = /** @class */ (function () { |
| function Expression(type, sourceSpan) { |
| this.type = type || null; |
| this.sourceSpan = sourceSpan || null; |
| } |
| Expression.prototype.prop = function (name, sourceSpan) { |
| return new ReadPropExpr(this, name, null, sourceSpan); |
| }; |
| Expression.prototype.key = function (index, type, sourceSpan) { |
| return new ReadKeyExpr(this, index, type, sourceSpan); |
| }; |
| Expression.prototype.callMethod = function (name, params, sourceSpan) { |
| return new InvokeMethodExpr(this, name, params, null, sourceSpan); |
| }; |
| Expression.prototype.callFn = function (params, sourceSpan, pure) { |
| return new InvokeFunctionExpr(this, params, null, sourceSpan, pure); |
| }; |
| Expression.prototype.instantiate = function (params, type, sourceSpan) { |
| return new InstantiateExpr(this, params, type, sourceSpan); |
| }; |
| Expression.prototype.conditional = function (trueCase, falseCase, sourceSpan) { |
| if (falseCase === void 0) { falseCase = null; } |
| return new ConditionalExpr(this, trueCase, falseCase, null, sourceSpan); |
| }; |
| Expression.prototype.equals = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Equals, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.notEquals = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.NotEquals, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.identical = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Identical, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.notIdentical = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.NotIdentical, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.minus = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Minus, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.plus = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Plus, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.divide = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Divide, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.multiply = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Multiply, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.modulo = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Modulo, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.and = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.And, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.bitwiseAnd = function (rhs, sourceSpan, parens) { |
| if (parens === void 0) { parens = true; } |
| return new BinaryOperatorExpr(exports.BinaryOperator.BitwiseAnd, this, rhs, null, sourceSpan, parens); |
| }; |
| Expression.prototype.or = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Or, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.lower = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Lower, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.lowerEquals = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.LowerEquals, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.bigger = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.Bigger, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.biggerEquals = function (rhs, sourceSpan) { |
| return new BinaryOperatorExpr(exports.BinaryOperator.BiggerEquals, this, rhs, null, sourceSpan); |
| }; |
| Expression.prototype.isBlank = function (sourceSpan) { |
| // Note: We use equals by purpose here to compare to null and undefined in JS. |
| // We use the typed null to allow strictNullChecks to narrow types. |
| return this.equals(TYPED_NULL_EXPR, sourceSpan); |
| }; |
| Expression.prototype.cast = function (type, sourceSpan) { |
| return new CastExpr(this, type, sourceSpan); |
| }; |
| Expression.prototype.toStmt = function () { |
| return new ExpressionStatement(this, null); |
| }; |
| return Expression; |
| }()); |
| (function (BuiltinVar) { |
| BuiltinVar[BuiltinVar["This"] = 0] = "This"; |
| BuiltinVar[BuiltinVar["Super"] = 1] = "Super"; |
| BuiltinVar[BuiltinVar["CatchError"] = 2] = "CatchError"; |
| BuiltinVar[BuiltinVar["CatchStack"] = 3] = "CatchStack"; |
| })(exports.BuiltinVar || (exports.BuiltinVar = {})); |
| var ReadVarExpr = /** @class */ (function (_super) { |
| __extends(ReadVarExpr, _super); |
| function ReadVarExpr(name, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| if (typeof name === 'string') { |
| _this.name = name; |
| _this.builtin = null; |
| } |
| else { |
| _this.name = null; |
| _this.builtin = name; |
| } |
| return _this; |
| } |
| ReadVarExpr.prototype.isEquivalent = function (e) { |
| return e instanceof ReadVarExpr && this.name === e.name && this.builtin === e.builtin; |
| }; |
| ReadVarExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| ReadVarExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitReadVarExpr(this, context); |
| }; |
| ReadVarExpr.prototype.set = function (value) { |
| if (!this.name) { |
| throw new Error("Built in variable " + this.builtin + " can not be assigned to."); |
| } |
| return new WriteVarExpr(this.name, value, null, this.sourceSpan); |
| }; |
| return ReadVarExpr; |
| }(Expression)); |
| var TypeofExpr = /** @class */ (function (_super) { |
| __extends(TypeofExpr, _super); |
| function TypeofExpr(expr, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.expr = expr; |
| return _this; |
| } |
| TypeofExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitTypeofExpr(this, context); |
| }; |
| TypeofExpr.prototype.isEquivalent = function (e) { |
| return e instanceof TypeofExpr && e.expr.isEquivalent(this.expr); |
| }; |
| TypeofExpr.prototype.isConstant = function () { |
| return this.expr.isConstant(); |
| }; |
| return TypeofExpr; |
| }(Expression)); |
| var WrappedNodeExpr = /** @class */ (function (_super) { |
| __extends(WrappedNodeExpr, _super); |
| function WrappedNodeExpr(node, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.node = node; |
| return _this; |
| } |
| WrappedNodeExpr.prototype.isEquivalent = function (e) { |
| return e instanceof WrappedNodeExpr && this.node === e.node; |
| }; |
| WrappedNodeExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| WrappedNodeExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitWrappedNodeExpr(this, context); |
| }; |
| return WrappedNodeExpr; |
| }(Expression)); |
| var WriteVarExpr = /** @class */ (function (_super) { |
| __extends(WriteVarExpr, _super); |
| function WriteVarExpr(name, value, type, sourceSpan) { |
| var _this = _super.call(this, type || value.type, sourceSpan) || this; |
| _this.name = name; |
| _this.value = value; |
| return _this; |
| } |
| WriteVarExpr.prototype.isEquivalent = function (e) { |
| return e instanceof WriteVarExpr && this.name === e.name && this.value.isEquivalent(e.value); |
| }; |
| WriteVarExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| WriteVarExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitWriteVarExpr(this, context); |
| }; |
| WriteVarExpr.prototype.toDeclStmt = function (type, modifiers) { |
| return new DeclareVarStmt(this.name, this.value, type, modifiers, this.sourceSpan); |
| }; |
| WriteVarExpr.prototype.toConstDecl = function () { |
| return this.toDeclStmt(INFERRED_TYPE, [exports.StmtModifier.Final]); |
| }; |
| return WriteVarExpr; |
| }(Expression)); |
| var WriteKeyExpr = /** @class */ (function (_super) { |
| __extends(WriteKeyExpr, _super); |
| function WriteKeyExpr(receiver, index, value, type, sourceSpan) { |
| var _this = _super.call(this, type || value.type, sourceSpan) || this; |
| _this.receiver = receiver; |
| _this.index = index; |
| _this.value = value; |
| return _this; |
| } |
| WriteKeyExpr.prototype.isEquivalent = function (e) { |
| return e instanceof WriteKeyExpr && this.receiver.isEquivalent(e.receiver) && |
| this.index.isEquivalent(e.index) && this.value.isEquivalent(e.value); |
| }; |
| WriteKeyExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| WriteKeyExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitWriteKeyExpr(this, context); |
| }; |
| return WriteKeyExpr; |
| }(Expression)); |
| var WritePropExpr = /** @class */ (function (_super) { |
| __extends(WritePropExpr, _super); |
| function WritePropExpr(receiver, name, value, type, sourceSpan) { |
| var _this = _super.call(this, type || value.type, sourceSpan) || this; |
| _this.receiver = receiver; |
| _this.name = name; |
| _this.value = value; |
| return _this; |
| } |
| WritePropExpr.prototype.isEquivalent = function (e) { |
| return e instanceof WritePropExpr && this.receiver.isEquivalent(e.receiver) && |
| this.name === e.name && this.value.isEquivalent(e.value); |
| }; |
| WritePropExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| WritePropExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitWritePropExpr(this, context); |
| }; |
| return WritePropExpr; |
| }(Expression)); |
| (function (BuiltinMethod) { |
| BuiltinMethod[BuiltinMethod["ConcatArray"] = 0] = "ConcatArray"; |
| BuiltinMethod[BuiltinMethod["SubscribeObservable"] = 1] = "SubscribeObservable"; |
| BuiltinMethod[BuiltinMethod["Bind"] = 2] = "Bind"; |
| })(exports.BuiltinMethod || (exports.BuiltinMethod = {})); |
| var InvokeMethodExpr = /** @class */ (function (_super) { |
| __extends(InvokeMethodExpr, _super); |
| function InvokeMethodExpr(receiver, method, args, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.receiver = receiver; |
| _this.args = args; |
| if (typeof method === 'string') { |
| _this.name = method; |
| _this.builtin = null; |
| } |
| else { |
| _this.name = null; |
| _this.builtin = method; |
| } |
| return _this; |
| } |
| InvokeMethodExpr.prototype.isEquivalent = function (e) { |
| return e instanceof InvokeMethodExpr && this.receiver.isEquivalent(e.receiver) && |
| this.name === e.name && this.builtin === e.builtin && areAllEquivalent(this.args, e.args); |
| }; |
| InvokeMethodExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| InvokeMethodExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitInvokeMethodExpr(this, context); |
| }; |
| return InvokeMethodExpr; |
| }(Expression)); |
| var InvokeFunctionExpr = /** @class */ (function (_super) { |
| __extends(InvokeFunctionExpr, _super); |
| function InvokeFunctionExpr(fn, args, type, sourceSpan, pure) { |
| if (pure === void 0) { pure = false; } |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.fn = fn; |
| _this.args = args; |
| _this.pure = pure; |
| return _this; |
| } |
| InvokeFunctionExpr.prototype.isEquivalent = function (e) { |
| return e instanceof InvokeFunctionExpr && this.fn.isEquivalent(e.fn) && |
| areAllEquivalent(this.args, e.args) && this.pure === e.pure; |
| }; |
| InvokeFunctionExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| InvokeFunctionExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitInvokeFunctionExpr(this, context); |
| }; |
| return InvokeFunctionExpr; |
| }(Expression)); |
| var TaggedTemplateExpr = /** @class */ (function (_super) { |
| __extends(TaggedTemplateExpr, _super); |
| function TaggedTemplateExpr(tag, template, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.tag = tag; |
| _this.template = template; |
| return _this; |
| } |
| TaggedTemplateExpr.prototype.isEquivalent = function (e) { |
| return e instanceof TaggedTemplateExpr && this.tag.isEquivalent(e.tag) && |
| areAllEquivalentPredicate(this.template.elements, e.template.elements, function (a, b) { return a.text === b.text; }) && |
| areAllEquivalent(this.template.expressions, e.template.expressions); |
| }; |
| TaggedTemplateExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| TaggedTemplateExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitTaggedTemplateExpr(this, context); |
| }; |
| return TaggedTemplateExpr; |
| }(Expression)); |
| var InstantiateExpr = /** @class */ (function (_super) { |
| __extends(InstantiateExpr, _super); |
| function InstantiateExpr(classExpr, args, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.classExpr = classExpr; |
| _this.args = args; |
| return _this; |
| } |
| InstantiateExpr.prototype.isEquivalent = function (e) { |
| return e instanceof InstantiateExpr && this.classExpr.isEquivalent(e.classExpr) && |
| areAllEquivalent(this.args, e.args); |
| }; |
| InstantiateExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| InstantiateExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitInstantiateExpr(this, context); |
| }; |
| return InstantiateExpr; |
| }(Expression)); |
| var LiteralExpr = /** @class */ (function (_super) { |
| __extends(LiteralExpr, _super); |
| function LiteralExpr(value, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.value = value; |
| return _this; |
| } |
| LiteralExpr.prototype.isEquivalent = function (e) { |
| return e instanceof LiteralExpr && this.value === e.value; |
| }; |
| LiteralExpr.prototype.isConstant = function () { |
| return true; |
| }; |
| LiteralExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitLiteralExpr(this, context); |
| }; |
| return LiteralExpr; |
| }(Expression)); |
| var TemplateLiteral = /** @class */ (function () { |
| function TemplateLiteral(elements, expressions) { |
| this.elements = elements; |
| this.expressions = expressions; |
| } |
| return TemplateLiteral; |
| }()); |
| var TemplateLiteralElement = /** @class */ (function () { |
| function TemplateLiteralElement(text, sourceSpan, rawText) { |
| var _a; |
| this.text = text; |
| this.sourceSpan = sourceSpan; |
| // If `rawText` is not provided, try to extract the raw string from its |
| // associated `sourceSpan`. If that is also not available, "fake" the raw |
| // string instead by escaping the following control sequences: |
| // - "\" would otherwise indicate that the next character is a control character. |
| // - "`" and "${" are template string control sequences that would otherwise prematurely |
| // indicate the end of the template literal element. |
| this.rawText = (_a = rawText !== null && rawText !== void 0 ? rawText : sourceSpan === null || sourceSpan === void 0 ? void 0 : sourceSpan.toString()) !== null && _a !== void 0 ? _a : escapeForTemplateLiteral(escapeSlashes(text)); |
| } |
| return TemplateLiteralElement; |
| }()); |
| var MessagePiece = /** @class */ (function () { |
| function MessagePiece(text, sourceSpan) { |
| this.text = text; |
| this.sourceSpan = sourceSpan; |
| } |
| return MessagePiece; |
| }()); |
| var LiteralPiece = /** @class */ (function (_super) { |
| __extends(LiteralPiece, _super); |
| function LiteralPiece() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| return LiteralPiece; |
| }(MessagePiece)); |
| var PlaceholderPiece = /** @class */ (function (_super) { |
| __extends(PlaceholderPiece, _super); |
| function PlaceholderPiece() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| return PlaceholderPiece; |
| }(MessagePiece)); |
| var LocalizedString = /** @class */ (function (_super) { |
| __extends(LocalizedString, _super); |
| function LocalizedString(metaBlock, messageParts, placeHolderNames, expressions, sourceSpan) { |
| var _this = _super.call(this, STRING_TYPE, sourceSpan) || this; |
| _this.metaBlock = metaBlock; |
| _this.messageParts = messageParts; |
| _this.placeHolderNames = placeHolderNames; |
| _this.expressions = expressions; |
| return _this; |
| } |
| LocalizedString.prototype.isEquivalent = function (e) { |
| // return e instanceof LocalizedString && this.message === e.message; |
| return false; |
| }; |
| LocalizedString.prototype.isConstant = function () { |
| return false; |
| }; |
| LocalizedString.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitLocalizedString(this, context); |
| }; |
| /** |
| * Serialize the given `meta` and `messagePart` into "cooked" and "raw" strings that can be used |
| * in a `$localize` tagged string. The format of the metadata is the same as that parsed by |
| * `parseI18nMeta()`. |
| * |
| * @param meta The metadata to serialize |
| * @param messagePart The first part of the tagged string |
| */ |
| LocalizedString.prototype.serializeI18nHead = function () { |
| var MEANING_SEPARATOR = '|'; |
| var ID_SEPARATOR = '@@'; |
| var LEGACY_ID_INDICATOR = '␟'; |
| var metaBlock = this.metaBlock.description || ''; |
| if (this.metaBlock.meaning) { |
| metaBlock = "" + this.metaBlock.meaning + MEANING_SEPARATOR + metaBlock; |
| } |
| if (this.metaBlock.customId) { |
| metaBlock = "" + metaBlock + ID_SEPARATOR + this.metaBlock.customId; |
| } |
| if (this.metaBlock.legacyIds) { |
| this.metaBlock.legacyIds.forEach(function (legacyId) { |
| metaBlock = "" + metaBlock + LEGACY_ID_INDICATOR + legacyId; |
| }); |
| } |
| return createCookedRawString(metaBlock, this.messageParts[0].text, this.getMessagePartSourceSpan(0)); |
| }; |
| LocalizedString.prototype.getMessagePartSourceSpan = function (i) { |
| var _a, _b; |
| return (_b = (_a = this.messageParts[i]) === null || _a === void 0 ? void 0 : _a.sourceSpan) !== null && _b !== void 0 ? _b : this.sourceSpan; |
| }; |
| LocalizedString.prototype.getPlaceholderSourceSpan = function (i) { |
| var _a, _b, _c, _d; |
| return (_d = (_b = (_a = this.placeHolderNames[i]) === null || _a === void 0 ? void 0 : _a.sourceSpan) !== null && _b !== void 0 ? _b : (_c = this.expressions[i]) === null || _c === void 0 ? void 0 : _c.sourceSpan) !== null && _d !== void 0 ? _d : this.sourceSpan; |
| }; |
| /** |
| * Serialize the given `placeholderName` and `messagePart` into "cooked" and "raw" strings that |
| * can be used in a `$localize` tagged string. |
| * |
| * @param placeholderName The placeholder name to serialize |
| * @param messagePart The following message string after this placeholder |
| */ |
| LocalizedString.prototype.serializeI18nTemplatePart = function (partIndex) { |
| var placeholderName = this.placeHolderNames[partIndex - 1].text; |
| var messagePart = this.messageParts[partIndex]; |
| return createCookedRawString(placeholderName, messagePart.text, this.getMessagePartSourceSpan(partIndex)); |
| }; |
| return LocalizedString; |
| }(Expression)); |
| var escapeSlashes = function (str) { return str.replace(/\\/g, '\\\\'); }; |
| var escapeStartingColon = function (str) { return str.replace(/^:/, '\\:'); }; |
| var escapeColons = function (str) { return str.replace(/:/g, '\\:'); }; |
| var escapeForTemplateLiteral = function (str) { return str.replace(/`/g, '\\`').replace(/\${/g, '$\\{'); }; |
| /** |
| * Creates a `{cooked, raw}` object from the `metaBlock` and `messagePart`. |
| * |
| * The `raw` text must have various character sequences escaped: |
| * * "\" would otherwise indicate that the next character is a control character. |
| * * "`" and "${" are template string control sequences that would otherwise prematurely indicate |
| * the end of a message part. |
| * * ":" inside a metablock would prematurely indicate the end of the metablock. |
| * * ":" at the start of a messagePart with no metablock would erroneously indicate the start of a |
| * metablock. |
| * |
| * @param metaBlock Any metadata that should be prepended to the string |
| * @param messagePart The message part of the string |
| */ |
| function createCookedRawString(metaBlock, messagePart, range) { |
| if (metaBlock === '') { |
| return { |
| cooked: messagePart, |
| raw: escapeForTemplateLiteral(escapeStartingColon(escapeSlashes(messagePart))), |
| range: range, |
| }; |
| } |
| else { |
| return { |
| cooked: ":" + metaBlock + ":" + messagePart, |
| raw: escapeForTemplateLiteral(":" + escapeColons(escapeSlashes(metaBlock)) + ":" + escapeSlashes(messagePart)), |
| range: range, |
| }; |
| } |
| } |
| var ExternalExpr = /** @class */ (function (_super) { |
| __extends(ExternalExpr, _super); |
| function ExternalExpr(value, type, typeParams, sourceSpan) { |
| if (typeParams === void 0) { typeParams = null; } |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.value = value; |
| _this.typeParams = typeParams; |
| return _this; |
| } |
| ExternalExpr.prototype.isEquivalent = function (e) { |
| return e instanceof ExternalExpr && this.value.name === e.value.name && |
| this.value.moduleName === e.value.moduleName && this.value.runtime === e.value.runtime; |
| }; |
| ExternalExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| ExternalExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitExternalExpr(this, context); |
| }; |
| return ExternalExpr; |
| }(Expression)); |
| var ExternalReference = /** @class */ (function () { |
| function ExternalReference(moduleName, name, runtime) { |
| this.moduleName = moduleName; |
| this.name = name; |
| this.runtime = runtime; |
| } |
| return ExternalReference; |
| }()); |
| var ConditionalExpr = /** @class */ (function (_super) { |
| __extends(ConditionalExpr, _super); |
| function ConditionalExpr(condition, trueCase, falseCase, type, sourceSpan) { |
| if (falseCase === void 0) { falseCase = null; } |
| var _this = _super.call(this, type || trueCase.type, sourceSpan) || this; |
| _this.condition = condition; |
| _this.falseCase = falseCase; |
| _this.trueCase = trueCase; |
| return _this; |
| } |
| ConditionalExpr.prototype.isEquivalent = function (e) { |
| return e instanceof ConditionalExpr && this.condition.isEquivalent(e.condition) && |
| this.trueCase.isEquivalent(e.trueCase) && nullSafeIsEquivalent(this.falseCase, e.falseCase); |
| }; |
| ConditionalExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| ConditionalExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitConditionalExpr(this, context); |
| }; |
| return ConditionalExpr; |
| }(Expression)); |
| var NotExpr = /** @class */ (function (_super) { |
| __extends(NotExpr, _super); |
| function NotExpr(condition, sourceSpan) { |
| var _this = _super.call(this, BOOL_TYPE, sourceSpan) || this; |
| _this.condition = condition; |
| return _this; |
| } |
| NotExpr.prototype.isEquivalent = function (e) { |
| return e instanceof NotExpr && this.condition.isEquivalent(e.condition); |
| }; |
| NotExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| NotExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitNotExpr(this, context); |
| }; |
| return NotExpr; |
| }(Expression)); |
| var AssertNotNull = /** @class */ (function (_super) { |
| __extends(AssertNotNull, _super); |
| function AssertNotNull(condition, sourceSpan) { |
| var _this = _super.call(this, condition.type, sourceSpan) || this; |
| _this.condition = condition; |
| return _this; |
| } |
| AssertNotNull.prototype.isEquivalent = function (e) { |
| return e instanceof AssertNotNull && this.condition.isEquivalent(e.condition); |
| }; |
| AssertNotNull.prototype.isConstant = function () { |
| return false; |
| }; |
| AssertNotNull.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitAssertNotNullExpr(this, context); |
| }; |
| return AssertNotNull; |
| }(Expression)); |
| var CastExpr = /** @class */ (function (_super) { |
| __extends(CastExpr, _super); |
| function CastExpr(value, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.value = value; |
| return _this; |
| } |
| CastExpr.prototype.isEquivalent = function (e) { |
| return e instanceof CastExpr && this.value.isEquivalent(e.value); |
| }; |
| CastExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| CastExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitCastExpr(this, context); |
| }; |
| return CastExpr; |
| }(Expression)); |
| var FnParam = /** @class */ (function () { |
| function FnParam(name, type) { |
| if (type === void 0) { type = null; } |
| this.name = name; |
| this.type = type; |
| } |
| FnParam.prototype.isEquivalent = function (param) { |
| return this.name === param.name; |
| }; |
| return FnParam; |
| }()); |
| var FunctionExpr = /** @class */ (function (_super) { |
| __extends(FunctionExpr, _super); |
| function FunctionExpr(params, statements, type, sourceSpan, name) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.params = params; |
| _this.statements = statements; |
| _this.name = name; |
| return _this; |
| } |
| FunctionExpr.prototype.isEquivalent = function (e) { |
| return e instanceof FunctionExpr && areAllEquivalent(this.params, e.params) && |
| areAllEquivalent(this.statements, e.statements); |
| }; |
| FunctionExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| FunctionExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitFunctionExpr(this, context); |
| }; |
| FunctionExpr.prototype.toDeclStmt = function (name, modifiers) { |
| return new DeclareFunctionStmt(name, this.params, this.statements, this.type, modifiers, this.sourceSpan); |
| }; |
| return FunctionExpr; |
| }(Expression)); |
| var UnaryOperatorExpr = /** @class */ (function (_super) { |
| __extends(UnaryOperatorExpr, _super); |
| function UnaryOperatorExpr(operator, expr, type, sourceSpan, parens) { |
| if (parens === void 0) { parens = true; } |
| var _this = _super.call(this, type || NUMBER_TYPE, sourceSpan) || this; |
| _this.operator = operator; |
| _this.expr = expr; |
| _this.parens = parens; |
| return _this; |
| } |
| UnaryOperatorExpr.prototype.isEquivalent = function (e) { |
| return e instanceof UnaryOperatorExpr && this.operator === e.operator && |
| this.expr.isEquivalent(e.expr); |
| }; |
| UnaryOperatorExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| UnaryOperatorExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitUnaryOperatorExpr(this, context); |
| }; |
| return UnaryOperatorExpr; |
| }(Expression)); |
| var BinaryOperatorExpr = /** @class */ (function (_super) { |
| __extends(BinaryOperatorExpr, _super); |
| function BinaryOperatorExpr(operator, lhs, rhs, type, sourceSpan, parens) { |
| if (parens === void 0) { parens = true; } |
| var _this = _super.call(this, type || lhs.type, sourceSpan) || this; |
| _this.operator = operator; |
| _this.rhs = rhs; |
| _this.parens = parens; |
| _this.lhs = lhs; |
| return _this; |
| } |
| BinaryOperatorExpr.prototype.isEquivalent = function (e) { |
| return e instanceof BinaryOperatorExpr && this.operator === e.operator && |
| this.lhs.isEquivalent(e.lhs) && this.rhs.isEquivalent(e.rhs); |
| }; |
| BinaryOperatorExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| BinaryOperatorExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitBinaryOperatorExpr(this, context); |
| }; |
| return BinaryOperatorExpr; |
| }(Expression)); |
| var ReadPropExpr = /** @class */ (function (_super) { |
| __extends(ReadPropExpr, _super); |
| function ReadPropExpr(receiver, name, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.receiver = receiver; |
| _this.name = name; |
| return _this; |
| } |
| ReadPropExpr.prototype.isEquivalent = function (e) { |
| return e instanceof ReadPropExpr && this.receiver.isEquivalent(e.receiver) && |
| this.name === e.name; |
| }; |
| ReadPropExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| ReadPropExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitReadPropExpr(this, context); |
| }; |
| ReadPropExpr.prototype.set = function (value) { |
| return new WritePropExpr(this.receiver, this.name, value, null, this.sourceSpan); |
| }; |
| return ReadPropExpr; |
| }(Expression)); |
| var ReadKeyExpr = /** @class */ (function (_super) { |
| __extends(ReadKeyExpr, _super); |
| function ReadKeyExpr(receiver, index, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.receiver = receiver; |
| _this.index = index; |
| return _this; |
| } |
| ReadKeyExpr.prototype.isEquivalent = function (e) { |
| return e instanceof ReadKeyExpr && this.receiver.isEquivalent(e.receiver) && |
| this.index.isEquivalent(e.index); |
| }; |
| ReadKeyExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| ReadKeyExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitReadKeyExpr(this, context); |
| }; |
| ReadKeyExpr.prototype.set = function (value) { |
| return new WriteKeyExpr(this.receiver, this.index, value, null, this.sourceSpan); |
| }; |
| return ReadKeyExpr; |
| }(Expression)); |
| var LiteralArrayExpr = /** @class */ (function (_super) { |
| __extends(LiteralArrayExpr, _super); |
| function LiteralArrayExpr(entries, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.entries = entries; |
| return _this; |
| } |
| LiteralArrayExpr.prototype.isConstant = function () { |
| return this.entries.every(function (e) { return e.isConstant(); }); |
| }; |
| LiteralArrayExpr.prototype.isEquivalent = function (e) { |
| return e instanceof LiteralArrayExpr && areAllEquivalent(this.entries, e.entries); |
| }; |
| LiteralArrayExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitLiteralArrayExpr(this, context); |
| }; |
| return LiteralArrayExpr; |
| }(Expression)); |
| var LiteralMapEntry = /** @class */ (function () { |
| function LiteralMapEntry(key, value, quoted) { |
| this.key = key; |
| this.value = value; |
| this.quoted = quoted; |
| } |
| LiteralMapEntry.prototype.isEquivalent = function (e) { |
| return this.key === e.key && this.value.isEquivalent(e.value); |
| }; |
| return LiteralMapEntry; |
| }()); |
| var LiteralMapExpr = /** @class */ (function (_super) { |
| __extends(LiteralMapExpr, _super); |
| function LiteralMapExpr(entries, type, sourceSpan) { |
| var _this = _super.call(this, type, sourceSpan) || this; |
| _this.entries = entries; |
| _this.valueType = null; |
| if (type) { |
| _this.valueType = type.valueType; |
| } |
| return _this; |
| } |
| LiteralMapExpr.prototype.isEquivalent = function (e) { |
| return e instanceof LiteralMapExpr && areAllEquivalent(this.entries, e.entries); |
| }; |
| LiteralMapExpr.prototype.isConstant = function () { |
| return this.entries.every(function (e) { return e.value.isConstant(); }); |
| }; |
| LiteralMapExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitLiteralMapExpr(this, context); |
| }; |
| return LiteralMapExpr; |
| }(Expression)); |
| var CommaExpr = /** @class */ (function (_super) { |
| __extends(CommaExpr, _super); |
| function CommaExpr(parts, sourceSpan) { |
| var _this = _super.call(this, parts[parts.length - 1].type, sourceSpan) || this; |
| _this.parts = parts; |
| return _this; |
| } |
| CommaExpr.prototype.isEquivalent = function (e) { |
| return e instanceof CommaExpr && areAllEquivalent(this.parts, e.parts); |
| }; |
| CommaExpr.prototype.isConstant = function () { |
| return false; |
| }; |
| CommaExpr.prototype.visitExpression = function (visitor, context) { |
| return visitor.visitCommaExpr(this, context); |
| }; |
| return CommaExpr; |
| }(Expression)); |
| var THIS_EXPR = new ReadVarExpr(exports.BuiltinVar.This, null, null); |
| var SUPER_EXPR = new ReadVarExpr(exports.BuiltinVar.Super, null, null); |
| var CATCH_ERROR_VAR = new ReadVarExpr(exports.BuiltinVar.CatchError, null, null); |
| var CATCH_STACK_VAR = new ReadVarExpr(exports.BuiltinVar.CatchStack, null, null); |
| var NULL_EXPR = new LiteralExpr(null, null, null); |
| var TYPED_NULL_EXPR = new LiteralExpr(null, INFERRED_TYPE, null); |
| (function (StmtModifier) { |
| StmtModifier[StmtModifier["Final"] = 0] = "Final"; |
| StmtModifier[StmtModifier["Private"] = 1] = "Private"; |
| StmtModifier[StmtModifier["Exported"] = 2] = "Exported"; |
| StmtModifier[StmtModifier["Static"] = 3] = "Static"; |
| })(exports.StmtModifier || (exports.StmtModifier = {})); |
| var LeadingComment = /** @class */ (function () { |
| function LeadingComment(text, multiline, trailingNewline) { |
| this.text = text; |
| this.multiline = multiline; |
| this.trailingNewline = trailingNewline; |
| } |
| LeadingComment.prototype.toString = function () { |
| return this.multiline ? " " + this.text + " " : this.text; |
| }; |
| return LeadingComment; |
| }()); |
| var JSDocComment = /** @class */ (function (_super) { |
| __extends(JSDocComment, _super); |
| function JSDocComment(tags) { |
| var _this = _super.call(this, '', /* multiline */ true, /* trailingNewline */ true) || this; |
| _this.tags = tags; |
| return _this; |
| } |
| JSDocComment.prototype.toString = function () { |
| return serializeTags(this.tags); |
| }; |
| return JSDocComment; |
| }(LeadingComment)); |
| var Statement = /** @class */ (function () { |
| function Statement(modifiers, sourceSpan, leadingComments) { |
| if (modifiers === void 0) { modifiers = []; } |
| if (sourceSpan === void 0) { sourceSpan = null; } |
| this.modifiers = modifiers; |
| this.sourceSpan = sourceSpan; |
| this.leadingComments = leadingComments; |
| } |
| Statement.prototype.hasModifier = function (modifier) { |
| return this.modifiers.indexOf(modifier) !== -1; |
| }; |
| Statement.prototype.addLeadingComment = function (leadingComment) { |
| var _a; |
| this.leadingComments = (_a = this.leadingComments) !== null && _a !== void 0 ? _a : []; |
| this.leadingComments.push(leadingComment); |
| }; |
| return Statement; |
| }()); |
| var DeclareVarStmt = /** @class */ (function (_super) { |
| __extends(DeclareVarStmt, _super); |
| function DeclareVarStmt(name, value, type, modifiers, sourceSpan, leadingComments) { |
| var _this = _super.call(this, modifiers, sourceSpan, leadingComments) || this; |
| _this.name = name; |
| _this.value = value; |
| _this.type = type || (value && value.type) || null; |
| return _this; |
| } |
| DeclareVarStmt.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof DeclareVarStmt && this.name === stmt.name && |
| (this.value ? !!stmt.value && this.value.isEquivalent(stmt.value) : !stmt.value); |
| }; |
| DeclareVarStmt.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitDeclareVarStmt(this, context); |
| }; |
| return DeclareVarStmt; |
| }(Statement)); |
| var DeclareFunctionStmt = /** @class */ (function (_super) { |
| __extends(DeclareFunctionStmt, _super); |
| function DeclareFunctionStmt(name, params, statements, type, modifiers, sourceSpan, leadingComments) { |
| var _this = _super.call(this, modifiers, sourceSpan, leadingComments) || this; |
| _this.name = name; |
| _this.params = params; |
| _this.statements = statements; |
| _this.type = type || null; |
| return _this; |
| } |
| DeclareFunctionStmt.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof DeclareFunctionStmt && areAllEquivalent(this.params, stmt.params) && |
| areAllEquivalent(this.statements, stmt.statements); |
| }; |
| DeclareFunctionStmt.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitDeclareFunctionStmt(this, context); |
| }; |
| return DeclareFunctionStmt; |
| }(Statement)); |
| var ExpressionStatement = /** @class */ (function (_super) { |
| __extends(ExpressionStatement, _super); |
| function ExpressionStatement(expr, sourceSpan, leadingComments) { |
| var _this = _super.call(this, [], sourceSpan, leadingComments) || this; |
| _this.expr = expr; |
| return _this; |
| } |
| ExpressionStatement.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof ExpressionStatement && this.expr.isEquivalent(stmt.expr); |
| }; |
| ExpressionStatement.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitExpressionStmt(this, context); |
| }; |
| return ExpressionStatement; |
| }(Statement)); |
| var ReturnStatement = /** @class */ (function (_super) { |
| __extends(ReturnStatement, _super); |
| function ReturnStatement(value, sourceSpan, leadingComments) { |
| if (sourceSpan === void 0) { sourceSpan = null; } |
| var _this = _super.call(this, [], sourceSpan, leadingComments) || this; |
| _this.value = value; |
| return _this; |
| } |
| ReturnStatement.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof ReturnStatement && this.value.isEquivalent(stmt.value); |
| }; |
| ReturnStatement.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitReturnStmt(this, context); |
| }; |
| return ReturnStatement; |
| }(Statement)); |
| var AbstractClassPart = /** @class */ (function () { |
| function AbstractClassPart(type, modifiers) { |
| if (type === void 0) { type = null; } |
| if (modifiers === void 0) { modifiers = []; } |
| this.type = type; |
| this.modifiers = modifiers; |
| } |
| AbstractClassPart.prototype.hasModifier = function (modifier) { |
| return this.modifiers.indexOf(modifier) !== -1; |
| }; |
| return AbstractClassPart; |
| }()); |
| var ClassField = /** @class */ (function (_super) { |
| __extends(ClassField, _super); |
| function ClassField(name, type, modifiers, initializer) { |
| var _this = _super.call(this, type, modifiers) || this; |
| _this.name = name; |
| _this.initializer = initializer; |
| return _this; |
| } |
| ClassField.prototype.isEquivalent = function (f) { |
| return this.name === f.name; |
| }; |
| return ClassField; |
| }(AbstractClassPart)); |
| var ClassMethod = /** @class */ (function (_super) { |
| __extends(ClassMethod, _super); |
| function ClassMethod(name, params, body, type, modifiers) { |
| var _this = _super.call(this, type, modifiers) || this; |
| _this.name = name; |
| _this.params = params; |
| _this.body = body; |
| return _this; |
| } |
| ClassMethod.prototype.isEquivalent = function (m) { |
| return this.name === m.name && areAllEquivalent(this.body, m.body); |
| }; |
| return ClassMethod; |
| }(AbstractClassPart)); |
| var ClassGetter = /** @class */ (function (_super) { |
| __extends(ClassGetter, _super); |
| function ClassGetter(name, body, type, modifiers) { |
| var _this = _super.call(this, type, modifiers) || this; |
| _this.name = name; |
| _this.body = body; |
| return _this; |
| } |
| ClassGetter.prototype.isEquivalent = function (m) { |
| return this.name === m.name && areAllEquivalent(this.body, m.body); |
| }; |
| return ClassGetter; |
| }(AbstractClassPart)); |
| var ClassStmt = /** @class */ (function (_super) { |
| __extends(ClassStmt, _super); |
| function ClassStmt(name, parent, fields, getters, constructorMethod, methods, modifiers, sourceSpan, leadingComments) { |
| var _this = _super.call(this, modifiers, sourceSpan, leadingComments) || this; |
| _this.name = name; |
| _this.parent = parent; |
| _this.fields = fields; |
| _this.getters = getters; |
| _this.constructorMethod = constructorMethod; |
| _this.methods = methods; |
| return _this; |
| } |
| ClassStmt.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof ClassStmt && this.name === stmt.name && |
| nullSafeIsEquivalent(this.parent, stmt.parent) && |
| areAllEquivalent(this.fields, stmt.fields) && |
| areAllEquivalent(this.getters, stmt.getters) && |
| this.constructorMethod.isEquivalent(stmt.constructorMethod) && |
| areAllEquivalent(this.methods, stmt.methods); |
| }; |
| ClassStmt.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitDeclareClassStmt(this, context); |
| }; |
| return ClassStmt; |
| }(Statement)); |
| var IfStmt = /** @class */ (function (_super) { |
| __extends(IfStmt, _super); |
| function IfStmt(condition, trueCase, falseCase, sourceSpan, leadingComments) { |
| if (falseCase === void 0) { falseCase = []; } |
| var _this = _super.call(this, [], sourceSpan, leadingComments) || this; |
| _this.condition = condition; |
| _this.trueCase = trueCase; |
| _this.falseCase = falseCase; |
| return _this; |
| } |
| IfStmt.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof IfStmt && this.condition.isEquivalent(stmt.condition) && |
| areAllEquivalent(this.trueCase, stmt.trueCase) && |
| areAllEquivalent(this.falseCase, stmt.falseCase); |
| }; |
| IfStmt.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitIfStmt(this, context); |
| }; |
| return IfStmt; |
| }(Statement)); |
| var TryCatchStmt = /** @class */ (function (_super) { |
| __extends(TryCatchStmt, _super); |
| function TryCatchStmt(bodyStmts, catchStmts, sourceSpan, leadingComments) { |
| if (sourceSpan === void 0) { sourceSpan = null; } |
| var _this = _super.call(this, [], sourceSpan, leadingComments) || this; |
| _this.bodyStmts = bodyStmts; |
| _this.catchStmts = catchStmts; |
| return _this; |
| } |
| TryCatchStmt.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof TryCatchStmt && areAllEquivalent(this.bodyStmts, stmt.bodyStmts) && |
| areAllEquivalent(this.catchStmts, stmt.catchStmts); |
| }; |
| TryCatchStmt.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitTryCatchStmt(this, context); |
| }; |
| return TryCatchStmt; |
| }(Statement)); |
| var ThrowStmt = /** @class */ (function (_super) { |
| __extends(ThrowStmt, _super); |
| function ThrowStmt(error, sourceSpan, leadingComments) { |
| if (sourceSpan === void 0) { sourceSpan = null; } |
| var _this = _super.call(this, [], sourceSpan, leadingComments) || this; |
| _this.error = error; |
| return _this; |
| } |
| ThrowStmt.prototype.isEquivalent = function (stmt) { |
| return stmt instanceof TryCatchStmt && this.error.isEquivalent(stmt.error); |
| }; |
| ThrowStmt.prototype.visitStatement = function (visitor, context) { |
| return visitor.visitThrowStmt(this, context); |
| }; |
| return ThrowStmt; |
| }(Statement)); |
| var AstTransformer = /** @class */ (function () { |
| function AstTransformer() { |
| } |
| AstTransformer.prototype.transformExpr = function (expr, context) { |
| return expr; |
| }; |
| AstTransformer.prototype.transformStmt = function (stmt, context) { |
| return stmt; |
| }; |
| AstTransformer.prototype.visitReadVarExpr = function (ast, context) { |
| return this.transformExpr(ast, context); |
| }; |
| AstTransformer.prototype.visitWrappedNodeExpr = function (ast, context) { |
| return this.transformExpr(ast, context); |
| }; |
| AstTransformer.prototype.visitTypeofExpr = function (expr, context) { |
| return this.transformExpr(new TypeofExpr(expr.expr.visitExpression(this, context), expr.type, expr.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitWriteVarExpr = function (expr, context) { |
| return this.transformExpr(new WriteVarExpr(expr.name, expr.value.visitExpression(this, context), expr.type, expr.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitWriteKeyExpr = function (expr, context) { |
| return this.transformExpr(new WriteKeyExpr(expr.receiver.visitExpression(this, context), expr.index.visitExpression(this, context), expr.value.visitExpression(this, context), expr.type, expr.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitWritePropExpr = function (expr, context) { |
| return this.transformExpr(new WritePropExpr(expr.receiver.visitExpression(this, context), expr.name, expr.value.visitExpression(this, context), expr.type, expr.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitInvokeMethodExpr = function (ast, context) { |
| var method = ast.builtin || ast.name; |
| return this.transformExpr(new InvokeMethodExpr(ast.receiver.visitExpression(this, context), method, this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitInvokeFunctionExpr = function (ast, context) { |
| return this.transformExpr(new InvokeFunctionExpr(ast.fn.visitExpression(this, context), this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitTaggedTemplateExpr = function (ast, context) { |
| var _this = this; |
| return this.transformExpr(new TaggedTemplateExpr(ast.tag.visitExpression(this, context), new TemplateLiteral(ast.template.elements, ast.template.expressions.map(function (e) { return e.visitExpression(_this, context); })), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitInstantiateExpr = function (ast, context) { |
| return this.transformExpr(new InstantiateExpr(ast.classExpr.visitExpression(this, context), this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitLiteralExpr = function (ast, context) { |
| return this.transformExpr(ast, context); |
| }; |
| AstTransformer.prototype.visitLocalizedString = function (ast, context) { |
| return this.transformExpr(new LocalizedString(ast.metaBlock, ast.messageParts, ast.placeHolderNames, this.visitAllExpressions(ast.expressions, context), ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitExternalExpr = function (ast, context) { |
| return this.transformExpr(ast, context); |
| }; |
| AstTransformer.prototype.visitConditionalExpr = function (ast, context) { |
| return this.transformExpr(new ConditionalExpr(ast.condition.visitExpression(this, context), ast.trueCase.visitExpression(this, context), ast.falseCase.visitExpression(this, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitNotExpr = function (ast, context) { |
| return this.transformExpr(new NotExpr(ast.condition.visitExpression(this, context), ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitAssertNotNullExpr = function (ast, context) { |
| return this.transformExpr(new AssertNotNull(ast.condition.visitExpression(this, context), ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitCastExpr = function (ast, context) { |
| return this.transformExpr(new CastExpr(ast.value.visitExpression(this, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitFunctionExpr = function (ast, context) { |
| return this.transformExpr(new FunctionExpr(ast.params, this.visitAllStatements(ast.statements, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitUnaryOperatorExpr = function (ast, context) { |
| return this.transformExpr(new UnaryOperatorExpr(ast.operator, ast.expr.visitExpression(this, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitBinaryOperatorExpr = function (ast, context) { |
| return this.transformExpr(new BinaryOperatorExpr(ast.operator, ast.lhs.visitExpression(this, context), ast.rhs.visitExpression(this, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitReadPropExpr = function (ast, context) { |
| return this.transformExpr(new ReadPropExpr(ast.receiver.visitExpression(this, context), ast.name, ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitReadKeyExpr = function (ast, context) { |
| return this.transformExpr(new ReadKeyExpr(ast.receiver.visitExpression(this, context), ast.index.visitExpression(this, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitLiteralArrayExpr = function (ast, context) { |
| return this.transformExpr(new LiteralArrayExpr(this.visitAllExpressions(ast.entries, context), ast.type, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitLiteralMapExpr = function (ast, context) { |
| var _this = this; |
| var entries = ast.entries.map(function (entry) { return new LiteralMapEntry(entry.key, entry.value.visitExpression(_this, context), entry.quoted); }); |
| var mapType = new MapType(ast.valueType); |
| return this.transformExpr(new LiteralMapExpr(entries, mapType, ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitCommaExpr = function (ast, context) { |
| return this.transformExpr(new CommaExpr(this.visitAllExpressions(ast.parts, context), ast.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitAllExpressions = function (exprs, context) { |
| var _this = this; |
| return exprs.map(function (expr) { return expr.visitExpression(_this, context); }); |
| }; |
| AstTransformer.prototype.visitDeclareVarStmt = function (stmt, context) { |
| var value = stmt.value && stmt.value.visitExpression(this, context); |
| return this.transformStmt(new DeclareVarStmt(stmt.name, value, stmt.type, stmt.modifiers, stmt.sourceSpan, stmt.leadingComments), context); |
| }; |
| AstTransformer.prototype.visitDeclareFunctionStmt = function (stmt, context) { |
| return this.transformStmt(new DeclareFunctionStmt(stmt.name, stmt.params, this.visitAllStatements(stmt.statements, context), stmt.type, stmt.modifiers, stmt.sourceSpan, stmt.leadingComments), context); |
| }; |
| AstTransformer.prototype.visitExpressionStmt = function (stmt, context) { |
| return this.transformStmt(new ExpressionStatement(stmt.expr.visitExpression(this, context), stmt.sourceSpan, stmt.leadingComments), context); |
| }; |
| AstTransformer.prototype.visitReturnStmt = function (stmt, context) { |
| return this.transformStmt(new ReturnStatement(stmt.value.visitExpression(this, context), stmt.sourceSpan, stmt.leadingComments), context); |
| }; |
| AstTransformer.prototype.visitDeclareClassStmt = function (stmt, context) { |
| var _this = this; |
| var parent = stmt.parent.visitExpression(this, context); |
| var getters = stmt.getters.map(function (getter) { return new ClassGetter(getter.name, _this.visitAllStatements(getter.body, context), getter.type, getter.modifiers); }); |
| var ctorMethod = stmt.constructorMethod && |
| new ClassMethod(stmt.constructorMethod.name, stmt.constructorMethod.params, this.visitAllStatements(stmt.constructorMethod.body, context), stmt.constructorMethod.type, stmt.constructorMethod.modifiers); |
| var methods = stmt.methods.map(function (method) { return new ClassMethod(method.name, method.params, _this.visitAllStatements(method.body, context), method.type, method.modifiers); }); |
| return this.transformStmt(new ClassStmt(stmt.name, parent, stmt.fields, getters, ctorMethod, methods, stmt.modifiers, stmt.sourceSpan), context); |
| }; |
| AstTransformer.prototype.visitIfStmt = function (stmt, context) { |
| return this.transformStmt(new IfStmt(stmt.condition.visitExpression(this, context), this.visitAllStatements(stmt.trueCase, context), this.visitAllStatements(stmt.falseCase, context), stmt.sourceSpan, stmt.leadingComments), context); |
| }; |
| AstTransformer.prototype.visitTryCatchStmt = function (stmt, context) { |
| return this.transformStmt(new TryCatchStmt(this.visitAllStatements(stmt.bodyStmts, context), this.visitAllStatements(stmt.catchStmts, context), stmt.sourceSpan, stmt.leadingComments), context); |
| }; |
| AstTransformer.prototype.visitThrowStmt = function (stmt, context) { |
| return this.transformStmt(new ThrowStmt(stmt.error.visitExpression(this, context), stmt.sourceSpan, stmt.leadingComments), context); |
| }; |
| AstTransformer.prototype.visitAllStatements = function (stmts, context) { |
| var _this = this; |
| return stmts.map(function (stmt) { return stmt.visitStatement(_this, context); }); |
| }; |
| return AstTransformer; |
| }()); |
| var RecursiveAstVisitor = /** @class */ (function () { |
| function RecursiveAstVisitor() { |
| } |
| RecursiveAstVisitor.prototype.visitType = function (ast, context) { |
| return ast; |
| }; |
| RecursiveAstVisitor.prototype.visitExpression = function (ast, context) { |
| if (ast.type) { |
| ast.type.visitType(this, context); |
| } |
| return ast; |
| }; |
| RecursiveAstVisitor.prototype.visitBuiltinType = function (type, context) { |
| return this.visitType(type, context); |
| }; |
| RecursiveAstVisitor.prototype.visitExpressionType = function (type, context) { |
| var _this = this; |
| type.value.visitExpression(this, context); |
| if (type.typeParams !== null) { |
| type.typeParams.forEach(function (param) { return _this.visitType(param, context); }); |
| } |
| return this.visitType(type, context); |
| }; |
| RecursiveAstVisitor.prototype.visitArrayType = function (type, context) { |
| return this.visitType(type, context); |
| }; |
| RecursiveAstVisitor.prototype.visitMapType = function (type, context) { |
| return this.visitType(type, context); |
| }; |
| RecursiveAstVisitor.prototype.visitWrappedNodeExpr = function (ast, context) { |
| return ast; |
| }; |
| RecursiveAstVisitor.prototype.visitTypeofExpr = function (ast, context) { |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitReadVarExpr = function (ast, context) { |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitWriteVarExpr = function (ast, context) { |
| ast.value.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitWriteKeyExpr = function (ast, context) { |
| ast.receiver.visitExpression(this, context); |
| ast.index.visitExpression(this, context); |
| ast.value.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitWritePropExpr = function (ast, context) { |
| ast.receiver.visitExpression(this, context); |
| ast.value.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitInvokeMethodExpr = function (ast, context) { |
| ast.receiver.visitExpression(this, context); |
| this.visitAllExpressions(ast.args, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitInvokeFunctionExpr = function (ast, context) { |
| ast.fn.visitExpression(this, context); |
| this.visitAllExpressions(ast.args, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitTaggedTemplateExpr = function (ast, context) { |
| ast.tag.visitExpression(this, context); |
| this.visitAllExpressions(ast.template.expressions, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitInstantiateExpr = function (ast, context) { |
| ast.classExpr.visitExpression(this, context); |
| this.visitAllExpressions(ast.args, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitLiteralExpr = function (ast, context) { |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitLocalizedString = function (ast, context) { |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitExternalExpr = function (ast, context) { |
| var _this = this; |
| if (ast.typeParams) { |
| ast.typeParams.forEach(function (type) { return type.visitType(_this, context); }); |
| } |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitConditionalExpr = function (ast, context) { |
| ast.condition.visitExpression(this, context); |
| ast.trueCase.visitExpression(this, context); |
| ast.falseCase.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitNotExpr = function (ast, context) { |
| ast.condition.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitAssertNotNullExpr = function (ast, context) { |
| ast.condition.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitCastExpr = function (ast, context) { |
| ast.value.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitFunctionExpr = function (ast, context) { |
| this.visitAllStatements(ast.statements, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitUnaryOperatorExpr = function (ast, context) { |
| ast.expr.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitBinaryOperatorExpr = function (ast, context) { |
| ast.lhs.visitExpression(this, context); |
| ast.rhs.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitReadPropExpr = function (ast, context) { |
| ast.receiver.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitReadKeyExpr = function (ast, context) { |
| ast.receiver.visitExpression(this, context); |
| ast.index.visitExpression(this, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitLiteralArrayExpr = function (ast, context) { |
| this.visitAllExpressions(ast.entries, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitLiteralMapExpr = function (ast, context) { |
| var _this = this; |
| ast.entries.forEach(function (entry) { return entry.value.visitExpression(_this, context); }); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitCommaExpr = function (ast, context) { |
| this.visitAllExpressions(ast.parts, context); |
| return this.visitExpression(ast, context); |
| }; |
| RecursiveAstVisitor.prototype.visitAllExpressions = function (exprs, context) { |
| var _this = this; |
| exprs.forEach(function (expr) { return expr.visitExpression(_this, context); }); |
| }; |
| RecursiveAstVisitor.prototype.visitDeclareVarStmt = function (stmt, context) { |
| if (stmt.value) { |
| stmt.value.visitExpression(this, context); |
| } |
| if (stmt.type) { |
| stmt.type.visitType(this, context); |
| } |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitDeclareFunctionStmt = function (stmt, context) { |
| this.visitAllStatements(stmt.statements, context); |
| if (stmt.type) { |
| stmt.type.visitType(this, context); |
| } |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitExpressionStmt = function (stmt, context) { |
| stmt.expr.visitExpression(this, context); |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitReturnStmt = function (stmt, context) { |
| stmt.value.visitExpression(this, context); |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitDeclareClassStmt = function (stmt, context) { |
| var _this = this; |
| stmt.parent.visitExpression(this, context); |
| stmt.getters.forEach(function (getter) { return _this.visitAllStatements(getter.body, context); }); |
| if (stmt.constructorMethod) { |
| this.visitAllStatements(stmt.constructorMethod.body, context); |
| } |
| stmt.methods.forEach(function (method) { return _this.visitAllStatements(method.body, context); }); |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitIfStmt = function (stmt, context) { |
| stmt.condition.visitExpression(this, context); |
| this.visitAllStatements(stmt.trueCase, context); |
| this.visitAllStatements(stmt.falseCase, context); |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitTryCatchStmt = function (stmt, context) { |
| this.visitAllStatements(stmt.bodyStmts, context); |
| this.visitAllStatements(stmt.catchStmts, context); |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitThrowStmt = function (stmt, context) { |
| stmt.error.visitExpression(this, context); |
| return stmt; |
| }; |
| RecursiveAstVisitor.prototype.visitAllStatements = function (stmts, context) { |
| var _this = this; |
| stmts.forEach(function (stmt) { return stmt.visitStatement(_this, context); }); |
| }; |
| return RecursiveAstVisitor; |
| }()); |
| function findReadVarNames(stmts) { |
| var visitor = new _ReadVarVisitor(); |
| visitor.visitAllStatements(stmts, null); |
| return visitor.varNames; |
| } |
| var _ReadVarVisitor = /** @class */ (function (_super) { |
| __extends(_ReadVarVisitor, _super); |
| function _ReadVarVisitor() { |
| var _this = _super.apply(this, __spread(arguments)) || this; |
| _this.varNames = new Set(); |
| return _this; |
| } |
| _ReadVarVisitor.prototype.visitDeclareFunctionStmt = function (stmt, context) { |
| // Don't descend into nested functions |
| return stmt; |
| }; |
| _ReadVarVisitor.prototype.visitDeclareClassStmt = function (stmt, context) { |
| // Don't descend into nested classes |
| return stmt; |
| }; |
| _ReadVarVisitor.prototype.visitReadVarExpr = function (ast, context) { |
| if (ast.name) { |
| this.varNames.add(ast.name); |
| } |
| return null; |
| }; |
| return _ReadVarVisitor; |
| }(RecursiveAstVisitor)); |
| function collectExternalReferences(stmts) { |
| var visitor = new _FindExternalReferencesVisitor(); |
| visitor.visitAllStatements(stmts, null); |
| return visitor.externalReferences; |
| } |
| var _FindExternalReferencesVisitor = /** @class */ (function (_super) { |
| __extends(_FindExternalReferencesVisitor, _super); |
| function _FindExternalReferencesVisitor() { |
| var _this = _super.apply(this, __spread(arguments)) || this; |
| _this.externalReferences = []; |
| return _this; |
| } |
| _FindExternalReferencesVisitor.prototype.visitExternalExpr = function (e, context) { |
| this.externalReferences.push(e.value); |
| return _super.prototype.visitExternalExpr.call(this, e, context); |
| }; |
| return _FindExternalReferencesVisitor; |
| }(RecursiveAstVisitor)); |
| function applySourceSpanToStatementIfNeeded(stmt, sourceSpan) { |
| if (!sourceSpan) { |
| return stmt; |
| } |
| var transformer = new _ApplySourceSpanTransformer(sourceSpan); |
| return stmt.visitStatement(transformer, null); |
| } |
| function applySourceSpanToExpressionIfNeeded(expr, sourceSpan) { |
| if (!sourceSpan) { |
| return expr; |
| } |
| var transformer = new _ApplySourceSpanTransformer(sourceSpan); |
| return expr.visitExpression(transformer, null); |
| } |
| var _ApplySourceSpanTransformer = /** @class */ (function (_super) { |
| __extends(_ApplySourceSpanTransformer, _super); |
| function _ApplySourceSpanTransformer(sourceSpan) { |
| var _this = _super.call(this) || this; |
| _this.sourceSpan = sourceSpan; |
| return _this; |
| } |
| _ApplySourceSpanTransformer.prototype._clone = function (obj) { |
| var e_1, _e; |
| var clone = Object.create(obj.constructor.prototype); |
| try { |
| for (var _f = __values(Object.keys(obj)), _g = _f.next(); !_g.done; _g = _f.next()) { |
| var prop = _g.value; |
| clone[prop] = obj[prop]; |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_g && !_g.done && (_e = _f.return)) _e.call(_f); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return clone; |
| }; |
| _ApplySourceSpanTransformer.prototype.transformExpr = function (expr, context) { |
| if (!expr.sourceSpan) { |
| expr = this._clone(expr); |
| expr.sourceSpan = this.sourceSpan; |
| } |
| return expr; |
| }; |
| _ApplySourceSpanTransformer.prototype.transformStmt = function (stmt, context) { |
| if (!stmt.sourceSpan) { |
| stmt = this._clone(stmt); |
| stmt.sourceSpan = this.sourceSpan; |
| } |
| return stmt; |
| }; |
| return _ApplySourceSpanTransformer; |
| }(AstTransformer)); |
| function leadingComment(text, multiline, trailingNewline) { |
| if (multiline === void 0) { multiline = false; } |
| if (trailingNewline === void 0) { trailingNewline = true; } |
| return new LeadingComment(text, multiline, trailingNewline); |
| } |
| function jsDocComment(tags) { |
| if (tags === void 0) { tags = []; } |
| return new JSDocComment(tags); |
| } |
| function variable(name, type, sourceSpan) { |
| return new ReadVarExpr(name, type, sourceSpan); |
| } |
| function importExpr(id, typeParams, sourceSpan) { |
| if (typeParams === void 0) { typeParams = null; } |
| return new ExternalExpr(id, null, typeParams, sourceSpan); |
| } |
| function importType(id, typeParams, typeModifiers) { |
| return id != null ? expressionType(importExpr(id, typeParams, null), typeModifiers) : null; |
| } |
| function expressionType(expr, typeModifiers, typeParams) { |
| return new ExpressionType(expr, typeModifiers, typeParams); |
| } |
| function typeofExpr(expr) { |
| return new TypeofExpr(expr); |
| } |
| function literalArr(values, type, sourceSpan) { |
| return new LiteralArrayExpr(values, type, sourceSpan); |
| } |
| function literalMap(values, type) { |
| if (type === void 0) { type = null; } |
| return new LiteralMapExpr(values.map(function (e) { return new LiteralMapEntry(e.key, e.value, e.quoted); }), type, null); |
| } |
| function unary(operator, expr, type, sourceSpan) { |
| return new UnaryOperatorExpr(operator, expr, type, sourceSpan); |
| } |
| function not(expr, sourceSpan) { |
| return new NotExpr(expr, sourceSpan); |
| } |
| function assertNotNull(expr, sourceSpan) { |
| return new AssertNotNull(expr, sourceSpan); |
| } |
| function fn(params, body, type, sourceSpan, name) { |
| return new FunctionExpr(params, body, type, sourceSpan, name); |
| } |
| function ifStmt(condition, thenClause, elseClause, sourceSpan, leadingComments) { |
| return new IfStmt(condition, thenClause, elseClause, sourceSpan, leadingComments); |
| } |
| function taggedTemplate(tag, template, type, sourceSpan) { |
| return new TaggedTemplateExpr(tag, template, type, sourceSpan); |
| } |
| function literal(value, type, sourceSpan) { |
| return new LiteralExpr(value, type, sourceSpan); |
| } |
| function localizedString(metaBlock, messageParts, placeholderNames, expressions, sourceSpan) { |
| return new LocalizedString(metaBlock, messageParts, placeholderNames, expressions, sourceSpan); |
| } |
| function isNull(exp) { |
| return exp instanceof LiteralExpr && exp.value === null; |
| } |
| /* |
| * Serializes a `Tag` into a string. |
| * Returns a string like " @foo {bar} baz" (note the leading whitespace before `@foo`). |
| */ |
| function tagToString(tag) { |
| var out = ''; |
| if (tag.tagName) { |
| out += " @" + tag.tagName; |
| } |
| if (tag.text) { |
| if (tag.text.match(/\/\*|\*\//)) { |
| throw new Error('JSDoc text cannot contain "/*" and "*/"'); |
| } |
| out += ' ' + tag.text.replace(/@/g, '\\@'); |
| } |
| return out; |
| } |
| function serializeTags(tags) { |
| var e_2, _e; |
| if (tags.length === 0) |
| return ''; |
| if (tags.length === 1 && tags[0].tagName && !tags[0].text) { |
| // The JSDOC comment is a single simple tag: e.g `/** @tagname */`. |
| return "*" + tagToString(tags[0]) + " "; |
| } |
| var out = '*\n'; |
| try { |
| for (var tags_1 = __values(tags), tags_1_1 = tags_1.next(); !tags_1_1.done; tags_1_1 = tags_1.next()) { |
| var tag = tags_1_1.value; |
| out += ' *'; |
| // If the tagToString is multi-line, insert " * " prefixes on lines. |
| out += tagToString(tag).replace(/\n/g, '\n * '); |
| out += '\n'; |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (tags_1_1 && !tags_1_1.done && (_e = tags_1.return)) _e.call(tags_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| out += ' '; |
| return out; |
| } |
| |
| var CONSTANT_PREFIX = '_c'; |
| /** |
| * `ConstantPool` tries to reuse literal factories when two or more literals are identical. |
| * We determine whether literals are identical by creating a key out of their AST using the |
| * `KeyVisitor`. This constant is used to replace dynamic expressions which can't be safely |
| * converted into a key. E.g. given an expression `{foo: bar()}`, since we don't know what |
| * the result of `bar` will be, we create a key that looks like `{foo: <unknown>}`. Note |
| * that we use a variable, rather than something like `null` in order to avoid collisions. |
| */ |
| var UNKNOWN_VALUE_KEY = variable('<unknown>'); |
| /** |
| * Context to use when producing a key. |
| * |
| * This ensures we see the constant not the reference variable when producing |
| * a key. |
| */ |
| var KEY_CONTEXT = {}; |
| /** |
| * Generally all primitive values are excluded from the `ConstantPool`, but there is an exclusion |
| * for strings that reach a certain length threshold. This constant defines the length threshold for |
| * strings. |
| */ |
| var POOL_INCLUSION_LENGTH_THRESHOLD_FOR_STRINGS = 50; |
| /** |
| * A node that is a place-holder that allows the node to be replaced when the actual |
| * node is known. |
| * |
| * This allows the constant pool to change an expression from a direct reference to |
| * a constant to a shared constant. It returns a fix-up node that is later allowed to |
| * change the referenced expression. |
| */ |
| var FixupExpression = /** @class */ (function (_super) { |
| __extends(FixupExpression, _super); |
| function FixupExpression(resolved) { |
| var _this = _super.call(this, resolved.type) || this; |
| _this.resolved = resolved; |
| _this.original = resolved; |
| return _this; |
| } |
| FixupExpression.prototype.visitExpression = function (visitor, context) { |
| if (context === KEY_CONTEXT) { |
| // When producing a key we want to traverse the constant not the |
| // variable used to refer to it. |
| return this.original.visitExpression(visitor, context); |
| } |
| else { |
| return this.resolved.visitExpression(visitor, context); |
| } |
| }; |
| FixupExpression.prototype.isEquivalent = function (e) { |
| return e instanceof FixupExpression && this.resolved.isEquivalent(e.resolved); |
| }; |
| FixupExpression.prototype.isConstant = function () { |
| return true; |
| }; |
| FixupExpression.prototype.fixup = function (expression) { |
| this.resolved = expression; |
| this.shared = true; |
| }; |
| return FixupExpression; |
| }(Expression)); |
| /** |
| * A constant pool allows a code emitter to share constant in an output context. |
| * |
| * The constant pool also supports sharing access to ivy definitions references. |
| */ |
| var ConstantPool = /** @class */ (function () { |
| function ConstantPool(isClosureCompilerEnabled) { |
| if (isClosureCompilerEnabled === void 0) { isClosureCompilerEnabled = false; } |
| this.isClosureCompilerEnabled = isClosureCompilerEnabled; |
| this.statements = []; |
| this.literals = new Map(); |
| this.literalFactories = new Map(); |
| this.injectorDefinitions = new Map(); |
| this.directiveDefinitions = new Map(); |
| this.componentDefinitions = new Map(); |
| this.pipeDefinitions = new Map(); |
| this.nextNameIndex = 0; |
| } |
| ConstantPool.prototype.getConstLiteral = function (literal, forceShared) { |
| if ((literal instanceof LiteralExpr && !isLongStringLiteral(literal)) || |
| literal instanceof FixupExpression) { |
| // Do no put simple literals into the constant pool or try to produce a constant for a |
| // reference to a constant. |
| return literal; |
| } |
| var key = this.keyOf(literal); |
| var fixup = this.literals.get(key); |
| var newValue = false; |
| if (!fixup) { |
| fixup = new FixupExpression(literal); |
| this.literals.set(key, fixup); |
| newValue = true; |
| } |
| if ((!newValue && !fixup.shared) || (newValue && forceShared)) { |
| // Replace the expression with a variable |
| var name = this.freshName(); |
| var definition = void 0; |
| var usage = void 0; |
| if (this.isClosureCompilerEnabled && isLongStringLiteral(literal)) { |
| // For string literals, Closure will **always** inline the string at |
| // **all** usages, duplicating it each time. For large strings, this |
| // unnecessarily bloats bundle size. To work around this restriction, we |
| // wrap the string in a function, and call that function for each usage. |
| // This tricks Closure into using inline logic for functions instead of |
| // string literals. Function calls are only inlined if the body is small |
| // enough to be worth it. By doing this, very large strings will be |
| // shared across multiple usages, rather than duplicating the string at |
| // each usage site. |
| // |
| // const myStr = function() { return "very very very long string"; }; |
| // const usage1 = myStr(); |
| // const usage2 = myStr(); |
| definition = variable(name).set(new FunctionExpr([], // Params. |
| [ |
| // Statements. |
| new ReturnStatement(literal), |
| ])); |
| usage = variable(name).callFn([]); |
| } |
| else { |
| // Just declare and use the variable directly, without a function call |
| // indirection. This saves a few bytes and avoids an unncessary call. |
| definition = variable(name).set(literal); |
| usage = variable(name); |
| } |
| this.statements.push(definition.toDeclStmt(INFERRED_TYPE, [exports.StmtModifier.Final])); |
| fixup.fixup(usage); |
| } |
| return fixup; |
| }; |
| ConstantPool.prototype.getDefinition = function (type, kind, ctx, forceShared) { |
| if (forceShared === void 0) { forceShared = false; } |
| var definitions = this.definitionsOf(kind); |
| var fixup = definitions.get(type); |
| var newValue = false; |
| if (!fixup) { |
| var property = this.propertyNameOf(kind); |
| fixup = new FixupExpression(ctx.importExpr(type).prop(property)); |
| definitions.set(type, fixup); |
| newValue = true; |
| } |
| if ((!newValue && !fixup.shared) || (newValue && forceShared)) { |
| var name = this.freshName(); |
| this.statements.push(variable(name).set(fixup.resolved).toDeclStmt(INFERRED_TYPE, [exports.StmtModifier.Final])); |
| fixup.fixup(variable(name)); |
| } |
| return fixup; |
| }; |
| ConstantPool.prototype.getLiteralFactory = function (literal) { |
| // Create a pure function that builds an array of a mix of constant and variable expressions |
| if (literal instanceof LiteralArrayExpr) { |
| var argumentsForKey = literal.entries.map(function (e) { return e.isConstant() ? e : UNKNOWN_VALUE_KEY; }); |
| var key = this.keyOf(literalArr(argumentsForKey)); |
| return this._getLiteralFactory(key, literal.entries, function (entries) { return literalArr(entries); }); |
| } |
| else { |
| var expressionForKey = literalMap(literal.entries.map(function (e) { return ({ |
| key: e.key, |
| value: e.value.isConstant() ? e.value : UNKNOWN_VALUE_KEY, |
| quoted: e.quoted |
| }); })); |
| var key = this.keyOf(expressionForKey); |
| return this._getLiteralFactory(key, literal.entries.map(function (e) { return e.value; }), function (entries) { return literalMap(entries.map(function (value, index) { return ({ |
| key: literal.entries[index].key, |
| value: value, |
| quoted: literal.entries[index].quoted |
| }); })); }); |
| } |
| }; |
| ConstantPool.prototype._getLiteralFactory = function (key, values, resultMap) { |
| var _this = this; |
| var literalFactory = this.literalFactories.get(key); |
| var literalFactoryArguments = values.filter((function (e) { return !e.isConstant(); })); |
| if (!literalFactory) { |
| var resultExpressions = values.map(function (e, index) { return e.isConstant() ? _this.getConstLiteral(e, true) : variable("a" + index); }); |
| var parameters = resultExpressions.filter(isVariable).map(function (e) { return new FnParam(e.name, DYNAMIC_TYPE); }); |
| var pureFunctionDeclaration = fn(parameters, [new ReturnStatement(resultMap(resultExpressions))], INFERRED_TYPE); |
| var name = this.freshName(); |
| this.statements.push(variable(name).set(pureFunctionDeclaration).toDeclStmt(INFERRED_TYPE, [ |
| exports.StmtModifier.Final |
| ])); |
| literalFactory = variable(name); |
| this.literalFactories.set(key, literalFactory); |
| } |
| return { literalFactory: literalFactory, literalFactoryArguments: literalFactoryArguments }; |
| }; |
| /** |
| * Produce a unique name. |
| * |
| * The name might be unique among different prefixes if any of the prefixes end in |
| * a digit so the prefix should be a constant string (not based on user input) and |
| * must not end in a digit. |
| */ |
| ConstantPool.prototype.uniqueName = function (prefix) { |
| return "" + prefix + this.nextNameIndex++; |
| }; |
| ConstantPool.prototype.definitionsOf = function (kind) { |
| switch (kind) { |
| case 2 /* Component */: |
| return this.componentDefinitions; |
| case 1 /* Directive */: |
| return this.directiveDefinitions; |
| case 0 /* Injector */: |
| return this.injectorDefinitions; |
| case 3 /* Pipe */: |
| return this.pipeDefinitions; |
| } |
| }; |
| ConstantPool.prototype.propertyNameOf = function (kind) { |
| switch (kind) { |
| case 2 /* Component */: |
| return 'ɵcmp'; |
| case 1 /* Directive */: |
| return 'ɵdir'; |
| case 0 /* Injector */: |
| return 'ɵinj'; |
| case 3 /* Pipe */: |
| return 'ɵpipe'; |
| } |
| }; |
| ConstantPool.prototype.freshName = function () { |
| return this.uniqueName(CONSTANT_PREFIX); |
| }; |
| ConstantPool.prototype.keyOf = function (expression) { |
| return expression.visitExpression(new KeyVisitor(), KEY_CONTEXT); |
| }; |
| return ConstantPool; |
| }()); |
| /** |
| * Visitor used to determine if 2 expressions are equivalent and can be shared in the |
| * `ConstantPool`. |
| * |
| * When the id (string) generated by the visitor is equal, expressions are considered equivalent. |
| */ |
| var KeyVisitor = /** @class */ (function () { |
| function KeyVisitor() { |
| this.visitWrappedNodeExpr = invalid; |
| this.visitWriteVarExpr = invalid; |
| this.visitWriteKeyExpr = invalid; |
| this.visitWritePropExpr = invalid; |
| this.visitInvokeMethodExpr = invalid; |
| this.visitInvokeFunctionExpr = invalid; |
| this.visitTaggedTemplateExpr = invalid; |
| this.visitInstantiateExpr = invalid; |
| this.visitConditionalExpr = invalid; |
| this.visitNotExpr = invalid; |
| this.visitAssertNotNullExpr = invalid; |
| this.visitCastExpr = invalid; |
| this.visitFunctionExpr = invalid; |
| this.visitUnaryOperatorExpr = invalid; |
| this.visitBinaryOperatorExpr = invalid; |
| this.visitReadPropExpr = invalid; |
| this.visitReadKeyExpr = invalid; |
| this.visitCommaExpr = invalid; |
| this.visitLocalizedString = invalid; |
| } |
| KeyVisitor.prototype.visitLiteralExpr = function (ast) { |
| return "" + (typeof ast.value === 'string' ? '"' + ast.value + '"' : ast.value); |
| }; |
| KeyVisitor.prototype.visitLiteralArrayExpr = function (ast, context) { |
| var _this = this; |
| return "[" + ast.entries.map(function (entry) { return entry.visitExpression(_this, context); }).join(',') + "]"; |
| }; |
| KeyVisitor.prototype.visitLiteralMapExpr = function (ast, context) { |
| var _this = this; |
| var mapKey = function (entry) { |
| var quote = entry.quoted ? '"' : ''; |
| return "" + quote + entry.key + quote; |
| }; |
| var mapEntry = function (entry) { return mapKey(entry) + ":" + entry.value.visitExpression(_this, context); }; |
| return "{" + ast.entries.map(mapEntry).join(','); |
| }; |
| KeyVisitor.prototype.visitExternalExpr = function (ast) { |
| return ast.value.moduleName ? "EX:" + ast.value.moduleName + ":" + ast.value.name : |
| "EX:" + ast.value.runtime.name; |
| }; |
| KeyVisitor.prototype.visitReadVarExpr = function (node) { |
| return "VAR:" + node.name; |
| }; |
| KeyVisitor.prototype.visitTypeofExpr = function (node, context) { |
| return "TYPEOF:" + node.expr.visitExpression(this, context); |
| }; |
| return KeyVisitor; |
| }()); |
| function invalid(arg) { |
| throw new Error("Invalid state: Visitor " + this.constructor.name + " doesn't handle " + arg.constructor.name); |
| } |
| function isVariable(e) { |
| return e instanceof ReadVarExpr; |
| } |
| function isLongStringLiteral(expr) { |
| return expr instanceof LiteralExpr && typeof expr.value === 'string' && |
| expr.value.length >= POOL_INCLUSION_LENGTH_THRESHOLD_FOR_STRINGS; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var CORE = '@angular/core'; |
| var Identifiers = /** @class */ (function () { |
| function Identifiers() { |
| } |
| return Identifiers; |
| }()); |
| Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS = { |
| name: 'ANALYZE_FOR_ENTRY_COMPONENTS', |
| moduleName: CORE, |
| }; |
| Identifiers.ElementRef = { name: 'ElementRef', moduleName: CORE }; |
| Identifiers.NgModuleRef = { name: 'NgModuleRef', moduleName: CORE }; |
| Identifiers.ViewContainerRef = { name: 'ViewContainerRef', moduleName: CORE }; |
| Identifiers.ChangeDetectorRef = { |
| name: 'ChangeDetectorRef', |
| moduleName: CORE, |
| }; |
| Identifiers.QueryList = { name: 'QueryList', moduleName: CORE }; |
| Identifiers.TemplateRef = { name: 'TemplateRef', moduleName: CORE }; |
| Identifiers.Renderer2 = { name: 'Renderer2', moduleName: CORE }; |
| Identifiers.CodegenComponentFactoryResolver = { |
| name: 'ɵCodegenComponentFactoryResolver', |
| moduleName: CORE, |
| }; |
| Identifiers.ComponentFactoryResolver = { |
| name: 'ComponentFactoryResolver', |
| moduleName: CORE, |
| }; |
| Identifiers.ComponentFactory = { name: 'ComponentFactory', moduleName: CORE }; |
| Identifiers.ComponentRef = { name: 'ComponentRef', moduleName: CORE }; |
| Identifiers.NgModuleFactory = { name: 'NgModuleFactory', moduleName: CORE }; |
| Identifiers.createModuleFactory = { |
| name: 'ɵcmf', |
| moduleName: CORE, |
| }; |
| Identifiers.moduleDef = { |
| name: 'ɵmod', |
| moduleName: CORE, |
| }; |
| Identifiers.moduleProviderDef = { |
| name: 'ɵmpd', |
| moduleName: CORE, |
| }; |
| Identifiers.RegisterModuleFactoryFn = { |
| name: 'ɵregisterModuleFactory', |
| moduleName: CORE, |
| }; |
| Identifiers.inject = { name: 'ɵɵinject', moduleName: CORE }; |
| Identifiers.directiveInject = { name: 'ɵɵdirectiveInject', moduleName: CORE }; |
| Identifiers.INJECTOR = { name: 'INJECTOR', moduleName: CORE }; |
| Identifiers.Injector = { name: 'Injector', moduleName: CORE }; |
| Identifiers.ɵɵdefineInjectable = { name: 'ɵɵdefineInjectable', moduleName: CORE }; |
| Identifiers.InjectableDef = { name: 'ɵɵInjectableDef', moduleName: CORE }; |
| Identifiers.ViewEncapsulation = { |
| name: 'ViewEncapsulation', |
| moduleName: CORE, |
| }; |
| Identifiers.ChangeDetectionStrategy = { |
| name: 'ChangeDetectionStrategy', |
| moduleName: CORE, |
| }; |
| Identifiers.SecurityContext = { |
| name: 'SecurityContext', |
| moduleName: CORE, |
| }; |
| Identifiers.LOCALE_ID = { name: 'LOCALE_ID', moduleName: CORE }; |
| Identifiers.TRANSLATIONS_FORMAT = { |
| name: 'TRANSLATIONS_FORMAT', |
| moduleName: CORE, |
| }; |
| Identifiers.inlineInterpolate = { |
| name: 'ɵinlineInterpolate', |
| moduleName: CORE, |
| }; |
| Identifiers.interpolate = { name: 'ɵinterpolate', moduleName: CORE }; |
| Identifiers.EMPTY_ARRAY = { name: 'ɵEMPTY_ARRAY', moduleName: CORE }; |
| Identifiers.EMPTY_MAP = { name: 'ɵEMPTY_MAP', moduleName: CORE }; |
| Identifiers.Renderer = { name: 'Renderer', moduleName: CORE }; |
| Identifiers.viewDef = { name: 'ɵvid', moduleName: CORE }; |
| Identifiers.elementDef = { name: 'ɵeld', moduleName: CORE }; |
| Identifiers.anchorDef = { name: 'ɵand', moduleName: CORE }; |
| Identifiers.textDef = { name: 'ɵted', moduleName: CORE }; |
| Identifiers.directiveDef = { name: 'ɵdid', moduleName: CORE }; |
| Identifiers.providerDef = { name: 'ɵprd', moduleName: CORE }; |
| Identifiers.queryDef = { name: 'ɵqud', moduleName: CORE }; |
| Identifiers.pureArrayDef = { name: 'ɵpad', moduleName: CORE }; |
| Identifiers.pureObjectDef = { name: 'ɵpod', moduleName: CORE }; |
| Identifiers.purePipeDef = { name: 'ɵppd', moduleName: CORE }; |
| Identifiers.pipeDef = { name: 'ɵpid', moduleName: CORE }; |
| Identifiers.nodeValue = { name: 'ɵnov', moduleName: CORE }; |
| Identifiers.ngContentDef = { name: 'ɵncd', moduleName: CORE }; |
| Identifiers.unwrapValue = { name: 'ɵunv', moduleName: CORE }; |
| Identifiers.createRendererType2 = { name: 'ɵcrt', moduleName: CORE }; |
| // type only |
| Identifiers.RendererType2 = { |
| name: 'RendererType2', |
| moduleName: CORE, |
| }; |
| // type only |
| Identifiers.ViewDefinition = { |
| name: 'ɵViewDefinition', |
| moduleName: CORE, |
| }; |
| Identifiers.createComponentFactory = { name: 'ɵccf', moduleName: CORE }; |
| Identifiers.setClassMetadata = { name: 'ɵsetClassMetadata', moduleName: CORE }; |
| function createTokenForReference(reference) { |
| return { identifier: { reference: reference } }; |
| } |
| function createTokenForExternalReference(reflector, reference) { |
| return createTokenForReference(reflector.resolveExternalReference(reference)); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * A token representing the a reference to a static type. |
| * |
| * This token is unique for a filePath and name and can be used as a hash table key. |
| */ |
| var StaticSymbol = /** @class */ (function () { |
| function StaticSymbol(filePath, name, members) { |
| this.filePath = filePath; |
| this.name = name; |
| this.members = members; |
| } |
| StaticSymbol.prototype.assertNoMembers = function () { |
| if (this.members.length) { |
| throw new Error("Illegal state: symbol without members expected, but got " + JSON.stringify(this) + "."); |
| } |
| }; |
| return StaticSymbol; |
| }()); |
| /** |
| * A cache of static symbol used by the StaticReflector to return the same symbol for the |
| * same symbol values. |
| */ |
| var StaticSymbolCache = /** @class */ (function () { |
| function StaticSymbolCache() { |
| this.cache = new Map(); |
| } |
| StaticSymbolCache.prototype.get = function (declarationFile, name, members) { |
| members = members || []; |
| var memberSuffix = members.length ? "." + members.join('.') : ''; |
| var key = "\"" + declarationFile + "\"." + name + memberSuffix; |
| var result = this.cache.get(key); |
| if (!result) { |
| result = new StaticSymbol(declarationFile, name, members); |
| this.cache.set(key, result); |
| } |
| return result; |
| }; |
| return StaticSymbolCache; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var DASH_CASE_REGEXP = /-+([a-z0-9])/g; |
| function dashCaseToCamelCase(input) { |
| return input.replace(DASH_CASE_REGEXP, function () { |
| var m = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| m[_i] = arguments[_i]; |
| } |
| return m[1].toUpperCase(); |
| }); |
| } |
| function splitAtColon(input, defaultValues) { |
| return _splitAt(input, ':', defaultValues); |
| } |
| function splitAtPeriod(input, defaultValues) { |
| return _splitAt(input, '.', defaultValues); |
| } |
| function _splitAt(input, character, defaultValues) { |
| var characterIndex = input.indexOf(character); |
| if (characterIndex == -1) |
| return defaultValues; |
| return [input.slice(0, characterIndex).trim(), input.slice(characterIndex + 1).trim()]; |
| } |
| function visitValue(value, visitor, context) { |
| if (Array.isArray(value)) { |
| return visitor.visitArray(value, context); |
| } |
| if (isStrictStringMap(value)) { |
| return visitor.visitStringMap(value, context); |
| } |
| if (value == null || typeof value == 'string' || typeof value == 'number' || |
| typeof value == 'boolean') { |
| return visitor.visitPrimitive(value, context); |
| } |
| return visitor.visitOther(value, context); |
| } |
| function isDefined(val) { |
| return val !== null && val !== undefined; |
| } |
| function noUndefined(val) { |
| return val === undefined ? null : val; |
| } |
| var ValueTransformer = /** @class */ (function () { |
| function ValueTransformer() { |
| } |
| ValueTransformer.prototype.visitArray = function (arr, context) { |
| var _this = this; |
| return arr.map(function (value) { return visitValue(value, _this, context); }); |
| }; |
| ValueTransformer.prototype.visitStringMap = function (map, context) { |
| var _this = this; |
| var result = {}; |
| Object.keys(map).forEach(function (key) { |
| result[key] = visitValue(map[key], _this, context); |
| }); |
| return result; |
| }; |
| ValueTransformer.prototype.visitPrimitive = function (value, context) { |
| return value; |
| }; |
| ValueTransformer.prototype.visitOther = function (value, context) { |
| return value; |
| }; |
| return ValueTransformer; |
| }()); |
| var SyncAsync = { |
| assertSync: function (value) { |
| if (isPromise(value)) { |
| throw new Error("Illegal state: value cannot be a promise"); |
| } |
| return value; |
| }, |
| then: function (value, cb) { |
| return isPromise(value) ? value.then(cb) : cb(value); |
| }, |
| all: function (syncAsyncValues) { |
| return syncAsyncValues.some(isPromise) ? Promise.all(syncAsyncValues) : syncAsyncValues; |
| } |
| }; |
| function error(msg) { |
| throw new Error("Internal Error: " + msg); |
| } |
| function syntaxError(msg, parseErrors) { |
| var error = Error(msg); |
| error[ERROR_SYNTAX_ERROR] = true; |
| if (parseErrors) |
| error[ERROR_PARSE_ERRORS] = parseErrors; |
| return error; |
| } |
| var ERROR_SYNTAX_ERROR = 'ngSyntaxError'; |
| var ERROR_PARSE_ERRORS = 'ngParseErrors'; |
| function isSyntaxError(error) { |
| return error[ERROR_SYNTAX_ERROR]; |
| } |
| function getParseErrors(error) { |
| return error[ERROR_PARSE_ERRORS] || []; |
| } |
| // Escape characters that have a special meaning in Regular Expressions |
| function escapeRegExp(s) { |
| return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); |
| } |
| var STRING_MAP_PROTO = Object.getPrototypeOf({}); |
| function isStrictStringMap(obj) { |
| return typeof obj === 'object' && obj !== null && Object.getPrototypeOf(obj) === STRING_MAP_PROTO; |
| } |
| function utf8Encode(str) { |
| var encoded = []; |
| for (var index = 0; index < str.length; index++) { |
| var codePoint = str.charCodeAt(index); |
| // decode surrogate |
| // see https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae |
| if (codePoint >= 0xd800 && codePoint <= 0xdbff && str.length > (index + 1)) { |
| var low = str.charCodeAt(index + 1); |
| if (low >= 0xdc00 && low <= 0xdfff) { |
| index++; |
| codePoint = ((codePoint - 0xd800) << 10) + low - 0xdc00 + 0x10000; |
| } |
| } |
| if (codePoint <= 0x7f) { |
| encoded.push(codePoint); |
| } |
| else if (codePoint <= 0x7ff) { |
| encoded.push(((codePoint >> 6) & 0x1F) | 0xc0, (codePoint & 0x3f) | 0x80); |
| } |
| else if (codePoint <= 0xffff) { |
| encoded.push((codePoint >> 12) | 0xe0, ((codePoint >> 6) & 0x3f) | 0x80, (codePoint & 0x3f) | 0x80); |
| } |
| else if (codePoint <= 0x1fffff) { |
| encoded.push(((codePoint >> 18) & 0x07) | 0xf0, ((codePoint >> 12) & 0x3f) | 0x80, ((codePoint >> 6) & 0x3f) | 0x80, (codePoint & 0x3f) | 0x80); |
| } |
| } |
| return encoded; |
| } |
| function stringify(token) { |
| if (typeof token === 'string') { |
| return token; |
| } |
| if (Array.isArray(token)) { |
| return '[' + token.map(stringify).join(', ') + ']'; |
| } |
| if (token == null) { |
| return '' + token; |
| } |
| if (token.overriddenName) { |
| return "" + token.overriddenName; |
| } |
| if (token.name) { |
| return "" + token.name; |
| } |
| if (!token.toString) { |
| return 'object'; |
| } |
| // WARNING: do not try to `JSON.stringify(token)` here |
| // see https://github.com/angular/angular/issues/23440 |
| var res = token.toString(); |
| if (res == null) { |
| return '' + res; |
| } |
| var newLineIndex = res.indexOf('\n'); |
| return newLineIndex === -1 ? res : res.substring(0, newLineIndex); |
| } |
| /** |
| * Lazily retrieves the reference value from a forwardRef. |
| */ |
| function resolveForwardRef(type) { |
| if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__')) { |
| return type(); |
| } |
| else { |
| return type; |
| } |
| } |
| /** |
| * 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'; |
| } |
| var Version = /** @class */ (function () { |
| function Version(full) { |
| this.full = full; |
| var splits = full.split('.'); |
| this.major = splits[0]; |
| this.minor = splits[1]; |
| this.patch = splits.slice(2).join('.'); |
| } |
| return Version; |
| }()); |
| 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; |
| function newArray(size, value) { |
| var list = []; |
| for (var i = 0; i < size; i++) { |
| list.push(value); |
| } |
| return list; |
| } |
| /** |
| * Partitions a given array into 2 arrays, based on a boolean value returned by the condition |
| * function. |
| * |
| * @param arr Input array that should be partitioned |
| * @param conditionFn Condition function that is called for each item in a given array and returns a |
| * boolean value. |
| */ |
| function partitionArray(arr, conditionFn) { |
| var e_1, _a; |
| var truthy = []; |
| var falsy = []; |
| try { |
| for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) { |
| var item = arr_1_1.value; |
| (conditionFn(item) ? truthy : falsy).push(item); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return [truthy, falsy]; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| // group 0: "[prop] or (event) or @trigger" |
| // group 1: "prop" from "[prop]" |
| // group 2: "event" from "(event)" |
| // group 3: "@trigger" from "@trigger" |
| var HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/; |
| function sanitizeIdentifier(name) { |
| return name.replace(/\W/g, '_'); |
| } |
| var _anonymousTypeIndex = 0; |
| function identifierName(compileIdentifier) { |
| if (!compileIdentifier || !compileIdentifier.reference) { |
| return null; |
| } |
| var ref = compileIdentifier.reference; |
| if (ref instanceof StaticSymbol) { |
| return ref.name; |
| } |
| if (ref['__anonymousType']) { |
| return ref['__anonymousType']; |
| } |
| var identifier = stringify(ref); |
| if (identifier.indexOf('(') >= 0) { |
| // case: anonymous functions! |
| identifier = "anonymous_" + _anonymousTypeIndex++; |
| ref['__anonymousType'] = identifier; |
| } |
| else { |
| identifier = sanitizeIdentifier(identifier); |
| } |
| return identifier; |
| } |
| function identifierModuleUrl(compileIdentifier) { |
| var ref = compileIdentifier.reference; |
| if (ref instanceof StaticSymbol) { |
| return ref.filePath; |
| } |
| // Runtime type |
| return "./" + stringify(ref); |
| } |
| function viewClassName(compType, embeddedTemplateIndex) { |
| return "View_" + identifierName({ reference: compType }) + "_" + embeddedTemplateIndex; |
| } |
| function rendererTypeName(compType) { |
| return "RenderType_" + identifierName({ reference: compType }); |
| } |
| function hostViewClassName(compType) { |
| return "HostView_" + identifierName({ reference: compType }); |
| } |
| function componentFactoryName(compType) { |
| return identifierName({ reference: compType }) + "NgFactory"; |
| } |
| (function (CompileSummaryKind) { |
| CompileSummaryKind[CompileSummaryKind["Pipe"] = 0] = "Pipe"; |
| CompileSummaryKind[CompileSummaryKind["Directive"] = 1] = "Directive"; |
| CompileSummaryKind[CompileSummaryKind["NgModule"] = 2] = "NgModule"; |
| CompileSummaryKind[CompileSummaryKind["Injectable"] = 3] = "Injectable"; |
| })(exports.CompileSummaryKind || (exports.CompileSummaryKind = {})); |
| function tokenName(token) { |
| return token.value != null ? sanitizeIdentifier(token.value) : identifierName(token.identifier); |
| } |
| function tokenReference(token) { |
| if (token.identifier != null) { |
| return token.identifier.reference; |
| } |
| else { |
| return token.value; |
| } |
| } |
| /** |
| * Metadata about a stylesheet |
| */ |
| var CompileStylesheetMetadata = /** @class */ (function () { |
| function CompileStylesheetMetadata(_a) { |
| var _b = _a === void 0 ? {} : _a, moduleUrl = _b.moduleUrl, styles = _b.styles, styleUrls = _b.styleUrls; |
| this.moduleUrl = moduleUrl || null; |
| this.styles = _normalizeArray(styles); |
| this.styleUrls = _normalizeArray(styleUrls); |
| } |
| return CompileStylesheetMetadata; |
| }()); |
| /** |
| * Metadata regarding compilation of a template. |
| */ |
| var CompileTemplateMetadata = /** @class */ (function () { |
| function CompileTemplateMetadata(_a) { |
| var encapsulation = _a.encapsulation, template = _a.template, templateUrl = _a.templateUrl, htmlAst = _a.htmlAst, styles = _a.styles, styleUrls = _a.styleUrls, externalStylesheets = _a.externalStylesheets, animations = _a.animations, ngContentSelectors = _a.ngContentSelectors, interpolation = _a.interpolation, isInline = _a.isInline, preserveWhitespaces = _a.preserveWhitespaces; |
| this.encapsulation = encapsulation; |
| this.template = template; |
| this.templateUrl = templateUrl; |
| this.htmlAst = htmlAst; |
| this.styles = _normalizeArray(styles); |
| this.styleUrls = _normalizeArray(styleUrls); |
| this.externalStylesheets = _normalizeArray(externalStylesheets); |
| this.animations = animations ? flatten(animations) : []; |
| this.ngContentSelectors = ngContentSelectors || []; |
| if (interpolation && interpolation.length != 2) { |
| throw new Error("'interpolation' should have a start and an end symbol."); |
| } |
| this.interpolation = interpolation; |
| this.isInline = isInline; |
| this.preserveWhitespaces = preserveWhitespaces; |
| } |
| CompileTemplateMetadata.prototype.toSummary = function () { |
| return { |
| ngContentSelectors: this.ngContentSelectors, |
| encapsulation: this.encapsulation, |
| styles: this.styles, |
| animations: this.animations |
| }; |
| }; |
| return CompileTemplateMetadata; |
| }()); |
| /** |
| * Metadata regarding compilation of a directive. |
| */ |
| var CompileDirectiveMetadata = /** @class */ (function () { |
| function CompileDirectiveMetadata(_a) { |
| var isHost = _a.isHost, type = _a.type, isComponent = _a.isComponent, selector = _a.selector, exportAs = _a.exportAs, changeDetection = _a.changeDetection, inputs = _a.inputs, outputs = _a.outputs, hostListeners = _a.hostListeners, hostProperties = _a.hostProperties, hostAttributes = _a.hostAttributes, providers = _a.providers, viewProviders = _a.viewProviders, queries = _a.queries, guards = _a.guards, viewQueries = _a.viewQueries, entryComponents = _a.entryComponents, template = _a.template, componentViewType = _a.componentViewType, rendererType = _a.rendererType, componentFactory = _a.componentFactory; |
| this.isHost = !!isHost; |
| this.type = type; |
| this.isComponent = isComponent; |
| this.selector = selector; |
| this.exportAs = exportAs; |
| this.changeDetection = changeDetection; |
| this.inputs = inputs; |
| this.outputs = outputs; |
| this.hostListeners = hostListeners; |
| this.hostProperties = hostProperties; |
| this.hostAttributes = hostAttributes; |
| this.providers = _normalizeArray(providers); |
| this.viewProviders = _normalizeArray(viewProviders); |
| this.queries = _normalizeArray(queries); |
| this.guards = guards; |
| this.viewQueries = _normalizeArray(viewQueries); |
| this.entryComponents = _normalizeArray(entryComponents); |
| this.template = template; |
| this.componentViewType = componentViewType; |
| this.rendererType = rendererType; |
| this.componentFactory = componentFactory; |
| } |
| CompileDirectiveMetadata.create = function (_a) { |
| var isHost = _a.isHost, type = _a.type, isComponent = _a.isComponent, selector = _a.selector, exportAs = _a.exportAs, changeDetection = _a.changeDetection, inputs = _a.inputs, outputs = _a.outputs, host = _a.host, providers = _a.providers, viewProviders = _a.viewProviders, queries = _a.queries, guards = _a.guards, viewQueries = _a.viewQueries, entryComponents = _a.entryComponents, template = _a.template, componentViewType = _a.componentViewType, rendererType = _a.rendererType, componentFactory = _a.componentFactory; |
| var hostListeners = {}; |
| var hostProperties = {}; |
| var hostAttributes = {}; |
| if (host != null) { |
| Object.keys(host).forEach(function (key) { |
| var value = host[key]; |
| var matches = key.match(HOST_REG_EXP); |
| if (matches === null) { |
| hostAttributes[key] = value; |
| } |
| else if (matches[1] != null) { |
| hostProperties[matches[1]] = value; |
| } |
| else if (matches[2] != null) { |
| hostListeners[matches[2]] = value; |
| } |
| }); |
| } |
| var inputsMap = {}; |
| if (inputs != null) { |
| inputs.forEach(function (bindConfig) { |
| // canonical syntax: `dirProp: elProp` |
| // if there is no `:`, use dirProp = elProp |
| var parts = splitAtColon(bindConfig, [bindConfig, bindConfig]); |
| inputsMap[parts[0]] = parts[1]; |
| }); |
| } |
| var outputsMap = {}; |
| if (outputs != null) { |
| outputs.forEach(function (bindConfig) { |
| // canonical syntax: `dirProp: elProp` |
| // if there is no `:`, use dirProp = elProp |
| var parts = splitAtColon(bindConfig, [bindConfig, bindConfig]); |
| outputsMap[parts[0]] = parts[1]; |
| }); |
| } |
| return new CompileDirectiveMetadata({ |
| isHost: isHost, |
| type: type, |
| isComponent: !!isComponent, |
| selector: selector, |
| exportAs: exportAs, |
| changeDetection: changeDetection, |
| inputs: inputsMap, |
| outputs: outputsMap, |
| hostListeners: hostListeners, |
| hostProperties: hostProperties, |
| hostAttributes: hostAttributes, |
| providers: providers, |
| viewProviders: viewProviders, |
| queries: queries, |
| guards: guards, |
| viewQueries: viewQueries, |
| entryComponents: entryComponents, |
| template: template, |
| componentViewType: componentViewType, |
| rendererType: rendererType, |
| componentFactory: componentFactory, |
| }); |
| }; |
| CompileDirectiveMetadata.prototype.toSummary = function () { |
| return { |
| summaryKind: exports.CompileSummaryKind.Directive, |
| type: this.type, |
| isComponent: this.isComponent, |
| selector: this.selector, |
| exportAs: this.exportAs, |
| inputs: this.inputs, |
| outputs: this.outputs, |
| hostListeners: this.hostListeners, |
| hostProperties: this.hostProperties, |
| hostAttributes: this.hostAttributes, |
| providers: this.providers, |
| viewProviders: this.viewProviders, |
| queries: this.queries, |
| guards: this.guards, |
| viewQueries: this.viewQueries, |
| entryComponents: this.entryComponents, |
| changeDetection: this.changeDetection, |
| template: this.template && this.template.toSummary(), |
| componentViewType: this.componentViewType, |
| rendererType: this.rendererType, |
| componentFactory: this.componentFactory |
| }; |
| }; |
| return CompileDirectiveMetadata; |
| }()); |
| var CompilePipeMetadata = /** @class */ (function () { |
| function CompilePipeMetadata(_a) { |
| var type = _a.type, name = _a.name, pure = _a.pure; |
| this.type = type; |
| this.name = name; |
| this.pure = !!pure; |
| } |
| CompilePipeMetadata.prototype.toSummary = function () { |
| return { |
| summaryKind: exports.CompileSummaryKind.Pipe, |
| type: this.type, |
| name: this.name, |
| pure: this.pure |
| }; |
| }; |
| return CompilePipeMetadata; |
| }()); |
| var CompileShallowModuleMetadata = /** @class */ (function () { |
| function CompileShallowModuleMetadata() { |
| } |
| return CompileShallowModuleMetadata; |
| }()); |
| /** |
| * Metadata regarding compilation of a module. |
| */ |
| var CompileNgModuleMetadata = /** @class */ (function () { |
| function CompileNgModuleMetadata(_a) { |
| var type = _a.type, providers = _a.providers, declaredDirectives = _a.declaredDirectives, exportedDirectives = _a.exportedDirectives, declaredPipes = _a.declaredPipes, exportedPipes = _a.exportedPipes, entryComponents = _a.entryComponents, bootstrapComponents = _a.bootstrapComponents, importedModules = _a.importedModules, exportedModules = _a.exportedModules, schemas = _a.schemas, transitiveModule = _a.transitiveModule, id = _a.id; |
| this.type = type || null; |
| this.declaredDirectives = _normalizeArray(declaredDirectives); |
| this.exportedDirectives = _normalizeArray(exportedDirectives); |
| this.declaredPipes = _normalizeArray(declaredPipes); |
| this.exportedPipes = _normalizeArray(exportedPipes); |
| this.providers = _normalizeArray(providers); |
| this.entryComponents = _normalizeArray(entryComponents); |
| this.bootstrapComponents = _normalizeArray(bootstrapComponents); |
| this.importedModules = _normalizeArray(importedModules); |
| this.exportedModules = _normalizeArray(exportedModules); |
| this.schemas = _normalizeArray(schemas); |
| this.id = id || null; |
| this.transitiveModule = transitiveModule || null; |
| } |
| CompileNgModuleMetadata.prototype.toSummary = function () { |
| var module = this.transitiveModule; |
| return { |
| summaryKind: exports.CompileSummaryKind.NgModule, |
| type: this.type, |
| entryComponents: module.entryComponents, |
| providers: module.providers, |
| modules: module.modules, |
| exportedDirectives: module.exportedDirectives, |
| exportedPipes: module.exportedPipes |
| }; |
| }; |
| return CompileNgModuleMetadata; |
| }()); |
| var TransitiveCompileNgModuleMetadata = /** @class */ (function () { |
| function TransitiveCompileNgModuleMetadata() { |
| this.directivesSet = new Set(); |
| this.directives = []; |
| this.exportedDirectivesSet = new Set(); |
| this.exportedDirectives = []; |
| this.pipesSet = new Set(); |
| this.pipes = []; |
| this.exportedPipesSet = new Set(); |
| this.exportedPipes = []; |
| this.modulesSet = new Set(); |
| this.modules = []; |
| this.entryComponentsSet = new Set(); |
| this.entryComponents = []; |
| this.providers = []; |
| } |
| TransitiveCompileNgModuleMetadata.prototype.addProvider = function (provider, module) { |
| this.providers.push({ provider: provider, module: module }); |
| }; |
| TransitiveCompileNgModuleMetadata.prototype.addDirective = function (id) { |
| if (!this.directivesSet.has(id.reference)) { |
| this.directivesSet.add(id.reference); |
| this.directives.push(id); |
| } |
| }; |
| TransitiveCompileNgModuleMetadata.prototype.addExportedDirective = function (id) { |
| if (!this.exportedDirectivesSet.has(id.reference)) { |
| this.exportedDirectivesSet.add(id.reference); |
| this.exportedDirectives.push(id); |
| } |
| }; |
| TransitiveCompileNgModuleMetadata.prototype.addPipe = function (id) { |
| if (!this.pipesSet.has(id.reference)) { |
| this.pipesSet.add(id.reference); |
| this.pipes.push(id); |
| } |
| }; |
| TransitiveCompileNgModuleMetadata.prototype.addExportedPipe = function (id) { |
| if (!this.exportedPipesSet.has(id.reference)) { |
| this.exportedPipesSet.add(id.reference); |
| this.exportedPipes.push(id); |
| } |
| }; |
| TransitiveCompileNgModuleMetadata.prototype.addModule = function (id) { |
| if (!this.modulesSet.has(id.reference)) { |
| this.modulesSet.add(id.reference); |
| this.modules.push(id); |
| } |
| }; |
| TransitiveCompileNgModuleMetadata.prototype.addEntryComponent = function (ec) { |
| if (!this.entryComponentsSet.has(ec.componentType)) { |
| this.entryComponentsSet.add(ec.componentType); |
| this.entryComponents.push(ec); |
| } |
| }; |
| return TransitiveCompileNgModuleMetadata; |
| }()); |
| function _normalizeArray(obj) { |
| return obj || []; |
| } |
| var ProviderMeta = /** @class */ (function () { |
| function ProviderMeta(token, _a) { |
| var useClass = _a.useClass, useValue = _a.useValue, useExisting = _a.useExisting, useFactory = _a.useFactory, deps = _a.deps, multi = _a.multi; |
| this.token = token; |
| this.useClass = useClass || null; |
| this.useValue = useValue; |
| this.useExisting = useExisting; |
| this.useFactory = useFactory || null; |
| this.dependencies = deps || null; |
| this.multi = !!multi; |
| } |
| return ProviderMeta; |
| }()); |
| function flatten(list) { |
| return list.reduce(function (flat, item) { |
| var flatItem = Array.isArray(item) ? flatten(item) : item; |
| return flat.concat(flatItem); |
| }, []); |
| } |
| function jitSourceUrl(url) { |
| // Note: We need 3 "/" so that ng shows up as a separate domain |
| // in the chrome dev tools. |
| return url.replace(/(\w+:\/\/[\w:-]+)?(\/+)?/, 'ng:///'); |
| } |
| function templateSourceUrl(ngModuleType, compMeta, templateMeta) { |
| var url; |
| if (templateMeta.isInline) { |
| if (compMeta.type.reference instanceof StaticSymbol) { |
| // Note: a .ts file might contain multiple components with inline templates, |
| // so we need to give them unique urls, as these will be used for sourcemaps. |
| url = compMeta.type.reference.filePath + "." + compMeta.type.reference.name + ".html"; |
| } |
| else { |
| url = identifierName(ngModuleType) + "/" + identifierName(compMeta.type) + ".html"; |
| } |
| } |
| else { |
| url = templateMeta.templateUrl; |
| } |
| return compMeta.type.reference instanceof StaticSymbol ? url : jitSourceUrl(url); |
| } |
| function sharedStylesheetJitUrl(meta, id) { |
| var pathParts = meta.moduleUrl.split(/\/\\/g); |
| var baseName = pathParts[pathParts.length - 1]; |
| return jitSourceUrl("css/" + id + baseName + ".ngstyle.js"); |
| } |
| function ngModuleJitUrl(moduleMeta) { |
| return jitSourceUrl(identifierName(moduleMeta.type) + "/module.ngfactory.js"); |
| } |
| function templateJitUrl(ngModuleType, compMeta) { |
| return jitSourceUrl(identifierName(ngModuleType) + "/" + identifierName(compMeta.type) + ".ngfactory.js"); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var CORE$1 = '@angular/core'; |
| var Identifiers$1 = /** @class */ (function () { |
| function Identifiers() { |
| } |
| return Identifiers; |
| }()); |
| /* Methods */ |
| Identifiers$1.NEW_METHOD = 'factory'; |
| Identifiers$1.TRANSFORM_METHOD = 'transform'; |
| Identifiers$1.PATCH_DEPS = 'patchedDeps'; |
| Identifiers$1.core = { name: null, moduleName: CORE$1 }; |
| /* Instructions */ |
| Identifiers$1.namespaceHTML = { name: 'ɵɵnamespaceHTML', moduleName: CORE$1 }; |
| Identifiers$1.namespaceMathML = { name: 'ɵɵnamespaceMathML', moduleName: CORE$1 }; |
| Identifiers$1.namespaceSVG = { name: 'ɵɵnamespaceSVG', moduleName: CORE$1 }; |
| Identifiers$1.element = { name: 'ɵɵelement', moduleName: CORE$1 }; |
| Identifiers$1.elementStart = { name: 'ɵɵelementStart', moduleName: CORE$1 }; |
| Identifiers$1.elementEnd = { name: 'ɵɵelementEnd', moduleName: CORE$1 }; |
| Identifiers$1.advance = { name: 'ɵɵadvance', moduleName: CORE$1 }; |
| Identifiers$1.syntheticHostProperty = { name: 'ɵɵsyntheticHostProperty', moduleName: CORE$1 }; |
| Identifiers$1.syntheticHostListener = { name: 'ɵɵsyntheticHostListener', moduleName: CORE$1 }; |
| Identifiers$1.attribute = { name: 'ɵɵattribute', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate1 = { name: 'ɵɵattributeInterpolate1', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate2 = { name: 'ɵɵattributeInterpolate2', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate3 = { name: 'ɵɵattributeInterpolate3', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate4 = { name: 'ɵɵattributeInterpolate4', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate5 = { name: 'ɵɵattributeInterpolate5', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate6 = { name: 'ɵɵattributeInterpolate6', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate7 = { name: 'ɵɵattributeInterpolate7', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolate8 = { name: 'ɵɵattributeInterpolate8', moduleName: CORE$1 }; |
| Identifiers$1.attributeInterpolateV = { name: 'ɵɵattributeInterpolateV', moduleName: CORE$1 }; |
| Identifiers$1.classProp = { name: 'ɵɵclassProp', moduleName: CORE$1 }; |
| Identifiers$1.elementContainerStart = { name: 'ɵɵelementContainerStart', moduleName: CORE$1 }; |
| Identifiers$1.elementContainerEnd = { name: 'ɵɵelementContainerEnd', moduleName: CORE$1 }; |
| Identifiers$1.elementContainer = { name: 'ɵɵelementContainer', moduleName: CORE$1 }; |
| Identifiers$1.styleMap = { name: 'ɵɵstyleMap', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate1 = { name: 'ɵɵstyleMapInterpolate1', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate2 = { name: 'ɵɵstyleMapInterpolate2', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate3 = { name: 'ɵɵstyleMapInterpolate3', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate4 = { name: 'ɵɵstyleMapInterpolate4', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate5 = { name: 'ɵɵstyleMapInterpolate5', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate6 = { name: 'ɵɵstyleMapInterpolate6', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate7 = { name: 'ɵɵstyleMapInterpolate7', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolate8 = { name: 'ɵɵstyleMapInterpolate8', moduleName: CORE$1 }; |
| Identifiers$1.styleMapInterpolateV = { name: 'ɵɵstyleMapInterpolateV', moduleName: CORE$1 }; |
| Identifiers$1.classMap = { name: 'ɵɵclassMap', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate1 = { name: 'ɵɵclassMapInterpolate1', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate2 = { name: 'ɵɵclassMapInterpolate2', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate3 = { name: 'ɵɵclassMapInterpolate3', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate4 = { name: 'ɵɵclassMapInterpolate4', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate5 = { name: 'ɵɵclassMapInterpolate5', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate6 = { name: 'ɵɵclassMapInterpolate6', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate7 = { name: 'ɵɵclassMapInterpolate7', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolate8 = { name: 'ɵɵclassMapInterpolate8', moduleName: CORE$1 }; |
| Identifiers$1.classMapInterpolateV = { name: 'ɵɵclassMapInterpolateV', moduleName: CORE$1 }; |
| Identifiers$1.styleProp = { name: 'ɵɵstyleProp', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate1 = { name: 'ɵɵstylePropInterpolate1', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate2 = { name: 'ɵɵstylePropInterpolate2', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate3 = { name: 'ɵɵstylePropInterpolate3', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate4 = { name: 'ɵɵstylePropInterpolate4', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate5 = { name: 'ɵɵstylePropInterpolate5', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate6 = { name: 'ɵɵstylePropInterpolate6', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate7 = { name: 'ɵɵstylePropInterpolate7', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolate8 = { name: 'ɵɵstylePropInterpolate8', moduleName: CORE$1 }; |
| Identifiers$1.stylePropInterpolateV = { name: 'ɵɵstylePropInterpolateV', moduleName: CORE$1 }; |
| Identifiers$1.nextContext = { name: 'ɵɵnextContext', moduleName: CORE$1 }; |
| Identifiers$1.templateCreate = { name: 'ɵɵtemplate', moduleName: CORE$1 }; |
| Identifiers$1.text = { name: 'ɵɵtext', moduleName: CORE$1 }; |
| Identifiers$1.enableBindings = { name: 'ɵɵenableBindings', moduleName: CORE$1 }; |
| Identifiers$1.disableBindings = { name: 'ɵɵdisableBindings', moduleName: CORE$1 }; |
| Identifiers$1.getCurrentView = { name: 'ɵɵgetCurrentView', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate = { name: 'ɵɵtextInterpolate', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate1 = { name: 'ɵɵtextInterpolate1', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate2 = { name: 'ɵɵtextInterpolate2', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate3 = { name: 'ɵɵtextInterpolate3', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate4 = { name: 'ɵɵtextInterpolate4', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate5 = { name: 'ɵɵtextInterpolate5', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate6 = { name: 'ɵɵtextInterpolate6', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate7 = { name: 'ɵɵtextInterpolate7', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolate8 = { name: 'ɵɵtextInterpolate8', moduleName: CORE$1 }; |
| Identifiers$1.textInterpolateV = { name: 'ɵɵtextInterpolateV', moduleName: CORE$1 }; |
| Identifiers$1.restoreView = { name: 'ɵɵrestoreView', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction0 = { name: 'ɵɵpureFunction0', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction1 = { name: 'ɵɵpureFunction1', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction2 = { name: 'ɵɵpureFunction2', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction3 = { name: 'ɵɵpureFunction3', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction4 = { name: 'ɵɵpureFunction4', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction5 = { name: 'ɵɵpureFunction5', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction6 = { name: 'ɵɵpureFunction6', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction7 = { name: 'ɵɵpureFunction7', moduleName: CORE$1 }; |
| Identifiers$1.pureFunction8 = { name: 'ɵɵpureFunction8', moduleName: CORE$1 }; |
| Identifiers$1.pureFunctionV = { name: 'ɵɵpureFunctionV', moduleName: CORE$1 }; |
| Identifiers$1.pipeBind1 = { name: 'ɵɵpipeBind1', moduleName: CORE$1 }; |
| Identifiers$1.pipeBind2 = { name: 'ɵɵpipeBind2', moduleName: CORE$1 }; |
| Identifiers$1.pipeBind3 = { name: 'ɵɵpipeBind3', moduleName: CORE$1 }; |
| Identifiers$1.pipeBind4 = { name: 'ɵɵpipeBind4', moduleName: CORE$1 }; |
| Identifiers$1.pipeBindV = { name: 'ɵɵpipeBindV', moduleName: CORE$1 }; |
| Identifiers$1.hostProperty = { name: 'ɵɵhostProperty', moduleName: CORE$1 }; |
| Identifiers$1.property = { name: 'ɵɵproperty', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate = { name: 'ɵɵpropertyInterpolate', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate1 = { name: 'ɵɵpropertyInterpolate1', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate2 = { name: 'ɵɵpropertyInterpolate2', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate3 = { name: 'ɵɵpropertyInterpolate3', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate4 = { name: 'ɵɵpropertyInterpolate4', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate5 = { name: 'ɵɵpropertyInterpolate5', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate6 = { name: 'ɵɵpropertyInterpolate6', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate7 = { name: 'ɵɵpropertyInterpolate7', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolate8 = { name: 'ɵɵpropertyInterpolate8', moduleName: CORE$1 }; |
| Identifiers$1.propertyInterpolateV = { name: 'ɵɵpropertyInterpolateV', moduleName: CORE$1 }; |
| Identifiers$1.i18n = { name: 'ɵɵi18n', moduleName: CORE$1 }; |
| Identifiers$1.i18nAttributes = { name: 'ɵɵi18nAttributes', moduleName: CORE$1 }; |
| Identifiers$1.i18nExp = { name: 'ɵɵi18nExp', moduleName: CORE$1 }; |
| Identifiers$1.i18nStart = { name: 'ɵɵi18nStart', moduleName: CORE$1 }; |
| Identifiers$1.i18nEnd = { name: 'ɵɵi18nEnd', moduleName: CORE$1 }; |
| Identifiers$1.i18nApply = { name: 'ɵɵi18nApply', moduleName: CORE$1 }; |
| Identifiers$1.i18nPostprocess = { name: 'ɵɵi18nPostprocess', moduleName: CORE$1 }; |
| Identifiers$1.pipe = { name: 'ɵɵpipe', moduleName: CORE$1 }; |
| Identifiers$1.projection = { name: 'ɵɵprojection', moduleName: CORE$1 }; |
| Identifiers$1.projectionDef = { name: 'ɵɵprojectionDef', moduleName: CORE$1 }; |
| Identifiers$1.reference = { name: 'ɵɵreference', moduleName: CORE$1 }; |
| Identifiers$1.inject = { name: 'ɵɵinject', moduleName: CORE$1 }; |
| Identifiers$1.injectAttribute = { name: 'ɵɵinjectAttribute', moduleName: CORE$1 }; |
| Identifiers$1.injectPipeChangeDetectorRef = { name: 'ɵɵinjectPipeChangeDetectorRef', moduleName: CORE$1 }; |
| Identifiers$1.directiveInject = { name: 'ɵɵdirectiveInject', moduleName: CORE$1 }; |
| Identifiers$1.invalidFactory = { name: 'ɵɵinvalidFactory', moduleName: CORE$1 }; |
| Identifiers$1.invalidFactoryDep = { name: 'ɵɵinvalidFactoryDep', moduleName: CORE$1 }; |
| Identifiers$1.templateRefExtractor = { name: 'ɵɵtemplateRefExtractor', moduleName: CORE$1 }; |
| Identifiers$1.forwardRef = { name: 'forwardRef', moduleName: CORE$1 }; |
| Identifiers$1.resolveForwardRef = { name: 'resolveForwardRef', moduleName: CORE$1 }; |
| Identifiers$1.resolveWindow = { name: 'ɵɵresolveWindow', moduleName: CORE$1 }; |
| Identifiers$1.resolveDocument = { name: 'ɵɵresolveDocument', moduleName: CORE$1 }; |
| Identifiers$1.resolveBody = { name: 'ɵɵresolveBody', moduleName: CORE$1 }; |
| Identifiers$1.defineComponent = { name: 'ɵɵdefineComponent', moduleName: CORE$1 }; |
| Identifiers$1.declareComponent = { name: 'ɵɵngDeclareComponent', moduleName: CORE$1 }; |
| Identifiers$1.setComponentScope = { name: 'ɵɵsetComponentScope', moduleName: CORE$1 }; |
| Identifiers$1.ChangeDetectionStrategy = { |
| name: 'ChangeDetectionStrategy', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.ViewEncapsulation = { |
| name: 'ViewEncapsulation', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.ComponentDefWithMeta = { |
| name: 'ɵɵComponentDefWithMeta', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.FactoryDef = { |
| name: 'ɵɵFactoryDef', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.defineDirective = { name: 'ɵɵdefineDirective', moduleName: CORE$1 }; |
| Identifiers$1.declareDirective = { name: 'ɵɵngDeclareDirective', moduleName: CORE$1 }; |
| Identifiers$1.DirectiveDefWithMeta = { |
| name: 'ɵɵDirectiveDefWithMeta', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.InjectorDef = { |
| name: 'ɵɵInjectorDef', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.defineInjector = { |
| name: 'ɵɵdefineInjector', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.NgModuleDefWithMeta = { |
| name: 'ɵɵNgModuleDefWithMeta', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.ModuleWithProviders = { |
| name: 'ModuleWithProviders', |
| moduleName: CORE$1, |
| }; |
| Identifiers$1.defineNgModule = { name: 'ɵɵdefineNgModule', moduleName: CORE$1 }; |
| Identifiers$1.setNgModuleScope = { name: 'ɵɵsetNgModuleScope', moduleName: CORE$1 }; |
| Identifiers$1.PipeDefWithMeta = { name: 'ɵɵPipeDefWithMeta', moduleName: CORE$1 }; |
| Identifiers$1.definePipe = { name: 'ɵɵdefinePipe', moduleName: CORE$1 }; |
| Identifiers$1.declarePipe = { name: 'ɵɵngDeclarePipe', moduleName: CORE$1 }; |
| Identifiers$1.queryRefresh = { name: 'ɵɵqueryRefresh', moduleName: CORE$1 }; |
| Identifiers$1.viewQuery = { name: 'ɵɵviewQuery', moduleName: CORE$1 }; |
| Identifiers$1.loadQuery = { name: 'ɵɵloadQuery', moduleName: CORE$1 }; |
| Identifiers$1.contentQuery = { name: 'ɵɵcontentQuery', moduleName: CORE$1 }; |
| Identifiers$1.NgOnChangesFeature = { name: 'ɵɵNgOnChangesFeature', moduleName: CORE$1 }; |
| Identifiers$1.InheritDefinitionFeature = { name: 'ɵɵInheritDefinitionFeature', moduleName: CORE$1 }; |
| Identifiers$1.CopyDefinitionFeature = { name: 'ɵɵCopyDefinitionFeature', moduleName: CORE$1 }; |
| Identifiers$1.ProvidersFeature = { name: 'ɵɵProvidersFeature', moduleName: CORE$1 }; |
| Identifiers$1.listener = { name: 'ɵɵlistener', moduleName: CORE$1 }; |
| Identifiers$1.getInheritedFactory = { |
| name: 'ɵɵgetInheritedFactory', |
| moduleName: CORE$1, |
| }; |
| // sanitization-related functions |
| Identifiers$1.sanitizeHtml = { name: 'ɵɵsanitizeHtml', moduleName: CORE$1 }; |
| Identifiers$1.sanitizeStyle = { name: 'ɵɵsanitizeStyle', moduleName: CORE$1 }; |
| Identifiers$1.sanitizeResourceUrl = { name: 'ɵɵsanitizeResourceUrl', moduleName: CORE$1 }; |
| Identifiers$1.sanitizeScript = { name: 'ɵɵsanitizeScript', moduleName: CORE$1 }; |
| Identifiers$1.sanitizeUrl = { name: 'ɵɵsanitizeUrl', moduleName: CORE$1 }; |
| Identifiers$1.sanitizeUrlOrResourceUrl = { name: 'ɵɵsanitizeUrlOrResourceUrl', moduleName: CORE$1 }; |
| Identifiers$1.trustConstantHtml = { name: 'ɵɵtrustConstantHtml', moduleName: CORE$1 }; |
| Identifiers$1.trustConstantResourceUrl = { name: 'ɵɵtrustConstantResourceUrl', moduleName: CORE$1 }; |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit |
| var VERSION = 3; |
| var JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,'; |
| var SourceMapGenerator = /** @class */ (function () { |
| function SourceMapGenerator(file) { |
| if (file === void 0) { file = null; } |
| this.file = file; |
| this.sourcesContent = new Map(); |
| this.lines = []; |
| this.lastCol0 = 0; |
| this.hasMappings = false; |
| } |
| // The content is `null` when the content is expected to be loaded using the URL |
| SourceMapGenerator.prototype.addSource = function (url, content) { |
| if (content === void 0) { content = null; } |
| if (!this.sourcesContent.has(url)) { |
| this.sourcesContent.set(url, content); |
| } |
| return this; |
| }; |
| SourceMapGenerator.prototype.addLine = function () { |
| this.lines.push([]); |
| this.lastCol0 = 0; |
| return this; |
| }; |
| SourceMapGenerator.prototype.addMapping = function (col0, sourceUrl, sourceLine0, sourceCol0) { |
| if (!this.currentLine) { |
| throw new Error("A line must be added before mappings can be added"); |
| } |
| if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) { |
| throw new Error("Unknown source file \"" + sourceUrl + "\""); |
| } |
| if (col0 == null) { |
| throw new Error("The column in the generated code must be provided"); |
| } |
| if (col0 < this.lastCol0) { |
| throw new Error("Mapping should be added in output order"); |
| } |
| if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) { |
| throw new Error("The source location must be provided when a source url is provided"); |
| } |
| this.hasMappings = true; |
| this.lastCol0 = col0; |
| this.currentLine.push({ col0: col0, sourceUrl: sourceUrl, sourceLine0: sourceLine0, sourceCol0: sourceCol0 }); |
| return this; |
| }; |
| Object.defineProperty(SourceMapGenerator.prototype, "currentLine", { |
| /** |
| * @internal strip this from published d.ts files due to |
| * https://github.com/microsoft/TypeScript/issues/36216 |
| */ |
| get: function () { |
| return this.lines.slice(-1)[0]; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| SourceMapGenerator.prototype.toJSON = function () { |
| var _this = this; |
| if (!this.hasMappings) { |
| return null; |
| } |
| var sourcesIndex = new Map(); |
| var sources = []; |
| var sourcesContent = []; |
| Array.from(this.sourcesContent.keys()).forEach(function (url, i) { |
| sourcesIndex.set(url, i); |
| sources.push(url); |
| sourcesContent.push(_this.sourcesContent.get(url) || null); |
| }); |
| var mappings = ''; |
| var lastCol0 = 0; |
| var lastSourceIndex = 0; |
| var lastSourceLine0 = 0; |
| var lastSourceCol0 = 0; |
| this.lines.forEach(function (segments) { |
| lastCol0 = 0; |
| mappings += segments |
| .map(function (segment) { |
| // zero-based starting column of the line in the generated code |
| var segAsStr = toBase64VLQ(segment.col0 - lastCol0); |
| lastCol0 = segment.col0; |
| if (segment.sourceUrl != null) { |
| // zero-based index into the “sources” list |
| segAsStr += |
| toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex); |
| lastSourceIndex = sourcesIndex.get(segment.sourceUrl); |
| // the zero-based starting line in the original source |
| segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0); |
| lastSourceLine0 = segment.sourceLine0; |
| // the zero-based starting column in the original source |
| segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0); |
| lastSourceCol0 = segment.sourceCol0; |
| } |
| return segAsStr; |
| }) |
| .join(','); |
| mappings += ';'; |
| }); |
| mappings = mappings.slice(0, -1); |
| return { |
| 'file': this.file || '', |
| 'version': VERSION, |
| 'sourceRoot': '', |
| 'sources': sources, |
| 'sourcesContent': sourcesContent, |
| 'mappings': mappings, |
| }; |
| }; |
| SourceMapGenerator.prototype.toJsComment = function () { |
| return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) : |
| ''; |
| }; |
| return SourceMapGenerator; |
| }()); |
| function toBase64String(value) { |
| var b64 = ''; |
| var encoded = utf8Encode(value); |
| for (var i = 0; i < encoded.length;) { |
| var i1 = encoded[i++]; |
| var i2 = i < encoded.length ? encoded[i++] : null; |
| var i3 = i < encoded.length ? encoded[i++] : null; |
| b64 += toBase64Digit(i1 >> 2); |
| b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4)); |
| b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6)); |
| b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63); |
| } |
| return b64; |
| } |
| function toBase64VLQ(value) { |
| value = value < 0 ? ((-value) << 1) + 1 : value << 1; |
| var out = ''; |
| do { |
| var digit = value & 31; |
| value = value >> 5; |
| if (value > 0) { |
| digit = digit | 32; |
| } |
| out += toBase64Digit(digit); |
| } while (value > 0); |
| return out; |
| } |
| var B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; |
| function toBase64Digit(value) { |
| if (value < 0 || value >= 64) { |
| throw new Error("Can only encode value in the range [0, 63]"); |
| } |
| return B64_DIGITS[value]; |
| } |
| |
| var _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g; |
| var _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i; |
| var _INDENT_WITH = ' '; |
| var CATCH_ERROR_VAR$1 = variable('error', null, null); |
| var CATCH_STACK_VAR$1 = variable('stack', null, null); |
| var _EmittedLine = /** @class */ (function () { |
| function _EmittedLine(indent) { |
| this.indent = indent; |
| this.partsLength = 0; |
| this.parts = []; |
| this.srcSpans = []; |
| } |
| return _EmittedLine; |
| }()); |
| var EmitterVisitorContext = /** @class */ (function () { |
| function EmitterVisitorContext(_indent) { |
| this._indent = _indent; |
| this._classes = []; |
| this._preambleLineCount = 0; |
| this._lines = [new _EmittedLine(_indent)]; |
| } |
| EmitterVisitorContext.createRoot = function () { |
| return new EmitterVisitorContext(0); |
| }; |
| Object.defineProperty(EmitterVisitorContext.prototype, "_currentLine", { |
| /** |
| * @internal strip this from published d.ts files due to |
| * https://github.com/microsoft/TypeScript/issues/36216 |
| */ |
| get: function () { |
| return this._lines[this._lines.length - 1]; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| EmitterVisitorContext.prototype.println = function (from, lastPart) { |
| if (lastPart === void 0) { lastPart = ''; } |
| this.print(from || null, lastPart, true); |
| }; |
| EmitterVisitorContext.prototype.lineIsEmpty = function () { |
| return this._currentLine.parts.length === 0; |
| }; |
| EmitterVisitorContext.prototype.lineLength = function () { |
| return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength; |
| }; |
| EmitterVisitorContext.prototype.print = function (from, part, newLine) { |
| if (newLine === void 0) { newLine = false; } |
| if (part.length > 0) { |
| this._currentLine.parts.push(part); |
| this._currentLine.partsLength += part.length; |
| this._currentLine.srcSpans.push(from && from.sourceSpan || null); |
| } |
| if (newLine) { |
| this._lines.push(new _EmittedLine(this._indent)); |
| } |
| }; |
| EmitterVisitorContext.prototype.removeEmptyLastLine = function () { |
| if (this.lineIsEmpty()) { |
| this._lines.pop(); |
| } |
| }; |
| EmitterVisitorContext.prototype.incIndent = function () { |
| this._indent++; |
| if (this.lineIsEmpty()) { |
| this._currentLine.indent = this._indent; |
| } |
| }; |
| EmitterVisitorContext.prototype.decIndent = function () { |
| this._indent--; |
| if (this.lineIsEmpty()) { |
| this._currentLine.indent = this._indent; |
| } |
| }; |
| EmitterVisitorContext.prototype.pushClass = function (clazz) { |
| this._classes.push(clazz); |
| }; |
| EmitterVisitorContext.prototype.popClass = function () { |
| return this._classes.pop(); |
| }; |
| Object.defineProperty(EmitterVisitorContext.prototype, "currentClass", { |
| get: function () { |
| return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| EmitterVisitorContext.prototype.toSource = function () { |
| return this.sourceLines |
| .map(function (l) { return l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : ''; }) |
| .join('\n'); |
| }; |
| EmitterVisitorContext.prototype.toSourceMapGenerator = function (genFilePath, startsAtLine) { |
| if (startsAtLine === void 0) { startsAtLine = 0; } |
| var map = new SourceMapGenerator(genFilePath); |
| var firstOffsetMapped = false; |
| var mapFirstOffsetIfNeeded = function () { |
| if (!firstOffsetMapped) { |
| // Add a single space so that tools won't try to load the file from disk. |
| // Note: We are using virtual urls like `ng:///`, so we have to |
| // provide a content here. |
| map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0); |
| firstOffsetMapped = true; |
| } |
| }; |
| for (var i = 0; i < startsAtLine; i++) { |
| map.addLine(); |
| mapFirstOffsetIfNeeded(); |
| } |
| this.sourceLines.forEach(function (line, lineIdx) { |
| map.addLine(); |
| var spans = line.srcSpans; |
| var parts = line.parts; |
| var col0 = line.indent * _INDENT_WITH.length; |
| var spanIdx = 0; |
| // skip leading parts without source spans |
| while (spanIdx < spans.length && !spans[spanIdx]) { |
| col0 += parts[spanIdx].length; |
| spanIdx++; |
| } |
| if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) { |
| firstOffsetMapped = true; |
| } |
| else { |
| mapFirstOffsetIfNeeded(); |
| } |
| while (spanIdx < spans.length) { |
| var span = spans[spanIdx]; |
| var source = span.start.file; |
| var sourceLine = span.start.line; |
| var sourceCol = span.start.col; |
| map.addSource(source.url, source.content) |
| .addMapping(col0, source.url, sourceLine, sourceCol); |
| col0 += parts[spanIdx].length; |
| spanIdx++; |
| // assign parts without span or the same span to the previous segment |
| while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) { |
| col0 += parts[spanIdx].length; |
| spanIdx++; |
| } |
| } |
| }); |
| return map; |
| }; |
| EmitterVisitorContext.prototype.setPreambleLineCount = function (count) { |
| return this._preambleLineCount = count; |
| }; |
| EmitterVisitorContext.prototype.spanOf = function (line, column) { |
| var emittedLine = this._lines[line - this._preambleLineCount]; |
| if (emittedLine) { |
| var columnsLeft = column - _createIndent(emittedLine.indent).length; |
| for (var partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) { |
| var part = emittedLine.parts[partIndex]; |
| if (part.length > columnsLeft) { |
| return emittedLine.srcSpans[partIndex]; |
| } |
| columnsLeft -= part.length; |
| } |
| } |
| return null; |
| }; |
| Object.defineProperty(EmitterVisitorContext.prototype, "sourceLines", { |
| /** |
| * @internal strip this from published d.ts files due to |
| * https://github.com/microsoft/TypeScript/issues/36216 |
| */ |
| get: function () { |
| if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) { |
| return this._lines.slice(0, -1); |
| } |
| return this._lines; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| return EmitterVisitorContext; |
| }()); |
| var AbstractEmitterVisitor = /** @class */ (function () { |
| function AbstractEmitterVisitor(_escapeDollarInStrings) { |
| this._escapeDollarInStrings = _escapeDollarInStrings; |
| } |
| AbstractEmitterVisitor.prototype.printLeadingComments = function (stmt, ctx) { |
| var e_1, _a; |
| if (stmt.leadingComments === undefined) { |
| return; |
| } |
| try { |
| for (var _b = __values(stmt.leadingComments), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var comment = _c.value; |
| if (comment instanceof JSDocComment) { |
| ctx.print(stmt, "/*" + comment.toString() + "*/", comment.trailingNewline); |
| } |
| else { |
| if (comment.multiline) { |
| ctx.print(stmt, "/* " + comment.text + " */", comment.trailingNewline); |
| } |
| else { |
| comment.text.split('\n').forEach(function (line) { |
| ctx.println(stmt, "// " + line); |
| }); |
| } |
| } |
| } |
| } |
| 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; } |
| } |
| }; |
| AbstractEmitterVisitor.prototype.visitExpressionStmt = function (stmt, ctx) { |
| this.printLeadingComments(stmt, ctx); |
| stmt.expr.visitExpression(this, ctx); |
| ctx.println(stmt, ';'); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitReturnStmt = function (stmt, ctx) { |
| this.printLeadingComments(stmt, ctx); |
| ctx.print(stmt, "return "); |
| stmt.value.visitExpression(this, ctx); |
| ctx.println(stmt, ';'); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitIfStmt = function (stmt, ctx) { |
| this.printLeadingComments(stmt, ctx); |
| ctx.print(stmt, "if ("); |
| stmt.condition.visitExpression(this, ctx); |
| ctx.print(stmt, ") {"); |
| var hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0; |
| if (stmt.trueCase.length <= 1 && !hasElseCase) { |
| ctx.print(stmt, " "); |
| this.visitAllStatements(stmt.trueCase, ctx); |
| ctx.removeEmptyLastLine(); |
| ctx.print(stmt, " "); |
| } |
| else { |
| ctx.println(); |
| ctx.incIndent(); |
| this.visitAllStatements(stmt.trueCase, ctx); |
| ctx.decIndent(); |
| if (hasElseCase) { |
| ctx.println(stmt, "} else {"); |
| ctx.incIndent(); |
| this.visitAllStatements(stmt.falseCase, ctx); |
| ctx.decIndent(); |
| } |
| } |
| ctx.println(stmt, "}"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitThrowStmt = function (stmt, ctx) { |
| this.printLeadingComments(stmt, ctx); |
| ctx.print(stmt, "throw "); |
| stmt.error.visitExpression(this, ctx); |
| ctx.println(stmt, ";"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitWriteVarExpr = function (expr, ctx) { |
| var lineWasEmpty = ctx.lineIsEmpty(); |
| if (!lineWasEmpty) { |
| ctx.print(expr, '('); |
| } |
| ctx.print(expr, expr.name + " = "); |
| expr.value.visitExpression(this, ctx); |
| if (!lineWasEmpty) { |
| ctx.print(expr, ')'); |
| } |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitWriteKeyExpr = function (expr, ctx) { |
| var lineWasEmpty = ctx.lineIsEmpty(); |
| if (!lineWasEmpty) { |
| ctx.print(expr, '('); |
| } |
| expr.receiver.visitExpression(this, ctx); |
| ctx.print(expr, "["); |
| expr.index.visitExpression(this, ctx); |
| ctx.print(expr, "] = "); |
| expr.value.visitExpression(this, ctx); |
| if (!lineWasEmpty) { |
| ctx.print(expr, ')'); |
| } |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitWritePropExpr = function (expr, ctx) { |
| var lineWasEmpty = ctx.lineIsEmpty(); |
| if (!lineWasEmpty) { |
| ctx.print(expr, '('); |
| } |
| expr.receiver.visitExpression(this, ctx); |
| ctx.print(expr, "." + expr.name + " = "); |
| expr.value.visitExpression(this, ctx); |
| if (!lineWasEmpty) { |
| ctx.print(expr, ')'); |
| } |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitInvokeMethodExpr = function (expr, ctx) { |
| expr.receiver.visitExpression(this, ctx); |
| var name = expr.name; |
| if (expr.builtin != null) { |
| name = this.getBuiltinMethodName(expr.builtin); |
| if (name == null) { |
| // some builtins just mean to skip the call. |
| return null; |
| } |
| } |
| ctx.print(expr, "." + name + "("); |
| this.visitAllExpressions(expr.args, ctx, ","); |
| ctx.print(expr, ")"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitInvokeFunctionExpr = function (expr, ctx) { |
| expr.fn.visitExpression(this, ctx); |
| ctx.print(expr, "("); |
| this.visitAllExpressions(expr.args, ctx, ','); |
| ctx.print(expr, ")"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitTaggedTemplateExpr = function (expr, ctx) { |
| expr.tag.visitExpression(this, ctx); |
| ctx.print(expr, '`' + expr.template.elements[0].rawText); |
| for (var i = 1; i < expr.template.elements.length; i++) { |
| ctx.print(expr, '${'); |
| expr.template.expressions[i - 1].visitExpression(this, ctx); |
| ctx.print(expr, "}" + expr.template.elements[i].rawText); |
| } |
| ctx.print(expr, '`'); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitWrappedNodeExpr = function (ast, ctx) { |
| throw new Error('Abstract emitter cannot visit WrappedNodeExpr.'); |
| }; |
| AbstractEmitterVisitor.prototype.visitTypeofExpr = function (expr, ctx) { |
| ctx.print(expr, 'typeof '); |
| expr.expr.visitExpression(this, ctx); |
| }; |
| AbstractEmitterVisitor.prototype.visitReadVarExpr = function (ast, ctx) { |
| var varName = ast.name; |
| if (ast.builtin != null) { |
| switch (ast.builtin) { |
| case exports.BuiltinVar.Super: |
| varName = 'super'; |
| break; |
| case exports.BuiltinVar.This: |
| varName = 'this'; |
| break; |
| case exports.BuiltinVar.CatchError: |
| varName = CATCH_ERROR_VAR$1.name; |
| break; |
| case exports.BuiltinVar.CatchStack: |
| varName = CATCH_STACK_VAR$1.name; |
| break; |
| default: |
| throw new Error("Unknown builtin variable " + ast.builtin); |
| } |
| } |
| ctx.print(ast, varName); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitInstantiateExpr = function (ast, ctx) { |
| ctx.print(ast, "new "); |
| ast.classExpr.visitExpression(this, ctx); |
| ctx.print(ast, "("); |
| this.visitAllExpressions(ast.args, ctx, ','); |
| ctx.print(ast, ")"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitLiteralExpr = function (ast, ctx) { |
| var value = ast.value; |
| if (typeof value === 'string') { |
| ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings)); |
| } |
| else { |
| ctx.print(ast, "" + value); |
| } |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitLocalizedString = function (ast, ctx) { |
| var head = ast.serializeI18nHead(); |
| ctx.print(ast, '$localize `' + head.raw); |
| for (var i = 1; i < ast.messageParts.length; i++) { |
| ctx.print(ast, '${'); |
| ast.expressions[i - 1].visitExpression(this, ctx); |
| ctx.print(ast, "}" + ast.serializeI18nTemplatePart(i).raw); |
| } |
| ctx.print(ast, '`'); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitConditionalExpr = function (ast, ctx) { |
| ctx.print(ast, "("); |
| ast.condition.visitExpression(this, ctx); |
| ctx.print(ast, '? '); |
| ast.trueCase.visitExpression(this, ctx); |
| ctx.print(ast, ': '); |
| ast.falseCase.visitExpression(this, ctx); |
| ctx.print(ast, ")"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitNotExpr = function (ast, ctx) { |
| ctx.print(ast, '!'); |
| ast.condition.visitExpression(this, ctx); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitAssertNotNullExpr = function (ast, ctx) { |
| ast.condition.visitExpression(this, ctx); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitUnaryOperatorExpr = function (ast, ctx) { |
| var opStr; |
| switch (ast.operator) { |
| case exports.UnaryOperator.Plus: |
| opStr = '+'; |
| break; |
| case exports.UnaryOperator.Minus: |
| opStr = '-'; |
| break; |
| default: |
| throw new Error("Unknown operator " + ast.operator); |
| } |
| if (ast.parens) |
| ctx.print(ast, "("); |
| ctx.print(ast, opStr); |
| ast.expr.visitExpression(this, ctx); |
| if (ast.parens) |
| ctx.print(ast, ")"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitBinaryOperatorExpr = function (ast, ctx) { |
| var opStr; |
| switch (ast.operator) { |
| case exports.BinaryOperator.Equals: |
| opStr = '=='; |
| break; |
| case exports.BinaryOperator.Identical: |
| opStr = '==='; |
| break; |
| case exports.BinaryOperator.NotEquals: |
| opStr = '!='; |
| break; |
| case exports.BinaryOperator.NotIdentical: |
| opStr = '!=='; |
| break; |
| case exports.BinaryOperator.And: |
| opStr = '&&'; |
| break; |
| case exports.BinaryOperator.BitwiseAnd: |
| opStr = '&'; |
| break; |
| case exports.BinaryOperator.Or: |
| opStr = '||'; |
| break; |
| case exports.BinaryOperator.Plus: |
| opStr = '+'; |
| break; |
| case exports.BinaryOperator.Minus: |
| opStr = '-'; |
| break; |
| case exports.BinaryOperator.Divide: |
| opStr = '/'; |
| break; |
| case exports.BinaryOperator.Multiply: |
| opStr = '*'; |
| break; |
| case exports.BinaryOperator.Modulo: |
| opStr = '%'; |
| break; |
| case exports.BinaryOperator.Lower: |
| opStr = '<'; |
| break; |
| case exports.BinaryOperator.LowerEquals: |
| opStr = '<='; |
| break; |
| case exports.BinaryOperator.Bigger: |
| opStr = '>'; |
| break; |
| case exports.BinaryOperator.BiggerEquals: |
| opStr = '>='; |
| break; |
| default: |
| throw new Error("Unknown operator " + ast.operator); |
| } |
| if (ast.parens) |
| ctx.print(ast, "("); |
| ast.lhs.visitExpression(this, ctx); |
| ctx.print(ast, " " + opStr + " "); |
| ast.rhs.visitExpression(this, ctx); |
| if (ast.parens) |
| ctx.print(ast, ")"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitReadPropExpr = function (ast, ctx) { |
| ast.receiver.visitExpression(this, ctx); |
| ctx.print(ast, "."); |
| ctx.print(ast, ast.name); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitReadKeyExpr = function (ast, ctx) { |
| ast.receiver.visitExpression(this, ctx); |
| ctx.print(ast, "["); |
| ast.index.visitExpression(this, ctx); |
| ctx.print(ast, "]"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitLiteralArrayExpr = function (ast, ctx) { |
| ctx.print(ast, "["); |
| this.visitAllExpressions(ast.entries, ctx, ','); |
| ctx.print(ast, "]"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitLiteralMapExpr = function (ast, ctx) { |
| var _this = this; |
| ctx.print(ast, "{"); |
| this.visitAllObjects(function (entry) { |
| ctx.print(ast, escapeIdentifier(entry.key, _this._escapeDollarInStrings, entry.quoted) + ":"); |
| entry.value.visitExpression(_this, ctx); |
| }, ast.entries, ctx, ','); |
| ctx.print(ast, "}"); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitCommaExpr = function (ast, ctx) { |
| ctx.print(ast, '('); |
| this.visitAllExpressions(ast.parts, ctx, ','); |
| ctx.print(ast, ')'); |
| return null; |
| }; |
| AbstractEmitterVisitor.prototype.visitAllExpressions = function (expressions, ctx, separator) { |
| var _this = this; |
| this.visitAllObjects(function (expr) { return expr.visitExpression(_this, ctx); }, expressions, ctx, separator); |
| }; |
| AbstractEmitterVisitor.prototype.visitAllObjects = function (handler, expressions, ctx, separator) { |
| var incrementedIndent = false; |
| for (var i = 0; i < expressions.length; i++) { |
| if (i > 0) { |
| if (ctx.lineLength() > 80) { |
| ctx.print(null, separator, true); |
| if (!incrementedIndent) { |
| // continuation are marked with double indent. |
| ctx.incIndent(); |
| ctx.incIndent(); |
| incrementedIndent = true; |
| } |
| } |
| else { |
| ctx.print(null, separator, false); |
| } |
| } |
| handler(expressions[i]); |
| } |
| if (incrementedIndent) { |
| // continuation are marked with double indent. |
| ctx.decIndent(); |
| ctx.decIndent(); |
| } |
| }; |
| AbstractEmitterVisitor.prototype.visitAllStatements = function (statements, ctx) { |
| var _this = this; |
| statements.forEach(function (stmt) { return stmt.visitStatement(_this, ctx); }); |
| }; |
| return AbstractEmitterVisitor; |
| }()); |
| function escapeIdentifier(input, escapeDollar, alwaysQuote) { |
| if (alwaysQuote === void 0) { alwaysQuote = true; } |
| if (input == null) { |
| return null; |
| } |
| var body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, function () { |
| var match = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| match[_i] = arguments[_i]; |
| } |
| if (match[0] == '$') { |
| return escapeDollar ? '\\$' : '$'; |
| } |
| else if (match[0] == '\n') { |
| return '\\n'; |
| } |
| else if (match[0] == '\r') { |
| return '\\r'; |
| } |
| else { |
| return "\\" + match[0]; |
| } |
| }); |
| var requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body); |
| return requiresQuotes ? "'" + body + "'" : body; |
| } |
| function _createIndent(count) { |
| var res = ''; |
| for (var i = 0; i < count; i++) { |
| res += _INDENT_WITH; |
| } |
| return res; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Convert an object map with `Expression` values into a `LiteralMapExpr`. |
| */ |
| function mapToMapExpression(map) { |
| var result = Object.keys(map).map(function (key) { return ({ |
| key: key, |
| // The assertion here is because really TypeScript doesn't allow us to express that if the |
| // key is present, it will have a value, but this is true in reality. |
| value: map[key], |
| quoted: false, |
| }); }); |
| return literalMap(result); |
| } |
| /** |
| * Convert metadata into an `Expression` in the given `OutputContext`. |
| * |
| * This operation will handle arrays, references to symbols, or literal `null` or `undefined`. |
| */ |
| function convertMetaToOutput(meta, ctx) { |
| if (Array.isArray(meta)) { |
| return literalArr(meta.map(function (entry) { return convertMetaToOutput(entry, ctx); })); |
| } |
| if (meta instanceof StaticSymbol) { |
| return ctx.importExpr(meta); |
| } |
| if (meta == null) { |
| return literal(meta); |
| } |
| throw new Error("Internal error: Unsupported or unknown metadata: " + meta); |
| } |
| function typeWithParameters(type, numParams) { |
| if (numParams === 0) { |
| return expressionType(type); |
| } |
| var params = []; |
| for (var i = 0; i < numParams; i++) { |
| params.push(DYNAMIC_TYPE); |
| } |
| return expressionType(type, undefined, params); |
| } |
| var ANIMATE_SYMBOL_PREFIX = '@'; |
| function prepareSyntheticPropertyName(name) { |
| return "" + ANIMATE_SYMBOL_PREFIX + name; |
| } |
| function prepareSyntheticListenerName(name, phase) { |
| return "" + ANIMATE_SYMBOL_PREFIX + name + "." + phase; |
| } |
| function isSyntheticPropertyOrListener(name) { |
| return name.charAt(0) == ANIMATE_SYMBOL_PREFIX; |
| } |
| function getSyntheticPropertyName(name) { |
| // this will strip out listener phase values... |
| // @foo.start => @foo |
| var i = name.indexOf('.'); |
| name = i > 0 ? name.substring(0, i) : name; |
| if (name.charAt(0) !== ANIMATE_SYMBOL_PREFIX) { |
| name = ANIMATE_SYMBOL_PREFIX + name; |
| } |
| return name; |
| } |
| function getSafePropertyAccessString(accessor, name) { |
| var escapedName = escapeIdentifier(name, false, false); |
| return escapedName !== name ? accessor + "[" + escapedName + "]" : accessor + "." + name; |
| } |
| function prepareSyntheticListenerFunctionName(name, phase) { |
| return "animation_" + name + "_" + phase; |
| } |
| function jitOnlyGuardedExpression(expr) { |
| return guardedExpression('ngJitMode', expr); |
| } |
| function devOnlyGuardedExpression(expr) { |
| return guardedExpression('ngDevMode', expr); |
| } |
| function guardedExpression(guard, expr) { |
| var guardExpr = new ExternalExpr({ name: guard, moduleName: null }); |
| var guardNotDefined = new BinaryOperatorExpr(exports.BinaryOperator.Identical, new TypeofExpr(guardExpr), literal('undefined')); |
| var guardUndefinedOrTrue = new BinaryOperatorExpr(exports.BinaryOperator.Or, guardNotDefined, guardExpr, /* type */ undefined, |
| /* sourceSpan */ undefined, true); |
| return new BinaryOperatorExpr(exports.BinaryOperator.And, guardUndefinedOrTrue, expr); |
| } |
| function wrapReference(value) { |
| var wrapped = new WrappedNodeExpr(value); |
| return { value: wrapped, type: wrapped }; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently |
| * require the implementation of a visitor for Comments as they are only collected at |
| * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']` |
| * is true. |
| */ |
| var Comment = /** @class */ (function () { |
| function Comment(value, sourceSpan) { |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| } |
| Comment.prototype.visit = function (_visitor) { |
| throw new Error('visit() not implemented for Comment'); |
| }; |
| return Comment; |
| }()); |
| var Text = /** @class */ (function () { |
| function Text(value, sourceSpan) { |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| } |
| Text.prototype.visit = function (visitor) { |
| return visitor.visitText(this); |
| }; |
| return Text; |
| }()); |
| var BoundText = /** @class */ (function () { |
| function BoundText(value, sourceSpan, i18n) { |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| this.i18n = i18n; |
| } |
| BoundText.prototype.visit = function (visitor) { |
| return visitor.visitBoundText(this); |
| }; |
| return BoundText; |
| }()); |
| /** |
| * Represents a text attribute in the template. |
| * |
| * `valueSpan` may not be present in cases where there is no value `<div a></div>`. |
| * `keySpan` may also not be present for synthetic attributes from ICU expansions. |
| */ |
| var TextAttribute = /** @class */ (function () { |
| function TextAttribute(name, value, sourceSpan, keySpan, valueSpan, i18n) { |
| this.name = name; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| this.keySpan = keySpan; |
| this.valueSpan = valueSpan; |
| this.i18n = i18n; |
| } |
| TextAttribute.prototype.visit = function (visitor) { |
| return visitor.visitTextAttribute(this); |
| }; |
| return TextAttribute; |
| }()); |
| var BoundAttribute = /** @class */ (function () { |
| function BoundAttribute(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) { |
| this.name = name; |
| this.type = type; |
| this.securityContext = securityContext; |
| this.value = value; |
| this.unit = unit; |
| this.sourceSpan = sourceSpan; |
| this.keySpan = keySpan; |
| this.valueSpan = valueSpan; |
| this.i18n = i18n; |
| } |
| BoundAttribute.fromBoundElementProperty = function (prop, i18n) { |
| if (prop.keySpan === undefined) { |
| throw new Error("Unexpected state: keySpan must be defined for bound attributes but was not for " + prop.name + ": " + prop.sourceSpan); |
| } |
| return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n); |
| }; |
| BoundAttribute.prototype.visit = function (visitor) { |
| return visitor.visitBoundAttribute(this); |
| }; |
| return BoundAttribute; |
| }()); |
| var BoundEvent = /** @class */ (function () { |
| function BoundEvent(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) { |
| this.name = name; |
| this.type = type; |
| this.handler = handler; |
| this.target = target; |
| this.phase = phase; |
| this.sourceSpan = sourceSpan; |
| this.handlerSpan = handlerSpan; |
| this.keySpan = keySpan; |
| } |
| BoundEvent.fromParsedEvent = function (event) { |
| var target = event.type === 0 /* Regular */ ? event.targetOrPhase : null; |
| var phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null; |
| if (event.keySpan === undefined) { |
| throw new Error("Unexpected state: keySpan must be defined for bound event but was not for " + event.name + ": " + event.sourceSpan); |
| } |
| return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan); |
| }; |
| BoundEvent.prototype.visit = function (visitor) { |
| return visitor.visitBoundEvent(this); |
| }; |
| return BoundEvent; |
| }()); |
| var Element = /** @class */ (function () { |
| function Element(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) { |
| this.name = name; |
| this.attributes = attributes; |
| this.inputs = inputs; |
| this.outputs = outputs; |
| this.children = children; |
| this.references = references; |
| this.sourceSpan = sourceSpan; |
| this.startSourceSpan = startSourceSpan; |
| this.endSourceSpan = endSourceSpan; |
| this.i18n = i18n; |
| } |
| Element.prototype.visit = function (visitor) { |
| return visitor.visitElement(this); |
| }; |
| return Element; |
| }()); |
| var Template = /** @class */ (function () { |
| function Template(tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) { |
| this.tagName = tagName; |
| this.attributes = attributes; |
| this.inputs = inputs; |
| this.outputs = outputs; |
| this.templateAttrs = templateAttrs; |
| this.children = children; |
| this.references = references; |
| this.variables = variables; |
| this.sourceSpan = sourceSpan; |
| this.startSourceSpan = startSourceSpan; |
| this.endSourceSpan = endSourceSpan; |
| this.i18n = i18n; |
| } |
| Template.prototype.visit = function (visitor) { |
| return visitor.visitTemplate(this); |
| }; |
| return Template; |
| }()); |
| var Content = /** @class */ (function () { |
| function Content(selector, attributes, sourceSpan, i18n) { |
| this.selector = selector; |
| this.attributes = attributes; |
| this.sourceSpan = sourceSpan; |
| this.i18n = i18n; |
| this.name = 'ng-content'; |
| } |
| Content.prototype.visit = function (visitor) { |
| return visitor.visitContent(this); |
| }; |
| return Content; |
| }()); |
| var Variable = /** @class */ (function () { |
| function Variable(name, value, sourceSpan, keySpan, valueSpan) { |
| this.name = name; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| this.keySpan = keySpan; |
| this.valueSpan = valueSpan; |
| } |
| Variable.prototype.visit = function (visitor) { |
| return visitor.visitVariable(this); |
| }; |
| return Variable; |
| }()); |
| var Reference = /** @class */ (function () { |
| function Reference(name, value, sourceSpan, keySpan, valueSpan) { |
| this.name = name; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| this.keySpan = keySpan; |
| this.valueSpan = valueSpan; |
| } |
| Reference.prototype.visit = function (visitor) { |
| return visitor.visitReference(this); |
| }; |
| return Reference; |
| }()); |
| var Icu = /** @class */ (function () { |
| function Icu(vars, placeholders, sourceSpan, i18n) { |
| this.vars = vars; |
| this.placeholders = placeholders; |
| this.sourceSpan = sourceSpan; |
| this.i18n = i18n; |
| } |
| Icu.prototype.visit = function (visitor) { |
| return visitor.visitIcu(this); |
| }; |
| return Icu; |
| }()); |
| var NullVisitor = /** @class */ (function () { |
| function NullVisitor() { |
| } |
| NullVisitor.prototype.visitElement = function (element) { }; |
| NullVisitor.prototype.visitTemplate = function (template) { }; |
| NullVisitor.prototype.visitContent = function (content) { }; |
| NullVisitor.prototype.visitVariable = function (variable) { }; |
| NullVisitor.prototype.visitReference = function (reference) { }; |
| NullVisitor.prototype.visitTextAttribute = function (attribute) { }; |
| NullVisitor.prototype.visitBoundAttribute = function (attribute) { }; |
| NullVisitor.prototype.visitBoundEvent = function (attribute) { }; |
| NullVisitor.prototype.visitText = function (text) { }; |
| NullVisitor.prototype.visitBoundText = function (text) { }; |
| NullVisitor.prototype.visitIcu = function (icu) { }; |
| return NullVisitor; |
| }()); |
| var RecursiveVisitor = /** @class */ (function () { |
| function RecursiveVisitor() { |
| } |
| RecursiveVisitor.prototype.visitElement = function (element) { |
| visitAll(this, element.attributes); |
| visitAll(this, element.children); |
| visitAll(this, element.references); |
| }; |
| RecursiveVisitor.prototype.visitTemplate = function (template) { |
| visitAll(this, template.attributes); |
| visitAll(this, template.children); |
| visitAll(this, template.references); |
| visitAll(this, template.variables); |
| }; |
| RecursiveVisitor.prototype.visitContent = function (content) { }; |
| RecursiveVisitor.prototype.visitVariable = function (variable) { }; |
| RecursiveVisitor.prototype.visitReference = function (reference) { }; |
| RecursiveVisitor.prototype.visitTextAttribute = function (attribute) { }; |
| RecursiveVisitor.prototype.visitBoundAttribute = function (attribute) { }; |
| RecursiveVisitor.prototype.visitBoundEvent = function (attribute) { }; |
| RecursiveVisitor.prototype.visitText = function (text) { }; |
| RecursiveVisitor.prototype.visitBoundText = function (text) { }; |
| RecursiveVisitor.prototype.visitIcu = function (icu) { }; |
| return RecursiveVisitor; |
| }()); |
| var TransformVisitor = /** @class */ (function () { |
| function TransformVisitor() { |
| } |
| TransformVisitor.prototype.visitElement = function (element) { |
| var newAttributes = transformAll(this, element.attributes); |
| var newInputs = transformAll(this, element.inputs); |
| var newOutputs = transformAll(this, element.outputs); |
| var newChildren = transformAll(this, element.children); |
| var newReferences = transformAll(this, element.references); |
| if (newAttributes != element.attributes || newInputs != element.inputs || |
| newOutputs != element.outputs || newChildren != element.children || |
| newReferences != element.references) { |
| return new Element(element.name, newAttributes, newInputs, newOutputs, newChildren, newReferences, element.sourceSpan, element.startSourceSpan, element.endSourceSpan); |
| } |
| return element; |
| }; |
| TransformVisitor.prototype.visitTemplate = function (template) { |
| var newAttributes = transformAll(this, template.attributes); |
| var newInputs = transformAll(this, template.inputs); |
| var newOutputs = transformAll(this, template.outputs); |
| var newTemplateAttrs = transformAll(this, template.templateAttrs); |
| var newChildren = transformAll(this, template.children); |
| var newReferences = transformAll(this, template.references); |
| var newVariables = transformAll(this, template.variables); |
| if (newAttributes != template.attributes || newInputs != template.inputs || |
| newOutputs != template.outputs || newTemplateAttrs != template.templateAttrs || |
| newChildren != template.children || newReferences != template.references || |
| newVariables != template.variables) { |
| return new Template(template.tagName, newAttributes, newInputs, newOutputs, newTemplateAttrs, newChildren, newReferences, newVariables, template.sourceSpan, template.startSourceSpan, template.endSourceSpan); |
| } |
| return template; |
| }; |
| TransformVisitor.prototype.visitContent = function (content) { |
| return content; |
| }; |
| TransformVisitor.prototype.visitVariable = function (variable) { |
| return variable; |
| }; |
| TransformVisitor.prototype.visitReference = function (reference) { |
| return reference; |
| }; |
| TransformVisitor.prototype.visitTextAttribute = function (attribute) { |
| return attribute; |
| }; |
| TransformVisitor.prototype.visitBoundAttribute = function (attribute) { |
| return attribute; |
| }; |
| TransformVisitor.prototype.visitBoundEvent = function (attribute) { |
| return attribute; |
| }; |
| TransformVisitor.prototype.visitText = function (text) { |
| return text; |
| }; |
| TransformVisitor.prototype.visitBoundText = function (text) { |
| return text; |
| }; |
| TransformVisitor.prototype.visitIcu = function (icu) { |
| return icu; |
| }; |
| return TransformVisitor; |
| }()); |
| function visitAll(visitor, nodes) { |
| var e_1, _a, e_2, _b; |
| var result = []; |
| if (visitor.visit) { |
| try { |
| for (var nodes_1 = __values(nodes), nodes_1_1 = nodes_1.next(); !nodes_1_1.done; nodes_1_1 = nodes_1.next()) { |
| var node = nodes_1_1.value; |
| var newNode = visitor.visit(node) || node.visit(visitor); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (nodes_1_1 && !nodes_1_1.done && (_a = nodes_1.return)) _a.call(nodes_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| } |
| else { |
| try { |
| for (var nodes_2 = __values(nodes), nodes_2_1 = nodes_2.next(); !nodes_2_1.done; nodes_2_1 = nodes_2.next()) { |
| var node = nodes_2_1.value; |
| var newNode = node.visit(visitor); |
| if (newNode) { |
| result.push(newNode); |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (nodes_2_1 && !nodes_2_1.done && (_b = nodes_2.return)) _b.call(nodes_2); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| } |
| return result; |
| } |
| function transformAll(visitor, nodes) { |
| var e_3, _a; |
| var result = []; |
| var changed = false; |
| try { |
| for (var nodes_3 = __values(nodes), nodes_3_1 = nodes_3.next(); !nodes_3_1.done; nodes_3_1 = nodes_3.next()) { |
| var node = nodes_3_1.value; |
| var newNode = node.visit(visitor); |
| if (newNode) { |
| result.push(newNode); |
| } |
| changed = changed || newNode != node; |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (nodes_3_1 && !nodes_3_1.done && (_a = nodes_3.return)) _a.call(nodes_3); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| return changed ? result : nodes; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var Message = /** @class */ (function () { |
| /** |
| * @param nodes message AST |
| * @param placeholders maps placeholder names to static content and their source spans |
| * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages) |
| * @param meaning |
| * @param description |
| * @param customId |
| */ |
| function Message(nodes, placeholders, placeholderToMessage, meaning, description, customId) { |
| this.nodes = nodes; |
| this.placeholders = placeholders; |
| this.placeholderToMessage = placeholderToMessage; |
| this.meaning = meaning; |
| this.description = description; |
| this.customId = customId; |
| this.id = this.customId; |
| /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */ |
| this.legacyIds = []; |
| if (nodes.length) { |
| this.sources = [{ |
| filePath: nodes[0].sourceSpan.start.file.url, |
| startLine: nodes[0].sourceSpan.start.line + 1, |
| startCol: nodes[0].sourceSpan.start.col + 1, |
| endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1, |
| endCol: nodes[0].sourceSpan.start.col + 1 |
| }]; |
| } |
| else { |
| this.sources = []; |
| } |
| } |
| return Message; |
| }()); |
| var Text$1 = /** @class */ (function () { |
| function Text(value, sourceSpan) { |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| } |
| Text.prototype.visit = function (visitor, context) { |
| return visitor.visitText(this, context); |
| }; |
| return Text; |
| }()); |
| // TODO(vicb): do we really need this node (vs an array) ? |
| var Container = /** @class */ (function () { |
| function Container(children, sourceSpan) { |
| this.children = children; |
| this.sourceSpan = sourceSpan; |
| } |
| Container.prototype.visit = function (visitor, context) { |
| return visitor.visitContainer(this, context); |
| }; |
| return Container; |
| }()); |
| var Icu$1 = /** @class */ (function () { |
| function Icu(expression, type, cases, sourceSpan) { |
| this.expression = expression; |
| this.type = type; |
| this.cases = cases; |
| this.sourceSpan = sourceSpan; |
| } |
| Icu.prototype.visit = function (visitor, context) { |
| return visitor.visitIcu(this, context); |
| }; |
| return Icu; |
| }()); |
| var TagPlaceholder = /** @class */ (function () { |
| function TagPlaceholder(tag, attrs, startName, closeName, children, isVoid, |
| // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan) |
| sourceSpan, startSourceSpan, endSourceSpan) { |
| this.tag = tag; |
| this.attrs = attrs; |
| this.startName = startName; |
| this.closeName = closeName; |
| this.children = children; |
| this.isVoid = isVoid; |
| this.sourceSpan = sourceSpan; |
| this.startSourceSpan = startSourceSpan; |
| this.endSourceSpan = endSourceSpan; |
| } |
| TagPlaceholder.prototype.visit = function (visitor, context) { |
| return visitor.visitTagPlaceholder(this, context); |
| }; |
| return TagPlaceholder; |
| }()); |
| var Placeholder = /** @class */ (function () { |
| function Placeholder(value, name, sourceSpan) { |
| this.value = value; |
| this.name = name; |
| this.sourceSpan = sourceSpan; |
| } |
| Placeholder.prototype.visit = function (visitor, context) { |
| return visitor.visitPlaceholder(this, context); |
| }; |
| return Placeholder; |
| }()); |
| var IcuPlaceholder = /** @class */ (function () { |
| function IcuPlaceholder(value, name, sourceSpan) { |
| this.value = value; |
| this.name = name; |
| this.sourceSpan = sourceSpan; |
| } |
| IcuPlaceholder.prototype.visit = function (visitor, context) { |
| return visitor.visitIcuPlaceholder(this, context); |
| }; |
| return IcuPlaceholder; |
| }()); |
| // Clone the AST |
| var CloneVisitor = /** @class */ (function () { |
| function CloneVisitor() { |
| } |
| CloneVisitor.prototype.visitText = function (text, context) { |
| return new Text$1(text.value, text.sourceSpan); |
| }; |
| CloneVisitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| var children = container.children.map(function (n) { return n.visit(_this, context); }); |
| return new Container(children, container.sourceSpan); |
| }; |
| CloneVisitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| var cases = {}; |
| Object.keys(icu.cases).forEach(function (key) { return cases[key] = icu.cases[key].visit(_this, context); }); |
| var msg = new Icu$1(icu.expression, icu.type, cases, icu.sourceSpan); |
| msg.expressionPlaceholder = icu.expressionPlaceholder; |
| return msg; |
| }; |
| CloneVisitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var _this = this; |
| var children = ph.children.map(function (n) { return n.visit(_this, context); }); |
| return new TagPlaceholder(ph.tag, ph.attrs, ph.startName, ph.closeName, children, ph.isVoid, ph.sourceSpan, ph.startSourceSpan, ph.endSourceSpan); |
| }; |
| CloneVisitor.prototype.visitPlaceholder = function (ph, context) { |
| return new Placeholder(ph.value, ph.name, ph.sourceSpan); |
| }; |
| CloneVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| return new IcuPlaceholder(ph.value, ph.name, ph.sourceSpan); |
| }; |
| return CloneVisitor; |
| }()); |
| // Visit all the nodes recursively |
| var RecurseVisitor = /** @class */ (function () { |
| function RecurseVisitor() { |
| } |
| RecurseVisitor.prototype.visitText = function (text, context) { }; |
| RecurseVisitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| container.children.forEach(function (child) { return child.visit(_this); }); |
| }; |
| RecurseVisitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| Object.keys(icu.cases).forEach(function (k) { |
| icu.cases[k].visit(_this); |
| }); |
| }; |
| RecurseVisitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var _this = this; |
| ph.children.forEach(function (child) { return child.visit(_this); }); |
| }; |
| RecurseVisitor.prototype.visitPlaceholder = function (ph, context) { }; |
| RecurseVisitor.prototype.visitIcuPlaceholder = function (ph, context) { }; |
| return RecurseVisitor; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Represents a big integer using a buffer of its individual digits, with the least significant |
| * digit stored at the beginning of the array (little endian). |
| * |
| * For performance reasons, each instance is mutable. The addition operation can be done in-place |
| * to reduce memory pressure of allocation for the digits array. |
| */ |
| var BigInteger = /** @class */ (function () { |
| /** |
| * Creates a big integer using its individual digits in little endian storage. |
| */ |
| function BigInteger(digits) { |
| this.digits = digits; |
| } |
| BigInteger.zero = function () { |
| return new BigInteger([0]); |
| }; |
| BigInteger.one = function () { |
| return new BigInteger([1]); |
| }; |
| /** |
| * Creates a clone of this instance. |
| */ |
| BigInteger.prototype.clone = function () { |
| return new BigInteger(this.digits.slice()); |
| }; |
| /** |
| * Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate |
| * `this` but instead returns a new instance, unlike `addToSelf`. |
| */ |
| BigInteger.prototype.add = function (other) { |
| var result = this.clone(); |
| result.addToSelf(other); |
| return result; |
| }; |
| /** |
| * Adds `other` to the instance itself, thereby mutating its value. |
| */ |
| BigInteger.prototype.addToSelf = function (other) { |
| var maxNrOfDigits = Math.max(this.digits.length, other.digits.length); |
| var carry = 0; |
| for (var i = 0; i < maxNrOfDigits; i++) { |
| var digitSum = carry; |
| if (i < this.digits.length) { |
| digitSum += this.digits[i]; |
| } |
| if (i < other.digits.length) { |
| digitSum += other.digits[i]; |
| } |
| if (digitSum >= 10) { |
| this.digits[i] = digitSum - 10; |
| carry = 1; |
| } |
| else { |
| this.digits[i] = digitSum; |
| carry = 0; |
| } |
| } |
| // Apply a remaining carry if needed. |
| if (carry > 0) { |
| this.digits[maxNrOfDigits] = 1; |
| } |
| }; |
| /** |
| * Builds the decimal string representation of the big integer. As this is stored in |
| * little endian, the digits are concatenated in reverse order. |
| */ |
| BigInteger.prototype.toString = function () { |
| var res = ''; |
| for (var i = this.digits.length - 1; i >= 0; i--) { |
| res += this.digits[i]; |
| } |
| return res; |
| }; |
| return BigInteger; |
| }()); |
| /** |
| * Represents a big integer which is optimized for multiplication operations, as its power-of-twos |
| * are memoized. See `multiplyBy()` for details on the multiplication algorithm. |
| */ |
| var BigIntForMultiplication = /** @class */ (function () { |
| function BigIntForMultiplication(value) { |
| this.powerOfTwos = [value]; |
| } |
| /** |
| * Returns the big integer itself. |
| */ |
| BigIntForMultiplication.prototype.getValue = function () { |
| return this.powerOfTwos[0]; |
| }; |
| /** |
| * Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The |
| * value for `b` is represented by a storage model that is optimized for this computation. |
| * |
| * This operation is implemented in N(log2(num)) by continuous halving of the number, where the |
| * least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is |
| * used as exponent into the power-of-two multiplication of `b`. |
| * |
| * As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the |
| * algorithm unrolls into the following iterations: |
| * |
| * Iteration | num | LSB | b * 2^iter | Add? | product |
| * -----------|------------|------|------------|------|-------- |
| * 0 | 0b00101010 | 0 | 1337 | No | 0 |
| * 1 | 0b00010101 | 1 | 2674 | Yes | 2674 |
| * 2 | 0b00001010 | 0 | 5348 | No | 2674 |
| * 3 | 0b00000101 | 1 | 10696 | Yes | 13370 |
| * 4 | 0b00000010 | 0 | 21392 | No | 13370 |
| * 5 | 0b00000001 | 1 | 42784 | Yes | 56154 |
| * 6 | 0b00000000 | 0 | 85568 | No | 56154 |
| * |
| * The computed product of 56154 is indeed the correct result. |
| * |
| * The `BigIntForMultiplication` representation for a big integer provides memoized access to the |
| * power-of-two values to reduce the workload in computing those values. |
| */ |
| BigIntForMultiplication.prototype.multiplyBy = function (num) { |
| var product = BigInteger.zero(); |
| this.multiplyByAndAddTo(num, product); |
| return product; |
| }; |
| /** |
| * See `multiplyBy()` for details. This function allows for the computed product to be added |
| * directly to the provided result big integer. |
| */ |
| BigIntForMultiplication.prototype.multiplyByAndAddTo = function (num, result) { |
| for (var exponent = 0; num !== 0; num = num >>> 1, exponent++) { |
| if (num & 1) { |
| var value = this.getMultipliedByPowerOfTwo(exponent); |
| result.addToSelf(value); |
| } |
| } |
| }; |
| /** |
| * Computes and memoizes the big integer value for `this.number * 2^exponent`. |
| */ |
| BigIntForMultiplication.prototype.getMultipliedByPowerOfTwo = function (exponent) { |
| // Compute the powers up until the requested exponent, where each value is computed from its |
| // predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e. |
| // added to itself) to reach `this.number * 2^exponent`. |
| for (var i = this.powerOfTwos.length; i <= exponent; i++) { |
| var previousPower = this.powerOfTwos[i - 1]; |
| this.powerOfTwos[i] = previousPower.add(previousPower); |
| } |
| return this.powerOfTwos[exponent]; |
| }; |
| return BigIntForMultiplication; |
| }()); |
| /** |
| * Represents an exponentiation operation for the provided base, of which exponents are computed and |
| * memoized. The results are represented by a `BigIntForMultiplication` which is tailored for |
| * multiplication operations by memoizing the power-of-twos. This effectively results in a matrix |
| * representation that is lazily computed upon request. |
| */ |
| var BigIntExponentiation = /** @class */ (function () { |
| function BigIntExponentiation(base) { |
| this.base = base; |
| this.exponents = [new BigIntForMultiplication(BigInteger.one())]; |
| } |
| /** |
| * Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for |
| * further multiplication operations. |
| */ |
| BigIntExponentiation.prototype.toThePowerOf = function (exponent) { |
| // Compute the results up until the requested exponent, where every value is computed from its |
| // predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base` |
| // to reach `this.base^exponent`. |
| for (var i = this.exponents.length; i <= exponent; i++) { |
| var value = this.exponents[i - 1].multiplyBy(this.base); |
| this.exponents[i] = new BigIntForMultiplication(value); |
| } |
| return this.exponents[exponent]; |
| }; |
| return BigIntExponentiation; |
| }()); |
| |
| /** |
| * Return the message id or compute it using the XLIFF1 digest. |
| */ |
| function digest(message) { |
| return message.id || computeDigest(message); |
| } |
| /** |
| * Compute the message id using the XLIFF1 digest. |
| */ |
| function computeDigest(message) { |
| return sha1(serializeNodes(message.nodes).join('') + ("[" + message.meaning + "]")); |
| } |
| /** |
| * Return the message id or compute it using the XLIFF2/XMB/$localize digest. |
| */ |
| function decimalDigest(message) { |
| return message.id || computeDecimalDigest(message); |
| } |
| /** |
| * Compute the message id using the XLIFF2/XMB/$localize digest. |
| */ |
| function computeDecimalDigest(message) { |
| var visitor = new _SerializerIgnoreIcuExpVisitor(); |
| var parts = message.nodes.map(function (a) { return a.visit(visitor, null); }); |
| return computeMsgId(parts.join(''), message.meaning); |
| } |
| /** |
| * Serialize the i18n ast to something xml-like in order to generate an UID. |
| * |
| * The visitor is also used in the i18n parser tests |
| * |
| * @internal |
| */ |
| var _SerializerVisitor = /** @class */ (function () { |
| function _SerializerVisitor() { |
| } |
| _SerializerVisitor.prototype.visitText = function (text, context) { |
| return text.value; |
| }; |
| _SerializerVisitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| return "[" + container.children.map(function (child) { return child.visit(_this); }).join(', ') + "]"; |
| }; |
| _SerializerVisitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| var strCases = Object.keys(icu.cases).map(function (k) { return k + " {" + icu.cases[k].visit(_this) + "}"; }); |
| return "{" + icu.expression + ", " + icu.type + ", " + strCases.join(', ') + "}"; |
| }; |
| _SerializerVisitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var _this = this; |
| return ph.isVoid ? |
| "<ph tag name=\"" + ph.startName + "\"/>" : |
| "<ph tag name=\"" + ph.startName + "\">" + ph.children.map(function (child) { return child.visit(_this); }).join(', ') + "</ph name=\"" + ph.closeName + "\">"; |
| }; |
| _SerializerVisitor.prototype.visitPlaceholder = function (ph, context) { |
| return ph.value ? "<ph name=\"" + ph.name + "\">" + ph.value + "</ph>" : "<ph name=\"" + ph.name + "\"/>"; |
| }; |
| _SerializerVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| return "<ph icu name=\"" + ph.name + "\">" + ph.value.visit(this) + "</ph>"; |
| }; |
| return _SerializerVisitor; |
| }()); |
| var serializerVisitor = new _SerializerVisitor(); |
| function serializeNodes(nodes) { |
| return nodes.map(function (a) { return a.visit(serializerVisitor, null); }); |
| } |
| /** |
| * Serialize the i18n ast to something xml-like in order to generate an UID. |
| * |
| * Ignore the ICU expressions so that message IDs stays identical if only the expression changes. |
| * |
| * @internal |
| */ |
| var _SerializerIgnoreIcuExpVisitor = /** @class */ (function (_super) { |
| __extends(_SerializerIgnoreIcuExpVisitor, _super); |
| function _SerializerIgnoreIcuExpVisitor() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| _SerializerIgnoreIcuExpVisitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| var strCases = Object.keys(icu.cases).map(function (k) { return k + " {" + icu.cases[k].visit(_this) + "}"; }); |
| // Do not take the expression into account |
| return "{" + icu.type + ", " + strCases.join(', ') + "}"; |
| }; |
| return _SerializerIgnoreIcuExpVisitor; |
| }(_SerializerVisitor)); |
| /** |
| * Compute the SHA1 of the given string |
| * |
| * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf |
| * |
| * WARNING: this function has not been designed not tested with security in mind. |
| * DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT. |
| */ |
| function sha1(str) { |
| var utf8 = utf8Encode(str); |
| var words32 = bytesToWords32(utf8, Endian.Big); |
| var len = utf8.length * 8; |
| var w = newArray(80); |
| var a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, e = 0xc3d2e1f0; |
| words32[len >> 5] |= 0x80 << (24 - len % 32); |
| words32[((len + 64 >> 9) << 4) + 15] = len; |
| for (var i = 0; i < words32.length; i += 16) { |
| var h0 = a, h1 = b, h2 = c, h3 = d, h4 = e; |
| for (var j = 0; j < 80; j++) { |
| if (j < 16) { |
| w[j] = words32[i + j]; |
| } |
| else { |
| w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); |
| } |
| var fkVal = fk(j, b, c, d); |
| var f = fkVal[0]; |
| var k = fkVal[1]; |
| var temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32); |
| e = d; |
| d = c; |
| c = rol32(b, 30); |
| b = a; |
| a = temp; |
| } |
| a = add32(a, h0); |
| b = add32(b, h1); |
| c = add32(c, h2); |
| d = add32(d, h3); |
| e = add32(e, h4); |
| } |
| return bytesToHexString(words32ToByteString([a, b, c, d, e])); |
| } |
| function fk(index, b, c, d) { |
| if (index < 20) { |
| return [(b & c) | (~b & d), 0x5a827999]; |
| } |
| if (index < 40) { |
| return [b ^ c ^ d, 0x6ed9eba1]; |
| } |
| if (index < 60) { |
| return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc]; |
| } |
| return [b ^ c ^ d, 0xca62c1d6]; |
| } |
| /** |
| * Compute the fingerprint of the given string |
| * |
| * The output is 64 bit number encoded as a decimal string |
| * |
| * based on: |
| * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java |
| */ |
| function fingerprint(str) { |
| var utf8 = utf8Encode(str); |
| var hi = hash32(utf8, 0); |
| var lo = hash32(utf8, 102072); |
| if (hi == 0 && (lo == 0 || lo == 1)) { |
| hi = hi ^ 0x130f9bef; |
| lo = lo ^ -0x6b5f56d8; |
| } |
| return [hi, lo]; |
| } |
| function computeMsgId(msg, meaning) { |
| if (meaning === void 0) { meaning = ''; } |
| var msgFingerprint = fingerprint(msg); |
| if (meaning) { |
| var meaningFingerprint = fingerprint(meaning); |
| msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint); |
| } |
| var hi = msgFingerprint[0]; |
| var lo = msgFingerprint[1]; |
| return wordsToDecimalString(hi & 0x7fffffff, lo); |
| } |
| function hash32(bytes, c) { |
| var a = 0x9e3779b9, b = 0x9e3779b9; |
| var i; |
| var len = bytes.length; |
| for (i = 0; i + 12 <= len; i += 12) { |
| a = add32(a, wordAt(bytes, i, Endian.Little)); |
| b = add32(b, wordAt(bytes, i + 4, Endian.Little)); |
| c = add32(c, wordAt(bytes, i + 8, Endian.Little)); |
| var res = mix(a, b, c); |
| a = res[0], b = res[1], c = res[2]; |
| } |
| a = add32(a, wordAt(bytes, i, Endian.Little)); |
| b = add32(b, wordAt(bytes, i + 4, Endian.Little)); |
| // the first byte of c is reserved for the length |
| c = add32(c, len); |
| c = add32(c, wordAt(bytes, i + 8, Endian.Little) << 8); |
| return mix(a, b, c)[2]; |
| } |
| // clang-format off |
| function mix(a, b, c) { |
| a = sub32(a, b); |
| a = sub32(a, c); |
| a ^= c >>> 13; |
| b = sub32(b, c); |
| b = sub32(b, a); |
| b ^= a << 8; |
| c = sub32(c, a); |
| c = sub32(c, b); |
| c ^= b >>> 13; |
| a = sub32(a, b); |
| a = sub32(a, c); |
| a ^= c >>> 12; |
| b = sub32(b, c); |
| b = sub32(b, a); |
| b ^= a << 16; |
| c = sub32(c, a); |
| c = sub32(c, b); |
| c ^= b >>> 5; |
| a = sub32(a, b); |
| a = sub32(a, c); |
| a ^= c >>> 3; |
| b = sub32(b, c); |
| b = sub32(b, a); |
| b ^= a << 10; |
| c = sub32(c, a); |
| c = sub32(c, b); |
| c ^= b >>> 15; |
| return [a, b, c]; |
| } |
| // clang-format on |
| // Utils |
| var Endian; |
| (function (Endian) { |
| Endian[Endian["Little"] = 0] = "Little"; |
| Endian[Endian["Big"] = 1] = "Big"; |
| })(Endian || (Endian = {})); |
| function add32(a, b) { |
| return add32to64(a, b)[1]; |
| } |
| function add32to64(a, b) { |
| var low = (a & 0xffff) + (b & 0xffff); |
| var high = (a >>> 16) + (b >>> 16) + (low >>> 16); |
| return [high >>> 16, (high << 16) | (low & 0xffff)]; |
| } |
| function add64(a, b) { |
| var ah = a[0], al = a[1]; |
| var bh = b[0], bl = b[1]; |
| var result = add32to64(al, bl); |
| var carry = result[0]; |
| var l = result[1]; |
| var h = add32(add32(ah, bh), carry); |
| return [h, l]; |
| } |
| function sub32(a, b) { |
| var low = (a & 0xffff) - (b & 0xffff); |
| var high = (a >> 16) - (b >> 16) + (low >> 16); |
| return (high << 16) | (low & 0xffff); |
| } |
| // Rotate a 32b number left `count` position |
| function rol32(a, count) { |
| return (a << count) | (a >>> (32 - count)); |
| } |
| // Rotate a 64b number left `count` position |
| function rol64(num, count) { |
| var hi = num[0], lo = num[1]; |
| var h = (hi << count) | (lo >>> (32 - count)); |
| var l = (lo << count) | (hi >>> (32 - count)); |
| return [h, l]; |
| } |
| function bytesToWords32(bytes, endian) { |
| var size = (bytes.length + 3) >>> 2; |
| var words32 = []; |
| for (var i = 0; i < size; i++) { |
| words32[i] = wordAt(bytes, i * 4, endian); |
| } |
| return words32; |
| } |
| function byteAt(bytes, index) { |
| return index >= bytes.length ? 0 : bytes[index]; |
| } |
| function wordAt(bytes, index, endian) { |
| var word = 0; |
| if (endian === Endian.Big) { |
| for (var i = 0; i < 4; i++) { |
| word += byteAt(bytes, index + i) << (24 - 8 * i); |
| } |
| } |
| else { |
| for (var i = 0; i < 4; i++) { |
| word += byteAt(bytes, index + i) << 8 * i; |
| } |
| } |
| return word; |
| } |
| function words32ToByteString(words32) { |
| return words32.reduce(function (bytes, word) { return bytes.concat(word32ToByteString(word)); }, []); |
| } |
| function word32ToByteString(word) { |
| var bytes = []; |
| for (var i = 0; i < 4; i++) { |
| bytes.push((word >>> 8 * (3 - i)) & 0xff); |
| } |
| return bytes; |
| } |
| function bytesToHexString(bytes) { |
| var hex = ''; |
| for (var i = 0; i < bytes.length; i++) { |
| var b = byteAt(bytes, i); |
| hex += (b >>> 4).toString(16) + (b & 0x0f).toString(16); |
| } |
| return hex.toLowerCase(); |
| } |
| /** |
| * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized |
| * power-of-256 results with memoized power-of-two computations for efficient multiplication. |
| * |
| * For our purposes, this can be safely stored as a global without memory concerns. The reason is |
| * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word) |
| * exponent. |
| */ |
| var base256 = new BigIntExponentiation(256); |
| /** |
| * Represents two 32-bit words as a single decimal number. This requires a big integer storage |
| * model as JS numbers are not accurate enough to represent the 64-bit number. |
| * |
| * Based on https://www.danvk.org/hex2dec.html |
| */ |
| function wordsToDecimalString(hi, lo) { |
| // Encode the four bytes in lo in the lower digits of the decimal number. |
| // Note: the multiplication results in lo itself but represented by a big integer using its |
| // decimal digits. |
| var decimal = base256.toThePowerOf(0).multiplyBy(lo); |
| // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why |
| // this multiplication factor is applied. |
| base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal); |
| return decimal.toString(); |
| } |
| |
| var Serializer = /** @class */ (function () { |
| function Serializer() { |
| } |
| // Creates a name mapper, see `PlaceholderMapper` |
| // Returning `null` means that no name mapping is used. |
| Serializer.prototype.createNameMapper = function (message) { |
| return null; |
| }; |
| return Serializer; |
| }()); |
| /** |
| * A simple mapper that take a function to transform an internal name to a public name |
| */ |
| var SimplePlaceholderMapper = /** @class */ (function (_super) { |
| __extends(SimplePlaceholderMapper, _super); |
| // create a mapping from the message |
| function SimplePlaceholderMapper(message, mapName) { |
| var _this = _super.call(this) || this; |
| _this.mapName = mapName; |
| _this.internalToPublic = {}; |
| _this.publicToNextId = {}; |
| _this.publicToInternal = {}; |
| message.nodes.forEach(function (node) { return node.visit(_this); }); |
| return _this; |
| } |
| SimplePlaceholderMapper.prototype.toPublicName = function (internalName) { |
| return this.internalToPublic.hasOwnProperty(internalName) ? |
| this.internalToPublic[internalName] : |
| null; |
| }; |
| SimplePlaceholderMapper.prototype.toInternalName = function (publicName) { |
| return this.publicToInternal.hasOwnProperty(publicName) ? this.publicToInternal[publicName] : |
| null; |
| }; |
| SimplePlaceholderMapper.prototype.visitText = function (text, context) { |
| return null; |
| }; |
| SimplePlaceholderMapper.prototype.visitTagPlaceholder = function (ph, context) { |
| this.visitPlaceholderName(ph.startName); |
| _super.prototype.visitTagPlaceholder.call(this, ph, context); |
| this.visitPlaceholderName(ph.closeName); |
| }; |
| SimplePlaceholderMapper.prototype.visitPlaceholder = function (ph, context) { |
| this.visitPlaceholderName(ph.name); |
| }; |
| SimplePlaceholderMapper.prototype.visitIcuPlaceholder = function (ph, context) { |
| this.visitPlaceholderName(ph.name); |
| }; |
| // XMB placeholders could only contains A-Z, 0-9 and _ |
| SimplePlaceholderMapper.prototype.visitPlaceholderName = function (internalName) { |
| if (!internalName || this.internalToPublic.hasOwnProperty(internalName)) { |
| return; |
| } |
| var publicName = this.mapName(internalName); |
| if (this.publicToInternal.hasOwnProperty(publicName)) { |
| // Create a new XMB when it has already been used |
| var nextId = this.publicToNextId[publicName]; |
| this.publicToNextId[publicName] = nextId + 1; |
| publicName = publicName + "_" + nextId; |
| } |
| else { |
| this.publicToNextId[publicName] = 1; |
| } |
| this.internalToPublic[internalName] = publicName; |
| this.publicToInternal[publicName] = internalName; |
| }; |
| return SimplePlaceholderMapper; |
| }(RecurseVisitor)); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var _Visitor = /** @class */ (function () { |
| function _Visitor() { |
| } |
| _Visitor.prototype.visitTag = function (tag) { |
| var _this = this; |
| var strAttrs = this._serializeAttributes(tag.attrs); |
| if (tag.children.length == 0) { |
| return "<" + tag.name + strAttrs + "/>"; |
| } |
| var strChildren = tag.children.map(function (node) { return node.visit(_this); }); |
| return "<" + tag.name + strAttrs + ">" + strChildren.join('') + "</" + tag.name + ">"; |
| }; |
| _Visitor.prototype.visitText = function (text) { |
| return text.value; |
| }; |
| _Visitor.prototype.visitDeclaration = function (decl) { |
| return "<?xml" + this._serializeAttributes(decl.attrs) + " ?>"; |
| }; |
| _Visitor.prototype._serializeAttributes = function (attrs) { |
| var strAttrs = Object.keys(attrs).map(function (name) { return name + "=\"" + attrs[name] + "\""; }).join(' '); |
| return strAttrs.length > 0 ? ' ' + strAttrs : ''; |
| }; |
| _Visitor.prototype.visitDoctype = function (doctype) { |
| return "<!DOCTYPE " + doctype.rootTag + " [\n" + doctype.dtd + "\n]>"; |
| }; |
| return _Visitor; |
| }()); |
| var _visitor = new _Visitor(); |
| function serialize(nodes) { |
| return nodes.map(function (node) { return node.visit(_visitor); }).join(''); |
| } |
| var Declaration = /** @class */ (function () { |
| function Declaration(unescapedAttrs) { |
| var _this = this; |
| this.attrs = {}; |
| Object.keys(unescapedAttrs).forEach(function (k) { |
| _this.attrs[k] = escapeXml(unescapedAttrs[k]); |
| }); |
| } |
| Declaration.prototype.visit = function (visitor) { |
| return visitor.visitDeclaration(this); |
| }; |
| return Declaration; |
| }()); |
| var Doctype = /** @class */ (function () { |
| function Doctype(rootTag, dtd) { |
| this.rootTag = rootTag; |
| this.dtd = dtd; |
| } |
| Doctype.prototype.visit = function (visitor) { |
| return visitor.visitDoctype(this); |
| }; |
| return Doctype; |
| }()); |
| var Tag = /** @class */ (function () { |
| function Tag(name, unescapedAttrs, children) { |
| var _this = this; |
| if (unescapedAttrs === void 0) { unescapedAttrs = {}; } |
| if (children === void 0) { children = []; } |
| this.name = name; |
| this.children = children; |
| this.attrs = {}; |
| Object.keys(unescapedAttrs).forEach(function (k) { |
| _this.attrs[k] = escapeXml(unescapedAttrs[k]); |
| }); |
| } |
| Tag.prototype.visit = function (visitor) { |
| return visitor.visitTag(this); |
| }; |
| return Tag; |
| }()); |
| var Text$2 = /** @class */ (function () { |
| function Text(unescapedValue) { |
| this.value = escapeXml(unescapedValue); |
| } |
| Text.prototype.visit = function (visitor) { |
| return visitor.visitText(this); |
| }; |
| return Text; |
| }()); |
| var CR = /** @class */ (function (_super) { |
| __extends(CR, _super); |
| function CR(ws) { |
| if (ws === void 0) { ws = 0; } |
| return _super.call(this, "\n" + new Array(ws + 1).join(' ')) || this; |
| } |
| return CR; |
| }(Text$2)); |
| var _ESCAPED_CHARS = [ |
| [/&/g, '&'], |
| [/"/g, '"'], |
| [/'/g, '''], |
| [/</g, '<'], |
| [/>/g, '>'], |
| ]; |
| // Escape `_ESCAPED_CHARS` characters in the given text with encoded entities |
| function escapeXml(text) { |
| return _ESCAPED_CHARS.reduce(function (text, entry) { return text.replace(entry[0], entry[1]); }, text); |
| } |
| |
| var _MESSAGES_TAG = 'messagebundle'; |
| var _MESSAGE_TAG = 'msg'; |
| var _PLACEHOLDER_TAG = 'ph'; |
| var _EXAMPLE_TAG = 'ex'; |
| var _SOURCE_TAG = 'source'; |
| var _DOCTYPE = "<!ELEMENT messagebundle (msg)*>\n<!ATTLIST messagebundle class CDATA #IMPLIED>\n\n<!ELEMENT msg (#PCDATA|ph|source)*>\n<!ATTLIST msg id CDATA #IMPLIED>\n<!ATTLIST msg seq CDATA #IMPLIED>\n<!ATTLIST msg name CDATA #IMPLIED>\n<!ATTLIST msg desc CDATA #IMPLIED>\n<!ATTLIST msg meaning CDATA #IMPLIED>\n<!ATTLIST msg obsolete (obsolete) #IMPLIED>\n<!ATTLIST msg xml:space (default|preserve) \"default\">\n<!ATTLIST msg is_hidden CDATA #IMPLIED>\n\n<!ELEMENT source (#PCDATA)>\n\n<!ELEMENT ph (#PCDATA|ex)*>\n<!ATTLIST ph name CDATA #REQUIRED>\n\n<!ELEMENT ex (#PCDATA)>"; |
| var Xmb = /** @class */ (function (_super) { |
| __extends(Xmb, _super); |
| function Xmb() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| Xmb.prototype.write = function (messages, locale) { |
| var exampleVisitor = new ExampleVisitor(); |
| var visitor = new _Visitor$1(); |
| var rootNode = new Tag(_MESSAGES_TAG); |
| messages.forEach(function (message) { |
| var attrs = { id: message.id }; |
| if (message.description) { |
| attrs['desc'] = message.description; |
| } |
| if (message.meaning) { |
| attrs['meaning'] = message.meaning; |
| } |
| var sourceTags = []; |
| message.sources.forEach(function (source) { |
| sourceTags.push(new Tag(_SOURCE_TAG, {}, [new Text$2(source.filePath + ":" + source.startLine + (source.endLine !== source.startLine ? ',' + source.endLine : ''))])); |
| }); |
| rootNode.children.push(new CR(2), new Tag(_MESSAGE_TAG, attrs, __spread(sourceTags, visitor.serialize(message.nodes)))); |
| }); |
| rootNode.children.push(new CR()); |
| return serialize([ |
| new Declaration({ version: '1.0', encoding: 'UTF-8' }), |
| new CR(), |
| new Doctype(_MESSAGES_TAG, _DOCTYPE), |
| new CR(), |
| exampleVisitor.addDefaultExamples(rootNode), |
| new CR(), |
| ]); |
| }; |
| Xmb.prototype.load = function (content, url) { |
| throw new Error('Unsupported'); |
| }; |
| Xmb.prototype.digest = function (message) { |
| return digest$1(message); |
| }; |
| Xmb.prototype.createNameMapper = function (message) { |
| return new SimplePlaceholderMapper(message, toPublicName); |
| }; |
| return Xmb; |
| }(Serializer)); |
| var _Visitor$1 = /** @class */ (function () { |
| function _Visitor() { |
| } |
| _Visitor.prototype.visitText = function (text, context) { |
| return [new Text$2(text.value)]; |
| }; |
| _Visitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| var nodes = []; |
| container.children.forEach(function (node) { return nodes.push.apply(nodes, __spread(node.visit(_this))); }); |
| return nodes; |
| }; |
| _Visitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| var nodes = [new Text$2("{" + icu.expressionPlaceholder + ", " + icu.type + ", ")]; |
| Object.keys(icu.cases).forEach(function (c) { |
| nodes.push.apply(nodes, __spread([new Text$2(c + " {")], icu.cases[c].visit(_this), [new Text$2("} ")])); |
| }); |
| nodes.push(new Text$2("}")); |
| return nodes; |
| }; |
| _Visitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var startTagAsText = new Text$2("<" + ph.tag + ">"); |
| var startEx = new Tag(_EXAMPLE_TAG, {}, [startTagAsText]); |
| // TC requires PH to have a non empty EX, and uses the text node to show the "original" value. |
| var startTagPh = new Tag(_PLACEHOLDER_TAG, { name: ph.startName }, [startEx, startTagAsText]); |
| if (ph.isVoid) { |
| // void tags have no children nor closing tags |
| return [startTagPh]; |
| } |
| var closeTagAsText = new Text$2("</" + ph.tag + ">"); |
| var closeEx = new Tag(_EXAMPLE_TAG, {}, [closeTagAsText]); |
| // TC requires PH to have a non empty EX, and uses the text node to show the "original" value. |
| var closeTagPh = new Tag(_PLACEHOLDER_TAG, { name: ph.closeName }, [closeEx, closeTagAsText]); |
| return __spread([startTagPh], this.serialize(ph.children), [closeTagPh]); |
| }; |
| _Visitor.prototype.visitPlaceholder = function (ph, context) { |
| var interpolationAsText = new Text$2("{{" + ph.value + "}}"); |
| // Example tag needs to be not-empty for TC. |
| var exTag = new Tag(_EXAMPLE_TAG, {}, [interpolationAsText]); |
| return [ |
| // TC requires PH to have a non empty EX, and uses the text node to show the "original" value. |
| new Tag(_PLACEHOLDER_TAG, { name: ph.name }, [exTag, interpolationAsText]) |
| ]; |
| }; |
| _Visitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| var icuExpression = ph.value.expression; |
| var icuType = ph.value.type; |
| var icuCases = Object.keys(ph.value.cases).map(function (value) { return value + ' {...}'; }).join(' '); |
| var icuAsText = new Text$2("{" + icuExpression + ", " + icuType + ", " + icuCases + "}"); |
| var exTag = new Tag(_EXAMPLE_TAG, {}, [icuAsText]); |
| return [ |
| // TC requires PH to have a non empty EX, and uses the text node to show the "original" value. |
| new Tag(_PLACEHOLDER_TAG, { name: ph.name }, [exTag, icuAsText]) |
| ]; |
| }; |
| _Visitor.prototype.serialize = function (nodes) { |
| var _this = this; |
| return [].concat.apply([], __spread(nodes.map(function (node) { return node.visit(_this); }))); |
| }; |
| return _Visitor; |
| }()); |
| function digest$1(message) { |
| return decimalDigest(message); |
| } |
| // TC requires at least one non-empty example on placeholders |
| var ExampleVisitor = /** @class */ (function () { |
| function ExampleVisitor() { |
| } |
| ExampleVisitor.prototype.addDefaultExamples = function (node) { |
| node.visit(this); |
| return node; |
| }; |
| ExampleVisitor.prototype.visitTag = function (tag) { |
| var _this = this; |
| if (tag.name === _PLACEHOLDER_TAG) { |
| if (!tag.children || tag.children.length == 0) { |
| var exText = new Text$2(tag.attrs['name'] || '...'); |
| tag.children = [new Tag(_EXAMPLE_TAG, {}, [exText])]; |
| } |
| } |
| else if (tag.children) { |
| tag.children.forEach(function (node) { return node.visit(_this); }); |
| } |
| }; |
| ExampleVisitor.prototype.visitText = function (text) { }; |
| ExampleVisitor.prototype.visitDeclaration = function (decl) { }; |
| ExampleVisitor.prototype.visitDoctype = function (doctype) { }; |
| return ExampleVisitor; |
| }()); |
| // XMB/XTB placeholders can only contain A-Z, 0-9 and _ |
| function toPublicName(internalName) { |
| return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_'); |
| } |
| |
| /* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */ |
| var CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_'; |
| /** |
| * Prefix for non-`goog.getMsg` i18n-related vars. |
| * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that |
| * considers variables like `I18N_0` as constants and throws an error when their value changes. |
| */ |
| var TRANSLATION_VAR_PREFIX = 'i18n_'; |
| /** Name of the i18n attributes **/ |
| var I18N_ATTR = 'i18n'; |
| var I18N_ATTR_PREFIX = 'i18n-'; |
| /** Prefix of var expressions used in ICUs */ |
| var I18N_ICU_VAR_PREFIX = 'VAR_'; |
| /** Prefix of ICU expressions for post processing */ |
| var I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_'; |
| /** Placeholder wrapper for i18n expressions **/ |
| var I18N_PLACEHOLDER_SYMBOL = '�'; |
| function isI18nAttribute(name) { |
| return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX); |
| } |
| function isI18nRootNode(meta) { |
| return meta instanceof Message; |
| } |
| function isSingleI18nIcu(meta) { |
| return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu$1; |
| } |
| function hasI18nMeta(node) { |
| return !!node.i18n; |
| } |
| function hasI18nAttrs(element) { |
| return element.attrs.some(function (attr) { return isI18nAttribute(attr.name); }); |
| } |
| function icuFromI18nMessage(message) { |
| return message.nodes[0]; |
| } |
| function wrapI18nPlaceholder(content, contextId) { |
| if (contextId === void 0) { contextId = 0; } |
| var blockId = contextId > 0 ? ":" + contextId : ''; |
| return "" + I18N_PLACEHOLDER_SYMBOL + content + blockId + I18N_PLACEHOLDER_SYMBOL; |
| } |
| function assembleI18nBoundString(strings, bindingStartIndex, contextId) { |
| if (bindingStartIndex === void 0) { bindingStartIndex = 0; } |
| if (contextId === void 0) { contextId = 0; } |
| if (!strings.length) |
| return ''; |
| var acc = ''; |
| var lastIdx = strings.length - 1; |
| for (var i = 0; i < lastIdx; i++) { |
| acc += "" + strings[i] + wrapI18nPlaceholder(bindingStartIndex + i, contextId); |
| } |
| acc += strings[lastIdx]; |
| return acc; |
| } |
| function getSeqNumberGenerator(startsAt) { |
| if (startsAt === void 0) { startsAt = 0; } |
| var current = startsAt; |
| return function () { return current++; }; |
| } |
| function placeholdersToParams(placeholders) { |
| var params = {}; |
| placeholders.forEach(function (values, key) { |
| params[key] = literal(values.length > 1 ? "[" + values.join('|') + "]" : values[0]); |
| }); |
| return params; |
| } |
| function updatePlaceholderMap(map, name) { |
| var values = []; |
| for (var _i = 2; _i < arguments.length; _i++) { |
| values[_i - 2] = arguments[_i]; |
| } |
| var current = map.get(name) || []; |
| current.push.apply(current, __spread(values)); |
| map.set(name, current); |
| } |
| function assembleBoundTextPlaceholders(meta, bindingStartIndex, contextId) { |
| if (bindingStartIndex === void 0) { bindingStartIndex = 0; } |
| if (contextId === void 0) { contextId = 0; } |
| var startIdx = bindingStartIndex; |
| var placeholders = new Map(); |
| var node = meta instanceof Message ? meta.nodes.find(function (node) { return node instanceof Container; }) : meta; |
| if (node) { |
| node |
| .children |
| .filter(function (child) { return child instanceof Placeholder; }) |
| .forEach(function (child, idx) { |
| var content = wrapI18nPlaceholder(startIdx + idx, contextId); |
| updatePlaceholderMap(placeholders, child.name, content); |
| }); |
| } |
| return placeholders; |
| } |
| /** |
| * Format the placeholder names in a map of placeholders to expressions. |
| * |
| * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external" |
| * format (e.g. `startTagDiv_1`). |
| * |
| * @param params A map of placeholder names to expressions. |
| * @param useCamelCase whether to camelCase the placeholder name when formatting. |
| * @returns A new map of formatted placeholder names to expressions. |
| */ |
| function i18nFormatPlaceholderNames(params, useCamelCase) { |
| if (params === void 0) { params = {}; } |
| var _params = {}; |
| if (params && Object.keys(params).length) { |
| Object.keys(params).forEach(function (key) { return _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]; }); |
| } |
| return _params; |
| } |
| /** |
| * Converts internal placeholder names to public-facing format |
| * (for example to use in goog.getMsg call). |
| * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`. |
| * |
| * @param name The placeholder name that should be formatted |
| * @returns Formatted placeholder name |
| */ |
| function formatI18nPlaceholderName(name, useCamelCase) { |
| if (useCamelCase === void 0) { useCamelCase = true; } |
| var publicName = toPublicName(name); |
| if (!useCamelCase) { |
| return publicName; |
| } |
| var chunks = publicName.split('_'); |
| if (chunks.length === 1) { |
| // if no "_" found - just lowercase the value |
| return name.toLowerCase(); |
| } |
| var postfix; |
| // eject last element if it's a number |
| if (/^\d+$/.test(chunks[chunks.length - 1])) { |
| postfix = chunks.pop(); |
| } |
| var raw = chunks.shift().toLowerCase(); |
| if (chunks.length) { |
| raw += chunks.map(function (c) { return c.charAt(0).toUpperCase() + c.slice(1).toLowerCase(); }).join(''); |
| } |
| return postfix ? raw + "_" + postfix : raw; |
| } |
| /** |
| * Generates a prefix for translation const name. |
| * |
| * @param extra Additional local prefix that should be injected into translation var name |
| * @returns Complete translation const prefix |
| */ |
| function getTranslationConstPrefix(extra) { |
| return ("" + CLOSURE_TRANSLATION_VAR_PREFIX + extra).toUpperCase(); |
| } |
| /** |
| * Generate AST to declare a variable. E.g. `var I18N_1;`. |
| * @param variable the name of the variable to declare. |
| */ |
| function declareI18nVariable(variable) { |
| return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan); |
| } |
| |
| /** |
| * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in |
| * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may |
| * bot work in some cases when object keys are mangled by minifier. |
| * |
| * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with |
| * inputs that contain potentially unsafe chars. |
| */ |
| var UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/; |
| /** Name of the temporary to use during data binding */ |
| var TEMPORARY_NAME = '_t'; |
| /** Name of the context parameter passed into a template function */ |
| var CONTEXT_NAME = 'ctx'; |
| /** Name of the RenderFlag passed into a template function */ |
| var RENDER_FLAGS = 'rf'; |
| /** The prefix reference variables */ |
| var REFERENCE_PREFIX = '_r'; |
| /** The name of the implicit context reference */ |
| var IMPLICIT_REFERENCE = '$implicit'; |
| /** Non bindable attribute name **/ |
| var NON_BINDABLE_ATTR = 'ngNonBindable'; |
| /** |
| * Creates an allocator for a temporary variable. |
| * |
| * A variable declaration is added to the statements the first time the allocator is invoked. |
| */ |
| function temporaryAllocator(statements, name) { |
| var temp = null; |
| return function () { |
| if (!temp) { |
| statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE)); |
| temp = variable(name); |
| } |
| return temp; |
| }; |
| } |
| function unsupported(feature) { |
| if (this) { |
| throw new Error("Builder " + this.constructor.name + " doesn't support " + feature + " yet"); |
| } |
| throw new Error("Feature " + feature + " is not supported yet"); |
| } |
| function invalid$1(arg) { |
| throw new Error("Invalid state: Visitor " + this.constructor.name + " doesn't handle " + arg.constructor.name); |
| } |
| function asLiteral(value) { |
| if (Array.isArray(value)) { |
| return literalArr(value.map(asLiteral)); |
| } |
| return literal(value, INFERRED_TYPE); |
| } |
| function conditionallyCreateMapObjectLiteral(keys, keepDeclared) { |
| if (Object.getOwnPropertyNames(keys).length > 0) { |
| return mapToExpression(keys, keepDeclared); |
| } |
| return null; |
| } |
| function mapToExpression(map, keepDeclared) { |
| return literalMap(Object.getOwnPropertyNames(map).map(function (key) { |
| var _a, _b; |
| // canonical syntax: `dirProp: publicProp` |
| // if there is no `:`, use dirProp = elProp |
| var value = map[key]; |
| var declaredName; |
| var publicName; |
| var minifiedName; |
| var needsDeclaredName; |
| if (Array.isArray(value)) { |
| _a = __read(value, 2), publicName = _a[0], declaredName = _a[1]; |
| minifiedName = key; |
| needsDeclaredName = publicName !== declaredName; |
| } |
| else { |
| _b = __read(splitAtColon(key, [key, value]), 2), declaredName = _b[0], publicName = _b[1]; |
| minifiedName = declaredName; |
| // Only include the declared name if extracted from the key, i.e. the key contains a colon. |
| // Otherwise the declared name should be omitted even if it is different from the public name, |
| // as it may have already been minified. |
| needsDeclaredName = publicName !== declaredName && key.includes(':'); |
| } |
| return { |
| key: minifiedName, |
| // put quotes around keys that contain potentially unsafe characters |
| quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName), |
| value: (keepDeclared && needsDeclaredName) ? |
| literalArr([asLiteral(publicName), asLiteral(declaredName)]) : |
| asLiteral(publicName) |
| }; |
| })); |
| } |
| /** |
| * Remove trailing null nodes as they are implied. |
| */ |
| function trimTrailingNulls(parameters) { |
| while (isNull(parameters[parameters.length - 1])) { |
| parameters.pop(); |
| } |
| return parameters; |
| } |
| function getQueryPredicate(query, constantPool) { |
| if (Array.isArray(query.predicate)) { |
| var predicate_1 = []; |
| query.predicate.forEach(function (selector) { |
| // Each item in predicates array may contain strings with comma-separated refs |
| // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them |
| // as separate array entities |
| var selectors = selector.split(',').map(function (token) { return literal(token.trim()); }); |
| predicate_1.push.apply(predicate_1, __spread(selectors)); |
| }); |
| return constantPool.getConstLiteral(literalArr(predicate_1), true); |
| } |
| else { |
| return query.predicate; |
| } |
| } |
| /** |
| * A representation for an object literal used during codegen of definition objects. The generic |
| * type `T` allows to reference a documented type of the generated structure, such that the |
| * property names that are set can be resolved to their documented declaration. |
| */ |
| var DefinitionMap = /** @class */ (function () { |
| function DefinitionMap() { |
| this.values = []; |
| } |
| DefinitionMap.prototype.set = function (key, value) { |
| if (value) { |
| this.values.push({ key: key, value: value, quoted: false }); |
| } |
| }; |
| DefinitionMap.prototype.toLiteralMap = function () { |
| return literalMap(this.values); |
| }; |
| return DefinitionMap; |
| }()); |
| /** |
| * Extract a map of properties to values for a given element or template node, which can be used |
| * by the directive matching machinery. |
| * |
| * @param elOrTpl the element or template in question |
| * @return an object set up for directive matching. For attributes on the element/template, this |
| * object maps a property name to its (static) value. For any bindings, this map simply maps the |
| * property name to an empty string. |
| */ |
| function getAttrsForDirectiveMatching(elOrTpl) { |
| var attributesMap = {}; |
| if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') { |
| elOrTpl.templateAttrs.forEach(function (a) { return attributesMap[a.name] = ''; }); |
| } |
| else { |
| elOrTpl.attributes.forEach(function (a) { |
| if (!isI18nAttribute(a.name)) { |
| attributesMap[a.name] = a.value; |
| } |
| }); |
| elOrTpl.inputs.forEach(function (i) { |
| attributesMap[i.name] = ''; |
| }); |
| elOrTpl.outputs.forEach(function (o) { |
| attributesMap[o.name] = ''; |
| }); |
| } |
| return attributesMap; |
| } |
| /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */ |
| function chainedInstruction(reference, calls, span) { |
| var expression = importExpr(reference, null, span); |
| if (calls.length > 0) { |
| for (var i = 0; i < calls.length; i++) { |
| expression = expression.callFn(calls[i], span); |
| } |
| } |
| else { |
| // Add a blank invocation, in case the `calls` array is empty. |
| expression = expression.callFn([], span); |
| } |
| return expression; |
| } |
| /** |
| * Gets the number of arguments expected to be passed to a generated instruction in the case of |
| * interpolation instructions. |
| * @param interpolation An interpolation ast |
| */ |
| function getInterpolationArgsLength(interpolation) { |
| var expressions = interpolation.expressions, strings = interpolation.strings; |
| if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') { |
| // If the interpolation has one interpolated value, but the prefix and suffix are both empty |
| // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or |
| // `textInterpolate`. |
| return 1; |
| } |
| else { |
| return expressions.length + strings.length; |
| } |
| } |
| |
| var R3FactoryDelegateType; |
| (function (R3FactoryDelegateType) { |
| R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class"; |
| R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function"; |
| })(R3FactoryDelegateType || (R3FactoryDelegateType = {})); |
| (function (R3FactoryTarget) { |
| R3FactoryTarget[R3FactoryTarget["Directive"] = 0] = "Directive"; |
| R3FactoryTarget[R3FactoryTarget["Component"] = 1] = "Component"; |
| R3FactoryTarget[R3FactoryTarget["Injectable"] = 2] = "Injectable"; |
| R3FactoryTarget[R3FactoryTarget["Pipe"] = 3] = "Pipe"; |
| R3FactoryTarget[R3FactoryTarget["NgModule"] = 4] = "NgModule"; |
| })(exports.R3FactoryTarget || (exports.R3FactoryTarget = {})); |
| (function (R3ResolvedDependencyType) { |
| /** |
| * A normal token dependency. |
| */ |
| R3ResolvedDependencyType[R3ResolvedDependencyType["Token"] = 0] = "Token"; |
| /** |
| * The dependency is for an attribute. |
| * |
| * The token expression is a string representing the attribute name. |
| */ |
| R3ResolvedDependencyType[R3ResolvedDependencyType["Attribute"] = 1] = "Attribute"; |
| /** |
| * Injecting the `ChangeDetectorRef` token. Needs special handling when injected into a pipe. |
| */ |
| R3ResolvedDependencyType[R3ResolvedDependencyType["ChangeDetectorRef"] = 2] = "ChangeDetectorRef"; |
| /** |
| * An invalid dependency (no token could be determined). An error should be thrown at runtime. |
| */ |
| R3ResolvedDependencyType[R3ResolvedDependencyType["Invalid"] = 3] = "Invalid"; |
| })(exports.R3ResolvedDependencyType || (exports.R3ResolvedDependencyType = {})); |
| /** |
| * Construct a factory function expression for the given `R3FactoryMetadata`. |
| */ |
| function compileFactoryFunction(meta) { |
| var t = variable('t'); |
| var statements = []; |
| var ctorDepsType = NONE_TYPE; |
| // The type to instantiate via constructor invocation. If there is no delegated factory, meaning |
| // this type is always created by constructor invocation, then this is the type-to-create |
| // parameter provided by the user (t) if specified, or the current type if not. If there is a |
| // delegated factory (which is used to create the current type) then this is only the type-to- |
| // create parameter (t). |
| var typeForCtor = !isDelegatedMetadata(meta) ? |
| new BinaryOperatorExpr(exports.BinaryOperator.Or, t, meta.internalType) : |
| t; |
| var ctorExpr = null; |
| if (meta.deps !== null) { |
| // There is a constructor (either explicitly or implicitly defined). |
| if (meta.deps !== 'invalid') { |
| ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.injectFn, meta.target === exports.R3FactoryTarget.Pipe)); |
| ctorDepsType = createCtorDepsType(meta.deps); |
| } |
| } |
| else { |
| var baseFactory = variable("\u0275" + meta.name + "_BaseFactory"); |
| var getInheritedFactory = importExpr(Identifiers$1.getInheritedFactory); |
| var baseFactoryStmt = baseFactory |
| .set(getInheritedFactory.callFn([meta.internalType], /* sourceSpan */ undefined, /* pure */ true)) |
| .toDeclStmt(INFERRED_TYPE, [exports.StmtModifier.Exported, exports.StmtModifier.Final]); |
| statements.push(baseFactoryStmt); |
| // There is no constructor, use the base class' factory to construct typeForCtor. |
| ctorExpr = baseFactory.callFn([typeForCtor]); |
| } |
| var ctorExprFinal = ctorExpr; |
| var body = []; |
| var retExpr = null; |
| function makeConditionalFactory(nonCtorExpr) { |
| var r = variable('r'); |
| body.push(r.set(NULL_EXPR).toDeclStmt()); |
| var ctorStmt = null; |
| if (ctorExprFinal !== null) { |
| ctorStmt = r.set(ctorExprFinal).toStmt(); |
| } |
| else { |
| ctorStmt = importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt(); |
| } |
| body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()])); |
| return r; |
| } |
| if (isDelegatedMetadata(meta)) { |
| // This type is created with a delegated factory. If a type parameter is not specified, call |
| // the factory instead. |
| var delegateArgs = injectDependencies(meta.delegateDeps, meta.injectFn, meta.target === exports.R3FactoryTarget.Pipe); |
| // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType. |
| var factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ? |
| InstantiateExpr : |
| InvokeFunctionExpr)(meta.delegate, delegateArgs); |
| retExpr = makeConditionalFactory(factoryExpr); |
| } |
| else if (isExpressionFactoryMetadata(meta)) { |
| // TODO(alxhub): decide whether to lower the value here or in the caller |
| retExpr = makeConditionalFactory(meta.expression); |
| } |
| else { |
| retExpr = ctorExpr; |
| } |
| if (retExpr !== null) { |
| body.push(new ReturnStatement(retExpr)); |
| } |
| else { |
| body.push(importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt()); |
| } |
| return { |
| factory: fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, meta.name + "_Factory"), |
| statements: statements, |
| type: expressionType(importExpr(Identifiers$1.FactoryDef, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType])) |
| }; |
| } |
| function injectDependencies(deps, injectFn, isPipe) { |
| return deps.map(function (dep, index) { return compileInjectDependency(dep, injectFn, isPipe, index); }); |
| } |
| function compileInjectDependency(dep, injectFn, isPipe, index) { |
| // Interpret the dependency according to its resolved type. |
| switch (dep.resolved) { |
| case exports.R3ResolvedDependencyType.Token: |
| case exports.R3ResolvedDependencyType.ChangeDetectorRef: |
| // Build up the injection flags according to the metadata. |
| var flags = 0 /* Default */ | (dep.self ? 2 /* Self */ : 0) | |
| (dep.skipSelf ? 4 /* SkipSelf */ : 0) | (dep.host ? 1 /* Host */ : 0) | |
| (dep.optional ? 8 /* Optional */ : 0); |
| // If this dependency is optional or otherwise has non-default flags, then additional |
| // parameters describing how to inject the dependency must be passed to the inject function |
| // that's being used. |
| var flagsParam = (flags !== 0 /* Default */ || dep.optional) ? literal(flags) : null; |
| // We have a separate instruction for injecting ChangeDetectorRef into a pipe. |
| if (isPipe && dep.resolved === exports.R3ResolvedDependencyType.ChangeDetectorRef) { |
| return importExpr(Identifiers$1.injectPipeChangeDetectorRef).callFn(flagsParam ? [flagsParam] : []); |
| } |
| // Build up the arguments to the injectFn call. |
| var injectArgs = [dep.token]; |
| if (flagsParam) { |
| injectArgs.push(flagsParam); |
| } |
| return importExpr(injectFn).callFn(injectArgs); |
| case exports.R3ResolvedDependencyType.Attribute: |
| // In the case of attributes, the attribute name in question is given as the token. |
| return importExpr(Identifiers$1.injectAttribute).callFn([dep.token]); |
| case exports.R3ResolvedDependencyType.Invalid: |
| return importExpr(Identifiers$1.invalidFactoryDep).callFn([literal(index)]); |
| default: |
| return unsupported("Unknown R3ResolvedDependencyType: " + exports.R3ResolvedDependencyType[dep.resolved]); |
| } |
| } |
| function createCtorDepsType(deps) { |
| var hasTypes = false; |
| var attributeTypes = deps.map(function (dep) { |
| var type = createCtorDepType(dep); |
| if (type !== null) { |
| hasTypes = true; |
| return type; |
| } |
| else { |
| return literal(null); |
| } |
| }); |
| if (hasTypes) { |
| return expressionType(literalArr(attributeTypes)); |
| } |
| else { |
| return NONE_TYPE; |
| } |
| } |
| function createCtorDepType(dep) { |
| var entries = []; |
| if (dep.resolved === exports.R3ResolvedDependencyType.Attribute) { |
| if (dep.attribute !== null) { |
| entries.push({ key: 'attribute', value: dep.attribute, quoted: false }); |
| } |
| } |
| if (dep.optional) { |
| entries.push({ key: 'optional', value: literal(true), quoted: false }); |
| } |
| if (dep.host) { |
| entries.push({ key: 'host', value: literal(true), quoted: false }); |
| } |
| if (dep.self) { |
| entries.push({ key: 'self', value: literal(true), quoted: false }); |
| } |
| if (dep.skipSelf) { |
| entries.push({ key: 'skipSelf', value: literal(true), quoted: false }); |
| } |
| return entries.length > 0 ? literalMap(entries) : null; |
| } |
| /** |
| * A helper function useful for extracting `R3DependencyMetadata` from a Render2 |
| * `CompileTypeMetadata` instance. |
| */ |
| function dependenciesFromGlobalMetadata(type, outputCtx, reflector) { |
| var e_1, _a; |
| // Use the `CompileReflector` to look up references to some well-known Angular types. These will |
| // be compared with the token to statically determine whether the token has significance to |
| // Angular, and set the correct `R3ResolvedDependencyType` as a result. |
| var injectorRef = reflector.resolveExternalReference(Identifiers.Injector); |
| // Iterate through the type's DI dependencies and produce `R3DependencyMetadata` for each of them. |
| var deps = []; |
| try { |
| for (var _b = __values(type.diDeps), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var dependency = _c.value; |
| if (dependency.token) { |
| var tokenRef = tokenReference(dependency.token); |
| var resolved = dependency.isAttribute ? |
| exports.R3ResolvedDependencyType.Attribute : |
| exports.R3ResolvedDependencyType.Token; |
| // In the case of most dependencies, the token will be a reference to a type. Sometimes, |
| // however, it can be a string, in the case of older Angular code or @Attribute injection. |
| var token = tokenRef instanceof StaticSymbol ? outputCtx.importExpr(tokenRef) : literal(tokenRef); |
| // Construct the dependency. |
| deps.push({ |
| token: token, |
| attribute: null, |
| resolved: resolved, |
| host: !!dependency.isHost, |
| optional: !!dependency.isOptional, |
| self: !!dependency.isSelf, |
| skipSelf: !!dependency.isSkipSelf, |
| }); |
| } |
| else { |
| unsupported('dependency without a token'); |
| } |
| } |
| } |
| 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 deps; |
| } |
| function isDelegatedMetadata(meta) { |
| return meta.delegateType !== undefined; |
| } |
| function isExpressionFactoryMetadata(meta) { |
| return meta.expression !== undefined; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| function compileInjectable(meta) { |
| var result = null; |
| var factoryMeta = { |
| name: meta.name, |
| type: meta.type, |
| internalType: meta.internalType, |
| typeArgumentCount: meta.typeArgumentCount, |
| deps: [], |
| injectFn: Identifiers.inject, |
| target: exports.R3FactoryTarget.Injectable, |
| }; |
| if (meta.useClass !== undefined) { |
| // meta.useClass has two modes of operation. Either deps are specified, in which case `new` is |
| // used to instantiate the class with dependencies injected, or deps are not specified and |
| // the factory of the class is used to instantiate it. |
| // |
| // A special case exists for useClass: Type where Type is the injectable type itself and no |
| // deps are specified, in which case 'useClass' is effectively ignored. |
| var useClassOnSelf = meta.useClass.isEquivalent(meta.internalType); |
| var deps = undefined; |
| if (meta.userDeps !== undefined) { |
| deps = meta.userDeps; |
| } |
| if (deps !== undefined) { |
| // factory: () => new meta.useClass(...deps) |
| result = compileFactoryFunction(Object.assign(Object.assign({}, factoryMeta), { delegate: meta.useClass, delegateDeps: deps, delegateType: R3FactoryDelegateType.Class })); |
| } |
| else if (useClassOnSelf) { |
| result = compileFactoryFunction(factoryMeta); |
| } |
| else { |
| result = delegateToFactory(meta.type.value, meta.useClass); |
| } |
| } |
| else if (meta.useFactory !== undefined) { |
| if (meta.userDeps !== undefined) { |
| result = compileFactoryFunction(Object.assign(Object.assign({}, factoryMeta), { delegate: meta.useFactory, delegateDeps: meta.userDeps || [], delegateType: R3FactoryDelegateType.Function })); |
| } |
| else { |
| result = { |
| statements: [], |
| factory: fn([], [new ReturnStatement(meta.useFactory.callFn([]))]) |
| }; |
| } |
| } |
| else if (meta.useValue !== undefined) { |
| // Note: it's safe to use `meta.useValue` instead of the `USE_VALUE in meta` check used for |
| // client code because meta.useValue is an Expression which will be defined even if the actual |
| // value is undefined. |
| result = compileFactoryFunction(Object.assign(Object.assign({}, factoryMeta), { expression: meta.useValue })); |
| } |
| else if (meta.useExisting !== undefined) { |
| // useExisting is an `inject` call on the existing token. |
| result = compileFactoryFunction(Object.assign(Object.assign({}, factoryMeta), { expression: importExpr(Identifiers.inject).callFn([meta.useExisting]) })); |
| } |
| else { |
| result = delegateToFactory(meta.type.value, meta.internalType); |
| } |
| var token = meta.internalType; |
| var injectableProps = { token: token, factory: result.factory }; |
| // Only generate providedIn property if it has a non-null value |
| if (meta.providedIn.value !== null) { |
| injectableProps.providedIn = meta.providedIn; |
| } |
| var expression = importExpr(Identifiers.ɵɵdefineInjectable).callFn([mapToMapExpression(injectableProps)]); |
| var type = new ExpressionType(importExpr(Identifiers.InjectableDef, [typeWithParameters(meta.type.type, meta.typeArgumentCount)])); |
| return { |
| expression: expression, |
| type: type, |
| statements: result.statements, |
| }; |
| } |
| function delegateToFactory(type, internalType) { |
| return { |
| statements: [], |
| // If types are the same, we can generate `factory: type.ɵfac` |
| // If types are different, we have to generate a wrapper function to ensure |
| // the internal type has been resolved (`factory: function(t) { return type.ɵfac(t); }`) |
| factory: type.node === internalType.node ? |
| internalType.prop('ɵfac') : |
| fn([new FnParam('t', DYNAMIC_TYPE)], [new ReturnStatement(internalType.callMethod('ɵfac', [variable('t')]))]) |
| }; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| function assertArrayOfStrings(identifier, value) { |
| if (value == null) { |
| return; |
| } |
| if (!Array.isArray(value)) { |
| throw new Error("Expected '" + identifier + "' to be an array of strings."); |
| } |
| for (var i = 0; i < value.length; i += 1) { |
| if (typeof value[i] !== 'string') { |
| throw new Error("Expected '" + identifier + "' to be an array of strings."); |
| } |
| } |
| } |
| var UNUSABLE_INTERPOLATION_REGEXPS = [ |
| /^\s*$/, |
| /[<>]/, |
| /^[{}]$/, |
| /&(#|[a-z])/i, |
| /^\/\//, |
| ]; |
| function assertInterpolationSymbols(identifier, value) { |
| if (value != null && !(Array.isArray(value) && value.length == 2)) { |
| throw new Error("Expected '" + identifier + "' to be an array, [start, end]."); |
| } |
| else if (value != null) { |
| var start_1 = value[0]; |
| var end_1 = value[1]; |
| // Check for unusable interpolation symbols |
| UNUSABLE_INTERPOLATION_REGEXPS.forEach(function (regexp) { |
| if (regexp.test(start_1) || regexp.test(end_1)) { |
| throw new Error("['" + start_1 + "', '" + end_1 + "'] contains unusable interpolation symbol."); |
| } |
| }); |
| } |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var InterpolationConfig = /** @class */ (function () { |
| function InterpolationConfig(start, end) { |
| this.start = start; |
| this.end = end; |
| } |
| InterpolationConfig.fromArray = function (markers) { |
| if (!markers) { |
| return DEFAULT_INTERPOLATION_CONFIG; |
| } |
| assertInterpolationSymbols('interpolation', markers); |
| return new InterpolationConfig(markers[0], markers[1]); |
| }; |
| return InterpolationConfig; |
| }()); |
| var DEFAULT_INTERPOLATION_CONFIG = new InterpolationConfig('{{', '}}'); |
| |
| /** |
| * In TypeScript, tagged template functions expect a "template object", which is an array of |
| * "cooked" strings plus a `raw` property that contains an array of "raw" strings. This is |
| * typically constructed with a function called `__makeTemplateObject(cooked, raw)`, but it may not |
| * be available in all environments. |
| * |
| * This is a JavaScript polyfill that uses __makeTemplateObject when it's available, but otherwise |
| * creates an inline helper with the same functionality. |
| * |
| * In the inline function, if `Object.defineProperty` is available we use that to attach the `raw` |
| * array. |
| */ |
| var makeTemplateObjectPolyfill = '(this&&this.__makeTemplateObject||function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e})'; |
| var AbstractJsEmitterVisitor = /** @class */ (function (_super) { |
| __extends(AbstractJsEmitterVisitor, _super); |
| function AbstractJsEmitterVisitor() { |
| return _super.call(this, false) || this; |
| } |
| AbstractJsEmitterVisitor.prototype.visitDeclareClassStmt = function (stmt, ctx) { |
| var _this = this; |
| ctx.pushClass(stmt); |
| this._visitClassConstructor(stmt, ctx); |
| if (stmt.parent != null) { |
| ctx.print(stmt, stmt.name + ".prototype = Object.create("); |
| stmt.parent.visitExpression(this, ctx); |
| ctx.println(stmt, ".prototype);"); |
| } |
| stmt.getters.forEach(function (getter) { return _this._visitClassGetter(stmt, getter, ctx); }); |
| stmt.methods.forEach(function (method) { return _this._visitClassMethod(stmt, method, ctx); }); |
| ctx.popClass(); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype._visitClassConstructor = function (stmt, ctx) { |
| ctx.print(stmt, "function " + stmt.name + "("); |
| if (stmt.constructorMethod != null) { |
| this._visitParams(stmt.constructorMethod.params, ctx); |
| } |
| ctx.println(stmt, ") {"); |
| ctx.incIndent(); |
| if (stmt.constructorMethod != null) { |
| if (stmt.constructorMethod.body.length > 0) { |
| ctx.println(stmt, "var self = this;"); |
| this.visitAllStatements(stmt.constructorMethod.body, ctx); |
| } |
| } |
| ctx.decIndent(); |
| ctx.println(stmt, "}"); |
| }; |
| AbstractJsEmitterVisitor.prototype._visitClassGetter = function (stmt, getter, ctx) { |
| ctx.println(stmt, "Object.defineProperty(" + stmt.name + ".prototype, '" + getter.name + "', { get: function() {"); |
| ctx.incIndent(); |
| if (getter.body.length > 0) { |
| ctx.println(stmt, "var self = this;"); |
| this.visitAllStatements(getter.body, ctx); |
| } |
| ctx.decIndent(); |
| ctx.println(stmt, "}});"); |
| }; |
| AbstractJsEmitterVisitor.prototype._visitClassMethod = function (stmt, method, ctx) { |
| ctx.print(stmt, stmt.name + ".prototype." + method.name + " = function("); |
| this._visitParams(method.params, ctx); |
| ctx.println(stmt, ") {"); |
| ctx.incIndent(); |
| if (method.body.length > 0) { |
| ctx.println(stmt, "var self = this;"); |
| this.visitAllStatements(method.body, ctx); |
| } |
| ctx.decIndent(); |
| ctx.println(stmt, "};"); |
| }; |
| AbstractJsEmitterVisitor.prototype.visitWrappedNodeExpr = function (ast, ctx) { |
| throw new Error('Cannot emit a WrappedNodeExpr in Javascript.'); |
| }; |
| AbstractJsEmitterVisitor.prototype.visitReadVarExpr = function (ast, ctx) { |
| if (ast.builtin === exports.BuiltinVar.This) { |
| ctx.print(ast, 'self'); |
| } |
| else if (ast.builtin === exports.BuiltinVar.Super) { |
| throw new Error("'super' needs to be handled at a parent ast node, not at the variable level!"); |
| } |
| else { |
| _super.prototype.visitReadVarExpr.call(this, ast, ctx); |
| } |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitDeclareVarStmt = function (stmt, ctx) { |
| ctx.print(stmt, "var " + stmt.name); |
| if (stmt.value) { |
| ctx.print(stmt, ' = '); |
| stmt.value.visitExpression(this, ctx); |
| } |
| ctx.println(stmt, ";"); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitCastExpr = function (ast, ctx) { |
| ast.value.visitExpression(this, ctx); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitInvokeFunctionExpr = function (expr, ctx) { |
| var fnExpr = expr.fn; |
| if (fnExpr instanceof ReadVarExpr && fnExpr.builtin === exports.BuiltinVar.Super) { |
| ctx.currentClass.parent.visitExpression(this, ctx); |
| ctx.print(expr, ".call(this"); |
| if (expr.args.length > 0) { |
| ctx.print(expr, ", "); |
| this.visitAllExpressions(expr.args, ctx, ','); |
| } |
| ctx.print(expr, ")"); |
| } |
| else { |
| _super.prototype.visitInvokeFunctionExpr.call(this, expr, ctx); |
| } |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitTaggedTemplateExpr = function (ast, ctx) { |
| var _this = this; |
| // The following convoluted piece of code is effectively the downlevelled equivalent of |
| // ``` |
| // tag`...` |
| // ``` |
| // which is effectively like: |
| // ``` |
| // tag(__makeTemplateObject(cooked, raw), expression1, expression2, ...); |
| // ``` |
| var elements = ast.template.elements; |
| ast.tag.visitExpression(this, ctx); |
| ctx.print(ast, "(" + makeTemplateObjectPolyfill + "("); |
| ctx.print(ast, "[" + elements.map(function (part) { return escapeIdentifier(part.text, false); }).join(', ') + "], "); |
| ctx.print(ast, "[" + elements.map(function (part) { return escapeIdentifier(part.rawText, false); }).join(', ') + "])"); |
| ast.template.expressions.forEach(function (expression) { |
| ctx.print(ast, ', '); |
| expression.visitExpression(_this, ctx); |
| }); |
| ctx.print(ast, ')'); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitFunctionExpr = function (ast, ctx) { |
| ctx.print(ast, "function" + (ast.name ? ' ' + ast.name : '') + "("); |
| this._visitParams(ast.params, ctx); |
| ctx.println(ast, ") {"); |
| ctx.incIndent(); |
| this.visitAllStatements(ast.statements, ctx); |
| ctx.decIndent(); |
| ctx.print(ast, "}"); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitDeclareFunctionStmt = function (stmt, ctx) { |
| ctx.print(stmt, "function " + stmt.name + "("); |
| this._visitParams(stmt.params, ctx); |
| ctx.println(stmt, ") {"); |
| ctx.incIndent(); |
| this.visitAllStatements(stmt.statements, ctx); |
| ctx.decIndent(); |
| ctx.println(stmt, "}"); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitTryCatchStmt = function (stmt, ctx) { |
| ctx.println(stmt, "try {"); |
| ctx.incIndent(); |
| this.visitAllStatements(stmt.bodyStmts, ctx); |
| ctx.decIndent(); |
| ctx.println(stmt, "} catch (" + CATCH_ERROR_VAR$1.name + ") {"); |
| ctx.incIndent(); |
| var catchStmts = [CATCH_STACK_VAR$1.set(CATCH_ERROR_VAR$1.prop('stack')).toDeclStmt(null, [ |
| exports.StmtModifier.Final |
| ])].concat(stmt.catchStmts); |
| this.visitAllStatements(catchStmts, ctx); |
| ctx.decIndent(); |
| ctx.println(stmt, "}"); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype.visitLocalizedString = function (ast, ctx) { |
| var _this = this; |
| // The following convoluted piece of code is effectively the downlevelled equivalent of |
| // ``` |
| // $localize `...` |
| // ``` |
| // which is effectively like: |
| // ``` |
| // $localize(__makeTemplateObject(cooked, raw), expression1, expression2, ...); |
| // ``` |
| ctx.print(ast, "$localize(" + makeTemplateObjectPolyfill + "("); |
| var parts = [ast.serializeI18nHead()]; |
| for (var i = 1; i < ast.messageParts.length; i++) { |
| parts.push(ast.serializeI18nTemplatePart(i)); |
| } |
| ctx.print(ast, "[" + parts.map(function (part) { return escapeIdentifier(part.cooked, false); }).join(', ') + "], "); |
| ctx.print(ast, "[" + parts.map(function (part) { return escapeIdentifier(part.raw, false); }).join(', ') + "])"); |
| ast.expressions.forEach(function (expression) { |
| ctx.print(ast, ', '); |
| expression.visitExpression(_this, ctx); |
| }); |
| ctx.print(ast, ')'); |
| return null; |
| }; |
| AbstractJsEmitterVisitor.prototype._visitParams = function (params, ctx) { |
| this.visitAllObjects(function (param) { return ctx.print(null, param.name); }, params, ctx, ','); |
| }; |
| AbstractJsEmitterVisitor.prototype.getBuiltinMethodName = function (method) { |
| var name; |
| switch (method) { |
| case exports.BuiltinMethod.ConcatArray: |
| name = 'concat'; |
| break; |
| case exports.BuiltinMethod.SubscribeObservable: |
| name = 'subscribe'; |
| break; |
| case exports.BuiltinMethod.Bind: |
| name = 'bind'; |
| break; |
| default: |
| throw new Error("Unknown builtin method: " + method); |
| } |
| return name; |
| }; |
| return AbstractJsEmitterVisitor; |
| }(AbstractEmitterVisitor)); |
| |
| /** |
| * The Trusted Types policy, or null if Trusted Types are not |
| * enabled/supported, or undefined if the policy has not been created yet. |
| */ |
| var policy; |
| /** |
| * Returns the Trusted Types policy, or null if Trusted Types are not |
| * enabled/supported. The first call to this function will create the policy. |
| */ |
| function getPolicy() { |
| if (policy === undefined) { |
| policy = null; |
| if (_global.trustedTypes) { |
| try { |
| policy = |
| _global.trustedTypes.createPolicy('angular#unsafe-jit', { |
| createScript: function (s) { return s; }, |
| }); |
| } |
| catch (_a) { |
| // trustedTypes.createPolicy throws if called with a name that is |
| // already registered, even in report-only mode. Until the API changes, |
| // catch the error not to break the applications functionally. In such |
| // cases, the code will fall back to using strings. |
| } |
| } |
| } |
| return policy; |
| } |
| /** |
| * Unsafely promote a string to a TrustedScript, falling back to strings when |
| * Trusted Types are not available. |
| * @security In particular, it must be assured that the provided string will |
| * never cause an XSS vulnerability if used in a context that will be |
| * interpreted and executed as a script by a browser, e.g. when calling eval. |
| */ |
| function trustedScriptFromString(script) { |
| var _a; |
| return ((_a = getPolicy()) === null || _a === void 0 ? void 0 : _a.createScript(script)) || script; |
| } |
| /** |
| * Unsafely call the Function constructor with the given string arguments. |
| * @security This is a security-sensitive function; any use of this function |
| * must go through security review. In particular, it must be assured that it |
| * is only called from the JIT compiler, as use in other code can lead to XSS |
| * vulnerabilities. |
| */ |
| function newTrustedFunctionForJIT() { |
| var args = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| args[_i] = arguments[_i]; |
| } |
| if (!_global.trustedTypes) { |
| // In environments that don't support Trusted Types, fall back to the most |
| // straightforward implementation: |
| return new (Function.bind.apply(Function, __spread([void 0], args)))(); |
| } |
| // Chrome currently does not support passing TrustedScript to the Function |
| // constructor. The following implements the workaround proposed on the page |
| // below, where the Chromium bug is also referenced: |
| // https://github.com/w3c/webappsec-trusted-types/wiki/Trusted-Types-for-function-constructor |
| var fnArgs = args.slice(0, -1).join(','); |
| var fnBody = args[args.length - 1]; |
| var body = "(function anonymous(" + fnArgs + "\n) { " + fnBody + "\n})"; |
| // Using eval directly confuses the compiler and prevents this module from |
| // being stripped out of JS binaries even if not used. The global['eval'] |
| // indirection fixes that. |
| var fn = _global['eval'](trustedScriptFromString(body)); |
| if (fn.bind === undefined) { |
| // Workaround for a browser bug that only exists in Chrome 83, where passing |
| // a TrustedScript to eval just returns the TrustedScript back without |
| // evaluating it. In that case, fall back to the most straightforward |
| // implementation: |
| return new (Function.bind.apply(Function, __spread([void 0], args)))(); |
| } |
| // To completely mimic the behavior of calling "new Function", two more |
| // things need to happen: |
| // 1. Stringifying the resulting function should return its source code |
| fn.toString = function () { return body; }; |
| // 2. When calling the resulting function, `this` should refer to `global` |
| return fn.bind(_global); |
| // When Trusted Types support in Function constructors is widely available, |
| // the implementation of this function can be simplified to: |
| // return new Function(...args.map(a => trustedScriptFromString(a))); |
| } |
| |
| /** |
| * A helper class to manage the evaluation of JIT generated code. |
| */ |
| var JitEvaluator = /** @class */ (function () { |
| function JitEvaluator() { |
| } |
| /** |
| * |
| * @param sourceUrl The URL of the generated code. |
| * @param statements An array of Angular statement AST nodes to be evaluated. |
| * @param reflector A helper used when converting the statements to executable code. |
| * @param createSourceMaps If true then create a source-map for the generated code and include it |
| * inline as a source-map comment. |
| * @returns A map of all the variables in the generated code. |
| */ |
| JitEvaluator.prototype.evaluateStatements = function (sourceUrl, statements, reflector, createSourceMaps) { |
| var converter = new JitEmitterVisitor(reflector); |
| var ctx = EmitterVisitorContext.createRoot(); |
| // Ensure generated code is in strict mode |
| if (statements.length > 0 && !isUseStrictStatement(statements[0])) { |
| statements = __spread([ |
| literal('use strict').toStmt() |
| ], statements); |
| } |
| converter.visitAllStatements(statements, ctx); |
| converter.createReturnStmt(ctx); |
| return this.evaluateCode(sourceUrl, ctx, converter.getArgs(), createSourceMaps); |
| }; |
| /** |
| * Evaluate a piece of JIT generated code. |
| * @param sourceUrl The URL of this generated code. |
| * @param ctx A context object that contains an AST of the code to be evaluated. |
| * @param vars A map containing the names and values of variables that the evaluated code might |
| * reference. |
| * @param createSourceMap If true then create a source-map for the generated code and include it |
| * inline as a source-map comment. |
| * @returns The result of evaluating the code. |
| */ |
| JitEvaluator.prototype.evaluateCode = function (sourceUrl, ctx, vars, createSourceMap) { |
| var fnBody = "\"use strict\";" + ctx.toSource() + "\n//# sourceURL=" + sourceUrl; |
| var fnArgNames = []; |
| var fnArgValues = []; |
| for (var argName in vars) { |
| fnArgValues.push(vars[argName]); |
| fnArgNames.push(argName); |
| } |
| if (createSourceMap) { |
| // using `new Function(...)` generates a header, 1 line of no arguments, 2 lines otherwise |
| // E.g. ``` |
| // function anonymous(a,b,c |
| // /**/) { ... }``` |
| // We don't want to hard code this fact, so we auto detect it via an empty function first. |
| var emptyFn = newTrustedFunctionForJIT.apply(void 0, __spread(fnArgNames.concat('return null;'))).toString(); |
| var headerLines = emptyFn.slice(0, emptyFn.indexOf('return null;')).split('\n').length - 1; |
| fnBody += "\n" + ctx.toSourceMapGenerator(sourceUrl, headerLines).toJsComment(); |
| } |
| var fn = newTrustedFunctionForJIT.apply(void 0, __spread(fnArgNames.concat(fnBody))); |
| return this.executeFunction(fn, fnArgValues); |
| }; |
| /** |
| * Execute a JIT generated function by calling it. |
| * |
| * This method can be overridden in tests to capture the functions that are generated |
| * by this `JitEvaluator` class. |
| * |
| * @param fn A function to execute. |
| * @param args The arguments to pass to the function being executed. |
| * @returns The return value of the executed function. |
| */ |
| JitEvaluator.prototype.executeFunction = function (fn, args) { |
| return fn.apply(void 0, __spread(args)); |
| }; |
| return JitEvaluator; |
| }()); |
| /** |
| * An Angular AST visitor that converts AST nodes into executable JavaScript code. |
| */ |
| var JitEmitterVisitor = /** @class */ (function (_super) { |
| __extends(JitEmitterVisitor, _super); |
| function JitEmitterVisitor(reflector) { |
| var _this = _super.call(this) || this; |
| _this.reflector = reflector; |
| _this._evalArgNames = []; |
| _this._evalArgValues = []; |
| _this._evalExportedVars = []; |
| return _this; |
| } |
| JitEmitterVisitor.prototype.createReturnStmt = function (ctx) { |
| var stmt = new ReturnStatement(new LiteralMapExpr(this._evalExportedVars.map(function (resultVar) { return new LiteralMapEntry(resultVar, variable(resultVar), false); }))); |
| stmt.visitStatement(this, ctx); |
| }; |
| JitEmitterVisitor.prototype.getArgs = function () { |
| var result = {}; |
| for (var i = 0; i < this._evalArgNames.length; i++) { |
| result[this._evalArgNames[i]] = this._evalArgValues[i]; |
| } |
| return result; |
| }; |
| JitEmitterVisitor.prototype.visitExternalExpr = function (ast, ctx) { |
| this._emitReferenceToExternal(ast, this.reflector.resolveExternalReference(ast.value), ctx); |
| return null; |
| }; |
| JitEmitterVisitor.prototype.visitWrappedNodeExpr = function (ast, ctx) { |
| this._emitReferenceToExternal(ast, ast.node, ctx); |
| return null; |
| }; |
| JitEmitterVisitor.prototype.visitDeclareVarStmt = function (stmt, ctx) { |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| this._evalExportedVars.push(stmt.name); |
| } |
| return _super.prototype.visitDeclareVarStmt.call(this, stmt, ctx); |
| }; |
| JitEmitterVisitor.prototype.visitDeclareFunctionStmt = function (stmt, ctx) { |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| this._evalExportedVars.push(stmt.name); |
| } |
| return _super.prototype.visitDeclareFunctionStmt.call(this, stmt, ctx); |
| }; |
| JitEmitterVisitor.prototype.visitDeclareClassStmt = function (stmt, ctx) { |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| this._evalExportedVars.push(stmt.name); |
| } |
| return _super.prototype.visitDeclareClassStmt.call(this, stmt, ctx); |
| }; |
| JitEmitterVisitor.prototype._emitReferenceToExternal = function (ast, value, ctx) { |
| var id = this._evalArgValues.indexOf(value); |
| if (id === -1) { |
| id = this._evalArgValues.length; |
| this._evalArgValues.push(value); |
| var name = identifierName({ reference: value }) || 'val'; |
| this._evalArgNames.push("jit_" + name + "_" + id); |
| } |
| ctx.print(ast, this._evalArgNames[id]); |
| }; |
| return JitEmitterVisitor; |
| }(AbstractJsEmitterVisitor)); |
| function isUseStrictStatement(statement) { |
| return statement.isEquivalent(literal('use strict').toStmt()); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var $EOF = 0; |
| var $BSPACE = 8; |
| var $TAB = 9; |
| var $LF = 10; |
| var $VTAB = 11; |
| var $FF = 12; |
| var $CR = 13; |
| var $SPACE = 32; |
| var $BANG = 33; |
| var $DQ = 34; |
| var $HASH = 35; |
| var $$ = 36; |
| var $PERCENT = 37; |
| var $AMPERSAND = 38; |
| var $SQ = 39; |
| var $LPAREN = 40; |
| var $RPAREN = 41; |
| var $STAR = 42; |
| var $PLUS = 43; |
| var $COMMA = 44; |
| var $MINUS = 45; |
| var $PERIOD = 46; |
| var $SLASH = 47; |
| var $COLON = 58; |
| var $SEMICOLON = 59; |
| var $LT = 60; |
| var $EQ = 61; |
| var $GT = 62; |
| var $QUESTION = 63; |
| var $0 = 48; |
| var $7 = 55; |
| var $9 = 57; |
| var $A = 65; |
| var $E = 69; |
| var $F = 70; |
| var $X = 88; |
| var $Z = 90; |
| var $LBRACKET = 91; |
| var $BACKSLASH = 92; |
| var $RBRACKET = 93; |
| var $CARET = 94; |
| var $_ = 95; |
| var $a = 97; |
| var $b = 98; |
| var $e = 101; |
| var $f = 102; |
| var $n = 110; |
| var $r = 114; |
| var $t = 116; |
| var $u = 117; |
| var $v = 118; |
| var $x = 120; |
| var $z = 122; |
| var $LBRACE = 123; |
| var $BAR = 124; |
| var $RBRACE = 125; |
| var $NBSP = 160; |
| var $PIPE = 124; |
| var $TILDA = 126; |
| var $AT = 64; |
| var $BT = 96; |
| function isWhitespace(code) { |
| return (code >= $TAB && code <= $SPACE) || (code == $NBSP); |
| } |
| function isDigit(code) { |
| return $0 <= code && code <= $9; |
| } |
| function isAsciiLetter(code) { |
| return code >= $a && code <= $z || code >= $A && code <= $Z; |
| } |
| function isAsciiHexDigit(code) { |
| return code >= $a && code <= $f || code >= $A && code <= $F || isDigit(code); |
| } |
| function isNewLine(code) { |
| return code === $LF || code === $CR; |
| } |
| function isOctalDigit(code) { |
| return $0 <= code && code <= $7; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var ParseLocation = /** @class */ (function () { |
| function ParseLocation(file, offset, line, col) { |
| this.file = file; |
| this.offset = offset; |
| this.line = line; |
| this.col = col; |
| } |
| ParseLocation.prototype.toString = function () { |
| return this.offset != null ? this.file.url + "@" + this.line + ":" + this.col : this.file.url; |
| }; |
| ParseLocation.prototype.moveBy = function (delta) { |
| var source = this.file.content; |
| var len = source.length; |
| var offset = this.offset; |
| var line = this.line; |
| var col = this.col; |
| while (offset > 0 && delta < 0) { |
| offset--; |
| delta++; |
| var ch = source.charCodeAt(offset); |
| if (ch == $LF) { |
| line--; |
| var priorLine = source.substr(0, offset - 1).lastIndexOf(String.fromCharCode($LF)); |
| col = priorLine > 0 ? offset - priorLine : offset; |
| } |
| else { |
| col--; |
| } |
| } |
| while (offset < len && delta > 0) { |
| var ch = source.charCodeAt(offset); |
| offset++; |
| delta--; |
| if (ch == $LF) { |
| line++; |
| col = 0; |
| } |
| else { |
| col++; |
| } |
| } |
| return new ParseLocation(this.file, offset, line, col); |
| }; |
| // Return the source around the location |
| // Up to `maxChars` or `maxLines` on each side of the location |
| ParseLocation.prototype.getContext = function (maxChars, maxLines) { |
| var content = this.file.content; |
| var startOffset = this.offset; |
| if (startOffset != null) { |
| if (startOffset > content.length - 1) { |
| startOffset = content.length - 1; |
| } |
| var endOffset = startOffset; |
| var ctxChars = 0; |
| var ctxLines = 0; |
| while (ctxChars < maxChars && startOffset > 0) { |
| startOffset--; |
| ctxChars++; |
| if (content[startOffset] == '\n') { |
| if (++ctxLines == maxLines) { |
| break; |
| } |
| } |
| } |
| ctxChars = 0; |
| ctxLines = 0; |
| while (ctxChars < maxChars && endOffset < content.length - 1) { |
| endOffset++; |
| ctxChars++; |
| if (content[endOffset] == '\n') { |
| if (++ctxLines == maxLines) { |
| break; |
| } |
| } |
| } |
| return { |
| before: content.substring(startOffset, this.offset), |
| after: content.substring(this.offset, endOffset + 1), |
| }; |
| } |
| return null; |
| }; |
| return ParseLocation; |
| }()); |
| var ParseSourceFile = /** @class */ (function () { |
| function ParseSourceFile(content, url) { |
| this.content = content; |
| this.url = url; |
| } |
| return ParseSourceFile; |
| }()); |
| var ParseSourceSpan = /** @class */ (function () { |
| /** |
| * Create an object that holds information about spans of tokens/nodes captured during |
| * lexing/parsing of text. |
| * |
| * @param start |
| * The location of the start of the span (having skipped leading trivia). |
| * Skipping leading trivia makes source-spans more "user friendly", since things like HTML |
| * elements will appear to begin at the start of the opening tag, rather than at the start of any |
| * leading trivia, which could include newlines. |
| * |
| * @param end |
| * The location of the end of the span. |
| * |
| * @param fullStart |
| * The start of the token without skipping the leading trivia. |
| * This is used by tooling that splits tokens further, such as extracting Angular interpolations |
| * from text tokens. Such tooling creates new source-spans relative to the original token's |
| * source-span. If leading trivia characters have been skipped then the new source-spans may be |
| * incorrectly offset. |
| * |
| * @param details |
| * Additional information (such as identifier names) that should be associated with the span. |
| */ |
| function ParseSourceSpan(start, end, fullStart, details) { |
| if (fullStart === void 0) { fullStart = start; } |
| if (details === void 0) { details = null; } |
| this.start = start; |
| this.end = end; |
| this.fullStart = fullStart; |
| this.details = details; |
| } |
| ParseSourceSpan.prototype.toString = function () { |
| return this.start.file.content.substring(this.start.offset, this.end.offset); |
| }; |
| return ParseSourceSpan; |
| }()); |
| (function (ParseErrorLevel) { |
| ParseErrorLevel[ParseErrorLevel["WARNING"] = 0] = "WARNING"; |
| ParseErrorLevel[ParseErrorLevel["ERROR"] = 1] = "ERROR"; |
| })(exports.ParseErrorLevel || (exports.ParseErrorLevel = {})); |
| var ParseError = /** @class */ (function () { |
| function ParseError(span, msg, level) { |
| if (level === void 0) { level = exports.ParseErrorLevel.ERROR; } |
| this.span = span; |
| this.msg = msg; |
| this.level = level; |
| } |
| ParseError.prototype.contextualMessage = function () { |
| var ctx = this.span.start.getContext(100, 3); |
| return ctx ? this.msg + " (\"" + ctx.before + "[" + exports.ParseErrorLevel[this.level] + " ->]" + ctx.after + "\")" : |
| this.msg; |
| }; |
| ParseError.prototype.toString = function () { |
| var details = this.span.details ? ", " + this.span.details : ''; |
| return this.contextualMessage() + ": " + this.span.start + details; |
| }; |
| return ParseError; |
| }()); |
| function typeSourceSpan(kind, type) { |
| var moduleUrl = identifierModuleUrl(type); |
| var sourceFileName = moduleUrl != null ? "in " + kind + " " + identifierName(type) + " in " + moduleUrl : |
| "in " + kind + " " + identifierName(type); |
| var sourceFile = new ParseSourceFile('', sourceFileName); |
| return new ParseSourceSpan(new ParseLocation(sourceFile, -1, -1, -1), new ParseLocation(sourceFile, -1, -1, -1)); |
| } |
| /** |
| * Generates Source Span object for a given R3 Type for JIT mode. |
| * |
| * @param kind Component or Directive. |
| * @param typeName name of the Component or Directive. |
| * @param sourceUrl reference to Component or Directive source. |
| * @returns instance of ParseSourceSpan that represent a given Component or Directive. |
| */ |
| function r3JitTypeSourceSpan(kind, typeName, sourceUrl) { |
| var sourceFileName = "in " + kind + " " + typeName + " in " + sourceUrl; |
| var sourceFile = new ParseSourceFile('', sourceFileName); |
| return new ParseSourceSpan(new ParseLocation(sourceFile, -1, -1, -1), new ParseLocation(sourceFile, -1, -1, -1)); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Implementation of `CompileReflector` which resolves references to @angular/core |
| * symbols at runtime, according to a consumer-provided mapping. |
| * |
| * Only supports `resolveExternalReference`, all other methods throw. |
| */ |
| var R3JitReflector = /** @class */ (function () { |
| function R3JitReflector(context) { |
| this.context = context; |
| } |
| R3JitReflector.prototype.resolveExternalReference = function (ref) { |
| // This reflector only handles @angular/core imports. |
| if (ref.moduleName !== '@angular/core') { |
| throw new Error("Cannot resolve external reference to " + ref.moduleName + ", only references to @angular/core are supported."); |
| } |
| if (!this.context.hasOwnProperty(ref.name)) { |
| throw new Error("No value provided for @angular/core symbol '" + ref.name + "'."); |
| } |
| return this.context[ref.name]; |
| }; |
| R3JitReflector.prototype.parameters = function (typeOrFunc) { |
| throw new Error('Not implemented.'); |
| }; |
| R3JitReflector.prototype.annotations = function (typeOrFunc) { |
| throw new Error('Not implemented.'); |
| }; |
| R3JitReflector.prototype.shallowAnnotations = function (typeOrFunc) { |
| throw new Error('Not implemented.'); |
| }; |
| R3JitReflector.prototype.tryAnnotations = function (typeOrFunc) { |
| throw new Error('Not implemented.'); |
| }; |
| R3JitReflector.prototype.propMetadata = function (typeOrFunc) { |
| throw new Error('Not implemented.'); |
| }; |
| R3JitReflector.prototype.hasLifecycleHook = function (type, lcProperty) { |
| throw new Error('Not implemented.'); |
| }; |
| R3JitReflector.prototype.guards = function (typeOrFunc) { |
| throw new Error('Not implemented.'); |
| }; |
| R3JitReflector.prototype.componentModuleUrl = function (type, cmpMetadata) { |
| throw new Error('Not implemented.'); |
| }; |
| return R3JitReflector; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Construct an `R3NgModuleDef` for the given `R3NgModuleMetadata`. |
| */ |
| function compileNgModule(meta) { |
| var internalType = meta.internalType, moduleType = meta.type, bootstrap = meta.bootstrap, declarations = meta.declarations, imports = meta.imports, exports = meta.exports, schemas = meta.schemas, containsForwardDecls = meta.containsForwardDecls, emitInline = meta.emitInline, id = meta.id; |
| var additionalStatements = []; |
| var definitionMap = { type: internalType }; |
| // Only generate the keys in the metadata if the arrays have values. |
| if (bootstrap.length) { |
| definitionMap.bootstrap = refsToArray(bootstrap, containsForwardDecls); |
| } |
| // If requested to emit scope information inline, pass the declarations, imports and exports to |
| // the `ɵɵdefineNgModule` call. The JIT compilation uses this. |
| if (emitInline) { |
| if (declarations.length) { |
| definitionMap.declarations = refsToArray(declarations, containsForwardDecls); |
| } |
| if (imports.length) { |
| definitionMap.imports = refsToArray(imports, containsForwardDecls); |
| } |
| if (exports.length) { |
| definitionMap.exports = refsToArray(exports, containsForwardDecls); |
| } |
| } |
| // If not emitting inline, the scope information is not passed into `ɵɵdefineNgModule` as it would |
| // prevent tree-shaking of the declarations, imports and exports references. |
| else { |
| var setNgModuleScopeCall = generateSetNgModuleScopeCall(meta); |
| if (setNgModuleScopeCall !== null) { |
| additionalStatements.push(setNgModuleScopeCall); |
| } |
| } |
| if (schemas && schemas.length) { |
| definitionMap.schemas = literalArr(schemas.map(function (ref) { return ref.value; })); |
| } |
| if (id) { |
| definitionMap.id = id; |
| } |
| var expression = importExpr(Identifiers$1.defineNgModule).callFn([mapToMapExpression(definitionMap)]); |
| var type = new ExpressionType(importExpr(Identifiers$1.NgModuleDefWithMeta, [ |
| new ExpressionType(moduleType.type), tupleTypeOf(declarations), tupleTypeOf(imports), |
| tupleTypeOf(exports) |
| ])); |
| return { expression: expression, type: type, additionalStatements: additionalStatements }; |
| } |
| /** |
| * Generates a function call to `ɵɵsetNgModuleScope` with all necessary information so that the |
| * transitive module scope can be computed during runtime in JIT mode. This call is marked pure |
| * such that the references to declarations, imports and exports may be elided causing these |
| * symbols to become tree-shakeable. |
| */ |
| function generateSetNgModuleScopeCall(meta) { |
| var moduleType = meta.adjacentType, declarations = meta.declarations, imports = meta.imports, exports = meta.exports, containsForwardDecls = meta.containsForwardDecls; |
| var scopeMap = {}; |
| if (declarations.length) { |
| scopeMap.declarations = refsToArray(declarations, containsForwardDecls); |
| } |
| if (imports.length) { |
| scopeMap.imports = refsToArray(imports, containsForwardDecls); |
| } |
| if (exports.length) { |
| scopeMap.exports = refsToArray(exports, containsForwardDecls); |
| } |
| if (Object.keys(scopeMap).length === 0) { |
| return null; |
| } |
| // setNgModuleScope(...) |
| var fnCall = new InvokeFunctionExpr( |
| /* fn */ importExpr(Identifiers$1.setNgModuleScope), |
| /* args */ [moduleType, mapToMapExpression(scopeMap)]); |
| // (ngJitMode guard) && setNgModuleScope(...) |
| var guardedCall = jitOnlyGuardedExpression(fnCall); |
| // function() { (ngJitMode guard) && setNgModuleScope(...); } |
| var iife = new FunctionExpr( |
| /* params */ [], |
| /* statements */ [guardedCall.toStmt()]); |
| // (function() { (ngJitMode guard) && setNgModuleScope(...); })() |
| var iifeCall = new InvokeFunctionExpr( |
| /* fn */ iife, |
| /* args */ []); |
| return iifeCall.toStmt(); |
| } |
| function compileInjector(meta) { |
| var definitionMap = {}; |
| if (meta.providers !== null) { |
| definitionMap.providers = meta.providers; |
| } |
| if (meta.imports.length > 0) { |
| definitionMap.imports = literalArr(meta.imports); |
| } |
| var expression = importExpr(Identifiers$1.defineInjector).callFn([mapToMapExpression(definitionMap)]); |
| var type = new ExpressionType(importExpr(Identifiers$1.InjectorDef, [new ExpressionType(meta.type.type)])); |
| return { expression: expression, type: type }; |
| } |
| function tupleTypeOf(exp) { |
| var types = exp.map(function (ref) { return typeofExpr(ref.type); }); |
| return exp.length > 0 ? expressionType(literalArr(types)) : NONE_TYPE; |
| } |
| function refsToArray(refs, shouldForwardDeclare) { |
| var values = literalArr(refs.map(function (ref) { return ref.value; })); |
| return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| function compilePipeFromMetadata(metadata) { |
| var definitionMapValues = []; |
| // e.g. `name: 'myPipe'` |
| definitionMapValues.push({ key: 'name', value: literal(metadata.pipeName), quoted: false }); |
| // e.g. `type: MyPipe` |
| definitionMapValues.push({ key: 'type', value: metadata.type.value, quoted: false }); |
| // e.g. `pure: true` |
| definitionMapValues.push({ key: 'pure', value: literal(metadata.pure), quoted: false }); |
| var expression = importExpr(Identifiers$1.definePipe).callFn([literalMap(definitionMapValues)]); |
| var type = createPipeType(metadata); |
| return { expression: expression, type: type }; |
| } |
| function createPipeType(metadata) { |
| return new ExpressionType(importExpr(Identifiers$1.PipeDefWithMeta, [ |
| typeWithParameters(metadata.type.type, metadata.typeArgumentCount), |
| new ExpressionType(new LiteralExpr(metadata.pipeName)), |
| ])); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var ParserError = /** @class */ (function () { |
| function ParserError(message, input, errLocation, ctxLocation) { |
| this.input = input; |
| this.errLocation = errLocation; |
| this.ctxLocation = ctxLocation; |
| this.message = "Parser Error: " + message + " " + errLocation + " [" + input + "] in " + ctxLocation; |
| } |
| return ParserError; |
| }()); |
| var ParseSpan = /** @class */ (function () { |
| function ParseSpan(start, end) { |
| this.start = start; |
| this.end = end; |
| } |
| ParseSpan.prototype.toAbsolute = function (absoluteOffset) { |
| return new AbsoluteSourceSpan(absoluteOffset + this.start, absoluteOffset + this.end); |
| }; |
| return ParseSpan; |
| }()); |
| var AST = /** @class */ (function () { |
| function AST(span, |
| /** |
| * Absolute location of the expression AST in a source code file. |
| */ |
| sourceSpan) { |
| this.span = span; |
| this.sourceSpan = sourceSpan; |
| } |
| AST.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return null; |
| }; |
| AST.prototype.toString = function () { |
| return 'AST'; |
| }; |
| return AST; |
| }()); |
| var ASTWithName = /** @class */ (function (_super) { |
| __extends(ASTWithName, _super); |
| function ASTWithName(span, sourceSpan, nameSpan) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.nameSpan = nameSpan; |
| return _this; |
| } |
| return ASTWithName; |
| }(AST)); |
| /** |
| * Represents a quoted expression of the form: |
| * |
| * quote = prefix `:` uninterpretedExpression |
| * prefix = identifier |
| * uninterpretedExpression = arbitrary string |
| * |
| * A quoted expression is meant to be pre-processed by an AST transformer that |
| * converts it into another AST that no longer contains quoted expressions. |
| * It is meant to allow third-party developers to extend Angular template |
| * expression language. The `uninterpretedExpression` part of the quote is |
| * therefore not interpreted by the Angular's own expression parser. |
| */ |
| var Quote = /** @class */ (function (_super) { |
| __extends(Quote, _super); |
| function Quote(span, sourceSpan, prefix, uninterpretedExpression, location) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.prefix = prefix; |
| _this.uninterpretedExpression = uninterpretedExpression; |
| _this.location = location; |
| return _this; |
| } |
| Quote.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitQuote(this, context); |
| }; |
| Quote.prototype.toString = function () { |
| return 'Quote'; |
| }; |
| return Quote; |
| }(AST)); |
| var EmptyExpr = /** @class */ (function (_super) { |
| __extends(EmptyExpr, _super); |
| function EmptyExpr() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| EmptyExpr.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| // do nothing |
| }; |
| return EmptyExpr; |
| }(AST)); |
| var ImplicitReceiver = /** @class */ (function (_super) { |
| __extends(ImplicitReceiver, _super); |
| function ImplicitReceiver() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| ImplicitReceiver.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitImplicitReceiver(this, context); |
| }; |
| return ImplicitReceiver; |
| }(AST)); |
| /** |
| * Receiver when something is accessed through `this` (e.g. `this.foo`). Note that this class |
| * inherits from `ImplicitReceiver`, because accessing something through `this` is treated the |
| * same as accessing it implicitly inside of an Angular template (e.g. `[attr.title]="this.title"` |
| * is the same as `[attr.title]="title"`.). Inheriting allows for the `this` accesses to be treated |
| * the same as implicit ones, except for a couple of exceptions like `$event` and `$any`. |
| * TODO: we should find a way for this class not to extend from `ImplicitReceiver` in the future. |
| */ |
| var ThisReceiver = /** @class */ (function (_super) { |
| __extends(ThisReceiver, _super); |
| function ThisReceiver() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| ThisReceiver.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| var _a; |
| return (_a = visitor.visitThisReceiver) === null || _a === void 0 ? void 0 : _a.call(visitor, this, context); |
| }; |
| return ThisReceiver; |
| }(ImplicitReceiver)); |
| /** |
| * Multiple expressions separated by a semicolon. |
| */ |
| var Chain = /** @class */ (function (_super) { |
| __extends(Chain, _super); |
| function Chain(span, sourceSpan, expressions) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.expressions = expressions; |
| return _this; |
| } |
| Chain.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitChain(this, context); |
| }; |
| return Chain; |
| }(AST)); |
| var Conditional = /** @class */ (function (_super) { |
| __extends(Conditional, _super); |
| function Conditional(span, sourceSpan, condition, trueExp, falseExp) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.condition = condition; |
| _this.trueExp = trueExp; |
| _this.falseExp = falseExp; |
| return _this; |
| } |
| Conditional.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitConditional(this, context); |
| }; |
| return Conditional; |
| }(AST)); |
| var PropertyRead = /** @class */ (function (_super) { |
| __extends(PropertyRead, _super); |
| function PropertyRead(span, sourceSpan, nameSpan, receiver, name) { |
| var _this = _super.call(this, span, sourceSpan, nameSpan) || this; |
| _this.receiver = receiver; |
| _this.name = name; |
| return _this; |
| } |
| PropertyRead.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitPropertyRead(this, context); |
| }; |
| return PropertyRead; |
| }(ASTWithName)); |
| var PropertyWrite = /** @class */ (function (_super) { |
| __extends(PropertyWrite, _super); |
| function PropertyWrite(span, sourceSpan, nameSpan, receiver, name, value) { |
| var _this = _super.call(this, span, sourceSpan, nameSpan) || this; |
| _this.receiver = receiver; |
| _this.name = name; |
| _this.value = value; |
| return _this; |
| } |
| PropertyWrite.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitPropertyWrite(this, context); |
| }; |
| return PropertyWrite; |
| }(ASTWithName)); |
| var SafePropertyRead = /** @class */ (function (_super) { |
| __extends(SafePropertyRead, _super); |
| function SafePropertyRead(span, sourceSpan, nameSpan, receiver, name) { |
| var _this = _super.call(this, span, sourceSpan, nameSpan) || this; |
| _this.receiver = receiver; |
| _this.name = name; |
| return _this; |
| } |
| SafePropertyRead.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitSafePropertyRead(this, context); |
| }; |
| return SafePropertyRead; |
| }(ASTWithName)); |
| var KeyedRead = /** @class */ (function (_super) { |
| __extends(KeyedRead, _super); |
| function KeyedRead(span, sourceSpan, obj, key) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.obj = obj; |
| _this.key = key; |
| return _this; |
| } |
| KeyedRead.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitKeyedRead(this, context); |
| }; |
| return KeyedRead; |
| }(AST)); |
| var KeyedWrite = /** @class */ (function (_super) { |
| __extends(KeyedWrite, _super); |
| function KeyedWrite(span, sourceSpan, obj, key, value) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.obj = obj; |
| _this.key = key; |
| _this.value = value; |
| return _this; |
| } |
| KeyedWrite.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitKeyedWrite(this, context); |
| }; |
| return KeyedWrite; |
| }(AST)); |
| var BindingPipe = /** @class */ (function (_super) { |
| __extends(BindingPipe, _super); |
| function BindingPipe(span, sourceSpan, exp, name, args, nameSpan) { |
| var _this = _super.call(this, span, sourceSpan, nameSpan) || this; |
| _this.exp = exp; |
| _this.name = name; |
| _this.args = args; |
| return _this; |
| } |
| BindingPipe.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitPipe(this, context); |
| }; |
| return BindingPipe; |
| }(ASTWithName)); |
| var LiteralPrimitive = /** @class */ (function (_super) { |
| __extends(LiteralPrimitive, _super); |
| function LiteralPrimitive(span, sourceSpan, value) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.value = value; |
| return _this; |
| } |
| LiteralPrimitive.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitLiteralPrimitive(this, context); |
| }; |
| return LiteralPrimitive; |
| }(AST)); |
| var LiteralArray = /** @class */ (function (_super) { |
| __extends(LiteralArray, _super); |
| function LiteralArray(span, sourceSpan, expressions) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.expressions = expressions; |
| return _this; |
| } |
| LiteralArray.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitLiteralArray(this, context); |
| }; |
| return LiteralArray; |
| }(AST)); |
| var LiteralMap = /** @class */ (function (_super) { |
| __extends(LiteralMap, _super); |
| function LiteralMap(span, sourceSpan, keys, values) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.keys = keys; |
| _this.values = values; |
| return _this; |
| } |
| LiteralMap.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitLiteralMap(this, context); |
| }; |
| return LiteralMap; |
| }(AST)); |
| var Interpolation = /** @class */ (function (_super) { |
| __extends(Interpolation, _super); |
| function Interpolation(span, sourceSpan, strings, expressions) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.strings = strings; |
| _this.expressions = expressions; |
| return _this; |
| } |
| Interpolation.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitInterpolation(this, context); |
| }; |
| return Interpolation; |
| }(AST)); |
| var Binary = /** @class */ (function (_super) { |
| __extends(Binary, _super); |
| function Binary(span, sourceSpan, operation, left, right) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.operation = operation; |
| _this.left = left; |
| _this.right = right; |
| return _this; |
| } |
| Binary.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitBinary(this, context); |
| }; |
| return Binary; |
| }(AST)); |
| /** |
| * For backwards compatibility reasons, `Unary` inherits from `Binary` and mimics the binary AST |
| * node that was originally used. This inheritance relation can be deleted in some future major, |
| * after consumers have been given a chance to fully support Unary. |
| */ |
| var Unary = /** @class */ (function (_super) { |
| __extends(Unary, _super); |
| /** |
| * During the deprecation period this constructor is private, to avoid consumers from creating |
| * a `Unary` with the fallback properties for `Binary`. |
| */ |
| function Unary(span, sourceSpan, operator, expr, binaryOp, binaryLeft, binaryRight) { |
| var _this = _super.call(this, span, sourceSpan, binaryOp, binaryLeft, binaryRight) || this; |
| _this.operator = operator; |
| _this.expr = expr; |
| return _this; |
| } |
| /** |
| * Creates a unary minus expression "-x", represented as `Binary` using "0 - x". |
| */ |
| Unary.createMinus = function (span, sourceSpan, expr) { |
| return new Unary(span, sourceSpan, '-', expr, '-', new LiteralPrimitive(span, sourceSpan, 0), expr); |
| }; |
| /** |
| * Creates a unary plus expression "+x", represented as `Binary` using "x - 0". |
| */ |
| Unary.createPlus = function (span, sourceSpan, expr) { |
| return new Unary(span, sourceSpan, '+', expr, '-', expr, new LiteralPrimitive(span, sourceSpan, 0)); |
| }; |
| Unary.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| if (visitor.visitUnary !== undefined) { |
| return visitor.visitUnary(this, context); |
| } |
| return visitor.visitBinary(this, context); |
| }; |
| return Unary; |
| }(Binary)); |
| var PrefixNot = /** @class */ (function (_super) { |
| __extends(PrefixNot, _super); |
| function PrefixNot(span, sourceSpan, expression) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.expression = expression; |
| return _this; |
| } |
| PrefixNot.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitPrefixNot(this, context); |
| }; |
| return PrefixNot; |
| }(AST)); |
| var NonNullAssert = /** @class */ (function (_super) { |
| __extends(NonNullAssert, _super); |
| function NonNullAssert(span, sourceSpan, expression) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.expression = expression; |
| return _this; |
| } |
| NonNullAssert.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitNonNullAssert(this, context); |
| }; |
| return NonNullAssert; |
| }(AST)); |
| var MethodCall = /** @class */ (function (_super) { |
| __extends(MethodCall, _super); |
| function MethodCall(span, sourceSpan, nameSpan, receiver, name, args) { |
| var _this = _super.call(this, span, sourceSpan, nameSpan) || this; |
| _this.receiver = receiver; |
| _this.name = name; |
| _this.args = args; |
| return _this; |
| } |
| MethodCall.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitMethodCall(this, context); |
| }; |
| return MethodCall; |
| }(ASTWithName)); |
| var SafeMethodCall = /** @class */ (function (_super) { |
| __extends(SafeMethodCall, _super); |
| function SafeMethodCall(span, sourceSpan, nameSpan, receiver, name, args) { |
| var _this = _super.call(this, span, sourceSpan, nameSpan) || this; |
| _this.receiver = receiver; |
| _this.name = name; |
| _this.args = args; |
| return _this; |
| } |
| SafeMethodCall.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitSafeMethodCall(this, context); |
| }; |
| return SafeMethodCall; |
| }(ASTWithName)); |
| var FunctionCall = /** @class */ (function (_super) { |
| __extends(FunctionCall, _super); |
| function FunctionCall(span, sourceSpan, target, args) { |
| var _this = _super.call(this, span, sourceSpan) || this; |
| _this.target = target; |
| _this.args = args; |
| return _this; |
| } |
| FunctionCall.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| return visitor.visitFunctionCall(this, context); |
| }; |
| return FunctionCall; |
| }(AST)); |
| /** |
| * Records the absolute position of a text span in a source file, where `start` and `end` are the |
| * starting and ending byte offsets, respectively, of the text span in a source file. |
| */ |
| var AbsoluteSourceSpan = /** @class */ (function () { |
| function AbsoluteSourceSpan(start, end) { |
| this.start = start; |
| this.end = end; |
| } |
| return AbsoluteSourceSpan; |
| }()); |
| var ASTWithSource = /** @class */ (function (_super) { |
| __extends(ASTWithSource, _super); |
| function ASTWithSource(ast, source, location, absoluteOffset, errors) { |
| var _this = _super.call(this, new ParseSpan(0, source === null ? 0 : source.length), new AbsoluteSourceSpan(absoluteOffset, source === null ? absoluteOffset : absoluteOffset + source.length)) || this; |
| _this.ast = ast; |
| _this.source = source; |
| _this.location = location; |
| _this.errors = errors; |
| return _this; |
| } |
| ASTWithSource.prototype.visit = function (visitor, context) { |
| if (context === void 0) { context = null; } |
| if (visitor.visitASTWithSource) { |
| return visitor.visitASTWithSource(this, context); |
| } |
| return this.ast.visit(visitor, context); |
| }; |
| ASTWithSource.prototype.toString = function () { |
| return this.source + " in " + this.location; |
| }; |
| return ASTWithSource; |
| }(AST)); |
| var VariableBinding = /** @class */ (function () { |
| /** |
| * @param sourceSpan entire span of the binding. |
| * @param key name of the LHS along with its span. |
| * @param value optional value for the RHS along with its span. |
| */ |
| function VariableBinding(sourceSpan, key, value) { |
| this.sourceSpan = sourceSpan; |
| this.key = key; |
| this.value = value; |
| } |
| return VariableBinding; |
| }()); |
| var ExpressionBinding = /** @class */ (function () { |
| /** |
| * @param sourceSpan entire span of the binding. |
| * @param key binding name, like ngForOf, ngForTrackBy, ngIf, along with its |
| * span. Note that the length of the span may not be the same as |
| * `key.source.length`. For example, |
| * 1. key.source = ngFor, key.span is for "ngFor" |
| * 2. key.source = ngForOf, key.span is for "of" |
| * 3. key.source = ngForTrackBy, key.span is for "trackBy" |
| * @param value optional expression for the RHS. |
| */ |
| function ExpressionBinding(sourceSpan, key, value) { |
| this.sourceSpan = sourceSpan; |
| this.key = key; |
| this.value = value; |
| } |
| return ExpressionBinding; |
| }()); |
| var RecursiveAstVisitor$1 = /** @class */ (function () { |
| function RecursiveAstVisitor() { |
| } |
| RecursiveAstVisitor.prototype.visit = function (ast, context) { |
| // The default implementation just visits every node. |
| // Classes that extend RecursiveAstVisitor should override this function |
| // to selectively visit the specified node. |
| ast.visit(this, context); |
| }; |
| RecursiveAstVisitor.prototype.visitUnary = function (ast, context) { |
| this.visit(ast.expr, context); |
| }; |
| RecursiveAstVisitor.prototype.visitBinary = function (ast, context) { |
| this.visit(ast.left, context); |
| this.visit(ast.right, context); |
| }; |
| RecursiveAstVisitor.prototype.visitChain = function (ast, context) { |
| this.visitAll(ast.expressions, context); |
| }; |
| RecursiveAstVisitor.prototype.visitConditional = function (ast, context) { |
| this.visit(ast.condition, context); |
| this.visit(ast.trueExp, context); |
| this.visit(ast.falseExp, context); |
| }; |
| RecursiveAstVisitor.prototype.visitPipe = function (ast, context) { |
| this.visit(ast.exp, context); |
| this.visitAll(ast.args, context); |
| }; |
| RecursiveAstVisitor.prototype.visitFunctionCall = function (ast, context) { |
| if (ast.target) { |
| this.visit(ast.target, context); |
| } |
| this.visitAll(ast.args, context); |
| }; |
| RecursiveAstVisitor.prototype.visitImplicitReceiver = function (ast, context) { }; |
| RecursiveAstVisitor.prototype.visitThisReceiver = function (ast, context) { }; |
| RecursiveAstVisitor.prototype.visitInterpolation = function (ast, context) { |
| this.visitAll(ast.expressions, context); |
| }; |
| RecursiveAstVisitor.prototype.visitKeyedRead = function (ast, context) { |
| this.visit(ast.obj, context); |
| this.visit(ast.key, context); |
| }; |
| RecursiveAstVisitor.prototype.visitKeyedWrite = function (ast, context) { |
| this.visit(ast.obj, context); |
| this.visit(ast.key, context); |
| this.visit(ast.value, context); |
| }; |
| RecursiveAstVisitor.prototype.visitLiteralArray = function (ast, context) { |
| this.visitAll(ast.expressions, context); |
| }; |
| RecursiveAstVisitor.prototype.visitLiteralMap = function (ast, context) { |
| this.visitAll(ast.values, context); |
| }; |
| RecursiveAstVisitor.prototype.visitLiteralPrimitive = function (ast, context) { }; |
| RecursiveAstVisitor.prototype.visitMethodCall = function (ast, context) { |
| this.visit(ast.receiver, context); |
| this.visitAll(ast.args, context); |
| }; |
| RecursiveAstVisitor.prototype.visitPrefixNot = function (ast, context) { |
| this.visit(ast.expression, context); |
| }; |
| RecursiveAstVisitor.prototype.visitNonNullAssert = function (ast, context) { |
| this.visit(ast.expression, context); |
| }; |
| RecursiveAstVisitor.prototype.visitPropertyRead = function (ast, context) { |
| this.visit(ast.receiver, context); |
| }; |
| RecursiveAstVisitor.prototype.visitPropertyWrite = function (ast, context) { |
| this.visit(ast.receiver, context); |
| this.visit(ast.value, context); |
| }; |
| RecursiveAstVisitor.prototype.visitSafePropertyRead = function (ast, context) { |
| this.visit(ast.receiver, context); |
| }; |
| RecursiveAstVisitor.prototype.visitSafeMethodCall = function (ast, context) { |
| this.visit(ast.receiver, context); |
| this.visitAll(ast.args, context); |
| }; |
| RecursiveAstVisitor.prototype.visitQuote = function (ast, context) { }; |
| // This is not part of the AstVisitor interface, just a helper method |
| RecursiveAstVisitor.prototype.visitAll = function (asts, context) { |
| var e_1, _b; |
| try { |
| for (var asts_1 = __values(asts), asts_1_1 = asts_1.next(); !asts_1_1.done; asts_1_1 = asts_1.next()) { |
| var ast = asts_1_1.value; |
| this.visit(ast, context); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (asts_1_1 && !asts_1_1.done && (_b = asts_1.return)) _b.call(asts_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| }; |
| return RecursiveAstVisitor; |
| }()); |
| var AstTransformer$1 = /** @class */ (function () { |
| function AstTransformer() { |
| } |
| AstTransformer.prototype.visitImplicitReceiver = function (ast, context) { |
| return ast; |
| }; |
| AstTransformer.prototype.visitThisReceiver = function (ast, context) { |
| return ast; |
| }; |
| AstTransformer.prototype.visitInterpolation = function (ast, context) { |
| return new Interpolation(ast.span, ast.sourceSpan, ast.strings, this.visitAll(ast.expressions)); |
| }; |
| AstTransformer.prototype.visitLiteralPrimitive = function (ast, context) { |
| return new LiteralPrimitive(ast.span, ast.sourceSpan, ast.value); |
| }; |
| AstTransformer.prototype.visitPropertyRead = function (ast, context) { |
| return new PropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name); |
| }; |
| AstTransformer.prototype.visitPropertyWrite = function (ast, context) { |
| return new PropertyWrite(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name, ast.value.visit(this)); |
| }; |
| AstTransformer.prototype.visitSafePropertyRead = function (ast, context) { |
| return new SafePropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name); |
| }; |
| AstTransformer.prototype.visitMethodCall = function (ast, context) { |
| return new MethodCall(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name, this.visitAll(ast.args)); |
| }; |
| AstTransformer.prototype.visitSafeMethodCall = function (ast, context) { |
| return new SafeMethodCall(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name, this.visitAll(ast.args)); |
| }; |
| AstTransformer.prototype.visitFunctionCall = function (ast, context) { |
| return new FunctionCall(ast.span, ast.sourceSpan, ast.target.visit(this), this.visitAll(ast.args)); |
| }; |
| AstTransformer.prototype.visitLiteralArray = function (ast, context) { |
| return new LiteralArray(ast.span, ast.sourceSpan, this.visitAll(ast.expressions)); |
| }; |
| AstTransformer.prototype.visitLiteralMap = function (ast, context) { |
| return new LiteralMap(ast.span, ast.sourceSpan, ast.keys, this.visitAll(ast.values)); |
| }; |
| AstTransformer.prototype.visitUnary = function (ast, context) { |
| switch (ast.operator) { |
| case '+': |
| return Unary.createPlus(ast.span, ast.sourceSpan, ast.expr.visit(this)); |
| case '-': |
| return Unary.createMinus(ast.span, ast.sourceSpan, ast.expr.visit(this)); |
| default: |
| throw new Error("Unknown unary operator " + ast.operator); |
| } |
| }; |
| AstTransformer.prototype.visitBinary = function (ast, context) { |
| return new Binary(ast.span, ast.sourceSpan, ast.operation, ast.left.visit(this), ast.right.visit(this)); |
| }; |
| AstTransformer.prototype.visitPrefixNot = function (ast, context) { |
| return new PrefixNot(ast.span, ast.sourceSpan, ast.expression.visit(this)); |
| }; |
| AstTransformer.prototype.visitNonNullAssert = function (ast, context) { |
| return new NonNullAssert(ast.span, ast.sourceSpan, ast.expression.visit(this)); |
| }; |
| AstTransformer.prototype.visitConditional = function (ast, context) { |
| return new Conditional(ast.span, ast.sourceSpan, ast.condition.visit(this), ast.trueExp.visit(this), ast.falseExp.visit(this)); |
| }; |
| AstTransformer.prototype.visitPipe = function (ast, context) { |
| return new BindingPipe(ast.span, ast.sourceSpan, ast.exp.visit(this), ast.name, this.visitAll(ast.args), ast.nameSpan); |
| }; |
| AstTransformer.prototype.visitKeyedRead = function (ast, context) { |
| return new KeyedRead(ast.span, ast.sourceSpan, ast.obj.visit(this), ast.key.visit(this)); |
| }; |
| AstTransformer.prototype.visitKeyedWrite = function (ast, context) { |
| return new KeyedWrite(ast.span, ast.sourceSpan, ast.obj.visit(this), ast.key.visit(this), ast.value.visit(this)); |
| }; |
| AstTransformer.prototype.visitAll = function (asts) { |
| var res = []; |
| for (var i = 0; i < asts.length; ++i) { |
| res[i] = asts[i].visit(this); |
| } |
| return res; |
| }; |
| AstTransformer.prototype.visitChain = function (ast, context) { |
| return new Chain(ast.span, ast.sourceSpan, this.visitAll(ast.expressions)); |
| }; |
| AstTransformer.prototype.visitQuote = function (ast, context) { |
| return new Quote(ast.span, ast.sourceSpan, ast.prefix, ast.uninterpretedExpression, ast.location); |
| }; |
| return AstTransformer; |
| }()); |
| // A transformer that only creates new nodes if the transformer makes a change or |
| // a change is made a child node. |
| var AstMemoryEfficientTransformer = /** @class */ (function () { |
| function AstMemoryEfficientTransformer() { |
| } |
| AstMemoryEfficientTransformer.prototype.visitImplicitReceiver = function (ast, context) { |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitThisReceiver = function (ast, context) { |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitInterpolation = function (ast, context) { |
| var expressions = this.visitAll(ast.expressions); |
| if (expressions !== ast.expressions) |
| return new Interpolation(ast.span, ast.sourceSpan, ast.strings, expressions); |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitLiteralPrimitive = function (ast, context) { |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitPropertyRead = function (ast, context) { |
| var receiver = ast.receiver.visit(this); |
| if (receiver !== ast.receiver) { |
| return new PropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitPropertyWrite = function (ast, context) { |
| var receiver = ast.receiver.visit(this); |
| var value = ast.value.visit(this); |
| if (receiver !== ast.receiver || value !== ast.value) { |
| return new PropertyWrite(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name, value); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitSafePropertyRead = function (ast, context) { |
| var receiver = ast.receiver.visit(this); |
| if (receiver !== ast.receiver) { |
| return new SafePropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitMethodCall = function (ast, context) { |
| var receiver = ast.receiver.visit(this); |
| var args = this.visitAll(ast.args); |
| if (receiver !== ast.receiver || args !== ast.args) { |
| return new MethodCall(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name, args); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitSafeMethodCall = function (ast, context) { |
| var receiver = ast.receiver.visit(this); |
| var args = this.visitAll(ast.args); |
| if (receiver !== ast.receiver || args !== ast.args) { |
| return new SafeMethodCall(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name, args); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitFunctionCall = function (ast, context) { |
| var target = ast.target && ast.target.visit(this); |
| var args = this.visitAll(ast.args); |
| if (target !== ast.target || args !== ast.args) { |
| return new FunctionCall(ast.span, ast.sourceSpan, target, args); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitLiteralArray = function (ast, context) { |
| var expressions = this.visitAll(ast.expressions); |
| if (expressions !== ast.expressions) { |
| return new LiteralArray(ast.span, ast.sourceSpan, expressions); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitLiteralMap = function (ast, context) { |
| var values = this.visitAll(ast.values); |
| if (values !== ast.values) { |
| return new LiteralMap(ast.span, ast.sourceSpan, ast.keys, values); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitUnary = function (ast, context) { |
| var expr = ast.expr.visit(this); |
| if (expr !== ast.expr) { |
| switch (ast.operator) { |
| case '+': |
| return Unary.createPlus(ast.span, ast.sourceSpan, expr); |
| case '-': |
| return Unary.createMinus(ast.span, ast.sourceSpan, expr); |
| default: |
| throw new Error("Unknown unary operator " + ast.operator); |
| } |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitBinary = function (ast, context) { |
| var left = ast.left.visit(this); |
| var right = ast.right.visit(this); |
| if (left !== ast.left || right !== ast.right) { |
| return new Binary(ast.span, ast.sourceSpan, ast.operation, left, right); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitPrefixNot = function (ast, context) { |
| var expression = ast.expression.visit(this); |
| if (expression !== ast.expression) { |
| return new PrefixNot(ast.span, ast.sourceSpan, expression); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitNonNullAssert = function (ast, context) { |
| var expression = ast.expression.visit(this); |
| if (expression !== ast.expression) { |
| return new NonNullAssert(ast.span, ast.sourceSpan, expression); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitConditional = function (ast, context) { |
| var condition = ast.condition.visit(this); |
| var trueExp = ast.trueExp.visit(this); |
| var falseExp = ast.falseExp.visit(this); |
| if (condition !== ast.condition || trueExp !== ast.trueExp || falseExp !== ast.falseExp) { |
| return new Conditional(ast.span, ast.sourceSpan, condition, trueExp, falseExp); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitPipe = function (ast, context) { |
| var exp = ast.exp.visit(this); |
| var args = this.visitAll(ast.args); |
| if (exp !== ast.exp || args !== ast.args) { |
| return new BindingPipe(ast.span, ast.sourceSpan, exp, ast.name, args, ast.nameSpan); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitKeyedRead = function (ast, context) { |
| var obj = ast.obj.visit(this); |
| var key = ast.key.visit(this); |
| if (obj !== ast.obj || key !== ast.key) { |
| return new KeyedRead(ast.span, ast.sourceSpan, obj, key); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitKeyedWrite = function (ast, context) { |
| var obj = ast.obj.visit(this); |
| var key = ast.key.visit(this); |
| var value = ast.value.visit(this); |
| if (obj !== ast.obj || key !== ast.key || value !== ast.value) { |
| return new KeyedWrite(ast.span, ast.sourceSpan, obj, key, value); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitAll = function (asts) { |
| var res = []; |
| var modified = false; |
| for (var i = 0; i < asts.length; ++i) { |
| var original = asts[i]; |
| var value = original.visit(this); |
| res[i] = value; |
| modified = modified || value !== original; |
| } |
| return modified ? res : asts; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitChain = function (ast, context) { |
| var expressions = this.visitAll(ast.expressions); |
| if (expressions !== ast.expressions) { |
| return new Chain(ast.span, ast.sourceSpan, expressions); |
| } |
| return ast; |
| }; |
| AstMemoryEfficientTransformer.prototype.visitQuote = function (ast, context) { |
| return ast; |
| }; |
| return AstMemoryEfficientTransformer; |
| }()); |
| // Bindings |
| var ParsedProperty = /** @class */ (function () { |
| function ParsedProperty(name, expression, type, |
| // TODO(FW-2095): `keySpan` should really be required but allows `undefined` so VE does |
| // not need to be updated. Make `keySpan` required when VE is removed. |
| sourceSpan, keySpan, valueSpan) { |
| this.name = name; |
| this.expression = expression; |
| this.type = type; |
| this.sourceSpan = sourceSpan; |
| this.keySpan = keySpan; |
| this.valueSpan = valueSpan; |
| this.isLiteral = this.type === exports.ParsedPropertyType.LITERAL_ATTR; |
| this.isAnimation = this.type === exports.ParsedPropertyType.ANIMATION; |
| } |
| return ParsedProperty; |
| }()); |
| (function (ParsedPropertyType) { |
| ParsedPropertyType[ParsedPropertyType["DEFAULT"] = 0] = "DEFAULT"; |
| ParsedPropertyType[ParsedPropertyType["LITERAL_ATTR"] = 1] = "LITERAL_ATTR"; |
| ParsedPropertyType[ParsedPropertyType["ANIMATION"] = 2] = "ANIMATION"; |
| })(exports.ParsedPropertyType || (exports.ParsedPropertyType = {})); |
| var ParsedEvent = /** @class */ (function () { |
| // Regular events have a target |
| // Animation events have a phase |
| function ParsedEvent(name, targetOrPhase, type, handler, sourceSpan, |
| // TODO(FW-2095): keySpan should be required but was made optional to avoid changing VE |
| handlerSpan, keySpan) { |
| this.name = name; |
| this.targetOrPhase = targetOrPhase; |
| this.type = type; |
| this.handler = handler; |
| this.sourceSpan = sourceSpan; |
| this.handlerSpan = handlerSpan; |
| this.keySpan = keySpan; |
| } |
| return ParsedEvent; |
| }()); |
| /** |
| * ParsedVariable represents a variable declaration in a microsyntax expression. |
| */ |
| var ParsedVariable = /** @class */ (function () { |
| function ParsedVariable(name, value, sourceSpan, keySpan, valueSpan) { |
| this.name = name; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| this.keySpan = keySpan; |
| this.valueSpan = valueSpan; |
| } |
| return ParsedVariable; |
| }()); |
| var BoundElementProperty = /** @class */ (function () { |
| function BoundElementProperty(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan) { |
| this.name = name; |
| this.type = type; |
| this.securityContext = securityContext; |
| this.value = value; |
| this.unit = unit; |
| this.sourceSpan = sourceSpan; |
| this.keySpan = keySpan; |
| this.valueSpan = valueSpan; |
| } |
| return BoundElementProperty; |
| }()); |
| |
| var EventHandlerVars = /** @class */ (function () { |
| function EventHandlerVars() { |
| } |
| return EventHandlerVars; |
| }()); |
| EventHandlerVars.event = variable('$event'); |
| var ConvertActionBindingResult = /** @class */ (function () { |
| function ConvertActionBindingResult( |
| /** |
| * Render2 compatible statements, |
| */ |
| stmts, |
| /** |
| * Variable name used with render2 compatible statements. |
| */ |
| allowDefault) { |
| this.stmts = stmts; |
| this.allowDefault = allowDefault; |
| /** |
| * This is bit of a hack. It converts statements which render2 expects to statements which are |
| * expected by render3. |
| * |
| * Example: `<div click="doSomething($event)">` will generate: |
| * |
| * Render3: |
| * ``` |
| * const pd_b:any = ((<any>ctx.doSomething($event)) !== false); |
| * return pd_b; |
| * ``` |
| * |
| * but render2 expects: |
| * ``` |
| * return ctx.doSomething($event); |
| * ``` |
| */ |
| // TODO(misko): remove this hack once we no longer support ViewEngine. |
| this.render3Stmts = stmts.map(function (statement) { |
| if (statement instanceof DeclareVarStmt && statement.name == allowDefault.name && |
| statement.value instanceof BinaryOperatorExpr) { |
| var lhs = statement.value.lhs; |
| return new ReturnStatement(lhs.value); |
| } |
| return statement; |
| }); |
| } |
| return ConvertActionBindingResult; |
| }()); |
| /** |
| * Converts the given expression AST into an executable output AST, assuming the expression is |
| * used in an action binding (e.g. an event handler). |
| */ |
| function convertActionBinding(localResolver, implicitReceiver, action, bindingId, interpolationFunction, baseSourceSpan, implicitReceiverAccesses, globals) { |
| if (!localResolver) { |
| localResolver = new DefaultLocalResolver(globals); |
| } |
| var actionWithoutBuiltins = convertPropertyBindingBuiltins({ |
| createLiteralArrayConverter: function (argCount) { |
| // Note: no caching for literal arrays in actions. |
| return function (args) { return literalArr(args); }; |
| }, |
| createLiteralMapConverter: function (keys) { |
| // Note: no caching for literal maps in actions. |
| return function (values) { |
| var entries = keys.map(function (k, i) { return ({ |
| key: k.key, |
| value: values[i], |
| quoted: k.quoted, |
| }); }); |
| return literalMap(entries); |
| }; |
| }, |
| createPipeConverter: function (name) { |
| throw new Error("Illegal State: Actions are not allowed to contain pipes. Pipe: " + name); |
| } |
| }, action); |
| var visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, interpolationFunction, baseSourceSpan, implicitReceiverAccesses); |
| var actionStmts = []; |
| flattenStatements(actionWithoutBuiltins.visit(visitor, _Mode.Statement), actionStmts); |
| prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts); |
| if (visitor.usesImplicitReceiver) { |
| localResolver.notifyImplicitReceiverUse(); |
| } |
| var lastIndex = actionStmts.length - 1; |
| var preventDefaultVar = null; |
| if (lastIndex >= 0) { |
| var lastStatement = actionStmts[lastIndex]; |
| var returnExpr = convertStmtIntoExpression(lastStatement); |
| if (returnExpr) { |
| // Note: We need to cast the result of the method call to dynamic, |
| // as it might be a void method! |
| preventDefaultVar = createPreventDefaultVar(bindingId); |
| actionStmts[lastIndex] = |
| preventDefaultVar.set(returnExpr.cast(DYNAMIC_TYPE).notIdentical(literal(false))) |
| .toDeclStmt(null, [exports.StmtModifier.Final]); |
| } |
| } |
| return new ConvertActionBindingResult(actionStmts, preventDefaultVar); |
| } |
| function convertPropertyBindingBuiltins(converterFactory, ast) { |
| return convertBuiltins(converterFactory, ast); |
| } |
| var ConvertPropertyBindingResult = /** @class */ (function () { |
| function ConvertPropertyBindingResult(stmts, currValExpr) { |
| this.stmts = stmts; |
| this.currValExpr = currValExpr; |
| } |
| return ConvertPropertyBindingResult; |
| }()); |
| var BindingForm; |
| (function (BindingForm) { |
| // The general form of binding expression, supports all expressions. |
| BindingForm[BindingForm["General"] = 0] = "General"; |
| // Try to generate a simple binding (no temporaries or statements) |
| // otherwise generate a general binding |
| BindingForm[BindingForm["TrySimple"] = 1] = "TrySimple"; |
| // Inlines assignment of temporaries into the generated expression. The result may still |
| // have statements attached for declarations of temporary variables. |
| // This is the only relevant form for Ivy, the other forms are only used in ViewEngine. |
| BindingForm[BindingForm["Expression"] = 2] = "Expression"; |
| })(BindingForm || (BindingForm = {})); |
| /** |
| * Converts the given expression AST into an executable output AST, assuming the expression |
| * is used in property binding. The expression has to be preprocessed via |
| * `convertPropertyBindingBuiltins`. |
| */ |
| function convertPropertyBinding(localResolver, implicitReceiver, expressionWithoutBuiltins, bindingId, form, interpolationFunction) { |
| if (!localResolver) { |
| localResolver = new DefaultLocalResolver(); |
| } |
| var visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, interpolationFunction); |
| var outputExpr = expressionWithoutBuiltins.visit(visitor, _Mode.Expression); |
| var stmts = getStatementsFromVisitor(visitor, bindingId); |
| if (visitor.usesImplicitReceiver) { |
| localResolver.notifyImplicitReceiverUse(); |
| } |
| if (visitor.temporaryCount === 0 && form == BindingForm.TrySimple) { |
| return new ConvertPropertyBindingResult([], outputExpr); |
| } |
| else if (form === BindingForm.Expression) { |
| return new ConvertPropertyBindingResult(stmts, outputExpr); |
| } |
| var currValExpr = createCurrValueExpr(bindingId); |
| stmts.push(currValExpr.set(outputExpr).toDeclStmt(DYNAMIC_TYPE, [exports.StmtModifier.Final])); |
| return new ConvertPropertyBindingResult(stmts, currValExpr); |
| } |
| /** |
| * Given some expression, such as a binding or interpolation expression, and a context expression to |
| * look values up on, visit each facet of the given expression resolving values from the context |
| * expression such that a list of arguments can be derived from the found values that can be used as |
| * arguments to an external update instruction. |
| * |
| * @param localResolver The resolver to use to look up expressions by name appropriately |
| * @param contextVariableExpression The expression representing the context variable used to create |
| * the final argument expressions |
| * @param expressionWithArgumentsToExtract The expression to visit to figure out what values need to |
| * be resolved and what arguments list to build. |
| * @param bindingId A name prefix used to create temporary variable names if they're needed for the |
| * arguments generated |
| * @returns An array of expressions that can be passed as arguments to instruction expressions like |
| * `o.importExpr(R3.propertyInterpolate).callFn(result)` |
| */ |
| function convertUpdateArguments(localResolver, contextVariableExpression, expressionWithArgumentsToExtract, bindingId) { |
| var visitor = new _AstToIrVisitor(localResolver, contextVariableExpression, bindingId, undefined); |
| var outputExpr = expressionWithArgumentsToExtract.visit(visitor, _Mode.Expression); |
| if (visitor.usesImplicitReceiver) { |
| localResolver.notifyImplicitReceiverUse(); |
| } |
| var stmts = getStatementsFromVisitor(visitor, bindingId); |
| // Removing the first argument, because it was a length for ViewEngine, not Ivy. |
| var args = outputExpr.args.slice(1); |
| if (expressionWithArgumentsToExtract instanceof Interpolation) { |
| // If we're dealing with an interpolation of 1 value with an empty prefix and suffix, reduce the |
| // args returned to just the value, because we're going to pass it to a special instruction. |
| var strings = expressionWithArgumentsToExtract.strings; |
| if (args.length === 3 && strings[0] === '' && strings[1] === '') { |
| // Single argument interpolate instructions. |
| args = [args[1]]; |
| } |
| else if (args.length >= 19) { |
| // 19 or more arguments must be passed to the `interpolateV`-style instructions, which accept |
| // an array of arguments |
| args = [literalArr(args)]; |
| } |
| } |
| return { stmts: stmts, args: args }; |
| } |
| function getStatementsFromVisitor(visitor, bindingId) { |
| var stmts = []; |
| for (var i = 0; i < visitor.temporaryCount; i++) { |
| stmts.push(temporaryDeclaration(bindingId, i)); |
| } |
| return stmts; |
| } |
| function convertBuiltins(converterFactory, ast) { |
| var visitor = new _BuiltinAstConverter(converterFactory); |
| return ast.visit(visitor); |
| } |
| function temporaryName(bindingId, temporaryNumber) { |
| return "tmp_" + bindingId + "_" + temporaryNumber; |
| } |
| function temporaryDeclaration(bindingId, temporaryNumber) { |
| return new DeclareVarStmt(temporaryName(bindingId, temporaryNumber), NULL_EXPR); |
| } |
| function prependTemporaryDecls(temporaryCount, bindingId, statements) { |
| for (var i = temporaryCount - 1; i >= 0; i--) { |
| statements.unshift(temporaryDeclaration(bindingId, i)); |
| } |
| } |
| var _Mode; |
| (function (_Mode) { |
| _Mode[_Mode["Statement"] = 0] = "Statement"; |
| _Mode[_Mode["Expression"] = 1] = "Expression"; |
| })(_Mode || (_Mode = {})); |
| function ensureStatementMode(mode, ast) { |
| if (mode !== _Mode.Statement) { |
| throw new Error("Expected a statement, but saw " + ast); |
| } |
| } |
| function ensureExpressionMode(mode, ast) { |
| if (mode !== _Mode.Expression) { |
| throw new Error("Expected an expression, but saw " + ast); |
| } |
| } |
| function convertToStatementIfNeeded(mode, expr) { |
| if (mode === _Mode.Statement) { |
| return expr.toStmt(); |
| } |
| else { |
| return expr; |
| } |
| } |
| var _BuiltinAstConverter = /** @class */ (function (_super) { |
| __extends(_BuiltinAstConverter, _super); |
| function _BuiltinAstConverter(_converterFactory) { |
| var _this = _super.call(this) || this; |
| _this._converterFactory = _converterFactory; |
| return _this; |
| } |
| _BuiltinAstConverter.prototype.visitPipe = function (ast, context) { |
| var _this = this; |
| var args = __spread([ast.exp], ast.args).map(function (ast) { return ast.visit(_this, context); }); |
| return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createPipeConverter(ast.name, args.length)); |
| }; |
| _BuiltinAstConverter.prototype.visitLiteralArray = function (ast, context) { |
| var _this = this; |
| var args = ast.expressions.map(function (ast) { return ast.visit(_this, context); }); |
| return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createLiteralArrayConverter(ast.expressions.length)); |
| }; |
| _BuiltinAstConverter.prototype.visitLiteralMap = function (ast, context) { |
| var _this = this; |
| var args = ast.values.map(function (ast) { return ast.visit(_this, context); }); |
| return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createLiteralMapConverter(ast.keys)); |
| }; |
| return _BuiltinAstConverter; |
| }(AstTransformer$1)); |
| var _AstToIrVisitor = /** @class */ (function () { |
| function _AstToIrVisitor(_localResolver, _implicitReceiver, bindingId, interpolationFunction, baseSourceSpan, implicitReceiverAccesses) { |
| this._localResolver = _localResolver; |
| this._implicitReceiver = _implicitReceiver; |
| this.bindingId = bindingId; |
| this.interpolationFunction = interpolationFunction; |
| this.baseSourceSpan = baseSourceSpan; |
| this.implicitReceiverAccesses = implicitReceiverAccesses; |
| this._nodeMap = new Map(); |
| this._resultMap = new Map(); |
| this._currentTemporary = 0; |
| this.temporaryCount = 0; |
| this.usesImplicitReceiver = false; |
| } |
| _AstToIrVisitor.prototype.visitUnary = function (ast, mode) { |
| var op; |
| switch (ast.operator) { |
| case '+': |
| op = exports.UnaryOperator.Plus; |
| break; |
| case '-': |
| op = exports.UnaryOperator.Minus; |
| break; |
| default: |
| throw new Error("Unsupported operator " + ast.operator); |
| } |
| return convertToStatementIfNeeded(mode, new UnaryOperatorExpr(op, this._visit(ast.expr, _Mode.Expression), undefined, this.convertSourceSpan(ast.span))); |
| }; |
| _AstToIrVisitor.prototype.visitBinary = function (ast, mode) { |
| var op; |
| switch (ast.operation) { |
| case '+': |
| op = exports.BinaryOperator.Plus; |
| break; |
| case '-': |
| op = exports.BinaryOperator.Minus; |
| break; |
| case '*': |
| op = exports.BinaryOperator.Multiply; |
| break; |
| case '/': |
| op = exports.BinaryOperator.Divide; |
| break; |
| case '%': |
| op = exports.BinaryOperator.Modulo; |
| break; |
| case '&&': |
| op = exports.BinaryOperator.And; |
| break; |
| case '||': |
| op = exports.BinaryOperator.Or; |
| break; |
| case '==': |
| op = exports.BinaryOperator.Equals; |
| break; |
| case '!=': |
| op = exports.BinaryOperator.NotEquals; |
| break; |
| case '===': |
| op = exports.BinaryOperator.Identical; |
| break; |
| case '!==': |
| op = exports.BinaryOperator.NotIdentical; |
| break; |
| case '<': |
| op = exports.BinaryOperator.Lower; |
| break; |
| case '>': |
| op = exports.BinaryOperator.Bigger; |
| break; |
| case '<=': |
| op = exports.BinaryOperator.LowerEquals; |
| break; |
| case '>=': |
| op = exports.BinaryOperator.BiggerEquals; |
| break; |
| default: |
| throw new Error("Unsupported operation " + ast.operation); |
| } |
| return convertToStatementIfNeeded(mode, new BinaryOperatorExpr(op, this._visit(ast.left, _Mode.Expression), this._visit(ast.right, _Mode.Expression), undefined, this.convertSourceSpan(ast.span))); |
| }; |
| _AstToIrVisitor.prototype.visitChain = function (ast, mode) { |
| ensureStatementMode(mode, ast); |
| return this.visitAll(ast.expressions, mode); |
| }; |
| _AstToIrVisitor.prototype.visitConditional = function (ast, mode) { |
| var value = this._visit(ast.condition, _Mode.Expression); |
| return convertToStatementIfNeeded(mode, value.conditional(this._visit(ast.trueExp, _Mode.Expression), this._visit(ast.falseExp, _Mode.Expression), this.convertSourceSpan(ast.span))); |
| }; |
| _AstToIrVisitor.prototype.visitPipe = function (ast, mode) { |
| throw new Error("Illegal state: Pipes should have been converted into functions. Pipe: " + ast.name); |
| }; |
| _AstToIrVisitor.prototype.visitFunctionCall = function (ast, mode) { |
| var convertedArgs = this.visitAll(ast.args, _Mode.Expression); |
| var fnResult; |
| if (ast instanceof BuiltinFunctionCall) { |
| fnResult = ast.converter(convertedArgs); |
| } |
| else { |
| fnResult = this._visit(ast.target, _Mode.Expression) |
| .callFn(convertedArgs, this.convertSourceSpan(ast.span)); |
| } |
| return convertToStatementIfNeeded(mode, fnResult); |
| }; |
| _AstToIrVisitor.prototype.visitImplicitReceiver = function (ast, mode) { |
| ensureExpressionMode(mode, ast); |
| this.usesImplicitReceiver = true; |
| return this._implicitReceiver; |
| }; |
| _AstToIrVisitor.prototype.visitThisReceiver = function (ast, mode) { |
| return this.visitImplicitReceiver(ast, mode); |
| }; |
| _AstToIrVisitor.prototype.visitInterpolation = function (ast, mode) { |
| ensureExpressionMode(mode, ast); |
| var args = [literal(ast.expressions.length)]; |
| for (var i = 0; i < ast.strings.length - 1; i++) { |
| args.push(literal(ast.strings[i])); |
| args.push(this._visit(ast.expressions[i], _Mode.Expression)); |
| } |
| args.push(literal(ast.strings[ast.strings.length - 1])); |
| if (this.interpolationFunction) { |
| return this.interpolationFunction(args); |
| } |
| return ast.expressions.length <= 9 ? |
| importExpr(Identifiers.inlineInterpolate).callFn(args) : |
| importExpr(Identifiers.interpolate).callFn([ |
| args[0], literalArr(args.slice(1), undefined, this.convertSourceSpan(ast.span)) |
| ]); |
| }; |
| _AstToIrVisitor.prototype.visitKeyedRead = function (ast, mode) { |
| var leftMostSafe = this.leftMostSafeNode(ast); |
| if (leftMostSafe) { |
| return this.convertSafeAccess(ast, leftMostSafe, mode); |
| } |
| else { |
| return convertToStatementIfNeeded(mode, this._visit(ast.obj, _Mode.Expression).key(this._visit(ast.key, _Mode.Expression))); |
| } |
| }; |
| _AstToIrVisitor.prototype.visitKeyedWrite = function (ast, mode) { |
| var obj = this._visit(ast.obj, _Mode.Expression); |
| var key = this._visit(ast.key, _Mode.Expression); |
| var value = this._visit(ast.value, _Mode.Expression); |
| return convertToStatementIfNeeded(mode, obj.key(key).set(value)); |
| }; |
| _AstToIrVisitor.prototype.visitLiteralArray = function (ast, mode) { |
| throw new Error("Illegal State: literal arrays should have been converted into functions"); |
| }; |
| _AstToIrVisitor.prototype.visitLiteralMap = function (ast, mode) { |
| throw new Error("Illegal State: literal maps should have been converted into functions"); |
| }; |
| _AstToIrVisitor.prototype.visitLiteralPrimitive = function (ast, mode) { |
| // For literal values of null, undefined, true, or false allow type interference |
| // to infer the type. |
| var type = ast.value === null || ast.value === undefined || ast.value === true || ast.value === true ? |
| INFERRED_TYPE : |
| undefined; |
| return convertToStatementIfNeeded(mode, literal(ast.value, type, this.convertSourceSpan(ast.span))); |
| }; |
| _AstToIrVisitor.prototype._getLocal = function (name, receiver) { |
| var _a; |
| if (((_a = this._localResolver.globals) === null || _a === void 0 ? void 0 : _a.has(name)) && receiver instanceof ThisReceiver) { |
| return null; |
| } |
| return this._localResolver.getLocal(name); |
| }; |
| _AstToIrVisitor.prototype.visitMethodCall = function (ast, mode) { |
| if (ast.receiver instanceof ImplicitReceiver && |
| !(ast.receiver instanceof ThisReceiver) && ast.name === '$any') { |
| var args = this.visitAll(ast.args, _Mode.Expression); |
| if (args.length != 1) { |
| throw new Error("Invalid call to $any, expected 1 argument but received " + (args.length || 'none')); |
| } |
| return args[0].cast(DYNAMIC_TYPE, this.convertSourceSpan(ast.span)); |
| } |
| var leftMostSafe = this.leftMostSafeNode(ast); |
| if (leftMostSafe) { |
| return this.convertSafeAccess(ast, leftMostSafe, mode); |
| } |
| else { |
| var args = this.visitAll(ast.args, _Mode.Expression); |
| var prevUsesImplicitReceiver = this.usesImplicitReceiver; |
| var result = null; |
| var receiver = this._visit(ast.receiver, _Mode.Expression); |
| if (receiver === this._implicitReceiver) { |
| var varExpr = this._getLocal(ast.name, ast.receiver); |
| if (varExpr) { |
| // Restore the previous "usesImplicitReceiver" state since the implicit |
| // receiver has been replaced with a resolved local expression. |
| this.usesImplicitReceiver = prevUsesImplicitReceiver; |
| result = varExpr.callFn(args); |
| this.addImplicitReceiverAccess(ast.name); |
| } |
| } |
| if (result == null) { |
| result = receiver.callMethod(ast.name, args, this.convertSourceSpan(ast.span)); |
| } |
| return convertToStatementIfNeeded(mode, result); |
| } |
| }; |
| _AstToIrVisitor.prototype.visitPrefixNot = function (ast, mode) { |
| return convertToStatementIfNeeded(mode, not(this._visit(ast.expression, _Mode.Expression))); |
| }; |
| _AstToIrVisitor.prototype.visitNonNullAssert = function (ast, mode) { |
| return convertToStatementIfNeeded(mode, assertNotNull(this._visit(ast.expression, _Mode.Expression))); |
| }; |
| _AstToIrVisitor.prototype.visitPropertyRead = function (ast, mode) { |
| var leftMostSafe = this.leftMostSafeNode(ast); |
| if (leftMostSafe) { |
| return this.convertSafeAccess(ast, leftMostSafe, mode); |
| } |
| else { |
| var result = null; |
| var prevUsesImplicitReceiver = this.usesImplicitReceiver; |
| var receiver = this._visit(ast.receiver, _Mode.Expression); |
| if (receiver === this._implicitReceiver) { |
| result = this._getLocal(ast.name, ast.receiver); |
| if (result) { |
| // Restore the previous "usesImplicitReceiver" state since the implicit |
| // receiver has been replaced with a resolved local expression. |
| this.usesImplicitReceiver = prevUsesImplicitReceiver; |
| this.addImplicitReceiverAccess(ast.name); |
| } |
| } |
| if (result == null) { |
| result = receiver.prop(ast.name); |
| } |
| return convertToStatementIfNeeded(mode, result); |
| } |
| }; |
| _AstToIrVisitor.prototype.visitPropertyWrite = function (ast, mode) { |
| var receiver = this._visit(ast.receiver, _Mode.Expression); |
| var prevUsesImplicitReceiver = this.usesImplicitReceiver; |
| var varExpr = null; |
| if (receiver === this._implicitReceiver) { |
| var localExpr = this._getLocal(ast.name, ast.receiver); |
| if (localExpr) { |
| if (localExpr instanceof ReadPropExpr) { |
| // If the local variable is a property read expression, it's a reference |
| // to a 'context.property' value and will be used as the target of the |
| // write expression. |
| varExpr = localExpr; |
| // Restore the previous "usesImplicitReceiver" state since the implicit |
| // receiver has been replaced with a resolved local expression. |
| this.usesImplicitReceiver = prevUsesImplicitReceiver; |
| this.addImplicitReceiverAccess(ast.name); |
| } |
| else { |
| // Otherwise it's an error. |
| var receiver_1 = ast.name; |
| var value = (ast.value instanceof PropertyRead) ? ast.value.name : undefined; |
| throw new Error("Cannot assign value \"" + value + "\" to template variable \"" + receiver_1 + "\". Template variables are read-only."); |
| } |
| } |
| } |
| // If no local expression could be produced, use the original receiver's |
| // property as the target. |
| if (varExpr === null) { |
| varExpr = receiver.prop(ast.name); |
| } |
| return convertToStatementIfNeeded(mode, varExpr.set(this._visit(ast.value, _Mode.Expression))); |
| }; |
| _AstToIrVisitor.prototype.visitSafePropertyRead = function (ast, mode) { |
| return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode); |
| }; |
| _AstToIrVisitor.prototype.visitSafeMethodCall = function (ast, mode) { |
| return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode); |
| }; |
| _AstToIrVisitor.prototype.visitAll = function (asts, mode) { |
| var _this = this; |
| return asts.map(function (ast) { return _this._visit(ast, mode); }); |
| }; |
| _AstToIrVisitor.prototype.visitQuote = function (ast, mode) { |
| throw new Error("Quotes are not supported for evaluation!\n Statement: " + ast.uninterpretedExpression + " located at " + ast.location); |
| }; |
| _AstToIrVisitor.prototype._visit = function (ast, mode) { |
| var result = this._resultMap.get(ast); |
| if (result) |
| return result; |
| return (this._nodeMap.get(ast) || ast).visit(this, mode); |
| }; |
| _AstToIrVisitor.prototype.convertSafeAccess = function (ast, leftMostSafe, mode) { |
| // If the expression contains a safe access node on the left it needs to be converted to |
| // an expression that guards the access to the member by checking the receiver for blank. As |
| // execution proceeds from left to right, the left most part of the expression must be guarded |
| // first but, because member access is left associative, the right side of the expression is at |
| // the top of the AST. The desired result requires lifting a copy of the left part of the |
| // expression up to test it for blank before generating the unguarded version. |
| // Consider, for example the following expression: a?.b.c?.d.e |
| // This results in the ast: |
| // . |
| // / \ |
| // ?. e |
| // / \ |
| // . d |
| // / \ |
| // ?. c |
| // / \ |
| // a b |
| // The following tree should be generated: |
| // |
| // /---- ? ----\ |
| // / | \ |
| // a /--- ? ---\ null |
| // / | \ |
| // . . null |
| // / \ / \ |
| // . c . e |
| // / \ / \ |
| // a b . d |
| // / \ |
| // . c |
| // / \ |
| // a b |
| // |
| // Notice that the first guard condition is the left hand of the left most safe access node |
| // which comes in as leftMostSafe to this routine. |
| var guardedExpression = this._visit(leftMostSafe.receiver, _Mode.Expression); |
| var temporary = undefined; |
| if (this.needsTemporary(leftMostSafe.receiver)) { |
| // If the expression has method calls or pipes then we need to save the result into a |
| // temporary variable to avoid calling stateful or impure code more than once. |
| temporary = this.allocateTemporary(); |
| // Preserve the result in the temporary variable |
| guardedExpression = temporary.set(guardedExpression); |
| // Ensure all further references to the guarded expression refer to the temporary instead. |
| this._resultMap.set(leftMostSafe.receiver, temporary); |
| } |
| var condition = guardedExpression.isBlank(); |
| // Convert the ast to an unguarded access to the receiver's member. The map will substitute |
| // leftMostNode with its unguarded version in the call to `this.visit()`. |
| if (leftMostSafe instanceof SafeMethodCall) { |
| this._nodeMap.set(leftMostSafe, new MethodCall(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.nameSpan, leftMostSafe.receiver, leftMostSafe.name, leftMostSafe.args)); |
| } |
| else { |
| this._nodeMap.set(leftMostSafe, new PropertyRead(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.nameSpan, leftMostSafe.receiver, leftMostSafe.name)); |
| } |
| // Recursively convert the node now without the guarded member access. |
| var access = this._visit(ast, _Mode.Expression); |
| // Remove the mapping. This is not strictly required as the converter only traverses each node |
| // once but is safer if the conversion is changed to traverse the nodes more than once. |
| this._nodeMap.delete(leftMostSafe); |
| // If we allocated a temporary, release it. |
| if (temporary) { |
| this.releaseTemporary(temporary); |
| } |
| // Produce the conditional |
| return convertToStatementIfNeeded(mode, condition.conditional(literal(null), access)); |
| }; |
| // Given an expression of the form a?.b.c?.d.e then the left most safe node is |
| // the (a?.b). The . and ?. are left associative thus can be rewritten as: |
| // ((((a?.c).b).c)?.d).e. This returns the most deeply nested safe read or |
| // safe method call as this needs to be transformed initially to: |
| // a == null ? null : a.c.b.c?.d.e |
| // then to: |
| // a == null ? null : a.b.c == null ? null : a.b.c.d.e |
| _AstToIrVisitor.prototype.leftMostSafeNode = function (ast) { |
| var _this = this; |
| var visit = function (visitor, ast) { |
| return (_this._nodeMap.get(ast) || ast).visit(visitor); |
| }; |
| return ast.visit({ |
| visitUnary: function (ast) { |
| return null; |
| }, |
| visitBinary: function (ast) { |
| return null; |
| }, |
| visitChain: function (ast) { |
| return null; |
| }, |
| visitConditional: function (ast) { |
| return null; |
| }, |
| visitFunctionCall: function (ast) { |
| return null; |
| }, |
| visitImplicitReceiver: function (ast) { |
| return null; |
| }, |
| visitThisReceiver: function (ast) { |
| return null; |
| }, |
| visitInterpolation: function (ast) { |
| return null; |
| }, |
| visitKeyedRead: function (ast) { |
| return visit(this, ast.obj); |
| }, |
| visitKeyedWrite: function (ast) { |
| return null; |
| }, |
| visitLiteralArray: function (ast) { |
| return null; |
| }, |
| visitLiteralMap: function (ast) { |
| return null; |
| }, |
| visitLiteralPrimitive: function (ast) { |
| return null; |
| }, |
| visitMethodCall: function (ast) { |
| return visit(this, ast.receiver); |
| }, |
| visitPipe: function (ast) { |
| return null; |
| }, |
| visitPrefixNot: function (ast) { |
| return null; |
| }, |
| visitNonNullAssert: function (ast) { |
| return null; |
| }, |
| visitPropertyRead: function (ast) { |
| return visit(this, ast.receiver); |
| }, |
| visitPropertyWrite: function (ast) { |
| return null; |
| }, |
| visitQuote: function (ast) { |
| return null; |
| }, |
| visitSafeMethodCall: function (ast) { |
| return visit(this, ast.receiver) || ast; |
| }, |
| visitSafePropertyRead: function (ast) { |
| return visit(this, ast.receiver) || ast; |
| } |
| }); |
| }; |
| // Returns true of the AST includes a method or a pipe indicating that, if the |
| // expression is used as the target of a safe property or method access then |
| // the expression should be stored into a temporary variable. |
| _AstToIrVisitor.prototype.needsTemporary = function (ast) { |
| var _this = this; |
| var visit = function (visitor, ast) { |
| return ast && (_this._nodeMap.get(ast) || ast).visit(visitor); |
| }; |
| var visitSome = function (visitor, ast) { |
| return ast.some(function (ast) { return visit(visitor, ast); }); |
| }; |
| return ast.visit({ |
| visitUnary: function (ast) { |
| return visit(this, ast.expr); |
| }, |
| visitBinary: function (ast) { |
| return visit(this, ast.left) || visit(this, ast.right); |
| }, |
| visitChain: function (ast) { |
| return false; |
| }, |
| visitConditional: function (ast) { |
| return visit(this, ast.condition) || visit(this, ast.trueExp) || visit(this, ast.falseExp); |
| }, |
| visitFunctionCall: function (ast) { |
| return true; |
| }, |
| visitImplicitReceiver: function (ast) { |
| return false; |
| }, |
| visitThisReceiver: function (ast) { |
| return false; |
| }, |
| visitInterpolation: function (ast) { |
| return visitSome(this, ast.expressions); |
| }, |
| visitKeyedRead: function (ast) { |
| return false; |
| }, |
| visitKeyedWrite: function (ast) { |
| return false; |
| }, |
| visitLiteralArray: function (ast) { |
| return true; |
| }, |
| visitLiteralMap: function (ast) { |
| return true; |
| }, |
| visitLiteralPrimitive: function (ast) { |
| return false; |
| }, |
| visitMethodCall: function (ast) { |
| return true; |
| }, |
| visitPipe: function (ast) { |
| return true; |
| }, |
| visitPrefixNot: function (ast) { |
| return visit(this, ast.expression); |
| }, |
| visitNonNullAssert: function (ast) { |
| return visit(this, ast.expression); |
| }, |
| visitPropertyRead: function (ast) { |
| return false; |
| }, |
| visitPropertyWrite: function (ast) { |
| return false; |
| }, |
| visitQuote: function (ast) { |
| return false; |
| }, |
| visitSafeMethodCall: function (ast) { |
| return true; |
| }, |
| visitSafePropertyRead: function (ast) { |
| return false; |
| } |
| }); |
| }; |
| _AstToIrVisitor.prototype.allocateTemporary = function () { |
| var tempNumber = this._currentTemporary++; |
| this.temporaryCount = Math.max(this._currentTemporary, this.temporaryCount); |
| return new ReadVarExpr(temporaryName(this.bindingId, tempNumber)); |
| }; |
| _AstToIrVisitor.prototype.releaseTemporary = function (temporary) { |
| this._currentTemporary--; |
| if (temporary.name != temporaryName(this.bindingId, this._currentTemporary)) { |
| throw new Error("Temporary " + temporary.name + " released out of order"); |
| } |
| }; |
| /** |
| * Creates an absolute `ParseSourceSpan` from the relative `ParseSpan`. |
| * |
| * `ParseSpan` objects are relative to the start of the expression. |
| * This method converts these to full `ParseSourceSpan` objects that |
| * show where the span is within the overall source file. |
| * |
| * @param span the relative span to convert. |
| * @returns a `ParseSourceSpan` for the given span or null if no |
| * `baseSourceSpan` was provided to this class. |
| */ |
| _AstToIrVisitor.prototype.convertSourceSpan = function (span) { |
| if (this.baseSourceSpan) { |
| var start = this.baseSourceSpan.start.moveBy(span.start); |
| var end = this.baseSourceSpan.start.moveBy(span.end); |
| var fullStart = this.baseSourceSpan.fullStart.moveBy(span.start); |
| return new ParseSourceSpan(start, end, fullStart); |
| } |
| else { |
| return null; |
| } |
| }; |
| /** Adds the name of an AST to the list of implicit receiver accesses. */ |
| _AstToIrVisitor.prototype.addImplicitReceiverAccess = function (name) { |
| if (this.implicitReceiverAccesses) { |
| this.implicitReceiverAccesses.add(name); |
| } |
| }; |
| return _AstToIrVisitor; |
| }()); |
| function flattenStatements(arg, output) { |
| if (Array.isArray(arg)) { |
| arg.forEach(function (entry) { return flattenStatements(entry, output); }); |
| } |
| else { |
| output.push(arg); |
| } |
| } |
| var DefaultLocalResolver = /** @class */ (function () { |
| function DefaultLocalResolver(globals) { |
| this.globals = globals; |
| } |
| DefaultLocalResolver.prototype.notifyImplicitReceiverUse = function () { }; |
| DefaultLocalResolver.prototype.getLocal = function (name) { |
| if (name === EventHandlerVars.event.name) { |
| return EventHandlerVars.event; |
| } |
| return null; |
| }; |
| return DefaultLocalResolver; |
| }()); |
| function createCurrValueExpr(bindingId) { |
| return variable("currVal_" + bindingId); // fix syntax highlighting: ` |
| } |
| function createPreventDefaultVar(bindingId) { |
| return variable("pd_" + bindingId); |
| } |
| function convertStmtIntoExpression(stmt) { |
| if (stmt instanceof ExpressionStatement) { |
| return stmt.expr; |
| } |
| else if (stmt instanceof ReturnStatement) { |
| return stmt.value; |
| } |
| return null; |
| } |
| var BuiltinFunctionCall = /** @class */ (function (_super) { |
| __extends(BuiltinFunctionCall, _super); |
| function BuiltinFunctionCall(span, sourceSpan, args, converter) { |
| var _this = _super.call(this, span, sourceSpan, null, args) || this; |
| _this.args = args; |
| _this.converter = converter; |
| return _this; |
| } |
| return BuiltinFunctionCall; |
| }(FunctionCall)); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * This file is a port of shadowCSS from webcomponents.js to TypeScript. |
| * |
| * Please make sure to keep to edits in sync with the source file. |
| * |
| * Source: |
| * https://github.com/webcomponents/webcomponentsjs/blob/4efecd7e0e/src/ShadowCSS/ShadowCSS.js |
| * |
| * The original file level comment is reproduced below |
| */ |
| /* |
| This is a limited shim for ShadowDOM css styling. |
| https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#styles |
| |
| The intention here is to support only the styling features which can be |
| relatively simply implemented. The goal is to allow users to avoid the |
| most obvious pitfalls and do so without compromising performance significantly. |
| For ShadowDOM styling that's not covered here, a set of best practices |
| can be provided that should allow users to accomplish more complex styling. |
| |
| The following is a list of specific ShadowDOM styling features and a brief |
| discussion of the approach used to shim. |
| |
| Shimmed features: |
| |
| * :host, :host-context: ShadowDOM allows styling of the shadowRoot's host |
| element using the :host rule. To shim this feature, the :host styles are |
| reformatted and prefixed with a given scope name and promoted to a |
| document level stylesheet. |
| For example, given a scope name of .foo, a rule like this: |
| |
| :host { |
| background: red; |
| } |
| } |
| |
| becomes: |
| |
| .foo { |
| background: red; |
| } |
| |
| * encapsulation: Styles defined within ShadowDOM, apply only to |
| dom inside the ShadowDOM. Polymer uses one of two techniques to implement |
| this feature. |
| |
| By default, rules are prefixed with the host element tag name |
| as a descendant selector. This ensures styling does not leak out of the 'top' |
| of the element's ShadowDOM. For example, |
| |
| div { |
| font-weight: bold; |
| } |
| |
| becomes: |
| |
| x-foo div { |
| font-weight: bold; |
| } |
| |
| becomes: |
| |
| |
| Alternatively, if WebComponents.ShadowCSS.strictStyling is set to true then |
| selectors are scoped by adding an attribute selector suffix to each |
| simple selector that contains the host element tag name. Each element |
| in the element's ShadowDOM template is also given the scope attribute. |
| Thus, these rules match only elements that have the scope attribute. |
| For example, given a scope name of x-foo, a rule like this: |
| |
| div { |
| font-weight: bold; |
| } |
| |
| becomes: |
| |
| div[x-foo] { |
| font-weight: bold; |
| } |
| |
| Note that elements that are dynamically added to a scope must have the scope |
| selector added to them manually. |
| |
| * upper/lower bound encapsulation: Styles which are defined outside a |
| shadowRoot should not cross the ShadowDOM boundary and should not apply |
| inside a shadowRoot. |
| |
| This styling behavior is not emulated. Some possible ways to do this that |
| were rejected due to complexity and/or performance concerns include: (1) reset |
| every possible property for every possible selector for a given scope name; |
| (2) re-implement css in javascript. |
| |
| As an alternative, users should make sure to use selectors |
| specific to the scope in which they are working. |
| |
| * ::distributed: This behavior is not emulated. It's often not necessary |
| to style the contents of a specific insertion point and instead, descendants |
| of the host element can be styled selectively. Users can also create an |
| extra node around an insertion point and style that node's contents |
| via descendent selectors. For example, with a shadowRoot like this: |
| |
| <style> |
| ::content(div) { |
| background: red; |
| } |
| </style> |
| <content></content> |
| |
| could become: |
| |
| <style> |
| / *@polyfill .content-container div * / |
| ::content(div) { |
| background: red; |
| } |
| </style> |
| <div class="content-container"> |
| <content></content> |
| </div> |
| |
| Note the use of @polyfill in the comment above a ShadowDOM specific style |
| declaration. This is a directive to the styling shim to use the selector |
| in comments in lieu of the next selector when running under polyfill. |
| */ |
| var ShadowCss = /** @class */ (function () { |
| function ShadowCss() { |
| this.strictStyling = true; |
| } |
| /* |
| * Shim some cssText with the given selector. Returns cssText that can |
| * be included in the document via WebComponents.ShadowCSS.addCssToDocument(css). |
| * |
| * When strictStyling is true: |
| * - selector is the attribute added to all elements inside the host, |
| * - hostSelector is the attribute added to the host itself. |
| */ |
| ShadowCss.prototype.shimCssText = function (cssText, selector, hostSelector) { |
| if (hostSelector === void 0) { hostSelector = ''; } |
| var commentsWithHash = extractCommentsWithHash(cssText); |
| cssText = stripComments(cssText); |
| cssText = this._insertDirectives(cssText); |
| var scopedCssText = this._scopeCssText(cssText, selector, hostSelector); |
| return __spread([scopedCssText], commentsWithHash).join('\n'); |
| }; |
| ShadowCss.prototype._insertDirectives = function (cssText) { |
| cssText = this._insertPolyfillDirectivesInCssText(cssText); |
| return this._insertPolyfillRulesInCssText(cssText); |
| }; |
| /* |
| * Process styles to convert native ShadowDOM rules that will trip |
| * up the css parser; we rely on decorating the stylesheet with inert rules. |
| * |
| * For example, we convert this rule: |
| * |
| * polyfill-next-selector { content: ':host menu-item'; } |
| * ::content menu-item { |
| * |
| * to this: |
| * |
| * scopeName menu-item { |
| * |
| **/ |
| ShadowCss.prototype._insertPolyfillDirectivesInCssText = function (cssText) { |
| // Difference with webcomponents.js: does not handle comments |
| return cssText.replace(_cssContentNextSelectorRe, function () { |
| var m = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| m[_i] = arguments[_i]; |
| } |
| return m[2] + '{'; |
| }); |
| }; |
| /* |
| * Process styles to add rules which will only apply under the polyfill |
| * |
| * For example, we convert this rule: |
| * |
| * polyfill-rule { |
| * content: ':host menu-item'; |
| * ... |
| * } |
| * |
| * to this: |
| * |
| * scopeName menu-item {...} |
| * |
| **/ |
| ShadowCss.prototype._insertPolyfillRulesInCssText = function (cssText) { |
| // Difference with webcomponents.js: does not handle comments |
| return cssText.replace(_cssContentRuleRe, function () { |
| var m = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| m[_i] = arguments[_i]; |
| } |
| var rule = m[0].replace(m[1], '').replace(m[2], ''); |
| return m[4] + rule; |
| }); |
| }; |
| /* Ensure styles are scoped. Pseudo-scoping takes a rule like: |
| * |
| * .foo {... } |
| * |
| * and converts this to |
| * |
| * scopeName .foo { ... } |
| */ |
| ShadowCss.prototype._scopeCssText = function (cssText, scopeSelector, hostSelector) { |
| var unscopedRules = this._extractUnscopedRulesFromCssText(cssText); |
| // replace :host and :host-context -shadowcsshost and -shadowcsshost respectively |
| cssText = this._insertPolyfillHostInCssText(cssText); |
| cssText = this._convertColonHost(cssText); |
| cssText = this._convertColonHostContext(cssText); |
| cssText = this._convertShadowDOMSelectors(cssText); |
| if (scopeSelector) { |
| cssText = this._scopeSelectors(cssText, scopeSelector, hostSelector); |
| } |
| cssText = cssText + '\n' + unscopedRules; |
| return cssText.trim(); |
| }; |
| /* |
| * Process styles to add rules which will only apply under the polyfill |
| * and do not process via CSSOM. (CSSOM is destructive to rules on rare |
| * occasions, e.g. -webkit-calc on Safari.) |
| * For example, we convert this rule: |
| * |
| * @polyfill-unscoped-rule { |
| * content: 'menu-item'; |
| * ... } |
| * |
| * to this: |
| * |
| * menu-item {...} |
| * |
| **/ |
| ShadowCss.prototype._extractUnscopedRulesFromCssText = function (cssText) { |
| // Difference with webcomponents.js: does not handle comments |
| var r = ''; |
| var m; |
| _cssContentUnscopedRuleRe.lastIndex = 0; |
| while ((m = _cssContentUnscopedRuleRe.exec(cssText)) !== null) { |
| var rule = m[0].replace(m[2], '').replace(m[1], m[4]); |
| r += rule + '\n\n'; |
| } |
| return r; |
| }; |
| /* |
| * convert a rule like :host(.foo) > .bar { } |
| * |
| * to |
| * |
| * .foo<scopeName> > .bar |
| */ |
| ShadowCss.prototype._convertColonHost = function (cssText) { |
| return cssText.replace(_cssColonHostRe, function (_, hostSelectors, otherSelectors) { |
| var e_1, _b; |
| if (hostSelectors) { |
| var convertedSelectors = []; |
| var hostSelectorArray = hostSelectors.split(',').map(function (p) { return p.trim(); }); |
| try { |
| for (var hostSelectorArray_1 = __values(hostSelectorArray), hostSelectorArray_1_1 = hostSelectorArray_1.next(); !hostSelectorArray_1_1.done; hostSelectorArray_1_1 = hostSelectorArray_1.next()) { |
| var hostSelector = hostSelectorArray_1_1.value; |
| if (!hostSelector) |
| break; |
| var convertedSelector = _polyfillHostNoCombinator + hostSelector.replace(_polyfillHost, '') + otherSelectors; |
| convertedSelectors.push(convertedSelector); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (hostSelectorArray_1_1 && !hostSelectorArray_1_1.done && (_b = hostSelectorArray_1.return)) _b.call(hostSelectorArray_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return convertedSelectors.join(','); |
| } |
| else { |
| return _polyfillHostNoCombinator + otherSelectors; |
| } |
| }); |
| }; |
| /* |
| * convert a rule like :host-context(.foo) > .bar { } |
| * |
| * to |
| * |
| * .foo<scopeName> > .bar, .foo <scopeName> > .bar { } |
| * |
| * and |
| * |
| * :host-context(.foo:host) .bar { ... } |
| * |
| * to |
| * |
| * .foo<scopeName> .bar { ... } |
| */ |
| ShadowCss.prototype._convertColonHostContext = function (cssText) { |
| return cssText.replace(_cssColonHostContextReGlobal, function (selectorText) { |
| // We have captured a selector that contains a `:host-context` rule. |
| var _a; |
| // For backward compatibility `:host-context` may contain a comma separated list of selectors. |
| // Each context selector group will contain a list of host-context selectors that must match |
| // an ancestor of the host. |
| // (Normally `contextSelectorGroups` will only contain a single array of context selectors.) |
| var contextSelectorGroups = [[]]; |
| // There may be more than `:host-context` in this selector so `selectorText` could look like: |
| // `:host-context(.one):host-context(.two)`. |
| // Execute `_cssColonHostContextRe` over and over until we have extracted all the |
| // `:host-context` selectors from this selector. |
| var match; |
| while (match = _cssColonHostContextRe.exec(selectorText)) { |
| // `match` = [':host-context(<selectors>)<rest>', <selectors>, <rest>] |
| // The `<selectors>` could actually be a comma separated list: `:host-context(.one, .two)`. |
| var newContextSelectors = ((_a = match[1]) !== null && _a !== void 0 ? _a : '').trim().split(',').map(function (m) { return m.trim(); }).filter(function (m) { return m !== ''; }); |
| // We must duplicate the current selector group for each of these new selectors. |
| // For example if the current groups are: |
| // ``` |
| // [ |
| // ['a', 'b', 'c'], |
| // ['x', 'y', 'z'], |
| // ] |
| // ``` |
| // And we have a new set of comma separated selectors: `:host-context(m,n)` then the new |
| // groups are: |
| // ``` |
| // [ |
| // ['a', 'b', 'c', 'm'], |
| // ['x', 'y', 'z', 'm'], |
| // ['a', 'b', 'c', 'n'], |
| // ['x', 'y', 'z', 'n'], |
| // ] |
| // ``` |
| var contextSelectorGroupsLength = contextSelectorGroups.length; |
| repeatGroups(contextSelectorGroups, newContextSelectors.length); |
| for (var i = 0; i < newContextSelectors.length; i++) { |
| for (var j = 0; j < contextSelectorGroupsLength; j++) { |
| contextSelectorGroups[j + (i * contextSelectorGroupsLength)].push(newContextSelectors[i]); |
| } |
| } |
| // Update the `selectorText` and see repeat to see if there are more `:host-context`s. |
| selectorText = match[2]; |
| } |
| // The context selectors now must be combined with each other to capture all the possible |
| // selectors that `:host-context` can match. See `combineHostContextSelectors()` for more |
| // info about how this is done. |
| return contextSelectorGroups |
| .map(function (contextSelectors) { return combineHostContextSelectors(contextSelectors, selectorText); }) |
| .join(', '); |
| }); |
| }; |
| /* |
| * Convert combinators like ::shadow and pseudo-elements like ::content |
| * by replacing with space. |
| */ |
| ShadowCss.prototype._convertShadowDOMSelectors = function (cssText) { |
| return _shadowDOMSelectorsRe.reduce(function (result, pattern) { return result.replace(pattern, ' '); }, cssText); |
| }; |
| // change a selector like 'div' to 'name div' |
| ShadowCss.prototype._scopeSelectors = function (cssText, scopeSelector, hostSelector) { |
| var _this = this; |
| return processRules(cssText, function (rule) { |
| var selector = rule.selector; |
| var content = rule.content; |
| if (rule.selector[0] != '@') { |
| selector = |
| _this._scopeSelector(rule.selector, scopeSelector, hostSelector, _this.strictStyling); |
| } |
| else if (rule.selector.startsWith('@media') || rule.selector.startsWith('@supports') || |
| rule.selector.startsWith('@page') || rule.selector.startsWith('@document')) { |
| content = _this._scopeSelectors(rule.content, scopeSelector, hostSelector); |
| } |
| else if (rule.selector.startsWith('@font-face')) { |
| content = _this._stripScopingSelectors(rule.content, scopeSelector, hostSelector); |
| } |
| return new CssRule(selector, content); |
| }); |
| }; |
| /** |
| * Handle a css text that is within a rule that should not contain scope selectors by simply |
| * removing them! An example of such a rule is `@font-face`. |
| * |
| * `@font-face` rules cannot contain nested selectors. Nor can they be nested under a selector. |
| * Normally this would be a syntax error by the author of the styles. But in some rare cases, such |
| * as importing styles from a library, and applying `:host ::ng-deep` to the imported styles, we |
| * can end up with broken css if the imported styles happen to contain @font-face rules. |
| * |
| * For example: |
| * |
| * ``` |
| * :host ::ng-deep { |
| * import 'some/lib/containing/font-face'; |
| * } |
| * ``` |
| */ |
| ShadowCss.prototype._stripScopingSelectors = function (cssText, scopeSelector, hostSelector) { |
| var _this = this; |
| return processRules(cssText, function (rule) { |
| var selector = rule.selector.replace(_shadowDeepSelectors, ' ') |
| .replace(_polyfillHostNoCombinatorRe, ' '); |
| var content = _this._scopeSelectors(rule.content, scopeSelector, hostSelector); |
| return new CssRule(selector, content); |
| }); |
| }; |
| ShadowCss.prototype._scopeSelector = function (selector, scopeSelector, hostSelector, strict) { |
| var _this = this; |
| return selector.split(',') |
| .map(function (part) { return part.trim().split(_shadowDeepSelectors); }) |
| .map(function (deepParts) { |
| var _b = __read(deepParts), shallowPart = _b[0], otherParts = _b.slice(1); |
| var applyScope = function (shallowPart) { |
| if (_this._selectorNeedsScoping(shallowPart, scopeSelector)) { |
| return strict ? |
| _this._applyStrictSelectorScope(shallowPart, scopeSelector, hostSelector) : |
| _this._applySelectorScope(shallowPart, scopeSelector, hostSelector); |
| } |
| else { |
| return shallowPart; |
| } |
| }; |
| return __spread([applyScope(shallowPart)], otherParts).join(' '); |
| }) |
| .join(', '); |
| }; |
| ShadowCss.prototype._selectorNeedsScoping = function (selector, scopeSelector) { |
| var re = this._makeScopeMatcher(scopeSelector); |
| return !re.test(selector); |
| }; |
| ShadowCss.prototype._makeScopeMatcher = function (scopeSelector) { |
| var lre = /\[/g; |
| var rre = /\]/g; |
| scopeSelector = scopeSelector.replace(lre, '\\[').replace(rre, '\\]'); |
| return new RegExp('^(' + scopeSelector + ')' + _selectorReSuffix, 'm'); |
| }; |
| ShadowCss.prototype._applySelectorScope = function (selector, scopeSelector, hostSelector) { |
| // Difference from webcomponents.js: scopeSelector could not be an array |
| return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector); |
| }; |
| // scope via name and [is=name] |
| ShadowCss.prototype._applySimpleSelectorScope = function (selector, scopeSelector, hostSelector) { |
| // In Android browser, the lastIndex is not reset when the regex is used in String.replace() |
| _polyfillHostRe.lastIndex = 0; |
| if (_polyfillHostRe.test(selector)) { |
| var replaceBy_1 = this.strictStyling ? "[" + hostSelector + "]" : scopeSelector; |
| return selector |
| .replace(_polyfillHostNoCombinatorRe, function (hnc, selector) { |
| return selector.replace(/([^:]*)(:*)(.*)/, function (_, before, colon, after) { |
| return before + replaceBy_1 + colon + after; |
| }); |
| }) |
| .replace(_polyfillHostRe, replaceBy_1 + ' '); |
| } |
| return scopeSelector + ' ' + selector; |
| }; |
| // return a selector with [name] suffix on each simple selector |
| // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name] /** @internal */ |
| ShadowCss.prototype._applyStrictSelectorScope = function (selector, scopeSelector, hostSelector) { |
| var _this = this; |
| var isRe = /\[is=([^\]]*)\]/g; |
| scopeSelector = scopeSelector.replace(isRe, function (_) { |
| var parts = []; |
| for (var _i = 1; _i < arguments.length; _i++) { |
| parts[_i - 1] = arguments[_i]; |
| } |
| return parts[0]; |
| }); |
| var attrName = '[' + scopeSelector + ']'; |
| var _scopeSelectorPart = function (p) { |
| var scopedP = p.trim(); |
| if (!scopedP) { |
| return ''; |
| } |
| if (p.indexOf(_polyfillHostNoCombinator) > -1) { |
| scopedP = _this._applySimpleSelectorScope(p, scopeSelector, hostSelector); |
| } |
| else { |
| // remove :host since it should be unnecessary |
| var t = p.replace(_polyfillHostRe, ''); |
| if (t.length > 0) { |
| var matches = t.match(/([^:]*)(:*)(.*)/); |
| if (matches) { |
| scopedP = matches[1] + attrName + matches[2] + matches[3]; |
| } |
| } |
| } |
| return scopedP; |
| }; |
| var safeContent = new SafeSelector(selector); |
| selector = safeContent.content(); |
| var scopedSelector = ''; |
| var startIndex = 0; |
| var res; |
| var sep = /( |>|\+|~(?!=))\s*/g; |
| // If a selector appears before :host it should not be shimmed as it |
| // matches on ancestor elements and not on elements in the host's shadow |
| // `:host-context(div)` is transformed to |
| // `-shadowcsshost-no-combinatordiv, div -shadowcsshost-no-combinator` |
| // the `div` is not part of the component in the 2nd selectors and should not be scoped. |
| // Historically `component-tag:host` was matching the component so we also want to preserve |
| // this behavior to avoid breaking legacy apps (it should not match). |
| // The behavior should be: |
| // - `tag:host` -> `tag[h]` (this is to avoid breaking legacy apps, should not match anything) |
| // - `tag :host` -> `tag [h]` (`tag` is not scoped because it's considered part of a |
| // `:host-context(tag)`) |
| var hasHost = selector.indexOf(_polyfillHostNoCombinator) > -1; |
| // Only scope parts after the first `-shadowcsshost-no-combinator` when it is present |
| var shouldScope = !hasHost; |
| while ((res = sep.exec(selector)) !== null) { |
| var separator = res[1]; |
| var part_1 = selector.slice(startIndex, res.index).trim(); |
| shouldScope = shouldScope || part_1.indexOf(_polyfillHostNoCombinator) > -1; |
| var scopedPart = shouldScope ? _scopeSelectorPart(part_1) : part_1; |
| scopedSelector += scopedPart + " " + separator + " "; |
| startIndex = sep.lastIndex; |
| } |
| var part = selector.substring(startIndex); |
| shouldScope = shouldScope || part.indexOf(_polyfillHostNoCombinator) > -1; |
| scopedSelector += shouldScope ? _scopeSelectorPart(part) : part; |
| // replace the placeholders with their original values |
| return safeContent.restore(scopedSelector); |
| }; |
| ShadowCss.prototype._insertPolyfillHostInCssText = function (selector) { |
| return selector.replace(_colonHostContextRe, _polyfillHostContext) |
| .replace(_colonHostRe, _polyfillHost); |
| }; |
| return ShadowCss; |
| }()); |
| var SafeSelector = /** @class */ (function () { |
| function SafeSelector(selector) { |
| var _this = this; |
| this.placeholders = []; |
| this.index = 0; |
| // Replaces attribute selectors with placeholders. |
| // The WS in [attr="va lue"] would otherwise be interpreted as a selector separator. |
| selector = this._escapeRegexMatches(selector, /(\[[^\]]*\])/g); |
| // CSS allows for certain special characters to be used in selectors if they're escaped. |
| // E.g. `.foo:blue` won't match a class called `foo:blue`, because the colon denotes a |
| // pseudo-class, but writing `.foo\:blue` will match, because the colon was escaped. |
| // Replace all escape sequences (`\` followed by a character) with a placeholder so |
| // that our handling of pseudo-selectors doesn't mess with them. |
| selector = this._escapeRegexMatches(selector, /(\\.)/g); |
| // Replaces the expression in `:nth-child(2n + 1)` with a placeholder. |
| // WS and "+" would otherwise be interpreted as selector separators. |
| this._content = selector.replace(/(:nth-[-\w]+)(\([^)]+\))/g, function (_, pseudo, exp) { |
| var replaceBy = "__ph-" + _this.index + "__"; |
| _this.placeholders.push(exp); |
| _this.index++; |
| return pseudo + replaceBy; |
| }); |
| } |
| SafeSelector.prototype.restore = function (content) { |
| var _this = this; |
| return content.replace(/__ph-(\d+)__/g, function (_ph, index) { return _this.placeholders[+index]; }); |
| }; |
| SafeSelector.prototype.content = function () { |
| return this._content; |
| }; |
| /** |
| * Replaces all of the substrings that match a regex within a |
| * special string (e.g. `__ph-0__`, `__ph-1__`, etc). |
| */ |
| SafeSelector.prototype._escapeRegexMatches = function (content, pattern) { |
| var _this = this; |
| return content.replace(pattern, function (_, keep) { |
| var replaceBy = "__ph-" + _this.index + "__"; |
| _this.placeholders.push(keep); |
| _this.index++; |
| return replaceBy; |
| }); |
| }; |
| return SafeSelector; |
| }()); |
| var _cssContentNextSelectorRe = /polyfill-next-selector[^}]*content:[\s]*?(['"])(.*?)\1[;\s]*}([^{]*?){/gim; |
| var _cssContentRuleRe = /(polyfill-rule)[^}]*(content:[\s]*(['"])(.*?)\3)[;\s]*[^}]*}/gim; |
| var _cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content:[\s]*(['"])(.*?)\3)[;\s]*[^}]*}/gim; |
| var _polyfillHost = '-shadowcsshost'; |
| // note: :host-context pre-processed to -shadowcsshostcontext. |
| var _polyfillHostContext = '-shadowcsscontext'; |
| var _parenSuffix = '(?:\\((' + |
| '(?:\\([^)(]*\\)|[^)(]*)+?' + |
| ')\\))?([^,{]*)'; |
| var _cssColonHostRe = new RegExp(_polyfillHost + _parenSuffix, 'gim'); |
| var _cssColonHostContextReGlobal = new RegExp(_polyfillHostContext + _parenSuffix, 'gim'); |
| var _cssColonHostContextRe = new RegExp(_polyfillHostContext + _parenSuffix, 'im'); |
| var _polyfillHostNoCombinator = _polyfillHost + '-no-combinator'; |
| var _polyfillHostNoCombinatorRe = /-shadowcsshost-no-combinator([^\s]*)/; |
| var _shadowDOMSelectorsRe = [ |
| /::shadow/g, |
| /::content/g, |
| // Deprecated selectors |
| /\/shadow-deep\//g, |
| /\/shadow\//g, |
| ]; |
| // The deep combinator is deprecated in the CSS spec |
| // Support for `>>>`, `deep`, `::ng-deep` is then also deprecated and will be removed in the future. |
| // see https://github.com/angular/angular/pull/17677 |
| var _shadowDeepSelectors = /(?:>>>)|(?:\/deep\/)|(?:::ng-deep)/g; |
| var _selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$'; |
| var _polyfillHostRe = /-shadowcsshost/gim; |
| var _colonHostRe = /:host/gim; |
| var _colonHostContextRe = /:host-context/gim; |
| var _commentRe = /\/\*\s*[\s\S]*?\*\//g; |
| function stripComments(input) { |
| return input.replace(_commentRe, ''); |
| } |
| var _commentWithHashRe = /\/\*\s*#\s*source(Mapping)?URL=[\s\S]+?\*\//g; |
| function extractCommentsWithHash(input) { |
| return input.match(_commentWithHashRe) || []; |
| } |
| var BLOCK_PLACEHOLDER = '%BLOCK%'; |
| var QUOTE_PLACEHOLDER = '%QUOTED%'; |
| var _ruleRe = /(\s*)([^;\{\}]+?)(\s*)((?:{%BLOCK%}?\s*;?)|(?:\s*;))/g; |
| var _quotedRe = /%QUOTED%/g; |
| var CONTENT_PAIRS = new Map([['{', '}']]); |
| var QUOTE_PAIRS = new Map([["\"", "\""], ["'", "'"]]); |
| var CssRule = /** @class */ (function () { |
| function CssRule(selector, content) { |
| this.selector = selector; |
| this.content = content; |
| } |
| return CssRule; |
| }()); |
| function processRules(input, ruleCallback) { |
| var inputWithEscapedQuotes = escapeBlocks(input, QUOTE_PAIRS, QUOTE_PLACEHOLDER); |
| var inputWithEscapedBlocks = escapeBlocks(inputWithEscapedQuotes.escapedString, CONTENT_PAIRS, BLOCK_PLACEHOLDER); |
| var nextBlockIndex = 0; |
| var nextQuoteIndex = 0; |
| return inputWithEscapedBlocks.escapedString |
| .replace(_ruleRe, function () { |
| var m = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| m[_i] = arguments[_i]; |
| } |
| var selector = m[2]; |
| var content = ''; |
| var suffix = m[4]; |
| var contentPrefix = ''; |
| if (suffix && suffix.startsWith('{' + BLOCK_PLACEHOLDER)) { |
| content = inputWithEscapedBlocks.blocks[nextBlockIndex++]; |
| suffix = suffix.substring(BLOCK_PLACEHOLDER.length + 1); |
| contentPrefix = '{'; |
| } |
| var rule = ruleCallback(new CssRule(selector, content)); |
| return "" + m[1] + rule.selector + m[3] + contentPrefix + rule.content + suffix; |
| }) |
| .replace(_quotedRe, function () { return inputWithEscapedQuotes.blocks[nextQuoteIndex++]; }); |
| } |
| var StringWithEscapedBlocks = /** @class */ (function () { |
| function StringWithEscapedBlocks(escapedString, blocks) { |
| this.escapedString = escapedString; |
| this.blocks = blocks; |
| } |
| return StringWithEscapedBlocks; |
| }()); |
| function escapeBlocks(input, charPairs, placeholder) { |
| var resultParts = []; |
| var escapedBlocks = []; |
| var openCharCount = 0; |
| var nonBlockStartIndex = 0; |
| var blockStartIndex = -1; |
| var openChar; |
| var closeChar; |
| for (var i = 0; i < input.length; i++) { |
| var char = input[i]; |
| if (char === '\\') { |
| i++; |
| } |
| else if (char === closeChar) { |
| openCharCount--; |
| if (openCharCount === 0) { |
| escapedBlocks.push(input.substring(blockStartIndex, i)); |
| resultParts.push(placeholder); |
| nonBlockStartIndex = i; |
| blockStartIndex = -1; |
| openChar = closeChar = undefined; |
| } |
| } |
| else if (char === openChar) { |
| openCharCount++; |
| } |
| else if (openCharCount === 0 && charPairs.has(char)) { |
| openChar = char; |
| closeChar = charPairs.get(char); |
| openCharCount = 1; |
| blockStartIndex = i + 1; |
| resultParts.push(input.substring(nonBlockStartIndex, blockStartIndex)); |
| } |
| } |
| if (blockStartIndex !== -1) { |
| escapedBlocks.push(input.substring(blockStartIndex)); |
| resultParts.push(placeholder); |
| } |
| else { |
| resultParts.push(input.substring(nonBlockStartIndex)); |
| } |
| return new StringWithEscapedBlocks(resultParts.join(''), escapedBlocks); |
| } |
| /** |
| * Combine the `contextSelectors` with the `hostMarker` and the `otherSelectors` |
| * to create a selector that matches the same as `:host-context()`. |
| * |
| * Given a single context selector `A` we need to output selectors that match on the host and as an |
| * ancestor of the host: |
| * |
| * ``` |
| * A <hostMarker>, A<hostMarker> {} |
| * ``` |
| * |
| * When there is more than one context selector we also have to create combinations of those |
| * selectors with each other. For example if there are `A` and `B` selectors the output is: |
| * |
| * ``` |
| * AB<hostMarker>, AB <hostMarker>, A B<hostMarker>, |
| * B A<hostMarker>, A B <hostMarker>, B A <hostMarker> {} |
| * ``` |
| * |
| * And so on... |
| * |
| * @param hostMarker the string that selects the host element. |
| * @param contextSelectors an array of context selectors that will be combined. |
| * @param otherSelectors the rest of the selectors that are not context selectors. |
| */ |
| function combineHostContextSelectors(contextSelectors, otherSelectors) { |
| var hostMarker = _polyfillHostNoCombinator; |
| _polyfillHostRe.lastIndex = 0; // reset the regex to ensure we get an accurate test |
| var otherSelectorsHasHost = _polyfillHostRe.test(otherSelectors); |
| // If there are no context selectors then just output a host marker |
| if (contextSelectors.length === 0) { |
| return hostMarker + otherSelectors; |
| } |
| var combined = [contextSelectors.pop() || '']; |
| while (contextSelectors.length > 0) { |
| var length = combined.length; |
| var contextSelector = contextSelectors.pop(); |
| for (var i = 0; i < length; i++) { |
| var previousSelectors = combined[i]; |
| // Add the new selector as a descendant of the previous selectors |
| combined[length * 2 + i] = previousSelectors + ' ' + contextSelector; |
| // Add the new selector as an ancestor of the previous selectors |
| combined[length + i] = contextSelector + ' ' + previousSelectors; |
| // Add the new selector to act on the same element as the previous selectors |
| combined[i] = contextSelector + previousSelectors; |
| } |
| } |
| // Finally connect the selector to the `hostMarker`s: either acting directly on the host |
| // (A<hostMarker>) or as an ancestor (A <hostMarker>). |
| return combined |
| .map(function (s) { return otherSelectorsHasHost ? |
| "" + s + otherSelectors : |
| "" + s + hostMarker + otherSelectors + ", " + s + " " + hostMarker + otherSelectors; }) |
| .join(','); |
| } |
| /** |
| * Mutate the given `groups` array so that there are `multiples` clones of the original array |
| * stored. |
| * |
| * For example `repeatGroups([a, b], 3)` will result in `[a, b, a, b, a, b]` - but importantly the |
| * newly added groups will be clones of the original. |
| * |
| * @param groups An array of groups of strings that will be repeated. This array is mutated |
| * in-place. |
| * @param multiples The number of times the current groups should appear. |
| */ |
| function repeatGroups(groups, multiples) { |
| var length = groups.length; |
| for (var i = 1; i < multiples; i++) { |
| for (var j = 0; j < length; j++) { |
| groups[j + (i * length)] = groups[j].slice(0); |
| } |
| } |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var COMPONENT_VARIABLE = '%COMP%'; |
| var HOST_ATTR = "_nghost-" + COMPONENT_VARIABLE; |
| var CONTENT_ATTR = "_ngcontent-" + COMPONENT_VARIABLE; |
| var StylesCompileDependency = /** @class */ (function () { |
| function StylesCompileDependency(name, moduleUrl, setValue) { |
| this.name = name; |
| this.moduleUrl = moduleUrl; |
| this.setValue = setValue; |
| } |
| return StylesCompileDependency; |
| }()); |
| var CompiledStylesheet = /** @class */ (function () { |
| function CompiledStylesheet(outputCtx, stylesVar, dependencies, isShimmed, meta) { |
| this.outputCtx = outputCtx; |
| this.stylesVar = stylesVar; |
| this.dependencies = dependencies; |
| this.isShimmed = isShimmed; |
| this.meta = meta; |
| } |
| return CompiledStylesheet; |
| }()); |
| var StyleCompiler = /** @class */ (function () { |
| function StyleCompiler(_urlResolver) { |
| this._urlResolver = _urlResolver; |
| this._shadowCss = new ShadowCss(); |
| } |
| StyleCompiler.prototype.compileComponent = function (outputCtx, comp) { |
| var template = comp.template; |
| return this._compileStyles(outputCtx, comp, new CompileStylesheetMetadata({ |
| styles: template.styles, |
| styleUrls: template.styleUrls, |
| moduleUrl: identifierModuleUrl(comp.type) |
| }), this.needsStyleShim(comp), true); |
| }; |
| StyleCompiler.prototype.compileStyles = function (outputCtx, comp, stylesheet, shim) { |
| if (shim === void 0) { shim = this.needsStyleShim(comp); } |
| return this._compileStyles(outputCtx, comp, stylesheet, shim, false); |
| }; |
| StyleCompiler.prototype.needsStyleShim = function (comp) { |
| return comp.template.encapsulation === ViewEncapsulation.Emulated; |
| }; |
| StyleCompiler.prototype._compileStyles = function (outputCtx, comp, stylesheet, shim, isComponentStylesheet) { |
| var _this = this; |
| var styleExpressions = stylesheet.styles.map(function (plainStyle) { return literal(_this._shimIfNeeded(plainStyle, shim)); }); |
| var dependencies = []; |
| stylesheet.styleUrls.forEach(function (styleUrl) { |
| var exprIndex = styleExpressions.length; |
| // Note: This placeholder will be filled later. |
| styleExpressions.push(null); |
| dependencies.push(new StylesCompileDependency(getStylesVarName(null), styleUrl, function (value) { return styleExpressions[exprIndex] = outputCtx.importExpr(value); })); |
| }); |
| // styles variable contains plain strings and arrays of other styles arrays (recursive), |
| // so we set its type to dynamic. |
| var stylesVar = getStylesVarName(isComponentStylesheet ? comp : null); |
| var stmt = variable(stylesVar) |
| .set(literalArr(styleExpressions, new ArrayType(DYNAMIC_TYPE, [TypeModifier.Const]))) |
| .toDeclStmt(null, isComponentStylesheet ? [exports.StmtModifier.Final] : [ |
| exports.StmtModifier.Final, exports.StmtModifier.Exported |
| ]); |
| outputCtx.statements.push(stmt); |
| return new CompiledStylesheet(outputCtx, stylesVar, dependencies, shim, stylesheet); |
| }; |
| StyleCompiler.prototype._shimIfNeeded = function (style, shim) { |
| return shim ? this._shadowCss.shimCssText(style, CONTENT_ATTR, HOST_ATTR) : style; |
| }; |
| return StyleCompiler; |
| }()); |
| function getStylesVarName(component) { |
| var result = "styles"; |
| if (component) { |
| result += "_" + identifierName(component.type); |
| } |
| return result; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * A path is an ordered set of elements. Typically a path is to a |
| * particular offset in a source file. The head of the list is the top |
| * most node. The tail is the node that contains the offset directly. |
| * |
| * For example, the expression `a + b + c` might have an ast that looks |
| * like: |
| * + |
| * / \ |
| * a + |
| * / \ |
| * b c |
| * |
| * The path to the node at offset 9 would be `['+' at 1-10, '+' at 7-10, |
| * 'c' at 9-10]` and the path the node at offset 1 would be |
| * `['+' at 1-10, 'a' at 1-2]`. |
| */ |
| var AstPath = /** @class */ (function () { |
| function AstPath(path, position) { |
| if (position === void 0) { position = -1; } |
| this.path = path; |
| this.position = position; |
| } |
| Object.defineProperty(AstPath.prototype, "empty", { |
| get: function () { |
| return !this.path || !this.path.length; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(AstPath.prototype, "head", { |
| get: function () { |
| return this.path[0]; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(AstPath.prototype, "tail", { |
| get: function () { |
| return this.path[this.path.length - 1]; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| AstPath.prototype.parentOf = function (node) { |
| return node && this.path[this.path.indexOf(node) - 1]; |
| }; |
| AstPath.prototype.childOf = function (node) { |
| return this.path[this.path.indexOf(node) + 1]; |
| }; |
| AstPath.prototype.first = function (ctor) { |
| for (var i = this.path.length - 1; i >= 0; i--) { |
| var item = this.path[i]; |
| if (item instanceof ctor) |
| return item; |
| } |
| }; |
| AstPath.prototype.push = function (node) { |
| this.path.push(node); |
| }; |
| AstPath.prototype.pop = function () { |
| return this.path.pop(); |
| }; |
| return AstPath; |
| }()); |
| |
| var NodeWithI18n = /** @class */ (function () { |
| function NodeWithI18n(sourceSpan, i18n) { |
| this.sourceSpan = sourceSpan; |
| this.i18n = i18n; |
| } |
| return NodeWithI18n; |
| }()); |
| var Text$3 = /** @class */ (function (_super) { |
| __extends(Text, _super); |
| function Text(value, sourceSpan, i18n) { |
| var _this = _super.call(this, sourceSpan, i18n) || this; |
| _this.value = value; |
| return _this; |
| } |
| Text.prototype.visit = function (visitor, context) { |
| return visitor.visitText(this, context); |
| }; |
| return Text; |
| }(NodeWithI18n)); |
| var Expansion = /** @class */ (function (_super) { |
| __extends(Expansion, _super); |
| function Expansion(switchValue, type, cases, sourceSpan, switchValueSourceSpan, i18n) { |
| var _this = _super.call(this, sourceSpan, i18n) || this; |
| _this.switchValue = switchValue; |
| _this.type = type; |
| _this.cases = cases; |
| _this.switchValueSourceSpan = switchValueSourceSpan; |
| return _this; |
| } |
| Expansion.prototype.visit = function (visitor, context) { |
| return visitor.visitExpansion(this, context); |
| }; |
| return Expansion; |
| }(NodeWithI18n)); |
| var ExpansionCase = /** @class */ (function () { |
| function ExpansionCase(value, expression, sourceSpan, valueSourceSpan, expSourceSpan) { |
| this.value = value; |
| this.expression = expression; |
| this.sourceSpan = sourceSpan; |
| this.valueSourceSpan = valueSourceSpan; |
| this.expSourceSpan = expSourceSpan; |
| } |
| ExpansionCase.prototype.visit = function (visitor, context) { |
| return visitor.visitExpansionCase(this, context); |
| }; |
| return ExpansionCase; |
| }()); |
| var Attribute = /** @class */ (function (_super) { |
| __extends(Attribute, _super); |
| function Attribute(name, value, sourceSpan, keySpan, valueSpan, i18n) { |
| var _this = _super.call(this, sourceSpan, i18n) || this; |
| _this.name = name; |
| _this.value = value; |
| _this.keySpan = keySpan; |
| _this.valueSpan = valueSpan; |
| return _this; |
| } |
| Attribute.prototype.visit = function (visitor, context) { |
| return visitor.visitAttribute(this, context); |
| }; |
| return Attribute; |
| }(NodeWithI18n)); |
| var Element$1 = /** @class */ (function (_super) { |
| __extends(Element, _super); |
| function Element(name, attrs, children, sourceSpan, startSourceSpan, endSourceSpan, i18n) { |
| if (endSourceSpan === void 0) { endSourceSpan = null; } |
| var _this = _super.call(this, sourceSpan, i18n) || this; |
| _this.name = name; |
| _this.attrs = attrs; |
| _this.children = children; |
| _this.startSourceSpan = startSourceSpan; |
| _this.endSourceSpan = endSourceSpan; |
| return _this; |
| } |
| Element.prototype.visit = function (visitor, context) { |
| return visitor.visitElement(this, context); |
| }; |
| return Element; |
| }(NodeWithI18n)); |
| var Comment$1 = /** @class */ (function () { |
| function Comment(value, sourceSpan) { |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| } |
| Comment.prototype.visit = function (visitor, context) { |
| return visitor.visitComment(this, context); |
| }; |
| return Comment; |
| }()); |
| function visitAll$1(visitor, nodes, context) { |
| if (context === void 0) { context = null; } |
| var result = []; |
| var visit = visitor.visit ? |
| function (ast) { return visitor.visit(ast, context) || ast.visit(visitor, context); } : |
| function (ast) { return ast.visit(visitor, context); }; |
| nodes.forEach(function (ast) { |
| var astResult = visit(ast); |
| if (astResult) { |
| result.push(astResult); |
| } |
| }); |
| return result; |
| } |
| var RecursiveVisitor$1 = /** @class */ (function () { |
| function RecursiveVisitor() { |
| } |
| RecursiveVisitor.prototype.visitElement = function (ast, context) { |
| this.visitChildren(context, function (visit) { |
| visit(ast.attrs); |
| visit(ast.children); |
| }); |
| }; |
| RecursiveVisitor.prototype.visitAttribute = function (ast, context) { }; |
| RecursiveVisitor.prototype.visitText = function (ast, context) { }; |
| RecursiveVisitor.prototype.visitComment = function (ast, context) { }; |
| RecursiveVisitor.prototype.visitExpansion = function (ast, context) { |
| return this.visitChildren(context, function (visit) { |
| visit(ast.cases); |
| }); |
| }; |
| RecursiveVisitor.prototype.visitExpansionCase = function (ast, context) { }; |
| RecursiveVisitor.prototype.visitChildren = function (context, cb) { |
| var results = []; |
| var t = this; |
| function visit(children) { |
| if (children) |
| results.push(visitAll$1(t, children, context)); |
| } |
| cb(visit); |
| return Array.prototype.concat.apply([], results); |
| }; |
| return RecursiveVisitor; |
| }()); |
| function spanOf(ast) { |
| var start = ast.sourceSpan.start.offset; |
| var end = ast.sourceSpan.end.offset; |
| if (ast instanceof Element$1) { |
| if (ast.endSourceSpan) { |
| end = ast.endSourceSpan.end.offset; |
| } |
| else if (ast.children && ast.children.length) { |
| end = spanOf(ast.children[ast.children.length - 1]).end; |
| } |
| } |
| return { start: start, end: end }; |
| } |
| function findNode(nodes, position) { |
| var path = []; |
| var visitor = new /** @class */ (function (_super) { |
| __extends(class_1, _super); |
| function class_1() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| class_1.prototype.visit = function (ast, context) { |
| var span = spanOf(ast); |
| if (span.start <= position && position < span.end) { |
| path.push(ast); |
| } |
| else { |
| // Returning a value here will result in the children being skipped. |
| return true; |
| } |
| }; |
| return class_1; |
| }(RecursiveVisitor$1)); |
| visitAll$1(visitor, nodes); |
| return new AstPath(path, position); |
| } |
| |
| var TokenType; |
| (function (TokenType) { |
| TokenType[TokenType["TAG_OPEN_START"] = 0] = "TAG_OPEN_START"; |
| TokenType[TokenType["TAG_OPEN_END"] = 1] = "TAG_OPEN_END"; |
| TokenType[TokenType["TAG_OPEN_END_VOID"] = 2] = "TAG_OPEN_END_VOID"; |
| TokenType[TokenType["TAG_CLOSE"] = 3] = "TAG_CLOSE"; |
| TokenType[TokenType["INCOMPLETE_TAG_OPEN"] = 4] = "INCOMPLETE_TAG_OPEN"; |
| TokenType[TokenType["TEXT"] = 5] = "TEXT"; |
| TokenType[TokenType["ESCAPABLE_RAW_TEXT"] = 6] = "ESCAPABLE_RAW_TEXT"; |
| TokenType[TokenType["RAW_TEXT"] = 7] = "RAW_TEXT"; |
| TokenType[TokenType["COMMENT_START"] = 8] = "COMMENT_START"; |
| TokenType[TokenType["COMMENT_END"] = 9] = "COMMENT_END"; |
| TokenType[TokenType["CDATA_START"] = 10] = "CDATA_START"; |
| TokenType[TokenType["CDATA_END"] = 11] = "CDATA_END"; |
| TokenType[TokenType["ATTR_NAME"] = 12] = "ATTR_NAME"; |
| TokenType[TokenType["ATTR_QUOTE"] = 13] = "ATTR_QUOTE"; |
| TokenType[TokenType["ATTR_VALUE"] = 14] = "ATTR_VALUE"; |
| TokenType[TokenType["DOC_TYPE"] = 15] = "DOC_TYPE"; |
| TokenType[TokenType["EXPANSION_FORM_START"] = 16] = "EXPANSION_FORM_START"; |
| TokenType[TokenType["EXPANSION_CASE_VALUE"] = 17] = "EXPANSION_CASE_VALUE"; |
| TokenType[TokenType["EXPANSION_CASE_EXP_START"] = 18] = "EXPANSION_CASE_EXP_START"; |
| TokenType[TokenType["EXPANSION_CASE_EXP_END"] = 19] = "EXPANSION_CASE_EXP_END"; |
| TokenType[TokenType["EXPANSION_FORM_END"] = 20] = "EXPANSION_FORM_END"; |
| TokenType[TokenType["EOF"] = 21] = "EOF"; |
| })(TokenType || (TokenType = {})); |
| var Token = /** @class */ (function () { |
| function Token(type, parts, sourceSpan) { |
| this.type = type; |
| this.parts = parts; |
| this.sourceSpan = sourceSpan; |
| } |
| return Token; |
| }()); |
| var TokenError = /** @class */ (function (_super) { |
| __extends(TokenError, _super); |
| function TokenError(errorMsg, tokenType, span) { |
| var _this = _super.call(this, span, errorMsg) || this; |
| _this.tokenType = tokenType; |
| return _this; |
| } |
| return TokenError; |
| }(ParseError)); |
| var TokenizeResult = /** @class */ (function () { |
| function TokenizeResult(tokens, errors, nonNormalizedIcuExpressions) { |
| this.tokens = tokens; |
| this.errors = errors; |
| this.nonNormalizedIcuExpressions = nonNormalizedIcuExpressions; |
| } |
| return TokenizeResult; |
| }()); |
| function tokenize(source, url, getTagDefinition, options) { |
| if (options === void 0) { options = {}; } |
| var tokenizer = new _Tokenizer(new ParseSourceFile(source, url), getTagDefinition, options); |
| tokenizer.tokenize(); |
| return new TokenizeResult(mergeTextTokens(tokenizer.tokens), tokenizer.errors, tokenizer.nonNormalizedIcuExpressions); |
| } |
| var _CR_OR_CRLF_REGEXP = /\r\n?/g; |
| function _unexpectedCharacterErrorMsg(charCode) { |
| var char = charCode === $EOF ? 'EOF' : String.fromCharCode(charCode); |
| return "Unexpected character \"" + char + "\""; |
| } |
| function _unknownEntityErrorMsg(entitySrc) { |
| return "Unknown entity \"" + entitySrc + "\" - use the \"&#<decimal>;\" or \"&#x<hex>;\" syntax"; |
| } |
| function _unparsableEntityErrorMsg(type, entityStr) { |
| return "Unable to parse entity \"" + entityStr + "\" - " + type + " character reference entities must end with \";\""; |
| } |
| var CharacterReferenceType; |
| (function (CharacterReferenceType) { |
| CharacterReferenceType["HEX"] = "hexadecimal"; |
| CharacterReferenceType["DEC"] = "decimal"; |
| })(CharacterReferenceType || (CharacterReferenceType = {})); |
| var _ControlFlowError = /** @class */ (function () { |
| function _ControlFlowError(error) { |
| this.error = error; |
| } |
| return _ControlFlowError; |
| }()); |
| // See https://www.w3.org/TR/html51/syntax.html#writing-html-documents |
| var _Tokenizer = /** @class */ (function () { |
| /** |
| * @param _file The html source file being tokenized. |
| * @param _getTagDefinition A function that will retrieve a tag definition for a given tag name. |
| * @param options Configuration of the tokenization. |
| */ |
| function _Tokenizer(_file, _getTagDefinition, options) { |
| this._getTagDefinition = _getTagDefinition; |
| this._currentTokenStart = null; |
| this._currentTokenType = null; |
| this._expansionCaseStack = []; |
| this._inInterpolation = false; |
| this.tokens = []; |
| this.errors = []; |
| this.nonNormalizedIcuExpressions = []; |
| this._tokenizeIcu = options.tokenizeExpansionForms || false; |
| this._interpolationConfig = options.interpolationConfig || DEFAULT_INTERPOLATION_CONFIG; |
| this._leadingTriviaCodePoints = |
| options.leadingTriviaChars && options.leadingTriviaChars.map(function (c) { return c.codePointAt(0) || 0; }); |
| var range = options.range || { endPos: _file.content.length, startPos: 0, startLine: 0, startCol: 0 }; |
| this._cursor = options.escapedString ? new EscapedCharacterCursor(_file, range) : |
| new PlainCharacterCursor(_file, range); |
| this._preserveLineEndings = options.preserveLineEndings || false; |
| this._escapedString = options.escapedString || false; |
| this._i18nNormalizeLineEndingsInICUs = options.i18nNormalizeLineEndingsInICUs || false; |
| try { |
| this._cursor.init(); |
| } |
| catch (e) { |
| this.handleError(e); |
| } |
| } |
| _Tokenizer.prototype._processCarriageReturns = function (content) { |
| if (this._preserveLineEndings) { |
| return content; |
| } |
| // https://www.w3.org/TR/html51/syntax.html#preprocessing-the-input-stream |
| // In order to keep the original position in the source, we can not |
| // pre-process it. |
| // Instead CRs are processed right before instantiating the tokens. |
| return content.replace(_CR_OR_CRLF_REGEXP, '\n'); |
| }; |
| _Tokenizer.prototype.tokenize = function () { |
| while (this._cursor.peek() !== $EOF) { |
| var start = this._cursor.clone(); |
| try { |
| if (this._attemptCharCode($LT)) { |
| if (this._attemptCharCode($BANG)) { |
| if (this._attemptCharCode($LBRACKET)) { |
| this._consumeCdata(start); |
| } |
| else if (this._attemptCharCode($MINUS)) { |
| this._consumeComment(start); |
| } |
| else { |
| this._consumeDocType(start); |
| } |
| } |
| else if (this._attemptCharCode($SLASH)) { |
| this._consumeTagClose(start); |
| } |
| else { |
| this._consumeTagOpen(start); |
| } |
| } |
| else if (!(this._tokenizeIcu && this._tokenizeExpansionForm())) { |
| this._consumeText(); |
| } |
| } |
| catch (e) { |
| this.handleError(e); |
| } |
| } |
| this._beginToken(TokenType.EOF); |
| this._endToken([]); |
| }; |
| /** |
| * @returns whether an ICU token has been created |
| * @internal |
| */ |
| _Tokenizer.prototype._tokenizeExpansionForm = function () { |
| if (this.isExpansionFormStart()) { |
| this._consumeExpansionFormStart(); |
| return true; |
| } |
| if (isExpansionCaseStart(this._cursor.peek()) && this._isInExpansionForm()) { |
| this._consumeExpansionCaseStart(); |
| return true; |
| } |
| if (this._cursor.peek() === $RBRACE) { |
| if (this._isInExpansionCase()) { |
| this._consumeExpansionCaseEnd(); |
| return true; |
| } |
| if (this._isInExpansionForm()) { |
| this._consumeExpansionFormEnd(); |
| return true; |
| } |
| } |
| return false; |
| }; |
| _Tokenizer.prototype._beginToken = function (type, start) { |
| if (start === void 0) { start = this._cursor.clone(); } |
| this._currentTokenStart = start; |
| this._currentTokenType = type; |
| }; |
| _Tokenizer.prototype._endToken = function (parts, end) { |
| if (this._currentTokenStart === null) { |
| throw new TokenError('Programming error - attempted to end a token when there was no start to the token', this._currentTokenType, this._cursor.getSpan(end)); |
| } |
| if (this._currentTokenType === null) { |
| throw new TokenError('Programming error - attempted to end a token which has no token type', null, this._cursor.getSpan(this._currentTokenStart)); |
| } |
| var token = new Token(this._currentTokenType, parts, this._cursor.getSpan(this._currentTokenStart, this._leadingTriviaCodePoints)); |
| this.tokens.push(token); |
| this._currentTokenStart = null; |
| this._currentTokenType = null; |
| return token; |
| }; |
| _Tokenizer.prototype._createError = function (msg, span) { |
| if (this._isInExpansionForm()) { |
| msg += " (Do you have an unescaped \"{\" in your template? Use \"{{ '{' }}\") to escape it.)"; |
| } |
| var error = new TokenError(msg, this._currentTokenType, span); |
| this._currentTokenStart = null; |
| this._currentTokenType = null; |
| return new _ControlFlowError(error); |
| }; |
| _Tokenizer.prototype.handleError = function (e) { |
| if (e instanceof CursorError) { |
| e = this._createError(e.msg, this._cursor.getSpan(e.cursor)); |
| } |
| if (e instanceof _ControlFlowError) { |
| this.errors.push(e.error); |
| } |
| else { |
| throw e; |
| } |
| }; |
| _Tokenizer.prototype._attemptCharCode = function (charCode) { |
| if (this._cursor.peek() === charCode) { |
| this._cursor.advance(); |
| return true; |
| } |
| return false; |
| }; |
| _Tokenizer.prototype._attemptCharCodeCaseInsensitive = function (charCode) { |
| if (compareCharCodeCaseInsensitive(this._cursor.peek(), charCode)) { |
| this._cursor.advance(); |
| return true; |
| } |
| return false; |
| }; |
| _Tokenizer.prototype._requireCharCode = function (charCode) { |
| var location = this._cursor.clone(); |
| if (!this._attemptCharCode(charCode)) { |
| throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(location)); |
| } |
| }; |
| _Tokenizer.prototype._attemptStr = function (chars) { |
| var len = chars.length; |
| if (this._cursor.charsLeft() < len) { |
| return false; |
| } |
| var initialPosition = this._cursor.clone(); |
| for (var i = 0; i < len; i++) { |
| if (!this._attemptCharCode(chars.charCodeAt(i))) { |
| // If attempting to parse the string fails, we want to reset the parser |
| // to where it was before the attempt |
| this._cursor = initialPosition; |
| return false; |
| } |
| } |
| return true; |
| }; |
| _Tokenizer.prototype._attemptStrCaseInsensitive = function (chars) { |
| for (var i = 0; i < chars.length; i++) { |
| if (!this._attemptCharCodeCaseInsensitive(chars.charCodeAt(i))) { |
| return false; |
| } |
| } |
| return true; |
| }; |
| _Tokenizer.prototype._requireStr = function (chars) { |
| var location = this._cursor.clone(); |
| if (!this._attemptStr(chars)) { |
| throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(location)); |
| } |
| }; |
| _Tokenizer.prototype._attemptCharCodeUntilFn = function (predicate) { |
| while (!predicate(this._cursor.peek())) { |
| this._cursor.advance(); |
| } |
| }; |
| _Tokenizer.prototype._requireCharCodeUntilFn = function (predicate, len) { |
| var start = this._cursor.clone(); |
| this._attemptCharCodeUntilFn(predicate); |
| if (this._cursor.diff(start) < len) { |
| throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(start)); |
| } |
| }; |
| _Tokenizer.prototype._attemptUntilChar = function (char) { |
| while (this._cursor.peek() !== char) { |
| this._cursor.advance(); |
| } |
| }; |
| _Tokenizer.prototype._readChar = function (decodeEntities) { |
| if (decodeEntities && this._cursor.peek() === $AMPERSAND) { |
| return this._decodeEntity(); |
| } |
| else { |
| // Don't rely upon reading directly from `_input` as the actual char value |
| // may have been generated from an escape sequence. |
| var char = String.fromCodePoint(this._cursor.peek()); |
| this._cursor.advance(); |
| return char; |
| } |
| }; |
| _Tokenizer.prototype._decodeEntity = function () { |
| var start = this._cursor.clone(); |
| this._cursor.advance(); |
| if (this._attemptCharCode($HASH)) { |
| var isHex = this._attemptCharCode($x) || this._attemptCharCode($X); |
| var codeStart = this._cursor.clone(); |
| this._attemptCharCodeUntilFn(isDigitEntityEnd); |
| if (this._cursor.peek() != $SEMICOLON) { |
| // Advance cursor to include the peeked character in the string provided to the error |
| // message. |
| this._cursor.advance(); |
| var entityType = isHex ? CharacterReferenceType.HEX : CharacterReferenceType.DEC; |
| throw this._createError(_unparsableEntityErrorMsg(entityType, this._cursor.getChars(start)), this._cursor.getSpan()); |
| } |
| var strNum = this._cursor.getChars(codeStart); |
| this._cursor.advance(); |
| try { |
| var charCode = parseInt(strNum, isHex ? 16 : 10); |
| return String.fromCharCode(charCode); |
| } |
| catch (_a) { |
| throw this._createError(_unknownEntityErrorMsg(this._cursor.getChars(start)), this._cursor.getSpan()); |
| } |
| } |
| else { |
| var nameStart = this._cursor.clone(); |
| this._attemptCharCodeUntilFn(isNamedEntityEnd); |
| if (this._cursor.peek() != $SEMICOLON) { |
| this._cursor = nameStart; |
| return '&'; |
| } |
| var name = this._cursor.getChars(nameStart); |
| this._cursor.advance(); |
| var char = NAMED_ENTITIES[name]; |
| if (!char) { |
| throw this._createError(_unknownEntityErrorMsg(name), this._cursor.getSpan(start)); |
| } |
| return char; |
| } |
| }; |
| _Tokenizer.prototype._consumeRawText = function (decodeEntities, endMarkerPredicate) { |
| this._beginToken(decodeEntities ? TokenType.ESCAPABLE_RAW_TEXT : TokenType.RAW_TEXT); |
| var parts = []; |
| while (true) { |
| var tagCloseStart = this._cursor.clone(); |
| var foundEndMarker = endMarkerPredicate(); |
| this._cursor = tagCloseStart; |
| if (foundEndMarker) { |
| break; |
| } |
| parts.push(this._readChar(decodeEntities)); |
| } |
| return this._endToken([this._processCarriageReturns(parts.join(''))]); |
| }; |
| _Tokenizer.prototype._consumeComment = function (start) { |
| var _this = this; |
| this._beginToken(TokenType.COMMENT_START, start); |
| this._requireCharCode($MINUS); |
| this._endToken([]); |
| this._consumeRawText(false, function () { return _this._attemptStr('-->'); }); |
| this._beginToken(TokenType.COMMENT_END); |
| this._requireStr('-->'); |
| this._endToken([]); |
| }; |
| _Tokenizer.prototype._consumeCdata = function (start) { |
| var _this = this; |
| this._beginToken(TokenType.CDATA_START, start); |
| this._requireStr('CDATA['); |
| this._endToken([]); |
| this._consumeRawText(false, function () { return _this._attemptStr(']]>'); }); |
| this._beginToken(TokenType.CDATA_END); |
| this._requireStr(']]>'); |
| this._endToken([]); |
| }; |
| _Tokenizer.prototype._consumeDocType = function (start) { |
| this._beginToken(TokenType.DOC_TYPE, start); |
| var contentStart = this._cursor.clone(); |
| this._attemptUntilChar($GT); |
| var content = this._cursor.getChars(contentStart); |
| this._cursor.advance(); |
| this._endToken([content]); |
| }; |
| _Tokenizer.prototype._consumePrefixAndName = function () { |
| var nameOrPrefixStart = this._cursor.clone(); |
| var prefix = ''; |
| while (this._cursor.peek() !== $COLON && !isPrefixEnd(this._cursor.peek())) { |
| this._cursor.advance(); |
| } |
| var nameStart; |
| if (this._cursor.peek() === $COLON) { |
| prefix = this._cursor.getChars(nameOrPrefixStart); |
| this._cursor.advance(); |
| nameStart = this._cursor.clone(); |
| } |
| else { |
| nameStart = nameOrPrefixStart; |
| } |
| this._requireCharCodeUntilFn(isNameEnd, prefix === '' ? 0 : 1); |
| var name = this._cursor.getChars(nameStart); |
| return [prefix, name]; |
| }; |
| _Tokenizer.prototype._consumeTagOpen = function (start) { |
| var tagName; |
| var prefix; |
| var openTagToken; |
| try { |
| if (!isAsciiLetter(this._cursor.peek())) { |
| throw this._createError(_unexpectedCharacterErrorMsg(this._cursor.peek()), this._cursor.getSpan(start)); |
| } |
| openTagToken = this._consumeTagOpenStart(start); |
| prefix = openTagToken.parts[0]; |
| tagName = openTagToken.parts[1]; |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| while (this._cursor.peek() !== $SLASH && this._cursor.peek() !== $GT && |
| this._cursor.peek() !== $LT && this._cursor.peek() !== $EOF) { |
| this._consumeAttributeName(); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| if (this._attemptCharCode($EQ)) { |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| this._consumeAttributeValue(); |
| } |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| } |
| this._consumeTagOpenEnd(); |
| } |
| catch (e) { |
| if (e instanceof _ControlFlowError) { |
| if (openTagToken) { |
| // We errored before we could close the opening tag, so it is incomplete. |
| openTagToken.type = TokenType.INCOMPLETE_TAG_OPEN; |
| } |
| else { |
| // When the start tag is invalid, assume we want a "<" as text. |
| // Back to back text tokens are merged at the end. |
| this._beginToken(TokenType.TEXT, start); |
| this._endToken(['<']); |
| } |
| return; |
| } |
| throw e; |
| } |
| var contentTokenType = this._getTagDefinition(tagName).getContentType(prefix); |
| if (contentTokenType === exports.TagContentType.RAW_TEXT) { |
| this._consumeRawTextWithTagClose(prefix, tagName, false); |
| } |
| else if (contentTokenType === exports.TagContentType.ESCAPABLE_RAW_TEXT) { |
| this._consumeRawTextWithTagClose(prefix, tagName, true); |
| } |
| }; |
| _Tokenizer.prototype._consumeRawTextWithTagClose = function (prefix, tagName, decodeEntities) { |
| var _this = this; |
| this._consumeRawText(decodeEntities, function () { |
| if (!_this._attemptCharCode($LT)) |
| return false; |
| if (!_this._attemptCharCode($SLASH)) |
| return false; |
| _this._attemptCharCodeUntilFn(isNotWhitespace); |
| if (!_this._attemptStrCaseInsensitive(tagName)) |
| return false; |
| _this._attemptCharCodeUntilFn(isNotWhitespace); |
| return _this._attemptCharCode($GT); |
| }); |
| this._beginToken(TokenType.TAG_CLOSE); |
| this._requireCharCodeUntilFn(function (code) { return code === $GT; }, 3); |
| this._cursor.advance(); // Consume the `>` |
| this._endToken([prefix, tagName]); |
| }; |
| _Tokenizer.prototype._consumeTagOpenStart = function (start) { |
| this._beginToken(TokenType.TAG_OPEN_START, start); |
| var parts = this._consumePrefixAndName(); |
| return this._endToken(parts); |
| }; |
| _Tokenizer.prototype._consumeAttributeName = function () { |
| var attrNameStart = this._cursor.peek(); |
| if (attrNameStart === $SQ || attrNameStart === $DQ) { |
| throw this._createError(_unexpectedCharacterErrorMsg(attrNameStart), this._cursor.getSpan()); |
| } |
| this._beginToken(TokenType.ATTR_NAME); |
| var prefixAndName = this._consumePrefixAndName(); |
| this._endToken(prefixAndName); |
| }; |
| _Tokenizer.prototype._consumeAttributeValue = function () { |
| var value; |
| if (this._cursor.peek() === $SQ || this._cursor.peek() === $DQ) { |
| this._beginToken(TokenType.ATTR_QUOTE); |
| var quoteChar = this._cursor.peek(); |
| this._cursor.advance(); |
| this._endToken([String.fromCodePoint(quoteChar)]); |
| this._beginToken(TokenType.ATTR_VALUE); |
| var parts = []; |
| while (this._cursor.peek() !== quoteChar) { |
| parts.push(this._readChar(true)); |
| } |
| value = parts.join(''); |
| this._endToken([this._processCarriageReturns(value)]); |
| this._beginToken(TokenType.ATTR_QUOTE); |
| this._cursor.advance(); |
| this._endToken([String.fromCodePoint(quoteChar)]); |
| } |
| else { |
| this._beginToken(TokenType.ATTR_VALUE); |
| var valueStart = this._cursor.clone(); |
| this._requireCharCodeUntilFn(isNameEnd, 1); |
| value = this._cursor.getChars(valueStart); |
| this._endToken([this._processCarriageReturns(value)]); |
| } |
| }; |
| _Tokenizer.prototype._consumeTagOpenEnd = function () { |
| var tokenType = this._attemptCharCode($SLASH) ? TokenType.TAG_OPEN_END_VOID : TokenType.TAG_OPEN_END; |
| this._beginToken(tokenType); |
| this._requireCharCode($GT); |
| this._endToken([]); |
| }; |
| _Tokenizer.prototype._consumeTagClose = function (start) { |
| this._beginToken(TokenType.TAG_CLOSE, start); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| var prefixAndName = this._consumePrefixAndName(); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| this._requireCharCode($GT); |
| this._endToken(prefixAndName); |
| }; |
| _Tokenizer.prototype._consumeExpansionFormStart = function () { |
| this._beginToken(TokenType.EXPANSION_FORM_START); |
| this._requireCharCode($LBRACE); |
| this._endToken([]); |
| this._expansionCaseStack.push(TokenType.EXPANSION_FORM_START); |
| this._beginToken(TokenType.RAW_TEXT); |
| var condition = this._readUntil($COMMA); |
| var normalizedCondition = this._processCarriageReturns(condition); |
| if (this._i18nNormalizeLineEndingsInICUs) { |
| // We explicitly want to normalize line endings for this text. |
| this._endToken([normalizedCondition]); |
| } |
| else { |
| // We are not normalizing line endings. |
| var conditionToken = this._endToken([condition]); |
| if (normalizedCondition !== condition) { |
| this.nonNormalizedIcuExpressions.push(conditionToken); |
| } |
| } |
| this._requireCharCode($COMMA); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| this._beginToken(TokenType.RAW_TEXT); |
| var type = this._readUntil($COMMA); |
| this._endToken([type]); |
| this._requireCharCode($COMMA); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| }; |
| _Tokenizer.prototype._consumeExpansionCaseStart = function () { |
| this._beginToken(TokenType.EXPANSION_CASE_VALUE); |
| var value = this._readUntil($LBRACE).trim(); |
| this._endToken([value]); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| this._beginToken(TokenType.EXPANSION_CASE_EXP_START); |
| this._requireCharCode($LBRACE); |
| this._endToken([]); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| this._expansionCaseStack.push(TokenType.EXPANSION_CASE_EXP_START); |
| }; |
| _Tokenizer.prototype._consumeExpansionCaseEnd = function () { |
| this._beginToken(TokenType.EXPANSION_CASE_EXP_END); |
| this._requireCharCode($RBRACE); |
| this._endToken([]); |
| this._attemptCharCodeUntilFn(isNotWhitespace); |
| this._expansionCaseStack.pop(); |
| }; |
| _Tokenizer.prototype._consumeExpansionFormEnd = function () { |
| this._beginToken(TokenType.EXPANSION_FORM_END); |
| this._requireCharCode($RBRACE); |
| this._endToken([]); |
| this._expansionCaseStack.pop(); |
| }; |
| _Tokenizer.prototype._consumeText = function () { |
| var start = this._cursor.clone(); |
| this._beginToken(TokenType.TEXT, start); |
| var parts = []; |
| do { |
| if (this._interpolationConfig && this._attemptStr(this._interpolationConfig.start)) { |
| parts.push(this._interpolationConfig.start); |
| this._inInterpolation = true; |
| } |
| else if (this._interpolationConfig && this._inInterpolation && |
| this._attemptStr(this._interpolationConfig.end)) { |
| parts.push(this._interpolationConfig.end); |
| this._inInterpolation = false; |
| } |
| else { |
| parts.push(this._readChar(true)); |
| } |
| } while (!this._isTextEnd()); |
| this._endToken([this._processCarriageReturns(parts.join(''))]); |
| }; |
| _Tokenizer.prototype._isTextEnd = function () { |
| if (this._cursor.peek() === $LT || this._cursor.peek() === $EOF) { |
| return true; |
| } |
| if (this._tokenizeIcu && !this._inInterpolation) { |
| if (this.isExpansionFormStart()) { |
| // start of an expansion form |
| return true; |
| } |
| if (this._cursor.peek() === $RBRACE && this._isInExpansionCase()) { |
| // end of and expansion case |
| return true; |
| } |
| } |
| return false; |
| }; |
| _Tokenizer.prototype._readUntil = function (char) { |
| var start = this._cursor.clone(); |
| this._attemptUntilChar(char); |
| return this._cursor.getChars(start); |
| }; |
| _Tokenizer.prototype._isInExpansionCase = function () { |
| return this._expansionCaseStack.length > 0 && |
| this._expansionCaseStack[this._expansionCaseStack.length - 1] === |
| TokenType.EXPANSION_CASE_EXP_START; |
| }; |
| _Tokenizer.prototype._isInExpansionForm = function () { |
| return this._expansionCaseStack.length > 0 && |
| this._expansionCaseStack[this._expansionCaseStack.length - 1] === |
| TokenType.EXPANSION_FORM_START; |
| }; |
| _Tokenizer.prototype.isExpansionFormStart = function () { |
| if (this._cursor.peek() !== $LBRACE) { |
| return false; |
| } |
| if (this._interpolationConfig) { |
| var start = this._cursor.clone(); |
| var isInterpolation = this._attemptStr(this._interpolationConfig.start); |
| this._cursor = start; |
| return !isInterpolation; |
| } |
| return true; |
| }; |
| return _Tokenizer; |
| }()); |
| function isNotWhitespace(code) { |
| return !isWhitespace(code) || code === $EOF; |
| } |
| function isNameEnd(code) { |
| return isWhitespace(code) || code === $GT || code === $LT || |
| code === $SLASH || code === $SQ || code === $DQ || code === $EQ || |
| code === $EOF; |
| } |
| function isPrefixEnd(code) { |
| return (code < $a || $z < code) && (code < $A || $Z < code) && |
| (code < $0 || code > $9); |
| } |
| function isDigitEntityEnd(code) { |
| return code == $SEMICOLON || code == $EOF || !isAsciiHexDigit(code); |
| } |
| function isNamedEntityEnd(code) { |
| return code == $SEMICOLON || code == $EOF || !isAsciiLetter(code); |
| } |
| function isExpansionCaseStart(peek) { |
| return peek !== $RBRACE; |
| } |
| function compareCharCodeCaseInsensitive(code1, code2) { |
| return toUpperCaseCharCode(code1) == toUpperCaseCharCode(code2); |
| } |
| function toUpperCaseCharCode(code) { |
| return code >= $a && code <= $z ? code - $a + $A : code; |
| } |
| function mergeTextTokens(srcTokens) { |
| var dstTokens = []; |
| var lastDstToken = undefined; |
| for (var i = 0; i < srcTokens.length; i++) { |
| var token = srcTokens[i]; |
| if (lastDstToken && lastDstToken.type == TokenType.TEXT && token.type == TokenType.TEXT) { |
| lastDstToken.parts[0] += token.parts[0]; |
| lastDstToken.sourceSpan.end = token.sourceSpan.end; |
| } |
| else { |
| lastDstToken = token; |
| dstTokens.push(lastDstToken); |
| } |
| } |
| return dstTokens; |
| } |
| var PlainCharacterCursor = /** @class */ (function () { |
| function PlainCharacterCursor(fileOrCursor, range) { |
| if (fileOrCursor instanceof PlainCharacterCursor) { |
| this.file = fileOrCursor.file; |
| this.input = fileOrCursor.input; |
| this.end = fileOrCursor.end; |
| var state = fileOrCursor.state; |
| // Note: avoid using `{...fileOrCursor.state}` here as that has a severe performance penalty. |
| // In ES5 bundles the object spread operator is translated into the `__assign` helper, which |
| // is not optimized by VMs as efficiently as a raw object literal. Since this constructor is |
| // called in tight loops, this difference matters. |
| this.state = { |
| peek: state.peek, |
| offset: state.offset, |
| line: state.line, |
| column: state.column, |
| }; |
| } |
| else { |
| if (!range) { |
| throw new Error('Programming error: the range argument must be provided with a file argument.'); |
| } |
| this.file = fileOrCursor; |
| this.input = fileOrCursor.content; |
| this.end = range.endPos; |
| this.state = { |
| peek: -1, |
| offset: range.startPos, |
| line: range.startLine, |
| column: range.startCol, |
| }; |
| } |
| } |
| PlainCharacterCursor.prototype.clone = function () { |
| return new PlainCharacterCursor(this); |
| }; |
| PlainCharacterCursor.prototype.peek = function () { |
| return this.state.peek; |
| }; |
| PlainCharacterCursor.prototype.charsLeft = function () { |
| return this.end - this.state.offset; |
| }; |
| PlainCharacterCursor.prototype.diff = function (other) { |
| return this.state.offset - other.state.offset; |
| }; |
| PlainCharacterCursor.prototype.advance = function () { |
| this.advanceState(this.state); |
| }; |
| PlainCharacterCursor.prototype.init = function () { |
| this.updatePeek(this.state); |
| }; |
| PlainCharacterCursor.prototype.getSpan = function (start, leadingTriviaCodePoints) { |
| start = start || this; |
| var fullStart = start; |
| if (leadingTriviaCodePoints) { |
| while (this.diff(start) > 0 && leadingTriviaCodePoints.indexOf(start.peek()) !== -1) { |
| if (fullStart === start) { |
| start = start.clone(); |
| } |
| start.advance(); |
| } |
| } |
| var startLocation = this.locationFromCursor(start); |
| var endLocation = this.locationFromCursor(this); |
| var fullStartLocation = fullStart !== start ? this.locationFromCursor(fullStart) : startLocation; |
| return new ParseSourceSpan(startLocation, endLocation, fullStartLocation); |
| }; |
| PlainCharacterCursor.prototype.getChars = function (start) { |
| return this.input.substring(start.state.offset, this.state.offset); |
| }; |
| PlainCharacterCursor.prototype.charAt = function (pos) { |
| return this.input.charCodeAt(pos); |
| }; |
| PlainCharacterCursor.prototype.advanceState = function (state) { |
| if (state.offset >= this.end) { |
| this.state = state; |
| throw new CursorError('Unexpected character "EOF"', this); |
| } |
| var currentChar = this.charAt(state.offset); |
| if (currentChar === $LF) { |
| state.line++; |
| state.column = 0; |
| } |
| else if (!isNewLine(currentChar)) { |
| state.column++; |
| } |
| state.offset++; |
| this.updatePeek(state); |
| }; |
| PlainCharacterCursor.prototype.updatePeek = function (state) { |
| state.peek = state.offset >= this.end ? $EOF : this.charAt(state.offset); |
| }; |
| PlainCharacterCursor.prototype.locationFromCursor = function (cursor) { |
| return new ParseLocation(cursor.file, cursor.state.offset, cursor.state.line, cursor.state.column); |
| }; |
| return PlainCharacterCursor; |
| }()); |
| var EscapedCharacterCursor = /** @class */ (function (_super) { |
| __extends(EscapedCharacterCursor, _super); |
| function EscapedCharacterCursor(fileOrCursor, range) { |
| var _this = this; |
| if (fileOrCursor instanceof EscapedCharacterCursor) { |
| _this = _super.call(this, fileOrCursor) || this; |
| _this.internalState = Object.assign({}, fileOrCursor.internalState); |
| } |
| else { |
| _this = _super.call(this, fileOrCursor, range) || this; |
| _this.internalState = _this.state; |
| } |
| return _this; |
| } |
| EscapedCharacterCursor.prototype.advance = function () { |
| this.state = this.internalState; |
| _super.prototype.advance.call(this); |
| this.processEscapeSequence(); |
| }; |
| EscapedCharacterCursor.prototype.init = function () { |
| _super.prototype.init.call(this); |
| this.processEscapeSequence(); |
| }; |
| EscapedCharacterCursor.prototype.clone = function () { |
| return new EscapedCharacterCursor(this); |
| }; |
| EscapedCharacterCursor.prototype.getChars = function (start) { |
| var cursor = start.clone(); |
| var chars = ''; |
| while (cursor.internalState.offset < this.internalState.offset) { |
| chars += String.fromCodePoint(cursor.peek()); |
| cursor.advance(); |
| } |
| return chars; |
| }; |
| /** |
| * Process the escape sequence that starts at the current position in the text. |
| * |
| * This method is called to ensure that `peek` has the unescaped value of escape sequences. |
| */ |
| EscapedCharacterCursor.prototype.processEscapeSequence = function () { |
| var _this = this; |
| var peek = function () { return _this.internalState.peek; }; |
| if (peek() === $BACKSLASH) { |
| // We have hit an escape sequence so we need the internal state to become independent |
| // of the external state. |
| this.internalState = Object.assign({}, this.state); |
| // Move past the backslash |
| this.advanceState(this.internalState); |
| // First check for standard control char sequences |
| if (peek() === $n) { |
| this.state.peek = $LF; |
| } |
| else if (peek() === $r) { |
| this.state.peek = $CR; |
| } |
| else if (peek() === $v) { |
| this.state.peek = $VTAB; |
| } |
| else if (peek() === $t) { |
| this.state.peek = $TAB; |
| } |
| else if (peek() === $b) { |
| this.state.peek = $BSPACE; |
| } |
| else if (peek() === $f) { |
| this.state.peek = $FF; |
| } |
| // Now consider more complex sequences |
| else if (peek() === $u) { |
| // Unicode code-point sequence |
| this.advanceState(this.internalState); // advance past the `u` char |
| if (peek() === $LBRACE) { |
| // Variable length Unicode, e.g. `\x{123}` |
| this.advanceState(this.internalState); // advance past the `{` char |
| // Advance past the variable number of hex digits until we hit a `}` char |
| var digitStart = this.clone(); |
| var length = 0; |
| while (peek() !== $RBRACE) { |
| this.advanceState(this.internalState); |
| length++; |
| } |
| this.state.peek = this.decodeHexDigits(digitStart, length); |
| } |
| else { |
| // Fixed length Unicode, e.g. `\u1234` |
| var digitStart = this.clone(); |
| this.advanceState(this.internalState); |
| this.advanceState(this.internalState); |
| this.advanceState(this.internalState); |
| this.state.peek = this.decodeHexDigits(digitStart, 4); |
| } |
| } |
| else if (peek() === $x) { |
| // Hex char code, e.g. `\x2F` |
| this.advanceState(this.internalState); // advance past the `x` char |
| var digitStart = this.clone(); |
| this.advanceState(this.internalState); |
| this.state.peek = this.decodeHexDigits(digitStart, 2); |
| } |
| else if (isOctalDigit(peek())) { |
| // Octal char code, e.g. `\012`, |
| var octal = ''; |
| var length = 0; |
| var previous = this.clone(); |
| while (isOctalDigit(peek()) && length < 3) { |
| previous = this.clone(); |
| octal += String.fromCodePoint(peek()); |
| this.advanceState(this.internalState); |
| length++; |
| } |
| this.state.peek = parseInt(octal, 8); |
| // Backup one char |
| this.internalState = previous.internalState; |
| } |
| else if (isNewLine(this.internalState.peek)) { |
| // Line continuation `\` followed by a new line |
| this.advanceState(this.internalState); // advance over the newline |
| this.state = this.internalState; |
| } |
| else { |
| // If none of the `if` blocks were executed then we just have an escaped normal character. |
| // In that case we just, effectively, skip the backslash from the character. |
| this.state.peek = this.internalState.peek; |
| } |
| } |
| }; |
| EscapedCharacterCursor.prototype.decodeHexDigits = function (start, length) { |
| var hex = this.input.substr(start.internalState.offset, length); |
| var charCode = parseInt(hex, 16); |
| if (!isNaN(charCode)) { |
| return charCode; |
| } |
| else { |
| start.state = start.internalState; |
| throw new CursorError('Invalid hexadecimal escape sequence', start); |
| } |
| }; |
| return EscapedCharacterCursor; |
| }(PlainCharacterCursor)); |
| var CursorError = /** @class */ (function () { |
| function CursorError(msg, cursor) { |
| this.msg = msg; |
| this.cursor = cursor; |
| } |
| return CursorError; |
| }()); |
| |
| var TreeError = /** @class */ (function (_super) { |
| __extends(TreeError, _super); |
| function TreeError(elementName, span, msg) { |
| var _this = _super.call(this, span, msg) || this; |
| _this.elementName = elementName; |
| return _this; |
| } |
| TreeError.create = function (elementName, span, msg) { |
| return new TreeError(elementName, span, msg); |
| }; |
| return TreeError; |
| }(ParseError)); |
| var ParseTreeResult = /** @class */ (function () { |
| function ParseTreeResult(rootNodes, errors) { |
| this.rootNodes = rootNodes; |
| this.errors = errors; |
| } |
| return ParseTreeResult; |
| }()); |
| var Parser = /** @class */ (function () { |
| function Parser(getTagDefinition) { |
| this.getTagDefinition = getTagDefinition; |
| } |
| Parser.prototype.parse = function (source, url, options) { |
| var tokenizeResult = tokenize(source, url, this.getTagDefinition, options); |
| var parser = new _TreeBuilder(tokenizeResult.tokens, this.getTagDefinition); |
| parser.build(); |
| return new ParseTreeResult(parser.rootNodes, tokenizeResult.errors.concat(parser.errors)); |
| }; |
| return Parser; |
| }()); |
| var _TreeBuilder = /** @class */ (function () { |
| function _TreeBuilder(tokens, getTagDefinition) { |
| this.tokens = tokens; |
| this.getTagDefinition = getTagDefinition; |
| this._index = -1; |
| this._elementStack = []; |
| this.rootNodes = []; |
| this.errors = []; |
| this._advance(); |
| } |
| _TreeBuilder.prototype.build = function () { |
| while (this._peek.type !== TokenType.EOF) { |
| if (this._peek.type === TokenType.TAG_OPEN_START || |
| this._peek.type === TokenType.INCOMPLETE_TAG_OPEN) { |
| this._consumeStartTag(this._advance()); |
| } |
| else if (this._peek.type === TokenType.TAG_CLOSE) { |
| this._consumeEndTag(this._advance()); |
| } |
| else if (this._peek.type === TokenType.CDATA_START) { |
| this._closeVoidElement(); |
| this._consumeCdata(this._advance()); |
| } |
| else if (this._peek.type === TokenType.COMMENT_START) { |
| this._closeVoidElement(); |
| this._consumeComment(this._advance()); |
| } |
| else if (this._peek.type === TokenType.TEXT || this._peek.type === TokenType.RAW_TEXT || |
| this._peek.type === TokenType.ESCAPABLE_RAW_TEXT) { |
| this._closeVoidElement(); |
| this._consumeText(this._advance()); |
| } |
| else if (this._peek.type === TokenType.EXPANSION_FORM_START) { |
| this._consumeExpansion(this._advance()); |
| } |
| else { |
| // Skip all other tokens... |
| this._advance(); |
| } |
| } |
| }; |
| _TreeBuilder.prototype._advance = function () { |
| var prev = this._peek; |
| if (this._index < this.tokens.length - 1) { |
| // Note: there is always an EOF token at the end |
| this._index++; |
| } |
| this._peek = this.tokens[this._index]; |
| return prev; |
| }; |
| _TreeBuilder.prototype._advanceIf = function (type) { |
| if (this._peek.type === type) { |
| return this._advance(); |
| } |
| return null; |
| }; |
| _TreeBuilder.prototype._consumeCdata = function (_startToken) { |
| this._consumeText(this._advance()); |
| this._advanceIf(TokenType.CDATA_END); |
| }; |
| _TreeBuilder.prototype._consumeComment = function (token) { |
| var text = this._advanceIf(TokenType.RAW_TEXT); |
| this._advanceIf(TokenType.COMMENT_END); |
| var value = text != null ? text.parts[0].trim() : null; |
| this._addToParent(new Comment$1(value, token.sourceSpan)); |
| }; |
| _TreeBuilder.prototype._consumeExpansion = function (token) { |
| var switchValue = this._advance(); |
| var type = this._advance(); |
| var cases = []; |
| // read = |
| while (this._peek.type === TokenType.EXPANSION_CASE_VALUE) { |
| var expCase = this._parseExpansionCase(); |
| if (!expCase) |
| return; // error |
| cases.push(expCase); |
| } |
| // read the final } |
| if (this._peek.type !== TokenType.EXPANSION_FORM_END) { |
| this.errors.push(TreeError.create(null, this._peek.sourceSpan, "Invalid ICU message. Missing '}'.")); |
| return; |
| } |
| var sourceSpan = new ParseSourceSpan(token.sourceSpan.start, this._peek.sourceSpan.end, token.sourceSpan.fullStart); |
| this._addToParent(new Expansion(switchValue.parts[0], type.parts[0], cases, sourceSpan, switchValue.sourceSpan)); |
| this._advance(); |
| }; |
| _TreeBuilder.prototype._parseExpansionCase = function () { |
| var value = this._advance(); |
| // read { |
| if (this._peek.type !== TokenType.EXPANSION_CASE_EXP_START) { |
| this.errors.push(TreeError.create(null, this._peek.sourceSpan, "Invalid ICU message. Missing '{'.")); |
| return null; |
| } |
| // read until } |
| var start = this._advance(); |
| var exp = this._collectExpansionExpTokens(start); |
| if (!exp) |
| return null; |
| var end = this._advance(); |
| exp.push(new Token(TokenType.EOF, [], end.sourceSpan)); |
| // parse everything in between { and } |
| var expansionCaseParser = new _TreeBuilder(exp, this.getTagDefinition); |
| expansionCaseParser.build(); |
| if (expansionCaseParser.errors.length > 0) { |
| this.errors = this.errors.concat(expansionCaseParser.errors); |
| return null; |
| } |
| var sourceSpan = new ParseSourceSpan(value.sourceSpan.start, end.sourceSpan.end, value.sourceSpan.fullStart); |
| var expSourceSpan = new ParseSourceSpan(start.sourceSpan.start, end.sourceSpan.end, start.sourceSpan.fullStart); |
| return new ExpansionCase(value.parts[0], expansionCaseParser.rootNodes, sourceSpan, value.sourceSpan, expSourceSpan); |
| }; |
| _TreeBuilder.prototype._collectExpansionExpTokens = function (start) { |
| var exp = []; |
| var expansionFormStack = [TokenType.EXPANSION_CASE_EXP_START]; |
| while (true) { |
| if (this._peek.type === TokenType.EXPANSION_FORM_START || |
| this._peek.type === TokenType.EXPANSION_CASE_EXP_START) { |
| expansionFormStack.push(this._peek.type); |
| } |
| if (this._peek.type === TokenType.EXPANSION_CASE_EXP_END) { |
| if (lastOnStack(expansionFormStack, TokenType.EXPANSION_CASE_EXP_START)) { |
| expansionFormStack.pop(); |
| if (expansionFormStack.length == 0) |
| return exp; |
| } |
| else { |
| this.errors.push(TreeError.create(null, start.sourceSpan, "Invalid ICU message. Missing '}'.")); |
| return null; |
| } |
| } |
| if (this._peek.type === TokenType.EXPANSION_FORM_END) { |
| if (lastOnStack(expansionFormStack, TokenType.EXPANSION_FORM_START)) { |
| expansionFormStack.pop(); |
| } |
| else { |
| this.errors.push(TreeError.create(null, start.sourceSpan, "Invalid ICU message. Missing '}'.")); |
| return null; |
| } |
| } |
| if (this._peek.type === TokenType.EOF) { |
| this.errors.push(TreeError.create(null, start.sourceSpan, "Invalid ICU message. Missing '}'.")); |
| return null; |
| } |
| exp.push(this._advance()); |
| } |
| }; |
| _TreeBuilder.prototype._consumeText = function (token) { |
| var text = token.parts[0]; |
| if (text.length > 0 && text[0] == '\n') { |
| var parent = this._getParentElement(); |
| if (parent != null && parent.children.length == 0 && |
| this.getTagDefinition(parent.name).ignoreFirstLf) { |
| text = text.substring(1); |
| } |
| } |
| if (text.length > 0) { |
| this._addToParent(new Text$3(text, token.sourceSpan)); |
| } |
| }; |
| _TreeBuilder.prototype._closeVoidElement = function () { |
| var el = this._getParentElement(); |
| if (el && this.getTagDefinition(el.name).isVoid) { |
| this._elementStack.pop(); |
| } |
| }; |
| _TreeBuilder.prototype._consumeStartTag = function (startTagToken) { |
| var _a = __read(startTagToken.parts, 2), prefix = _a[0], name = _a[1]; |
| var attrs = []; |
| while (this._peek.type === TokenType.ATTR_NAME) { |
| attrs.push(this._consumeAttr(this._advance())); |
| } |
| var fullName = this._getElementFullName(prefix, name, this._getParentElement()); |
| var selfClosing = false; |
| // Note: There could have been a tokenizer error |
| // so that we don't get a token for the end tag... |
| if (this._peek.type === TokenType.TAG_OPEN_END_VOID) { |
| this._advance(); |
| selfClosing = true; |
| var tagDef = this.getTagDefinition(fullName); |
| if (!(tagDef.canSelfClose || getNsPrefix(fullName) !== null || tagDef.isVoid)) { |
| this.errors.push(TreeError.create(fullName, startTagToken.sourceSpan, "Only void and foreign elements can be self closed \"" + startTagToken.parts[1] + "\"")); |
| } |
| } |
| else if (this._peek.type === TokenType.TAG_OPEN_END) { |
| this._advance(); |
| selfClosing = false; |
| } |
| var end = this._peek.sourceSpan.fullStart; |
| var span = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart); |
| // Create a separate `startSpan` because `span` will be modified when there is an `end` span. |
| var startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart); |
| var el = new Element$1(fullName, attrs, [], span, startSpan, undefined); |
| this._pushElement(el); |
| if (selfClosing) { |
| // Elements that are self-closed have their `endSourceSpan` set to the full span, as the |
| // element start tag also represents the end tag. |
| this._popElement(fullName, span); |
| } |
| else if (startTagToken.type === TokenType.INCOMPLETE_TAG_OPEN) { |
| // We already know the opening tag is not complete, so it is unlikely it has a corresponding |
| // close tag. Let's optimistically parse it as a full element and emit an error. |
| this._popElement(fullName, null); |
| this.errors.push(TreeError.create(fullName, span, "Opening tag \"" + fullName + "\" not terminated.")); |
| } |
| }; |
| _TreeBuilder.prototype._pushElement = function (el) { |
| var parentEl = this._getParentElement(); |
| if (parentEl && this.getTagDefinition(parentEl.name).isClosedByChild(el.name)) { |
| this._elementStack.pop(); |
| } |
| this._addToParent(el); |
| this._elementStack.push(el); |
| }; |
| _TreeBuilder.prototype._consumeEndTag = function (endTagToken) { |
| var fullName = this._getElementFullName(endTagToken.parts[0], endTagToken.parts[1], this._getParentElement()); |
| if (this.getTagDefinition(fullName).isVoid) { |
| this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, "Void elements do not have end tags \"" + endTagToken.parts[1] + "\"")); |
| } |
| else if (!this._popElement(fullName, endTagToken.sourceSpan)) { |
| var errMsg = "Unexpected closing tag \"" + fullName + "\". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags"; |
| this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, errMsg)); |
| } |
| }; |
| /** |
| * Closes the nearest element with the tag name `fullName` in the parse tree. |
| * `endSourceSpan` is the span of the closing tag, or null if the element does |
| * not have a closing tag (for example, this happens when an incomplete |
| * opening tag is recovered). |
| */ |
| _TreeBuilder.prototype._popElement = function (fullName, endSourceSpan) { |
| for (var stackIndex = this._elementStack.length - 1; stackIndex >= 0; stackIndex--) { |
| var el = this._elementStack[stackIndex]; |
| if (el.name == fullName) { |
| // Record the parse span with the element that is being closed. Any elements that are |
| // removed from the element stack at this point are closed implicitly, so they won't get |
| // an end source span (as there is no explicit closing element). |
| el.endSourceSpan = endSourceSpan; |
| el.sourceSpan.end = endSourceSpan !== null ? endSourceSpan.end : el.sourceSpan.end; |
| this._elementStack.splice(stackIndex, this._elementStack.length - stackIndex); |
| return true; |
| } |
| if (!this.getTagDefinition(el.name).closedByParent) { |
| return false; |
| } |
| } |
| return false; |
| }; |
| _TreeBuilder.prototype._consumeAttr = function (attrName) { |
| var fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]); |
| var end = attrName.sourceSpan.end; |
| var value = ''; |
| var valueSpan = undefined; |
| if (this._peek.type === TokenType.ATTR_QUOTE) { |
| this._advance(); |
| } |
| if (this._peek.type === TokenType.ATTR_VALUE) { |
| var valueToken = this._advance(); |
| value = valueToken.parts[0]; |
| end = valueToken.sourceSpan.end; |
| valueSpan = valueToken.sourceSpan; |
| } |
| if (this._peek.type === TokenType.ATTR_QUOTE) { |
| var quoteToken = this._advance(); |
| end = quoteToken.sourceSpan.end; |
| } |
| var keySpan = new ParseSourceSpan(attrName.sourceSpan.start, attrName.sourceSpan.end); |
| return new Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, end, attrName.sourceSpan.fullStart), keySpan, valueSpan); |
| }; |
| _TreeBuilder.prototype._getParentElement = function () { |
| return this._elementStack.length > 0 ? this._elementStack[this._elementStack.length - 1] : null; |
| }; |
| _TreeBuilder.prototype._addToParent = function (node) { |
| var parent = this._getParentElement(); |
| if (parent != null) { |
| parent.children.push(node); |
| } |
| else { |
| this.rootNodes.push(node); |
| } |
| }; |
| _TreeBuilder.prototype._getElementFullName = function (prefix, localName, parentElement) { |
| if (prefix === '') { |
| prefix = this.getTagDefinition(localName).implicitNamespacePrefix || ''; |
| if (prefix === '' && parentElement != null) { |
| var parentTagName = splitNsName(parentElement.name)[1]; |
| var parentTagDefinition = this.getTagDefinition(parentTagName); |
| if (!parentTagDefinition.preventNamespaceInheritance) { |
| prefix = getNsPrefix(parentElement.name); |
| } |
| } |
| } |
| return mergeNsAndName(prefix, localName); |
| }; |
| return _TreeBuilder; |
| }()); |
| function lastOnStack(stack, element) { |
| return stack.length > 0 && stack[stack.length - 1] === element; |
| } |
| |
| var HtmlParser = /** @class */ (function (_super) { |
| __extends(HtmlParser, _super); |
| function HtmlParser() { |
| return _super.call(this, getHtmlTagDefinition) || this; |
| } |
| HtmlParser.prototype.parse = function (source, url, options) { |
| return _super.prototype.parse.call(this, source, url, options); |
| }; |
| return HtmlParser; |
| }(Parser)); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var PRESERVE_WS_ATTR_NAME = 'ngPreserveWhitespaces'; |
| var SKIP_WS_TRIM_TAGS = new Set(['pre', 'template', 'textarea', 'script', 'style']); |
| // Equivalent to \s with \u00a0 (non-breaking space) excluded. |
| // Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp |
| var WS_CHARS = ' \f\n\r\t\v\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff'; |
| var NO_WS_REGEXP = new RegExp("[^" + WS_CHARS + "]"); |
| var WS_REPLACE_REGEXP = new RegExp("[" + WS_CHARS + "]{2,}", 'g'); |
| function hasPreserveWhitespacesAttr(attrs) { |
| return attrs.some(function (attr) { return attr.name === PRESERVE_WS_ATTR_NAME; }); |
| } |
| /** |
| * Angular Dart introduced &ngsp; as a placeholder for non-removable space, see: |
| * https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart#L25-L32 |
| * In Angular Dart &ngsp; is converted to the 0xE500 PUA (Private Use Areas) unicode character |
| * and later on replaced by a space. We are re-implementing the same idea here. |
| */ |
| function replaceNgsp(value) { |
| // lexer is replacing the &ngsp; pseudo-entity with NGSP_UNICODE |
| return value.replace(new RegExp(NGSP_UNICODE, 'g'), ' '); |
| } |
| /** |
| * This visitor can walk HTML parse tree and remove / trim text nodes using the following rules: |
| * - consider spaces, tabs and new lines as whitespace characters; |
| * - drop text nodes consisting of whitespace characters only; |
| * - for all other text nodes replace consecutive whitespace characters with one space; |
| * - convert &ngsp; pseudo-entity to a single space; |
| * |
| * Removal and trimming of whitespaces have positive performance impact (less code to generate |
| * while compiling templates, faster view creation). At the same time it can be "destructive" |
| * in some cases (whitespaces can influence layout). Because of the potential of breaking layout |
| * this visitor is not activated by default in Angular 5 and people need to explicitly opt-in for |
| * whitespace removal. The default option for whitespace removal will be revisited in Angular 6 |
| * and might be changed to "on" by default. |
| */ |
| var WhitespaceVisitor = /** @class */ (function () { |
| function WhitespaceVisitor() { |
| } |
| WhitespaceVisitor.prototype.visitElement = function (element, context) { |
| if (SKIP_WS_TRIM_TAGS.has(element.name) || hasPreserveWhitespacesAttr(element.attrs)) { |
| // don't descent into elements where we need to preserve whitespaces |
| // but still visit all attributes to eliminate one used as a market to preserve WS |
| return new Element$1(element.name, visitAll$1(this, element.attrs), element.children, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); |
| } |
| return new Element$1(element.name, element.attrs, visitAllWithSiblings(this, element.children), element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); |
| }; |
| WhitespaceVisitor.prototype.visitAttribute = function (attribute, context) { |
| return attribute.name !== PRESERVE_WS_ATTR_NAME ? attribute : null; |
| }; |
| WhitespaceVisitor.prototype.visitText = function (text, context) { |
| var isNotBlank = text.value.match(NO_WS_REGEXP); |
| var hasExpansionSibling = context && |
| (context.prev instanceof Expansion || context.next instanceof Expansion); |
| if (isNotBlank || hasExpansionSibling) { |
| return new Text$3(replaceNgsp(text.value).replace(WS_REPLACE_REGEXP, ' '), text.sourceSpan, text.i18n); |
| } |
| return null; |
| }; |
| WhitespaceVisitor.prototype.visitComment = function (comment, context) { |
| return comment; |
| }; |
| WhitespaceVisitor.prototype.visitExpansion = function (expansion, context) { |
| return expansion; |
| }; |
| WhitespaceVisitor.prototype.visitExpansionCase = function (expansionCase, context) { |
| return expansionCase; |
| }; |
| return WhitespaceVisitor; |
| }()); |
| function removeWhitespaces(htmlAstWithErrors) { |
| return new ParseTreeResult(visitAll$1(new WhitespaceVisitor(), htmlAstWithErrors.rootNodes), htmlAstWithErrors.errors); |
| } |
| function visitAllWithSiblings(visitor, nodes) { |
| var result = []; |
| nodes.forEach(function (ast, i) { |
| var context = { prev: nodes[i - 1], next: nodes[i + 1] }; |
| var astResult = ast.visit(visitor, context); |
| if (astResult) { |
| result.push(astResult); |
| } |
| }); |
| return result; |
| } |
| |
| // http://cldr.unicode.org/index/cldr-spec/plural-rules |
| var PLURAL_CASES = ['zero', 'one', 'two', 'few', 'many', 'other']; |
| /** |
| * Expands special forms into elements. |
| * |
| * For example, |
| * |
| * ``` |
| * { messages.length, plural, |
| * =0 {zero} |
| * =1 {one} |
| * other {more than one} |
| * } |
| * ``` |
| * |
| * will be expanded into |
| * |
| * ``` |
| * <ng-container [ngPlural]="messages.length"> |
| * <ng-template ngPluralCase="=0">zero</ng-template> |
| * <ng-template ngPluralCase="=1">one</ng-template> |
| * <ng-template ngPluralCase="other">more than one</ng-template> |
| * </ng-container> |
| * ``` |
| */ |
| function expandNodes(nodes) { |
| var expander = new _Expander(); |
| return new ExpansionResult(visitAll$1(expander, nodes), expander.isExpanded, expander.errors); |
| } |
| var ExpansionResult = /** @class */ (function () { |
| function ExpansionResult(nodes, expanded, errors) { |
| this.nodes = nodes; |
| this.expanded = expanded; |
| this.errors = errors; |
| } |
| return ExpansionResult; |
| }()); |
| var ExpansionError = /** @class */ (function (_super) { |
| __extends(ExpansionError, _super); |
| function ExpansionError(span, errorMsg) { |
| return _super.call(this, span, errorMsg) || this; |
| } |
| return ExpansionError; |
| }(ParseError)); |
| /** |
| * Expand expansion forms (plural, select) to directives |
| * |
| * @internal |
| */ |
| var _Expander = /** @class */ (function () { |
| function _Expander() { |
| this.isExpanded = false; |
| this.errors = []; |
| } |
| _Expander.prototype.visitElement = function (element, context) { |
| return new Element$1(element.name, element.attrs, visitAll$1(this, element.children), element.sourceSpan, element.startSourceSpan, element.endSourceSpan); |
| }; |
| _Expander.prototype.visitAttribute = function (attribute, context) { |
| return attribute; |
| }; |
| _Expander.prototype.visitText = function (text, context) { |
| return text; |
| }; |
| _Expander.prototype.visitComment = function (comment, context) { |
| return comment; |
| }; |
| _Expander.prototype.visitExpansion = function (icu, context) { |
| this.isExpanded = true; |
| return icu.type == 'plural' ? _expandPluralForm(icu, this.errors) : |
| _expandDefaultForm(icu, this.errors); |
| }; |
| _Expander.prototype.visitExpansionCase = function (icuCase, context) { |
| throw new Error('Should not be reached'); |
| }; |
| return _Expander; |
| }()); |
| // Plural forms are expanded to `NgPlural` and `NgPluralCase`s |
| function _expandPluralForm(ast, errors) { |
| var children = ast.cases.map(function (c) { |
| if (PLURAL_CASES.indexOf(c.value) == -1 && !c.value.match(/^=\d+$/)) { |
| errors.push(new ExpansionError(c.valueSourceSpan, "Plural cases should be \"=<number>\" or one of " + PLURAL_CASES.join(', '))); |
| } |
| var expansionResult = expandNodes(c.expression); |
| errors.push.apply(errors, __spread(expansionResult.errors)); |
| return new Element$1("ng-template", [new Attribute('ngPluralCase', "" + c.value, c.valueSourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* i18n */)], expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan); |
| }); |
| var switchAttr = new Attribute('[ngPlural]', ast.switchValue, ast.switchValueSourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* i18n */); |
| return new Element$1('ng-container', [switchAttr], children, ast.sourceSpan, ast.sourceSpan, ast.sourceSpan); |
| } |
| // ICU messages (excluding plural form) are expanded to `NgSwitch` and `NgSwitchCase`s |
| function _expandDefaultForm(ast, errors) { |
| var children = ast.cases.map(function (c) { |
| var expansionResult = expandNodes(c.expression); |
| errors.push.apply(errors, __spread(expansionResult.errors)); |
| if (c.value === 'other') { |
| // other is the default case when no values match |
| return new Element$1("ng-template", [new Attribute('ngSwitchDefault', '', c.valueSourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* i18n */)], expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan); |
| } |
| return new Element$1("ng-template", [new Attribute('ngSwitchCase', "" + c.value, c.valueSourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* i18n */)], expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan); |
| }); |
| var switchAttr = new Attribute('[ngSwitch]', ast.switchValue, ast.switchValueSourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* i18n */); |
| return new Element$1('ng-container', [switchAttr], children, ast.sourceSpan, ast.sourceSpan, ast.sourceSpan); |
| } |
| |
| var _a; |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * A segment of text within the template. |
| */ |
| var TextAst = /** @class */ (function () { |
| function TextAst(value, ngContentIndex, sourceSpan) { |
| this.value = value; |
| this.ngContentIndex = ngContentIndex; |
| this.sourceSpan = sourceSpan; |
| } |
| TextAst.prototype.visit = function (visitor, context) { |
| return visitor.visitText(this, context); |
| }; |
| return TextAst; |
| }()); |
| /** |
| * A bound expression within the text of a template. |
| */ |
| var BoundTextAst = /** @class */ (function () { |
| function BoundTextAst(value, ngContentIndex, sourceSpan) { |
| this.value = value; |
| this.ngContentIndex = ngContentIndex; |
| this.sourceSpan = sourceSpan; |
| } |
| BoundTextAst.prototype.visit = function (visitor, context) { |
| return visitor.visitBoundText(this, context); |
| }; |
| return BoundTextAst; |
| }()); |
| /** |
| * A plain attribute on an element. |
| */ |
| var AttrAst = /** @class */ (function () { |
| function AttrAst(name, value, sourceSpan) { |
| this.name = name; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| } |
| AttrAst.prototype.visit = function (visitor, context) { |
| return visitor.visitAttr(this, context); |
| }; |
| return AttrAst; |
| }()); |
| var BoundPropertyMapping = (_a = {}, |
| _a[4 /* Animation */] = 4 /* Animation */, |
| _a[1 /* Attribute */] = 1 /* Attribute */, |
| _a[2 /* Class */] = 2 /* Class */, |
| _a[0 /* Property */] = 0 /* Property */, |
| _a[3 /* Style */] = 3 /* Style */, |
| _a); |
| /** |
| * A binding for an element property (e.g. `[property]="expression"`) or an animation trigger (e.g. |
| * `[@trigger]="stateExp"`) |
| */ |
| var BoundElementPropertyAst = /** @class */ (function () { |
| function BoundElementPropertyAst(name, type, securityContext, value, unit, sourceSpan) { |
| this.name = name; |
| this.type = type; |
| this.securityContext = securityContext; |
| this.value = value; |
| this.unit = unit; |
| this.sourceSpan = sourceSpan; |
| this.isAnimation = this.type === 4 /* Animation */; |
| } |
| BoundElementPropertyAst.fromBoundProperty = function (prop) { |
| var type = BoundPropertyMapping[prop.type]; |
| return new BoundElementPropertyAst(prop.name, type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan); |
| }; |
| BoundElementPropertyAst.prototype.visit = function (visitor, context) { |
| return visitor.visitElementProperty(this, context); |
| }; |
| return BoundElementPropertyAst; |
| }()); |
| /** |
| * A binding for an element event (e.g. `(event)="handler()"`) or an animation trigger event (e.g. |
| * `(@trigger.phase)="callback($event)"`). |
| */ |
| var BoundEventAst = /** @class */ (function () { |
| function BoundEventAst(name, target, phase, handler, sourceSpan, handlerSpan) { |
| this.name = name; |
| this.target = target; |
| this.phase = phase; |
| this.handler = handler; |
| this.sourceSpan = sourceSpan; |
| this.handlerSpan = handlerSpan; |
| this.fullName = BoundEventAst.calcFullName(this.name, this.target, this.phase); |
| this.isAnimation = !!this.phase; |
| } |
| BoundEventAst.calcFullName = function (name, target, phase) { |
| if (target) { |
| return target + ":" + name; |
| } |
| if (phase) { |
| return "@" + name + "." + phase; |
| } |
| return name; |
| }; |
| BoundEventAst.fromParsedEvent = function (event) { |
| var target = event.type === 0 /* Regular */ ? event.targetOrPhase : null; |
| var phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null; |
| return new BoundEventAst(event.name, target, phase, event.handler, event.sourceSpan, event.handlerSpan); |
| }; |
| BoundEventAst.prototype.visit = function (visitor, context) { |
| return visitor.visitEvent(this, context); |
| }; |
| return BoundEventAst; |
| }()); |
| /** |
| * A reference declaration on an element (e.g. `let someName="expression"`). |
| */ |
| var ReferenceAst = /** @class */ (function () { |
| function ReferenceAst(name, value, originalValue, sourceSpan) { |
| this.name = name; |
| this.value = value; |
| this.originalValue = originalValue; |
| this.sourceSpan = sourceSpan; |
| } |
| ReferenceAst.prototype.visit = function (visitor, context) { |
| return visitor.visitReference(this, context); |
| }; |
| return ReferenceAst; |
| }()); |
| /** |
| * A variable declaration on a <ng-template> (e.g. `var-someName="someLocalName"`). |
| */ |
| var VariableAst = /** @class */ (function () { |
| function VariableAst(name, value, sourceSpan, valueSpan) { |
| this.name = name; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| this.valueSpan = valueSpan; |
| } |
| VariableAst.fromParsedVariable = function (v) { |
| return new VariableAst(v.name, v.value, v.sourceSpan, v.valueSpan); |
| }; |
| VariableAst.prototype.visit = function (visitor, context) { |
| return visitor.visitVariable(this, context); |
| }; |
| return VariableAst; |
| }()); |
| /** |
| * An element declaration in a template. |
| */ |
| var ElementAst = /** @class */ (function () { |
| function ElementAst(name, attrs, inputs, outputs, references, directives, providers, hasViewContainer, queryMatches, children, ngContentIndex, sourceSpan, endSourceSpan) { |
| this.name = name; |
| this.attrs = attrs; |
| this.inputs = inputs; |
| this.outputs = outputs; |
| this.references = references; |
| this.directives = directives; |
| this.providers = providers; |
| this.hasViewContainer = hasViewContainer; |
| this.queryMatches = queryMatches; |
| this.children = children; |
| this.ngContentIndex = ngContentIndex; |
| this.sourceSpan = sourceSpan; |
| this.endSourceSpan = endSourceSpan; |
| } |
| ElementAst.prototype.visit = function (visitor, context) { |
| return visitor.visitElement(this, context); |
| }; |
| return ElementAst; |
| }()); |
| /** |
| * A `<ng-template>` element included in an Angular template. |
| */ |
| var EmbeddedTemplateAst = /** @class */ (function () { |
| function EmbeddedTemplateAst(attrs, outputs, references, variables, directives, providers, hasViewContainer, queryMatches, children, ngContentIndex, sourceSpan) { |
| this.attrs = attrs; |
| this.outputs = outputs; |
| this.references = references; |
| this.variables = variables; |
| this.directives = directives; |
| this.providers = providers; |
| this.hasViewContainer = hasViewContainer; |
| this.queryMatches = queryMatches; |
| this.children = children; |
| this.ngContentIndex = ngContentIndex; |
| this.sourceSpan = sourceSpan; |
| } |
| EmbeddedTemplateAst.prototype.visit = function (visitor, context) { |
| return visitor.visitEmbeddedTemplate(this, context); |
| }; |
| return EmbeddedTemplateAst; |
| }()); |
| /** |
| * A directive property with a bound value (e.g. `*ngIf="condition"). |
| */ |
| var BoundDirectivePropertyAst = /** @class */ (function () { |
| function BoundDirectivePropertyAst(directiveName, templateName, value, sourceSpan) { |
| this.directiveName = directiveName; |
| this.templateName = templateName; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| } |
| BoundDirectivePropertyAst.prototype.visit = function (visitor, context) { |
| return visitor.visitDirectiveProperty(this, context); |
| }; |
| return BoundDirectivePropertyAst; |
| }()); |
| /** |
| * A directive declared on an element. |
| */ |
| var DirectiveAst = /** @class */ (function () { |
| function DirectiveAst(directive, inputs, hostProperties, hostEvents, contentQueryStartId, sourceSpan) { |
| this.directive = directive; |
| this.inputs = inputs; |
| this.hostProperties = hostProperties; |
| this.hostEvents = hostEvents; |
| this.contentQueryStartId = contentQueryStartId; |
| this.sourceSpan = sourceSpan; |
| } |
| DirectiveAst.prototype.visit = function (visitor, context) { |
| return visitor.visitDirective(this, context); |
| }; |
| return DirectiveAst; |
| }()); |
| /** |
| * A provider declared on an element |
| */ |
| var ProviderAst = /** @class */ (function () { |
| function ProviderAst(token, multiProvider, eager, providers, providerType, lifecycleHooks, sourceSpan, isModule) { |
| this.token = token; |
| this.multiProvider = multiProvider; |
| this.eager = eager; |
| this.providers = providers; |
| this.providerType = providerType; |
| this.lifecycleHooks = lifecycleHooks; |
| this.sourceSpan = sourceSpan; |
| this.isModule = isModule; |
| } |
| ProviderAst.prototype.visit = function (visitor, context) { |
| // No visit method in the visitor for now... |
| return null; |
| }; |
| return ProviderAst; |
| }()); |
| (function (ProviderAstType) { |
| ProviderAstType[ProviderAstType["PublicService"] = 0] = "PublicService"; |
| ProviderAstType[ProviderAstType["PrivateService"] = 1] = "PrivateService"; |
| ProviderAstType[ProviderAstType["Component"] = 2] = "Component"; |
| ProviderAstType[ProviderAstType["Directive"] = 3] = "Directive"; |
| ProviderAstType[ProviderAstType["Builtin"] = 4] = "Builtin"; |
| })(exports.ProviderAstType || (exports.ProviderAstType = {})); |
| /** |
| * Position where content is to be projected (instance of `<ng-content>` in a template). |
| */ |
| var NgContentAst = /** @class */ (function () { |
| function NgContentAst(index, ngContentIndex, sourceSpan) { |
| this.index = index; |
| this.ngContentIndex = ngContentIndex; |
| this.sourceSpan = sourceSpan; |
| } |
| NgContentAst.prototype.visit = function (visitor, context) { |
| return visitor.visitNgContent(this, context); |
| }; |
| return NgContentAst; |
| }()); |
| /** |
| * A visitor that accepts each node but doesn't do anything. It is intended to be used |
| * as the base class for a visitor that is only interested in a subset of the node types. |
| */ |
| var NullTemplateVisitor = /** @class */ (function () { |
| function NullTemplateVisitor() { |
| } |
| NullTemplateVisitor.prototype.visitNgContent = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitEmbeddedTemplate = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitElement = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitReference = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitVariable = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitEvent = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitElementProperty = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitAttr = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitBoundText = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitText = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitDirective = function (ast, context) { }; |
| NullTemplateVisitor.prototype.visitDirectiveProperty = function (ast, context) { }; |
| return NullTemplateVisitor; |
| }()); |
| /** |
| * Base class that can be used to build a visitor that visits each node |
| * in an template ast recursively. |
| */ |
| var RecursiveTemplateAstVisitor = /** @class */ (function (_super) { |
| __extends(RecursiveTemplateAstVisitor, _super); |
| function RecursiveTemplateAstVisitor() { |
| return _super.call(this) || this; |
| } |
| // Nodes with children |
| RecursiveTemplateAstVisitor.prototype.visitEmbeddedTemplate = function (ast, context) { |
| return this.visitChildren(context, function (visit) { |
| visit(ast.attrs); |
| visit(ast.references); |
| visit(ast.variables); |
| visit(ast.directives); |
| visit(ast.providers); |
| visit(ast.children); |
| }); |
| }; |
| RecursiveTemplateAstVisitor.prototype.visitElement = function (ast, context) { |
| return this.visitChildren(context, function (visit) { |
| visit(ast.attrs); |
| visit(ast.inputs); |
| visit(ast.outputs); |
| visit(ast.references); |
| visit(ast.directives); |
| visit(ast.providers); |
| visit(ast.children); |
| }); |
| }; |
| RecursiveTemplateAstVisitor.prototype.visitDirective = function (ast, context) { |
| return this.visitChildren(context, function (visit) { |
| visit(ast.inputs); |
| visit(ast.hostProperties); |
| visit(ast.hostEvents); |
| }); |
| }; |
| RecursiveTemplateAstVisitor.prototype.visitChildren = function (context, cb) { |
| var results = []; |
| var t = this; |
| function visit(children) { |
| if (children && children.length) |
| results.push(templateVisitAll(t, children, context)); |
| } |
| cb(visit); |
| return Array.prototype.concat.apply([], results); |
| }; |
| return RecursiveTemplateAstVisitor; |
| }(NullTemplateVisitor)); |
| /** |
| * Visit every node in a list of {@link TemplateAst}s with the given {@link TemplateAstVisitor}. |
| */ |
| function templateVisitAll(visitor, asts, context) { |
| if (context === void 0) { context = null; } |
| var result = []; |
| var visit = visitor.visit ? |
| function (ast) { return visitor.visit(ast, context) || ast.visit(visitor, context); } : |
| function (ast) { return ast.visit(visitor, context); }; |
| asts.forEach(function (ast) { |
| var astResult = visit(ast); |
| if (astResult) { |
| result.push(astResult); |
| } |
| }); |
| return result; |
| } |
| |
| var ProviderError = /** @class */ (function (_super) { |
| __extends(ProviderError, _super); |
| function ProviderError(message, span) { |
| return _super.call(this, span, message) || this; |
| } |
| return ProviderError; |
| }(ParseError)); |
| var ProviderViewContext = /** @class */ (function () { |
| function ProviderViewContext(reflector, component) { |
| var _this = this; |
| this.reflector = reflector; |
| this.component = component; |
| this.errors = []; |
| this.viewQueries = _getViewQueries(component); |
| this.viewProviders = new Map(); |
| component.viewProviders.forEach(function (provider) { |
| if (_this.viewProviders.get(tokenReference(provider.token)) == null) { |
| _this.viewProviders.set(tokenReference(provider.token), true); |
| } |
| }); |
| } |
| return ProviderViewContext; |
| }()); |
| var ProviderElementContext = /** @class */ (function () { |
| function ProviderElementContext(viewContext, _parent, _isViewRoot, _directiveAsts, attrs, refs, isTemplate, contentQueryStartId, _sourceSpan) { |
| var _this = this; |
| this.viewContext = viewContext; |
| this._parent = _parent; |
| this._isViewRoot = _isViewRoot; |
| this._directiveAsts = _directiveAsts; |
| this._sourceSpan = _sourceSpan; |
| this._transformedProviders = new Map(); |
| this._seenProviders = new Map(); |
| this._queriedTokens = new Map(); |
| this.transformedHasViewContainer = false; |
| this._attrs = {}; |
| attrs.forEach(function (attrAst) { return _this._attrs[attrAst.name] = attrAst.value; }); |
| var directivesMeta = _directiveAsts.map(function (directiveAst) { return directiveAst.directive; }); |
| this._allProviders = |
| _resolveProvidersFromDirectives(directivesMeta, _sourceSpan, viewContext.errors); |
| this._contentQueries = _getContentQueries(contentQueryStartId, directivesMeta); |
| Array.from(this._allProviders.values()).forEach(function (provider) { |
| _this._addQueryReadsTo(provider.token, provider.token, _this._queriedTokens); |
| }); |
| if (isTemplate) { |
| var templateRefId = createTokenForExternalReference(this.viewContext.reflector, Identifiers.TemplateRef); |
| this._addQueryReadsTo(templateRefId, templateRefId, this._queriedTokens); |
| } |
| refs.forEach(function (refAst) { |
| var defaultQueryValue = refAst.value || |
| createTokenForExternalReference(_this.viewContext.reflector, Identifiers.ElementRef); |
| _this._addQueryReadsTo({ value: refAst.name }, defaultQueryValue, _this._queriedTokens); |
| }); |
| if (this._queriedTokens.get(this.viewContext.reflector.resolveExternalReference(Identifiers.ViewContainerRef))) { |
| this.transformedHasViewContainer = true; |
| } |
| // create the providers that we know are eager first |
| Array.from(this._allProviders.values()).forEach(function (provider) { |
| var eager = provider.eager || _this._queriedTokens.get(tokenReference(provider.token)); |
| if (eager) { |
| _this._getOrCreateLocalProvider(provider.providerType, provider.token, true); |
| } |
| }); |
| } |
| ProviderElementContext.prototype.afterElement = function () { |
| var _this = this; |
| // collect lazy providers |
| Array.from(this._allProviders.values()).forEach(function (provider) { |
| _this._getOrCreateLocalProvider(provider.providerType, provider.token, false); |
| }); |
| }; |
| Object.defineProperty(ProviderElementContext.prototype, "transformProviders", { |
| get: function () { |
| // Note: Maps keep their insertion order. |
| var lazyProviders = []; |
| var eagerProviders = []; |
| this._transformedProviders.forEach(function (provider) { |
| if (provider.eager) { |
| eagerProviders.push(provider); |
| } |
| else { |
| lazyProviders.push(provider); |
| } |
| }); |
| return lazyProviders.concat(eagerProviders); |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(ProviderElementContext.prototype, "transformedDirectiveAsts", { |
| get: function () { |
| var sortedProviderTypes = this.transformProviders.map(function (provider) { return provider.token.identifier; }); |
| var sortedDirectives = this._directiveAsts.slice(); |
| sortedDirectives.sort(function (dir1, dir2) { return sortedProviderTypes.indexOf(dir1.directive.type) - |
| sortedProviderTypes.indexOf(dir2.directive.type); }); |
| return sortedDirectives; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(ProviderElementContext.prototype, "queryMatches", { |
| get: function () { |
| var allMatches = []; |
| this._queriedTokens.forEach(function (matches) { |
| allMatches.push.apply(allMatches, __spread(matches)); |
| }); |
| return allMatches; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| ProviderElementContext.prototype._addQueryReadsTo = function (token, defaultValue, queryReadTokens) { |
| this._getQueriesFor(token).forEach(function (query) { |
| var queryValue = query.meta.read || defaultValue; |
| var tokenRef = tokenReference(queryValue); |
| var queryMatches = queryReadTokens.get(tokenRef); |
| if (!queryMatches) { |
| queryMatches = []; |
| queryReadTokens.set(tokenRef, queryMatches); |
| } |
| queryMatches.push({ queryId: query.queryId, value: queryValue }); |
| }); |
| }; |
| ProviderElementContext.prototype._getQueriesFor = function (token) { |
| var result = []; |
| var currentEl = this; |
| var distance = 0; |
| var queries; |
| while (currentEl !== null) { |
| queries = currentEl._contentQueries.get(tokenReference(token)); |
| if (queries) { |
| result.push.apply(result, __spread(queries.filter(function (query) { return query.meta.descendants || distance <= 1; }))); |
| } |
| if (currentEl._directiveAsts.length > 0) { |
| distance++; |
| } |
| currentEl = currentEl._parent; |
| } |
| queries = this.viewContext.viewQueries.get(tokenReference(token)); |
| if (queries) { |
| result.push.apply(result, __spread(queries)); |
| } |
| return result; |
| }; |
| ProviderElementContext.prototype._getOrCreateLocalProvider = function (requestingProviderType, token, eager) { |
| var _this = this; |
| var resolvedProvider = this._allProviders.get(tokenReference(token)); |
| if (!resolvedProvider || |
| ((requestingProviderType === exports.ProviderAstType.Directive || |
| requestingProviderType === exports.ProviderAstType.PublicService) && |
| resolvedProvider.providerType === exports.ProviderAstType.PrivateService) || |
| ((requestingProviderType === exports.ProviderAstType.PrivateService || |
| requestingProviderType === exports.ProviderAstType.PublicService) && |
| resolvedProvider.providerType === exports.ProviderAstType.Builtin)) { |
| return null; |
| } |
| var transformedProviderAst = this._transformedProviders.get(tokenReference(token)); |
| if (transformedProviderAst) { |
| return transformedProviderAst; |
| } |
| if (this._seenProviders.get(tokenReference(token)) != null) { |
| this.viewContext.errors.push(new ProviderError("Cannot instantiate cyclic dependency! " + tokenName(token), this._sourceSpan)); |
| return null; |
| } |
| this._seenProviders.set(tokenReference(token), true); |
| var transformedProviders = resolvedProvider.providers.map(function (provider) { |
| var transformedUseValue = provider.useValue; |
| var transformedUseExisting = provider.useExisting; |
| var transformedDeps = undefined; |
| if (provider.useExisting != null) { |
| var existingDiDep = _this._getDependency(resolvedProvider.providerType, { token: provider.useExisting }, eager); |
| if (existingDiDep.token != null) { |
| transformedUseExisting = existingDiDep.token; |
| } |
| else { |
| transformedUseExisting = null; |
| transformedUseValue = existingDiDep.value; |
| } |
| } |
| else if (provider.useFactory) { |
| var deps = provider.deps || provider.useFactory.diDeps; |
| transformedDeps = |
| deps.map(function (dep) { return _this._getDependency(resolvedProvider.providerType, dep, eager); }); |
| } |
| else if (provider.useClass) { |
| var deps = provider.deps || provider.useClass.diDeps; |
| transformedDeps = |
| deps.map(function (dep) { return _this._getDependency(resolvedProvider.providerType, dep, eager); }); |
| } |
| return _transformProvider(provider, { |
| useExisting: transformedUseExisting, |
| useValue: transformedUseValue, |
| deps: transformedDeps |
| }); |
| }); |
| transformedProviderAst = |
| _transformProviderAst(resolvedProvider, { eager: eager, providers: transformedProviders }); |
| this._transformedProviders.set(tokenReference(token), transformedProviderAst); |
| return transformedProviderAst; |
| }; |
| ProviderElementContext.prototype._getLocalDependency = function (requestingProviderType, dep, eager) { |
| if (eager === void 0) { eager = false; } |
| if (dep.isAttribute) { |
| var attrValue = this._attrs[dep.token.value]; |
| return { isValue: true, value: attrValue == null ? null : attrValue }; |
| } |
| if (dep.token != null) { |
| // access builtints |
| if ((requestingProviderType === exports.ProviderAstType.Directive || |
| requestingProviderType === exports.ProviderAstType.Component)) { |
| if (tokenReference(dep.token) === |
| this.viewContext.reflector.resolveExternalReference(Identifiers.Renderer) || |
| tokenReference(dep.token) === |
| this.viewContext.reflector.resolveExternalReference(Identifiers.ElementRef) || |
| tokenReference(dep.token) === |
| this.viewContext.reflector.resolveExternalReference(Identifiers.ChangeDetectorRef) || |
| tokenReference(dep.token) === |
| this.viewContext.reflector.resolveExternalReference(Identifiers.TemplateRef)) { |
| return dep; |
| } |
| if (tokenReference(dep.token) === |
| this.viewContext.reflector.resolveExternalReference(Identifiers.ViewContainerRef)) { |
| this.transformedHasViewContainer = true; |
| } |
| } |
| // access the injector |
| if (tokenReference(dep.token) === |
| this.viewContext.reflector.resolveExternalReference(Identifiers.Injector)) { |
| return dep; |
| } |
| // access providers |
| if (this._getOrCreateLocalProvider(requestingProviderType, dep.token, eager) != null) { |
| return dep; |
| } |
| } |
| return null; |
| }; |
| ProviderElementContext.prototype._getDependency = function (requestingProviderType, dep, eager) { |
| if (eager === void 0) { eager = false; } |
| var currElement = this; |
| var currEager = eager; |
| var result = null; |
| if (!dep.isSkipSelf) { |
| result = this._getLocalDependency(requestingProviderType, dep, eager); |
| } |
| if (dep.isSelf) { |
| if (!result && dep.isOptional) { |
| result = { isValue: true, value: null }; |
| } |
| } |
| else { |
| // check parent elements |
| while (!result && currElement._parent) { |
| var prevElement = currElement; |
| currElement = currElement._parent; |
| if (prevElement._isViewRoot) { |
| currEager = false; |
| } |
| result = currElement._getLocalDependency(exports.ProviderAstType.PublicService, dep, currEager); |
| } |
| // check @Host restriction |
| if (!result) { |
| if (!dep.isHost || this.viewContext.component.isHost || |
| this.viewContext.component.type.reference === tokenReference(dep.token) || |
| this.viewContext.viewProviders.get(tokenReference(dep.token)) != null) { |
| result = dep; |
| } |
| else { |
| result = dep.isOptional ? { isValue: true, value: null } : null; |
| } |
| } |
| } |
| if (!result) { |
| this.viewContext.errors.push(new ProviderError("No provider for " + tokenName(dep.token), this._sourceSpan)); |
| } |
| return result; |
| }; |
| return ProviderElementContext; |
| }()); |
| var NgModuleProviderAnalyzer = /** @class */ (function () { |
| function NgModuleProviderAnalyzer(reflector, ngModule, extraProviders, sourceSpan) { |
| var _this = this; |
| this.reflector = reflector; |
| this._transformedProviders = new Map(); |
| this._seenProviders = new Map(); |
| this._errors = []; |
| this._allProviders = new Map(); |
| ngModule.transitiveModule.modules.forEach(function (ngModuleType) { |
| var ngModuleProvider = { token: { identifier: ngModuleType }, useClass: ngModuleType }; |
| _resolveProviders([ngModuleProvider], exports.ProviderAstType.PublicService, true, sourceSpan, _this._errors, _this._allProviders, /* isModule */ true); |
| }); |
| _resolveProviders(ngModule.transitiveModule.providers.map(function (entry) { return entry.provider; }).concat(extraProviders), exports.ProviderAstType.PublicService, false, sourceSpan, this._errors, this._allProviders, |
| /* isModule */ false); |
| } |
| NgModuleProviderAnalyzer.prototype.parse = function () { |
| var _this = this; |
| Array.from(this._allProviders.values()).forEach(function (provider) { |
| _this._getOrCreateLocalProvider(provider.token, provider.eager); |
| }); |
| if (this._errors.length > 0) { |
| var errorString = this._errors.join('\n'); |
| throw new Error("Provider parse errors:\n" + errorString); |
| } |
| // Note: Maps keep their insertion order. |
| var lazyProviders = []; |
| var eagerProviders = []; |
| this._transformedProviders.forEach(function (provider) { |
| if (provider.eager) { |
| eagerProviders.push(provider); |
| } |
| else { |
| lazyProviders.push(provider); |
| } |
| }); |
| return lazyProviders.concat(eagerProviders); |
| }; |
| NgModuleProviderAnalyzer.prototype._getOrCreateLocalProvider = function (token, eager) { |
| var _this = this; |
| var resolvedProvider = this._allProviders.get(tokenReference(token)); |
| if (!resolvedProvider) { |
| return null; |
| } |
| var transformedProviderAst = this._transformedProviders.get(tokenReference(token)); |
| if (transformedProviderAst) { |
| return transformedProviderAst; |
| } |
| if (this._seenProviders.get(tokenReference(token)) != null) { |
| this._errors.push(new ProviderError("Cannot instantiate cyclic dependency! " + tokenName(token), resolvedProvider.sourceSpan)); |
| return null; |
| } |
| this._seenProviders.set(tokenReference(token), true); |
| var transformedProviders = resolvedProvider.providers.map(function (provider) { |
| var transformedUseValue = provider.useValue; |
| var transformedUseExisting = provider.useExisting; |
| var transformedDeps = undefined; |
| if (provider.useExisting != null) { |
| var existingDiDep = _this._getDependency({ token: provider.useExisting }, eager, resolvedProvider.sourceSpan); |
| if (existingDiDep.token != null) { |
| transformedUseExisting = existingDiDep.token; |
| } |
| else { |
| transformedUseExisting = null; |
| transformedUseValue = existingDiDep.value; |
| } |
| } |
| else if (provider.useFactory) { |
| var deps = provider.deps || provider.useFactory.diDeps; |
| transformedDeps = |
| deps.map(function (dep) { return _this._getDependency(dep, eager, resolvedProvider.sourceSpan); }); |
| } |
| else if (provider.useClass) { |
| var deps = provider.deps || provider.useClass.diDeps; |
| transformedDeps = |
| deps.map(function (dep) { return _this._getDependency(dep, eager, resolvedProvider.sourceSpan); }); |
| } |
| return _transformProvider(provider, { |
| useExisting: transformedUseExisting, |
| useValue: transformedUseValue, |
| deps: transformedDeps |
| }); |
| }); |
| transformedProviderAst = |
| _transformProviderAst(resolvedProvider, { eager: eager, providers: transformedProviders }); |
| this._transformedProviders.set(tokenReference(token), transformedProviderAst); |
| return transformedProviderAst; |
| }; |
| NgModuleProviderAnalyzer.prototype._getDependency = function (dep, eager, requestorSourceSpan) { |
| if (eager === void 0) { eager = false; } |
| var foundLocal = false; |
| if (!dep.isSkipSelf && dep.token != null) { |
| // access the injector |
| if (tokenReference(dep.token) === |
| this.reflector.resolveExternalReference(Identifiers.Injector) || |
| tokenReference(dep.token) === |
| this.reflector.resolveExternalReference(Identifiers.ComponentFactoryResolver)) { |
| foundLocal = true; |
| // access providers |
| } |
| else if (this._getOrCreateLocalProvider(dep.token, eager) != null) { |
| foundLocal = true; |
| } |
| } |
| return dep; |
| }; |
| return NgModuleProviderAnalyzer; |
| }()); |
| function _transformProvider(provider, _a) { |
| var useExisting = _a.useExisting, useValue = _a.useValue, deps = _a.deps; |
| return { |
| token: provider.token, |
| useClass: provider.useClass, |
| useExisting: useExisting, |
| useFactory: provider.useFactory, |
| useValue: useValue, |
| deps: deps, |
| multi: provider.multi |
| }; |
| } |
| function _transformProviderAst(provider, _a) { |
| var eager = _a.eager, providers = _a.providers; |
| return new ProviderAst(provider.token, provider.multiProvider, provider.eager || eager, providers, provider.providerType, provider.lifecycleHooks, provider.sourceSpan, provider.isModule); |
| } |
| function _resolveProvidersFromDirectives(directives, sourceSpan, targetErrors) { |
| var providersByToken = new Map(); |
| directives.forEach(function (directive) { |
| var dirProvider = { token: { identifier: directive.type }, useClass: directive.type }; |
| _resolveProviders([dirProvider], directive.isComponent ? exports.ProviderAstType.Component : exports.ProviderAstType.Directive, true, sourceSpan, targetErrors, providersByToken, /* isModule */ false); |
| }); |
| // Note: directives need to be able to overwrite providers of a component! |
| var directivesWithComponentFirst = directives.filter(function (dir) { return dir.isComponent; }).concat(directives.filter(function (dir) { return !dir.isComponent; })); |
| directivesWithComponentFirst.forEach(function (directive) { |
| _resolveProviders(directive.providers, exports.ProviderAstType.PublicService, false, sourceSpan, targetErrors, providersByToken, /* isModule */ false); |
| _resolveProviders(directive.viewProviders, exports.ProviderAstType.PrivateService, false, sourceSpan, targetErrors, providersByToken, /* isModule */ false); |
| }); |
| return providersByToken; |
| } |
| function _resolveProviders(providers, providerType, eager, sourceSpan, targetErrors, targetProvidersByToken, isModule) { |
| providers.forEach(function (provider) { |
| var resolvedProvider = targetProvidersByToken.get(tokenReference(provider.token)); |
| if (resolvedProvider != null && !!resolvedProvider.multiProvider !== !!provider.multi) { |
| targetErrors.push(new ProviderError("Mixing multi and non multi provider is not possible for token " + tokenName(resolvedProvider.token), sourceSpan)); |
| } |
| if (!resolvedProvider) { |
| var lifecycleHooks = provider.token.identifier && |
| provider.token.identifier.lifecycleHooks ? |
| provider.token.identifier.lifecycleHooks : |
| []; |
| var isUseValue = !(provider.useClass || provider.useExisting || provider.useFactory); |
| resolvedProvider = new ProviderAst(provider.token, !!provider.multi, eager || isUseValue, [provider], providerType, lifecycleHooks, sourceSpan, isModule); |
| targetProvidersByToken.set(tokenReference(provider.token), resolvedProvider); |
| } |
| else { |
| if (!provider.multi) { |
| resolvedProvider.providers.length = 0; |
| } |
| resolvedProvider.providers.push(provider); |
| } |
| }); |
| } |
| function _getViewQueries(component) { |
| // Note: queries start with id 1 so we can use the number in a Bloom filter! |
| var viewQueryId = 1; |
| var viewQueries = new Map(); |
| if (component.viewQueries) { |
| component.viewQueries.forEach(function (query) { return _addQueryToTokenMap(viewQueries, { meta: query, queryId: viewQueryId++ }); }); |
| } |
| return viewQueries; |
| } |
| function _getContentQueries(contentQueryStartId, directives) { |
| var contentQueryId = contentQueryStartId; |
| var contentQueries = new Map(); |
| directives.forEach(function (directive, directiveIndex) { |
| if (directive.queries) { |
| directive.queries.forEach(function (query) { return _addQueryToTokenMap(contentQueries, { meta: query, queryId: contentQueryId++ }); }); |
| } |
| }); |
| return contentQueries; |
| } |
| function _addQueryToTokenMap(map, query) { |
| query.meta.selectors.forEach(function (token) { |
| var entry = map.get(tokenReference(token)); |
| if (!entry) { |
| entry = []; |
| map.set(tokenReference(token), entry); |
| } |
| entry.push(query); |
| }); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var StyleWithImports = /** @class */ (function () { |
| function StyleWithImports(style, styleUrls) { |
| this.style = style; |
| this.styleUrls = styleUrls; |
| } |
| return StyleWithImports; |
| }()); |
| function isStyleUrlResolvable(url) { |
| if (url == null || url.length === 0 || url[0] == '/') |
| return false; |
| var schemeMatch = url.match(URL_WITH_SCHEMA_REGEXP); |
| return schemeMatch === null || schemeMatch[1] == 'package' || schemeMatch[1] == 'asset'; |
| } |
| /** |
| * Rewrites stylesheets by resolving and removing the @import urls that |
| * are either relative or don't have a `package:` scheme |
| */ |
| function extractStyleUrls(resolver, baseUrl, cssText) { |
| var foundUrls = []; |
| var modifiedCssText = cssText.replace(CSS_STRIPPABLE_COMMENT_REGEXP, '') |
| .replace(CSS_IMPORT_REGEXP, function () { |
| var m = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| m[_i] = arguments[_i]; |
| } |
| var url = m[1] || m[2]; |
| if (!isStyleUrlResolvable(url)) { |
| // Do not attempt to resolve non-package absolute URLs with URI |
| // scheme |
| return m[0]; |
| } |
| foundUrls.push(resolver.resolve(baseUrl, url)); |
| return ''; |
| }); |
| return new StyleWithImports(modifiedCssText, foundUrls); |
| } |
| var CSS_IMPORT_REGEXP = /@import\s+(?:url\()?\s*(?:(?:['"]([^'"]*))|([^;\)\s]*))[^;]*;?/g; |
| var CSS_STRIPPABLE_COMMENT_REGEXP = /\/\*(?!#\s*(?:sourceURL|sourceMappingURL)=)[\s\S]+?\*\//g; |
| var URL_WITH_SCHEMA_REGEXP = /^([^:/?#]+):/; |
| |
| var PROPERTY_PARTS_SEPARATOR = '.'; |
| var ATTRIBUTE_PREFIX = 'attr'; |
| var CLASS_PREFIX = 'class'; |
| var STYLE_PREFIX = 'style'; |
| var TEMPLATE_ATTR_PREFIX = '*'; |
| var ANIMATE_PROP_PREFIX = 'animate-'; |
| /** |
| * Parses bindings in templates and in the directive host area. |
| */ |
| var BindingParser = /** @class */ (function () { |
| function BindingParser(_exprParser, _interpolationConfig, _schemaRegistry, pipes, errors) { |
| this._exprParser = _exprParser; |
| this._interpolationConfig = _interpolationConfig; |
| this._schemaRegistry = _schemaRegistry; |
| this.errors = errors; |
| this.pipesByName = null; |
| this._usedPipes = new Map(); |
| // When the `pipes` parameter is `null`, do not check for used pipes |
| // This is used in IVY when we might not know the available pipes at compile time |
| if (pipes) { |
| var pipesByName_1 = new Map(); |
| pipes.forEach(function (pipe) { return pipesByName_1.set(pipe.name, pipe); }); |
| this.pipesByName = pipesByName_1; |
| } |
| } |
| Object.defineProperty(BindingParser.prototype, "interpolationConfig", { |
| get: function () { |
| return this._interpolationConfig; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| BindingParser.prototype.getUsedPipes = function () { |
| return Array.from(this._usedPipes.values()); |
| }; |
| BindingParser.prototype.createBoundHostProperties = function (dirMeta, sourceSpan) { |
| var _this = this; |
| if (dirMeta.hostProperties) { |
| var boundProps_1 = []; |
| Object.keys(dirMeta.hostProperties).forEach(function (propName) { |
| var expression = dirMeta.hostProperties[propName]; |
| if (typeof expression === 'string') { |
| _this.parsePropertyBinding(propName, expression, true, sourceSpan, sourceSpan.start.offset, undefined, [], |
| // Use the `sourceSpan` for `keySpan`. This isn't really accurate, but neither is the |
| // sourceSpan, as it represents the sourceSpan of the host itself rather than the |
| // source of the host binding (which doesn't exist in the template). Regardless, |
| // neither of these values are used in Ivy but are only here to satisfy the function |
| // signature. This should likely be refactored in the future so that `sourceSpan` |
| // isn't being used inaccurately. |
| boundProps_1, sourceSpan); |
| } |
| else { |
| _this._reportError("Value of the host property binding \"" + propName + "\" needs to be a string representing an expression but got \"" + expression + "\" (" + typeof expression + ")", sourceSpan); |
| } |
| }); |
| return boundProps_1; |
| } |
| return null; |
| }; |
| BindingParser.prototype.createDirectiveHostPropertyAsts = function (dirMeta, elementSelector, sourceSpan) { |
| var _this = this; |
| var boundProps = this.createBoundHostProperties(dirMeta, sourceSpan); |
| return boundProps && |
| boundProps.map(function (prop) { return _this.createBoundElementProperty(elementSelector, prop); }); |
| }; |
| BindingParser.prototype.createDirectiveHostEventAsts = function (dirMeta, sourceSpan) { |
| var _this = this; |
| if (dirMeta.hostListeners) { |
| var targetEvents_1 = []; |
| Object.keys(dirMeta.hostListeners).forEach(function (propName) { |
| var expression = dirMeta.hostListeners[propName]; |
| if (typeof expression === 'string') { |
| // Use the `sourceSpan` for `keySpan` and `handlerSpan`. This isn't really accurate, but |
| // neither is the `sourceSpan`, as it represents the `sourceSpan` of the host itself |
| // rather than the source of the host binding (which doesn't exist in the template). |
| // Regardless, neither of these values are used in Ivy but are only here to satisfy the |
| // function signature. This should likely be refactored in the future so that `sourceSpan` |
| // isn't being used inaccurately. |
| _this.parseEvent(propName, expression, sourceSpan, sourceSpan, [], targetEvents_1, sourceSpan); |
| } |
| else { |
| _this._reportError("Value of the host listener \"" + propName + "\" needs to be a string representing an expression but got \"" + expression + "\" (" + typeof expression + ")", sourceSpan); |
| } |
| }); |
| return targetEvents_1; |
| } |
| return null; |
| }; |
| BindingParser.prototype.parseInterpolation = function (value, sourceSpan) { |
| var sourceInfo = sourceSpan.start.toString(); |
| var absoluteOffset = sourceSpan.fullStart.offset; |
| try { |
| var ast = this._exprParser.parseInterpolation(value, sourceInfo, absoluteOffset, this._interpolationConfig); |
| if (ast) |
| this._reportExpressionParserErrors(ast.errors, sourceSpan); |
| this._checkPipes(ast, sourceSpan); |
| return ast; |
| } |
| catch (e) { |
| this._reportError("" + e, sourceSpan); |
| return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset); |
| } |
| }; |
| /** |
| * Similar to `parseInterpolation`, but treats the provided string as a single expression |
| * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`). |
| * This is used for parsing the switch expression in ICUs. |
| */ |
| BindingParser.prototype.parseInterpolationExpression = function (expression, sourceSpan) { |
| var sourceInfo = sourceSpan.start.toString(); |
| var absoluteOffset = sourceSpan.start.offset; |
| try { |
| var ast = this._exprParser.parseInterpolationExpression(expression, sourceInfo, absoluteOffset); |
| if (ast) |
| this._reportExpressionParserErrors(ast.errors, sourceSpan); |
| this._checkPipes(ast, sourceSpan); |
| return ast; |
| } |
| catch (e) { |
| this._reportError("" + e, sourceSpan); |
| return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset); |
| } |
| }; |
| /** |
| * Parses the bindings in a microsyntax expression, and converts them to |
| * `ParsedProperty` or `ParsedVariable`. |
| * |
| * @param tplKey template binding name |
| * @param tplValue template binding value |
| * @param sourceSpan span of template binding relative to entire the template |
| * @param absoluteValueOffset start of the tplValue relative to the entire template |
| * @param targetMatchableAttrs potential attributes to match in the template |
| * @param targetProps target property bindings in the template |
| * @param targetVars target variables in the template |
| */ |
| BindingParser.prototype.parseInlineTemplateBinding = function (tplKey, tplValue, sourceSpan, absoluteValueOffset, targetMatchableAttrs, targetProps, targetVars, isIvyAst) { |
| var e_1, _a; |
| var absoluteKeyOffset = sourceSpan.start.offset + TEMPLATE_ATTR_PREFIX.length; |
| var bindings = this._parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset); |
| try { |
| for (var bindings_1 = __values(bindings), bindings_1_1 = bindings_1.next(); !bindings_1_1.done; bindings_1_1 = bindings_1.next()) { |
| var binding = bindings_1_1.value; |
| // sourceSpan is for the entire HTML attribute. bindingSpan is for a particular |
| // binding within the microsyntax expression so it's more narrow than sourceSpan. |
| var bindingSpan = moveParseSourceSpan(sourceSpan, binding.sourceSpan); |
| var key = binding.key.source; |
| var keySpan = moveParseSourceSpan(sourceSpan, binding.key.span); |
| if (binding instanceof VariableBinding) { |
| var value = binding.value ? binding.value.source : '$implicit'; |
| var valueSpan = binding.value ? moveParseSourceSpan(sourceSpan, binding.value.span) : undefined; |
| targetVars.push(new ParsedVariable(key, value, bindingSpan, keySpan, valueSpan)); |
| } |
| else if (binding.value) { |
| var srcSpan = isIvyAst ? bindingSpan : sourceSpan; |
| var valueSpan = moveParseSourceSpan(sourceSpan, binding.value.ast.sourceSpan); |
| this._parsePropertyAst(key, binding.value, srcSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps); |
| } |
| else { |
| targetMatchableAttrs.push([key, '' /* value */]); |
| // Since this is a literal attribute with no RHS, source span should be |
| // just the key span. |
| this.parseLiteralAttr(key, null /* value */, keySpan, absoluteValueOffset, undefined /* valueSpan */, targetMatchableAttrs, targetProps, keySpan); |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (bindings_1_1 && !bindings_1_1.done && (_a = bindings_1.return)) _a.call(bindings_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| }; |
| /** |
| * Parses the bindings in a microsyntax expression, e.g. |
| * ``` |
| * <tag *tplKey="let value1 = prop; let value2 = localVar"> |
| * ``` |
| * |
| * @param tplKey template binding name |
| * @param tplValue template binding value |
| * @param sourceSpan span of template binding relative to entire the template |
| * @param absoluteKeyOffset start of the `tplKey` |
| * @param absoluteValueOffset start of the `tplValue` |
| */ |
| BindingParser.prototype._parseTemplateBindings = function (tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset) { |
| var _this = this; |
| var sourceInfo = sourceSpan.start.toString(); |
| try { |
| var bindingsResult = this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceInfo, absoluteKeyOffset, absoluteValueOffset); |
| this._reportExpressionParserErrors(bindingsResult.errors, sourceSpan); |
| bindingsResult.templateBindings.forEach(function (binding) { |
| if (binding.value instanceof ASTWithSource) { |
| _this._checkPipes(binding.value, sourceSpan); |
| } |
| }); |
| bindingsResult.warnings.forEach(function (warning) { |
| _this._reportError(warning, sourceSpan, exports.ParseErrorLevel.WARNING); |
| }); |
| return bindingsResult.templateBindings; |
| } |
| catch (e) { |
| this._reportError("" + e, sourceSpan); |
| return []; |
| } |
| }; |
| BindingParser.prototype.parseLiteralAttr = function (name, value, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, |
| // TODO(atscott): keySpan is only optional here so VE template parser implementation does not |
| // have to change This should be required when VE is removed. |
| targetProps, keySpan) { |
| if (isAnimationLabel(name)) { |
| name = name.substring(1); |
| if (keySpan !== undefined) { |
| keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset)); |
| } |
| if (value) { |
| this._reportError("Assigning animation triggers via @prop=\"exp\" attributes with an expression is invalid." + |
| " Use property bindings (e.g. [@prop]=\"exp\") or use an attribute without a value (e.g. @prop) instead.", sourceSpan, exports.ParseErrorLevel.ERROR); |
| } |
| this._parseAnimation(name, value, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps); |
| } |
| else { |
| targetProps.push(new ParsedProperty(name, this._exprParser.wrapLiteralPrimitive(value, '', absoluteOffset), exports.ParsedPropertyType.LITERAL_ATTR, sourceSpan, keySpan, valueSpan)); |
| } |
| }; |
| BindingParser.prototype.parsePropertyBinding = function (name, expression, isHost, sourceSpan, absoluteOffset, valueSpan, |
| // TODO(atscott): keySpan is only optional here so VE template parser implementation does not |
| // have to change This should be required when VE is removed. |
| targetMatchableAttrs, targetProps, keySpan) { |
| if (name.length === 0) { |
| this._reportError("Property name is missing in binding", sourceSpan); |
| } |
| var isAnimationProp = false; |
| if (name.startsWith(ANIMATE_PROP_PREFIX)) { |
| isAnimationProp = true; |
| name = name.substring(ANIMATE_PROP_PREFIX.length); |
| if (keySpan !== undefined) { |
| keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + ANIMATE_PROP_PREFIX.length, keySpan.end.offset)); |
| } |
| } |
| else if (isAnimationLabel(name)) { |
| isAnimationProp = true; |
| name = name.substring(1); |
| if (keySpan !== undefined) { |
| keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset)); |
| } |
| } |
| if (isAnimationProp) { |
| this._parseAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps); |
| } |
| else { |
| this._parsePropertyAst(name, this._parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps); |
| } |
| }; |
| BindingParser.prototype.parsePropertyInterpolation = function (name, value, sourceSpan, valueSpan, targetMatchableAttrs, |
| // TODO(atscott): keySpan is only optional here so VE template parser implementation does not |
| // have to change This should be required when VE is removed. |
| targetProps, keySpan) { |
| var expr = this.parseInterpolation(value, valueSpan || sourceSpan); |
| if (expr) { |
| this._parsePropertyAst(name, expr, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps); |
| return true; |
| } |
| return false; |
| }; |
| BindingParser.prototype._parsePropertyAst = function (name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) { |
| targetMatchableAttrs.push([name, ast.source]); |
| targetProps.push(new ParsedProperty(name, ast, exports.ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan)); |
| }; |
| BindingParser.prototype._parseAnimation = function (name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) { |
| if (name.length === 0) { |
| this._reportError('Animation trigger is missing', sourceSpan); |
| } |
| // This will occur when a @trigger is not paired with an expression. |
| // For animations it is valid to not have an expression since */void |
| // states will be applied by angular when the element is attached/detached |
| var ast = this._parseBinding(expression || 'undefined', false, valueSpan || sourceSpan, absoluteOffset); |
| targetMatchableAttrs.push([name, ast.source]); |
| targetProps.push(new ParsedProperty(name, ast, exports.ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan)); |
| }; |
| BindingParser.prototype._parseBinding = function (value, isHostBinding, sourceSpan, absoluteOffset) { |
| var sourceInfo = (sourceSpan && sourceSpan.start || '(unknown)').toString(); |
| try { |
| var ast = isHostBinding ? |
| this._exprParser.parseSimpleBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig) : |
| this._exprParser.parseBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig); |
| if (ast) |
| this._reportExpressionParserErrors(ast.errors, sourceSpan); |
| this._checkPipes(ast, sourceSpan); |
| return ast; |
| } |
| catch (e) { |
| this._reportError("" + e, sourceSpan); |
| return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset); |
| } |
| }; |
| BindingParser.prototype.createBoundElementProperty = function (elementSelector, boundProp, skipValidation, mapPropertyName) { |
| if (skipValidation === void 0) { skipValidation = false; } |
| if (mapPropertyName === void 0) { mapPropertyName = true; } |
| if (boundProp.isAnimation) { |
| return new BoundElementProperty(boundProp.name, 4 /* Animation */, SecurityContext.NONE, boundProp.expression, null, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan); |
| } |
| var unit = null; |
| var bindingType = undefined; |
| var boundPropertyName = null; |
| var parts = boundProp.name.split(PROPERTY_PARTS_SEPARATOR); |
| var securityContexts = undefined; |
| // Check for special cases (prefix style, attr, class) |
| if (parts.length > 1) { |
| if (parts[0] == ATTRIBUTE_PREFIX) { |
| boundPropertyName = parts.slice(1).join(PROPERTY_PARTS_SEPARATOR); |
| if (!skipValidation) { |
| this._validatePropertyOrAttributeName(boundPropertyName, boundProp.sourceSpan, true); |
| } |
| securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, boundPropertyName, true); |
| var nsSeparatorIdx = boundPropertyName.indexOf(':'); |
| if (nsSeparatorIdx > -1) { |
| var ns = boundPropertyName.substring(0, nsSeparatorIdx); |
| var name = boundPropertyName.substring(nsSeparatorIdx + 1); |
| boundPropertyName = mergeNsAndName(ns, name); |
| } |
| bindingType = 1 /* Attribute */; |
| } |
| else if (parts[0] == CLASS_PREFIX) { |
| boundPropertyName = parts[1]; |
| bindingType = 2 /* Class */; |
| securityContexts = [SecurityContext.NONE]; |
| } |
| else if (parts[0] == STYLE_PREFIX) { |
| unit = parts.length > 2 ? parts[2] : null; |
| boundPropertyName = parts[1]; |
| bindingType = 3 /* Style */; |
| securityContexts = [SecurityContext.STYLE]; |
| } |
| } |
| // If not a special case, use the full property name |
| if (boundPropertyName === null) { |
| var mappedPropName = this._schemaRegistry.getMappedPropName(boundProp.name); |
| boundPropertyName = mapPropertyName ? mappedPropName : boundProp.name; |
| securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, mappedPropName, false); |
| bindingType = 0 /* Property */; |
| if (!skipValidation) { |
| this._validatePropertyOrAttributeName(mappedPropName, boundProp.sourceSpan, false); |
| } |
| } |
| return new BoundElementProperty(boundPropertyName, bindingType, securityContexts[0], boundProp.expression, unit, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan); |
| }; |
| // TODO: keySpan should be required but was made optional to avoid changing VE parser. |
| BindingParser.prototype.parseEvent = function (name, expression, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) { |
| if (name.length === 0) { |
| this._reportError("Event name is missing in binding", sourceSpan); |
| } |
| if (isAnimationLabel(name)) { |
| name = name.substr(1); |
| if (keySpan !== undefined) { |
| keySpan = moveParseSourceSpan(keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset)); |
| } |
| this._parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan); |
| } |
| else { |
| this._parseRegularEvent(name, expression, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan); |
| } |
| }; |
| BindingParser.prototype.calcPossibleSecurityContexts = function (selector, propName, isAttribute) { |
| var prop = this._schemaRegistry.getMappedPropName(propName); |
| return calcPossibleSecurityContexts(this._schemaRegistry, selector, prop, isAttribute); |
| }; |
| BindingParser.prototype._parseAnimationEvent = function (name, expression, sourceSpan, handlerSpan, targetEvents, keySpan) { |
| var matches = splitAtPeriod(name, [name, '']); |
| var eventName = matches[0]; |
| var phase = matches[1].toLowerCase(); |
| var ast = this._parseAction(expression, handlerSpan); |
| targetEvents.push(new ParsedEvent(eventName, phase, 1 /* Animation */, ast, sourceSpan, handlerSpan, keySpan)); |
| if (eventName.length === 0) { |
| this._reportError("Animation event name is missing in binding", sourceSpan); |
| } |
| if (phase) { |
| if (phase !== 'start' && phase !== 'done') { |
| this._reportError("The provided animation output phase value \"" + phase + "\" for \"@" + eventName + "\" is not supported (use start or done)", sourceSpan); |
| } |
| } |
| else { |
| this._reportError("The animation trigger output event (@" + eventName + ") is missing its phase value name (start or done are currently supported)", sourceSpan); |
| } |
| }; |
| BindingParser.prototype._parseRegularEvent = function (name, expression, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) { |
| // long format: 'target: eventName' |
| var _a = __read(splitAtColon(name, [null, name]), 2), target = _a[0], eventName = _a[1]; |
| var ast = this._parseAction(expression, handlerSpan); |
| targetMatchableAttrs.push([name, ast.source]); |
| targetEvents.push(new ParsedEvent(eventName, target, 0 /* Regular */, ast, sourceSpan, handlerSpan, keySpan)); |
| // Don't detect directives for event names for now, |
| // so don't add the event name to the matchableAttrs |
| }; |
| BindingParser.prototype._parseAction = function (value, sourceSpan) { |
| var sourceInfo = (sourceSpan && sourceSpan.start || '(unknown').toString(); |
| var absoluteOffset = (sourceSpan && sourceSpan.start) ? sourceSpan.start.offset : 0; |
| try { |
| var ast = this._exprParser.parseAction(value, sourceInfo, absoluteOffset, this._interpolationConfig); |
| if (ast) { |
| this._reportExpressionParserErrors(ast.errors, sourceSpan); |
| } |
| if (!ast || ast.ast instanceof EmptyExpr) { |
| this._reportError("Empty expressions are not allowed", sourceSpan); |
| return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset); |
| } |
| this._checkPipes(ast, sourceSpan); |
| return ast; |
| } |
| catch (e) { |
| this._reportError("" + e, sourceSpan); |
| return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset); |
| } |
| }; |
| BindingParser.prototype._reportError = function (message, sourceSpan, level) { |
| if (level === void 0) { level = exports.ParseErrorLevel.ERROR; } |
| this.errors.push(new ParseError(sourceSpan, message, level)); |
| }; |
| BindingParser.prototype._reportExpressionParserErrors = function (errors, sourceSpan) { |
| var e_2, _a; |
| try { |
| for (var errors_1 = __values(errors), errors_1_1 = errors_1.next(); !errors_1_1.done; errors_1_1 = errors_1.next()) { |
| var error = errors_1_1.value; |
| this._reportError(error.message, sourceSpan); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (errors_1_1 && !errors_1_1.done && (_a = errors_1.return)) _a.call(errors_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| }; |
| // Make sure all the used pipes are known in `this.pipesByName` |
| BindingParser.prototype._checkPipes = function (ast, sourceSpan) { |
| var _this = this; |
| if (ast && this.pipesByName) { |
| var collector = new PipeCollector(); |
| ast.visit(collector); |
| collector.pipes.forEach(function (ast, pipeName) { |
| var pipeMeta = _this.pipesByName.get(pipeName); |
| if (!pipeMeta) { |
| _this._reportError("The pipe '" + pipeName + "' could not be found", new ParseSourceSpan(sourceSpan.start.moveBy(ast.span.start), sourceSpan.start.moveBy(ast.span.end))); |
| } |
| else { |
| _this._usedPipes.set(pipeName, pipeMeta); |
| } |
| }); |
| } |
| }; |
| /** |
| * @param propName the name of the property / attribute |
| * @param sourceSpan |
| * @param isAttr true when binding to an attribute |
| */ |
| BindingParser.prototype._validatePropertyOrAttributeName = function (propName, sourceSpan, isAttr) { |
| var report = isAttr ? this._schemaRegistry.validateAttribute(propName) : |
| this._schemaRegistry.validateProperty(propName); |
| if (report.error) { |
| this._reportError(report.msg, sourceSpan, exports.ParseErrorLevel.ERROR); |
| } |
| }; |
| return BindingParser; |
| }()); |
| var PipeCollector = /** @class */ (function (_super) { |
| __extends(PipeCollector, _super); |
| function PipeCollector() { |
| var _this = _super.apply(this, __spread(arguments)) || this; |
| _this.pipes = new Map(); |
| return _this; |
| } |
| PipeCollector.prototype.visitPipe = function (ast, context) { |
| this.pipes.set(ast.name, ast); |
| ast.exp.visit(this); |
| this.visitAll(ast.args, context); |
| return null; |
| }; |
| return PipeCollector; |
| }(RecursiveAstVisitor$1)); |
| function isAnimationLabel(name) { |
| return name[0] == '@'; |
| } |
| function calcPossibleSecurityContexts(registry, selector, propName, isAttribute) { |
| var ctxs = []; |
| CssSelector.parse(selector).forEach(function (selector) { |
| var elementNames = selector.element ? [selector.element] : registry.allKnownElementNames(); |
| var notElementNames = new Set(selector.notSelectors.filter(function (selector) { return selector.isElementSelector(); }) |
| .map(function (selector) { return selector.element; })); |
| var possibleElementNames = elementNames.filter(function (elementName) { return !notElementNames.has(elementName); }); |
| ctxs.push.apply(ctxs, __spread(possibleElementNames.map(function (elementName) { return registry.securityContext(elementName, propName, isAttribute); }))); |
| }); |
| return ctxs.length === 0 ? [SecurityContext.NONE] : Array.from(new Set(ctxs)).sort(); |
| } |
| /** |
| * Compute a new ParseSourceSpan based off an original `sourceSpan` by using |
| * absolute offsets from the specified `absoluteSpan`. |
| * |
| * @param sourceSpan original source span |
| * @param absoluteSpan absolute source span to move to |
| */ |
| function moveParseSourceSpan(sourceSpan, absoluteSpan) { |
| // The difference of two absolute offsets provide the relative offset |
| var startDiff = absoluteSpan.start - sourceSpan.start.offset; |
| var endDiff = absoluteSpan.end - sourceSpan.end.offset; |
| return new ParseSourceSpan(sourceSpan.start.moveBy(startDiff), sourceSpan.end.moveBy(endDiff), sourceSpan.fullStart.moveBy(startDiff), sourceSpan.details); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var NG_CONTENT_SELECT_ATTR = 'select'; |
| var LINK_ELEMENT = 'link'; |
| var LINK_STYLE_REL_ATTR = 'rel'; |
| var LINK_STYLE_HREF_ATTR = 'href'; |
| var LINK_STYLE_REL_VALUE = 'stylesheet'; |
| var STYLE_ELEMENT = 'style'; |
| var SCRIPT_ELEMENT = 'script'; |
| var NG_NON_BINDABLE_ATTR = 'ngNonBindable'; |
| var NG_PROJECT_AS = 'ngProjectAs'; |
| function preparseElement(ast) { |
| var selectAttr = null; |
| var hrefAttr = null; |
| var relAttr = null; |
| var nonBindable = false; |
| var projectAs = ''; |
| ast.attrs.forEach(function (attr) { |
| var lcAttrName = attr.name.toLowerCase(); |
| if (lcAttrName == NG_CONTENT_SELECT_ATTR) { |
| selectAttr = attr.value; |
| } |
| else if (lcAttrName == LINK_STYLE_HREF_ATTR) { |
| hrefAttr = attr.value; |
| } |
| else if (lcAttrName == LINK_STYLE_REL_ATTR) { |
| relAttr = attr.value; |
| } |
| else if (attr.name == NG_NON_BINDABLE_ATTR) { |
| nonBindable = true; |
| } |
| else if (attr.name == NG_PROJECT_AS) { |
| if (attr.value.length > 0) { |
| projectAs = attr.value; |
| } |
| } |
| }); |
| selectAttr = normalizeNgContentSelect(selectAttr); |
| var nodeName = ast.name.toLowerCase(); |
| var type = PreparsedElementType.OTHER; |
| if (isNgContent(nodeName)) { |
| type = PreparsedElementType.NG_CONTENT; |
| } |
| else if (nodeName == STYLE_ELEMENT) { |
| type = PreparsedElementType.STYLE; |
| } |
| else if (nodeName == SCRIPT_ELEMENT) { |
| type = PreparsedElementType.SCRIPT; |
| } |
| else if (nodeName == LINK_ELEMENT && relAttr == LINK_STYLE_REL_VALUE) { |
| type = PreparsedElementType.STYLESHEET; |
| } |
| return new PreparsedElement(type, selectAttr, hrefAttr, nonBindable, projectAs); |
| } |
| var PreparsedElementType; |
| (function (PreparsedElementType) { |
| PreparsedElementType[PreparsedElementType["NG_CONTENT"] = 0] = "NG_CONTENT"; |
| PreparsedElementType[PreparsedElementType["STYLE"] = 1] = "STYLE"; |
| PreparsedElementType[PreparsedElementType["STYLESHEET"] = 2] = "STYLESHEET"; |
| PreparsedElementType[PreparsedElementType["SCRIPT"] = 3] = "SCRIPT"; |
| PreparsedElementType[PreparsedElementType["OTHER"] = 4] = "OTHER"; |
| })(PreparsedElementType || (PreparsedElementType = {})); |
| var PreparsedElement = /** @class */ (function () { |
| function PreparsedElement(type, selectAttr, hrefAttr, nonBindable, projectAs) { |
| this.type = type; |
| this.selectAttr = selectAttr; |
| this.hrefAttr = hrefAttr; |
| this.nonBindable = nonBindable; |
| this.projectAs = projectAs; |
| } |
| return PreparsedElement; |
| }()); |
| function normalizeNgContentSelect(selectAttr) { |
| if (selectAttr === null || selectAttr.length === 0) { |
| return '*'; |
| } |
| return selectAttr; |
| } |
| |
| var BIND_NAME_REGEXP = /^(?:(?:(?:(bind-)|(let-)|(ref-|#)|(on-)|(bindon-)|(@))(.*))|\[\(([^\)]+)\)\]|\[([^\]]+)\]|\(([^\)]+)\))$/; |
| // Group 1 = "bind-" |
| var KW_BIND_IDX = 1; |
| // Group 2 = "let-" |
| var KW_LET_IDX = 2; |
| // Group 3 = "ref-/#" |
| var KW_REF_IDX = 3; |
| // Group 4 = "on-" |
| var KW_ON_IDX = 4; |
| // Group 5 = "bindon-" |
| var KW_BINDON_IDX = 5; |
| // Group 6 = "@" |
| var KW_AT_IDX = 6; |
| // Group 7 = the identifier after "bind-", "let-", "ref-/#", "on-", "bindon-" or "@" |
| var IDENT_KW_IDX = 7; |
| // Group 8 = identifier inside [()] |
| var IDENT_BANANA_BOX_IDX = 8; |
| // Group 9 = identifier inside [] |
| var IDENT_PROPERTY_IDX = 9; |
| // Group 10 = identifier inside () |
| var IDENT_EVENT_IDX = 10; |
| var TEMPLATE_ATTR_PREFIX$1 = '*'; |
| var CLASS_ATTR = 'class'; |
| var _TEXT_CSS_SELECTOR; |
| function TEXT_CSS_SELECTOR() { |
| if (!_TEXT_CSS_SELECTOR) { |
| _TEXT_CSS_SELECTOR = CssSelector.parse('*')[0]; |
| } |
| return _TEXT_CSS_SELECTOR; |
| } |
| var TemplateParseError = /** @class */ (function (_super) { |
| __extends(TemplateParseError, _super); |
| function TemplateParseError(message, span, level) { |
| return _super.call(this, span, message, level) || this; |
| } |
| return TemplateParseError; |
| }(ParseError)); |
| var TemplateParseResult = /** @class */ (function () { |
| function TemplateParseResult(templateAst, usedPipes, errors) { |
| this.templateAst = templateAst; |
| this.usedPipes = usedPipes; |
| this.errors = errors; |
| } |
| return TemplateParseResult; |
| }()); |
| var TemplateParser = /** @class */ (function () { |
| function TemplateParser(_config, _reflector, _exprParser, _schemaRegistry, _htmlParser, _console, transforms) { |
| this._config = _config; |
| this._reflector = _reflector; |
| this._exprParser = _exprParser; |
| this._schemaRegistry = _schemaRegistry; |
| this._htmlParser = _htmlParser; |
| this._console = _console; |
| this.transforms = transforms; |
| } |
| Object.defineProperty(TemplateParser.prototype, "expressionParser", { |
| get: function () { |
| return this._exprParser; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| TemplateParser.prototype.parse = function (component, template, directives, pipes, schemas, templateUrl, preserveWhitespaces) { |
| var _a; |
| var result = this.tryParse(component, template, directives, pipes, schemas, templateUrl, preserveWhitespaces); |
| var warnings = result.errors.filter(function (error) { return error.level === exports.ParseErrorLevel.WARNING; }); |
| var errors = result.errors.filter(function (error) { return error.level === exports.ParseErrorLevel.ERROR; }); |
| if (warnings.length > 0) { |
| (_a = this._console) === null || _a === void 0 ? void 0 : _a.warn("Template parse warnings:\n" + warnings.join('\n')); |
| } |
| if (errors.length > 0) { |
| var errorString = errors.join('\n'); |
| throw syntaxError("Template parse errors:\n" + errorString, errors); |
| } |
| return { template: result.templateAst, pipes: result.usedPipes }; |
| }; |
| TemplateParser.prototype.tryParse = function (component, template, directives, pipes, schemas, templateUrl, preserveWhitespaces) { |
| var htmlParseResult = typeof template === 'string' ? |
| this._htmlParser.parse(template, templateUrl, { |
| tokenizeExpansionForms: true, |
| interpolationConfig: this.getInterpolationConfig(component) |
| }) : |
| template; |
| if (!preserveWhitespaces) { |
| htmlParseResult = removeWhitespaces(htmlParseResult); |
| } |
| return this.tryParseHtml(this.expandHtml(htmlParseResult), component, directives, pipes, schemas); |
| }; |
| TemplateParser.prototype.tryParseHtml = function (htmlAstWithErrors, component, directives, pipes, schemas) { |
| var result; |
| var errors = htmlAstWithErrors.errors; |
| var usedPipes = []; |
| if (htmlAstWithErrors.rootNodes.length > 0) { |
| var uniqDirectives = removeSummaryDuplicates(directives); |
| var uniqPipes = removeSummaryDuplicates(pipes); |
| var providerViewContext = new ProviderViewContext(this._reflector, component); |
| var interpolationConfig = undefined; |
| if (component.template && component.template.interpolation) { |
| interpolationConfig = { |
| start: component.template.interpolation[0], |
| end: component.template.interpolation[1] |
| }; |
| } |
| var bindingParser = new BindingParser(this._exprParser, interpolationConfig, this._schemaRegistry, uniqPipes, errors); |
| var parseVisitor = new TemplateParseVisitor(this._reflector, this._config, providerViewContext, uniqDirectives, bindingParser, this._schemaRegistry, schemas, errors); |
| result = visitAll$1(parseVisitor, htmlAstWithErrors.rootNodes, EMPTY_ELEMENT_CONTEXT); |
| errors.push.apply(errors, __spread(providerViewContext.errors)); |
| usedPipes.push.apply(usedPipes, __spread(bindingParser.getUsedPipes())); |
| } |
| else { |
| result = []; |
| } |
| this._assertNoReferenceDuplicationOnTemplate(result, errors); |
| if (errors.length > 0) { |
| return new TemplateParseResult(result, usedPipes, errors); |
| } |
| if (this.transforms) { |
| this.transforms.forEach(function (transform) { |
| result = templateVisitAll(transform, result); |
| }); |
| } |
| return new TemplateParseResult(result, usedPipes, errors); |
| }; |
| TemplateParser.prototype.expandHtml = function (htmlAstWithErrors, forced) { |
| if (forced === void 0) { forced = false; } |
| var errors = htmlAstWithErrors.errors; |
| if (errors.length == 0 || forced) { |
| // Transform ICU messages to angular directives |
| var expandedHtmlAst = expandNodes(htmlAstWithErrors.rootNodes); |
| errors.push.apply(errors, __spread(expandedHtmlAst.errors)); |
| htmlAstWithErrors = new ParseTreeResult(expandedHtmlAst.nodes, errors); |
| } |
| return htmlAstWithErrors; |
| }; |
| TemplateParser.prototype.getInterpolationConfig = function (component) { |
| if (component.template) { |
| return InterpolationConfig.fromArray(component.template.interpolation); |
| } |
| return undefined; |
| }; |
| /** @internal */ |
| TemplateParser.prototype._assertNoReferenceDuplicationOnTemplate = function (result, errors) { |
| var existingReferences = []; |
| result.filter(function (element) { return !!element.references; }) |
| .forEach(function (element) { return element.references.forEach(function (reference) { |
| var name = reference.name; |
| if (existingReferences.indexOf(name) < 0) { |
| existingReferences.push(name); |
| } |
| else { |
| var error = new TemplateParseError("Reference \"#" + name + "\" is defined several times", reference.sourceSpan, exports.ParseErrorLevel.ERROR); |
| errors.push(error); |
| } |
| }); }); |
| }; |
| return TemplateParser; |
| }()); |
| var TemplateParseVisitor = /** @class */ (function () { |
| function TemplateParseVisitor(reflector, config, providerViewContext, directives, _bindingParser, _schemaRegistry, _schemas, _targetErrors) { |
| var _this = this; |
| this.reflector = reflector; |
| this.config = config; |
| this.providerViewContext = providerViewContext; |
| this._bindingParser = _bindingParser; |
| this._schemaRegistry = _schemaRegistry; |
| this._schemas = _schemas; |
| this._targetErrors = _targetErrors; |
| this.selectorMatcher = new SelectorMatcher(); |
| this.directivesIndex = new Map(); |
| this.ngContentCount = 0; |
| // Note: queries start with id 1 so we can use the number in a Bloom filter! |
| this.contentQueryStartId = providerViewContext.component.viewQueries.length + 1; |
| directives.forEach(function (directive, index) { |
| var selector = CssSelector.parse(directive.selector); |
| _this.selectorMatcher.addSelectables(selector, directive); |
| _this.directivesIndex.set(directive, index); |
| }); |
| } |
| TemplateParseVisitor.prototype.visitExpansion = function (expansion, context) { |
| return null; |
| }; |
| TemplateParseVisitor.prototype.visitExpansionCase = function (expansionCase, context) { |
| return null; |
| }; |
| TemplateParseVisitor.prototype.visitText = function (text, parent) { |
| var ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR()); |
| var valueNoNgsp = replaceNgsp(text.value); |
| var expr = this._bindingParser.parseInterpolation(valueNoNgsp, text.sourceSpan); |
| return expr ? new BoundTextAst(expr, ngContentIndex, text.sourceSpan) : |
| new TextAst(valueNoNgsp, ngContentIndex, text.sourceSpan); |
| }; |
| TemplateParseVisitor.prototype.visitAttribute = function (attribute, context) { |
| return new AttrAst(attribute.name, attribute.value, attribute.sourceSpan); |
| }; |
| TemplateParseVisitor.prototype.visitComment = function (comment, context) { |
| return null; |
| }; |
| TemplateParseVisitor.prototype.visitElement = function (element, parent) { |
| var _this = this; |
| var queryStartIndex = this.contentQueryStartId; |
| var elName = element.name; |
| var preparsedElement = preparseElement(element); |
| if (preparsedElement.type === PreparsedElementType.SCRIPT || |
| preparsedElement.type === PreparsedElementType.STYLE) { |
| // Skipping <script> for security reasons |
| // Skipping <style> as we already processed them |
| // in the StyleCompiler |
| return null; |
| } |
| if (preparsedElement.type === PreparsedElementType.STYLESHEET && |
| isStyleUrlResolvable(preparsedElement.hrefAttr)) { |
| // Skipping stylesheets with either relative urls or package scheme as we already processed |
| // them in the StyleCompiler |
| return null; |
| } |
| var matchableAttrs = []; |
| var elementOrDirectiveProps = []; |
| var elementOrDirectiveRefs = []; |
| var elementVars = []; |
| var events = []; |
| var templateElementOrDirectiveProps = []; |
| var templateMatchableAttrs = []; |
| var templateElementVars = []; |
| var hasInlineTemplates = false; |
| var attrs = []; |
| var isTemplateElement = isNgTemplate(element.name); |
| element.attrs.forEach(function (attr) { |
| var parsedVariables = []; |
| var hasBinding = _this._parseAttr(isTemplateElement, attr, matchableAttrs, elementOrDirectiveProps, events, elementOrDirectiveRefs, elementVars); |
| elementVars.push.apply(elementVars, __spread(parsedVariables.map(function (v) { return VariableAst.fromParsedVariable(v); }))); |
| var templateValue; |
| var templateKey; |
| var normalizedName = _this._normalizeAttributeName(attr.name); |
| if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX$1)) { |
| templateValue = attr.value; |
| templateKey = normalizedName.substring(TEMPLATE_ATTR_PREFIX$1.length); |
| } |
| var hasTemplateBinding = templateValue != null; |
| if (hasTemplateBinding) { |
| if (hasInlineTemplates) { |
| _this._reportError("Can't have multiple template bindings on one element. Use only one attribute prefixed with *", attr.sourceSpan); |
| } |
| hasInlineTemplates = true; |
| var parsedVariables_1 = []; |
| var absoluteOffset = (attr.valueSpan || attr.sourceSpan).start.offset; |
| _this._bindingParser.parseInlineTemplateBinding(templateKey, templateValue, attr.sourceSpan, absoluteOffset, templateMatchableAttrs, templateElementOrDirectiveProps, parsedVariables_1, false /* isIvyAst */); |
| templateElementVars.push.apply(templateElementVars, __spread(parsedVariables_1.map(function (v) { return VariableAst.fromParsedVariable(v); }))); |
| } |
| if (!hasBinding && !hasTemplateBinding) { |
| // don't include the bindings as attributes as well in the AST |
| attrs.push(_this.visitAttribute(attr, null)); |
| matchableAttrs.push([attr.name, attr.value]); |
| } |
| }); |
| var elementCssSelector = createElementCssSelector(elName, matchableAttrs); |
| var _b = this._parseDirectives(this.selectorMatcher, elementCssSelector), directiveMetas = _b.directives, matchElement = _b.matchElement; |
| var references = []; |
| var boundDirectivePropNames = new Set(); |
| var directiveAsts = this._createDirectiveAsts(isTemplateElement, element.name, directiveMetas, elementOrDirectiveProps, elementOrDirectiveRefs, element.sourceSpan, references, boundDirectivePropNames); |
| var elementProps = this._createElementPropertyAsts(element.name, elementOrDirectiveProps, boundDirectivePropNames); |
| var isViewRoot = parent.isTemplateElement || hasInlineTemplates; |
| var providerContext = new ProviderElementContext(this.providerViewContext, parent.providerContext, isViewRoot, directiveAsts, attrs, references, isTemplateElement, queryStartIndex, element.sourceSpan); |
| var children = visitAll$1(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children, ElementContext.create(isTemplateElement, directiveAsts, isTemplateElement ? parent.providerContext : providerContext)); |
| providerContext.afterElement(); |
| // Override the actual selector when the `ngProjectAs` attribute is provided |
| var projectionSelector = preparsedElement.projectAs != '' ? |
| CssSelector.parse(preparsedElement.projectAs)[0] : |
| elementCssSelector; |
| var ngContentIndex = parent.findNgContentIndex(projectionSelector); |
| var parsedElement; |
| if (preparsedElement.type === PreparsedElementType.NG_CONTENT) { |
| // `<ng-content>` element |
| if (element.children && !element.children.every(_isEmptyTextNode)) { |
| this._reportError("<ng-content> element cannot have content.", element.sourceSpan); |
| } |
| parsedElement = new NgContentAst(this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan); |
| } |
| else if (isTemplateElement) { |
| // `<ng-template>` element |
| this._assertAllEventsPublishedByDirectives(directiveAsts, events); |
| this._assertNoComponentsNorElementBindingsOnTemplate(directiveAsts, elementProps, element.sourceSpan); |
| parsedElement = new EmbeddedTemplateAst(attrs, events, references, elementVars, providerContext.transformedDirectiveAsts, providerContext.transformProviders, providerContext.transformedHasViewContainer, providerContext.queryMatches, children, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan); |
| } |
| else { |
| // element other than `<ng-content>` and `<ng-template>` |
| this._assertElementExists(matchElement, element); |
| this._assertOnlyOneComponent(directiveAsts, element.sourceSpan); |
| var ngContentIndex_1 = hasInlineTemplates ? null : parent.findNgContentIndex(projectionSelector); |
| parsedElement = new ElementAst(elName, attrs, elementProps, events, references, providerContext.transformedDirectiveAsts, providerContext.transformProviders, providerContext.transformedHasViewContainer, providerContext.queryMatches, children, hasInlineTemplates ? null : ngContentIndex_1, element.sourceSpan, element.endSourceSpan || null); |
| } |
| if (hasInlineTemplates) { |
| // The element as a *-attribute |
| var templateQueryStartIndex = this.contentQueryStartId; |
| var templateSelector = createElementCssSelector('ng-template', templateMatchableAttrs); |
| var directives = this._parseDirectives(this.selectorMatcher, templateSelector).directives; |
| var templateBoundDirectivePropNames = new Set(); |
| var templateDirectiveAsts = this._createDirectiveAsts(true, elName, directives, templateElementOrDirectiveProps, [], element.sourceSpan, [], templateBoundDirectivePropNames); |
| var templateElementProps = this._createElementPropertyAsts(elName, templateElementOrDirectiveProps, templateBoundDirectivePropNames); |
| this._assertNoComponentsNorElementBindingsOnTemplate(templateDirectiveAsts, templateElementProps, element.sourceSpan); |
| var templateProviderContext = new ProviderElementContext(this.providerViewContext, parent.providerContext, parent.isTemplateElement, templateDirectiveAsts, [], [], true, templateQueryStartIndex, element.sourceSpan); |
| templateProviderContext.afterElement(); |
| parsedElement = new EmbeddedTemplateAst([], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts, templateProviderContext.transformProviders, templateProviderContext.transformedHasViewContainer, templateProviderContext.queryMatches, [parsedElement], ngContentIndex, element.sourceSpan); |
| } |
| return parsedElement; |
| }; |
| TemplateParseVisitor.prototype._parseAttr = function (isTemplateElement, attr, targetMatchableAttrs, targetProps, targetEvents, targetRefs, targetVars) { |
| var name = this._normalizeAttributeName(attr.name); |
| var value = attr.value; |
| var srcSpan = attr.sourceSpan; |
| var absoluteOffset = attr.valueSpan ? attr.valueSpan.start.offset : srcSpan.start.offset; |
| var boundEvents = []; |
| var bindParts = name.match(BIND_NAME_REGEXP); |
| var hasBinding = false; |
| if (bindParts !== null) { |
| hasBinding = true; |
| if (bindParts[KW_BIND_IDX] != null) { |
| this._bindingParser.parsePropertyBinding(bindParts[IDENT_KW_IDX], value, false, srcSpan, absoluteOffset, attr.valueSpan, targetMatchableAttrs, targetProps); |
| } |
| else if (bindParts[KW_LET_IDX]) { |
| if (isTemplateElement) { |
| var identifier = bindParts[IDENT_KW_IDX]; |
| this._parseVariable(identifier, value, srcSpan, targetVars); |
| } |
| else { |
| this._reportError("\"let-\" is only supported on ng-template elements.", srcSpan); |
| } |
| } |
| else if (bindParts[KW_REF_IDX]) { |
| var identifier = bindParts[IDENT_KW_IDX]; |
| this._parseReference(identifier, value, srcSpan, targetRefs); |
| } |
| else if (bindParts[KW_ON_IDX]) { |
| this._bindingParser.parseEvent(bindParts[IDENT_KW_IDX], value, srcSpan, attr.valueSpan || srcSpan, targetMatchableAttrs, boundEvents); |
| } |
| else if (bindParts[KW_BINDON_IDX]) { |
| this._bindingParser.parsePropertyBinding(bindParts[IDENT_KW_IDX], value, false, srcSpan, absoluteOffset, attr.valueSpan, targetMatchableAttrs, targetProps); |
| this._parseAssignmentEvent(bindParts[IDENT_KW_IDX], value, srcSpan, attr.valueSpan || srcSpan, targetMatchableAttrs, boundEvents); |
| } |
| else if (bindParts[KW_AT_IDX]) { |
| this._bindingParser.parseLiteralAttr(name, value, srcSpan, absoluteOffset, attr.valueSpan, targetMatchableAttrs, targetProps); |
| } |
| else if (bindParts[IDENT_BANANA_BOX_IDX]) { |
| this._bindingParser.parsePropertyBinding(bindParts[IDENT_BANANA_BOX_IDX], value, false, srcSpan, absoluteOffset, attr.valueSpan, targetMatchableAttrs, targetProps); |
| this._parseAssignmentEvent(bindParts[IDENT_BANANA_BOX_IDX], value, srcSpan, attr.valueSpan || srcSpan, targetMatchableAttrs, boundEvents); |
| } |
| else if (bindParts[IDENT_PROPERTY_IDX]) { |
| this._bindingParser.parsePropertyBinding(bindParts[IDENT_PROPERTY_IDX], value, false, srcSpan, absoluteOffset, attr.valueSpan, targetMatchableAttrs, targetProps); |
| } |
| else if (bindParts[IDENT_EVENT_IDX]) { |
| this._bindingParser.parseEvent(bindParts[IDENT_EVENT_IDX], value, srcSpan, attr.valueSpan || srcSpan, targetMatchableAttrs, boundEvents); |
| } |
| } |
| else { |
| hasBinding = this._bindingParser.parsePropertyInterpolation(name, value, srcSpan, attr.valueSpan, targetMatchableAttrs, targetProps); |
| } |
| if (!hasBinding) { |
| this._bindingParser.parseLiteralAttr(name, value, srcSpan, absoluteOffset, attr.valueSpan, targetMatchableAttrs, targetProps); |
| } |
| targetEvents.push.apply(targetEvents, __spread(boundEvents.map(function (e) { return BoundEventAst.fromParsedEvent(e); }))); |
| return hasBinding; |
| }; |
| TemplateParseVisitor.prototype._normalizeAttributeName = function (attrName) { |
| return /^data-/i.test(attrName) ? attrName.substring(5) : attrName; |
| }; |
| TemplateParseVisitor.prototype._parseVariable = function (identifier, value, sourceSpan, targetVars) { |
| if (identifier.indexOf('-') > -1) { |
| this._reportError("\"-\" is not allowed in variable names", sourceSpan); |
| } |
| else if (identifier.length === 0) { |
| this._reportError("Variable does not have a name", sourceSpan); |
| } |
| targetVars.push(new VariableAst(identifier, value, sourceSpan)); |
| }; |
| TemplateParseVisitor.prototype._parseReference = function (identifier, value, sourceSpan, targetRefs) { |
| if (identifier.indexOf('-') > -1) { |
| this._reportError("\"-\" is not allowed in reference names", sourceSpan); |
| } |
| else if (identifier.length === 0) { |
| this._reportError("Reference does not have a name", sourceSpan); |
| } |
| targetRefs.push(new ElementOrDirectiveRef(identifier, value, sourceSpan)); |
| }; |
| TemplateParseVisitor.prototype._parseAssignmentEvent = function (name, expression, sourceSpan, valueSpan, targetMatchableAttrs, targetEvents) { |
| this._bindingParser.parseEvent(name + "Change", expression + "=$event", sourceSpan, valueSpan, targetMatchableAttrs, targetEvents); |
| }; |
| TemplateParseVisitor.prototype._parseDirectives = function (selectorMatcher, elementCssSelector) { |
| var _this = this; |
| // Need to sort the directives so that we get consistent results throughout, |
| // as selectorMatcher uses Maps inside. |
| // Also deduplicate directives as they might match more than one time! |
| var directives = newArray(this.directivesIndex.size); |
| // Whether any directive selector matches on the element name |
| var matchElement = false; |
| selectorMatcher.match(elementCssSelector, function (selector, directive) { |
| directives[_this.directivesIndex.get(directive)] = directive; |
| matchElement = matchElement || selector.hasElementSelector(); |
| }); |
| return { |
| directives: directives.filter(function (dir) { return !!dir; }), |
| matchElement: matchElement, |
| }; |
| }; |
| TemplateParseVisitor.prototype._createDirectiveAsts = function (isTemplateElement, elementName, directives, props, elementOrDirectiveRefs, elementSourceSpan, targetReferences, targetBoundDirectivePropNames) { |
| var _this = this; |
| var matchedReferences = new Set(); |
| var component = null; |
| var directiveAsts = directives.map(function (directive) { |
| var sourceSpan = new ParseSourceSpan(elementSourceSpan.start, elementSourceSpan.end, elementSourceSpan.fullStart, "Directive " + identifierName(directive.type)); |
| if (directive.isComponent) { |
| component = directive; |
| } |
| var directiveProperties = []; |
| var boundProperties = _this._bindingParser.createDirectiveHostPropertyAsts(directive, elementName, sourceSpan); |
| var hostProperties = boundProperties.map(function (prop) { return BoundElementPropertyAst.fromBoundProperty(prop); }); |
| // Note: We need to check the host properties here as well, |
| // as we don't know the element name in the DirectiveWrapperCompiler yet. |
| hostProperties = _this._checkPropertiesInSchema(elementName, hostProperties); |
| var parsedEvents = _this._bindingParser.createDirectiveHostEventAsts(directive, sourceSpan); |
| _this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties, targetBoundDirectivePropNames); |
| elementOrDirectiveRefs.forEach(function (elOrDirRef) { |
| if ((elOrDirRef.value.length === 0 && directive.isComponent) || |
| (elOrDirRef.isReferenceToDirective(directive))) { |
| targetReferences.push(new ReferenceAst(elOrDirRef.name, createTokenForReference(directive.type.reference), elOrDirRef.value, elOrDirRef.sourceSpan)); |
| matchedReferences.add(elOrDirRef.name); |
| } |
| }); |
| var hostEvents = parsedEvents.map(function (e) { return BoundEventAst.fromParsedEvent(e); }); |
| var contentQueryStartId = _this.contentQueryStartId; |
| _this.contentQueryStartId += directive.queries.length; |
| return new DirectiveAst(directive, directiveProperties, hostProperties, hostEvents, contentQueryStartId, sourceSpan); |
| }); |
| elementOrDirectiveRefs.forEach(function (elOrDirRef) { |
| if (elOrDirRef.value.length > 0) { |
| if (!matchedReferences.has(elOrDirRef.name)) { |
| _this._reportError("There is no directive with \"exportAs\" set to \"" + elOrDirRef.value + "\"", elOrDirRef.sourceSpan); |
| } |
| } |
| else if (!component) { |
| var refToken = null; |
| if (isTemplateElement) { |
| refToken = createTokenForExternalReference(_this.reflector, Identifiers.TemplateRef); |
| } |
| targetReferences.push(new ReferenceAst(elOrDirRef.name, refToken, elOrDirRef.value, elOrDirRef.sourceSpan)); |
| } |
| }); |
| return directiveAsts; |
| }; |
| TemplateParseVisitor.prototype._createDirectivePropertyAsts = function (directiveProperties, boundProps, targetBoundDirectiveProps, targetBoundDirectivePropNames) { |
| if (directiveProperties) { |
| var boundPropsByName_1 = new Map(); |
| boundProps.forEach(function (boundProp) { |
| var prevValue = boundPropsByName_1.get(boundProp.name); |
| if (!prevValue || prevValue.isLiteral) { |
| // give [a]="b" a higher precedence than a="b" on the same element |
| boundPropsByName_1.set(boundProp.name, boundProp); |
| } |
| }); |
| Object.keys(directiveProperties).forEach(function (dirProp) { |
| var elProp = directiveProperties[dirProp]; |
| var boundProp = boundPropsByName_1.get(elProp); |
| // Bindings are optional, so this binding only needs to be set up if an expression is given. |
| if (boundProp) { |
| targetBoundDirectivePropNames.add(boundProp.name); |
| if (!isEmptyExpression(boundProp.expression)) { |
| targetBoundDirectiveProps.push(new BoundDirectivePropertyAst(dirProp, boundProp.name, boundProp.expression, boundProp.sourceSpan)); |
| } |
| } |
| }); |
| } |
| }; |
| TemplateParseVisitor.prototype._createElementPropertyAsts = function (elementName, props, boundDirectivePropNames) { |
| var _this = this; |
| var boundElementProps = []; |
| props.forEach(function (prop) { |
| if (!prop.isLiteral && !boundDirectivePropNames.has(prop.name)) { |
| var boundProp = _this._bindingParser.createBoundElementProperty(elementName, prop); |
| boundElementProps.push(BoundElementPropertyAst.fromBoundProperty(boundProp)); |
| } |
| }); |
| return this._checkPropertiesInSchema(elementName, boundElementProps); |
| }; |
| TemplateParseVisitor.prototype._findComponentDirectives = function (directives) { |
| return directives.filter(function (directive) { return directive.directive.isComponent; }); |
| }; |
| TemplateParseVisitor.prototype._findComponentDirectiveNames = function (directives) { |
| return this._findComponentDirectives(directives) |
| .map(function (directive) { return identifierName(directive.directive.type); }); |
| }; |
| TemplateParseVisitor.prototype._assertOnlyOneComponent = function (directives, sourceSpan) { |
| var componentTypeNames = this._findComponentDirectiveNames(directives); |
| if (componentTypeNames.length > 1) { |
| this._reportError("More than one component matched on this element.\n" + |
| "Make sure that only one component's selector can match a given element.\n" + |
| ("Conflicting components: " + componentTypeNames.join(',')), sourceSpan); |
| } |
| }; |
| /** |
| * Make sure that non-angular tags conform to the schemas. |
| * |
| * Note: An element is considered an angular tag when at least one directive selector matches the |
| * tag name. |
| * |
| * @param matchElement Whether any directive has matched on the tag name |
| * @param element the html element |
| */ |
| TemplateParseVisitor.prototype._assertElementExists = function (matchElement, element) { |
| var elName = element.name.replace(/^:xhtml:/, ''); |
| if (!matchElement && !this._schemaRegistry.hasElement(elName, this._schemas)) { |
| var errorMsg = "'" + elName + "' is not a known element:\n"; |
| errorMsg += "1. If '" + elName + "' is an Angular component, then verify that it is part of this module.\n"; |
| if (elName.indexOf('-') > -1) { |
| errorMsg += "2. If '" + elName + "' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message."; |
| } |
| else { |
| errorMsg += |
| "2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component."; |
| } |
| this._reportError(errorMsg, element.sourceSpan); |
| } |
| }; |
| TemplateParseVisitor.prototype._assertNoComponentsNorElementBindingsOnTemplate = function (directives, elementProps, sourceSpan) { |
| var _this = this; |
| var componentTypeNames = this._findComponentDirectiveNames(directives); |
| if (componentTypeNames.length > 0) { |
| this._reportError("Components on an embedded template: " + componentTypeNames.join(','), sourceSpan); |
| } |
| elementProps.forEach(function (prop) { |
| _this._reportError("Property binding " + prop.name + " not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the \"@NgModule.declarations\".", sourceSpan); |
| }); |
| }; |
| TemplateParseVisitor.prototype._assertAllEventsPublishedByDirectives = function (directives, events) { |
| var _this = this; |
| var allDirectiveEvents = new Set(); |
| directives.forEach(function (directive) { |
| Object.keys(directive.directive.outputs).forEach(function (k) { |
| var eventName = directive.directive.outputs[k]; |
| allDirectiveEvents.add(eventName); |
| }); |
| }); |
| events.forEach(function (event) { |
| if (event.target != null || !allDirectiveEvents.has(event.name)) { |
| _this._reportError("Event binding " + event |
| .fullName + " not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the \"@NgModule.declarations\".", event.sourceSpan); |
| } |
| }); |
| }; |
| TemplateParseVisitor.prototype._checkPropertiesInSchema = function (elementName, boundProps) { |
| var _this = this; |
| // Note: We can't filter out empty expressions before this method, |
| // as we still want to validate them! |
| return boundProps.filter(function (boundProp) { |
| if (boundProp.type === 0 /* Property */ && |
| !_this._schemaRegistry.hasProperty(elementName, boundProp.name, _this._schemas)) { |
| var errorMsg = "Can't bind to '" + boundProp.name + "' since it isn't a known property of '" + elementName + "'."; |
| if (elementName.startsWith('ng-')) { |
| errorMsg += |
| "\n1. If '" + boundProp |
| .name + "' is an Angular directive, then add 'CommonModule' to the '@NgModule.imports' of this component." + |
| "\n2. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component."; |
| } |
| else if (elementName.indexOf('-') > -1) { |
| errorMsg += |
| "\n1. If '" + elementName + "' is an Angular component and it has '" + boundProp.name + "' input, then verify that it is part of this module." + |
| ("\n2. If '" + elementName + "' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.") + |
| "\n3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component."; |
| } |
| _this._reportError(errorMsg, boundProp.sourceSpan); |
| } |
| return !isEmptyExpression(boundProp.value); |
| }); |
| }; |
| TemplateParseVisitor.prototype._reportError = function (message, sourceSpan, level) { |
| if (level === void 0) { level = exports.ParseErrorLevel.ERROR; } |
| this._targetErrors.push(new ParseError(sourceSpan, message, level)); |
| }; |
| return TemplateParseVisitor; |
| }()); |
| var NonBindableVisitor = /** @class */ (function () { |
| function NonBindableVisitor() { |
| } |
| NonBindableVisitor.prototype.visitElement = function (ast, parent) { |
| var preparsedElement = preparseElement(ast); |
| if (preparsedElement.type === PreparsedElementType.SCRIPT || |
| preparsedElement.type === PreparsedElementType.STYLE || |
| preparsedElement.type === PreparsedElementType.STYLESHEET) { |
| // Skipping <script> for security reasons |
| // Skipping <style> and stylesheets as we already processed them |
| // in the StyleCompiler |
| return null; |
| } |
| var attrNameAndValues = ast.attrs.map(function (attr) { return [attr.name, attr.value]; }); |
| var selector = createElementCssSelector(ast.name, attrNameAndValues); |
| var ngContentIndex = parent.findNgContentIndex(selector); |
| var children = visitAll$1(this, ast.children, EMPTY_ELEMENT_CONTEXT); |
| return new ElementAst(ast.name, visitAll$1(this, ast.attrs), [], [], [], [], [], false, [], children, ngContentIndex, ast.sourceSpan, ast.endSourceSpan); |
| }; |
| NonBindableVisitor.prototype.visitComment = function (comment, context) { |
| return null; |
| }; |
| NonBindableVisitor.prototype.visitAttribute = function (attribute, context) { |
| return new AttrAst(attribute.name, attribute.value, attribute.sourceSpan); |
| }; |
| NonBindableVisitor.prototype.visitText = function (text, parent) { |
| var ngContentIndex = parent.findNgContentIndex(TEXT_CSS_SELECTOR()); |
| return new TextAst(text.value, ngContentIndex, text.sourceSpan); |
| }; |
| NonBindableVisitor.prototype.visitExpansion = function (expansion, context) { |
| return expansion; |
| }; |
| NonBindableVisitor.prototype.visitExpansionCase = function (expansionCase, context) { |
| return expansionCase; |
| }; |
| return NonBindableVisitor; |
| }()); |
| /** |
| * A reference to an element or directive in a template. E.g., the reference in this template: |
| * |
| * <div #myMenu="coolMenu"> |
| * |
| * would be {name: 'myMenu', value: 'coolMenu', sourceSpan: ...} |
| */ |
| var ElementOrDirectiveRef = /** @class */ (function () { |
| function ElementOrDirectiveRef(name, value, sourceSpan) { |
| this.name = name; |
| this.value = value; |
| this.sourceSpan = sourceSpan; |
| } |
| /** Gets whether this is a reference to the given directive. */ |
| ElementOrDirectiveRef.prototype.isReferenceToDirective = function (directive) { |
| return splitExportAs(directive.exportAs).indexOf(this.value) !== -1; |
| }; |
| return ElementOrDirectiveRef; |
| }()); |
| /** Splits a raw, potentially comma-delimited `exportAs` value into an array of names. */ |
| function splitExportAs(exportAs) { |
| return exportAs ? exportAs.split(',').map(function (e) { return e.trim(); }) : []; |
| } |
| function splitClasses(classAttrValue) { |
| return classAttrValue.trim().split(/\s+/g); |
| } |
| var ElementContext = /** @class */ (function () { |
| function ElementContext(isTemplateElement, _ngContentIndexMatcher, _wildcardNgContentIndex, providerContext) { |
| this.isTemplateElement = isTemplateElement; |
| this._ngContentIndexMatcher = _ngContentIndexMatcher; |
| this._wildcardNgContentIndex = _wildcardNgContentIndex; |
| this.providerContext = providerContext; |
| } |
| ElementContext.create = function (isTemplateElement, directives, providerContext) { |
| var matcher = new SelectorMatcher(); |
| var wildcardNgContentIndex = null; |
| var component = directives.find(function (directive) { return directive.directive.isComponent; }); |
| if (component) { |
| var ngContentSelectors = component.directive.template.ngContentSelectors; |
| for (var i = 0; i < ngContentSelectors.length; i++) { |
| var selector = ngContentSelectors[i]; |
| if (selector === '*') { |
| wildcardNgContentIndex = i; |
| } |
| else { |
| matcher.addSelectables(CssSelector.parse(ngContentSelectors[i]), i); |
| } |
| } |
| } |
| return new ElementContext(isTemplateElement, matcher, wildcardNgContentIndex, providerContext); |
| }; |
| ElementContext.prototype.findNgContentIndex = function (selector) { |
| var ngContentIndices = []; |
| this._ngContentIndexMatcher.match(selector, function (selector, ngContentIndex) { |
| ngContentIndices.push(ngContentIndex); |
| }); |
| ngContentIndices.sort(); |
| if (this._wildcardNgContentIndex != null) { |
| ngContentIndices.push(this._wildcardNgContentIndex); |
| } |
| return ngContentIndices.length > 0 ? ngContentIndices[0] : null; |
| }; |
| return ElementContext; |
| }()); |
| function createElementCssSelector(elementName, attributes) { |
| var cssSelector = new CssSelector(); |
| var elNameNoNs = splitNsName(elementName)[1]; |
| cssSelector.setElement(elNameNoNs); |
| for (var i = 0; i < attributes.length; i++) { |
| var attrName = attributes[i][0]; |
| var attrNameNoNs = splitNsName(attrName)[1]; |
| var attrValue = attributes[i][1]; |
| cssSelector.addAttribute(attrNameNoNs, attrValue); |
| if (attrName.toLowerCase() == CLASS_ATTR) { |
| var classes = splitClasses(attrValue); |
| classes.forEach(function (className) { return cssSelector.addClassName(className); }); |
| } |
| } |
| return cssSelector; |
| } |
| var EMPTY_ELEMENT_CONTEXT = new ElementContext(true, new SelectorMatcher(), null, null); |
| var NON_BINDABLE_VISITOR = new NonBindableVisitor(); |
| function _isEmptyTextNode(node) { |
| return node instanceof Text$3 && node.value.trim().length == 0; |
| } |
| function removeSummaryDuplicates(items) { |
| var map = new Map(); |
| items.forEach(function (item) { |
| if (!map.get(item.type.reference)) { |
| map.set(item.type.reference, item); |
| } |
| }); |
| return Array.from(map.values()); |
| } |
| function isEmptyExpression(ast) { |
| if (ast instanceof ASTWithSource) { |
| ast = ast.ast; |
| } |
| return ast instanceof EmptyExpr; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Parses string representation of a style and converts it into object literal. |
| * |
| * @param value string representation of style as used in the `style` attribute in HTML. |
| * Example: `color: red; height: auto`. |
| * @returns An array of style property name and value pairs, e.g. `['color', 'red', 'height', |
| * 'auto']` |
| */ |
| function parse(value) { |
| // we use a string array here instead of a string map |
| // because a string-map is not guaranteed to retain the |
| // order of the entries whereas a string array can be |
| // constructed in a [key, value, key, value] format. |
| var styles = []; |
| var i = 0; |
| var parenDepth = 0; |
| var quote = 0 /* QuoteNone */; |
| var valueStart = 0; |
| var propStart = 0; |
| var currentProp = null; |
| var valueHasQuotes = false; |
| while (i < value.length) { |
| var token = value.charCodeAt(i++); |
| switch (token) { |
| case 40 /* OpenParen */: |
| parenDepth++; |
| break; |
| case 41 /* CloseParen */: |
| parenDepth--; |
| break; |
| case 39 /* QuoteSingle */: |
| // valueStart needs to be there since prop values don't |
| // have quotes in CSS |
| valueHasQuotes = valueHasQuotes || valueStart > 0; |
| if (quote === 0 /* QuoteNone */) { |
| quote = 39 /* QuoteSingle */; |
| } |
| else if (quote === 39 /* QuoteSingle */ && value.charCodeAt(i - 1) !== 92 /* BackSlash */) { |
| quote = 0 /* QuoteNone */; |
| } |
| break; |
| case 34 /* QuoteDouble */: |
| // same logic as above |
| valueHasQuotes = valueHasQuotes || valueStart > 0; |
| if (quote === 0 /* QuoteNone */) { |
| quote = 34 /* QuoteDouble */; |
| } |
| else if (quote === 34 /* QuoteDouble */ && value.charCodeAt(i - 1) !== 92 /* BackSlash */) { |
| quote = 0 /* QuoteNone */; |
| } |
| break; |
| case 58 /* Colon */: |
| if (!currentProp && parenDepth === 0 && quote === 0 /* QuoteNone */) { |
| currentProp = hyphenate(value.substring(propStart, i - 1).trim()); |
| valueStart = i; |
| } |
| break; |
| case 59 /* Semicolon */: |
| if (currentProp && valueStart > 0 && parenDepth === 0 && quote === 0 /* QuoteNone */) { |
| var styleVal = value.substring(valueStart, i - 1).trim(); |
| styles.push(currentProp, valueHasQuotes ? stripUnnecessaryQuotes(styleVal) : styleVal); |
| propStart = i; |
| valueStart = 0; |
| currentProp = null; |
| valueHasQuotes = false; |
| } |
| break; |
| } |
| } |
| if (currentProp && valueStart) { |
| var styleVal = value.substr(valueStart).trim(); |
| styles.push(currentProp, valueHasQuotes ? stripUnnecessaryQuotes(styleVal) : styleVal); |
| } |
| return styles; |
| } |
| function stripUnnecessaryQuotes(value) { |
| var qS = value.charCodeAt(0); |
| var qE = value.charCodeAt(value.length - 1); |
| if (qS == qE && (qS == 39 /* QuoteSingle */ || qS == 34 /* QuoteDouble */)) { |
| var tempValue = value.substring(1, value.length - 1); |
| // special case to avoid using a multi-quoted string that was just chomped |
| // (e.g. `font-family: "Verdana", "sans-serif"`) |
| if (tempValue.indexOf('\'') == -1 && tempValue.indexOf('"') == -1) { |
| value = tempValue; |
| } |
| } |
| return value; |
| } |
| function hyphenate(value) { |
| return value |
| .replace(/[a-z][A-Z]/g, function (v) { |
| return v.charAt(0) + '-' + v.charAt(1); |
| }) |
| .toLowerCase(); |
| } |
| |
| var IMPORTANT_FLAG = '!important'; |
| /** |
| * Minimum amount of binding slots required in the runtime for style/class bindings. |
| * |
| * Styling in Angular uses up two slots in the runtime LView/TData data structures to |
| * record binding data, property information and metadata. |
| * |
| * When a binding is registered it will place the following information in the `LView`: |
| * |
| * slot 1) binding value |
| * slot 2) cached value (all other values collected before it in string form) |
| * |
| * When a binding is registered it will place the following information in the `TData`: |
| * |
| * slot 1) prop name |
| * slot 2) binding index that points to the previous style/class binding (and some extra config |
| * values) |
| * |
| * Let's imagine we have a binding that looks like so: |
| * |
| * ``` |
| * <div [style.width]="x" [style.height]="y"> |
| * ``` |
| * |
| * Our `LView` and `TData` data-structures look like so: |
| * |
| * ```typescript |
| * LView = [ |
| * // ... |
| * x, // value of x |
| * "width: x", |
| * |
| * y, // value of y |
| * "width: x; height: y", |
| * // ... |
| * ]; |
| * |
| * TData = [ |
| * // ... |
| * "width", // binding slot 20 |
| * 0, |
| * |
| * "height", |
| * 20, |
| * // ... |
| * ]; |
| * ``` |
| * |
| * */ |
| var MIN_STYLING_BINDING_SLOTS_REQUIRED = 2; |
| /** |
| * Produces creation/update instructions for all styling bindings (class and style) |
| * |
| * It also produces the creation instruction to register all initial styling values |
| * (which are all the static class="..." and style="..." attribute values that exist |
| * on an element within a template). |
| * |
| * The builder class below handles producing instructions for the following cases: |
| * |
| * - Static style/class attributes (style="..." and class="...") |
| * - Dynamic style/class map bindings ([style]="map" and [class]="map|string") |
| * - Dynamic style/class property bindings ([style.prop]="exp" and [class.name]="exp") |
| * |
| * Due to the complex relationship of all of these cases, the instructions generated |
| * for these attributes/properties/bindings must be done so in the correct order. The |
| * order which these must be generated is as follows: |
| * |
| * if (createMode) { |
| * styling(...) |
| * } |
| * if (updateMode) { |
| * styleMap(...) |
| * classMap(...) |
| * styleProp(...) |
| * classProp(...) |
| * } |
| * |
| * The creation/update methods within the builder class produce these instructions. |
| */ |
| var StylingBuilder = /** @class */ (function () { |
| function StylingBuilder(_directiveExpr) { |
| this._directiveExpr = _directiveExpr; |
| /** Whether or not there are any static styling values present */ |
| this._hasInitialValues = false; |
| /** |
| * Whether or not there are any styling bindings present |
| * (i.e. `[style]`, `[class]`, `[style.prop]` or `[class.name]`) |
| */ |
| this.hasBindings = false; |
| this.hasBindingsWithPipes = false; |
| /** the input for [class] (if it exists) */ |
| this._classMapInput = null; |
| /** the input for [style] (if it exists) */ |
| this._styleMapInput = null; |
| /** an array of each [style.prop] input */ |
| this._singleStyleInputs = null; |
| /** an array of each [class.name] input */ |
| this._singleClassInputs = null; |
| this._lastStylingInput = null; |
| this._firstStylingInput = null; |
| // maps are used instead of hash maps because a Map will |
| // retain the ordering of the keys |
| /** |
| * Represents the location of each style binding in the template |
| * (e.g. `<div [style.width]="w" [style.height]="h">` implies |
| * that `width=0` and `height=1`) |
| */ |
| this._stylesIndex = new Map(); |
| /** |
| * Represents the location of each class binding in the template |
| * (e.g. `<div [class.big]="b" [class.hidden]="h">` implies |
| * that `big=0` and `hidden=1`) |
| */ |
| this._classesIndex = new Map(); |
| this._initialStyleValues = []; |
| this._initialClassValues = []; |
| } |
| /** |
| * Registers a given input to the styling builder to be later used when producing AOT code. |
| * |
| * The code below will only accept the input if it is somehow tied to styling (whether it be |
| * style/class bindings or static style/class attributes). |
| */ |
| StylingBuilder.prototype.registerBoundInput = function (input) { |
| // [attr.style] or [attr.class] are skipped in the code below, |
| // they should not be treated as styling-based bindings since |
| // they are intended to be written directly to the attr and |
| // will therefore skip all style/class resolution that is present |
| // with style="", [style]="" and [style.prop]="", class="", |
| // [class.prop]="". [class]="" assignments |
| var binding = null; |
| var name = input.name; |
| switch (input.type) { |
| case 0 /* Property */: |
| binding = this.registerInputBasedOnName(name, input.value, input.sourceSpan); |
| break; |
| case 3 /* Style */: |
| binding = this.registerStyleInput(name, false, input.value, input.sourceSpan, input.unit); |
| break; |
| case 2 /* Class */: |
| binding = this.registerClassInput(name, false, input.value, input.sourceSpan); |
| break; |
| } |
| return binding ? true : false; |
| }; |
| StylingBuilder.prototype.registerInputBasedOnName = function (name, expression, sourceSpan) { |
| var binding = null; |
| var prefix = name.substring(0, 6); |
| var isStyle = name === 'style' || prefix === 'style.' || prefix === 'style!'; |
| var isClass = !isStyle && (name === 'class' || prefix === 'class.' || prefix === 'class!'); |
| if (isStyle || isClass) { |
| var isMapBased = name.charAt(5) !== '.'; // style.prop or class.prop makes this a no |
| var property = name.substr(isMapBased ? 5 : 6); // the dot explains why there's a +1 |
| if (isStyle) { |
| binding = this.registerStyleInput(property, isMapBased, expression, sourceSpan); |
| } |
| else { |
| binding = this.registerClassInput(property, isMapBased, expression, sourceSpan); |
| } |
| } |
| return binding; |
| }; |
| StylingBuilder.prototype.registerStyleInput = function (name, isMapBased, value, sourceSpan, suffix) { |
| if (isEmptyExpression(value)) { |
| return null; |
| } |
| // CSS custom properties are case-sensitive so we shouldn't normalize them. |
| // See: https://www.w3.org/TR/css-variables-1/#defining-variables |
| if (!isCssCustomProperty(name)) { |
| name = hyphenate(name); |
| } |
| var _a = parseProperty(name), property = _a.property, hasOverrideFlag = _a.hasOverrideFlag, bindingSuffix = _a.suffix; |
| suffix = typeof suffix === 'string' && suffix.length !== 0 ? suffix : bindingSuffix; |
| var entry = { name: property, suffix: suffix, value: value, sourceSpan: sourceSpan, hasOverrideFlag: hasOverrideFlag }; |
| if (isMapBased) { |
| this._styleMapInput = entry; |
| } |
| else { |
| (this._singleStyleInputs = this._singleStyleInputs || []).push(entry); |
| registerIntoMap(this._stylesIndex, property); |
| } |
| this._lastStylingInput = entry; |
| this._firstStylingInput = this._firstStylingInput || entry; |
| this._checkForPipes(value); |
| this.hasBindings = true; |
| return entry; |
| }; |
| StylingBuilder.prototype.registerClassInput = function (name, isMapBased, value, sourceSpan) { |
| if (isEmptyExpression(value)) { |
| return null; |
| } |
| var _a = parseProperty(name), property = _a.property, hasOverrideFlag = _a.hasOverrideFlag; |
| var entry = { name: property, value: value, sourceSpan: sourceSpan, hasOverrideFlag: hasOverrideFlag, suffix: null }; |
| if (isMapBased) { |
| this._classMapInput = entry; |
| } |
| else { |
| (this._singleClassInputs = this._singleClassInputs || []).push(entry); |
| registerIntoMap(this._classesIndex, property); |
| } |
| this._lastStylingInput = entry; |
| this._firstStylingInput = this._firstStylingInput || entry; |
| this._checkForPipes(value); |
| this.hasBindings = true; |
| return entry; |
| }; |
| StylingBuilder.prototype._checkForPipes = function (value) { |
| if ((value instanceof ASTWithSource) && (value.ast instanceof BindingPipe)) { |
| this.hasBindingsWithPipes = true; |
| } |
| }; |
| /** |
| * Registers the element's static style string value to the builder. |
| * |
| * @param value the style string (e.g. `width:100px; height:200px;`) |
| */ |
| StylingBuilder.prototype.registerStyleAttr = function (value) { |
| this._initialStyleValues = parse(value); |
| this._hasInitialValues = true; |
| }; |
| /** |
| * Registers the element's static class string value to the builder. |
| * |
| * @param value the className string (e.g. `disabled gold zoom`) |
| */ |
| StylingBuilder.prototype.registerClassAttr = function (value) { |
| this._initialClassValues = value.trim().split(/\s+/g); |
| this._hasInitialValues = true; |
| }; |
| /** |
| * Appends all styling-related expressions to the provided attrs array. |
| * |
| * @param attrs an existing array where each of the styling expressions |
| * will be inserted into. |
| */ |
| StylingBuilder.prototype.populateInitialStylingAttrs = function (attrs) { |
| // [CLASS_MARKER, 'foo', 'bar', 'baz' ...] |
| if (this._initialClassValues.length) { |
| attrs.push(literal(1 /* Classes */)); |
| for (var i = 0; i < this._initialClassValues.length; i++) { |
| attrs.push(literal(this._initialClassValues[i])); |
| } |
| } |
| // [STYLE_MARKER, 'width', '200px', 'height', '100px', ...] |
| if (this._initialStyleValues.length) { |
| attrs.push(literal(2 /* Styles */)); |
| for (var i = 0; i < this._initialStyleValues.length; i += 2) { |
| attrs.push(literal(this._initialStyleValues[i]), literal(this._initialStyleValues[i + 1])); |
| } |
| } |
| }; |
| /** |
| * Builds an instruction with all the expressions and parameters for `elementHostAttrs`. |
| * |
| * The instruction generation code below is used for producing the AOT statement code which is |
| * responsible for registering initial styles (within a directive hostBindings' creation block), |
| * as well as any of the provided attribute values, to the directive host element. |
| */ |
| StylingBuilder.prototype.assignHostAttrs = function (attrs, definitionMap) { |
| if (this._directiveExpr && (attrs.length || this._hasInitialValues)) { |
| this.populateInitialStylingAttrs(attrs); |
| definitionMap.set('hostAttrs', literalArr(attrs)); |
| } |
| }; |
| /** |
| * Builds an instruction with all the expressions and parameters for `classMap`. |
| * |
| * The instruction data will contain all expressions for `classMap` to function |
| * which includes the `[class]` expression params. |
| */ |
| StylingBuilder.prototype.buildClassMapInstruction = function (valueConverter) { |
| if (this._classMapInput) { |
| return this._buildMapBasedInstruction(valueConverter, true, this._classMapInput); |
| } |
| return null; |
| }; |
| /** |
| * Builds an instruction with all the expressions and parameters for `styleMap`. |
| * |
| * The instruction data will contain all expressions for `styleMap` to function |
| * which includes the `[style]` expression params. |
| */ |
| StylingBuilder.prototype.buildStyleMapInstruction = function (valueConverter) { |
| if (this._styleMapInput) { |
| return this._buildMapBasedInstruction(valueConverter, false, this._styleMapInput); |
| } |
| return null; |
| }; |
| StylingBuilder.prototype._buildMapBasedInstruction = function (valueConverter, isClassBased, stylingInput) { |
| // each styling binding value is stored in the LView |
| // map-based bindings allocate two slots: one for the |
| // previous binding value and another for the previous |
| // className or style attribute value. |
| var totalBindingSlotsRequired = MIN_STYLING_BINDING_SLOTS_REQUIRED; |
| // these values must be outside of the update block so that they can |
| // be evaluated (the AST visit call) during creation time so that any |
| // pipes can be picked up in time before the template is built |
| var mapValue = stylingInput.value.visit(valueConverter); |
| var reference; |
| if (mapValue instanceof Interpolation) { |
| totalBindingSlotsRequired += mapValue.expressions.length; |
| reference = isClassBased ? getClassMapInterpolationExpression(mapValue) : |
| getStyleMapInterpolationExpression(mapValue); |
| } |
| else { |
| reference = isClassBased ? Identifiers$1.classMap : Identifiers$1.styleMap; |
| } |
| return { |
| reference: reference, |
| calls: [{ |
| supportsInterpolation: true, |
| sourceSpan: stylingInput.sourceSpan, |
| allocateBindingSlots: totalBindingSlotsRequired, |
| params: function (convertFn) { |
| var convertResult = convertFn(mapValue); |
| var params = Array.isArray(convertResult) ? convertResult : [convertResult]; |
| return params; |
| } |
| }] |
| }; |
| }; |
| StylingBuilder.prototype._buildSingleInputs = function (reference, inputs, valueConverter, getInterpolationExpressionFn, isClassBased) { |
| var instructions = []; |
| inputs.forEach(function (input) { |
| var previousInstruction = instructions[instructions.length - 1]; |
| var value = input.value.visit(valueConverter); |
| var referenceForCall = reference; |
| // each styling binding value is stored in the LView |
| // but there are two values stored for each binding: |
| // 1) the value itself |
| // 2) an intermediate value (concatenation of style up to this point). |
| // We need to store the intermediate value so that we don't allocate |
| // the strings on each CD. |
| var totalBindingSlotsRequired = MIN_STYLING_BINDING_SLOTS_REQUIRED; |
| if (value instanceof Interpolation) { |
| totalBindingSlotsRequired += value.expressions.length; |
| if (getInterpolationExpressionFn) { |
| referenceForCall = getInterpolationExpressionFn(value); |
| } |
| } |
| var call = { |
| sourceSpan: input.sourceSpan, |
| allocateBindingSlots: totalBindingSlotsRequired, |
| supportsInterpolation: !!getInterpolationExpressionFn, |
| params: function (convertFn) { |
| // params => stylingProp(propName, value, suffix) |
| var params = []; |
| params.push(literal(input.name)); |
| var convertResult = convertFn(value); |
| if (Array.isArray(convertResult)) { |
| params.push.apply(params, __spread(convertResult)); |
| } |
| else { |
| params.push(convertResult); |
| } |
| // [style.prop] bindings may use suffix values (e.g. px, em, etc...), therefore, |
| // if that is detected then we need to pass that in as an optional param. |
| if (!isClassBased && input.suffix !== null) { |
| params.push(literal(input.suffix)); |
| } |
| return params; |
| } |
| }; |
| // If we ended up generating a call to the same instruction as the previous styling property |
| // we can chain the calls together safely to save some bytes, otherwise we have to generate |
| // a separate instruction call. This is primarily a concern with interpolation instructions |
| // where we may start off with one `reference`, but end up using another based on the |
| // number of interpolations. |
| if (previousInstruction && previousInstruction.reference === referenceForCall) { |
| previousInstruction.calls.push(call); |
| } |
| else { |
| instructions.push({ reference: referenceForCall, calls: [call] }); |
| } |
| }); |
| return instructions; |
| }; |
| StylingBuilder.prototype._buildClassInputs = function (valueConverter) { |
| if (this._singleClassInputs) { |
| return this._buildSingleInputs(Identifiers$1.classProp, this._singleClassInputs, valueConverter, null, true); |
| } |
| return []; |
| }; |
| StylingBuilder.prototype._buildStyleInputs = function (valueConverter) { |
| if (this._singleStyleInputs) { |
| return this._buildSingleInputs(Identifiers$1.styleProp, this._singleStyleInputs, valueConverter, getStylePropInterpolationExpression, false); |
| } |
| return []; |
| }; |
| /** |
| * Constructs all instructions which contain the expressions that will be placed |
| * into the update block of a template function or a directive hostBindings function. |
| */ |
| StylingBuilder.prototype.buildUpdateLevelInstructions = function (valueConverter) { |
| var instructions = []; |
| if (this.hasBindings) { |
| var styleMapInstruction = this.buildStyleMapInstruction(valueConverter); |
| if (styleMapInstruction) { |
| instructions.push(styleMapInstruction); |
| } |
| var classMapInstruction = this.buildClassMapInstruction(valueConverter); |
| if (classMapInstruction) { |
| instructions.push(classMapInstruction); |
| } |
| instructions.push.apply(instructions, __spread(this._buildStyleInputs(valueConverter))); |
| instructions.push.apply(instructions, __spread(this._buildClassInputs(valueConverter))); |
| } |
| return instructions; |
| }; |
| return StylingBuilder; |
| }()); |
| function registerIntoMap(map, key) { |
| if (!map.has(key)) { |
| map.set(key, map.size); |
| } |
| } |
| function parseProperty(name) { |
| var hasOverrideFlag = false; |
| var overrideIndex = name.indexOf(IMPORTANT_FLAG); |
| if (overrideIndex !== -1) { |
| name = overrideIndex > 0 ? name.substring(0, overrideIndex) : ''; |
| hasOverrideFlag = true; |
| } |
| var suffix = null; |
| var property = name; |
| var unitIndex = name.lastIndexOf('.'); |
| if (unitIndex > 0) { |
| suffix = name.substr(unitIndex + 1); |
| property = name.substring(0, unitIndex); |
| } |
| return { property: property, suffix: suffix, hasOverrideFlag: hasOverrideFlag }; |
| } |
| /** |
| * Gets the instruction to generate for an interpolated class map. |
| * @param interpolation An Interpolation AST |
| */ |
| function getClassMapInterpolationExpression(interpolation) { |
| switch (getInterpolationArgsLength(interpolation)) { |
| case 1: |
| return Identifiers$1.classMap; |
| case 3: |
| return Identifiers$1.classMapInterpolate1; |
| case 5: |
| return Identifiers$1.classMapInterpolate2; |
| case 7: |
| return Identifiers$1.classMapInterpolate3; |
| case 9: |
| return Identifiers$1.classMapInterpolate4; |
| case 11: |
| return Identifiers$1.classMapInterpolate5; |
| case 13: |
| return Identifiers$1.classMapInterpolate6; |
| case 15: |
| return Identifiers$1.classMapInterpolate7; |
| case 17: |
| return Identifiers$1.classMapInterpolate8; |
| default: |
| return Identifiers$1.classMapInterpolateV; |
| } |
| } |
| /** |
| * Gets the instruction to generate for an interpolated style map. |
| * @param interpolation An Interpolation AST |
| */ |
| function getStyleMapInterpolationExpression(interpolation) { |
| switch (getInterpolationArgsLength(interpolation)) { |
| case 1: |
| return Identifiers$1.styleMap; |
| case 3: |
| return Identifiers$1.styleMapInterpolate1; |
| case 5: |
| return Identifiers$1.styleMapInterpolate2; |
| case 7: |
| return Identifiers$1.styleMapInterpolate3; |
| case 9: |
| return Identifiers$1.styleMapInterpolate4; |
| case 11: |
| return Identifiers$1.styleMapInterpolate5; |
| case 13: |
| return Identifiers$1.styleMapInterpolate6; |
| case 15: |
| return Identifiers$1.styleMapInterpolate7; |
| case 17: |
| return Identifiers$1.styleMapInterpolate8; |
| default: |
| return Identifiers$1.styleMapInterpolateV; |
| } |
| } |
| /** |
| * Gets the instruction to generate for an interpolated style prop. |
| * @param interpolation An Interpolation AST |
| */ |
| function getStylePropInterpolationExpression(interpolation) { |
| switch (getInterpolationArgsLength(interpolation)) { |
| case 1: |
| return Identifiers$1.styleProp; |
| case 3: |
| return Identifiers$1.stylePropInterpolate1; |
| case 5: |
| return Identifiers$1.stylePropInterpolate2; |
| case 7: |
| return Identifiers$1.stylePropInterpolate3; |
| case 9: |
| return Identifiers$1.stylePropInterpolate4; |
| case 11: |
| return Identifiers$1.stylePropInterpolate5; |
| case 13: |
| return Identifiers$1.stylePropInterpolate6; |
| case 15: |
| return Identifiers$1.stylePropInterpolate7; |
| case 17: |
| return Identifiers$1.stylePropInterpolate8; |
| default: |
| return Identifiers$1.stylePropInterpolateV; |
| } |
| } |
| /** |
| * Checks whether property name is a custom CSS property. |
| * See: https://www.w3.org/TR/css-variables-1 |
| */ |
| function isCssCustomProperty(name) { |
| return name.startsWith('--'); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| (function (TokenType) { |
| TokenType[TokenType["Character"] = 0] = "Character"; |
| TokenType[TokenType["Identifier"] = 1] = "Identifier"; |
| TokenType[TokenType["Keyword"] = 2] = "Keyword"; |
| TokenType[TokenType["String"] = 3] = "String"; |
| TokenType[TokenType["Operator"] = 4] = "Operator"; |
| TokenType[TokenType["Number"] = 5] = "Number"; |
| TokenType[TokenType["Error"] = 6] = "Error"; |
| })(exports.TokenType || (exports.TokenType = {})); |
| var KEYWORDS = ['var', 'let', 'as', 'null', 'undefined', 'true', 'false', 'if', 'else', 'this']; |
| var Lexer = /** @class */ (function () { |
| function Lexer() { |
| } |
| Lexer.prototype.tokenize = function (text) { |
| var scanner = new _Scanner(text); |
| var tokens = []; |
| var token = scanner.scanToken(); |
| while (token != null) { |
| tokens.push(token); |
| token = scanner.scanToken(); |
| } |
| return tokens; |
| }; |
| return Lexer; |
| }()); |
| var Token$1 = /** @class */ (function () { |
| function Token(index, end, type, numValue, strValue) { |
| this.index = index; |
| this.end = end; |
| this.type = type; |
| this.numValue = numValue; |
| this.strValue = strValue; |
| } |
| Token.prototype.isCharacter = function (code) { |
| return this.type == exports.TokenType.Character && this.numValue == code; |
| }; |
| Token.prototype.isNumber = function () { |
| return this.type == exports.TokenType.Number; |
| }; |
| Token.prototype.isString = function () { |
| return this.type == exports.TokenType.String; |
| }; |
| Token.prototype.isOperator = function (operator) { |
| return this.type == exports.TokenType.Operator && this.strValue == operator; |
| }; |
| Token.prototype.isIdentifier = function () { |
| return this.type == exports.TokenType.Identifier; |
| }; |
| Token.prototype.isKeyword = function () { |
| return this.type == exports.TokenType.Keyword; |
| }; |
| Token.prototype.isKeywordLet = function () { |
| return this.type == exports.TokenType.Keyword && this.strValue == 'let'; |
| }; |
| Token.prototype.isKeywordAs = function () { |
| return this.type == exports.TokenType.Keyword && this.strValue == 'as'; |
| }; |
| Token.prototype.isKeywordNull = function () { |
| return this.type == exports.TokenType.Keyword && this.strValue == 'null'; |
| }; |
| Token.prototype.isKeywordUndefined = function () { |
| return this.type == exports.TokenType.Keyword && this.strValue == 'undefined'; |
| }; |
| Token.prototype.isKeywordTrue = function () { |
| return this.type == exports.TokenType.Keyword && this.strValue == 'true'; |
| }; |
| Token.prototype.isKeywordFalse = function () { |
| return this.type == exports.TokenType.Keyword && this.strValue == 'false'; |
| }; |
| Token.prototype.isKeywordThis = function () { |
| return this.type == exports.TokenType.Keyword && this.strValue == 'this'; |
| }; |
| Token.prototype.isError = function () { |
| return this.type == exports.TokenType.Error; |
| }; |
| Token.prototype.toNumber = function () { |
| return this.type == exports.TokenType.Number ? this.numValue : -1; |
| }; |
| Token.prototype.toString = function () { |
| switch (this.type) { |
| case exports.TokenType.Character: |
| case exports.TokenType.Identifier: |
| case exports.TokenType.Keyword: |
| case exports.TokenType.Operator: |
| case exports.TokenType.String: |
| case exports.TokenType.Error: |
| return this.strValue; |
| case exports.TokenType.Number: |
| return this.numValue.toString(); |
| default: |
| return null; |
| } |
| }; |
| return Token; |
| }()); |
| function newCharacterToken(index, end, code) { |
| return new Token$1(index, end, exports.TokenType.Character, code, String.fromCharCode(code)); |
| } |
| function newIdentifierToken(index, end, text) { |
| return new Token$1(index, end, exports.TokenType.Identifier, 0, text); |
| } |
| function newKeywordToken(index, end, text) { |
| return new Token$1(index, end, exports.TokenType.Keyword, 0, text); |
| } |
| function newOperatorToken(index, end, text) { |
| return new Token$1(index, end, exports.TokenType.Operator, 0, text); |
| } |
| function newStringToken(index, end, text) { |
| return new Token$1(index, end, exports.TokenType.String, 0, text); |
| } |
| function newNumberToken(index, end, n) { |
| return new Token$1(index, end, exports.TokenType.Number, n, ''); |
| } |
| function newErrorToken(index, end, message) { |
| return new Token$1(index, end, exports.TokenType.Error, 0, message); |
| } |
| var EOF = new Token$1(-1, -1, exports.TokenType.Character, 0, ''); |
| var _Scanner = /** @class */ (function () { |
| function _Scanner(input) { |
| this.input = input; |
| this.peek = 0; |
| this.index = -1; |
| this.length = input.length; |
| this.advance(); |
| } |
| _Scanner.prototype.advance = function () { |
| this.peek = ++this.index >= this.length ? $EOF : this.input.charCodeAt(this.index); |
| }; |
| _Scanner.prototype.scanToken = function () { |
| var input = this.input, length = this.length; |
| var peek = this.peek, index = this.index; |
| // Skip whitespace. |
| while (peek <= $SPACE) { |
| if (++index >= length) { |
| peek = $EOF; |
| break; |
| } |
| else { |
| peek = input.charCodeAt(index); |
| } |
| } |
| this.peek = peek; |
| this.index = index; |
| if (index >= length) { |
| return null; |
| } |
| // Handle identifiers and numbers. |
| if (isIdentifierStart(peek)) |
| return this.scanIdentifier(); |
| if (isDigit(peek)) |
| return this.scanNumber(index); |
| var start = index; |
| switch (peek) { |
| case $PERIOD: |
| this.advance(); |
| return isDigit(this.peek) ? this.scanNumber(start) : |
| newCharacterToken(start, this.index, $PERIOD); |
| case $LPAREN: |
| case $RPAREN: |
| case $LBRACE: |
| case $RBRACE: |
| case $LBRACKET: |
| case $RBRACKET: |
| case $COMMA: |
| case $COLON: |
| case $SEMICOLON: |
| return this.scanCharacter(start, peek); |
| case $SQ: |
| case $DQ: |
| return this.scanString(); |
| case $HASH: |
| case $PLUS: |
| case $MINUS: |
| case $STAR: |
| case $SLASH: |
| case $PERCENT: |
| case $CARET: |
| return this.scanOperator(start, String.fromCharCode(peek)); |
| case $QUESTION: |
| return this.scanComplexOperator(start, '?', $PERIOD, '.'); |
| case $LT: |
| case $GT: |
| return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '='); |
| case $BANG: |
| case $EQ: |
| return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '=', $EQ, '='); |
| case $AMPERSAND: |
| return this.scanComplexOperator(start, '&', $AMPERSAND, '&'); |
| case $BAR: |
| return this.scanComplexOperator(start, '|', $BAR, '|'); |
| case $NBSP: |
| while (isWhitespace(this.peek)) |
| this.advance(); |
| return this.scanToken(); |
| } |
| this.advance(); |
| return this.error("Unexpected character [" + String.fromCharCode(peek) + "]", 0); |
| }; |
| _Scanner.prototype.scanCharacter = function (start, code) { |
| this.advance(); |
| return newCharacterToken(start, this.index, code); |
| }; |
| _Scanner.prototype.scanOperator = function (start, str) { |
| this.advance(); |
| return newOperatorToken(start, this.index, str); |
| }; |
| /** |
| * Tokenize a 2/3 char long operator |
| * |
| * @param start start index in the expression |
| * @param one first symbol (always part of the operator) |
| * @param twoCode code point for the second symbol |
| * @param two second symbol (part of the operator when the second code point matches) |
| * @param threeCode code point for the third symbol |
| * @param three third symbol (part of the operator when provided and matches source expression) |
| */ |
| _Scanner.prototype.scanComplexOperator = function (start, one, twoCode, two, threeCode, three) { |
| this.advance(); |
| var str = one; |
| if (this.peek == twoCode) { |
| this.advance(); |
| str += two; |
| } |
| if (threeCode != null && this.peek == threeCode) { |
| this.advance(); |
| str += three; |
| } |
| return newOperatorToken(start, this.index, str); |
| }; |
| _Scanner.prototype.scanIdentifier = function () { |
| var start = this.index; |
| this.advance(); |
| while (isIdentifierPart(this.peek)) |
| this.advance(); |
| var str = this.input.substring(start, this.index); |
| return KEYWORDS.indexOf(str) > -1 ? newKeywordToken(start, this.index, str) : |
| newIdentifierToken(start, this.index, str); |
| }; |
| _Scanner.prototype.scanNumber = function (start) { |
| var simple = (this.index === start); |
| this.advance(); // Skip initial digit. |
| while (true) { |
| if (isDigit(this.peek)) { |
| // Do nothing. |
| } |
| else if (this.peek == $PERIOD) { |
| simple = false; |
| } |
| else if (isExponentStart(this.peek)) { |
| this.advance(); |
| if (isExponentSign(this.peek)) |
| this.advance(); |
| if (!isDigit(this.peek)) |
| return this.error('Invalid exponent', -1); |
| simple = false; |
| } |
| else { |
| break; |
| } |
| this.advance(); |
| } |
| var str = this.input.substring(start, this.index); |
| var value = simple ? parseIntAutoRadix(str) : parseFloat(str); |
| return newNumberToken(start, this.index, value); |
| }; |
| _Scanner.prototype.scanString = function () { |
| var start = this.index; |
| var quote = this.peek; |
| this.advance(); // Skip initial quote. |
| var buffer = ''; |
| var marker = this.index; |
| var input = this.input; |
| while (this.peek != quote) { |
| if (this.peek == $BACKSLASH) { |
| buffer += input.substring(marker, this.index); |
| this.advance(); |
| var unescapedCode = void 0; |
| // Workaround for TS2.1-introduced type strictness |
| this.peek = this.peek; |
| if (this.peek == $u) { |
| // 4 character hex code for unicode character. |
| var hex = input.substring(this.index + 1, this.index + 5); |
| if (/^[0-9a-f]+$/i.test(hex)) { |
| unescapedCode = parseInt(hex, 16); |
| } |
| else { |
| return this.error("Invalid unicode escape [\\u" + hex + "]", 0); |
| } |
| for (var i = 0; i < 5; i++) { |
| this.advance(); |
| } |
| } |
| else { |
| unescapedCode = unescape(this.peek); |
| this.advance(); |
| } |
| buffer += String.fromCharCode(unescapedCode); |
| marker = this.index; |
| } |
| else if (this.peek == $EOF) { |
| return this.error('Unterminated quote', 0); |
| } |
| else { |
| this.advance(); |
| } |
| } |
| var last = input.substring(marker, this.index); |
| this.advance(); // Skip terminating quote. |
| return newStringToken(start, this.index, buffer + last); |
| }; |
| _Scanner.prototype.error = function (message, offset) { |
| var position = this.index + offset; |
| return newErrorToken(position, this.index, "Lexer Error: " + message + " at column " + position + " in expression [" + this.input + "]"); |
| }; |
| return _Scanner; |
| }()); |
| function isIdentifierStart(code) { |
| return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || |
| (code == $_) || (code == $$); |
| } |
| function isIdentifier(input) { |
| if (input.length == 0) |
| return false; |
| var scanner = new _Scanner(input); |
| if (!isIdentifierStart(scanner.peek)) |
| return false; |
| scanner.advance(); |
| while (scanner.peek !== $EOF) { |
| if (!isIdentifierPart(scanner.peek)) |
| return false; |
| scanner.advance(); |
| } |
| return true; |
| } |
| function isIdentifierPart(code) { |
| return isAsciiLetter(code) || isDigit(code) || (code == $_) || |
| (code == $$); |
| } |
| function isExponentStart(code) { |
| return code == $e || code == $E; |
| } |
| function isExponentSign(code) { |
| return code == $MINUS || code == $PLUS; |
| } |
| function isQuote(code) { |
| return code === $SQ || code === $DQ || code === $BT; |
| } |
| function unescape(code) { |
| switch (code) { |
| case $n: |
| return $LF; |
| case $f: |
| return $FF; |
| case $r: |
| return $CR; |
| case $t: |
| return $TAB; |
| case $v: |
| return $VTAB; |
| default: |
| return code; |
| } |
| } |
| function parseIntAutoRadix(text) { |
| var result = parseInt(text); |
| if (isNaN(result)) { |
| throw new Error('Invalid integer literal when parsing ' + text); |
| } |
| return result; |
| } |
| |
| var SplitInterpolation = /** @class */ (function () { |
| function SplitInterpolation(strings, expressions, offsets) { |
| this.strings = strings; |
| this.expressions = expressions; |
| this.offsets = offsets; |
| } |
| return SplitInterpolation; |
| }()); |
| var TemplateBindingParseResult = /** @class */ (function () { |
| function TemplateBindingParseResult(templateBindings, warnings, errors) { |
| this.templateBindings = templateBindings; |
| this.warnings = warnings; |
| this.errors = errors; |
| } |
| return TemplateBindingParseResult; |
| }()); |
| var Parser$1 = /** @class */ (function () { |
| function Parser(_lexer) { |
| this._lexer = _lexer; |
| this.errors = []; |
| this.simpleExpressionChecker = SimpleExpressionChecker; |
| } |
| Parser.prototype.parseAction = function (input, location, absoluteOffset, interpolationConfig) { |
| if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } |
| this._checkNoInterpolation(input, location, interpolationConfig); |
| var sourceToLex = this._stripComments(input); |
| var tokens = this._lexer.tokenize(this._stripComments(input)); |
| var ast = new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, true, this.errors, input.length - sourceToLex.length) |
| .parseChain(); |
| return new ASTWithSource(ast, input, location, absoluteOffset, this.errors); |
| }; |
| Parser.prototype.parseBinding = function (input, location, absoluteOffset, interpolationConfig) { |
| if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } |
| var ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig); |
| return new ASTWithSource(ast, input, location, absoluteOffset, this.errors); |
| }; |
| Parser.prototype.checkSimpleExpression = function (ast) { |
| var checker = new this.simpleExpressionChecker(); |
| ast.visit(checker); |
| return checker.errors; |
| }; |
| Parser.prototype.parseSimpleBinding = function (input, location, absoluteOffset, interpolationConfig) { |
| if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } |
| var ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig); |
| var errors = this.checkSimpleExpression(ast); |
| if (errors.length > 0) { |
| this._reportError("Host binding expression cannot contain " + errors.join(' '), input, location); |
| } |
| return new ASTWithSource(ast, input, location, absoluteOffset, this.errors); |
| }; |
| Parser.prototype._reportError = function (message, input, errLocation, ctxLocation) { |
| this.errors.push(new ParserError(message, input, errLocation, ctxLocation)); |
| }; |
| Parser.prototype._parseBindingAst = function (input, location, absoluteOffset, interpolationConfig) { |
| // Quotes expressions use 3rd-party expression language. We don't want to use |
| // our lexer or parser for that, so we check for that ahead of time. |
| var quote = this._parseQuote(input, location, absoluteOffset); |
| if (quote != null) { |
| return quote; |
| } |
| this._checkNoInterpolation(input, location, interpolationConfig); |
| var sourceToLex = this._stripComments(input); |
| var tokens = this._lexer.tokenize(sourceToLex); |
| return new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, false, this.errors, input.length - sourceToLex.length) |
| .parseChain(); |
| }; |
| Parser.prototype._parseQuote = function (input, location, absoluteOffset) { |
| if (input == null) |
| return null; |
| var prefixSeparatorIndex = input.indexOf(':'); |
| if (prefixSeparatorIndex == -1) |
| return null; |
| var prefix = input.substring(0, prefixSeparatorIndex).trim(); |
| if (!isIdentifier(prefix)) |
| return null; |
| var uninterpretedExpression = input.substring(prefixSeparatorIndex + 1); |
| var span = new ParseSpan(0, input.length); |
| return new Quote(span, span.toAbsolute(absoluteOffset), prefix, uninterpretedExpression, location); |
| }; |
| /** |
| * Parse microsyntax template expression and return a list of bindings or |
| * parsing errors in case the given expression is invalid. |
| * |
| * For example, |
| * ``` |
| * <div *ngFor="let item of items"> |
| * ^ ^ absoluteValueOffset for `templateValue` |
| * absoluteKeyOffset for `templateKey` |
| * ``` |
| * contains three bindings: |
| * 1. ngFor -> null |
| * 2. item -> NgForOfContext.$implicit |
| * 3. ngForOf -> items |
| * |
| * This is apparent from the de-sugared template: |
| * ``` |
| * <ng-template ngFor let-item [ngForOf]="items"> |
| * ``` |
| * |
| * @param templateKey name of directive, without the * prefix. For example: ngIf, ngFor |
| * @param templateValue RHS of the microsyntax attribute |
| * @param templateUrl template filename if it's external, component filename if it's inline |
| * @param absoluteKeyOffset start of the `templateKey` |
| * @param absoluteValueOffset start of the `templateValue` |
| */ |
| Parser.prototype.parseTemplateBindings = function (templateKey, templateValue, templateUrl, absoluteKeyOffset, absoluteValueOffset) { |
| var tokens = this._lexer.tokenize(templateValue); |
| var parser = new _ParseAST(templateValue, templateUrl, absoluteValueOffset, tokens, templateValue.length, false /* parseAction */, this.errors, 0 /* relative offset */); |
| return parser.parseTemplateBindings({ |
| source: templateKey, |
| span: new AbsoluteSourceSpan(absoluteKeyOffset, absoluteKeyOffset + templateKey.length), |
| }); |
| }; |
| Parser.prototype.parseInterpolation = function (input, location, absoluteOffset, interpolationConfig) { |
| if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } |
| var _b = this.splitInterpolation(input, location, interpolationConfig), strings = _b.strings, expressions = _b.expressions, offsets = _b.offsets; |
| if (expressions.length === 0) |
| return null; |
| var expressionNodes = []; |
| for (var i = 0; i < expressions.length; ++i) { |
| var expressionText = expressions[i].text; |
| var sourceToLex = this._stripComments(expressionText); |
| var tokens = this._lexer.tokenize(sourceToLex); |
| var ast = new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, false, this.errors, offsets[i] + (expressionText.length - sourceToLex.length)) |
| .parseChain(); |
| expressionNodes.push(ast); |
| } |
| return this.createInterpolationAst(strings.map(function (s) { return s.text; }), expressionNodes, input, location, absoluteOffset); |
| }; |
| /** |
| * Similar to `parseInterpolation`, but treats the provided string as a single expression |
| * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`). |
| * This is used for parsing the switch expression in ICUs. |
| */ |
| Parser.prototype.parseInterpolationExpression = function (expression, location, absoluteOffset) { |
| var sourceToLex = this._stripComments(expression); |
| var tokens = this._lexer.tokenize(sourceToLex); |
| var ast = new _ParseAST(expression, location, absoluteOffset, tokens, sourceToLex.length, |
| /* parseAction */ false, this.errors, 0) |
| .parseChain(); |
| var strings = ['', '']; // The prefix and suffix strings are both empty |
| return this.createInterpolationAst(strings, [ast], expression, location, absoluteOffset); |
| }; |
| Parser.prototype.createInterpolationAst = function (strings, expressions, input, location, absoluteOffset) { |
| var span = new ParseSpan(0, input.length); |
| var interpolation = new Interpolation(span, span.toAbsolute(absoluteOffset), strings, expressions); |
| return new ASTWithSource(interpolation, input, location, absoluteOffset, this.errors); |
| }; |
| /** |
| * Splits a string of text into "raw" text segments and expressions present in interpolations in |
| * the string. |
| * Returns `null` if there are no interpolations, otherwise a |
| * `SplitInterpolation` with splits that look like |
| * <raw text> <expression> <raw text> ... <raw text> <expression> <raw text> |
| */ |
| Parser.prototype.splitInterpolation = function (input, location, interpolationConfig) { |
| if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } |
| var strings = []; |
| var expressions = []; |
| var offsets = []; |
| var i = 0; |
| var atInterpolation = false; |
| var extendLastString = false; |
| var interpStart = interpolationConfig.start, interpEnd = interpolationConfig.end; |
| while (i < input.length) { |
| if (!atInterpolation) { |
| // parse until starting {{ |
| var start = i; |
| i = input.indexOf(interpStart, i); |
| if (i === -1) { |
| i = input.length; |
| } |
| var text = input.substring(start, i); |
| strings.push({ text: text, start: start, end: i }); |
| atInterpolation = true; |
| } |
| else { |
| // parse from starting {{ to ending }} while ignoring content inside quotes. |
| var fullStart = i; |
| var exprStart = fullStart + interpStart.length; |
| var exprEnd = this._getInterpolationEndIndex(input, interpEnd, exprStart); |
| if (exprEnd === -1) { |
| // Could not find the end of the interpolation; do not parse an expression. |
| // Instead we should extend the content on the last raw string. |
| atInterpolation = false; |
| extendLastString = true; |
| break; |
| } |
| var fullEnd = exprEnd + interpEnd.length; |
| var text = input.substring(exprStart, exprEnd); |
| if (text.trim().length === 0) { |
| this._reportError('Blank expressions are not allowed in interpolated strings', input, "at column " + i + " in", location); |
| } |
| expressions.push({ text: text, start: fullStart, end: fullEnd }); |
| offsets.push(exprStart); |
| i = fullEnd; |
| atInterpolation = false; |
| } |
| } |
| if (!atInterpolation) { |
| // If we are now at a text section, add the remaining content as a raw string. |
| if (extendLastString) { |
| var piece = strings[strings.length - 1]; |
| piece.text += input.substring(i); |
| piece.end = input.length; |
| } |
| else { |
| strings.push({ text: input.substring(i), start: i, end: input.length }); |
| } |
| } |
| return new SplitInterpolation(strings, expressions, offsets); |
| }; |
| Parser.prototype.wrapLiteralPrimitive = function (input, location, absoluteOffset) { |
| var span = new ParseSpan(0, input == null ? 0 : input.length); |
| return new ASTWithSource(new LiteralPrimitive(span, span.toAbsolute(absoluteOffset), input), input, location, absoluteOffset, this.errors); |
| }; |
| Parser.prototype._stripComments = function (input) { |
| var i = this._commentStart(input); |
| return i != null ? input.substring(0, i).trim() : input; |
| }; |
| Parser.prototype._commentStart = function (input) { |
| var outerQuote = null; |
| for (var i = 0; i < input.length - 1; i++) { |
| var char = input.charCodeAt(i); |
| var nextChar = input.charCodeAt(i + 1); |
| if (char === $SLASH && nextChar == $SLASH && outerQuote == null) |
| return i; |
| if (outerQuote === char) { |
| outerQuote = null; |
| } |
| else if (outerQuote == null && isQuote(char)) { |
| outerQuote = char; |
| } |
| } |
| return null; |
| }; |
| Parser.prototype._checkNoInterpolation = function (input, location, _b) { |
| var e_1, _c; |
| var start = _b.start, end = _b.end; |
| var startIndex = -1; |
| var endIndex = -1; |
| try { |
| for (var _d = __values(this._forEachUnquotedChar(input, 0)), _e = _d.next(); !_e.done; _e = _d.next()) { |
| var charIndex = _e.value; |
| if (startIndex === -1) { |
| if (input.startsWith(start)) { |
| startIndex = charIndex; |
| } |
| } |
| else { |
| endIndex = this._getInterpolationEndIndex(input, end, charIndex); |
| if (endIndex > -1) { |
| break; |
| } |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_e && !_e.done && (_c = _d.return)) _c.call(_d); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| if (startIndex > -1 && endIndex > -1) { |
| this._reportError("Got interpolation (" + start + end + ") where expression was expected", input, "at column " + startIndex + " in", location); |
| } |
| }; |
| /** |
| * Finds the index of the end of an interpolation expression |
| * while ignoring comments and quoted content. |
| */ |
| Parser.prototype._getInterpolationEndIndex = function (input, expressionEnd, start) { |
| var e_2, _b; |
| try { |
| for (var _c = __values(this._forEachUnquotedChar(input, start)), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var charIndex = _d.value; |
| if (input.startsWith(expressionEnd, charIndex)) { |
| return charIndex; |
| } |
| // Nothing else in the expression matters after we've |
| // hit a comment so look directly for the end token. |
| if (input.startsWith('//', charIndex)) { |
| return input.indexOf(expressionEnd, charIndex); |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_b = _c.return)) _b.call(_c); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| return -1; |
| }; |
| /** |
| * Generator used to iterate over the character indexes of a string that are outside of quotes. |
| * @param input String to loop through. |
| * @param start Index within the string at which to start. |
| */ |
| Parser.prototype._forEachUnquotedChar = function (input, start) { |
| var currentQuote, escapeCount, i, char; |
| return __generator(this, function (_b) { |
| switch (_b.label) { |
| case 0: |
| currentQuote = null; |
| escapeCount = 0; |
| i = start; |
| _b.label = 1; |
| case 1: |
| if (!(i < input.length)) return [3 /*break*/, 6]; |
| char = input[i]; |
| if (!(isQuote(input.charCodeAt(i)) && (currentQuote === null || currentQuote === char) && |
| escapeCount % 2 === 0)) return [3 /*break*/, 2]; |
| currentQuote = currentQuote === null ? char : null; |
| return [3 /*break*/, 4]; |
| case 2: |
| if (!(currentQuote === null)) return [3 /*break*/, 4]; |
| return [4 /*yield*/, i]; |
| case 3: |
| _b.sent(); |
| _b.label = 4; |
| case 4: |
| escapeCount = char === '\\' ? escapeCount + 1 : 0; |
| _b.label = 5; |
| case 5: |
| i++; |
| return [3 /*break*/, 1]; |
| case 6: return [2 /*return*/]; |
| } |
| }); |
| }; |
| return Parser; |
| }()); |
| var IvyParser = /** @class */ (function (_super) { |
| __extends(IvyParser, _super); |
| function IvyParser() { |
| var _this = _super.apply(this, __spread(arguments)) || this; |
| _this.simpleExpressionChecker = IvySimpleExpressionChecker; |
| return _this; |
| } |
| return IvyParser; |
| }(Parser$1)); |
| /** Describes a stateful context an expression parser is in. */ |
| var ParseContextFlags; |
| (function (ParseContextFlags) { |
| ParseContextFlags[ParseContextFlags["None"] = 0] = "None"; |
| /** |
| * A Writable context is one in which a value may be written to an lvalue. |
| * For example, after we see a property access, we may expect a write to the |
| * property via the "=" operator. |
| * prop |
| * ^ possible "=" after |
| */ |
| ParseContextFlags[ParseContextFlags["Writable"] = 1] = "Writable"; |
| })(ParseContextFlags || (ParseContextFlags = {})); |
| var _ParseAST = /** @class */ (function () { |
| function _ParseAST(input, location, absoluteOffset, tokens, inputLength, parseAction, errors, offset) { |
| this.input = input; |
| this.location = location; |
| this.absoluteOffset = absoluteOffset; |
| this.tokens = tokens; |
| this.inputLength = inputLength; |
| this.parseAction = parseAction; |
| this.errors = errors; |
| this.offset = offset; |
| this.rparensExpected = 0; |
| this.rbracketsExpected = 0; |
| this.rbracesExpected = 0; |
| this.context = ParseContextFlags.None; |
| // Cache of expression start and input indeces to the absolute source span they map to, used to |
| // prevent creating superfluous source spans in `sourceSpan`. |
| // A serial of the expression start and input index is used for mapping because both are stateful |
| // and may change for subsequent expressions visited by the parser. |
| this.sourceSpanCache = new Map(); |
| this.index = 0; |
| } |
| _ParseAST.prototype.peek = function (offset) { |
| var i = this.index + offset; |
| return i < this.tokens.length ? this.tokens[i] : EOF; |
| }; |
| Object.defineProperty(_ParseAST.prototype, "next", { |
| get: function () { |
| return this.peek(0); |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(_ParseAST.prototype, "atEOF", { |
| /** Whether all the parser input has been processed. */ |
| get: function () { |
| return this.index >= this.tokens.length; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(_ParseAST.prototype, "inputIndex", { |
| /** |
| * Index of the next token to be processed, or the end of the last token if all have been |
| * processed. |
| */ |
| get: function () { |
| return this.atEOF ? this.currentEndIndex : this.next.index + this.offset; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(_ParseAST.prototype, "currentEndIndex", { |
| /** |
| * End index of the last processed token, or the start of the first token if none have been |
| * processed. |
| */ |
| get: function () { |
| if (this.index > 0) { |
| var curToken = this.peek(-1); |
| return curToken.end + this.offset; |
| } |
| // No tokens have been processed yet; return the next token's start or the length of the input |
| // if there is no token. |
| if (this.tokens.length === 0) { |
| return this.inputLength + this.offset; |
| } |
| return this.next.index + this.offset; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(_ParseAST.prototype, "currentAbsoluteOffset", { |
| /** |
| * Returns the absolute offset of the start of the current token. |
| */ |
| get: function () { |
| return this.absoluteOffset + this.inputIndex; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| /** |
| * Retrieve a `ParseSpan` from `start` to the current position (or to `artificialEndIndex` if |
| * provided). |
| * |
| * @param start Position from which the `ParseSpan` will start. |
| * @param artificialEndIndex Optional ending index to be used if provided (and if greater than the |
| * natural ending index) |
| */ |
| _ParseAST.prototype.span = function (start, artificialEndIndex) { |
| var endIndex = this.currentEndIndex; |
| if (artificialEndIndex !== undefined && artificialEndIndex > this.currentEndIndex) { |
| endIndex = artificialEndIndex; |
| } |
| return new ParseSpan(start, endIndex); |
| }; |
| _ParseAST.prototype.sourceSpan = function (start, artificialEndIndex) { |
| var serial = start + "@" + this.inputIndex + ":" + artificialEndIndex; |
| if (!this.sourceSpanCache.has(serial)) { |
| this.sourceSpanCache.set(serial, this.span(start, artificialEndIndex).toAbsolute(this.absoluteOffset)); |
| } |
| return this.sourceSpanCache.get(serial); |
| }; |
| _ParseAST.prototype.advance = function () { |
| this.index++; |
| }; |
| /** |
| * Executes a callback in the provided context. |
| */ |
| _ParseAST.prototype.withContext = function (context, cb) { |
| this.context |= context; |
| var ret = cb(); |
| this.context ^= context; |
| return ret; |
| }; |
| _ParseAST.prototype.consumeOptionalCharacter = function (code) { |
| if (this.next.isCharacter(code)) { |
| this.advance(); |
| return true; |
| } |
| else { |
| return false; |
| } |
| }; |
| _ParseAST.prototype.peekKeywordLet = function () { |
| return this.next.isKeywordLet(); |
| }; |
| _ParseAST.prototype.peekKeywordAs = function () { |
| return this.next.isKeywordAs(); |
| }; |
| /** |
| * Consumes an expected character, otherwise emits an error about the missing expected character |
| * and skips over the token stream until reaching a recoverable point. |
| * |
| * See `this.error` and `this.skip` for more details. |
| */ |
| _ParseAST.prototype.expectCharacter = function (code) { |
| if (this.consumeOptionalCharacter(code)) |
| return; |
| this.error("Missing expected " + String.fromCharCode(code)); |
| }; |
| _ParseAST.prototype.consumeOptionalOperator = function (op) { |
| if (this.next.isOperator(op)) { |
| this.advance(); |
| return true; |
| } |
| else { |
| return false; |
| } |
| }; |
| _ParseAST.prototype.expectOperator = function (operator) { |
| if (this.consumeOptionalOperator(operator)) |
| return; |
| this.error("Missing expected operator " + operator); |
| }; |
| _ParseAST.prototype.prettyPrintToken = function (tok) { |
| return tok === EOF ? 'end of input' : "token " + tok; |
| }; |
| _ParseAST.prototype.expectIdentifierOrKeyword = function () { |
| var n = this.next; |
| if (!n.isIdentifier() && !n.isKeyword()) { |
| this.error("Unexpected " + this.prettyPrintToken(n) + ", expected identifier or keyword"); |
| return null; |
| } |
| this.advance(); |
| return n.toString(); |
| }; |
| _ParseAST.prototype.expectIdentifierOrKeywordOrString = function () { |
| var n = this.next; |
| if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) { |
| this.error("Unexpected " + this.prettyPrintToken(n) + ", expected identifier, keyword, or string"); |
| return ''; |
| } |
| this.advance(); |
| return n.toString(); |
| }; |
| _ParseAST.prototype.parseChain = function () { |
| var exprs = []; |
| var start = this.inputIndex; |
| while (this.index < this.tokens.length) { |
| var expr = this.parsePipe(); |
| exprs.push(expr); |
| if (this.consumeOptionalCharacter($SEMICOLON)) { |
| if (!this.parseAction) { |
| this.error('Binding expression cannot contain chained expression'); |
| } |
| while (this.consumeOptionalCharacter($SEMICOLON)) { |
| } // read all semicolons |
| } |
| else if (this.index < this.tokens.length) { |
| this.error("Unexpected token '" + this.next + "'"); |
| } |
| } |
| if (exprs.length == 0) { |
| // We have no expressions so create an empty expression that spans the entire input length |
| var artificialStart = this.offset; |
| var artificialEnd = this.offset + this.inputLength; |
| return new EmptyExpr(this.span(artificialStart, artificialEnd), this.sourceSpan(artificialStart, artificialEnd)); |
| } |
| if (exprs.length == 1) |
| return exprs[0]; |
| return new Chain(this.span(start), this.sourceSpan(start), exprs); |
| }; |
| _ParseAST.prototype.parsePipe = function () { |
| var start = this.inputIndex; |
| var result = this.parseExpression(); |
| if (this.consumeOptionalOperator('|')) { |
| if (this.parseAction) { |
| this.error('Cannot have a pipe in an action expression'); |
| } |
| do { |
| var nameStart = this.inputIndex; |
| var nameId = this.expectIdentifierOrKeyword(); |
| var nameSpan = void 0; |
| var fullSpanEnd = undefined; |
| if (nameId !== null) { |
| nameSpan = this.sourceSpan(nameStart); |
| } |
| else { |
| // No valid identifier was found, so we'll assume an empty pipe name (''). |
| nameId = ''; |
| // However, there may have been whitespace present between the pipe character and the next |
| // token in the sequence (or the end of input). We want to track this whitespace so that |
| // the `BindingPipe` we produce covers not just the pipe character, but any trailing |
| // whitespace beyond it. Another way of thinking about this is that the zero-length name |
| // is assumed to be at the end of any whitespace beyond the pipe character. |
| // |
| // Therefore, we push the end of the `ParseSpan` for this pipe all the way up to the |
| // beginning of the next token, or until the end of input if the next token is EOF. |
| fullSpanEnd = this.next.index !== -1 ? this.next.index : this.inputLength + this.offset; |
| // The `nameSpan` for an empty pipe name is zero-length at the end of any whitespace |
| // beyond the pipe character. |
| nameSpan = new ParseSpan(fullSpanEnd, fullSpanEnd).toAbsolute(this.absoluteOffset); |
| } |
| var args = []; |
| while (this.consumeOptionalCharacter($COLON)) { |
| args.push(this.parseExpression()); |
| // If there are additional expressions beyond the name, then the artificial end for the |
| // name is no longer relevant. |
| } |
| result = new BindingPipe(this.span(start), this.sourceSpan(start, fullSpanEnd), result, nameId, args, nameSpan); |
| } while (this.consumeOptionalOperator('|')); |
| } |
| return result; |
| }; |
| _ParseAST.prototype.parseExpression = function () { |
| return this.parseConditional(); |
| }; |
| _ParseAST.prototype.parseConditional = function () { |
| var start = this.inputIndex; |
| var result = this.parseLogicalOr(); |
| if (this.consumeOptionalOperator('?')) { |
| var yes = this.parsePipe(); |
| var no = void 0; |
| if (!this.consumeOptionalCharacter($COLON)) { |
| var end = this.inputIndex; |
| var expression = this.input.substring(start, end); |
| this.error("Conditional expression " + expression + " requires all 3 expressions"); |
| no = new EmptyExpr(this.span(start), this.sourceSpan(start)); |
| } |
| else { |
| no = this.parsePipe(); |
| } |
| return new Conditional(this.span(start), this.sourceSpan(start), result, yes, no); |
| } |
| else { |
| return result; |
| } |
| }; |
| _ParseAST.prototype.parseLogicalOr = function () { |
| // '||' |
| var start = this.inputIndex; |
| var result = this.parseLogicalAnd(); |
| while (this.consumeOptionalOperator('||')) { |
| var right = this.parseLogicalAnd(); |
| result = new Binary(this.span(start), this.sourceSpan(start), '||', result, right); |
| } |
| return result; |
| }; |
| _ParseAST.prototype.parseLogicalAnd = function () { |
| // '&&' |
| var start = this.inputIndex; |
| var result = this.parseEquality(); |
| while (this.consumeOptionalOperator('&&')) { |
| var right = this.parseEquality(); |
| result = new Binary(this.span(start), this.sourceSpan(start), '&&', result, right); |
| } |
| return result; |
| }; |
| _ParseAST.prototype.parseEquality = function () { |
| // '==','!=','===','!==' |
| var start = this.inputIndex; |
| var result = this.parseRelational(); |
| while (this.next.type == exports.TokenType.Operator) { |
| var operator = this.next.strValue; |
| switch (operator) { |
| case '==': |
| case '===': |
| case '!=': |
| case '!==': |
| this.advance(); |
| var right = this.parseRelational(); |
| result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right); |
| continue; |
| } |
| break; |
| } |
| return result; |
| }; |
| _ParseAST.prototype.parseRelational = function () { |
| // '<', '>', '<=', '>=' |
| var start = this.inputIndex; |
| var result = this.parseAdditive(); |
| while (this.next.type == exports.TokenType.Operator) { |
| var operator = this.next.strValue; |
| switch (operator) { |
| case '<': |
| case '>': |
| case '<=': |
| case '>=': |
| this.advance(); |
| var right = this.parseAdditive(); |
| result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right); |
| continue; |
| } |
| break; |
| } |
| return result; |
| }; |
| _ParseAST.prototype.parseAdditive = function () { |
| // '+', '-' |
| var start = this.inputIndex; |
| var result = this.parseMultiplicative(); |
| while (this.next.type == exports.TokenType.Operator) { |
| var operator = this.next.strValue; |
| switch (operator) { |
| case '+': |
| case '-': |
| this.advance(); |
| var right = this.parseMultiplicative(); |
| result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right); |
| continue; |
| } |
| break; |
| } |
| return result; |
| }; |
| _ParseAST.prototype.parseMultiplicative = function () { |
| // '*', '%', '/' |
| var start = this.inputIndex; |
| var result = this.parsePrefix(); |
| while (this.next.type == exports.TokenType.Operator) { |
| var operator = this.next.strValue; |
| switch (operator) { |
| case '*': |
| case '%': |
| case '/': |
| this.advance(); |
| var right = this.parsePrefix(); |
| result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right); |
| continue; |
| } |
| break; |
| } |
| return result; |
| }; |
| _ParseAST.prototype.parsePrefix = function () { |
| if (this.next.type == exports.TokenType.Operator) { |
| var start = this.inputIndex; |
| var operator = this.next.strValue; |
| var result = void 0; |
| switch (operator) { |
| case '+': |
| this.advance(); |
| result = this.parsePrefix(); |
| return Unary.createPlus(this.span(start), this.sourceSpan(start), result); |
| case '-': |
| this.advance(); |
| result = this.parsePrefix(); |
| return Unary.createMinus(this.span(start), this.sourceSpan(start), result); |
| case '!': |
| this.advance(); |
| result = this.parsePrefix(); |
| return new PrefixNot(this.span(start), this.sourceSpan(start), result); |
| } |
| } |
| return this.parseCallChain(); |
| }; |
| _ParseAST.prototype.parseCallChain = function () { |
| var _this = this; |
| var start = this.inputIndex; |
| var result = this.parsePrimary(); |
| while (true) { |
| if (this.consumeOptionalCharacter($PERIOD)) { |
| result = this.parseAccessMemberOrMethodCall(result, start, false); |
| } |
| else if (this.consumeOptionalOperator('?.')) { |
| result = this.parseAccessMemberOrMethodCall(result, start, true); |
| } |
| else if (this.consumeOptionalCharacter($LBRACKET)) { |
| this.withContext(ParseContextFlags.Writable, function () { |
| _this.rbracketsExpected++; |
| var key = _this.parsePipe(); |
| if (key instanceof EmptyExpr) { |
| _this.error("Key access cannot be empty"); |
| } |
| _this.rbracketsExpected--; |
| _this.expectCharacter($RBRACKET); |
| if (_this.consumeOptionalOperator('=')) { |
| var value = _this.parseConditional(); |
| result = new KeyedWrite(_this.span(start), _this.sourceSpan(start), result, key, value); |
| } |
| else { |
| result = new KeyedRead(_this.span(start), _this.sourceSpan(start), result, key); |
| } |
| }); |
| } |
| else if (this.consumeOptionalCharacter($LPAREN)) { |
| this.rparensExpected++; |
| var args = this.parseCallArguments(); |
| this.rparensExpected--; |
| this.expectCharacter($RPAREN); |
| result = new FunctionCall(this.span(start), this.sourceSpan(start), result, args); |
| } |
| else if (this.consumeOptionalOperator('!')) { |
| result = new NonNullAssert(this.span(start), this.sourceSpan(start), result); |
| } |
| else { |
| return result; |
| } |
| } |
| }; |
| _ParseAST.prototype.parsePrimary = function () { |
| var start = this.inputIndex; |
| if (this.consumeOptionalCharacter($LPAREN)) { |
| this.rparensExpected++; |
| var result = this.parsePipe(); |
| this.rparensExpected--; |
| this.expectCharacter($RPAREN); |
| return result; |
| } |
| else if (this.next.isKeywordNull()) { |
| this.advance(); |
| return new LiteralPrimitive(this.span(start), this.sourceSpan(start), null); |
| } |
| else if (this.next.isKeywordUndefined()) { |
| this.advance(); |
| return new LiteralPrimitive(this.span(start), this.sourceSpan(start), void 0); |
| } |
| else if (this.next.isKeywordTrue()) { |
| this.advance(); |
| return new LiteralPrimitive(this.span(start), this.sourceSpan(start), true); |
| } |
| else if (this.next.isKeywordFalse()) { |
| this.advance(); |
| return new LiteralPrimitive(this.span(start), this.sourceSpan(start), false); |
| } |
| else if (this.next.isKeywordThis()) { |
| this.advance(); |
| return new ThisReceiver(this.span(start), this.sourceSpan(start)); |
| } |
| else if (this.consumeOptionalCharacter($LBRACKET)) { |
| this.rbracketsExpected++; |
| var elements = this.parseExpressionList($RBRACKET); |
| this.rbracketsExpected--; |
| this.expectCharacter($RBRACKET); |
| return new LiteralArray(this.span(start), this.sourceSpan(start), elements); |
| } |
| else if (this.next.isCharacter($LBRACE)) { |
| return this.parseLiteralMap(); |
| } |
| else if (this.next.isIdentifier()) { |
| return this.parseAccessMemberOrMethodCall(new ImplicitReceiver(this.span(start), this.sourceSpan(start)), start, false); |
| } |
| else if (this.next.isNumber()) { |
| var value = this.next.toNumber(); |
| this.advance(); |
| return new LiteralPrimitive(this.span(start), this.sourceSpan(start), value); |
| } |
| else if (this.next.isString()) { |
| var literalValue = this.next.toString(); |
| this.advance(); |
| return new LiteralPrimitive(this.span(start), this.sourceSpan(start), literalValue); |
| } |
| else if (this.index >= this.tokens.length) { |
| this.error("Unexpected end of expression: " + this.input); |
| return new EmptyExpr(this.span(start), this.sourceSpan(start)); |
| } |
| else { |
| this.error("Unexpected token " + this.next); |
| return new EmptyExpr(this.span(start), this.sourceSpan(start)); |
| } |
| }; |
| _ParseAST.prototype.parseExpressionList = function (terminator) { |
| var result = []; |
| do { |
| if (!this.next.isCharacter(terminator)) { |
| result.push(this.parsePipe()); |
| } |
| else { |
| break; |
| } |
| } while (this.consumeOptionalCharacter($COMMA)); |
| return result; |
| }; |
| _ParseAST.prototype.parseLiteralMap = function () { |
| var keys = []; |
| var values = []; |
| var start = this.inputIndex; |
| this.expectCharacter($LBRACE); |
| if (!this.consumeOptionalCharacter($RBRACE)) { |
| this.rbracesExpected++; |
| do { |
| var quoted = this.next.isString(); |
| var key = this.expectIdentifierOrKeywordOrString(); |
| keys.push({ key: key, quoted: quoted }); |
| this.expectCharacter($COLON); |
| values.push(this.parsePipe()); |
| } while (this.consumeOptionalCharacter($COMMA)); |
| this.rbracesExpected--; |
| this.expectCharacter($RBRACE); |
| } |
| return new LiteralMap(this.span(start), this.sourceSpan(start), keys, values); |
| }; |
| _ParseAST.prototype.parseAccessMemberOrMethodCall = function (receiver, start, isSafe) { |
| var _this = this; |
| if (isSafe === void 0) { isSafe = false; } |
| var nameStart = this.inputIndex; |
| var id = this.withContext(ParseContextFlags.Writable, function () { |
| var _a; |
| var id = (_a = _this.expectIdentifierOrKeyword()) !== null && _a !== void 0 ? _a : ''; |
| if (id.length === 0) { |
| _this.error("Expected identifier for property access", receiver.span.end); |
| } |
| return id; |
| }); |
| var nameSpan = this.sourceSpan(nameStart); |
| if (this.consumeOptionalCharacter($LPAREN)) { |
| this.rparensExpected++; |
| var args = this.parseCallArguments(); |
| this.expectCharacter($RPAREN); |
| this.rparensExpected--; |
| var span = this.span(start); |
| var sourceSpan = this.sourceSpan(start); |
| return isSafe ? new SafeMethodCall(span, sourceSpan, nameSpan, receiver, id, args) : |
| new MethodCall(span, sourceSpan, nameSpan, receiver, id, args); |
| } |
| else { |
| if (isSafe) { |
| if (this.consumeOptionalOperator('=')) { |
| this.error('The \'?.\' operator cannot be used in the assignment'); |
| return new EmptyExpr(this.span(start), this.sourceSpan(start)); |
| } |
| else { |
| return new SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id); |
| } |
| } |
| else { |
| if (this.consumeOptionalOperator('=')) { |
| if (!this.parseAction) { |
| this.error('Bindings cannot contain assignments'); |
| return new EmptyExpr(this.span(start), this.sourceSpan(start)); |
| } |
| var value = this.parseConditional(); |
| return new PropertyWrite(this.span(start), this.sourceSpan(start), nameSpan, receiver, id, value); |
| } |
| else { |
| return new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id); |
| } |
| } |
| } |
| }; |
| _ParseAST.prototype.parseCallArguments = function () { |
| if (this.next.isCharacter($RPAREN)) |
| return []; |
| var positionals = []; |
| do { |
| positionals.push(this.parsePipe()); |
| } while (this.consumeOptionalCharacter($COMMA)); |
| return positionals; |
| }; |
| /** |
| * Parses an identifier, a keyword, a string with an optional `-` in between, |
| * and returns the string along with its absolute source span. |
| */ |
| _ParseAST.prototype.expectTemplateBindingKey = function () { |
| var result = ''; |
| var operatorFound = false; |
| var start = this.currentAbsoluteOffset; |
| do { |
| result += this.expectIdentifierOrKeywordOrString(); |
| operatorFound = this.consumeOptionalOperator('-'); |
| if (operatorFound) { |
| result += '-'; |
| } |
| } while (operatorFound); |
| return { |
| source: result, |
| span: new AbsoluteSourceSpan(start, start + result.length), |
| }; |
| }; |
| /** |
| * Parse microsyntax template expression and return a list of bindings or |
| * parsing errors in case the given expression is invalid. |
| * |
| * For example, |
| * ``` |
| * <div *ngFor="let item of items; index as i; trackBy: func"> |
| * ``` |
| * contains five bindings: |
| * 1. ngFor -> null |
| * 2. item -> NgForOfContext.$implicit |
| * 3. ngForOf -> items |
| * 4. i -> NgForOfContext.index |
| * 5. ngForTrackBy -> func |
| * |
| * For a full description of the microsyntax grammar, see |
| * https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855 |
| * |
| * @param templateKey name of the microsyntax directive, like ngIf, ngFor, |
| * without the *, along with its absolute span. |
| */ |
| _ParseAST.prototype.parseTemplateBindings = function (templateKey) { |
| var bindings = []; |
| // The first binding is for the template key itself |
| // In *ngFor="let item of items", key = "ngFor", value = null |
| // In *ngIf="cond | pipe", key = "ngIf", value = "cond | pipe" |
| bindings.push.apply(bindings, __spread(this.parseDirectiveKeywordBindings(templateKey))); |
| while (this.index < this.tokens.length) { |
| // If it starts with 'let', then this must be variable declaration |
| var letBinding = this.parseLetBinding(); |
| if (letBinding) { |
| bindings.push(letBinding); |
| } |
| else { |
| // Two possible cases here, either `value "as" key` or |
| // "directive-keyword expression". We don't know which case, but both |
| // "value" and "directive-keyword" are template binding key, so consume |
| // the key first. |
| var key = this.expectTemplateBindingKey(); |
| // Peek at the next token, if it is "as" then this must be variable |
| // declaration. |
| var binding = this.parseAsBinding(key); |
| if (binding) { |
| bindings.push(binding); |
| } |
| else { |
| // Otherwise the key must be a directive keyword, like "of". Transform |
| // the key to actual key. Eg. of -> ngForOf, trackBy -> ngForTrackBy |
| key.source = |
| templateKey.source + key.source.charAt(0).toUpperCase() + key.source.substring(1); |
| bindings.push.apply(bindings, __spread(this.parseDirectiveKeywordBindings(key))); |
| } |
| } |
| this.consumeStatementTerminator(); |
| } |
| return new TemplateBindingParseResult(bindings, [] /* warnings */, this.errors); |
| }; |
| /** |
| * Parse a directive keyword, followed by a mandatory expression. |
| * For example, "of items", "trackBy: func". |
| * The bindings are: ngForOf -> items, ngForTrackBy -> func |
| * There could be an optional "as" binding that follows the expression. |
| * For example, |
| * ``` |
| * *ngFor="let item of items | slice:0:1 as collection". |
| * ^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ |
| * keyword bound target optional 'as' binding |
| * ``` |
| * |
| * @param key binding key, for example, ngFor, ngIf, ngForOf, along with its |
| * absolute span. |
| */ |
| _ParseAST.prototype.parseDirectiveKeywordBindings = function (key) { |
| var bindings = []; |
| this.consumeOptionalCharacter($COLON); // trackBy: trackByFunction |
| var value = this.getDirectiveBoundTarget(); |
| var spanEnd = this.currentAbsoluteOffset; |
| // The binding could optionally be followed by "as". For example, |
| // *ngIf="cond | pipe as x". In this case, the key in the "as" binding |
| // is "x" and the value is the template key itself ("ngIf"). Note that the |
| // 'key' in the current context now becomes the "value" in the next binding. |
| var asBinding = this.parseAsBinding(key); |
| if (!asBinding) { |
| this.consumeStatementTerminator(); |
| spanEnd = this.currentAbsoluteOffset; |
| } |
| var sourceSpan = new AbsoluteSourceSpan(key.span.start, spanEnd); |
| bindings.push(new ExpressionBinding(sourceSpan, key, value)); |
| if (asBinding) { |
| bindings.push(asBinding); |
| } |
| return bindings; |
| }; |
| /** |
| * Return the expression AST for the bound target of a directive keyword |
| * binding. For example, |
| * ``` |
| * *ngIf="condition | pipe" |
| * ^^^^^^^^^^^^^^^^ bound target for "ngIf" |
| * *ngFor="let item of items" |
| * ^^^^^ bound target for "ngForOf" |
| * ``` |
| */ |
| _ParseAST.prototype.getDirectiveBoundTarget = function () { |
| if (this.next === EOF || this.peekKeywordAs() || this.peekKeywordLet()) { |
| return null; |
| } |
| var ast = this.parsePipe(); // example: "condition | async" |
| var _b = ast.span, start = _b.start, end = _b.end; |
| var value = this.input.substring(start, end); |
| return new ASTWithSource(ast, value, this.location, this.absoluteOffset + start, this.errors); |
| }; |
| /** |
| * Return the binding for a variable declared using `as`. Note that the order |
| * of the key-value pair in this declaration is reversed. For example, |
| * ``` |
| * *ngFor="let item of items; index as i" |
| * ^^^^^ ^ |
| * value key |
| * ``` |
| * |
| * @param value name of the value in the declaration, "ngIf" in the example |
| * above, along with its absolute span. |
| */ |
| _ParseAST.prototype.parseAsBinding = function (value) { |
| if (!this.peekKeywordAs()) { |
| return null; |
| } |
| this.advance(); // consume the 'as' keyword |
| var key = this.expectTemplateBindingKey(); |
| this.consumeStatementTerminator(); |
| var sourceSpan = new AbsoluteSourceSpan(value.span.start, this.currentAbsoluteOffset); |
| return new VariableBinding(sourceSpan, key, value); |
| }; |
| /** |
| * Return the binding for a variable declared using `let`. For example, |
| * ``` |
| * *ngFor="let item of items; let i=index;" |
| * ^^^^^^^^ ^^^^^^^^^^^ |
| * ``` |
| * In the first binding, `item` is bound to `NgForOfContext.$implicit`. |
| * In the second binding, `i` is bound to `NgForOfContext.index`. |
| */ |
| _ParseAST.prototype.parseLetBinding = function () { |
| if (!this.peekKeywordLet()) { |
| return null; |
| } |
| var spanStart = this.currentAbsoluteOffset; |
| this.advance(); // consume the 'let' keyword |
| var key = this.expectTemplateBindingKey(); |
| var value = null; |
| if (this.consumeOptionalOperator('=')) { |
| value = this.expectTemplateBindingKey(); |
| } |
| this.consumeStatementTerminator(); |
| var sourceSpan = new AbsoluteSourceSpan(spanStart, this.currentAbsoluteOffset); |
| return new VariableBinding(sourceSpan, key, value); |
| }; |
| /** |
| * Consume the optional statement terminator: semicolon or comma. |
| */ |
| _ParseAST.prototype.consumeStatementTerminator = function () { |
| this.consumeOptionalCharacter($SEMICOLON) || this.consumeOptionalCharacter($COMMA); |
| }; |
| /** |
| * Records an error and skips over the token stream until reaching a recoverable point. See |
| * `this.skip` for more details on token skipping. |
| */ |
| _ParseAST.prototype.error = function (message, index) { |
| if (index === void 0) { index = null; } |
| this.errors.push(new ParserError(message, this.input, this.locationText(index), this.location)); |
| this.skip(); |
| }; |
| _ParseAST.prototype.locationText = function (index) { |
| if (index === void 0) { index = null; } |
| if (index == null) |
| index = this.index; |
| return (index < this.tokens.length) ? "at column " + (this.tokens[index].index + 1) + " in" : |
| "at the end of the expression"; |
| }; |
| /** |
| * Error recovery should skip tokens until it encounters a recovery point. |
| * |
| * The following are treated as unconditional recovery points: |
| * - end of input |
| * - ';' (parseChain() is always the root production, and it expects a ';') |
| * - '|' (since pipes may be chained and each pipe expression may be treated independently) |
| * |
| * The following are conditional recovery points: |
| * - ')', '}', ']' if one of calling productions is expecting one of these symbols |
| * - This allows skip() to recover from errors such as '(a.) + 1' allowing more of the AST to |
| * be retained (it doesn't skip any tokens as the ')' is retained because of the '(' begins |
| * an '(' <expr> ')' production). |
| * The recovery points of grouping symbols must be conditional as they must be skipped if |
| * none of the calling productions are not expecting the closing token else we will never |
| * make progress in the case of an extraneous group closing symbol (such as a stray ')'). |
| * That is, we skip a closing symbol if we are not in a grouping production. |
| * - '=' in a `Writable` context |
| * - In this context, we are able to recover after seeing the `=` operator, which |
| * signals the presence of an independent rvalue expression following the `=` operator. |
| * |
| * If a production expects one of these token it increments the corresponding nesting count, |
| * and then decrements it just prior to checking if the token is in the input. |
| */ |
| _ParseAST.prototype.skip = function () { |
| var n = this.next; |
| while (this.index < this.tokens.length && !n.isCharacter($SEMICOLON) && |
| !n.isOperator('|') && (this.rparensExpected <= 0 || !n.isCharacter($RPAREN)) && |
| (this.rbracesExpected <= 0 || !n.isCharacter($RBRACE)) && |
| (this.rbracketsExpected <= 0 || !n.isCharacter($RBRACKET)) && |
| (!(this.context & ParseContextFlags.Writable) || !n.isOperator('='))) { |
| if (this.next.isError()) { |
| this.errors.push(new ParserError(this.next.toString(), this.input, this.locationText(), this.location)); |
| } |
| this.advance(); |
| n = this.next; |
| } |
| }; |
| return _ParseAST; |
| }()); |
| var SimpleExpressionChecker = /** @class */ (function () { |
| function SimpleExpressionChecker() { |
| this.errors = []; |
| } |
| SimpleExpressionChecker.prototype.visitImplicitReceiver = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitThisReceiver = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitInterpolation = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitLiteralPrimitive = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitPropertyRead = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitPropertyWrite = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitSafePropertyRead = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitMethodCall = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitSafeMethodCall = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitFunctionCall = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitLiteralArray = function (ast, context) { |
| this.visitAll(ast.expressions, context); |
| }; |
| SimpleExpressionChecker.prototype.visitLiteralMap = function (ast, context) { |
| this.visitAll(ast.values, context); |
| }; |
| SimpleExpressionChecker.prototype.visitUnary = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitBinary = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitPrefixNot = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitNonNullAssert = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitConditional = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitPipe = function (ast, context) { |
| this.errors.push('pipes'); |
| }; |
| SimpleExpressionChecker.prototype.visitKeyedRead = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitKeyedWrite = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitAll = function (asts, context) { |
| var _this = this; |
| return asts.map(function (node) { return node.visit(_this, context); }); |
| }; |
| SimpleExpressionChecker.prototype.visitChain = function (ast, context) { }; |
| SimpleExpressionChecker.prototype.visitQuote = function (ast, context) { }; |
| return SimpleExpressionChecker; |
| }()); |
| /** |
| * This class implements SimpleExpressionChecker used in View Engine and performs more strict checks |
| * to make sure host bindings do not contain pipes. In View Engine, having pipes in host bindings is |
| * not supported as well, but in some cases (like `!(value | async)`) the error is not triggered at |
| * compile time. In order to preserve View Engine behavior, more strict checks are introduced for |
| * Ivy mode only. |
| */ |
| var IvySimpleExpressionChecker = /** @class */ (function (_super) { |
| __extends(IvySimpleExpressionChecker, _super); |
| function IvySimpleExpressionChecker() { |
| var _this = _super.apply(this, __spread(arguments)) || this; |
| _this.errors = []; |
| return _this; |
| } |
| IvySimpleExpressionChecker.prototype.visitPipe = function () { |
| this.errors.push('pipes'); |
| }; |
| return IvySimpleExpressionChecker; |
| }(RecursiveAstVisitor$1)); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| function mapEntry(key, value) { |
| return { key: key, value: value, quoted: false }; |
| } |
| function mapLiteral(obj, quoted) { |
| if (quoted === void 0) { quoted = false; } |
| return literalMap(Object.keys(obj).map(function (key) { return ({ |
| key: key, |
| quoted: quoted, |
| value: obj[key], |
| }); })); |
| } |
| |
| // ================================================================================================= |
| // ================================================================================================= |
| // =========== S T O P - S T O P - S T O P - S T O P - S T O P - S T O P =========== |
| // ================================================================================================= |
| // ================================================================================================= |
| // |
| // DO NOT EDIT THIS LIST OF SECURITY SENSITIVE PROPERTIES WITHOUT A SECURITY REVIEW! |
| // Reach out to mprobst for details. |
| // |
| // ================================================================================================= |
| /** Map from tagName|propertyName to SecurityContext. Properties applying to all tags use '*'. */ |
| var _SECURITY_SCHEMA; |
| function SECURITY_SCHEMA() { |
| if (!_SECURITY_SCHEMA) { |
| _SECURITY_SCHEMA = {}; |
| // Case is insignificant below, all element and attribute names are lower-cased for lookup. |
| registerContext(SecurityContext.HTML, [ |
| 'iframe|srcdoc', |
| '*|innerHTML', |
| '*|outerHTML', |
| ]); |
| registerContext(SecurityContext.STYLE, ['*|style']); |
| // NB: no SCRIPT contexts here, they are never allowed due to the parser stripping them. |
| registerContext(SecurityContext.URL, [ |
| '*|formAction', 'area|href', 'area|ping', 'audio|src', 'a|href', |
| 'a|ping', 'blockquote|cite', 'body|background', 'del|cite', 'form|action', |
| 'img|src', 'img|srcset', 'input|src', 'ins|cite', 'q|cite', |
| 'source|src', 'source|srcset', 'track|src', 'video|poster', 'video|src', |
| ]); |
| registerContext(SecurityContext.RESOURCE_URL, [ |
| 'applet|code', |
| 'applet|codebase', |
| 'base|href', |
| 'embed|src', |
| 'frame|src', |
| 'head|profile', |
| 'html|manifest', |
| 'iframe|src', |
| 'link|href', |
| 'media|src', |
| 'object|codebase', |
| 'object|data', |
| 'script|src', |
| ]); |
| } |
| return _SECURITY_SCHEMA; |
| } |
| function registerContext(ctx, specs) { |
| var e_1, _a; |
| try { |
| for (var specs_1 = __values(specs), specs_1_1 = specs_1.next(); !specs_1_1.done; specs_1_1 = specs_1.next()) { |
| var spec = specs_1_1.value; |
| _SECURITY_SCHEMA[spec.toLowerCase()] = ctx; |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (specs_1_1 && !specs_1_1.done && (_a = specs_1.return)) _a.call(specs_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var ElementSchemaRegistry = /** @class */ (function () { |
| function ElementSchemaRegistry() { |
| } |
| return ElementSchemaRegistry; |
| }()); |
| |
| var BOOLEAN = 'boolean'; |
| var NUMBER = 'number'; |
| var STRING = 'string'; |
| var OBJECT = 'object'; |
| /** |
| * This array represents the DOM schema. It encodes inheritance, properties, and events. |
| * |
| * ## Overview |
| * |
| * Each line represents one kind of element. The `element_inheritance` and properties are joined |
| * using `element_inheritance|properties` syntax. |
| * |
| * ## Element Inheritance |
| * |
| * The `element_inheritance` can be further subdivided as `element1,element2,...^parentElement`. |
| * Here the individual elements are separated by `,` (commas). Every element in the list |
| * has identical properties. |
| * |
| * An `element` may inherit additional properties from `parentElement` If no `^parentElement` is |
| * specified then `""` (blank) element is assumed. |
| * |
| * NOTE: The blank element inherits from root `[Element]` element, the super element of all |
| * elements. |
| * |
| * NOTE an element prefix such as `:svg:` has no special meaning to the schema. |
| * |
| * ## Properties |
| * |
| * Each element has a set of properties separated by `,` (commas). Each property can be prefixed |
| * by a special character designating its type: |
| * |
| * - (no prefix): property is a string. |
| * - `*`: property represents an event. |
| * - `!`: property is a boolean. |
| * - `#`: property is a number. |
| * - `%`: property is an object. |
| * |
| * ## Query |
| * |
| * The class creates an internal squas representation which allows to easily answer the query of |
| * if a given property exist on a given element. |
| * |
| * NOTE: We don't yet support querying for types or events. |
| * NOTE: This schema is auto extracted from `schema_extractor.ts` located in the test folder, |
| * see dom_element_schema_registry_spec.ts |
| */ |
| // ================================================================================================= |
| // ================================================================================================= |
| // =========== S T O P - S T O P - S T O P - S T O P - S T O P - S T O P =========== |
| // ================================================================================================= |
| // ================================================================================================= |
| // |
| // DO NOT EDIT THIS DOM SCHEMA WITHOUT A SECURITY REVIEW! |
| // |
| // Newly added properties must be security reviewed and assigned an appropriate SecurityContext in |
| // dom_security_schema.ts. Reach out to mprobst & rjamet for details. |
| // |
| // ================================================================================================= |
| var SCHEMA = [ |
| '[Element]|textContent,%classList,className,id,innerHTML,*beforecopy,*beforecut,*beforepaste,*copy,*cut,*paste,*search,*selectstart,*webkitfullscreenchange,*webkitfullscreenerror,*wheel,outerHTML,#scrollLeft,#scrollTop,slot' + |
| /* added manually to avoid breaking changes */ |
| ',*message,*mozfullscreenchange,*mozfullscreenerror,*mozpointerlockchange,*mozpointerlockerror,*webglcontextcreationerror,*webglcontextlost,*webglcontextrestored', |
| '[HTMLElement]^[Element]|accessKey,contentEditable,dir,!draggable,!hidden,innerText,lang,*abort,*auxclick,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*cuechange,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*seeked,*seeking,*select,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,outerText,!spellcheck,%style,#tabIndex,title,!translate', |
| 'abbr,address,article,aside,b,bdi,bdo,cite,code,dd,dfn,dt,em,figcaption,figure,footer,header,i,kbd,main,mark,nav,noscript,rb,rp,rt,rtc,ruby,s,samp,section,small,strong,sub,sup,u,var,wbr^[HTMLElement]|accessKey,contentEditable,dir,!draggable,!hidden,innerText,lang,*abort,*auxclick,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*cuechange,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*seeked,*seeking,*select,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,outerText,!spellcheck,%style,#tabIndex,title,!translate', |
| 'media^[HTMLElement]|!autoplay,!controls,%controlsList,%crossOrigin,#currentTime,!defaultMuted,#defaultPlaybackRate,!disableRemotePlayback,!loop,!muted,*encrypted,*waitingforkey,#playbackRate,preload,src,%srcObject,#volume', |
| ':svg:^[HTMLElement]|*abort,*auxclick,*blur,*cancel,*canplay,*canplaythrough,*change,*click,*close,*contextmenu,*cuechange,*dblclick,*drag,*dragend,*dragenter,*dragleave,*dragover,*dragstart,*drop,*durationchange,*emptied,*ended,*error,*focus,*gotpointercapture,*input,*invalid,*keydown,*keypress,*keyup,*load,*loadeddata,*loadedmetadata,*loadstart,*lostpointercapture,*mousedown,*mouseenter,*mouseleave,*mousemove,*mouseout,*mouseover,*mouseup,*mousewheel,*pause,*play,*playing,*pointercancel,*pointerdown,*pointerenter,*pointerleave,*pointermove,*pointerout,*pointerover,*pointerup,*progress,*ratechange,*reset,*resize,*scroll,*seeked,*seeking,*select,*show,*stalled,*submit,*suspend,*timeupdate,*toggle,*volumechange,*waiting,%style,#tabIndex', |
| ':svg:graphics^:svg:|', |
| ':svg:animation^:svg:|*begin,*end,*repeat', |
| ':svg:geometry^:svg:|', |
| ':svg:componentTransferFunction^:svg:|', |
| ':svg:gradient^:svg:|', |
| ':svg:textContent^:svg:graphics|', |
| ':svg:textPositioning^:svg:textContent|', |
| 'a^[HTMLElement]|charset,coords,download,hash,host,hostname,href,hreflang,name,password,pathname,ping,port,protocol,referrerPolicy,rel,rev,search,shape,target,text,type,username', |
| 'area^[HTMLElement]|alt,coords,download,hash,host,hostname,href,!noHref,password,pathname,ping,port,protocol,referrerPolicy,rel,search,shape,target,username', |
| 'audio^media|', |
| 'br^[HTMLElement]|clear', |
| 'base^[HTMLElement]|href,target', |
| 'body^[HTMLElement]|aLink,background,bgColor,link,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,text,vLink', |
| 'button^[HTMLElement]|!autofocus,!disabled,formAction,formEnctype,formMethod,!formNoValidate,formTarget,name,type,value', |
| 'canvas^[HTMLElement]|#height,#width', |
| 'content^[HTMLElement]|select', |
| 'dl^[HTMLElement]|!compact', |
| 'datalist^[HTMLElement]|', |
| 'details^[HTMLElement]|!open', |
| 'dialog^[HTMLElement]|!open,returnValue', |
| 'dir^[HTMLElement]|!compact', |
| 'div^[HTMLElement]|align', |
| 'embed^[HTMLElement]|align,height,name,src,type,width', |
| 'fieldset^[HTMLElement]|!disabled,name', |
| 'font^[HTMLElement]|color,face,size', |
| 'form^[HTMLElement]|acceptCharset,action,autocomplete,encoding,enctype,method,name,!noValidate,target', |
| 'frame^[HTMLElement]|frameBorder,longDesc,marginHeight,marginWidth,name,!noResize,scrolling,src', |
| 'frameset^[HTMLElement]|cols,*beforeunload,*blur,*error,*focus,*hashchange,*languagechange,*load,*message,*offline,*online,*pagehide,*pageshow,*popstate,*rejectionhandled,*resize,*scroll,*storage,*unhandledrejection,*unload,rows', |
| 'hr^[HTMLElement]|align,color,!noShade,size,width', |
| 'head^[HTMLElement]|', |
| 'h1,h2,h3,h4,h5,h6^[HTMLElement]|align', |
| 'html^[HTMLElement]|version', |
| 'iframe^[HTMLElement]|align,!allowFullscreen,frameBorder,height,longDesc,marginHeight,marginWidth,name,referrerPolicy,%sandbox,scrolling,src,srcdoc,width', |
| 'img^[HTMLElement]|align,alt,border,%crossOrigin,#height,#hspace,!isMap,longDesc,lowsrc,name,referrerPolicy,sizes,src,srcset,useMap,#vspace,#width', |
| 'input^[HTMLElement]|accept,align,alt,autocapitalize,autocomplete,!autofocus,!checked,!defaultChecked,defaultValue,dirName,!disabled,%files,formAction,formEnctype,formMethod,!formNoValidate,formTarget,#height,!incremental,!indeterminate,max,#maxLength,min,#minLength,!multiple,name,pattern,placeholder,!readOnly,!required,selectionDirection,#selectionEnd,#selectionStart,#size,src,step,type,useMap,value,%valueAsDate,#valueAsNumber,#width', |
| 'li^[HTMLElement]|type,#value', |
| 'label^[HTMLElement]|htmlFor', |
| 'legend^[HTMLElement]|align', |
| 'link^[HTMLElement]|as,charset,%crossOrigin,!disabled,href,hreflang,integrity,media,referrerPolicy,rel,%relList,rev,%sizes,target,type', |
| 'map^[HTMLElement]|name', |
| 'marquee^[HTMLElement]|behavior,bgColor,direction,height,#hspace,#loop,#scrollAmount,#scrollDelay,!trueSpeed,#vspace,width', |
| 'menu^[HTMLElement]|!compact', |
| 'meta^[HTMLElement]|content,httpEquiv,name,scheme', |
| 'meter^[HTMLElement]|#high,#low,#max,#min,#optimum,#value', |
| 'ins,del^[HTMLElement]|cite,dateTime', |
| 'ol^[HTMLElement]|!compact,!reversed,#start,type', |
| 'object^[HTMLElement]|align,archive,border,code,codeBase,codeType,data,!declare,height,#hspace,name,standby,type,useMap,#vspace,width', |
| 'optgroup^[HTMLElement]|!disabled,label', |
| 'option^[HTMLElement]|!defaultSelected,!disabled,label,!selected,text,value', |
| 'output^[HTMLElement]|defaultValue,%htmlFor,name,value', |
| 'p^[HTMLElement]|align', |
| 'param^[HTMLElement]|name,type,value,valueType', |
| 'picture^[HTMLElement]|', |
| 'pre^[HTMLElement]|#width', |
| 'progress^[HTMLElement]|#max,#value', |
| 'q,blockquote,cite^[HTMLElement]|', |
| 'script^[HTMLElement]|!async,charset,%crossOrigin,!defer,event,htmlFor,integrity,src,text,type', |
| 'select^[HTMLElement]|autocomplete,!autofocus,!disabled,#length,!multiple,name,!required,#selectedIndex,#size,value', |
| 'shadow^[HTMLElement]|', |
| 'slot^[HTMLElement]|name', |
| 'source^[HTMLElement]|media,sizes,src,srcset,type', |
| 'span^[HTMLElement]|', |
| 'style^[HTMLElement]|!disabled,media,type', |
| 'caption^[HTMLElement]|align', |
| 'th,td^[HTMLElement]|abbr,align,axis,bgColor,ch,chOff,#colSpan,headers,height,!noWrap,#rowSpan,scope,vAlign,width', |
| 'col,colgroup^[HTMLElement]|align,ch,chOff,#span,vAlign,width', |
| 'table^[HTMLElement]|align,bgColor,border,%caption,cellPadding,cellSpacing,frame,rules,summary,%tFoot,%tHead,width', |
| 'tr^[HTMLElement]|align,bgColor,ch,chOff,vAlign', |
| 'tfoot,thead,tbody^[HTMLElement]|align,ch,chOff,vAlign', |
| 'template^[HTMLElement]|', |
| 'textarea^[HTMLElement]|autocapitalize,autocomplete,!autofocus,#cols,defaultValue,dirName,!disabled,#maxLength,#minLength,name,placeholder,!readOnly,!required,#rows,selectionDirection,#selectionEnd,#selectionStart,value,wrap', |
| 'title^[HTMLElement]|text', |
| 'track^[HTMLElement]|!default,kind,label,src,srclang', |
| 'ul^[HTMLElement]|!compact,type', |
| 'unknown^[HTMLElement]|', |
| 'video^media|#height,poster,#width', |
| ':svg:a^:svg:graphics|', |
| ':svg:animate^:svg:animation|', |
| ':svg:animateMotion^:svg:animation|', |
| ':svg:animateTransform^:svg:animation|', |
| ':svg:circle^:svg:geometry|', |
| ':svg:clipPath^:svg:graphics|', |
| ':svg:defs^:svg:graphics|', |
| ':svg:desc^:svg:|', |
| ':svg:discard^:svg:|', |
| ':svg:ellipse^:svg:geometry|', |
| ':svg:feBlend^:svg:|', |
| ':svg:feColorMatrix^:svg:|', |
| ':svg:feComponentTransfer^:svg:|', |
| ':svg:feComposite^:svg:|', |
| ':svg:feConvolveMatrix^:svg:|', |
| ':svg:feDiffuseLighting^:svg:|', |
| ':svg:feDisplacementMap^:svg:|', |
| ':svg:feDistantLight^:svg:|', |
| ':svg:feDropShadow^:svg:|', |
| ':svg:feFlood^:svg:|', |
| ':svg:feFuncA^:svg:componentTransferFunction|', |
| ':svg:feFuncB^:svg:componentTransferFunction|', |
| ':svg:feFuncG^:svg:componentTransferFunction|', |
| ':svg:feFuncR^:svg:componentTransferFunction|', |
| ':svg:feGaussianBlur^:svg:|', |
| ':svg:feImage^:svg:|', |
| ':svg:feMerge^:svg:|', |
| ':svg:feMergeNode^:svg:|', |
| ':svg:feMorphology^:svg:|', |
| ':svg:feOffset^:svg:|', |
| ':svg:fePointLight^:svg:|', |
| ':svg:feSpecularLighting^:svg:|', |
| ':svg:feSpotLight^:svg:|', |
| ':svg:feTile^:svg:|', |
| ':svg:feTurbulence^:svg:|', |
| ':svg:filter^:svg:|', |
| ':svg:foreignObject^:svg:graphics|', |
| ':svg:g^:svg:graphics|', |
| ':svg:image^:svg:graphics|', |
| ':svg:line^:svg:geometry|', |
| ':svg:linearGradient^:svg:gradient|', |
| ':svg:mpath^:svg:|', |
| ':svg:marker^:svg:|', |
| ':svg:mask^:svg:|', |
| ':svg:metadata^:svg:|', |
| ':svg:path^:svg:geometry|', |
| ':svg:pattern^:svg:|', |
| ':svg:polygon^:svg:geometry|', |
| ':svg:polyline^:svg:geometry|', |
| ':svg:radialGradient^:svg:gradient|', |
| ':svg:rect^:svg:geometry|', |
| ':svg:svg^:svg:graphics|#currentScale,#zoomAndPan', |
| ':svg:script^:svg:|type', |
| ':svg:set^:svg:animation|', |
| ':svg:stop^:svg:|', |
| ':svg:style^:svg:|!disabled,media,title,type', |
| ':svg:switch^:svg:graphics|', |
| ':svg:symbol^:svg:|', |
| ':svg:tspan^:svg:textPositioning|', |
| ':svg:text^:svg:textPositioning|', |
| ':svg:textPath^:svg:textContent|', |
| ':svg:title^:svg:|', |
| ':svg:use^:svg:graphics|', |
| ':svg:view^:svg:|#zoomAndPan', |
| 'data^[HTMLElement]|value', |
| 'keygen^[HTMLElement]|!autofocus,challenge,!disabled,form,keytype,name', |
| 'menuitem^[HTMLElement]|type,label,icon,!disabled,!checked,radiogroup,!default', |
| 'summary^[HTMLElement]|', |
| 'time^[HTMLElement]|dateTime', |
| ':svg:cursor^:svg:|', |
| ]; |
| var _ATTR_TO_PROP = { |
| 'class': 'className', |
| 'for': 'htmlFor', |
| 'formaction': 'formAction', |
| 'innerHtml': 'innerHTML', |
| 'readonly': 'readOnly', |
| 'tabindex': 'tabIndex', |
| }; |
| // Invert _ATTR_TO_PROP. |
| var _PROP_TO_ATTR = Object.keys(_ATTR_TO_PROP).reduce(function (inverted, attr) { |
| inverted[_ATTR_TO_PROP[attr]] = attr; |
| return inverted; |
| }, {}); |
| var DomElementSchemaRegistry = /** @class */ (function (_super) { |
| __extends(DomElementSchemaRegistry, _super); |
| function DomElementSchemaRegistry() { |
| var _this = _super.call(this) || this; |
| _this._schema = {}; |
| SCHEMA.forEach(function (encodedType) { |
| var type = {}; |
| var _b = __read(encodedType.split('|'), 2), strType = _b[0], strProperties = _b[1]; |
| var properties = strProperties.split(','); |
| var _c = __read(strType.split('^'), 2), typeNames = _c[0], superName = _c[1]; |
| typeNames.split(',').forEach(function (tag) { return _this._schema[tag.toLowerCase()] = type; }); |
| var superType = superName && _this._schema[superName.toLowerCase()]; |
| if (superType) { |
| Object.keys(superType).forEach(function (prop) { |
| type[prop] = superType[prop]; |
| }); |
| } |
| properties.forEach(function (property) { |
| if (property.length > 0) { |
| switch (property[0]) { |
| case '*': |
| // We don't yet support events. |
| // If ever allowing to bind to events, GO THROUGH A SECURITY REVIEW, allowing events |
| // will |
| // almost certainly introduce bad XSS vulnerabilities. |
| // type[property.substring(1)] = EVENT; |
| break; |
| case '!': |
| type[property.substring(1)] = BOOLEAN; |
| break; |
| case '#': |
| type[property.substring(1)] = NUMBER; |
| break; |
| case '%': |
| type[property.substring(1)] = OBJECT; |
| break; |
| default: |
| type[property] = STRING; |
| } |
| } |
| }); |
| }); |
| return _this; |
| } |
| DomElementSchemaRegistry.prototype.hasProperty = function (tagName, propName, schemaMetas) { |
| if (schemaMetas.some(function (schema) { return schema.name === NO_ERRORS_SCHEMA.name; })) { |
| return true; |
| } |
| if (tagName.indexOf('-') > -1) { |
| if (isNgContainer(tagName) || isNgContent(tagName)) { |
| return false; |
| } |
| if (schemaMetas.some(function (schema) { return schema.name === CUSTOM_ELEMENTS_SCHEMA.name; })) { |
| // Can't tell now as we don't know which properties a custom element will get |
| // once it is instantiated |
| return true; |
| } |
| } |
| var elementProperties = this._schema[tagName.toLowerCase()] || this._schema['unknown']; |
| return !!elementProperties[propName]; |
| }; |
| DomElementSchemaRegistry.prototype.hasElement = function (tagName, schemaMetas) { |
| if (schemaMetas.some(function (schema) { return schema.name === NO_ERRORS_SCHEMA.name; })) { |
| return true; |
| } |
| if (tagName.indexOf('-') > -1) { |
| if (isNgContainer(tagName) || isNgContent(tagName)) { |
| return true; |
| } |
| if (schemaMetas.some(function (schema) { return schema.name === CUSTOM_ELEMENTS_SCHEMA.name; })) { |
| // Allow any custom elements |
| return true; |
| } |
| } |
| return !!this._schema[tagName.toLowerCase()]; |
| }; |
| /** |
| * securityContext returns the security context for the given property on the given DOM tag. |
| * |
| * Tag and property name are statically known and cannot change at runtime, i.e. it is not |
| * possible to bind a value into a changing attribute or tag name. |
| * |
| * The filtering is based on a list of allowed tags|attributes. All attributes in the schema |
| * above are assumed to have the 'NONE' security context, i.e. that they are safe inert |
| * string values. Only specific well known attack vectors are assigned their appropriate context. |
| */ |
| DomElementSchemaRegistry.prototype.securityContext = function (tagName, propName, isAttribute) { |
| if (isAttribute) { |
| // NB: For security purposes, use the mapped property name, not the attribute name. |
| propName = this.getMappedPropName(propName); |
| } |
| // Make sure comparisons are case insensitive, so that case differences between attribute and |
| // property names do not have a security impact. |
| tagName = tagName.toLowerCase(); |
| propName = propName.toLowerCase(); |
| var ctx = SECURITY_SCHEMA()[tagName + '|' + propName]; |
| if (ctx) { |
| return ctx; |
| } |
| ctx = SECURITY_SCHEMA()['*|' + propName]; |
| return ctx ? ctx : SecurityContext.NONE; |
| }; |
| DomElementSchemaRegistry.prototype.getMappedPropName = function (propName) { |
| return _ATTR_TO_PROP[propName] || propName; |
| }; |
| DomElementSchemaRegistry.prototype.getDefaultComponentElementName = function () { |
| return 'ng-component'; |
| }; |
| DomElementSchemaRegistry.prototype.validateProperty = function (name) { |
| if (name.toLowerCase().startsWith('on')) { |
| var msg = "Binding to event property '" + name + "' is disallowed for security reasons, " + |
| ("please use (" + name.slice(2) + ")=...") + |
| ("\nIf '" + name + "' is a directive input, make sure the directive is imported by the") + |
| " current module."; |
| return { error: true, msg: msg }; |
| } |
| else { |
| return { error: false }; |
| } |
| }; |
| DomElementSchemaRegistry.prototype.validateAttribute = function (name) { |
| if (name.toLowerCase().startsWith('on')) { |
| var msg = "Binding to event attribute '" + name + "' is disallowed for security reasons, " + |
| ("please use (" + name.slice(2) + ")=..."); |
| return { error: true, msg: msg }; |
| } |
| else { |
| return { error: false }; |
| } |
| }; |
| DomElementSchemaRegistry.prototype.allKnownElementNames = function () { |
| return Object.keys(this._schema); |
| }; |
| DomElementSchemaRegistry.prototype.allKnownAttributesOfElement = function (tagName) { |
| var elementProperties = this._schema[tagName.toLowerCase()] || this._schema['unknown']; |
| // Convert properties to attributes. |
| return Object.keys(elementProperties).map(function (prop) { var _a; return (_a = _PROP_TO_ATTR[prop]) !== null && _a !== void 0 ? _a : prop; }); |
| }; |
| DomElementSchemaRegistry.prototype.normalizeAnimationStyleProperty = function (propName) { |
| return dashCaseToCamelCase(propName); |
| }; |
| DomElementSchemaRegistry.prototype.normalizeAnimationStyleValue = function (camelCaseProp, userProvidedProp, val) { |
| var unit = ''; |
| var strVal = val.toString().trim(); |
| var errorMsg = null; |
| if (_isPixelDimensionStyle(camelCaseProp) && val !== 0 && val !== '0') { |
| if (typeof val === 'number') { |
| unit = 'px'; |
| } |
| else { |
| var valAndSuffixMatch = val.match(/^[+-]?[\d\.]+([a-z]*)$/); |
| if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) { |
| errorMsg = "Please provide a CSS unit value for " + userProvidedProp + ":" + val; |
| } |
| } |
| } |
| return { error: errorMsg, value: strVal + unit }; |
| }; |
| return DomElementSchemaRegistry; |
| }(ElementSchemaRegistry)); |
| function _isPixelDimensionStyle(prop) { |
| switch (prop) { |
| case 'width': |
| case 'height': |
| case 'minWidth': |
| case 'minHeight': |
| case 'maxWidth': |
| case 'maxHeight': |
| case 'left': |
| case 'top': |
| case 'bottom': |
| case 'right': |
| case 'fontSize': |
| case 'outlineWidth': |
| case 'outlineOffset': |
| case 'paddingTop': |
| case 'paddingLeft': |
| case 'paddingBottom': |
| case 'paddingRight': |
| case 'marginTop': |
| case 'marginLeft': |
| case 'marginBottom': |
| case 'marginRight': |
| case 'borderRadius': |
| case 'borderWidth': |
| case 'borderTopWidth': |
| case 'borderLeftWidth': |
| case 'borderRightWidth': |
| case 'borderBottomWidth': |
| case 'textIndent': |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Set of tagName|propertyName corresponding to Trusted Types sinks. Properties applying to all |
| * tags use '*'. |
| * |
| * Extracted from, and should be kept in sync with |
| * https://w3c.github.io/webappsec-trusted-types/dist/spec/#integrations |
| */ |
| var TRUSTED_TYPES_SINKS = new Set([ |
| // NOTE: All strings in this set *must* be lowercase! |
| // TrustedHTML |
| 'iframe|srcdoc', |
| '*|innerhtml', |
| '*|outerhtml', |
| // NB: no TrustedScript here, as the corresponding tags are stripped by the compiler. |
| // TrustedScriptURL |
| 'embed|src', |
| 'object|codebase', |
| 'object|data', |
| ]); |
| /** |
| * isTrustedTypesSink returns true if the given property on the given DOM tag is a Trusted Types |
| * sink. In that case, use `ElementSchemaRegistry.securityContext` to determine which particular |
| * Trusted Type is required for values passed to the sink: |
| * - SecurityContext.HTML corresponds to TrustedHTML |
| * - SecurityContext.RESOURCE_URL corresponds to TrustedScriptURL |
| */ |
| function isTrustedTypesSink(tagName, propName) { |
| // Make sure comparisons are case insensitive, so that case differences between attribute and |
| // property names do not have a security impact. |
| tagName = tagName.toLowerCase(); |
| propName = propName.toLowerCase(); |
| return TRUSTED_TYPES_SINKS.has(tagName + '|' + propName) || |
| TRUSTED_TYPES_SINKS.has('*|' + propName); |
| } |
| |
| var BIND_NAME_REGEXP$1 = /^(?:(bind-)|(let-)|(ref-|#)|(on-)|(bindon-)|(@))(.*)$/; |
| // Group 1 = "bind-" |
| var KW_BIND_IDX$1 = 1; |
| // Group 2 = "let-" |
| var KW_LET_IDX$1 = 2; |
| // Group 3 = "ref-/#" |
| var KW_REF_IDX$1 = 3; |
| // Group 4 = "on-" |
| var KW_ON_IDX$1 = 4; |
| // Group 5 = "bindon-" |
| var KW_BINDON_IDX$1 = 5; |
| // Group 6 = "@" |
| var KW_AT_IDX$1 = 6; |
| // Group 7 = the identifier after "bind-", "let-", "ref-/#", "on-", "bindon-" or "@" |
| var IDENT_KW_IDX$1 = 7; |
| var BINDING_DELIMS = { |
| BANANA_BOX: { start: '[(', end: ')]' }, |
| PROPERTY: { start: '[', end: ']' }, |
| EVENT: { start: '(', end: ')' }, |
| }; |
| var TEMPLATE_ATTR_PREFIX$2 = '*'; |
| function htmlAstToRender3Ast(htmlNodes, bindingParser, options) { |
| var transformer = new HtmlAstToIvyAst(bindingParser, options); |
| var ivyNodes = visitAll$1(transformer, htmlNodes); |
| // Errors might originate in either the binding parser or the html to ivy transformer |
| var allErrors = bindingParser.errors.concat(transformer.errors); |
| var result = { |
| nodes: ivyNodes, |
| errors: allErrors, |
| styleUrls: transformer.styleUrls, |
| styles: transformer.styles, |
| ngContentSelectors: transformer.ngContentSelectors |
| }; |
| if (options.collectCommentNodes) { |
| result.commentNodes = transformer.commentNodes; |
| } |
| return result; |
| } |
| var HtmlAstToIvyAst = /** @class */ (function () { |
| function HtmlAstToIvyAst(bindingParser, options) { |
| this.bindingParser = bindingParser; |
| this.options = options; |
| this.errors = []; |
| this.styles = []; |
| this.styleUrls = []; |
| this.ngContentSelectors = []; |
| // This array will be populated if `Render3ParseOptions['collectCommentNodes']` is true |
| this.commentNodes = []; |
| this.inI18nBlock = false; |
| } |
| // HTML visitor |
| HtmlAstToIvyAst.prototype.visitElement = function (element) { |
| var e_1, _a; |
| var _this = this; |
| var isI18nRootElement = isI18nRootNode(element.i18n); |
| if (isI18nRootElement) { |
| if (this.inI18nBlock) { |
| this.reportError('Cannot mark an element as translatable inside of a translatable section. Please remove the nested i18n marker.', element.sourceSpan); |
| } |
| this.inI18nBlock = true; |
| } |
| var preparsedElement = preparseElement(element); |
| if (preparsedElement.type === PreparsedElementType.SCRIPT) { |
| return null; |
| } |
| else if (preparsedElement.type === PreparsedElementType.STYLE) { |
| var contents = textContents(element); |
| if (contents !== null) { |
| this.styles.push(contents); |
| } |
| return null; |
| } |
| else if (preparsedElement.type === PreparsedElementType.STYLESHEET && |
| isStyleUrlResolvable(preparsedElement.hrefAttr)) { |
| this.styleUrls.push(preparsedElement.hrefAttr); |
| return null; |
| } |
| // Whether the element is a `<ng-template>` |
| var isTemplateElement = isNgTemplate(element.name); |
| var parsedProperties = []; |
| var boundEvents = []; |
| var variables = []; |
| var references = []; |
| var attributes = []; |
| var i18nAttrsMeta = {}; |
| var templateParsedProperties = []; |
| var templateVariables = []; |
| // Whether the element has any *-attribute |
| var elementHasInlineTemplate = false; |
| try { |
| for (var _b = __values(element.attrs), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var attribute = _c.value; |
| var hasBinding = false; |
| var normalizedName = normalizeAttributeName(attribute.name); |
| // `*attr` defines template bindings |
| var isTemplateBinding = false; |
| if (attribute.i18n) { |
| i18nAttrsMeta[attribute.name] = attribute.i18n; |
| } |
| if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX$2)) { |
| // *-attributes |
| if (elementHasInlineTemplate) { |
| this.reportError("Can't have multiple template bindings on one element. Use only one attribute prefixed with *", attribute.sourceSpan); |
| } |
| isTemplateBinding = true; |
| elementHasInlineTemplate = true; |
| var templateValue = attribute.value; |
| var templateKey = normalizedName.substring(TEMPLATE_ATTR_PREFIX$2.length); |
| var parsedVariables = []; |
| var absoluteValueOffset = attribute.valueSpan ? |
| attribute.valueSpan.start.offset : |
| // If there is no value span the attribute does not have a value, like `attr` in |
| //`<div attr></div>`. In this case, point to one character beyond the last character of |
| // the attribute name. |
| attribute.sourceSpan.start.offset + attribute.name.length; |
| this.bindingParser.parseInlineTemplateBinding(templateKey, templateValue, attribute.sourceSpan, absoluteValueOffset, [], templateParsedProperties, parsedVariables, true /* isIvyAst */); |
| templateVariables.push.apply(templateVariables, __spread(parsedVariables.map(function (v) { return new Variable(v.name, v.value, v.sourceSpan, v.keySpan, v.valueSpan); }))); |
| } |
| else { |
| // Check for variables, events, property bindings, interpolation |
| hasBinding = this.parseAttribute(isTemplateElement, attribute, [], parsedProperties, boundEvents, variables, references); |
| } |
| if (!hasBinding && !isTemplateBinding) { |
| // don't include the bindings as attributes as well in the AST |
| attributes.push(this.visitAttribute(attribute)); |
| } |
| } |
| } |
| 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; } |
| } |
| var children = visitAll$1(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR$1 : this, element.children); |
| var parsedElement; |
| if (preparsedElement.type === PreparsedElementType.NG_CONTENT) { |
| // `<ng-content>` |
| if (element.children && |
| !element.children.every(function (node) { return isEmptyTextNode(node) || isCommentNode(node); })) { |
| this.reportError("<ng-content> element cannot have content.", element.sourceSpan); |
| } |
| var selector = preparsedElement.selectAttr; |
| var attrs = element.attrs.map(function (attr) { return _this.visitAttribute(attr); }); |
| parsedElement = new Content(selector, attrs, element.sourceSpan, element.i18n); |
| this.ngContentSelectors.push(selector); |
| } |
| else if (isTemplateElement) { |
| // `<ng-template>` |
| var attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta); |
| parsedElement = new Template(element.name, attributes, attrs.bound, boundEvents, [ /* no template attributes */], children, references, variables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); |
| } |
| else { |
| var attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta); |
| parsedElement = new Element(element.name, attributes, attrs.bound, boundEvents, children, references, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); |
| } |
| if (elementHasInlineTemplate) { |
| // If this node is an inline-template (e.g. has *ngFor) then we need to create a template |
| // node that contains this node. |
| // Moreover, if the node is an element, then we need to hoist its attributes to the template |
| // node for matching against content projection selectors. |
| var attrs = this.extractAttributes('ng-template', templateParsedProperties, i18nAttrsMeta); |
| var templateAttrs_1 = []; |
| attrs.literal.forEach(function (attr) { return templateAttrs_1.push(attr); }); |
| attrs.bound.forEach(function (attr) { return templateAttrs_1.push(attr); }); |
| var hoistedAttrs = parsedElement instanceof Element ? |
| { |
| attributes: parsedElement.attributes, |
| inputs: parsedElement.inputs, |
| outputs: parsedElement.outputs, |
| } : |
| { attributes: [], inputs: [], outputs: [] }; |
| // For <ng-template>s with structural directives on them, avoid passing i18n information to |
| // the wrapping template to prevent unnecessary i18n instructions from being generated. The |
| // necessary i18n meta information will be extracted from child elements. |
| var i18n = isTemplateElement && isI18nRootElement ? undefined : element.i18n; |
| // TODO(pk): test for this case |
| parsedElement = new Template(parsedElement.name, hoistedAttrs.attributes, hoistedAttrs.inputs, hoistedAttrs.outputs, templateAttrs_1, [parsedElement], [ /* no references */], templateVariables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, i18n); |
| } |
| if (isI18nRootElement) { |
| this.inI18nBlock = false; |
| } |
| return parsedElement; |
| }; |
| HtmlAstToIvyAst.prototype.visitAttribute = function (attribute) { |
| return new TextAttribute(attribute.name, attribute.value, attribute.sourceSpan, attribute.keySpan, attribute.valueSpan, attribute.i18n); |
| }; |
| HtmlAstToIvyAst.prototype.visitText = function (text) { |
| return this._visitTextWithInterpolation(text.value, text.sourceSpan, text.i18n); |
| }; |
| HtmlAstToIvyAst.prototype.visitExpansion = function (expansion) { |
| var _this = this; |
| if (!expansion.i18n) { |
| // do not generate Icu in case it was created |
| // outside of i18n block in a template |
| return null; |
| } |
| if (!isI18nRootNode(expansion.i18n)) { |
| throw new Error("Invalid type \"" + expansion.i18n.constructor + "\" for \"i18n\" property of " + expansion.sourceSpan.toString() + ". Expected a \"Message\""); |
| } |
| var message = expansion.i18n; |
| var vars = {}; |
| var placeholders = {}; |
| // extract VARs from ICUs - we process them separately while |
| // assembling resulting message via goog.getMsg function, since |
| // we need to pass them to top-level goog.getMsg call |
| Object.keys(message.placeholders).forEach(function (key) { |
| var value = message.placeholders[key]; |
| if (key.startsWith(I18N_ICU_VAR_PREFIX)) { |
| // Currently when the `plural` or `select` keywords in an ICU contain trailing spaces (e.g. |
| // `{count, select , ...}`), these spaces are also included into the key names in ICU vars |
| // (e.g. "VAR_SELECT "). These trailing spaces are not desirable, since they will later be |
| // converted into `_` symbols while normalizing placeholder names, which might lead to |
| // mismatches at runtime (i.e. placeholder will not be replaced with the correct value). |
| var formattedKey = key.trim(); |
| var ast = _this.bindingParser.parseInterpolationExpression(value.text, value.sourceSpan); |
| vars[formattedKey] = new BoundText(ast, value.sourceSpan); |
| } |
| else { |
| placeholders[key] = _this._visitTextWithInterpolation(value.text, value.sourceSpan); |
| } |
| }); |
| return new Icu(vars, placeholders, expansion.sourceSpan, message); |
| }; |
| HtmlAstToIvyAst.prototype.visitExpansionCase = function (expansionCase) { |
| return null; |
| }; |
| HtmlAstToIvyAst.prototype.visitComment = function (comment) { |
| if (this.options.collectCommentNodes) { |
| this.commentNodes.push(new Comment(comment.value || '', comment.sourceSpan)); |
| } |
| return null; |
| }; |
| // convert view engine `ParsedProperty` to a format suitable for IVY |
| HtmlAstToIvyAst.prototype.extractAttributes = function (elementName, properties, i18nPropsMeta) { |
| var _this = this; |
| var bound = []; |
| var literal = []; |
| properties.forEach(function (prop) { |
| var i18n = i18nPropsMeta[prop.name]; |
| if (prop.isLiteral) { |
| literal.push(new TextAttribute(prop.name, prop.expression.source || '', prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n)); |
| } |
| else { |
| // Note that validation is skipped and property mapping is disabled |
| // due to the fact that we need to make sure a given prop is not an |
| // input of a directive and directive matching happens at runtime. |
| var bep = _this.bindingParser.createBoundElementProperty(elementName, prop, /* skipValidation */ true, /* mapPropertyName */ false); |
| bound.push(BoundAttribute.fromBoundElementProperty(bep, i18n)); |
| } |
| }); |
| return { bound: bound, literal: literal }; |
| }; |
| HtmlAstToIvyAst.prototype.parseAttribute = function (isTemplateElement, attribute, matchableAttributes, parsedProperties, boundEvents, variables, references) { |
| var name = normalizeAttributeName(attribute.name); |
| var value = attribute.value; |
| var srcSpan = attribute.sourceSpan; |
| var absoluteOffset = attribute.valueSpan ? attribute.valueSpan.start.offset : srcSpan.start.offset; |
| function createKeySpan(srcSpan, prefix, identifier) { |
| // We need to adjust the start location for the keySpan to account for the removed 'data-' |
| // prefix from `normalizeAttributeName`. |
| var normalizationAdjustment = attribute.name.length - name.length; |
| var keySpanStart = srcSpan.start.moveBy(prefix.length + normalizationAdjustment); |
| var keySpanEnd = keySpanStart.moveBy(identifier.length); |
| return new ParseSourceSpan(keySpanStart, keySpanEnd, keySpanStart, identifier); |
| } |
| var bindParts = name.match(BIND_NAME_REGEXP$1); |
| if (bindParts) { |
| if (bindParts[KW_BIND_IDX$1] != null) { |
| var identifier = bindParts[IDENT_KW_IDX$1]; |
| var keySpan_1 = createKeySpan(srcSpan, bindParts[KW_BIND_IDX$1], identifier); |
| this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_1); |
| } |
| else if (bindParts[KW_LET_IDX$1]) { |
| if (isTemplateElement) { |
| var identifier = bindParts[IDENT_KW_IDX$1]; |
| var keySpan_2 = createKeySpan(srcSpan, bindParts[KW_LET_IDX$1], identifier); |
| this.parseVariable(identifier, value, srcSpan, keySpan_2, attribute.valueSpan, variables); |
| } |
| else { |
| this.reportError("\"let-\" is only supported on ng-template elements.", srcSpan); |
| } |
| } |
| else if (bindParts[KW_REF_IDX$1]) { |
| var identifier = bindParts[IDENT_KW_IDX$1]; |
| var keySpan_3 = createKeySpan(srcSpan, bindParts[KW_REF_IDX$1], identifier); |
| this.parseReference(identifier, value, srcSpan, keySpan_3, attribute.valueSpan, references); |
| } |
| else if (bindParts[KW_ON_IDX$1]) { |
| var events = []; |
| var identifier = bindParts[IDENT_KW_IDX$1]; |
| var keySpan_4 = createKeySpan(srcSpan, bindParts[KW_ON_IDX$1], identifier); |
| this.bindingParser.parseEvent(identifier, value, srcSpan, attribute.valueSpan || srcSpan, matchableAttributes, events, keySpan_4); |
| addEvents(events, boundEvents); |
| } |
| else if (bindParts[KW_BINDON_IDX$1]) { |
| var identifier = bindParts[IDENT_KW_IDX$1]; |
| var keySpan_5 = createKeySpan(srcSpan, bindParts[KW_BINDON_IDX$1], identifier); |
| this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_5); |
| this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan_5); |
| } |
| else if (bindParts[KW_AT_IDX$1]) { |
| var keySpan_6 = createKeySpan(srcSpan, '', name); |
| this.bindingParser.parseLiteralAttr(name, value, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_6); |
| } |
| return true; |
| } |
| // We didn't see a kw-prefixed property binding, but we have not yet checked |
| // for the []/()/[()] syntax. |
| var delims = null; |
| if (name.startsWith(BINDING_DELIMS.BANANA_BOX.start)) { |
| delims = BINDING_DELIMS.BANANA_BOX; |
| } |
| else if (name.startsWith(BINDING_DELIMS.PROPERTY.start)) { |
| delims = BINDING_DELIMS.PROPERTY; |
| } |
| else if (name.startsWith(BINDING_DELIMS.EVENT.start)) { |
| delims = BINDING_DELIMS.EVENT; |
| } |
| if (delims !== null && |
| // NOTE: older versions of the parser would match a start/end delimited |
| // binding iff the property name was terminated by the ending delimiter |
| // and the identifier in the binding was non-empty. |
| // TODO(ayazhafiz): update this to handle malformed bindings. |
| name.endsWith(delims.end) && name.length > delims.start.length + delims.end.length) { |
| var identifier = name.substring(delims.start.length, name.length - delims.end.length); |
| var keySpan_7 = createKeySpan(srcSpan, delims.start, identifier); |
| if (delims.start === BINDING_DELIMS.BANANA_BOX.start) { |
| this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_7); |
| this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan_7); |
| } |
| else if (delims.start === BINDING_DELIMS.PROPERTY.start) { |
| this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan_7); |
| } |
| else { |
| var events = []; |
| this.bindingParser.parseEvent(identifier, value, srcSpan, attribute.valueSpan || srcSpan, matchableAttributes, events, keySpan_7); |
| addEvents(events, boundEvents); |
| } |
| return true; |
| } |
| // No explicit binding found. |
| var keySpan = createKeySpan(srcSpan, '' /* prefix */, name); |
| var hasBinding = this.bindingParser.parsePropertyInterpolation(name, value, srcSpan, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan); |
| return hasBinding; |
| }; |
| HtmlAstToIvyAst.prototype._visitTextWithInterpolation = function (value, sourceSpan, i18n) { |
| var valueNoNgsp = replaceNgsp(value); |
| var expr = this.bindingParser.parseInterpolation(valueNoNgsp, sourceSpan); |
| return expr ? new BoundText(expr, sourceSpan, i18n) : new Text(valueNoNgsp, sourceSpan); |
| }; |
| HtmlAstToIvyAst.prototype.parseVariable = function (identifier, value, sourceSpan, keySpan, valueSpan, variables) { |
| if (identifier.indexOf('-') > -1) { |
| this.reportError("\"-\" is not allowed in variable names", sourceSpan); |
| } |
| else if (identifier.length === 0) { |
| this.reportError("Variable does not have a name", sourceSpan); |
| } |
| variables.push(new Variable(identifier, value, sourceSpan, keySpan, valueSpan)); |
| }; |
| HtmlAstToIvyAst.prototype.parseReference = function (identifier, value, sourceSpan, keySpan, valueSpan, references) { |
| if (identifier.indexOf('-') > -1) { |
| this.reportError("\"-\" is not allowed in reference names", sourceSpan); |
| } |
| else if (identifier.length === 0) { |
| this.reportError("Reference does not have a name", sourceSpan); |
| } |
| else if (references.some(function (reference) { return reference.name === identifier; })) { |
| this.reportError("Reference \"#" + identifier + "\" is defined more than once", sourceSpan); |
| } |
| references.push(new Reference(identifier, value, sourceSpan, keySpan, valueSpan)); |
| }; |
| HtmlAstToIvyAst.prototype.parseAssignmentEvent = function (name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) { |
| var events = []; |
| this.bindingParser.parseEvent(name + "Change", expression + "=$event", sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan); |
| addEvents(events, boundEvents); |
| }; |
| HtmlAstToIvyAst.prototype.reportError = function (message, sourceSpan, level) { |
| if (level === void 0) { level = exports.ParseErrorLevel.ERROR; } |
| this.errors.push(new ParseError(sourceSpan, message, level)); |
| }; |
| return HtmlAstToIvyAst; |
| }()); |
| var NonBindableVisitor$1 = /** @class */ (function () { |
| function NonBindableVisitor() { |
| } |
| NonBindableVisitor.prototype.visitElement = function (ast) { |
| var preparsedElement = preparseElement(ast); |
| if (preparsedElement.type === PreparsedElementType.SCRIPT || |
| preparsedElement.type === PreparsedElementType.STYLE || |
| preparsedElement.type === PreparsedElementType.STYLESHEET) { |
| // Skipping <script> for security reasons |
| // Skipping <style> and stylesheets as we already processed them |
| // in the StyleCompiler |
| return null; |
| } |
| var children = visitAll$1(this, ast.children, null); |
| return new Element(ast.name, visitAll$1(this, ast.attrs), |
| /* inputs */ [], /* outputs */ [], children, /* references */ [], ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan); |
| }; |
| NonBindableVisitor.prototype.visitComment = function (comment) { |
| return null; |
| }; |
| NonBindableVisitor.prototype.visitAttribute = function (attribute) { |
| return new TextAttribute(attribute.name, attribute.value, attribute.sourceSpan, attribute.keySpan, attribute.valueSpan, attribute.i18n); |
| }; |
| NonBindableVisitor.prototype.visitText = function (text) { |
| return new Text(text.value, text.sourceSpan); |
| }; |
| NonBindableVisitor.prototype.visitExpansion = function (expansion) { |
| return null; |
| }; |
| NonBindableVisitor.prototype.visitExpansionCase = function (expansionCase) { |
| return null; |
| }; |
| return NonBindableVisitor; |
| }()); |
| var NON_BINDABLE_VISITOR$1 = new NonBindableVisitor$1(); |
| function normalizeAttributeName(attrName) { |
| return /^data-/i.test(attrName) ? attrName.substring(5) : attrName; |
| } |
| function addEvents(events, boundEvents) { |
| boundEvents.push.apply(boundEvents, __spread(events.map(function (e) { return BoundEvent.fromParsedEvent(e); }))); |
| } |
| function isEmptyTextNode(node) { |
| return node instanceof Text$3 && node.value.trim().length == 0; |
| } |
| function isCommentNode(node) { |
| return node instanceof Comment$1; |
| } |
| function textContents(node) { |
| if (node.children.length !== 1 || !(node.children[0] instanceof Text$3)) { |
| return null; |
| } |
| else { |
| return node.children[0].value; |
| } |
| } |
| |
| var TagType; |
| (function (TagType) { |
| TagType[TagType["ELEMENT"] = 0] = "ELEMENT"; |
| TagType[TagType["TEMPLATE"] = 1] = "TEMPLATE"; |
| })(TagType || (TagType = {})); |
| /** |
| * Generates an object that is used as a shared state between parent and all child contexts. |
| */ |
| function setupRegistry() { |
| return { getUniqueId: getSeqNumberGenerator(), icus: new Map() }; |
| } |
| /** |
| * I18nContext is a helper class which keeps track of all i18n-related aspects |
| * (accumulates placeholders, bindings, etc) between i18nStart and i18nEnd instructions. |
| * |
| * When we enter a nested template, the top-level context is being passed down |
| * to the nested component, which uses this context to generate a child instance |
| * of I18nContext class (to handle nested template) and at the end, reconciles it back |
| * with the parent context. |
| * |
| * @param index Instruction index of i18nStart, which initiates this context |
| * @param ref Reference to a translation const that represents the content if thus context |
| * @param level Nestng level defined for child contexts |
| * @param templateIndex Instruction index of a template which this context belongs to |
| * @param meta Meta information (id, meaning, description, etc) associated with this context |
| */ |
| var I18nContext = /** @class */ (function () { |
| function I18nContext(index, ref, level, templateIndex, meta, registry) { |
| if (level === void 0) { level = 0; } |
| if (templateIndex === void 0) { templateIndex = null; } |
| this.index = index; |
| this.ref = ref; |
| this.level = level; |
| this.templateIndex = templateIndex; |
| this.meta = meta; |
| this.registry = registry; |
| this.bindings = new Set(); |
| this.placeholders = new Map(); |
| this.isEmitted = false; |
| this._unresolvedCtxCount = 0; |
| this._registry = registry || setupRegistry(); |
| this.id = this._registry.getUniqueId(); |
| } |
| I18nContext.prototype.appendTag = function (type, node, index, closed) { |
| if (node.isVoid && closed) { |
| return; // ignore "close" for void tags |
| } |
| var ph = node.isVoid || !closed ? node.startName : node.closeName; |
| var content = { type: type, index: index, ctx: this.id, isVoid: node.isVoid, closed: closed }; |
| updatePlaceholderMap(this.placeholders, ph, content); |
| }; |
| Object.defineProperty(I18nContext.prototype, "icus", { |
| get: function () { |
| return this._registry.icus; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(I18nContext.prototype, "isRoot", { |
| get: function () { |
| return this.level === 0; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| Object.defineProperty(I18nContext.prototype, "isResolved", { |
| get: function () { |
| return this._unresolvedCtxCount === 0; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| I18nContext.prototype.getSerializedPlaceholders = function () { |
| var result = new Map(); |
| this.placeholders.forEach(function (values, key) { return result.set(key, values.map(serializePlaceholderValue)); }); |
| return result; |
| }; |
| // public API to accumulate i18n-related content |
| I18nContext.prototype.appendBinding = function (binding) { |
| this.bindings.add(binding); |
| }; |
| I18nContext.prototype.appendIcu = function (name, ref) { |
| updatePlaceholderMap(this._registry.icus, name, ref); |
| }; |
| I18nContext.prototype.appendBoundText = function (node) { |
| var _this = this; |
| var phs = assembleBoundTextPlaceholders(node, this.bindings.size, this.id); |
| phs.forEach(function (values, key) { return updatePlaceholderMap.apply(void 0, __spread([_this.placeholders, key], values)); }); |
| }; |
| I18nContext.prototype.appendTemplate = function (node, index) { |
| // add open and close tags at the same time, |
| // since we process nested templates separately |
| this.appendTag(TagType.TEMPLATE, node, index, false); |
| this.appendTag(TagType.TEMPLATE, node, index, true); |
| this._unresolvedCtxCount++; |
| }; |
| I18nContext.prototype.appendElement = function (node, index, closed) { |
| this.appendTag(TagType.ELEMENT, node, index, closed); |
| }; |
| I18nContext.prototype.appendProjection = function (node, index) { |
| // Add open and close tags at the same time, since `<ng-content>` has no content, |
| // so when we come across `<ng-content>` we can register both open and close tags. |
| // Note: runtime i18n logic doesn't distinguish `<ng-content>` tag placeholders and |
| // regular element tag placeholders, so we generate element placeholders for both types. |
| this.appendTag(TagType.ELEMENT, node, index, false); |
| this.appendTag(TagType.ELEMENT, node, index, true); |
| }; |
| /** |
| * Generates an instance of a child context based on the root one, |
| * when we enter a nested template within I18n section. |
| * |
| * @param index Instruction index of corresponding i18nStart, which initiates this context |
| * @param templateIndex Instruction index of a template which this context belongs to |
| * @param meta Meta information (id, meaning, description, etc) associated with this context |
| * |
| * @returns I18nContext instance |
| */ |
| I18nContext.prototype.forkChildContext = function (index, templateIndex, meta) { |
| return new I18nContext(index, this.ref, this.level + 1, templateIndex, meta, this._registry); |
| }; |
| /** |
| * Reconciles child context into parent one once the end of the i18n block is reached (i18nEnd). |
| * |
| * @param context Child I18nContext instance to be reconciled with parent context. |
| */ |
| I18nContext.prototype.reconcileChildContext = function (context) { |
| var _this = this; |
| // set the right context id for open and close |
| // template tags, so we can use it as sub-block ids |
| ['start', 'close'].forEach(function (op) { |
| var key = context.meta[op + "Name"]; |
| var phs = _this.placeholders.get(key) || []; |
| var tag = phs.find(findTemplateFn(_this.id, context.templateIndex)); |
| if (tag) { |
| tag.ctx = context.id; |
| } |
| }); |
| // reconcile placeholders |
| var childPhs = context.placeholders; |
| childPhs.forEach(function (values, key) { |
| var phs = _this.placeholders.get(key); |
| if (!phs) { |
| _this.placeholders.set(key, values); |
| return; |
| } |
| // try to find matching template... |
| var tmplIdx = phs.findIndex(findTemplateFn(context.id, context.templateIndex)); |
| if (tmplIdx >= 0) { |
| // ... if found - replace it with nested template content |
| var isCloseTag = key.startsWith('CLOSE'); |
| var isTemplateTag = key.endsWith('NG-TEMPLATE'); |
| if (isTemplateTag) { |
| // current template's content is placed before or after |
| // parent template tag, depending on the open/close atrribute |
| phs.splice.apply(phs, __spread([tmplIdx + (isCloseTag ? 0 : 1), 0], values)); |
| } |
| else { |
| var idx = isCloseTag ? values.length - 1 : 0; |
| values[idx].tmpl = phs[tmplIdx]; |
| phs.splice.apply(phs, __spread([tmplIdx, 1], values)); |
| } |
| } |
| else { |
| // ... otherwise just append content to placeholder value |
| phs.push.apply(phs, __spread(values)); |
| } |
| _this.placeholders.set(key, phs); |
| }); |
| this._unresolvedCtxCount--; |
| }; |
| return I18nContext; |
| }()); |
| // |
| // Helper methods |
| // |
| function wrap(symbol, index, contextId, closed) { |
| var state = closed ? '/' : ''; |
| return wrapI18nPlaceholder("" + state + symbol + index, contextId); |
| } |
| function wrapTag(symbol, _a, closed) { |
| var index = _a.index, ctx = _a.ctx, isVoid = _a.isVoid; |
| return isVoid ? wrap(symbol, index, ctx) + wrap(symbol, index, ctx, true) : |
| wrap(symbol, index, ctx, closed); |
| } |
| function findTemplateFn(ctx, templateIndex) { |
| return function (token) { return typeof token === 'object' && token.type === TagType.TEMPLATE && |
| token.index === templateIndex && token.ctx === ctx; }; |
| } |
| function serializePlaceholderValue(value) { |
| var element = function (data, closed) { return wrapTag('#', data, closed); }; |
| var template = function (data, closed) { return wrapTag('*', data, closed); }; |
| var projection = function (data, closed) { return wrapTag('!', data, closed); }; |
| switch (value.type) { |
| case TagType.ELEMENT: |
| // close element tag |
| if (value.closed) { |
| return element(value, true) + (value.tmpl ? template(value.tmpl, true) : ''); |
| } |
| // open element tag that also initiates a template |
| if (value.tmpl) { |
| return template(value.tmpl) + element(value) + |
| (value.isVoid ? template(value.tmpl, true) : ''); |
| } |
| return element(value); |
| case TagType.TEMPLATE: |
| return template(value, value.closed); |
| default: |
| return value; |
| } |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var IcuSerializerVisitor = /** @class */ (function () { |
| function IcuSerializerVisitor() { |
| } |
| IcuSerializerVisitor.prototype.visitText = function (text) { |
| return text.value; |
| }; |
| IcuSerializerVisitor.prototype.visitContainer = function (container) { |
| var _this = this; |
| return container.children.map(function (child) { return child.visit(_this); }).join(''); |
| }; |
| IcuSerializerVisitor.prototype.visitIcu = function (icu) { |
| var _this = this; |
| var strCases = Object.keys(icu.cases).map(function (k) { return k + " {" + icu.cases[k].visit(_this) + "}"; }); |
| var result = "{" + icu.expressionPlaceholder + ", " + icu.type + ", " + strCases.join(' ') + "}"; |
| return result; |
| }; |
| IcuSerializerVisitor.prototype.visitTagPlaceholder = function (ph) { |
| var _this = this; |
| return ph.isVoid ? |
| this.formatPh(ph.startName) : |
| "" + this.formatPh(ph.startName) + ph.children.map(function (child) { return child.visit(_this); }).join('') + this.formatPh(ph.closeName); |
| }; |
| IcuSerializerVisitor.prototype.visitPlaceholder = function (ph) { |
| return this.formatPh(ph.name); |
| }; |
| IcuSerializerVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| return this.formatPh(ph.name); |
| }; |
| IcuSerializerVisitor.prototype.formatPh = function (value) { |
| return "{" + formatI18nPlaceholderName(value, /* useCamelCase */ false) + "}"; |
| }; |
| return IcuSerializerVisitor; |
| }()); |
| var serializer = new IcuSerializerVisitor(); |
| function serializeIcuNode(icu) { |
| return icu.visit(serializer); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var TAG_TO_PLACEHOLDER_NAMES = { |
| 'A': 'LINK', |
| 'B': 'BOLD_TEXT', |
| 'BR': 'LINE_BREAK', |
| 'EM': 'EMPHASISED_TEXT', |
| 'H1': 'HEADING_LEVEL1', |
| 'H2': 'HEADING_LEVEL2', |
| 'H3': 'HEADING_LEVEL3', |
| 'H4': 'HEADING_LEVEL4', |
| 'H5': 'HEADING_LEVEL5', |
| 'H6': 'HEADING_LEVEL6', |
| 'HR': 'HORIZONTAL_RULE', |
| 'I': 'ITALIC_TEXT', |
| 'LI': 'LIST_ITEM', |
| 'LINK': 'MEDIA_LINK', |
| 'OL': 'ORDERED_LIST', |
| 'P': 'PARAGRAPH', |
| 'Q': 'QUOTATION', |
| 'S': 'STRIKETHROUGH_TEXT', |
| 'SMALL': 'SMALL_TEXT', |
| 'SUB': 'SUBSTRIPT', |
| 'SUP': 'SUPERSCRIPT', |
| 'TBODY': 'TABLE_BODY', |
| 'TD': 'TABLE_CELL', |
| 'TFOOT': 'TABLE_FOOTER', |
| 'TH': 'TABLE_HEADER_CELL', |
| 'THEAD': 'TABLE_HEADER', |
| 'TR': 'TABLE_ROW', |
| 'TT': 'MONOSPACED_TEXT', |
| 'U': 'UNDERLINED_TEXT', |
| 'UL': 'UNORDERED_LIST', |
| }; |
| /** |
| * Creates unique names for placeholder with different content. |
| * |
| * Returns the same placeholder name when the content is identical. |
| */ |
| var PlaceholderRegistry = /** @class */ (function () { |
| function PlaceholderRegistry() { |
| // Count the occurrence of the base name top generate a unique name |
| this._placeHolderNameCounts = {}; |
| // Maps signature to placeholder names |
| this._signatureToName = {}; |
| } |
| PlaceholderRegistry.prototype.getStartTagPlaceholderName = function (tag, attrs, isVoid) { |
| var signature = this._hashTag(tag, attrs, isVoid); |
| if (this._signatureToName[signature]) { |
| return this._signatureToName[signature]; |
| } |
| var upperTag = tag.toUpperCase(); |
| var baseName = TAG_TO_PLACEHOLDER_NAMES[upperTag] || "TAG_" + upperTag; |
| var name = this._generateUniqueName(isVoid ? baseName : "START_" + baseName); |
| this._signatureToName[signature] = name; |
| return name; |
| }; |
| PlaceholderRegistry.prototype.getCloseTagPlaceholderName = function (tag) { |
| var signature = this._hashClosingTag(tag); |
| if (this._signatureToName[signature]) { |
| return this._signatureToName[signature]; |
| } |
| var upperTag = tag.toUpperCase(); |
| var baseName = TAG_TO_PLACEHOLDER_NAMES[upperTag] || "TAG_" + upperTag; |
| var name = this._generateUniqueName("CLOSE_" + baseName); |
| this._signatureToName[signature] = name; |
| return name; |
| }; |
| PlaceholderRegistry.prototype.getPlaceholderName = function (name, content) { |
| var upperName = name.toUpperCase(); |
| var signature = "PH: " + upperName + "=" + content; |
| if (this._signatureToName[signature]) { |
| return this._signatureToName[signature]; |
| } |
| var uniqueName = this._generateUniqueName(upperName); |
| this._signatureToName[signature] = uniqueName; |
| return uniqueName; |
| }; |
| PlaceholderRegistry.prototype.getUniquePlaceholder = function (name) { |
| return this._generateUniqueName(name.toUpperCase()); |
| }; |
| // Generate a hash for a tag - does not take attribute order into account |
| PlaceholderRegistry.prototype._hashTag = function (tag, attrs, isVoid) { |
| var start = "<" + tag; |
| var strAttrs = Object.keys(attrs).sort().map(function (name) { return " " + name + "=" + attrs[name]; }).join(''); |
| var end = isVoid ? '/>' : "></" + tag + ">"; |
| return start + strAttrs + end; |
| }; |
| PlaceholderRegistry.prototype._hashClosingTag = function (tag) { |
| return this._hashTag("/" + tag, {}, false); |
| }; |
| PlaceholderRegistry.prototype._generateUniqueName = function (base) { |
| var seen = this._placeHolderNameCounts.hasOwnProperty(base); |
| if (!seen) { |
| this._placeHolderNameCounts[base] = 1; |
| return base; |
| } |
| var id = this._placeHolderNameCounts[base]; |
| this._placeHolderNameCounts[base] = id + 1; |
| return base + "_" + id; |
| }; |
| return PlaceholderRegistry; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var _expParser = new Parser$1(new Lexer()); |
| /** |
| * Returns a function converting html nodes to an i18n Message given an interpolationConfig |
| */ |
| function createI18nMessageFactory(interpolationConfig) { |
| var visitor = new _I18nVisitor(_expParser, interpolationConfig); |
| return function (nodes, meaning, description, customId, visitNodeFn) { return visitor.toI18nMessage(nodes, meaning, description, customId, visitNodeFn); }; |
| } |
| function noopVisitNodeFn(_html, i18n) { |
| return i18n; |
| } |
| var _I18nVisitor = /** @class */ (function () { |
| function _I18nVisitor(_expressionParser, _interpolationConfig) { |
| this._expressionParser = _expressionParser; |
| this._interpolationConfig = _interpolationConfig; |
| } |
| _I18nVisitor.prototype.toI18nMessage = function (nodes, meaning, description, customId, visitNodeFn) { |
| if (meaning === void 0) { meaning = ''; } |
| if (description === void 0) { description = ''; } |
| if (customId === void 0) { customId = ''; } |
| var context = { |
| isIcu: nodes.length == 1 && nodes[0] instanceof Expansion, |
| icuDepth: 0, |
| placeholderRegistry: new PlaceholderRegistry(), |
| placeholderToContent: {}, |
| placeholderToMessage: {}, |
| visitNodeFn: visitNodeFn || noopVisitNodeFn, |
| }; |
| var i18nodes = visitAll$1(this, nodes, context); |
| return new Message(i18nodes, context.placeholderToContent, context.placeholderToMessage, meaning, description, customId); |
| }; |
| _I18nVisitor.prototype.visitElement = function (el, context) { |
| var _a; |
| var children = visitAll$1(this, el.children, context); |
| var attrs = {}; |
| el.attrs.forEach(function (attr) { |
| // Do not visit the attributes, translatable ones are top-level ASTs |
| attrs[attr.name] = attr.value; |
| }); |
| var isVoid = getHtmlTagDefinition(el.name).isVoid; |
| var startPhName = context.placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid); |
| context.placeholderToContent[startPhName] = { |
| text: el.startSourceSpan.toString(), |
| sourceSpan: el.startSourceSpan, |
| }; |
| var closePhName = ''; |
| if (!isVoid) { |
| closePhName = context.placeholderRegistry.getCloseTagPlaceholderName(el.name); |
| context.placeholderToContent[closePhName] = { |
| text: "</" + el.name + ">", |
| sourceSpan: (_a = el.endSourceSpan) !== null && _a !== void 0 ? _a : el.sourceSpan, |
| }; |
| } |
| var node = new TagPlaceholder(el.name, attrs, startPhName, closePhName, children, isVoid, el.sourceSpan, el.startSourceSpan, el.endSourceSpan); |
| return context.visitNodeFn(el, node); |
| }; |
| _I18nVisitor.prototype.visitAttribute = function (attribute, context) { |
| var node = this._visitTextWithInterpolation(attribute.value, attribute.valueSpan || attribute.sourceSpan, context, attribute.i18n); |
| return context.visitNodeFn(attribute, node); |
| }; |
| _I18nVisitor.prototype.visitText = function (text, context) { |
| var node = this._visitTextWithInterpolation(text.value, text.sourceSpan, context, text.i18n); |
| return context.visitNodeFn(text, node); |
| }; |
| _I18nVisitor.prototype.visitComment = function (comment, context) { |
| return null; |
| }; |
| _I18nVisitor.prototype.visitExpansion = function (icu, context) { |
| var _this = this; |
| context.icuDepth++; |
| var i18nIcuCases = {}; |
| var i18nIcu = new Icu$1(icu.switchValue, icu.type, i18nIcuCases, icu.sourceSpan); |
| icu.cases.forEach(function (caze) { |
| i18nIcuCases[caze.value] = new Container(caze.expression.map(function (node) { return node.visit(_this, context); }), caze.expSourceSpan); |
| }); |
| context.icuDepth--; |
| if (context.isIcu || context.icuDepth > 0) { |
| // Returns an ICU node when: |
| // - the message (vs a part of the message) is an ICU message, or |
| // - the ICU message is nested. |
| var expPh = context.placeholderRegistry.getUniquePlaceholder("VAR_" + icu.type); |
| i18nIcu.expressionPlaceholder = expPh; |
| context.placeholderToContent[expPh] = { |
| text: icu.switchValue, |
| sourceSpan: icu.switchValueSourceSpan, |
| }; |
| return context.visitNodeFn(icu, i18nIcu); |
| } |
| // Else returns a placeholder |
| // ICU placeholders should not be replaced with their original content but with the their |
| // translations. |
| // TODO(vicb): add a html.Node -> i18n.Message cache to avoid having to re-create the msg |
| var phName = context.placeholderRegistry.getPlaceholderName('ICU', icu.sourceSpan.toString()); |
| context.placeholderToMessage[phName] = this.toI18nMessage([icu], '', '', '', undefined); |
| var node = new IcuPlaceholder(i18nIcu, phName, icu.sourceSpan); |
| return context.visitNodeFn(icu, node); |
| }; |
| _I18nVisitor.prototype.visitExpansionCase = function (_icuCase, _context) { |
| throw new Error('Unreachable code'); |
| }; |
| /** |
| * Split the, potentially interpolated, text up into text and placeholder pieces. |
| * |
| * @param text The potentially interpolated string to be split. |
| * @param sourceSpan The span of the whole of the `text` string. |
| * @param context The current context of the visitor, used to compute and store placeholders. |
| * @param previousI18n Any i18n metadata associated with this `text` from a previous pass. |
| */ |
| _I18nVisitor.prototype._visitTextWithInterpolation = function (text, sourceSpan, context, previousI18n) { |
| var _b = this._expressionParser.splitInterpolation(text, sourceSpan.start.toString(), this._interpolationConfig), strings = _b.strings, expressions = _b.expressions; |
| // No expressions, return a single text. |
| if (expressions.length === 0) { |
| return new Text$1(text, sourceSpan); |
| } |
| // Return a sequence of `Text` and `Placeholder` nodes grouped in a `Container`. |
| var nodes = []; |
| for (var i = 0; i < strings.length - 1; i++) { |
| this._addText(nodes, strings[i], sourceSpan); |
| this._addPlaceholder(nodes, context, expressions[i], sourceSpan); |
| } |
| // The last index contains no expression |
| this._addText(nodes, strings[strings.length - 1], sourceSpan); |
| // Whitespace removal may have invalidated the interpolation source-spans. |
| reusePreviousSourceSpans(nodes, previousI18n); |
| return new Container(nodes, sourceSpan); |
| }; |
| /** |
| * Create a new `Text` node from the `textPiece` and add it to the `nodes` collection. |
| * |
| * @param nodes The nodes to which the created `Text` node should be added. |
| * @param textPiece The text and relative span information for this `Text` node. |
| * @param interpolationSpan The span of the whole interpolated text. |
| */ |
| _I18nVisitor.prototype._addText = function (nodes, textPiece, interpolationSpan) { |
| if (textPiece.text.length > 0) { |
| // No need to add empty strings |
| var stringSpan = getOffsetSourceSpan(interpolationSpan, textPiece); |
| nodes.push(new Text$1(textPiece.text, stringSpan)); |
| } |
| }; |
| /** |
| * Create a new `Placeholder` node from the `expression` and add it to the `nodes` collection. |
| * |
| * @param nodes The nodes to which the created `Text` node should be added. |
| * @param context The current context of the visitor, used to compute and store placeholders. |
| * @param expression The expression text and relative span information for this `Placeholder` |
| * node. |
| * @param interpolationSpan The span of the whole interpolated text. |
| */ |
| _I18nVisitor.prototype._addPlaceholder = function (nodes, context, expression, interpolationSpan) { |
| var sourceSpan = getOffsetSourceSpan(interpolationSpan, expression); |
| var baseName = extractPlaceholderName(expression.text) || 'INTERPOLATION'; |
| var phName = context.placeholderRegistry.getPlaceholderName(baseName, expression.text); |
| var text = this._interpolationConfig.start + expression.text + this._interpolationConfig.end; |
| context.placeholderToContent[phName] = { text: text, sourceSpan: sourceSpan }; |
| nodes.push(new Placeholder(expression.text, phName, sourceSpan)); |
| }; |
| return _I18nVisitor; |
| }()); |
| /** |
| * Re-use the source-spans from `previousI18n` metadata for the `nodes`. |
| * |
| * Whitespace removal can invalidate the source-spans of interpolation nodes, so we |
| * reuse the source-span stored from a previous pass before the whitespace was removed. |
| * |
| * @param nodes The `Text` and `Placeholder` nodes to be processed. |
| * @param previousI18n Any i18n metadata for these `nodes` stored from a previous pass. |
| */ |
| function reusePreviousSourceSpans(nodes, previousI18n) { |
| if (previousI18n instanceof Message) { |
| // The `previousI18n` is an i18n `Message`, so we are processing an `Attribute` with i18n |
| // metadata. The `Message` should consist only of a single `Container` that contains the |
| // parts (`Text` and `Placeholder`) to process. |
| assertSingleContainerMessage(previousI18n); |
| previousI18n = previousI18n.nodes[0]; |
| } |
| if (previousI18n instanceof Container) { |
| // The `previousI18n` is a `Container`, which means that this is a second i18n extraction pass |
| // after whitespace has been removed from the AST ndoes. |
| assertEquivalentNodes(previousI18n.children, nodes); |
| // Reuse the source-spans from the first pass. |
| for (var i = 0; i < nodes.length; i++) { |
| nodes[i].sourceSpan = previousI18n.children[i].sourceSpan; |
| } |
| } |
| } |
| /** |
| * Asserts that the `message` contains exactly one `Container` node. |
| */ |
| function assertSingleContainerMessage(message) { |
| var nodes = message.nodes; |
| if (nodes.length !== 1 || !(nodes[0] instanceof Container)) { |
| throw new Error('Unexpected previous i18n message - expected it to consist of only a single `Container` node.'); |
| } |
| } |
| /** |
| * Asserts that the `previousNodes` and `node` collections have the same number of elements and |
| * corresponding elements have the same node type. |
| */ |
| function assertEquivalentNodes(previousNodes, nodes) { |
| if (previousNodes.length !== nodes.length) { |
| throw new Error('The number of i18n message children changed between first and second pass.'); |
| } |
| if (previousNodes.some(function (node, i) { return nodes[i].constructor !== node.constructor; })) { |
| throw new Error('The types of the i18n message children changed between first and second pass.'); |
| } |
| } |
| /** |
| * Create a new `ParseSourceSpan` from the `sourceSpan`, offset by the `start` and `end` values. |
| */ |
| function getOffsetSourceSpan(sourceSpan, _b) { |
| var start = _b.start, end = _b.end; |
| return new ParseSourceSpan(sourceSpan.fullStart.moveBy(start), sourceSpan.fullStart.moveBy(end)); |
| } |
| var _CUSTOM_PH_EXP = /\/\/[\s\S]*i18n[\s\S]*\([\s\S]*ph[\s\S]*=[\s\S]*("|')([\s\S]*?)\1[\s\S]*\)/g; |
| function extractPlaceholderName(input) { |
| return input.split(_CUSTOM_PH_EXP)[2]; |
| } |
| |
| /** |
| * An i18n error. |
| */ |
| var I18nError = /** @class */ (function (_super) { |
| __extends(I18nError, _super); |
| function I18nError(span, msg) { |
| return _super.call(this, span, msg) || this; |
| } |
| return I18nError; |
| }(ParseError)); |
| |
| var setI18nRefs = function (htmlNode, i18nNode) { |
| if (htmlNode instanceof NodeWithI18n) { |
| if (i18nNode instanceof IcuPlaceholder && htmlNode.i18n instanceof Message) { |
| // This html node represents an ICU but this is a second processing pass, and the legacy id |
| // was computed in the previous pass and stored in the `i18n` property as a message. |
| // We are about to wipe out that property so capture the previous message to be reused when |
| // generating the message for this ICU later. See `_generateI18nMessage()`. |
| i18nNode.previousMessage = htmlNode.i18n; |
| } |
| htmlNode.i18n = i18nNode; |
| } |
| return i18nNode; |
| }; |
| /** |
| * This visitor walks over HTML parse tree and converts information stored in |
| * i18n-related attributes ("i18n" and "i18n-*") into i18n meta object that is |
| * stored with other element's and attribute's information. |
| */ |
| var I18nMetaVisitor = /** @class */ (function () { |
| function I18nMetaVisitor(interpolationConfig, keepI18nAttrs, enableI18nLegacyMessageIdFormat) { |
| if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } |
| if (keepI18nAttrs === void 0) { keepI18nAttrs = false; } |
| if (enableI18nLegacyMessageIdFormat === void 0) { enableI18nLegacyMessageIdFormat = false; } |
| this.interpolationConfig = interpolationConfig; |
| this.keepI18nAttrs = keepI18nAttrs; |
| this.enableI18nLegacyMessageIdFormat = enableI18nLegacyMessageIdFormat; |
| // whether visited nodes contain i18n information |
| this.hasI18nMeta = false; |
| this._errors = []; |
| // i18n message generation factory |
| this._createI18nMessage = createI18nMessageFactory(this.interpolationConfig); |
| } |
| I18nMetaVisitor.prototype._generateI18nMessage = function (nodes, meta, visitNodeFn) { |
| if (meta === void 0) { meta = ''; } |
| var _a = this._parseMetadata(meta), meaning = _a.meaning, description = _a.description, customId = _a.customId; |
| var message = this._createI18nMessage(nodes, meaning, description, customId, visitNodeFn); |
| this._setMessageId(message, meta); |
| this._setLegacyIds(message, meta); |
| return message; |
| }; |
| I18nMetaVisitor.prototype.visitAllWithErrors = function (nodes) { |
| var _this = this; |
| var result = nodes.map(function (node) { return node.visit(_this, null); }); |
| return new ParseTreeResult(result, this._errors); |
| }; |
| I18nMetaVisitor.prototype.visitElement = function (element) { |
| var e_1, _a, e_2, _b; |
| if (hasI18nAttrs(element)) { |
| this.hasI18nMeta = true; |
| var attrs = []; |
| var attrsMeta = {}; |
| try { |
| for (var _c = __values(element.attrs), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var attr = _d.value; |
| if (attr.name === I18N_ATTR) { |
| // root 'i18n' node attribute |
| var i18n_1 = element.i18n || attr.value; |
| var message = this._generateI18nMessage(element.children, i18n_1, setI18nRefs); |
| // do not assign empty i18n meta |
| if (message.nodes.length) { |
| element.i18n = message; |
| } |
| } |
| else if (attr.name.startsWith(I18N_ATTR_PREFIX)) { |
| // 'i18n-*' attributes |
| var name = attr.name.slice(I18N_ATTR_PREFIX.length); |
| if (isTrustedTypesSink(element.name, name)) { |
| this._reportError(attr, "Translating attribute '" + name + "' is disallowed for security reasons."); |
| } |
| else { |
| attrsMeta[name] = attr.value; |
| } |
| } |
| else { |
| // non-i18n attributes |
| attrs.push(attr); |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_a = _c.return)) _a.call(_c); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| // set i18n meta for attributes |
| if (Object.keys(attrsMeta).length) { |
| try { |
| for (var attrs_1 = __values(attrs), attrs_1_1 = attrs_1.next(); !attrs_1_1.done; attrs_1_1 = attrs_1.next()) { |
| var attr = attrs_1_1.value; |
| var meta = attrsMeta[attr.name]; |
| // do not create translation for empty attributes |
| if (meta !== undefined && attr.value) { |
| attr.i18n = this._generateI18nMessage([attr], attr.i18n || meta); |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (attrs_1_1 && !attrs_1_1.done && (_b = attrs_1.return)) _b.call(attrs_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| } |
| if (!this.keepI18nAttrs) { |
| // update element's attributes, |
| // keeping only non-i18n related ones |
| element.attrs = attrs; |
| } |
| } |
| visitAll$1(this, element.children, element.i18n); |
| return element; |
| }; |
| I18nMetaVisitor.prototype.visitExpansion = function (expansion, currentMessage) { |
| var message; |
| var meta = expansion.i18n; |
| this.hasI18nMeta = true; |
| if (meta instanceof IcuPlaceholder) { |
| // set ICU placeholder name (e.g. "ICU_1"), |
| // generated while processing root element contents, |
| // so we can reference it when we output translation |
| var name = meta.name; |
| message = this._generateI18nMessage([expansion], meta); |
| var icu = icuFromI18nMessage(message); |
| icu.name = name; |
| } |
| else { |
| // ICU is a top level message, try to use metadata from container element if provided via |
| // `context` argument. Note: context may not be available for standalone ICUs (without |
| // wrapping element), so fallback to ICU metadata in this case. |
| message = this._generateI18nMessage([expansion], currentMessage || meta); |
| } |
| expansion.i18n = message; |
| return expansion; |
| }; |
| I18nMetaVisitor.prototype.visitText = function (text) { |
| return text; |
| }; |
| I18nMetaVisitor.prototype.visitAttribute = function (attribute) { |
| return attribute; |
| }; |
| I18nMetaVisitor.prototype.visitComment = function (comment) { |
| return comment; |
| }; |
| I18nMetaVisitor.prototype.visitExpansionCase = function (expansionCase) { |
| return expansionCase; |
| }; |
| /** |
| * Parse the general form `meta` passed into extract the explicit metadata needed to create a |
| * `Message`. |
| * |
| * There are three possibilities for the `meta` variable |
| * 1) a string from an `i18n` template attribute: parse it to extract the metadata values. |
| * 2) a `Message` from a previous processing pass: reuse the metadata values in the message. |
| * 4) other: ignore this and just process the message metadata as normal |
| * |
| * @param meta the bucket that holds information about the message |
| * @returns the parsed metadata. |
| */ |
| I18nMetaVisitor.prototype._parseMetadata = function (meta) { |
| return typeof meta === 'string' ? parseI18nMeta(meta) : |
| meta instanceof Message ? meta : {}; |
| }; |
| /** |
| * Generate (or restore) message id if not specified already. |
| */ |
| I18nMetaVisitor.prototype._setMessageId = function (message, meta) { |
| if (!message.id) { |
| message.id = meta instanceof Message && meta.id || decimalDigest(message); |
| } |
| }; |
| /** |
| * Update the `message` with a `legacyId` if necessary. |
| * |
| * @param message the message whose legacy id should be set |
| * @param meta information about the message being processed |
| */ |
| I18nMetaVisitor.prototype._setLegacyIds = function (message, meta) { |
| if (this.enableI18nLegacyMessageIdFormat) { |
| message.legacyIds = [computeDigest(message), computeDecimalDigest(message)]; |
| } |
| else if (typeof meta !== 'string') { |
| // This occurs if we are doing the 2nd pass after whitespace removal (see `parseTemplate()` in |
| // `packages/compiler/src/render3/view/template.ts`). |
| // In that case we want to reuse the legacy message generated in the 1st pass (see |
| // `setI18nRefs()`). |
| var previousMessage = meta instanceof Message ? |
| meta : |
| meta instanceof IcuPlaceholder ? meta.previousMessage : undefined; |
| message.legacyIds = previousMessage ? previousMessage.legacyIds : []; |
| } |
| }; |
| I18nMetaVisitor.prototype._reportError = function (node, msg) { |
| this._errors.push(new I18nError(node.sourceSpan, msg)); |
| }; |
| return I18nMetaVisitor; |
| }()); |
| /** I18n separators for metadata **/ |
| var I18N_MEANING_SEPARATOR = '|'; |
| var I18N_ID_SEPARATOR = '@@'; |
| /** |
| * Parses i18n metas like: |
| * - "@@id", |
| * - "description[@@id]", |
| * - "meaning|description[@@id]" |
| * and returns an object with parsed output. |
| * |
| * @param meta String that represents i18n meta |
| * @returns Object with id, meaning and description fields |
| */ |
| function parseI18nMeta(meta) { |
| var _a, _b; |
| if (meta === void 0) { meta = ''; } |
| var customId; |
| var meaning; |
| var description; |
| meta = meta.trim(); |
| if (meta) { |
| var idIndex = meta.indexOf(I18N_ID_SEPARATOR); |
| var descIndex = meta.indexOf(I18N_MEANING_SEPARATOR); |
| var meaningAndDesc = void 0; |
| _a = __read((idIndex > -1) ? [meta.slice(0, idIndex), meta.slice(idIndex + 2)] : [meta, ''], 2), meaningAndDesc = _a[0], customId = _a[1]; |
| _b = __read((descIndex > -1) ? |
| [meaningAndDesc.slice(0, descIndex), meaningAndDesc.slice(descIndex + 1)] : |
| ['', meaningAndDesc], 2), meaning = _b[0], description = _b[1]; |
| } |
| return { customId: customId, meaning: meaning, description: description }; |
| } |
| // Converts i18n meta information for a message (id, description, meaning) |
| // to a JsDoc statement formatted as expected by the Closure compiler. |
| function i18nMetaToJSDoc(meta) { |
| var tags = []; |
| if (meta.description) { |
| tags.push({ tagName: "desc" /* Desc */, text: meta.description }); |
| } |
| if (meta.meaning) { |
| tags.push({ tagName: "meaning" /* Meaning */, text: meta.meaning }); |
| } |
| return tags.length == 0 ? null : jsDocComment(tags); |
| } |
| |
| /** Closure uses `goog.getMsg(message)` to lookup translations */ |
| var GOOG_GET_MSG = 'goog.getMsg'; |
| function createGoogleGetMsgStatements(variable$1, message, closureVar, params) { |
| var messageString = serializeI18nMessageForGetMsg(message); |
| var args = [literal(messageString)]; |
| if (Object.keys(params).length) { |
| args.push(mapLiteral(params, true)); |
| } |
| // /** |
| // * @desc description of message |
| // * @meaning meaning of message |
| // */ |
| // const MSG_... = goog.getMsg(..); |
| // I18N_X = MSG_...; |
| var googGetMsgStmt = closureVar.set(variable(GOOG_GET_MSG).callFn(args)).toConstDecl(); |
| var metaComment = i18nMetaToJSDoc(message); |
| if (metaComment !== null) { |
| googGetMsgStmt.addLeadingComment(metaComment); |
| } |
| var i18nAssignmentStmt = new ExpressionStatement(variable$1.set(closureVar)); |
| return [googGetMsgStmt, i18nAssignmentStmt]; |
| } |
| /** |
| * This visitor walks over i18n tree and generates its string representation, including ICUs and |
| * placeholders in `{$placeholder}` (for plain messages) or `{PLACEHOLDER}` (inside ICUs) format. |
| */ |
| var GetMsgSerializerVisitor = /** @class */ (function () { |
| function GetMsgSerializerVisitor() { |
| } |
| GetMsgSerializerVisitor.prototype.formatPh = function (value) { |
| return "{$" + formatI18nPlaceholderName(value) + "}"; |
| }; |
| GetMsgSerializerVisitor.prototype.visitText = function (text) { |
| return text.value; |
| }; |
| GetMsgSerializerVisitor.prototype.visitContainer = function (container) { |
| var _this = this; |
| return container.children.map(function (child) { return child.visit(_this); }).join(''); |
| }; |
| GetMsgSerializerVisitor.prototype.visitIcu = function (icu) { |
| return serializeIcuNode(icu); |
| }; |
| GetMsgSerializerVisitor.prototype.visitTagPlaceholder = function (ph) { |
| var _this = this; |
| return ph.isVoid ? |
| this.formatPh(ph.startName) : |
| "" + this.formatPh(ph.startName) + ph.children.map(function (child) { return child.visit(_this); }).join('') + this.formatPh(ph.closeName); |
| }; |
| GetMsgSerializerVisitor.prototype.visitPlaceholder = function (ph) { |
| return this.formatPh(ph.name); |
| }; |
| GetMsgSerializerVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| return this.formatPh(ph.name); |
| }; |
| return GetMsgSerializerVisitor; |
| }()); |
| var serializerVisitor$1 = new GetMsgSerializerVisitor(); |
| function serializeI18nMessageForGetMsg(message) { |
| return message.nodes.map(function (node) { return node.visit(serializerVisitor$1, null); }).join(''); |
| } |
| |
| function createLocalizeStatements(variable, message, params) { |
| var _c = serializeI18nMessageForLocalize(message), messageParts = _c.messageParts, placeHolders = _c.placeHolders; |
| var sourceSpan = getSourceSpan(message); |
| var expressions = placeHolders.map(function (ph) { return params[ph.text]; }); |
| var localizedString$1 = localizedString(message, messageParts, placeHolders, expressions, sourceSpan); |
| var variableInitialization = variable.set(localizedString$1); |
| return [new ExpressionStatement(variableInitialization)]; |
| } |
| /** |
| * This visitor walks over an i18n tree, capturing literal strings and placeholders. |
| * |
| * The result can be used for generating the `$localize` tagged template literals. |
| */ |
| var LocalizeSerializerVisitor = /** @class */ (function () { |
| function LocalizeSerializerVisitor() { |
| } |
| LocalizeSerializerVisitor.prototype.visitText = function (text, context) { |
| if (context[context.length - 1] instanceof LiteralPiece) { |
| // Two literal pieces in a row means that there was some comment node in-between. |
| context[context.length - 1].text += text.value; |
| } |
| else { |
| context.push(new LiteralPiece(text.value, text.sourceSpan)); |
| } |
| }; |
| LocalizeSerializerVisitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| container.children.forEach(function (child) { return child.visit(_this, context); }); |
| }; |
| LocalizeSerializerVisitor.prototype.visitIcu = function (icu, context) { |
| context.push(new LiteralPiece(serializeIcuNode(icu), icu.sourceSpan)); |
| }; |
| LocalizeSerializerVisitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var _this = this; |
| var _a, _b; |
| context.push(this.createPlaceholderPiece(ph.startName, (_a = ph.startSourceSpan) !== null && _a !== void 0 ? _a : ph.sourceSpan)); |
| if (!ph.isVoid) { |
| ph.children.forEach(function (child) { return child.visit(_this, context); }); |
| context.push(this.createPlaceholderPiece(ph.closeName, (_b = ph.endSourceSpan) !== null && _b !== void 0 ? _b : ph.sourceSpan)); |
| } |
| }; |
| LocalizeSerializerVisitor.prototype.visitPlaceholder = function (ph, context) { |
| context.push(this.createPlaceholderPiece(ph.name, ph.sourceSpan)); |
| }; |
| LocalizeSerializerVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| context.push(this.createPlaceholderPiece(ph.name, ph.sourceSpan)); |
| }; |
| LocalizeSerializerVisitor.prototype.createPlaceholderPiece = function (name, sourceSpan) { |
| return new PlaceholderPiece(formatI18nPlaceholderName(name, /* useCamelCase */ false), sourceSpan); |
| }; |
| return LocalizeSerializerVisitor; |
| }()); |
| var serializerVisitor$2 = new LocalizeSerializerVisitor(); |
| /** |
| * Serialize an i18n message into two arrays: messageParts and placeholders. |
| * |
| * These arrays will be used to generate `$localize` tagged template literals. |
| * |
| * @param message The message to be serialized. |
| * @returns an object containing the messageParts and placeholders. |
| */ |
| function serializeI18nMessageForLocalize(message) { |
| var pieces = []; |
| message.nodes.forEach(function (node) { return node.visit(serializerVisitor$2, pieces); }); |
| return processMessagePieces(pieces); |
| } |
| function getSourceSpan(message) { |
| var startNode = message.nodes[0]; |
| var endNode = message.nodes[message.nodes.length - 1]; |
| return new ParseSourceSpan(startNode.sourceSpan.start, endNode.sourceSpan.end, startNode.sourceSpan.fullStart, startNode.sourceSpan.details); |
| } |
| /** |
| * Convert the list of serialized MessagePieces into two arrays. |
| * |
| * One contains the literal string pieces and the other the placeholders that will be replaced by |
| * expressions when rendering `$localize` tagged template literals. |
| * |
| * @param pieces The pieces to process. |
| * @returns an object containing the messageParts and placeholders. |
| */ |
| function processMessagePieces(pieces) { |
| var messageParts = []; |
| var placeHolders = []; |
| if (pieces[0] instanceof PlaceholderPiece) { |
| // The first piece was a placeholder so we need to add an initial empty message part. |
| messageParts.push(createEmptyMessagePart(pieces[0].sourceSpan.start)); |
| } |
| for (var i = 0; i < pieces.length; i++) { |
| var part = pieces[i]; |
| if (part instanceof LiteralPiece) { |
| messageParts.push(part); |
| } |
| else { |
| placeHolders.push(part); |
| if (pieces[i - 1] instanceof PlaceholderPiece) { |
| // There were two placeholders in a row, so we need to add an empty message part. |
| messageParts.push(createEmptyMessagePart(pieces[i - 1].sourceSpan.end)); |
| } |
| } |
| } |
| if (pieces[pieces.length - 1] instanceof PlaceholderPiece) { |
| // The last piece was a placeholder so we need to add a final empty message part. |
| messageParts.push(createEmptyMessagePart(pieces[pieces.length - 1].sourceSpan.end)); |
| } |
| return { messageParts: messageParts, placeHolders: placeHolders }; |
| } |
| function createEmptyMessagePart(location) { |
| return new LiteralPiece('', new ParseSourceSpan(location, location)); |
| } |
| |
| // Selector attribute name of `<ng-content>` |
| var NG_CONTENT_SELECT_ATTR$1 = 'select'; |
| // Attribute name of `ngProjectAs`. |
| var NG_PROJECT_AS_ATTR_NAME = 'ngProjectAs'; |
| // Global symbols available only inside event bindings. |
| var EVENT_BINDING_SCOPE_GLOBALS = new Set(['$event']); |
| // List of supported global targets for event listeners |
| var GLOBAL_TARGET_RESOLVERS = new Map([['window', Identifiers$1.resolveWindow], ['document', Identifiers$1.resolveDocument], ['body', Identifiers$1.resolveBody]]); |
| var LEADING_TRIVIA_CHARS = [' ', '\n', '\r', '\t']; |
| // if (rf & flags) { .. } |
| function renderFlagCheckIfStmt(flags, statements) { |
| return ifStmt(variable(RENDER_FLAGS).bitwiseAnd(literal(flags), null, false), statements); |
| } |
| function prepareEventListenerParameters(eventAst, handlerName, scope) { |
| if (handlerName === void 0) { handlerName = null; } |
| if (scope === void 0) { scope = null; } |
| var type = eventAst.type, name = eventAst.name, target = eventAst.target, phase = eventAst.phase, handler = eventAst.handler; |
| if (target && !GLOBAL_TARGET_RESOLVERS.has(target)) { |
| throw new Error("Unexpected global target '" + target + "' defined for '" + name + "' event.\n Supported list of global targets: " + Array.from(GLOBAL_TARGET_RESOLVERS.keys()) + "."); |
| } |
| var eventArgumentName = '$event'; |
| var implicitReceiverAccesses = new Set(); |
| var implicitReceiverExpr = (scope === null || scope.bindingLevel === 0) ? |
| variable(CONTEXT_NAME) : |
| scope.getOrCreateSharedContextVar(0); |
| var bindingExpr = convertActionBinding(scope, implicitReceiverExpr, handler, 'b', function () { return error('Unexpected interpolation'); }, eventAst.handlerSpan, implicitReceiverAccesses, EVENT_BINDING_SCOPE_GLOBALS); |
| var statements = []; |
| if (scope) { |
| statements.push.apply(statements, __spread(scope.restoreViewStatement())); |
| statements.push.apply(statements, __spread(scope.variableDeclarations())); |
| } |
| statements.push.apply(statements, __spread(bindingExpr.render3Stmts)); |
| var eventName = type === 1 /* Animation */ ? prepareSyntheticListenerName(name, phase) : name; |
| var fnName = handlerName && sanitizeIdentifier(handlerName); |
| var fnArgs = []; |
| if (implicitReceiverAccesses.has(eventArgumentName)) { |
| fnArgs.push(new FnParam(eventArgumentName, DYNAMIC_TYPE)); |
| } |
| var handlerFn = fn(fnArgs, statements, INFERRED_TYPE, null, fnName); |
| var params = [literal(eventName), handlerFn]; |
| if (target) { |
| params.push(literal(false), // `useCapture` flag, defaults to `false` |
| importExpr(GLOBAL_TARGET_RESOLVERS.get(target))); |
| } |
| return params; |
| } |
| function createComponentDefConsts() { |
| return { |
| prepareStatements: [], |
| constExpressions: [], |
| i18nVarRefsCache: new Map(), |
| }; |
| } |
| var TemplateDefinitionBuilder = /** @class */ (function () { |
| function TemplateDefinitionBuilder(constantPool, parentBindingScope, level, contextName, i18nContext, templateIndex, templateName, directiveMatcher, directives, pipeTypeByName, pipes, _namespace, relativeContextFilePath, i18nUseExternalIds, _constants) { |
| var _this = this; |
| if (level === void 0) { level = 0; } |
| if (_constants === void 0) { _constants = createComponentDefConsts(); } |
| this.constantPool = constantPool; |
| this.level = level; |
| this.contextName = contextName; |
| this.i18nContext = i18nContext; |
| this.templateIndex = templateIndex; |
| this.templateName = templateName; |
| this.directiveMatcher = directiveMatcher; |
| this.directives = directives; |
| this.pipeTypeByName = pipeTypeByName; |
| this.pipes = pipes; |
| this._namespace = _namespace; |
| this.i18nUseExternalIds = i18nUseExternalIds; |
| this._constants = _constants; |
| this._dataIndex = 0; |
| this._bindingContext = 0; |
| this._prefixCode = []; |
| /** |
| * List of callbacks to generate creation mode instructions. We store them here as we process |
| * the template so bindings in listeners are resolved only once all nodes have been visited. |
| * This ensures all local refs and context variables are available for matching. |
| */ |
| this._creationCodeFns = []; |
| /** |
| * List of callbacks to generate update mode instructions. We store them here as we process |
| * the template so bindings are resolved only once all nodes have been visited. This ensures |
| * all local refs and context variables are available for matching. |
| */ |
| this._updateCodeFns = []; |
| /** Index of the currently-selected node. */ |
| this._currentIndex = 0; |
| /** Temporary variable declarations generated from visiting pipes, literals, etc. */ |
| this._tempVariables = []; |
| /** |
| * List of callbacks to build nested templates. Nested templates must not be visited until |
| * after the parent template has finished visiting all of its nodes. This ensures that all |
| * local ref bindings in nested templates are able to find local ref values if the refs |
| * are defined after the template declaration. |
| */ |
| this._nestedTemplateFns = []; |
| this._unsupported = unsupported; |
| // i18n context local to this template |
| this.i18n = null; |
| // Number of slots to reserve for pureFunctions |
| this._pureFunctionSlots = 0; |
| // Number of binding slots |
| this._bindingSlots = 0; |
| // Projection slots found in the template. Projection slots can distribute projected |
| // nodes based on a selector, or can just use the wildcard selector to match |
| // all nodes which aren't matching any selector. |
| this._ngContentReservedSlots = []; |
| // Number of non-default selectors found in all parent templates of this template. We need to |
| // track it to properly adjust projection slot index in the `projection` instruction. |
| this._ngContentSelectorsOffset = 0; |
| // Expression that should be used as implicit receiver when converting template |
| // expressions to output AST. |
| this._implicitReceiverExpr = null; |
| // These should be handled in the template or element directly. |
| this.visitReference = invalid$1; |
| this.visitVariable = invalid$1; |
| this.visitTextAttribute = invalid$1; |
| this.visitBoundAttribute = invalid$1; |
| this.visitBoundEvent = invalid$1; |
| this._bindingScope = parentBindingScope.nestedScope(level); |
| // Turn the relative context file path into an identifier by replacing non-alphanumeric |
| // characters with underscores. |
| this.fileBasedI18nSuffix = relativeContextFilePath.replace(/[^A-Za-z0-9]/g, '_') + '_'; |
| this._valueConverter = new ValueConverter(constantPool, function () { return _this.allocateDataSlot(); }, function (numSlots) { return _this.allocatePureFunctionSlots(numSlots); }, function (name, localName, slot, value) { |
| var pipeType = pipeTypeByName.get(name); |
| if (pipeType) { |
| _this.pipes.add(pipeType); |
| } |
| _this._bindingScope.set(_this.level, localName, value); |
| _this.creationInstruction(null, Identifiers$1.pipe, [literal(slot), literal(name)]); |
| }); |
| } |
| TemplateDefinitionBuilder.prototype.buildTemplateFunction = function (nodes, variables, ngContentSelectorsOffset, i18n) { |
| var _this = this; |
| if (ngContentSelectorsOffset === void 0) { ngContentSelectorsOffset = 0; } |
| this._ngContentSelectorsOffset = ngContentSelectorsOffset; |
| if (this._namespace !== Identifiers$1.namespaceHTML) { |
| this.creationInstruction(null, this._namespace); |
| } |
| // Create variable bindings |
| variables.forEach(function (v) { return _this.registerContextVariables(v); }); |
| // Initiate i18n context in case: |
| // - this template has parent i18n context |
| // - or the template has i18n meta associated with it, |
| // but it's not initiated by the Element (e.g. <ng-template i18n>) |
| var initI18nContext = this.i18nContext || |
| (isI18nRootNode(i18n) && !isSingleI18nIcu(i18n) && |
| !(isSingleElementTemplate(nodes) && nodes[0].i18n === i18n)); |
| var selfClosingI18nInstruction = hasTextChildrenOnly(nodes); |
| if (initI18nContext) { |
| this.i18nStart(null, i18n, selfClosingI18nInstruction); |
| } |
| // This is the initial pass through the nodes of this template. In this pass, we |
| // queue all creation mode and update mode instructions for generation in the second |
| // pass. It's necessary to separate the passes to ensure local refs are defined before |
| // resolving bindings. We also count bindings in this pass as we walk bound expressions. |
| visitAll(this, nodes); |
| // Add total binding count to pure function count so pure function instructions are |
| // generated with the correct slot offset when update instructions are processed. |
| this._pureFunctionSlots += this._bindingSlots; |
| // Pipes are walked in the first pass (to enqueue `pipe()` creation instructions and |
| // `pipeBind` update instructions), so we have to update the slot offsets manually |
| // to account for bindings. |
| this._valueConverter.updatePipeSlotOffsets(this._bindingSlots); |
| // Nested templates must be processed before creation instructions so template() |
| // instructions can be generated with the correct internal const count. |
| this._nestedTemplateFns.forEach(function (buildTemplateFn) { return buildTemplateFn(); }); |
| // Output the `projectionDef` instruction when some `<ng-content>` tags are present. |
| // The `projectionDef` instruction is only emitted for the component template and |
| // is skipped for nested templates (<ng-template> tags). |
| if (this.level === 0 && this._ngContentReservedSlots.length) { |
| var parameters = []; |
| // By default the `projectionDef` instructions creates one slot for the wildcard |
| // selector if no parameters are passed. Therefore we only want to allocate a new |
| // array for the projection slots if the default projection slot is not sufficient. |
| if (this._ngContentReservedSlots.length > 1 || this._ngContentReservedSlots[0] !== '*') { |
| var r3ReservedSlots = this._ngContentReservedSlots.map(function (s) { return s !== '*' ? parseSelectorToR3Selector(s) : s; }); |
| parameters.push(this.constantPool.getConstLiteral(asLiteral(r3ReservedSlots), true)); |
| } |
| // Since we accumulate ngContent selectors while processing template elements, |
| // we *prepend* `projectionDef` to creation instructions block, to put it before |
| // any `projection` instructions |
| this.creationInstruction(null, Identifiers$1.projectionDef, parameters, /* prepend */ true); |
| } |
| if (initI18nContext) { |
| this.i18nEnd(null, selfClosingI18nInstruction); |
| } |
| // Generate all the creation mode instructions (e.g. resolve bindings in listeners) |
| var creationStatements = this._creationCodeFns.map(function (fn) { return fn(); }); |
| // Generate all the update mode instructions (e.g. resolve property or text bindings) |
| var updateStatements = this._updateCodeFns.map(function (fn) { return fn(); }); |
| // Variable declaration must occur after binding resolution so we can generate context |
| // instructions that build on each other. |
| // e.g. const b = nextContext().$implicit(); const b = nextContext(); |
| var creationVariables = this._bindingScope.viewSnapshotStatements(); |
| var updateVariables = this._bindingScope.variableDeclarations().concat(this._tempVariables); |
| var creationBlock = creationStatements.length > 0 ? |
| [renderFlagCheckIfStmt(1 /* Create */, creationVariables.concat(creationStatements))] : |
| []; |
| var updateBlock = updateStatements.length > 0 ? |
| [renderFlagCheckIfStmt(2 /* Update */, updateVariables.concat(updateStatements))] : |
| []; |
| return fn( |
| // i.e. (rf: RenderFlags, ctx: any) |
| [new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], __spread(this._prefixCode, creationBlock, updateBlock), INFERRED_TYPE, null, this.templateName); |
| }; |
| // LocalResolver |
| TemplateDefinitionBuilder.prototype.getLocal = function (name) { |
| return this._bindingScope.get(name); |
| }; |
| // LocalResolver |
| TemplateDefinitionBuilder.prototype.notifyImplicitReceiverUse = function () { |
| this._bindingScope.notifyImplicitReceiverUse(); |
| }; |
| TemplateDefinitionBuilder.prototype.i18nTranslate = function (message, params, ref, transformFn) { |
| var _c; |
| if (params === void 0) { params = {}; } |
| var _ref = ref || this.i18nGenerateMainBlockVar(); |
| // Closure Compiler requires const names to start with `MSG_` but disallows any other const to |
| // start with `MSG_`. We define a variable starting with `MSG_` just for the `goog.getMsg` call |
| var closureVar = this.i18nGenerateClosureVar(message.id); |
| var statements = getTranslationDeclStmts(message, _ref, closureVar, params, transformFn); |
| (_c = this._constants.prepareStatements).push.apply(_c, __spread(statements)); |
| return _ref; |
| }; |
| TemplateDefinitionBuilder.prototype.registerContextVariables = function (variable$1) { |
| var scopedName = this._bindingScope.freshReferenceName(); |
| var retrievalLevel = this.level; |
| var lhs = variable(variable$1.name + scopedName); |
| this._bindingScope.set(retrievalLevel, variable$1.name, lhs, 1 /* CONTEXT */, function (scope, relativeLevel) { |
| var rhs; |
| if (scope.bindingLevel === retrievalLevel) { |
| // e.g. ctx |
| rhs = variable(CONTEXT_NAME); |
| } |
| else { |
| var sharedCtxVar = scope.getSharedContextName(retrievalLevel); |
| // e.g. ctx_r0 OR x(2); |
| rhs = sharedCtxVar ? sharedCtxVar : generateNextContextExpr(relativeLevel); |
| } |
| // e.g. const $item$ = x(2).$implicit; |
| return [lhs.set(rhs.prop(variable$1.value || IMPLICIT_REFERENCE)).toConstDecl()]; |
| }); |
| }; |
| TemplateDefinitionBuilder.prototype.i18nAppendBindings = function (expressions) { |
| var _this = this; |
| if (expressions.length > 0) { |
| expressions.forEach(function (expression) { return _this.i18n.appendBinding(expression); }); |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.i18nBindProps = function (props) { |
| var _this = this; |
| var bound = {}; |
| Object.keys(props).forEach(function (key) { |
| var prop = props[key]; |
| if (prop instanceof Text) { |
| bound[key] = literal(prop.value); |
| } |
| else { |
| var value = prop.value.visit(_this._valueConverter); |
| _this.allocateBindingSlots(value); |
| if (value instanceof Interpolation) { |
| var strings = value.strings, expressions = value.expressions; |
| var _c = _this.i18n, id = _c.id, bindings = _c.bindings; |
| var label = assembleI18nBoundString(strings, bindings.size, id); |
| _this.i18nAppendBindings(expressions); |
| bound[key] = literal(label); |
| } |
| } |
| }); |
| return bound; |
| }; |
| // Generates top level vars for i18n blocks (i.e. `i18n_N`). |
| TemplateDefinitionBuilder.prototype.i18nGenerateMainBlockVar = function () { |
| return variable(this.constantPool.uniqueName(TRANSLATION_VAR_PREFIX)); |
| }; |
| // Generates vars with Closure-specific names for i18n blocks (i.e. `MSG_XXX`). |
| TemplateDefinitionBuilder.prototype.i18nGenerateClosureVar = function (messageId) { |
| var name; |
| var suffix = this.fileBasedI18nSuffix.toUpperCase(); |
| if (this.i18nUseExternalIds) { |
| var prefix = getTranslationConstPrefix("EXTERNAL_"); |
| var uniqueSuffix = this.constantPool.uniqueName(suffix); |
| name = "" + prefix + sanitizeIdentifier(messageId) + "$$" + uniqueSuffix; |
| } |
| else { |
| var prefix = getTranslationConstPrefix(suffix); |
| name = this.constantPool.uniqueName(prefix); |
| } |
| return variable(name); |
| }; |
| TemplateDefinitionBuilder.prototype.i18nUpdateRef = function (context) { |
| var icus = context.icus, meta = context.meta, isRoot = context.isRoot, isResolved = context.isResolved, isEmitted = context.isEmitted; |
| if (isRoot && isResolved && !isEmitted && !isSingleI18nIcu(meta)) { |
| context.isEmitted = true; |
| var placeholders = context.getSerializedPlaceholders(); |
| var icuMapping_1 = {}; |
| var params_1 = placeholders.size ? placeholdersToParams(placeholders) : {}; |
| if (icus.size) { |
| icus.forEach(function (refs, key) { |
| if (refs.length === 1) { |
| // if we have one ICU defined for a given |
| // placeholder - just output its reference |
| params_1[key] = refs[0]; |
| } |
| else { |
| // ... otherwise we need to activate post-processing |
| // to replace ICU placeholders with proper values |
| var placeholder = wrapI18nPlaceholder("" + I18N_ICU_MAPPING_PREFIX + key); |
| params_1[key] = literal(placeholder); |
| icuMapping_1[key] = literalArr(refs); |
| } |
| }); |
| } |
| // translation requires post processing in 2 cases: |
| // - if we have placeholders with multiple values (ex. `START_DIV`: [�#1�, �#2�, ...]) |
| // - if we have multiple ICUs that refer to the same placeholder name |
| var needsPostprocessing = Array.from(placeholders.values()).some(function (value) { return value.length > 1; }) || |
| Object.keys(icuMapping_1).length; |
| var transformFn = void 0; |
| if (needsPostprocessing) { |
| transformFn = function (raw) { |
| var args = [raw]; |
| if (Object.keys(icuMapping_1).length) { |
| args.push(mapLiteral(icuMapping_1, true)); |
| } |
| return instruction(null, Identifiers$1.i18nPostprocess, args); |
| }; |
| } |
| this.i18nTranslate(meta, params_1, context.ref, transformFn); |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.i18nStart = function (span, meta, selfClosing) { |
| if (span === void 0) { span = null; } |
| var index = this.allocateDataSlot(); |
| this.i18n = this.i18nContext ? |
| this.i18nContext.forkChildContext(index, this.templateIndex, meta) : |
| new I18nContext(index, this.i18nGenerateMainBlockVar(), 0, this.templateIndex, meta); |
| // generate i18nStart instruction |
| var _c = this.i18n, id = _c.id, ref = _c.ref; |
| var params = [literal(index), this.addToConsts(ref)]; |
| if (id > 0) { |
| // do not push 3rd argument (sub-block id) |
| // into i18nStart call for top level i18n context |
| params.push(literal(id)); |
| } |
| this.creationInstruction(span, selfClosing ? Identifiers$1.i18n : Identifiers$1.i18nStart, params); |
| }; |
| TemplateDefinitionBuilder.prototype.i18nEnd = function (span, selfClosing) { |
| var _this = this; |
| if (span === void 0) { span = null; } |
| if (!this.i18n) { |
| throw new Error('i18nEnd is executed with no i18n context present'); |
| } |
| if (this.i18nContext) { |
| this.i18nContext.reconcileChildContext(this.i18n); |
| this.i18nUpdateRef(this.i18nContext); |
| } |
| else { |
| this.i18nUpdateRef(this.i18n); |
| } |
| // setup accumulated bindings |
| var _c = this.i18n, index = _c.index, bindings = _c.bindings; |
| if (bindings.size) { |
| var chainBindings_1 = []; |
| bindings.forEach(function (binding) { |
| chainBindings_1.push({ sourceSpan: span, value: function () { return _this.convertPropertyBinding(binding); } }); |
| }); |
| // for i18n block, advance to the most recent element index (by taking the current number of |
| // elements and subtracting one) before invoking `i18nExp` instructions, to make sure the |
| // necessary lifecycle hooks of components/directives are properly flushed. |
| this.updateInstructionChainWithAdvance(this.getConstCount() - 1, Identifiers$1.i18nExp, chainBindings_1); |
| this.updateInstruction(span, Identifiers$1.i18nApply, [literal(index)]); |
| } |
| if (!selfClosing) { |
| this.creationInstruction(span, Identifiers$1.i18nEnd); |
| } |
| this.i18n = null; // reset local i18n context |
| }; |
| TemplateDefinitionBuilder.prototype.i18nAttributesInstruction = function (nodeIndex, attrs, sourceSpan) { |
| var _this = this; |
| var hasBindings = false; |
| var i18nAttrArgs = []; |
| var bindings = []; |
| attrs.forEach(function (attr) { |
| var message = attr.i18n; |
| var converted = attr.value.visit(_this._valueConverter); |
| _this.allocateBindingSlots(converted); |
| if (converted instanceof Interpolation) { |
| var placeholders = assembleBoundTextPlaceholders(message); |
| var params = placeholdersToParams(placeholders); |
| i18nAttrArgs.push(literal(attr.name), _this.i18nTranslate(message, params)); |
| converted.expressions.forEach(function (expression) { |
| hasBindings = true; |
| bindings.push({ |
| sourceSpan: sourceSpan, |
| value: function () { return _this.convertPropertyBinding(expression); }, |
| }); |
| }); |
| } |
| }); |
| if (bindings.length > 0) { |
| this.updateInstructionChainWithAdvance(nodeIndex, Identifiers$1.i18nExp, bindings); |
| } |
| if (i18nAttrArgs.length > 0) { |
| var index = literal(this.allocateDataSlot()); |
| var constIndex = this.addToConsts(literalArr(i18nAttrArgs)); |
| this.creationInstruction(sourceSpan, Identifiers$1.i18nAttributes, [index, constIndex]); |
| if (hasBindings) { |
| this.updateInstruction(sourceSpan, Identifiers$1.i18nApply, [index]); |
| } |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.getNamespaceInstruction = function (namespaceKey) { |
| switch (namespaceKey) { |
| case 'math': |
| return Identifiers$1.namespaceMathML; |
| case 'svg': |
| return Identifiers$1.namespaceSVG; |
| default: |
| return Identifiers$1.namespaceHTML; |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.addNamespaceInstruction = function (nsInstruction, element) { |
| this._namespace = nsInstruction; |
| this.creationInstruction(element.startSourceSpan, nsInstruction); |
| }; |
| /** |
| * Adds an update instruction for an interpolated property or attribute, such as |
| * `prop="{{value}}"` or `attr.title="{{value}}"` |
| */ |
| TemplateDefinitionBuilder.prototype.interpolatedUpdateInstruction = function (instruction, elementIndex, attrName, input, value, params) { |
| var _this = this; |
| this.updateInstructionWithAdvance(elementIndex, input.sourceSpan, instruction, function () { return __spread([literal(attrName)], _this.getUpdateInstructionArguments(value), params); }); |
| }; |
| TemplateDefinitionBuilder.prototype.visitContent = function (ngContent) { |
| var slot = this.allocateDataSlot(); |
| var projectionSlotIdx = this._ngContentSelectorsOffset + this._ngContentReservedSlots.length; |
| var parameters = [literal(slot)]; |
| this._ngContentReservedSlots.push(ngContent.selector); |
| var nonContentSelectAttributes = ngContent.attributes.filter(function (attr) { return attr.name.toLowerCase() !== NG_CONTENT_SELECT_ATTR$1; }); |
| var attributes = this.getAttributeExpressions(ngContent.name, nonContentSelectAttributes, [], []); |
| if (attributes.length > 0) { |
| parameters.push(literal(projectionSlotIdx), literalArr(attributes)); |
| } |
| else if (projectionSlotIdx !== 0) { |
| parameters.push(literal(projectionSlotIdx)); |
| } |
| this.creationInstruction(ngContent.sourceSpan, Identifiers$1.projection, parameters); |
| if (this.i18n) { |
| this.i18n.appendProjection(ngContent.i18n, slot); |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.visitElement = function (element) { |
| var e_1, _c; |
| var _this = this; |
| var _a, _b; |
| var elementIndex = this.allocateDataSlot(); |
| var stylingBuilder = new StylingBuilder(null); |
| var isNonBindableMode = false; |
| var isI18nRootElement = isI18nRootNode(element.i18n) && !isSingleI18nIcu(element.i18n); |
| var outputAttrs = []; |
| var _d = __read(splitNsName(element.name), 2), namespaceKey = _d[0], elementName = _d[1]; |
| var isNgContainer$1 = isNgContainer(element.name); |
| try { |
| // Handle styling, i18n, ngNonBindable attributes |
| for (var _e = __values(element.attributes), _f = _e.next(); !_f.done; _f = _e.next()) { |
| var attr = _f.value; |
| var name = attr.name, value = attr.value; |
| if (name === NON_BINDABLE_ATTR) { |
| isNonBindableMode = true; |
| } |
| else if (name === 'style') { |
| stylingBuilder.registerStyleAttr(value); |
| } |
| else if (name === 'class') { |
| stylingBuilder.registerClassAttr(value); |
| } |
| else { |
| outputAttrs.push(attr); |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_f && !_f.done && (_c = _e.return)) _c.call(_e); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| // Match directives on non i18n attributes |
| this.matchDirectives(element.name, element); |
| // Regular element or ng-container creation mode |
| var parameters = [literal(elementIndex)]; |
| if (!isNgContainer$1) { |
| parameters.push(literal(elementName)); |
| } |
| // Add the attributes |
| var allOtherInputs = []; |
| var boundI18nAttrs = []; |
| element.inputs.forEach(function (input) { |
| var stylingInputWasSet = stylingBuilder.registerBoundInput(input); |
| if (!stylingInputWasSet) { |
| if (input.type === 0 /* Property */ && input.i18n) { |
| boundI18nAttrs.push(input); |
| } |
| else { |
| allOtherInputs.push(input); |
| } |
| } |
| }); |
| // add attributes for directive and projection matching purposes |
| var attributes = this.getAttributeExpressions(element.name, outputAttrs, allOtherInputs, element.outputs, stylingBuilder, [], boundI18nAttrs); |
| parameters.push(this.addAttrsToConsts(attributes)); |
| // local refs (ex.: <div #foo #bar="baz">) |
| var refs = this.prepareRefsArray(element.references); |
| parameters.push(this.addToConsts(refs)); |
| var wasInNamespace = this._namespace; |
| var currentNamespace = this.getNamespaceInstruction(namespaceKey); |
| // If the namespace is changing now, include an instruction to change it |
| // during element creation. |
| if (currentNamespace !== wasInNamespace) { |
| this.addNamespaceInstruction(currentNamespace, element); |
| } |
| if (this.i18n) { |
| this.i18n.appendElement(element.i18n, elementIndex); |
| } |
| // Note that we do not append text node instructions and ICUs inside i18n section, |
| // so we exclude them while calculating whether current element has children |
| var hasChildren = (!isI18nRootElement && this.i18n) ? !hasTextChildrenOnly(element.children) : |
| element.children.length > 0; |
| var createSelfClosingInstruction = !stylingBuilder.hasBindingsWithPipes && |
| element.outputs.length === 0 && boundI18nAttrs.length === 0 && !hasChildren; |
| var createSelfClosingI18nInstruction = !createSelfClosingInstruction && hasTextChildrenOnly(element.children); |
| if (createSelfClosingInstruction) { |
| this.creationInstruction(element.sourceSpan, isNgContainer$1 ? Identifiers$1.elementContainer : Identifiers$1.element, trimTrailingNulls(parameters)); |
| } |
| else { |
| this.creationInstruction(element.startSourceSpan, isNgContainer$1 ? Identifiers$1.elementContainerStart : Identifiers$1.elementStart, trimTrailingNulls(parameters)); |
| if (isNonBindableMode) { |
| this.creationInstruction(element.startSourceSpan, Identifiers$1.disableBindings); |
| } |
| if (boundI18nAttrs.length > 0) { |
| this.i18nAttributesInstruction(elementIndex, boundI18nAttrs, (_a = element.startSourceSpan) !== null && _a !== void 0 ? _a : element.sourceSpan); |
| } |
| // Generate Listeners (outputs) |
| if (element.outputs.length > 0) { |
| var listeners = element.outputs.map(function (outputAst) { return ({ |
| sourceSpan: outputAst.sourceSpan, |
| params: _this.prepareListenerParameter(element.name, outputAst, elementIndex) |
| }); }); |
| this.creationInstructionChain(Identifiers$1.listener, listeners); |
| } |
| // Note: it's important to keep i18n/i18nStart instructions after i18nAttributes and |
| // listeners, to make sure i18nAttributes instruction targets current element at runtime. |
| if (isI18nRootElement) { |
| this.i18nStart(element.startSourceSpan, element.i18n, createSelfClosingI18nInstruction); |
| } |
| } |
| // the code here will collect all update-level styling instructions and add them to the |
| // update block of the template function AOT code. Instructions like `styleProp`, |
| // `styleMap`, `classMap`, `classProp` |
| // are all generated and assigned in the code below. |
| var stylingInstructions = stylingBuilder.buildUpdateLevelInstructions(this._valueConverter); |
| var limit = stylingInstructions.length - 1; |
| for (var i = 0; i <= limit; i++) { |
| var instruction_1 = stylingInstructions[i]; |
| this._bindingSlots += this.processStylingUpdateInstruction(elementIndex, instruction_1); |
| } |
| // the reason why `undefined` is used is because the renderer understands this as a |
| // special value to symbolize that there is no RHS to this binding |
| // TODO (matsko): revisit this once FW-959 is approached |
| var emptyValueBindInstruction = literal(undefined); |
| var propertyBindings = []; |
| var attributeBindings = []; |
| // Generate element input bindings |
| allOtherInputs.forEach(function (input) { |
| var inputType = input.type; |
| if (inputType === 4 /* Animation */) { |
| var value_1 = input.value.visit(_this._valueConverter); |
| // animation bindings can be presented in the following formats: |
| // 1. [@binding]="fooExp" |
| // 2. [@binding]="{value:fooExp, params:{...}}" |
| // 3. [@binding] |
| // 4. @binding |
| // All formats will be valid for when a synthetic binding is created. |
| // The reasoning for this is because the renderer should get each |
| // synthetic binding value in the order of the array that they are |
| // defined in... |
| var hasValue_1 = value_1 instanceof LiteralPrimitive ? !!value_1.value : true; |
| _this.allocateBindingSlots(value_1); |
| propertyBindings.push({ |
| name: prepareSyntheticPropertyName(input.name), |
| sourceSpan: input.sourceSpan, |
| value: function () { return hasValue_1 ? _this.convertPropertyBinding(value_1) : emptyValueBindInstruction; } |
| }); |
| } |
| else { |
| // we must skip attributes with associated i18n context, since these attributes are handled |
| // separately and corresponding `i18nExp` and `i18nApply` instructions will be generated |
| if (input.i18n) |
| return; |
| var value_2 = input.value.visit(_this._valueConverter); |
| if (value_2 !== undefined) { |
| var params_2 = []; |
| var _c = __read(splitNsName(input.name), 2), attrNamespace = _c[0], attrName_1 = _c[1]; |
| var isAttributeBinding = inputType === 1 /* Attribute */; |
| var sanitizationRef = resolveSanitizationFn(input.securityContext, isAttributeBinding); |
| if (sanitizationRef) |
| params_2.push(sanitizationRef); |
| if (attrNamespace) { |
| var namespaceLiteral = literal(attrNamespace); |
| if (sanitizationRef) { |
| params_2.push(namespaceLiteral); |
| } |
| else { |
| // If there wasn't a sanitization ref, we need to add |
| // an extra param so that we can pass in the namespace. |
| params_2.push(literal(null), namespaceLiteral); |
| } |
| } |
| _this.allocateBindingSlots(value_2); |
| if (inputType === 0 /* Property */) { |
| if (value_2 instanceof Interpolation) { |
| // prop="{{value}}" and friends |
| _this.interpolatedUpdateInstruction(getPropertyInterpolationExpression(value_2), elementIndex, attrName_1, input, value_2, params_2); |
| } |
| else { |
| // [prop]="value" |
| // Collect all the properties so that we can chain into a single function at the end. |
| propertyBindings.push({ |
| name: attrName_1, |
| sourceSpan: input.sourceSpan, |
| value: function () { return _this.convertPropertyBinding(value_2); }, |
| params: params_2 |
| }); |
| } |
| } |
| else if (inputType === 1 /* Attribute */) { |
| if (value_2 instanceof Interpolation && getInterpolationArgsLength(value_2) > 1) { |
| // attr.name="text{{value}}" and friends |
| _this.interpolatedUpdateInstruction(getAttributeInterpolationExpression(value_2), elementIndex, attrName_1, input, value_2, params_2); |
| } |
| else { |
| var boundValue_1 = value_2 instanceof Interpolation ? value_2.expressions[0] : value_2; |
| // [attr.name]="value" or attr.name="{{value}}" |
| // Collect the attribute bindings so that they can be chained at the end. |
| attributeBindings.push({ |
| name: attrName_1, |
| sourceSpan: input.sourceSpan, |
| value: function () { return _this.convertPropertyBinding(boundValue_1); }, |
| params: params_2 |
| }); |
| } |
| } |
| else { |
| // class prop |
| _this.updateInstructionWithAdvance(elementIndex, input.sourceSpan, Identifiers$1.classProp, function () { |
| return __spread([ |
| literal(elementIndex), literal(attrName_1), _this.convertPropertyBinding(value_2) |
| ], params_2); |
| }); |
| } |
| } |
| } |
| }); |
| if (propertyBindings.length > 0) { |
| this.updateInstructionChainWithAdvance(elementIndex, Identifiers$1.property, propertyBindings); |
| } |
| if (attributeBindings.length > 0) { |
| this.updateInstructionChainWithAdvance(elementIndex, Identifiers$1.attribute, attributeBindings); |
| } |
| // Traverse element child nodes |
| visitAll(this, element.children); |
| if (!isI18nRootElement && this.i18n) { |
| this.i18n.appendElement(element.i18n, elementIndex, true); |
| } |
| if (!createSelfClosingInstruction) { |
| // Finish element construction mode. |
| var span = (_b = element.endSourceSpan) !== null && _b !== void 0 ? _b : element.sourceSpan; |
| if (isI18nRootElement) { |
| this.i18nEnd(span, createSelfClosingI18nInstruction); |
| } |
| if (isNonBindableMode) { |
| this.creationInstruction(span, Identifiers$1.enableBindings); |
| } |
| this.creationInstruction(span, isNgContainer$1 ? Identifiers$1.elementContainerEnd : Identifiers$1.elementEnd); |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.visitTemplate = function (template) { |
| var _this = this; |
| var _a; |
| var NG_TEMPLATE_TAG_NAME = 'ng-template'; |
| var templateIndex = this.allocateDataSlot(); |
| if (this.i18n) { |
| this.i18n.appendTemplate(template.i18n, templateIndex); |
| } |
| var tagName = sanitizeIdentifier(template.tagName || ''); |
| var contextName = "" + this.contextName + (tagName ? '_' + tagName : '') + "_" + templateIndex; |
| var templateName = contextName + "_Template"; |
| var parameters = [ |
| literal(templateIndex), |
| variable(templateName), |
| // We don't care about the tag's namespace here, because we infer |
| // it based on the parent nodes inside the template instruction. |
| literal(template.tagName ? splitNsName(template.tagName)[1] : template.tagName), |
| ]; |
| // find directives matching on a given <ng-template> node |
| this.matchDirectives(NG_TEMPLATE_TAG_NAME, template); |
| // prepare attributes parameter (including attributes used for directive matching) |
| var attrsExprs = this.getAttributeExpressions(NG_TEMPLATE_TAG_NAME, template.attributes, template.inputs, template.outputs, undefined /* styles */, template.templateAttrs); |
| parameters.push(this.addAttrsToConsts(attrsExprs)); |
| // local refs (ex.: <ng-template #foo>) |
| if (template.references && template.references.length) { |
| var refs = this.prepareRefsArray(template.references); |
| parameters.push(this.addToConsts(refs)); |
| parameters.push(importExpr(Identifiers$1.templateRefExtractor)); |
| } |
| // Create the template function |
| var templateVisitor = new TemplateDefinitionBuilder(this.constantPool, this._bindingScope, this.level + 1, contextName, this.i18n, templateIndex, templateName, this.directiveMatcher, this.directives, this.pipeTypeByName, this.pipes, this._namespace, this.fileBasedI18nSuffix, this.i18nUseExternalIds, this._constants); |
| // Nested templates must not be visited until after their parent templates have completed |
| // processing, so they are queued here until after the initial pass. Otherwise, we wouldn't |
| // be able to support bindings in nested templates to local refs that occur after the |
| // template definition. e.g. <div *ngIf="showing">{{ foo }}</div> <div #foo></div> |
| this._nestedTemplateFns.push(function () { |
| var _c; |
| var templateFunctionExpr = templateVisitor.buildTemplateFunction(template.children, template.variables, _this._ngContentReservedSlots.length + _this._ngContentSelectorsOffset, template.i18n); |
| _this.constantPool.statements.push(templateFunctionExpr.toDeclStmt(templateName)); |
| if (templateVisitor._ngContentReservedSlots.length) { |
| (_c = _this._ngContentReservedSlots).push.apply(_c, __spread(templateVisitor._ngContentReservedSlots)); |
| } |
| }); |
| // e.g. template(1, MyComp_Template_1) |
| this.creationInstruction(template.sourceSpan, Identifiers$1.templateCreate, function () { |
| parameters.splice(2, 0, literal(templateVisitor.getConstCount()), literal(templateVisitor.getVarCount())); |
| return trimTrailingNulls(parameters); |
| }); |
| // handle property bindings e.g. ɵɵproperty('ngForOf', ctx.items), et al; |
| this.templatePropertyBindings(templateIndex, template.templateAttrs); |
| // Only add normal input/output binding instructions on explicit <ng-template> elements. |
| if (template.tagName === NG_TEMPLATE_TAG_NAME) { |
| var _c = __read(partitionArray(template.inputs, hasI18nMeta), 2), i18nInputs = _c[0], inputs = _c[1]; |
| // Add i18n attributes that may act as inputs to directives. If such attributes are present, |
| // generate `i18nAttributes` instruction. Note: we generate it only for explicit <ng-template> |
| // elements, in case of inline templates, corresponding instructions will be generated in the |
| // nested template function. |
| if (i18nInputs.length > 0) { |
| this.i18nAttributesInstruction(templateIndex, i18nInputs, (_a = template.startSourceSpan) !== null && _a !== void 0 ? _a : template.sourceSpan); |
| } |
| // Add the input bindings |
| if (inputs.length > 0) { |
| this.templatePropertyBindings(templateIndex, inputs); |
| } |
| // Generate listeners for directive output |
| if (template.outputs.length > 0) { |
| var listeners = template.outputs.map(function (outputAst) { return ({ |
| sourceSpan: outputAst.sourceSpan, |
| params: _this.prepareListenerParameter('ng_template', outputAst, templateIndex) |
| }); }); |
| this.creationInstructionChain(Identifiers$1.listener, listeners); |
| } |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.visitBoundText = function (text) { |
| var _this = this; |
| if (this.i18n) { |
| var value_3 = text.value.visit(this._valueConverter); |
| this.allocateBindingSlots(value_3); |
| if (value_3 instanceof Interpolation) { |
| this.i18n.appendBoundText(text.i18n); |
| this.i18nAppendBindings(value_3.expressions); |
| } |
| return; |
| } |
| var nodeIndex = this.allocateDataSlot(); |
| this.creationInstruction(text.sourceSpan, Identifiers$1.text, [literal(nodeIndex)]); |
| var value = text.value.visit(this._valueConverter); |
| this.allocateBindingSlots(value); |
| if (value instanceof Interpolation) { |
| this.updateInstructionWithAdvance(nodeIndex, text.sourceSpan, getTextInterpolationExpression(value), function () { return _this.getUpdateInstructionArguments(value); }); |
| } |
| else { |
| error('Text nodes should be interpolated and never bound directly.'); |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.visitText = function (text) { |
| // when a text element is located within a translatable |
| // block, we exclude this text element from instructions set, |
| // since it will be captured in i18n content and processed at runtime |
| if (!this.i18n) { |
| this.creationInstruction(text.sourceSpan, Identifiers$1.text, [literal(this.allocateDataSlot()), literal(text.value)]); |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.visitIcu = function (icu) { |
| var initWasInvoked = false; |
| // if an ICU was created outside of i18n block, we still treat |
| // it as a translatable entity and invoke i18nStart and i18nEnd |
| // to generate i18n context and the necessary instructions |
| if (!this.i18n) { |
| initWasInvoked = true; |
| this.i18nStart(null, icu.i18n, true); |
| } |
| var i18n = this.i18n; |
| var vars = this.i18nBindProps(icu.vars); |
| var placeholders = this.i18nBindProps(icu.placeholders); |
| // output ICU directly and keep ICU reference in context |
| var message = icu.i18n; |
| // we always need post-processing function for ICUs, to make sure that: |
| // - all placeholders in a form of {PLACEHOLDER} are replaced with actual values (note: |
| // `goog.getMsg` does not process ICUs and uses the `{PLACEHOLDER}` format for placeholders |
| // inside ICUs) |
| // - all ICU vars (such as `VAR_SELECT` or `VAR_PLURAL`) are replaced with correct values |
| var transformFn = function (raw) { |
| var params = Object.assign(Object.assign({}, vars), placeholders); |
| var formatted = i18nFormatPlaceholderNames(params, /* useCamelCase */ false); |
| return instruction(null, Identifiers$1.i18nPostprocess, [raw, mapLiteral(formatted, true)]); |
| }; |
| // in case the whole i18n message is a single ICU - we do not need to |
| // create a separate top-level translation, we can use the root ref instead |
| // and make this ICU a top-level translation |
| // note: ICU placeholders are replaced with actual values in `i18nPostprocess` function |
| // separately, so we do not pass placeholders into `i18nTranslate` function. |
| if (isSingleI18nIcu(i18n.meta)) { |
| this.i18nTranslate(message, /* placeholders */ {}, i18n.ref, transformFn); |
| } |
| else { |
| // output ICU directly and keep ICU reference in context |
| var ref = this.i18nTranslate(message, /* placeholders */ {}, /* ref */ undefined, transformFn); |
| i18n.appendIcu(icuFromI18nMessage(message).name, ref); |
| } |
| if (initWasInvoked) { |
| this.i18nEnd(null, true); |
| } |
| return null; |
| }; |
| TemplateDefinitionBuilder.prototype.allocateDataSlot = function () { |
| return this._dataIndex++; |
| }; |
| TemplateDefinitionBuilder.prototype.getConstCount = function () { |
| return this._dataIndex; |
| }; |
| TemplateDefinitionBuilder.prototype.getVarCount = function () { |
| return this._pureFunctionSlots; |
| }; |
| TemplateDefinitionBuilder.prototype.getConsts = function () { |
| return this._constants; |
| }; |
| TemplateDefinitionBuilder.prototype.getNgContentSelectors = function () { |
| return this._ngContentReservedSlots.length ? |
| this.constantPool.getConstLiteral(asLiteral(this._ngContentReservedSlots), true) : |
| null; |
| }; |
| TemplateDefinitionBuilder.prototype.bindingContext = function () { |
| return "" + this._bindingContext++; |
| }; |
| TemplateDefinitionBuilder.prototype.templatePropertyBindings = function (templateIndex, attrs) { |
| var _this = this; |
| var propertyBindings = []; |
| attrs.forEach(function (input) { |
| if (input instanceof BoundAttribute) { |
| var value_4 = input.value.visit(_this._valueConverter); |
| if (value_4 !== undefined) { |
| _this.allocateBindingSlots(value_4); |
| if (value_4 instanceof Interpolation) { |
| // Params typically contain attribute namespace and value sanitizer, which is applicable |
| // for regular HTML elements, but not applicable for <ng-template> (since props act as |
| // inputs to directives), so keep params array empty. |
| var params = []; |
| // prop="{{value}}" case |
| _this.interpolatedUpdateInstruction(getPropertyInterpolationExpression(value_4), templateIndex, input.name, input, value_4, params); |
| } |
| else { |
| // [prop]="value" case |
| propertyBindings.push({ |
| name: input.name, |
| sourceSpan: input.sourceSpan, |
| value: function () { return _this.convertPropertyBinding(value_4); } |
| }); |
| } |
| } |
| } |
| }); |
| if (propertyBindings.length > 0) { |
| this.updateInstructionChainWithAdvance(templateIndex, Identifiers$1.property, propertyBindings); |
| } |
| }; |
| // Bindings must only be resolved after all local refs have been visited, so all |
| // instructions are queued in callbacks that execute once the initial pass has completed. |
| // Otherwise, we wouldn't be able to support local refs that are defined after their |
| // bindings. e.g. {{ foo }} <div #foo></div> |
| TemplateDefinitionBuilder.prototype.instructionFn = function (fns, span, reference, paramsOrFn, prepend) { |
| if (prepend === void 0) { prepend = false; } |
| fns[prepend ? 'unshift' : 'push'](function () { |
| var params = Array.isArray(paramsOrFn) ? paramsOrFn : paramsOrFn(); |
| return instruction(span, reference, params).toStmt(); |
| }); |
| }; |
| TemplateDefinitionBuilder.prototype.processStylingUpdateInstruction = function (elementIndex, instruction) { |
| var _this = this; |
| var allocateBindingSlots = 0; |
| if (instruction) { |
| var calls_1 = []; |
| instruction.calls.forEach(function (call) { |
| allocateBindingSlots += call.allocateBindingSlots; |
| calls_1.push({ |
| sourceSpan: call.sourceSpan, |
| value: function () { |
| return call.params(function (value) { return (call.supportsInterpolation && value instanceof Interpolation) ? |
| _this.getUpdateInstructionArguments(value) : |
| _this.convertPropertyBinding(value); }); |
| } |
| }); |
| }); |
| this.updateInstructionChainWithAdvance(elementIndex, instruction.reference, calls_1); |
| } |
| return allocateBindingSlots; |
| }; |
| TemplateDefinitionBuilder.prototype.creationInstruction = function (span, reference, paramsOrFn, prepend) { |
| this.instructionFn(this._creationCodeFns, span, reference, paramsOrFn || [], prepend); |
| }; |
| TemplateDefinitionBuilder.prototype.creationInstructionChain = function (reference, calls) { |
| var span = calls.length ? calls[0].sourceSpan : null; |
| this._creationCodeFns.push(function () { |
| return chainedInstruction(reference, calls.map(function (call) { return call.params(); }), span).toStmt(); |
| }); |
| }; |
| TemplateDefinitionBuilder.prototype.updateInstructionWithAdvance = function (nodeIndex, span, reference, paramsOrFn) { |
| this.addAdvanceInstructionIfNecessary(nodeIndex, span); |
| this.updateInstruction(span, reference, paramsOrFn); |
| }; |
| TemplateDefinitionBuilder.prototype.updateInstruction = function (span, reference, paramsOrFn) { |
| this.instructionFn(this._updateCodeFns, span, reference, paramsOrFn || []); |
| }; |
| TemplateDefinitionBuilder.prototype.updateInstructionChain = function (reference, bindings) { |
| var span = bindings.length ? bindings[0].sourceSpan : null; |
| this._updateCodeFns.push(function () { |
| var calls = bindings.map(function (property) { |
| var value = property.value(); |
| var fnParams = Array.isArray(value) ? value : [value]; |
| if (property.params) { |
| fnParams.push.apply(fnParams, __spread(property.params)); |
| } |
| if (property.name) { |
| // We want the property name to always be the first function parameter. |
| fnParams.unshift(literal(property.name)); |
| } |
| return fnParams; |
| }); |
| return chainedInstruction(reference, calls, span).toStmt(); |
| }); |
| }; |
| TemplateDefinitionBuilder.prototype.updateInstructionChainWithAdvance = function (nodeIndex, reference, bindings) { |
| this.addAdvanceInstructionIfNecessary(nodeIndex, bindings.length ? bindings[0].sourceSpan : null); |
| this.updateInstructionChain(reference, bindings); |
| }; |
| TemplateDefinitionBuilder.prototype.addAdvanceInstructionIfNecessary = function (nodeIndex, span) { |
| if (nodeIndex !== this._currentIndex) { |
| var delta = nodeIndex - this._currentIndex; |
| if (delta < 1) { |
| throw new Error('advance instruction can only go forwards'); |
| } |
| this.instructionFn(this._updateCodeFns, span, Identifiers$1.advance, [literal(delta)]); |
| this._currentIndex = nodeIndex; |
| } |
| }; |
| TemplateDefinitionBuilder.prototype.allocatePureFunctionSlots = function (numSlots) { |
| var originalSlots = this._pureFunctionSlots; |
| this._pureFunctionSlots += numSlots; |
| return originalSlots; |
| }; |
| TemplateDefinitionBuilder.prototype.allocateBindingSlots = function (value) { |
| this._bindingSlots += value instanceof Interpolation ? value.expressions.length : 1; |
| }; |
| /** |
| * Gets an expression that refers to the implicit receiver. The implicit |
| * receiver is always the root level context. |
| */ |
| TemplateDefinitionBuilder.prototype.getImplicitReceiverExpr = function () { |
| if (this._implicitReceiverExpr) { |
| return this._implicitReceiverExpr; |
| } |
| return this._implicitReceiverExpr = this.level === 0 ? |
| variable(CONTEXT_NAME) : |
| this._bindingScope.getOrCreateSharedContextVar(0); |
| }; |
| TemplateDefinitionBuilder.prototype.convertPropertyBinding = function (value) { |
| var _c; |
| var convertedPropertyBinding = convertPropertyBinding(this, this.getImplicitReceiverExpr(), value, this.bindingContext(), BindingForm.Expression, function () { return error('Unexpected interpolation'); }); |
| var valExpr = convertedPropertyBinding.currValExpr; |
| (_c = this._tempVariables).push.apply(_c, __spread(convertedPropertyBinding.stmts)); |
| return valExpr; |
| }; |
| /** |
| * Gets a list of argument expressions to pass to an update instruction expression. Also updates |
| * the temp variables state with temp variables that were identified as needing to be created |
| * while visiting the arguments. |
| * @param value The original expression we will be resolving an arguments list from. |
| */ |
| TemplateDefinitionBuilder.prototype.getUpdateInstructionArguments = function (value) { |
| var _c; |
| var _d = convertUpdateArguments(this, this.getImplicitReceiverExpr(), value, this.bindingContext()), args = _d.args, stmts = _d.stmts; |
| (_c = this._tempVariables).push.apply(_c, __spread(stmts)); |
| return args; |
| }; |
| TemplateDefinitionBuilder.prototype.matchDirectives = function (elementName, elOrTpl) { |
| var _this = this; |
| if (this.directiveMatcher) { |
| var selector = createCssSelector(elementName, getAttrsForDirectiveMatching(elOrTpl)); |
| this.directiveMatcher.match(selector, function (cssSelector, staticType) { |
| _this.directives.add(staticType); |
| }); |
| } |
| }; |
| /** |
| * Prepares all attribute expression values for the `TAttributes` array. |
| * |
| * The purpose of this function is to properly construct an attributes array that |
| * is passed into the `elementStart` (or just `element`) functions. Because there |
| * are many different types of attributes, the array needs to be constructed in a |
| * special way so that `elementStart` can properly evaluate them. |
| * |
| * The format looks like this: |
| * |
| * ``` |
| * attrs = [prop, value, prop2, value2, |
| * PROJECT_AS, selector, |
| * CLASSES, class1, class2, |
| * STYLES, style1, value1, style2, value2, |
| * BINDINGS, name1, name2, name3, |
| * TEMPLATE, name4, name5, name6, |
| * I18N, name7, name8, ...] |
| * ``` |
| * |
| * Note that this function will fully ignore all synthetic (@foo) attribute values |
| * because those values are intended to always be generated as property instructions. |
| */ |
| TemplateDefinitionBuilder.prototype.getAttributeExpressions = function (elementName, renderAttributes, inputs, outputs, styles, templateAttrs, boundI18nAttrs) { |
| var e_2, _c; |
| if (templateAttrs === void 0) { templateAttrs = []; } |
| if (boundI18nAttrs === void 0) { boundI18nAttrs = []; } |
| var alreadySeen = new Set(); |
| var attrExprs = []; |
| var ngProjectAsAttr; |
| try { |
| for (var renderAttributes_1 = __values(renderAttributes), renderAttributes_1_1 = renderAttributes_1.next(); !renderAttributes_1_1.done; renderAttributes_1_1 = renderAttributes_1.next()) { |
| var attr = renderAttributes_1_1.value; |
| if (attr.name === NG_PROJECT_AS_ATTR_NAME) { |
| ngProjectAsAttr = attr; |
| } |
| // Note that static i18n attributes aren't in the i18n array, |
| // because they're treated in the same way as regular attributes. |
| if (attr.i18n) { |
| // When i18n attributes are present on elements with structural directives |
| // (e.g. `<div *ngIf title="Hello" i18n-title>`), we want to avoid generating |
| // duplicate i18n translation blocks for `ɵɵtemplate` and `ɵɵelement` instruction |
| // attributes. So we do a cache lookup to see if suitable i18n translation block |
| // already exists. |
| var i18nVarRefsCache = this._constants.i18nVarRefsCache; |
| var i18nVarRef = void 0; |
| if (i18nVarRefsCache.has(attr.i18n)) { |
| i18nVarRef = i18nVarRefsCache.get(attr.i18n); |
| } |
| else { |
| i18nVarRef = this.i18nTranslate(attr.i18n); |
| i18nVarRefsCache.set(attr.i18n, i18nVarRef); |
| } |
| attrExprs.push(literal(attr.name), i18nVarRef); |
| } |
| else { |
| attrExprs.push.apply(attrExprs, __spread(getAttributeNameLiterals(attr.name), [trustedConstAttribute(elementName, attr)])); |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (renderAttributes_1_1 && !renderAttributes_1_1.done && (_c = renderAttributes_1.return)) _c.call(renderAttributes_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| // Keep ngProjectAs next to the other name, value pairs so we can verify that we match |
| // ngProjectAs marker in the attribute name slot. |
| if (ngProjectAsAttr) { |
| attrExprs.push.apply(attrExprs, __spread(getNgProjectAsLiteral(ngProjectAsAttr))); |
| } |
| function addAttrExpr(key, value) { |
| if (typeof key === 'string') { |
| if (!alreadySeen.has(key)) { |
| attrExprs.push.apply(attrExprs, __spread(getAttributeNameLiterals(key))); |
| value !== undefined && attrExprs.push(value); |
| alreadySeen.add(key); |
| } |
| } |
| else { |
| attrExprs.push(literal(key)); |
| } |
| } |
| // it's important that this occurs before BINDINGS and TEMPLATE because once `elementStart` |
| // comes across the BINDINGS or TEMPLATE markers then it will continue reading each value as |
| // as single property value cell by cell. |
| if (styles) { |
| styles.populateInitialStylingAttrs(attrExprs); |
| } |
| if (inputs.length || outputs.length) { |
| var attrsLengthBeforeInputs = attrExprs.length; |
| for (var i = 0; i < inputs.length; i++) { |
| var input = inputs[i]; |
| // We don't want the animation and attribute bindings in the |
| // attributes array since they aren't used for directive matching. |
| if (input.type !== 4 /* Animation */ && input.type !== 1 /* Attribute */) { |
| addAttrExpr(input.name); |
| } |
| } |
| for (var i = 0; i < outputs.length; i++) { |
| var output = outputs[i]; |
| if (output.type !== 1 /* Animation */) { |
| addAttrExpr(output.name); |
| } |
| } |
| // this is a cheap way of adding the marker only after all the input/output |
| // values have been filtered (by not including the animation ones) and added |
| // to the expressions. The marker is important because it tells the runtime |
| // code that this is where attributes without values start... |
| if (attrExprs.length !== attrsLengthBeforeInputs) { |
| attrExprs.splice(attrsLengthBeforeInputs, 0, literal(3 /* Bindings */)); |
| } |
| } |
| if (templateAttrs.length) { |
| attrExprs.push(literal(4 /* Template */)); |
| templateAttrs.forEach(function (attr) { return addAttrExpr(attr.name); }); |
| } |
| if (boundI18nAttrs.length) { |
| attrExprs.push(literal(6 /* I18n */)); |
| boundI18nAttrs.forEach(function (attr) { return addAttrExpr(attr.name); }); |
| } |
| return attrExprs; |
| }; |
| TemplateDefinitionBuilder.prototype.addToConsts = function (expression) { |
| if (isNull(expression)) { |
| return TYPED_NULL_EXPR; |
| } |
| var consts = this._constants.constExpressions; |
| // Try to reuse a literal that's already in the array, if possible. |
| for (var i = 0; i < consts.length; i++) { |
| if (consts[i].isEquivalent(expression)) { |
| return literal(i); |
| } |
| } |
| return literal(consts.push(expression) - 1); |
| }; |
| TemplateDefinitionBuilder.prototype.addAttrsToConsts = function (attrs) { |
| return attrs.length > 0 ? this.addToConsts(literalArr(attrs)) : TYPED_NULL_EXPR; |
| }; |
| TemplateDefinitionBuilder.prototype.prepareRefsArray = function (references) { |
| var _this = this; |
| if (!references || references.length === 0) { |
| return TYPED_NULL_EXPR; |
| } |
| var refsParam = flatten(references.map(function (reference) { |
| var slot = _this.allocateDataSlot(); |
| // Generate the update temporary. |
| var variableName = _this._bindingScope.freshReferenceName(); |
| var retrievalLevel = _this.level; |
| var lhs = variable(variableName); |
| _this._bindingScope.set(retrievalLevel, reference.name, lhs, 0 /* DEFAULT */, function (scope, relativeLevel) { |
| // e.g. nextContext(2); |
| var nextContextStmt = relativeLevel > 0 ? [generateNextContextExpr(relativeLevel).toStmt()] : []; |
| // e.g. const $foo$ = reference(1); |
| var refExpr = lhs.set(importExpr(Identifiers$1.reference).callFn([literal(slot)])); |
| return nextContextStmt.concat(refExpr.toConstDecl()); |
| }, true); |
| return [reference.name, reference.value]; |
| })); |
| return asLiteral(refsParam); |
| }; |
| TemplateDefinitionBuilder.prototype.prepareListenerParameter = function (tagName, outputAst, index) { |
| var _this = this; |
| return function () { |
| var eventName = outputAst.name; |
| var bindingFnName = outputAst.type === 1 /* Animation */ ? |
| // synthetic @listener.foo values are treated the exact same as are standard listeners |
| prepareSyntheticListenerFunctionName(eventName, outputAst.phase) : |
| sanitizeIdentifier(eventName); |
| var handlerName = _this.templateName + "_" + tagName + "_" + bindingFnName + "_" + index + "_listener"; |
| var scope = _this._bindingScope.nestedScope(_this._bindingScope.bindingLevel, EVENT_BINDING_SCOPE_GLOBALS); |
| return prepareEventListenerParameters(outputAst, handlerName, scope); |
| }; |
| }; |
| return TemplateDefinitionBuilder; |
| }()); |
| var ValueConverter = /** @class */ (function (_super) { |
| __extends(ValueConverter, _super); |
| function ValueConverter(constantPool, allocateSlot, allocatePureFunctionSlots, definePipe) { |
| var _this = _super.call(this) || this; |
| _this.constantPool = constantPool; |
| _this.allocateSlot = allocateSlot; |
| _this.allocatePureFunctionSlots = allocatePureFunctionSlots; |
| _this.definePipe = definePipe; |
| _this._pipeBindExprs = []; |
| return _this; |
| } |
| // AstMemoryEfficientTransformer |
| ValueConverter.prototype.visitPipe = function (pipe, context) { |
| // Allocate a slot to create the pipe |
| var slot = this.allocateSlot(); |
| var slotPseudoLocal = "PIPE:" + slot; |
| // Allocate one slot for the result plus one slot per pipe argument |
| var pureFunctionSlot = this.allocatePureFunctionSlots(2 + pipe.args.length); |
| var target = new PropertyRead(pipe.span, pipe.sourceSpan, pipe.nameSpan, new ImplicitReceiver(pipe.span, pipe.sourceSpan), slotPseudoLocal); |
| var _c = pipeBindingCallInfo(pipe.args), identifier = _c.identifier, isVarLength = _c.isVarLength; |
| this.definePipe(pipe.name, slotPseudoLocal, slot, importExpr(identifier)); |
| var args = __spread([pipe.exp], pipe.args); |
| var convertedArgs = isVarLength ? |
| this.visitAll([new LiteralArray(pipe.span, pipe.sourceSpan, args)]) : |
| this.visitAll(args); |
| var pipeBindExpr = new FunctionCall(pipe.span, pipe.sourceSpan, target, __spread([ |
| new LiteralPrimitive(pipe.span, pipe.sourceSpan, slot), |
| new LiteralPrimitive(pipe.span, pipe.sourceSpan, pureFunctionSlot) |
| ], convertedArgs)); |
| this._pipeBindExprs.push(pipeBindExpr); |
| return pipeBindExpr; |
| }; |
| ValueConverter.prototype.updatePipeSlotOffsets = function (bindingSlots) { |
| this._pipeBindExprs.forEach(function (pipe) { |
| // update the slot offset arg (index 1) to account for binding slots |
| var slotOffset = pipe.args[1]; |
| slotOffset.value += bindingSlots; |
| }); |
| }; |
| ValueConverter.prototype.visitLiteralArray = function (array, context) { |
| var _this = this; |
| return new BuiltinFunctionCall(array.span, array.sourceSpan, this.visitAll(array.expressions), function (values) { |
| // If the literal has calculated (non-literal) elements transform it into |
| // calls to literal factories that compose the literal and will cache intermediate |
| // values. |
| var literal = literalArr(values); |
| return getLiteralFactory(_this.constantPool, literal, _this.allocatePureFunctionSlots); |
| }); |
| }; |
| ValueConverter.prototype.visitLiteralMap = function (map, context) { |
| var _this = this; |
| return new BuiltinFunctionCall(map.span, map.sourceSpan, this.visitAll(map.values), function (values) { |
| // If the literal has calculated (non-literal) elements transform it into |
| // calls to literal factories that compose the literal and will cache intermediate |
| // values. |
| var literal = literalMap(values.map(function (value, index) { return ({ key: map.keys[index].key, value: value, quoted: map.keys[index].quoted }); })); |
| return getLiteralFactory(_this.constantPool, literal, _this.allocatePureFunctionSlots); |
| }); |
| }; |
| return ValueConverter; |
| }(AstMemoryEfficientTransformer)); |
| // Pipes always have at least one parameter, the value they operate on |
| var pipeBindingIdentifiers = [Identifiers$1.pipeBind1, Identifiers$1.pipeBind2, Identifiers$1.pipeBind3, Identifiers$1.pipeBind4]; |
| function pipeBindingCallInfo(args) { |
| var identifier = pipeBindingIdentifiers[args.length]; |
| return { |
| identifier: identifier || Identifiers$1.pipeBindV, |
| isVarLength: !identifier, |
| }; |
| } |
| var pureFunctionIdentifiers = [ |
| Identifiers$1.pureFunction0, Identifiers$1.pureFunction1, Identifiers$1.pureFunction2, Identifiers$1.pureFunction3, Identifiers$1.pureFunction4, |
| Identifiers$1.pureFunction5, Identifiers$1.pureFunction6, Identifiers$1.pureFunction7, Identifiers$1.pureFunction8 |
| ]; |
| function pureFunctionCallInfo(args) { |
| var identifier = pureFunctionIdentifiers[args.length]; |
| return { |
| identifier: identifier || Identifiers$1.pureFunctionV, |
| isVarLength: !identifier, |
| }; |
| } |
| function instruction(span, reference, params) { |
| return importExpr(reference, null, span).callFn(params, span); |
| } |
| // e.g. x(2); |
| function generateNextContextExpr(relativeLevelDiff) { |
| return importExpr(Identifiers$1.nextContext) |
| .callFn(relativeLevelDiff > 1 ? [literal(relativeLevelDiff)] : []); |
| } |
| function getLiteralFactory(constantPool, literal$1, allocateSlots) { |
| var _c = constantPool.getLiteralFactory(literal$1), literalFactory = _c.literalFactory, literalFactoryArguments = _c.literalFactoryArguments; |
| // Allocate 1 slot for the result plus 1 per argument |
| var startSlot = allocateSlots(1 + literalFactoryArguments.length); |
| var _d = pureFunctionCallInfo(literalFactoryArguments), identifier = _d.identifier, isVarLength = _d.isVarLength; |
| // Literal factories are pure functions that only need to be re-invoked when the parameters |
| // change. |
| var args = [literal(startSlot), literalFactory]; |
| if (isVarLength) { |
| args.push(literalArr(literalFactoryArguments)); |
| } |
| else { |
| args.push.apply(args, __spread(literalFactoryArguments)); |
| } |
| return importExpr(identifier).callFn(args); |
| } |
| /** |
| * Gets an array of literals that can be added to an expression |
| * to represent the name and namespace of an attribute. E.g. |
| * `:xlink:href` turns into `[AttributeMarker.NamespaceURI, 'xlink', 'href']`. |
| * |
| * @param name Name of the attribute, including the namespace. |
| */ |
| function getAttributeNameLiterals(name) { |
| var _c = __read(splitNsName(name), 2), attributeNamespace = _c[0], attributeName = _c[1]; |
| var nameLiteral = literal(attributeName); |
| if (attributeNamespace) { |
| return [ |
| literal(0 /* NamespaceURI */), literal(attributeNamespace), nameLiteral |
| ]; |
| } |
| return [nameLiteral]; |
| } |
| /** The prefix used to get a shared context in BindingScope's map. */ |
| var SHARED_CONTEXT_KEY = '$$shared_ctx$$'; |
| var BindingScope = /** @class */ (function () { |
| function BindingScope(bindingLevel, parent, globals) { |
| var e_3, _c; |
| if (bindingLevel === void 0) { bindingLevel = 0; } |
| if (parent === void 0) { parent = null; } |
| this.bindingLevel = bindingLevel; |
| this.parent = parent; |
| this.globals = globals; |
| /** Keeps a map from local variables to their BindingData. */ |
| this.map = new Map(); |
| this.referenceNameIndex = 0; |
| this.restoreViewVariable = null; |
| if (globals !== undefined) { |
| try { |
| for (var globals_1 = __values(globals), globals_1_1 = globals_1.next(); !globals_1_1.done; globals_1_1 = globals_1.next()) { |
| var name = globals_1_1.value; |
| this.set(0, name, variable(name)); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (globals_1_1 && !globals_1_1.done && (_c = globals_1.return)) _c.call(globals_1); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| } |
| } |
| BindingScope.createRootScope = function () { |
| return new BindingScope(); |
| }; |
| BindingScope.prototype.get = function (name) { |
| var current = this; |
| while (current) { |
| var value = current.map.get(name); |
| if (value != null) { |
| if (current !== this) { |
| // make a local copy and reset the `declare` state |
| value = { |
| retrievalLevel: value.retrievalLevel, |
| lhs: value.lhs, |
| declareLocalCallback: value.declareLocalCallback, |
| declare: false, |
| priority: value.priority, |
| localRef: value.localRef |
| }; |
| // Cache the value locally. |
| this.map.set(name, value); |
| // Possibly generate a shared context var |
| this.maybeGenerateSharedContextVar(value); |
| this.maybeRestoreView(value.retrievalLevel, value.localRef); |
| } |
| if (value.declareLocalCallback && !value.declare) { |
| value.declare = true; |
| } |
| return value.lhs; |
| } |
| current = current.parent; |
| } |
| // If we get to this point, we are looking for a property on the top level component |
| // - If level === 0, we are on the top and don't need to re-declare `ctx`. |
| // - If level > 0, we are in an embedded view. We need to retrieve the name of the |
| // local var we used to store the component context, e.g. const $comp$ = x(); |
| return this.bindingLevel === 0 ? null : this.getComponentProperty(name); |
| }; |
| /** |
| * Create a local variable for later reference. |
| * |
| * @param retrievalLevel The level from which this value can be retrieved |
| * @param name Name of the variable. |
| * @param lhs AST representing the left hand side of the `let lhs = rhs;`. |
| * @param priority The sorting priority of this var |
| * @param declareLocalCallback The callback to invoke when declaring this local var |
| * @param localRef Whether or not this is a local ref |
| */ |
| BindingScope.prototype.set = function (retrievalLevel, name, lhs, priority /* DEFAULT */, declareLocalCallback, localRef) { |
| if (priority === void 0) { priority = 0; } |
| if (this.map.has(name)) { |
| if (localRef) { |
| // Do not throw an error if it's a local ref and do not update existing value, |
| // so the first defined ref is always returned. |
| return this; |
| } |
| error("The name " + name + " is already defined in scope to be " + this.map.get(name)); |
| } |
| this.map.set(name, { |
| retrievalLevel: retrievalLevel, |
| lhs: lhs, |
| declare: false, |
| declareLocalCallback: declareLocalCallback, |
| priority: priority, |
| localRef: localRef || false |
| }); |
| return this; |
| }; |
| // Implemented as part of LocalResolver. |
| BindingScope.prototype.getLocal = function (name) { |
| return this.get(name); |
| }; |
| // Implemented as part of LocalResolver. |
| BindingScope.prototype.notifyImplicitReceiverUse = function () { |
| if (this.bindingLevel !== 0) { |
| // Since the implicit receiver is accessed in an embedded view, we need to |
| // ensure that we declare a shared context variable for the current template |
| // in the update variables. |
| this.map.get(SHARED_CONTEXT_KEY + 0).declare = true; |
| } |
| }; |
| BindingScope.prototype.nestedScope = function (level, globals) { |
| var newScope = new BindingScope(level, this, globals); |
| if (level > 0) |
| newScope.generateSharedContextVar(0); |
| return newScope; |
| }; |
| /** |
| * Gets or creates a shared context variable and returns its expression. Note that |
| * this does not mean that the shared variable will be declared. Variables in the |
| * binding scope will be only declared if they are used. |
| */ |
| BindingScope.prototype.getOrCreateSharedContextVar = function (retrievalLevel) { |
| var bindingKey = SHARED_CONTEXT_KEY + retrievalLevel; |
| if (!this.map.has(bindingKey)) { |
| this.generateSharedContextVar(retrievalLevel); |
| } |
| // Shared context variables are always generated as "ReadVarExpr". |
| return this.map.get(bindingKey).lhs; |
| }; |
| BindingScope.prototype.getSharedContextName = function (retrievalLevel) { |
| var sharedCtxObj = this.map.get(SHARED_CONTEXT_KEY + retrievalLevel); |
| // Shared context variables are always generated as "ReadVarExpr". |
| return sharedCtxObj && sharedCtxObj.declare ? sharedCtxObj.lhs : null; |
| }; |
| BindingScope.prototype.maybeGenerateSharedContextVar = function (value) { |
| if (value.priority === 1 /* CONTEXT */ && |
| value.retrievalLevel < this.bindingLevel) { |
| var sharedCtxObj = this.map.get(SHARED_CONTEXT_KEY + value.retrievalLevel); |
| if (sharedCtxObj) { |
| sharedCtxObj.declare = true; |
| } |
| else { |
| this.generateSharedContextVar(value.retrievalLevel); |
| } |
| } |
| }; |
| BindingScope.prototype.generateSharedContextVar = function (retrievalLevel) { |
| var lhs = variable(CONTEXT_NAME + this.freshReferenceName()); |
| this.map.set(SHARED_CONTEXT_KEY + retrievalLevel, { |
| retrievalLevel: retrievalLevel, |
| lhs: lhs, |
| declareLocalCallback: function (scope, relativeLevel) { |
| // const ctx_r0 = nextContext(2); |
| return [lhs.set(generateNextContextExpr(relativeLevel)).toConstDecl()]; |
| }, |
| declare: false, |
| priority: 2 /* SHARED_CONTEXT */, |
| localRef: false |
| }); |
| }; |
| BindingScope.prototype.getComponentProperty = function (name) { |
| var componentValue = this.map.get(SHARED_CONTEXT_KEY + 0); |
| componentValue.declare = true; |
| this.maybeRestoreView(0, false); |
| return componentValue.lhs.prop(name); |
| }; |
| BindingScope.prototype.maybeRestoreView = function (retrievalLevel, localRefLookup) { |
| // We want to restore the current view in listener fns if: |
| // 1 - we are accessing a value in a parent view, which requires walking the view tree rather |
| // than using the ctx arg. In this case, the retrieval and binding level will be different. |
| // 2 - we are looking up a local ref, which requires restoring the view where the local |
| // ref is stored |
| if (this.isListenerScope() && (retrievalLevel < this.bindingLevel || localRefLookup)) { |
| if (!this.parent.restoreViewVariable) { |
| // parent saves variable to generate a shared `const $s$ = getCurrentView();` instruction |
| this.parent.restoreViewVariable = variable(this.parent.freshReferenceName()); |
| } |
| this.restoreViewVariable = this.parent.restoreViewVariable; |
| } |
| }; |
| BindingScope.prototype.restoreViewStatement = function () { |
| // restoreView($state$); |
| return this.restoreViewVariable ? |
| [instruction(null, Identifiers$1.restoreView, [this.restoreViewVariable]).toStmt()] : |
| []; |
| }; |
| BindingScope.prototype.viewSnapshotStatements = function () { |
| // const $state$ = getCurrentView(); |
| var getCurrentViewInstruction = instruction(null, Identifiers$1.getCurrentView, []); |
| return this.restoreViewVariable ? |
| [this.restoreViewVariable.set(getCurrentViewInstruction).toConstDecl()] : |
| []; |
| }; |
| BindingScope.prototype.isListenerScope = function () { |
| return this.parent && this.parent.bindingLevel === this.bindingLevel; |
| }; |
| BindingScope.prototype.variableDeclarations = function () { |
| var _this = this; |
| var currentContextLevel = 0; |
| return Array.from(this.map.values()) |
| .filter(function (value) { return value.declare; }) |
| .sort(function (a, b) { return b.retrievalLevel - a.retrievalLevel || b.priority - a.priority; }) |
| .reduce(function (stmts, value) { |
| var levelDiff = _this.bindingLevel - value.retrievalLevel; |
| var currStmts = value.declareLocalCallback(_this, levelDiff - currentContextLevel); |
| currentContextLevel = levelDiff; |
| return stmts.concat(currStmts); |
| }, []); |
| }; |
| BindingScope.prototype.freshReferenceName = function () { |
| var current = this; |
| // Find the top scope as it maintains the global reference count |
| while (current.parent) |
| current = current.parent; |
| var ref = "" + REFERENCE_PREFIX + current.referenceNameIndex++; |
| return ref; |
| }; |
| return BindingScope; |
| }()); |
| /** |
| * Creates a `CssSelector` given a tag name and a map of attributes |
| */ |
| function createCssSelector(elementName, attributes) { |
| var cssSelector = new CssSelector(); |
| var elementNameNoNs = splitNsName(elementName)[1]; |
| cssSelector.setElement(elementNameNoNs); |
| Object.getOwnPropertyNames(attributes).forEach(function (name) { |
| var nameNoNs = splitNsName(name)[1]; |
| var value = attributes[name]; |
| cssSelector.addAttribute(nameNoNs, value); |
| if (name.toLowerCase() === 'class') { |
| var classes = value.trim().split(/\s+/); |
| classes.forEach(function (className) { return cssSelector.addClassName(className); }); |
| } |
| }); |
| return cssSelector; |
| } |
| /** |
| * Creates an array of expressions out of an `ngProjectAs` attributes |
| * which can be added to the instruction parameters. |
| */ |
| function getNgProjectAsLiteral(attribute) { |
| // Parse the attribute value into a CssSelectorList. Note that we only take the |
| // first selector, because we don't support multiple selectors in ngProjectAs. |
| var parsedR3Selector = parseSelectorToR3Selector(attribute.value)[0]; |
| return [literal(5 /* ProjectAs */), asLiteral(parsedR3Selector)]; |
| } |
| /** |
| * Gets the instruction to generate for an interpolated property |
| * @param interpolation An Interpolation AST |
| */ |
| function getPropertyInterpolationExpression(interpolation) { |
| switch (getInterpolationArgsLength(interpolation)) { |
| case 1: |
| return Identifiers$1.propertyInterpolate; |
| case 3: |
| return Identifiers$1.propertyInterpolate1; |
| case 5: |
| return Identifiers$1.propertyInterpolate2; |
| case 7: |
| return Identifiers$1.propertyInterpolate3; |
| case 9: |
| return Identifiers$1.propertyInterpolate4; |
| case 11: |
| return Identifiers$1.propertyInterpolate5; |
| case 13: |
| return Identifiers$1.propertyInterpolate6; |
| case 15: |
| return Identifiers$1.propertyInterpolate7; |
| case 17: |
| return Identifiers$1.propertyInterpolate8; |
| default: |
| return Identifiers$1.propertyInterpolateV; |
| } |
| } |
| /** |
| * Gets the instruction to generate for an interpolated attribute |
| * @param interpolation An Interpolation AST |
| */ |
| function getAttributeInterpolationExpression(interpolation) { |
| switch (getInterpolationArgsLength(interpolation)) { |
| case 3: |
| return Identifiers$1.attributeInterpolate1; |
| case 5: |
| return Identifiers$1.attributeInterpolate2; |
| case 7: |
| return Identifiers$1.attributeInterpolate3; |
| case 9: |
| return Identifiers$1.attributeInterpolate4; |
| case 11: |
| return Identifiers$1.attributeInterpolate5; |
| case 13: |
| return Identifiers$1.attributeInterpolate6; |
| case 15: |
| return Identifiers$1.attributeInterpolate7; |
| case 17: |
| return Identifiers$1.attributeInterpolate8; |
| default: |
| return Identifiers$1.attributeInterpolateV; |
| } |
| } |
| /** |
| * Gets the instruction to generate for interpolated text. |
| * @param interpolation An Interpolation AST |
| */ |
| function getTextInterpolationExpression(interpolation) { |
| switch (getInterpolationArgsLength(interpolation)) { |
| case 1: |
| return Identifiers$1.textInterpolate; |
| case 3: |
| return Identifiers$1.textInterpolate1; |
| case 5: |
| return Identifiers$1.textInterpolate2; |
| case 7: |
| return Identifiers$1.textInterpolate3; |
| case 9: |
| return Identifiers$1.textInterpolate4; |
| case 11: |
| return Identifiers$1.textInterpolate5; |
| case 13: |
| return Identifiers$1.textInterpolate6; |
| case 15: |
| return Identifiers$1.textInterpolate7; |
| case 17: |
| return Identifiers$1.textInterpolate8; |
| default: |
| return Identifiers$1.textInterpolateV; |
| } |
| } |
| /** |
| * Parse a template into render3 `Node`s and additional metadata, with no other dependencies. |
| * |
| * @param template text of the template to parse |
| * @param templateUrl URL to use for source mapping of the parsed template |
| * @param options options to modify how the template is parsed |
| */ |
| function parseTemplate(template, templateUrl, options) { |
| if (options === void 0) { options = {}; } |
| var _a; |
| var interpolationConfig = options.interpolationConfig, preserveWhitespaces = options.preserveWhitespaces, enableI18nLegacyMessageIdFormat = options.enableI18nLegacyMessageIdFormat; |
| var isInline = (_a = options.isInline) !== null && _a !== void 0 ? _a : false; |
| var bindingParser = makeBindingParser(interpolationConfig); |
| var htmlParser = new HtmlParser(); |
| var parseResult = htmlParser.parse(template, templateUrl, Object.assign(Object.assign({ leadingTriviaChars: LEADING_TRIVIA_CHARS }, options), { tokenizeExpansionForms: true })); |
| if (!options.alwaysAttemptHtmlToR3AstConversion && parseResult.errors && |
| parseResult.errors.length > 0) { |
| var parsedTemplate_1 = { |
| interpolationConfig: interpolationConfig, |
| preserveWhitespaces: preserveWhitespaces, |
| template: template, |
| templateUrl: templateUrl, |
| isInline: isInline, |
| errors: parseResult.errors, |
| nodes: [], |
| styleUrls: [], |
| styles: [], |
| ngContentSelectors: [] |
| }; |
| if (options.collectCommentNodes) { |
| parsedTemplate_1.commentNodes = []; |
| } |
| return parsedTemplate_1; |
| } |
| var rootNodes = parseResult.rootNodes; |
| // process i18n meta information (scan attributes, generate ids) |
| // before we run whitespace removal process, because existing i18n |
| // extraction process (ng extract-i18n) relies on a raw content to generate |
| // message ids |
| var i18nMetaVisitor = new I18nMetaVisitor(interpolationConfig, /* keepI18nAttrs */ !preserveWhitespaces, enableI18nLegacyMessageIdFormat); |
| var i18nMetaResult = i18nMetaVisitor.visitAllWithErrors(rootNodes); |
| if (!options.alwaysAttemptHtmlToR3AstConversion && i18nMetaResult.errors && |
| i18nMetaResult.errors.length > 0) { |
| var parsedTemplate_2 = { |
| interpolationConfig: interpolationConfig, |
| preserveWhitespaces: preserveWhitespaces, |
| template: template, |
| templateUrl: templateUrl, |
| isInline: isInline, |
| errors: i18nMetaResult.errors, |
| nodes: [], |
| styleUrls: [], |
| styles: [], |
| ngContentSelectors: [] |
| }; |
| if (options.collectCommentNodes) { |
| parsedTemplate_2.commentNodes = []; |
| } |
| return parsedTemplate_2; |
| } |
| rootNodes = i18nMetaResult.rootNodes; |
| if (!preserveWhitespaces) { |
| rootNodes = visitAll$1(new WhitespaceVisitor(), rootNodes); |
| // run i18n meta visitor again in case whitespaces are removed (because that might affect |
| // generated i18n message content) and first pass indicated that i18n content is present in a |
| // template. During this pass i18n IDs generated at the first pass will be preserved, so we can |
| // mimic existing extraction process (ng extract-i18n) |
| if (i18nMetaVisitor.hasI18nMeta) { |
| rootNodes = visitAll$1(new I18nMetaVisitor(interpolationConfig, /* keepI18nAttrs */ false), rootNodes); |
| } |
| } |
| var _c = htmlAstToRender3Ast(rootNodes, bindingParser, { collectCommentNodes: !!options.collectCommentNodes }), nodes = _c.nodes, errors = _c.errors, styleUrls = _c.styleUrls, styles = _c.styles, ngContentSelectors = _c.ngContentSelectors, commentNodes = _c.commentNodes; |
| errors.push.apply(errors, __spread(parseResult.errors, i18nMetaResult.errors)); |
| var parsedTemplate = { |
| interpolationConfig: interpolationConfig, |
| preserveWhitespaces: preserveWhitespaces, |
| errors: errors.length > 0 ? errors : null, |
| template: template, |
| templateUrl: templateUrl, |
| isInline: isInline, |
| nodes: nodes, |
| styleUrls: styleUrls, |
| styles: styles, |
| ngContentSelectors: ngContentSelectors |
| }; |
| if (options.collectCommentNodes) { |
| parsedTemplate.commentNodes = commentNodes; |
| } |
| return parsedTemplate; |
| } |
| var elementRegistry = new DomElementSchemaRegistry(); |
| /** |
| * Construct a `BindingParser` with a default configuration. |
| */ |
| function makeBindingParser(interpolationConfig) { |
| if (interpolationConfig === void 0) { interpolationConfig = DEFAULT_INTERPOLATION_CONFIG; } |
| return new BindingParser(new IvyParser(new Lexer()), interpolationConfig, elementRegistry, null, []); |
| } |
| function resolveSanitizationFn(context, isAttribute) { |
| switch (context) { |
| case SecurityContext.HTML: |
| return importExpr(Identifiers$1.sanitizeHtml); |
| case SecurityContext.SCRIPT: |
| return importExpr(Identifiers$1.sanitizeScript); |
| case SecurityContext.STYLE: |
| // the compiler does not fill in an instruction for [style.prop?] binding |
| // values because the style algorithm knows internally what props are subject |
| // to sanitization (only [attr.style] values are explicitly sanitized) |
| return isAttribute ? importExpr(Identifiers$1.sanitizeStyle) : null; |
| case SecurityContext.URL: |
| return importExpr(Identifiers$1.sanitizeUrl); |
| case SecurityContext.RESOURCE_URL: |
| return importExpr(Identifiers$1.sanitizeResourceUrl); |
| default: |
| return null; |
| } |
| } |
| function trustedConstAttribute(tagName, attr) { |
| var value = asLiteral(attr.value); |
| if (isTrustedTypesSink(tagName, attr.name)) { |
| switch (elementRegistry.securityContext(tagName, attr.name, /* isAttribute */ true)) { |
| case SecurityContext.HTML: |
| return taggedTemplate(importExpr(Identifiers$1.trustConstantHtml), new TemplateLiteral([new TemplateLiteralElement(attr.value)], []), undefined, attr.valueSpan); |
| // NB: no SecurityContext.SCRIPT here, as the corresponding tags are stripped by the compiler. |
| case SecurityContext.RESOURCE_URL: |
| return taggedTemplate(importExpr(Identifiers$1.trustConstantResourceUrl), new TemplateLiteral([new TemplateLiteralElement(attr.value)], []), undefined, attr.valueSpan); |
| default: |
| return value; |
| } |
| } |
| else { |
| return value; |
| } |
| } |
| function isSingleElementTemplate(children) { |
| return children.length === 1 && children[0] instanceof Element; |
| } |
| function isTextNode(node) { |
| return node instanceof Text || node instanceof BoundText || node instanceof Icu; |
| } |
| function hasTextChildrenOnly(children) { |
| return children.every(isTextNode); |
| } |
| /** Name of the global variable that is used to determine if we use Closure translations or not */ |
| var NG_I18N_CLOSURE_MODE = 'ngI18nClosureMode'; |
| /** |
| * Generate statements that define a given translation message. |
| * |
| * ``` |
| * var I18N_1; |
| * if (typeof ngI18nClosureMode !== undefined && ngI18nClosureMode) { |
| * var MSG_EXTERNAL_XXX = goog.getMsg( |
| * "Some message with {$interpolation}!", |
| * { "interpolation": "\uFFFD0\uFFFD" } |
| * ); |
| * I18N_1 = MSG_EXTERNAL_XXX; |
| * } |
| * else { |
| * I18N_1 = $localize`Some message with ${'\uFFFD0\uFFFD'}!`; |
| * } |
| * ``` |
| * |
| * @param message The original i18n AST message node |
| * @param variable The variable that will be assigned the translation, e.g. `I18N_1`. |
| * @param closureVar The variable for Closure `goog.getMsg` calls, e.g. `MSG_EXTERNAL_XXX`. |
| * @param params Object mapping placeholder names to their values (e.g. |
| * `{ "interpolation": "\uFFFD0\uFFFD" }`). |
| * @param transformFn Optional transformation function that will be applied to the translation (e.g. |
| * post-processing). |
| * @returns An array of statements that defined a given translation. |
| */ |
| function getTranslationDeclStmts(message, variable, closureVar, params, transformFn) { |
| if (params === void 0) { params = {}; } |
| var statements = [ |
| declareI18nVariable(variable), |
| ifStmt(createClosureModeGuard(), createGoogleGetMsgStatements(variable, message, closureVar, i18nFormatPlaceholderNames(params, /* useCamelCase */ true)), createLocalizeStatements(variable, message, i18nFormatPlaceholderNames(params, /* useCamelCase */ false))), |
| ]; |
| if (transformFn) { |
| statements.push(new ExpressionStatement(variable.set(transformFn(variable)))); |
| } |
| return statements; |
| } |
| /** |
| * Create the expression that will be used to guard the closure mode block |
| * It is equivalent to: |
| * |
| * ``` |
| * typeof ngI18nClosureMode !== undefined && ngI18nClosureMode |
| * ``` |
| */ |
| function createClosureModeGuard() { |
| return typeofExpr(variable(NG_I18N_CLOSURE_MODE)) |
| .notIdentical(literal('undefined', STRING_TYPE)) |
| .and(variable(NG_I18N_CLOSURE_MODE)); |
| } |
| |
| // This regex matches any binding names that contain the "attr." prefix, e.g. "attr.required" |
| // If there is a match, the first matching group will contain the attribute name to bind. |
| var ATTR_REGEX = /attr\.([^\]]+)/; |
| function baseDirectiveFields(meta, constantPool, bindingParser) { |
| var definitionMap = new DefinitionMap(); |
| var selectors = parseSelectorToR3Selector(meta.selector); |
| // e.g. `type: MyDirective` |
| definitionMap.set('type', meta.internalType); |
| // e.g. `selectors: [['', 'someDir', '']]` |
| if (selectors.length > 0) { |
| definitionMap.set('selectors', asLiteral(selectors)); |
| } |
| if (meta.queries.length > 0) { |
| // e.g. `contentQueries: (rf, ctx, dirIndex) => { ... } |
| definitionMap.set('contentQueries', createContentQueriesFunction(meta.queries, constantPool, meta.name)); |
| } |
| if (meta.viewQueries.length) { |
| definitionMap.set('viewQuery', createViewQueriesFunction(meta.viewQueries, constantPool, meta.name)); |
| } |
| // e.g. `hostBindings: (rf, ctx) => { ... } |
| definitionMap.set('hostBindings', createHostBindingsFunction(meta.host, meta.typeSourceSpan, bindingParser, constantPool, meta.selector || '', meta.name, definitionMap)); |
| // e.g 'inputs: {a: 'a'}` |
| definitionMap.set('inputs', conditionallyCreateMapObjectLiteral(meta.inputs, true)); |
| // e.g 'outputs: {a: 'a'}` |
| definitionMap.set('outputs', conditionallyCreateMapObjectLiteral(meta.outputs)); |
| if (meta.exportAs !== null) { |
| definitionMap.set('exportAs', literalArr(meta.exportAs.map(function (e) { return literal(e); }))); |
| } |
| return definitionMap; |
| } |
| /** |
| * Add features to the definition map. |
| */ |
| function addFeatures(definitionMap, meta) { |
| // e.g. `features: [NgOnChangesFeature]` |
| var features = []; |
| var providers = meta.providers; |
| var viewProviders = meta.viewProviders; |
| if (providers || viewProviders) { |
| var args = [providers || new LiteralArrayExpr([])]; |
| if (viewProviders) { |
| args.push(viewProviders); |
| } |
| features.push(importExpr(Identifiers$1.ProvidersFeature).callFn(args)); |
| } |
| if (meta.usesInheritance) { |
| features.push(importExpr(Identifiers$1.InheritDefinitionFeature)); |
| } |
| if (meta.fullInheritance) { |
| features.push(importExpr(Identifiers$1.CopyDefinitionFeature)); |
| } |
| if (meta.lifecycle.usesOnChanges) { |
| features.push(importExpr(Identifiers$1.NgOnChangesFeature)); |
| } |
| if (features.length) { |
| definitionMap.set('features', literalArr(features)); |
| } |
| } |
| /** |
| * Compile a directive for the render3 runtime as defined by the `R3DirectiveMetadata`. |
| */ |
| function compileDirectiveFromMetadata(meta, constantPool, bindingParser) { |
| var definitionMap = baseDirectiveFields(meta, constantPool, bindingParser); |
| addFeatures(definitionMap, meta); |
| var expression = importExpr(Identifiers$1.defineDirective).callFn([definitionMap.toLiteralMap()]); |
| var type = createDirectiveType(meta); |
| return { expression: expression, type: type }; |
| } |
| /** |
| * Compile a component for the render3 runtime as defined by the `R3ComponentMetadata`. |
| */ |
| function compileComponentFromMetadata(meta, constantPool, bindingParser) { |
| var e_1, _a; |
| var definitionMap = baseDirectiveFields(meta, constantPool, bindingParser); |
| addFeatures(definitionMap, meta); |
| var selector = meta.selector && CssSelector.parse(meta.selector); |
| var firstSelector = selector && selector[0]; |
| // e.g. `attr: ["class", ".my.app"]` |
| // This is optional an only included if the first selector of a component specifies attributes. |
| if (firstSelector) { |
| var selectorAttributes = firstSelector.getAttrs(); |
| if (selectorAttributes.length) { |
| definitionMap.set('attrs', constantPool.getConstLiteral(literalArr(selectorAttributes.map(function (value) { return value != null ? literal(value) : literal(undefined); })), |
| /* forceShared */ true)); |
| } |
| } |
| // Generate the CSS matcher that recognize directive |
| var directiveMatcher = null; |
| if (meta.directives.length > 0) { |
| var matcher = new SelectorMatcher(); |
| try { |
| for (var _b = __values(meta.directives), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var _d = _c.value, selector_1 = _d.selector, type_1 = _d.type; |
| matcher.addSelectables(CssSelector.parse(selector_1), type_1); |
| } |
| } |
| 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; } |
| } |
| directiveMatcher = matcher; |
| } |
| // e.g. `template: function MyComponent_Template(_ctx, _cm) {...}` |
| var templateTypeName = meta.name; |
| var templateName = templateTypeName ? templateTypeName + "_Template" : null; |
| var directivesUsed = new Set(); |
| var pipesUsed = new Set(); |
| var changeDetection = meta.changeDetection; |
| var template = meta.template; |
| var templateBuilder = new TemplateDefinitionBuilder(constantPool, BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName, directiveMatcher, directivesUsed, meta.pipes, pipesUsed, Identifiers$1.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds); |
| var templateFunctionExpression = templateBuilder.buildTemplateFunction(template.nodes, []); |
| // We need to provide this so that dynamically generated components know what |
| // projected content blocks to pass through to the component when it is instantiated. |
| var ngContentSelectors = templateBuilder.getNgContentSelectors(); |
| if (ngContentSelectors) { |
| definitionMap.set('ngContentSelectors', ngContentSelectors); |
| } |
| // e.g. `decls: 2` |
| definitionMap.set('decls', literal(templateBuilder.getConstCount())); |
| // e.g. `vars: 2` |
| definitionMap.set('vars', literal(templateBuilder.getVarCount())); |
| // Generate `consts` section of ComponentDef: |
| // - either as an array: |
| // `consts: [['one', 'two'], ['three', 'four']]` |
| // - or as a factory function in case additional statements are present (to support i18n): |
| // `consts: function() { var i18n_0; if (ngI18nClosureMode) {...} else {...} return [i18n_0]; }` |
| var _e = templateBuilder.getConsts(), constExpressions = _e.constExpressions, prepareStatements = _e.prepareStatements; |
| if (constExpressions.length > 0) { |
| var constsExpr = literalArr(constExpressions); |
| // Prepare statements are present - turn `consts` into a function. |
| if (prepareStatements.length > 0) { |
| constsExpr = fn([], __spread(prepareStatements, [new ReturnStatement(constsExpr)])); |
| } |
| definitionMap.set('consts', constsExpr); |
| } |
| definitionMap.set('template', templateFunctionExpression); |
| // e.g. `directives: [MyDirective]` |
| if (directivesUsed.size) { |
| var directivesList = literalArr(Array.from(directivesUsed)); |
| var directivesExpr = compileDeclarationList(directivesList, meta.declarationListEmitMode); |
| definitionMap.set('directives', directivesExpr); |
| } |
| // e.g. `pipes: [MyPipe]` |
| if (pipesUsed.size) { |
| var pipesList = literalArr(Array.from(pipesUsed)); |
| var pipesExpr = compileDeclarationList(pipesList, meta.declarationListEmitMode); |
| definitionMap.set('pipes', pipesExpr); |
| } |
| if (meta.encapsulation === null) { |
| meta.encapsulation = ViewEncapsulation.Emulated; |
| } |
| // e.g. `styles: [str1, str2]` |
| if (meta.styles && meta.styles.length) { |
| var styleValues = meta.encapsulation == ViewEncapsulation.Emulated ? |
| compileStyles(meta.styles, CONTENT_ATTR, HOST_ATTR) : |
| meta.styles; |
| var strings = styleValues.map(function (str) { return constantPool.getConstLiteral(literal(str)); }); |
| definitionMap.set('styles', literalArr(strings)); |
| } |
| else if (meta.encapsulation === ViewEncapsulation.Emulated) { |
| // If there is no style, don't generate css selectors on elements |
| meta.encapsulation = ViewEncapsulation.None; |
| } |
| // Only set view encapsulation if it's not the default value |
| if (meta.encapsulation !== ViewEncapsulation.Emulated) { |
| definitionMap.set('encapsulation', literal(meta.encapsulation)); |
| } |
| // e.g. `animation: [trigger('123', [])]` |
| if (meta.animations !== null) { |
| definitionMap.set('data', literalMap([{ key: 'animation', value: meta.animations, quoted: false }])); |
| } |
| // Only set the change detection flag if it's defined and it's not the default. |
| if (changeDetection != null && changeDetection !== ChangeDetectionStrategy.Default) { |
| definitionMap.set('changeDetection', literal(changeDetection)); |
| } |
| var expression = importExpr(Identifiers$1.defineComponent).callFn([definitionMap.toLiteralMap()]); |
| var type = createComponentType(meta); |
| return { expression: expression, type: type }; |
| } |
| /** |
| * Creates the type specification from the component meta. This type is inserted into .d.ts files |
| * to be consumed by upstream compilations. |
| */ |
| function createComponentType(meta) { |
| var typeParams = createDirectiveTypeParams(meta); |
| typeParams.push(stringArrayAsType(meta.template.ngContentSelectors)); |
| return expressionType(importExpr(Identifiers$1.ComponentDefWithMeta, typeParams)); |
| } |
| /** |
| * Compiles the array literal of declarations into an expression according to the provided emit |
| * mode. |
| */ |
| function compileDeclarationList(list, mode) { |
| switch (mode) { |
| case 0 /* Direct */: |
| // directives: [MyDir], |
| return list; |
| case 1 /* Closure */: |
| // directives: function () { return [MyDir]; } |
| return fn([], [new ReturnStatement(list)]); |
| case 2 /* ClosureResolved */: |
| // directives: function () { return [MyDir].map(ng.resolveForwardRef); } |
| var resolvedList = list.callMethod('map', [importExpr(Identifiers$1.resolveForwardRef)]); |
| return fn([], [new ReturnStatement(resolvedList)]); |
| } |
| } |
| function prepareQueryParams(query, constantPool) { |
| var parameters = [getQueryPredicate(query, constantPool), literal(toQueryFlags(query))]; |
| if (query.read) { |
| parameters.push(query.read); |
| } |
| return parameters; |
| } |
| /** |
| * Translates query flags into `TQueryFlags` type in packages/core/src/render3/interfaces/query.ts |
| * @param query |
| */ |
| function toQueryFlags(query) { |
| return (query.descendants ? 1 /* descendants */ : 0 /* none */) | |
| (query.static ? 2 /* isStatic */ : 0 /* none */) | |
| (query.emitDistinctChangesOnly ? 4 /* emitDistinctChangesOnly */ : 0 /* none */); |
| } |
| function convertAttributesToExpressions(attributes) { |
| var e_2, _a; |
| var values = []; |
| try { |
| for (var _b = __values(Object.getOwnPropertyNames(attributes)), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var key = _c.value; |
| var value = attributes[key]; |
| values.push(literal(key), value); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_c && !_c.done && (_a = _b.return)) _a.call(_b); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| return values; |
| } |
| // Define and update any content queries |
| function createContentQueriesFunction(queries, constantPool, name) { |
| var e_3, _a; |
| var createStatements = []; |
| var updateStatements = []; |
| var tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME); |
| try { |
| for (var queries_1 = __values(queries), queries_1_1 = queries_1.next(); !queries_1_1.done; queries_1_1 = queries_1.next()) { |
| var query = queries_1_1.value; |
| // creation, e.g. r3.contentQuery(dirIndex, somePredicate, true, null); |
| createStatements.push(importExpr(Identifiers$1.contentQuery) |
| .callFn(__spread([variable('dirIndex')], prepareQueryParams(query, constantPool))) |
| .toStmt()); |
| // update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp)); |
| var temporary = tempAllocator(); |
| var getQueryList = importExpr(Identifiers$1.loadQuery).callFn([]); |
| var refresh = importExpr(Identifiers$1.queryRefresh).callFn([temporary.set(getQueryList)]); |
| var updateDirective = variable(CONTEXT_NAME) |
| .prop(query.propertyName) |
| .set(query.first ? temporary.prop('first') : temporary); |
| updateStatements.push(refresh.and(updateDirective).toStmt()); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (queries_1_1 && !queries_1_1.done && (_a = queries_1.return)) _a.call(queries_1); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| var contentQueriesFnName = name ? name + "_ContentQueries" : null; |
| return fn([ |
| new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null), |
| new FnParam('dirIndex', null) |
| ], [ |
| renderFlagCheckIfStmt(1 /* Create */, createStatements), |
| renderFlagCheckIfStmt(2 /* Update */, updateStatements) |
| ], INFERRED_TYPE, null, contentQueriesFnName); |
| } |
| function stringAsType(str) { |
| return expressionType(literal(str)); |
| } |
| function stringMapAsType(map) { |
| var mapValues = Object.keys(map).map(function (key) { |
| var value = Array.isArray(map[key]) ? map[key][0] : map[key]; |
| return { |
| key: key, |
| value: literal(value), |
| quoted: true, |
| }; |
| }); |
| return expressionType(literalMap(mapValues)); |
| } |
| function stringArrayAsType(arr) { |
| return arr.length > 0 ? expressionType(literalArr(arr.map(function (value) { return literal(value); }))) : |
| NONE_TYPE; |
| } |
| function createDirectiveTypeParams(meta) { |
| // On the type side, remove newlines from the selector as it will need to fit into a TypeScript |
| // string literal, which must be on one line. |
| var selectorForType = meta.selector !== null ? meta.selector.replace(/\n/g, '') : null; |
| return [ |
| typeWithParameters(meta.type.type, meta.typeArgumentCount), |
| selectorForType !== null ? stringAsType(selectorForType) : NONE_TYPE, |
| meta.exportAs !== null ? stringArrayAsType(meta.exportAs) : NONE_TYPE, |
| stringMapAsType(meta.inputs), |
| stringMapAsType(meta.outputs), |
| stringArrayAsType(meta.queries.map(function (q) { return q.propertyName; })), |
| ]; |
| } |
| /** |
| * Creates the type specification from the directive meta. This type is inserted into .d.ts files |
| * to be consumed by upstream compilations. |
| */ |
| function createDirectiveType(meta) { |
| var typeParams = createDirectiveTypeParams(meta); |
| return expressionType(importExpr(Identifiers$1.DirectiveDefWithMeta, typeParams)); |
| } |
| // Define and update any view queries |
| function createViewQueriesFunction(viewQueries, constantPool, name) { |
| var createStatements = []; |
| var updateStatements = []; |
| var tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME); |
| viewQueries.forEach(function (query) { |
| // creation, e.g. r3.viewQuery(somePredicate, true); |
| var queryDefinition = importExpr(Identifiers$1.viewQuery).callFn(prepareQueryParams(query, constantPool)); |
| createStatements.push(queryDefinition.toStmt()); |
| // update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp)); |
| var temporary = tempAllocator(); |
| var getQueryList = importExpr(Identifiers$1.loadQuery).callFn([]); |
| var refresh = importExpr(Identifiers$1.queryRefresh).callFn([temporary.set(getQueryList)]); |
| var updateDirective = variable(CONTEXT_NAME) |
| .prop(query.propertyName) |
| .set(query.first ? temporary.prop('first') : temporary); |
| updateStatements.push(refresh.and(updateDirective).toStmt()); |
| }); |
| var viewQueryFnName = name ? name + "_Query" : null; |
| return fn([new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], [ |
| renderFlagCheckIfStmt(1 /* Create */, createStatements), |
| renderFlagCheckIfStmt(2 /* Update */, updateStatements) |
| ], INFERRED_TYPE, null, viewQueryFnName); |
| } |
| // Return a host binding function or null if one is not necessary. |
| function createHostBindingsFunction(hostBindingsMetadata, typeSourceSpan, bindingParser, constantPool, selector, name, definitionMap) { |
| var bindingContext = variable(CONTEXT_NAME); |
| var styleBuilder = new StylingBuilder(bindingContext); |
| var _a = hostBindingsMetadata.specialAttributes, styleAttr = _a.styleAttr, classAttr = _a.classAttr; |
| if (styleAttr !== undefined) { |
| styleBuilder.registerStyleAttr(styleAttr); |
| } |
| if (classAttr !== undefined) { |
| styleBuilder.registerClassAttr(classAttr); |
| } |
| var createStatements = []; |
| var updateStatements = []; |
| var hostBindingSourceSpan = typeSourceSpan; |
| var directiveSummary = metadataAsSummary(hostBindingsMetadata); |
| // Calculate host event bindings |
| var eventBindings = bindingParser.createDirectiveHostEventAsts(directiveSummary, hostBindingSourceSpan); |
| if (eventBindings && eventBindings.length) { |
| var listeners = createHostListeners(eventBindings, name); |
| createStatements.push.apply(createStatements, __spread(listeners)); |
| } |
| // Calculate the host property bindings |
| var bindings = bindingParser.createBoundHostProperties(directiveSummary, hostBindingSourceSpan); |
| var allOtherBindings = []; |
| // We need to calculate the total amount of binding slots required by |
| // all the instructions together before any value conversions happen. |
| // Value conversions may require additional slots for interpolation and |
| // bindings with pipes. These calculates happen after this block. |
| var totalHostVarsCount = 0; |
| bindings && bindings.forEach(function (binding) { |
| var stylingInputWasSet = styleBuilder.registerInputBasedOnName(binding.name, binding.expression, hostBindingSourceSpan); |
| if (stylingInputWasSet) { |
| totalHostVarsCount += MIN_STYLING_BINDING_SLOTS_REQUIRED; |
| } |
| else { |
| allOtherBindings.push(binding); |
| totalHostVarsCount++; |
| } |
| }); |
| var valueConverter; |
| var getValueConverter = function () { |
| if (!valueConverter) { |
| var hostVarsCountFn = function (numSlots) { |
| var originalVarsCount = totalHostVarsCount; |
| totalHostVarsCount += numSlots; |
| return originalVarsCount; |
| }; |
| valueConverter = new ValueConverter(constantPool, function () { return error('Unexpected node'); }, // new nodes are illegal here |
| hostVarsCountFn, function () { return error('Unexpected pipe'); }); // pipes are illegal here |
| } |
| return valueConverter; |
| }; |
| var propertyBindings = []; |
| var attributeBindings = []; |
| var syntheticHostBindings = []; |
| allOtherBindings.forEach(function (binding) { |
| // resolve literal arrays and literal objects |
| var value = binding.expression.visit(getValueConverter()); |
| var bindingExpr = bindingFn(bindingContext, value); |
| var _a = getBindingNameAndInstruction(binding), bindingName = _a.bindingName, instruction = _a.instruction, isAttribute = _a.isAttribute; |
| var securityContexts = bindingParser.calcPossibleSecurityContexts(selector, bindingName, isAttribute) |
| .filter(function (context) { return context !== SecurityContext.NONE; }); |
| var sanitizerFn = null; |
| if (securityContexts.length) { |
| if (securityContexts.length === 2 && |
| securityContexts.indexOf(SecurityContext.URL) > -1 && |
| securityContexts.indexOf(SecurityContext.RESOURCE_URL) > -1) { |
| // Special case for some URL attributes (such as "src" and "href") that may be a part |
| // of different security contexts. In this case we use special santitization function and |
| // select the actual sanitizer at runtime based on a tag name that is provided while |
| // invoking sanitization function. |
| sanitizerFn = importExpr(Identifiers$1.sanitizeUrlOrResourceUrl); |
| } |
| else { |
| sanitizerFn = resolveSanitizationFn(securityContexts[0], isAttribute); |
| } |
| } |
| var instructionParams = [literal(bindingName), bindingExpr.currValExpr]; |
| if (sanitizerFn) { |
| instructionParams.push(sanitizerFn); |
| } |
| updateStatements.push.apply(updateStatements, __spread(bindingExpr.stmts)); |
| if (instruction === Identifiers$1.hostProperty) { |
| propertyBindings.push(instructionParams); |
| } |
| else if (instruction === Identifiers$1.attribute) { |
| attributeBindings.push(instructionParams); |
| } |
| else if (instruction === Identifiers$1.syntheticHostProperty) { |
| syntheticHostBindings.push(instructionParams); |
| } |
| else { |
| updateStatements.push(importExpr(instruction).callFn(instructionParams).toStmt()); |
| } |
| }); |
| if (propertyBindings.length > 0) { |
| updateStatements.push(chainedInstruction(Identifiers$1.hostProperty, propertyBindings).toStmt()); |
| } |
| if (attributeBindings.length > 0) { |
| updateStatements.push(chainedInstruction(Identifiers$1.attribute, attributeBindings).toStmt()); |
| } |
| if (syntheticHostBindings.length > 0) { |
| updateStatements.push(chainedInstruction(Identifiers$1.syntheticHostProperty, syntheticHostBindings).toStmt()); |
| } |
| // since we're dealing with directives/components and both have hostBinding |
| // functions, we need to generate a special hostAttrs instruction that deals |
| // with both the assignment of styling as well as static attributes to the host |
| // element. The instruction below will instruct all initial styling (styling |
| // that is inside of a host binding within a directive/component) to be attached |
| // to the host element alongside any of the provided host attributes that were |
| // collected earlier. |
| var hostAttrs = convertAttributesToExpressions(hostBindingsMetadata.attributes); |
| styleBuilder.assignHostAttrs(hostAttrs, definitionMap); |
| if (styleBuilder.hasBindings) { |
| // finally each binding that was registered in the statement above will need to be added to |
| // the update block of a component/directive templateFn/hostBindingsFn so that the bindings |
| // are evaluated and updated for the element. |
| styleBuilder.buildUpdateLevelInstructions(getValueConverter()).forEach(function (instruction) { |
| if (instruction.calls.length > 0) { |
| var calls_1 = []; |
| instruction.calls.forEach(function (call) { |
| // we subtract a value of `1` here because the binding slot was already allocated |
| // at the top of this method when all the input bindings were counted. |
| totalHostVarsCount += |
| Math.max(call.allocateBindingSlots - MIN_STYLING_BINDING_SLOTS_REQUIRED, 0); |
| calls_1.push(convertStylingCall(call, bindingContext, bindingFn)); |
| }); |
| updateStatements.push(chainedInstruction(instruction.reference, calls_1).toStmt()); |
| } |
| }); |
| } |
| if (totalHostVarsCount) { |
| definitionMap.set('hostVars', literal(totalHostVarsCount)); |
| } |
| if (createStatements.length > 0 || updateStatements.length > 0) { |
| var hostBindingsFnName = name ? name + "_HostBindings" : null; |
| var statements = []; |
| if (createStatements.length > 0) { |
| statements.push(renderFlagCheckIfStmt(1 /* Create */, createStatements)); |
| } |
| if (updateStatements.length > 0) { |
| statements.push(renderFlagCheckIfStmt(2 /* Update */, updateStatements)); |
| } |
| return fn([new FnParam(RENDER_FLAGS, NUMBER_TYPE), new FnParam(CONTEXT_NAME, null)], statements, INFERRED_TYPE, null, hostBindingsFnName); |
| } |
| return null; |
| } |
| function bindingFn(implicit, value) { |
| return convertPropertyBinding(null, implicit, value, 'b', BindingForm.Expression, function () { return error('Unexpected interpolation'); }); |
| } |
| function convertStylingCall(call, bindingContext, bindingFn) { |
| return call.params(function (value) { return bindingFn(bindingContext, value).currValExpr; }); |
| } |
| function getBindingNameAndInstruction(binding) { |
| var bindingName = binding.name; |
| var instruction; |
| // Check to see if this is an attr binding or a property binding |
| var attrMatches = bindingName.match(ATTR_REGEX); |
| if (attrMatches) { |
| bindingName = attrMatches[1]; |
| instruction = Identifiers$1.attribute; |
| } |
| else { |
| if (binding.isAnimation) { |
| bindingName = prepareSyntheticPropertyName(bindingName); |
| // host bindings that have a synthetic property (e.g. @foo) should always be rendered |
| // in the context of the component and not the parent. Therefore there is a special |
| // compatibility instruction available for this purpose. |
| instruction = Identifiers$1.syntheticHostProperty; |
| } |
| else { |
| instruction = Identifiers$1.hostProperty; |
| } |
| } |
| return { bindingName: bindingName, instruction: instruction, isAttribute: !!attrMatches }; |
| } |
| function createHostListeners(eventBindings, name) { |
| var listeners = []; |
| var syntheticListeners = []; |
| var instructions = []; |
| eventBindings.forEach(function (binding) { |
| var bindingName = binding.name && sanitizeIdentifier(binding.name); |
| var bindingFnName = binding.type === 1 /* Animation */ ? |
| prepareSyntheticListenerFunctionName(bindingName, binding.targetOrPhase) : |
| bindingName; |
| var handlerName = name && bindingName ? name + "_" + bindingFnName + "_HostBindingHandler" : null; |
| var params = prepareEventListenerParameters(BoundEvent.fromParsedEvent(binding), handlerName); |
| if (binding.type == 1 /* Animation */) { |
| syntheticListeners.push(params); |
| } |
| else { |
| listeners.push(params); |
| } |
| }); |
| if (syntheticListeners.length > 0) { |
| instructions.push(chainedInstruction(Identifiers$1.syntheticHostListener, syntheticListeners).toStmt()); |
| } |
| if (listeners.length > 0) { |
| instructions.push(chainedInstruction(Identifiers$1.listener, listeners).toStmt()); |
| } |
| return instructions; |
| } |
| function metadataAsSummary(meta) { |
| // clang-format off |
| return { |
| // This is used by the BindingParser, which only deals with listeners and properties. There's no |
| // need to pass attributes to it. |
| hostAttributes: {}, |
| hostListeners: meta.listeners, |
| hostProperties: meta.properties, |
| }; |
| // clang-format on |
| } |
| var HOST_REG_EXP$1 = /^(?:\[([^\]]+)\])|(?:\(([^\)]+)\))$/; |
| function parseHostBindings(host) { |
| var e_4, _a; |
| var attributes = {}; |
| var listeners = {}; |
| var properties = {}; |
| var specialAttributes = {}; |
| try { |
| for (var _b = __values(Object.keys(host)), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var key = _c.value; |
| var value = host[key]; |
| var matches = key.match(HOST_REG_EXP$1); |
| if (matches === null) { |
| switch (key) { |
| case 'class': |
| if (typeof value !== 'string') { |
| // TODO(alxhub): make this a diagnostic. |
| throw new Error("Class binding must be string"); |
| } |
| specialAttributes.classAttr = value; |
| break; |
| case 'style': |
| if (typeof value !== 'string') { |
| // TODO(alxhub): make this a diagnostic. |
| throw new Error("Style binding must be string"); |
| } |
| specialAttributes.styleAttr = value; |
| break; |
| default: |
| if (typeof value === 'string') { |
| attributes[key] = literal(value); |
| } |
| else { |
| attributes[key] = value; |
| } |
| } |
| } |
| else if (matches[1 /* Binding */] != null) { |
| if (typeof value !== 'string') { |
| // TODO(alxhub): make this a diagnostic. |
| throw new Error("Property binding must be string"); |
| } |
| // synthetic properties (the ones that have a `@` as a prefix) |
| // are still treated the same as regular properties. Therefore |
| // there is no point in storing them in a separate map. |
| properties[matches[1 /* Binding */]] = value; |
| } |
| else if (matches[2 /* Event */] != null) { |
| if (typeof value !== 'string') { |
| // TODO(alxhub): make this a diagnostic. |
| throw new Error("Event binding must be string"); |
| } |
| listeners[matches[2 /* Event */]] = value; |
| } |
| } |
| } |
| catch (e_4_1) { e_4 = { error: e_4_1 }; } |
| finally { |
| try { |
| if (_c && !_c.done && (_a = _b.return)) _a.call(_b); |
| } |
| finally { if (e_4) throw e_4.error; } |
| } |
| return { attributes: attributes, listeners: listeners, properties: properties, specialAttributes: specialAttributes }; |
| } |
| /** |
| * Verifies host bindings and returns the list of errors (if any). Empty array indicates that a |
| * given set of host bindings has no errors. |
| * |
| * @param bindings set of host bindings to verify. |
| * @param sourceSpan source span where host bindings were defined. |
| * @returns array of errors associated with a given set of host bindings. |
| */ |
| function verifyHostBindings(bindings, sourceSpan) { |
| var summary = metadataAsSummary(bindings); |
| // TODO: abstract out host bindings verification logic and use it instead of |
| // creating events and properties ASTs to detect errors (FW-996) |
| var bindingParser = makeBindingParser(); |
| bindingParser.createDirectiveHostEventAsts(summary, sourceSpan); |
| bindingParser.createBoundHostProperties(summary, sourceSpan); |
| return bindingParser.errors; |
| } |
| function compileStyles(styles, selector, hostSelector) { |
| var shadowCss = new ShadowCss(); |
| return styles.map(function (style) { |
| return shadowCss.shimCssText(style, selector, hostSelector); |
| }); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * An interface for retrieving documents by URL that the compiler uses |
| * to load templates. |
| */ |
| var ResourceLoader = /** @class */ (function () { |
| function ResourceLoader() { |
| } |
| ResourceLoader.prototype.get = function (url) { |
| return ''; |
| }; |
| return ResourceLoader; |
| }()); |
| |
| var CompilerFacadeImpl = /** @class */ (function () { |
| function CompilerFacadeImpl(jitEvaluator) { |
| if (jitEvaluator === void 0) { jitEvaluator = new JitEvaluator(); } |
| this.jitEvaluator = jitEvaluator; |
| this.R3ResolvedDependencyType = exports.R3ResolvedDependencyType; |
| this.R3FactoryTarget = exports.R3FactoryTarget; |
| this.ResourceLoader = ResourceLoader; |
| this.elementSchemaRegistry = new DomElementSchemaRegistry(); |
| } |
| CompilerFacadeImpl.prototype.compilePipe = function (angularCoreEnv, sourceMapUrl, facade) { |
| var metadata = { |
| name: facade.name, |
| type: wrapReference$1(facade.type), |
| internalType: new WrappedNodeExpr(facade.type), |
| typeArgumentCount: facade.typeArgumentCount, |
| deps: convertR3DependencyMetadataArray(facade.deps), |
| pipeName: facade.pipeName, |
| pure: facade.pure, |
| }; |
| var res = compilePipeFromMetadata(metadata); |
| return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []); |
| }; |
| CompilerFacadeImpl.prototype.compilePipeDeclaration = function (angularCoreEnv, sourceMapUrl, declaration) { |
| var meta = convertDeclarePipeFacadeToMetadata(declaration); |
| var res = compilePipeFromMetadata(meta); |
| return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []); |
| }; |
| CompilerFacadeImpl.prototype.compileInjectable = function (angularCoreEnv, sourceMapUrl, facade) { |
| var _j = compileInjectable({ |
| name: facade.name, |
| type: wrapReference$1(facade.type), |
| internalType: new WrappedNodeExpr(facade.type), |
| typeArgumentCount: facade.typeArgumentCount, |
| providedIn: computeProvidedIn(facade.providedIn), |
| useClass: wrapExpression(facade, USE_CLASS), |
| useFactory: wrapExpression(facade, USE_FACTORY), |
| useValue: wrapExpression(facade, USE_VALUE), |
| useExisting: wrapExpression(facade, USE_EXISTING), |
| userDeps: convertR3DependencyMetadataArray(facade.userDeps) || undefined, |
| }), expression = _j.expression, statements = _j.statements; |
| return this.jitExpression(expression, angularCoreEnv, sourceMapUrl, statements); |
| }; |
| CompilerFacadeImpl.prototype.compileInjector = function (angularCoreEnv, sourceMapUrl, facade) { |
| var meta = { |
| name: facade.name, |
| type: wrapReference$1(facade.type), |
| internalType: new WrappedNodeExpr(facade.type), |
| providers: new WrappedNodeExpr(facade.providers), |
| imports: facade.imports.map(function (i) { return new WrappedNodeExpr(i); }), |
| }; |
| var res = compileInjector(meta); |
| return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []); |
| }; |
| CompilerFacadeImpl.prototype.compileNgModule = function (angularCoreEnv, sourceMapUrl, facade) { |
| var meta = { |
| type: wrapReference$1(facade.type), |
| internalType: new WrappedNodeExpr(facade.type), |
| adjacentType: new WrappedNodeExpr(facade.type), |
| bootstrap: facade.bootstrap.map(wrapReference$1), |
| declarations: facade.declarations.map(wrapReference$1), |
| imports: facade.imports.map(wrapReference$1), |
| exports: facade.exports.map(wrapReference$1), |
| emitInline: true, |
| containsForwardDecls: false, |
| schemas: facade.schemas ? facade.schemas.map(wrapReference$1) : null, |
| id: facade.id ? new WrappedNodeExpr(facade.id) : null, |
| }; |
| var res = compileNgModule(meta); |
| return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []); |
| }; |
| CompilerFacadeImpl.prototype.compileDirective = function (angularCoreEnv, sourceMapUrl, facade) { |
| var meta = convertDirectiveFacadeToMetadata(facade); |
| return this.compileDirectiveFromMeta(angularCoreEnv, sourceMapUrl, meta); |
| }; |
| CompilerFacadeImpl.prototype.compileDirectiveDeclaration = function (angularCoreEnv, sourceMapUrl, declaration) { |
| var typeSourceSpan = this.createParseSourceSpan('Directive', declaration.type.name, sourceMapUrl); |
| var meta = convertDeclareDirectiveFacadeToMetadata(declaration, typeSourceSpan); |
| return this.compileDirectiveFromMeta(angularCoreEnv, sourceMapUrl, meta); |
| }; |
| CompilerFacadeImpl.prototype.compileDirectiveFromMeta = function (angularCoreEnv, sourceMapUrl, meta) { |
| var constantPool = new ConstantPool(); |
| var bindingParser = makeBindingParser(); |
| var res = compileDirectiveFromMetadata(meta, constantPool, bindingParser); |
| return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, constantPool.statements); |
| }; |
| CompilerFacadeImpl.prototype.compileComponent = function (angularCoreEnv, sourceMapUrl, facade) { |
| // Parse the template and check for errors. |
| var _j = parseJitTemplate(facade.template, facade.name, sourceMapUrl, facade.preserveWhitespaces, facade.interpolation), template = _j.template, interpolation = _j.interpolation; |
| // Compile the component metadata, including template, into an expression. |
| var meta = Object.assign(Object.assign(Object.assign({}, facade), convertDirectiveFacadeToMetadata(facade)), { selector: facade.selector || this.elementSchemaRegistry.getDefaultComponentElementName(), template: template, declarationListEmitMode: 0 /* Direct */, styles: __spread(facade.styles, template.styles), encapsulation: facade.encapsulation, interpolation: interpolation, changeDetection: facade.changeDetection, animations: facade.animations != null ? new WrappedNodeExpr(facade.animations) : null, viewProviders: facade.viewProviders != null ? new WrappedNodeExpr(facade.viewProviders) : |
| null, relativeContextFilePath: '', i18nUseExternalIds: true }); |
| var jitExpressionSourceMap = "ng:///" + facade.name + ".js"; |
| return this.compileComponentFromMeta(angularCoreEnv, jitExpressionSourceMap, meta); |
| }; |
| CompilerFacadeImpl.prototype.compileComponentDeclaration = function (angularCoreEnv, sourceMapUrl, declaration) { |
| var typeSourceSpan = this.createParseSourceSpan('Component', declaration.type.name, sourceMapUrl); |
| var meta = convertDeclareComponentFacadeToMetadata(declaration, typeSourceSpan, sourceMapUrl); |
| return this.compileComponentFromMeta(angularCoreEnv, sourceMapUrl, meta); |
| }; |
| CompilerFacadeImpl.prototype.compileComponentFromMeta = function (angularCoreEnv, sourceMapUrl, meta) { |
| var constantPool = new ConstantPool(); |
| var bindingParser = makeBindingParser(meta.interpolation); |
| var res = compileComponentFromMetadata(meta, constantPool, bindingParser); |
| return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, constantPool.statements); |
| }; |
| CompilerFacadeImpl.prototype.compileFactory = function (angularCoreEnv, sourceMapUrl, meta) { |
| var factoryRes = compileFactoryFunction({ |
| name: meta.name, |
| type: wrapReference$1(meta.type), |
| internalType: new WrappedNodeExpr(meta.type), |
| typeArgumentCount: meta.typeArgumentCount, |
| deps: convertR3DependencyMetadataArray(meta.deps), |
| injectFn: meta.injectFn === 'directiveInject' ? Identifiers.directiveInject : |
| Identifiers.inject, |
| target: meta.target, |
| }); |
| return this.jitExpression(factoryRes.factory, angularCoreEnv, sourceMapUrl, factoryRes.statements); |
| }; |
| CompilerFacadeImpl.prototype.createParseSourceSpan = function (kind, typeName, sourceUrl) { |
| return r3JitTypeSourceSpan(kind, typeName, sourceUrl); |
| }; |
| /** |
| * JIT compiles an expression and returns the result of executing that expression. |
| * |
| * @param def the definition which will be compiled and executed to get the value to patch |
| * @param context an object map of @angular/core symbol names to symbols which will be available |
| * in the context of the compiled expression |
| * @param sourceUrl a URL to use for the source map of the compiled expression |
| * @param preStatements a collection of statements that should be evaluated before the expression. |
| */ |
| CompilerFacadeImpl.prototype.jitExpression = function (def, context, sourceUrl, preStatements) { |
| // The ConstantPool may contain Statements which declare variables used in the final expression. |
| // Therefore, its statements need to precede the actual JIT operation. The final statement is a |
| // declaration of $def which is set to the expression being compiled. |
| var statements = __spread(preStatements, [ |
| new DeclareVarStmt('$def', def, undefined, [exports.StmtModifier.Exported]), |
| ]); |
| var res = this.jitEvaluator.evaluateStatements(sourceUrl, statements, new R3JitReflector(context), /* enableSourceMaps */ true); |
| return res['$def']; |
| }; |
| return CompilerFacadeImpl; |
| }()); |
| var USE_CLASS = Object.keys({ useClass: null })[0]; |
| var USE_FACTORY = Object.keys({ useFactory: null })[0]; |
| var USE_VALUE = Object.keys({ useValue: null })[0]; |
| var USE_EXISTING = Object.keys({ useExisting: null })[0]; |
| var wrapReference$1 = function (value) { |
| var wrapped = new WrappedNodeExpr(value); |
| return { value: wrapped, type: wrapped }; |
| }; |
| function convertToR3QueryMetadata(facade) { |
| return Object.assign(Object.assign({}, facade), { predicate: Array.isArray(facade.predicate) ? facade.predicate : |
| new WrappedNodeExpr(facade.predicate), read: facade.read ? new WrappedNodeExpr(facade.read) : null, static: facade.static, emitDistinctChangesOnly: facade.emitDistinctChangesOnly }); |
| } |
| function convertQueryDeclarationToMetadata(declaration) { |
| var _a, _b, _c, _d; |
| return { |
| propertyName: declaration.propertyName, |
| first: (_a = declaration.first) !== null && _a !== void 0 ? _a : false, |
| predicate: Array.isArray(declaration.predicate) ? declaration.predicate : |
| new WrappedNodeExpr(declaration.predicate), |
| descendants: (_b = declaration.descendants) !== null && _b !== void 0 ? _b : false, |
| read: declaration.read ? new WrappedNodeExpr(declaration.read) : null, |
| static: (_c = declaration.static) !== null && _c !== void 0 ? _c : false, |
| emitDistinctChangesOnly: (_d = declaration.emitDistinctChangesOnly) !== null && _d !== void 0 ? _d : true, |
| }; |
| } |
| function convertDirectiveFacadeToMetadata(facade) { |
| var inputsFromMetadata = parseInputOutputs(facade.inputs || []); |
| var outputsFromMetadata = parseInputOutputs(facade.outputs || []); |
| var propMetadata = facade.propMetadata; |
| var inputsFromType = {}; |
| var outputsFromType = {}; |
| var _loop_1 = function (field) { |
| if (propMetadata.hasOwnProperty(field)) { |
| propMetadata[field].forEach(function (ann) { |
| if (isInput(ann)) { |
| inputsFromType[field] = |
| ann.bindingPropertyName ? [ann.bindingPropertyName, field] : field; |
| } |
| else if (isOutput(ann)) { |
| outputsFromType[field] = ann.bindingPropertyName || field; |
| } |
| }); |
| } |
| }; |
| for (var field in propMetadata) { |
| _loop_1(field); |
| } |
| return Object.assign(Object.assign({}, facade), { typeSourceSpan: facade.typeSourceSpan, type: wrapReference$1(facade.type), internalType: new WrappedNodeExpr(facade.type), deps: convertR3DependencyMetadataArray(facade.deps), host: extractHostBindings(facade.propMetadata, facade.typeSourceSpan, facade.host), inputs: Object.assign(Object.assign({}, inputsFromMetadata), inputsFromType), outputs: Object.assign(Object.assign({}, outputsFromMetadata), outputsFromType), queries: facade.queries.map(convertToR3QueryMetadata), providers: facade.providers != null ? new WrappedNodeExpr(facade.providers) : null, viewQueries: facade.viewQueries.map(convertToR3QueryMetadata), fullInheritance: false }); |
| } |
| function convertDeclareDirectiveFacadeToMetadata(declaration, typeSourceSpan) { |
| var _a, _b, _c, _d, _e, _f, _g, _h; |
| return { |
| name: declaration.type.name, |
| type: wrapReference$1(declaration.type), |
| typeSourceSpan: typeSourceSpan, |
| internalType: new WrappedNodeExpr(declaration.type), |
| selector: (_a = declaration.selector) !== null && _a !== void 0 ? _a : null, |
| inputs: (_b = declaration.inputs) !== null && _b !== void 0 ? _b : {}, |
| outputs: (_c = declaration.outputs) !== null && _c !== void 0 ? _c : {}, |
| host: convertHostDeclarationToMetadata(declaration.host), |
| queries: ((_d = declaration.queries) !== null && _d !== void 0 ? _d : []).map(convertQueryDeclarationToMetadata), |
| viewQueries: ((_e = declaration.viewQueries) !== null && _e !== void 0 ? _e : []).map(convertQueryDeclarationToMetadata), |
| providers: declaration.providers !== undefined ? new WrappedNodeExpr(declaration.providers) : |
| null, |
| exportAs: (_f = declaration.exportAs) !== null && _f !== void 0 ? _f : null, |
| usesInheritance: (_g = declaration.usesInheritance) !== null && _g !== void 0 ? _g : false, |
| lifecycle: { usesOnChanges: (_h = declaration.usesOnChanges) !== null && _h !== void 0 ? _h : false }, |
| deps: null, |
| typeArgumentCount: 0, |
| fullInheritance: false, |
| }; |
| } |
| function convertHostDeclarationToMetadata(host) { |
| if (host === void 0) { host = {}; } |
| var _a, _b, _c; |
| return { |
| attributes: convertOpaqueValuesToExpressions((_a = host.attributes) !== null && _a !== void 0 ? _a : {}), |
| listeners: (_b = host.listeners) !== null && _b !== void 0 ? _b : {}, |
| properties: (_c = host.properties) !== null && _c !== void 0 ? _c : {}, |
| specialAttributes: { |
| classAttr: host.classAttribute, |
| styleAttr: host.styleAttribute, |
| }, |
| }; |
| } |
| function convertOpaqueValuesToExpressions(obj) { |
| var e_1, _j; |
| var result = {}; |
| try { |
| for (var _k = __values(Object.keys(obj)), _l = _k.next(); !_l.done; _l = _k.next()) { |
| var key = _l.value; |
| result[key] = new WrappedNodeExpr(obj[key]); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_l && !_l.done && (_j = _k.return)) _j.call(_k); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return result; |
| } |
| function convertDeclareComponentFacadeToMetadata(declaration, typeSourceSpan, sourceMapUrl) { |
| var _a, _b, _c, _d, _e; |
| var _j = parseJitTemplate(declaration.template, declaration.type.name, sourceMapUrl, (_a = declaration.preserveWhitespaces) !== null && _a !== void 0 ? _a : false, declaration.interpolation), template = _j.template, interpolation = _j.interpolation; |
| return Object.assign(Object.assign({}, convertDeclareDirectiveFacadeToMetadata(declaration, typeSourceSpan)), { template: template, styles: (_b = declaration.styles) !== null && _b !== void 0 ? _b : [], directives: ((_c = declaration.directives) !== null && _c !== void 0 ? _c : []).map(convertUsedDirectiveDeclarationToMetadata), pipes: convertUsedPipesToMetadata(declaration.pipes), viewProviders: declaration.viewProviders !== undefined ? |
| new WrappedNodeExpr(declaration.viewProviders) : |
| null, animations: declaration.animations !== undefined ? new WrappedNodeExpr(declaration.animations) : |
| null, changeDetection: (_d = declaration.changeDetection) !== null && _d !== void 0 ? _d : ChangeDetectionStrategy.Default, encapsulation: (_e = declaration.encapsulation) !== null && _e !== void 0 ? _e : ViewEncapsulation.Emulated, interpolation: interpolation, declarationListEmitMode: 2 /* ClosureResolved */, relativeContextFilePath: '', i18nUseExternalIds: true }); |
| } |
| function convertUsedDirectiveDeclarationToMetadata(declaration) { |
| var _a, _b, _c; |
| return { |
| selector: declaration.selector, |
| type: new WrappedNodeExpr(declaration.type), |
| inputs: (_a = declaration.inputs) !== null && _a !== void 0 ? _a : [], |
| outputs: (_b = declaration.outputs) !== null && _b !== void 0 ? _b : [], |
| exportAs: (_c = declaration.exportAs) !== null && _c !== void 0 ? _c : null, |
| }; |
| } |
| function convertUsedPipesToMetadata(declaredPipes) { |
| var e_2, _j; |
| var pipes = new Map(); |
| if (declaredPipes === undefined) { |
| return pipes; |
| } |
| try { |
| for (var _k = __values(Object.keys(declaredPipes)), _l = _k.next(); !_l.done; _l = _k.next()) { |
| var pipeName = _l.value; |
| var pipeType = declaredPipes[pipeName]; |
| pipes.set(pipeName, new WrappedNodeExpr(pipeType)); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_l && !_l.done && (_j = _k.return)) _j.call(_k); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| return pipes; |
| } |
| function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces, interpolation) { |
| var interpolationConfig = interpolation ? InterpolationConfig.fromArray(interpolation) : DEFAULT_INTERPOLATION_CONFIG; |
| // Parse the template and check for errors. |
| var parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces: preserveWhitespaces, interpolationConfig: interpolationConfig }); |
| if (parsed.errors !== null) { |
| var errors = parsed.errors.map(function (err) { return err.toString(); }).join(', '); |
| throw new Error("Errors during JIT compilation of template for " + typeName + ": " + errors); |
| } |
| return { template: parsed, interpolation: interpolationConfig }; |
| } |
| function wrapExpression(obj, property) { |
| if (obj.hasOwnProperty(property)) { |
| return new WrappedNodeExpr(obj[property]); |
| } |
| else { |
| return undefined; |
| } |
| } |
| function computeProvidedIn(providedIn) { |
| if (providedIn == null || typeof providedIn === 'string') { |
| return new LiteralExpr(providedIn); |
| } |
| else { |
| return new WrappedNodeExpr(providedIn); |
| } |
| } |
| function convertR3DependencyMetadata(facade) { |
| var tokenExpr; |
| if (facade.token === null) { |
| tokenExpr = new LiteralExpr(null); |
| } |
| else if (facade.resolved === exports.R3ResolvedDependencyType.Attribute) { |
| tokenExpr = new LiteralExpr(facade.token); |
| } |
| else { |
| tokenExpr = new WrappedNodeExpr(facade.token); |
| } |
| return { |
| token: tokenExpr, |
| attribute: null, |
| resolved: facade.resolved, |
| host: facade.host, |
| optional: facade.optional, |
| self: facade.self, |
| skipSelf: facade.skipSelf, |
| }; |
| } |
| function convertR3DependencyMetadataArray(facades) { |
| return facades == null ? null : facades.map(convertR3DependencyMetadata); |
| } |
| function extractHostBindings(propMetadata, sourceSpan, host) { |
| // First parse the declarations from the metadata. |
| var bindings = parseHostBindings(host || {}); |
| // After that check host bindings for errors |
| var errors = verifyHostBindings(bindings, sourceSpan); |
| if (errors.length) { |
| throw new Error(errors.map(function (error) { return error.msg; }).join('\n')); |
| } |
| var _loop_2 = function (field) { |
| if (propMetadata.hasOwnProperty(field)) { |
| propMetadata[field].forEach(function (ann) { |
| if (isHostBinding(ann)) { |
| // Since this is a decorator, we know that the value is a class member. Always access it |
| // through `this` so that further down the line it can't be confused for a literal value |
| // (e.g. if there's a property called `true`). |
| bindings.properties[ann.hostPropertyName || field] = |
| getSafePropertyAccessString('this', field); |
| } |
| else if (isHostListener(ann)) { |
| bindings.listeners[ann.eventName || field] = field + "(" + (ann.args || []).join(',') + ")"; |
| } |
| }); |
| } |
| }; |
| // Next, loop over the properties of the object, looking for @HostBinding and @HostListener. |
| for (var field in propMetadata) { |
| _loop_2(field); |
| } |
| return bindings; |
| } |
| function isHostBinding(value) { |
| return value.ngMetadataName === 'HostBinding'; |
| } |
| function isHostListener(value) { |
| return value.ngMetadataName === 'HostListener'; |
| } |
| function isInput(value) { |
| return value.ngMetadataName === 'Input'; |
| } |
| function isOutput(value) { |
| return value.ngMetadataName === 'Output'; |
| } |
| function parseInputOutputs(values) { |
| return values.reduce(function (map, value) { |
| var _j = __read(value.split(',').map(function (piece) { return piece.trim(); }), 2), field = _j[0], property = _j[1]; |
| map[field] = property || field; |
| return map; |
| }, {}); |
| } |
| function convertDeclarePipeFacadeToMetadata(declaration) { |
| var _a; |
| return { |
| name: declaration.type.name, |
| type: wrapReference$1(declaration.type), |
| internalType: new WrappedNodeExpr(declaration.type), |
| typeArgumentCount: 0, |
| pipeName: declaration.name, |
| deps: null, |
| pure: (_a = declaration.pure) !== null && _a !== void 0 ? _a : true, |
| }; |
| } |
| function publishFacade(global) { |
| var ng = global.ng || (global.ng = {}); |
| ng.ɵcompilerFacade = new CompilerFacadeImpl(); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var VERSION$1 = new Version('11.2.14'); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var CompilerConfig = /** @class */ (function () { |
| function CompilerConfig(_a) { |
| var _b = _a === void 0 ? {} : _a, _c = _b.defaultEncapsulation, defaultEncapsulation = _c === void 0 ? ViewEncapsulation.Emulated : _c, _d = _b.useJit, useJit = _d === void 0 ? true : _d, _e = _b.jitDevMode, jitDevMode = _e === void 0 ? false : _e, _f = _b.missingTranslation, missingTranslation = _f === void 0 ? null : _f, preserveWhitespaces = _b.preserveWhitespaces, strictInjectionParameters = _b.strictInjectionParameters; |
| this.defaultEncapsulation = defaultEncapsulation; |
| this.useJit = !!useJit; |
| this.jitDevMode = !!jitDevMode; |
| this.missingTranslation = missingTranslation; |
| this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces)); |
| this.strictInjectionParameters = strictInjectionParameters === true; |
| } |
| return CompilerConfig; |
| }()); |
| function preserveWhitespacesDefault(preserveWhitespacesOption, defaultSetting) { |
| if (defaultSetting === void 0) { defaultSetting = false; } |
| return preserveWhitespacesOption === null ? defaultSetting : preserveWhitespacesOption; |
| } |
| |
| var DirectiveNormalizer = /** @class */ (function () { |
| function DirectiveNormalizer(_resourceLoader, _urlResolver, _htmlParser, _config) { |
| this._resourceLoader = _resourceLoader; |
| this._urlResolver = _urlResolver; |
| this._htmlParser = _htmlParser; |
| this._config = _config; |
| this._resourceLoaderCache = new Map(); |
| } |
| DirectiveNormalizer.prototype.clearCache = function () { |
| this._resourceLoaderCache.clear(); |
| }; |
| DirectiveNormalizer.prototype.clearCacheFor = function (normalizedDirective) { |
| var _this = this; |
| if (!normalizedDirective.isComponent) { |
| return; |
| } |
| var template = normalizedDirective.template; |
| this._resourceLoaderCache.delete(template.templateUrl); |
| template.externalStylesheets.forEach(function (stylesheet) { |
| _this._resourceLoaderCache.delete(stylesheet.moduleUrl); |
| }); |
| }; |
| DirectiveNormalizer.prototype._fetch = function (url) { |
| var result = this._resourceLoaderCache.get(url); |
| if (!result) { |
| result = this._resourceLoader.get(url); |
| this._resourceLoaderCache.set(url, result); |
| } |
| return result; |
| }; |
| DirectiveNormalizer.prototype.normalizeTemplate = function (prenormData) { |
| var _this = this; |
| if (isDefined(prenormData.template)) { |
| if (isDefined(prenormData.templateUrl)) { |
| throw syntaxError("'" + stringify(prenormData |
| .componentType) + "' component cannot define both template and templateUrl"); |
| } |
| if (typeof prenormData.template !== 'string') { |
| throw syntaxError("The template specified for component " + stringify(prenormData.componentType) + " is not a string"); |
| } |
| } |
| else if (isDefined(prenormData.templateUrl)) { |
| if (typeof prenormData.templateUrl !== 'string') { |
| throw syntaxError("The templateUrl specified for component " + stringify(prenormData.componentType) + " is not a string"); |
| } |
| } |
| else { |
| throw syntaxError("No template specified for component " + stringify(prenormData.componentType)); |
| } |
| if (isDefined(prenormData.preserveWhitespaces) && |
| typeof prenormData.preserveWhitespaces !== 'boolean') { |
| throw syntaxError("The preserveWhitespaces option for component " + stringify(prenormData.componentType) + " must be a boolean"); |
| } |
| return SyncAsync.then(this._preParseTemplate(prenormData), function (preparsedTemplate) { return _this._normalizeTemplateMetadata(prenormData, preparsedTemplate); }); |
| }; |
| DirectiveNormalizer.prototype._preParseTemplate = function (prenomData) { |
| var _this = this; |
| var template; |
| var templateUrl; |
| if (prenomData.template != null) { |
| template = prenomData.template; |
| templateUrl = prenomData.moduleUrl; |
| } |
| else { |
| templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl); |
| template = this._fetch(templateUrl); |
| } |
| return SyncAsync.then(template, function (template) { return _this._preparseLoadedTemplate(prenomData, template, templateUrl); }); |
| }; |
| DirectiveNormalizer.prototype._preparseLoadedTemplate = function (prenormData, template, templateAbsUrl) { |
| var isInline = !!prenormData.template; |
| var interpolationConfig = InterpolationConfig.fromArray(prenormData.interpolation); |
| var templateUrl = templateSourceUrl({ reference: prenormData.ngModuleType }, { type: { reference: prenormData.componentType } }, { isInline: isInline, templateUrl: templateAbsUrl }); |
| var rootNodesAndErrors = this._htmlParser.parse(template, templateUrl, { tokenizeExpansionForms: true, interpolationConfig: interpolationConfig }); |
| if (rootNodesAndErrors.errors.length > 0) { |
| var errorString = rootNodesAndErrors.errors.join('\n'); |
| throw syntaxError("Template parse errors:\n" + errorString); |
| } |
| var templateMetadataStyles = this._normalizeStylesheet(new CompileStylesheetMetadata({ styles: prenormData.styles, moduleUrl: prenormData.moduleUrl })); |
| var visitor = new TemplatePreparseVisitor(); |
| visitAll$1(visitor, rootNodesAndErrors.rootNodes); |
| var templateStyles = this._normalizeStylesheet(new CompileStylesheetMetadata({ styles: visitor.styles, styleUrls: visitor.styleUrls, moduleUrl: templateAbsUrl })); |
| var styles = templateMetadataStyles.styles.concat(templateStyles.styles); |
| var inlineStyleUrls = templateMetadataStyles.styleUrls.concat(templateStyles.styleUrls); |
| var styleUrls = this |
| ._normalizeStylesheet(new CompileStylesheetMetadata({ styleUrls: prenormData.styleUrls, moduleUrl: prenormData.moduleUrl })) |
| .styleUrls; |
| return { |
| template: template, |
| templateUrl: templateAbsUrl, |
| isInline: isInline, |
| htmlAst: rootNodesAndErrors, |
| styles: styles, |
| inlineStyleUrls: inlineStyleUrls, |
| styleUrls: styleUrls, |
| ngContentSelectors: visitor.ngContentSelectors, |
| }; |
| }; |
| DirectiveNormalizer.prototype._normalizeTemplateMetadata = function (prenormData, preparsedTemplate) { |
| var _this = this; |
| return SyncAsync.then(this._loadMissingExternalStylesheets(preparsedTemplate.styleUrls.concat(preparsedTemplate.inlineStyleUrls)), function (externalStylesheets) { return _this._normalizeLoadedTemplateMetadata(prenormData, preparsedTemplate, externalStylesheets); }); |
| }; |
| DirectiveNormalizer.prototype._normalizeLoadedTemplateMetadata = function (prenormData, preparsedTemplate, stylesheets) { |
| var _this = this; |
| // Algorithm: |
| // - produce exactly 1 entry per original styleUrl in |
| // CompileTemplateMetadata.externalStylesheets with all styles inlined |
| // - inline all styles that are referenced by the template into CompileTemplateMetadata.styles. |
| // Reason: be able to determine how many stylesheets there are even without loading |
| // the template nor the stylesheets, so we can create a stub for TypeScript always synchronously |
| // (as resource loading may be async) |
| var styles = __spread(preparsedTemplate.styles); |
| this._inlineStyles(preparsedTemplate.inlineStyleUrls, stylesheets, styles); |
| var styleUrls = preparsedTemplate.styleUrls; |
| var externalStylesheets = styleUrls.map(function (styleUrl) { |
| var stylesheet = stylesheets.get(styleUrl); |
| var styles = __spread(stylesheet.styles); |
| _this._inlineStyles(stylesheet.styleUrls, stylesheets, styles); |
| return new CompileStylesheetMetadata({ moduleUrl: styleUrl, styles: styles }); |
| }); |
| var encapsulation = prenormData.encapsulation; |
| if (encapsulation == null) { |
| encapsulation = this._config.defaultEncapsulation; |
| } |
| if (encapsulation === ViewEncapsulation.Emulated && styles.length === 0 && |
| styleUrls.length === 0) { |
| encapsulation = ViewEncapsulation.None; |
| } |
| return new CompileTemplateMetadata({ |
| encapsulation: encapsulation, |
| template: preparsedTemplate.template, |
| templateUrl: preparsedTemplate.templateUrl, |
| htmlAst: preparsedTemplate.htmlAst, |
| styles: styles, |
| styleUrls: styleUrls, |
| ngContentSelectors: preparsedTemplate.ngContentSelectors, |
| animations: prenormData.animations, |
| interpolation: prenormData.interpolation, |
| isInline: preparsedTemplate.isInline, |
| externalStylesheets: externalStylesheets, |
| preserveWhitespaces: preserveWhitespacesDefault(prenormData.preserveWhitespaces, this._config.preserveWhitespaces), |
| }); |
| }; |
| DirectiveNormalizer.prototype._inlineStyles = function (styleUrls, stylesheets, targetStyles) { |
| var _this = this; |
| styleUrls.forEach(function (styleUrl) { |
| var stylesheet = stylesheets.get(styleUrl); |
| stylesheet.styles.forEach(function (style) { return targetStyles.push(style); }); |
| _this._inlineStyles(stylesheet.styleUrls, stylesheets, targetStyles); |
| }); |
| }; |
| DirectiveNormalizer.prototype._loadMissingExternalStylesheets = function (styleUrls, loadedStylesheets) { |
| var _this = this; |
| if (loadedStylesheets === void 0) { loadedStylesheets = new Map(); } |
| return SyncAsync.then(SyncAsync.all(styleUrls.filter(function (styleUrl) { return !loadedStylesheets.has(styleUrl); }) |
| .map(function (styleUrl) { return SyncAsync.then(_this._fetch(styleUrl), function (loadedStyle) { |
| var stylesheet = _this._normalizeStylesheet(new CompileStylesheetMetadata({ styles: [loadedStyle], moduleUrl: styleUrl })); |
| loadedStylesheets.set(styleUrl, stylesheet); |
| return _this._loadMissingExternalStylesheets(stylesheet.styleUrls, loadedStylesheets); |
| }); })), function (_) { return loadedStylesheets; }); |
| }; |
| DirectiveNormalizer.prototype._normalizeStylesheet = function (stylesheet) { |
| var _this = this; |
| var moduleUrl = stylesheet.moduleUrl; |
| var allStyleUrls = stylesheet.styleUrls.filter(isStyleUrlResolvable) |
| .map(function (url) { return _this._urlResolver.resolve(moduleUrl, url); }); |
| var allStyles = stylesheet.styles.map(function (style) { |
| var styleWithImports = extractStyleUrls(_this._urlResolver, moduleUrl, style); |
| allStyleUrls.push.apply(allStyleUrls, __spread(styleWithImports.styleUrls)); |
| return styleWithImports.style; |
| }); |
| return new CompileStylesheetMetadata({ styles: allStyles, styleUrls: allStyleUrls, moduleUrl: moduleUrl }); |
| }; |
| return DirectiveNormalizer; |
| }()); |
| var TemplatePreparseVisitor = /** @class */ (function () { |
| function TemplatePreparseVisitor() { |
| this.ngContentSelectors = []; |
| this.styles = []; |
| this.styleUrls = []; |
| this.ngNonBindableStackCount = 0; |
| } |
| TemplatePreparseVisitor.prototype.visitElement = function (ast, context) { |
| var preparsedElement = preparseElement(ast); |
| switch (preparsedElement.type) { |
| case PreparsedElementType.NG_CONTENT: |
| if (this.ngNonBindableStackCount === 0) { |
| this.ngContentSelectors.push(preparsedElement.selectAttr); |
| } |
| break; |
| case PreparsedElementType.STYLE: |
| var textContent_1 = ''; |
| ast.children.forEach(function (child) { |
| if (child instanceof Text$3) { |
| textContent_1 += child.value; |
| } |
| }); |
| this.styles.push(textContent_1); |
| break; |
| case PreparsedElementType.STYLESHEET: |
| this.styleUrls.push(preparsedElement.hrefAttr); |
| break; |
| default: |
| break; |
| } |
| if (preparsedElement.nonBindable) { |
| this.ngNonBindableStackCount++; |
| } |
| visitAll$1(this, ast.children); |
| if (preparsedElement.nonBindable) { |
| this.ngNonBindableStackCount--; |
| } |
| return null; |
| }; |
| TemplatePreparseVisitor.prototype.visitExpansion = function (ast, context) { |
| visitAll$1(this, ast.cases); |
| }; |
| TemplatePreparseVisitor.prototype.visitExpansionCase = function (ast, context) { |
| visitAll$1(this, ast.expression); |
| }; |
| TemplatePreparseVisitor.prototype.visitComment = function (ast, context) { |
| return null; |
| }; |
| TemplatePreparseVisitor.prototype.visitAttribute = function (ast, context) { |
| return null; |
| }; |
| TemplatePreparseVisitor.prototype.visitText = function (ast, context) { |
| return null; |
| }; |
| return TemplatePreparseVisitor; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var QUERY_METADATA_IDENTIFIERS = [ |
| createViewChild, |
| createViewChildren, |
| createContentChild, |
| createContentChildren, |
| ]; |
| /* |
| * Resolve a `Type` for {@link Directive}. |
| * |
| * This interface can be overridden by the application developer to create custom behavior. |
| * |
| * See {@link Compiler} |
| */ |
| var DirectiveResolver = /** @class */ (function () { |
| function DirectiveResolver(_reflector) { |
| this._reflector = _reflector; |
| } |
| DirectiveResolver.prototype.isDirective = function (type) { |
| var typeMetadata = this._reflector.annotations(resolveForwardRef(type)); |
| return typeMetadata && typeMetadata.some(isDirectiveMetadata); |
| }; |
| DirectiveResolver.prototype.resolve = function (type, throwIfNotFound) { |
| if (throwIfNotFound === void 0) { throwIfNotFound = true; } |
| var typeMetadata = this._reflector.annotations(resolveForwardRef(type)); |
| if (typeMetadata) { |
| var metadata = findLast(typeMetadata, isDirectiveMetadata); |
| if (metadata) { |
| var propertyMetadata = this._reflector.propMetadata(type); |
| var guards = this._reflector.guards(type); |
| return this._mergeWithPropertyMetadata(metadata, propertyMetadata, guards, type); |
| } |
| } |
| if (throwIfNotFound) { |
| throw new Error("No Directive annotation found on " + stringify(type)); |
| } |
| return null; |
| }; |
| DirectiveResolver.prototype._mergeWithPropertyMetadata = function (dm, propertyMetadata, guards, directiveType) { |
| var inputs = []; |
| var outputs = []; |
| var host = {}; |
| var queries = {}; |
| Object.keys(propertyMetadata).forEach(function (propName) { |
| var input = findLast(propertyMetadata[propName], function (a) { return createInput.isTypeOf(a); }); |
| if (input) { |
| if (input.bindingPropertyName) { |
| inputs.push(propName + ": " + input.bindingPropertyName); |
| } |
| else { |
| inputs.push(propName); |
| } |
| } |
| var output = findLast(propertyMetadata[propName], function (a) { return createOutput.isTypeOf(a); }); |
| if (output) { |
| if (output.bindingPropertyName) { |
| outputs.push(propName + ": " + output.bindingPropertyName); |
| } |
| else { |
| outputs.push(propName); |
| } |
| } |
| var hostBindings = propertyMetadata[propName].filter(function (a) { return createHostBinding.isTypeOf(a); }); |
| hostBindings.forEach(function (hostBinding) { |
| if (hostBinding.hostPropertyName) { |
| var startWith = hostBinding.hostPropertyName[0]; |
| if (startWith === '(') { |
| throw new Error("@HostBinding can not bind to events. Use @HostListener instead."); |
| } |
| else if (startWith === '[') { |
| throw new Error("@HostBinding parameter should be a property name, 'class.<name>', or 'attr.<name>'."); |
| } |
| host["[" + hostBinding.hostPropertyName + "]"] = propName; |
| } |
| else { |
| host["[" + propName + "]"] = propName; |
| } |
| }); |
| var hostListeners = propertyMetadata[propName].filter(function (a) { return createHostListener.isTypeOf(a); }); |
| hostListeners.forEach(function (hostListener) { |
| var args = hostListener.args || []; |
| host["(" + hostListener.eventName + ")"] = propName + "(" + args.join(',') + ")"; |
| }); |
| var query = findLast(propertyMetadata[propName], function (a) { return QUERY_METADATA_IDENTIFIERS.some(function (i) { return i.isTypeOf(a); }); }); |
| if (query) { |
| queries[propName] = query; |
| } |
| }); |
| return this._merge(dm, inputs, outputs, host, queries, guards, directiveType); |
| }; |
| DirectiveResolver.prototype._extractPublicName = function (def) { |
| return splitAtColon(def, [null, def])[1].trim(); |
| }; |
| DirectiveResolver.prototype._dedupeBindings = function (bindings) { |
| var names = new Set(); |
| var publicNames = new Set(); |
| var reversedResult = []; |
| // go last to first to allow later entries to overwrite previous entries |
| for (var i = bindings.length - 1; i >= 0; i--) { |
| var binding = bindings[i]; |
| var name = this._extractPublicName(binding); |
| publicNames.add(name); |
| if (!names.has(name)) { |
| names.add(name); |
| reversedResult.push(binding); |
| } |
| } |
| return reversedResult.reverse(); |
| }; |
| DirectiveResolver.prototype._merge = function (directive, inputs, outputs, host, queries, guards, directiveType) { |
| var mergedInputs = this._dedupeBindings(directive.inputs ? directive.inputs.concat(inputs) : inputs); |
| var mergedOutputs = this._dedupeBindings(directive.outputs ? directive.outputs.concat(outputs) : outputs); |
| var mergedHost = directive.host ? Object.assign(Object.assign({}, directive.host), host) : host; |
| var mergedQueries = directive.queries ? Object.assign(Object.assign({}, directive.queries), queries) : queries; |
| if (createComponent.isTypeOf(directive)) { |
| var comp = directive; |
| return createComponent({ |
| selector: comp.selector, |
| inputs: mergedInputs, |
| outputs: mergedOutputs, |
| host: mergedHost, |
| exportAs: comp.exportAs, |
| moduleId: comp.moduleId, |
| queries: mergedQueries, |
| changeDetection: comp.changeDetection, |
| providers: comp.providers, |
| viewProviders: comp.viewProviders, |
| entryComponents: comp.entryComponents, |
| template: comp.template, |
| templateUrl: comp.templateUrl, |
| styles: comp.styles, |
| styleUrls: comp.styleUrls, |
| encapsulation: comp.encapsulation, |
| animations: comp.animations, |
| interpolation: comp.interpolation, |
| preserveWhitespaces: directive.preserveWhitespaces, |
| }); |
| } |
| else { |
| return createDirective({ |
| selector: directive.selector, |
| inputs: mergedInputs, |
| outputs: mergedOutputs, |
| host: mergedHost, |
| exportAs: directive.exportAs, |
| queries: mergedQueries, |
| providers: directive.providers, |
| guards: guards |
| }); |
| } |
| }; |
| return DirectiveResolver; |
| }()); |
| function isDirectiveMetadata(type) { |
| return createDirective.isTypeOf(type) || createComponent.isTypeOf(type); |
| } |
| function findLast(arr, condition) { |
| for (var i = arr.length - 1; i >= 0; i--) { |
| if (condition(arr[i])) { |
| return arr[i]; |
| } |
| } |
| return null; |
| } |
| |
| var _I18N_ATTR = 'i18n'; |
| var _I18N_ATTR_PREFIX = 'i18n-'; |
| var _I18N_COMMENT_PREFIX_REGEXP = /^i18n:?/; |
| var MEANING_SEPARATOR = '|'; |
| var ID_SEPARATOR = '@@'; |
| var i18nCommentsWarned = false; |
| /** |
| * Extract translatable messages from an html AST |
| */ |
| function extractMessages(nodes, interpolationConfig, implicitTags, implicitAttrs) { |
| var visitor = new _Visitor$2(implicitTags, implicitAttrs); |
| return visitor.extract(nodes, interpolationConfig); |
| } |
| function mergeTranslations(nodes, translations, interpolationConfig, implicitTags, implicitAttrs) { |
| var visitor = new _Visitor$2(implicitTags, implicitAttrs); |
| return visitor.merge(nodes, translations, interpolationConfig); |
| } |
| var ExtractionResult = /** @class */ (function () { |
| function ExtractionResult(messages, errors) { |
| this.messages = messages; |
| this.errors = errors; |
| } |
| return ExtractionResult; |
| }()); |
| var _VisitorMode; |
| (function (_VisitorMode) { |
| _VisitorMode[_VisitorMode["Extract"] = 0] = "Extract"; |
| _VisitorMode[_VisitorMode["Merge"] = 1] = "Merge"; |
| })(_VisitorMode || (_VisitorMode = {})); |
| /** |
| * This Visitor is used: |
| * 1. to extract all the translatable strings from an html AST (see `extract()`), |
| * 2. to replace the translatable strings with the actual translations (see `merge()`) |
| * |
| * @internal |
| */ |
| var _Visitor$2 = /** @class */ (function () { |
| function _Visitor(_implicitTags, _implicitAttrs) { |
| this._implicitTags = _implicitTags; |
| this._implicitAttrs = _implicitAttrs; |
| } |
| /** |
| * Extracts the messages from the tree |
| */ |
| _Visitor.prototype.extract = function (nodes, interpolationConfig) { |
| var _this = this; |
| this._init(_VisitorMode.Extract, interpolationConfig); |
| nodes.forEach(function (node) { return node.visit(_this, null); }); |
| if (this._inI18nBlock) { |
| this._reportError(nodes[nodes.length - 1], 'Unclosed block'); |
| } |
| return new ExtractionResult(this._messages, this._errors); |
| }; |
| /** |
| * Returns a tree where all translatable nodes are translated |
| */ |
| _Visitor.prototype.merge = function (nodes, translations, interpolationConfig) { |
| this._init(_VisitorMode.Merge, interpolationConfig); |
| this._translations = translations; |
| // Construct a single fake root element |
| var wrapper = new Element$1('wrapper', [], nodes, undefined, undefined, undefined); |
| var translatedNode = wrapper.visit(this, null); |
| if (this._inI18nBlock) { |
| this._reportError(nodes[nodes.length - 1], 'Unclosed block'); |
| } |
| return new ParseTreeResult(translatedNode.children, this._errors); |
| }; |
| _Visitor.prototype.visitExpansionCase = function (icuCase, context) { |
| // Parse cases for translatable html attributes |
| var expression = visitAll$1(this, icuCase.expression, context); |
| if (this._mode === _VisitorMode.Merge) { |
| return new ExpansionCase(icuCase.value, expression, icuCase.sourceSpan, icuCase.valueSourceSpan, icuCase.expSourceSpan); |
| } |
| }; |
| _Visitor.prototype.visitExpansion = function (icu, context) { |
| this._mayBeAddBlockChildren(icu); |
| var wasInIcu = this._inIcu; |
| if (!this._inIcu) { |
| // nested ICU messages should not be extracted but top-level translated as a whole |
| if (this._isInTranslatableSection) { |
| this._addMessage([icu]); |
| } |
| this._inIcu = true; |
| } |
| var cases = visitAll$1(this, icu.cases, context); |
| if (this._mode === _VisitorMode.Merge) { |
| icu = new Expansion(icu.switchValue, icu.type, cases, icu.sourceSpan, icu.switchValueSourceSpan); |
| } |
| this._inIcu = wasInIcu; |
| return icu; |
| }; |
| _Visitor.prototype.visitComment = function (comment, context) { |
| var isOpening = _isOpeningComment(comment); |
| if (isOpening && this._isInTranslatableSection) { |
| this._reportError(comment, 'Could not start a block inside a translatable section'); |
| return; |
| } |
| var isClosing = _isClosingComment(comment); |
| if (isClosing && !this._inI18nBlock) { |
| this._reportError(comment, 'Trying to close an unopened block'); |
| return; |
| } |
| if (!this._inI18nNode && !this._inIcu) { |
| if (!this._inI18nBlock) { |
| if (isOpening) { |
| // deprecated from v5 you should use <ng-container i18n> instead of i18n comments |
| if (!i18nCommentsWarned && console && console.warn) { |
| i18nCommentsWarned = true; |
| var details = comment.sourceSpan.details ? ", " + comment.sourceSpan.details : ''; |
| // TODO(ocombe): use a log service once there is a public one available |
| console.warn("I18n comments are deprecated, use an <ng-container> element instead (" + comment.sourceSpan.start + details + ")"); |
| } |
| this._inI18nBlock = true; |
| this._blockStartDepth = this._depth; |
| this._blockChildren = []; |
| this._blockMeaningAndDesc = |
| comment.value.replace(_I18N_COMMENT_PREFIX_REGEXP, '').trim(); |
| this._openTranslatableSection(comment); |
| } |
| } |
| else { |
| if (isClosing) { |
| if (this._depth == this._blockStartDepth) { |
| this._closeTranslatableSection(comment, this._blockChildren); |
| this._inI18nBlock = false; |
| var message = this._addMessage(this._blockChildren, this._blockMeaningAndDesc); |
| // merge attributes in sections |
| var nodes = this._translateMessage(comment, message); |
| return visitAll$1(this, nodes); |
| } |
| else { |
| this._reportError(comment, 'I18N blocks should not cross element boundaries'); |
| return; |
| } |
| } |
| } |
| } |
| }; |
| _Visitor.prototype.visitText = function (text, context) { |
| if (this._isInTranslatableSection) { |
| this._mayBeAddBlockChildren(text); |
| } |
| return text; |
| }; |
| _Visitor.prototype.visitElement = function (el, context) { |
| var _this = this; |
| this._mayBeAddBlockChildren(el); |
| this._depth++; |
| var wasInI18nNode = this._inI18nNode; |
| var wasInImplicitNode = this._inImplicitNode; |
| var childNodes = []; |
| var translatedChildNodes = undefined; |
| // Extract: |
| // - top level nodes with the (implicit) "i18n" attribute if not already in a section |
| // - ICU messages |
| var i18nAttr = _getI18nAttr(el); |
| var i18nMeta = i18nAttr ? i18nAttr.value : ''; |
| var isImplicit = this._implicitTags.some(function (tag) { return el.name === tag; }) && !this._inIcu && |
| !this._isInTranslatableSection; |
| var isTopLevelImplicit = !wasInImplicitNode && isImplicit; |
| this._inImplicitNode = wasInImplicitNode || isImplicit; |
| if (!this._isInTranslatableSection && !this._inIcu) { |
| if (i18nAttr || isTopLevelImplicit) { |
| this._inI18nNode = true; |
| var message = this._addMessage(el.children, i18nMeta); |
| translatedChildNodes = this._translateMessage(el, message); |
| } |
| if (this._mode == _VisitorMode.Extract) { |
| var isTranslatable = i18nAttr || isTopLevelImplicit; |
| if (isTranslatable) |
| this._openTranslatableSection(el); |
| visitAll$1(this, el.children); |
| if (isTranslatable) |
| this._closeTranslatableSection(el, el.children); |
| } |
| } |
| else { |
| if (i18nAttr || isTopLevelImplicit) { |
| this._reportError(el, 'Could not mark an element as translatable inside a translatable section'); |
| } |
| if (this._mode == _VisitorMode.Extract) { |
| // Descend into child nodes for extraction |
| visitAll$1(this, el.children); |
| } |
| } |
| if (this._mode === _VisitorMode.Merge) { |
| var visitNodes = translatedChildNodes || el.children; |
| visitNodes.forEach(function (child) { |
| var visited = child.visit(_this, context); |
| if (visited && !_this._isInTranslatableSection) { |
| // Do not add the children from translatable sections (= i18n blocks here) |
| // They will be added later in this loop when the block closes (i.e. on `<!-- /i18n -->`) |
| childNodes = childNodes.concat(visited); |
| } |
| }); |
| } |
| this._visitAttributesOf(el); |
| this._depth--; |
| this._inI18nNode = wasInI18nNode; |
| this._inImplicitNode = wasInImplicitNode; |
| if (this._mode === _VisitorMode.Merge) { |
| var translatedAttrs = this._translateAttributes(el); |
| return new Element$1(el.name, translatedAttrs, childNodes, el.sourceSpan, el.startSourceSpan, el.endSourceSpan); |
| } |
| return null; |
| }; |
| _Visitor.prototype.visitAttribute = function (attribute, context) { |
| throw new Error('unreachable code'); |
| }; |
| _Visitor.prototype._init = function (mode, interpolationConfig) { |
| this._mode = mode; |
| this._inI18nBlock = false; |
| this._inI18nNode = false; |
| this._depth = 0; |
| this._inIcu = false; |
| this._msgCountAtSectionStart = undefined; |
| this._errors = []; |
| this._messages = []; |
| this._inImplicitNode = false; |
| this._createI18nMessage = createI18nMessageFactory(interpolationConfig); |
| }; |
| // looks for translatable attributes |
| _Visitor.prototype._visitAttributesOf = function (el) { |
| var _this = this; |
| var explicitAttrNameToValue = {}; |
| var implicitAttrNames = this._implicitAttrs[el.name] || []; |
| el.attrs.filter(function (attr) { return attr.name.startsWith(_I18N_ATTR_PREFIX); }) |
| .forEach(function (attr) { return explicitAttrNameToValue[attr.name.slice(_I18N_ATTR_PREFIX.length)] = |
| attr.value; }); |
| el.attrs.forEach(function (attr) { |
| if (attr.name in explicitAttrNameToValue) { |
| _this._addMessage([attr], explicitAttrNameToValue[attr.name]); |
| } |
| else if (implicitAttrNames.some(function (name) { return attr.name === name; })) { |
| _this._addMessage([attr]); |
| } |
| }); |
| }; |
| // add a translatable message |
| _Visitor.prototype._addMessage = function (ast, msgMeta) { |
| if (ast.length == 0 || |
| ast.length == 1 && ast[0] instanceof Attribute && !ast[0].value) { |
| // Do not create empty messages |
| return null; |
| } |
| var _a = _parseMessageMeta(msgMeta), meaning = _a.meaning, description = _a.description, id = _a.id; |
| var message = this._createI18nMessage(ast, meaning, description, id); |
| this._messages.push(message); |
| return message; |
| }; |
| // Translates the given message given the `TranslationBundle` |
| // This is used for translating elements / blocks - see `_translateAttributes` for attributes |
| // no-op when called in extraction mode (returns []) |
| _Visitor.prototype._translateMessage = function (el, message) { |
| if (message && this._mode === _VisitorMode.Merge) { |
| var nodes = this._translations.get(message); |
| if (nodes) { |
| return nodes; |
| } |
| this._reportError(el, "Translation unavailable for message id=\"" + this._translations.digest(message) + "\""); |
| } |
| return []; |
| }; |
| // translate the attributes of an element and remove i18n specific attributes |
| _Visitor.prototype._translateAttributes = function (el) { |
| var _this = this; |
| var attributes = el.attrs; |
| var i18nParsedMessageMeta = {}; |
| attributes.forEach(function (attr) { |
| if (attr.name.startsWith(_I18N_ATTR_PREFIX)) { |
| i18nParsedMessageMeta[attr.name.slice(_I18N_ATTR_PREFIX.length)] = |
| _parseMessageMeta(attr.value); |
| } |
| }); |
| var translatedAttributes = []; |
| attributes.forEach(function (attr) { |
| if (attr.name === _I18N_ATTR || attr.name.startsWith(_I18N_ATTR_PREFIX)) { |
| // strip i18n specific attributes |
| return; |
| } |
| if (attr.value && attr.value != '' && i18nParsedMessageMeta.hasOwnProperty(attr.name)) { |
| var _a = i18nParsedMessageMeta[attr.name], meaning = _a.meaning, description = _a.description, id = _a.id; |
| var message = _this._createI18nMessage([attr], meaning, description, id); |
| var nodes = _this._translations.get(message); |
| if (nodes) { |
| if (nodes.length == 0) { |
| translatedAttributes.push(new Attribute(attr.name, '', attr.sourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* i18n */)); |
| } |
| else if (nodes[0] instanceof Text$3) { |
| var value = nodes[0].value; |
| translatedAttributes.push(new Attribute(attr.name, value, attr.sourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* i18n */)); |
| } |
| else { |
| _this._reportError(el, "Unexpected translation for attribute \"" + attr.name + "\" (id=\"" + (id || _this._translations.digest(message)) + "\")"); |
| } |
| } |
| else { |
| _this._reportError(el, "Translation unavailable for attribute \"" + attr.name + "\" (id=\"" + (id || _this._translations.digest(message)) + "\")"); |
| } |
| } |
| else { |
| translatedAttributes.push(attr); |
| } |
| }); |
| return translatedAttributes; |
| }; |
| /** |
| * Add the node as a child of the block when: |
| * - we are in a block, |
| * - we are not inside a ICU message (those are handled separately), |
| * - the node is a "direct child" of the block |
| */ |
| _Visitor.prototype._mayBeAddBlockChildren = function (node) { |
| if (this._inI18nBlock && !this._inIcu && this._depth == this._blockStartDepth) { |
| this._blockChildren.push(node); |
| } |
| }; |
| /** |
| * Marks the start of a section, see `_closeTranslatableSection` |
| */ |
| _Visitor.prototype._openTranslatableSection = function (node) { |
| if (this._isInTranslatableSection) { |
| this._reportError(node, 'Unexpected section start'); |
| } |
| else { |
| this._msgCountAtSectionStart = this._messages.length; |
| } |
| }; |
| Object.defineProperty(_Visitor.prototype, "_isInTranslatableSection", { |
| /** |
| * A translatable section could be: |
| * - the content of translatable element, |
| * - nodes between `<!-- i18n -->` and `<!-- /i18n -->` comments |
| */ |
| get: function () { |
| return this._msgCountAtSectionStart !== void 0; |
| }, |
| enumerable: false, |
| configurable: true |
| }); |
| /** |
| * Terminates a section. |
| * |
| * If a section has only one significant children (comments not significant) then we should not |
| * keep the message from this children: |
| * |
| * `<p i18n="meaning|description">{ICU message}</p>` would produce two messages: |
| * - one for the <p> content with meaning and description, |
| * - another one for the ICU message. |
| * |
| * In this case the last message is discarded as it contains less information (the AST is |
| * otherwise identical). |
| * |
| * Note that we should still keep messages extracted from attributes inside the section (ie in the |
| * ICU message here) |
| */ |
| _Visitor.prototype._closeTranslatableSection = function (node, directChildren) { |
| if (!this._isInTranslatableSection) { |
| this._reportError(node, 'Unexpected section end'); |
| return; |
| } |
| var startIndex = this._msgCountAtSectionStart; |
| var significantChildren = directChildren.reduce(function (count, node) { return count + (node instanceof Comment$1 ? 0 : 1); }, 0); |
| if (significantChildren == 1) { |
| for (var i = this._messages.length - 1; i >= startIndex; i--) { |
| var ast = this._messages[i].nodes; |
| if (!(ast.length == 1 && ast[0] instanceof Text$1)) { |
| this._messages.splice(i, 1); |
| break; |
| } |
| } |
| } |
| this._msgCountAtSectionStart = undefined; |
| }; |
| _Visitor.prototype._reportError = function (node, msg) { |
| this._errors.push(new I18nError(node.sourceSpan, msg)); |
| }; |
| return _Visitor; |
| }()); |
| function _isOpeningComment(n) { |
| return !!(n instanceof Comment$1 && n.value && n.value.startsWith('i18n')); |
| } |
| function _isClosingComment(n) { |
| return !!(n instanceof Comment$1 && n.value && n.value === '/i18n'); |
| } |
| function _getI18nAttr(p) { |
| return p.attrs.find(function (attr) { return attr.name === _I18N_ATTR; }) || null; |
| } |
| function _parseMessageMeta(i18n) { |
| if (!i18n) |
| return { meaning: '', description: '', id: '' }; |
| var idIndex = i18n.indexOf(ID_SEPARATOR); |
| var descIndex = i18n.indexOf(MEANING_SEPARATOR); |
| var _a = __read((idIndex > -1) ? [i18n.slice(0, idIndex), i18n.slice(idIndex + 2)] : [i18n, ''], 2), meaningAndDesc = _a[0], id = _a[1]; |
| var _b = __read((descIndex > -1) ? |
| [meaningAndDesc.slice(0, descIndex), meaningAndDesc.slice(descIndex + 1)] : |
| ['', meaningAndDesc], 2), meaning = _b[0], description = _b[1]; |
| return { meaning: meaning, description: description, id: id.trim() }; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var XmlTagDefinition = /** @class */ (function () { |
| function XmlTagDefinition() { |
| this.closedByParent = false; |
| this.isVoid = false; |
| this.ignoreFirstLf = false; |
| this.canSelfClose = true; |
| this.preventNamespaceInheritance = false; |
| } |
| XmlTagDefinition.prototype.requireExtraParent = function (currentParent) { |
| return false; |
| }; |
| XmlTagDefinition.prototype.isClosedByChild = function (name) { |
| return false; |
| }; |
| XmlTagDefinition.prototype.getContentType = function () { |
| return exports.TagContentType.PARSABLE_DATA; |
| }; |
| return XmlTagDefinition; |
| }()); |
| var _TAG_DEFINITION = new XmlTagDefinition(); |
| function getXmlTagDefinition(tagName) { |
| return _TAG_DEFINITION; |
| } |
| |
| var XmlParser = /** @class */ (function (_super) { |
| __extends(XmlParser, _super); |
| function XmlParser() { |
| return _super.call(this, getXmlTagDefinition) || this; |
| } |
| XmlParser.prototype.parse = function (source, url, options) { |
| return _super.prototype.parse.call(this, source, url, options); |
| }; |
| return XmlParser; |
| }(Parser)); |
| |
| var _VERSION = '1.2'; |
| var _XMLNS = 'urn:oasis:names:tc:xliff:document:1.2'; |
| // TODO(vicb): make this a param (s/_/-/) |
| var _DEFAULT_SOURCE_LANG = 'en'; |
| var _PLACEHOLDER_TAG$1 = 'x'; |
| var _MARKER_TAG = 'mrk'; |
| var _FILE_TAG = 'file'; |
| var _SOURCE_TAG$1 = 'source'; |
| var _SEGMENT_SOURCE_TAG = 'seg-source'; |
| var _ALT_TRANS_TAG = 'alt-trans'; |
| var _TARGET_TAG = 'target'; |
| var _UNIT_TAG = 'trans-unit'; |
| var _CONTEXT_GROUP_TAG = 'context-group'; |
| var _CONTEXT_TAG = 'context'; |
| // https://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html |
| // https://docs.oasis-open.org/xliff/v1.2/xliff-profile-html/xliff-profile-html-1.2.html |
| var Xliff = /** @class */ (function (_super) { |
| __extends(Xliff, _super); |
| function Xliff() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| Xliff.prototype.write = function (messages, locale) { |
| var visitor = new _WriteVisitor(); |
| var transUnits = []; |
| messages.forEach(function (message) { |
| var _a; |
| var contextTags = []; |
| message.sources.forEach(function (source) { |
| var contextGroupTag = new Tag(_CONTEXT_GROUP_TAG, { purpose: 'location' }); |
| contextGroupTag.children.push(new CR(10), new Tag(_CONTEXT_TAG, { 'context-type': 'sourcefile' }, [new Text$2(source.filePath)]), new CR(10), new Tag(_CONTEXT_TAG, { 'context-type': 'linenumber' }, [new Text$2("" + source.startLine)]), new CR(8)); |
| contextTags.push(new CR(8), contextGroupTag); |
| }); |
| var transUnit = new Tag(_UNIT_TAG, { id: message.id, datatype: 'html' }); |
| (_a = transUnit.children).push.apply(_a, __spread([new CR(8), new Tag(_SOURCE_TAG$1, {}, visitor.serialize(message.nodes))], contextTags)); |
| if (message.description) { |
| transUnit.children.push(new CR(8), new Tag('note', { priority: '1', from: 'description' }, [new Text$2(message.description)])); |
| } |
| if (message.meaning) { |
| transUnit.children.push(new CR(8), new Tag('note', { priority: '1', from: 'meaning' }, [new Text$2(message.meaning)])); |
| } |
| transUnit.children.push(new CR(6)); |
| transUnits.push(new CR(6), transUnit); |
| }); |
| var body = new Tag('body', {}, __spread(transUnits, [new CR(4)])); |
| var file = new Tag('file', { |
| 'source-language': locale || _DEFAULT_SOURCE_LANG, |
| datatype: 'plaintext', |
| original: 'ng2.template', |
| }, [new CR(4), body, new CR(2)]); |
| var xliff = new Tag('xliff', { version: _VERSION, xmlns: _XMLNS }, [new CR(2), file, new CR()]); |
| return serialize([ |
| new Declaration({ version: '1.0', encoding: 'UTF-8' }), new CR(), xliff, new CR() |
| ]); |
| }; |
| Xliff.prototype.load = function (content, url) { |
| // xliff to xml nodes |
| var xliffParser = new XliffParser(); |
| var _a = xliffParser.parse(content, url), locale = _a.locale, msgIdToHtml = _a.msgIdToHtml, errors = _a.errors; |
| // xml nodes to i18n nodes |
| var i18nNodesByMsgId = {}; |
| var converter = new XmlToI18n(); |
| Object.keys(msgIdToHtml).forEach(function (msgId) { |
| var _a = converter.convert(msgIdToHtml[msgId], url), i18nNodes = _a.i18nNodes, e = _a.errors; |
| errors.push.apply(errors, __spread(e)); |
| i18nNodesByMsgId[msgId] = i18nNodes; |
| }); |
| if (errors.length) { |
| throw new Error("xliff parse errors:\n" + errors.join('\n')); |
| } |
| return { locale: locale, i18nNodesByMsgId: i18nNodesByMsgId }; |
| }; |
| Xliff.prototype.digest = function (message) { |
| return digest(message); |
| }; |
| return Xliff; |
| }(Serializer)); |
| var _WriteVisitor = /** @class */ (function () { |
| function _WriteVisitor() { |
| } |
| _WriteVisitor.prototype.visitText = function (text, context) { |
| return [new Text$2(text.value)]; |
| }; |
| _WriteVisitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| var nodes = []; |
| container.children.forEach(function (node) { return nodes.push.apply(nodes, __spread(node.visit(_this))); }); |
| return nodes; |
| }; |
| _WriteVisitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| var nodes = [new Text$2("{" + icu.expressionPlaceholder + ", " + icu.type + ", ")]; |
| Object.keys(icu.cases).forEach(function (c) { |
| nodes.push.apply(nodes, __spread([new Text$2(c + " {")], icu.cases[c].visit(_this), [new Text$2("} ")])); |
| }); |
| nodes.push(new Text$2("}")); |
| return nodes; |
| }; |
| _WriteVisitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var ctype = getCtypeForTag(ph.tag); |
| if (ph.isVoid) { |
| // void tags have no children nor closing tags |
| return [new Tag(_PLACEHOLDER_TAG$1, { id: ph.startName, ctype: ctype, 'equiv-text': "<" + ph.tag + "/>" })]; |
| } |
| var startTagPh = new Tag(_PLACEHOLDER_TAG$1, { id: ph.startName, ctype: ctype, 'equiv-text': "<" + ph.tag + ">" }); |
| var closeTagPh = new Tag(_PLACEHOLDER_TAG$1, { id: ph.closeName, ctype: ctype, 'equiv-text': "</" + ph.tag + ">" }); |
| return __spread([startTagPh], this.serialize(ph.children), [closeTagPh]); |
| }; |
| _WriteVisitor.prototype.visitPlaceholder = function (ph, context) { |
| return [new Tag(_PLACEHOLDER_TAG$1, { id: ph.name, 'equiv-text': "{{" + ph.value + "}}" })]; |
| }; |
| _WriteVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| var equivText = "{" + ph.value.expression + ", " + ph.value.type + ", " + Object.keys(ph.value.cases).map(function (value) { return value + ' {...}'; }).join(' ') + "}"; |
| return [new Tag(_PLACEHOLDER_TAG$1, { id: ph.name, 'equiv-text': equivText })]; |
| }; |
| _WriteVisitor.prototype.serialize = function (nodes) { |
| var _this = this; |
| return [].concat.apply([], __spread(nodes.map(function (node) { return node.visit(_this); }))); |
| }; |
| return _WriteVisitor; |
| }()); |
| // TODO(vicb): add error management (structure) |
| // Extract messages as xml nodes from the xliff file |
| var XliffParser = /** @class */ (function () { |
| function XliffParser() { |
| this._locale = null; |
| } |
| XliffParser.prototype.parse = function (xliff, url) { |
| this._unitMlString = null; |
| this._msgIdToHtml = {}; |
| var xml = new XmlParser().parse(xliff, url); |
| this._errors = xml.errors; |
| visitAll$1(this, xml.rootNodes, null); |
| return { |
| msgIdToHtml: this._msgIdToHtml, |
| errors: this._errors, |
| locale: this._locale, |
| }; |
| }; |
| XliffParser.prototype.visitElement = function (element, context) { |
| switch (element.name) { |
| case _UNIT_TAG: |
| this._unitMlString = null; |
| var idAttr = element.attrs.find(function (attr) { return attr.name === 'id'; }); |
| if (!idAttr) { |
| this._addError(element, "<" + _UNIT_TAG + "> misses the \"id\" attribute"); |
| } |
| else { |
| var id = idAttr.value; |
| if (this._msgIdToHtml.hasOwnProperty(id)) { |
| this._addError(element, "Duplicated translations for msg " + id); |
| } |
| else { |
| visitAll$1(this, element.children, null); |
| if (typeof this._unitMlString === 'string') { |
| this._msgIdToHtml[id] = this._unitMlString; |
| } |
| else { |
| this._addError(element, "Message " + id + " misses a translation"); |
| } |
| } |
| } |
| break; |
| // ignore those tags |
| case _SOURCE_TAG$1: |
| case _SEGMENT_SOURCE_TAG: |
| case _ALT_TRANS_TAG: |
| break; |
| case _TARGET_TAG: |
| var innerTextStart = element.startSourceSpan.end.offset; |
| var innerTextEnd = element.endSourceSpan.start.offset; |
| var content = element.startSourceSpan.start.file.content; |
| var innerText = content.slice(innerTextStart, innerTextEnd); |
| this._unitMlString = innerText; |
| break; |
| case _FILE_TAG: |
| var localeAttr = element.attrs.find(function (attr) { return attr.name === 'target-language'; }); |
| if (localeAttr) { |
| this._locale = localeAttr.value; |
| } |
| visitAll$1(this, element.children, null); |
| break; |
| default: |
| // TODO(vicb): assert file structure, xliff version |
| // For now only recurse on unhandled nodes |
| visitAll$1(this, element.children, null); |
| } |
| }; |
| XliffParser.prototype.visitAttribute = function (attribute, context) { }; |
| XliffParser.prototype.visitText = function (text, context) { }; |
| XliffParser.prototype.visitComment = function (comment, context) { }; |
| XliffParser.prototype.visitExpansion = function (expansion, context) { }; |
| XliffParser.prototype.visitExpansionCase = function (expansionCase, context) { }; |
| XliffParser.prototype._addError = function (node, message) { |
| this._errors.push(new I18nError(node.sourceSpan, message)); |
| }; |
| return XliffParser; |
| }()); |
| // Convert ml nodes (xliff syntax) to i18n nodes |
| var XmlToI18n = /** @class */ (function () { |
| function XmlToI18n() { |
| } |
| XmlToI18n.prototype.convert = function (message, url) { |
| var xmlIcu = new XmlParser().parse(message, url, { tokenizeExpansionForms: true }); |
| this._errors = xmlIcu.errors; |
| var i18nNodes = this._errors.length > 0 || xmlIcu.rootNodes.length == 0 ? |
| [] : [].concat.apply([], __spread(visitAll$1(this, xmlIcu.rootNodes))); |
| return { |
| i18nNodes: i18nNodes, |
| errors: this._errors, |
| }; |
| }; |
| XmlToI18n.prototype.visitText = function (text, context) { |
| return new Text$1(text.value, text.sourceSpan); |
| }; |
| XmlToI18n.prototype.visitElement = function (el, context) { |
| if (el.name === _PLACEHOLDER_TAG$1) { |
| var nameAttr = el.attrs.find(function (attr) { return attr.name === 'id'; }); |
| if (nameAttr) { |
| return new Placeholder('', nameAttr.value, el.sourceSpan); |
| } |
| this._addError(el, "<" + _PLACEHOLDER_TAG$1 + "> misses the \"id\" attribute"); |
| return null; |
| } |
| if (el.name === _MARKER_TAG) { |
| return [].concat.apply([], __spread(visitAll$1(this, el.children))); |
| } |
| this._addError(el, "Unexpected tag"); |
| return null; |
| }; |
| XmlToI18n.prototype.visitExpansion = function (icu, context) { |
| var caseMap = {}; |
| visitAll$1(this, icu.cases).forEach(function (c) { |
| caseMap[c.value] = new Container(c.nodes, icu.sourceSpan); |
| }); |
| return new Icu$1(icu.switchValue, icu.type, caseMap, icu.sourceSpan); |
| }; |
| XmlToI18n.prototype.visitExpansionCase = function (icuCase, context) { |
| return { |
| value: icuCase.value, |
| nodes: visitAll$1(this, icuCase.expression), |
| }; |
| }; |
| XmlToI18n.prototype.visitComment = function (comment, context) { }; |
| XmlToI18n.prototype.visitAttribute = function (attribute, context) { }; |
| XmlToI18n.prototype._addError = function (node, message) { |
| this._errors.push(new I18nError(node.sourceSpan, message)); |
| }; |
| return XmlToI18n; |
| }()); |
| function getCtypeForTag(tag) { |
| switch (tag.toLowerCase()) { |
| case 'br': |
| return 'lb'; |
| case 'img': |
| return 'image'; |
| default: |
| return "x-" + tag; |
| } |
| } |
| |
| var _VERSION$1 = '2.0'; |
| var _XMLNS$1 = 'urn:oasis:names:tc:xliff:document:2.0'; |
| // TODO(vicb): make this a param (s/_/-/) |
| var _DEFAULT_SOURCE_LANG$1 = 'en'; |
| var _PLACEHOLDER_TAG$2 = 'ph'; |
| var _PLACEHOLDER_SPANNING_TAG = 'pc'; |
| var _MARKER_TAG$1 = 'mrk'; |
| var _XLIFF_TAG = 'xliff'; |
| var _SOURCE_TAG$2 = 'source'; |
| var _TARGET_TAG$1 = 'target'; |
| var _UNIT_TAG$1 = 'unit'; |
| // https://docs.oasis-open.org/xliff/xliff-core/v2.0/os/xliff-core-v2.0-os.html |
| var Xliff2 = /** @class */ (function (_super) { |
| __extends(Xliff2, _super); |
| function Xliff2() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| Xliff2.prototype.write = function (messages, locale) { |
| var visitor = new _WriteVisitor$1(); |
| var units = []; |
| messages.forEach(function (message) { |
| var unit = new Tag(_UNIT_TAG$1, { id: message.id }); |
| var notes = new Tag('notes'); |
| if (message.description || message.meaning) { |
| if (message.description) { |
| notes.children.push(new CR(8), new Tag('note', { category: 'description' }, [new Text$2(message.description)])); |
| } |
| if (message.meaning) { |
| notes.children.push(new CR(8), new Tag('note', { category: 'meaning' }, [new Text$2(message.meaning)])); |
| } |
| } |
| message.sources.forEach(function (source) { |
| notes.children.push(new CR(8), new Tag('note', { category: 'location' }, [ |
| new Text$2(source.filePath + ":" + source.startLine + (source.endLine !== source.startLine ? ',' + source.endLine : '')) |
| ])); |
| }); |
| notes.children.push(new CR(6)); |
| unit.children.push(new CR(6), notes); |
| var segment = new Tag('segment'); |
| segment.children.push(new CR(8), new Tag(_SOURCE_TAG$2, {}, visitor.serialize(message.nodes)), new CR(6)); |
| unit.children.push(new CR(6), segment, new CR(4)); |
| units.push(new CR(4), unit); |
| }); |
| var file = new Tag('file', { 'original': 'ng.template', id: 'ngi18n' }, __spread(units, [new CR(2)])); |
| var xliff = new Tag(_XLIFF_TAG, { version: _VERSION$1, xmlns: _XMLNS$1, srcLang: locale || _DEFAULT_SOURCE_LANG$1 }, [new CR(2), file, new CR()]); |
| return serialize([ |
| new Declaration({ version: '1.0', encoding: 'UTF-8' }), new CR(), xliff, new CR() |
| ]); |
| }; |
| Xliff2.prototype.load = function (content, url) { |
| // xliff to xml nodes |
| var xliff2Parser = new Xliff2Parser(); |
| var _a = xliff2Parser.parse(content, url), locale = _a.locale, msgIdToHtml = _a.msgIdToHtml, errors = _a.errors; |
| // xml nodes to i18n nodes |
| var i18nNodesByMsgId = {}; |
| var converter = new XmlToI18n$1(); |
| Object.keys(msgIdToHtml).forEach(function (msgId) { |
| var _a = converter.convert(msgIdToHtml[msgId], url), i18nNodes = _a.i18nNodes, e = _a.errors; |
| errors.push.apply(errors, __spread(e)); |
| i18nNodesByMsgId[msgId] = i18nNodes; |
| }); |
| if (errors.length) { |
| throw new Error("xliff2 parse errors:\n" + errors.join('\n')); |
| } |
| return { locale: locale, i18nNodesByMsgId: i18nNodesByMsgId }; |
| }; |
| Xliff2.prototype.digest = function (message) { |
| return decimalDigest(message); |
| }; |
| return Xliff2; |
| }(Serializer)); |
| var _WriteVisitor$1 = /** @class */ (function () { |
| function _WriteVisitor() { |
| } |
| _WriteVisitor.prototype.visitText = function (text, context) { |
| return [new Text$2(text.value)]; |
| }; |
| _WriteVisitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| var nodes = []; |
| container.children.forEach(function (node) { return nodes.push.apply(nodes, __spread(node.visit(_this))); }); |
| return nodes; |
| }; |
| _WriteVisitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| var nodes = [new Text$2("{" + icu.expressionPlaceholder + ", " + icu.type + ", ")]; |
| Object.keys(icu.cases).forEach(function (c) { |
| nodes.push.apply(nodes, __spread([new Text$2(c + " {")], icu.cases[c].visit(_this), [new Text$2("} ")])); |
| }); |
| nodes.push(new Text$2("}")); |
| return nodes; |
| }; |
| _WriteVisitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var _this = this; |
| var type = getTypeForTag(ph.tag); |
| if (ph.isVoid) { |
| var tagPh = new Tag(_PLACEHOLDER_TAG$2, { |
| id: (this._nextPlaceholderId++).toString(), |
| equiv: ph.startName, |
| type: type, |
| disp: "<" + ph.tag + "/>", |
| }); |
| return [tagPh]; |
| } |
| var tagPc = new Tag(_PLACEHOLDER_SPANNING_TAG, { |
| id: (this._nextPlaceholderId++).toString(), |
| equivStart: ph.startName, |
| equivEnd: ph.closeName, |
| type: type, |
| dispStart: "<" + ph.tag + ">", |
| dispEnd: "</" + ph.tag + ">", |
| }); |
| var nodes = [].concat.apply([], __spread(ph.children.map(function (node) { return node.visit(_this); }))); |
| if (nodes.length) { |
| nodes.forEach(function (node) { return tagPc.children.push(node); }); |
| } |
| else { |
| tagPc.children.push(new Text$2('')); |
| } |
| return [tagPc]; |
| }; |
| _WriteVisitor.prototype.visitPlaceholder = function (ph, context) { |
| var idStr = (this._nextPlaceholderId++).toString(); |
| return [new Tag(_PLACEHOLDER_TAG$2, { |
| id: idStr, |
| equiv: ph.name, |
| disp: "{{" + ph.value + "}}", |
| })]; |
| }; |
| _WriteVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| var cases = Object.keys(ph.value.cases).map(function (value) { return value + ' {...}'; }).join(' '); |
| var idStr = (this._nextPlaceholderId++).toString(); |
| return [new Tag(_PLACEHOLDER_TAG$2, { id: idStr, equiv: ph.name, disp: "{" + ph.value.expression + ", " + ph.value.type + ", " + cases + "}" })]; |
| }; |
| _WriteVisitor.prototype.serialize = function (nodes) { |
| var _this = this; |
| this._nextPlaceholderId = 0; |
| return [].concat.apply([], __spread(nodes.map(function (node) { return node.visit(_this); }))); |
| }; |
| return _WriteVisitor; |
| }()); |
| // Extract messages as xml nodes from the xliff file |
| var Xliff2Parser = /** @class */ (function () { |
| function Xliff2Parser() { |
| this._locale = null; |
| } |
| Xliff2Parser.prototype.parse = function (xliff, url) { |
| this._unitMlString = null; |
| this._msgIdToHtml = {}; |
| var xml = new XmlParser().parse(xliff, url); |
| this._errors = xml.errors; |
| visitAll$1(this, xml.rootNodes, null); |
| return { |
| msgIdToHtml: this._msgIdToHtml, |
| errors: this._errors, |
| locale: this._locale, |
| }; |
| }; |
| Xliff2Parser.prototype.visitElement = function (element, context) { |
| switch (element.name) { |
| case _UNIT_TAG$1: |
| this._unitMlString = null; |
| var idAttr = element.attrs.find(function (attr) { return attr.name === 'id'; }); |
| if (!idAttr) { |
| this._addError(element, "<" + _UNIT_TAG$1 + "> misses the \"id\" attribute"); |
| } |
| else { |
| var id = idAttr.value; |
| if (this._msgIdToHtml.hasOwnProperty(id)) { |
| this._addError(element, "Duplicated translations for msg " + id); |
| } |
| else { |
| visitAll$1(this, element.children, null); |
| if (typeof this._unitMlString === 'string') { |
| this._msgIdToHtml[id] = this._unitMlString; |
| } |
| else { |
| this._addError(element, "Message " + id + " misses a translation"); |
| } |
| } |
| } |
| break; |
| case _SOURCE_TAG$2: |
| // ignore source message |
| break; |
| case _TARGET_TAG$1: |
| var innerTextStart = element.startSourceSpan.end.offset; |
| var innerTextEnd = element.endSourceSpan.start.offset; |
| var content = element.startSourceSpan.start.file.content; |
| var innerText = content.slice(innerTextStart, innerTextEnd); |
| this._unitMlString = innerText; |
| break; |
| case _XLIFF_TAG: |
| var localeAttr = element.attrs.find(function (attr) { return attr.name === 'trgLang'; }); |
| if (localeAttr) { |
| this._locale = localeAttr.value; |
| } |
| var versionAttr = element.attrs.find(function (attr) { return attr.name === 'version'; }); |
| if (versionAttr) { |
| var version = versionAttr.value; |
| if (version !== '2.0') { |
| this._addError(element, "The XLIFF file version " + version + " is not compatible with XLIFF 2.0 serializer"); |
| } |
| else { |
| visitAll$1(this, element.children, null); |
| } |
| } |
| break; |
| default: |
| visitAll$1(this, element.children, null); |
| } |
| }; |
| Xliff2Parser.prototype.visitAttribute = function (attribute, context) { }; |
| Xliff2Parser.prototype.visitText = function (text, context) { }; |
| Xliff2Parser.prototype.visitComment = function (comment, context) { }; |
| Xliff2Parser.prototype.visitExpansion = function (expansion, context) { }; |
| Xliff2Parser.prototype.visitExpansionCase = function (expansionCase, context) { }; |
| Xliff2Parser.prototype._addError = function (node, message) { |
| this._errors.push(new I18nError(node.sourceSpan, message)); |
| }; |
| return Xliff2Parser; |
| }()); |
| // Convert ml nodes (xliff syntax) to i18n nodes |
| var XmlToI18n$1 = /** @class */ (function () { |
| function XmlToI18n() { |
| } |
| XmlToI18n.prototype.convert = function (message, url) { |
| var xmlIcu = new XmlParser().parse(message, url, { tokenizeExpansionForms: true }); |
| this._errors = xmlIcu.errors; |
| var i18nNodes = this._errors.length > 0 || xmlIcu.rootNodes.length == 0 ? |
| [] : [].concat.apply([], __spread(visitAll$1(this, xmlIcu.rootNodes))); |
| return { |
| i18nNodes: i18nNodes, |
| errors: this._errors, |
| }; |
| }; |
| XmlToI18n.prototype.visitText = function (text, context) { |
| return new Text$1(text.value, text.sourceSpan); |
| }; |
| XmlToI18n.prototype.visitElement = function (el, context) { |
| var _this = this; |
| switch (el.name) { |
| case _PLACEHOLDER_TAG$2: |
| var nameAttr = el.attrs.find(function (attr) { return attr.name === 'equiv'; }); |
| if (nameAttr) { |
| return [new Placeholder('', nameAttr.value, el.sourceSpan)]; |
| } |
| this._addError(el, "<" + _PLACEHOLDER_TAG$2 + "> misses the \"equiv\" attribute"); |
| break; |
| case _PLACEHOLDER_SPANNING_TAG: |
| var startAttr = el.attrs.find(function (attr) { return attr.name === 'equivStart'; }); |
| var endAttr = el.attrs.find(function (attr) { return attr.name === 'equivEnd'; }); |
| if (!startAttr) { |
| this._addError(el, "<" + _PLACEHOLDER_TAG$2 + "> misses the \"equivStart\" attribute"); |
| } |
| else if (!endAttr) { |
| this._addError(el, "<" + _PLACEHOLDER_TAG$2 + "> misses the \"equivEnd\" attribute"); |
| } |
| else { |
| var startId = startAttr.value; |
| var endId = endAttr.value; |
| var nodes = []; |
| return nodes.concat.apply(nodes, __spread([new Placeholder('', startId, el.sourceSpan)], el.children.map(function (node) { return node.visit(_this, null); }), [new Placeholder('', endId, el.sourceSpan)])); |
| } |
| break; |
| case _MARKER_TAG$1: |
| return [].concat.apply([], __spread(visitAll$1(this, el.children))); |
| default: |
| this._addError(el, "Unexpected tag"); |
| } |
| return null; |
| }; |
| XmlToI18n.prototype.visitExpansion = function (icu, context) { |
| var caseMap = {}; |
| visitAll$1(this, icu.cases).forEach(function (c) { |
| caseMap[c.value] = new Container(c.nodes, icu.sourceSpan); |
| }); |
| return new Icu$1(icu.switchValue, icu.type, caseMap, icu.sourceSpan); |
| }; |
| XmlToI18n.prototype.visitExpansionCase = function (icuCase, context) { |
| return { |
| value: icuCase.value, |
| nodes: [].concat.apply([], __spread(visitAll$1(this, icuCase.expression))), |
| }; |
| }; |
| XmlToI18n.prototype.visitComment = function (comment, context) { }; |
| XmlToI18n.prototype.visitAttribute = function (attribute, context) { }; |
| XmlToI18n.prototype._addError = function (node, message) { |
| this._errors.push(new I18nError(node.sourceSpan, message)); |
| }; |
| return XmlToI18n; |
| }()); |
| function getTypeForTag(tag) { |
| switch (tag.toLowerCase()) { |
| case 'br': |
| case 'b': |
| case 'i': |
| case 'u': |
| return 'fmt'; |
| case 'img': |
| return 'image'; |
| case 'a': |
| return 'link'; |
| default: |
| return 'other'; |
| } |
| } |
| |
| var _TRANSLATIONS_TAG = 'translationbundle'; |
| var _TRANSLATION_TAG = 'translation'; |
| var _PLACEHOLDER_TAG$3 = 'ph'; |
| var Xtb = /** @class */ (function (_super) { |
| __extends(Xtb, _super); |
| function Xtb() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| Xtb.prototype.write = function (messages, locale) { |
| throw new Error('Unsupported'); |
| }; |
| Xtb.prototype.load = function (content, url) { |
| // xtb to xml nodes |
| var xtbParser = new XtbParser(); |
| var _a = xtbParser.parse(content, url), locale = _a.locale, msgIdToHtml = _a.msgIdToHtml, errors = _a.errors; |
| // xml nodes to i18n nodes |
| var i18nNodesByMsgId = {}; |
| var converter = new XmlToI18n$2(); |
| // Because we should be able to load xtb files that rely on features not supported by angular, |
| // we need to delay the conversion of html to i18n nodes so that non angular messages are not |
| // converted |
| Object.keys(msgIdToHtml).forEach(function (msgId) { |
| var valueFn = function () { |
| var _a = converter.convert(msgIdToHtml[msgId], url), i18nNodes = _a.i18nNodes, errors = _a.errors; |
| if (errors.length) { |
| throw new Error("xtb parse errors:\n" + errors.join('\n')); |
| } |
| return i18nNodes; |
| }; |
| createLazyProperty(i18nNodesByMsgId, msgId, valueFn); |
| }); |
| if (errors.length) { |
| throw new Error("xtb parse errors:\n" + errors.join('\n')); |
| } |
| return { locale: locale, i18nNodesByMsgId: i18nNodesByMsgId }; |
| }; |
| Xtb.prototype.digest = function (message) { |
| return digest$1(message); |
| }; |
| Xtb.prototype.createNameMapper = function (message) { |
| return new SimplePlaceholderMapper(message, toPublicName); |
| }; |
| return Xtb; |
| }(Serializer)); |
| function createLazyProperty(messages, id, valueFn) { |
| Object.defineProperty(messages, id, { |
| configurable: true, |
| enumerable: true, |
| get: function () { |
| var value = valueFn(); |
| Object.defineProperty(messages, id, { enumerable: true, value: value }); |
| return value; |
| }, |
| set: function (_) { |
| throw new Error('Could not overwrite an XTB translation'); |
| }, |
| }); |
| } |
| // Extract messages as xml nodes from the xtb file |
| var XtbParser = /** @class */ (function () { |
| function XtbParser() { |
| this._locale = null; |
| } |
| XtbParser.prototype.parse = function (xtb, url) { |
| this._bundleDepth = 0; |
| this._msgIdToHtml = {}; |
| // We can not parse the ICU messages at this point as some messages might not originate |
| // from Angular that could not be lex'd. |
| var xml = new XmlParser().parse(xtb, url); |
| this._errors = xml.errors; |
| visitAll$1(this, xml.rootNodes); |
| return { |
| msgIdToHtml: this._msgIdToHtml, |
| errors: this._errors, |
| locale: this._locale, |
| }; |
| }; |
| XtbParser.prototype.visitElement = function (element, context) { |
| switch (element.name) { |
| case _TRANSLATIONS_TAG: |
| this._bundleDepth++; |
| if (this._bundleDepth > 1) { |
| this._addError(element, "<" + _TRANSLATIONS_TAG + "> elements can not be nested"); |
| } |
| var langAttr = element.attrs.find(function (attr) { return attr.name === 'lang'; }); |
| if (langAttr) { |
| this._locale = langAttr.value; |
| } |
| visitAll$1(this, element.children, null); |
| this._bundleDepth--; |
| break; |
| case _TRANSLATION_TAG: |
| var idAttr = element.attrs.find(function (attr) { return attr.name === 'id'; }); |
| if (!idAttr) { |
| this._addError(element, "<" + _TRANSLATION_TAG + "> misses the \"id\" attribute"); |
| } |
| else { |
| var id = idAttr.value; |
| if (this._msgIdToHtml.hasOwnProperty(id)) { |
| this._addError(element, "Duplicated translations for msg " + id); |
| } |
| else { |
| var innerTextStart = element.startSourceSpan.end.offset; |
| var innerTextEnd = element.endSourceSpan.start.offset; |
| var content = element.startSourceSpan.start.file.content; |
| var innerText = content.slice(innerTextStart, innerTextEnd); |
| this._msgIdToHtml[id] = innerText; |
| } |
| } |
| break; |
| default: |
| this._addError(element, 'Unexpected tag'); |
| } |
| }; |
| XtbParser.prototype.visitAttribute = function (attribute, context) { }; |
| XtbParser.prototype.visitText = function (text, context) { }; |
| XtbParser.prototype.visitComment = function (comment, context) { }; |
| XtbParser.prototype.visitExpansion = function (expansion, context) { }; |
| XtbParser.prototype.visitExpansionCase = function (expansionCase, context) { }; |
| XtbParser.prototype._addError = function (node, message) { |
| this._errors.push(new I18nError(node.sourceSpan, message)); |
| }; |
| return XtbParser; |
| }()); |
| // Convert ml nodes (xtb syntax) to i18n nodes |
| var XmlToI18n$2 = /** @class */ (function () { |
| function XmlToI18n() { |
| } |
| XmlToI18n.prototype.convert = function (message, url) { |
| var xmlIcu = new XmlParser().parse(message, url, { tokenizeExpansionForms: true }); |
| this._errors = xmlIcu.errors; |
| var i18nNodes = this._errors.length > 0 || xmlIcu.rootNodes.length == 0 ? |
| [] : |
| visitAll$1(this, xmlIcu.rootNodes); |
| return { |
| i18nNodes: i18nNodes, |
| errors: this._errors, |
| }; |
| }; |
| XmlToI18n.prototype.visitText = function (text, context) { |
| return new Text$1(text.value, text.sourceSpan); |
| }; |
| XmlToI18n.prototype.visitExpansion = function (icu, context) { |
| var caseMap = {}; |
| visitAll$1(this, icu.cases).forEach(function (c) { |
| caseMap[c.value] = new Container(c.nodes, icu.sourceSpan); |
| }); |
| return new Icu$1(icu.switchValue, icu.type, caseMap, icu.sourceSpan); |
| }; |
| XmlToI18n.prototype.visitExpansionCase = function (icuCase, context) { |
| return { |
| value: icuCase.value, |
| nodes: visitAll$1(this, icuCase.expression), |
| }; |
| }; |
| XmlToI18n.prototype.visitElement = function (el, context) { |
| if (el.name === _PLACEHOLDER_TAG$3) { |
| var nameAttr = el.attrs.find(function (attr) { return attr.name === 'name'; }); |
| if (nameAttr) { |
| return new Placeholder('', nameAttr.value, el.sourceSpan); |
| } |
| this._addError(el, "<" + _PLACEHOLDER_TAG$3 + "> misses the \"name\" attribute"); |
| } |
| else { |
| this._addError(el, "Unexpected tag"); |
| } |
| return null; |
| }; |
| XmlToI18n.prototype.visitComment = function (comment, context) { }; |
| XmlToI18n.prototype.visitAttribute = function (attribute, context) { }; |
| XmlToI18n.prototype._addError = function (node, message) { |
| this._errors.push(new I18nError(node.sourceSpan, message)); |
| }; |
| return XmlToI18n; |
| }()); |
| |
| /** |
| * A container for translated messages |
| */ |
| var TranslationBundle = /** @class */ (function () { |
| function TranslationBundle(_i18nNodesByMsgId, locale, digest, mapperFactory, missingTranslationStrategy, console) { |
| if (_i18nNodesByMsgId === void 0) { _i18nNodesByMsgId = {}; } |
| if (missingTranslationStrategy === void 0) { missingTranslationStrategy = MissingTranslationStrategy.Warning; } |
| this._i18nNodesByMsgId = _i18nNodesByMsgId; |
| this.digest = digest; |
| this.mapperFactory = mapperFactory; |
| this._i18nToHtml = new I18nToHtmlVisitor(_i18nNodesByMsgId, locale, digest, mapperFactory, missingTranslationStrategy, console); |
| } |
| // Creates a `TranslationBundle` by parsing the given `content` with the `serializer`. |
| TranslationBundle.load = function (content, url, serializer, missingTranslationStrategy, console) { |
| var _a = serializer.load(content, url), locale = _a.locale, i18nNodesByMsgId = _a.i18nNodesByMsgId; |
| var digestFn = function (m) { return serializer.digest(m); }; |
| var mapperFactory = function (m) { return serializer.createNameMapper(m); }; |
| return new TranslationBundle(i18nNodesByMsgId, locale, digestFn, mapperFactory, missingTranslationStrategy, console); |
| }; |
| // Returns the translation as HTML nodes from the given source message. |
| TranslationBundle.prototype.get = function (srcMsg) { |
| var html = this._i18nToHtml.convert(srcMsg); |
| if (html.errors.length) { |
| throw new Error(html.errors.join('\n')); |
| } |
| return html.nodes; |
| }; |
| TranslationBundle.prototype.has = function (srcMsg) { |
| return this.digest(srcMsg) in this._i18nNodesByMsgId; |
| }; |
| return TranslationBundle; |
| }()); |
| var I18nToHtmlVisitor = /** @class */ (function () { |
| function I18nToHtmlVisitor(_i18nNodesByMsgId, _locale, _digest, _mapperFactory, _missingTranslationStrategy, _console) { |
| if (_i18nNodesByMsgId === void 0) { _i18nNodesByMsgId = {}; } |
| this._i18nNodesByMsgId = _i18nNodesByMsgId; |
| this._locale = _locale; |
| this._digest = _digest; |
| this._mapperFactory = _mapperFactory; |
| this._missingTranslationStrategy = _missingTranslationStrategy; |
| this._console = _console; |
| this._contextStack = []; |
| this._errors = []; |
| } |
| I18nToHtmlVisitor.prototype.convert = function (srcMsg) { |
| this._contextStack.length = 0; |
| this._errors.length = 0; |
| // i18n to text |
| var text = this._convertToText(srcMsg); |
| // text to html |
| var url = srcMsg.nodes[0].sourceSpan.start.file.url; |
| var html = new HtmlParser().parse(text, url, { tokenizeExpansionForms: true }); |
| return { |
| nodes: html.rootNodes, |
| errors: __spread(this._errors, html.errors), |
| }; |
| }; |
| I18nToHtmlVisitor.prototype.visitText = function (text, context) { |
| // `convert()` uses an `HtmlParser` to return `html.Node`s |
| // we should then make sure that any special characters are escaped |
| return escapeXml(text.value); |
| }; |
| I18nToHtmlVisitor.prototype.visitContainer = function (container, context) { |
| var _this = this; |
| return container.children.map(function (n) { return n.visit(_this); }).join(''); |
| }; |
| I18nToHtmlVisitor.prototype.visitIcu = function (icu, context) { |
| var _this = this; |
| var cases = Object.keys(icu.cases).map(function (k) { return k + " {" + icu.cases[k].visit(_this) + "}"; }); |
| // TODO(vicb): Once all format switch to using expression placeholders |
| // we should throw when the placeholder is not in the source message |
| var exp = this._srcMsg.placeholders.hasOwnProperty(icu.expression) ? |
| this._srcMsg.placeholders[icu.expression].text : |
| icu.expression; |
| return "{" + exp + ", " + icu.type + ", " + cases.join(' ') + "}"; |
| }; |
| I18nToHtmlVisitor.prototype.visitPlaceholder = function (ph, context) { |
| var phName = this._mapper(ph.name); |
| if (this._srcMsg.placeholders.hasOwnProperty(phName)) { |
| return this._srcMsg.placeholders[phName].text; |
| } |
| if (this._srcMsg.placeholderToMessage.hasOwnProperty(phName)) { |
| return this._convertToText(this._srcMsg.placeholderToMessage[phName]); |
| } |
| this._addError(ph, "Unknown placeholder \"" + ph.name + "\""); |
| return ''; |
| }; |
| // Loaded message contains only placeholders (vs tag and icu placeholders). |
| // However when a translation can not be found, we need to serialize the source message |
| // which can contain tag placeholders |
| I18nToHtmlVisitor.prototype.visitTagPlaceholder = function (ph, context) { |
| var _this = this; |
| var tag = "" + ph.tag; |
| var attrs = Object.keys(ph.attrs).map(function (name) { return name + "=\"" + ph.attrs[name] + "\""; }).join(' '); |
| if (ph.isVoid) { |
| return "<" + tag + " " + attrs + "/>"; |
| } |
| var children = ph.children.map(function (c) { return c.visit(_this); }).join(''); |
| return "<" + tag + " " + attrs + ">" + children + "</" + tag + ">"; |
| }; |
| // Loaded message contains only placeholders (vs tag and icu placeholders). |
| // However when a translation can not be found, we need to serialize the source message |
| // which can contain tag placeholders |
| I18nToHtmlVisitor.prototype.visitIcuPlaceholder = function (ph, context) { |
| // An ICU placeholder references the source message to be serialized |
| return this._convertToText(this._srcMsg.placeholderToMessage[ph.name]); |
| }; |
| /** |
| * Convert a source message to a translated text string: |
| * - text nodes are replaced with their translation, |
| * - placeholders are replaced with their content, |
| * - ICU nodes are converted to ICU expressions. |
| */ |
| I18nToHtmlVisitor.prototype._convertToText = function (srcMsg) { |
| var _this = this; |
| var id = this._digest(srcMsg); |
| var mapper = this._mapperFactory ? this._mapperFactory(srcMsg) : null; |
| var nodes; |
| this._contextStack.push({ msg: this._srcMsg, mapper: this._mapper }); |
| this._srcMsg = srcMsg; |
| if (this._i18nNodesByMsgId.hasOwnProperty(id)) { |
| // When there is a translation use its nodes as the source |
| // And create a mapper to convert serialized placeholder names to internal names |
| nodes = this._i18nNodesByMsgId[id]; |
| this._mapper = function (name) { return mapper ? mapper.toInternalName(name) : name; }; |
| } |
| else { |
| // When no translation has been found |
| // - report an error / a warning / nothing, |
| // - use the nodes from the original message |
| // - placeholders are already internal and need no mapper |
| if (this._missingTranslationStrategy === MissingTranslationStrategy.Error) { |
| var ctx = this._locale ? " for locale \"" + this._locale + "\"" : ''; |
| this._addError(srcMsg.nodes[0], "Missing translation for message \"" + id + "\"" + ctx); |
| } |
| else if (this._console && |
| this._missingTranslationStrategy === MissingTranslationStrategy.Warning) { |
| var ctx = this._locale ? " for locale \"" + this._locale + "\"" : ''; |
| this._console.warn("Missing translation for message \"" + id + "\"" + ctx); |
| } |
| nodes = srcMsg.nodes; |
| this._mapper = function (name) { return name; }; |
| } |
| var text = nodes.map(function (node) { return node.visit(_this); }).join(''); |
| var context = this._contextStack.pop(); |
| this._srcMsg = context.msg; |
| this._mapper = context.mapper; |
| return text; |
| }; |
| I18nToHtmlVisitor.prototype._addError = function (el, msg) { |
| this._errors.push(new I18nError(el.sourceSpan, msg)); |
| }; |
| return I18nToHtmlVisitor; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var I18NHtmlParser = /** @class */ (function () { |
| function I18NHtmlParser(_htmlParser, translations, translationsFormat, missingTranslation, console) { |
| if (missingTranslation === void 0) { missingTranslation = MissingTranslationStrategy.Warning; } |
| this._htmlParser = _htmlParser; |
| if (translations) { |
| var serializer = createSerializer(translationsFormat); |
| this._translationBundle = |
| TranslationBundle.load(translations, 'i18n', serializer, missingTranslation, console); |
| } |
| else { |
| this._translationBundle = |
| new TranslationBundle({}, null, digest, undefined, missingTranslation, console); |
| } |
| } |
| I18NHtmlParser.prototype.parse = function (source, url, options) { |
| if (options === void 0) { options = {}; } |
| var interpolationConfig = options.interpolationConfig || DEFAULT_INTERPOLATION_CONFIG; |
| var parseResult = this._htmlParser.parse(source, url, Object.assign({ interpolationConfig: interpolationConfig }, options)); |
| if (parseResult.errors.length) { |
| return new ParseTreeResult(parseResult.rootNodes, parseResult.errors); |
| } |
| return mergeTranslations(parseResult.rootNodes, this._translationBundle, interpolationConfig, [], {}); |
| }; |
| return I18NHtmlParser; |
| }()); |
| function createSerializer(format) { |
| format = (format || 'xlf').toLowerCase(); |
| switch (format) { |
| case 'xmb': |
| return new Xmb(); |
| case 'xtb': |
| return new Xtb(); |
| case 'xliff2': |
| case 'xlf2': |
| return new Xliff2(); |
| case 'xliff': |
| case 'xlf': |
| default: |
| return new Xliff(); |
| } |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var QUOTED_KEYS = '$quoted$'; |
| function convertValueToOutputAst(ctx, value, type) { |
| if (type === void 0) { type = null; } |
| return visitValue(value, new _ValueOutputAstTransformer(ctx), type); |
| } |
| var _ValueOutputAstTransformer = /** @class */ (function () { |
| function _ValueOutputAstTransformer(ctx) { |
| this.ctx = ctx; |
| } |
| _ValueOutputAstTransformer.prototype.visitArray = function (arr, type) { |
| var values = []; |
| // Note Array.map() must not be used to convert the values because it will |
| // skip over empty elements in arrays constructed using `new Array(length)`, |
| // resulting in `undefined` elements. This breaks the type guarantee that |
| // all values in `o.LiteralArrayExpr` are of type `o.Expression`. |
| // See test case in `value_util_spec.ts`. |
| for (var i = 0; i < arr.length; ++i) { |
| values.push(visitValue(arr[i], this, null /* context */)); |
| } |
| return literalArr(values, type); |
| }; |
| _ValueOutputAstTransformer.prototype.visitStringMap = function (map, type) { |
| var _this = this; |
| var entries = []; |
| var quotedSet = new Set(map && map[QUOTED_KEYS]); |
| Object.keys(map).forEach(function (key) { |
| entries.push(new LiteralMapEntry(key, visitValue(map[key], _this, null), quotedSet.has(key))); |
| }); |
| return new LiteralMapExpr(entries, type); |
| }; |
| _ValueOutputAstTransformer.prototype.visitPrimitive = function (value, type) { |
| return literal(value, type); |
| }; |
| _ValueOutputAstTransformer.prototype.visitOther = function (value, type) { |
| if (value instanceof Expression) { |
| return value; |
| } |
| else { |
| return this.ctx.importExpr(value); |
| } |
| }; |
| return _ValueOutputAstTransformer; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| function mapEntry$1(key, value) { |
| return { key: key, value: value, quoted: false }; |
| } |
| var InjectableCompiler = /** @class */ (function () { |
| function InjectableCompiler(reflector, alwaysGenerateDef) { |
| this.reflector = reflector; |
| this.alwaysGenerateDef = alwaysGenerateDef; |
| this.tokenInjector = reflector.resolveExternalReference(Identifiers.Injector); |
| } |
| InjectableCompiler.prototype.depsArray = function (deps, ctx) { |
| var _this = this; |
| return deps.map(function (dep) { |
| var token = dep; |
| var args = [token]; |
| var flags = 0 /* Default */; |
| if (Array.isArray(dep)) { |
| for (var i = 0; i < dep.length; i++) { |
| var v = dep[i]; |
| if (v) { |
| if (v.ngMetadataName === 'Optional') { |
| flags |= 8 /* Optional */; |
| } |
| else if (v.ngMetadataName === 'SkipSelf') { |
| flags |= 4 /* SkipSelf */; |
| } |
| else if (v.ngMetadataName === 'Self') { |
| flags |= 2 /* Self */; |
| } |
| else if (v.ngMetadataName === 'Inject') { |
| token = v.token; |
| } |
| else { |
| token = v; |
| } |
| } |
| } |
| } |
| var tokenExpr; |
| if (typeof token === 'string') { |
| tokenExpr = literal(token); |
| } |
| else if (token === _this.tokenInjector) { |
| tokenExpr = importExpr(Identifiers.INJECTOR); |
| } |
| else { |
| tokenExpr = ctx.importExpr(token); |
| } |
| if (flags !== 0 /* Default */) { |
| args = [tokenExpr, literal(flags)]; |
| } |
| else { |
| args = [tokenExpr]; |
| } |
| return importExpr(Identifiers.inject).callFn(args); |
| }); |
| }; |
| InjectableCompiler.prototype.factoryFor = function (injectable, ctx) { |
| var retValue; |
| if (injectable.useExisting) { |
| retValue = importExpr(Identifiers.inject).callFn([ctx.importExpr(injectable.useExisting)]); |
| } |
| else if (injectable.useFactory) { |
| var deps = injectable.deps || []; |
| if (deps.length > 0) { |
| retValue = ctx.importExpr(injectable.useFactory).callFn(this.depsArray(deps, ctx)); |
| } |
| else { |
| return ctx.importExpr(injectable.useFactory); |
| } |
| } |
| else if (injectable.useValue) { |
| retValue = convertValueToOutputAst(ctx, injectable.useValue); |
| } |
| else { |
| var clazz = injectable.useClass || injectable.symbol; |
| var depArgs = this.depsArray(this.reflector.parameters(clazz), ctx); |
| retValue = new InstantiateExpr(ctx.importExpr(clazz), depArgs); |
| } |
| return fn([], [new ReturnStatement(retValue)], undefined, undefined, injectable.symbol.name + '_Factory'); |
| }; |
| InjectableCompiler.prototype.injectableDef = function (injectable, ctx) { |
| var providedIn = NULL_EXPR; |
| if (injectable.providedIn !== undefined) { |
| if (injectable.providedIn === null) { |
| providedIn = NULL_EXPR; |
| } |
| else if (typeof injectable.providedIn === 'string') { |
| providedIn = literal(injectable.providedIn); |
| } |
| else { |
| providedIn = ctx.importExpr(injectable.providedIn); |
| } |
| } |
| var def = [ |
| mapEntry$1('factory', this.factoryFor(injectable, ctx)), |
| mapEntry$1('token', ctx.importExpr(injectable.type.reference)), |
| mapEntry$1('providedIn', providedIn), |
| ]; |
| return importExpr(Identifiers.ɵɵdefineInjectable).callFn([literalMap(def)]); |
| }; |
| InjectableCompiler.prototype.compile = function (injectable, ctx) { |
| if (this.alwaysGenerateDef || injectable.providedIn !== undefined) { |
| var className = identifierName(injectable.type); |
| var clazz = new ClassStmt(className, null, [ |
| new ClassField('ɵprov', INFERRED_TYPE, [exports.StmtModifier.Static], this.injectableDef(injectable, ctx)), |
| ], [], new ClassMethod(null, [], []), []); |
| ctx.statements.push(clazz); |
| } |
| }; |
| return InjectableCompiler; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var STRIP_SRC_FILE_SUFFIXES = /(\.ts|\.d\.ts|\.js|\.jsx|\.tsx)$/; |
| var GENERATED_FILE = /\.ngfactory\.|\.ngsummary\./; |
| var JIT_SUMMARY_FILE = /\.ngsummary\./; |
| var JIT_SUMMARY_NAME = /NgSummary$/; |
| function ngfactoryFilePath(filePath, forceSourceFile) { |
| if (forceSourceFile === void 0) { forceSourceFile = false; } |
| var urlWithSuffix = splitTypescriptSuffix(filePath, forceSourceFile); |
| return urlWithSuffix[0] + ".ngfactory" + normalizeGenFileSuffix(urlWithSuffix[1]); |
| } |
| function stripGeneratedFileSuffix(filePath) { |
| return filePath.replace(GENERATED_FILE, '.'); |
| } |
| function isGeneratedFile(filePath) { |
| return GENERATED_FILE.test(filePath); |
| } |
| function splitTypescriptSuffix(path, forceSourceFile) { |
| if (forceSourceFile === void 0) { forceSourceFile = false; } |
| if (path.endsWith('.d.ts')) { |
| return [path.slice(0, -5), forceSourceFile ? '.ts' : '.d.ts']; |
| } |
| var lastDot = path.lastIndexOf('.'); |
| if (lastDot !== -1) { |
| return [path.substring(0, lastDot), path.substring(lastDot)]; |
| } |
| return [path, '']; |
| } |
| function normalizeGenFileSuffix(srcFileSuffix) { |
| return srcFileSuffix === '.tsx' ? '.ts' : srcFileSuffix; |
| } |
| function summaryFileName(fileName) { |
| var fileNameWithoutSuffix = fileName.replace(STRIP_SRC_FILE_SUFFIXES, ''); |
| return fileNameWithoutSuffix + ".ngsummary.json"; |
| } |
| function summaryForJitFileName(fileName, forceSourceFile) { |
| if (forceSourceFile === void 0) { forceSourceFile = false; } |
| var urlWithSuffix = splitTypescriptSuffix(stripGeneratedFileSuffix(fileName), forceSourceFile); |
| return urlWithSuffix[0] + ".ngsummary" + urlWithSuffix[1]; |
| } |
| function stripSummaryForJitFileSuffix(filePath) { |
| return filePath.replace(JIT_SUMMARY_FILE, '.'); |
| } |
| function summaryForJitName(symbolName) { |
| return symbolName + "NgSummary"; |
| } |
| function stripSummaryForJitNameSuffix(symbolName) { |
| return symbolName.replace(JIT_SUMMARY_NAME, ''); |
| } |
| var LOWERED_SYMBOL = /\u0275\d+/; |
| function isLoweredSymbol(name) { |
| return LOWERED_SYMBOL.test(name); |
| } |
| function createLoweredSymbol(id) { |
| return "\u0275" + id; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var LifecycleHooks; |
| (function (LifecycleHooks) { |
| LifecycleHooks[LifecycleHooks["OnInit"] = 0] = "OnInit"; |
| LifecycleHooks[LifecycleHooks["OnDestroy"] = 1] = "OnDestroy"; |
| LifecycleHooks[LifecycleHooks["DoCheck"] = 2] = "DoCheck"; |
| LifecycleHooks[LifecycleHooks["OnChanges"] = 3] = "OnChanges"; |
| LifecycleHooks[LifecycleHooks["AfterContentInit"] = 4] = "AfterContentInit"; |
| LifecycleHooks[LifecycleHooks["AfterContentChecked"] = 5] = "AfterContentChecked"; |
| LifecycleHooks[LifecycleHooks["AfterViewInit"] = 6] = "AfterViewInit"; |
| LifecycleHooks[LifecycleHooks["AfterViewChecked"] = 7] = "AfterViewChecked"; |
| })(LifecycleHooks || (LifecycleHooks = {})); |
| var LIFECYCLE_HOOKS_VALUES = [ |
| LifecycleHooks.OnInit, LifecycleHooks.OnDestroy, LifecycleHooks.DoCheck, LifecycleHooks.OnChanges, |
| LifecycleHooks.AfterContentInit, LifecycleHooks.AfterContentChecked, LifecycleHooks.AfterViewInit, |
| LifecycleHooks.AfterViewChecked |
| ]; |
| function hasLifecycleHook(reflector, hook, token) { |
| return reflector.hasLifecycleHook(token, getHookName(hook)); |
| } |
| function getAllLifecycleHooks(reflector, token) { |
| return LIFECYCLE_HOOKS_VALUES.filter(function (hook) { return hasLifecycleHook(reflector, hook, token); }); |
| } |
| function getHookName(hook) { |
| switch (hook) { |
| case LifecycleHooks.OnInit: |
| return 'ngOnInit'; |
| case LifecycleHooks.OnDestroy: |
| return 'ngOnDestroy'; |
| case LifecycleHooks.DoCheck: |
| return 'ngDoCheck'; |
| case LifecycleHooks.OnChanges: |
| return 'ngOnChanges'; |
| case LifecycleHooks.AfterContentInit: |
| return 'ngAfterContentInit'; |
| case LifecycleHooks.AfterContentChecked: |
| return 'ngAfterContentChecked'; |
| case LifecycleHooks.AfterViewInit: |
| return 'ngAfterViewInit'; |
| case LifecycleHooks.AfterViewChecked: |
| return 'ngAfterViewChecked'; |
| default: |
| // This default case is not needed by TypeScript compiler, as the switch is exhaustive. |
| // However Closure Compiler does not understand that and reports an error in typed mode. |
| // The `throw new Error` below works around the problem, and the unexpected: never variable |
| // makes sure tsc still checks this code is unreachable. |
| var unexpected = hook; |
| throw new Error("unexpected " + unexpected); |
| } |
| } |
| |
| var ERROR_COMPONENT_TYPE = 'ngComponentType'; |
| var MISSING_NG_MODULE_METADATA_ERROR_DATA = 'ngMissingNgModuleMetadataErrorData'; |
| function getMissingNgModuleMetadataErrorData(error) { |
| var _a; |
| return (_a = error[MISSING_NG_MODULE_METADATA_ERROR_DATA]) !== null && _a !== void 0 ? _a : null; |
| } |
| // Design notes: |
| // - don't lazily create metadata: |
| // For some metadata, we need to do async work sometimes, |
| // so the user has to kick off this loading. |
| // But we want to report errors even when the async work is |
| // not required to check that the user would have been able |
| // to wait correctly. |
| var CompileMetadataResolver = /** @class */ (function () { |
| function CompileMetadataResolver(_config, _htmlParser, _ngModuleResolver, _directiveResolver, _pipeResolver, _summaryResolver, _schemaRegistry, _directiveNormalizer, _console, _staticSymbolCache, _reflector, _errorCollector) { |
| this._config = _config; |
| this._htmlParser = _htmlParser; |
| this._ngModuleResolver = _ngModuleResolver; |
| this._directiveResolver = _directiveResolver; |
| this._pipeResolver = _pipeResolver; |
| this._summaryResolver = _summaryResolver; |
| this._schemaRegistry = _schemaRegistry; |
| this._directiveNormalizer = _directiveNormalizer; |
| this._console = _console; |
| this._staticSymbolCache = _staticSymbolCache; |
| this._reflector = _reflector; |
| this._errorCollector = _errorCollector; |
| this._nonNormalizedDirectiveCache = new Map(); |
| this._directiveCache = new Map(); |
| this._summaryCache = new Map(); |
| this._pipeCache = new Map(); |
| this._ngModuleCache = new Map(); |
| this._ngModuleOfTypes = new Map(); |
| this._shallowModuleCache = new Map(); |
| } |
| CompileMetadataResolver.prototype.getReflector = function () { |
| return this._reflector; |
| }; |
| CompileMetadataResolver.prototype.clearCacheFor = function (type) { |
| var dirMeta = this._directiveCache.get(type); |
| this._directiveCache.delete(type); |
| this._nonNormalizedDirectiveCache.delete(type); |
| this._summaryCache.delete(type); |
| this._pipeCache.delete(type); |
| this._ngModuleOfTypes.delete(type); |
| // Clear all of the NgModule as they contain transitive information! |
| this._ngModuleCache.clear(); |
| if (dirMeta) { |
| this._directiveNormalizer.clearCacheFor(dirMeta); |
| } |
| }; |
| CompileMetadataResolver.prototype.clearCache = function () { |
| this._directiveCache.clear(); |
| this._nonNormalizedDirectiveCache.clear(); |
| this._summaryCache.clear(); |
| this._pipeCache.clear(); |
| this._ngModuleCache.clear(); |
| this._ngModuleOfTypes.clear(); |
| this._directiveNormalizer.clearCache(); |
| }; |
| CompileMetadataResolver.prototype._createProxyClass = function (baseType, name) { |
| var delegate = null; |
| var proxyClass = function () { |
| if (!delegate) { |
| throw new Error("Illegal state: Class " + name + " for type " + stringify(baseType) + " is not compiled yet!"); |
| } |
| return delegate.apply(this, arguments); |
| }; |
| proxyClass.setDelegate = function (d) { |
| delegate = d; |
| proxyClass.prototype = d.prototype; |
| }; |
| // Make stringify work correctly |
| proxyClass.overriddenName = name; |
| return proxyClass; |
| }; |
| CompileMetadataResolver.prototype.getGeneratedClass = function (dirType, name) { |
| if (dirType instanceof StaticSymbol) { |
| return this._staticSymbolCache.get(ngfactoryFilePath(dirType.filePath), name); |
| } |
| else { |
| return this._createProxyClass(dirType, name); |
| } |
| }; |
| CompileMetadataResolver.prototype.getComponentViewClass = function (dirType) { |
| return this.getGeneratedClass(dirType, viewClassName(dirType, 0)); |
| }; |
| CompileMetadataResolver.prototype.getHostComponentViewClass = function (dirType) { |
| return this.getGeneratedClass(dirType, hostViewClassName(dirType)); |
| }; |
| CompileMetadataResolver.prototype.getHostComponentType = function (dirType) { |
| var name = identifierName({ reference: dirType }) + "_Host"; |
| if (dirType instanceof StaticSymbol) { |
| return this._staticSymbolCache.get(dirType.filePath, name); |
| } |
| return this._createProxyClass(dirType, name); |
| }; |
| CompileMetadataResolver.prototype.getRendererType = function (dirType) { |
| if (dirType instanceof StaticSymbol) { |
| return this._staticSymbolCache.get(ngfactoryFilePath(dirType.filePath), rendererTypeName(dirType)); |
| } |
| else { |
| // returning an object as proxy, |
| // that we fill later during runtime compilation. |
| return {}; |
| } |
| }; |
| CompileMetadataResolver.prototype.getComponentFactory = function (selector, dirType, inputs, outputs) { |
| if (dirType instanceof StaticSymbol) { |
| return this._staticSymbolCache.get(ngfactoryFilePath(dirType.filePath), componentFactoryName(dirType)); |
| } |
| else { |
| var hostView = this.getHostComponentViewClass(dirType); |
| // Note: ngContentSelectors will be filled later once the template is |
| // loaded. |
| var createComponentFactory = this._reflector.resolveExternalReference(Identifiers.createComponentFactory); |
| return createComponentFactory(selector, dirType, hostView, inputs, outputs, []); |
| } |
| }; |
| CompileMetadataResolver.prototype.initComponentFactory = function (factory, ngContentSelectors) { |
| var _b; |
| if (!(factory instanceof StaticSymbol)) { |
| (_b = factory.ngContentSelectors).push.apply(_b, __spread(ngContentSelectors)); |
| } |
| }; |
| CompileMetadataResolver.prototype._loadSummary = function (type, kind) { |
| var typeSummary = this._summaryCache.get(type); |
| if (!typeSummary) { |
| var summary = this._summaryResolver.resolveSummary(type); |
| typeSummary = summary ? summary.type : null; |
| this._summaryCache.set(type, typeSummary || null); |
| } |
| return typeSummary && typeSummary.summaryKind === kind ? typeSummary : null; |
| }; |
| CompileMetadataResolver.prototype.getHostComponentMetadata = function (compMeta, hostViewType) { |
| var hostType = this.getHostComponentType(compMeta.type.reference); |
| if (!hostViewType) { |
| hostViewType = this.getHostComponentViewClass(hostType); |
| } |
| // Note: ! is ok here as this method should only be called with normalized directive |
| // metadata, which always fills in the selector. |
| var template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate(); |
| var templateUrl = ''; |
| var htmlAst = this._htmlParser.parse(template, templateUrl); |
| return CompileDirectiveMetadata.create({ |
| isHost: true, |
| type: { reference: hostType, diDeps: [], lifecycleHooks: [] }, |
| template: new CompileTemplateMetadata({ |
| encapsulation: ViewEncapsulation.None, |
| template: template, |
| templateUrl: templateUrl, |
| htmlAst: htmlAst, |
| styles: [], |
| styleUrls: [], |
| ngContentSelectors: [], |
| animations: [], |
| isInline: true, |
| externalStylesheets: [], |
| interpolation: null, |
| preserveWhitespaces: false, |
| }), |
| exportAs: null, |
| changeDetection: ChangeDetectionStrategy.Default, |
| inputs: [], |
| outputs: [], |
| host: {}, |
| isComponent: true, |
| selector: '*', |
| providers: [], |
| viewProviders: [], |
| queries: [], |
| guards: {}, |
| viewQueries: [], |
| componentViewType: hostViewType, |
| rendererType: { id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {} }, |
| entryComponents: [], |
| componentFactory: null |
| }); |
| }; |
| CompileMetadataResolver.prototype.loadDirectiveMetadata = function (ngModuleType, directiveType, isSync) { |
| var _this = this; |
| if (this._directiveCache.has(directiveType)) { |
| return null; |
| } |
| directiveType = resolveForwardRef(directiveType); |
| var _b = this.getNonNormalizedDirectiveMetadata(directiveType), annotation = _b.annotation, metadata = _b.metadata; |
| var createDirectiveMetadata = function (templateMetadata) { |
| var normalizedDirMeta = new CompileDirectiveMetadata({ |
| isHost: false, |
| type: metadata.type, |
| isComponent: metadata.isComponent, |
| selector: metadata.selector, |
| exportAs: metadata.exportAs, |
| changeDetection: metadata.changeDetection, |
| inputs: metadata.inputs, |
| outputs: metadata.outputs, |
| hostListeners: metadata.hostListeners, |
| hostProperties: metadata.hostProperties, |
| hostAttributes: metadata.hostAttributes, |
| providers: metadata.providers, |
| viewProviders: metadata.viewProviders, |
| queries: metadata.queries, |
| guards: metadata.guards, |
| viewQueries: metadata.viewQueries, |
| entryComponents: metadata.entryComponents, |
| componentViewType: metadata.componentViewType, |
| rendererType: metadata.rendererType, |
| componentFactory: metadata.componentFactory, |
| template: templateMetadata |
| }); |
| if (templateMetadata) { |
| _this.initComponentFactory(metadata.componentFactory, templateMetadata.ngContentSelectors); |
| } |
| _this._directiveCache.set(directiveType, normalizedDirMeta); |
| _this._summaryCache.set(directiveType, normalizedDirMeta.toSummary()); |
| return null; |
| }; |
| if (metadata.isComponent) { |
| var template = metadata.template; |
| var templateMeta = this._directiveNormalizer.normalizeTemplate({ |
| ngModuleType: ngModuleType, |
| componentType: directiveType, |
| moduleUrl: this._reflector.componentModuleUrl(directiveType, annotation), |
| encapsulation: template.encapsulation, |
| template: template.template, |
| templateUrl: template.templateUrl, |
| styles: template.styles, |
| styleUrls: template.styleUrls, |
| animations: template.animations, |
| interpolation: template.interpolation, |
| preserveWhitespaces: template.preserveWhitespaces |
| }); |
| if (isPromise(templateMeta) && isSync) { |
| this._reportError(componentStillLoadingError(directiveType), directiveType); |
| return null; |
| } |
| return SyncAsync.then(templateMeta, createDirectiveMetadata); |
| } |
| else { |
| // directive |
| createDirectiveMetadata(null); |
| return null; |
| } |
| }; |
| CompileMetadataResolver.prototype.getNonNormalizedDirectiveMetadata = function (directiveType) { |
| var _this = this; |
| directiveType = resolveForwardRef(directiveType); |
| if (!directiveType) { |
| return null; |
| } |
| var cacheEntry = this._nonNormalizedDirectiveCache.get(directiveType); |
| if (cacheEntry) { |
| return cacheEntry; |
| } |
| var dirMeta = this._directiveResolver.resolve(directiveType, false); |
| if (!dirMeta) { |
| return null; |
| } |
| var nonNormalizedTemplateMetadata = undefined; |
| if (createComponent.isTypeOf(dirMeta)) { |
| // component |
| var compMeta = dirMeta; |
| assertArrayOfStrings('styles', compMeta.styles); |
| assertArrayOfStrings('styleUrls', compMeta.styleUrls); |
| assertInterpolationSymbols('interpolation', compMeta.interpolation); |
| var animations = compMeta.animations; |
| nonNormalizedTemplateMetadata = new CompileTemplateMetadata({ |
| encapsulation: noUndefined(compMeta.encapsulation), |
| template: noUndefined(compMeta.template), |
| templateUrl: noUndefined(compMeta.templateUrl), |
| htmlAst: null, |
| styles: compMeta.styles || [], |
| styleUrls: compMeta.styleUrls || [], |
| animations: animations || [], |
| interpolation: noUndefined(compMeta.interpolation), |
| isInline: !!compMeta.template, |
| externalStylesheets: [], |
| ngContentSelectors: [], |
| preserveWhitespaces: noUndefined(dirMeta.preserveWhitespaces), |
| }); |
| } |
| var changeDetectionStrategy = null; |
| var viewProviders = []; |
| var entryComponentMetadata = []; |
| var selector = dirMeta.selector; |
| if (createComponent.isTypeOf(dirMeta)) { |
| // Component |
| var compMeta = dirMeta; |
| changeDetectionStrategy = compMeta.changeDetection; |
| if (compMeta.viewProviders) { |
| viewProviders = this._getProvidersMetadata(compMeta.viewProviders, entryComponentMetadata, "viewProviders for \"" + stringifyType(directiveType) + "\"", [], directiveType); |
| } |
| if (compMeta.entryComponents) { |
| entryComponentMetadata = flattenAndDedupeArray(compMeta.entryComponents) |
| .map(function (type) { return _this._getEntryComponentMetadata(type); }) |
| .concat(entryComponentMetadata); |
| } |
| if (!selector) { |
| selector = this._schemaRegistry.getDefaultComponentElementName(); |
| } |
| } |
| else { |
| // Directive |
| if (!selector) { |
| selector = null; |
| } |
| } |
| var providers = []; |
| if (dirMeta.providers != null) { |
| providers = this._getProvidersMetadata(dirMeta.providers, entryComponentMetadata, "providers for \"" + stringifyType(directiveType) + "\"", [], directiveType); |
| } |
| var queries = []; |
| var viewQueries = []; |
| if (dirMeta.queries != null) { |
| queries = this._getQueriesMetadata(dirMeta.queries, false, directiveType); |
| viewQueries = this._getQueriesMetadata(dirMeta.queries, true, directiveType); |
| } |
| var metadata = CompileDirectiveMetadata.create({ |
| isHost: false, |
| selector: selector, |
| exportAs: noUndefined(dirMeta.exportAs), |
| isComponent: !!nonNormalizedTemplateMetadata, |
| type: this._getTypeMetadata(directiveType), |
| template: nonNormalizedTemplateMetadata, |
| changeDetection: changeDetectionStrategy, |
| inputs: dirMeta.inputs || [], |
| outputs: dirMeta.outputs || [], |
| host: dirMeta.host || {}, |
| providers: providers || [], |
| viewProviders: viewProviders || [], |
| queries: queries || [], |
| guards: dirMeta.guards || {}, |
| viewQueries: viewQueries || [], |
| entryComponents: entryComponentMetadata, |
| componentViewType: nonNormalizedTemplateMetadata ? this.getComponentViewClass(directiveType) : |
| null, |
| rendererType: nonNormalizedTemplateMetadata ? this.getRendererType(directiveType) : null, |
| componentFactory: null |
| }); |
| if (nonNormalizedTemplateMetadata) { |
| metadata.componentFactory = |
| this.getComponentFactory(selector, directiveType, metadata.inputs, metadata.outputs); |
| } |
| cacheEntry = { metadata: metadata, annotation: dirMeta }; |
| this._nonNormalizedDirectiveCache.set(directiveType, cacheEntry); |
| return cacheEntry; |
| }; |
| /** |
| * Gets the metadata for the given directive. |
| * This assumes `loadNgModuleDirectiveAndPipeMetadata` has been called first. |
| */ |
| CompileMetadataResolver.prototype.getDirectiveMetadata = function (directiveType) { |
| var dirMeta = this._directiveCache.get(directiveType); |
| if (!dirMeta) { |
| this._reportError(syntaxError("Illegal state: getDirectiveMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Directive " + stringifyType(directiveType) + "."), directiveType); |
| } |
| return dirMeta; |
| }; |
| CompileMetadataResolver.prototype.getDirectiveSummary = function (dirType) { |
| var dirSummary = this._loadSummary(dirType, exports.CompileSummaryKind.Directive); |
| if (!dirSummary) { |
| this._reportError(syntaxError("Illegal state: Could not load the summary for directive " + stringifyType(dirType) + "."), dirType); |
| } |
| return dirSummary; |
| }; |
| CompileMetadataResolver.prototype.isDirective = function (type) { |
| return !!this._loadSummary(type, exports.CompileSummaryKind.Directive) || |
| this._directiveResolver.isDirective(type); |
| }; |
| CompileMetadataResolver.prototype.isAbstractDirective = function (type) { |
| var summary = this._loadSummary(type, exports.CompileSummaryKind.Directive); |
| if (summary && !summary.isComponent) { |
| return !summary.selector; |
| } |
| var meta = this._directiveResolver.resolve(type, false); |
| if (meta && !createComponent.isTypeOf(meta)) { |
| return !meta.selector; |
| } |
| return false; |
| }; |
| CompileMetadataResolver.prototype.isPipe = function (type) { |
| return !!this._loadSummary(type, exports.CompileSummaryKind.Pipe) || |
| this._pipeResolver.isPipe(type); |
| }; |
| CompileMetadataResolver.prototype.isNgModule = function (type) { |
| return !!this._loadSummary(type, exports.CompileSummaryKind.NgModule) || |
| this._ngModuleResolver.isNgModule(type); |
| }; |
| CompileMetadataResolver.prototype.getNgModuleSummary = function (moduleType, alreadyCollecting) { |
| if (alreadyCollecting === void 0) { alreadyCollecting = null; } |
| var moduleSummary = this._loadSummary(moduleType, exports.CompileSummaryKind.NgModule); |
| if (!moduleSummary) { |
| var moduleMeta = this.getNgModuleMetadata(moduleType, false, alreadyCollecting); |
| moduleSummary = moduleMeta ? moduleMeta.toSummary() : null; |
| if (moduleSummary) { |
| this._summaryCache.set(moduleType, moduleSummary); |
| } |
| } |
| return moduleSummary; |
| }; |
| /** |
| * Loads the declared directives and pipes of an NgModule. |
| */ |
| CompileMetadataResolver.prototype.loadNgModuleDirectiveAndPipeMetadata = function (moduleType, isSync, throwIfNotFound) { |
| var _this = this; |
| if (throwIfNotFound === void 0) { throwIfNotFound = true; } |
| var ngModule = this.getNgModuleMetadata(moduleType, throwIfNotFound); |
| var loading = []; |
| if (ngModule) { |
| ngModule.declaredDirectives.forEach(function (id) { |
| var promise = _this.loadDirectiveMetadata(moduleType, id.reference, isSync); |
| if (promise) { |
| loading.push(promise); |
| } |
| }); |
| ngModule.declaredPipes.forEach(function (id) { return _this._loadPipeMetadata(id.reference); }); |
| } |
| return Promise.all(loading); |
| }; |
| CompileMetadataResolver.prototype.getShallowModuleMetadata = function (moduleType) { |
| var compileMeta = this._shallowModuleCache.get(moduleType); |
| if (compileMeta) { |
| return compileMeta; |
| } |
| var ngModuleMeta = findLast(this._reflector.shallowAnnotations(moduleType), createNgModule.isTypeOf); |
| compileMeta = { |
| type: this._getTypeMetadata(moduleType), |
| rawExports: ngModuleMeta.exports, |
| rawImports: ngModuleMeta.imports, |
| rawProviders: ngModuleMeta.providers, |
| }; |
| this._shallowModuleCache.set(moduleType, compileMeta); |
| return compileMeta; |
| }; |
| CompileMetadataResolver.prototype.getNgModuleMetadata = function (moduleType, throwIfNotFound, alreadyCollecting) { |
| var _this = this; |
| if (throwIfNotFound === void 0) { throwIfNotFound = true; } |
| if (alreadyCollecting === void 0) { alreadyCollecting = null; } |
| moduleType = resolveForwardRef(moduleType); |
| var compileMeta = this._ngModuleCache.get(moduleType); |
| if (compileMeta) { |
| return compileMeta; |
| } |
| var meta = this._ngModuleResolver.resolve(moduleType, throwIfNotFound); |
| if (!meta) { |
| return null; |
| } |
| var declaredDirectives = []; |
| var exportedNonModuleIdentifiers = []; |
| var declaredPipes = []; |
| var importedModules = []; |
| var exportedModules = []; |
| var providers = []; |
| var entryComponents = []; |
| var bootstrapComponents = []; |
| var schemas = []; |
| if (meta.imports) { |
| flattenAndDedupeArray(meta.imports).forEach(function (importedType) { |
| var importedModuleType = undefined; |
| if (isValidType(importedType)) { |
| importedModuleType = importedType; |
| } |
| else if (importedType && importedType.ngModule) { |
| var moduleWithProviders = importedType; |
| importedModuleType = moduleWithProviders.ngModule; |
| if (moduleWithProviders.providers) { |
| providers.push.apply(providers, __spread(_this._getProvidersMetadata(moduleWithProviders.providers, entryComponents, "provider for the NgModule '" + stringifyType(importedModuleType) + "'", [], importedType))); |
| } |
| } |
| if (importedModuleType) { |
| if (_this._checkSelfImport(moduleType, importedModuleType)) |
| return; |
| if (!alreadyCollecting) |
| alreadyCollecting = new Set(); |
| if (alreadyCollecting.has(importedModuleType)) { |
| _this._reportError(syntaxError(_this._getTypeDescriptor(importedModuleType) + " '" + stringifyType(importedType) + "' is imported recursively by the module '" + stringifyType(moduleType) + "'."), moduleType); |
| return; |
| } |
| alreadyCollecting.add(importedModuleType); |
| var importedModuleSummary = _this.getNgModuleSummary(importedModuleType, alreadyCollecting); |
| alreadyCollecting.delete(importedModuleType); |
| if (!importedModuleSummary) { |
| var err = syntaxError("Unexpected " + _this._getTypeDescriptor(importedType) + " '" + stringifyType(importedType) + "' imported by the module '" + stringifyType(moduleType) + "'. Please add a @NgModule annotation."); |
| // If possible, record additional context for this error to enable more useful |
| // diagnostics on the compiler side. |
| if (importedType instanceof StaticSymbol) { |
| err[MISSING_NG_MODULE_METADATA_ERROR_DATA] = { |
| fileName: importedType.filePath, |
| className: importedType.name, |
| }; |
| } |
| _this._reportError(err, moduleType); |
| return; |
| } |
| importedModules.push(importedModuleSummary); |
| } |
| else { |
| _this._reportError(syntaxError("Unexpected value '" + stringifyType(importedType) + "' imported by the module '" + stringifyType(moduleType) + "'"), moduleType); |
| return; |
| } |
| }); |
| } |
| if (meta.exports) { |
| flattenAndDedupeArray(meta.exports).forEach(function (exportedType) { |
| if (!isValidType(exportedType)) { |
| _this._reportError(syntaxError("Unexpected value '" + stringifyType(exportedType) + "' exported by the module '" + stringifyType(moduleType) + "'"), moduleType); |
| return; |
| } |
| if (!alreadyCollecting) |
| alreadyCollecting = new Set(); |
| if (alreadyCollecting.has(exportedType)) { |
| _this._reportError(syntaxError(_this._getTypeDescriptor(exportedType) + " '" + stringify(exportedType) + "' is exported recursively by the module '" + stringifyType(moduleType) + "'"), moduleType); |
| return; |
| } |
| alreadyCollecting.add(exportedType); |
| var exportedModuleSummary = _this.getNgModuleSummary(exportedType, alreadyCollecting); |
| alreadyCollecting.delete(exportedType); |
| if (exportedModuleSummary) { |
| exportedModules.push(exportedModuleSummary); |
| } |
| else { |
| exportedNonModuleIdentifiers.push(_this._getIdentifierMetadata(exportedType)); |
| } |
| }); |
| } |
| // Note: This will be modified later, so we rely on |
| // getting a new instance every time! |
| var transitiveModule = this._getTransitiveNgModuleMetadata(importedModules, exportedModules); |
| if (meta.declarations) { |
| flattenAndDedupeArray(meta.declarations).forEach(function (declaredType) { |
| if (!isValidType(declaredType)) { |
| _this._reportError(syntaxError("Unexpected value '" + stringifyType(declaredType) + "' declared by the module '" + stringifyType(moduleType) + "'"), moduleType); |
| return; |
| } |
| var declaredIdentifier = _this._getIdentifierMetadata(declaredType); |
| if (_this.isDirective(declaredType)) { |
| if (_this.isAbstractDirective(declaredType)) { |
| _this._reportError(syntaxError("Directive " + stringifyType(declaredType) + " has no selector, please add it!"), declaredType); |
| } |
| transitiveModule.addDirective(declaredIdentifier); |
| declaredDirectives.push(declaredIdentifier); |
| _this._addTypeToModule(declaredType, moduleType); |
| } |
| else if (_this.isPipe(declaredType)) { |
| transitiveModule.addPipe(declaredIdentifier); |
| transitiveModule.pipes.push(declaredIdentifier); |
| declaredPipes.push(declaredIdentifier); |
| _this._addTypeToModule(declaredType, moduleType); |
| } |
| else { |
| _this._reportError(syntaxError("Unexpected " + _this._getTypeDescriptor(declaredType) + " '" + stringifyType(declaredType) + "' declared by the module '" + stringifyType(moduleType) + "'. Please add a @Pipe/@Directive/@Component annotation."), moduleType); |
| return; |
| } |
| }); |
| } |
| var exportedDirectives = []; |
| var exportedPipes = []; |
| exportedNonModuleIdentifiers.forEach(function (exportedId) { |
| if (transitiveModule.directivesSet.has(exportedId.reference)) { |
| exportedDirectives.push(exportedId); |
| transitiveModule.addExportedDirective(exportedId); |
| } |
| else if (transitiveModule.pipesSet.has(exportedId.reference)) { |
| exportedPipes.push(exportedId); |
| transitiveModule.addExportedPipe(exportedId); |
| } |
| else { |
| _this._reportError(syntaxError("Can't export " + _this._getTypeDescriptor(exportedId.reference) + " " + stringifyType(exportedId.reference) + " from " + stringifyType(moduleType) + " as it was neither declared nor imported!"), moduleType); |
| return; |
| } |
| }); |
| // The providers of the module have to go last |
| // so that they overwrite any other provider we already added. |
| if (meta.providers) { |
| providers.push.apply(providers, __spread(this._getProvidersMetadata(meta.providers, entryComponents, "provider for the NgModule '" + stringifyType(moduleType) + "'", [], moduleType))); |
| } |
| if (meta.entryComponents) { |
| entryComponents.push.apply(entryComponents, __spread(flattenAndDedupeArray(meta.entryComponents) |
| .map(function (type) { return _this._getEntryComponentMetadata(type); }))); |
| } |
| if (meta.bootstrap) { |
| flattenAndDedupeArray(meta.bootstrap).forEach(function (type) { |
| if (!isValidType(type)) { |
| _this._reportError(syntaxError("Unexpected value '" + stringifyType(type) + "' used in the bootstrap property of module '" + stringifyType(moduleType) + "'"), moduleType); |
| return; |
| } |
| bootstrapComponents.push(_this._getIdentifierMetadata(type)); |
| }); |
| } |
| entryComponents.push.apply(entryComponents, __spread(bootstrapComponents.map(function (type) { return _this._getEntryComponentMetadata(type.reference); }))); |
| if (meta.schemas) { |
| schemas.push.apply(schemas, __spread(flattenAndDedupeArray(meta.schemas))); |
| } |
| compileMeta = new CompileNgModuleMetadata({ |
| type: this._getTypeMetadata(moduleType), |
| providers: providers, |
| entryComponents: entryComponents, |
| bootstrapComponents: bootstrapComponents, |
| schemas: schemas, |
| declaredDirectives: declaredDirectives, |
| exportedDirectives: exportedDirectives, |
| declaredPipes: declaredPipes, |
| exportedPipes: exportedPipes, |
| importedModules: importedModules, |
| exportedModules: exportedModules, |
| transitiveModule: transitiveModule, |
| id: meta.id || null, |
| }); |
| entryComponents.forEach(function (id) { return transitiveModule.addEntryComponent(id); }); |
| providers.forEach(function (provider) { return transitiveModule.addProvider(provider, compileMeta.type); }); |
| transitiveModule.addModule(compileMeta.type); |
| this._ngModuleCache.set(moduleType, compileMeta); |
| return compileMeta; |
| }; |
| CompileMetadataResolver.prototype._checkSelfImport = function (moduleType, importedModuleType) { |
| if (moduleType === importedModuleType) { |
| this._reportError(syntaxError("'" + stringifyType(moduleType) + "' module can't import itself"), moduleType); |
| return true; |
| } |
| return false; |
| }; |
| CompileMetadataResolver.prototype._getTypeDescriptor = function (type) { |
| if (isValidType(type)) { |
| if (this.isDirective(type)) { |
| return 'directive'; |
| } |
| if (this.isPipe(type)) { |
| return 'pipe'; |
| } |
| if (this.isNgModule(type)) { |
| return 'module'; |
| } |
| } |
| if (type.provide) { |
| return 'provider'; |
| } |
| return 'value'; |
| }; |
| CompileMetadataResolver.prototype._addTypeToModule = function (type, moduleType) { |
| var oldModule = this._ngModuleOfTypes.get(type); |
| if (oldModule && oldModule !== moduleType) { |
| this._reportError(syntaxError("Type " + stringifyType(type) + " is part of the declarations of 2 modules: " + stringifyType(oldModule) + " and " + stringifyType(moduleType) + "! " + |
| ("Please consider moving " + stringifyType(type) + " to a higher module that imports " + stringifyType(oldModule) + " and " + stringifyType(moduleType) + ". ") + |
| ("You can also create a new NgModule that exports and includes " + stringifyType(type) + " then import that NgModule in " + stringifyType(oldModule) + " and " + stringifyType(moduleType) + ".")), moduleType); |
| return; |
| } |
| this._ngModuleOfTypes.set(type, moduleType); |
| }; |
| CompileMetadataResolver.prototype._getTransitiveNgModuleMetadata = function (importedModules, exportedModules) { |
| // collect `providers` / `entryComponents` from all imported and all exported modules |
| var result = new TransitiveCompileNgModuleMetadata(); |
| var modulesByToken = new Map(); |
| importedModules.concat(exportedModules).forEach(function (modSummary) { |
| modSummary.modules.forEach(function (mod) { return result.addModule(mod); }); |
| modSummary.entryComponents.forEach(function (comp) { return result.addEntryComponent(comp); }); |
| var addedTokens = new Set(); |
| modSummary.providers.forEach(function (entry) { |
| var tokenRef = tokenReference(entry.provider.token); |
| var prevModules = modulesByToken.get(tokenRef); |
| if (!prevModules) { |
| prevModules = new Set(); |
| modulesByToken.set(tokenRef, prevModules); |
| } |
| var moduleRef = entry.module.reference; |
| // Note: the providers of one module may still contain multiple providers |
| // per token (e.g. for multi providers), and we need to preserve these. |
| if (addedTokens.has(tokenRef) || !prevModules.has(moduleRef)) { |
| prevModules.add(moduleRef); |
| addedTokens.add(tokenRef); |
| result.addProvider(entry.provider, entry.module); |
| } |
| }); |
| }); |
| exportedModules.forEach(function (modSummary) { |
| modSummary.exportedDirectives.forEach(function (id) { return result.addExportedDirective(id); }); |
| modSummary.exportedPipes.forEach(function (id) { return result.addExportedPipe(id); }); |
| }); |
| importedModules.forEach(function (modSummary) { |
| modSummary.exportedDirectives.forEach(function (id) { return result.addDirective(id); }); |
| modSummary.exportedPipes.forEach(function (id) { return result.addPipe(id); }); |
| }); |
| return result; |
| }; |
| CompileMetadataResolver.prototype._getIdentifierMetadata = function (type) { |
| type = resolveForwardRef(type); |
| return { reference: type }; |
| }; |
| CompileMetadataResolver.prototype.isInjectable = function (type) { |
| var annotations = this._reflector.tryAnnotations(type); |
| return annotations.some(function (ann) { return createInjectable.isTypeOf(ann); }); |
| }; |
| CompileMetadataResolver.prototype.getInjectableSummary = function (type) { |
| return { |
| summaryKind: exports.CompileSummaryKind.Injectable, |
| type: this._getTypeMetadata(type, null, false) |
| }; |
| }; |
| CompileMetadataResolver.prototype.getInjectableMetadata = function (type, dependencies, throwOnUnknownDeps) { |
| if (dependencies === void 0) { dependencies = null; } |
| if (throwOnUnknownDeps === void 0) { throwOnUnknownDeps = true; } |
| var typeSummary = this._loadSummary(type, exports.CompileSummaryKind.Injectable); |
| var typeMetadata = typeSummary ? |
| typeSummary.type : |
| this._getTypeMetadata(type, dependencies, throwOnUnknownDeps); |
| var annotations = this._reflector.annotations(type).filter(function (ann) { return createInjectable.isTypeOf(ann); }); |
| if (annotations.length === 0) { |
| return null; |
| } |
| var meta = annotations[annotations.length - 1]; |
| return { |
| symbol: type, |
| type: typeMetadata, |
| providedIn: meta.providedIn, |
| useValue: meta.useValue, |
| useClass: meta.useClass, |
| useExisting: meta.useExisting, |
| useFactory: meta.useFactory, |
| deps: meta.deps, |
| }; |
| }; |
| CompileMetadataResolver.prototype._getTypeMetadata = function (type, dependencies, throwOnUnknownDeps) { |
| if (dependencies === void 0) { dependencies = null; } |
| if (throwOnUnknownDeps === void 0) { throwOnUnknownDeps = true; } |
| var identifier = this._getIdentifierMetadata(type); |
| return { |
| reference: identifier.reference, |
| diDeps: this._getDependenciesMetadata(identifier.reference, dependencies, throwOnUnknownDeps), |
| lifecycleHooks: getAllLifecycleHooks(this._reflector, identifier.reference), |
| }; |
| }; |
| CompileMetadataResolver.prototype._getFactoryMetadata = function (factory, dependencies) { |
| if (dependencies === void 0) { dependencies = null; } |
| factory = resolveForwardRef(factory); |
| return { reference: factory, diDeps: this._getDependenciesMetadata(factory, dependencies) }; |
| }; |
| /** |
| * Gets the metadata for the given pipe. |
| * This assumes `loadNgModuleDirectiveAndPipeMetadata` has been called first. |
| */ |
| CompileMetadataResolver.prototype.getPipeMetadata = function (pipeType) { |
| var pipeMeta = this._pipeCache.get(pipeType); |
| if (!pipeMeta) { |
| this._reportError(syntaxError("Illegal state: getPipeMetadata can only be called after loadNgModuleDirectiveAndPipeMetadata for a module that declares it. Pipe " + stringifyType(pipeType) + "."), pipeType); |
| } |
| return pipeMeta || null; |
| }; |
| CompileMetadataResolver.prototype.getPipeSummary = function (pipeType) { |
| var pipeSummary = this._loadSummary(pipeType, exports.CompileSummaryKind.Pipe); |
| if (!pipeSummary) { |
| this._reportError(syntaxError("Illegal state: Could not load the summary for pipe " + stringifyType(pipeType) + "."), pipeType); |
| } |
| return pipeSummary; |
| }; |
| CompileMetadataResolver.prototype.getOrLoadPipeMetadata = function (pipeType) { |
| var pipeMeta = this._pipeCache.get(pipeType); |
| if (!pipeMeta) { |
| pipeMeta = this._loadPipeMetadata(pipeType); |
| } |
| return pipeMeta; |
| }; |
| CompileMetadataResolver.prototype._loadPipeMetadata = function (pipeType) { |
| pipeType = resolveForwardRef(pipeType); |
| var pipeAnnotation = this._pipeResolver.resolve(pipeType); |
| var pipeMeta = new CompilePipeMetadata({ |
| type: this._getTypeMetadata(pipeType), |
| name: pipeAnnotation.name, |
| pure: !!pipeAnnotation.pure |
| }); |
| this._pipeCache.set(pipeType, pipeMeta); |
| this._summaryCache.set(pipeType, pipeMeta.toSummary()); |
| return pipeMeta; |
| }; |
| CompileMetadataResolver.prototype._getDependenciesMetadata = function (typeOrFunc, dependencies, throwOnUnknownDeps) { |
| var _this = this; |
| if (throwOnUnknownDeps === void 0) { throwOnUnknownDeps = true; } |
| var hasUnknownDeps = false; |
| var params = dependencies || this._reflector.parameters(typeOrFunc) || []; |
| var dependenciesMetadata = params.map(function (param) { |
| var isAttribute = false; |
| var isHost = false; |
| var isSelf = false; |
| var isSkipSelf = false; |
| var isOptional = false; |
| var token = null; |
| if (Array.isArray(param)) { |
| param.forEach(function (paramEntry) { |
| if (createHost.isTypeOf(paramEntry)) { |
| isHost = true; |
| } |
| else if (createSelf.isTypeOf(paramEntry)) { |
| isSelf = true; |
| } |
| else if (createSkipSelf.isTypeOf(paramEntry)) { |
| isSkipSelf = true; |
| } |
| else if (createOptional.isTypeOf(paramEntry)) { |
| isOptional = true; |
| } |
| else if (createAttribute.isTypeOf(paramEntry)) { |
| isAttribute = true; |
| token = paramEntry.attributeName; |
| } |
| else if (createInject.isTypeOf(paramEntry)) { |
| token = paramEntry.token; |
| } |
| else if (createInjectionToken.isTypeOf(paramEntry) || |
| paramEntry instanceof StaticSymbol) { |
| token = paramEntry; |
| } |
| else if (isValidType(paramEntry) && token == null) { |
| token = paramEntry; |
| } |
| }); |
| } |
| else { |
| token = param; |
| } |
| if (token == null) { |
| hasUnknownDeps = true; |
| return {}; |
| } |
| return { |
| isAttribute: isAttribute, |
| isHost: isHost, |
| isSelf: isSelf, |
| isSkipSelf: isSkipSelf, |
| isOptional: isOptional, |
| token: _this._getTokenMetadata(token) |
| }; |
| }); |
| if (hasUnknownDeps) { |
| var depsTokens = dependenciesMetadata.map(function (dep) { return dep.token ? stringifyType(dep.token) : '?'; }).join(', '); |
| var message = "Can't resolve all parameters for " + stringifyType(typeOrFunc) + ": (" + depsTokens + ")."; |
| if (throwOnUnknownDeps || this._config.strictInjectionParameters) { |
| this._reportError(syntaxError(message), typeOrFunc); |
| } |
| } |
| return dependenciesMetadata; |
| }; |
| CompileMetadataResolver.prototype._getTokenMetadata = function (token) { |
| token = resolveForwardRef(token); |
| var compileToken; |
| if (typeof token === 'string') { |
| compileToken = { value: token }; |
| } |
| else { |
| compileToken = { identifier: { reference: token } }; |
| } |
| return compileToken; |
| }; |
| CompileMetadataResolver.prototype._getProvidersMetadata = function (providers, targetEntryComponents, debugInfo, compileProviders, type) { |
| var _this = this; |
| if (compileProviders === void 0) { compileProviders = []; } |
| providers.forEach(function (provider, providerIdx) { |
| if (Array.isArray(provider)) { |
| _this._getProvidersMetadata(provider, targetEntryComponents, debugInfo, compileProviders); |
| } |
| else { |
| provider = resolveForwardRef(provider); |
| var providerMeta = undefined; |
| if (provider && typeof provider === 'object' && provider.hasOwnProperty('provide')) { |
| _this._validateProvider(provider); |
| providerMeta = new ProviderMeta(provider.provide, provider); |
| } |
| else if (isValidType(provider)) { |
| providerMeta = new ProviderMeta(provider, { useClass: provider }); |
| } |
| else if (provider === void 0) { |
| _this._reportError(syntaxError("Encountered undefined provider! Usually this means you have a circular dependencies. This might be caused by using 'barrel' index.ts files.")); |
| return; |
| } |
| else { |
| var providersInfo = providers |
| .reduce(function (soFar, seenProvider, seenProviderIdx) { |
| if (seenProviderIdx < providerIdx) { |
| soFar.push("" + stringifyType(seenProvider)); |
| } |
| else if (seenProviderIdx == providerIdx) { |
| soFar.push("?" + stringifyType(seenProvider) + "?"); |
| } |
| else if (seenProviderIdx == providerIdx + 1) { |
| soFar.push('...'); |
| } |
| return soFar; |
| }, []) |
| .join(', '); |
| _this._reportError(syntaxError("Invalid " + (debugInfo ? |
| debugInfo : |
| 'provider') + " - only instances of Provider and Type are allowed, got: [" + providersInfo + "]"), type); |
| return; |
| } |
| if (providerMeta.token === |
| _this._reflector.resolveExternalReference(Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS)) { |
| targetEntryComponents.push.apply(targetEntryComponents, __spread(_this._getEntryComponentsFromProvider(providerMeta, type))); |
| } |
| else { |
| compileProviders.push(_this.getProviderMetadata(providerMeta)); |
| } |
| } |
| }); |
| return compileProviders; |
| }; |
| CompileMetadataResolver.prototype._validateProvider = function (provider) { |
| if (provider.hasOwnProperty('useClass') && provider.useClass == null) { |
| this._reportError(syntaxError("Invalid provider for " + stringifyType(provider.provide) + ". useClass cannot be " + provider.useClass + ".\n Usually it happens when:\n 1. There's a circular dependency (might be caused by using index.ts (barrel) files).\n 2. Class was used before it was declared. Use forwardRef in this case.")); |
| } |
| }; |
| CompileMetadataResolver.prototype._getEntryComponentsFromProvider = function (provider, type) { |
| var _this = this; |
| var components = []; |
| var collectedIdentifiers = []; |
| if (provider.useFactory || provider.useExisting || provider.useClass) { |
| this._reportError(syntaxError("The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!"), type); |
| return []; |
| } |
| if (!provider.multi) { |
| this._reportError(syntaxError("The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!"), type); |
| return []; |
| } |
| extractIdentifiers(provider.useValue, collectedIdentifiers); |
| collectedIdentifiers.forEach(function (identifier) { |
| var entry = _this._getEntryComponentMetadata(identifier.reference, false); |
| if (entry) { |
| components.push(entry); |
| } |
| }); |
| return components; |
| }; |
| CompileMetadataResolver.prototype._getEntryComponentMetadata = function (dirType, throwIfNotFound) { |
| if (throwIfNotFound === void 0) { throwIfNotFound = true; } |
| var dirMeta = this.getNonNormalizedDirectiveMetadata(dirType); |
| if (dirMeta && dirMeta.metadata.isComponent) { |
| return { componentType: dirType, componentFactory: dirMeta.metadata.componentFactory }; |
| } |
| var dirSummary = this._loadSummary(dirType, exports.CompileSummaryKind.Directive); |
| if (dirSummary && dirSummary.isComponent) { |
| return { componentType: dirType, componentFactory: dirSummary.componentFactory }; |
| } |
| if (throwIfNotFound) { |
| throw syntaxError(dirType.name + " cannot be used as an entry component."); |
| } |
| return null; |
| }; |
| CompileMetadataResolver.prototype._getInjectableTypeMetadata = function (type, dependencies) { |
| if (dependencies === void 0) { dependencies = null; } |
| var typeSummary = this._loadSummary(type, exports.CompileSummaryKind.Injectable); |
| if (typeSummary) { |
| return typeSummary.type; |
| } |
| return this._getTypeMetadata(type, dependencies); |
| }; |
| CompileMetadataResolver.prototype.getProviderMetadata = function (provider) { |
| var compileDeps = undefined; |
| var compileTypeMetadata = null; |
| var compileFactoryMetadata = null; |
| var token = this._getTokenMetadata(provider.token); |
| if (provider.useClass) { |
| compileTypeMetadata = |
| this._getInjectableTypeMetadata(provider.useClass, provider.dependencies); |
| compileDeps = compileTypeMetadata.diDeps; |
| if (provider.token === provider.useClass) { |
| // use the compileTypeMetadata as it contains information about lifecycleHooks... |
| token = { identifier: compileTypeMetadata }; |
| } |
| } |
| else if (provider.useFactory) { |
| compileFactoryMetadata = this._getFactoryMetadata(provider.useFactory, provider.dependencies); |
| compileDeps = compileFactoryMetadata.diDeps; |
| } |
| return { |
| token: token, |
| useClass: compileTypeMetadata, |
| useValue: provider.useValue, |
| useFactory: compileFactoryMetadata, |
| useExisting: provider.useExisting ? this._getTokenMetadata(provider.useExisting) : undefined, |
| deps: compileDeps, |
| multi: provider.multi |
| }; |
| }; |
| CompileMetadataResolver.prototype._getQueriesMetadata = function (queries, isViewQuery, directiveType) { |
| var _this = this; |
| var res = []; |
| Object.keys(queries).forEach(function (propertyName) { |
| var query = queries[propertyName]; |
| if (query.isViewQuery === isViewQuery) { |
| res.push(_this._getQueryMetadata(query, propertyName, directiveType)); |
| } |
| }); |
| return res; |
| }; |
| CompileMetadataResolver.prototype._queryVarBindings = function (selector) { |
| return selector.split(/\s*,\s*/); |
| }; |
| CompileMetadataResolver.prototype._getQueryMetadata = function (q, propertyName, typeOrFunc) { |
| var _this = this; |
| var selectors; |
| if (typeof q.selector === 'string') { |
| selectors = |
| this._queryVarBindings(q.selector).map(function (varName) { return _this._getTokenMetadata(varName); }); |
| } |
| else { |
| if (!q.selector) { |
| this._reportError(syntaxError("Can't construct a query for the property \"" + propertyName + "\" of \"" + stringifyType(typeOrFunc) + "\" since the query selector wasn't defined."), typeOrFunc); |
| selectors = []; |
| } |
| else { |
| selectors = [this._getTokenMetadata(q.selector)]; |
| } |
| } |
| return { |
| selectors: selectors, |
| first: q.first, |
| descendants: q.descendants, |
| emitDistinctChangesOnly: q.emitDistinctChangesOnly, |
| propertyName: propertyName, |
| read: q.read ? this._getTokenMetadata(q.read) : null, |
| static: q.static |
| }; |
| }; |
| CompileMetadataResolver.prototype._reportError = function (error, type, otherType) { |
| if (this._errorCollector) { |
| this._errorCollector(error, type); |
| if (otherType) { |
| this._errorCollector(error, otherType); |
| } |
| } |
| else { |
| throw error; |
| } |
| }; |
| return CompileMetadataResolver; |
| }()); |
| function flattenArray(tree, out) { |
| if (out === void 0) { out = []; } |
| if (tree) { |
| for (var i = 0; i < tree.length; i++) { |
| var item = resolveForwardRef(tree[i]); |
| if (Array.isArray(item)) { |
| flattenArray(item, out); |
| } |
| else { |
| out.push(item); |
| } |
| } |
| } |
| return out; |
| } |
| function dedupeArray(array) { |
| if (array) { |
| return Array.from(new Set(array)); |
| } |
| return []; |
| } |
| function flattenAndDedupeArray(tree) { |
| return dedupeArray(flattenArray(tree)); |
| } |
| function isValidType(value) { |
| return (value instanceof StaticSymbol) || (value instanceof Type); |
| } |
| function extractIdentifiers(value, targetIdentifiers) { |
| visitValue(value, new _CompileValueConverter(), targetIdentifiers); |
| } |
| var _CompileValueConverter = /** @class */ (function (_super) { |
| __extends(_CompileValueConverter, _super); |
| function _CompileValueConverter() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| _CompileValueConverter.prototype.visitOther = function (value, targetIdentifiers) { |
| targetIdentifiers.push({ reference: value }); |
| }; |
| return _CompileValueConverter; |
| }(ValueTransformer)); |
| function stringifyType(type) { |
| if (type instanceof StaticSymbol) { |
| return type.name + " in " + type.filePath; |
| } |
| else { |
| return stringify(type); |
| } |
| } |
| /** |
| * Indicates that a component is still being loaded in a synchronous compile. |
| */ |
| function componentStillLoadingError(compType) { |
| var error = Error("Can't compile synchronously as " + stringify(compType) + " is still being loaded!"); |
| error[ERROR_COMPONENT_TYPE] = compType; |
| return error; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| function providerDef(ctx, providerAst) { |
| var flags = 0 /* None */; |
| if (!providerAst.eager) { |
| flags |= 4096 /* LazyProvider */; |
| } |
| if (providerAst.providerType === exports.ProviderAstType.PrivateService) { |
| flags |= 8192 /* PrivateProvider */; |
| } |
| if (providerAst.isModule) { |
| flags |= 1073741824 /* TypeModuleProvider */; |
| } |
| providerAst.lifecycleHooks.forEach(function (lifecycleHook) { |
| // for regular providers, we only support ngOnDestroy |
| if (lifecycleHook === LifecycleHooks.OnDestroy || |
| providerAst.providerType === exports.ProviderAstType.Directive || |
| providerAst.providerType === exports.ProviderAstType.Component) { |
| flags |= lifecycleHookToNodeFlag(lifecycleHook); |
| } |
| }); |
| var _a = providerAst.multiProvider ? |
| multiProviderDef(ctx, flags, providerAst.providers) : |
| singleProviderDef(ctx, flags, providerAst.providerType, providerAst.providers[0]), providerExpr = _a.providerExpr, providerFlags = _a.flags, depsExpr = _a.depsExpr; |
| return { |
| providerExpr: providerExpr, |
| flags: providerFlags, |
| depsExpr: depsExpr, |
| tokenExpr: tokenExpr(ctx, providerAst.token), |
| }; |
| } |
| function multiProviderDef(ctx, flags, providers) { |
| var allDepDefs = []; |
| var allParams = []; |
| var exprs = providers.map(function (provider, providerIndex) { |
| var expr; |
| if (provider.useClass) { |
| var depExprs = convertDeps(providerIndex, provider.deps || provider.useClass.diDeps); |
| expr = ctx.importExpr(provider.useClass.reference).instantiate(depExprs); |
| } |
| else if (provider.useFactory) { |
| var depExprs = convertDeps(providerIndex, provider.deps || provider.useFactory.diDeps); |
| expr = ctx.importExpr(provider.useFactory.reference).callFn(depExprs); |
| } |
| else if (provider.useExisting) { |
| var depExprs = convertDeps(providerIndex, [{ token: provider.useExisting }]); |
| expr = depExprs[0]; |
| } |
| else { |
| expr = convertValueToOutputAst(ctx, provider.useValue); |
| } |
| return expr; |
| }); |
| var providerExpr = fn(allParams, [new ReturnStatement(literalArr(exprs))], INFERRED_TYPE); |
| return { |
| providerExpr: providerExpr, |
| flags: flags | 1024 /* TypeFactoryProvider */, |
| depsExpr: literalArr(allDepDefs) |
| }; |
| function convertDeps(providerIndex, deps) { |
| return deps.map(function (dep, depIndex) { |
| var paramName = "p" + providerIndex + "_" + depIndex; |
| allParams.push(new FnParam(paramName, DYNAMIC_TYPE)); |
| allDepDefs.push(depDef(ctx, dep)); |
| return variable(paramName); |
| }); |
| } |
| } |
| function singleProviderDef(ctx, flags, providerType, providerMeta) { |
| var providerExpr; |
| var deps; |
| if (providerType === exports.ProviderAstType.Directive || providerType === exports.ProviderAstType.Component) { |
| providerExpr = ctx.importExpr(providerMeta.useClass.reference); |
| flags |= 16384 /* TypeDirective */; |
| deps = providerMeta.deps || providerMeta.useClass.diDeps; |
| } |
| else { |
| if (providerMeta.useClass) { |
| providerExpr = ctx.importExpr(providerMeta.useClass.reference); |
| flags |= 512 /* TypeClassProvider */; |
| deps = providerMeta.deps || providerMeta.useClass.diDeps; |
| } |
| else if (providerMeta.useFactory) { |
| providerExpr = ctx.importExpr(providerMeta.useFactory.reference); |
| flags |= 1024 /* TypeFactoryProvider */; |
| deps = providerMeta.deps || providerMeta.useFactory.diDeps; |
| } |
| else if (providerMeta.useExisting) { |
| providerExpr = NULL_EXPR; |
| flags |= 2048 /* TypeUseExistingProvider */; |
| deps = [{ token: providerMeta.useExisting }]; |
| } |
| else { |
| providerExpr = convertValueToOutputAst(ctx, providerMeta.useValue); |
| flags |= 256 /* TypeValueProvider */; |
| deps = []; |
| } |
| } |
| var depsExpr = literalArr(deps.map(function (dep) { return depDef(ctx, dep); })); |
| return { providerExpr: providerExpr, flags: flags, depsExpr: depsExpr }; |
| } |
| function tokenExpr(ctx, tokenMeta) { |
| return tokenMeta.identifier ? ctx.importExpr(tokenMeta.identifier.reference) : |
| literal(tokenMeta.value); |
| } |
| function depDef(ctx, dep) { |
| // Note: the following fields have already been normalized out by provider_analyzer: |
| // - isAttribute, isHost |
| var expr = dep.isValue ? convertValueToOutputAst(ctx, dep.value) : tokenExpr(ctx, dep.token); |
| var flags = 0 /* None */; |
| if (dep.isSkipSelf) { |
| flags |= 1 /* SkipSelf */; |
| } |
| if (dep.isOptional) { |
| flags |= 2 /* Optional */; |
| } |
| if (dep.isSelf) { |
| flags |= 4 /* Self */; |
| } |
| if (dep.isValue) { |
| flags |= 8 /* Value */; |
| } |
| return flags === 0 /* None */ ? expr : literalArr([literal(flags), expr]); |
| } |
| function lifecycleHookToNodeFlag(lifecycleHook) { |
| var nodeFlag = 0 /* None */; |
| switch (lifecycleHook) { |
| case LifecycleHooks.AfterContentChecked: |
| nodeFlag = 2097152 /* AfterContentChecked */; |
| break; |
| case LifecycleHooks.AfterContentInit: |
| nodeFlag = 1048576 /* AfterContentInit */; |
| break; |
| case LifecycleHooks.AfterViewChecked: |
| nodeFlag = 8388608 /* AfterViewChecked */; |
| break; |
| case LifecycleHooks.AfterViewInit: |
| nodeFlag = 4194304 /* AfterViewInit */; |
| break; |
| case LifecycleHooks.DoCheck: |
| nodeFlag = 262144 /* DoCheck */; |
| break; |
| case LifecycleHooks.OnChanges: |
| nodeFlag = 524288 /* OnChanges */; |
| break; |
| case LifecycleHooks.OnDestroy: |
| nodeFlag = 131072 /* OnDestroy */; |
| break; |
| case LifecycleHooks.OnInit: |
| nodeFlag = 65536 /* OnInit */; |
| break; |
| } |
| return nodeFlag; |
| } |
| function componentFactoryResolverProviderDef(reflector, ctx, flags, entryComponents) { |
| var entryComponentFactories = entryComponents.map(function (entryComponent) { return ctx.importExpr(entryComponent.componentFactory); }); |
| var token = createTokenForExternalReference(reflector, Identifiers.ComponentFactoryResolver); |
| var classMeta = { |
| diDeps: [ |
| { isValue: true, value: literalArr(entryComponentFactories) }, |
| { token: token, isSkipSelf: true, isOptional: true }, |
| { token: createTokenForExternalReference(reflector, Identifiers.NgModuleRef) }, |
| ], |
| lifecycleHooks: [], |
| reference: reflector.resolveExternalReference(Identifiers.CodegenComponentFactoryResolver) |
| }; |
| var _a = singleProviderDef(ctx, flags, exports.ProviderAstType.PrivateService, { |
| token: token, |
| multi: false, |
| useClass: classMeta, |
| }), providerExpr = _a.providerExpr, providerFlags = _a.flags, depsExpr = _a.depsExpr; |
| return { providerExpr: providerExpr, flags: providerFlags, depsExpr: depsExpr, tokenExpr: tokenExpr(ctx, token) }; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var NgModuleCompileResult = /** @class */ (function () { |
| function NgModuleCompileResult(ngModuleFactoryVar) { |
| this.ngModuleFactoryVar = ngModuleFactoryVar; |
| } |
| return NgModuleCompileResult; |
| }()); |
| var LOG_VAR = variable('_l'); |
| var NgModuleCompiler = /** @class */ (function () { |
| function NgModuleCompiler(reflector) { |
| this.reflector = reflector; |
| } |
| NgModuleCompiler.prototype.compile = function (ctx, ngModuleMeta, extraProviders) { |
| var sourceSpan = typeSourceSpan('NgModule', ngModuleMeta.type); |
| var entryComponentFactories = ngModuleMeta.transitiveModule.entryComponents; |
| var bootstrapComponents = ngModuleMeta.bootstrapComponents; |
| var providerParser = new NgModuleProviderAnalyzer(this.reflector, ngModuleMeta, extraProviders, sourceSpan); |
| var providerDefs = [componentFactoryResolverProviderDef(this.reflector, ctx, 0 /* None */, entryComponentFactories)] |
| .concat(providerParser.parse().map(function (provider) { return providerDef(ctx, provider); })) |
| .map(function (_a) { |
| var providerExpr = _a.providerExpr, depsExpr = _a.depsExpr, flags = _a.flags, tokenExpr = _a.tokenExpr; |
| return importExpr(Identifiers.moduleProviderDef).callFn([ |
| literal(flags), tokenExpr, providerExpr, depsExpr |
| ]); |
| }); |
| var ngModuleDef = importExpr(Identifiers.moduleDef).callFn([literalArr(providerDefs)]); |
| var ngModuleDefFactory = fn([new FnParam(LOG_VAR.name)], [new ReturnStatement(ngModuleDef)], INFERRED_TYPE); |
| var ngModuleFactoryVar = identifierName(ngModuleMeta.type) + "NgFactory"; |
| this._createNgModuleFactory(ctx, ngModuleMeta.type.reference, importExpr(Identifiers.createModuleFactory).callFn([ |
| ctx.importExpr(ngModuleMeta.type.reference), |
| literalArr(bootstrapComponents.map(function (id) { return ctx.importExpr(id.reference); })), |
| ngModuleDefFactory |
| ])); |
| if (ngModuleMeta.id) { |
| var id = typeof ngModuleMeta.id === 'string' ? literal(ngModuleMeta.id) : |
| ctx.importExpr(ngModuleMeta.id); |
| var registerFactoryStmt = importExpr(Identifiers.RegisterModuleFactoryFn) |
| .callFn([id, variable(ngModuleFactoryVar)]) |
| .toStmt(); |
| ctx.statements.push(registerFactoryStmt); |
| } |
| return new NgModuleCompileResult(ngModuleFactoryVar); |
| }; |
| NgModuleCompiler.prototype.createStub = function (ctx, ngModuleReference) { |
| this._createNgModuleFactory(ctx, ngModuleReference, NULL_EXPR); |
| }; |
| NgModuleCompiler.prototype._createNgModuleFactory = function (ctx, reference, value) { |
| var ngModuleFactoryVar = identifierName({ reference: reference }) + "NgFactory"; |
| var ngModuleFactoryStmt = variable(ngModuleFactoryVar) |
| .set(value) |
| .toDeclStmt(importType(Identifiers.NgModuleFactory, [expressionType(ctx.importExpr(reference))], [TypeModifier.Const]), [exports.StmtModifier.Final, exports.StmtModifier.Exported]); |
| ctx.statements.push(ngModuleFactoryStmt); |
| }; |
| return NgModuleCompiler; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Resolves types to {@link NgModule}. |
| */ |
| var NgModuleResolver = /** @class */ (function () { |
| function NgModuleResolver(_reflector) { |
| this._reflector = _reflector; |
| } |
| NgModuleResolver.prototype.isNgModule = function (type) { |
| return this._reflector.annotations(type).some(createNgModule.isTypeOf); |
| }; |
| NgModuleResolver.prototype.resolve = function (type, throwIfNotFound) { |
| if (throwIfNotFound === void 0) { throwIfNotFound = true; } |
| var ngModuleMeta = findLast(this._reflector.annotations(type), createNgModule.isTypeOf); |
| if (ngModuleMeta) { |
| return ngModuleMeta; |
| } |
| else { |
| if (throwIfNotFound) { |
| throw new Error("No NgModule metadata found for '" + stringify(type) + "'."); |
| } |
| return null; |
| } |
| }; |
| return NgModuleResolver; |
| }()); |
| |
| function debugOutputAstAsTypeScript(ast) { |
| var converter = new _TsEmitterVisitor(); |
| var ctx = EmitterVisitorContext.createRoot(); |
| var asts = Array.isArray(ast) ? ast : [ast]; |
| asts.forEach(function (ast) { |
| if (ast instanceof Statement) { |
| ast.visitStatement(converter, ctx); |
| } |
| else if (ast instanceof Expression) { |
| ast.visitExpression(converter, ctx); |
| } |
| else if (ast instanceof Type$1) { |
| ast.visitType(converter, ctx); |
| } |
| else { |
| throw new Error("Don't know how to print debug info for " + ast); |
| } |
| }); |
| return ctx.toSource(); |
| } |
| var TypeScriptEmitter = /** @class */ (function () { |
| function TypeScriptEmitter() { |
| } |
| TypeScriptEmitter.prototype.emitStatementsAndContext = function (genFilePath, stmts, preamble, emitSourceMaps, referenceFilter, importFilter) { |
| if (preamble === void 0) { preamble = ''; } |
| if (emitSourceMaps === void 0) { emitSourceMaps = true; } |
| var converter = new _TsEmitterVisitor(referenceFilter, importFilter); |
| var ctx = EmitterVisitorContext.createRoot(); |
| converter.visitAllStatements(stmts, ctx); |
| var preambleLines = preamble ? preamble.split('\n') : []; |
| converter.reexports.forEach(function (reexports, exportedModuleName) { |
| var reexportsCode = reexports.map(function (reexport) { return reexport.name + " as " + reexport.as; }).join(','); |
| preambleLines.push("export {" + reexportsCode + "} from '" + exportedModuleName + "';"); |
| }); |
| converter.importsWithPrefixes.forEach(function (prefix, importedModuleName) { |
| // Note: can't write the real word for import as it screws up system.js auto detection... |
| preambleLines.push("imp" + |
| ("ort * as " + prefix + " from '" + importedModuleName + "';")); |
| }); |
| var sm = emitSourceMaps ? |
| ctx.toSourceMapGenerator(genFilePath, preambleLines.length).toJsComment() : |
| ''; |
| var lines = __spread(preambleLines, [ctx.toSource(), sm]); |
| if (sm) { |
| // always add a newline at the end, as some tools have bugs without it. |
| lines.push(''); |
| } |
| ctx.setPreambleLineCount(preambleLines.length); |
| return { sourceText: lines.join('\n'), context: ctx }; |
| }; |
| TypeScriptEmitter.prototype.emitStatements = function (genFilePath, stmts, preamble) { |
| if (preamble === void 0) { preamble = ''; } |
| return this.emitStatementsAndContext(genFilePath, stmts, preamble).sourceText; |
| }; |
| return TypeScriptEmitter; |
| }()); |
| var _TsEmitterVisitor = /** @class */ (function (_super) { |
| __extends(_TsEmitterVisitor, _super); |
| function _TsEmitterVisitor(referenceFilter, importFilter) { |
| var _this = _super.call(this, false) || this; |
| _this.referenceFilter = referenceFilter; |
| _this.importFilter = importFilter; |
| _this.typeExpression = 0; |
| _this.importsWithPrefixes = new Map(); |
| _this.reexports = new Map(); |
| return _this; |
| } |
| _TsEmitterVisitor.prototype.visitType = function (t, ctx, defaultType) { |
| if (defaultType === void 0) { defaultType = 'any'; } |
| if (t) { |
| this.typeExpression++; |
| t.visitType(this, ctx); |
| this.typeExpression--; |
| } |
| else { |
| ctx.print(null, defaultType); |
| } |
| }; |
| _TsEmitterVisitor.prototype.visitLiteralExpr = function (ast, ctx) { |
| var value = ast.value; |
| if (value == null && ast.type != INFERRED_TYPE) { |
| ctx.print(ast, "(" + value + " as any)"); |
| return null; |
| } |
| return _super.prototype.visitLiteralExpr.call(this, ast, ctx); |
| }; |
| // Temporary workaround to support strictNullCheck enabled consumers of ngc emit. |
| // In SNC mode, [] have the type never[], so we cast here to any[]. |
| // TODO: narrow the cast to a more explicit type, or use a pattern that does not |
| // start with [].concat. see https://github.com/angular/angular/pull/11846 |
| _TsEmitterVisitor.prototype.visitLiteralArrayExpr = function (ast, ctx) { |
| if (ast.entries.length === 0) { |
| ctx.print(ast, '('); |
| } |
| var result = _super.prototype.visitLiteralArrayExpr.call(this, ast, ctx); |
| if (ast.entries.length === 0) { |
| ctx.print(ast, ' as any[])'); |
| } |
| return result; |
| }; |
| _TsEmitterVisitor.prototype.visitExternalExpr = function (ast, ctx) { |
| this._visitIdentifier(ast.value, ast.typeParams, ctx); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitAssertNotNullExpr = function (ast, ctx) { |
| var result = _super.prototype.visitAssertNotNullExpr.call(this, ast, ctx); |
| ctx.print(ast, '!'); |
| return result; |
| }; |
| _TsEmitterVisitor.prototype.visitDeclareVarStmt = function (stmt, ctx) { |
| if (stmt.hasModifier(exports.StmtModifier.Exported) && stmt.value instanceof ExternalExpr && |
| !stmt.type) { |
| // check for a reexport |
| var _a = stmt.value.value, name = _a.name, moduleName = _a.moduleName; |
| if (moduleName) { |
| var reexports = this.reexports.get(moduleName); |
| if (!reexports) { |
| reexports = []; |
| this.reexports.set(moduleName, reexports); |
| } |
| reexports.push({ name: name, as: stmt.name }); |
| return null; |
| } |
| } |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| ctx.print(stmt, "export "); |
| } |
| if (stmt.hasModifier(exports.StmtModifier.Final)) { |
| ctx.print(stmt, "const"); |
| } |
| else { |
| ctx.print(stmt, "var"); |
| } |
| ctx.print(stmt, " " + stmt.name); |
| this._printColonType(stmt.type, ctx); |
| if (stmt.value) { |
| ctx.print(stmt, " = "); |
| stmt.value.visitExpression(this, ctx); |
| } |
| ctx.println(stmt, ";"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitWrappedNodeExpr = function (ast, ctx) { |
| throw new Error('Cannot visit a WrappedNodeExpr when outputting Typescript.'); |
| }; |
| _TsEmitterVisitor.prototype.visitCastExpr = function (ast, ctx) { |
| ctx.print(ast, "(<"); |
| ast.type.visitType(this, ctx); |
| ctx.print(ast, ">"); |
| ast.value.visitExpression(this, ctx); |
| ctx.print(ast, ")"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitInstantiateExpr = function (ast, ctx) { |
| ctx.print(ast, "new "); |
| this.typeExpression++; |
| ast.classExpr.visitExpression(this, ctx); |
| this.typeExpression--; |
| ctx.print(ast, "("); |
| this.visitAllExpressions(ast.args, ctx, ','); |
| ctx.print(ast, ")"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitDeclareClassStmt = function (stmt, ctx) { |
| var _this = this; |
| ctx.pushClass(stmt); |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| ctx.print(stmt, "export "); |
| } |
| ctx.print(stmt, "class " + stmt.name); |
| if (stmt.parent != null) { |
| ctx.print(stmt, " extends "); |
| this.typeExpression++; |
| stmt.parent.visitExpression(this, ctx); |
| this.typeExpression--; |
| } |
| ctx.println(stmt, " {"); |
| ctx.incIndent(); |
| stmt.fields.forEach(function (field) { return _this._visitClassField(field, ctx); }); |
| if (stmt.constructorMethod != null) { |
| this._visitClassConstructor(stmt, ctx); |
| } |
| stmt.getters.forEach(function (getter) { return _this._visitClassGetter(getter, ctx); }); |
| stmt.methods.forEach(function (method) { return _this._visitClassMethod(method, ctx); }); |
| ctx.decIndent(); |
| ctx.println(stmt, "}"); |
| ctx.popClass(); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype._visitClassField = function (field, ctx) { |
| if (field.hasModifier(exports.StmtModifier.Private)) { |
| // comment out as a workaround for #10967 |
| ctx.print(null, "/*private*/ "); |
| } |
| if (field.hasModifier(exports.StmtModifier.Static)) { |
| ctx.print(null, 'static '); |
| } |
| ctx.print(null, field.name); |
| this._printColonType(field.type, ctx); |
| if (field.initializer) { |
| ctx.print(null, ' = '); |
| field.initializer.visitExpression(this, ctx); |
| } |
| ctx.println(null, ";"); |
| }; |
| _TsEmitterVisitor.prototype._visitClassGetter = function (getter, ctx) { |
| if (getter.hasModifier(exports.StmtModifier.Private)) { |
| ctx.print(null, "private "); |
| } |
| ctx.print(null, "get " + getter.name + "()"); |
| this._printColonType(getter.type, ctx); |
| ctx.println(null, " {"); |
| ctx.incIndent(); |
| this.visitAllStatements(getter.body, ctx); |
| ctx.decIndent(); |
| ctx.println(null, "}"); |
| }; |
| _TsEmitterVisitor.prototype._visitClassConstructor = function (stmt, ctx) { |
| ctx.print(stmt, "constructor("); |
| this._visitParams(stmt.constructorMethod.params, ctx); |
| ctx.println(stmt, ") {"); |
| ctx.incIndent(); |
| this.visitAllStatements(stmt.constructorMethod.body, ctx); |
| ctx.decIndent(); |
| ctx.println(stmt, "}"); |
| }; |
| _TsEmitterVisitor.prototype._visitClassMethod = function (method, ctx) { |
| if (method.hasModifier(exports.StmtModifier.Private)) { |
| ctx.print(null, "private "); |
| } |
| ctx.print(null, method.name + "("); |
| this._visitParams(method.params, ctx); |
| ctx.print(null, ")"); |
| this._printColonType(method.type, ctx, 'void'); |
| ctx.println(null, " {"); |
| ctx.incIndent(); |
| this.visitAllStatements(method.body, ctx); |
| ctx.decIndent(); |
| ctx.println(null, "}"); |
| }; |
| _TsEmitterVisitor.prototype.visitFunctionExpr = function (ast, ctx) { |
| if (ast.name) { |
| ctx.print(ast, 'function '); |
| ctx.print(ast, ast.name); |
| } |
| ctx.print(ast, "("); |
| this._visitParams(ast.params, ctx); |
| ctx.print(ast, ")"); |
| this._printColonType(ast.type, ctx, 'void'); |
| if (!ast.name) { |
| ctx.print(ast, " => "); |
| } |
| ctx.println(ast, '{'); |
| ctx.incIndent(); |
| this.visitAllStatements(ast.statements, ctx); |
| ctx.decIndent(); |
| ctx.print(ast, "}"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitDeclareFunctionStmt = function (stmt, ctx) { |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| ctx.print(stmt, "export "); |
| } |
| ctx.print(stmt, "function " + stmt.name + "("); |
| this._visitParams(stmt.params, ctx); |
| ctx.print(stmt, ")"); |
| this._printColonType(stmt.type, ctx, 'void'); |
| ctx.println(stmt, " {"); |
| ctx.incIndent(); |
| this.visitAllStatements(stmt.statements, ctx); |
| ctx.decIndent(); |
| ctx.println(stmt, "}"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitTryCatchStmt = function (stmt, ctx) { |
| ctx.println(stmt, "try {"); |
| ctx.incIndent(); |
| this.visitAllStatements(stmt.bodyStmts, ctx); |
| ctx.decIndent(); |
| ctx.println(stmt, "} catch (" + CATCH_ERROR_VAR$1.name + ") {"); |
| ctx.incIndent(); |
| var catchStmts = [CATCH_STACK_VAR$1.set(CATCH_ERROR_VAR$1.prop('stack', null)).toDeclStmt(null, [ |
| exports.StmtModifier.Final |
| ])].concat(stmt.catchStmts); |
| this.visitAllStatements(catchStmts, ctx); |
| ctx.decIndent(); |
| ctx.println(stmt, "}"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitBuiltinType = function (type, ctx) { |
| var typeStr; |
| switch (type.name) { |
| case exports.BuiltinTypeName.Bool: |
| typeStr = 'boolean'; |
| break; |
| case exports.BuiltinTypeName.Dynamic: |
| typeStr = 'any'; |
| break; |
| case exports.BuiltinTypeName.Function: |
| typeStr = 'Function'; |
| break; |
| case exports.BuiltinTypeName.Number: |
| typeStr = 'number'; |
| break; |
| case exports.BuiltinTypeName.Int: |
| typeStr = 'number'; |
| break; |
| case exports.BuiltinTypeName.String: |
| typeStr = 'string'; |
| break; |
| case exports.BuiltinTypeName.None: |
| typeStr = 'never'; |
| break; |
| default: |
| throw new Error("Unsupported builtin type " + type.name); |
| } |
| ctx.print(null, typeStr); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitExpressionType = function (ast, ctx) { |
| var _this = this; |
| ast.value.visitExpression(this, ctx); |
| if (ast.typeParams !== null) { |
| ctx.print(null, '<'); |
| this.visitAllObjects(function (type) { return _this.visitType(type, ctx); }, ast.typeParams, ctx, ','); |
| ctx.print(null, '>'); |
| } |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitArrayType = function (type, ctx) { |
| this.visitType(type.of, ctx); |
| ctx.print(null, "[]"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.visitMapType = function (type, ctx) { |
| ctx.print(null, "{[key: string]:"); |
| this.visitType(type.valueType, ctx); |
| ctx.print(null, "}"); |
| return null; |
| }; |
| _TsEmitterVisitor.prototype.getBuiltinMethodName = function (method) { |
| var name; |
| switch (method) { |
| case exports.BuiltinMethod.ConcatArray: |
| name = 'concat'; |
| break; |
| case exports.BuiltinMethod.SubscribeObservable: |
| name = 'subscribe'; |
| break; |
| case exports.BuiltinMethod.Bind: |
| name = 'bind'; |
| break; |
| default: |
| throw new Error("Unknown builtin method: " + method); |
| } |
| return name; |
| }; |
| _TsEmitterVisitor.prototype._visitParams = function (params, ctx) { |
| var _this = this; |
| this.visitAllObjects(function (param) { |
| ctx.print(null, param.name); |
| _this._printColonType(param.type, ctx); |
| }, params, ctx, ','); |
| }; |
| _TsEmitterVisitor.prototype._visitIdentifier = function (value, typeParams, ctx) { |
| var _this = this; |
| var name = value.name, moduleName = value.moduleName; |
| if (this.referenceFilter && this.referenceFilter(value)) { |
| ctx.print(null, '(null as any)'); |
| return; |
| } |
| if (moduleName && (!this.importFilter || !this.importFilter(value))) { |
| var prefix = this.importsWithPrefixes.get(moduleName); |
| if (prefix == null) { |
| prefix = "i" + this.importsWithPrefixes.size; |
| this.importsWithPrefixes.set(moduleName, prefix); |
| } |
| ctx.print(null, prefix + "."); |
| } |
| ctx.print(null, name); |
| if (this.typeExpression > 0) { |
| // If we are in a type expression that refers to a generic type then supply |
| // the required type parameters. If there were not enough type parameters |
| // supplied, supply any as the type. Outside a type expression the reference |
| // should not supply type parameters and be treated as a simple value reference |
| // to the constructor function itself. |
| var suppliedParameters = typeParams || []; |
| if (suppliedParameters.length > 0) { |
| ctx.print(null, "<"); |
| this.visitAllObjects(function (type) { return type.visitType(_this, ctx); }, typeParams, ctx, ','); |
| ctx.print(null, ">"); |
| } |
| } |
| }; |
| _TsEmitterVisitor.prototype._printColonType = function (type, ctx, defaultType) { |
| if (type !== INFERRED_TYPE) { |
| ctx.print(null, ':'); |
| this.visitType(type, ctx, defaultType); |
| } |
| }; |
| return _TsEmitterVisitor; |
| }(AbstractEmitterVisitor)); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Resolve a `Type` for {@link Pipe}. |
| * |
| * This interface can be overridden by the application developer to create custom behavior. |
| * |
| * See {@link Compiler} |
| */ |
| var PipeResolver = /** @class */ (function () { |
| function PipeResolver(_reflector) { |
| this._reflector = _reflector; |
| } |
| PipeResolver.prototype.isPipe = function (type) { |
| var typeMetadata = this._reflector.annotations(resolveForwardRef(type)); |
| return typeMetadata && typeMetadata.some(createPipe.isTypeOf); |
| }; |
| /** |
| * Return {@link Pipe} for a given `Type`. |
| */ |
| PipeResolver.prototype.resolve = function (type, throwIfNotFound) { |
| if (throwIfNotFound === void 0) { throwIfNotFound = true; } |
| var metas = this._reflector.annotations(resolveForwardRef(type)); |
| if (metas) { |
| var annotation = findLast(metas, createPipe.isTypeOf); |
| if (annotation) { |
| return annotation; |
| } |
| } |
| if (throwIfNotFound) { |
| throw new Error("No Pipe decorator found on " + stringify(type)); |
| } |
| return null; |
| }; |
| return PipeResolver; |
| }()); |
| |
| /** |
| * Generates code that is used to type check templates. |
| */ |
| var TypeCheckCompiler = /** @class */ (function () { |
| function TypeCheckCompiler(options, reflector) { |
| this.options = options; |
| this.reflector = reflector; |
| } |
| /** |
| * Important notes: |
| * - This must not produce new `import` statements, but only refer to types outside |
| * of the file via the variables provided via externalReferenceVars. |
| * This allows Typescript to reuse the old program's structure as no imports have changed. |
| * - This must not produce any exports, as this would pollute the .d.ts file |
| * and also violate the point above. |
| */ |
| TypeCheckCompiler.prototype.compileComponent = function (componentId, component, template, usedPipes, externalReferenceVars, ctx) { |
| var _this = this; |
| var pipes = new Map(); |
| usedPipes.forEach(function (p) { return pipes.set(p.name, p.type.reference); }); |
| var embeddedViewCount = 0; |
| var viewBuilderFactory = function (parent, guards) { |
| var embeddedViewIndex = embeddedViewCount++; |
| return new ViewBuilder(_this.options, _this.reflector, externalReferenceVars, parent, component.type.reference, component.isHost, embeddedViewIndex, pipes, guards, ctx, viewBuilderFactory); |
| }; |
| var visitor = viewBuilderFactory(null, []); |
| visitor.visitAll([], template); |
| return visitor.build(componentId); |
| }; |
| return TypeCheckCompiler; |
| }()); |
| var DYNAMIC_VAR_NAME = '_any'; |
| var TypeCheckLocalResolver = /** @class */ (function () { |
| function TypeCheckLocalResolver() { |
| } |
| TypeCheckLocalResolver.prototype.notifyImplicitReceiverUse = function () { }; |
| TypeCheckLocalResolver.prototype.getLocal = function (name) { |
| if (name === EventHandlerVars.event.name) { |
| // References to the event should not be type-checked. |
| // TODO(chuckj): determine a better type for the event. |
| return variable(DYNAMIC_VAR_NAME); |
| } |
| return null; |
| }; |
| return TypeCheckLocalResolver; |
| }()); |
| var defaultResolver = new TypeCheckLocalResolver(); |
| var ViewBuilder = /** @class */ (function () { |
| function ViewBuilder(options, reflector, externalReferenceVars, parent, component, isHostComponent, embeddedViewIndex, pipes, guards, ctx, viewBuilderFactory) { |
| this.options = options; |
| this.reflector = reflector; |
| this.externalReferenceVars = externalReferenceVars; |
| this.parent = parent; |
| this.component = component; |
| this.isHostComponent = isHostComponent; |
| this.embeddedViewIndex = embeddedViewIndex; |
| this.pipes = pipes; |
| this.guards = guards; |
| this.ctx = ctx; |
| this.viewBuilderFactory = viewBuilderFactory; |
| this.refOutputVars = new Map(); |
| this.variables = []; |
| this.children = []; |
| this.updates = []; |
| this.actions = []; |
| } |
| ViewBuilder.prototype.getOutputVar = function (type) { |
| var varName; |
| if (type === this.component && this.isHostComponent) { |
| varName = DYNAMIC_VAR_NAME; |
| } |
| else if (type instanceof StaticSymbol) { |
| varName = this.externalReferenceVars.get(type); |
| } |
| else { |
| varName = DYNAMIC_VAR_NAME; |
| } |
| if (!varName) { |
| throw new Error("Illegal State: referring to a type without a variable " + JSON.stringify(type)); |
| } |
| return varName; |
| }; |
| ViewBuilder.prototype.getTypeGuardExpressions = function (ast) { |
| var e_1, _a, e_2, _b; |
| var result = __spread(this.guards); |
| try { |
| for (var _c = __values(ast.directives), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var directive = _d.value; |
| try { |
| for (var _e = (e_2 = void 0, __values(directive.inputs)), _f = _e.next(); !_f.done; _f = _e.next()) { |
| var input = _f.value; |
| var guard = directive.directive.guards[input.directiveName]; |
| if (guard) { |
| var useIf = guard === 'UseIf'; |
| result.push({ |
| guard: guard, |
| useIf: useIf, |
| expression: { |
| context: this.component, |
| value: input.value, |
| sourceSpan: input.sourceSpan, |
| }, |
| }); |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_f && !_f.done && (_b = _e.return)) _b.call(_e); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_a = _c.return)) _a.call(_c); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return result; |
| }; |
| ViewBuilder.prototype.visitAll = function (variables, astNodes) { |
| this.variables = variables; |
| templateVisitAll(this, astNodes); |
| }; |
| ViewBuilder.prototype.build = function (componentId, targetStatements) { |
| var e_3, _a; |
| var _this = this; |
| if (targetStatements === void 0) { targetStatements = []; } |
| this.children.forEach(function (child) { return child.build(componentId, targetStatements); }); |
| var viewStmts = [variable(DYNAMIC_VAR_NAME).set(NULL_EXPR).toDeclStmt(DYNAMIC_TYPE)]; |
| var bindingCount = 0; |
| this.updates.forEach(function (expression) { |
| var _a = _this.preprocessUpdateExpression(expression), sourceSpan = _a.sourceSpan, context = _a.context, value = _a.value; |
| var bindingId = "" + bindingCount++; |
| var nameResolver = context === _this.component ? _this : defaultResolver; |
| var _b = convertPropertyBinding(nameResolver, variable(_this.getOutputVar(context)), value, bindingId, BindingForm.General), stmts = _b.stmts, currValExpr = _b.currValExpr; |
| stmts.push(new ExpressionStatement(currValExpr)); |
| viewStmts.push.apply(viewStmts, __spread(stmts.map(function (stmt) { return applySourceSpanToStatementIfNeeded(stmt, sourceSpan); }))); |
| }); |
| this.actions.forEach(function (_a) { |
| var sourceSpan = _a.sourceSpan, context = _a.context, value = _a.value; |
| var bindingId = "" + bindingCount++; |
| var nameResolver = context === _this.component ? _this : defaultResolver; |
| var stmts = convertActionBinding(nameResolver, variable(_this.getOutputVar(context)), value, bindingId).stmts; |
| viewStmts.push.apply(viewStmts, __spread(stmts.map(function (stmt) { return applySourceSpanToStatementIfNeeded(stmt, sourceSpan); }))); |
| }); |
| if (this.guards.length) { |
| var guardExpression = undefined; |
| try { |
| for (var _b = __values(this.guards), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var guard = _c.value; |
| var _d = this.preprocessUpdateExpression(guard.expression), context = _d.context, value = _d.value; |
| var bindingId = "" + bindingCount++; |
| var nameResolver = context === this.component ? this : defaultResolver; |
| // We only support support simple expressions and ignore others as they |
| // are unlikely to affect type narrowing. |
| var _e = convertPropertyBinding(nameResolver, variable(this.getOutputVar(context)), value, bindingId, BindingForm.TrySimple), stmts = _e.stmts, currValExpr = _e.currValExpr; |
| if (stmts.length == 0) { |
| var guardClause = guard.useIf ? currValExpr : this.ctx.importExpr(guard.guard).callFn([currValExpr]); |
| guardExpression = guardExpression ? guardExpression.and(guardClause) : guardClause; |
| } |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (_c && !_c.done && (_a = _b.return)) _a.call(_b); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| if (guardExpression) { |
| viewStmts = [new IfStmt(guardExpression, viewStmts)]; |
| } |
| } |
| var viewName = "_View_" + componentId + "_" + this.embeddedViewIndex; |
| var viewFactory = new DeclareFunctionStmt(viewName, [], viewStmts); |
| targetStatements.push(viewFactory); |
| return targetStatements; |
| }; |
| ViewBuilder.prototype.visitBoundText = function (ast, context) { |
| var _this = this; |
| var astWithSource = ast.value; |
| var inter = astWithSource.ast; |
| inter.expressions.forEach(function (expr) { return _this.updates.push({ context: _this.component, value: expr, sourceSpan: ast.sourceSpan }); }); |
| }; |
| ViewBuilder.prototype.visitEmbeddedTemplate = function (ast, context) { |
| this.visitElementOrTemplate(ast); |
| // Note: The old view compiler used to use an `any` type |
| // for the context in any embedded view. |
| // We keep this behaivor behind a flag for now. |
| if (this.options.fullTemplateTypeCheck) { |
| // Find any applicable type guards. For example, NgIf has a type guard on ngIf |
| // (see NgIf.ngIfTypeGuard) that can be used to indicate that a template is only |
| // stamped out if ngIf is truthy so any bindings in the template can assume that, |
| // if a nullable type is used for ngIf, that expression is not null or undefined. |
| var guards = this.getTypeGuardExpressions(ast); |
| var childVisitor = this.viewBuilderFactory(this, guards); |
| this.children.push(childVisitor); |
| childVisitor.visitAll(ast.variables, ast.children); |
| } |
| }; |
| ViewBuilder.prototype.visitElement = function (ast, context) { |
| var _this = this; |
| this.visitElementOrTemplate(ast); |
| var inputDefs = []; |
| var updateRendererExpressions = []; |
| var outputDefs = []; |
| ast.inputs.forEach(function (inputAst) { |
| _this.updates.push({ context: _this.component, value: inputAst.value, sourceSpan: inputAst.sourceSpan }); |
| }); |
| templateVisitAll(this, ast.children); |
| }; |
| ViewBuilder.prototype.visitElementOrTemplate = function (ast) { |
| var _this = this; |
| ast.directives.forEach(function (dirAst) { |
| _this.visitDirective(dirAst); |
| }); |
| ast.references.forEach(function (ref) { |
| var outputVarType = null; |
| // Note: The old view compiler used to use an `any` type |
| // for directives exposed via `exportAs`. |
| // We keep this behaivor behind a flag for now. |
| if (ref.value && ref.value.identifier && _this.options.fullTemplateTypeCheck) { |
| outputVarType = ref.value.identifier.reference; |
| } |
| else { |
| outputVarType = exports.BuiltinTypeName.Dynamic; |
| } |
| _this.refOutputVars.set(ref.name, outputVarType); |
| }); |
| ast.outputs.forEach(function (outputAst) { |
| _this.actions.push({ context: _this.component, value: outputAst.handler, sourceSpan: outputAst.sourceSpan }); |
| }); |
| }; |
| ViewBuilder.prototype.visitDirective = function (dirAst) { |
| var _this = this; |
| var dirType = dirAst.directive.type.reference; |
| dirAst.inputs.forEach(function (input) { return _this.updates.push({ context: _this.component, value: input.value, sourceSpan: input.sourceSpan }); }); |
| // Note: The old view compiler used to use an `any` type |
| // for expressions in host properties / events. |
| // We keep this behaivor behind a flag for now. |
| if (this.options.fullTemplateTypeCheck) { |
| dirAst.hostProperties.forEach(function (inputAst) { return _this.updates.push({ context: dirType, value: inputAst.value, sourceSpan: inputAst.sourceSpan }); }); |
| dirAst.hostEvents.forEach(function (hostEventAst) { return _this.actions.push({ |
| context: dirType, |
| value: hostEventAst.handler, |
| sourceSpan: hostEventAst.sourceSpan |
| }); }); |
| } |
| }; |
| ViewBuilder.prototype.notifyImplicitReceiverUse = function () { }; |
| ViewBuilder.prototype.getLocal = function (name) { |
| if (name == EventHandlerVars.event.name) { |
| return variable(this.getOutputVar(exports.BuiltinTypeName.Dynamic)); |
| } |
| for (var currBuilder = this; currBuilder; currBuilder = currBuilder.parent) { |
| var outputVarType = void 0; |
| // check references |
| outputVarType = currBuilder.refOutputVars.get(name); |
| if (outputVarType == null) { |
| // check variables |
| var varAst = currBuilder.variables.find(function (varAst) { return varAst.name === name; }); |
| if (varAst) { |
| outputVarType = exports.BuiltinTypeName.Dynamic; |
| } |
| } |
| if (outputVarType != null) { |
| return variable(this.getOutputVar(outputVarType)); |
| } |
| } |
| return null; |
| }; |
| ViewBuilder.prototype.pipeOutputVar = function (name) { |
| var pipe = this.pipes.get(name); |
| if (!pipe) { |
| throw new Error("Illegal State: Could not find pipe " + name + " in template of " + this.component); |
| } |
| return this.getOutputVar(pipe); |
| }; |
| ViewBuilder.prototype.preprocessUpdateExpression = function (expression) { |
| var _this = this; |
| return { |
| sourceSpan: expression.sourceSpan, |
| context: expression.context, |
| value: convertPropertyBindingBuiltins({ |
| createLiteralArrayConverter: function (argCount) { return function (args) { |
| var arr = literalArr(args); |
| // Note: The old view compiler used to use an `any` type |
| // for arrays. |
| return _this.options.fullTemplateTypeCheck ? arr : arr.cast(DYNAMIC_TYPE); |
| }; }, |
| createLiteralMapConverter: function (keys) { return function (values) { |
| var entries = keys.map(function (k, i) { return ({ |
| key: k.key, |
| value: values[i], |
| quoted: k.quoted, |
| }); }); |
| var map = literalMap(entries); |
| // Note: The old view compiler used to use an `any` type |
| // for maps. |
| return _this.options.fullTemplateTypeCheck ? map : map.cast(DYNAMIC_TYPE); |
| }; }, |
| createPipeConverter: function (name, argCount) { return function (args) { |
| // Note: The old view compiler used to use an `any` type |
| // for pipes. |
| var pipeExpr = _this.options.fullTemplateTypeCheck ? |
| variable(_this.pipeOutputVar(name)) : |
| variable(_this.getOutputVar(exports.BuiltinTypeName.Dynamic)); |
| return pipeExpr.callMethod('transform', args); |
| }; }, |
| }, expression.value) |
| }; |
| }; |
| ViewBuilder.prototype.visitNgContent = function (ast, context) { }; |
| ViewBuilder.prototype.visitText = function (ast, context) { }; |
| ViewBuilder.prototype.visitDirectiveProperty = function (ast, context) { }; |
| ViewBuilder.prototype.visitReference = function (ast, context) { }; |
| ViewBuilder.prototype.visitVariable = function (ast, context) { }; |
| ViewBuilder.prototype.visitEvent = function (ast, context) { }; |
| ViewBuilder.prototype.visitElementProperty = function (ast, context) { }; |
| ViewBuilder.prototype.visitAttr = function (ast, context) { }; |
| return ViewBuilder; |
| }()); |
| |
| var CLASS_ATTR$1 = 'class'; |
| var STYLE_ATTR = 'style'; |
| var IMPLICIT_TEMPLATE_VAR = '\$implicit'; |
| var ViewCompileResult = /** @class */ (function () { |
| function ViewCompileResult(viewClassVar, rendererTypeVar) { |
| this.viewClassVar = viewClassVar; |
| this.rendererTypeVar = rendererTypeVar; |
| } |
| return ViewCompileResult; |
| }()); |
| var ViewCompiler = /** @class */ (function () { |
| function ViewCompiler(_reflector) { |
| this._reflector = _reflector; |
| } |
| ViewCompiler.prototype.compileComponent = function (outputCtx, component, template, styles, usedPipes) { |
| var _a; |
| var _this = this; |
| var embeddedViewCount = 0; |
| var renderComponentVarName = undefined; |
| if (!component.isHost) { |
| var template_1 = component.template; |
| var customRenderData = []; |
| if (template_1.animations && template_1.animations.length) { |
| customRenderData.push(new LiteralMapEntry('animation', convertValueToOutputAst(outputCtx, template_1.animations), true)); |
| } |
| var renderComponentVar = variable(rendererTypeName(component.type.reference)); |
| renderComponentVarName = renderComponentVar.name; |
| outputCtx.statements.push(renderComponentVar |
| .set(importExpr(Identifiers.createRendererType2).callFn([new LiteralMapExpr([ |
| new LiteralMapEntry('encapsulation', literal(template_1.encapsulation), false), |
| new LiteralMapEntry('styles', styles, false), |
| new LiteralMapEntry('data', new LiteralMapExpr(customRenderData), false) |
| ])])) |
| .toDeclStmt(importType(Identifiers.RendererType2), [exports.StmtModifier.Final, exports.StmtModifier.Exported])); |
| } |
| var viewBuilderFactory = function (parent) { |
| var embeddedViewIndex = embeddedViewCount++; |
| return new ViewBuilder$1(_this._reflector, outputCtx, parent, component, embeddedViewIndex, usedPipes, viewBuilderFactory); |
| }; |
| var visitor = viewBuilderFactory(null); |
| visitor.visitAll([], template); |
| (_a = outputCtx.statements).push.apply(_a, __spread(visitor.build())); |
| return new ViewCompileResult(visitor.viewName, renderComponentVarName); |
| }; |
| return ViewCompiler; |
| }()); |
| var LOG_VAR$1 = variable('_l'); |
| var VIEW_VAR = variable('_v'); |
| var CHECK_VAR = variable('_ck'); |
| var COMP_VAR = variable('_co'); |
| var EVENT_NAME_VAR = variable('en'); |
| var ALLOW_DEFAULT_VAR = variable("ad"); |
| var ViewBuilder$1 = /** @class */ (function () { |
| function ViewBuilder(reflector, outputCtx, parent, component, embeddedViewIndex, usedPipes, viewBuilderFactory) { |
| this.reflector = reflector; |
| this.outputCtx = outputCtx; |
| this.parent = parent; |
| this.component = component; |
| this.embeddedViewIndex = embeddedViewIndex; |
| this.usedPipes = usedPipes; |
| this.viewBuilderFactory = viewBuilderFactory; |
| this.nodes = []; |
| this.purePipeNodeIndices = Object.create(null); |
| // Need Object.create so that we don't have builtin values... |
| this.refNodeIndices = Object.create(null); |
| this.variables = []; |
| this.children = []; |
| // TODO(tbosch): The old view compiler used to use an `any` type |
| // for the context in any embedded view. We keep this behaivor for now |
| // to be able to introduce the new view compiler without too many errors. |
| this.compType = this.embeddedViewIndex > 0 ? |
| DYNAMIC_TYPE : |
| expressionType(outputCtx.importExpr(this.component.type.reference)); |
| this.viewName = viewClassName(this.component.type.reference, this.embeddedViewIndex); |
| } |
| ViewBuilder.prototype.visitAll = function (variables, astNodes) { |
| var _this = this; |
| this.variables = variables; |
| // create the pipes for the pure pipes immediately, so that we know their indices. |
| if (!this.parent) { |
| this.usedPipes.forEach(function (pipe) { |
| if (pipe.pure) { |
| _this.purePipeNodeIndices[pipe.name] = _this._createPipe(null, pipe); |
| } |
| }); |
| } |
| if (!this.parent) { |
| this.component.viewQueries.forEach(function (query, queryIndex) { |
| // Note: queries start with id 1 so we can use the number in a Bloom filter! |
| var queryId = queryIndex + 1; |
| var bindingType = query.first ? 0 /* First */ : 1 /* All */; |
| var flags = 134217728 /* TypeViewQuery */ | calcQueryFlags(query); |
| _this.nodes.push(function () { return ({ |
| sourceSpan: null, |
| nodeFlags: flags, |
| nodeDef: importExpr(Identifiers.queryDef).callFn([ |
| literal(flags), literal(queryId), |
| new LiteralMapExpr([new LiteralMapEntry(query.propertyName, literal(bindingType), false)]) |
| ]) |
| }); }); |
| }); |
| } |
| templateVisitAll(this, astNodes); |
| if (this.parent && (astNodes.length === 0 || needsAdditionalRootNode(astNodes))) { |
| // if the view is an embedded view, then we need to add an additional root node in some cases |
| this.nodes.push(function () { return ({ |
| sourceSpan: null, |
| nodeFlags: 1 /* TypeElement */, |
| nodeDef: importExpr(Identifiers.anchorDef).callFn([ |
| literal(0 /* None */), NULL_EXPR, NULL_EXPR, literal(0) |
| ]) |
| }); }); |
| } |
| }; |
| ViewBuilder.prototype.build = function (targetStatements) { |
| if (targetStatements === void 0) { targetStatements = []; } |
| this.children.forEach(function (child) { return child.build(targetStatements); }); |
| var _a = this._createNodeExpressions(), updateRendererStmts = _a.updateRendererStmts, updateDirectivesStmts = _a.updateDirectivesStmts, nodeDefExprs = _a.nodeDefExprs; |
| var updateRendererFn = this._createUpdateFn(updateRendererStmts); |
| var updateDirectivesFn = this._createUpdateFn(updateDirectivesStmts); |
| var viewFlags = 0 /* None */; |
| if (!this.parent && this.component.changeDetection === ChangeDetectionStrategy.OnPush) { |
| viewFlags |= 2 /* OnPush */; |
| } |
| var viewFactory = new DeclareFunctionStmt(this.viewName, [new FnParam(LOG_VAR$1.name)], [new ReturnStatement(importExpr(Identifiers.viewDef).callFn([ |
| literal(viewFlags), |
| literalArr(nodeDefExprs), |
| updateDirectivesFn, |
| updateRendererFn, |
| ]))], importType(Identifiers.ViewDefinition), this.embeddedViewIndex === 0 ? [exports.StmtModifier.Exported] : []); |
| targetStatements.push(viewFactory); |
| return targetStatements; |
| }; |
| ViewBuilder.prototype._createUpdateFn = function (updateStmts) { |
| var updateFn; |
| if (updateStmts.length > 0) { |
| var preStmts = []; |
| if (!this.component.isHost && findReadVarNames(updateStmts).has(COMP_VAR.name)) { |
| preStmts.push(COMP_VAR.set(VIEW_VAR.prop('component')).toDeclStmt(this.compType)); |
| } |
| updateFn = fn([ |
| new FnParam(CHECK_VAR.name, INFERRED_TYPE), |
| new FnParam(VIEW_VAR.name, INFERRED_TYPE) |
| ], __spread(preStmts, updateStmts), INFERRED_TYPE); |
| } |
| else { |
| updateFn = NULL_EXPR; |
| } |
| return updateFn; |
| }; |
| ViewBuilder.prototype.visitNgContent = function (ast, context) { |
| // ngContentDef(ngContentIndex: number, index: number): NodeDef; |
| this.nodes.push(function () { return ({ |
| sourceSpan: ast.sourceSpan, |
| nodeFlags: 8 /* TypeNgContent */, |
| nodeDef: importExpr(Identifiers.ngContentDef) |
| .callFn([literal(ast.ngContentIndex), literal(ast.index)]) |
| }); }); |
| }; |
| ViewBuilder.prototype.visitText = function (ast, context) { |
| // Static text nodes have no check function |
| var checkIndex = -1; |
| this.nodes.push(function () { return ({ |
| sourceSpan: ast.sourceSpan, |
| nodeFlags: 2 /* TypeText */, |
| nodeDef: importExpr(Identifiers.textDef).callFn([ |
| literal(checkIndex), |
| literal(ast.ngContentIndex), |
| literalArr([literal(ast.value)]), |
| ]) |
| }); }); |
| }; |
| ViewBuilder.prototype.visitBoundText = function (ast, context) { |
| var _this = this; |
| var nodeIndex = this.nodes.length; |
| // reserve the space in the nodeDefs array |
| this.nodes.push(null); |
| var astWithSource = ast.value; |
| var inter = astWithSource.ast; |
| var updateRendererExpressions = inter.expressions.map(function (expr, bindingIndex) { return _this._preprocessUpdateExpression({ nodeIndex: nodeIndex, bindingIndex: bindingIndex, sourceSpan: ast.sourceSpan, context: COMP_VAR, value: expr }); }); |
| // Check index is the same as the node index during compilation |
| // They might only differ at runtime |
| var checkIndex = nodeIndex; |
| this.nodes[nodeIndex] = function () { return ({ |
| sourceSpan: ast.sourceSpan, |
| nodeFlags: 2 /* TypeText */, |
| nodeDef: importExpr(Identifiers.textDef).callFn([ |
| literal(checkIndex), |
| literal(ast.ngContentIndex), |
| literalArr(inter.strings.map(function (s) { return literal(s); })), |
| ]), |
| updateRenderer: updateRendererExpressions |
| }); }; |
| }; |
| ViewBuilder.prototype.visitEmbeddedTemplate = function (ast, context) { |
| var _this = this; |
| var nodeIndex = this.nodes.length; |
| // reserve the space in the nodeDefs array |
| this.nodes.push(null); |
| var _a = this._visitElementOrTemplate(nodeIndex, ast), flags = _a.flags, queryMatchesExpr = _a.queryMatchesExpr, hostEvents = _a.hostEvents; |
| var childVisitor = this.viewBuilderFactory(this); |
| this.children.push(childVisitor); |
| childVisitor.visitAll(ast.variables, ast.children); |
| var childCount = this.nodes.length - nodeIndex - 1; |
| // anchorDef( |
| // flags: NodeFlags, matchedQueries: [string, QueryValueType][], ngContentIndex: number, |
| // childCount: number, handleEventFn?: ElementHandleEventFn, templateFactory?: |
| // ViewDefinitionFactory): NodeDef; |
| this.nodes[nodeIndex] = function () { return ({ |
| sourceSpan: ast.sourceSpan, |
| nodeFlags: 1 /* TypeElement */ | flags, |
| nodeDef: importExpr(Identifiers.anchorDef).callFn([ |
| literal(flags), |
| queryMatchesExpr, |
| literal(ast.ngContentIndex), |
| literal(childCount), |
| _this._createElementHandleEventFn(nodeIndex, hostEvents), |
| variable(childVisitor.viewName), |
| ]) |
| }); }; |
| }; |
| ViewBuilder.prototype.visitElement = function (ast, context) { |
| var _this = this; |
| var nodeIndex = this.nodes.length; |
| // reserve the space in the nodeDefs array so we can add children |
| this.nodes.push(null); |
| // Using a null element name creates an anchor. |
| var elName = isNgContainer(ast.name) ? null : ast.name; |
| var _a = this._visitElementOrTemplate(nodeIndex, ast), flags = _a.flags, usedEvents = _a.usedEvents, queryMatchesExpr = _a.queryMatchesExpr, dirHostBindings = _a.hostBindings, hostEvents = _a.hostEvents; |
| var inputDefs = []; |
| var updateRendererExpressions = []; |
| var outputDefs = []; |
| if (elName) { |
| var hostBindings = ast.inputs |
| .map(function (inputAst) { return ({ |
| context: COMP_VAR, |
| inputAst: inputAst, |
| dirAst: null, |
| }); }) |
| .concat(dirHostBindings); |
| if (hostBindings.length) { |
| updateRendererExpressions = |
| hostBindings.map(function (hostBinding, bindingIndex) { return _this._preprocessUpdateExpression({ |
| context: hostBinding.context, |
| nodeIndex: nodeIndex, |
| bindingIndex: bindingIndex, |
| sourceSpan: hostBinding.inputAst.sourceSpan, |
| value: hostBinding.inputAst.value |
| }); }); |
| inputDefs = hostBindings.map(function (hostBinding) { return elementBindingDef(hostBinding.inputAst, hostBinding.dirAst); }); |
| } |
| outputDefs = usedEvents.map(function (_a) { |
| var _b = __read(_a, 2), target = _b[0], eventName = _b[1]; |
| return literalArr([literal(target), literal(eventName)]); |
| }); |
| } |
| templateVisitAll(this, ast.children); |
| var childCount = this.nodes.length - nodeIndex - 1; |
| var compAst = ast.directives.find(function (dirAst) { return dirAst.directive.isComponent; }); |
| var compRendererType = NULL_EXPR; |
| var compView = NULL_EXPR; |
| if (compAst) { |
| compView = this.outputCtx.importExpr(compAst.directive.componentViewType); |
| compRendererType = this.outputCtx.importExpr(compAst.directive.rendererType); |
| } |
| // Check index is the same as the node index during compilation |
| // They might only differ at runtime |
| var checkIndex = nodeIndex; |
| this.nodes[nodeIndex] = function () { return ({ |
| sourceSpan: ast.sourceSpan, |
| nodeFlags: 1 /* TypeElement */ | flags, |
| nodeDef: importExpr(Identifiers.elementDef).callFn([ |
| literal(checkIndex), |
| literal(flags), |
| queryMatchesExpr, |
| literal(ast.ngContentIndex), |
| literal(childCount), |
| literal(elName), |
| elName ? fixedAttrsDef(ast) : NULL_EXPR, |
| inputDefs.length ? literalArr(inputDefs) : NULL_EXPR, |
| outputDefs.length ? literalArr(outputDefs) : NULL_EXPR, |
| _this._createElementHandleEventFn(nodeIndex, hostEvents), |
| compView, |
| compRendererType, |
| ]), |
| updateRenderer: updateRendererExpressions |
| }); }; |
| }; |
| ViewBuilder.prototype._visitElementOrTemplate = function (nodeIndex, ast) { |
| var _this = this; |
| var flags = 0 /* None */; |
| if (ast.hasViewContainer) { |
| flags |= 16777216 /* EmbeddedViews */; |
| } |
| var usedEvents = new Map(); |
| ast.outputs.forEach(function (event) { |
| var _a = elementEventNameAndTarget(event, null), name = _a.name, target = _a.target; |
| usedEvents.set(elementEventFullName(target, name), [target, name]); |
| }); |
| ast.directives.forEach(function (dirAst) { |
| dirAst.hostEvents.forEach(function (event) { |
| var _a = elementEventNameAndTarget(event, dirAst), name = _a.name, target = _a.target; |
| usedEvents.set(elementEventFullName(target, name), [target, name]); |
| }); |
| }); |
| var hostBindings = []; |
| var hostEvents = []; |
| this._visitComponentFactoryResolverProvider(ast.directives); |
| ast.providers.forEach(function (providerAst) { |
| var dirAst = undefined; |
| ast.directives.forEach(function (localDirAst) { |
| if (localDirAst.directive.type.reference === tokenReference(providerAst.token)) { |
| dirAst = localDirAst; |
| } |
| }); |
| if (dirAst) { |
| var _a = _this._visitDirective(providerAst, dirAst, ast.references, ast.queryMatches, usedEvents), dirHostBindings = _a.hostBindings, dirHostEvents = _a.hostEvents; |
| hostBindings.push.apply(hostBindings, __spread(dirHostBindings)); |
| hostEvents.push.apply(hostEvents, __spread(dirHostEvents)); |
| } |
| else { |
| _this._visitProvider(providerAst, ast.queryMatches); |
| } |
| }); |
| var queryMatchExprs = []; |
| ast.queryMatches.forEach(function (match) { |
| var valueType = undefined; |
| if (tokenReference(match.value) === |
| _this.reflector.resolveExternalReference(Identifiers.ElementRef)) { |
| valueType = 0 /* ElementRef */; |
| } |
| else if (tokenReference(match.value) === |
| _this.reflector.resolveExternalReference(Identifiers.ViewContainerRef)) { |
| valueType = 3 /* ViewContainerRef */; |
| } |
| else if (tokenReference(match.value) === |
| _this.reflector.resolveExternalReference(Identifiers.TemplateRef)) { |
| valueType = 2 /* TemplateRef */; |
| } |
| if (valueType != null) { |
| queryMatchExprs.push(literalArr([literal(match.queryId), literal(valueType)])); |
| } |
| }); |
| ast.references.forEach(function (ref) { |
| var valueType = undefined; |
| if (!ref.value) { |
| valueType = 1 /* RenderElement */; |
| } |
| else if (tokenReference(ref.value) === |
| _this.reflector.resolveExternalReference(Identifiers.TemplateRef)) { |
| valueType = 2 /* TemplateRef */; |
| } |
| if (valueType != null) { |
| _this.refNodeIndices[ref.name] = nodeIndex; |
| queryMatchExprs.push(literalArr([literal(ref.name), literal(valueType)])); |
| } |
| }); |
| ast.outputs.forEach(function (outputAst) { |
| hostEvents.push({ context: COMP_VAR, eventAst: outputAst, dirAst: null }); |
| }); |
| return { |
| flags: flags, |
| usedEvents: Array.from(usedEvents.values()), |
| queryMatchesExpr: queryMatchExprs.length ? literalArr(queryMatchExprs) : NULL_EXPR, |
| hostBindings: hostBindings, |
| hostEvents: hostEvents |
| }; |
| }; |
| ViewBuilder.prototype._visitDirective = function (providerAst, dirAst, refs, queryMatches, usedEvents) { |
| var _this = this; |
| var nodeIndex = this.nodes.length; |
| // reserve the space in the nodeDefs array so we can add children |
| this.nodes.push(null); |
| dirAst.directive.queries.forEach(function (query, queryIndex) { |
| var queryId = dirAst.contentQueryStartId + queryIndex; |
| var flags = 67108864 /* TypeContentQuery */ | calcQueryFlags(query); |
| var bindingType = query.first ? 0 /* First */ : 1 /* All */; |
| _this.nodes.push(function () { return ({ |
| sourceSpan: dirAst.sourceSpan, |
| nodeFlags: flags, |
| nodeDef: importExpr(Identifiers.queryDef).callFn([ |
| literal(flags), literal(queryId), |
| new LiteralMapExpr([new LiteralMapEntry(query.propertyName, literal(bindingType), false)]) |
| ]), |
| }); }); |
| }); |
| // Note: the operation below might also create new nodeDefs, |
| // but we don't want them to be a child of a directive, |
| // as they might be a provider/pipe on their own. |
| // I.e. we only allow queries as children of directives nodes. |
| var childCount = this.nodes.length - nodeIndex - 1; |
| var _a = this._visitProviderOrDirective(providerAst, queryMatches), flags = _a.flags, queryMatchExprs = _a.queryMatchExprs, providerExpr = _a.providerExpr, depsExpr = _a.depsExpr; |
| refs.forEach(function (ref) { |
| if (ref.value && tokenReference(ref.value) === tokenReference(providerAst.token)) { |
| _this.refNodeIndices[ref.name] = nodeIndex; |
| queryMatchExprs.push(literalArr([literal(ref.name), literal(4 /* Provider */)])); |
| } |
| }); |
| if (dirAst.directive.isComponent) { |
| flags |= 32768 /* Component */; |
| } |
| var inputDefs = dirAst.inputs.map(function (inputAst, inputIndex) { |
| var mapValue = literalArr([literal(inputIndex), literal(inputAst.directiveName)]); |
| // Note: it's important to not quote the key so that we can capture renames by minifiers! |
| return new LiteralMapEntry(inputAst.directiveName, mapValue, false); |
| }); |
| var outputDefs = []; |
| var dirMeta = dirAst.directive; |
| Object.keys(dirMeta.outputs).forEach(function (propName) { |
| var eventName = dirMeta.outputs[propName]; |
| if (usedEvents.has(eventName)) { |
| // Note: it's important to not quote the key so that we can capture renames by minifiers! |
| outputDefs.push(new LiteralMapEntry(propName, literal(eventName), false)); |
| } |
| }); |
| var updateDirectiveExpressions = []; |
| if (dirAst.inputs.length || (flags & (262144 /* DoCheck */ | 65536 /* OnInit */)) > 0) { |
| updateDirectiveExpressions = |
| dirAst.inputs.map(function (input, bindingIndex) { return _this._preprocessUpdateExpression({ |
| nodeIndex: nodeIndex, |
| bindingIndex: bindingIndex, |
| sourceSpan: input.sourceSpan, |
| context: COMP_VAR, |
| value: input.value |
| }); }); |
| } |
| var dirContextExpr = importExpr(Identifiers.nodeValue).callFn([VIEW_VAR, literal(nodeIndex)]); |
| var hostBindings = dirAst.hostProperties.map(function (inputAst) { return ({ |
| context: dirContextExpr, |
| dirAst: dirAst, |
| inputAst: inputAst, |
| }); }); |
| var hostEvents = dirAst.hostEvents.map(function (hostEventAst) { return ({ |
| context: dirContextExpr, |
| eventAst: hostEventAst, |
| dirAst: dirAst, |
| }); }); |
| // Check index is the same as the node index during compilation |
| // They might only differ at runtime |
| var checkIndex = nodeIndex; |
| this.nodes[nodeIndex] = function () { return ({ |
| sourceSpan: dirAst.sourceSpan, |
| nodeFlags: 16384 /* TypeDirective */ | flags, |
| nodeDef: importExpr(Identifiers.directiveDef).callFn([ |
| literal(checkIndex), |
| literal(flags), |
| queryMatchExprs.length ? literalArr(queryMatchExprs) : NULL_EXPR, |
| literal(childCount), |
| providerExpr, |
| depsExpr, |
| inputDefs.length ? new LiteralMapExpr(inputDefs) : NULL_EXPR, |
| outputDefs.length ? new LiteralMapExpr(outputDefs) : NULL_EXPR, |
| ]), |
| updateDirectives: updateDirectiveExpressions, |
| directive: dirAst.directive.type, |
| }); }; |
| return { hostBindings: hostBindings, hostEvents: hostEvents }; |
| }; |
| ViewBuilder.prototype._visitProvider = function (providerAst, queryMatches) { |
| this._addProviderNode(this._visitProviderOrDirective(providerAst, queryMatches)); |
| }; |
| ViewBuilder.prototype._visitComponentFactoryResolverProvider = function (directives) { |
| var componentDirMeta = directives.find(function (dirAst) { return dirAst.directive.isComponent; }); |
| if (componentDirMeta && componentDirMeta.directive.entryComponents.length) { |
| var _a = componentFactoryResolverProviderDef(this.reflector, this.outputCtx, 8192 /* PrivateProvider */, componentDirMeta.directive.entryComponents), providerExpr = _a.providerExpr, depsExpr = _a.depsExpr, flags = _a.flags, tokenExpr = _a.tokenExpr; |
| this._addProviderNode({ |
| providerExpr: providerExpr, |
| depsExpr: depsExpr, |
| flags: flags, |
| tokenExpr: tokenExpr, |
| queryMatchExprs: [], |
| sourceSpan: componentDirMeta.sourceSpan |
| }); |
| } |
| }; |
| ViewBuilder.prototype._addProviderNode = function (data) { |
| // providerDef( |
| // flags: NodeFlags, matchedQueries: [string, QueryValueType][], token:any, |
| // value: any, deps: ([DepFlags, any] | any)[]): NodeDef; |
| this.nodes.push(function () { return ({ |
| sourceSpan: data.sourceSpan, |
| nodeFlags: data.flags, |
| nodeDef: importExpr(Identifiers.providerDef).callFn([ |
| literal(data.flags), |
| data.queryMatchExprs.length ? literalArr(data.queryMatchExprs) : NULL_EXPR, |
| data.tokenExpr, data.providerExpr, data.depsExpr |
| ]) |
| }); }); |
| }; |
| ViewBuilder.prototype._visitProviderOrDirective = function (providerAst, queryMatches) { |
| var flags = 0 /* None */; |
| var queryMatchExprs = []; |
| queryMatches.forEach(function (match) { |
| if (tokenReference(match.value) === tokenReference(providerAst.token)) { |
| queryMatchExprs.push(literalArr([literal(match.queryId), literal(4 /* Provider */)])); |
| } |
| }); |
| var _a = providerDef(this.outputCtx, providerAst), providerExpr = _a.providerExpr, depsExpr = _a.depsExpr, providerFlags = _a.flags, tokenExpr = _a.tokenExpr; |
| return { |
| flags: flags | providerFlags, |
| queryMatchExprs: queryMatchExprs, |
| providerExpr: providerExpr, |
| depsExpr: depsExpr, |
| tokenExpr: tokenExpr, |
| sourceSpan: providerAst.sourceSpan |
| }; |
| }; |
| ViewBuilder.prototype.getLocal = function (name) { |
| if (name == EventHandlerVars.event.name) { |
| return EventHandlerVars.event; |
| } |
| var currViewExpr = VIEW_VAR; |
| for (var currBuilder = this; currBuilder; currBuilder = currBuilder.parent, |
| currViewExpr = currViewExpr.prop('parent').cast(DYNAMIC_TYPE)) { |
| // check references |
| var refNodeIndex = currBuilder.refNodeIndices[name]; |
| if (refNodeIndex != null) { |
| return importExpr(Identifiers.nodeValue).callFn([currViewExpr, literal(refNodeIndex)]); |
| } |
| // check variables |
| var varAst = currBuilder.variables.find(function (varAst) { return varAst.name === name; }); |
| if (varAst) { |
| var varValue = varAst.value || IMPLICIT_TEMPLATE_VAR; |
| return currViewExpr.prop('context').prop(varValue); |
| } |
| } |
| return null; |
| }; |
| ViewBuilder.prototype.notifyImplicitReceiverUse = function () { |
| // Not needed in View Engine as View Engine walks through the generated |
| // expressions to figure out if the implicit receiver is used and needs |
| // to be generated as part of the pre-update statements. |
| }; |
| ViewBuilder.prototype._createLiteralArrayConverter = function (sourceSpan, argCount) { |
| if (argCount === 0) { |
| var valueExpr_1 = importExpr(Identifiers.EMPTY_ARRAY); |
| return function () { return valueExpr_1; }; |
| } |
| var checkIndex = this.nodes.length; |
| this.nodes.push(function () { return ({ |
| sourceSpan: sourceSpan, |
| nodeFlags: 32 /* TypePureArray */, |
| nodeDef: importExpr(Identifiers.pureArrayDef).callFn([ |
| literal(checkIndex), |
| literal(argCount), |
| ]) |
| }); }); |
| return function (args) { return callCheckStmt(checkIndex, args); }; |
| }; |
| ViewBuilder.prototype._createLiteralMapConverter = function (sourceSpan, keys) { |
| if (keys.length === 0) { |
| var valueExpr_2 = importExpr(Identifiers.EMPTY_MAP); |
| return function () { return valueExpr_2; }; |
| } |
| var map = literalMap(keys.map(function (e, i) { return (Object.assign(Object.assign({}, e), { value: literal(i) })); })); |
| var checkIndex = this.nodes.length; |
| this.nodes.push(function () { return ({ |
| sourceSpan: sourceSpan, |
| nodeFlags: 64 /* TypePureObject */, |
| nodeDef: importExpr(Identifiers.pureObjectDef).callFn([ |
| literal(checkIndex), |
| map, |
| ]) |
| }); }); |
| return function (args) { return callCheckStmt(checkIndex, args); }; |
| }; |
| ViewBuilder.prototype._createPipeConverter = function (expression, name, argCount) { |
| var pipe = this.usedPipes.find(function (pipeSummary) { return pipeSummary.name === name; }); |
| if (pipe.pure) { |
| var checkIndex_1 = this.nodes.length; |
| this.nodes.push(function () { return ({ |
| sourceSpan: expression.sourceSpan, |
| nodeFlags: 128 /* TypePurePipe */, |
| nodeDef: importExpr(Identifiers.purePipeDef).callFn([ |
| literal(checkIndex_1), |
| literal(argCount), |
| ]) |
| }); }); |
| // find underlying pipe in the component view |
| var compViewExpr = VIEW_VAR; |
| var compBuilder = this; |
| while (compBuilder.parent) { |
| compBuilder = compBuilder.parent; |
| compViewExpr = compViewExpr.prop('parent').cast(DYNAMIC_TYPE); |
| } |
| var pipeNodeIndex = compBuilder.purePipeNodeIndices[name]; |
| var pipeValueExpr_1 = importExpr(Identifiers.nodeValue).callFn([compViewExpr, literal(pipeNodeIndex)]); |
| return function (args) { return callUnwrapValue(expression.nodeIndex, expression.bindingIndex, callCheckStmt(checkIndex_1, [pipeValueExpr_1].concat(args))); }; |
| } |
| else { |
| var nodeIndex = this._createPipe(expression.sourceSpan, pipe); |
| var nodeValueExpr_1 = importExpr(Identifiers.nodeValue).callFn([VIEW_VAR, literal(nodeIndex)]); |
| return function (args) { return callUnwrapValue(expression.nodeIndex, expression.bindingIndex, nodeValueExpr_1.callMethod('transform', args)); }; |
| } |
| }; |
| ViewBuilder.prototype._createPipe = function (sourceSpan, pipe) { |
| var _this = this; |
| var nodeIndex = this.nodes.length; |
| var flags = 0 /* None */; |
| pipe.type.lifecycleHooks.forEach(function (lifecycleHook) { |
| // for pipes, we only support ngOnDestroy |
| if (lifecycleHook === LifecycleHooks.OnDestroy) { |
| flags |= lifecycleHookToNodeFlag(lifecycleHook); |
| } |
| }); |
| var depExprs = pipe.type.diDeps.map(function (diDep) { return depDef(_this.outputCtx, diDep); }); |
| // function pipeDef( |
| // flags: NodeFlags, ctor: any, deps: ([DepFlags, any] | any)[]): NodeDef |
| this.nodes.push(function () { return ({ |
| sourceSpan: sourceSpan, |
| nodeFlags: 16 /* TypePipe */, |
| nodeDef: importExpr(Identifiers.pipeDef).callFn([ |
| literal(flags), _this.outputCtx.importExpr(pipe.type.reference), literalArr(depExprs) |
| ]) |
| }); }); |
| return nodeIndex; |
| }; |
| /** |
| * For the AST in `UpdateExpression.value`: |
| * - create nodes for pipes, literal arrays and, literal maps, |
| * - update the AST to replace pipes, literal arrays and, literal maps with calls to check fn. |
| * |
| * WARNING: This might create new nodeDefs (for pipes and literal arrays and literal maps)! |
| */ |
| ViewBuilder.prototype._preprocessUpdateExpression = function (expression) { |
| var _this = this; |
| return { |
| nodeIndex: expression.nodeIndex, |
| bindingIndex: expression.bindingIndex, |
| sourceSpan: expression.sourceSpan, |
| context: expression.context, |
| value: convertPropertyBindingBuiltins({ |
| createLiteralArrayConverter: function (argCount) { return _this._createLiteralArrayConverter(expression.sourceSpan, argCount); }, |
| createLiteralMapConverter: function (keys) { return _this._createLiteralMapConverter(expression.sourceSpan, keys); }, |
| createPipeConverter: function (name, argCount) { return _this._createPipeConverter(expression, name, argCount); } |
| }, expression.value) |
| }; |
| }; |
| ViewBuilder.prototype._createNodeExpressions = function () { |
| var self = this; |
| var updateBindingCount = 0; |
| var updateRendererStmts = []; |
| var updateDirectivesStmts = []; |
| var nodeDefExprs = this.nodes.map(function (factory, nodeIndex) { |
| var _a = factory(), nodeDef = _a.nodeDef, nodeFlags = _a.nodeFlags, updateDirectives = _a.updateDirectives, updateRenderer = _a.updateRenderer, sourceSpan = _a.sourceSpan; |
| if (updateRenderer) { |
| updateRendererStmts.push.apply(updateRendererStmts, __spread(createUpdateStatements(nodeIndex, sourceSpan, updateRenderer, false))); |
| } |
| if (updateDirectives) { |
| updateDirectivesStmts.push.apply(updateDirectivesStmts, __spread(createUpdateStatements(nodeIndex, sourceSpan, updateDirectives, (nodeFlags & (262144 /* DoCheck */ | 65536 /* OnInit */)) > 0))); |
| } |
| // We use a comma expression to call the log function before |
| // the nodeDef function, but still use the result of the nodeDef function |
| // as the value. |
| // Note: We only add the logger to elements / text nodes, |
| // so we don't generate too much code. |
| var logWithNodeDef = nodeFlags & 3 /* CatRenderNode */ ? |
| new CommaExpr([LOG_VAR$1.callFn([]).callFn([]), nodeDef]) : |
| nodeDef; |
| return applySourceSpanToExpressionIfNeeded(logWithNodeDef, sourceSpan); |
| }); |
| return { updateRendererStmts: updateRendererStmts, updateDirectivesStmts: updateDirectivesStmts, nodeDefExprs: nodeDefExprs }; |
| function createUpdateStatements(nodeIndex, sourceSpan, expressions, allowEmptyExprs) { |
| var updateStmts = []; |
| var exprs = expressions.map(function (_a) { |
| var sourceSpan = _a.sourceSpan, context = _a.context, value = _a.value; |
| var bindingId = "" + updateBindingCount++; |
| var nameResolver = context === COMP_VAR ? self : null; |
| var _b = convertPropertyBinding(nameResolver, context, value, bindingId, BindingForm.General), stmts = _b.stmts, currValExpr = _b.currValExpr; |
| updateStmts.push.apply(updateStmts, __spread(stmts.map(function (stmt) { return applySourceSpanToStatementIfNeeded(stmt, sourceSpan); }))); |
| return applySourceSpanToExpressionIfNeeded(currValExpr, sourceSpan); |
| }); |
| if (expressions.length || allowEmptyExprs) { |
| updateStmts.push(applySourceSpanToStatementIfNeeded(callCheckStmt(nodeIndex, exprs).toStmt(), sourceSpan)); |
| } |
| return updateStmts; |
| } |
| }; |
| ViewBuilder.prototype._createElementHandleEventFn = function (nodeIndex, handlers) { |
| var _this = this; |
| var handleEventStmts = []; |
| var handleEventBindingCount = 0; |
| handlers.forEach(function (_a) { |
| var context = _a.context, eventAst = _a.eventAst, dirAst = _a.dirAst; |
| var bindingId = "" + handleEventBindingCount++; |
| var nameResolver = context === COMP_VAR ? _this : null; |
| var _b = convertActionBinding(nameResolver, context, eventAst.handler, bindingId), stmts = _b.stmts, allowDefault = _b.allowDefault; |
| var trueStmts = stmts; |
| if (allowDefault) { |
| trueStmts.push(ALLOW_DEFAULT_VAR.set(allowDefault.and(ALLOW_DEFAULT_VAR)).toStmt()); |
| } |
| var _c = elementEventNameAndTarget(eventAst, dirAst), eventTarget = _c.target, eventName = _c.name; |
| var fullEventName = elementEventFullName(eventTarget, eventName); |
| handleEventStmts.push(applySourceSpanToStatementIfNeeded(new IfStmt(literal(fullEventName).identical(EVENT_NAME_VAR), trueStmts), eventAst.sourceSpan)); |
| }); |
| var handleEventFn; |
| if (handleEventStmts.length > 0) { |
| var preStmts = [ALLOW_DEFAULT_VAR.set(literal(true)).toDeclStmt(BOOL_TYPE)]; |
| if (!this.component.isHost && findReadVarNames(handleEventStmts).has(COMP_VAR.name)) { |
| preStmts.push(COMP_VAR.set(VIEW_VAR.prop('component')).toDeclStmt(this.compType)); |
| } |
| handleEventFn = fn([ |
| new FnParam(VIEW_VAR.name, INFERRED_TYPE), |
| new FnParam(EVENT_NAME_VAR.name, INFERRED_TYPE), |
| new FnParam(EventHandlerVars.event.name, INFERRED_TYPE) |
| ], __spread(preStmts, handleEventStmts, [new ReturnStatement(ALLOW_DEFAULT_VAR)]), INFERRED_TYPE); |
| } |
| else { |
| handleEventFn = NULL_EXPR; |
| } |
| return handleEventFn; |
| }; |
| ViewBuilder.prototype.visitDirective = function (ast, context) { }; |
| ViewBuilder.prototype.visitDirectiveProperty = function (ast, context) { }; |
| ViewBuilder.prototype.visitReference = function (ast, context) { }; |
| ViewBuilder.prototype.visitVariable = function (ast, context) { }; |
| ViewBuilder.prototype.visitEvent = function (ast, context) { }; |
| ViewBuilder.prototype.visitElementProperty = function (ast, context) { }; |
| ViewBuilder.prototype.visitAttr = function (ast, context) { }; |
| return ViewBuilder; |
| }()); |
| function needsAdditionalRootNode(astNodes) { |
| var lastAstNode = astNodes[astNodes.length - 1]; |
| if (lastAstNode instanceof EmbeddedTemplateAst) { |
| return lastAstNode.hasViewContainer; |
| } |
| if (lastAstNode instanceof ElementAst) { |
| if (isNgContainer(lastAstNode.name) && lastAstNode.children.length) { |
| return needsAdditionalRootNode(lastAstNode.children); |
| } |
| return lastAstNode.hasViewContainer; |
| } |
| return lastAstNode instanceof NgContentAst; |
| } |
| function elementBindingDef(inputAst, dirAst) { |
| var inputType = inputAst.type; |
| switch (inputType) { |
| case 1 /* Attribute */: |
| return literalArr([ |
| literal(1 /* TypeElementAttribute */), literal(inputAst.name), |
| literal(inputAst.securityContext) |
| ]); |
| case 0 /* Property */: |
| return literalArr([ |
| literal(8 /* TypeProperty */), literal(inputAst.name), |
| literal(inputAst.securityContext) |
| ]); |
| case 4 /* Animation */: |
| var bindingType = 8 /* TypeProperty */ | |
| (dirAst && dirAst.directive.isComponent ? 32 /* SyntheticHostProperty */ : |
| 16 /* SyntheticProperty */); |
| return literalArr([ |
| literal(bindingType), literal('@' + inputAst.name), literal(inputAst.securityContext) |
| ]); |
| case 2 /* Class */: |
| return literalArr([literal(2 /* TypeElementClass */), literal(inputAst.name), NULL_EXPR]); |
| case 3 /* Style */: |
| return literalArr([ |
| literal(4 /* TypeElementStyle */), literal(inputAst.name), literal(inputAst.unit) |
| ]); |
| default: |
| // This default case is not needed by TypeScript compiler, as the switch is exhaustive. |
| // However Closure Compiler does not understand that and reports an error in typed mode. |
| // The `throw new Error` below works around the problem, and the unexpected: never variable |
| // makes sure tsc still checks this code is unreachable. |
| var unexpected = inputType; |
| throw new Error("unexpected " + unexpected); |
| } |
| } |
| function fixedAttrsDef(elementAst) { |
| var mapResult = Object.create(null); |
| elementAst.attrs.forEach(function (attrAst) { |
| mapResult[attrAst.name] = attrAst.value; |
| }); |
| elementAst.directives.forEach(function (dirAst) { |
| Object.keys(dirAst.directive.hostAttributes).forEach(function (name) { |
| var value = dirAst.directive.hostAttributes[name]; |
| var prevValue = mapResult[name]; |
| mapResult[name] = prevValue != null ? mergeAttributeValue(name, prevValue, value) : value; |
| }); |
| }); |
| // Note: We need to sort to get a defined output order |
| // for tests and for caching generated artifacts... |
| return literalArr(Object.keys(mapResult).sort().map(function (attrName) { return literalArr([literal(attrName), literal(mapResult[attrName])]); })); |
| } |
| function mergeAttributeValue(attrName, attrValue1, attrValue2) { |
| if (attrName == CLASS_ATTR$1 || attrName == STYLE_ATTR) { |
| return attrValue1 + " " + attrValue2; |
| } |
| else { |
| return attrValue2; |
| } |
| } |
| function callCheckStmt(nodeIndex, exprs) { |
| if (exprs.length > 10) { |
| return CHECK_VAR.callFn([VIEW_VAR, literal(nodeIndex), literal(1 /* Dynamic */), literalArr(exprs)]); |
| } |
| else { |
| return CHECK_VAR.callFn(__spread([VIEW_VAR, literal(nodeIndex), literal(0 /* Inline */)], exprs)); |
| } |
| } |
| function callUnwrapValue(nodeIndex, bindingIdx, expr) { |
| return importExpr(Identifiers.unwrapValue).callFn([ |
| VIEW_VAR, literal(nodeIndex), literal(bindingIdx), expr |
| ]); |
| } |
| function elementEventNameAndTarget(eventAst, dirAst) { |
| if (eventAst.isAnimation) { |
| return { |
| name: "@" + eventAst.name + "." + eventAst.phase, |
| target: dirAst && dirAst.directive.isComponent ? 'component' : null |
| }; |
| } |
| else { |
| return eventAst; |
| } |
| } |
| function calcQueryFlags(query) { |
| var flags = 0 /* None */; |
| // Note: We only make queries static that query for a single item and the user specifically |
| // set the to be static. This is because of backwards compatibility with the old view compiler... |
| if (query.first && query.static) { |
| flags |= 268435456 /* StaticQuery */; |
| } |
| else { |
| flags |= 536870912 /* DynamicQuery */; |
| } |
| if (query.emitDistinctChangesOnly) { |
| flags |= -2147483648 /* EmitDistinctChangesOnly */; |
| } |
| return flags; |
| } |
| function elementEventFullName(target, name) { |
| return target ? target + ":" + name : name; |
| } |
| |
| /** |
| * A container for message extracted from the templates. |
| */ |
| var MessageBundle = /** @class */ (function () { |
| function MessageBundle(_htmlParser, _implicitTags, _implicitAttrs, _locale) { |
| if (_locale === void 0) { _locale = null; } |
| this._htmlParser = _htmlParser; |
| this._implicitTags = _implicitTags; |
| this._implicitAttrs = _implicitAttrs; |
| this._locale = _locale; |
| this._messages = []; |
| } |
| MessageBundle.prototype.updateFromTemplate = function (html, url, interpolationConfig) { |
| var _a; |
| var htmlParserResult = this._htmlParser.parse(html, url, { tokenizeExpansionForms: true, interpolationConfig: interpolationConfig }); |
| if (htmlParserResult.errors.length) { |
| return htmlParserResult.errors; |
| } |
| var i18nParserResult = extractMessages(htmlParserResult.rootNodes, interpolationConfig, this._implicitTags, this._implicitAttrs); |
| if (i18nParserResult.errors.length) { |
| return i18nParserResult.errors; |
| } |
| (_a = this._messages).push.apply(_a, __spread(i18nParserResult.messages)); |
| return []; |
| }; |
| // Return the message in the internal format |
| // The public (serialized) format might be different, see the `write` method. |
| MessageBundle.prototype.getMessages = function () { |
| return this._messages; |
| }; |
| MessageBundle.prototype.write = function (serializer, filterSources) { |
| var messages = {}; |
| var mapperVisitor = new MapPlaceholderNames(); |
| // Deduplicate messages based on their ID |
| this._messages.forEach(function (message) { |
| var _a; |
| var id = serializer.digest(message); |
| if (!messages.hasOwnProperty(id)) { |
| messages[id] = message; |
| } |
| else { |
| (_a = messages[id].sources).push.apply(_a, __spread(message.sources)); |
| } |
| }); |
| // Transform placeholder names using the serializer mapping |
| var msgList = Object.keys(messages).map(function (id) { |
| var mapper = serializer.createNameMapper(messages[id]); |
| var src = messages[id]; |
| var nodes = mapper ? mapperVisitor.convert(src.nodes, mapper) : src.nodes; |
| var transformedMessage = new Message(nodes, {}, {}, src.meaning, src.description, id); |
| transformedMessage.sources = src.sources; |
| if (filterSources) { |
| transformedMessage.sources.forEach(function (source) { return source.filePath = filterSources(source.filePath); }); |
| } |
| return transformedMessage; |
| }); |
| return serializer.write(msgList, this._locale); |
| }; |
| return MessageBundle; |
| }()); |
| // Transform an i18n AST by renaming the placeholder nodes with the given mapper |
| var MapPlaceholderNames = /** @class */ (function (_super) { |
| __extends(MapPlaceholderNames, _super); |
| function MapPlaceholderNames() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| MapPlaceholderNames.prototype.convert = function (nodes, mapper) { |
| var _this = this; |
| return mapper ? nodes.map(function (n) { return n.visit(_this, mapper); }) : nodes; |
| }; |
| MapPlaceholderNames.prototype.visitTagPlaceholder = function (ph, mapper) { |
| var _this = this; |
| var startName = mapper.toPublicName(ph.startName); |
| var closeName = ph.closeName ? mapper.toPublicName(ph.closeName) : ph.closeName; |
| var children = ph.children.map(function (n) { return n.visit(_this, mapper); }); |
| return new TagPlaceholder(ph.tag, ph.attrs, startName, closeName, children, ph.isVoid, ph.sourceSpan, ph.startSourceSpan, ph.endSourceSpan); |
| }; |
| MapPlaceholderNames.prototype.visitPlaceholder = function (ph, mapper) { |
| return new Placeholder(ph.value, mapper.toPublicName(ph.name), ph.sourceSpan); |
| }; |
| MapPlaceholderNames.prototype.visitIcuPlaceholder = function (ph, mapper) { |
| return new IcuPlaceholder(ph.value, mapper.toPublicName(ph.name), ph.sourceSpan); |
| }; |
| return MapPlaceholderNames; |
| }(CloneVisitor)); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var GeneratedFile = /** @class */ (function () { |
| function GeneratedFile(srcFileUrl, genFileUrl, sourceOrStmts) { |
| this.srcFileUrl = srcFileUrl; |
| this.genFileUrl = genFileUrl; |
| if (typeof sourceOrStmts === 'string') { |
| this.source = sourceOrStmts; |
| this.stmts = null; |
| } |
| else { |
| this.source = null; |
| this.stmts = sourceOrStmts; |
| } |
| } |
| GeneratedFile.prototype.isEquivalent = function (other) { |
| if (this.genFileUrl !== other.genFileUrl) { |
| return false; |
| } |
| if (this.source) { |
| return this.source === other.source; |
| } |
| if (other.stmts == null) { |
| return false; |
| } |
| // Note: the constructor guarantees that if this.source is not filled, |
| // then this.stmts is. |
| return areAllEquivalent(this.stmts, other.stmts); |
| }; |
| return GeneratedFile; |
| }()); |
| function toTypeScript(file, preamble) { |
| if (preamble === void 0) { preamble = ''; } |
| if (!file.stmts) { |
| throw new Error("Illegal state: No stmts present on GeneratedFile " + file.genFileUrl); |
| } |
| return new TypeScriptEmitter().emitStatements(file.genFileUrl, file.stmts, preamble); |
| } |
| |
| function listLazyRoutes(moduleMeta, reflector) { |
| var e_1, _a, e_2, _b; |
| var allLazyRoutes = []; |
| try { |
| for (var _c = __values(moduleMeta.transitiveModule.providers), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var _e = _d.value, provider = _e.provider, module = _e.module; |
| if (tokenReference(provider.token) === reflector.ROUTES) { |
| var loadChildren = _collectLoadChildren(provider.useValue); |
| try { |
| for (var loadChildren_1 = (e_2 = void 0, __values(loadChildren)), loadChildren_1_1 = loadChildren_1.next(); !loadChildren_1_1.done; loadChildren_1_1 = loadChildren_1.next()) { |
| var route = loadChildren_1_1.value; |
| allLazyRoutes.push(parseLazyRoute(route, reflector, module.reference)); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (loadChildren_1_1 && !loadChildren_1_1.done && (_b = loadChildren_1.return)) _b.call(loadChildren_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_a = _c.return)) _a.call(_c); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return allLazyRoutes; |
| } |
| function _collectLoadChildren(routes, target) { |
| var e_3, _a; |
| if (target === void 0) { target = []; } |
| if (typeof routes === 'string') { |
| target.push(routes); |
| } |
| else if (Array.isArray(routes)) { |
| try { |
| for (var routes_1 = __values(routes), routes_1_1 = routes_1.next(); !routes_1_1.done; routes_1_1 = routes_1.next()) { |
| var route = routes_1_1.value; |
| _collectLoadChildren(route, target); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| } |
| else if (routes.loadChildren) { |
| _collectLoadChildren(routes.loadChildren, target); |
| } |
| else if (routes.children) { |
| _collectLoadChildren(routes.children, target); |
| } |
| return target; |
| } |
| function parseLazyRoute(route, reflector, module) { |
| var _a = __read(route.split('#'), 2), routePath = _a[0], routeName = _a[1]; |
| var referencedModule = reflector.resolveExternalReference({ |
| moduleName: routePath, |
| name: routeName, |
| }, module ? module.filePath : undefined); |
| return { route: route, module: module || referencedModule, referencedModule: referencedModule }; |
| } |
| |
| var TS = /^(?!.*\.d\.ts$).*\.ts$/; |
| var ResolvedStaticSymbol = /** @class */ (function () { |
| function ResolvedStaticSymbol(symbol, metadata) { |
| this.symbol = symbol; |
| this.metadata = metadata; |
| } |
| return ResolvedStaticSymbol; |
| }()); |
| var SUPPORTED_SCHEMA_VERSION = 4; |
| /** |
| * This class is responsible for loading metadata per symbol, |
| * and normalizing references between symbols. |
| * |
| * Internally, it only uses symbols without members, |
| * and deduces the values for symbols with members based |
| * on these symbols. |
| */ |
| var StaticSymbolResolver = /** @class */ (function () { |
| function StaticSymbolResolver(host, staticSymbolCache, summaryResolver, errorRecorder) { |
| this.host = host; |
| this.staticSymbolCache = staticSymbolCache; |
| this.summaryResolver = summaryResolver; |
| this.errorRecorder = errorRecorder; |
| this.metadataCache = new Map(); |
| // Note: this will only contain StaticSymbols without members! |
| this.resolvedSymbols = new Map(); |
| // Note: this will only contain StaticSymbols without members! |
| this.importAs = new Map(); |
| this.symbolResourcePaths = new Map(); |
| this.symbolFromFile = new Map(); |
| this.knownFileNameToModuleNames = new Map(); |
| } |
| StaticSymbolResolver.prototype.resolveSymbol = function (staticSymbol) { |
| if (staticSymbol.members.length > 0) { |
| return this._resolveSymbolMembers(staticSymbol); |
| } |
| // Note: always ask for a summary first, |
| // as we might have read shallow metadata via a .d.ts file |
| // for the symbol. |
| var resultFromSummary = this._resolveSymbolFromSummary(staticSymbol); |
| if (resultFromSummary) { |
| return resultFromSummary; |
| } |
| var resultFromCache = this.resolvedSymbols.get(staticSymbol); |
| if (resultFromCache) { |
| return resultFromCache; |
| } |
| // Note: Some users use libraries that were not compiled with ngc, i.e. they don't |
| // have summaries, only .d.ts files. So we always need to check both, the summary |
| // and metadata. |
| this._createSymbolsOf(staticSymbol.filePath); |
| return this.resolvedSymbols.get(staticSymbol); |
| }; |
| /** |
| * getImportAs produces a symbol that can be used to import the given symbol. |
| * The import might be different than the symbol if the symbol is exported from |
| * a library with a summary; in which case we want to import the symbol from the |
| * ngfactory re-export instead of directly to avoid introducing a direct dependency |
| * on an otherwise indirect dependency. |
| * |
| * @param staticSymbol the symbol for which to generate a import symbol |
| */ |
| StaticSymbolResolver.prototype.getImportAs = function (staticSymbol, useSummaries) { |
| if (useSummaries === void 0) { useSummaries = true; } |
| if (staticSymbol.members.length) { |
| var baseSymbol = this.getStaticSymbol(staticSymbol.filePath, staticSymbol.name); |
| var baseImportAs = this.getImportAs(baseSymbol, useSummaries); |
| return baseImportAs ? |
| this.getStaticSymbol(baseImportAs.filePath, baseImportAs.name, staticSymbol.members) : |
| null; |
| } |
| var summarizedFileName = stripSummaryForJitFileSuffix(staticSymbol.filePath); |
| if (summarizedFileName !== staticSymbol.filePath) { |
| var summarizedName = stripSummaryForJitNameSuffix(staticSymbol.name); |
| var baseSymbol = this.getStaticSymbol(summarizedFileName, summarizedName, staticSymbol.members); |
| var baseImportAs = this.getImportAs(baseSymbol, useSummaries); |
| return baseImportAs ? this.getStaticSymbol(summaryForJitFileName(baseImportAs.filePath), summaryForJitName(baseImportAs.name), baseSymbol.members) : |
| null; |
| } |
| var result = (useSummaries && this.summaryResolver.getImportAs(staticSymbol)) || null; |
| if (!result) { |
| result = this.importAs.get(staticSymbol); |
| } |
| return result; |
| }; |
| /** |
| * getResourcePath produces the path to the original location of the symbol and should |
| * be used to determine the relative location of resource references recorded in |
| * symbol metadata. |
| */ |
| StaticSymbolResolver.prototype.getResourcePath = function (staticSymbol) { |
| return this.symbolResourcePaths.get(staticSymbol) || staticSymbol.filePath; |
| }; |
| /** |
| * getTypeArity returns the number of generic type parameters the given symbol |
| * has. If the symbol is not a type the result is null. |
| */ |
| StaticSymbolResolver.prototype.getTypeArity = function (staticSymbol) { |
| // If the file is a factory/ngsummary file, don't resolve the symbol as doing so would |
| // cause the metadata for an factory/ngsummary file to be loaded which doesn't exist. |
| // All references to generated classes must include the correct arity whenever |
| // generating code. |
| if (isGeneratedFile(staticSymbol.filePath)) { |
| return null; |
| } |
| var resolvedSymbol = unwrapResolvedMetadata(this.resolveSymbol(staticSymbol)); |
| while (resolvedSymbol && resolvedSymbol.metadata instanceof StaticSymbol) { |
| resolvedSymbol = unwrapResolvedMetadata(this.resolveSymbol(resolvedSymbol.metadata)); |
| } |
| return (resolvedSymbol && resolvedSymbol.metadata && resolvedSymbol.metadata.arity) || null; |
| }; |
| StaticSymbolResolver.prototype.getKnownModuleName = function (filePath) { |
| return this.knownFileNameToModuleNames.get(filePath) || null; |
| }; |
| StaticSymbolResolver.prototype.recordImportAs = function (sourceSymbol, targetSymbol) { |
| sourceSymbol.assertNoMembers(); |
| targetSymbol.assertNoMembers(); |
| this.importAs.set(sourceSymbol, targetSymbol); |
| }; |
| StaticSymbolResolver.prototype.recordModuleNameForFileName = function (fileName, moduleName) { |
| this.knownFileNameToModuleNames.set(fileName, moduleName); |
| }; |
| /** |
| * Invalidate all information derived from the given file and return the |
| * static symbols contained in the file. |
| * |
| * @param fileName the file to invalidate |
| */ |
| StaticSymbolResolver.prototype.invalidateFile = function (fileName) { |
| var e_1, _a; |
| this.metadataCache.delete(fileName); |
| var symbols = this.symbolFromFile.get(fileName); |
| if (!symbols) { |
| return []; |
| } |
| this.symbolFromFile.delete(fileName); |
| try { |
| for (var symbols_1 = __values(symbols), symbols_1_1 = symbols_1.next(); !symbols_1_1.done; symbols_1_1 = symbols_1.next()) { |
| var symbol = symbols_1_1.value; |
| this.resolvedSymbols.delete(symbol); |
| this.importAs.delete(symbol); |
| this.symbolResourcePaths.delete(symbol); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (symbols_1_1 && !symbols_1_1.done && (_a = symbols_1.return)) _a.call(symbols_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return symbols; |
| }; |
| /** @internal */ |
| StaticSymbolResolver.prototype.ignoreErrorsFor = function (cb) { |
| var recorder = this.errorRecorder; |
| this.errorRecorder = function () { }; |
| try { |
| return cb(); |
| } |
| finally { |
| this.errorRecorder = recorder; |
| } |
| }; |
| StaticSymbolResolver.prototype._resolveSymbolMembers = function (staticSymbol) { |
| var members = staticSymbol.members; |
| var baseResolvedSymbol = this.resolveSymbol(this.getStaticSymbol(staticSymbol.filePath, staticSymbol.name)); |
| if (!baseResolvedSymbol) { |
| return null; |
| } |
| var baseMetadata = unwrapResolvedMetadata(baseResolvedSymbol.metadata); |
| if (baseMetadata instanceof StaticSymbol) { |
| return new ResolvedStaticSymbol(staticSymbol, this.getStaticSymbol(baseMetadata.filePath, baseMetadata.name, members)); |
| } |
| else if (baseMetadata && baseMetadata.__symbolic === 'class') { |
| if (baseMetadata.statics && members.length === 1) { |
| return new ResolvedStaticSymbol(staticSymbol, baseMetadata.statics[members[0]]); |
| } |
| } |
| else { |
| var value = baseMetadata; |
| for (var i = 0; i < members.length && value; i++) { |
| value = value[members[i]]; |
| } |
| return new ResolvedStaticSymbol(staticSymbol, value); |
| } |
| return null; |
| }; |
| StaticSymbolResolver.prototype._resolveSymbolFromSummary = function (staticSymbol) { |
| var summary = this.summaryResolver.resolveSummary(staticSymbol); |
| return summary ? new ResolvedStaticSymbol(staticSymbol, summary.metadata) : null; |
| }; |
| /** |
| * getStaticSymbol produces a Type whose metadata is known but whose implementation is not loaded. |
| * All types passed to the StaticResolver should be pseudo-types returned by this method. |
| * |
| * @param declarationFile the absolute path of the file where the symbol is declared |
| * @param name the name of the type. |
| * @param members a symbol for a static member of the named type |
| */ |
| StaticSymbolResolver.prototype.getStaticSymbol = function (declarationFile, name, members) { |
| return this.staticSymbolCache.get(declarationFile, name, members); |
| }; |
| /** |
| * hasDecorators checks a file's metadata for the presence of decorators without evaluating the |
| * metadata. |
| * |
| * @param filePath the absolute path to examine for decorators. |
| * @returns true if any class in the file has a decorator. |
| */ |
| StaticSymbolResolver.prototype.hasDecorators = function (filePath) { |
| var metadata = this.getModuleMetadata(filePath); |
| if (metadata['metadata']) { |
| return Object.keys(metadata['metadata']).some(function (metadataKey) { |
| var entry = metadata['metadata'][metadataKey]; |
| return entry && entry.__symbolic === 'class' && entry.decorators; |
| }); |
| } |
| return false; |
| }; |
| StaticSymbolResolver.prototype.getSymbolsOf = function (filePath) { |
| var summarySymbols = this.summaryResolver.getSymbolsOf(filePath); |
| if (summarySymbols) { |
| return summarySymbols; |
| } |
| // Note: Some users use libraries that were not compiled with ngc, i.e. they don't |
| // have summaries, only .d.ts files, but `summaryResolver.isLibraryFile` returns true. |
| this._createSymbolsOf(filePath); |
| return this.symbolFromFile.get(filePath) || []; |
| }; |
| StaticSymbolResolver.prototype._createSymbolsOf = function (filePath) { |
| var e_2, _a, e_3, _b; |
| var _this = this; |
| if (this.symbolFromFile.has(filePath)) { |
| return; |
| } |
| var resolvedSymbols = []; |
| var metadata = this.getModuleMetadata(filePath); |
| if (metadata['importAs']) { |
| // Index bundle indices should use the importAs module name defined |
| // in the bundle. |
| this.knownFileNameToModuleNames.set(filePath, metadata['importAs']); |
| } |
| // handle the symbols in one of the re-export location |
| if (metadata['exports']) { |
| var _loop_1 = function (moduleExport) { |
| // handle the symbols in the list of explicitly re-exported symbols. |
| if (moduleExport.export) { |
| moduleExport.export.forEach(function (exportSymbol) { |
| var symbolName; |
| if (typeof exportSymbol === 'string') { |
| symbolName = exportSymbol; |
| } |
| else { |
| symbolName = exportSymbol.as; |
| } |
| symbolName = unescapeIdentifier(symbolName); |
| var symName = symbolName; |
| if (typeof exportSymbol !== 'string') { |
| symName = unescapeIdentifier(exportSymbol.name); |
| } |
| var resolvedModule = _this.resolveModule(moduleExport.from, filePath); |
| if (resolvedModule) { |
| var targetSymbol = _this.getStaticSymbol(resolvedModule, symName); |
| var sourceSymbol = _this.getStaticSymbol(filePath, symbolName); |
| resolvedSymbols.push(_this.createExport(sourceSymbol, targetSymbol)); |
| } |
| }); |
| } |
| else { |
| // Handle the symbols loaded by 'export *' directives. |
| var resolvedModule = this_1.resolveModule(moduleExport.from, filePath); |
| if (resolvedModule && resolvedModule !== filePath) { |
| var nestedExports = this_1.getSymbolsOf(resolvedModule); |
| nestedExports.forEach(function (targetSymbol) { |
| var sourceSymbol = _this.getStaticSymbol(filePath, targetSymbol.name); |
| resolvedSymbols.push(_this.createExport(sourceSymbol, targetSymbol)); |
| }); |
| } |
| } |
| }; |
| var this_1 = this; |
| try { |
| for (var _c = __values(metadata['exports']), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var moduleExport = _d.value; |
| _loop_1(moduleExport); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_a = _c.return)) _a.call(_c); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| } |
| // handle the actual metadata. Has to be after the exports |
| // as there might be collisions in the names, and we want the symbols |
| // of the current module to win ofter reexports. |
| if (metadata['metadata']) { |
| // handle direct declarations of the symbol |
| var topLevelSymbolNames_1 = new Set(Object.keys(metadata['metadata']).map(unescapeIdentifier)); |
| var origins_1 = metadata['origins'] || {}; |
| Object.keys(metadata['metadata']).forEach(function (metadataKey) { |
| var symbolMeta = metadata['metadata'][metadataKey]; |
| var name = unescapeIdentifier(metadataKey); |
| var symbol = _this.getStaticSymbol(filePath, name); |
| var origin = origins_1.hasOwnProperty(metadataKey) && origins_1[metadataKey]; |
| if (origin) { |
| // If the symbol is from a bundled index, use the declaration location of the |
| // symbol so relative references (such as './my.html') will be calculated |
| // correctly. |
| var originFilePath = _this.resolveModule(origin, filePath); |
| if (!originFilePath) { |
| _this.reportError(new Error("Couldn't resolve original symbol for " + origin + " from " + _this.host.getOutputName(filePath))); |
| } |
| else { |
| _this.symbolResourcePaths.set(symbol, originFilePath); |
| } |
| } |
| resolvedSymbols.push(_this.createResolvedSymbol(symbol, filePath, topLevelSymbolNames_1, symbolMeta)); |
| }); |
| } |
| var uniqueSymbols = new Set(); |
| try { |
| for (var resolvedSymbols_1 = __values(resolvedSymbols), resolvedSymbols_1_1 = resolvedSymbols_1.next(); !resolvedSymbols_1_1.done; resolvedSymbols_1_1 = resolvedSymbols_1.next()) { |
| var resolvedSymbol = resolvedSymbols_1_1.value; |
| this.resolvedSymbols.set(resolvedSymbol.symbol, resolvedSymbol); |
| uniqueSymbols.add(resolvedSymbol.symbol); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (resolvedSymbols_1_1 && !resolvedSymbols_1_1.done && (_b = resolvedSymbols_1.return)) _b.call(resolvedSymbols_1); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| this.symbolFromFile.set(filePath, Array.from(uniqueSymbols)); |
| }; |
| StaticSymbolResolver.prototype.createResolvedSymbol = function (sourceSymbol, topLevelPath, topLevelSymbolNames, metadata) { |
| var _this = this; |
| // For classes that don't have Angular summaries / metadata, |
| // we only keep their arity, but nothing else |
| // (e.g. their constructor parameters). |
| // We do this to prevent introducing deep imports |
| // as we didn't generate .ngfactory.ts files with proper reexports. |
| var isTsFile = TS.test(sourceSymbol.filePath); |
| if (this.summaryResolver.isLibraryFile(sourceSymbol.filePath) && !isTsFile && metadata && |
| metadata['__symbolic'] === 'class') { |
| var transformedMeta_1 = { __symbolic: 'class', arity: metadata.arity }; |
| return new ResolvedStaticSymbol(sourceSymbol, transformedMeta_1); |
| } |
| var _originalFileMemo; |
| var getOriginalName = function () { |
| if (!_originalFileMemo) { |
| // Guess what the original file name is from the reference. If it has a `.d.ts` extension |
| // replace it with `.ts`. If it already has `.ts` just leave it in place. If it doesn't have |
| // .ts or .d.ts, append `.ts'. Also, if it is in `node_modules`, trim the `node_module` |
| // location as it is not important to finding the file. |
| _originalFileMemo = |
| _this.host.getOutputName(topLevelPath.replace(/((\.ts)|(\.d\.ts)|)$/, '.ts') |
| .replace(/^.*node_modules[/\\]/, '')); |
| } |
| return _originalFileMemo; |
| }; |
| var self = this; |
| var ReferenceTransformer = /** @class */ (function (_super) { |
| __extends(ReferenceTransformer, _super); |
| function ReferenceTransformer() { |
| return _super !== null && _super.apply(this, arguments) || this; |
| } |
| ReferenceTransformer.prototype.visitStringMap = function (map, functionParams) { |
| var symbolic = map['__symbolic']; |
| if (symbolic === 'function') { |
| var oldLen = functionParams.length; |
| functionParams.push.apply(functionParams, __spread((map['parameters'] || []))); |
| var result = _super.prototype.visitStringMap.call(this, map, functionParams); |
| functionParams.length = oldLen; |
| return result; |
| } |
| else if (symbolic === 'reference') { |
| var module = map['module']; |
| var name = map['name'] ? unescapeIdentifier(map['name']) : map['name']; |
| if (!name) { |
| return null; |
| } |
| var filePath = void 0; |
| if (module) { |
| filePath = self.resolveModule(module, sourceSymbol.filePath); |
| if (!filePath) { |
| return { |
| __symbolic: 'error', |
| message: "Could not resolve " + module + " relative to " + self.host.getMetadataFor(sourceSymbol.filePath) + ".", |
| line: map['line'], |
| character: map['character'], |
| fileName: getOriginalName() |
| }; |
| } |
| return { |
| __symbolic: 'resolved', |
| symbol: self.getStaticSymbol(filePath, name), |
| line: map['line'], |
| character: map['character'], |
| fileName: getOriginalName() |
| }; |
| } |
| else if (functionParams.indexOf(name) >= 0) { |
| // reference to a function parameter |
| return { __symbolic: 'reference', name: name }; |
| } |
| else { |
| if (topLevelSymbolNames.has(name)) { |
| return self.getStaticSymbol(topLevelPath, name); |
| } |
| // ambient value |
| null; |
| } |
| } |
| else if (symbolic === 'error') { |
| return Object.assign(Object.assign({}, map), { fileName: getOriginalName() }); |
| } |
| else { |
| return _super.prototype.visitStringMap.call(this, map, functionParams); |
| } |
| }; |
| return ReferenceTransformer; |
| }(ValueTransformer)); |
| var transformedMeta = visitValue(metadata, new ReferenceTransformer(), []); |
| var unwrappedTransformedMeta = unwrapResolvedMetadata(transformedMeta); |
| if (unwrappedTransformedMeta instanceof StaticSymbol) { |
| return this.createExport(sourceSymbol, unwrappedTransformedMeta); |
| } |
| return new ResolvedStaticSymbol(sourceSymbol, transformedMeta); |
| }; |
| StaticSymbolResolver.prototype.createExport = function (sourceSymbol, targetSymbol) { |
| sourceSymbol.assertNoMembers(); |
| targetSymbol.assertNoMembers(); |
| if (this.summaryResolver.isLibraryFile(sourceSymbol.filePath) && |
| this.summaryResolver.isLibraryFile(targetSymbol.filePath)) { |
| // This case is for an ng library importing symbols from a plain ts library |
| // transitively. |
| // Note: We rely on the fact that we discover symbols in the direction |
| // from source files to library files |
| this.importAs.set(targetSymbol, this.getImportAs(sourceSymbol) || sourceSymbol); |
| } |
| return new ResolvedStaticSymbol(sourceSymbol, targetSymbol); |
| }; |
| StaticSymbolResolver.prototype.reportError = function (error, context, path) { |
| if (this.errorRecorder) { |
| this.errorRecorder(error, (context && context.filePath) || path); |
| } |
| else { |
| throw error; |
| } |
| }; |
| /** |
| * @param module an absolute path to a module file. |
| */ |
| StaticSymbolResolver.prototype.getModuleMetadata = function (module) { |
| var moduleMetadata = this.metadataCache.get(module); |
| if (!moduleMetadata) { |
| var moduleMetadatas = this.host.getMetadataFor(module); |
| if (moduleMetadatas) { |
| var maxVersion_1 = -1; |
| moduleMetadatas.forEach(function (md) { |
| if (md && md['version'] > maxVersion_1) { |
| maxVersion_1 = md['version']; |
| moduleMetadata = md; |
| } |
| }); |
| } |
| if (!moduleMetadata) { |
| moduleMetadata = |
| { __symbolic: 'module', version: SUPPORTED_SCHEMA_VERSION, module: module, metadata: {} }; |
| } |
| if (moduleMetadata['version'] != SUPPORTED_SCHEMA_VERSION) { |
| var errorMessage = moduleMetadata['version'] == 2 ? |
| "Unsupported metadata version " + moduleMetadata['version'] + " for module " + module + ". This module should be compiled with a newer version of ngc" : |
| "Metadata version mismatch for module " + this.host.getOutputName(module) + ", found version " + moduleMetadata['version'] + ", expected " + SUPPORTED_SCHEMA_VERSION; |
| this.reportError(new Error(errorMessage)); |
| } |
| this.metadataCache.set(module, moduleMetadata); |
| } |
| return moduleMetadata; |
| }; |
| StaticSymbolResolver.prototype.getSymbolByModule = function (module, symbolName, containingFile) { |
| var filePath = this.resolveModule(module, containingFile); |
| if (!filePath) { |
| this.reportError(new Error("Could not resolve module " + module + (containingFile ? ' relative to ' + this.host.getOutputName(containingFile) : ''))); |
| return this.getStaticSymbol("ERROR:" + module, symbolName); |
| } |
| return this.getStaticSymbol(filePath, symbolName); |
| }; |
| StaticSymbolResolver.prototype.resolveModule = function (module, containingFile) { |
| try { |
| return this.host.moduleNameToFileName(module, containingFile); |
| } |
| catch (e) { |
| console.error("Could not resolve module '" + module + "' relative to file " + containingFile); |
| this.reportError(e, undefined, containingFile); |
| } |
| return null; |
| }; |
| return StaticSymbolResolver; |
| }()); |
| // Remove extra underscore from escaped identifier. |
| // See https://github.com/Microsoft/TypeScript/blob/master/src/compiler/utilities.ts |
| function unescapeIdentifier(identifier) { |
| return identifier.startsWith('___') ? identifier.substr(1) : identifier; |
| } |
| function unwrapResolvedMetadata(metadata) { |
| if (metadata && metadata.__symbolic === 'resolved') { |
| return metadata.symbol; |
| } |
| return metadata; |
| } |
| |
| function serializeSummaries(srcFileName, forJitCtx, summaryResolver, symbolResolver, symbols, types, createExternalSymbolReexports) { |
| if (createExternalSymbolReexports === void 0) { createExternalSymbolReexports = false; } |
| var toJsonSerializer = new ToJsonSerializer(symbolResolver, summaryResolver, srcFileName); |
| // for symbols, we use everything except for the class metadata itself |
| // (we keep the statics though), as the class metadata is contained in the |
| // CompileTypeSummary. |
| symbols.forEach(function (resolvedSymbol) { return toJsonSerializer.addSummary({ symbol: resolvedSymbol.symbol, metadata: resolvedSymbol.metadata }); }); |
| // Add type summaries. |
| types.forEach(function (_a) { |
| var summary = _a.summary, metadata = _a.metadata; |
| toJsonSerializer.addSummary({ symbol: summary.type.reference, metadata: undefined, type: summary }); |
| }); |
| var _a = toJsonSerializer.serialize(createExternalSymbolReexports), json = _a.json, exportAs = _a.exportAs; |
| if (forJitCtx) { |
| var forJitSerializer_1 = new ForJitSerializer(forJitCtx, symbolResolver, summaryResolver); |
| types.forEach(function (_a) { |
| var summary = _a.summary, metadata = _a.metadata; |
| forJitSerializer_1.addSourceType(summary, metadata); |
| }); |
| toJsonSerializer.unprocessedSymbolSummariesBySymbol.forEach(function (summary) { |
| if (summaryResolver.isLibraryFile(summary.symbol.filePath) && summary.type) { |
| forJitSerializer_1.addLibType(summary.type); |
| } |
| }); |
| forJitSerializer_1.serialize(exportAs); |
| } |
| return { json: json, exportAs: exportAs }; |
| } |
| function deserializeSummaries(symbolCache, summaryResolver, libraryFileName, json) { |
| var deserializer = new FromJsonDeserializer(symbolCache, summaryResolver); |
| return deserializer.deserialize(libraryFileName, json); |
| } |
| function createForJitStub(outputCtx, reference) { |
| return createSummaryForJitFunction(outputCtx, reference, NULL_EXPR); |
| } |
| function createSummaryForJitFunction(outputCtx, reference, value) { |
| var fnName = summaryForJitName(reference.name); |
| outputCtx.statements.push(fn([], [new ReturnStatement(value)], new ArrayType(DYNAMIC_TYPE)).toDeclStmt(fnName, [ |
| exports.StmtModifier.Final, exports.StmtModifier.Exported |
| ])); |
| } |
| var ToJsonSerializer = /** @class */ (function (_super) { |
| __extends(ToJsonSerializer, _super); |
| function ToJsonSerializer(symbolResolver, summaryResolver, srcFileName) { |
| var _this = _super.call(this) || this; |
| _this.symbolResolver = symbolResolver; |
| _this.summaryResolver = summaryResolver; |
| _this.srcFileName = srcFileName; |
| // Note: This only contains symbols without members. |
| _this.symbols = []; |
| _this.indexBySymbol = new Map(); |
| _this.reexportedBy = new Map(); |
| // This now contains a `__symbol: number` in the place of |
| // StaticSymbols, but otherwise has the same shape as the original objects. |
| _this.processedSummaryBySymbol = new Map(); |
| _this.processedSummaries = []; |
| _this.unprocessedSymbolSummariesBySymbol = new Map(); |
| _this.moduleName = symbolResolver.getKnownModuleName(srcFileName); |
| return _this; |
| } |
| ToJsonSerializer.prototype.addSummary = function (summary) { |
| var _this = this; |
| var unprocessedSummary = this.unprocessedSymbolSummariesBySymbol.get(summary.symbol); |
| var processedSummary = this.processedSummaryBySymbol.get(summary.symbol); |
| if (!unprocessedSummary) { |
| unprocessedSummary = { symbol: summary.symbol, metadata: undefined }; |
| this.unprocessedSymbolSummariesBySymbol.set(summary.symbol, unprocessedSummary); |
| processedSummary = { symbol: this.processValue(summary.symbol, 0 /* None */) }; |
| this.processedSummaries.push(processedSummary); |
| this.processedSummaryBySymbol.set(summary.symbol, processedSummary); |
| } |
| if (!unprocessedSummary.metadata && summary.metadata) { |
| var metadata_1 = summary.metadata || {}; |
| if (metadata_1.__symbolic === 'class') { |
| // For classes, we keep everything except their class decorators. |
| // We need to keep e.g. the ctor args, method names, method decorators |
| // so that the class can be extended in another compilation unit. |
| // We don't keep the class decorators as |
| // 1) they refer to data |
| // that should not cause a rebuild of downstream compilation units |
| // (e.g. inline templates of @Component, or @NgModule.declarations) |
| // 2) their data is already captured in TypeSummaries, e.g. DirectiveSummary. |
| var clone_1 = {}; |
| Object.keys(metadata_1).forEach(function (propName) { |
| if (propName !== 'decorators') { |
| clone_1[propName] = metadata_1[propName]; |
| } |
| }); |
| metadata_1 = clone_1; |
| } |
| else if (isCall(metadata_1)) { |
| if (!isFunctionCall(metadata_1) && !isMethodCallOnVariable(metadata_1)) { |
| // Don't store complex calls as we won't be able to simplify them anyways later on. |
| metadata_1 = { |
| __symbolic: 'error', |
| message: 'Complex function calls are not supported.', |
| }; |
| } |
| } |
| // Note: We need to keep storing ctor calls for e.g. |
| // `export const x = new InjectionToken(...)` |
| unprocessedSummary.metadata = metadata_1; |
| processedSummary.metadata = this.processValue(metadata_1, 1 /* ResolveValue */); |
| if (metadata_1 instanceof StaticSymbol && |
| this.summaryResolver.isLibraryFile(metadata_1.filePath)) { |
| var declarationSymbol = this.symbols[this.indexBySymbol.get(metadata_1)]; |
| if (!isLoweredSymbol(declarationSymbol.name)) { |
| // Note: symbols that were introduced during codegen in the user file can have a reexport |
| // if a user used `export *`. However, we can't rely on this as tsickle will change |
| // `export *` into named exports, using only the information from the typechecker. |
| // As we introduce the new symbols after typecheck, Tsickle does not know about them, |
| // and omits them when expanding `export *`. |
| // So we have to keep reexporting these symbols manually via .ngfactory files. |
| this.reexportedBy.set(declarationSymbol, summary.symbol); |
| } |
| } |
| } |
| if (!unprocessedSummary.type && summary.type) { |
| unprocessedSummary.type = summary.type; |
| // Note: We don't add the summaries of all referenced symbols as for the ResolvedSymbols, |
| // as the type summaries already contain the transitive data that they require |
| // (in a minimal way). |
| processedSummary.type = this.processValue(summary.type, 0 /* None */); |
| // except for reexported directives / pipes, so we need to store |
| // their summaries explicitly. |
| if (summary.type.summaryKind === exports.CompileSummaryKind.NgModule) { |
| var ngModuleSummary = summary.type; |
| ngModuleSummary.exportedDirectives.concat(ngModuleSummary.exportedPipes).forEach(function (id) { |
| var symbol = id.reference; |
| if (_this.summaryResolver.isLibraryFile(symbol.filePath) && |
| !_this.unprocessedSymbolSummariesBySymbol.has(symbol)) { |
| var summary_1 = _this.summaryResolver.resolveSummary(symbol); |
| if (summary_1) { |
| _this.addSummary(summary_1); |
| } |
| } |
| }); |
| } |
| } |
| }; |
| /** |
| * @param createExternalSymbolReexports Whether external static symbols should be re-exported. |
| * This can be enabled if external symbols should be re-exported by the current module in |
| * order to avoid dynamically generated module dependencies which can break strict dependency |
| * enforcements (as in Google3). Read more here: https://github.com/angular/angular/issues/25644 |
| */ |
| ToJsonSerializer.prototype.serialize = function (createExternalSymbolReexports) { |
| var _this = this; |
| var exportAs = []; |
| var json = JSON.stringify({ |
| moduleName: this.moduleName, |
| summaries: this.processedSummaries, |
| symbols: this.symbols.map(function (symbol, index) { |
| symbol.assertNoMembers(); |
| var importAs = undefined; |
| if (_this.summaryResolver.isLibraryFile(symbol.filePath)) { |
| var reexportSymbol = _this.reexportedBy.get(symbol); |
| if (reexportSymbol) { |
| // In case the given external static symbol is already manually exported by the |
| // user, we just proxy the external static symbol reference to the manual export. |
| // This ensures that the AOT compiler imports the external symbol through the |
| // user export and does not introduce another dependency which is not needed. |
| importAs = _this.indexBySymbol.get(reexportSymbol); |
| } |
| else if (createExternalSymbolReexports) { |
| // In this case, the given external static symbol is *not* manually exported by |
| // the user, and we manually create a re-export in the factory file so that we |
| // don't introduce another module dependency. This is useful when running within |
| // Bazel so that the AOT compiler does not introduce any module dependencies |
| // which can break the strict dependency enforcement. (e.g. as in Google3) |
| // Read more about this here: https://github.com/angular/angular/issues/25644 |
| var summary = _this.unprocessedSymbolSummariesBySymbol.get(symbol); |
| if (!summary || !summary.metadata || summary.metadata.__symbolic !== 'interface') { |
| importAs = symbol.name + "_" + index; |
| exportAs.push({ symbol: symbol, exportAs: importAs }); |
| } |
| } |
| } |
| return { |
| __symbol: index, |
| name: symbol.name, |
| filePath: _this.summaryResolver.toSummaryFileName(symbol.filePath, _this.srcFileName), |
| importAs: importAs |
| }; |
| }) |
| }); |
| return { json: json, exportAs: exportAs }; |
| }; |
| ToJsonSerializer.prototype.processValue = function (value, flags) { |
| return visitValue(value, this, flags); |
| }; |
| ToJsonSerializer.prototype.visitOther = function (value, context) { |
| if (value instanceof StaticSymbol) { |
| var baseSymbol = this.symbolResolver.getStaticSymbol(value.filePath, value.name); |
| var index = this.visitStaticSymbol(baseSymbol, context); |
| return { __symbol: index, members: value.members }; |
| } |
| }; |
| /** |
| * Strip line and character numbers from ngsummaries. |
| * Emitting them causes white spaces changes to retrigger upstream |
| * recompilations in bazel. |
| * TODO: find out a way to have line and character numbers in errors without |
| * excessive recompilation in bazel. |
| */ |
| ToJsonSerializer.prototype.visitStringMap = function (map, context) { |
| if (map['__symbolic'] === 'resolved') { |
| return visitValue(map['symbol'], this, context); |
| } |
| if (map['__symbolic'] === 'error') { |
| delete map['line']; |
| delete map['character']; |
| } |
| return _super.prototype.visitStringMap.call(this, map, context); |
| }; |
| /** |
| * Returns null if the options.resolveValue is true, and the summary for the symbol |
| * resolved to a type or could not be resolved. |
| */ |
| ToJsonSerializer.prototype.visitStaticSymbol = function (baseSymbol, flags) { |
| var index = this.indexBySymbol.get(baseSymbol); |
| var summary = null; |
| if (flags & 1 /* ResolveValue */ && |
| this.summaryResolver.isLibraryFile(baseSymbol.filePath)) { |
| if (this.unprocessedSymbolSummariesBySymbol.has(baseSymbol)) { |
| // the summary for this symbol was already added |
| // -> nothing to do. |
| return index; |
| } |
| summary = this.loadSummary(baseSymbol); |
| if (summary && summary.metadata instanceof StaticSymbol) { |
| // The summary is a reexport |
| index = this.visitStaticSymbol(summary.metadata, flags); |
| // reset the summary as it is just a reexport, so we don't want to store it. |
| summary = null; |
| } |
| } |
| else if (index != null) { |
| // Note: == on purpose to compare with undefined! |
| // No summary and the symbol is already added -> nothing to do. |
| return index; |
| } |
| // Note: == on purpose to compare with undefined! |
| if (index == null) { |
| index = this.symbols.length; |
| this.symbols.push(baseSymbol); |
| } |
| this.indexBySymbol.set(baseSymbol, index); |
| if (summary) { |
| this.addSummary(summary); |
| } |
| return index; |
| }; |
| ToJsonSerializer.prototype.loadSummary = function (symbol) { |
| var summary = this.summaryResolver.resolveSummary(symbol); |
| if (!summary) { |
| // some symbols might originate from a plain typescript library |
| // that just exported .d.ts and .metadata.json files, i.e. where no summary |
| // files were created. |
| var resolvedSymbol = this.symbolResolver.resolveSymbol(symbol); |
| if (resolvedSymbol) { |
| summary = { symbol: resolvedSymbol.symbol, metadata: resolvedSymbol.metadata }; |
| } |
| } |
| return summary; |
| }; |
| return ToJsonSerializer; |
| }(ValueTransformer)); |
| var ForJitSerializer = /** @class */ (function () { |
| function ForJitSerializer(outputCtx, symbolResolver, summaryResolver) { |
| this.outputCtx = outputCtx; |
| this.symbolResolver = symbolResolver; |
| this.summaryResolver = summaryResolver; |
| this.data = []; |
| } |
| ForJitSerializer.prototype.addSourceType = function (summary, metadata) { |
| this.data.push({ summary: summary, metadata: metadata, isLibrary: false }); |
| }; |
| ForJitSerializer.prototype.addLibType = function (summary) { |
| this.data.push({ summary: summary, metadata: null, isLibrary: true }); |
| }; |
| ForJitSerializer.prototype.serialize = function (exportAsArr) { |
| var e_1, _a, e_2, _b, e_3, _c; |
| var _this = this; |
| var exportAsBySymbol = new Map(); |
| try { |
| for (var exportAsArr_1 = __values(exportAsArr), exportAsArr_1_1 = exportAsArr_1.next(); !exportAsArr_1_1.done; exportAsArr_1_1 = exportAsArr_1.next()) { |
| var _d = exportAsArr_1_1.value, symbol = _d.symbol, exportAs = _d.exportAs; |
| exportAsBySymbol.set(symbol, exportAs); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (exportAsArr_1_1 && !exportAsArr_1_1.done && (_a = exportAsArr_1.return)) _a.call(exportAsArr_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| var ngModuleSymbols = new Set(); |
| try { |
| for (var _e = __values(this.data), _f = _e.next(); !_f.done; _f = _e.next()) { |
| var _g = _f.value, summary = _g.summary, metadata = _g.metadata, isLibrary = _g.isLibrary; |
| if (summary.summaryKind === exports.CompileSummaryKind.NgModule) { |
| // collect the symbols that refer to NgModule classes. |
| // Note: we can't just rely on `summary.type.summaryKind` to determine this as |
| // we don't add the summaries of all referenced symbols when we serialize type summaries. |
| // See serializeSummaries for details. |
| ngModuleSymbols.add(summary.type.reference); |
| var modSummary = summary; |
| try { |
| for (var _h = (e_3 = void 0, __values(modSummary.modules)), _j = _h.next(); !_j.done; _j = _h.next()) { |
| var mod = _j.value; |
| ngModuleSymbols.add(mod.reference); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (_j && !_j.done && (_c = _h.return)) _c.call(_h); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| } |
| if (!isLibrary) { |
| var fnName = summaryForJitName(summary.type.reference.name); |
| createSummaryForJitFunction(this.outputCtx, summary.type.reference, this.serializeSummaryWithDeps(summary, metadata)); |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_f && !_f.done && (_b = _e.return)) _b.call(_e); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| ngModuleSymbols.forEach(function (ngModuleSymbol) { |
| if (_this.summaryResolver.isLibraryFile(ngModuleSymbol.filePath)) { |
| var exportAs = exportAsBySymbol.get(ngModuleSymbol) || ngModuleSymbol.name; |
| var jitExportAsName = summaryForJitName(exportAs); |
| _this.outputCtx.statements.push(variable(jitExportAsName) |
| .set(_this.serializeSummaryRef(ngModuleSymbol)) |
| .toDeclStmt(null, [exports.StmtModifier.Exported])); |
| } |
| }); |
| }; |
| ForJitSerializer.prototype.serializeSummaryWithDeps = function (summary, metadata) { |
| var _this = this; |
| var expressions = [this.serializeSummary(summary)]; |
| var providers = []; |
| if (metadata instanceof CompileNgModuleMetadata) { |
| expressions.push.apply(expressions, __spread( |
| // For directives / pipes, we only add the declared ones, |
| // and rely on transitively importing NgModules to get the transitive |
| // summaries. |
| metadata.declaredDirectives.concat(metadata.declaredPipes) |
| .map(function (type) { return type.reference; }) |
| // For modules, |
| // we also add the summaries for modules |
| // from libraries. |
| // This is ok as we produce reexports for all transitive modules. |
| .concat(metadata.transitiveModule.modules.map(function (type) { return type.reference; }) |
| .filter(function (ref) { return ref !== metadata.type.reference; })) |
| .map(function (ref) { return _this.serializeSummaryRef(ref); }))); |
| // Note: We don't use `NgModuleSummary.providers`, as that one is transitive, |
| // and we already have transitive modules. |
| providers = metadata.providers; |
| } |
| else if (summary.summaryKind === exports.CompileSummaryKind.Directive) { |
| var dirSummary = summary; |
| providers = dirSummary.providers.concat(dirSummary.viewProviders); |
| } |
| // Note: We can't just refer to the `ngsummary.ts` files for `useClass` providers (as we do for |
| // declaredDirectives / declaredPipes), as we allow |
| // providers without ctor arguments to skip the `@Injectable` decorator, |
| // i.e. we didn't generate .ngsummary.ts files for these. |
| expressions.push.apply(expressions, __spread(providers.filter(function (provider) { return !!provider.useClass; }).map(function (provider) { return _this.serializeSummary({ |
| summaryKind: exports.CompileSummaryKind.Injectable, |
| type: provider.useClass |
| }); }))); |
| return literalArr(expressions); |
| }; |
| ForJitSerializer.prototype.serializeSummaryRef = function (typeSymbol) { |
| var jitImportedSymbol = this.symbolResolver.getStaticSymbol(summaryForJitFileName(typeSymbol.filePath), summaryForJitName(typeSymbol.name)); |
| return this.outputCtx.importExpr(jitImportedSymbol); |
| }; |
| ForJitSerializer.prototype.serializeSummary = function (data) { |
| var outputCtx = this.outputCtx; |
| var Transformer = /** @class */ (function () { |
| function Transformer() { |
| } |
| Transformer.prototype.visitArray = function (arr, context) { |
| var _this = this; |
| return literalArr(arr.map(function (entry) { return visitValue(entry, _this, context); })); |
| }; |
| Transformer.prototype.visitStringMap = function (map, context) { |
| var _this = this; |
| return new LiteralMapExpr(Object.keys(map).map(function (key) { return new LiteralMapEntry(key, visitValue(map[key], _this, context), false); })); |
| }; |
| Transformer.prototype.visitPrimitive = function (value, context) { |
| return literal(value); |
| }; |
| Transformer.prototype.visitOther = function (value, context) { |
| if (value instanceof StaticSymbol) { |
| return outputCtx.importExpr(value); |
| } |
| else { |
| throw new Error("Illegal State: Encountered value " + value); |
| } |
| }; |
| return Transformer; |
| }()); |
| return visitValue(data, new Transformer(), null); |
| }; |
| return ForJitSerializer; |
| }()); |
| var FromJsonDeserializer = /** @class */ (function (_super) { |
| __extends(FromJsonDeserializer, _super); |
| function FromJsonDeserializer(symbolCache, summaryResolver) { |
| var _this = _super.call(this) || this; |
| _this.symbolCache = symbolCache; |
| _this.summaryResolver = summaryResolver; |
| return _this; |
| } |
| FromJsonDeserializer.prototype.deserialize = function (libraryFileName, json) { |
| var _this = this; |
| var data = JSON.parse(json); |
| var allImportAs = []; |
| this.symbols = data.symbols.map(function (serializedSymbol) { return _this.symbolCache.get(_this.summaryResolver.fromSummaryFileName(serializedSymbol.filePath, libraryFileName), serializedSymbol.name); }); |
| data.symbols.forEach(function (serializedSymbol, index) { |
| var symbol = _this.symbols[index]; |
| var importAs = serializedSymbol.importAs; |
| if (typeof importAs === 'number') { |
| allImportAs.push({ symbol: symbol, importAs: _this.symbols[importAs] }); |
| } |
| else if (typeof importAs === 'string') { |
| allImportAs.push({ symbol: symbol, importAs: _this.symbolCache.get(ngfactoryFilePath(libraryFileName), importAs) }); |
| } |
| }); |
| var summaries = visitValue(data.summaries, this, null); |
| return { moduleName: data.moduleName, summaries: summaries, importAs: allImportAs }; |
| }; |
| FromJsonDeserializer.prototype.visitStringMap = function (map, context) { |
| if ('__symbol' in map) { |
| var baseSymbol = this.symbols[map['__symbol']]; |
| var members = map['members']; |
| return members.length ? this.symbolCache.get(baseSymbol.filePath, baseSymbol.name, members) : |
| baseSymbol; |
| } |
| else { |
| return _super.prototype.visitStringMap.call(this, map, context); |
| } |
| }; |
| return FromJsonDeserializer; |
| }(ValueTransformer)); |
| function isCall(metadata) { |
| return metadata && metadata.__symbolic === 'call'; |
| } |
| function isFunctionCall(metadata) { |
| return isCall(metadata) && unwrapResolvedMetadata(metadata.expression) instanceof StaticSymbol; |
| } |
| function isMethodCallOnVariable(metadata) { |
| return isCall(metadata) && metadata.expression && metadata.expression.__symbolic === 'select' && |
| unwrapResolvedMetadata(metadata.expression.expression) instanceof StaticSymbol; |
| } |
| |
| var AotCompiler = /** @class */ (function () { |
| function AotCompiler(_config, _options, _host, reflector, _metadataResolver, _templateParser, _styleCompiler, _viewCompiler, _typeCheckCompiler, _ngModuleCompiler, _injectableCompiler, _outputEmitter, _summaryResolver, _symbolResolver) { |
| this._config = _config; |
| this._options = _options; |
| this._host = _host; |
| this.reflector = reflector; |
| this._metadataResolver = _metadataResolver; |
| this._templateParser = _templateParser; |
| this._styleCompiler = _styleCompiler; |
| this._viewCompiler = _viewCompiler; |
| this._typeCheckCompiler = _typeCheckCompiler; |
| this._ngModuleCompiler = _ngModuleCompiler; |
| this._injectableCompiler = _injectableCompiler; |
| this._outputEmitter = _outputEmitter; |
| this._summaryResolver = _summaryResolver; |
| this._symbolResolver = _symbolResolver; |
| this._templateAstCache = new Map(); |
| this._analyzedFiles = new Map(); |
| this._analyzedFilesForInjectables = new Map(); |
| } |
| AotCompiler.prototype.clearCache = function () { |
| this._metadataResolver.clearCache(); |
| }; |
| AotCompiler.prototype.analyzeModulesSync = function (rootFiles) { |
| var _this = this; |
| var analyzeResult = analyzeAndValidateNgModules(rootFiles, this._host, this._symbolResolver, this._metadataResolver); |
| analyzeResult.ngModules.forEach(function (ngModule) { return _this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, true); }); |
| return analyzeResult; |
| }; |
| AotCompiler.prototype.analyzeModulesAsync = function (rootFiles) { |
| var _this = this; |
| var analyzeResult = analyzeAndValidateNgModules(rootFiles, this._host, this._symbolResolver, this._metadataResolver); |
| return Promise |
| .all(analyzeResult.ngModules.map(function (ngModule) { return _this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, false); })) |
| .then(function () { return analyzeResult; }); |
| }; |
| AotCompiler.prototype._analyzeFile = function (fileName) { |
| var analyzedFile = this._analyzedFiles.get(fileName); |
| if (!analyzedFile) { |
| analyzedFile = |
| analyzeFile(this._host, this._symbolResolver, this._metadataResolver, fileName); |
| this._analyzedFiles.set(fileName, analyzedFile); |
| } |
| return analyzedFile; |
| }; |
| AotCompiler.prototype._analyzeFileForInjectables = function (fileName) { |
| var analyzedFile = this._analyzedFilesForInjectables.get(fileName); |
| if (!analyzedFile) { |
| analyzedFile = analyzeFileForInjectables(this._host, this._symbolResolver, this._metadataResolver, fileName); |
| this._analyzedFilesForInjectables.set(fileName, analyzedFile); |
| } |
| return analyzedFile; |
| }; |
| AotCompiler.prototype.findGeneratedFileNames = function (fileName) { |
| var _this = this; |
| var genFileNames = []; |
| var file = this._analyzeFile(fileName); |
| // Make sure we create a .ngfactory if we have a injectable/directive/pipe/NgModule |
| // or a reference to a non source file. |
| // Note: This is overestimating the required .ngfactory files as the real calculation is harder. |
| // Only do this for StubEmitFlags.Basic, as adding a type check block |
| // does not change this file (as we generate type check blocks based on NgModules). |
| if (this._options.allowEmptyCodegenFiles || file.directives.length || file.pipes.length || |
| file.injectables.length || file.ngModules.length || file.exportsNonSourceFiles) { |
| genFileNames.push(ngfactoryFilePath(file.fileName, true)); |
| if (this._options.enableSummariesForJit) { |
| genFileNames.push(summaryForJitFileName(file.fileName, true)); |
| } |
| } |
| var fileSuffix = normalizeGenFileSuffix(splitTypescriptSuffix(file.fileName, true)[1]); |
| file.directives.forEach(function (dirSymbol) { |
| var compMeta = _this._metadataResolver.getNonNormalizedDirectiveMetadata(dirSymbol).metadata; |
| if (!compMeta.isComponent) { |
| return; |
| } |
| // Note: compMeta is a component and therefore template is non null. |
| compMeta.template.styleUrls.forEach(function (styleUrl) { |
| var normalizedUrl = _this._host.resourceNameToFileName(styleUrl, file.fileName); |
| if (!normalizedUrl) { |
| throw syntaxError("Couldn't resolve resource " + styleUrl + " relative to " + file.fileName); |
| } |
| var needsShim = (compMeta.template.encapsulation || |
| _this._config.defaultEncapsulation) === ViewEncapsulation.Emulated; |
| genFileNames.push(_stylesModuleUrl(normalizedUrl, needsShim, fileSuffix)); |
| if (_this._options.allowEmptyCodegenFiles) { |
| genFileNames.push(_stylesModuleUrl(normalizedUrl, !needsShim, fileSuffix)); |
| } |
| }); |
| }); |
| return genFileNames; |
| }; |
| AotCompiler.prototype.emitBasicStub = function (genFileName, originalFileName) { |
| var outputCtx = this._createOutputContext(genFileName); |
| if (genFileName.endsWith('.ngfactory.ts')) { |
| if (!originalFileName) { |
| throw new Error("Assertion error: require the original file for .ngfactory.ts stubs. File: " + genFileName); |
| } |
| var originalFile = this._analyzeFile(originalFileName); |
| this._createNgFactoryStub(outputCtx, originalFile, 1 /* Basic */); |
| } |
| else if (genFileName.endsWith('.ngsummary.ts')) { |
| if (this._options.enableSummariesForJit) { |
| if (!originalFileName) { |
| throw new Error("Assertion error: require the original file for .ngsummary.ts stubs. File: " + genFileName); |
| } |
| var originalFile = this._analyzeFile(originalFileName); |
| _createEmptyStub(outputCtx); |
| originalFile.ngModules.forEach(function (ngModule) { |
| // create exports that user code can reference |
| createForJitStub(outputCtx, ngModule.type.reference); |
| }); |
| } |
| } |
| else if (genFileName.endsWith('.ngstyle.ts')) { |
| _createEmptyStub(outputCtx); |
| } |
| // Note: for the stubs, we don't need a property srcFileUrl, |
| // as later on in emitAllImpls we will create the proper GeneratedFiles with the |
| // correct srcFileUrl. |
| // This is good as e.g. for .ngstyle.ts files we can't derive |
| // the url of components based on the genFileUrl. |
| return this._codegenSourceModule('unknown', outputCtx); |
| }; |
| AotCompiler.prototype.emitTypeCheckStub = function (genFileName, originalFileName) { |
| var originalFile = this._analyzeFile(originalFileName); |
| var outputCtx = this._createOutputContext(genFileName); |
| if (genFileName.endsWith('.ngfactory.ts')) { |
| this._createNgFactoryStub(outputCtx, originalFile, 2 /* TypeCheck */); |
| } |
| return outputCtx.statements.length > 0 ? |
| this._codegenSourceModule(originalFile.fileName, outputCtx) : |
| null; |
| }; |
| AotCompiler.prototype.loadFilesAsync = function (fileNames, tsFiles) { |
| var _this = this; |
| var files = fileNames.map(function (fileName) { return _this._analyzeFile(fileName); }); |
| var loadingPromises = []; |
| files.forEach(function (file) { return file.ngModules.forEach(function (ngModule) { return loadingPromises.push(_this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, false)); }); }); |
| var analyzedInjectables = tsFiles.map(function (tsFile) { return _this._analyzeFileForInjectables(tsFile); }); |
| return Promise.all(loadingPromises).then(function (_) { return ({ |
| analyzedModules: mergeAndValidateNgFiles(files), |
| analyzedInjectables: analyzedInjectables, |
| }); }); |
| }; |
| AotCompiler.prototype.loadFilesSync = function (fileNames, tsFiles) { |
| var _this = this; |
| var files = fileNames.map(function (fileName) { return _this._analyzeFile(fileName); }); |
| files.forEach(function (file) { return file.ngModules.forEach(function (ngModule) { return _this._metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, true); }); }); |
| var analyzedInjectables = tsFiles.map(function (tsFile) { return _this._analyzeFileForInjectables(tsFile); }); |
| return { |
| analyzedModules: mergeAndValidateNgFiles(files), |
| analyzedInjectables: analyzedInjectables, |
| }; |
| }; |
| AotCompiler.prototype._createNgFactoryStub = function (outputCtx, file, emitFlags) { |
| var _this = this; |
| var componentId = 0; |
| file.ngModules.forEach(function (ngModuleMeta, ngModuleIndex) { |
| // Note: the code below needs to executed for StubEmitFlags.Basic and StubEmitFlags.TypeCheck, |
| // so we don't change the .ngfactory file too much when adding the type-check block. |
| // create exports that user code can reference |
| _this._ngModuleCompiler.createStub(outputCtx, ngModuleMeta.type.reference); |
| // add references to the symbols from the metadata. |
| // These can be used by the type check block for components, |
| // and they also cause TypeScript to include these files into the program too, |
| // which will make them part of the analyzedFiles. |
| var externalReferences = __spread(ngModuleMeta.transitiveModule.directives.map(function (d) { return d.reference; }), ngModuleMeta.transitiveModule.pipes.map(function (d) { return d.reference; }), ngModuleMeta.importedModules.map(function (m) { return m.type.reference; }), ngModuleMeta.exportedModules.map(function (m) { return m.type.reference; }), _this._externalIdentifierReferences([Identifiers.TemplateRef, Identifiers.ElementRef])); |
| var externalReferenceVars = new Map(); |
| externalReferences.forEach(function (ref, typeIndex) { |
| externalReferenceVars.set(ref, "_decl" + ngModuleIndex + "_" + typeIndex); |
| }); |
| externalReferenceVars.forEach(function (varName, reference) { |
| outputCtx.statements.push(variable(varName) |
| .set(NULL_EXPR.cast(DYNAMIC_TYPE)) |
| .toDeclStmt(expressionType(outputCtx.importExpr(reference, /* typeParams */ null, /* useSummaries */ false)))); |
| }); |
| if (emitFlags & 2 /* TypeCheck */) { |
| // add the type-check block for all components of the NgModule |
| ngModuleMeta.declaredDirectives.forEach(function (dirId) { |
| var compMeta = _this._metadataResolver.getDirectiveMetadata(dirId.reference); |
| if (!compMeta.isComponent) { |
| return; |
| } |
| componentId++; |
| _this._createTypeCheckBlock(outputCtx, compMeta.type.reference.name + "_Host_" + componentId, ngModuleMeta, _this._metadataResolver.getHostComponentMetadata(compMeta), [compMeta.type], externalReferenceVars); |
| _this._createTypeCheckBlock(outputCtx, compMeta.type.reference.name + "_" + componentId, ngModuleMeta, compMeta, ngModuleMeta.transitiveModule.directives, externalReferenceVars); |
| }); |
| } |
| }); |
| if (outputCtx.statements.length === 0) { |
| _createEmptyStub(outputCtx); |
| } |
| }; |
| AotCompiler.prototype._externalIdentifierReferences = function (references) { |
| var e_1, _a; |
| var result = []; |
| try { |
| for (var references_1 = __values(references), references_1_1 = references_1.next(); !references_1_1.done; references_1_1 = references_1.next()) { |
| var reference = references_1_1.value; |
| var token = createTokenForExternalReference(this.reflector, reference); |
| if (token.identifier) { |
| result.push(token.identifier.reference); |
| } |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (references_1_1 && !references_1_1.done && (_a = references_1.return)) _a.call(references_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| return result; |
| }; |
| AotCompiler.prototype._createTypeCheckBlock = function (ctx, componentId, moduleMeta, compMeta, directives, externalReferenceVars) { |
| var _a; |
| var _b = this._parseTemplate(compMeta, moduleMeta, directives), parsedTemplate = _b.template, usedPipes = _b.pipes; |
| (_a = ctx.statements).push.apply(_a, __spread(this._typeCheckCompiler.compileComponent(componentId, compMeta, parsedTemplate, usedPipes, externalReferenceVars, ctx))); |
| }; |
| AotCompiler.prototype.emitMessageBundle = function (analyzeResult, locale) { |
| var _this = this; |
| var errors = []; |
| var htmlParser = new HtmlParser(); |
| // TODO(vicb): implicit tags & attributes |
| var messageBundle = new MessageBundle(htmlParser, [], {}, locale); |
| analyzeResult.files.forEach(function (file) { |
| var compMetas = []; |
| file.directives.forEach(function (directiveType) { |
| var dirMeta = _this._metadataResolver.getDirectiveMetadata(directiveType); |
| if (dirMeta && dirMeta.isComponent) { |
| compMetas.push(dirMeta); |
| } |
| }); |
| compMetas.forEach(function (compMeta) { |
| var html = compMeta.template.template; |
| // Template URL points to either an HTML or TS file depending on whether |
| // the file is used with `templateUrl:` or `template:`, respectively. |
| var templateUrl = compMeta.template.templateUrl; |
| var interpolationConfig = InterpolationConfig.fromArray(compMeta.template.interpolation); |
| errors.push.apply(errors, __spread(messageBundle.updateFromTemplate(html, templateUrl, interpolationConfig))); |
| }); |
| }); |
| if (errors.length) { |
| throw new Error(errors.map(function (e) { return e.toString(); }).join('\n')); |
| } |
| return messageBundle; |
| }; |
| AotCompiler.prototype.emitAllPartialModules2 = function (files) { |
| var _this = this; |
| // Using reduce like this is a select many pattern (where map is a select pattern) |
| return files.reduce(function (r, file) { |
| r.push.apply(r, __spread(_this._emitPartialModule2(file.fileName, file.injectables))); |
| return r; |
| }, []); |
| }; |
| AotCompiler.prototype._emitPartialModule2 = function (fileName, injectables) { |
| var _this = this; |
| var context = this._createOutputContext(fileName); |
| injectables.forEach(function (injectable) { return _this._injectableCompiler.compile(injectable, context); }); |
| if (context.statements && context.statements.length > 0) { |
| return [{ fileName: fileName, statements: __spread(context.constantPool.statements, context.statements) }]; |
| } |
| return []; |
| }; |
| AotCompiler.prototype.emitAllImpls = function (analyzeResult) { |
| var _this = this; |
| var ngModuleByPipeOrDirective = analyzeResult.ngModuleByPipeOrDirective, files = analyzeResult.files; |
| var sourceModules = files.map(function (file) { return _this._compileImplFile(file.fileName, ngModuleByPipeOrDirective, file.directives, file.pipes, file.ngModules, file.injectables); }); |
| return flatten(sourceModules); |
| }; |
| AotCompiler.prototype._compileImplFile = function (srcFileUrl, ngModuleByPipeOrDirective, directives, pipes, ngModules, injectables) { |
| var _this = this; |
| var fileSuffix = normalizeGenFileSuffix(splitTypescriptSuffix(srcFileUrl, true)[1]); |
| var generatedFiles = []; |
| var outputCtx = this._createOutputContext(ngfactoryFilePath(srcFileUrl, true)); |
| generatedFiles.push.apply(generatedFiles, __spread(this._createSummary(srcFileUrl, directives, pipes, ngModules, injectables, outputCtx))); |
| // compile all ng modules |
| ngModules.forEach(function (ngModuleMeta) { return _this._compileModule(outputCtx, ngModuleMeta); }); |
| // compile components |
| directives.forEach(function (dirType) { |
| var compMeta = _this._metadataResolver.getDirectiveMetadata(dirType); |
| if (!compMeta.isComponent) { |
| return; |
| } |
| var ngModule = ngModuleByPipeOrDirective.get(dirType); |
| if (!ngModule) { |
| throw new Error("Internal Error: cannot determine the module for component " + identifierName(compMeta.type) + "!"); |
| } |
| // compile styles |
| var componentStylesheet = _this._styleCompiler.compileComponent(outputCtx, compMeta); |
| // Note: compMeta is a component and therefore template is non null. |
| compMeta.template.externalStylesheets.forEach(function (stylesheetMeta) { |
| // Note: fill non shim and shim style files as they might |
| // be shared by component with and without ViewEncapsulation. |
| var shim = _this._styleCompiler.needsStyleShim(compMeta); |
| generatedFiles.push(_this._codegenStyles(srcFileUrl, compMeta, stylesheetMeta, shim, fileSuffix)); |
| if (_this._options.allowEmptyCodegenFiles) { |
| generatedFiles.push(_this._codegenStyles(srcFileUrl, compMeta, stylesheetMeta, !shim, fileSuffix)); |
| } |
| }); |
| // compile components |
| var compViewVars = _this._compileComponent(outputCtx, compMeta, ngModule, ngModule.transitiveModule.directives, componentStylesheet, fileSuffix); |
| _this._compileComponentFactory(outputCtx, compMeta, ngModule, fileSuffix); |
| }); |
| if (outputCtx.statements.length > 0 || this._options.allowEmptyCodegenFiles) { |
| var srcModule = this._codegenSourceModule(srcFileUrl, outputCtx); |
| generatedFiles.unshift(srcModule); |
| } |
| return generatedFiles; |
| }; |
| AotCompiler.prototype._createSummary = function (srcFileName, directives, pipes, ngModules, injectables, ngFactoryCtx) { |
| var _this = this; |
| var symbolSummaries = this._symbolResolver.getSymbolsOf(srcFileName) |
| .map(function (symbol) { return _this._symbolResolver.resolveSymbol(symbol); }); |
| var typeData = __spread(ngModules.map(function (meta) { return ({ |
| summary: _this._metadataResolver.getNgModuleSummary(meta.type.reference), |
| metadata: _this._metadataResolver.getNgModuleMetadata(meta.type.reference) |
| }); }), directives.map(function (ref) { return ({ |
| summary: _this._metadataResolver.getDirectiveSummary(ref), |
| metadata: _this._metadataResolver.getDirectiveMetadata(ref) |
| }); }), pipes.map(function (ref) { return ({ |
| summary: _this._metadataResolver.getPipeSummary(ref), |
| metadata: _this._metadataResolver.getPipeMetadata(ref) |
| }); }), injectables.map(function (ref) { return ({ |
| summary: _this._metadataResolver.getInjectableSummary(ref.symbol), |
| metadata: _this._metadataResolver.getInjectableSummary(ref.symbol).type |
| }); })); |
| var forJitOutputCtx = this._options.enableSummariesForJit ? |
| this._createOutputContext(summaryForJitFileName(srcFileName, true)) : |
| null; |
| var _a = serializeSummaries(srcFileName, forJitOutputCtx, this._summaryResolver, this._symbolResolver, symbolSummaries, typeData, this._options.createExternalSymbolFactoryReexports), json = _a.json, exportAs = _a.exportAs; |
| exportAs.forEach(function (entry) { |
| ngFactoryCtx.statements.push(variable(entry.exportAs).set(ngFactoryCtx.importExpr(entry.symbol)).toDeclStmt(null, [ |
| exports.StmtModifier.Exported |
| ])); |
| }); |
| var summaryJson = new GeneratedFile(srcFileName, summaryFileName(srcFileName), json); |
| var result = [summaryJson]; |
| if (forJitOutputCtx) { |
| result.push(this._codegenSourceModule(srcFileName, forJitOutputCtx)); |
| } |
| return result; |
| }; |
| AotCompiler.prototype._compileModule = function (outputCtx, ngModule) { |
| var providers = []; |
| if (this._options.locale) { |
| var normalizedLocale = this._options.locale.replace(/_/g, '-'); |
| providers.push({ |
| token: createTokenForExternalReference(this.reflector, Identifiers.LOCALE_ID), |
| useValue: normalizedLocale, |
| }); |
| } |
| if (this._options.i18nFormat) { |
| providers.push({ |
| token: createTokenForExternalReference(this.reflector, Identifiers.TRANSLATIONS_FORMAT), |
| useValue: this._options.i18nFormat |
| }); |
| } |
| this._ngModuleCompiler.compile(outputCtx, ngModule, providers); |
| }; |
| AotCompiler.prototype._compileComponentFactory = function (outputCtx, compMeta, ngModule, fileSuffix) { |
| var hostMeta = this._metadataResolver.getHostComponentMetadata(compMeta); |
| var hostViewFactoryVar = this._compileComponent(outputCtx, hostMeta, ngModule, [compMeta.type], null, fileSuffix) |
| .viewClassVar; |
| var compFactoryVar = componentFactoryName(compMeta.type.reference); |
| var inputsExprs = []; |
| for (var propName in compMeta.inputs) { |
| var templateName = compMeta.inputs[propName]; |
| // Don't quote so that the key gets minified... |
| inputsExprs.push(new LiteralMapEntry(propName, literal(templateName), false)); |
| } |
| var outputsExprs = []; |
| for (var propName in compMeta.outputs) { |
| var templateName = compMeta.outputs[propName]; |
| // Don't quote so that the key gets minified... |
| outputsExprs.push(new LiteralMapEntry(propName, literal(templateName), false)); |
| } |
| outputCtx.statements.push(variable(compFactoryVar) |
| .set(importExpr(Identifiers.createComponentFactory).callFn([ |
| literal(compMeta.selector), outputCtx.importExpr(compMeta.type.reference), |
| variable(hostViewFactoryVar), new LiteralMapExpr(inputsExprs), |
| new LiteralMapExpr(outputsExprs), |
| literalArr(compMeta.template.ngContentSelectors.map(function (selector) { return literal(selector); })) |
| ])) |
| .toDeclStmt(importType(Identifiers.ComponentFactory, [expressionType(outputCtx.importExpr(compMeta.type.reference))], [TypeModifier.Const]), [exports.StmtModifier.Final, exports.StmtModifier.Exported])); |
| }; |
| AotCompiler.prototype._compileComponent = function (outputCtx, compMeta, ngModule, directiveIdentifiers, componentStyles, fileSuffix) { |
| var _a = this._parseTemplate(compMeta, ngModule, directiveIdentifiers), parsedTemplate = _a.template, usedPipes = _a.pipes; |
| var stylesExpr = componentStyles ? variable(componentStyles.stylesVar) : literalArr([]); |
| var viewResult = this._viewCompiler.compileComponent(outputCtx, compMeta, parsedTemplate, stylesExpr, usedPipes); |
| if (componentStyles) { |
| _resolveStyleStatements(this._symbolResolver, componentStyles, this._styleCompiler.needsStyleShim(compMeta), fileSuffix); |
| } |
| return viewResult; |
| }; |
| AotCompiler.prototype._parseTemplate = function (compMeta, ngModule, directiveIdentifiers) { |
| var _this = this; |
| if (this._templateAstCache.has(compMeta.type.reference)) { |
| return this._templateAstCache.get(compMeta.type.reference); |
| } |
| var preserveWhitespaces = compMeta.template.preserveWhitespaces; |
| var directives = directiveIdentifiers.map(function (dir) { return _this._metadataResolver.getDirectiveSummary(dir.reference); }); |
| var pipes = ngModule.transitiveModule.pipes.map(function (pipe) { return _this._metadataResolver.getPipeSummary(pipe.reference); }); |
| var result = this._templateParser.parse(compMeta, compMeta.template.htmlAst, directives, pipes, ngModule.schemas, templateSourceUrl(ngModule.type, compMeta, compMeta.template), preserveWhitespaces); |
| this._templateAstCache.set(compMeta.type.reference, result); |
| return result; |
| }; |
| AotCompiler.prototype._createOutputContext = function (genFilePath) { |
| var _this = this; |
| var importExpr$1 = function (symbol, typeParams, useSummaries) { |
| if (typeParams === void 0) { typeParams = null; } |
| if (useSummaries === void 0) { useSummaries = true; } |
| if (!(symbol instanceof StaticSymbol)) { |
| throw new Error("Internal error: unknown identifier " + JSON.stringify(symbol)); |
| } |
| var arity = _this._symbolResolver.getTypeArity(symbol) || 0; |
| var _a = _this._symbolResolver.getImportAs(symbol, useSummaries) || symbol, filePath = _a.filePath, name = _a.name, members = _a.members; |
| var importModule = _this._fileNameToModuleName(filePath, genFilePath); |
| // It should be good enough to compare filePath to genFilePath and if they are equal |
| // there is a self reference. However, ngfactory files generate to .ts but their |
| // symbols have .d.ts so a simple compare is insufficient. They should be canonical |
| // and is tracked by #17705. |
| var selfReference = _this._fileNameToModuleName(genFilePath, genFilePath); |
| var moduleName = importModule === selfReference ? null : importModule; |
| // If we are in a type expression that refers to a generic type then supply |
| // the required type parameters. If there were not enough type parameters |
| // supplied, supply any as the type. Outside a type expression the reference |
| // should not supply type parameters and be treated as a simple value reference |
| // to the constructor function itself. |
| var suppliedTypeParams = typeParams || []; |
| var missingTypeParamsCount = arity - suppliedTypeParams.length; |
| var allTypeParams = suppliedTypeParams.concat(newArray(missingTypeParamsCount, DYNAMIC_TYPE)); |
| return members.reduce(function (expr, memberName) { return expr.prop(memberName); }, importExpr(new ExternalReference(moduleName, name, null), allTypeParams)); |
| }; |
| return { statements: [], genFilePath: genFilePath, importExpr: importExpr$1, constantPool: new ConstantPool() }; |
| }; |
| AotCompiler.prototype._fileNameToModuleName = function (importedFilePath, containingFilePath) { |
| return this._summaryResolver.getKnownModuleName(importedFilePath) || |
| this._symbolResolver.getKnownModuleName(importedFilePath) || |
| this._host.fileNameToModuleName(importedFilePath, containingFilePath); |
| }; |
| AotCompiler.prototype._codegenStyles = function (srcFileUrl, compMeta, stylesheetMetadata, isShimmed, fileSuffix) { |
| var outputCtx = this._createOutputContext(_stylesModuleUrl(stylesheetMetadata.moduleUrl, isShimmed, fileSuffix)); |
| var compiledStylesheet = this._styleCompiler.compileStyles(outputCtx, compMeta, stylesheetMetadata, isShimmed); |
| _resolveStyleStatements(this._symbolResolver, compiledStylesheet, isShimmed, fileSuffix); |
| return this._codegenSourceModule(srcFileUrl, outputCtx); |
| }; |
| AotCompiler.prototype._codegenSourceModule = function (srcFileUrl, ctx) { |
| return new GeneratedFile(srcFileUrl, ctx.genFilePath, ctx.statements); |
| }; |
| AotCompiler.prototype.listLazyRoutes = function (entryRoute, analyzedModules) { |
| var e_2, _a, e_3, _b; |
| var self = this; |
| if (entryRoute) { |
| var symbol = parseLazyRoute(entryRoute, this.reflector).referencedModule; |
| return visitLazyRoute(symbol); |
| } |
| else if (analyzedModules) { |
| var allLazyRoutes = []; |
| try { |
| for (var _c = __values(analyzedModules.ngModules), _d = _c.next(); !_d.done; _d = _c.next()) { |
| var ngModule = _d.value; |
| var lazyRoutes = listLazyRoutes(ngModule, this.reflector); |
| try { |
| for (var lazyRoutes_1 = (e_3 = void 0, __values(lazyRoutes)), lazyRoutes_1_1 = lazyRoutes_1.next(); !lazyRoutes_1_1.done; lazyRoutes_1_1 = lazyRoutes_1.next()) { |
| var lazyRoute = lazyRoutes_1_1.value; |
| allLazyRoutes.push(lazyRoute); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (lazyRoutes_1_1 && !lazyRoutes_1_1.done && (_b = lazyRoutes_1.return)) _b.call(lazyRoutes_1); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (_d && !_d.done && (_a = _c.return)) _a.call(_c); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| return allLazyRoutes; |
| } |
| else { |
| throw new Error("Either route or analyzedModules has to be specified!"); |
| } |
| function visitLazyRoute(symbol, seenRoutes, allLazyRoutes) { |
| var e_4, _a; |
| if (seenRoutes === void 0) { seenRoutes = new Set(); } |
| if (allLazyRoutes === void 0) { allLazyRoutes = []; } |
| // Support pointing to default exports, but stop recursing there, |
| // as the StaticReflector does not yet support default exports. |
| if (seenRoutes.has(symbol) || !symbol.name) { |
| return allLazyRoutes; |
| } |
| seenRoutes.add(symbol); |
| var lazyRoutes = listLazyRoutes(self._metadataResolver.getNgModuleMetadata(symbol, true), self.reflector); |
| try { |
| for (var lazyRoutes_2 = __values(lazyRoutes), lazyRoutes_2_1 = lazyRoutes_2.next(); !lazyRoutes_2_1.done; lazyRoutes_2_1 = lazyRoutes_2.next()) { |
| var lazyRoute = lazyRoutes_2_1.value; |
| allLazyRoutes.push(lazyRoute); |
| visitLazyRoute(lazyRoute.referencedModule, seenRoutes, allLazyRoutes); |
| } |
| } |
| catch (e_4_1) { e_4 = { error: e_4_1 }; } |
| finally { |
| try { |
| if (lazyRoutes_2_1 && !lazyRoutes_2_1.done && (_a = lazyRoutes_2.return)) _a.call(lazyRoutes_2); |
| } |
| finally { if (e_4) throw e_4.error; } |
| } |
| return allLazyRoutes; |
| } |
| }; |
| return AotCompiler; |
| }()); |
| function _createEmptyStub(outputCtx) { |
| // Note: We need to produce at least one import statement so that |
| // TypeScript knows that the file is an es6 module. Otherwise our generated |
| // exports / imports won't be emitted properly by TypeScript. |
| outputCtx.statements.push(importExpr(Identifiers.ComponentFactory).toStmt()); |
| } |
| function _resolveStyleStatements(symbolResolver, compileResult, needsShim, fileSuffix) { |
| compileResult.dependencies.forEach(function (dep) { |
| dep.setValue(symbolResolver.getStaticSymbol(_stylesModuleUrl(dep.moduleUrl, needsShim, fileSuffix), dep.name)); |
| }); |
| } |
| function _stylesModuleUrl(stylesheetUrl, shim, suffix) { |
| return "" + stylesheetUrl + (shim ? '.shim' : '') + ".ngstyle" + suffix; |
| } |
| function analyzeNgModules(fileNames, host, staticSymbolResolver, metadataResolver) { |
| var files = _analyzeFilesIncludingNonProgramFiles(fileNames, host, staticSymbolResolver, metadataResolver); |
| return mergeAnalyzedFiles(files); |
| } |
| function analyzeAndValidateNgModules(fileNames, host, staticSymbolResolver, metadataResolver) { |
| return validateAnalyzedModules(analyzeNgModules(fileNames, host, staticSymbolResolver, metadataResolver)); |
| } |
| function validateAnalyzedModules(analyzedModules) { |
| if (analyzedModules.symbolsMissingModule && analyzedModules.symbolsMissingModule.length) { |
| var messages = analyzedModules.symbolsMissingModule.map(function (s) { return "Cannot determine the module for class " + s.name + " in " + s.filePath + "! Add " + s.name + " to the NgModule to fix it."; }); |
| throw syntaxError(messages.join('\n')); |
| } |
| return analyzedModules; |
| } |
| // Analyzes all of the program files, |
| // including files that are not part of the program |
| // but are referenced by an NgModule. |
| function _analyzeFilesIncludingNonProgramFiles(fileNames, host, staticSymbolResolver, metadataResolver) { |
| var seenFiles = new Set(); |
| var files = []; |
| var visitFile = function (fileName) { |
| if (seenFiles.has(fileName) || !host.isSourceFile(fileName)) { |
| return false; |
| } |
| seenFiles.add(fileName); |
| var analyzedFile = analyzeFile(host, staticSymbolResolver, metadataResolver, fileName); |
| files.push(analyzedFile); |
| analyzedFile.ngModules.forEach(function (ngModule) { |
| ngModule.transitiveModule.modules.forEach(function (modMeta) { return visitFile(modMeta.reference.filePath); }); |
| }); |
| }; |
| fileNames.forEach(function (fileName) { return visitFile(fileName); }); |
| return files; |
| } |
| function analyzeFile(host, staticSymbolResolver, metadataResolver, fileName) { |
| var abstractDirectives = []; |
| var directives = []; |
| var pipes = []; |
| var injectables = []; |
| var ngModules = []; |
| var hasDecorators = staticSymbolResolver.hasDecorators(fileName); |
| var exportsNonSourceFiles = false; |
| var isDeclarationFile = fileName.endsWith('.d.ts'); |
| // Don't analyze .d.ts files that have no decorators as a shortcut |
| // to speed up the analysis. This prevents us from |
| // resolving the references in these files. |
| // Note: exportsNonSourceFiles is only needed when compiling with summaries, |
| // which is not the case when .d.ts files are treated as input files. |
| if (!isDeclarationFile || hasDecorators) { |
| staticSymbolResolver.getSymbolsOf(fileName).forEach(function (symbol) { |
| var resolvedSymbol = staticSymbolResolver.resolveSymbol(symbol); |
| var symbolMeta = resolvedSymbol.metadata; |
| if (!symbolMeta || symbolMeta.__symbolic === 'error') { |
| return; |
| } |
| var isNgSymbol = false; |
| if (symbolMeta.__symbolic === 'class') { |
| if (metadataResolver.isDirective(symbol)) { |
| isNgSymbol = true; |
| // This directive either has a selector or doesn't. Selector-less directives get tracked |
| // in abstractDirectives, not directives. The compiler doesn't deal with selector-less |
| // directives at all, really, other than to persist their metadata. This is done so that |
| // apps will have an easier time migrating to Ivy, which requires the selector-less |
| // annotations to be applied. |
| if (!metadataResolver.isAbstractDirective(symbol)) { |
| // The directive is an ordinary directive. |
| directives.push(symbol); |
| } |
| else { |
| // The directive has no selector and is an "abstract" directive, so track it |
| // accordingly. |
| abstractDirectives.push(symbol); |
| } |
| } |
| else if (metadataResolver.isPipe(symbol)) { |
| isNgSymbol = true; |
| pipes.push(symbol); |
| } |
| else if (metadataResolver.isNgModule(symbol)) { |
| var ngModule = metadataResolver.getNgModuleMetadata(symbol, false); |
| if (ngModule) { |
| isNgSymbol = true; |
| ngModules.push(ngModule); |
| } |
| } |
| else if (metadataResolver.isInjectable(symbol)) { |
| isNgSymbol = true; |
| var injectable = metadataResolver.getInjectableMetadata(symbol, null, false); |
| if (injectable) { |
| injectables.push(injectable); |
| } |
| } |
| } |
| if (!isNgSymbol) { |
| exportsNonSourceFiles = |
| exportsNonSourceFiles || isValueExportingNonSourceFile(host, symbolMeta); |
| } |
| }); |
| } |
| return { |
| fileName: fileName, |
| directives: directives, |
| abstractDirectives: abstractDirectives, |
| pipes: pipes, |
| ngModules: ngModules, |
| injectables: injectables, |
| exportsNonSourceFiles: exportsNonSourceFiles, |
| }; |
| } |
| function analyzeFileForInjectables(host, staticSymbolResolver, metadataResolver, fileName) { |
| var injectables = []; |
| var shallowModules = []; |
| if (staticSymbolResolver.hasDecorators(fileName)) { |
| staticSymbolResolver.getSymbolsOf(fileName).forEach(function (symbol) { |
| var resolvedSymbol = staticSymbolResolver.resolveSymbol(symbol); |
| var symbolMeta = resolvedSymbol.metadata; |
| if (!symbolMeta || symbolMeta.__symbolic === 'error') { |
| return; |
| } |
| if (symbolMeta.__symbolic === 'class') { |
| if (metadataResolver.isInjectable(symbol)) { |
| var injectable = metadataResolver.getInjectableMetadata(symbol, null, false); |
| if (injectable) { |
| injectables.push(injectable); |
| } |
| } |
| else if (metadataResolver.isNgModule(symbol)) { |
| var module = metadataResolver.getShallowModuleMetadata(symbol); |
| if (module) { |
| shallowModules.push(module); |
| } |
| } |
| } |
| }); |
| } |
| return { fileName: fileName, injectables: injectables, shallowModules: shallowModules }; |
| } |
| function isValueExportingNonSourceFile(host, metadata) { |
| var exportsNonSourceFiles = false; |
| var Visitor = /** @class */ (function () { |
| function Visitor() { |
| } |
| Visitor.prototype.visitArray = function (arr, context) { |
| var _this = this; |
| arr.forEach(function (v) { return visitValue(v, _this, context); }); |
| }; |
| Visitor.prototype.visitStringMap = function (map, context) { |
| var _this = this; |
| Object.keys(map).forEach(function (key) { return visitValue(map[key], _this, context); }); |
| }; |
| Visitor.prototype.visitPrimitive = function (value, context) { }; |
| Visitor.prototype.visitOther = function (value, context) { |
| if (value instanceof StaticSymbol && !host.isSourceFile(value.filePath)) { |
| exportsNonSourceFiles = true; |
| } |
| }; |
| return Visitor; |
| }()); |
| visitValue(metadata, new Visitor(), null); |
| return exportsNonSourceFiles; |
| } |
| function mergeAnalyzedFiles(analyzedFiles) { |
| var allNgModules = []; |
| var ngModuleByPipeOrDirective = new Map(); |
| var allPipesAndDirectives = new Set(); |
| analyzedFiles.forEach(function (af) { |
| af.ngModules.forEach(function (ngModule) { |
| allNgModules.push(ngModule); |
| ngModule.declaredDirectives.forEach(function (d) { return ngModuleByPipeOrDirective.set(d.reference, ngModule); }); |
| ngModule.declaredPipes.forEach(function (p) { return ngModuleByPipeOrDirective.set(p.reference, ngModule); }); |
| }); |
| af.directives.forEach(function (d) { return allPipesAndDirectives.add(d); }); |
| af.pipes.forEach(function (p) { return allPipesAndDirectives.add(p); }); |
| }); |
| var symbolsMissingModule = []; |
| allPipesAndDirectives.forEach(function (ref) { |
| if (!ngModuleByPipeOrDirective.has(ref)) { |
| symbolsMissingModule.push(ref); |
| } |
| }); |
| return { |
| ngModules: allNgModules, |
| ngModuleByPipeOrDirective: ngModuleByPipeOrDirective, |
| symbolsMissingModule: symbolsMissingModule, |
| files: analyzedFiles |
| }; |
| } |
| function mergeAndValidateNgFiles(files) { |
| return validateAnalyzedModules(mergeAnalyzedFiles(files)); |
| } |
| |
| var FORMATTED_MESSAGE = 'ngFormattedMessage'; |
| function indentStr(level) { |
| if (level <= 0) |
| return ''; |
| if (level < 6) |
| return ['', ' ', ' ', ' ', ' ', ' '][level]; |
| var half = indentStr(Math.floor(level / 2)); |
| return half + half + (level % 2 === 1 ? ' ' : ''); |
| } |
| function formatChain(chain, indent) { |
| var e_1, _a; |
| if (indent === void 0) { indent = 0; } |
| if (!chain) |
| return ''; |
| var position = chain.position ? |
| chain.position.fileName + "(" + (chain.position.line + 1) + "," + (chain.position.column + 1) + ")" : |
| ''; |
| var prefix = position && indent === 0 ? position + ": " : ''; |
| var postfix = position && indent !== 0 ? " at " + position : ''; |
| var message = "" + prefix + chain.message + postfix; |
| if (chain.next) { |
| try { |
| for (var _b = __values(chain.next), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var kid = _c.value; |
| message += '\n' + formatChain(kid, indent + 2); |
| } |
| } |
| 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 "" + indentStr(indent) + message; |
| } |
| function formattedError(chain) { |
| var message = formatChain(chain) + '.'; |
| var error = syntaxError(message); |
| error[FORMATTED_MESSAGE] = true; |
| error.chain = chain; |
| error.position = chain.position; |
| return error; |
| } |
| function isFormattedError(error) { |
| return !!error[FORMATTED_MESSAGE]; |
| } |
| |
| var ANGULAR_CORE = '@angular/core'; |
| var ANGULAR_ROUTER = '@angular/router'; |
| var HIDDEN_KEY = /^\$.*\$$/; |
| var IGNORE = { |
| __symbolic: 'ignore' |
| }; |
| var USE_VALUE$1 = 'useValue'; |
| var PROVIDE = 'provide'; |
| var REFERENCE_SET = new Set([USE_VALUE$1, 'useFactory', 'data', 'id', 'loadChildren']); |
| var TYPEGUARD_POSTFIX = 'TypeGuard'; |
| var USE_IF = 'UseIf'; |
| function shouldIgnore(value) { |
| return value && value.__symbolic == 'ignore'; |
| } |
| /** |
| * A static reflector implements enough of the Reflector API that is necessary to compile |
| * templates statically. |
| */ |
| var StaticReflector = /** @class */ (function () { |
| function StaticReflector(summaryResolver, symbolResolver, knownMetadataClasses, knownMetadataFunctions, errorRecorder) { |
| var _this = this; |
| if (knownMetadataClasses === void 0) { knownMetadataClasses = []; } |
| if (knownMetadataFunctions === void 0) { knownMetadataFunctions = []; } |
| this.summaryResolver = summaryResolver; |
| this.symbolResolver = symbolResolver; |
| this.errorRecorder = errorRecorder; |
| this.annotationCache = new Map(); |
| this.shallowAnnotationCache = new Map(); |
| this.propertyCache = new Map(); |
| this.parameterCache = new Map(); |
| this.methodCache = new Map(); |
| this.staticCache = new Map(); |
| this.conversionMap = new Map(); |
| this.resolvedExternalReferences = new Map(); |
| this.annotationForParentClassWithSummaryKind = new Map(); |
| this.initializeConversionMap(); |
| knownMetadataClasses.forEach(function (kc) { return _this._registerDecoratorOrConstructor(_this.getStaticSymbol(kc.filePath, kc.name), kc.ctor); }); |
| knownMetadataFunctions.forEach(function (kf) { return _this._registerFunction(_this.getStaticSymbol(kf.filePath, kf.name), kf.fn); }); |
| this.annotationForParentClassWithSummaryKind.set(exports.CompileSummaryKind.Directive, [createDirective, createComponent]); |
| this.annotationForParentClassWithSummaryKind.set(exports.CompileSummaryKind.Pipe, [createPipe]); |
| this.annotationForParentClassWithSummaryKind.set(exports.CompileSummaryKind.NgModule, [createNgModule]); |
| this.annotationForParentClassWithSummaryKind.set(exports.CompileSummaryKind.Injectable, [createInjectable, createPipe, createDirective, createComponent, createNgModule]); |
| } |
| StaticReflector.prototype.componentModuleUrl = function (typeOrFunc) { |
| var staticSymbol = this.findSymbolDeclaration(typeOrFunc); |
| return this.symbolResolver.getResourcePath(staticSymbol); |
| }; |
| /** |
| * Invalidate the specified `symbols` on program change. |
| * @param symbols |
| */ |
| StaticReflector.prototype.invalidateSymbols = function (symbols) { |
| var e_1, _a; |
| try { |
| for (var symbols_1 = __values(symbols), symbols_1_1 = symbols_1.next(); !symbols_1_1.done; symbols_1_1 = symbols_1.next()) { |
| var symbol = symbols_1_1.value; |
| this.annotationCache.delete(symbol); |
| this.shallowAnnotationCache.delete(symbol); |
| this.propertyCache.delete(symbol); |
| this.parameterCache.delete(symbol); |
| this.methodCache.delete(symbol); |
| this.staticCache.delete(symbol); |
| this.conversionMap.delete(symbol); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (symbols_1_1 && !symbols_1_1.done && (_a = symbols_1.return)) _a.call(symbols_1); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| }; |
| StaticReflector.prototype.resolveExternalReference = function (ref, containingFile) { |
| var key = undefined; |
| if (!containingFile) { |
| key = ref.moduleName + ":" + ref.name; |
| var declarationSymbol_1 = this.resolvedExternalReferences.get(key); |
| if (declarationSymbol_1) |
| return declarationSymbol_1; |
| } |
| var refSymbol = this.symbolResolver.getSymbolByModule(ref.moduleName, ref.name, containingFile); |
| var declarationSymbol = this.findSymbolDeclaration(refSymbol); |
| if (!containingFile) { |
| this.symbolResolver.recordModuleNameForFileName(refSymbol.filePath, ref.moduleName); |
| this.symbolResolver.recordImportAs(declarationSymbol, refSymbol); |
| } |
| if (key) { |
| this.resolvedExternalReferences.set(key, declarationSymbol); |
| } |
| return declarationSymbol; |
| }; |
| StaticReflector.prototype.findDeclaration = function (moduleUrl, name, containingFile) { |
| return this.findSymbolDeclaration(this.symbolResolver.getSymbolByModule(moduleUrl, name, containingFile)); |
| }; |
| StaticReflector.prototype.tryFindDeclaration = function (moduleUrl, name, containingFile) { |
| var _this = this; |
| return this.symbolResolver.ignoreErrorsFor(function () { return _this.findDeclaration(moduleUrl, name, containingFile); }); |
| }; |
| StaticReflector.prototype.findSymbolDeclaration = function (symbol) { |
| var resolvedSymbol = this.symbolResolver.resolveSymbol(symbol); |
| if (resolvedSymbol) { |
| var resolvedMetadata = resolvedSymbol.metadata; |
| if (resolvedMetadata && resolvedMetadata.__symbolic === 'resolved') { |
| resolvedMetadata = resolvedMetadata.symbol; |
| } |
| if (resolvedMetadata instanceof StaticSymbol) { |
| return this.findSymbolDeclaration(resolvedSymbol.metadata); |
| } |
| } |
| return symbol; |
| }; |
| StaticReflector.prototype.tryAnnotations = function (type) { |
| var originalRecorder = this.errorRecorder; |
| this.errorRecorder = function (error, fileName) { }; |
| try { |
| return this.annotations(type); |
| } |
| finally { |
| this.errorRecorder = originalRecorder; |
| } |
| }; |
| StaticReflector.prototype.annotations = function (type) { |
| var _this = this; |
| return this._annotations(type, function (type, decorators) { return _this.simplify(type, decorators); }, this.annotationCache); |
| }; |
| StaticReflector.prototype.shallowAnnotations = function (type) { |
| var _this = this; |
| return this._annotations(type, function (type, decorators) { return _this.simplify(type, decorators, true); }, this.shallowAnnotationCache); |
| }; |
| StaticReflector.prototype._annotations = function (type, simplify, annotationCache) { |
| var annotations = annotationCache.get(type); |
| if (!annotations) { |
| annotations = []; |
| var classMetadata = this.getTypeMetadata(type); |
| var parentType = this.findParentType(type, classMetadata); |
| if (parentType) { |
| var parentAnnotations = this.annotations(parentType); |
| annotations.push.apply(annotations, __spread(parentAnnotations)); |
| } |
| var ownAnnotations_1 = []; |
| if (classMetadata['decorators']) { |
| ownAnnotations_1 = simplify(type, classMetadata['decorators']); |
| if (ownAnnotations_1) { |
| annotations.push.apply(annotations, __spread(ownAnnotations_1)); |
| } |
| } |
| if (parentType && !this.summaryResolver.isLibraryFile(type.filePath) && |
| this.summaryResolver.isLibraryFile(parentType.filePath)) { |
| var summary = this.summaryResolver.resolveSummary(parentType); |
| if (summary && summary.type) { |
| var requiredAnnotationTypes = this.annotationForParentClassWithSummaryKind.get(summary.type.summaryKind); |
| var typeHasRequiredAnnotation = requiredAnnotationTypes.some(function (requiredType) { return ownAnnotations_1.some(function (ann) { return requiredType.isTypeOf(ann); }); }); |
| if (!typeHasRequiredAnnotation) { |
| this.reportError(formatMetadataError(metadataError("Class " + type.name + " in " + type.filePath + " extends from a " + exports.CompileSummaryKind[summary.type.summaryKind] + " in another compilation unit without duplicating the decorator", |
| /* summary */ undefined, "Please add a " + requiredAnnotationTypes.map(function (type) { return type.ngMetadataName; }) |
| .join(' or ') + " decorator to the class"), type), type); |
| } |
| } |
| } |
| annotationCache.set(type, annotations.filter(function (ann) { return !!ann; })); |
| } |
| return annotations; |
| }; |
| StaticReflector.prototype.propMetadata = function (type) { |
| var _this = this; |
| var propMetadata = this.propertyCache.get(type); |
| if (!propMetadata) { |
| var classMetadata = this.getTypeMetadata(type); |
| propMetadata = {}; |
| var parentType = this.findParentType(type, classMetadata); |
| if (parentType) { |
| var parentPropMetadata_1 = this.propMetadata(parentType); |
| Object.keys(parentPropMetadata_1).forEach(function (parentProp) { |
| propMetadata[parentProp] = parentPropMetadata_1[parentProp]; |
| }); |
| } |
| var members_1 = classMetadata['members'] || {}; |
| Object.keys(members_1).forEach(function (propName) { |
| var propData = members_1[propName]; |
| var prop = propData |
| .find(function (a) { return a['__symbolic'] == 'property' || a['__symbolic'] == 'method'; }); |
| var decorators = []; |
| // hasOwnProperty() is used here to make sure we do not look up methods |
| // on `Object.prototype`. |
| if (propMetadata === null || propMetadata === void 0 ? void 0 : propMetadata.hasOwnProperty(propName)) { |
| decorators.push.apply(decorators, __spread(propMetadata[propName])); |
| } |
| propMetadata[propName] = decorators; |
| if (prop && prop['decorators']) { |
| decorators.push.apply(decorators, __spread(_this.simplify(type, prop['decorators']))); |
| } |
| }); |
| this.propertyCache.set(type, propMetadata); |
| } |
| return propMetadata; |
| }; |
| StaticReflector.prototype.parameters = function (type) { |
| var _this = this; |
| if (!(type instanceof StaticSymbol)) { |
| this.reportError(new Error("parameters received " + JSON.stringify(type) + " which is not a StaticSymbol"), type); |
| return []; |
| } |
| try { |
| var parameters_1 = this.parameterCache.get(type); |
| if (!parameters_1) { |
| var classMetadata = this.getTypeMetadata(type); |
| var parentType = this.findParentType(type, classMetadata); |
| var members = classMetadata ? classMetadata['members'] : null; |
| var ctorData = members ? members['__ctor__'] : null; |
| if (ctorData) { |
| var ctor = ctorData.find(function (a) { return a['__symbolic'] == 'constructor'; }); |
| var rawParameterTypes = ctor['parameters'] || []; |
| var parameterDecorators_1 = this.simplify(type, ctor['parameterDecorators'] || []); |
| parameters_1 = []; |
| rawParameterTypes.forEach(function (rawParamType, index) { |
| var nestedResult = []; |
| var paramType = _this.trySimplify(type, rawParamType); |
| if (paramType) |
| nestedResult.push(paramType); |
| var decorators = parameterDecorators_1 ? parameterDecorators_1[index] : null; |
| if (decorators) { |
| nestedResult.push.apply(nestedResult, __spread(decorators)); |
| } |
| parameters_1.push(nestedResult); |
| }); |
| } |
| else if (parentType) { |
| parameters_1 = this.parameters(parentType); |
| } |
| if (!parameters_1) { |
| parameters_1 = []; |
| } |
| this.parameterCache.set(type, parameters_1); |
| } |
| return parameters_1; |
| } |
| catch (e) { |
| console.error("Failed on type " + JSON.stringify(type) + " with error " + e); |
| throw e; |
| } |
| }; |
| StaticReflector.prototype._methodNames = function (type) { |
| var methodNames = this.methodCache.get(type); |
| if (!methodNames) { |
| var classMetadata = this.getTypeMetadata(type); |
| methodNames = {}; |
| var parentType = this.findParentType(type, classMetadata); |
| if (parentType) { |
| var parentMethodNames_1 = this._methodNames(parentType); |
| Object.keys(parentMethodNames_1).forEach(function (parentProp) { |
| methodNames[parentProp] = parentMethodNames_1[parentProp]; |
| }); |
| } |
| var members_2 = classMetadata['members'] || {}; |
| Object.keys(members_2).forEach(function (propName) { |
| var propData = members_2[propName]; |
| var isMethod = propData.some(function (a) { return a['__symbolic'] == 'method'; }); |
| methodNames[propName] = methodNames[propName] || isMethod; |
| }); |
| this.methodCache.set(type, methodNames); |
| } |
| return methodNames; |
| }; |
| StaticReflector.prototype._staticMembers = function (type) { |
| var staticMembers = this.staticCache.get(type); |
| if (!staticMembers) { |
| var classMetadata = this.getTypeMetadata(type); |
| var staticMemberData = classMetadata['statics'] || {}; |
| staticMembers = Object.keys(staticMemberData); |
| this.staticCache.set(type, staticMembers); |
| } |
| return staticMembers; |
| }; |
| StaticReflector.prototype.findParentType = function (type, classMetadata) { |
| var parentType = this.trySimplify(type, classMetadata['extends']); |
| if (parentType instanceof StaticSymbol) { |
| return parentType; |
| } |
| }; |
| StaticReflector.prototype.hasLifecycleHook = function (type, lcProperty) { |
| if (!(type instanceof StaticSymbol)) { |
| this.reportError(new Error("hasLifecycleHook received " + JSON.stringify(type) + " which is not a StaticSymbol"), type); |
| } |
| try { |
| return !!this._methodNames(type)[lcProperty]; |
| } |
| catch (e) { |
| console.error("Failed on type " + JSON.stringify(type) + " with error " + e); |
| throw e; |
| } |
| }; |
| StaticReflector.prototype.guards = function (type) { |
| var e_2, _a; |
| if (!(type instanceof StaticSymbol)) { |
| this.reportError(new Error("guards received " + JSON.stringify(type) + " which is not a StaticSymbol"), type); |
| return {}; |
| } |
| var staticMembers = this._staticMembers(type); |
| var result = {}; |
| try { |
| for (var staticMembers_1 = __values(staticMembers), staticMembers_1_1 = staticMembers_1.next(); !staticMembers_1_1.done; staticMembers_1_1 = staticMembers_1.next()) { |
| var name = staticMembers_1_1.value; |
| if (name.endsWith(TYPEGUARD_POSTFIX)) { |
| var property = name.substr(0, name.length - TYPEGUARD_POSTFIX.length); |
| var value = void 0; |
| if (property.endsWith(USE_IF)) { |
| property = name.substr(0, property.length - USE_IF.length); |
| value = USE_IF; |
| } |
| else { |
| value = this.getStaticSymbol(type.filePath, type.name, [name]); |
| } |
| result[property] = value; |
| } |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (staticMembers_1_1 && !staticMembers_1_1.done && (_a = staticMembers_1.return)) _a.call(staticMembers_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| return result; |
| }; |
| StaticReflector.prototype._registerDecoratorOrConstructor = function (type, ctor) { |
| this.conversionMap.set(type, function (context, args) { return new (ctor.bind.apply(ctor, __spread([void 0], args)))(); }); |
| }; |
| StaticReflector.prototype._registerFunction = function (type, fn) { |
| this.conversionMap.set(type, function (context, args) { return fn.apply(undefined, args); }); |
| }; |
| StaticReflector.prototype.initializeConversionMap = function () { |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Injectable'), createInjectable); |
| this.injectionToken = this.findDeclaration(ANGULAR_CORE, 'InjectionToken'); |
| this.opaqueToken = this.findDeclaration(ANGULAR_CORE, 'OpaqueToken'); |
| this.ROUTES = this.tryFindDeclaration(ANGULAR_ROUTER, 'ROUTES'); |
| this.ANALYZE_FOR_ENTRY_COMPONENTS = |
| this.findDeclaration(ANGULAR_CORE, 'ANALYZE_FOR_ENTRY_COMPONENTS'); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), createHost); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), createSelf); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), createSkipSelf); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Inject'), createInject); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Optional'), createOptional); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Attribute'), createAttribute); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ContentChild'), createContentChild); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ContentChildren'), createContentChildren); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ViewChild'), createViewChild); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ViewChildren'), createViewChildren); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Input'), createInput); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Output'), createOutput); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Pipe'), createPipe); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'HostBinding'), createHostBinding); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'HostListener'), createHostListener); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Directive'), createDirective); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Component'), createComponent); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'NgModule'), createNgModule); |
| // Note: Some metadata classes can be used directly with Provider.deps. |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), createHost); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), createSelf); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), createSkipSelf); |
| this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Optional'), createOptional); |
| }; |
| /** |
| * getStaticSymbol produces a Type whose metadata is known but whose implementation is not loaded. |
| * All types passed to the StaticResolver should be pseudo-types returned by this method. |
| * |
| * @param declarationFile the absolute path of the file where the symbol is declared |
| * @param name the name of the type. |
| */ |
| StaticReflector.prototype.getStaticSymbol = function (declarationFile, name, members) { |
| return this.symbolResolver.getStaticSymbol(declarationFile, name, members); |
| }; |
| /** |
| * Simplify but discard any errors |
| */ |
| StaticReflector.prototype.trySimplify = function (context, value) { |
| var originalRecorder = this.errorRecorder; |
| this.errorRecorder = function (error, fileName) { }; |
| var result = this.simplify(context, value); |
| this.errorRecorder = originalRecorder; |
| return result; |
| }; |
| /** @internal */ |
| StaticReflector.prototype.simplify = function (context, value, lazy) { |
| if (lazy === void 0) { lazy = false; } |
| var self = this; |
| var scope = BindingScope$1.empty; |
| var calling = new Map(); |
| var rootContext = context; |
| function simplifyInContext(context, value, depth, references) { |
| function resolveReferenceValue(staticSymbol) { |
| var resolvedSymbol = self.symbolResolver.resolveSymbol(staticSymbol); |
| return resolvedSymbol ? resolvedSymbol.metadata : null; |
| } |
| function simplifyEagerly(value) { |
| return simplifyInContext(context, value, depth, 0); |
| } |
| function simplifyLazily(value) { |
| return simplifyInContext(context, value, depth, references + 1); |
| } |
| function simplifyNested(nestedContext, value) { |
| if (nestedContext === context) { |
| // If the context hasn't changed let the exception propagate unmodified. |
| return simplifyInContext(nestedContext, value, depth + 1, references); |
| } |
| try { |
| return simplifyInContext(nestedContext, value, depth + 1, references); |
| } |
| catch (e) { |
| if (isMetadataError(e)) { |
| // Propagate the message text up but add a message to the chain that explains how we got |
| // here. |
| // e.chain implies e.symbol |
| var summaryMsg = e.chain ? 'references \'' + e.symbol.name + '\'' : errorSummary(e); |
| var summary = "'" + nestedContext.name + "' " + summaryMsg; |
| var chain = { message: summary, position: e.position, next: e.chain }; |
| // TODO(chuckj): retrieve the position information indirectly from the collectors node |
| // map if the metadata is from a .ts file. |
| self.error({ |
| message: e.message, |
| advise: e.advise, |
| context: e.context, |
| chain: chain, |
| symbol: nestedContext |
| }, context); |
| } |
| else { |
| // It is probably an internal error. |
| throw e; |
| } |
| } |
| } |
| function simplifyCall(functionSymbol, targetFunction, args, targetExpression) { |
| if (targetFunction && targetFunction['__symbolic'] == 'function') { |
| if (calling.get(functionSymbol)) { |
| self.error({ |
| message: 'Recursion is not supported', |
| summary: "called '" + functionSymbol.name + "' recursively", |
| value: targetFunction |
| }, functionSymbol); |
| } |
| try { |
| var value_1 = targetFunction['value']; |
| if (value_1 && (depth != 0 || value_1.__symbolic != 'error')) { |
| var parameters = targetFunction['parameters']; |
| var defaults = targetFunction.defaults; |
| args = args.map(function (arg) { return simplifyNested(context, arg); }) |
| .map(function (arg) { return shouldIgnore(arg) ? undefined : arg; }); |
| if (defaults && defaults.length > args.length) { |
| args.push.apply(args, __spread(defaults.slice(args.length).map(function (value) { return simplify(value); }))); |
| } |
| calling.set(functionSymbol, true); |
| var functionScope = BindingScope$1.build(); |
| for (var i = 0; i < parameters.length; i++) { |
| functionScope.define(parameters[i], args[i]); |
| } |
| var oldScope = scope; |
| var result_1; |
| try { |
| scope = functionScope.done(); |
| result_1 = simplifyNested(functionSymbol, value_1); |
| } |
| finally { |
| scope = oldScope; |
| } |
| return result_1; |
| } |
| } |
| finally { |
| calling.delete(functionSymbol); |
| } |
| } |
| if (depth === 0) { |
| // If depth is 0 we are evaluating the top level expression that is describing element |
| // decorator. In this case, it is a decorator we don't understand, such as a custom |
| // non-angular decorator, and we should just ignore it. |
| return IGNORE; |
| } |
| var position = undefined; |
| if (targetExpression && targetExpression.__symbolic == 'resolved') { |
| var line = targetExpression.line; |
| var character = targetExpression.character; |
| var fileName = targetExpression.fileName; |
| if (fileName != null && line != null && character != null) { |
| position = { fileName: fileName, line: line, column: character }; |
| } |
| } |
| self.error({ |
| message: FUNCTION_CALL_NOT_SUPPORTED, |
| context: functionSymbol, |
| value: targetFunction, |
| position: position |
| }, context); |
| } |
| function simplify(expression) { |
| var e_3, _a, e_4, _b; |
| if (isPrimitive(expression)) { |
| return expression; |
| } |
| if (Array.isArray(expression)) { |
| var result_2 = []; |
| try { |
| for (var expression_1 = __values(expression), expression_1_1 = expression_1.next(); !expression_1_1.done; expression_1_1 = expression_1.next()) { |
| var item = expression_1_1.value; |
| // Check for a spread expression |
| if (item && item.__symbolic === 'spread') { |
| // We call with references as 0 because we require the actual value and cannot |
| // tolerate a reference here. |
| var spreadArray = simplifyEagerly(item.expression); |
| if (Array.isArray(spreadArray)) { |
| try { |
| for (var spreadArray_1 = (e_4 = void 0, __values(spreadArray)), spreadArray_1_1 = spreadArray_1.next(); !spreadArray_1_1.done; spreadArray_1_1 = spreadArray_1.next()) { |
| var spreadItem = spreadArray_1_1.value; |
| result_2.push(spreadItem); |
| } |
| } |
| catch (e_4_1) { e_4 = { error: e_4_1 }; } |
| finally { |
| try { |
| if (spreadArray_1_1 && !spreadArray_1_1.done && (_b = spreadArray_1.return)) _b.call(spreadArray_1); |
| } |
| finally { if (e_4) throw e_4.error; } |
| } |
| continue; |
| } |
| } |
| var value_2 = simplify(item); |
| if (shouldIgnore(value_2)) { |
| continue; |
| } |
| result_2.push(value_2); |
| } |
| } |
| catch (e_3_1) { e_3 = { error: e_3_1 }; } |
| finally { |
| try { |
| if (expression_1_1 && !expression_1_1.done && (_a = expression_1.return)) _a.call(expression_1); |
| } |
| finally { if (e_3) throw e_3.error; } |
| } |
| return result_2; |
| } |
| if (expression instanceof StaticSymbol) { |
| // Stop simplification at builtin symbols or if we are in a reference context and |
| // the symbol doesn't have members. |
| if (expression === self.injectionToken || self.conversionMap.has(expression) || |
| (references > 0 && !expression.members.length)) { |
| return expression; |
| } |
| else { |
| var staticSymbol = expression; |
| var declarationValue = resolveReferenceValue(staticSymbol); |
| if (declarationValue != null) { |
| return simplifyNested(staticSymbol, declarationValue); |
| } |
| else { |
| return staticSymbol; |
| } |
| } |
| } |
| if (expression) { |
| if (expression['__symbolic']) { |
| var staticSymbol = void 0; |
| switch (expression['__symbolic']) { |
| case 'binop': |
| var left = simplify(expression['left']); |
| if (shouldIgnore(left)) |
| return left; |
| var right = simplify(expression['right']); |
| if (shouldIgnore(right)) |
| return right; |
| switch (expression['operator']) { |
| case '&&': |
| return left && right; |
| case '||': |
| return left || right; |
| case '|': |
| return left | right; |
| case '^': |
| return left ^ right; |
| case '&': |
| return left & right; |
| case '==': |
| return left == right; |
| case '!=': |
| return left != right; |
| case '===': |
| return left === right; |
| case '!==': |
| return left !== right; |
| case '<': |
| return left < right; |
| case '>': |
| return left > right; |
| case '<=': |
| return left <= right; |
| case '>=': |
| return left >= right; |
| case '<<': |
| return left << right; |
| case '>>': |
| return left >> right; |
| case '+': |
| return left + right; |
| case '-': |
| return left - right; |
| case '*': |
| return left * right; |
| case '/': |
| return left / right; |
| case '%': |
| return left % right; |
| } |
| return null; |
| case 'if': |
| var condition = simplify(expression['condition']); |
| return condition ? simplify(expression['thenExpression']) : |
| simplify(expression['elseExpression']); |
| case 'pre': |
| var operand = simplify(expression['operand']); |
| if (shouldIgnore(operand)) |
| return operand; |
| switch (expression['operator']) { |
| case '+': |
| return operand; |
| case '-': |
| return -operand; |
| case '!': |
| return !operand; |
| case '~': |
| return ~operand; |
| } |
| return null; |
| case 'index': |
| var indexTarget = simplifyEagerly(expression['expression']); |
| var index = simplifyEagerly(expression['index']); |
| if (indexTarget && isPrimitive(index)) |
| return indexTarget[index]; |
| return null; |
| case 'select': |
| var member = expression['member']; |
| var selectContext = context; |
| var selectTarget = simplify(expression['expression']); |
| if (selectTarget instanceof StaticSymbol) { |
| var members = selectTarget.members.concat(member); |
| selectContext = |
| self.getStaticSymbol(selectTarget.filePath, selectTarget.name, members); |
| var declarationValue = resolveReferenceValue(selectContext); |
| if (declarationValue != null) { |
| return simplifyNested(selectContext, declarationValue); |
| } |
| else { |
| return selectContext; |
| } |
| } |
| if (selectTarget && isPrimitive(member)) |
| return simplifyNested(selectContext, selectTarget[member]); |
| return null; |
| case 'reference': |
| // Note: This only has to deal with variable references, as symbol references have |
| // been converted into 'resolved' |
| // in the StaticSymbolResolver. |
| var name = expression['name']; |
| var localValue = scope.resolve(name); |
| if (localValue != BindingScope$1.missing) { |
| return localValue; |
| } |
| break; |
| case 'resolved': |
| try { |
| return simplify(expression.symbol); |
| } |
| catch (e) { |
| // If an error is reported evaluating the symbol record the position of the |
| // reference in the error so it can |
| // be reported in the error message generated from the exception. |
| if (isMetadataError(e) && expression.fileName != null && |
| expression.line != null && expression.character != null) { |
| e.position = { |
| fileName: expression.fileName, |
| line: expression.line, |
| column: expression.character |
| }; |
| } |
| throw e; |
| } |
| case 'class': |
| return context; |
| case 'function': |
| return context; |
| case 'new': |
| case 'call': |
| // Determine if the function is a built-in conversion |
| staticSymbol = simplifyInContext(context, expression['expression'], depth + 1, /* references */ 0); |
| if (staticSymbol instanceof StaticSymbol) { |
| if (staticSymbol === self.injectionToken || staticSymbol === self.opaqueToken) { |
| // if somebody calls new InjectionToken, don't create an InjectionToken, |
| // but rather return the symbol to which the InjectionToken is assigned to. |
| // OpaqueToken is supported too as it is required by the language service to |
| // support v4 and prior versions of Angular. |
| return context; |
| } |
| var argExpressions = expression['arguments'] || []; |
| var converter = self.conversionMap.get(staticSymbol); |
| if (converter) { |
| var args = argExpressions.map(function (arg) { return simplifyNested(context, arg); }) |
| .map(function (arg) { return shouldIgnore(arg) ? undefined : arg; }); |
| return converter(context, args); |
| } |
| else { |
| // Determine if the function is one we can simplify. |
| var targetFunction = resolveReferenceValue(staticSymbol); |
| return simplifyCall(staticSymbol, targetFunction, argExpressions, expression['expression']); |
| } |
| } |
| return IGNORE; |
| case 'error': |
| var message = expression.message; |
| if (expression['line'] != null) { |
| self.error({ |
| message: message, |
| context: expression.context, |
| value: expression, |
| position: { |
| fileName: expression['fileName'], |
| line: expression['line'], |
| column: expression['character'] |
| } |
| }, context); |
| } |
| else { |
| self.error({ message: message, context: expression.context }, context); |
| } |
| return IGNORE; |
| case 'ignore': |
| return expression; |
| } |
| return null; |
| } |
| return mapStringMap(expression, function (value, name) { |
| if (REFERENCE_SET.has(name)) { |
| if (name === USE_VALUE$1 && PROVIDE in expression) { |
| // If this is a provider expression, check for special tokens that need the value |
| // during analysis. |
| var provide = simplify(expression.provide); |
| if (provide === self.ROUTES || provide == self.ANALYZE_FOR_ENTRY_COMPONENTS) { |
| return simplify(value); |
| } |
| } |
| return simplifyLazily(value); |
| } |
| return simplify(value); |
| }); |
| } |
| return IGNORE; |
| } |
| return simplify(value); |
| } |
| var result; |
| try { |
| result = simplifyInContext(context, value, 0, lazy ? 1 : 0); |
| } |
| catch (e) { |
| if (this.errorRecorder) { |
| this.reportError(e, context); |
| } |
| else { |
| throw formatMetadataError(e, context); |
| } |
| } |
| if (shouldIgnore(result)) { |
| return undefined; |
| } |
| return result; |
| }; |
| StaticReflector.prototype.getTypeMetadata = function (type) { |
| var resolvedSymbol = this.symbolResolver.resolveSymbol(type); |
| return resolvedSymbol && resolvedSymbol.metadata ? resolvedSymbol.metadata : |
| { __symbolic: 'class' }; |
| }; |
| StaticReflector.prototype.reportError = function (error, context, path) { |
| if (this.errorRecorder) { |
| this.errorRecorder(formatMetadataError(error, context), (context && context.filePath) || path); |
| } |
| else { |
| throw error; |
| } |
| }; |
| StaticReflector.prototype.error = function (_a, reportingContext) { |
| var message = _a.message, summary = _a.summary, advise = _a.advise, position = _a.position, context = _a.context, value = _a.value, symbol = _a.symbol, chain = _a.chain; |
| this.reportError(metadataError(message, summary, advise, position, symbol, context, chain), reportingContext); |
| }; |
| return StaticReflector; |
| }()); |
| var METADATA_ERROR = 'ngMetadataError'; |
| function metadataError(message, summary, advise, position, symbol, context, chain) { |
| var error = syntaxError(message); |
| error[METADATA_ERROR] = true; |
| if (advise) |
| error.advise = advise; |
| if (position) |
| error.position = position; |
| if (summary) |
| error.summary = summary; |
| if (context) |
| error.context = context; |
| if (chain) |
| error.chain = chain; |
| if (symbol) |
| error.symbol = symbol; |
| return error; |
| } |
| function isMetadataError(error) { |
| return !!error[METADATA_ERROR]; |
| } |
| var REFERENCE_TO_NONEXPORTED_CLASS = 'Reference to non-exported class'; |
| var VARIABLE_NOT_INITIALIZED = 'Variable not initialized'; |
| var DESTRUCTURE_NOT_SUPPORTED = 'Destructuring not supported'; |
| var COULD_NOT_RESOLVE_TYPE = 'Could not resolve type'; |
| var FUNCTION_CALL_NOT_SUPPORTED = 'Function call not supported'; |
| var REFERENCE_TO_LOCAL_SYMBOL = 'Reference to a local symbol'; |
| var LAMBDA_NOT_SUPPORTED = 'Lambda not supported'; |
| function expandedMessage(message, context) { |
| switch (message) { |
| case REFERENCE_TO_NONEXPORTED_CLASS: |
| if (context && context.className) { |
| return "References to a non-exported class are not supported in decorators but " + context.className + " was referenced."; |
| } |
| break; |
| case VARIABLE_NOT_INITIALIZED: |
| return 'Only initialized variables and constants can be referenced in decorators because the value of this variable is needed by the template compiler'; |
| case DESTRUCTURE_NOT_SUPPORTED: |
| return 'Referencing an exported destructured variable or constant is not supported in decorators and this value is needed by the template compiler'; |
| case COULD_NOT_RESOLVE_TYPE: |
| if (context && context.typeName) { |
| return "Could not resolve type " + context.typeName; |
| } |
| break; |
| case FUNCTION_CALL_NOT_SUPPORTED: |
| if (context && context.name) { |
| return "Function calls are not supported in decorators but '" + context.name + "' was called"; |
| } |
| return 'Function calls are not supported in decorators'; |
| case REFERENCE_TO_LOCAL_SYMBOL: |
| if (context && context.name) { |
| return "Reference to a local (non-exported) symbols are not supported in decorators but '" + context.name + "' was referenced"; |
| } |
| break; |
| case LAMBDA_NOT_SUPPORTED: |
| return "Function expressions are not supported in decorators"; |
| } |
| return message; |
| } |
| function messageAdvise(message, context) { |
| switch (message) { |
| case REFERENCE_TO_NONEXPORTED_CLASS: |
| if (context && context.className) { |
| return "Consider exporting '" + context.className + "'"; |
| } |
| break; |
| case DESTRUCTURE_NOT_SUPPORTED: |
| return 'Consider simplifying to avoid destructuring'; |
| case REFERENCE_TO_LOCAL_SYMBOL: |
| if (context && context.name) { |
| return "Consider exporting '" + context.name + "'"; |
| } |
| break; |
| case LAMBDA_NOT_SUPPORTED: |
| return "Consider changing the function expression into an exported function"; |
| } |
| return undefined; |
| } |
| function errorSummary(error) { |
| if (error.summary) { |
| return error.summary; |
| } |
| switch (error.message) { |
| case REFERENCE_TO_NONEXPORTED_CLASS: |
| if (error.context && error.context.className) { |
| return "references non-exported class " + error.context.className; |
| } |
| break; |
| case VARIABLE_NOT_INITIALIZED: |
| return 'is not initialized'; |
| case DESTRUCTURE_NOT_SUPPORTED: |
| return 'is a destructured variable'; |
| case COULD_NOT_RESOLVE_TYPE: |
| return 'could not be resolved'; |
| case FUNCTION_CALL_NOT_SUPPORTED: |
| if (error.context && error.context.name) { |
| return "calls '" + error.context.name + "'"; |
| } |
| return "calls a function"; |
| case REFERENCE_TO_LOCAL_SYMBOL: |
| if (error.context && error.context.name) { |
| return "references local variable " + error.context.name; |
| } |
| return "references a local variable"; |
| } |
| return 'contains the error'; |
| } |
| function mapStringMap(input, transform) { |
| if (!input) |
| return {}; |
| var result = {}; |
| Object.keys(input).forEach(function (key) { |
| var value = transform(input[key], key); |
| if (!shouldIgnore(value)) { |
| if (HIDDEN_KEY.test(key)) { |
| Object.defineProperty(result, key, { enumerable: false, configurable: true, value: value }); |
| } |
| else { |
| result[key] = value; |
| } |
| } |
| }); |
| return result; |
| } |
| function isPrimitive(o) { |
| return o === null || (typeof o !== 'function' && typeof o !== 'object'); |
| } |
| var BindingScope$1 = /** @class */ (function () { |
| function BindingScope() { |
| } |
| BindingScope.build = function () { |
| var current = new Map(); |
| return { |
| define: function (name, value) { |
| current.set(name, value); |
| return this; |
| }, |
| done: function () { |
| return current.size > 0 ? new PopulatedScope(current) : BindingScope.empty; |
| } |
| }; |
| }; |
| return BindingScope; |
| }()); |
| BindingScope$1.missing = {}; |
| BindingScope$1.empty = { resolve: function (name) { return BindingScope$1.missing; } }; |
| var PopulatedScope = /** @class */ (function (_super) { |
| __extends(PopulatedScope, _super); |
| function PopulatedScope(bindings) { |
| var _this = _super.call(this) || this; |
| _this.bindings = bindings; |
| return _this; |
| } |
| PopulatedScope.prototype.resolve = function (name) { |
| return this.bindings.has(name) ? this.bindings.get(name) : BindingScope$1.missing; |
| }; |
| return PopulatedScope; |
| }(BindingScope$1)); |
| function formatMetadataMessageChain(chain, advise) { |
| var expanded = expandedMessage(chain.message, chain.context); |
| var nesting = chain.symbol ? " in '" + chain.symbol.name + "'" : ''; |
| var message = "" + expanded + nesting; |
| var position = chain.position; |
| var next = chain.next ? |
| formatMetadataMessageChain(chain.next, advise) : |
| advise ? { message: advise } : undefined; |
| return { message: message, position: position, next: next ? [next] : undefined }; |
| } |
| function formatMetadataError(e, context) { |
| if (isMetadataError(e)) { |
| // Produce a formatted version of the and leaving enough information in the original error |
| // to recover the formatting information to eventually produce a diagnostic error message. |
| var position = e.position; |
| var chain = { |
| message: "Error during template compile of '" + context.name + "'", |
| position: position, |
| next: { message: e.message, next: e.chain, context: e.context, symbol: e.symbol } |
| }; |
| var advise = e.advise || messageAdvise(e.message, e.context); |
| return formattedError(formatMetadataMessageChain(chain, advise)); |
| } |
| return e; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| var AotSummaryResolver = /** @class */ (function () { |
| function AotSummaryResolver(host, staticSymbolCache) { |
| this.host = host; |
| this.staticSymbolCache = staticSymbolCache; |
| // Note: this will only contain StaticSymbols without members! |
| this.summaryCache = new Map(); |
| this.loadedFilePaths = new Map(); |
| // Note: this will only contain StaticSymbols without members! |
| this.importAs = new Map(); |
| this.knownFileNameToModuleNames = new Map(); |
| } |
| AotSummaryResolver.prototype.isLibraryFile = function (filePath) { |
| // Note: We need to strip the .ngfactory. file path, |
| // so this method also works for generated files |
| // (for which host.isSourceFile will always return false). |
| return !this.host.isSourceFile(stripGeneratedFileSuffix(filePath)); |
| }; |
| AotSummaryResolver.prototype.toSummaryFileName = function (filePath, referringSrcFileName) { |
| return this.host.toSummaryFileName(filePath, referringSrcFileName); |
| }; |
| AotSummaryResolver.prototype.fromSummaryFileName = function (fileName, referringLibFileName) { |
| return this.host.fromSummaryFileName(fileName, referringLibFileName); |
| }; |
| AotSummaryResolver.prototype.resolveSummary = function (staticSymbol) { |
| var rootSymbol = staticSymbol.members.length ? |
| this.staticSymbolCache.get(staticSymbol.filePath, staticSymbol.name) : |
| staticSymbol; |
| var summary = this.summaryCache.get(rootSymbol); |
| if (!summary) { |
| this._loadSummaryFile(staticSymbol.filePath); |
| summary = this.summaryCache.get(staticSymbol); |
| } |
| return (rootSymbol === staticSymbol && summary) || null; |
| }; |
| AotSummaryResolver.prototype.getSymbolsOf = function (filePath) { |
| if (this._loadSummaryFile(filePath)) { |
| return Array.from(this.summaryCache.keys()).filter(function (symbol) { return symbol.filePath === filePath; }); |
| } |
| return null; |
| }; |
| AotSummaryResolver.prototype.getImportAs = function (staticSymbol) { |
| staticSymbol.assertNoMembers(); |
| return this.importAs.get(staticSymbol); |
| }; |
| /** |
| * Converts a file path to a module name that can be used as an `import`. |
| */ |
| AotSummaryResolver.prototype.getKnownModuleName = function (importedFilePath) { |
| return this.knownFileNameToModuleNames.get(importedFilePath) || null; |
| }; |
| AotSummaryResolver.prototype.addSummary = function (summary) { |
| this.summaryCache.set(summary.symbol, summary); |
| }; |
| AotSummaryResolver.prototype._loadSummaryFile = function (filePath) { |
| var _this = this; |
| var hasSummary = this.loadedFilePaths.get(filePath); |
| if (hasSummary != null) { |
| return hasSummary; |
| } |
| var json = null; |
| if (this.isLibraryFile(filePath)) { |
| var summaryFilePath = summaryFileName(filePath); |
| try { |
| json = this.host.loadSummary(summaryFilePath); |
| } |
| catch (e) { |
| console.error("Error loading summary file " + summaryFilePath); |
| throw e; |
| } |
| } |
| hasSummary = json != null; |
| this.loadedFilePaths.set(filePath, hasSummary); |
| if (json) { |
| var _a = deserializeSummaries(this.staticSymbolCache, this, filePath, json), moduleName = _a.moduleName, summaries = _a.summaries, importAs = _a.importAs; |
| summaries.forEach(function (summary) { return _this.summaryCache.set(summary.symbol, summary); }); |
| if (moduleName) { |
| this.knownFileNameToModuleNames.set(filePath, moduleName); |
| } |
| importAs.forEach(function (importAs) { |
| _this.importAs.set(importAs.symbol, importAs.importAs); |
| }); |
| } |
| return hasSummary; |
| }; |
| return AotSummaryResolver; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| function createAotUrlResolver(host) { |
| return { |
| resolve: function (basePath, url) { |
| var filePath = host.resourceNameToFileName(url, basePath); |
| if (!filePath) { |
| throw syntaxError("Couldn't resolve resource " + url + " from " + basePath); |
| } |
| return filePath; |
| } |
| }; |
| } |
| /** |
| * Creates a new AotCompiler based on options and a host. |
| */ |
| function createAotCompiler(compilerHost, options, errorCollector) { |
| var translations = options.translations || ''; |
| var urlResolver = createAotUrlResolver(compilerHost); |
| var symbolCache = new StaticSymbolCache(); |
| var summaryResolver = new AotSummaryResolver(compilerHost, symbolCache); |
| var symbolResolver = new StaticSymbolResolver(compilerHost, symbolCache, summaryResolver); |
| var staticReflector = new StaticReflector(summaryResolver, symbolResolver, [], [], errorCollector); |
| var htmlParser; |
| if (!!options.enableIvy) { |
| // Ivy handles i18n at the compiler level so we must use a regular parser |
| htmlParser = new HtmlParser(); |
| } |
| else { |
| htmlParser = new I18NHtmlParser(new HtmlParser(), translations, options.i18nFormat, options.missingTranslation, console); |
| } |
| var config = new CompilerConfig({ |
| defaultEncapsulation: ViewEncapsulation.Emulated, |
| useJit: false, |
| missingTranslation: options.missingTranslation, |
| preserveWhitespaces: options.preserveWhitespaces, |
| strictInjectionParameters: options.strictInjectionParameters, |
| }); |
| var normalizer = new DirectiveNormalizer({ get: function (url) { return compilerHost.loadResource(url); } }, urlResolver, htmlParser, config); |
| var expressionParser = new Parser$1(new Lexer()); |
| var elementSchemaRegistry = new DomElementSchemaRegistry(); |
| var tmplParser = new TemplateParser(config, staticReflector, expressionParser, elementSchemaRegistry, htmlParser, console, []); |
| var resolver = new CompileMetadataResolver(config, htmlParser, new NgModuleResolver(staticReflector), new DirectiveResolver(staticReflector), new PipeResolver(staticReflector), summaryResolver, elementSchemaRegistry, normalizer, console, symbolCache, staticReflector, errorCollector); |
| // TODO(vicb): do not pass options.i18nFormat here |
| var viewCompiler = new ViewCompiler(staticReflector); |
| var typeCheckCompiler = new TypeCheckCompiler(options, staticReflector); |
| var compiler = new AotCompiler(config, options, compilerHost, staticReflector, resolver, tmplParser, new StyleCompiler(urlResolver), viewCompiler, typeCheckCompiler, new NgModuleCompiler(staticReflector), new InjectableCompiler(staticReflector, !!options.enableIvy), new TypeScriptEmitter(), summaryResolver, symbolResolver); |
| return { compiler: compiler, reflector: staticReflector }; |
| } |
| |
| var SummaryResolver = /** @class */ (function () { |
| function SummaryResolver() { |
| } |
| return SummaryResolver; |
| }()); |
| var JitSummaryResolver = /** @class */ (function () { |
| function JitSummaryResolver() { |
| this._summaries = new Map(); |
| } |
| JitSummaryResolver.prototype.isLibraryFile = function () { |
| return false; |
| }; |
| JitSummaryResolver.prototype.toSummaryFileName = function (fileName) { |
| return fileName; |
| }; |
| JitSummaryResolver.prototype.fromSummaryFileName = function (fileName) { |
| return fileName; |
| }; |
| JitSummaryResolver.prototype.resolveSummary = function (reference) { |
| return this._summaries.get(reference) || null; |
| }; |
| JitSummaryResolver.prototype.getSymbolsOf = function () { |
| return []; |
| }; |
| JitSummaryResolver.prototype.getImportAs = function (reference) { |
| return reference; |
| }; |
| JitSummaryResolver.prototype.getKnownModuleName = function (fileName) { |
| return null; |
| }; |
| JitSummaryResolver.prototype.addSummary = function (summary) { |
| this._summaries.set(summary.symbol, summary); |
| }; |
| return JitSummaryResolver; |
| }()); |
| |
| function interpretStatements(statements, reflector) { |
| var ctx = new _ExecutionContext(null, null, null, new Map()); |
| var visitor = new StatementInterpreter(reflector); |
| visitor.visitAllStatements(statements, ctx); |
| var result = {}; |
| ctx.exports.forEach(function (exportName) { |
| result[exportName] = ctx.vars.get(exportName); |
| }); |
| return result; |
| } |
| function _executeFunctionStatements(varNames, varValues, statements, ctx, visitor) { |
| var childCtx = ctx.createChildWihtLocalVars(); |
| for (var i = 0; i < varNames.length; i++) { |
| childCtx.vars.set(varNames[i], varValues[i]); |
| } |
| var result = visitor.visitAllStatements(statements, childCtx); |
| return result ? result.value : null; |
| } |
| var _ExecutionContext = /** @class */ (function () { |
| function _ExecutionContext(parent, instance, className, vars) { |
| this.parent = parent; |
| this.instance = instance; |
| this.className = className; |
| this.vars = vars; |
| this.exports = []; |
| } |
| _ExecutionContext.prototype.createChildWihtLocalVars = function () { |
| return new _ExecutionContext(this, this.instance, this.className, new Map()); |
| }; |
| return _ExecutionContext; |
| }()); |
| var ReturnValue = /** @class */ (function () { |
| function ReturnValue(value) { |
| this.value = value; |
| } |
| return ReturnValue; |
| }()); |
| function createDynamicClass(_classStmt, _ctx, _visitor) { |
| var propertyDescriptors = {}; |
| _classStmt.getters.forEach(function (getter) { |
| // Note: use `function` instead of arrow function to capture `this` |
| propertyDescriptors[getter.name] = { |
| configurable: false, |
| get: function () { |
| var instanceCtx = new _ExecutionContext(_ctx, this, _classStmt.name, _ctx.vars); |
| return _executeFunctionStatements([], [], getter.body, instanceCtx, _visitor); |
| } |
| }; |
| }); |
| _classStmt.methods.forEach(function (method) { |
| var paramNames = method.params.map(function (param) { return param.name; }); |
| // Note: use `function` instead of arrow function to capture `this` |
| propertyDescriptors[method.name] = { |
| writable: false, |
| configurable: false, |
| value: function () { |
| var args = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| args[_i] = arguments[_i]; |
| } |
| var instanceCtx = new _ExecutionContext(_ctx, this, _classStmt.name, _ctx.vars); |
| return _executeFunctionStatements(paramNames, args, method.body, instanceCtx, _visitor); |
| } |
| }; |
| }); |
| var ctorParamNames = _classStmt.constructorMethod.params.map(function (param) { return param.name; }); |
| // Note: use `function` instead of arrow function to capture `this` |
| var ctor = function () { |
| var _this = this; |
| var args = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| args[_i] = arguments[_i]; |
| } |
| var instanceCtx = new _ExecutionContext(_ctx, this, _classStmt.name, _ctx.vars); |
| _classStmt.fields.forEach(function (field) { |
| _this[field.name] = undefined; |
| }); |
| _executeFunctionStatements(ctorParamNames, args, _classStmt.constructorMethod.body, instanceCtx, _visitor); |
| }; |
| var superClass = _classStmt.parent ? _classStmt.parent.visitExpression(_visitor, _ctx) : Object; |
| ctor.prototype = Object.create(superClass.prototype, propertyDescriptors); |
| return ctor; |
| } |
| var StatementInterpreter = /** @class */ (function () { |
| function StatementInterpreter(reflector) { |
| this.reflector = reflector; |
| } |
| StatementInterpreter.prototype.debugAst = function (ast) { |
| return debugOutputAstAsTypeScript(ast); |
| }; |
| StatementInterpreter.prototype.visitDeclareVarStmt = function (stmt, ctx) { |
| var initialValue = stmt.value ? stmt.value.visitExpression(this, ctx) : undefined; |
| ctx.vars.set(stmt.name, initialValue); |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| ctx.exports.push(stmt.name); |
| } |
| return null; |
| }; |
| StatementInterpreter.prototype.visitWriteVarExpr = function (expr, ctx) { |
| var value = expr.value.visitExpression(this, ctx); |
| var currCtx = ctx; |
| while (currCtx != null) { |
| if (currCtx.vars.has(expr.name)) { |
| currCtx.vars.set(expr.name, value); |
| return value; |
| } |
| currCtx = currCtx.parent; |
| } |
| throw new Error("Not declared variable " + expr.name); |
| }; |
| StatementInterpreter.prototype.visitWrappedNodeExpr = function (ast, ctx) { |
| throw new Error('Cannot interpret a WrappedNodeExpr.'); |
| }; |
| StatementInterpreter.prototype.visitTypeofExpr = function (ast, ctx) { |
| throw new Error('Cannot interpret a TypeofExpr'); |
| }; |
| StatementInterpreter.prototype.visitReadVarExpr = function (ast, ctx) { |
| var varName = ast.name; |
| if (ast.builtin != null) { |
| switch (ast.builtin) { |
| case exports.BuiltinVar.Super: |
| return Object.getPrototypeOf(ctx.instance); |
| case exports.BuiltinVar.This: |
| return ctx.instance; |
| case exports.BuiltinVar.CatchError: |
| varName = CATCH_ERROR_VAR$2; |
| break; |
| case exports.BuiltinVar.CatchStack: |
| varName = CATCH_STACK_VAR$2; |
| break; |
| default: |
| throw new Error("Unknown builtin variable " + ast.builtin); |
| } |
| } |
| var currCtx = ctx; |
| while (currCtx != null) { |
| if (currCtx.vars.has(varName)) { |
| return currCtx.vars.get(varName); |
| } |
| currCtx = currCtx.parent; |
| } |
| throw new Error("Not declared variable " + varName); |
| }; |
| StatementInterpreter.prototype.visitWriteKeyExpr = function (expr, ctx) { |
| var receiver = expr.receiver.visitExpression(this, ctx); |
| var index = expr.index.visitExpression(this, ctx); |
| var value = expr.value.visitExpression(this, ctx); |
| receiver[index] = value; |
| return value; |
| }; |
| StatementInterpreter.prototype.visitWritePropExpr = function (expr, ctx) { |
| var receiver = expr.receiver.visitExpression(this, ctx); |
| var value = expr.value.visitExpression(this, ctx); |
| receiver[expr.name] = value; |
| return value; |
| }; |
| StatementInterpreter.prototype.visitInvokeMethodExpr = function (expr, ctx) { |
| var receiver = expr.receiver.visitExpression(this, ctx); |
| var args = this.visitAllExpressions(expr.args, ctx); |
| var result; |
| if (expr.builtin != null) { |
| switch (expr.builtin) { |
| case exports.BuiltinMethod.ConcatArray: |
| result = receiver.concat.apply(receiver, __spread(args)); |
| break; |
| case exports.BuiltinMethod.SubscribeObservable: |
| result = receiver.subscribe({ next: args[0] }); |
| break; |
| case exports.BuiltinMethod.Bind: |
| result = receiver.bind.apply(receiver, __spread(args)); |
| break; |
| default: |
| throw new Error("Unknown builtin method " + expr.builtin); |
| } |
| } |
| else { |
| result = receiver[expr.name].apply(receiver, args); |
| } |
| return result; |
| }; |
| StatementInterpreter.prototype.visitInvokeFunctionExpr = function (stmt, ctx) { |
| var args = this.visitAllExpressions(stmt.args, ctx); |
| var fnExpr = stmt.fn; |
| if (fnExpr instanceof ReadVarExpr && fnExpr.builtin === exports.BuiltinVar.Super) { |
| ctx.instance.constructor.prototype.constructor.apply(ctx.instance, args); |
| return null; |
| } |
| else { |
| var fn = stmt.fn.visitExpression(this, ctx); |
| return fn.apply(null, args); |
| } |
| }; |
| StatementInterpreter.prototype.visitTaggedTemplateExpr = function (expr, ctx) { |
| var templateElements = expr.template.elements.map(function (e) { return e.text; }); |
| Object.defineProperty(templateElements, 'raw', { value: expr.template.elements.map(function (e) { return e.rawText; }) }); |
| var args = this.visitAllExpressions(expr.template.expressions, ctx); |
| args.unshift(templateElements); |
| var tag = expr.tag.visitExpression(this, ctx); |
| return tag.apply(null, args); |
| }; |
| StatementInterpreter.prototype.visitReturnStmt = function (stmt, ctx) { |
| return new ReturnValue(stmt.value.visitExpression(this, ctx)); |
| }; |
| StatementInterpreter.prototype.visitDeclareClassStmt = function (stmt, ctx) { |
| var clazz = createDynamicClass(stmt, ctx, this); |
| ctx.vars.set(stmt.name, clazz); |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| ctx.exports.push(stmt.name); |
| } |
| return null; |
| }; |
| StatementInterpreter.prototype.visitExpressionStmt = function (stmt, ctx) { |
| return stmt.expr.visitExpression(this, ctx); |
| }; |
| StatementInterpreter.prototype.visitIfStmt = function (stmt, ctx) { |
| var condition = stmt.condition.visitExpression(this, ctx); |
| if (condition) { |
| return this.visitAllStatements(stmt.trueCase, ctx); |
| } |
| else if (stmt.falseCase != null) { |
| return this.visitAllStatements(stmt.falseCase, ctx); |
| } |
| return null; |
| }; |
| StatementInterpreter.prototype.visitTryCatchStmt = function (stmt, ctx) { |
| try { |
| return this.visitAllStatements(stmt.bodyStmts, ctx); |
| } |
| catch (e) { |
| var childCtx = ctx.createChildWihtLocalVars(); |
| childCtx.vars.set(CATCH_ERROR_VAR$2, e); |
| childCtx.vars.set(CATCH_STACK_VAR$2, e.stack); |
| return this.visitAllStatements(stmt.catchStmts, childCtx); |
| } |
| }; |
| StatementInterpreter.prototype.visitThrowStmt = function (stmt, ctx) { |
| throw stmt.error.visitExpression(this, ctx); |
| }; |
| StatementInterpreter.prototype.visitInstantiateExpr = function (ast, ctx) { |
| var args = this.visitAllExpressions(ast.args, ctx); |
| var clazz = ast.classExpr.visitExpression(this, ctx); |
| return new (clazz.bind.apply(clazz, __spread([void 0], args)))(); |
| }; |
| StatementInterpreter.prototype.visitLiteralExpr = function (ast, ctx) { |
| return ast.value; |
| }; |
| StatementInterpreter.prototype.visitLocalizedString = function (ast, context) { |
| return null; |
| }; |
| StatementInterpreter.prototype.visitExternalExpr = function (ast, ctx) { |
| return this.reflector.resolveExternalReference(ast.value); |
| }; |
| StatementInterpreter.prototype.visitConditionalExpr = function (ast, ctx) { |
| if (ast.condition.visitExpression(this, ctx)) { |
| return ast.trueCase.visitExpression(this, ctx); |
| } |
| else if (ast.falseCase != null) { |
| return ast.falseCase.visitExpression(this, ctx); |
| } |
| return null; |
| }; |
| StatementInterpreter.prototype.visitNotExpr = function (ast, ctx) { |
| return !ast.condition.visitExpression(this, ctx); |
| }; |
| StatementInterpreter.prototype.visitAssertNotNullExpr = function (ast, ctx) { |
| return ast.condition.visitExpression(this, ctx); |
| }; |
| StatementInterpreter.prototype.visitCastExpr = function (ast, ctx) { |
| return ast.value.visitExpression(this, ctx); |
| }; |
| StatementInterpreter.prototype.visitFunctionExpr = function (ast, ctx) { |
| var paramNames = ast.params.map(function (param) { return param.name; }); |
| return _declareFn(paramNames, ast.statements, ctx, this); |
| }; |
| StatementInterpreter.prototype.visitDeclareFunctionStmt = function (stmt, ctx) { |
| var paramNames = stmt.params.map(function (param) { return param.name; }); |
| ctx.vars.set(stmt.name, _declareFn(paramNames, stmt.statements, ctx, this)); |
| if (stmt.hasModifier(exports.StmtModifier.Exported)) { |
| ctx.exports.push(stmt.name); |
| } |
| return null; |
| }; |
| StatementInterpreter.prototype.visitUnaryOperatorExpr = function (ast, ctx) { |
| var _this = this; |
| var rhs = function () { return ast.expr.visitExpression(_this, ctx); }; |
| switch (ast.operator) { |
| case exports.UnaryOperator.Plus: |
| return +rhs(); |
| case exports.UnaryOperator.Minus: |
| return -rhs(); |
| default: |
| throw new Error("Unknown operator " + ast.operator); |
| } |
| }; |
| StatementInterpreter.prototype.visitBinaryOperatorExpr = function (ast, ctx) { |
| var _this = this; |
| var lhs = function () { return ast.lhs.visitExpression(_this, ctx); }; |
| var rhs = function () { return ast.rhs.visitExpression(_this, ctx); }; |
| switch (ast.operator) { |
| case exports.BinaryOperator.Equals: |
| return lhs() == rhs(); |
| case exports.BinaryOperator.Identical: |
| return lhs() === rhs(); |
| case exports.BinaryOperator.NotEquals: |
| return lhs() != rhs(); |
| case exports.BinaryOperator.NotIdentical: |
| return lhs() !== rhs(); |
| case exports.BinaryOperator.And: |
| return lhs() && rhs(); |
| case exports.BinaryOperator.Or: |
| return lhs() || rhs(); |
| case exports.BinaryOperator.Plus: |
| return lhs() + rhs(); |
| case exports.BinaryOperator.Minus: |
| return lhs() - rhs(); |
| case exports.BinaryOperator.Divide: |
| return lhs() / rhs(); |
| case exports.BinaryOperator.Multiply: |
| return lhs() * rhs(); |
| case exports.BinaryOperator.Modulo: |
| return lhs() % rhs(); |
| case exports.BinaryOperator.Lower: |
| return lhs() < rhs(); |
| case exports.BinaryOperator.LowerEquals: |
| return lhs() <= rhs(); |
| case exports.BinaryOperator.Bigger: |
| return lhs() > rhs(); |
| case exports.BinaryOperator.BiggerEquals: |
| return lhs() >= rhs(); |
| default: |
| throw new Error("Unknown operator " + ast.operator); |
| } |
| }; |
| StatementInterpreter.prototype.visitReadPropExpr = function (ast, ctx) { |
| var result; |
| var receiver = ast.receiver.visitExpression(this, ctx); |
| result = receiver[ast.name]; |
| return result; |
| }; |
| StatementInterpreter.prototype.visitReadKeyExpr = function (ast, ctx) { |
| var receiver = ast.receiver.visitExpression(this, ctx); |
| var prop = ast.index.visitExpression(this, ctx); |
| return receiver[prop]; |
| }; |
| StatementInterpreter.prototype.visitLiteralArrayExpr = function (ast, ctx) { |
| return this.visitAllExpressions(ast.entries, ctx); |
| }; |
| StatementInterpreter.prototype.visitLiteralMapExpr = function (ast, ctx) { |
| var _this = this; |
| var result = {}; |
| ast.entries.forEach(function (entry) { return result[entry.key] = entry.value.visitExpression(_this, ctx); }); |
| return result; |
| }; |
| StatementInterpreter.prototype.visitCommaExpr = function (ast, context) { |
| var values = this.visitAllExpressions(ast.parts, context); |
| return values[values.length - 1]; |
| }; |
| StatementInterpreter.prototype.visitAllExpressions = function (expressions, ctx) { |
| var _this = this; |
| return expressions.map(function (expr) { return expr.visitExpression(_this, ctx); }); |
| }; |
| StatementInterpreter.prototype.visitAllStatements = function (statements, ctx) { |
| for (var i = 0; i < statements.length; i++) { |
| var stmt = statements[i]; |
| var val = stmt.visitStatement(this, ctx); |
| if (val instanceof ReturnValue) { |
| return val; |
| } |
| } |
| return null; |
| }; |
| return StatementInterpreter; |
| }()); |
| function _declareFn(varNames, statements, ctx, visitor) { |
| return function () { |
| var args = []; |
| for (var _i = 0; _i < arguments.length; _i++) { |
| args[_i] = arguments[_i]; |
| } |
| return _executeFunctionStatements(varNames, args, statements, ctx, visitor); |
| }; |
| } |
| var CATCH_ERROR_VAR$2 = 'error'; |
| var CATCH_STACK_VAR$2 = 'stack'; |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * An internal module of the Angular compiler that begins with component types, |
| * extracts templates, and eventually produces a compiled version of the component |
| * ready for linking into an application. |
| * |
| * @security When compiling templates at runtime, you must ensure that the entire template comes |
| * from a trusted source. Attacker-controlled data introduced by a template could expose your |
| * application to XSS risks. For more detail, see the [Security Guide](https://g.co/ng/security). |
| */ |
| var JitCompiler = /** @class */ (function () { |
| function JitCompiler(_metadataResolver, _templateParser, _styleCompiler, _viewCompiler, _ngModuleCompiler, _summaryResolver, _reflector, _jitEvaluator, _compilerConfig, _console, getExtraNgModuleProviders) { |
| this._metadataResolver = _metadataResolver; |
| this._templateParser = _templateParser; |
| this._styleCompiler = _styleCompiler; |
| this._viewCompiler = _viewCompiler; |
| this._ngModuleCompiler = _ngModuleCompiler; |
| this._summaryResolver = _summaryResolver; |
| this._reflector = _reflector; |
| this._jitEvaluator = _jitEvaluator; |
| this._compilerConfig = _compilerConfig; |
| this._console = _console; |
| this.getExtraNgModuleProviders = getExtraNgModuleProviders; |
| this._compiledTemplateCache = new Map(); |
| this._compiledHostTemplateCache = new Map(); |
| this._compiledDirectiveWrapperCache = new Map(); |
| this._compiledNgModuleCache = new Map(); |
| this._sharedStylesheetCount = 0; |
| this._addedAotSummaries = new Set(); |
| } |
| JitCompiler.prototype.compileModuleSync = function (moduleType) { |
| return SyncAsync.assertSync(this._compileModuleAndComponents(moduleType, true)); |
| }; |
| JitCompiler.prototype.compileModuleAsync = function (moduleType) { |
| return Promise.resolve(this._compileModuleAndComponents(moduleType, false)); |
| }; |
| JitCompiler.prototype.compileModuleAndAllComponentsSync = function (moduleType) { |
| return SyncAsync.assertSync(this._compileModuleAndAllComponents(moduleType, true)); |
| }; |
| JitCompiler.prototype.compileModuleAndAllComponentsAsync = function (moduleType) { |
| return Promise.resolve(this._compileModuleAndAllComponents(moduleType, false)); |
| }; |
| JitCompiler.prototype.getComponentFactory = function (component) { |
| var summary = this._metadataResolver.getDirectiveSummary(component); |
| return summary.componentFactory; |
| }; |
| JitCompiler.prototype.loadAotSummaries = function (summaries) { |
| this.clearCache(); |
| this._addAotSummaries(summaries); |
| }; |
| JitCompiler.prototype._addAotSummaries = function (fn) { |
| if (this._addedAotSummaries.has(fn)) { |
| return; |
| } |
| this._addedAotSummaries.add(fn); |
| var summaries = fn(); |
| for (var i = 0; i < summaries.length; i++) { |
| var entry = summaries[i]; |
| if (typeof entry === 'function') { |
| this._addAotSummaries(entry); |
| } |
| else { |
| var summary = entry; |
| this._summaryResolver.addSummary({ symbol: summary.type.reference, metadata: null, type: summary }); |
| } |
| } |
| }; |
| JitCompiler.prototype.hasAotSummary = function (ref) { |
| return !!this._summaryResolver.resolveSummary(ref); |
| }; |
| JitCompiler.prototype._filterJitIdentifiers = function (ids) { |
| var _this = this; |
| return ids.map(function (mod) { return mod.reference; }).filter(function (ref) { return !_this.hasAotSummary(ref); }); |
| }; |
| JitCompiler.prototype._compileModuleAndComponents = function (moduleType, isSync) { |
| var _this = this; |
| return SyncAsync.then(this._loadModules(moduleType, isSync), function () { |
| _this._compileComponents(moduleType, null); |
| return _this._compileModule(moduleType); |
| }); |
| }; |
| JitCompiler.prototype._compileModuleAndAllComponents = function (moduleType, isSync) { |
| var _this = this; |
| return SyncAsync.then(this._loadModules(moduleType, isSync), function () { |
| var componentFactories = []; |
| _this._compileComponents(moduleType, componentFactories); |
| return { |
| ngModuleFactory: _this._compileModule(moduleType), |
| componentFactories: componentFactories |
| }; |
| }); |
| }; |
| JitCompiler.prototype._loadModules = function (mainModule, isSync) { |
| var _this = this; |
| var loading = []; |
| var mainNgModule = this._metadataResolver.getNgModuleMetadata(mainModule); |
| // Note: for runtime compilation, we want to transitively compile all modules, |
| // so we also need to load the declared directives / pipes for all nested modules. |
| this._filterJitIdentifiers(mainNgModule.transitiveModule.modules).forEach(function (nestedNgModule) { |
| // getNgModuleMetadata only returns null if the value passed in is not an NgModule |
| var moduleMeta = _this._metadataResolver.getNgModuleMetadata(nestedNgModule); |
| _this._filterJitIdentifiers(moduleMeta.declaredDirectives).forEach(function (ref) { |
| var promise = _this._metadataResolver.loadDirectiveMetadata(moduleMeta.type.reference, ref, isSync); |
| if (promise) { |
| loading.push(promise); |
| } |
| }); |
| _this._filterJitIdentifiers(moduleMeta.declaredPipes) |
| .forEach(function (ref) { return _this._metadataResolver.getOrLoadPipeMetadata(ref); }); |
| }); |
| return SyncAsync.all(loading); |
| }; |
| JitCompiler.prototype._compileModule = function (moduleType) { |
| var ngModuleFactory = this._compiledNgModuleCache.get(moduleType); |
| if (!ngModuleFactory) { |
| var moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType); |
| // Always provide a bound Compiler |
| var extraProviders = this.getExtraNgModuleProviders(moduleMeta.type.reference); |
| var outputCtx = createOutputContext(); |
| var compileResult = this._ngModuleCompiler.compile(outputCtx, moduleMeta, extraProviders); |
| ngModuleFactory = this._interpretOrJit(ngModuleJitUrl(moduleMeta), outputCtx.statements)[compileResult.ngModuleFactoryVar]; |
| this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory); |
| } |
| return ngModuleFactory; |
| }; |
| /** |
| * @internal |
| */ |
| JitCompiler.prototype._compileComponents = function (mainModule, allComponentFactories) { |
| var _this = this; |
| var ngModule = this._metadataResolver.getNgModuleMetadata(mainModule); |
| var moduleByJitDirective = new Map(); |
| var templates = new Set(); |
| var transJitModules = this._filterJitIdentifiers(ngModule.transitiveModule.modules); |
| transJitModules.forEach(function (localMod) { |
| var localModuleMeta = _this._metadataResolver.getNgModuleMetadata(localMod); |
| _this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach(function (dirRef) { |
| moduleByJitDirective.set(dirRef, localModuleMeta); |
| var dirMeta = _this._metadataResolver.getDirectiveMetadata(dirRef); |
| if (dirMeta.isComponent) { |
| templates.add(_this._createCompiledTemplate(dirMeta, localModuleMeta)); |
| if (allComponentFactories) { |
| var template = _this._createCompiledHostTemplate(dirMeta.type.reference, localModuleMeta); |
| templates.add(template); |
| allComponentFactories.push(dirMeta.componentFactory); |
| } |
| } |
| }); |
| }); |
| transJitModules.forEach(function (localMod) { |
| var localModuleMeta = _this._metadataResolver.getNgModuleMetadata(localMod); |
| _this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach(function (dirRef) { |
| var dirMeta = _this._metadataResolver.getDirectiveMetadata(dirRef); |
| if (dirMeta.isComponent) { |
| dirMeta.entryComponents.forEach(function (entryComponentType) { |
| var moduleMeta = moduleByJitDirective.get(entryComponentType.componentType); |
| templates.add(_this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta)); |
| }); |
| } |
| }); |
| localModuleMeta.entryComponents.forEach(function (entryComponentType) { |
| if (!_this.hasAotSummary(entryComponentType.componentType)) { |
| var moduleMeta = moduleByJitDirective.get(entryComponentType.componentType); |
| templates.add(_this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta)); |
| } |
| }); |
| }); |
| templates.forEach(function (template) { return _this._compileTemplate(template); }); |
| }; |
| JitCompiler.prototype.clearCacheFor = function (type) { |
| this._compiledNgModuleCache.delete(type); |
| this._metadataResolver.clearCacheFor(type); |
| this._compiledHostTemplateCache.delete(type); |
| var compiledTemplate = this._compiledTemplateCache.get(type); |
| if (compiledTemplate) { |
| this._compiledTemplateCache.delete(type); |
| } |
| }; |
| JitCompiler.prototype.clearCache = function () { |
| // Note: don't clear the _addedAotSummaries, as they don't change! |
| this._metadataResolver.clearCache(); |
| this._compiledTemplateCache.clear(); |
| this._compiledHostTemplateCache.clear(); |
| this._compiledNgModuleCache.clear(); |
| }; |
| JitCompiler.prototype._createCompiledHostTemplate = function (compType, ngModule) { |
| if (!ngModule) { |
| throw new Error("Component " + stringify(compType) + " is not part of any NgModule or the module has not been imported into your module."); |
| } |
| var compiledTemplate = this._compiledHostTemplateCache.get(compType); |
| if (!compiledTemplate) { |
| var compMeta = this._metadataResolver.getDirectiveMetadata(compType); |
| assertComponent(compMeta); |
| var hostMeta = this._metadataResolver.getHostComponentMetadata(compMeta, compMeta.componentFactory.viewDefFactory); |
| compiledTemplate = |
| new CompiledTemplate(true, compMeta.type, hostMeta, ngModule, [compMeta.type]); |
| this._compiledHostTemplateCache.set(compType, compiledTemplate); |
| } |
| return compiledTemplate; |
| }; |
| JitCompiler.prototype._createCompiledTemplate = function (compMeta, ngModule) { |
| var compiledTemplate = this._compiledTemplateCache.get(compMeta.type.reference); |
| if (!compiledTemplate) { |
| assertComponent(compMeta); |
| compiledTemplate = new CompiledTemplate(false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives); |
| this._compiledTemplateCache.set(compMeta.type.reference, compiledTemplate); |
| } |
| return compiledTemplate; |
| }; |
| JitCompiler.prototype._compileTemplate = function (template) { |
| var _this = this; |
| if (template.isCompiled) { |
| return; |
| } |
| var compMeta = template.compMeta; |
| var externalStylesheetsByModuleUrl = new Map(); |
| var outputContext = createOutputContext(); |
| var componentStylesheet = this._styleCompiler.compileComponent(outputContext, compMeta); |
| compMeta.template.externalStylesheets.forEach(function (stylesheetMeta) { |
| var compiledStylesheet = _this._styleCompiler.compileStyles(createOutputContext(), compMeta, stylesheetMeta); |
| externalStylesheetsByModuleUrl.set(stylesheetMeta.moduleUrl, compiledStylesheet); |
| }); |
| this._resolveStylesCompileResult(componentStylesheet, externalStylesheetsByModuleUrl); |
| var pipes = template.ngModule.transitiveModule.pipes.map(function (pipe) { return _this._metadataResolver.getPipeSummary(pipe.reference); }); |
| var _a = this._parseTemplate(compMeta, template.ngModule, template.directives), parsedTemplate = _a.template, usedPipes = _a.pipes; |
| var compileResult = this._viewCompiler.compileComponent(outputContext, compMeta, parsedTemplate, variable(componentStylesheet.stylesVar), usedPipes); |
| var evalResult = this._interpretOrJit(templateJitUrl(template.ngModule.type, template.compMeta), outputContext.statements); |
| var viewClass = evalResult[compileResult.viewClassVar]; |
| var rendererType = evalResult[compileResult.rendererTypeVar]; |
| template.compiled(viewClass, rendererType); |
| }; |
| JitCompiler.prototype._parseTemplate = function (compMeta, ngModule, directiveIdentifiers) { |
| var _this = this; |
| // Note: ! is ok here as components always have a template. |
| var preserveWhitespaces = compMeta.template.preserveWhitespaces; |
| var directives = directiveIdentifiers.map(function (dir) { return _this._metadataResolver.getDirectiveSummary(dir.reference); }); |
| var pipes = ngModule.transitiveModule.pipes.map(function (pipe) { return _this._metadataResolver.getPipeSummary(pipe.reference); }); |
| return this._templateParser.parse(compMeta, compMeta.template.htmlAst, directives, pipes, ngModule.schemas, templateSourceUrl(ngModule.type, compMeta, compMeta.template), preserveWhitespaces); |
| }; |
| JitCompiler.prototype._resolveStylesCompileResult = function (result, externalStylesheetsByModuleUrl) { |
| var _this = this; |
| result.dependencies.forEach(function (dep, i) { |
| var nestedCompileResult = externalStylesheetsByModuleUrl.get(dep.moduleUrl); |
| var nestedStylesArr = _this._resolveAndEvalStylesCompileResult(nestedCompileResult, externalStylesheetsByModuleUrl); |
| dep.setValue(nestedStylesArr); |
| }); |
| }; |
| JitCompiler.prototype._resolveAndEvalStylesCompileResult = function (result, externalStylesheetsByModuleUrl) { |
| this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl); |
| return this._interpretOrJit(sharedStylesheetJitUrl(result.meta, this._sharedStylesheetCount++), result.outputCtx.statements)[result.stylesVar]; |
| }; |
| JitCompiler.prototype._interpretOrJit = function (sourceUrl, statements) { |
| if (!this._compilerConfig.useJit) { |
| return interpretStatements(statements, this._reflector); |
| } |
| else { |
| return this._jitEvaluator.evaluateStatements(sourceUrl, statements, this._reflector, this._compilerConfig.jitDevMode); |
| } |
| }; |
| return JitCompiler; |
| }()); |
| var CompiledTemplate = /** @class */ (function () { |
| function CompiledTemplate(isHost, compType, compMeta, ngModule, directives) { |
| this.isHost = isHost; |
| this.compType = compType; |
| this.compMeta = compMeta; |
| this.ngModule = ngModule; |
| this.directives = directives; |
| this._viewClass = null; |
| this.isCompiled = false; |
| } |
| CompiledTemplate.prototype.compiled = function (viewClass, rendererType) { |
| this._viewClass = viewClass; |
| this.compMeta.componentViewType.setDelegate(viewClass); |
| for (var prop in rendererType) { |
| this.compMeta.rendererType[prop] = rendererType[prop]; |
| } |
| this.isCompiled = true; |
| }; |
| return CompiledTemplate; |
| }()); |
| function assertComponent(meta) { |
| if (!meta.isComponent) { |
| throw new Error("Could not compile '" + identifierName(meta.type) + "' because it is not a component."); |
| } |
| } |
| function createOutputContext() { |
| var importExpr$1 = function (symbol) { return importExpr({ name: identifierName(symbol), moduleName: null, runtime: symbol }); }; |
| return { statements: [], genFilePath: '', importExpr: importExpr$1, constantPool: new ConstantPool() }; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Provides access to reflection data about symbols that the compiler needs. |
| */ |
| var CompileReflector = /** @class */ (function () { |
| function CompileReflector() { |
| } |
| return CompileReflector; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Create a {@link UrlResolver} with no package prefix. |
| */ |
| function createUrlResolverWithoutPackagePrefix() { |
| return new UrlResolver(); |
| } |
| function createOfflineCompileUrlResolver() { |
| return new UrlResolver('.'); |
| } |
| var UrlResolver = /** @class */ (function () { |
| function UrlResolverImpl(_packagePrefix) { |
| if (_packagePrefix === void 0) { _packagePrefix = null; } |
| this._packagePrefix = _packagePrefix; |
| } |
| /** |
| * Resolves the `url` given the `baseUrl`: |
| * - when the `url` is null, the `baseUrl` is returned, |
| * - if `url` is relative ('path/to/here', './path/to/here'), the resolved url is a combination of |
| * `baseUrl` and `url`, |
| * - if `url` is absolute (it has a scheme: 'http://', 'https://' or start with '/'), the `url` is |
| * returned as is (ignoring the `baseUrl`) |
| */ |
| UrlResolverImpl.prototype.resolve = function (baseUrl, url) { |
| var resolvedUrl = url; |
| if (baseUrl != null && baseUrl.length > 0) { |
| resolvedUrl = _resolveUrl(baseUrl, resolvedUrl); |
| } |
| var resolvedParts = _split(resolvedUrl); |
| var prefix = this._packagePrefix; |
| if (prefix != null && resolvedParts != null && |
| resolvedParts[_ComponentIndex.Scheme] == 'package') { |
| var path = resolvedParts[_ComponentIndex.Path]; |
| prefix = prefix.replace(/\/+$/, ''); |
| path = path.replace(/^\/+/, ''); |
| return prefix + "/" + path; |
| } |
| return resolvedUrl; |
| }; |
| return UrlResolverImpl; |
| }()); |
| /** |
| * Extract the scheme of a URL. |
| */ |
| function getUrlScheme(url) { |
| var match = _split(url); |
| return (match && match[_ComponentIndex.Scheme]) || ''; |
| } |
| // The code below is adapted from Traceur: |
| // https://github.com/google/traceur-compiler/blob/9511c1dafa972bf0de1202a8a863bad02f0f95a8/src/runtime/url.js |
| /** |
| * Builds a URI string from already-encoded parts. |
| * |
| * No encoding is performed. Any component may be omitted as either null or |
| * undefined. |
| * |
| * @param opt_scheme The scheme such as 'http'. |
| * @param opt_userInfo The user name before the '@'. |
| * @param opt_domain The domain such as 'www.google.com', already |
| * URI-encoded. |
| * @param opt_port The port number. |
| * @param opt_path The path, already URI-encoded. If it is not |
| * empty, it must begin with a slash. |
| * @param opt_queryData The URI-encoded query data. |
| * @param opt_fragment The URI-encoded fragment identifier. |
| * @return The fully combined URI. |
| */ |
| function _buildFromEncodedParts(opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData, opt_fragment) { |
| var out = []; |
| if (opt_scheme != null) { |
| out.push(opt_scheme + ':'); |
| } |
| if (opt_domain != null) { |
| out.push('//'); |
| if (opt_userInfo != null) { |
| out.push(opt_userInfo + '@'); |
| } |
| out.push(opt_domain); |
| if (opt_port != null) { |
| out.push(':' + opt_port); |
| } |
| } |
| if (opt_path != null) { |
| out.push(opt_path); |
| } |
| if (opt_queryData != null) { |
| out.push('?' + opt_queryData); |
| } |
| if (opt_fragment != null) { |
| out.push('#' + opt_fragment); |
| } |
| return out.join(''); |
| } |
| /** |
| * A regular expression for breaking a URI into its component parts. |
| * |
| * {@link https://tools.ietf.org/html/rfc3986#appendix-B} says |
| * As the "first-match-wins" algorithm is identical to the "greedy" |
| * disambiguation method used by POSIX regular expressions, it is natural and |
| * commonplace to use a regular expression for parsing the potential five |
| * components of a URI reference. |
| * |
| * The following line is the regular expression for breaking-down a |
| * well-formed URI reference into its components. |
| * |
| * <pre> |
| * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? |
| * 12 3 4 5 6 7 8 9 |
| * </pre> |
| * |
| * The numbers in the second line above are only to assist readability; they |
| * indicate the reference points for each subexpression (i.e., each paired |
| * parenthesis). We refer to the value matched for subexpression <n> as $<n>. |
| * For example, matching the above expression to |
| * <pre> |
| * http://www.ics.uci.edu/pub/ietf/uri/#Related |
| * </pre> |
| * results in the following subexpression matches: |
| * <pre> |
| * $1 = http: |
| * $2 = http |
| * $3 = //www.ics.uci.edu |
| * $4 = www.ics.uci.edu |
| * $5 = /pub/ietf/uri/ |
| * $6 = <undefined> |
| * $7 = <undefined> |
| * $8 = #Related |
| * $9 = Related |
| * </pre> |
| * where <undefined> indicates that the component is not present, as is the |
| * case for the query component in the above example. Therefore, we can |
| * determine the value of the five components as |
| * <pre> |
| * scheme = $2 |
| * authority = $4 |
| * path = $5 |
| * query = $7 |
| * fragment = $9 |
| * </pre> |
| * |
| * The regular expression has been modified slightly to expose the |
| * userInfo, domain, and port separately from the authority. |
| * The modified version yields |
| * <pre> |
| * $1 = http scheme |
| * $2 = <undefined> userInfo -\ |
| * $3 = www.ics.uci.edu domain | authority |
| * $4 = <undefined> port -/ |
| * $5 = /pub/ietf/uri/ path |
| * $6 = <undefined> query without ? |
| * $7 = Related fragment without # |
| * </pre> |
| * @internal |
| */ |
| var _splitRe = new RegExp('^' + |
| '(?:' + |
| '([^:/?#.]+)' + // scheme - ignore special characters |
| // used by other URL parts such as :, |
| // ?, /, #, and . |
| ':)?' + |
| '(?://' + |
| '(?:([^/?#]*)@)?' + // userInfo |
| '([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters, |
| // digits, dashes, dots, percent |
| // escapes, and unicode characters. |
| '(?::([0-9]+))?' + // port |
| ')?' + |
| '([^?#]+)?' + // path |
| '(?:\\?([^#]*))?' + // query |
| '(?:#(.*))?' + // fragment |
| '$'); |
| /** |
| * The index of each URI component in the return value of goog.uri.utils.split. |
| * @enum {number} |
| */ |
| var _ComponentIndex; |
| (function (_ComponentIndex) { |
| _ComponentIndex[_ComponentIndex["Scheme"] = 1] = "Scheme"; |
| _ComponentIndex[_ComponentIndex["UserInfo"] = 2] = "UserInfo"; |
| _ComponentIndex[_ComponentIndex["Domain"] = 3] = "Domain"; |
| _ComponentIndex[_ComponentIndex["Port"] = 4] = "Port"; |
| _ComponentIndex[_ComponentIndex["Path"] = 5] = "Path"; |
| _ComponentIndex[_ComponentIndex["QueryData"] = 6] = "QueryData"; |
| _ComponentIndex[_ComponentIndex["Fragment"] = 7] = "Fragment"; |
| })(_ComponentIndex || (_ComponentIndex = {})); |
| /** |
| * Splits a URI into its component parts. |
| * |
| * Each component can be accessed via the component indices; for example: |
| * <pre> |
| * goog.uri.utils.split(someStr)[goog.uri.utils.CompontentIndex.QUERY_DATA]; |
| * </pre> |
| * |
| * @param uri The URI string to examine. |
| * @return Each component still URI-encoded. |
| * Each component that is present will contain the encoded value, whereas |
| * components that are not present will be undefined or empty, depending |
| * on the browser's regular expression implementation. Never null, since |
| * arbitrary strings may still look like path names. |
| */ |
| function _split(uri) { |
| return uri.match(_splitRe); |
| } |
| /** |
| * Removes dot segments in given path component, as described in |
| * RFC 3986, section 5.2.4. |
| * |
| * @param path A non-empty path component. |
| * @return Path component with removed dot segments. |
| */ |
| function _removeDotSegments(path) { |
| if (path == '/') |
| return '/'; |
| var leadingSlash = path[0] == '/' ? '/' : ''; |
| var trailingSlash = path[path.length - 1] === '/' ? '/' : ''; |
| var segments = path.split('/'); |
| var out = []; |
| var up = 0; |
| for (var pos = 0; pos < segments.length; pos++) { |
| var segment = segments[pos]; |
| switch (segment) { |
| case '': |
| case '.': |
| break; |
| case '..': |
| if (out.length > 0) { |
| out.pop(); |
| } |
| else { |
| up++; |
| } |
| break; |
| default: |
| out.push(segment); |
| } |
| } |
| if (leadingSlash == '') { |
| while (up-- > 0) { |
| out.unshift('..'); |
| } |
| if (out.length === 0) |
| out.push('.'); |
| } |
| return leadingSlash + out.join('/') + trailingSlash; |
| } |
| /** |
| * Takes an array of the parts from split and canonicalizes the path part |
| * and then joins all the parts. |
| */ |
| function _joinAndCanonicalizePath(parts) { |
| var path = parts[_ComponentIndex.Path]; |
| path = path == null ? '' : _removeDotSegments(path); |
| parts[_ComponentIndex.Path] = path; |
| return _buildFromEncodedParts(parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo], parts[_ComponentIndex.Domain], parts[_ComponentIndex.Port], path, parts[_ComponentIndex.QueryData], parts[_ComponentIndex.Fragment]); |
| } |
| /** |
| * Resolves a URL. |
| * @param base The URL acting as the base URL. |
| * @param to The URL to resolve. |
| */ |
| function _resolveUrl(base, url) { |
| var parts = _split(encodeURI(url)); |
| var baseParts = _split(base); |
| if (parts[_ComponentIndex.Scheme] != null) { |
| return _joinAndCanonicalizePath(parts); |
| } |
| else { |
| parts[_ComponentIndex.Scheme] = baseParts[_ComponentIndex.Scheme]; |
| } |
| for (var i = _ComponentIndex.Scheme; i <= _ComponentIndex.Port; i++) { |
| if (parts[i] == null) { |
| parts[i] = baseParts[i]; |
| } |
| } |
| if (parts[_ComponentIndex.Path][0] == '/') { |
| return _joinAndCanonicalizePath(parts); |
| } |
| var path = baseParts[_ComponentIndex.Path]; |
| if (path == null) |
| path = '/'; |
| var index = path.lastIndexOf('/'); |
| path = path.substring(0, index + 1) + parts[_ComponentIndex.Path]; |
| parts[_ComponentIndex.Path] = path; |
| return _joinAndCanonicalizePath(parts); |
| } |
| |
| var Extractor = /** @class */ (function () { |
| function Extractor(host, staticSymbolResolver, messageBundle, metadataResolver) { |
| this.host = host; |
| this.staticSymbolResolver = staticSymbolResolver; |
| this.messageBundle = messageBundle; |
| this.metadataResolver = metadataResolver; |
| } |
| Extractor.prototype.extract = function (rootFiles) { |
| var _this = this; |
| var _a = analyzeAndValidateNgModules(rootFiles, this.host, this.staticSymbolResolver, this.metadataResolver), files = _a.files, ngModules = _a.ngModules; |
| return Promise |
| .all(ngModules.map(function (ngModule) { return _this.metadataResolver.loadNgModuleDirectiveAndPipeMetadata(ngModule.type.reference, false); })) |
| .then(function () { |
| var errors = []; |
| files.forEach(function (file) { |
| var compMetas = []; |
| file.directives.forEach(function (directiveType) { |
| var dirMeta = _this.metadataResolver.getDirectiveMetadata(directiveType); |
| if (dirMeta && dirMeta.isComponent) { |
| compMetas.push(dirMeta); |
| } |
| }); |
| compMetas.forEach(function (compMeta) { |
| var html = compMeta.template.template; |
| // Template URL points to either an HTML or TS file depending on |
| // whether the file is used with `templateUrl:` or `template:`, |
| // respectively. |
| var templateUrl = compMeta.template.templateUrl; |
| var interpolationConfig = InterpolationConfig.fromArray(compMeta.template.interpolation); |
| errors.push.apply(errors, __spread(_this.messageBundle.updateFromTemplate(html, templateUrl, interpolationConfig))); |
| }); |
| }); |
| if (errors.length) { |
| throw new Error(errors.map(function (e) { return e.toString(); }).join('\n')); |
| } |
| return _this.messageBundle; |
| }); |
| }; |
| Extractor.create = function (host, locale) { |
| var htmlParser = new HtmlParser(); |
| var urlResolver = createAotUrlResolver(host); |
| var symbolCache = new StaticSymbolCache(); |
| var summaryResolver = new AotSummaryResolver(host, symbolCache); |
| var staticSymbolResolver = new StaticSymbolResolver(host, symbolCache, summaryResolver); |
| var staticReflector = new StaticReflector(summaryResolver, staticSymbolResolver); |
| var config = new CompilerConfig({ defaultEncapsulation: ViewEncapsulation.Emulated, useJit: false }); |
| var normalizer = new DirectiveNormalizer({ get: function (url) { return host.loadResource(url); } }, urlResolver, htmlParser, config); |
| var elementSchemaRegistry = new DomElementSchemaRegistry(); |
| var resolver = new CompileMetadataResolver(config, htmlParser, new NgModuleResolver(staticReflector), new DirectiveResolver(staticReflector), new PipeResolver(staticReflector), summaryResolver, elementSchemaRegistry, normalizer, console, symbolCache, staticReflector); |
| // TODO(vicb): implicit tags & attributes |
| var messageBundle = new MessageBundle(htmlParser, [], {}, locale); |
| var extractor = new Extractor(host, staticSymbolResolver, messageBundle, resolver); |
| return { extractor: extractor, staticReflector: staticReflector }; |
| }; |
| return Extractor; |
| }()); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| |
| /** |
| * Processes `Target`s with a given set of directives and performs a binding operation, which |
| * returns an object similar to TypeScript's `ts.TypeChecker` that contains knowledge about the |
| * target. |
| */ |
| var R3TargetBinder = /** @class */ (function () { |
| function R3TargetBinder(directiveMatcher) { |
| this.directiveMatcher = directiveMatcher; |
| } |
| /** |
| * Perform a binding operation on the given `Target` and return a `BoundTarget` which contains |
| * metadata about the types referenced in the template. |
| */ |
| R3TargetBinder.prototype.bind = function (target) { |
| if (!target.template) { |
| // TODO(alxhub): handle targets which contain things like HostBindings, etc. |
| throw new Error('Binding without a template not yet supported'); |
| } |
| // First, parse the template into a `Scope` structure. This operation captures the syntactic |
| // scopes in the template and makes them available for later use. |
| var scope = Scope.apply(target.template); |
| // Use the `Scope` to extract the entities present at every level of the template. |
| var templateEntities = extractTemplateEntities(scope); |
| // Next, perform directive matching on the template using the `DirectiveBinder`. This returns: |
| // - directives: Map of nodes (elements & ng-templates) to the directives on them. |
| // - bindings: Map of inputs, outputs, and attributes to the directive/element that claims |
| // them. TODO(alxhub): handle multiple directives claiming an input/output/etc. |
| // - references: Map of #references to their targets. |
| var _b = DirectiveBinder.apply(target.template, this.directiveMatcher), directives = _b.directives, bindings = _b.bindings, references = _b.references; |
| // Finally, run the TemplateBinder to bind references, variables, and other entities within the |
| // template. This extracts all the metadata that doesn't depend on directive matching. |
| var _c = TemplateBinder.apply(target.template, scope), expressions = _c.expressions, symbols = _c.symbols, nestingLevel = _c.nestingLevel, usedPipes = _c.usedPipes; |
| return new R3BoundTarget(target, directives, bindings, references, expressions, symbols, nestingLevel, templateEntities, usedPipes); |
| }; |
| return R3TargetBinder; |
| }()); |
| /** |
| * Represents a binding scope within a template. |
| * |
| * Any variables, references, or other named entities declared within the template will |
| * be captured and available by name in `namedEntities`. Additionally, child templates will |
| * be analyzed and have their child `Scope`s available in `childScopes`. |
| */ |
| var Scope = /** @class */ (function () { |
| function Scope(parentScope, template) { |
| this.parentScope = parentScope; |
| this.template = template; |
| /** |
| * Named members of the `Scope`, such as `Reference`s or `Variable`s. |
| */ |
| this.namedEntities = new Map(); |
| /** |
| * Child `Scope`s for immediately nested `Template`s. |
| */ |
| this.childScopes = new Map(); |
| } |
| Scope.newRootScope = function () { |
| return new Scope(null, null); |
| }; |
| /** |
| * Process a template (either as a `Template` sub-template with variables, or a plain array of |
| * template `Node`s) and construct its `Scope`. |
| */ |
| Scope.apply = function (template) { |
| var scope = Scope.newRootScope(); |
| scope.ingest(template); |
| return scope; |
| }; |
| /** |
| * Internal method to process the template and populate the `Scope`. |
| */ |
| Scope.prototype.ingest = function (template) { |
| var _this = this; |
| if (template instanceof Template) { |
| // Variables on an <ng-template> are defined in the inner scope. |
| template.variables.forEach(function (node) { return _this.visitVariable(node); }); |
| // Process the nodes of the template. |
| template.children.forEach(function (node) { return node.visit(_this); }); |
| } |
| else { |
| // No overarching `Template` instance, so process the nodes directly. |
| template.forEach(function (node) { return node.visit(_this); }); |
| } |
| }; |
| Scope.prototype.visitElement = function (element) { |
| var _this = this; |
| // `Element`s in the template may have `Reference`s which are captured in the scope. |
| element.references.forEach(function (node) { return _this.visitReference(node); }); |
| // Recurse into the `Element`'s children. |
| element.children.forEach(function (node) { return node.visit(_this); }); |
| }; |
| Scope.prototype.visitTemplate = function (template) { |
| var _this = this; |
| // References on a <ng-template> are defined in the outer scope, so capture them before |
| // processing the template's child scope. |
| template.references.forEach(function (node) { return _this.visitReference(node); }); |
| // Next, create an inner scope and process the template within it. |
| var scope = new Scope(this, template); |
| scope.ingest(template); |
| this.childScopes.set(template, scope); |
| }; |
| Scope.prototype.visitVariable = function (variable) { |
| // Declare the variable if it's not already. |
| this.maybeDeclare(variable); |
| }; |
| Scope.prototype.visitReference = function (reference) { |
| // Declare the variable if it's not already. |
| this.maybeDeclare(reference); |
| }; |
| // Unused visitors. |
| Scope.prototype.visitContent = function (content) { }; |
| Scope.prototype.visitBoundAttribute = function (attr) { }; |
| Scope.prototype.visitBoundEvent = function (event) { }; |
| Scope.prototype.visitBoundText = function (text) { }; |
| Scope.prototype.visitText = function (text) { }; |
| Scope.prototype.visitTextAttribute = function (attr) { }; |
| Scope.prototype.visitIcu = function (icu) { }; |
| Scope.prototype.maybeDeclare = function (thing) { |
| // Declare something with a name, as long as that name isn't taken. |
| if (!this.namedEntities.has(thing.name)) { |
| this.namedEntities.set(thing.name, thing); |
| } |
| }; |
| /** |
| * Look up a variable within this `Scope`. |
| * |
| * This can recurse into a parent `Scope` if it's available. |
| */ |
| Scope.prototype.lookup = function (name) { |
| if (this.namedEntities.has(name)) { |
| // Found in the local scope. |
| return this.namedEntities.get(name); |
| } |
| else if (this.parentScope !== null) { |
| // Not in the local scope, but there's a parent scope so check there. |
| return this.parentScope.lookup(name); |
| } |
| else { |
| // At the top level and it wasn't found. |
| return null; |
| } |
| }; |
| /** |
| * Get the child scope for a `Template`. |
| * |
| * This should always be defined. |
| */ |
| Scope.prototype.getChildScope = function (template) { |
| var res = this.childScopes.get(template); |
| if (res === undefined) { |
| throw new Error("Assertion error: child scope for " + template + " not found"); |
| } |
| return res; |
| }; |
| return Scope; |
| }()); |
| /** |
| * Processes a template and matches directives on nodes (elements and templates). |
| * |
| * Usually used via the static `apply()` method. |
| */ |
| var DirectiveBinder = /** @class */ (function () { |
| function DirectiveBinder(matcher, directives, bindings, references) { |
| this.matcher = matcher; |
| this.directives = directives; |
| this.bindings = bindings; |
| this.references = references; |
| } |
| /** |
| * Process a template (list of `Node`s) and perform directive matching against each node. |
| * |
| * @param template the list of template `Node`s to match (recursively). |
| * @param selectorMatcher a `SelectorMatcher` containing the directives that are in scope for |
| * this template. |
| * @returns three maps which contain information about directives in the template: the |
| * `directives` map which lists directives matched on each node, the `bindings` map which |
| * indicates which directives claimed which bindings (inputs, outputs, etc), and the `references` |
| * map which resolves #references (`Reference`s) within the template to the named directive or |
| * template node. |
| */ |
| DirectiveBinder.apply = function (template, selectorMatcher) { |
| var directives = new Map(); |
| var bindings = new Map(); |
| var references = new Map(); |
| var matcher = new DirectiveBinder(selectorMatcher, directives, bindings, references); |
| matcher.ingest(template); |
| return { directives: directives, bindings: bindings, references: references }; |
| }; |
| DirectiveBinder.prototype.ingest = function (template) { |
| var _this = this; |
| template.forEach(function (node) { return node.visit(_this); }); |
| }; |
| DirectiveBinder.prototype.visitElement = function (element) { |
| this.visitElementOrTemplate(element.name, element); |
| }; |
| DirectiveBinder.prototype.visitTemplate = function (template) { |
| this.visitElementOrTemplate('ng-template', template); |
| }; |
| DirectiveBinder.prototype.visitElementOrTemplate = function (elementName, node) { |
| var _this = this; |
| // First, determine the HTML shape of the node for the purpose of directive matching. |
| // Do this by building up a `CssSelector` for the node. |
| var cssSelector = createCssSelector(elementName, getAttrsForDirectiveMatching(node)); |
| // Next, use the `SelectorMatcher` to get the list of directives on the node. |
| var directives = []; |
| this.matcher.match(cssSelector, function (_, directive) { return directives.push(directive); }); |
| if (directives.length > 0) { |
| this.directives.set(node, directives); |
| } |
| // Resolve any references that are created on this node. |
| node.references.forEach(function (ref) { |
| var dirTarget = null; |
| // If the reference expression is empty, then it matches the "primary" directive on the node |
| // (if there is one). Otherwise it matches the host node itself (either an element or |
| // <ng-template> node). |
| if (ref.value.trim() === '') { |
| // This could be a reference to a component if there is one. |
| dirTarget = directives.find(function (dir) { return dir.isComponent; }) || null; |
| } |
| else { |
| // This should be a reference to a directive exported via exportAs. |
| dirTarget = |
| directives.find(function (dir) { return dir.exportAs !== null && dir.exportAs.some(function (value) { return value === ref.value; }); }) || |
| null; |
| // Check if a matching directive was found. |
| if (dirTarget === null) { |
| // No matching directive was found - this reference points to an unknown target. Leave it |
| // unmapped. |
| return; |
| } |
| } |
| if (dirTarget !== null) { |
| // This reference points to a directive. |
| _this.references.set(ref, { directive: dirTarget, node: node }); |
| } |
| else { |
| // This reference points to the node itself. |
| _this.references.set(ref, node); |
| } |
| }); |
| var setAttributeBinding = function (attribute, ioType) { |
| var dir = directives.find(function (dir) { return dir[ioType].hasBindingPropertyName(attribute.name); }); |
| var binding = dir !== undefined ? dir : node; |
| _this.bindings.set(attribute, binding); |
| }; |
| // Node inputs (bound attributes) and text attributes can be bound to an |
| // input on a directive. |
| node.inputs.forEach(function (input) { return setAttributeBinding(input, 'inputs'); }); |
| node.attributes.forEach(function (attr) { return setAttributeBinding(attr, 'inputs'); }); |
| if (node instanceof Template) { |
| node.templateAttrs.forEach(function (attr) { return setAttributeBinding(attr, 'inputs'); }); |
| } |
| // Node outputs (bound events) can be bound to an output on a directive. |
| node.outputs.forEach(function (output) { return setAttributeBinding(output, 'outputs'); }); |
| // Recurse into the node's children. |
| node.children.forEach(function (child) { return child.visit(_this); }); |
| }; |
| // Unused visitors. |
| DirectiveBinder.prototype.visitContent = function (content) { }; |
| DirectiveBinder.prototype.visitVariable = function (variable) { }; |
| DirectiveBinder.prototype.visitReference = function (reference) { }; |
| DirectiveBinder.prototype.visitTextAttribute = function (attribute) { }; |
| DirectiveBinder.prototype.visitBoundAttribute = function (attribute) { }; |
| DirectiveBinder.prototype.visitBoundEvent = function (attribute) { }; |
| DirectiveBinder.prototype.visitBoundAttributeOrEvent = function (node) { }; |
| DirectiveBinder.prototype.visitText = function (text) { }; |
| DirectiveBinder.prototype.visitBoundText = function (text) { }; |
| DirectiveBinder.prototype.visitIcu = function (icu) { }; |
| return DirectiveBinder; |
| }()); |
| /** |
| * Processes a template and extract metadata about expressions and symbols within. |
| * |
| * This is a companion to the `DirectiveBinder` that doesn't require knowledge of directives matched |
| * within the template in order to operate. |
| * |
| * Expressions are visited by the superclass `RecursiveAstVisitor`, with custom logic provided |
| * by overridden methods from that visitor. |
| */ |
| var TemplateBinder = /** @class */ (function (_super) { |
| __extends(TemplateBinder, _super); |
| function TemplateBinder(bindings, symbols, usedPipes, nestingLevel, scope, template, level) { |
| var _this = _super.call(this) || this; |
| _this.bindings = bindings; |
| _this.symbols = symbols; |
| _this.usedPipes = usedPipes; |
| _this.nestingLevel = nestingLevel; |
| _this.scope = scope; |
| _this.template = template; |
| _this.level = level; |
| _this.pipesUsed = []; |
| // Save a bit of processing time by constructing this closure in advance. |
| _this.visitNode = function (node) { return node.visit(_this); }; |
| return _this; |
| } |
| // This method is defined to reconcile the type of TemplateBinder since both |
| // RecursiveAstVisitor and Visitor define the visit() method in their |
| // interfaces. |
| TemplateBinder.prototype.visit = function (node, context) { |
| if (node instanceof AST) { |
| node.visit(this, context); |
| } |
| else { |
| node.visit(this); |
| } |
| }; |
| /** |
| * Process a template and extract metadata about expressions and symbols within. |
| * |
| * @param template the nodes of the template to process |
| * @param scope the `Scope` of the template being processed. |
| * @returns three maps which contain metadata about the template: `expressions` which interprets |
| * special `AST` nodes in expressions as pointing to references or variables declared within the |
| * template, `symbols` which maps those variables and references to the nested `Template` which |
| * declares them, if any, and `nestingLevel` which associates each `Template` with a integer |
| * nesting level (how many levels deep within the template structure the `Template` is), starting |
| * at 1. |
| */ |
| TemplateBinder.apply = function (template, scope) { |
| var expressions = new Map(); |
| var symbols = new Map(); |
| var nestingLevel = new Map(); |
| var usedPipes = new Set(); |
| // The top-level template has nesting level 0. |
| var binder = new TemplateBinder(expressions, symbols, usedPipes, nestingLevel, scope, template instanceof Template ? template : null, 0); |
| binder.ingest(template); |
| return { expressions: expressions, symbols: symbols, nestingLevel: nestingLevel, usedPipes: usedPipes }; |
| }; |
| TemplateBinder.prototype.ingest = function (template) { |
| if (template instanceof Template) { |
| // For <ng-template>s, process only variables and child nodes. Inputs, outputs, templateAttrs, |
| // and references were all processed in the scope of the containing template. |
| template.variables.forEach(this.visitNode); |
| template.children.forEach(this.visitNode); |
| // Set the nesting level. |
| this.nestingLevel.set(template, this.level); |
| } |
| else { |
| // Visit each node from the top-level template. |
| template.forEach(this.visitNode); |
| } |
| }; |
| TemplateBinder.prototype.visitElement = function (element) { |
| // Visit the inputs, outputs, and children of the element. |
| element.inputs.forEach(this.visitNode); |
| element.outputs.forEach(this.visitNode); |
| element.children.forEach(this.visitNode); |
| }; |
| TemplateBinder.prototype.visitTemplate = function (template) { |
| // First, visit inputs, outputs and template attributes of the template node. |
| template.inputs.forEach(this.visitNode); |
| template.outputs.forEach(this.visitNode); |
| template.templateAttrs.forEach(this.visitNode); |
| // References are also evaluated in the outer context. |
| template.references.forEach(this.visitNode); |
| // Next, recurse into the template using its scope, and bumping the nesting level up by one. |
| var childScope = this.scope.getChildScope(template); |
| var binder = new TemplateBinder(this.bindings, this.symbols, this.usedPipes, this.nestingLevel, childScope, template, this.level + 1); |
| binder.ingest(template); |
| }; |
| TemplateBinder.prototype.visitVariable = function (variable) { |
| // Register the `Variable` as a symbol in the current `Template`. |
| if (this.template !== null) { |
| this.symbols.set(variable, this.template); |
| } |
| }; |
| TemplateBinder.prototype.visitReference = function (reference) { |
| // Register the `Reference` as a symbol in the current `Template`. |
| if (this.template !== null) { |
| this.symbols.set(reference, this.template); |
| } |
| }; |
| // Unused template visitors |
| TemplateBinder.prototype.visitText = function (text) { }; |
| TemplateBinder.prototype.visitContent = function (content) { }; |
| TemplateBinder.prototype.visitTextAttribute = function (attribute) { }; |
| TemplateBinder.prototype.visitIcu = function (icu) { |
| var _this = this; |
| Object.keys(icu.vars).forEach(function (key) { return icu.vars[key].visit(_this); }); |
| Object.keys(icu.placeholders).forEach(function (key) { return icu.placeholders[key].visit(_this); }); |
| }; |
| // The remaining visitors are concerned with processing AST expressions within template bindings |
| TemplateBinder.prototype.visitBoundAttribute = function (attribute) { |
| attribute.value.visit(this); |
| }; |
| TemplateBinder.prototype.visitBoundEvent = function (event) { |
| event.handler.visit(this); |
| }; |
| TemplateBinder.prototype.visitBoundText = function (text) { |
| text.value.visit(this); |
| }; |
| TemplateBinder.prototype.visitPipe = function (ast, context) { |
| this.usedPipes.add(ast.name); |
| return _super.prototype.visitPipe.call(this, ast, context); |
| }; |
| // These five types of AST expressions can refer to expression roots, which could be variables |
| // or references in the current scope. |
| TemplateBinder.prototype.visitPropertyRead = function (ast, context) { |
| this.maybeMap(context, ast, ast.name); |
| return _super.prototype.visitPropertyRead.call(this, ast, context); |
| }; |
| TemplateBinder.prototype.visitSafePropertyRead = function (ast, context) { |
| this.maybeMap(context, ast, ast.name); |
| return _super.prototype.visitSafePropertyRead.call(this, ast, context); |
| }; |
| TemplateBinder.prototype.visitPropertyWrite = function (ast, context) { |
| this.maybeMap(context, ast, ast.name); |
| return _super.prototype.visitPropertyWrite.call(this, ast, context); |
| }; |
| TemplateBinder.prototype.visitMethodCall = function (ast, context) { |
| this.maybeMap(context, ast, ast.name); |
| return _super.prototype.visitMethodCall.call(this, ast, context); |
| }; |
| TemplateBinder.prototype.visitSafeMethodCall = function (ast, context) { |
| this.maybeMap(context, ast, ast.name); |
| return _super.prototype.visitSafeMethodCall.call(this, ast, context); |
| }; |
| TemplateBinder.prototype.maybeMap = function (scope, ast, name) { |
| // If the receiver of the expression isn't the `ImplicitReceiver`, this isn't the root of an |
| // `AST` expression that maps to a `Variable` or `Reference`. |
| if (!(ast.receiver instanceof ImplicitReceiver)) { |
| return; |
| } |
| // Check whether the name exists in the current scope. If so, map it. Otherwise, the name is |
| // probably a property on the top-level component context. |
| var target = this.scope.lookup(name); |
| if (target !== null) { |
| this.bindings.set(ast, target); |
| } |
| }; |
| return TemplateBinder; |
| }(RecursiveAstVisitor$1)); |
| /** |
| * Metadata container for a `Target` that allows queries for specific bits of metadata. |
| * |
| * See `BoundTarget` for documentation on the individual methods. |
| */ |
| var R3BoundTarget = /** @class */ (function () { |
| function R3BoundTarget(target, directives, bindings, references, exprTargets, symbols, nestingLevel, templateEntities, usedPipes) { |
| this.target = target; |
| this.directives = directives; |
| this.bindings = bindings; |
| this.references = references; |
| this.exprTargets = exprTargets; |
| this.symbols = symbols; |
| this.nestingLevel = nestingLevel; |
| this.templateEntities = templateEntities; |
| this.usedPipes = usedPipes; |
| } |
| R3BoundTarget.prototype.getEntitiesInTemplateScope = function (template) { |
| var _a; |
| return (_a = this.templateEntities.get(template)) !== null && _a !== void 0 ? _a : new Set(); |
| }; |
| R3BoundTarget.prototype.getDirectivesOfNode = function (node) { |
| return this.directives.get(node) || null; |
| }; |
| R3BoundTarget.prototype.getReferenceTarget = function (ref) { |
| return this.references.get(ref) || null; |
| }; |
| R3BoundTarget.prototype.getConsumerOfBinding = function (binding) { |
| return this.bindings.get(binding) || null; |
| }; |
| R3BoundTarget.prototype.getExpressionTarget = function (expr) { |
| return this.exprTargets.get(expr) || null; |
| }; |
| R3BoundTarget.prototype.getTemplateOfSymbol = function (symbol) { |
| return this.symbols.get(symbol) || null; |
| }; |
| R3BoundTarget.prototype.getNestingLevel = function (template) { |
| return this.nestingLevel.get(template) || 0; |
| }; |
| R3BoundTarget.prototype.getUsedDirectives = function () { |
| var set = new Set(); |
| this.directives.forEach(function (dirs) { return dirs.forEach(function (dir) { return set.add(dir); }); }); |
| return Array.from(set.values()); |
| }; |
| R3BoundTarget.prototype.getUsedPipes = function () { |
| return Array.from(this.usedPipes); |
| }; |
| return R3BoundTarget; |
| }()); |
| function extractTemplateEntities(rootScope) { |
| var e_1, _b, e_2, _c; |
| var entityMap = new Map(); |
| function extractScopeEntities(scope) { |
| if (entityMap.has(scope.template)) { |
| return entityMap.get(scope.template); |
| } |
| var currentEntities = scope.namedEntities; |
| var templateEntities; |
| if (scope.parentScope !== null) { |
| templateEntities = new Map(__spread(extractScopeEntities(scope.parentScope), currentEntities)); |
| } |
| else { |
| templateEntities = new Map(currentEntities); |
| } |
| entityMap.set(scope.template, templateEntities); |
| return templateEntities; |
| } |
| var scopesToProcess = [rootScope]; |
| while (scopesToProcess.length > 0) { |
| var scope = scopesToProcess.pop(); |
| try { |
| for (var _d = (e_1 = void 0, __values(scope.childScopes.values())), _e = _d.next(); !_e.done; _e = _d.next()) { |
| var childScope = _e.value; |
| scopesToProcess.push(childScope); |
| } |
| } |
| catch (e_1_1) { e_1 = { error: e_1_1 }; } |
| finally { |
| try { |
| if (_e && !_e.done && (_b = _d.return)) _b.call(_d); |
| } |
| finally { if (e_1) throw e_1.error; } |
| } |
| extractScopeEntities(scope); |
| } |
| var templateEntities = new Map(); |
| try { |
| for (var entityMap_1 = __values(entityMap), entityMap_1_1 = entityMap_1.next(); !entityMap_1_1.done; entityMap_1_1 = entityMap_1.next()) { |
| var _f = __read(entityMap_1_1.value, 2), template = _f[0], entities = _f[1]; |
| templateEntities.set(template, new Set(entities.values())); |
| } |
| } |
| catch (e_2_1) { e_2 = { error: e_2_1 }; } |
| finally { |
| try { |
| if (entityMap_1_1 && !entityMap_1_1.done && (_c = entityMap_1.return)) _c.call(entityMap_1); |
| } |
| finally { if (e_2) throw e_2.error; } |
| } |
| return templateEntities; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Creates an array literal expression from the given array, mapping all values to an expression |
| * using the provided mapping function. If the array is empty or null, then null is returned. |
| * |
| * @param values The array to transfer into literal array expression. |
| * @param mapper The logic to use for creating an expression for the array's values. |
| * @returns An array literal expression representing `values`, or null if `values` is empty or |
| * is itself null. |
| */ |
| function toOptionalLiteralArray(values, mapper) { |
| if (values === null || values.length === 0) { |
| return null; |
| } |
| return literalArr(values.map(function (value) { return mapper(value); })); |
| } |
| /** |
| * Creates an object literal expression from the given object, mapping all values to an expression |
| * using the provided mapping function. If the object has no keys, then null is returned. |
| * |
| * @param object The object to transfer into an object literal expression. |
| * @param mapper The logic to use for creating an expression for the object's values. |
| * @returns An object literal expression representing `object`, or null if `object` does not have |
| * any keys. |
| */ |
| function toOptionalLiteralMap(object, mapper) { |
| var entries = Object.keys(object).map(function (key) { |
| var value = object[key]; |
| return { key: key, value: mapper(value), quoted: true }; |
| }); |
| if (entries.length > 0) { |
| return literalMap(entries); |
| } |
| else { |
| return null; |
| } |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Compile a directive declaration defined by the `R3DirectiveMetadata`. |
| */ |
| function compileDeclareDirectiveFromMetadata(meta) { |
| var definitionMap = createDirectiveDefinitionMap(meta); |
| var expression = importExpr(Identifiers$1.declareDirective).callFn([definitionMap.toLiteralMap()]); |
| var type = createDirectiveType(meta); |
| return { expression: expression, type: type }; |
| } |
| /** |
| * Gathers the declaration fields for a directive into a `DefinitionMap`. This allows for reusing |
| * this logic for components, as they extend the directive metadata. |
| */ |
| function createDirectiveDefinitionMap(meta) { |
| var definitionMap = new DefinitionMap(); |
| definitionMap.set('version', literal('11.2.14')); |
| // e.g. `type: MyDirective` |
| definitionMap.set('type', meta.internalType); |
| // e.g. `selector: 'some-dir'` |
| if (meta.selector !== null) { |
| definitionMap.set('selector', literal(meta.selector)); |
| } |
| definitionMap.set('inputs', conditionallyCreateMapObjectLiteral(meta.inputs, true)); |
| definitionMap.set('outputs', conditionallyCreateMapObjectLiteral(meta.outputs)); |
| definitionMap.set('host', compileHostMetadata(meta.host)); |
| definitionMap.set('providers', meta.providers); |
| if (meta.queries.length > 0) { |
| definitionMap.set('queries', literalArr(meta.queries.map(compileQuery))); |
| } |
| if (meta.viewQueries.length > 0) { |
| definitionMap.set('viewQueries', literalArr(meta.viewQueries.map(compileQuery))); |
| } |
| if (meta.exportAs !== null) { |
| definitionMap.set('exportAs', asLiteral(meta.exportAs)); |
| } |
| if (meta.usesInheritance) { |
| definitionMap.set('usesInheritance', literal(true)); |
| } |
| if (meta.lifecycle.usesOnChanges) { |
| definitionMap.set('usesOnChanges', literal(true)); |
| } |
| definitionMap.set('ngImport', importExpr(Identifiers$1.core)); |
| return definitionMap; |
| } |
| /** |
| * Compiles the metadata of a single query into its partial declaration form as declared |
| * by `R3DeclareQueryMetadata`. |
| */ |
| function compileQuery(query) { |
| var meta = new DefinitionMap(); |
| meta.set('propertyName', literal(query.propertyName)); |
| if (query.first) { |
| meta.set('first', literal(true)); |
| } |
| meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) : query.predicate); |
| if (!query.emitDistinctChangesOnly) { |
| // `emitDistinctChangesOnly` is special because in future we expect it to be `true`. For this |
| // reason the absence should be interpreted as `true`. |
| meta.set('emitDistinctChangesOnly', literal(false)); |
| } |
| if (query.descendants) { |
| meta.set('descendants', literal(true)); |
| } |
| meta.set('read', query.read); |
| if (query.static) { |
| meta.set('static', literal(true)); |
| } |
| return meta.toLiteralMap(); |
| } |
| /** |
| * Compiles the host metadata into its partial declaration form as declared |
| * in `R3DeclareDirectiveMetadata['host']` |
| */ |
| function compileHostMetadata(meta) { |
| var hostMetadata = new DefinitionMap(); |
| hostMetadata.set('attributes', toOptionalLiteralMap(meta.attributes, function (expression) { return expression; })); |
| hostMetadata.set('listeners', toOptionalLiteralMap(meta.listeners, literal)); |
| hostMetadata.set('properties', toOptionalLiteralMap(meta.properties, literal)); |
| if (meta.specialAttributes.styleAttr) { |
| hostMetadata.set('styleAttribute', literal(meta.specialAttributes.styleAttr)); |
| } |
| if (meta.specialAttributes.classAttr) { |
| hostMetadata.set('classAttribute', literal(meta.specialAttributes.classAttr)); |
| } |
| if (hostMetadata.values.length > 0) { |
| return hostMetadata.toLiteralMap(); |
| } |
| else { |
| return null; |
| } |
| } |
| |
| /** |
| * Compile a component declaration defined by the `R3ComponentMetadata`. |
| */ |
| function compileDeclareComponentFromMetadata(meta, template) { |
| var definitionMap = createComponentDefinitionMap(meta, template); |
| var expression = importExpr(Identifiers$1.declareComponent).callFn([definitionMap.toLiteralMap()]); |
| var type = createComponentType(meta); |
| return { expression: expression, type: type }; |
| } |
| /** |
| * Gathers the declaration fields for a component into a `DefinitionMap`. |
| */ |
| function createComponentDefinitionMap(meta, template) { |
| var definitionMap = createDirectiveDefinitionMap(meta); |
| definitionMap.set('template', getTemplateExpression(template)); |
| if (template.isInline) { |
| definitionMap.set('isInline', literal(true)); |
| } |
| definitionMap.set('styles', toOptionalLiteralArray(meta.styles, literal)); |
| definitionMap.set('directives', compileUsedDirectiveMetadata(meta)); |
| definitionMap.set('pipes', compileUsedPipeMetadata(meta)); |
| definitionMap.set('viewProviders', meta.viewProviders); |
| definitionMap.set('animations', meta.animations); |
| if (meta.changeDetection !== undefined) { |
| definitionMap.set('changeDetection', importExpr(Identifiers$1.ChangeDetectionStrategy) |
| .prop(ChangeDetectionStrategy[meta.changeDetection])); |
| } |
| if (meta.encapsulation !== ViewEncapsulation.Emulated) { |
| definitionMap.set('encapsulation', importExpr(Identifiers$1.ViewEncapsulation).prop(ViewEncapsulation[meta.encapsulation])); |
| } |
| if (meta.interpolation !== DEFAULT_INTERPOLATION_CONFIG) { |
| definitionMap.set('interpolation', literalArr([literal(meta.interpolation.start), literal(meta.interpolation.end)])); |
| } |
| if (template.preserveWhitespaces === true) { |
| definitionMap.set('preserveWhitespaces', literal(true)); |
| } |
| return definitionMap; |
| } |
| function getTemplateExpression(template) { |
| if (typeof template.template === 'string') { |
| if (template.isInline) { |
| // The template is inline but not a simple literal string, so give up with trying to |
| // source-map it and just return a simple literal here. |
| return literal(template.template); |
| } |
| else { |
| // The template is external so we must synthesize an expression node with the appropriate |
| // source-span. |
| var contents = template.template; |
| var file = new ParseSourceFile(contents, template.templateUrl); |
| var start = new ParseLocation(file, 0, 0, 0); |
| var end = computeEndLocation(file, contents); |
| var span = new ParseSourceSpan(start, end); |
| return literal(contents, null, span); |
| } |
| } |
| else { |
| // The template is inline so we can just reuse the current expression node. |
| return template.template; |
| } |
| } |
| function computeEndLocation(file, contents) { |
| var length = contents.length; |
| var lineStart = 0; |
| var lastLineStart = 0; |
| var line = 0; |
| do { |
| lineStart = contents.indexOf('\n', lastLineStart); |
| if (lineStart !== -1) { |
| lastLineStart = lineStart + 1; |
| line++; |
| } |
| } while (lineStart !== -1); |
| return new ParseLocation(file, length, line, length - lastLineStart); |
| } |
| /** |
| * Compiles the directives as registered in the component metadata into an array literal of the |
| * individual directives. If the component does not use any directives, then null is returned. |
| */ |
| function compileUsedDirectiveMetadata(meta) { |
| var wrapType = meta.declarationListEmitMode !== 0 /* Direct */ ? |
| generateForwardRef : |
| function (expr) { return expr; }; |
| return toOptionalLiteralArray(meta.directives, function (directive) { |
| var dirMeta = new DefinitionMap(); |
| dirMeta.set('type', wrapType(directive.type)); |
| dirMeta.set('selector', literal(directive.selector)); |
| dirMeta.set('inputs', toOptionalLiteralArray(directive.inputs, literal)); |
| dirMeta.set('outputs', toOptionalLiteralArray(directive.outputs, literal)); |
| dirMeta.set('exportAs', toOptionalLiteralArray(directive.exportAs, literal)); |
| return dirMeta.toLiteralMap(); |
| }); |
| } |
| /** |
| * Compiles the pipes as registered in the component metadata into an object literal, where the |
| * pipe's name is used as key and a reference to its type as value. If the component does not use |
| * any pipes, then null is returned. |
| */ |
| function compileUsedPipeMetadata(meta) { |
| var e_1, _a; |
| if (meta.pipes.size === 0) { |
| return null; |
| } |
| var wrapType = meta.declarationListEmitMode !== 0 /* Direct */ ? |
| generateForwardRef : |
| function (expr) { return expr; }; |
| var entries = []; |
| try { |
| for (var _b = __values(meta.pipes), _c = _b.next(); !_c.done; _c = _b.next()) { |
| var _d = __read(_c.value, 2), name = _d[0], pipe = _d[1]; |
| entries.push({ key: name, value: wrapType(pipe), quoted: 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 literalMap(entries); |
| } |
| function generateForwardRef(expr) { |
| return importExpr(Identifiers$1.forwardRef).callFn([fn([], [new ReturnStatement(expr)])]); |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * Compile a Pipe declaration defined by the `R3PipeMetadata`. |
| */ |
| function compileDeclarePipeFromMetadata(meta) { |
| var definitionMap = createPipeDefinitionMap(meta); |
| var expression = importExpr(Identifiers$1.declarePipe).callFn([definitionMap.toLiteralMap()]); |
| var type = createPipeType(meta); |
| return { expression: expression, type: type }; |
| } |
| /** |
| * Gathers the declaration fields for a Pipe into a `DefinitionMap`. This allows for reusing |
| * this logic for components, as they extend the Pipe metadata. |
| */ |
| function createPipeDefinitionMap(meta) { |
| var definitionMap = new DefinitionMap(); |
| definitionMap.set('version', literal('11.2.14')); |
| definitionMap.set('ngImport', importExpr(Identifiers$1.core)); |
| // e.g. `type: MyPipe` |
| definitionMap.set('type', meta.internalType); |
| // e.g. `name: "myPipe"` |
| definitionMap.set('name', literal(meta.pipeName)); |
| if (meta.pure === false) { |
| // e.g. `pure: false` |
| definitionMap.set('pure', literal(meta.pure)); |
| } |
| return definitionMap; |
| } |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| // This file only reexports content of the `src` folder. Keep it that way. |
| // This function call has a global side effects and publishes the compiler into global namespace for |
| // the late binding of the Compiler to the @angular/core for jit compilation. |
| publishFacade(_global); |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| // This file only reexports content of the `src` folder. Keep it that way. |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| |
| /** |
| * @license |
| * Copyright Google LLC All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| |
| exports.AST = AST; |
| exports.ASTWithName = ASTWithName; |
| exports.ASTWithSource = ASTWithSource; |
| exports.AbsoluteSourceSpan = AbsoluteSourceSpan; |
| exports.AotCompiler = AotCompiler; |
| exports.AotSummaryResolver = AotSummaryResolver; |
| exports.ArrayType = ArrayType; |
| exports.AssertNotNull = AssertNotNull; |
| exports.AstMemoryEfficientTransformer = AstMemoryEfficientTransformer; |
| exports.AstPath = AstPath; |
| exports.AstTransformer = AstTransformer$1; |
| exports.AttrAst = AttrAst; |
| exports.Attribute = Attribute; |
| exports.Binary = Binary; |
| exports.BinaryOperatorExpr = BinaryOperatorExpr; |
| exports.BindingPipe = BindingPipe; |
| exports.BoundDirectivePropertyAst = BoundDirectivePropertyAst; |
| exports.BoundElementProperty = BoundElementProperty; |
| exports.BoundElementPropertyAst = BoundElementPropertyAst; |
| exports.BoundEventAst = BoundEventAst; |
| exports.BoundTextAst = BoundTextAst; |
| exports.BuiltinType = BuiltinType; |
| exports.CONTENT_ATTR = CONTENT_ATTR; |
| exports.CUSTOM_ELEMENTS_SCHEMA = CUSTOM_ELEMENTS_SCHEMA; |
| exports.CastExpr = CastExpr; |
| exports.Chain = Chain; |
| exports.ClassField = ClassField; |
| exports.ClassMethod = ClassMethod; |
| exports.ClassStmt = ClassStmt; |
| exports.CommaExpr = CommaExpr; |
| exports.Comment = Comment$1; |
| exports.CompileDirectiveMetadata = CompileDirectiveMetadata; |
| exports.CompileMetadataResolver = CompileMetadataResolver; |
| exports.CompileNgModuleMetadata = CompileNgModuleMetadata; |
| exports.CompilePipeMetadata = CompilePipeMetadata; |
| exports.CompileReflector = CompileReflector; |
| exports.CompileShallowModuleMetadata = CompileShallowModuleMetadata; |
| exports.CompileStylesheetMetadata = CompileStylesheetMetadata; |
| exports.CompileTemplateMetadata = CompileTemplateMetadata; |
| exports.CompiledStylesheet = CompiledStylesheet; |
| exports.CompilerConfig = CompilerConfig; |
| exports.Conditional = Conditional; |
| exports.ConditionalExpr = ConditionalExpr; |
| exports.ConstantPool = ConstantPool; |
| exports.CssSelector = CssSelector; |
| exports.DEFAULT_INTERPOLATION_CONFIG = DEFAULT_INTERPOLATION_CONFIG; |
| exports.DYNAMIC_TYPE = DYNAMIC_TYPE; |
| exports.DeclareFunctionStmt = DeclareFunctionStmt; |
| exports.DeclareVarStmt = DeclareVarStmt; |
| exports.DirectiveAst = DirectiveAst; |
| exports.DirectiveNormalizer = DirectiveNormalizer; |
| exports.DirectiveResolver = DirectiveResolver; |
| exports.DomElementSchemaRegistry = DomElementSchemaRegistry; |
| exports.EOF = EOF; |
| exports.ERROR_COMPONENT_TYPE = ERROR_COMPONENT_TYPE; |
| exports.Element = Element$1; |
| exports.ElementAst = ElementAst; |
| exports.ElementSchemaRegistry = ElementSchemaRegistry; |
| exports.EmbeddedTemplateAst = EmbeddedTemplateAst; |
| exports.EmitterVisitorContext = EmitterVisitorContext; |
| exports.EmptyExpr = EmptyExpr; |
| exports.Expansion = Expansion; |
| exports.ExpansionCase = ExpansionCase; |
| exports.Expression = Expression; |
| exports.ExpressionBinding = ExpressionBinding; |
| exports.ExpressionStatement = ExpressionStatement; |
| exports.ExpressionType = ExpressionType; |
| exports.ExternalExpr = ExternalExpr; |
| exports.ExternalReference = ExternalReference; |
| exports.Extractor = Extractor; |
| exports.FunctionCall = FunctionCall; |
| exports.FunctionExpr = FunctionExpr; |
| exports.GeneratedFile = GeneratedFile; |
| exports.HOST_ATTR = HOST_ATTR; |
| exports.HtmlParser = HtmlParser; |
| exports.HtmlTagDefinition = HtmlTagDefinition; |
| exports.I18NHtmlParser = I18NHtmlParser; |
| exports.Identifiers = Identifiers; |
| exports.IfStmt = IfStmt; |
| exports.ImplicitReceiver = ImplicitReceiver; |
| exports.InstantiateExpr = InstantiateExpr; |
| exports.Interpolation = Interpolation; |
| exports.InterpolationConfig = InterpolationConfig; |
| exports.InvokeFunctionExpr = InvokeFunctionExpr; |
| exports.InvokeMethodExpr = InvokeMethodExpr; |
| exports.IvyParser = IvyParser; |
| exports.JSDocComment = JSDocComment; |
| exports.JitCompiler = JitCompiler; |
| exports.JitEvaluator = JitEvaluator; |
| exports.JitSummaryResolver = JitSummaryResolver; |
| exports.KeyedRead = KeyedRead; |
| exports.KeyedWrite = KeyedWrite; |
| exports.LeadingComment = LeadingComment; |
| exports.Lexer = Lexer; |
| exports.LiteralArray = LiteralArray; |
| exports.LiteralArrayExpr = LiteralArrayExpr; |
| exports.LiteralExpr = LiteralExpr; |
| exports.LiteralMap = LiteralMap; |
| exports.LiteralMapExpr = LiteralMapExpr; |
| exports.LiteralPrimitive = LiteralPrimitive; |
| exports.LocalizedString = LocalizedString; |
| exports.MapType = MapType; |
| exports.MessageBundle = MessageBundle; |
| exports.MethodCall = MethodCall; |
| exports.NAMED_ENTITIES = NAMED_ENTITIES; |
| exports.NGSP_UNICODE = NGSP_UNICODE; |
| exports.NONE_TYPE = NONE_TYPE; |
| exports.NO_ERRORS_SCHEMA = NO_ERRORS_SCHEMA; |
| exports.NgContentAst = NgContentAst; |
| exports.NgModuleCompiler = NgModuleCompiler; |
| exports.NgModuleResolver = NgModuleResolver; |
| exports.NodeWithI18n = NodeWithI18n; |
| exports.NonNullAssert = NonNullAssert; |
| exports.NotExpr = NotExpr; |
| exports.NullTemplateVisitor = NullTemplateVisitor; |
| exports.ParseError = ParseError; |
| exports.ParseLocation = ParseLocation; |
| exports.ParseSourceFile = ParseSourceFile; |
| exports.ParseSourceSpan = ParseSourceSpan; |
| exports.ParseSpan = ParseSpan; |
| exports.ParseTreeResult = ParseTreeResult; |
| exports.ParsedEvent = ParsedEvent; |
| exports.ParsedProperty = ParsedProperty; |
| exports.ParsedVariable = ParsedVariable; |
| exports.Parser = Parser$1; |
| exports.ParserError = ParserError; |
| exports.PipeResolver = PipeResolver; |
| exports.PrefixNot = PrefixNot; |
| exports.PropertyRead = PropertyRead; |
| exports.PropertyWrite = PropertyWrite; |
| exports.ProviderAst = ProviderAst; |
| exports.ProviderMeta = ProviderMeta; |
| exports.Quote = Quote; |
| exports.R3BoundTarget = R3BoundTarget; |
| exports.R3Identifiers = Identifiers$1; |
| exports.R3TargetBinder = R3TargetBinder; |
| exports.ReadKeyExpr = ReadKeyExpr; |
| exports.ReadPropExpr = ReadPropExpr; |
| exports.ReadVarExpr = ReadVarExpr; |
| exports.RecursiveAstVisitor = RecursiveAstVisitor$1; |
| exports.RecursiveTemplateAstVisitor = RecursiveTemplateAstVisitor; |
| exports.RecursiveVisitor = RecursiveVisitor$1; |
| exports.ReferenceAst = ReferenceAst; |
| exports.ResolvedStaticSymbol = ResolvedStaticSymbol; |
| exports.ResourceLoader = ResourceLoader; |
| exports.ReturnStatement = ReturnStatement; |
| exports.STRING_TYPE = STRING_TYPE; |
| exports.SafeMethodCall = SafeMethodCall; |
| exports.SafePropertyRead = SafePropertyRead; |
| exports.SelectorContext = SelectorContext; |
| exports.SelectorListContext = SelectorListContext; |
| exports.SelectorMatcher = SelectorMatcher; |
| exports.Serializer = Serializer; |
| exports.SplitInterpolation = SplitInterpolation; |
| exports.Statement = Statement; |
| exports.StaticReflector = StaticReflector; |
| exports.StaticSymbol = StaticSymbol; |
| exports.StaticSymbolCache = StaticSymbolCache; |
| exports.StaticSymbolResolver = StaticSymbolResolver; |
| exports.StyleCompiler = StyleCompiler; |
| exports.StylesCompileDependency = StylesCompileDependency; |
| exports.SummaryResolver = SummaryResolver; |
| exports.TaggedTemplateExpr = TaggedTemplateExpr; |
| exports.TemplateBindingParseResult = TemplateBindingParseResult; |
| exports.TemplateLiteral = TemplateLiteral; |
| exports.TemplateLiteralElement = TemplateLiteralElement; |
| exports.TemplateParseError = TemplateParseError; |
| exports.TemplateParseResult = TemplateParseResult; |
| exports.TemplateParser = TemplateParser; |
| exports.Text = Text$3; |
| exports.TextAst = TextAst; |
| exports.ThisReceiver = ThisReceiver; |
| exports.ThrowStmt = ThrowStmt; |
| exports.TmplAstBoundAttribute = BoundAttribute; |
| exports.TmplAstBoundEvent = BoundEvent; |
| exports.TmplAstBoundText = BoundText; |
| exports.TmplAstContent = Content; |
| exports.TmplAstElement = Element; |
| exports.TmplAstIcu = Icu; |
| exports.TmplAstRecursiveVisitor = RecursiveVisitor; |
| exports.TmplAstReference = Reference; |
| exports.TmplAstTemplate = Template; |
| exports.TmplAstText = Text; |
| exports.TmplAstTextAttribute = TextAttribute; |
| exports.TmplAstVariable = Variable; |
| exports.Token = Token$1; |
| exports.TransitiveCompileNgModuleMetadata = TransitiveCompileNgModuleMetadata; |
| exports.TreeError = TreeError; |
| exports.TryCatchStmt = TryCatchStmt; |
| exports.Type = Type$1; |
| exports.TypeScriptEmitter = TypeScriptEmitter; |
| exports.TypeofExpr = TypeofExpr; |
| exports.Unary = Unary; |
| exports.UnaryOperatorExpr = UnaryOperatorExpr; |
| exports.UrlResolver = UrlResolver; |
| exports.VERSION = VERSION$1; |
| exports.VariableAst = VariableAst; |
| exports.VariableBinding = VariableBinding; |
| exports.Version = Version; |
| exports.ViewCompiler = ViewCompiler; |
| exports.WrappedNodeExpr = WrappedNodeExpr; |
| exports.WriteKeyExpr = WriteKeyExpr; |
| exports.WritePropExpr = WritePropExpr; |
| exports.WriteVarExpr = WriteVarExpr; |
| exports.Xliff = Xliff; |
| exports.Xliff2 = Xliff2; |
| exports.Xmb = Xmb; |
| exports.XmlParser = XmlParser; |
| exports.Xtb = Xtb; |
| exports._ParseAST = _ParseAST; |
| exports.analyzeAndValidateNgModules = analyzeAndValidateNgModules; |
| exports.analyzeFile = analyzeFile; |
| exports.analyzeFileForInjectables = analyzeFileForInjectables; |
| exports.analyzeNgModules = analyzeNgModules; |
| exports.collectExternalReferences = collectExternalReferences; |
| exports.compileComponentFromMetadata = compileComponentFromMetadata; |
| exports.compileDeclareComponentFromMetadata = compileDeclareComponentFromMetadata; |
| exports.compileDeclareDirectiveFromMetadata = compileDeclareDirectiveFromMetadata; |
| exports.compileDeclarePipeFromMetadata = compileDeclarePipeFromMetadata; |
| exports.compileDirectiveFromMetadata = compileDirectiveFromMetadata; |
| exports.compileFactoryFunction = compileFactoryFunction; |
| exports.compileInjectable = compileInjectable; |
| exports.compileInjector = compileInjector; |
| exports.compileNgModule = compileNgModule; |
| exports.compilePipeFromMetadata = compilePipeFromMetadata; |
| exports.componentFactoryName = componentFactoryName; |
| exports.computeMsgId = computeMsgId; |
| exports.core = core; |
| exports.createAotCompiler = createAotCompiler; |
| exports.createAotUrlResolver = createAotUrlResolver; |
| exports.createElementCssSelector = createElementCssSelector; |
| exports.createLoweredSymbol = createLoweredSymbol; |
| exports.createOfflineCompileUrlResolver = createOfflineCompileUrlResolver; |
| exports.createUrlResolverWithoutPackagePrefix = createUrlResolverWithoutPackagePrefix; |
| exports.debugOutputAstAsTypeScript = debugOutputAstAsTypeScript; |
| exports.devOnlyGuardedExpression = devOnlyGuardedExpression; |
| exports.findNode = findNode; |
| exports.flatten = flatten; |
| exports.formattedError = formattedError; |
| exports.getHtmlTagDefinition = getHtmlTagDefinition; |
| exports.getMissingNgModuleMetadataErrorData = getMissingNgModuleMetadataErrorData; |
| exports.getNsPrefix = getNsPrefix; |
| exports.getParseErrors = getParseErrors; |
| exports.getSafePropertyAccessString = getSafePropertyAccessString; |
| exports.getUrlScheme = getUrlScheme; |
| exports.hostViewClassName = hostViewClassName; |
| exports.identifierModuleUrl = identifierModuleUrl; |
| exports.identifierName = identifierName; |
| exports.isEmptyExpression = isEmptyExpression; |
| exports.isFormattedError = isFormattedError; |
| exports.isIdentifier = isIdentifier; |
| exports.isLoweredSymbol = isLoweredSymbol; |
| exports.isNgContainer = isNgContainer; |
| exports.isNgContent = isNgContent; |
| exports.isNgTemplate = isNgTemplate; |
| exports.isQuote = isQuote; |
| exports.isSyntaxError = isSyntaxError; |
| exports.jsDocComment = jsDocComment; |
| exports.leadingComment = leadingComment; |
| exports.literalMap = literalMap; |
| exports.makeBindingParser = makeBindingParser; |
| exports.mergeAnalyzedFiles = mergeAnalyzedFiles; |
| exports.mergeNsAndName = mergeNsAndName; |
| exports.ngModuleJitUrl = ngModuleJitUrl; |
| exports.parseHostBindings = parseHostBindings; |
| exports.parseTemplate = parseTemplate; |
| exports.preserveWhitespacesDefault = preserveWhitespacesDefault; |
| exports.publishFacade = publishFacade; |
| exports.r3JitTypeSourceSpan = r3JitTypeSourceSpan; |
| exports.removeSummaryDuplicates = removeSummaryDuplicates; |
| exports.rendererTypeName = rendererTypeName; |
| exports.sanitizeIdentifier = sanitizeIdentifier; |
| exports.sharedStylesheetJitUrl = sharedStylesheetJitUrl; |
| exports.splitClasses = splitClasses; |
| exports.splitNsName = splitNsName; |
| exports.syntaxError = syntaxError; |
| exports.templateJitUrl = templateJitUrl; |
| exports.templateSourceUrl = templateSourceUrl; |
| exports.templateVisitAll = templateVisitAll; |
| exports.toTypeScript = toTypeScript; |
| exports.tokenName = tokenName; |
| exports.tokenReference = tokenReference; |
| exports.typeSourceSpan = typeSourceSpan; |
| exports.unescapeIdentifier = unescapeIdentifier; |
| exports.unwrapResolvedMetadata = unwrapResolvedMetadata; |
| exports.verifyHostBindings = verifyHostBindings; |
| exports.viewClassName = viewClassName; |
| exports.visitAll = visitAll$1; |
| |
| Object.defineProperty(exports, '__esModule', { value: true }); |
| |
| }))); |
| //# sourceMappingURL=compiler.umd.js.map |