Skip to content

Commit

Permalink
refactor(router): implement scope owner and source
Browse files Browse the repository at this point in the history
  • Loading branch information
jwx committed Dec 9, 2019
1 parent 7ba62ef commit 7cf7963
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 14 deletions.
143 changes: 132 additions & 11 deletions packages/router/src/viewport-scope.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { CustomElementType } from '@aurelia/runtime';
import { ComponentAppellation, INavigatorInstruction, IRoute, RouteableComponentType } from './interfaces';
import { FoundRoute } from './found-route';
import { IRouter } from './router';
import { ViewportInstruction } from './viewport-instruction';
import { NavigationInstructionResolver } from './type-resolvers';
import { Viewport, IViewportOptions } from './viewport';
import { IScopeOwner, Scope } from './scope';
import { IScopeOwner, IScopeOwnerOptions, Scope } from './scope';
import { arrayRemove } from './utils';

export interface IViewportScopeOptions {
export interface IViewportScopeOptions extends IScopeOwnerOptions {
catches?: string | string[];
collection?: boolean;
source?: unknown[] | null;
}

Expand All @@ -18,8 +17,14 @@ export class ViewportScope implements IScopeOwner {
public path: string | null = null;

public content: ViewportInstruction | null = null;
public nextContent: ViewportInstruction | null = null;

public available: boolean = true;
public sourceItem: unknown | null = null;
public sourceItemIndex: number = -1;

private remove: boolean = false;
private add: boolean = false;

public constructor(
public name: string,
Expand Down Expand Up @@ -68,15 +73,100 @@ export class ViewportScope implements IScopeOwner {
return this.rootComponentType === null && (this.options.catches === void 0 || this.options.catches.length === 0);
}

public get siblings(): ViewportScope[] {
const parent: Scope | null = this.connectedScope.parent;
if (parent === null) {
return [this];
}
return parent.enabledChildren
.filter(child => child.isViewportScope && child.viewportScope!.name === this.name)
.map(child => child.viewportScope!);
}

public get source(): unknown[] | null {
return this.options.source || null;
// let source: unknown[] | undefined = this.connectedScope!.parent!.childCollections[this.name];
// if (source === void 0) {
// source = [];
// source.push({});
// this.connectedScope.parent!.childCollections[this.name] = source;
// }
// return source;
}

public setNextContent(content: ComponentAppellation | ViewportInstruction, instruction: INavigatorInstruction): boolean {
this.content = content as ViewportInstruction;
let viewportInstruction: ViewportInstruction;
if (content instanceof ViewportInstruction) {
viewportInstruction = content;
} else {
if (typeof content === 'string') {
viewportInstruction = this.router.instructionResolver.parseViewportInstruction(content);
} else {
viewportInstruction = this.router.createViewportInstruction(content);
}
}
viewportInstruction.viewportScope = this;

this.remove = this.router.instructionResolver.isClearViewportInstruction(viewportInstruction)
|| this.router.instructionResolver.isClearAllViewportsInstruction(viewportInstruction);
this.add = this.router.instructionResolver.isAddViewportInstruction(viewportInstruction)
&& Array.isArray(this.source);

if (this.add) {
this.addSourceItem();
}
if (this.remove && Array.isArray(this.source)) {
this.removeSourceItem();
}

this.nextContent = viewportInstruction;
return true;
}

public canLeave(): Promise<boolean> {
return Promise.resolve(true);
}
public canEnter(): Promise<boolean | ViewportInstruction[]> {
return Promise.resolve(true);
}

public enter(): Promise<boolean> {
return Promise.resolve(true);
}

public loadContent(): Promise<boolean> {
this.content = !this.remove ? this.nextContent : null;
this.nextContent = null;

return Promise.resolve(true);
}

public finalizeContentChange(): void {
console.log('ViewportScope finalizing', this.content);
}
public async abortContentChange(): Promise<void> {
this.nextContent = null;
if (this.remove) {
this.source!.splice(this.sourceItemIndex, 0, this.sourceItem);
}
if (this.add) {
const index: number = this.source!.indexOf(this.sourceItem);
this.source!.splice(index, 1);
this.sourceItem = null;
}
}

public acceptSegment(segment: string): boolean {
if (segment === null && segment === void 0 || segment.length === 0) {
return true;
}
let catches = this.options.catches || [];
if (segment === this.router.instructionResolver.clearViewportInstruction
|| segment === this.router.instructionResolver.addViewportInstruction
|| segment === this.name) {
return true;
}

let catches: string | string[] = this.options.catches || [];
if (typeof catches === 'string') {
catches = catches.split(',');
}
Expand All @@ -93,14 +183,45 @@ export class ViewportScope implements IScopeOwner {
return false;
}

public binding(): void {
let source: unknown[] = this.source || [];
if (source.length > 0 && this.sourceItem === null) {
this.sourceItem = this.getAvailableSourceItem();
}
}
public unbinding(): void {
if (this.sourceItem !== null && this.source !== null) {
arrayRemove(this.source!, (item: unknown) => item === this.sourceItem);
}
this.sourceItem = null;
}

public getAvailableSourceItem(): unknown | null {
if (this.source === null) {
return null;
}
const siblings: ViewportScope[] = this.siblings;
for (const item of this.source) {
if (siblings.every(sibling => sibling.sourceItem !== item)) {
return item;
}
}
return null;
}
public addSourceItem(): void {
this.source!.push({ id: Math.max(...this.source!.map(w => (w as any).id)) + 1 });
}
public removeSourceItem(): void {
this.sourceItemIndex = this.source!.indexOf(this.sourceItem);
if (this.sourceItemIndex >= 0) {
this.source!.splice(this.sourceItemIndex, 1);
}
}

public getRoutes(): IRoute[] | null {
if (this.rootComponentType !== null) {
return (this.rootComponentType as RouteableComponentType & { routes: IRoute[] }).routes;
}
return null;
}

public canLeave(): Promise<boolean> {
return Promise.resolve(true);
}
}
5 changes: 2 additions & 3 deletions packages/router/src/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import { IRouter } from './router';
import { arrayRemove } from './utils';
import { ViewportContent } from './viewport-content';
import { ViewportInstruction } from './viewport-instruction';
import { IScopeOwner, Scope } from './scope';
import { IScopeOwner, IScopeOwnerOptions, Scope } from './scope';

export interface IViewportOptions {
export interface IViewportOptions extends IScopeOwnerOptions {
scope?: boolean;
usedBy?: string | string[];
default?: string;
fallback?: string;
noLink?: boolean;
noHistory?: boolean;
stateful?: boolean;
forceDescription?: boolean;
}
Expand Down

0 comments on commit 7cf7963

Please sign in to comment.