Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@aurelia/runtime

Package Overview
Dependencies
Maintainers
1
Versions
1116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aurelia/runtime - npm Package Compare versions

Comparing version 0.2.0-dev.20181001 to 0.2.0-dev.20181002

9

dist/binding/observation.d.ts

@@ -182,3 +182,3 @@ import { IDisposable, IIndexable } from '@aurelia/kernel';

interface IObservedCollection {
$observer: CollectionObserver;
$observer?: CollectionObserver;
}

@@ -211,5 +211,6 @@ /**

}
declare type LengthPropertyName<T> = T extends any[] ? 'length' : T extends Set<any> ? 'size' : T extends Map<any, any> ? 'size' : never;
declare type CollectionKindToType<T> = T extends CollectionKind.array ? any[] : T extends CollectionKind.indexed ? any[] : T extends CollectionKind.map ? Map<any, any> : T extends CollectionKind.set ? Set<any> : T extends CollectionKind.keyed ? Set<any> | Map<any, any> : never;
declare type ObservedCollectionKindToType<T> = T extends CollectionKind.array ? IObservedArray : T extends CollectionKind.indexed ? IObservedArray : T extends CollectionKind.map ? IObservedMap : T extends CollectionKind.set ? IObservedSet : T extends CollectionKind.keyed ? IObservedSet | IObservedMap : never;
export declare type LengthPropertyName<T> = T extends any[] ? 'length' : T extends Set<any> ? 'size' : T extends Map<any, any> ? 'size' : never;
export declare type CollectionTypeToKind<T> = T extends any[] ? CollectionKind.array | CollectionKind.indexed : T extends Set<any> ? CollectionKind.set | CollectionKind.keyed : T extends Map<any, any> ? CollectionKind.map | CollectionKind.keyed : never;
export declare type CollectionKindToType<T> = T extends CollectionKind.array ? any[] : T extends CollectionKind.indexed ? any[] : T extends CollectionKind.map ? Map<any, any> : T extends CollectionKind.set ? Set<any> : T extends CollectionKind.keyed ? Set<any> | Map<any, any> : never;
export declare type ObservedCollectionKindToType<T> = T extends CollectionKind.array ? IObservedArray : T extends CollectionKind.indexed ? IObservedArray : T extends CollectionKind.map ? IObservedMap : T extends CollectionKind.set ? IObservedSet : T extends CollectionKind.keyed ? IObservedSet | IObservedMap : never;
/**

@@ -216,0 +217,0 @@ * An observer that tracks collection mutations and notifies subscribers (either directly or in batches)

@@ -5,3 +5,3 @@ import { IIndexable, Primitive } from '@aurelia/kernel';

import { IEventManager } from './event-manager';
import { AccessorOrObserver, CollectionKind, IBindingTargetAccessor, IBindingTargetObserver, ICollectionObserver, IObservable, IObservedArray, IObservedMap, IObservedSet } from './observation';
import { AccessorOrObserver, CollectionKind, IBindingTargetAccessor, IBindingTargetObserver, ICollectionObserver, IObservable, IObservedArray, IObservedMap, IObservedSet, CollectionObserver } from './observation';
import { ISVGAnalyzer } from './svg-analyzer';

@@ -38,2 +38,3 @@ export interface IObjectObservationAdapter {

}
export declare function getCollectionObserver(changeSet: IChangeSet, collection: IObservedMap | IObservedSet | IObservedArray): CollectionObserver;
//# sourceMappingURL=observer-locator.d.ts.map

@@ -5,3 +5,4 @@ import { BindingFlags } from '../../binding/binding-flags';

import { IAttachLifecycle, IDetachLifecycle } from '../lifecycle';
import { IViewFactory } from '../view';
import { IView, IViewFactory } from '../view';
import { CompositionCoordinator } from './composition-coordinator';
export interface If extends ICustomAttribute {

@@ -11,8 +12,8 @@ }

ifFactory: IViewFactory;
private location;
location: IRenderLocation;
value: boolean;
elseFactory: IViewFactory;
private ifView;
private elseView;
private coordinator;
ifView: IView;
elseView: IView;
coordinator: CompositionCoordinator;
constructor(ifFactory: IViewFactory, location: IRenderLocation);

@@ -19,0 +20,0 @@ binding(flags: BindingFlags): void;

@@ -1,18 +0,10 @@

import { IContainer, Immutable } from '@aurelia/kernel';
import { ForOfStatement } from '../../binding/ast';
import { IScope } from '../../binding/binding-context';
import { BindingFlags } from '../../binding/binding-flags';
import { IChangeSet } from '../../binding/change-set';
import { CollectionObserver, IObservedArray, IObservedSet, ObservedCollection } from '../../binding/observation';
import { BindingFlags, CollectionObserver, ForOfStatement, IBatchedCollectionSubscriber, IChangeSet, IObservedArray, IScope, ObservedCollection, SetterObserver } from '../../binding';
import { INode, IRenderLocation } from '../../dom';
import { IResourceKind, IResourceType } from '../../resource';
import { ICustomAttribute, ICustomAttributeSource } from '../custom-attribute';
import { ICustomAttribute } from '../custom-attribute';
import { IAttachLifecycle, IDetachLifecycle } from '../lifecycle';
import { IRenderable } from '../renderable';
import { IRenderingEngine } from '../rendering-engine';
import { IRuntimeBehavior } from '../runtime-behavior';
import { IView, IViewFactory } from '../view';
import { IBatchedCollectionSubscriber, IObservedMap } from './../../binding/observation';
export declare function getCollectionObserver(changeSet: IChangeSet, collection: IObservedMap | IObservedSet | IObservedArray): CollectionObserver;
export declare class Repeat<T extends ObservedCollection> implements ICustomAttribute, IBatchedCollectionSubscriber {
export interface Repeat<T extends ObservedCollection> extends ICustomAttribute, IBatchedCollectionSubscriber {
}
export declare class Repeat<T extends ObservedCollection = IObservedArray> {
changeSet: IChangeSet;

@@ -22,34 +14,25 @@ location: IRenderLocation;

factory: IViewFactory;
container: IContainer;
static kind: IResourceKind<ICustomAttributeSource, IResourceType<ICustomAttributeSource, ICustomAttribute>>;
static description: Immutable<Required<ICustomAttributeSource>>;
static register(container: IContainer): void;
$changeCallbacks: (() => void)[];
items: T;
$isAttached: boolean;
$isBound: boolean;
$scope: IScope;
$behavior: IRuntimeBehavior;
$hydrate(renderingEngine: IRenderingEngine): void;
private _items;
items: T & {
$observer: CollectionObserver;
$observers: {
items: SetterObserver;
};
encapsulationSource: INode;
views: IView[];
local: string;
viewsRequireLifecycle: boolean;
observer: CollectionObserver;
hasPendingInstanceMutation: boolean;
sourceExpression: ForOfStatement;
constructor(changeSet: IChangeSet, location: IRenderLocation, renderable: IRenderable, factory: IViewFactory, container: IContainer);
$bind(flags: BindingFlags, scope: IScope): void;
$attach(encapsulationSource: INode, lifecycle: IAttachLifecycle): void;
$detach(lifecycle: IDetachLifecycle): void;
$unbind(flags: BindingFlags): void;
$cache(): void;
flushChanges(): void;
handleBatchedChange(indexMap?: number[]): void;
private handleBatchedItemsOrInstanceMutation;
private removeAllViews;
forOf: ForOfStatement;
local: string;
constructor(changeSet: IChangeSet, location: IRenderLocation, renderable: IRenderable, factory: IViewFactory);
bound(flags: BindingFlags): void;
attaching(encapsulationSource: INode, lifecycle: IAttachLifecycle): void;
detaching(lifecycle: IDetachLifecycle): void;
unbound(flags: BindingFlags): void;
itemsChanged(newValue: T, oldValue: T, flags: BindingFlags): void;
handleBatchedChange(indexMap: number[] | null): void;
private processViews;
private checkCollectionObserver;
}
//# sourceMappingURL=repeat.d.ts.map
{
"name": "@aurelia/runtime",
"version": "0.2.0-dev.20181001",
"version": "0.2.0-dev.20181002",
"main": "dist/index.umd.js",

@@ -46,3 +46,3 @@ "module": "dist/index.es6.js",

"dependencies": {
"@aurelia/kernel": "0.2.0-dev.20181001"
"@aurelia/kernel": "0.2.0-dev.20181002"
},

@@ -88,3 +88,3 @@ "devDependencies": {

},
"gitHead": "5971d36d4b8629352b3d1ec29eb06cfddd0ef9c7"
"gitHead": "cd5c6207fecfad5c3fcdec959f7edeed9f9525a6"
}

@@ -255,3 +255,3 @@ import { IDisposable, IIndexable } from '@aurelia/kernel';

interface IObservedCollection {
$observer: CollectionObserver;
$observer?: CollectionObserver;
}

@@ -284,3 +284,3 @@

type LengthPropertyName<T> =
export type LengthPropertyName<T> =
T extends any[] ? 'length' :

@@ -291,3 +291,3 @@ T extends Set<any> ? 'size' :

type CollectionTypeToKind<T> =
export type CollectionTypeToKind<T> =
T extends any[] ? CollectionKind.array | CollectionKind.indexed :

@@ -298,3 +298,3 @@ T extends Set<any> ? CollectionKind.set | CollectionKind.keyed :

type CollectionKindToType<T> =
export type CollectionKindToType<T> =
T extends CollectionKind.array ? any[] :

@@ -307,3 +307,3 @@ T extends CollectionKind.indexed ? any[] :

type ObservedCollectionKindToType<T> =
export type ObservedCollectionKindToType<T> =
T extends CollectionKind.array ? IObservedArray :

@@ -310,0 +310,0 @@ T extends CollectionKind.indexed ? IObservedArray :

@@ -10,3 +10,3 @@ import { DI, IIndexable, inject, Primitive, Reporter } from '@aurelia/kernel';

import { getMapObserver } from './map-observer';
import { AccessorOrObserver, CollectionKind, IBindingTargetAccessor, IBindingTargetObserver, ICollectionObserver, IObservable, IObservedArray, IObservedMap, IObservedSet } from './observation';
import { AccessorOrObserver, CollectionKind, IBindingTargetAccessor, IBindingTargetObserver, ICollectionObserver, IObservable, IObservedArray, IObservedMap, IObservedSet, CollectionObserver } from './observation';
import { PrimitiveObserver, SetterObserver } from './property-observation';

@@ -244,1 +244,13 @@ import { getSetObserver } from './set-observer';

}
export function getCollectionObserver(changeSet: IChangeSet, collection: IObservedMap | IObservedSet | IObservedArray): CollectionObserver {
switch (toStringTag.call(collection)) {
case '[object Array]':
return getArrayObserver(changeSet, <IObservedArray>collection);
case '[object Map]':
return getMapObserver(changeSet, <IObservedMap>collection);
case '[object Set]':
return getSetObserver(changeSet, <IObservedSet>collection);
}
return null;
}

@@ -39,3 +39,6 @@ import { Constructable, PLATFORM } from '@aurelia/kernel';

cache: 0,
build: {
build: typeof this.node === 'string' ? {
required: true,
compiler: 'default'
} : {
required: false

@@ -42,0 +45,0 @@ },

@@ -41,3 +41,2 @@ import {

$behavior: IRuntimeBehavior;
$encapsulationSource: INode;
}

@@ -228,4 +227,3 @@

this.$encapsulationSource = encapsulationSource
= this.$projector.provideEncapsulationSource(encapsulationSource);
encapsulationSource = this.$projector.provideEncapsulationSource(encapsulationSource);

@@ -393,3 +391,3 @@ if (this.$behavior.hasAttaching) {

if (host.childNodes.length) {
this.childNodes = Array.from(host.childNodes);
this.childNodes = PLATFORM.toArray(host.childNodes);
} else {

@@ -396,0 +394,0 @@ this.childNodes = PLATFORM.emptyArray;

@@ -142,3 +142,3 @@ import { BindingFlags, IBindScope } from '../binding';

/*@internal*/
class AttachLifecycleController implements IAttachLifecycle, IAttachLifecycleController {
export class AttachLifecycleController implements IAttachLifecycle, IAttachLifecycleController {
/*@internal*/

@@ -183,9 +183,6 @@ public $nextAddNodes: LifecycleNodeAddable;

} else {
let task = this.task;
if (task === null) {
this.task = task = new AggregateLifecycleTask();
if (this.task === null) {
this.task = new AggregateLifecycleTask();
}
task.addTask(task);
this.task.addTask(task);
}

@@ -308,9 +305,6 @@ }

} else {
let task = this.task;
if (task === null) {
this.task = task = new AggregateLifecycleTask();
if (this.task === null) {
this.task = new AggregateLifecycleTask();
}
task.addTask(task);
this.task.addTask(task);
}

@@ -317,0 +311,0 @@ }

