aurelia-templating
Version:
An extensible HTML templating engine supporting databinding, custom elements, attached behaviors and more.
114 lines (99 loc) • 2.83 kB
text/typescript
/**
* A mechanism by which an enlisted async render operation can notify the owning transaction when its work is done.
*/
export class CompositionTransactionNotifier {
/** @internal */
private owner: CompositionTransaction;
constructor(owner) {
this.owner = owner;
this.owner._compositionCount++;
}
/**
* Notifies the owning transaction that its work is done.
*/
done(): void {
this.owner._compositionCount--;
this.owner._tryCompleteTransaction();
}
}
/**
* Referenced by the subsytem which wishes to control a composition transaction.
*/
export class CompositionTransactionOwnershipToken {
/** @internal */
owner: CompositionTransaction;
/** @internal */
thenable: Promise<void>;
constructor(owner) {
this.owner = owner;
this.owner._ownershipToken = this;
this.thenable = this._createThenable();
}
/**
* Allows the transaction owner to wait for the completion of all child compositions.
* @return A promise that resolves when all child compositions are done.
*/
waitForCompositionComplete(): Promise<void> {
this.owner._tryCompleteTransaction();
return this.thenable;
}
/**
* Used internall to resolve the composition complete promise.
*/
resolve(): void {
this._resolveCallback();
}
/** @internal */
_resolveCallback() {
throw new Error("Method not implemented.");
}
/** @internal */
_createThenable() {
return new Promise<void>((resolve) => {
this._resolveCallback = resolve;
});
}
}
/**
* Enables an initiator of a view composition to track any internal async rendering processes for completion.
*/
export class CompositionTransaction {
/** @internal */
_ownershipToken: any;
/** @internal */
_compositionCount: number;
/**
* Creates an instance of CompositionTransaction.
*/
constructor() {
this._ownershipToken = null;
this._compositionCount = 0;
}
/**
* Attempt to take ownership of the composition transaction.
* @return An ownership token if successful, otherwise null.
*/
tryCapture(): CompositionTransactionOwnershipToken {
return this._ownershipToken === null
? new CompositionTransactionOwnershipToken(this)
: null;
}
/**
* Enlist an async render operation into the transaction.
* @return A completion notifier.
*/
enlist(): CompositionTransactionNotifier {
return new CompositionTransactionNotifier(this);
}
/** @internal */
_tryCompleteTransaction() {
if (this._compositionCount <= 0) {
this._compositionCount = 0;
if (this._ownershipToken !== null) {
let token = this._ownershipToken;
this._ownershipToken = null;
token.resolve();
}
}
}
}