From ba009400a9429cf235556c7d528aac490d4200bd Mon Sep 17 00:00:00 2001 From: bigopon Date: Tue, 23 Jan 2024 19:52:46 +1100 Subject: [PATCH] chore(release): prepare release 1.5.1 --- bower.json | 2 +- dist/amd/aurelia-templating-resources.js | 11 ++++++++--- dist/amd/aurelia-templating-resources.js.map | 2 +- dist/commonjs/aurelia-templating-resources.js | 11 ++++++++--- dist/commonjs/aurelia-templating-resources.js.map | 2 +- dist/es2015/aurelia-templating-resources.js | 11 ++++++++--- dist/es2015/aurelia-templating-resources.js.map | 2 +- dist/es2017/aurelia-templating-resources.js | 11 ++++++++--- dist/es2017/aurelia-templating-resources.js.map | 2 +- dist/native-modules/aurelia-templating-resources.js | 11 ++++++++--- .../aurelia-templating-resources.js.map | 2 +- dist/system/aurelia-templating-resources.js | 11 ++++++++--- dist/system/aurelia-templating-resources.js.map | 2 +- doc/CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 16 files changed, 65 insertions(+), 28 deletions(-) diff --git a/bower.json b/bower.json index 754b704..103ca40 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "aurelia-templating-resources", - "version": "1.15.0", + "version": "1.15.1", "description": "A standard set of behaviors, converters and other resources for use with the Aurelia templating library.", "keywords": [ "aurelia", diff --git a/dist/amd/aurelia-templating-resources.js b/dist/amd/aurelia-templating-resources.js index 193be72..8dd00ab 100644 --- a/dist/amd/aurelia-templating-resources.js +++ b/dist/amd/aurelia-templating-resources.js @@ -141,10 +141,12 @@ define('aurelia-templating-resources', ['exports', 'aurelia-dependency-injection function processChanges(composer) { var changes = composer.changes; composer.changes = Object.create(null); - if (needsReInitialization(composer, changes)) { + var activationStrategy = determineActivationStrategy(composer); + if (needsReInitialization(activationStrategy, changes)) { + var currentViewModel = activationStrategy === exports.ComposeActivationStrategy.Replace ? null : composer.currentViewModel; var instruction = { view: composer.view, - viewModel: composer.currentViewModel || composer.viewModel, + viewModel: currentViewModel || composer.viewModel, model: composer.model }; instruction = Object.assign(instruction, changes); @@ -184,12 +186,15 @@ define('aurelia-templating-resources', ['exports', 'aurelia-dependency-injection processChanges(composer); }); } - function needsReInitialization(composer, changes) { + function determineActivationStrategy(composer) { var activationStrategy = composer.activationStrategy; var vm = composer.currentViewModel; if (vm && typeof vm.determineActivationStrategy === 'function') { activationStrategy = vm.determineActivationStrategy(); } + return activationStrategy; + } + function needsReInitialization(activationStrategy, changes) { return 'view' in changes || 'viewModel' in changes || activationStrategy === exports.ComposeActivationStrategy.Replace; diff --git a/dist/amd/aurelia-templating-resources.js.map b/dist/amd/aurelia-templating-resources.js.map index 12b5815..fc572f7 100644 --- a/dist/amd/aurelia-templating-resources.js.map +++ b/dist/amd/aurelia-templating-resources.js.map @@ -1 +1 @@ -{"version":3,"file":"aurelia-templating-resources.js","sources":["../../node_modules/tslib/tslib.es6.js","../../src/compose.ts","../../src/if-core.ts","../../src/if.ts","../../src/else.ts","../../src/with.ts","../../src/repeat-utilities.ts","../../src/array-repeat-strategy.ts","../../src/map-repeat-strategy.ts","../../src/null-repeat-strategy.ts","../../src/number-repeat-strategy.ts","../../src/set-repeat-strategy.ts","../../src/repeat-strategy-locator.ts","../../src/analyze-view-factory.ts","../../src/abstract-repeater.ts","../../src/repeat.ts","../../src/aurelia-hide-style.ts","../../src/show.ts","../../src/hide.ts","../../src/html-sanitizer.ts","../../src/sanitize-html.ts","../../src/replaceable.ts","../../src/focus.ts","../../src/css-resource.ts","../../src/attr-binding-behavior.ts","../../src/binding-mode-behaviors.ts","../../src/throttle-binding-behavior.ts","../../src/debounce-binding-behavior.ts","../../src/self-binding-behavior.ts","../../src/binding-signaler.ts","../../src/signal-binding-behavior.ts","../../src/update-trigger-binding-behavior.ts","../../src/dynamic-element.ts","../../src/html-resource-plugin.ts","../../src/aurelia-templating-resources.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n 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;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n 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;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n 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); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n 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; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n 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);\r\n 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); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n","import { Container } from 'aurelia-dependency-injection';\r\nimport { DOM } from 'aurelia-pal';\r\nimport { TaskQueue } from 'aurelia-task-queue';\r\nimport { bindable, CompositionContext, CompositionEngine, customElement, noView, View, ViewResources, ViewSlot } from 'aurelia-templating';\r\n\r\n/**\r\n * Available activation strategies for the view and view-model bound to `` element\r\n *\r\n * @export\r\n * @enum {string}\r\n */\r\nexport enum ActivationStrategy {\r\n /**\r\n * Default activation strategy; the 'activate' lifecycle hook will be invoked when the model changes.\r\n */\r\n InvokeLifecycle = 'invoke-lifecycle',\r\n /**\r\n * The view/view-model will be recreated, when the \"model\" changes.\r\n */\r\n Replace = 'replace'\r\n}\r\n\r\n/**\r\n * Used to compose a new view / view-model template or bind to an existing instance.\r\n */\r\n@noView\r\n@customElement('compose')\r\nexport class Compose {\r\n\r\n /**@internal */\r\n static inject() {\r\n return [DOM.Element, Container, CompositionEngine, ViewSlot, ViewResources, TaskQueue];\r\n }\r\n\r\n /**\r\n * Model to bind the custom element to.\r\n *\r\n * @property model\r\n * @type {CustomElement}\r\n */\r\n @bindable model: any;\r\n /**\r\n * View to bind the custom element to.\r\n *\r\n * @property view\r\n * @type {HtmlElement}\r\n */\r\n @bindable view: any;\r\n /**\r\n * View-model to bind the custom element's template to.\r\n *\r\n * @property viewModel\r\n * @type {Class}\r\n */\r\n @bindable viewModel: any;\r\n\r\n /**\r\n * Strategy to activate the view-model. Default is \"invoke-lifecycle\".\r\n * Bind \"replace\" to recreate the view/view-model when the model changes.\r\n *\r\n * @property activationStrategy\r\n * @type {ActivationStrategy}\r\n */\r\n @bindable activationStrategy: ActivationStrategy = ActivationStrategy.InvokeLifecycle;\r\n\r\n /**\r\n * SwapOrder to control the swapping order of the custom element's view.\r\n *\r\n * @property view\r\n * @type {String}\r\n */\r\n @bindable swapOrder: any;\r\n\r\n /**\r\n *@internal\r\n */\r\n element: any;\r\n /**\r\n *@internal\r\n */\r\n container: any;\r\n /**\r\n *@internal\r\n */\r\n compositionEngine: any;\r\n /**\r\n *@internal\r\n */\r\n viewSlot: any;\r\n /**\r\n *@internal\r\n */\r\n viewResources: any;\r\n /**\r\n *@internal\r\n */\r\n taskQueue: any;\r\n /**\r\n *@internal\r\n */\r\n currentController: any;\r\n /**\r\n *@internal\r\n */\r\n currentViewModel: any;\r\n /**\r\n *@internal\r\n */\r\n changes: any;\r\n /**\r\n *@internal\r\n */\r\n owningView: View;\r\n /**\r\n *@internal\r\n */\r\n bindingContext: any;\r\n /**\r\n *@internal\r\n */\r\n overrideContext: any;\r\n /**\r\n *@internal\r\n */\r\n pendingTask: any;\r\n /**\r\n *@internal\r\n */\r\n updateRequested: any;\r\n\r\n /**\r\n * Creates an instance of Compose.\r\n * @param element The Compose element.\r\n * @param container The dependency injection container instance.\r\n * @param compositionEngine CompositionEngine instance to compose the element.\r\n * @param viewSlot The slot the view is injected in to.\r\n * @param viewResources Collection of resources used to compile the the view.\r\n * @param taskQueue The TaskQueue instance.\r\n */\r\n constructor(element, container, compositionEngine, viewSlot, viewResources, taskQueue) {\r\n this.element = element;\r\n this.container = container;\r\n this.compositionEngine = compositionEngine;\r\n this.viewSlot = viewSlot;\r\n this.viewResources = viewResources;\r\n this.taskQueue = taskQueue;\r\n this.currentController = null;\r\n this.currentViewModel = null;\r\n this.changes = Object.create(null);\r\n }\r\n\r\n /**\r\n * Invoked when the component has been created.\r\n *\r\n * @param owningView The view that this component was created inside of.\r\n */\r\n created(owningView: View) {\r\n this.owningView = owningView;\r\n }\r\n\r\n /**\r\n * Used to set the bindingContext.\r\n *\r\n * @param bindingContext The context in which the view model is executed in.\r\n * @param overrideContext The context in which the view model is executed in.\r\n */\r\n bind(bindingContext, overrideContext) {\r\n this.bindingContext = bindingContext;\r\n this.overrideContext = overrideContext;\r\n let changes = this.changes;\r\n changes.view = this.view;\r\n changes.viewModel = this.viewModel;\r\n changes.model = this.model;\r\n if (!this.pendingTask) {\r\n processChanges(this);\r\n }\r\n }\r\n\r\n /**\r\n * Unbinds the Compose.\r\n */\r\n unbind() {\r\n this.changes = Object.create(null);\r\n this.bindingContext = null;\r\n this.overrideContext = null;\r\n let returnToCache = true;\r\n let skipAnimation = true;\r\n this.viewSlot.removeAll(returnToCache, skipAnimation);\r\n }\r\n\r\n /**\r\n * Invoked everytime the bound model changes.\r\n * @param newValue The new value.\r\n * @param oldValue The old value.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n modelChanged(newValue, oldValue) {\r\n this.changes.model = newValue;\r\n requestUpdate(this);\r\n }\r\n\r\n /**\r\n * Invoked everytime the bound view changes.\r\n * @param newValue The new value.\r\n * @param oldValue The old value.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n viewChanged(newValue, oldValue) {\r\n this.changes.view = newValue;\r\n requestUpdate(this);\r\n }\r\n\r\n /**\r\n * Invoked everytime the bound view model changes.\r\n * @param newValue The new value.\r\n * @param oldValue The old value.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n viewModelChanged(newValue, oldValue) {\r\n this.changes.viewModel = newValue;\r\n requestUpdate(this);\r\n }\r\n}\r\n\r\nfunction isEmpty(obj) {\r\n for (const _ in obj) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\nfunction tryActivateViewModel(vm, model) {\r\n if (vm && typeof vm.activate === 'function') {\r\n return Promise.resolve(vm.activate(model));\r\n }\r\n}\r\n\r\nfunction createInstruction(composer: Compose, instruction: CompositionContext): CompositionContext {\r\n return Object.assign(instruction, {\r\n bindingContext: composer.bindingContext,\r\n overrideContext: composer.overrideContext,\r\n owningView: composer.owningView,\r\n container: composer.container,\r\n viewSlot: composer.viewSlot,\r\n viewResources: composer.viewResources,\r\n currentController: composer.currentController,\r\n host: composer.element,\r\n swapOrder: composer.swapOrder\r\n });\r\n}\r\n\r\nfunction processChanges(composer: Compose) {\r\n const changes = composer.changes;\r\n composer.changes = Object.create(null);\r\n\r\n if (needsReInitialization(composer, changes)) {\r\n // init context\r\n let instruction = {\r\n view: composer.view,\r\n viewModel: composer.currentViewModel || composer.viewModel,\r\n model: composer.model\r\n } as CompositionContext;\r\n\r\n // apply changes\r\n instruction = Object.assign(instruction, changes);\r\n\r\n // create context\r\n instruction = createInstruction(composer, instruction);\r\n\r\n composer.pendingTask = composer.compositionEngine.compose(instruction).then(controller => {\r\n composer.currentController = controller;\r\n composer.currentViewModel = controller ? controller.viewModel : null;\r\n });\r\n } else {\r\n // just try to activate the current view model\r\n composer.pendingTask = tryActivateViewModel(composer.currentViewModel, changes.model);\r\n if (!composer.pendingTask) { return; }\r\n }\r\n\r\n composer.pendingTask = composer.pendingTask\r\n .then(() => {\r\n completeCompositionTask(composer);\r\n }, reason => {\r\n completeCompositionTask(composer);\r\n throw reason;\r\n });\r\n}\r\n\r\nfunction completeCompositionTask(composer) {\r\n composer.pendingTask = null;\r\n if (!isEmpty(composer.changes)) {\r\n processChanges(composer);\r\n }\r\n}\r\n\r\nfunction requestUpdate(composer: Compose) {\r\n if (composer.pendingTask || composer.updateRequested) { return; }\r\n composer.updateRequested = true;\r\n composer.taskQueue.queueMicroTask(() => {\r\n composer.updateRequested = false;\r\n processChanges(composer);\r\n });\r\n}\r\n\r\nfunction needsReInitialization(composer: Compose, changes: any) {\r\n let activationStrategy = composer.activationStrategy;\r\n const vm = composer.currentViewModel;\r\n if (vm && typeof vm.determineActivationStrategy === 'function') {\r\n activationStrategy = vm.determineActivationStrategy();\r\n }\r\n\r\n return 'view' in changes\r\n || 'viewModel' in changes\r\n || activationStrategy === ActivationStrategy.Replace;\r\n}\r\n","import { ViewFactory, ViewSlot } from 'aurelia-templating';\r\n\r\n/**\r\n * For internal use only. May change without warning.\r\n */\r\nexport class IfCore {\r\n /**\r\n * @internal\r\n */\r\n viewFactory: ViewFactory;\r\n /**\r\n * @internal\r\n */\r\n viewSlot: ViewSlot;\r\n /**\r\n * @internal\r\n */\r\n view: any;\r\n /**\r\n * @internal\r\n */\r\n bindingContext: any;\r\n /**\r\n * @internal\r\n */\r\n overrideContext: any;\r\n /**\r\n * @internal\r\n */\r\n showing: boolean;\r\n /**\r\n * @internal\r\n */\r\n cache: boolean | string;\r\n\r\n constructor(viewFactory: ViewFactory, viewSlot: ViewSlot) {\r\n this.viewFactory = viewFactory;\r\n this.viewSlot = viewSlot;\r\n this.view = null;\r\n this.bindingContext = null;\r\n this.overrideContext = null;\r\n // If the child view is animated, `value` might not reflect the internal\r\n // state anymore, so we use `showing` for that.\r\n // Eventually, `showing` and `value` should be consistent.\r\n this.showing = false;\r\n this.cache = true;\r\n }\r\n\r\n bind(bindingContext, overrideContext) {\r\n // Store parent bindingContext, so we can pass it down\r\n this.bindingContext = bindingContext;\r\n this.overrideContext = overrideContext;\r\n }\r\n\r\n unbind() {\r\n if (this.view === null) {\r\n return;\r\n }\r\n\r\n this.view.unbind();\r\n\r\n // It seems to me that this code is subject to race conditions when animating.\r\n // For example a view could be returned to the cache and reused while it's still\r\n // attached to the DOM and animated.\r\n if (!this.viewFactory.isCaching) {\r\n return;\r\n }\r\n\r\n if (this.showing) {\r\n this.showing = false;\r\n this.viewSlot.remove(this.view, /*returnToCache:*/true, /*skipAnimation:*/true);\r\n } else {\r\n this.view.returnToCache();\r\n }\r\n\r\n this.view = null;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _show() {\r\n if (this.showing) {\r\n // Ensures the view is bound.\r\n // It might not be the case when the if was unbound but not detached, then rebound.\r\n // Typical case where this happens is nested ifs\r\n if (!this.view.isBound) {\r\n this.view.bind(this.bindingContext, this.overrideContext);\r\n }\r\n return;\r\n }\r\n\r\n if (this.view === null) {\r\n this.view = (this.viewFactory as any).create();\r\n }\r\n\r\n if (!this.view.isBound) {\r\n this.view.bind(this.bindingContext, this.overrideContext);\r\n }\r\n\r\n this.showing = true;\r\n return this.viewSlot.add(this.view); // Promise or void\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _hide() {\r\n if (!this.showing) {\r\n return;\r\n }\r\n\r\n this.showing = false;\r\n let removed = this.viewSlot.remove(this.view); // Promise or View\r\n\r\n if (removed instanceof Promise) {\r\n return removed.then(() => {\r\n this._unbindView();\r\n });\r\n }\r\n\r\n this._unbindView();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _unbindView() {\r\n const cache = this.cache === 'false' ? false : !!this.cache;\r\n this.view.unbind();\r\n if (!cache) {\r\n this.view = null;\r\n }\r\n }\r\n}\r\n","import {BoundViewFactory, ViewSlot, bindable, customAttribute, templateController} from 'aurelia-templating';\r\nimport {inject} from 'aurelia-dependency-injection';\r\nimport {IfCore} from './if-core';\r\n\r\n/**\r\n * Binding to conditionally include or not include template logic depending on returned result\r\n * - value should be Boolean or will be treated as such (truthy / falsey)\r\n */\r\n@customAttribute('if')\r\n@templateController\r\n@inject(BoundViewFactory, ViewSlot)\r\nexport class If extends IfCore {\r\n @bindable({ primaryProperty: true }) condition: any;\r\n @bindable swapOrder: 'before'|'with'|'after';\r\n @bindable cache: boolean|string = true;\r\n\r\n /**@internal*/\r\n animating: any;\r\n /**@internal*/\r\n elseVm: any;\r\n\r\n /**\r\n * Binds the if to the binding context and override context\r\n * @param bindingContext The binding context\r\n * @param overrideContext An override context for binding.\r\n */\r\n bind(bindingContext, overrideContext) {\r\n super.bind(bindingContext, overrideContext);\r\n if (this.condition) {\r\n this._show();\r\n } else {\r\n this._hide();\r\n }\r\n }\r\n\r\n /**\r\n * Invoked everytime value property changes.\r\n * @param newValue The new value\r\n */\r\n conditionChanged(newValue) {\r\n this._update(newValue);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _update(show) {\r\n if (this.animating) {\r\n return;\r\n }\r\n\r\n let promise;\r\n if (this.elseVm) {\r\n promise = show ? this._swap(this.elseVm, this) : this._swap(this, this.elseVm);\r\n } else {\r\n promise = show ? this._show() : this._hide();\r\n }\r\n\r\n if (promise) {\r\n this.animating = true;\r\n promise.then(() => {\r\n this.animating = false;\r\n if (this.condition !== this.showing) {\r\n this._update(this.condition);\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _swap(remove, add) {\r\n switch (this.swapOrder) {\r\n case 'before':\r\n return Promise.resolve(add._show()).then(() => remove._hide());\r\n case 'with':\r\n return Promise.all([ remove._hide(), add._show() ]);\r\n default: // \"after\", default and unknown values\r\n let promise = remove._hide();\r\n return promise ? promise.then(() => add._show()) : add._show();\r\n }\r\n }\r\n}\r\n","import { inject } from 'aurelia-dependency-injection';\r\nimport { BoundViewFactory, customAttribute, templateController, ViewSlot } from 'aurelia-templating';\r\nimport { IfCore } from './if-core';\r\n\r\n@customAttribute('else')\r\n@templateController\r\n@inject(BoundViewFactory, ViewSlot)\r\nexport class Else extends IfCore {\r\n\r\n /**\r\n * @internal\r\n */\r\n ifVm: any;\r\n\r\n constructor(viewFactory, viewSlot) {\r\n super(viewFactory, viewSlot);\r\n this._registerInIf();\r\n }\r\n\r\n bind(bindingContext, overrideContext) {\r\n super.bind(bindingContext, overrideContext);\r\n // Render on initial\r\n if (this.ifVm.condition) {\r\n this._hide();\r\n } else {\r\n this._show();\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _registerInIf() {\r\n // We support the pattern
.\r\n // Obvisouly between the two, we must accepts text (spaces) and comments.\r\n // The `if` node is expected to be a comment anchor, because of `@templateController`.\r\n // To simplify the code we basically walk up to the first Aurelia predecessor,\r\n // so having static tags in between (no binding) would work but is not intended to be supported.\r\n let previous = (this.viewSlot as ViewSlot & { anchor: any}).anchor.previousSibling;\r\n while (previous && !previous.au) {\r\n previous = previous.previousSibling;\r\n }\r\n if (!previous || !previous.au.if) {\r\n throw new Error(\"Can't find matching If for Else custom attribute.\");\r\n }\r\n this.ifVm = previous.au.if.viewModel;\r\n this.ifVm.elseVm = this;\r\n }\r\n}\r\n","import {inject} from 'aurelia-dependency-injection';\r\nimport {BoundViewFactory, ViewSlot, customAttribute, templateController, ViewFactory} from 'aurelia-templating';\r\nimport {createOverrideContext} from 'aurelia-binding';\r\n\r\n/**\r\n * Creates a binding context for decandant elements to bind to.\r\n */\r\n@customAttribute('with')\r\n@templateController\r\n@inject(BoundViewFactory, ViewSlot)\r\nexport class With {\r\n\r\n /**@internal*/\r\n viewFactory: any;\r\n /**@internal*/\r\n viewSlot: any;\r\n /**@internal*/\r\n parentOverrideContext: any;\r\n /**@internal*/\r\n view: any;\r\n\r\n value: any;\r\n\r\n /**\r\n * Creates an instance of With.\r\n * @param viewFactory The factory generating the view.\r\n * @param viewSlot The slot the view is injected in to.\r\n */\r\n constructor(viewFactory: ViewFactory, viewSlot: ViewSlot) {\r\n this.viewFactory = viewFactory;\r\n this.viewSlot = viewSlot;\r\n this.parentOverrideContext = null;\r\n this.view = null;\r\n }\r\n\r\n /**\r\n * Binds the With with provided binding context and override context.\r\n * @param bindingContext The binding context.\r\n * @param overrideContext An override context for binding.\r\n */\r\n bind(bindingContext, overrideContext) {\r\n this.parentOverrideContext = overrideContext;\r\n this.valueChanged(this.value);\r\n }\r\n\r\n /**\r\n * Invoked everytime the bound value changes.\r\n * @param newValue The new value.\r\n */\r\n valueChanged(newValue) {\r\n let overrideContext = createOverrideContext(newValue, this.parentOverrideContext);\r\n let view = this.view;\r\n if (!view) {\r\n view = this.view = this.viewFactory.create();\r\n view.bind(newValue, overrideContext);\r\n this.viewSlot.add(view);\r\n } else {\r\n view.bind(newValue, overrideContext);\r\n }\r\n }\r\n\r\n /**\r\n * Unbinds With\r\n */\r\n unbind() {\r\n let view = this.view;\r\n this.parentOverrideContext = null;\r\n\r\n if (view) {\r\n view.unbind();\r\n }\r\n }\r\n}\r\n","import {\r\n createOverrideContext,\r\n BindingBehavior,\r\n ValueConverter,\r\n sourceContext,\r\n bindingMode,\r\n OverrideContext\r\n} from 'aurelia-binding';\r\n\r\nconst oneTime = bindingMode.oneTime;\r\n\r\n/**\r\n * Update the override context.\r\n * @param startIndex index in collection where to start updating.\r\n */\r\nexport function updateOverrideContexts(views, startIndex) {\r\n let length = views.length;\r\n\r\n if (startIndex > 0) {\r\n startIndex = startIndex - 1;\r\n }\r\n\r\n for (; startIndex < length; ++startIndex) {\r\n updateOverrideContext(views[startIndex].overrideContext, startIndex, length);\r\n }\r\n}\r\n\r\n/**\r\n * Creates a complete override context.\r\n * @param data The item's value.\r\n * @param index The item's index.\r\n * @param length The collections total length.\r\n * @param key The key in a key/value pair.\r\n */\r\nexport function createFullOverrideContext(repeat, data, index, length, key?: string): OverrideContext {\r\n let bindingContext = {};\r\n let overrideContext = createOverrideContext(bindingContext, repeat.scope.overrideContext);\r\n // is key/value pair (Map)\r\n if (typeof key !== 'undefined') {\r\n bindingContext[repeat.key] = key;\r\n bindingContext[repeat.value] = data;\r\n } else {\r\n bindingContext[repeat.local] = data;\r\n }\r\n updateOverrideContext(overrideContext, index, length);\r\n return overrideContext;\r\n}\r\n\r\n/**\r\n * Updates the override context.\r\n * @param context The context to be updated.\r\n * @param index The context's index.\r\n * @param length The collection's length.\r\n */\r\nexport function updateOverrideContext(overrideContext, index, length) {\r\n let first = (index === 0);\r\n let last = (index === length - 1);\r\n let even = index % 2 === 0;\r\n\r\n overrideContext.$index = index;\r\n overrideContext.$first = first;\r\n overrideContext.$last = last;\r\n overrideContext.$middle = !(first || last);\r\n overrideContext.$odd = !even;\r\n overrideContext.$even = even;\r\n}\r\n\r\n/**\r\n * Gets a repeat instruction's source expression.\r\n */\r\nexport function getItemsSourceExpression(instruction, attrName) {\r\n return instruction.behaviorInstructions\r\n .filter(bi => bi.originalAttrName === attrName)[0]\r\n .attributes\r\n .items\r\n .sourceExpression;\r\n}\r\n\r\n/**\r\n * Unwraps an expression to expose the inner, pre-converted / behavior-free expression.\r\n */\r\nexport function unwrapExpression(expression) {\r\n let unwrapped = false;\r\n while (expression instanceof BindingBehavior) {\r\n expression = expression.expression;\r\n }\r\n while (expression instanceof ValueConverter) {\r\n expression = expression.expression;\r\n unwrapped = true;\r\n }\r\n return unwrapped ? expression : null;\r\n}\r\n\r\n/**\r\n * Returns whether an expression has the OneTimeBindingBehavior applied.\r\n */\r\nexport function isOneTime(expression) {\r\n while (expression instanceof BindingBehavior) {\r\n if (expression.name === 'oneTime') {\r\n return true;\r\n }\r\n expression = expression.expression;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Forces a binding instance to reevaluate.\r\n */\r\nexport function updateOneTimeBinding(binding) {\r\n if (binding.call && binding.mode === oneTime) {\r\n binding.call(sourceContext);\r\n } else if (binding.updateOneTimeBindings) {\r\n binding.updateOneTimeBindings();\r\n }\r\n}\r\n\r\n/**\r\n * Returns the index of the element in an array, optionally using a matcher function.\r\n */\r\nexport function indexOf(array, item, matcher, startIndex?: number) {\r\n if (!matcher) {\r\n // native indexOf is more performant than a for loop\r\n return array.indexOf(item);\r\n }\r\n const length = array.length;\r\n for (let index = startIndex || 0; index < length; index++) {\r\n if (matcher(array[index], item)) {\r\n return index;\r\n }\r\n }\r\n return -1;\r\n}\r\n","import {createFullOverrideContext, updateOverrideContexts, updateOverrideContext, indexOf} from './repeat-utilities';\r\nimport {mergeSplice} from 'aurelia-binding';\r\nimport { Repeat } from './repeat';\r\n\r\n/**\r\n * A strategy for repeating a template over an array.\r\n */\r\nexport class ArrayRepeatStrategy {\r\n /**\r\n * Gets an observer for the specified collection.\r\n * @param observerLocator The observer locator instance.\r\n * @param items The items to be observed.\r\n */\r\n getCollectionObserver(observerLocator, items) {\r\n return observerLocator.getArrayObserver(items);\r\n }\r\n\r\n /**\r\n * Handle the repeat's collection instance changing.\r\n * @param repeat The repeater instance.\r\n * @param items The new array instance.\r\n */\r\n instanceChanged(repeat, items) {\r\n const $repeat = repeat as Repeat;\r\n const itemsLength = items.length;\r\n\r\n // if the new instance does not contain any items,\r\n // just remove all views and don't do any further processing\r\n if (!items || itemsLength === 0) {\r\n $repeat.removeAllViews(true, !$repeat.viewsRequireLifecycle);\r\n return;\r\n }\r\n\r\n const children = $repeat.views();\r\n const viewsLength = children.length;\r\n\r\n // likewise, if we previously didn't have any views,\r\n // simply make them and return\r\n if (viewsLength === 0) {\r\n this._standardProcessInstanceChanged($repeat, items);\r\n return;\r\n }\r\n\r\n if ($repeat.viewsRequireLifecycle) {\r\n const childrenSnapshot = children.slice(0);\r\n const itemNameInBindingContext = $repeat.local;\r\n const matcher = $repeat.matcher();\r\n\r\n // the cache of the current state (it will be transformed along with the views to keep track of indicies)\r\n let itemsPreviouslyInViews = [];\r\n const viewsToRemove = [];\r\n\r\n for (let index = 0; index < viewsLength; index++) {\r\n const view = childrenSnapshot[index];\r\n const oldItem = view.bindingContext[itemNameInBindingContext];\r\n\r\n if (indexOf(items, oldItem, matcher) === -1) {\r\n // remove the item if no longer in the new instance of items\r\n viewsToRemove.push(view);\r\n } else {\r\n // or add the item to the cache list\r\n itemsPreviouslyInViews.push(oldItem);\r\n }\r\n }\r\n\r\n let updateViews;\r\n let removePromise;\r\n\r\n if (itemsPreviouslyInViews.length > 0) {\r\n removePromise = $repeat.removeViews(viewsToRemove, true, !$repeat.viewsRequireLifecycle);\r\n updateViews = () => {\r\n // update views (create new and move existing)\r\n for (let index = 0; index < itemsLength; index++) {\r\n const item = items[index];\r\n const indexOfView = indexOf(itemsPreviouslyInViews, item, matcher, index);\r\n let view;\r\n\r\n if (indexOfView === -1) { // create views for new items\r\n const overrideContext = createFullOverrideContext($repeat, items[index], index, itemsLength);\r\n $repeat.insertView(index, overrideContext.bindingContext, overrideContext);\r\n // reflect the change in our cache list so indicies are valid\r\n itemsPreviouslyInViews.splice(index, 0, undefined);\r\n } else if (indexOfView === index) { // leave unchanged items\r\n view = children[indexOfView];\r\n itemsPreviouslyInViews[indexOfView] = undefined;\r\n } else { // move the element to the right place\r\n view = children[indexOfView];\r\n $repeat.moveView(indexOfView, index);\r\n itemsPreviouslyInViews.splice(indexOfView, 1);\r\n itemsPreviouslyInViews.splice(index, 0, undefined);\r\n }\r\n\r\n if (view) {\r\n updateOverrideContext(view.overrideContext, index, itemsLength);\r\n }\r\n }\r\n\r\n // remove extraneous elements in case of duplicates,\r\n // also update binding contexts if objects changed using the matcher function\r\n this._inPlaceProcessItems($repeat, items);\r\n };\r\n } else {\r\n // if all of the items are different, remove all and add all from scratch\r\n removePromise = $repeat.removeAllViews(true, !$repeat.viewsRequireLifecycle);\r\n updateViews = () => this._standardProcessInstanceChanged($repeat, items);\r\n }\r\n\r\n if (removePromise instanceof Promise) {\r\n removePromise.then(updateViews);\r\n } else {\r\n updateViews();\r\n }\r\n } else {\r\n // no lifecycle needed, use the fast in-place processing\r\n this._inPlaceProcessItems($repeat, items);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _standardProcessInstanceChanged(repeat, items) {\r\n for (let i = 0, ii = items.length; i < ii; i++) {\r\n let overrideContext = createFullOverrideContext(repeat, items[i], i, ii);\r\n repeat.addView(overrideContext.bindingContext, overrideContext);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _inPlaceProcessItems(repeat, items) {\r\n let itemsLength = items.length;\r\n let viewsLength = repeat.viewCount();\r\n // remove unneeded views.\r\n while (viewsLength > itemsLength) {\r\n viewsLength--;\r\n repeat.removeView(viewsLength, true, !repeat.viewsRequireLifecycle);\r\n }\r\n // avoid repeated evaluating the property-getter for the \"local\" property.\r\n let local = repeat.local;\r\n // re-evaluate bindings on existing views.\r\n for (let i = 0; i < viewsLength; i++) {\r\n let view = repeat.view(i);\r\n let last = i === itemsLength - 1;\r\n let middle = i !== 0 && !last;\r\n let bindingContext = view.bindingContext;\r\n let overrideContext = view.overrideContext;\r\n // any changes to the binding context?\r\n if (bindingContext[local] === items[i]\r\n && overrideContext.$middle === middle\r\n && overrideContext.$last === last) {\r\n // no changes. continue...\r\n continue;\r\n }\r\n // update the binding context and refresh the bindings.\r\n bindingContext[local] = items[i];\r\n overrideContext.$middle = middle;\r\n overrideContext.$last = last;\r\n repeat.updateBindings(view);\r\n }\r\n // add new views\r\n for (let i = viewsLength; i < itemsLength; i++) {\r\n let overrideContext = createFullOverrideContext(repeat, items[i], i, itemsLength);\r\n repeat.addView(overrideContext.bindingContext, overrideContext);\r\n }\r\n }\r\n\r\n /**\r\n * Handle the repeat's collection instance mutating.\r\n * @param repeat The repeat instance.\r\n * @param array The modified array.\r\n * @param splices Records of array changes.\r\n */\r\n instanceMutated(repeat, array, splices) {\r\n if (repeat.__queuedSplices) {\r\n for (let i = 0, ii = splices.length; i < ii; ++i) {\r\n let {index, removed, addedCount} = splices[i];\r\n mergeSplice(repeat.__queuedSplices, index, removed, addedCount);\r\n }\r\n // Array.prototype.slice is used here to clone the array\r\n repeat.__array = array.slice(0);\r\n return;\r\n }\r\n\r\n // Array.prototype.slice is used here to clone the array\r\n let maybePromise = this._runSplices(repeat, array.slice(0), splices);\r\n if (maybePromise instanceof Promise) {\r\n let queuedSplices = repeat.__queuedSplices = [];\r\n\r\n let runQueuedSplices = () => {\r\n if (!queuedSplices.length) {\r\n repeat.__queuedSplices = undefined;\r\n repeat.__array = undefined;\r\n return;\r\n }\r\n\r\n let nextPromise = this._runSplices(repeat, repeat.__array, queuedSplices) || Promise.resolve();\r\n queuedSplices = repeat.__queuedSplices = [];\r\n nextPromise.then(runQueuedSplices);\r\n };\r\n\r\n maybePromise.then(runQueuedSplices);\r\n }\r\n }\r\n\r\n /**\r\n * Run a normalised set of splices against the viewSlot children.\r\n * @param repeat The repeat instance.\r\n * @param array The modified array.\r\n * @param splices Records of array changes.\r\n * @return {Promise|undefined} A promise if animations have to be run.\r\n * @pre The splices must be normalised so as:\r\n * * Any item added may not be later removed.\r\n * * Removals are ordered by asending index\r\n * @internal\r\n */\r\n _runSplices(repeat, array, splices) {\r\n let removeDelta = 0;\r\n let rmPromises = [];\r\n\r\n for (let i = 0, ii = splices.length; i < ii; ++i) {\r\n let splice = splices[i];\r\n let removed = splice.removed;\r\n\r\n for (let j = 0, jj = removed.length; j < jj; ++j) {\r\n // the rmPromises.length correction works due to the ordered removal precondition\r\n let viewOrPromise = repeat.removeView(splice.index + removeDelta + rmPromises.length, true);\r\n if (viewOrPromise instanceof Promise) {\r\n rmPromises.push(viewOrPromise);\r\n }\r\n }\r\n removeDelta -= splice.addedCount;\r\n }\r\n\r\n if (rmPromises.length > 0) {\r\n return Promise.all(rmPromises).then(() => {\r\n let spliceIndexLow = this._handleAddedSplices(repeat, array, splices);\r\n updateOverrideContexts(repeat.views(), spliceIndexLow);\r\n });\r\n }\r\n\r\n let spliceIndexLow = this._handleAddedSplices(repeat, array, splices);\r\n updateOverrideContexts(repeat.views(), spliceIndexLow);\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _handleAddedSplices(repeat, array, splices) {\r\n let spliceIndex: number;\r\n let spliceIndexLow: number;\r\n let arrayLength = array.length;\r\n for (let i = 0, ii = splices.length; i < ii; ++i) {\r\n let splice = splices[i];\r\n let addIndex = spliceIndex = splice.index;\r\n let end = splice.index + splice.addedCount;\r\n\r\n if (typeof spliceIndexLow === 'undefined' || spliceIndexLow === null || spliceIndexLow > splice.index) {\r\n spliceIndexLow = spliceIndex;\r\n }\r\n\r\n for (; addIndex < end; ++addIndex) {\r\n let overrideContext = createFullOverrideContext(repeat, array[addIndex], addIndex, arrayLength);\r\n repeat.insertView(addIndex, overrideContext.bindingContext, overrideContext);\r\n }\r\n }\r\n\r\n return spliceIndexLow;\r\n }\r\n}\r\n","import {createFullOverrideContext, updateOverrideContexts} from './repeat-utilities';\r\n\r\n/**\r\n * A strategy for repeating a template over a Map.\r\n */\r\nexport class MapRepeatStrategy {\r\n /**\r\n * Gets a Map observer.\r\n * @param items The items to be observed.\r\n */\r\n getCollectionObserver(observerLocator, items) {\r\n return observerLocator.getMapObserver(items);\r\n }\r\n\r\n /**\r\n * Process the provided Map entries.\r\n * @param items The entries to process.\r\n */\r\n instanceChanged(repeat, items) {\r\n let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);\r\n if (removePromise instanceof Promise) {\r\n removePromise.then(() => this._standardProcessItems(repeat, items));\r\n return;\r\n }\r\n this._standardProcessItems(repeat, items);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _standardProcessItems(repeat, items) {\r\n let index = 0;\r\n let overrideContext;\r\n\r\n items.forEach((value, key) => {\r\n overrideContext = createFullOverrideContext(repeat, value, index, items.size, key);\r\n repeat.addView(overrideContext.bindingContext, overrideContext);\r\n ++index;\r\n });\r\n }\r\n\r\n /**\r\n * Handle changes in a Map collection.\r\n * @param map The underlying Map collection.\r\n * @param records The change records.\r\n */\r\n instanceMutated(repeat, map, records) {\r\n let key;\r\n let i;\r\n let ii;\r\n let overrideContext;\r\n let removeIndex;\r\n let addIndex;\r\n let record;\r\n let rmPromises = [];\r\n let viewOrPromise;\r\n\r\n for (i = 0, ii = records.length; i < ii; ++i) {\r\n record = records[i];\r\n key = record.key;\r\n switch (record.type) {\r\n case 'update':\r\n removeIndex = this._getViewIndexByKey(repeat, key);\r\n viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);\r\n if (viewOrPromise instanceof Promise) {\r\n rmPromises.push(viewOrPromise);\r\n }\r\n overrideContext = createFullOverrideContext(repeat, map.get(key), removeIndex, map.size, key);\r\n repeat.insertView(removeIndex, overrideContext.bindingContext, overrideContext);\r\n break;\r\n case 'add':\r\n addIndex = repeat.viewCount() <= map.size - 1 ? repeat.viewCount() : map.size - 1;\r\n overrideContext = createFullOverrideContext(repeat, map.get(key), addIndex, map.size, key);\r\n repeat.insertView(map.size - 1, overrideContext.bindingContext, overrideContext);\r\n break;\r\n case 'delete':\r\n if (record.oldValue === undefined) { return; }\r\n removeIndex = this._getViewIndexByKey(repeat, key);\r\n viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);\r\n if (viewOrPromise instanceof Promise) {\r\n rmPromises.push(viewOrPromise);\r\n }\r\n break;\r\n case 'clear':\r\n repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);\r\n break;\r\n default:\r\n continue;\r\n }\r\n }\r\n\r\n if (rmPromises.length > 0) {\r\n Promise.all(rmPromises).then(() => {\r\n updateOverrideContexts(repeat.views(), 0);\r\n });\r\n } else {\r\n updateOverrideContexts(repeat.views(), 0);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _getViewIndexByKey(repeat, key) {\r\n let i: number;\r\n let ii: number;\r\n let child;\r\n\r\n for (i = 0, ii = repeat.viewCount(); i < ii; ++i) {\r\n child = repeat.view(i);\r\n if (child.bindingContext[repeat.key] === key) {\r\n return i;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\n/**\r\n * A strategy for repeating a template over null or undefined (does nothing)\r\n */\r\nexport class NullRepeatStrategy {\r\n instanceChanged(repeat, items): void {\r\n repeat.removeAllViews(true);\r\n }\r\n\r\n getCollectionObserver(observerLocator, items): any {\r\n // empty\r\n }\r\n}\r\n","import {createFullOverrideContext, updateOverrideContexts} from './repeat-utilities';\r\n\r\n/**\r\n * A strategy for repeating a template over a number.\r\n */\r\nexport class NumberRepeatStrategy {\r\n /**\r\n * Return the strategies collection observer. In this case none.\r\n */\r\n getCollectionObserver() {\r\n return null;\r\n }\r\n\r\n /**\r\n * Process the provided Number.\r\n * @param value The Number of how many time to iterate.\r\n */\r\n instanceChanged(repeat, value) {\r\n let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);\r\n if (removePromise instanceof Promise) {\r\n removePromise.then(() => this._standardProcessItems(repeat, value));\r\n return;\r\n }\r\n this._standardProcessItems(repeat, value);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _standardProcessItems(repeat, value) {\r\n let childrenLength = repeat.viewCount();\r\n let i;\r\n let ii;\r\n let overrideContext;\r\n let viewsToRemove;\r\n\r\n value = Math.floor(value);\r\n viewsToRemove = childrenLength - value;\r\n\r\n if (viewsToRemove > 0) {\r\n if (viewsToRemove > childrenLength) {\r\n viewsToRemove = childrenLength;\r\n }\r\n\r\n for (i = 0, ii = viewsToRemove; i < ii; ++i) {\r\n repeat.removeView(childrenLength - (i + 1), true, !repeat.viewsRequireLifecycle);\r\n }\r\n\r\n return;\r\n }\r\n\r\n for (i = childrenLength, ii = value; i < ii; ++i) {\r\n overrideContext = createFullOverrideContext(repeat, i, i, ii);\r\n repeat.addView(overrideContext.bindingContext, overrideContext);\r\n }\r\n\r\n updateOverrideContexts(repeat.views(), 0);\r\n }\r\n}\r\n","import {createFullOverrideContext, updateOverrideContexts} from './repeat-utilities';\r\n\r\n/**\r\n * A strategy for repeating a template over a Set.\r\n */\r\nexport class SetRepeatStrategy {\r\n /**\r\n * Gets a Set observer.\r\n * @param items The items to be observed.\r\n */\r\n getCollectionObserver(observerLocator, items) {\r\n return observerLocator.getSetObserver(items);\r\n }\r\n\r\n /**\r\n * Process the provided Set entries.\r\n * @param items The entries to process.\r\n */\r\n instanceChanged(repeat, items) {\r\n let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);\r\n if (removePromise instanceof Promise) {\r\n removePromise.then(() => this._standardProcessItems(repeat, items));\r\n return;\r\n }\r\n this._standardProcessItems(repeat, items);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _standardProcessItems(repeat, items) {\r\n let index = 0;\r\n let overrideContext;\r\n\r\n items.forEach(value => {\r\n overrideContext = createFullOverrideContext(repeat, value, index, items.size);\r\n repeat.addView(overrideContext.bindingContext, overrideContext);\r\n ++index;\r\n });\r\n }\r\n\r\n /**\r\n * Handle changes in a Set collection.\r\n * @param repeat The repeat instance.\r\n * @param set The underlying Set collection.\r\n * @param records The change records.\r\n */\r\n instanceMutated(repeat, set, records) {\r\n let value;\r\n let i;\r\n let ii;\r\n let overrideContext;\r\n let removeIndex;\r\n let record;\r\n let rmPromises = [];\r\n let viewOrPromise;\r\n\r\n for (i = 0, ii = records.length; i < ii; ++i) {\r\n record = records[i];\r\n value = record.value;\r\n switch (record.type) {\r\n case 'add':\r\n let size = Math.max(set.size - 1, 0);\r\n overrideContext = createFullOverrideContext(repeat, value, size, set.size);\r\n repeat.insertView(size, overrideContext.bindingContext, overrideContext);\r\n break;\r\n case 'delete':\r\n removeIndex = this._getViewIndexByValue(repeat, value);\r\n viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);\r\n if (viewOrPromise instanceof Promise) {\r\n rmPromises.push(viewOrPromise);\r\n }\r\n break;\r\n case 'clear':\r\n repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);\r\n break;\r\n default:\r\n continue;\r\n }\r\n }\r\n\r\n if (rmPromises.length > 0) {\r\n Promise.all(rmPromises).then(() => {\r\n updateOverrideContexts(repeat.views(), 0);\r\n });\r\n } else {\r\n updateOverrideContexts(repeat.views(), 0);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _getViewIndexByValue(repeat, value) {\r\n let i;\r\n let ii;\r\n let child;\r\n\r\n for (i = 0, ii = repeat.viewCount(); i < ii; ++i) {\r\n child = repeat.view(i);\r\n if (child.bindingContext[repeat.local] === value) {\r\n return i;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n}\r\n","import { ArrayRepeatStrategy } from './array-repeat-strategy';\r\nimport { MapRepeatStrategy } from './map-repeat-strategy';\r\nimport { NullRepeatStrategy } from './null-repeat-strategy';\r\nimport { NumberRepeatStrategy } from './number-repeat-strategy';\r\nimport { Repeat } from './repeat';\r\nimport { SetRepeatStrategy } from './set-repeat-strategy';\r\n\r\n/**\r\n * A strategy is for repeating a template over an iterable or iterable-like object.\r\n */\r\nexport interface RepeatStrategy {\r\n instanceChanged(repeat: Repeat, items: any): void;\r\n instanceMutated(repeat: Repeat, items: any, changes: any): void;\r\n getCollectionObserver(observerLocator: any, items: any): any;\r\n}\r\n\r\n/**\r\n * Locates the best strategy to best repeating a template over different types of collections.\r\n * Custom strategies can be plugged in as well.\r\n */\r\nexport class RepeatStrategyLocator {\r\n\r\n /**@internal*/\r\n matchers: any[];\r\n /**@internal*/\r\n strategies: any[];\r\n\r\n /**\r\n * Creates a new RepeatStrategyLocator.\r\n */\r\n constructor() {\r\n this.matchers = [];\r\n this.strategies = [];\r\n\r\n this.addStrategy(items => items === null || items === undefined, new NullRepeatStrategy() as RepeatStrategy);\r\n this.addStrategy(items => items instanceof Array, new ArrayRepeatStrategy());\r\n this.addStrategy(items => items instanceof Map, new MapRepeatStrategy());\r\n this.addStrategy(items => items instanceof Set, new SetRepeatStrategy());\r\n this.addStrategy(items => typeof items === 'number', new NumberRepeatStrategy() as Partial as RepeatStrategy);\r\n }\r\n\r\n /**\r\n * Adds a repeat strategy to be located when repeating a template over different collection types.\r\n * @param strategy A repeat strategy that can iterate a specific collection type.\r\n */\r\n addStrategy(matcher: (items: any) => boolean, strategy: RepeatStrategy) {\r\n this.matchers.push(matcher);\r\n this.strategies.push(strategy);\r\n }\r\n\r\n /**\r\n * Gets the best strategy to handle iteration.\r\n */\r\n getStrategy(items: any): RepeatStrategy {\r\n let matchers = this.matchers;\r\n\r\n for (let i = 0, ii = matchers.length; i < ii; ++i) {\r\n if (matchers[i](items)) {\r\n return this.strategies[i];\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n}\r\n","/**\r\n* Behaviors that do not require the composition lifecycle callbacks when replacing\r\n* their binding context.\r\n*/\r\nexport const lifecycleOptionalBehaviors = ['focus', 'if', 'else', 'repeat', 'show', 'hide', 'with'];\r\n\r\nfunction behaviorRequiresLifecycle(instruction) {\r\n let t = instruction.type;\r\n let name = t.elementName !== null ? t.elementName : t.attributeName;\r\n return lifecycleOptionalBehaviors.indexOf(name) === -1 && (t.handlesAttached || t.handlesBind || t.handlesCreated || t.handlesDetached || t.handlesUnbind)\r\n || t.viewFactory && viewsRequireLifecycle(t.viewFactory)\r\n || instruction.viewFactory && viewsRequireLifecycle(instruction.viewFactory);\r\n}\r\n\r\nfunction targetRequiresLifecycle(instruction) {\r\n // check each behavior instruction.\r\n let behaviors = instruction.behaviorInstructions;\r\n if (behaviors) {\r\n let i = behaviors.length;\r\n while (i--) {\r\n if (behaviorRequiresLifecycle(behaviors[i])) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n // check the instruction's view factory (if it has one).\r\n return instruction.viewFactory && viewsRequireLifecycle(instruction.viewFactory);\r\n}\r\n\r\nexport function viewsRequireLifecycle(viewFactory) {\r\n // already analyzed?\r\n if ('_viewsRequireLifecycle' in viewFactory) {\r\n return viewFactory._viewsRequireLifecycle;\r\n }\r\n\r\n // set prop to avoid infinite recursion.\r\n viewFactory._viewsRequireLifecycle = false;\r\n\r\n // access inner view factory.\r\n if (viewFactory.viewFactory) {\r\n viewFactory._viewsRequireLifecycle = viewsRequireLifecycle(viewFactory.viewFactory);\r\n return viewFactory._viewsRequireLifecycle;\r\n }\r\n\r\n // template uses animation?\r\n if (viewFactory.template.querySelector('.au-animate')) {\r\n viewFactory._viewsRequireLifecycle = true;\r\n return true;\r\n }\r\n\r\n // target instructions require lifecycle?\r\n for (let id in viewFactory.instructions) {\r\n if (targetRequiresLifecycle(viewFactory.instructions[id])) {\r\n viewFactory._viewsRequireLifecycle = true;\r\n return true;\r\n }\r\n }\r\n\r\n // safe to skip lifecycle.\r\n viewFactory._viewsRequireLifecycle = false;\r\n return false;\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { View } from 'aurelia-templating';\r\n\r\n/**\r\n* An abstract base class for elements and attributes that repeat\r\n* views.\r\n*/\r\nexport class AbstractRepeater {\r\n constructor(options) {\r\n Object.assign(this, {\r\n local: 'items',\r\n viewsRequireLifecycle: true\r\n }, options);\r\n }\r\n\r\n /**\r\n * Returns the number of views the repeater knows about.\r\n *\r\n * @return the number of views.\r\n */\r\n viewCount(): number {\r\n throw new Error('subclass must implement `viewCount`');\r\n }\r\n\r\n /**\r\n * Returns all of the repeaters views as an array.\r\n *\r\n * @return The repeater's array of views;\r\n */\r\n views(): any[] {\r\n throw new Error('subclass must implement `views`');\r\n }\r\n\r\n /**\r\n * Returns a single view from the repeater at the provided index.\r\n *\r\n * @param index The index of the requested view.\r\n * @return {View|ViewSlot} The requested view.\r\n */\r\n view(index: number): any {\r\n throw new Error('subclass must implement `view`');\r\n }\r\n\r\n /**\r\n * Returns the matcher function to be used by the repeater, or null if strict matching is to be performed.\r\n *\r\n * @return The requested matcher function.\r\n */\r\n matcher(): Function | null {\r\n throw new Error('subclass must implement `matcher`');\r\n }\r\n\r\n /**\r\n * Adds a view to the repeater, binding the view to the\r\n * provided contexts.\r\n *\r\n * @param {Object} bindingContext The binding context to bind the new view to.\r\n * @param {Object} overrideContext A secondary binding context that can override the primary context.\r\n */\r\n addView(bindingContext, overrideContext): any {\r\n throw new Error('subclass must implement `addView`');\r\n }\r\n\r\n /**\r\n * Inserts a view to the repeater at a specific index, binding the view to the\r\n * provided contexts.\r\n *\r\n * @param {Number} index The index at which to create the new view at.\r\n * @param {Object} bindingContext The binding context to bind the new view to.\r\n * @param {Object} overrideContext A secondary binding context that can override the primary context.\r\n */\r\n insertView(index, bindingContext, overrideContext): any {\r\n throw new Error('subclass must implement `insertView`');\r\n }\r\n\r\n /**\r\n * Moves a view across the repeater.\r\n *\r\n * @param {Number} sourceIndex The index of the view to be moved.\r\n * @param {Number} sourceIndex The index where the view should be placed at.\r\n */\r\n moveView(sourceIndex, targetIndex): any {\r\n throw new Error('subclass must implement `moveView`');\r\n }\r\n\r\n /**\r\n * Removes all views from the repeater.\r\n * @param {Boolean} returnToCache Should the view be returned to the view cache?\r\n * @param {Boolean} skipAnimation Should the removal animation be skipped?\r\n * @return {Promise|null}\r\n */\r\n removeAllViews(returnToCache?: boolean, skipAnimation?: boolean): any {\r\n throw new Error('subclass must implement `removeAllViews`');\r\n }\r\n\r\n /**\r\n * Removes an array of Views from the repeater.\r\n *\r\n * @param {Array} viewsToRemove The array of views to be removed.\r\n * @param {Boolean} returnToCache Should the view be returned to the view cache?\r\n * @param {Boolean} skipAnimation Should the removal animation be skipped?\r\n */\r\n removeViews(viewsToRemove: Array, returnToCache?: boolean, skipAnimation?: boolean): any {\r\n throw new Error('subclass must implement `removeView`');\r\n }\r\n\r\n /**\r\n * Removes a view from the repeater at a specific index.\r\n *\r\n * @param {Number} index The index of the view to be removed.\r\n * @param {Boolean} returnToCache Should the view be returned to the view cache?\r\n * @param {Boolean} skipAnimation Should the removal animation be skipped?\r\n */\r\n removeView(index: number, returnToCache?: boolean, skipAnimation?: boolean): any {\r\n throw new Error('subclass must implement `removeView`');\r\n }\r\n\r\n /**\r\n * Forces a particular view to update it's bindings, called as part of\r\n * an in-place processing of items for better performance\r\n *\r\n * @param {Object} view the target view for bindings updates\r\n */\r\n updateBindings(view: View) {\r\n throw new Error('subclass must implement `updateBindings`');\r\n }\r\n}\r\n","/*eslint no-loop-func:0, no-unused-vars:0*/\r\nimport {inject} from 'aurelia-dependency-injection';\r\nimport {ObserverLocator, BindingExpression} from 'aurelia-binding';\r\nimport {\r\n BoundViewFactory,\r\n TargetInstruction,\r\n ViewSlot,\r\n ViewResources,\r\n customAttribute,\r\n bindable,\r\n templateController,\r\n View,\r\n ViewFactory\r\n} from 'aurelia-templating';\r\nimport {RepeatStrategyLocator} from './repeat-strategy-locator';\r\nimport {\r\n getItemsSourceExpression,\r\n unwrapExpression,\r\n isOneTime,\r\n updateOneTimeBinding\r\n} from './repeat-utilities';\r\nimport {viewsRequireLifecycle} from './analyze-view-factory';\r\nimport {AbstractRepeater} from './abstract-repeater';\r\n\r\nconst matcherExtractionMarker = '__marker_extracted__';\r\n\r\n/**\r\n * Binding to iterate over iterable objects (Array, Map and Number) to genereate a template for each iteration.\r\n */\r\n@customAttribute('repeat')\r\n@templateController\r\n@inject(BoundViewFactory, TargetInstruction, ViewSlot, ViewResources, ObserverLocator, RepeatStrategyLocator)\r\nexport class Repeat extends AbstractRepeater {\r\n\r\n /**\r\n * Setting this to `true` to enable legacy behavior, where a repeat would take first `matcher` binding\r\n * any where inside its view if there's no `matcher` binding on the repeated element itself.\r\n *\r\n * Default value is true to avoid breaking change\r\n * @default true\r\n */\r\n static useInnerMatcher = true;\r\n\r\n /**\r\n * List of items to bind the repeater to.\r\n *\r\n * @property items\r\n */\r\n @bindable items;\r\n /**\r\n * Local variable which gets assigned on each iteration.\r\n *\r\n * @property local\r\n */\r\n @bindable local;\r\n /**\r\n * Key when iterating over Maps.\r\n *\r\n * @property key\r\n */\r\n @bindable key;\r\n /**\r\n * Value when iterating over Maps.\r\n *\r\n * @property value\r\n */\r\n @bindable value;\r\n\r\n /**@internal*/\r\n viewFactory: any;\r\n /**@internal*/\r\n instruction: any;\r\n /**@internal*/\r\n viewSlot: any;\r\n /**@internal*/\r\n lookupFunctions: any;\r\n /**@internal*/\r\n observerLocator: any;\r\n /**@internal*/\r\n strategyLocator: any;\r\n /**@internal*/\r\n ignoreMutation: boolean;\r\n /**@internal*/\r\n sourceExpression: any;\r\n /**@internal*/\r\n isOneTime: any;\r\n /**@internal*/\r\n viewsRequireLifecycle: any;\r\n /**@internal*/\r\n scope: { bindingContext: any; overrideContext: any; };\r\n /**@internal*/\r\n matcherBinding: any;\r\n /**@internal*/\r\n collectionObserver: any;\r\n /**@internal*/\r\n strategy: any;\r\n /**@internal */\r\n callContext: 'handleCollectionMutated' | 'handleInnerCollectionMutated';\r\n\r\n /**\r\n * Creates an instance of Repeat.\r\n * @param viewFactory The factory generating the view\r\n * @param instruction The instructions for how the element should be enhanced.\r\n * @param viewResources Collection of resources used to compile the the views.\r\n * @param viewSlot The slot the view is injected in to.\r\n * @param observerLocator The observer locator instance.\r\n * @param collectionStrategyLocator The strategy locator to locate best strategy to iterate the collection.\r\n */\r\n constructor(viewFactory, instruction, viewSlot, viewResources, observerLocator, strategyLocator) {\r\n super({\r\n local: 'item',\r\n viewsRequireLifecycle: viewsRequireLifecycle(viewFactory)\r\n });\r\n\r\n this.viewFactory = viewFactory;\r\n this.instruction = instruction;\r\n this.viewSlot = viewSlot;\r\n this.lookupFunctions = viewResources.lookupFunctions;\r\n this.observerLocator = observerLocator;\r\n this.key = 'key';\r\n this.value = 'value';\r\n this.strategyLocator = strategyLocator;\r\n this.ignoreMutation = false;\r\n this.sourceExpression = getItemsSourceExpression(this.instruction, 'repeat.for');\r\n this.isOneTime = isOneTime(this.sourceExpression);\r\n this.viewsRequireLifecycle = viewsRequireLifecycle(viewFactory);\r\n }\r\n\r\n call(context, changes) {\r\n this[context](this.items, changes);\r\n }\r\n\r\n /**\r\n * Binds the repeat to the binding context and override context.\r\n * @param bindingContext The binding context.\r\n * @param overrideContext An override context for binding.\r\n */\r\n bind(bindingContext, overrideContext) {\r\n this.scope = { bindingContext, overrideContext };\r\n const instruction = this.instruction;\r\n if (!(matcherExtractionMarker in instruction)) {\r\n instruction[matcherExtractionMarker] = this._captureAndRemoveMatcherBinding();\r\n }\r\n this.matcherBinding = instruction[matcherExtractionMarker];\r\n this.itemsChanged();\r\n }\r\n\r\n /**\r\n * Unbinds the repeat\r\n */\r\n unbind() {\r\n this.scope = null;\r\n this.items = null;\r\n this.matcherBinding = null;\r\n this.viewSlot.removeAll(true, true);\r\n this._unsubscribeCollection();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _unsubscribeCollection() {\r\n if (this.collectionObserver) {\r\n this.collectionObserver.unsubscribe(this.callContext, this);\r\n this.collectionObserver = null;\r\n this.callContext = null;\r\n }\r\n }\r\n\r\n /**\r\n * Invoked everytime the item property changes.\r\n */\r\n itemsChanged() {\r\n this._unsubscribeCollection();\r\n\r\n // still bound?\r\n if (!this.scope) {\r\n return;\r\n }\r\n\r\n let items = this.items;\r\n this.strategy = this.strategyLocator.getStrategy(items);\r\n if (!this.strategy) {\r\n throw new Error(`Value for '${this.sourceExpression}' is non-repeatable`);\r\n }\r\n\r\n if (!this.isOneTime && !this._observeInnerCollection()) {\r\n this._observeCollection();\r\n }\r\n this.ignoreMutation = true;\r\n this.strategy.instanceChanged(this, items);\r\n this.observerLocator.taskQueue.queueMicroTask(() => {\r\n this.ignoreMutation = false;\r\n });\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _getInnerCollection() {\r\n let expression = unwrapExpression(this.sourceExpression);\r\n if (!expression) {\r\n return null;\r\n }\r\n return expression.evaluate(this.scope, null);\r\n }\r\n\r\n /**\r\n * Invoked when the underlying collection changes.\r\n */\r\n handleCollectionMutated(collection, changes) {\r\n if (!this.collectionObserver) {\r\n return;\r\n }\r\n if (this.ignoreMutation) {\r\n return;\r\n }\r\n this.strategy.instanceMutated(this, collection, changes);\r\n }\r\n\r\n /**\r\n * Invoked when the underlying inner collection changes.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n handleInnerCollectionMutated(collection, changes) {\r\n if (!this.collectionObserver) {\r\n return;\r\n }\r\n // guard against source expressions that have observable side-effects that could\r\n // cause an infinite loop- eg a value converter that mutates the source array.\r\n if (this.ignoreMutation) {\r\n return;\r\n }\r\n this.ignoreMutation = true;\r\n let newItems = this.sourceExpression.evaluate(this.scope, this.lookupFunctions);\r\n this.observerLocator.taskQueue.queueMicroTask(() => this.ignoreMutation = false);\r\n\r\n // call itemsChanged...\r\n if (newItems === this.items) {\r\n // call itemsChanged directly.\r\n this.itemsChanged();\r\n } else {\r\n // call itemsChanged indirectly by assigning the new collection value to\r\n // the items property, which will trigger the self-subscriber to call itemsChanged.\r\n this.items = newItems;\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _observeInnerCollection() {\r\n let items = this._getInnerCollection();\r\n let strategy = this.strategyLocator.getStrategy(items);\r\n if (!strategy) {\r\n return false;\r\n }\r\n this.collectionObserver = strategy.getCollectionObserver(this.observerLocator, items);\r\n if (!this.collectionObserver) {\r\n return false;\r\n }\r\n this.callContext = 'handleInnerCollectionMutated';\r\n this.collectionObserver.subscribe(this.callContext, this);\r\n return true;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n _observeCollection() {\r\n let items = this.items;\r\n this.collectionObserver = this.strategy.getCollectionObserver(this.observerLocator, items);\r\n if (this.collectionObserver) {\r\n this.callContext = 'handleCollectionMutated';\r\n this.collectionObserver.subscribe(this.callContext, this);\r\n }\r\n }\r\n\r\n /**\r\n * Capture and remove matcher binding is a way to cache matcher binding + reduce redundant work\r\n * caused by multiple unnecessary matcher bindings\r\n * @internal\r\n */\r\n _captureAndRemoveMatcherBinding() {\r\n const viewFactory: ViewFactory = this.viewFactory.viewFactory;\r\n if (viewFactory) {\r\n const template = viewFactory.template;\r\n const instructions = viewFactory.instructions as Record;\r\n // legacy behavior enabled when Repeat.useInnerMathcer === true\r\n if (Repeat.useInnerMatcher) {\r\n return extractMatcherBindingExpression(instructions);\r\n }\r\n // if the template has more than 1 immediate child element\r\n // it's a repeat put on a