@@ -1,2 +0,2 @@

import { IContainer, IDisposable, Immutable, ImmutableArray, IResolver, IServiceLocator, PLATFORM } from '@aurelia/kernel';
import { IContainer, IDisposable, Immutable, ImmutableArray, IResolver, IServiceLocator, PLATFORM, Reporter } from '@aurelia/kernel';
import { DOM, INode, IRenderLocation } from '../dom';

@@ -77,2 +77,5 @@ import { ITargetedInstruction, TemplateDefinition, TemplatePartDefinitions } from './instructions';

public resolve(handler: IContainer, requestor: IContainer): T {
if (this.instance === undefined) { // unmet precondition: call prepare
throw Reporter.error(50); // TODO: organize error codes
}
return this.instance;

@@ -99,4 +102,10 @@ }

public resolve(handler: IContainer, requestor: ExposedContext): IViewFactory {
const found = this.replacements[this.factory.name];
const factory = this.factory;
if (factory === undefined) { // unmet precondition: call prepare
throw Reporter.error(50); // TODO: organize error codes
}
if (!factory.name || !factory.name.length) { // unmet invariant: factory must have a name
throw Reporter.error(51); // TODO: organize error codes
}
const found = this.replacements[factory.name];
if (found) {

@@ -103,0 +112,0 @@ return this.renderingEngine.getViewFactory(found, requestor);

@@ -6,12 +6,10 @@ import { all, DI, IContainer, Immutable, inject, PLATFORM, Reporter } from '@aurelia/kernel';

import { IObserverLocator } from '../binding/observer-locator';
import { DOM, INode, INodeSequence, NodeSequence } from '../dom';
import { IResourceDescriptions, IResourceKind, IResourceType, ResourceDescription } from '../resource';
import { ICustomAttribute, ICustomAttributeType } from './custom-attribute';
import { ICustomElement, ICustomElementType } from './custom-element';
import { ITemplateSource, TemplateDefinition, TemplatePartDefinitions } from './instructions';
import { createRenderContext, ExposedContext, IRenderContext } from './render-context';
import { IRenderable } from './renderable';
import { ITemplateSource, TemplateDefinition } from './instructions';
import { ExposedContext, IRenderContext } from './render-context';
import { IRenderer, Renderer } from './renderer';
import { RuntimeBehavior } from './runtime-behavior';
import { ITemplate } from './template';
import { CompiledTemplate, ITemplate, noViewTemplate } from './template';
import { ITemplateCompiler } from './template-compiler';

@@ -26,3 +24,3 @@ import { IViewFactory, ViewFactory } from './view';

applyRuntimeBehavior(type: ICustomAttributeType, instance: ICustomAttribute): void;
applyRuntimeBehavior(type: ICustomElementType, instance: ICustomElement): void
applyRuntimeBehavior(type: ICustomElementType, instance: ICustomElement): void;

@@ -35,10 +33,2 @@ createRenderer(context: IRenderContext): IRenderer;

// This is an implementation of ITemplate that always returns a node sequence representing "no DOM" to render.
const noViewTemplate: ITemplate = {
renderContext: null,
createFor(renderable: IRenderable): INodeSequence {
return NodeSequence.empty;
}
};
const defaultCompilerName = 'default';

@@ -49,5 +39,5 @@

export class RenderingEngine implements IRenderingEngine {
private templateLookup = new Map<TemplateDefinition, ITemplate>();
private factoryLookup = new Map<Immutable<ITemplateSource>, IViewFactory>();
private behaviorLookup = new Map<ICustomElementType | ICustomAttributeType, RuntimeBehavior>();
private templateLookup: Map<TemplateDefinition, ITemplate> = new Map();
private factoryLookup: Map<Immutable<ITemplateSource>, IViewFactory> = new Map();
private behaviorLookup: Map<ICustomElementType | ICustomAttributeType, RuntimeBehavior> = new Map();
private compilers: Record<string, ITemplateCompiler>;

@@ -178,26 +168,3 @@

// This is the main implementation of ITemplate.
// It is used to create instances of IView based on a compiled TemplateDefinition.
// TemplateDefinitions are hand-coded today, but will ultimately be the output of the
// TemplateCompiler either through a JIT or AOT process.
// Essentially, CompiledTemplate wraps up the small bit of code that is needed to take a TemplateDefinition
// and create instances of it on demand.
/*@internal*/
export class CompiledTemplate implements ITemplate {
public renderContext: IRenderContext;
private createNodeSequence: () => INodeSequence;
constructor(renderingEngine: IRenderingEngine, parentRenderContext: IRenderContext, private templateDefinition: TemplateDefinition) {
this.renderContext = createRenderContext(renderingEngine, parentRenderContext, templateDefinition.dependencies);
this.createNodeSequence = DOM.createFactoryFromMarkupOrNode(templateDefinition.templateOrNode);
}
public createFor(renderable: IRenderable, host?: INode, replacements?: TemplatePartDefinitions): INodeSequence {
const nodes = this.createNodeSequence();
this.renderContext.render(renderable, nodes.findTargets(), this.templateDefinition, host, replacements);
return nodes;
}
}
/*@internal*/
export class RuntimeCompilationResources implements IResourceDescriptions {

@@ -204,0 +171,0 @@ constructor(private context: ExposedContext) {}

@@ -18,7 +18,7 @@ import { inject } from '@aurelia/kernel';

private ifView: IView = null;
private elseView: IView = null;
private coordinator: CompositionCoordinator;
public ifView: IView = null;
public elseView: IView = null;
public coordinator: CompositionCoordinator;
constructor(public ifFactory: IViewFactory, private location: IRenderLocation) {
constructor(public ifFactory: IViewFactory, public location: IRenderLocation) {
this.coordinator = new CompositionCoordinator();

@@ -25,0 +25,0 @@ }

@@ -1,269 +0,173 @@

import { IContainer, Immutable, inject, PLATFORM, Registration } from '@aurelia/kernel';
import { getArrayObserver } from '../../binding/array-observer';
import { ForOfStatement } from '../../binding/ast';
import { Binding } from '../../binding/binding';
import { IOverrideContext, IScope } from '../../binding/binding-context';
import { BindingFlags } from '../../binding/binding-flags';
import { BindingMode } from '../../binding/binding-mode';
import { IChangeSet } from '../../binding/change-set';
import { getMapObserver } from '../../binding/map-observer';
import { CollectionObserver, IObservedArray, IObservedSet, ObservedCollection } from '../../binding/observation';
import { getSetObserver } from '../../binding/set-observer';
import { inject } from '@aurelia/kernel';
import { Binding, BindingContext, BindingFlags, CollectionObserver, ForOfStatement, getCollectionObserver, IBatchedCollectionSubscriber, IChangeSet, IObservedArray, IScope, ObservedCollection, SetterObserver } from '../../binding';
import { INode, IRenderLocation } from '../../dom';
import { IResourceKind, IResourceType } from '../../resource';
import { CustomAttributeResource, ICustomAttribute, ICustomAttributeSource } from '../custom-attribute';
import { IAttachLifecycle, IDetachLifecycle, LifecycleFlags, Lifecycle } from '../lifecycle';
import { bindable } from '../bindable';
import { ICustomAttribute, templateController } from '../custom-attribute';
import { IAttachLifecycle, IDetachLifecycle, Lifecycle, LifecycleFlags } from '../lifecycle';
import { IRenderable } from '../renderable';
import { IRenderingEngine } from '../rendering-engine';
import { IRuntimeBehavior, RuntimeBehavior } from '../runtime-behavior';
import { IView, IViewFactory } from '../view';
import { IBatchedCollectionSubscriber, IObservedMap } from './../../binding/observation';
export function getCollectionObserver(changeSet: IChangeSet, collection: IObservedMap | IObservedSet | IObservedArray): CollectionObserver {
if (Array.isArray(collection)) {
return getArrayObserver(changeSet, collection);
} else if (collection instanceof Map) {
return getMapObserver(changeSet, collection);
} else if (collection instanceof Set) {
return getSetObserver(changeSet, collection);
}
}
// tslint:disable:no-this-assignment
// tslint:disable-next-line:interface-name
export interface Repeat<T extends ObservedCollection> extends ICustomAttribute, IBatchedCollectionSubscriber {}
@inject(IChangeSet, IRenderLocation, IRenderable, IViewFactory, IContainer)
export class Repeat<T extends ObservedCollection> implements ICustomAttribute, IBatchedCollectionSubscriber {
public static kind: IResourceKind<ICustomAttributeSource, IResourceType<ICustomAttributeSource, ICustomAttribute>> = CustomAttributeResource;
public static description: Immutable<Required<ICustomAttributeSource>> = {
name: 'repeat',
aliases: PLATFORM.emptyArray,
defaultBindingMode: BindingMode.toView,
isTemplateController: true,
bindables: {
items: { attribute: 'items', mode: BindingMode.toView, property: 'items' },
local: { attribute: 'local', mode: BindingMode.toView, property: 'local' }
}
};
public static register(container: IContainer): void {
container.register(Registration.transient('custom-attribute:repeat', Repeat));
}
// tslint:disable:member-ordering
public $changeCallbacks: (() => void)[] = [];
public $isAttached: boolean = false;
public $isBound: boolean = false;
public $scope: IScope = null;
public $behavior: IRuntimeBehavior = new (<any>RuntimeBehavior)();
public $hydrate(renderingEngine: IRenderingEngine): void {
let b: RuntimeBehavior = renderingEngine['behaviorLookup'].get(Repeat);
if (!b) {
b = new (<any>RuntimeBehavior)();
b.bindables = Repeat.description.bindables;
b.hasCreated = b.hasAttaching = b.hasAttached = b.hasDetaching = b.hasDetached = b.hasRender = false;
b.hasBound = b.hasUnbound = true;
renderingEngine['behaviorLookup'].set(Repeat, b);
}
this.$behavior = b;
}
const batchedChangesFlags = BindingFlags.fromFlushChanges | BindingFlags.fromBind;
private _items: T & { $observer: CollectionObserver };
public set items(newValue: T & { $observer: CollectionObserver }) {
const oldValue = this._items;
if (oldValue === newValue) {
// don't do anything if the same instance is re-assigned (the existing observer should pick up on any changes)
return;
}
this._items = newValue;
this.hasPendingInstanceMutation = true;
if (this.$isBound) {
this.changeSet.add(this);
}
}
public get items(): T & { $observer: CollectionObserver } {
return this._items;
}
@inject(IChangeSet, IRenderLocation, IRenderable, IViewFactory)
@templateController('repeat')
export class Repeat<T extends ObservedCollection = IObservedArray> {
@bindable public items: T;
public encapsulationSource: INode;
public $isAttached: boolean;
public $isBound: boolean;
public $scope: IScope;
public $observers: { items: SetterObserver }
public encapsulationSource: INode = null;
public views: IView[] = [];
public observer: CollectionObserver = null;
public hasPendingInstanceMutation: boolean = false;
public forOf: ForOfStatement;
public local: string;
public viewsRequireLifecycle: boolean;
public observer: CollectionObserver;
public hasPendingInstanceMutation: boolean;
// TODO: this is not quite yet where it needs to be, have to handle observation correctly in non-collection scenarios
public sourceExpression: ForOfStatement;
constructor(public changeSet: IChangeSet, public location: IRenderLocation, public renderable: IRenderable, public factory: IViewFactory, public container: IContainer) {
this.encapsulationSource = null;
this.observer = null;
this.hasPendingInstanceMutation = false;
constructor(
public changeSet: IChangeSet,
public location: IRenderLocation,
public renderable: IRenderable,
public factory: IViewFactory) { }
public bound(flags: BindingFlags): void {
this.forOf = (<Binding[]>this.renderable.$bindables).find(b => b.target === this).sourceExpression as ForOfStatement;
this.local = this.forOf.declaration.evaluate(flags, this.$scope, null);
this.processViews(null, flags);
this.checkCollectionObserver();
}
// tslint:enable:member-ordering
public $bind(flags: BindingFlags, scope: IScope): void {
if (this.$isBound) {
if (this.$scope === scope) {
return;
}
this.$unbind(flags | BindingFlags.fromBind);
public attaching(encapsulationSource: INode, lifecycle: IAttachLifecycle): void {
const { views, location } = this;
for (let i = 0, ii = views.length; i < ii; ++i) {
const view = views[i];
view.mount(location);
view.$attach(encapsulationSource, lifecycle);
}
this.$scope = scope;
this.$isBound = true;
this.sourceExpression = <any>(<Binding[]>this.renderable.$bindables).find(b => b.target === this && b.targetProperty === 'items').sourceExpression;
this.local = this.sourceExpression.declaration.evaluate(flags, scope, null);
if (this.hasPendingInstanceMutation) {
this.changeSet.add(this);
}
}
public $attach(encapsulationSource: INode, lifecycle: IAttachLifecycle): void {
this.encapsulationSource = encapsulationSource;
this.$isAttached = true;
public detaching(lifecycle: IDetachLifecycle): void {
const { views } = this;
for (let i = 0, ii = views.length; i < ii; ++i) {
const view = views[i];
view.$detach(lifecycle);
view.release();
}
}
public $detach(lifecycle: IDetachLifecycle): void {
this.$isAttached = false;
this.encapsulationSource = null;
}
public unbound(flags: BindingFlags): void {
this.checkCollectionObserver();
public $unbind(flags: BindingFlags): void {
if (this.$isBound) {
this.$isBound = false;
if (this.observer) {
this.observer.unsubscribeBatched(this);
}
this.observer = this._items = null;
// if this is a re-bind triggered by some ancestor repeater, then keep the views so we can reuse them
// (this flag is passed down from handleInstanceMutation/handleItemsMutation down below at view.$bind)
if (!(flags & BindingFlags.fromBind)) {
this.removeAllViews();
}
const { views } = this;
for (let i = 0, ii = views.length; i < ii; ++i) {
const view = views[i];
view.$unbind(flags);
}
}
public $cache(): void { }
public flushChanges(): void {
this.handleBatchedChange();
// called by SetterObserver (sync)
public itemsChanged(newValue: T, oldValue: T, flags: BindingFlags): void {
this.checkCollectionObserver();
this.processViews(null, flags | BindingFlags.updateTargetInstance);
}
public handleBatchedChange(indexMap?: number[]): void {
if (this.hasPendingInstanceMutation) {
if (this.observer) {
this.observer.unsubscribeBatched(this);
}
const items = this._items;
this.observer = getCollectionObserver(this.changeSet, items);
if (this.observer) {
this.observer.subscribeBatched(this);
}
this.handleBatchedItemsOrInstanceMutation();
} else {
this.handleBatchedItemsOrInstanceMutation(indexMap);
}
// called by a CollectionObserver (async)
public handleBatchedChange(indexMap: number[] | null): void {
this.processViews(indexMap, BindingFlags.fromFlushChanges | BindingFlags.updateTargetInstance);
}
// if the indexMap === undefined, it is an instance mutation, otherwise it's an items mutation
private handleBatchedItemsOrInstanceMutation(indexMap?: number[]): void {
// determine if there is anything to process and whether or not we can return early
const location = this.location;
// if the indexMap === null, it is an instance mutation, otherwise it's an items mutation
private processViews(indexMap: number[] | null, flags: BindingFlags): void {
const views = this.views;
const items = this._items;
const oldLength = views.length;
const sourceExpression = this.sourceExpression;
const newLength = sourceExpression.count(items);
if (newLength === 0) {
if (oldLength === 0) {
// if we had 0 items and still have 0 items, we don't need to do anything
if (this.$isBound) {
const { local, $scope, factory, forOf, items } = this;
const oldLength = views.length;
const newLength = forOf.count(items);
if (oldLength < newLength) {
views.length = newLength;
for (let i = oldLength; i < newLength; ++i) {
views[i] = factory.create();
}
} else if (newLength < oldLength) {
const lifecycle = Lifecycle.beginDetach(LifecycleFlags.unbindAfterDetached);
for (let i = newLength, view = views[i]; i < oldLength; view = views[++i]) {
view.release();
lifecycle.detach(view);
}
lifecycle.end();
views.length = newLength;
if (newLength === 0) {
return;
}
} else if (newLength === 0) {
return;
} else {
// if we had >0 items and now have 0 items, just remove all and return
this.removeAllViews();
return;
}
}
// store the scopes of the current indices so we can reuse them for other views
const previousScopes = new Array<IScope>(oldLength);
let i = 0;
while (i < oldLength) {
previousScopes[i] = views[i].$scope;
i++;
}
const flags = BindingFlags.none;
const isAttached = this.$isAttached;
const scope = this.$scope;
const overrideContext = scope.overrideContext;
const local = this.local;
if (oldLength < newLength) {
// expand the array (we add the views later)
views.length = newLength;
} else if (newLength < oldLength) {
// remove any surplus views
i = newLength;
const lifecycle = Lifecycle.beginDetach(LifecycleFlags.none);
while (i < oldLength) {
const view = views[i++];
view.release();
lifecycle.detach(view);
if (indexMap === null) {
forOf.iterate(items, (arr, i, item) => {
const view = views[i];
if (!!view.$scope && view.$scope.bindingContext[local] === item) {
view.$bind(flags, BindingContext.createScopeFromParent($scope, view.$scope.bindingContext));
} else {
view.$bind(flags, BindingContext.createScopeFromParent($scope, { [local]: item }))
}
});
} else {
forOf.iterate(items, (arr, i, item) => {
const view = views[i];
if (indexMap[i] === i) {
view.$bind(flags, BindingContext.createScopeFromParent($scope, view.$scope.bindingContext));
} else {
view.$bind(flags, BindingContext.createScopeFromParent($scope, { [local]: item }))
}
});
}
lifecycle.end();
views.length = newLength;
}
if (indexMap === undefined) {
this.hasPendingInstanceMutation = false;
}
const factory = this.factory;
const encapsulationSource = this.encapsulationSource;
const lifecycle = Lifecycle.beginAttach(encapsulationSource, LifecycleFlags.none);
i = 0;
sourceExpression.iterate(items, (arr, i, item) => {
let view = views[i];
if (view === undefined) {
// add view if it doesn't exist yet
view = views[i] = factory.create();
view.$bind(flags, createChildScope(overrideContext, { [local]: item }));
view.mount(location);
if (isAttached) {
if (this.$isAttached) {
const { location } = this;
const lifecycle = Lifecycle.beginAttach(this.encapsulationSource, LifecycleFlags.none);
if (indexMap === null) {
for (let i = 0, ii = views.length; i < ii; ++i) {
const view = views[i];
view.mount(location);
lifecycle.attach(view);
}
} else {
// TODO: optimize this again (but in a more efficient way and one that works in multiple scenarios)
view.$bind(flags | BindingFlags.fromBind, createChildScope(overrideContext, { [local]: item }));
for (let i = 0, ii = views.length; i < ii; ++i) {
if (indexMap[i] !== i) {
const view = views[i];
view.mount(location);
lifecycle.attach(view);
}
}
}
});
lifecycle.end();
lifecycle.end();
}
}
private removeAllViews(): void {
const views = this.views;
this.views = [];
const len = views.length;
let i = 0;
const lifecycle = Lifecycle.beginDetach(LifecycleFlags.none);
while (i < len) {
const view = views[i++];
view.release();
lifecycle.detach(view);
private checkCollectionObserver(): void {
const oldObserver = this.observer;
if (this.$isBound) {
const newObserver = this.observer = getCollectionObserver(this.changeSet, this.items);
if (oldObserver !== newObserver) {
if (oldObserver) {
oldObserver.unsubscribeBatched(this);
}
if (newObserver) {
newObserver.subscribeBatched(this);
}
}
} else if (oldObserver) {
oldObserver.unsubscribeBatched(this);
}
lifecycle.end();
}
}
Repeat.prototype.observer = null;
function createChildScope(parentOverrideContext: IOverrideContext, bindingContext: { [key: string]: any }): IScope {
return {
bindingContext,
overrideContext: {
bindingContext,
parentOverrideContext
}
};
}

@@ -1,5 +0,6 @@

import { INode, INodeSequence } from '../dom';
import { TemplatePartDefinitions } from './instructions';
import { IRenderContext } from './render-context';
import { DOM, INode, INodeSequence, NodeSequence } from '../dom';
import { TemplateDefinition, TemplatePartDefinitions } from './instructions';
import { createRenderContext, IRenderContext } from './render-context';
import { IRenderable } from './renderable';
import { IRenderingEngine } from './rendering-engine';

@@ -15,1 +16,33 @@ // The basic template abstraction that allows consumers to create

}
// This is the main implementation of ITemplate.
// It is used to create instances of IView based on a compiled TemplateDefinition.
// TemplateDefinitions are hand-coded today, but will ultimately be the output of the
// TemplateCompiler either through a JIT or AOT process.
// Essentially, CompiledTemplate wraps up the small bit of code that is needed to take a TemplateDefinition
// and create instances of it on demand.
/*@internal*/
export class CompiledTemplate implements ITemplate {
public renderContext: IRenderContext;
private createNodeSequence: () => INodeSequence;
constructor(renderingEngine: IRenderingEngine, parentRenderContext: IRenderContext, private templateDefinition: TemplateDefinition) {
this.renderContext = createRenderContext(renderingEngine, parentRenderContext, templateDefinition.dependencies);
this.createNodeSequence = DOM.createFactoryFromMarkupOrNode(templateDefinition.templateOrNode);
}
public createFor(renderable: IRenderable, host?: INode, replacements?: TemplatePartDefinitions): INodeSequence {
const nodes = this.createNodeSequence();
this.renderContext.render(renderable, nodes.findTargets(), this.templateDefinition, host, replacements);
return nodes;
}
}
// This is an implementation of ITemplate that always returns a node sequence representing "no DOM" to render.
/*@internal*/
export const noViewTemplate: ITemplate = {
renderContext: null,
createFor(renderable: IRenderable): INodeSequence {
return NodeSequence.empty;
}
};

@@ -1,2 +0,2 @@

import { DI } from '@aurelia/kernel';
import { DI, Reporter } from '@aurelia/kernel';
import { IScope } from '../binding/binding-context';

@@ -43,3 +43,2 @@ import { BindingFlags } from '../binding/binding-flags';

public $context: IRenderContext;
private $encapsulationSource: INode;
private location: IRenderLocation;

@@ -54,5 +53,8 @@ private requiresNodeAdd: boolean = false;

public mount(location: IRenderLocation): void {
if (!location.parentNode) { // unmet invariant: location must be a child of some other node
throw Reporter.error(60); // TODO: organize error codes
}
this.location = location;
if (this.$nodes.lastChild.previousSibling !== location) {
if (this.$nodes.lastChild && this.$nodes.lastChild.nextSibling !== location) {
this.requiresNodeAdd = true;

@@ -118,4 +120,2 @@ }

this.$encapsulationSource = encapsulationSource;
const attachables = this.$attachables;

@@ -122,0 +122,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc