@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
JavaScript
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