UNPKG

@danielkalen/simplybind

Version:

Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.

1,897 lines (1,527 loc) 127 kB
var _class4, _temp, _dec, _class5, _dec2, _class6, _dec3, _class7, _dec4, _class8, _dec5, _class9, _class10, _temp2, _dec6, _class11, _class12, _temp3, _class15, _dec7, _class17, _dec8, _class18, _class19, _temp4, _dec9, _class21, _dec10, _class22, _dec11, _class23; import * as LogManager from 'aurelia-logging'; import { metadata, Origin, protocol } from 'aurelia-metadata'; import { DOM, PLATFORM, FEATURE } from 'aurelia-pal'; import { relativeToFile } from 'aurelia-path'; import { TemplateRegistryEntry, Loader } from 'aurelia-loader'; import { inject, Container, resolver } from 'aurelia-dependency-injection'; import { Binding, createOverrideContext, ValueConverterResource, BindingBehaviorResource, subscriberCollection, bindingMode, ObserverLocator, EventManager } from 'aurelia-binding'; import { TaskQueue } from 'aurelia-task-queue'; export const animationEvent = { enterBegin: 'animation:enter:begin', enterActive: 'animation:enter:active', enterDone: 'animation:enter:done', enterTimeout: 'animation:enter:timeout', leaveBegin: 'animation:leave:begin', leaveActive: 'animation:leave:active', leaveDone: 'animation:leave:done', leaveTimeout: 'animation:leave:timeout', staggerNext: 'animation:stagger:next', removeClassBegin: 'animation:remove-class:begin', removeClassActive: 'animation:remove-class:active', removeClassDone: 'animation:remove-class:done', removeClassTimeout: 'animation:remove-class:timeout', addClassBegin: 'animation:add-class:begin', addClassActive: 'animation:add-class:active', addClassDone: 'animation:add-class:done', addClassTimeout: 'animation:add-class:timeout', animateBegin: 'animation:animate:begin', animateActive: 'animation:animate:active', animateDone: 'animation:animate:done', animateTimeout: 'animation:animate:timeout', sequenceBegin: 'animation:sequence:begin', sequenceDone: 'animation:sequence:done' }; export let Animator = class Animator { enter(element) { return Promise.resolve(false); } leave(element) { return Promise.resolve(false); } removeClass(element, className) { element.classList.remove(className); return Promise.resolve(false); } addClass(element, className) { element.classList.add(className); return Promise.resolve(false); } animate(element, className) { return Promise.resolve(false); } runSequence(animations) {} registerEffect(effectName, properties) {} unregisterEffect(effectName) {} }; export let CompositionTransactionNotifier = class CompositionTransactionNotifier { constructor(owner) { this.owner = owner; this.owner._compositionCount++; } done() { this.owner._compositionCount--; this.owner._tryCompleteTransaction(); } }; export let CompositionTransactionOwnershipToken = class CompositionTransactionOwnershipToken { constructor(owner) { this.owner = owner; this.owner._ownershipToken = this; this.thenable = this._createThenable(); } waitForCompositionComplete() { this.owner._tryCompleteTransaction(); return this.thenable; } resolve() { this._resolveCallback(); } _createThenable() { return new Promise((resolve, reject) => { this._resolveCallback = resolve; }); } }; export let CompositionTransaction = class CompositionTransaction { constructor() { this._ownershipToken = null; this._compositionCount = 0; } tryCapture() { return this._ownershipToken === null ? new CompositionTransactionOwnershipToken(this) : null; } enlist() { return new CompositionTransactionNotifier(this); } _tryCompleteTransaction() { if (this._compositionCount <= 0) { this._compositionCount = 0; if (this._ownershipToken !== null) { let token = this._ownershipToken; this._ownershipToken = null; token.resolve(); } } } }; const capitalMatcher = /([A-Z])/g; function addHyphenAndLower(char) { return '-' + char.toLowerCase(); } export function _hyphenate(name) { return (name.charAt(0).toLowerCase() + name.slice(1)).replace(capitalMatcher, addHyphenAndLower); } export function _isAllWhitespace(node) { return !(node.auInterpolationTarget || /[^\t\n\r ]/.test(node.textContent)); } export let ViewEngineHooksResource = class ViewEngineHooksResource { constructor() {} initialize(container, target) { this.instance = container.get(target); } register(registry, name) { registry.registerViewEngineHooks(this.instance); } load(container, target) {} static convention(name) { if (name.endsWith('ViewEngineHooks')) { return new ViewEngineHooksResource(); } } }; export function viewEngineHooks(target) { let deco = function (t) { metadata.define(metadata.resource, new ViewEngineHooksResource(), t); }; return target ? deco(target) : deco; } export let ElementEvents = class ElementEvents { constructor(element) { this.element = element; this.subscriptions = {}; } _enqueueHandler(handler) { this.subscriptions[handler.eventName] = this.subscriptions[handler.eventName] || []; this.subscriptions[handler.eventName].push(handler); } _dequeueHandler(handler) { let index; let subscriptions = this.subscriptions[handler.eventName]; if (subscriptions) { index = subscriptions.indexOf(handler); if (index > -1) { subscriptions.splice(index, 1); } } return handler; } publish(eventName, detail = {}, bubbles = true, cancelable = true) { let event = DOM.createCustomEvent(eventName, { cancelable, bubbles, detail }); this.element.dispatchEvent(event); } subscribe(eventName, handler, bubbles = true) { if (handler && typeof handler === 'function') { handler.eventName = eventName; handler.handler = handler; handler.bubbles = bubbles; handler.dispose = () => { this.element.removeEventListener(eventName, handler, bubbles); this._dequeueHandler(handler); }; this.element.addEventListener(eventName, handler, bubbles); this._enqueueHandler(handler); return handler; } return undefined; } subscribeOnce(eventName, handler, bubbles = true) { if (handler && typeof handler === 'function') { let _handler = event => { handler(event); _handler.dispose(); }; return this.subscribe(eventName, _handler, bubbles); } return undefined; } dispose(eventName) { if (eventName && typeof eventName === 'string') { let subscriptions = this.subscriptions[eventName]; if (subscriptions) { while (subscriptions.length) { let subscription = subscriptions.pop(); if (subscription) { subscription.dispose(); } } } } else { this.disposeAll(); } } disposeAll() { for (let key in this.subscriptions) { this.dispose(key); } } }; export let ResourceLoadContext = class ResourceLoadContext { constructor() { this.dependencies = {}; } addDependency(url) { this.dependencies[url] = true; } hasDependency(url) { return url in this.dependencies; } }; export let ViewCompileInstruction = class ViewCompileInstruction { constructor(targetShadowDOM = false, compileSurrogate = false) { this.targetShadowDOM = targetShadowDOM; this.compileSurrogate = compileSurrogate; this.associatedModuleId = null; } }; ViewCompileInstruction.normal = new ViewCompileInstruction(); export let BehaviorInstruction = class BehaviorInstruction { static enhance() { let instruction = new BehaviorInstruction(); instruction.enhance = true; return instruction; } static unitTest(type, attributes) { let instruction = new BehaviorInstruction(); instruction.type = type; instruction.attributes = attributes || {}; return instruction; } static element(node, type) { let instruction = new BehaviorInstruction(); instruction.type = type; instruction.attributes = {}; instruction.anchorIsContainer = !(node.hasAttribute('containerless') || type.containerless); instruction.initiatedByBehavior = true; return instruction; } static attribute(attrName, type) { let instruction = new BehaviorInstruction(); instruction.attrName = attrName; instruction.type = type || null; instruction.attributes = {}; return instruction; } static dynamic(host, viewModel, viewFactory) { let instruction = new BehaviorInstruction(); instruction.host = host; instruction.viewModel = viewModel; instruction.viewFactory = viewFactory; instruction.inheritBindingContext = true; return instruction; } constructor() { this.initiatedByBehavior = false; this.enhance = false; this.partReplacements = null; this.viewFactory = null; this.originalAttrName = null; this.skipContentProcessing = false; this.contentFactory = null; this.viewModel = null; this.anchorIsContainer = false; this.host = null; this.attributes = null; this.type = null; this.attrName = null; this.inheritBindingContext = false; } }; BehaviorInstruction.normal = new BehaviorInstruction(); export let TargetInstruction = (_temp = _class4 = class TargetInstruction { static shadowSlot(parentInjectorId) { let instruction = new TargetInstruction(); instruction.parentInjectorId = parentInjectorId; instruction.shadowSlot = true; return instruction; } static contentExpression(expression) { let instruction = new TargetInstruction(); instruction.contentExpression = expression; return instruction; } static lifting(parentInjectorId, liftingInstruction) { let instruction = new TargetInstruction(); instruction.parentInjectorId = parentInjectorId; instruction.expressions = TargetInstruction.noExpressions; instruction.behaviorInstructions = [liftingInstruction]; instruction.viewFactory = liftingInstruction.viewFactory; instruction.providers = [liftingInstruction.type.target]; instruction.lifting = true; return instruction; } static normal(injectorId, parentInjectorId, providers, behaviorInstructions, expressions, elementInstruction) { let instruction = new TargetInstruction(); instruction.injectorId = injectorId; instruction.parentInjectorId = parentInjectorId; instruction.providers = providers; instruction.behaviorInstructions = behaviorInstructions; instruction.expressions = expressions; instruction.anchorIsContainer = elementInstruction ? elementInstruction.anchorIsContainer : true; instruction.elementInstruction = elementInstruction; return instruction; } static surrogate(providers, behaviorInstructions, expressions, values) { let instruction = new TargetInstruction(); instruction.expressions = expressions; instruction.behaviorInstructions = behaviorInstructions; instruction.providers = providers; instruction.values = values; return instruction; } constructor() { this.injectorId = null; this.parentInjectorId = null; this.shadowSlot = false; this.slotName = null; this.slotFallbackFactory = null; this.contentExpression = null; this.expressions = null; this.behaviorInstructions = null; this.providers = null; this.viewFactory = null; this.anchorIsContainer = false; this.elementInstruction = null; this.lifting = false; this.values = null; } }, _class4.noExpressions = Object.freeze([]), _temp); export const viewStrategy = protocol.create('aurelia:view-strategy', { validate(target) { if (!(typeof target.loadViewFactory === 'function')) { return 'View strategies must implement: loadViewFactory(viewEngine: ViewEngine, compileInstruction: ViewCompileInstruction, loadContext?: ResourceLoadContext): Promise<ViewFactory>'; } return true; }, compose(target) { if (!(typeof target.makeRelativeTo === 'function')) { target.makeRelativeTo = PLATFORM.noop; } } }); export let RelativeViewStrategy = (_dec = viewStrategy(), _dec(_class5 = class RelativeViewStrategy { constructor(path) { this.path = path; this.absolutePath = null; } loadViewFactory(viewEngine, compileInstruction, loadContext, target) { if (this.absolutePath === null && this.moduleId) { this.absolutePath = relativeToFile(this.path, this.moduleId); } compileInstruction.associatedModuleId = this.moduleId; return viewEngine.loadViewFactory(this.absolutePath || this.path, compileInstruction, loadContext, target); } makeRelativeTo(file) { if (this.absolutePath === null) { this.absolutePath = relativeToFile(this.path, file); } } }) || _class5); export let ConventionalViewStrategy = (_dec2 = viewStrategy(), _dec2(_class6 = class ConventionalViewStrategy { constructor(viewLocator, origin) { this.moduleId = origin.moduleId; this.viewUrl = viewLocator.convertOriginToViewUrl(origin); } loadViewFactory(viewEngine, compileInstruction, loadContext, target) { compileInstruction.associatedModuleId = this.moduleId; return viewEngine.loadViewFactory(this.viewUrl, compileInstruction, loadContext, target); } }) || _class6); export let NoViewStrategy = (_dec3 = viewStrategy(), _dec3(_class7 = class NoViewStrategy { constructor(dependencies, dependencyBaseUrl) { this.dependencies = dependencies || null; this.dependencyBaseUrl = dependencyBaseUrl || ''; } loadViewFactory(viewEngine, compileInstruction, loadContext, target) { let entry = this.entry; let dependencies = this.dependencies; if (entry && entry.factoryIsReady) { return Promise.resolve(null); } this.entry = entry = new TemplateRegistryEntry(this.moduleId || this.dependencyBaseUrl); entry.dependencies = []; entry.templateIsLoaded = true; if (dependencies !== null) { for (let i = 0, ii = dependencies.length; i < ii; ++i) { let current = dependencies[i]; if (typeof current === 'string' || typeof current === 'function') { entry.addDependency(current); } else { entry.addDependency(current.from, current.as); } } } compileInstruction.associatedModuleId = this.moduleId; return viewEngine.loadViewFactory(entry, compileInstruction, loadContext, target); } }) || _class7); export let TemplateRegistryViewStrategy = (_dec4 = viewStrategy(), _dec4(_class8 = class TemplateRegistryViewStrategy { constructor(moduleId, entry) { this.moduleId = moduleId; this.entry = entry; } loadViewFactory(viewEngine, compileInstruction, loadContext, target) { let entry = this.entry; if (entry.factoryIsReady) { return Promise.resolve(entry.factory); } compileInstruction.associatedModuleId = this.moduleId; return viewEngine.loadViewFactory(entry, compileInstruction, loadContext, target); } }) || _class8); export let InlineViewStrategy = (_dec5 = viewStrategy(), _dec5(_class9 = class InlineViewStrategy { constructor(markup, dependencies, dependencyBaseUrl) { this.markup = markup; this.dependencies = dependencies || null; this.dependencyBaseUrl = dependencyBaseUrl || ''; } loadViewFactory(viewEngine, compileInstruction, loadContext, target) { let entry = this.entry; let dependencies = this.dependencies; if (entry && entry.factoryIsReady) { return Promise.resolve(entry.factory); } this.entry = entry = new TemplateRegistryEntry(this.moduleId || this.dependencyBaseUrl); entry.template = DOM.createTemplateFromMarkup(this.markup); if (dependencies !== null) { for (let i = 0, ii = dependencies.length; i < ii; ++i) { let current = dependencies[i]; if (typeof current === 'string' || typeof current === 'function') { entry.addDependency(current); } else { entry.addDependency(current.from, current.as); } } } compileInstruction.associatedModuleId = this.moduleId; return viewEngine.loadViewFactory(entry, compileInstruction, loadContext, target); } }) || _class9); export let ViewLocator = (_temp2 = _class10 = class ViewLocator { getViewStrategy(value) { if (!value) { return null; } if (typeof value === 'object' && 'getViewStrategy' in value) { let origin = Origin.get(value.constructor); value = value.getViewStrategy(); if (typeof value === 'string') { value = new RelativeViewStrategy(value); } viewStrategy.assert(value); if (origin.moduleId) { value.makeRelativeTo(origin.moduleId); } return value; } if (typeof value === 'string') { value = new RelativeViewStrategy(value); } if (viewStrategy.validate(value)) { return value; } if (typeof value !== 'function') { value = value.constructor; } let origin = Origin.get(value); let strategy = metadata.get(ViewLocator.viewStrategyMetadataKey, value); if (!strategy) { if (!origin.moduleId) { throw new Error('Cannot determine default view strategy for object.', value); } strategy = this.createFallbackViewStrategy(origin); } else if (origin.moduleId) { strategy.moduleId = origin.moduleId; } return strategy; } createFallbackViewStrategy(origin) { return new ConventionalViewStrategy(this, origin); } convertOriginToViewUrl(origin) { let moduleId = origin.moduleId; let id = moduleId.endsWith('.js') || moduleId.endsWith('.ts') ? moduleId.substring(0, moduleId.length - 3) : moduleId; return id + '.html'; } }, _class10.viewStrategyMetadataKey = 'aurelia:view-strategy', _temp2); function mi(name) { throw new Error(`BindingLanguage must implement ${ name }().`); } export let BindingLanguage = class BindingLanguage { inspectAttribute(resources, elementName, attrName, attrValue) { mi('inspectAttribute'); } createAttributeInstruction(resources, element, info, existingInstruction) { mi('createAttributeInstruction'); } inspectTextContent(resources, value) { mi('inspectTextContent'); } }; let noNodes = Object.freeze([]); export let SlotCustomAttribute = (_dec6 = inject(DOM.Element), _dec6(_class11 = class SlotCustomAttribute { constructor(element) { this.element = element; this.element.auSlotAttribute = this; } valueChanged(newValue, oldValue) {} }) || _class11); export let PassThroughSlot = class PassThroughSlot { constructor(anchor, name, destinationName, fallbackFactory) { this.anchor = anchor; this.anchor.viewSlot = this; this.name = name; this.destinationName = destinationName; this.fallbackFactory = fallbackFactory; this.destinationSlot = null; this.projections = 0; this.contentView = null; let attr = new SlotCustomAttribute(this.anchor); attr.value = this.destinationName; } get needsFallbackRendering() { return this.fallbackFactory && this.projections === 0; } renderFallbackContent(view, nodes, projectionSource, index) { if (this.contentView === null) { this.contentView = this.fallbackFactory.create(this.ownerView.container); this.contentView.bind(this.ownerView.bindingContext, this.ownerView.overrideContext); let slots = Object.create(null); slots[this.destinationSlot.name] = this.destinationSlot; ShadowDOM.distributeView(this.contentView, slots, projectionSource, index, this.destinationSlot.name); } } passThroughTo(destinationSlot) { this.destinationSlot = destinationSlot; } addNode(view, node, projectionSource, index) { if (this.contentView !== null) { this.contentView.removeNodes(); this.contentView.detached(); this.contentView.unbind(); this.contentView = null; } if (node.viewSlot instanceof PassThroughSlot) { node.viewSlot.passThroughTo(this); return; } this.projections++; this.destinationSlot.addNode(view, node, projectionSource, index); } removeView(view, projectionSource) { this.projections--; this.destinationSlot.removeView(view, projectionSource); if (this.needsFallbackRendering) { this.renderFallbackContent(null, noNodes, projectionSource); } } removeAll(projectionSource) { this.projections = 0; this.destinationSlot.removeAll(projectionSource); if (this.needsFallbackRendering) { this.renderFallbackContent(null, noNodes, projectionSource); } } projectFrom(view, projectionSource) { this.destinationSlot.projectFrom(view, projectionSource); } created(ownerView) { this.ownerView = ownerView; } bind(view) { if (this.contentView) { this.contentView.bind(view.bindingContext, view.overrideContext); } } attached() { if (this.contentView) { this.contentView.attached(); } } detached() { if (this.contentView) { this.contentView.detached(); } } unbind() { if (this.contentView) { this.contentView.unbind(); } } }; export let ShadowSlot = class ShadowSlot { constructor(anchor, name, fallbackFactory) { this.anchor = anchor; this.anchor.isContentProjectionSource = true; this.anchor.viewSlot = this; this.name = name; this.fallbackFactory = fallbackFactory; this.contentView = null; this.projections = 0; this.children = []; this.projectFromAnchors = null; this.destinationSlots = null; } get needsFallbackRendering() { return this.fallbackFactory && this.projections === 0; } addNode(view, node, projectionSource, index, destination) { if (this.contentView !== null) { this.contentView.removeNodes(); this.contentView.detached(); this.contentView.unbind(); this.contentView = null; } if (node.viewSlot instanceof PassThroughSlot) { node.viewSlot.passThroughTo(this); return; } if (this.destinationSlots !== null) { ShadowDOM.distributeNodes(view, [node], this.destinationSlots, this, index); } else { node.auOwnerView = view; node.auProjectionSource = projectionSource; node.auAssignedSlot = this; let anchor = this._findAnchor(view, node, projectionSource, index); let parent = anchor.parentNode; parent.insertBefore(node, anchor); this.children.push(node); this.projections++; } } removeView(view, projectionSource) { if (this.destinationSlots !== null) { ShadowDOM.undistributeView(view, this.destinationSlots, this); } else if (this.contentView && this.contentView.hasSlots) { ShadowDOM.undistributeView(view, this.contentView.slots, projectionSource); } else { let found = this.children.find(x => x.auSlotProjectFrom === projectionSource); if (found) { let children = found.auProjectionChildren; for (let i = 0, ii = children.length; i < ii; ++i) { let child = children[i]; if (child.auOwnerView === view) { children.splice(i, 1); view.fragment.appendChild(child); i--;ii--; this.projections--; } } if (this.needsFallbackRendering) { this.renderFallbackContent(view, noNodes, projectionSource); } } } } removeAll(projectionSource) { if (this.destinationSlots !== null) { ShadowDOM.undistributeAll(this.destinationSlots, this); } else if (this.contentView && this.contentView.hasSlots) { ShadowDOM.undistributeAll(this.contentView.slots, projectionSource); } else { let found = this.children.find(x => x.auSlotProjectFrom === projectionSource); if (found) { let children = found.auProjectionChildren; for (let i = 0, ii = children.length; i < ii; ++i) { let child = children[i]; child.auOwnerView.fragment.appendChild(child); this.projections--; } found.auProjectionChildren = []; if (this.needsFallbackRendering) { this.renderFallbackContent(null, noNodes, projectionSource); } } } } _findAnchor(view, node, projectionSource, index) { if (projectionSource) { let found = this.children.find(x => x.auSlotProjectFrom === projectionSource); if (found) { if (index !== undefined) { let children = found.auProjectionChildren; let viewIndex = -1; let lastView; for (let i = 0, ii = children.length; i < ii; ++i) { let current = children[i]; if (current.auOwnerView !== lastView) { viewIndex++; lastView = current.auOwnerView; if (viewIndex >= index && lastView !== view) { children.splice(i, 0, node); return current; } } } } found.auProjectionChildren.push(node); return found; } } return this.anchor; } projectTo(slots) { this.destinationSlots = slots; } projectFrom(view, projectionSource) { let anchor = DOM.createComment('anchor'); let parent = this.anchor.parentNode; anchor.auSlotProjectFrom = projectionSource; anchor.auOwnerView = view; anchor.auProjectionChildren = []; parent.insertBefore(anchor, this.anchor); this.children.push(anchor); if (this.projectFromAnchors === null) { this.projectFromAnchors = []; } this.projectFromAnchors.push(anchor); } renderFallbackContent(view, nodes, projectionSource, index) { if (this.contentView === null) { this.contentView = this.fallbackFactory.create(this.ownerView.container); this.contentView.bind(this.ownerView.bindingContext, this.ownerView.overrideContext); this.contentView.insertNodesBefore(this.anchor); } if (this.contentView.hasSlots) { let slots = this.contentView.slots; let projectFromAnchors = this.projectFromAnchors; if (projectFromAnchors !== null) { for (let slotName in slots) { let slot = slots[slotName]; for (let i = 0, ii = projectFromAnchors.length; i < ii; ++i) { let anchor = projectFromAnchors[i]; slot.projectFrom(anchor.auOwnerView, anchor.auSlotProjectFrom); } } } this.fallbackSlots = slots; ShadowDOM.distributeNodes(view, nodes, slots, projectionSource, index); } } created(ownerView) { this.ownerView = ownerView; } bind(view) { if (this.contentView) { this.contentView.bind(view.bindingContext, view.overrideContext); } } attached() { if (this.contentView) { this.contentView.attached(); } } detached() { if (this.contentView) { this.contentView.detached(); } } unbind() { if (this.contentView) { this.contentView.unbind(); } } }; export let ShadowDOM = (_temp3 = _class12 = class ShadowDOM { static getSlotName(node) { if (node.auSlotAttribute === undefined) { return ShadowDOM.defaultSlotKey; } return node.auSlotAttribute.value; } static distributeView(view, slots, projectionSource, index, destinationOverride) { let nodes; if (view === null) { nodes = noNodes; } else { let childNodes = view.fragment.childNodes; let ii = childNodes.length; nodes = new Array(ii); for (let i = 0; i < ii; ++i) { nodes[i] = childNodes[i]; } } ShadowDOM.distributeNodes(view, nodes, slots, projectionSource, index, destinationOverride); } static undistributeView(view, slots, projectionSource) { for (let slotName in slots) { slots[slotName].removeView(view, projectionSource); } } static undistributeAll(slots, projectionSource) { for (let slotName in slots) { slots[slotName].removeAll(projectionSource); } } static distributeNodes(view, nodes, slots, projectionSource, index, destinationOverride) { for (let i = 0, ii = nodes.length; i < ii; ++i) { let currentNode = nodes[i]; let nodeType = currentNode.nodeType; if (currentNode.isContentProjectionSource) { currentNode.viewSlot.projectTo(slots); for (let slotName in slots) { slots[slotName].projectFrom(view, currentNode.viewSlot); } nodes.splice(i, 1); ii--;i--; } else if (nodeType === 1 || nodeType === 3 || currentNode.viewSlot instanceof PassThroughSlot) { if (nodeType === 3 && _isAllWhitespace(currentNode)) { nodes.splice(i, 1); ii--;i--; } else { let found = slots[destinationOverride || ShadowDOM.getSlotName(currentNode)]; if (found) { found.addNode(view, currentNode, projectionSource, index); nodes.splice(i, 1); ii--;i--; } } } else { nodes.splice(i, 1); ii--;i--; } } for (let slotName in slots) { let slot = slots[slotName]; if (slot.needsFallbackRendering) { slot.renderFallbackContent(view, nodes, projectionSource, index); } } } }, _class12.defaultSlotKey = '__au-default-slot-key__', _temp3); function register(lookup, name, resource, type) { if (!name) { return; } let existing = lookup[name]; if (existing) { if (existing !== resource) { throw new Error(`Attempted to register ${ type } when one with the same name already exists. Name: ${ name }.`); } return; } lookup[name] = resource; } export let ViewResources = class ViewResources { constructor(parent, viewUrl) { this.bindingLanguage = null; this.parent = parent || null; this.hasParent = this.parent !== null; this.viewUrl = viewUrl || ''; this.lookupFunctions = { valueConverters: this.getValueConverter.bind(this), bindingBehaviors: this.getBindingBehavior.bind(this) }; this.attributes = Object.create(null); this.elements = Object.create(null); this.valueConverters = Object.create(null); this.bindingBehaviors = Object.create(null); this.attributeMap = Object.create(null); this.values = Object.create(null); this.beforeCompile = this.afterCompile = this.beforeCreate = this.afterCreate = this.beforeBind = this.beforeUnbind = false; } _tryAddHook(obj, name) { if (typeof obj[name] === 'function') { let func = obj[name].bind(obj); let counter = 1; let callbackName; while (this[callbackName = name + counter.toString()] !== undefined) { counter++; } this[name] = true; this[callbackName] = func; } } _invokeHook(name, one, two, three, four) { if (this.hasParent) { this.parent._invokeHook(name, one, two, three, four); } if (this[name]) { this[name + '1'](one, two, three, four); let callbackName = name + '2'; if (this[callbackName]) { this[callbackName](one, two, three, four); callbackName = name + '3'; if (this[callbackName]) { this[callbackName](one, two, three, four); let counter = 4; while (this[callbackName = name + counter.toString()] !== undefined) { this[callbackName](one, two, three, four); counter++; } } } } } registerViewEngineHooks(hooks) { this._tryAddHook(hooks, 'beforeCompile'); this._tryAddHook(hooks, 'afterCompile'); this._tryAddHook(hooks, 'beforeCreate'); this._tryAddHook(hooks, 'afterCreate'); this._tryAddHook(hooks, 'beforeBind'); this._tryAddHook(hooks, 'beforeUnbind'); } getBindingLanguage(bindingLanguageFallback) { return this.bindingLanguage || (this.bindingLanguage = bindingLanguageFallback); } patchInParent(newParent) { let originalParent = this.parent; this.parent = newParent || null; this.hasParent = this.parent !== null; if (newParent.parent === null) { newParent.parent = originalParent; newParent.hasParent = originalParent !== null; } } relativeToView(path) { return relativeToFile(path, this.viewUrl); } registerElement(tagName, behavior) { register(this.elements, tagName, behavior, 'an Element'); } getElement(tagName) { return this.elements[tagName] || (this.hasParent ? this.parent.getElement(tagName) : null); } mapAttribute(attribute) { return this.attributeMap[attribute] || (this.hasParent ? this.parent.mapAttribute(attribute) : null); } registerAttribute(attribute, behavior, knownAttribute) { this.attributeMap[attribute] = knownAttribute; register(this.attributes, attribute, behavior, 'an Attribute'); } getAttribute(attribute) { return this.attributes[attribute] || (this.hasParent ? this.parent.getAttribute(attribute) : null); } registerValueConverter(name, valueConverter) { register(this.valueConverters, name, valueConverter, 'a ValueConverter'); } getValueConverter(name) { return this.valueConverters[name] || (this.hasParent ? this.parent.getValueConverter(name) : null); } registerBindingBehavior(name, bindingBehavior) { register(this.bindingBehaviors, name, bindingBehavior, 'a BindingBehavior'); } getBindingBehavior(name) { return this.bindingBehaviors[name] || (this.hasParent ? this.parent.getBindingBehavior(name) : null); } registerValue(name, value) { register(this.values, name, value, 'a value'); } getValue(name) { return this.values[name] || (this.hasParent ? this.parent.getValue(name) : null); } }; export let View = class View { constructor(container, viewFactory, fragment, controllers, bindings, children, slots) { this.container = container; this.viewFactory = viewFactory; this.resources = viewFactory.resources; this.fragment = fragment; this.firstChild = fragment.firstChild; this.lastChild = fragment.lastChild; this.controllers = controllers; this.bindings = bindings; this.children = children; this.slots = slots; this.hasSlots = false; this.fromCache = false; this.isBound = false; this.isAttached = false; this.bindingContext = null; this.overrideContext = null; this.controller = null; this.viewModelScope = null; this.animatableElement = undefined; this._isUserControlled = false; this.contentView = null; for (let key in slots) { this.hasSlots = true; break; } } returnToCache() { this.viewFactory.returnViewToCache(this); } created() { let i; let ii; let controllers = this.controllers; for (i = 0, ii = controllers.length; i < ii; ++i) { controllers[i].created(this); } } bind(bindingContext, overrideContext, _systemUpdate) { let controllers; let bindings; let children; let i; let ii; if (_systemUpdate && this._isUserControlled) { return; } if (this.isBound) { if (this.bindingContext === bindingContext) { return; } this.unbind(); } this.isBound = true; this.bindingContext = bindingContext; this.overrideContext = overrideContext || createOverrideContext(bindingContext); this.resources._invokeHook('beforeBind', this); bindings = this.bindings; for (i = 0, ii = bindings.length; i < ii; ++i) { bindings[i].bind(this); } if (this.viewModelScope !== null) { bindingContext.bind(this.viewModelScope.bindingContext, this.viewModelScope.overrideContext); this.viewModelScope = null; } controllers = this.controllers; for (i = 0, ii = controllers.length; i < ii; ++i) { controllers[i].bind(this); } children = this.children; for (i = 0, ii = children.length; i < ii; ++i) { children[i].bind(bindingContext, overrideContext, true); } if (this.hasSlots) { ShadowDOM.distributeView(this.contentView, this.slots); } } addBinding(binding) { this.bindings.push(binding); if (this.isBound) { binding.bind(this); } } unbind() { let controllers; let bindings; let children; let i; let ii; if (this.isBound) { this.isBound = false; this.resources._invokeHook('beforeUnbind', this); if (this.controller !== null) { this.controller.unbind(); } bindings = this.bindings; for (i = 0, ii = bindings.length; i < ii; ++i) { bindings[i].unbind(); } controllers = this.controllers; for (i = 0, ii = controllers.length; i < ii; ++i) { controllers[i].unbind(); } children = this.children; for (i = 0, ii = children.length; i < ii; ++i) { children[i].unbind(); } this.bindingContext = null; this.overrideContext = null; } } insertNodesBefore(refNode) { refNode.parentNode.insertBefore(this.fragment, refNode); } appendNodesTo(parent) { parent.appendChild(this.fragment); } removeNodes() { let fragment = this.fragment; let current = this.firstChild; let end = this.lastChild; let next; while (current) { next = current.nextSibling; fragment.appendChild(current); if (current === end) { break; } current = next; } } attached() { let controllers; let children; let i; let ii; if (this.isAttached) { return; } this.isAttached = true; if (this.controller !== null) { this.controller.attached(); } controllers = this.controllers; for (i = 0, ii = controllers.length; i < ii; ++i) { controllers[i].attached(); } children = this.children; for (i = 0, ii = children.length; i < ii; ++i) { children[i].attached(); } } detached() { let controllers; let children; let i; let ii; if (this.isAttached) { this.isAttached = false; if (this.controller !== null) { this.controller.detached(); } controllers = this.controllers; for (i = 0, ii = controllers.length; i < ii; ++i) { controllers[i].detached(); } children = this.children; for (i = 0, ii = children.length; i < ii; ++i) { children[i].detached(); } } } }; function getAnimatableElement(view) { if (view.animatableElement !== undefined) { return view.animatableElement; } let current = view.firstChild; while (current && current.nodeType !== 1) { current = current.nextSibling; } if (current && current.nodeType === 1) { return view.animatableElement = current.classList.contains('au-animate') ? current : null; } return view.animatableElement = null; } export let ViewSlot = class ViewSlot { constructor(anchor, anchorIsContainer, animator = Animator.instance) { this.anchor = anchor; this.anchorIsContainer = anchorIsContainer; this.bindingContext = null; this.overrideContext = null; this.animator = animator; this.children = []; this.isBound = false; this.isAttached = false; this.contentSelectors = null; anchor.viewSlot = this; anchor.isContentProjectionSource = false; } animateView(view, direction = 'enter') { let animatableElement = getAnimatableElement(view); if (animatableElement !== null) { switch (direction) { case 'enter': return this.animator.enter(animatableElement); case 'leave': return this.animator.leave(animatableElement); default: throw new Error('Invalid animation direction: ' + direction); } } } transformChildNodesIntoView() { let parent = this.anchor; this.children.push({ fragment: parent, firstChild: parent.firstChild, lastChild: parent.lastChild, returnToCache() {}, removeNodes() { let last; while (last = parent.lastChild) { parent.removeChild(last); } }, created() {}, bind() {}, unbind() {}, attached() {}, detached() {} }); } bind(bindingContext, overrideContext) { let i; let ii; let children; if (this.isBound) { if (this.bindingContext === bindingContext) { return; } this.unbind(); } this.isBound = true; this.bindingContext = bindingContext = bindingContext || this.bindingContext; this.overrideContext = overrideContext = overrideContext || this.overrideContext; children = this.children; for (i = 0, ii = children.length; i < ii; ++i) { children[i].bind(bindingContext, overrideContext, true); } } unbind() { if (this.isBound) { let i; let ii; let children = this.children; this.isBound = false; this.bindingContext = null; this.overrideContext = null; for (i = 0, ii = children.length; i < ii; ++i) { children[i].unbind(); } } } add(view) { if (this.anchorIsContainer) { view.appendNodesTo(this.anchor); } else { view.insertNodesBefore(this.anchor); } this.children.push(view); if (this.isAttached) { view.attached(); return this.animateView(view, 'enter'); } } insert(index, view) { let children = this.children; let length = children.length; if (index === 0 && length === 0 || index >= length) { return this.add(view); } view.insertNodesBefore(children[index].firstChild); children.splice(index, 0, view); if (this.isAttached) { view.attached(); return this.animateView(view, 'enter'); } } move(sourceIndex, targetIndex) { if (sourceIndex === targetIndex) { return; } const children = this.children; const view = children[sourceIndex]; view.removeNodes(); view.insertNodesBefore(children[targetIndex].firstChild); children.splice(sourceIndex, 1); children.splice(targetIndex, 0, view); } remove(view, returnToCache, skipAnimation) { return this.removeAt(this.children.indexOf(view), returnToCache, skipAnimation); } removeMany(viewsToRemove, returnToCache, skipAnimation) { const children = this.children; let ii = viewsToRemove.length; let i; let rmPromises = []; viewsToRemove.forEach(child => { if (skipAnimation) { child.removeNodes(); return; } let animation = this.animateView(child, 'leave'); if (animation) { rmPromises.push(animation.then(() => child.removeNodes())); } else { child.removeNodes(); } }); let removeAction = () => { if (this.isAttached) { for (i = 0; i < ii; ++i) { viewsToRemove[i].detached(); } } if (returnToCache) { for (i = 0; i < ii; ++i) { viewsToRemove[i].returnToCache(); } } for (i = 0; i < ii; ++i) { const index = children.indexOf(viewsToRemove[i]); if (index >= 0) { children.splice(index, 1); } } }; if (rmPromises.length > 0) { return Promise.all(rmPromises).then(() => removeAction()); } return removeAction(); } removeAt(index, returnToCache, skipAnimation) { let view = this.children[index]; let removeAction = () => { index = this.children.indexOf(view); view.removeNodes(); this.children.splice(index, 1); if (this.isAttached) { view.detached(); } if (returnToCache) { view.returnToCache(); } return view; }; if (!skipAnimation) { let animation = this.animateView(view, 'leave'); if (animation) { return animation.then(() => removeAction()); } } return removeAction(); } removeAll(returnToCache, skipAnimation) { let children = this.children; let ii = children.length; let i; let rmPromises = []; children.forEach(child => { if (skipAnimation) { child.removeNodes(); return; } let animation = this.animateView(child, 'leave'); if (animation) { rmPromises.push(animation.then(() => child.removeNodes())); } else { child.removeNodes(); } }); let removeAction = () => { if (this.isAttached) { for (i = 0; i < ii; ++i) { children[i].detached(); } } if (returnToCache) { for (i = 0; i < ii; ++i) { children[i].returnToCache(); } } this.children = []; }; if (rmPromises.length > 0) { return Promise.all(rmPromises).then(() => removeAction()); } return removeAction(); } attached() { let i; let ii; let children; let child; if (this.isAttached) { return; } this.isAttached = true; children = this.children; for (i = 0, ii = children.length; i < ii; ++i) { child = children[i]; child.attached(); this.animateView(child, 'enter'); } } detached() { let i; let ii; let children; if (this.isAttached) { this.isAttached = false; children = this.children; for (i = 0, ii = children.length; i < ii; ++i) { children[i].detached(); } } } projectTo(slots) { this.projectToSlots = slots; this.add = this._projectionAdd; this.insert = this._projectionInsert; this.move = this._projectionMove; this.remove = this._projectionRemove; this.removeAt = this._projectionRemoveAt; this.removeMany = this._projectionRemoveMany; this.removeAll = this._projectionRemoveAll; this.children.forEach(view => ShadowDOM.distributeView(view, slots, this)); } _projectionAdd(view) { ShadowDOM.distributeView(view, this.projectToSlots, this); this.children.push(view); if (this.isAttached) { view.attached(); } } _projectionInsert(index, view) { if (index === 0 && !this.children.length || index >= this.children.length) { this.add(view); } else { ShadowDOM.distributeView(view, this.projectToSlots, this, index); this.children.splice(index, 0, view); if (this.isAttached) { view.attached(); } } } _projectionMove(sourceIndex, targetIndex) { if (sourceIndex === targetIndex) { return; } const children = this.children; const view = children[sourceIndex]; ShadowDOM.undistributeView(view, this.projectToSlots, this); ShadowDOM.distributeView(view, this.projectToSlots, this, targetIndex); children.splice(sourceIndex, 1); children.splice(targetIndex, 0, view); } _projectionRemove(view, returnToCache) { ShadowDOM.undistributeView(view, this.projectToSlots, this); this.children.splice(this.children.indexOf(view), 1); if (this.isAttached) { view.detached(); } } _projectionRemoveAt(index, returnToCache) { let view = this.children[index]; ShadowDOM.undistributeView(view, this.projectToSlots, this); this.children.splice(index, 1); if (this.isAttached) { view.detached(); } } _projectionRemoveMany(viewsToRemove, returnToCache) { viewsToRemove.forEach(view => this.remove(view, returnToCache)); } _projectionRemoveAll(returnToCache) { ShadowDOM.undistributeAll(this.projectToSlots, this); let children = this.children; if (this.isAttached) { for (let i = 0, ii = children.length; i < ii; ++i) { children[i].detached(); } } this.children = []; } }; let ProviderResolver = resolver(_class15 = class ProviderResolver { get(container, key) { let id = key.__providerId__; return id in container ? container[id] : container[id] = container.invoke(key); } }) || _class15; let providerResolverInstance = new ProviderResolver(); function elementContainerGet(key) { if (key === DOM.Element) { return this.element; } if (key === BoundViewFactory) { if (this.boundViewFactory) { return this.boundViewFactory; } let factory = this.instruction.viewFactory; let partReplacements = this.partReplacements; if (partReplacements) { factory = partReplacements[factory.part] || factory; } this.boundViewFactory = new BoundViewFactory(this, factory, partReplacements); return this.boundViewFactory; } if (key === ViewSlot) { if (this.viewSlot === undefined) { this.viewSlot = new ViewSlot(this.element, this.instruction.anchorIsContainer); this.element.isContentProjectionSource = this.instruction.lifting; this.children.push(this.viewSlot); } return this.viewSlot; } if (key === ElementEvents) { return this.elementEvents || (this.elementEvents = new ElementEvents(this.element)); } if (key === CompositionTransaction) { return this.compositionTransaction || (this.compositionTransaction = this.parent.get(key)); } if (key === ViewResources) { return this.viewResources; } if (key === TargetInstruction) { return this.instruction; } return this.superGet(key); } function createElementContainer(parent, element, instruction, children, partReplacements, resources) { let container = parent.createChild(); let providers; let i; container.element = element; container.instruction = instruction; container.children = children; container.viewResources = resources; container.partReplacements = partReplacements; providers = instruction.providers; i = providers.length; while (i--) { container._resolvers.set(providers[i], providerResolverInstance); } container.superGet = container.get; container.get = elementContainerGet; return container; } function makeElementIntoAnchor(element, elementInstruction) { let anchor = DOM.createComment('anchor'); if (elementInstructio