Skip to content

Commit

Permalink
feat(life cycle): add life cycle. support promise
Browse files Browse the repository at this point in the history
  • Loading branch information
bigopon committed Jan 18, 2018
1 parent dd6feb2 commit 2f72e12
Show file tree
Hide file tree
Showing 12 changed files with 774 additions and 152 deletions.
32 changes: 28 additions & 4 deletions dist/amd/portal.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { OverrideContext } from 'aurelia-binding';
import { ViewSlot, BoundViewFactory } from 'aurelia-templating';
import { ViewSlot, BoundViewFactory, View } from 'aurelia-templating';
export declare type PortalLifecycleCallback = (target: Element, view: View) => Promise<any> | any;
export declare class Portal {
private viewFactory;
private originalViewslot;
private static getTarget(target);
private static getTarget(target, context?);
/**
* Only needs the BoundViewFactory as a custom viewslot will be used
*/
Expand All @@ -12,17 +13,40 @@ export declare class Portal {
* Target to render to, CSS string | Element
*/
target: string | Element | null | undefined;
renderContext: string | Element | null | undefined;
strict: boolean;
initialRender: boolean;
/**
* Will be called when the attribute receive new target after the first render.
*/
deactivating: PortalLifecycleCallback;
/**
* Will be called after `portaled` element has been added to target
*/
activating: PortalLifecycleCallback;
/**
* Will be called after activating has been resolved
*/
activated: PortalLifecycleCallback;
/**
* Will be called after deactivating has been resolved.
*/
deactivated: PortalLifecycleCallback;
/**
* The object that will becontextwhen calling life cycle methods above
*/
callbackContext: any;
private currentTarget;
private isAttached;
private viewSlot;
private view;
private removed;
constructor(viewFactory: BoundViewFactory, originalViewslot: ViewSlot);
bind(bindingContext: any, overrideContext: OverrideContext): void;
attached(): void;
attached(): Promise<void | null> | undefined;
detached(): void;
unbind(): void;
private getTarget();
private render();
targetChanged(): void;
targetChanged(): Promise<void | null> | undefined;
}
109 changes: 89 additions & 20 deletions dist/amd/portal.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,34 @@ define(["require", "exports", "aurelia-templating", "aurelia-pal"], function (re
this.initialRender = false;
}
Portal_1 = Portal;
Portal.getTarget = function (target) {
Portal.getTarget = function (target, context) {
if (target) {
if (typeof target === 'string') {
target = document.querySelector(target);
var queryContext = document;
if (context) {
if (typeof context === 'string') {
context = document.querySelector(context);
}
if (context instanceof Element) {
queryContext = context;
}
}
target = queryContext.querySelector(target);
}
if (target && (target instanceof Element)) {
if (target instanceof Element) {
return target;
}
}
return null;
};
Portal.prototype.bind = function (bindingContext, overrideContext) {
var view = this.view = this.viewFactory.create();
if (!this.callbackContext) {
this.callbackContext = bindingContext;
}
var view = this.view;
if (!view) {
view = this.view = this.viewFactory.create();
}
var shouldInitRender = this.initialRender;
if (shouldInitRender) {
this.originalViewslot.add(view);
Expand All @@ -40,19 +55,24 @@ define(["require", "exports", "aurelia-templating", "aurelia-pal"], function (re
};
Portal.prototype.attached = function () {
this.isAttached = true;
this.render();
return this.render();
};
Portal.prototype.detached = function () {
this.isAttached = false;
this.view.detached();
if (this.viewSlot) {
this.viewSlot.detached();
}
};
Portal.prototype.unbind = function () {
this.viewSlot.remove(this.view);
if (this.viewSlot) {
this.viewSlot.remove(this.view);
this.viewSlot = null;
}
this.view.unbind();
this.viewSlot = null;
this.callbackContext = null;
};
Portal.prototype.getTarget = function () {
var target = Portal_1.getTarget(this.target);
var target = Portal_1.getTarget(this.target, this.renderContext);
if (target === null) {
if (this.strict) {
throw new Error('Render target not found.');
Expand All @@ -64,23 +84,53 @@ define(["require", "exports", "aurelia-templating", "aurelia-pal"], function (re
return target;
};
Portal.prototype.render = function () {
var _this = this;
var oldTarget = this.currentTarget;
var view = this.view;
var target = this.getTarget();
var target = this.currentTarget = this.getTarget();
var oldViewSlot = this.viewSlot;
if (oldViewSlot) {
oldViewSlot.remove(view);
if (this.isAttached) {
view.detached();
}
if (oldTarget === target && oldViewSlot) {
return;
}
if (this.isAttached) {
var viewSlot = this.viewSlot = new aurelia_templating_1.ViewSlot(target, true);
viewSlot.add(view);
view.attached();
var addAction = function () {
if (_this.isAttached) {
return Promise.resolve(typeof _this.activating === 'function'
? _this.activating.call(_this.callbackContext, target, view)
: null).then(function () {
if (target === _this.currentTarget || oldTarget === unset) {
var viewSlot = _this.viewSlot = new aurelia_templating_1.ViewSlot(target, true);
viewSlot.attached();
viewSlot.add(view);
_this.removed = false;
}
return Promise.resolve().then(function () {
typeof _this.activated === 'function'
? _this.activated.call(_this.callbackContext, target, view)
: null;
});
});
}
return Promise.resolve(null);
};
if (oldViewSlot) {
return Promise.resolve(typeof this.deactivating === 'function'
? this.deactivating.call(this.callbackContext, oldTarget, view)
: null).then(function () {
if (typeof _this.deactivated === 'function') {
_this.deactivated.call(_this.callbackContext, oldTarget, view);
}
_this.viewSlot = null;
if (!_this.removed) {
oldViewSlot.remove(view);
_this.removed = true;
}
return addAction();
});
}
return Promise.resolve(addAction());
};
Portal.prototype.targetChanged = function () {
this.render();
return this.render();
};
/**
* Only needs the BoundViewFactory as a custom viewslot will be used
Expand All @@ -92,12 +142,30 @@ define(["require", "exports", "aurelia-templating", "aurelia-pal"], function (re
defaultValue: null
})
], Portal.prototype, "target", void 0);
__decorate([
aurelia_templating_1.bindable({ changeHandler: 'targetChanged' })
], Portal.prototype, "renderContext", void 0);
__decorate([
aurelia_templating_1.bindable()
], Portal.prototype, "strict", void 0);
__decorate([
aurelia_templating_1.bindable()
], Portal.prototype, "initialRender", void 0);
__decorate([
aurelia_templating_1.bindable()
], Portal.prototype, "deactivating", void 0);
__decorate([
aurelia_templating_1.bindable()
], Portal.prototype, "activating", void 0);
__decorate([
aurelia_templating_1.bindable()
], Portal.prototype, "activated", void 0);
__decorate([
aurelia_templating_1.bindable()
], Portal.prototype, "deactivated", void 0);
__decorate([
aurelia_templating_1.bindable()
], Portal.prototype, "callbackContext", void 0);
Portal = Portal_1 = __decorate([
aurelia_templating_1.templateController(),
aurelia_templating_1.customAttribute('portal')
Expand All @@ -106,4 +174,5 @@ define(["require", "exports", "aurelia-templating", "aurelia-pal"], function (re
var Portal_1;
}());
exports.Portal = Portal;
var unset = {};
});
32 changes: 28 additions & 4 deletions dist/commonjs/portal.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { OverrideContext } from 'aurelia-binding';
import { ViewSlot, BoundViewFactory } from 'aurelia-templating';
import { ViewSlot, BoundViewFactory, View } from 'aurelia-templating';
export declare type PortalLifecycleCallback = (target: Element, view: View) => Promise<any> | any;
export declare class Portal {
private viewFactory;
private originalViewslot;
private static getTarget(target);
private static getTarget(target, context?);
/**
* Only needs the BoundViewFactory as a custom viewslot will be used
*/
Expand All @@ -12,17 +13,40 @@ export declare class Portal {
* Target to render to, CSS string | Element
*/
target: string | Element | null | undefined;
renderContext: string | Element | null | undefined;
strict: boolean;
initialRender: boolean;
/**
* Will be called when the attribute receive new target after the first render.
*/
deactivating: PortalLifecycleCallback;
/**
* Will be called after `portaled` element has been added to target
*/
activating: PortalLifecycleCallback;
/**
* Will be called after activating has been resolved
*/
activated: PortalLifecycleCallback;
/**
* Will be called after deactivating has been resolved.
*/
deactivated: PortalLifecycleCallback;
/**
* The object that will becontextwhen calling life cycle methods above
*/
callbackContext: any;
private currentTarget;
private isAttached;
private viewSlot;
private view;
private removed;
constructor(viewFactory: BoundViewFactory, originalViewslot: ViewSlot);
bind(bindingContext: any, overrideContext: OverrideContext): void;
attached(): void;
attached(): Promise<void | null> | undefined;
detached(): void;
unbind(): void;
private getTarget();
private render();
targetChanged(): void;
targetChanged(): Promise<void | null> | undefined;
}
Loading

0 comments on commit 2f72e12

Please sign in to comment.