repackaging: all the file moves

This commit is contained in:
Igor Minar
2016-04-28 08:02:15 -07:00
committed by Misko Hevery
parent 4fe0f1fa65
commit 505da6c0a8
739 changed files with 0 additions and 52 deletions

View File

@ -0,0 +1,84 @@
import {Directive} from 'angular2/core';
import {Location} from 'angular2/platform/common';
import {isString} from 'angular2/src/facade/lang';
import {Router} from '../router';
import {Instruction} from '../instruction';
/**
* The RouterLink directive lets you link to specific parts of your app.
*
* Consider the following route configuration:
* ```
* @RouteConfig([
* { path: '/user', component: UserCmp, as: 'User' }
* ]);
* class MyComp {}
* ```
*
* When linking to this `User` route, you can write:
*
* ```
* <a [routerLink]="['./User']">link to user component</a>
* ```
*
* RouterLink expects the value to be an array of route names, followed by the params
* for that level of routing. For instance `['/Team', {teamId: 1}, 'User', {userId: 2}]`
* means that we want to generate a link for the `Team` route with params `{teamId: 1}`,
* and with a child route `User` with params `{userId: 2}`.
*
* The first route name should be prepended with `/`, `./`, or `../`.
* If the route begins with `/`, the router will look up the route from the root of the app.
* If the route begins with `./`, the router will instead look in the current component's
* children for the route. And if the route begins with `../`, the router will look at the
* current component's parent.
*/
@Directive({
selector: '[routerLink]',
inputs: ['routeParams: routerLink', 'target: target'],
host: {
'(click)': 'onClick()',
'[attr.href]': 'visibleHref',
'[class.router-link-active]': 'isRouteActive'
}
})
export class RouterLink {
private _routeParams: any[];
// the url displayed on the anchor element.
visibleHref: string;
target: string;
// the instruction passed to the router to navigate
private _navigationInstruction: Instruction;
constructor(private _router: Router, private _location: Location) {
// we need to update the link whenever a route changes to account for aux routes
this._router.subscribe((_) => this._updateLink());
}
// because auxiliary links take existing primary and auxiliary routes into account,
// we need to update the link whenever params or other routes change.
private _updateLink(): void {
this._navigationInstruction = this._router.generate(this._routeParams);
var navigationHref = this._navigationInstruction.toLinkUrl();
this.visibleHref = this._location.prepareExternalUrl(navigationHref);
}
get isRouteActive(): boolean { return this._router.isRouteActive(this._navigationInstruction); }
set routeParams(changes: any[]) {
this._routeParams = changes;
this._updateLink();
}
onClick(): boolean {
// If no target, or if target is _self, prevent default browser behavior
if (!isString(this.target) || this.target == '_self') {
this._router.navigateByInstruction(this._navigationInstruction);
return false;
}
return true;
}
}

View File

@ -0,0 +1,218 @@
import {
TemplateAstVisitor,
ElementAst,
BoundDirectivePropertyAst,
DirectiveAst,
BoundElementPropertyAst
} from 'angular2/compiler';
import {
AstTransformer,
Quote,
AST,
EmptyExpr,
LiteralArray,
LiteralPrimitive,
ASTWithSource
} from 'angular2/src/compiler/expression_parser/ast';
import {BaseException} from 'angular2/src/facade/exceptions';
import {Injectable} from 'angular2/core';
import {Parser} from 'angular2/src/compiler/expression_parser/parser';
/**
* e.g., './User', 'Modal' in ./User[Modal(param: value)]
*/
class FixedPart {
constructor(public value: string) {}
}
/**
* The square bracket
*/
class AuxiliaryStart {
constructor() {}
}
/**
* The square bracket
*/
class AuxiliaryEnd {
constructor() {}
}
/**
* e.g., param:value in ./User[Modal(param: value)]
*/
class Params {
constructor(public ast: AST) {}
}
class RouterLinkLexer {
index: number = 0;
constructor(private parser: Parser, private exp: string) {}
tokenize(): Array<FixedPart | AuxiliaryStart | AuxiliaryEnd | Params> {
let tokens = [];
while (this.index < this.exp.length) {
tokens.push(this._parseToken());
}
return tokens;
}
private _parseToken() {
let c = this.exp[this.index];
if (c == '[') {
this.index++;
return new AuxiliaryStart();
} else if (c == ']') {
this.index++;
return new AuxiliaryEnd();
} else if (c == '(') {
return this._parseParams();
} else if (c == '/' && this.index !== 0) {
this.index++;
return this._parseFixedPart();
} else {
return this._parseFixedPart();
}
}
private _parseParams() {
let start = this.index;
for (; this.index < this.exp.length; ++this.index) {
let c = this.exp[this.index];
if (c == ')') {
let paramsContent = this.exp.substring(start + 1, this.index);
this.index++;
return new Params(this.parser.parseBinding(`{${paramsContent}}`, null).ast);
}
}
throw new BaseException("Cannot find ')'");
}
private _parseFixedPart() {
let start = this.index;
let sawNonSlash = false;
for (; this.index < this.exp.length; ++this.index) {
let c = this.exp[this.index];
if (c == '(' || c == '[' || c == ']' || (c == '/' && sawNonSlash)) {
break;
}
if (c != '.' && c != '/') {
sawNonSlash = true;
}
}
let fixed = this.exp.substring(start, this.index);
if (start === this.index || !sawNonSlash || fixed.startsWith('//')) {
throw new BaseException("Invalid router link");
}
return new FixedPart(fixed);
}
}
class RouterLinkAstGenerator {
index: number = 0;
constructor(private tokens: any[]) {}
generate(): AST { return this._genAuxiliary(); }
private _genAuxiliary(): AST {
let arr = [];
for (; this.index < this.tokens.length; this.index++) {
let r = this.tokens[this.index];
if (r instanceof FixedPart) {
arr.push(new LiteralPrimitive(r.value));
} else if (r instanceof Params) {
arr.push(r.ast);
} else if (r instanceof AuxiliaryEnd) {
break;
} else if (r instanceof AuxiliaryStart) {
this.index++;
arr.push(this._genAuxiliary());
}
}
return new LiteralArray(arr);
}
}
class RouterLinkAstTransformer extends AstTransformer {
constructor(private parser: Parser) { super(); }
visitQuote(ast: Quote, context: any): AST {
if (ast.prefix == "route") {
return parseRouterLinkExpression(this.parser, ast.uninterpretedExpression);
} else {
return super.visitQuote(ast, context);
}
}
}
export function parseRouterLinkExpression(parser: Parser, exp: string): AST {
let tokens = new RouterLinkLexer(parser, exp.trim()).tokenize();
return new RouterLinkAstGenerator(tokens).generate();
}
/**
* A compiler plugin that implements the router link DSL.
*/
@Injectable()
export class RouterLinkTransform implements TemplateAstVisitor {
private astTransformer;
constructor(parser: Parser) { this.astTransformer = new RouterLinkAstTransformer(parser); }
visitNgContent(ast: any, context: any): any { return ast; }
visitEmbeddedTemplate(ast: any, context: any): any { return ast; }
visitElement(ast: ElementAst, context: any): any {
let updatedChildren = ast.children.map(c => c.visit(this, context));
let updatedInputs = ast.inputs.map(c => c.visit(this, context));
let updatedDirectives = ast.directives.map(c => c.visit(this, context));
return new ElementAst(ast.name, ast.attrs, updatedInputs, ast.outputs, ast.references,
updatedDirectives, ast.providers, ast.hasViewContainer, updatedChildren,
ast.ngContentIndex, ast.sourceSpan);
}
visitReference(ast: any, context: any): any { return ast; }
visitVariable(ast: any, context: any): any { return ast; }
visitEvent(ast: any, context: any): any { return ast; }
visitElementProperty(ast: any, context: any): any { return ast; }
visitAttr(ast: any, context: any): any { return ast; }
visitBoundText(ast: any, context: any): any { return ast; }
visitText(ast: any, context: any): any { return ast; }
visitDirective(ast: DirectiveAst, context: any): any {
let updatedInputs = ast.inputs.map(c => c.visit(this, context));
return new DirectiveAst(ast.directive, updatedInputs, ast.hostProperties, ast.hostEvents,
ast.sourceSpan);
}
visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any {
let transformedValue = ast.value.visit(this.astTransformer);
return new BoundDirectivePropertyAst(ast.directiveName, ast.templateName, transformedValue,
ast.sourceSpan);
}
}

View File

@ -0,0 +1,178 @@
import {PromiseWrapper, EventEmitter} from 'angular2/src/facade/async';
import {StringMapWrapper} from 'angular2/src/facade/collection';
import {isBlank, isPresent} from 'angular2/src/facade/lang';
import {
Directive,
Attribute,
DynamicComponentLoader,
ComponentRef,
ViewContainerRef,
provide,
ReflectiveInjector,
OnDestroy,
Output
} from 'angular2/core';
import * as routerMod from '../router';
import {ComponentInstruction, RouteParams, RouteData} from '../instruction';
import * as hookMod from '../lifecycle/lifecycle_annotations';
import {hasLifecycleHook} from '../lifecycle/route_lifecycle_reflector';
import {OnActivate, CanReuse, OnReuse, OnDeactivate, CanDeactivate} from '../interfaces';
let _resolveToTrue = PromiseWrapper.resolve(true);
/**
* A router outlet is a placeholder that Angular dynamically fills based on the application's route.
*
* ## Use
*
* ```
* <router-outlet></router-outlet>
* ```
*/
@Directive({selector: 'router-outlet'})
export class RouterOutlet implements OnDestroy {
name: string = null;
private _componentRef: Promise<ComponentRef<any>> = null;
private _currentInstruction: ComponentInstruction = null;
@Output('activate') public activateEvents = new EventEmitter<any>();
constructor(private _viewContainerRef: ViewContainerRef, private _loader: DynamicComponentLoader,
private _parentRouter: routerMod.Router, @Attribute('name') nameAttr: string) {
if (isPresent(nameAttr)) {
this.name = nameAttr;
this._parentRouter.registerAuxOutlet(this);
} else {
this._parentRouter.registerPrimaryOutlet(this);
}
}
/**
* Called by the Router to instantiate a new component during the commit phase of a navigation.
* This method in turn is responsible for calling the `routerOnActivate` hook of its child.
*/
activate(nextInstruction: ComponentInstruction): Promise<any> {
var previousInstruction = this._currentInstruction;
this._currentInstruction = nextInstruction;
var componentType = nextInstruction.componentType;
var childRouter = this._parentRouter.childRouter(componentType);
var providers = ReflectiveInjector.resolve([
provide(RouteData, {useValue: nextInstruction.routeData}),
provide(RouteParams, {useValue: new RouteParams(nextInstruction.params)}),
provide(routerMod.Router, {useValue: childRouter})
]);
this._componentRef =
this._loader.loadNextToLocation(componentType, this._viewContainerRef, providers);
return this._componentRef.then((componentRef) => {
this.activateEvents.emit(componentRef.instance);
if (hasLifecycleHook(hookMod.routerOnActivate, componentType)) {
return this._componentRef.then(
(ref: ComponentRef<any>) =>
(<OnActivate>ref.instance).routerOnActivate(nextInstruction, previousInstruction));
} else {
return componentRef;
}
});
}
/**
* Called by the {@link Router} during the commit phase of a navigation when an outlet
* reuses a component between different routes.
* This method in turn is responsible for calling the `routerOnReuse` hook of its child.
*/
reuse(nextInstruction: ComponentInstruction): Promise<any> {
var previousInstruction = this._currentInstruction;
this._currentInstruction = nextInstruction;
// it's possible the component is removed before it can be reactivated (if nested withing
// another dynamically loaded component, for instance). In that case, we simply activate
// a new one.
if (isBlank(this._componentRef)) {
return this.activate(nextInstruction);
} else {
return PromiseWrapper.resolve(
hasLifecycleHook(hookMod.routerOnReuse, this._currentInstruction.componentType) ?
this._componentRef.then(
(ref: ComponentRef<any>) =>
(<OnReuse>ref.instance).routerOnReuse(nextInstruction, previousInstruction)) :
true);
}
}
/**
* Called by the {@link Router} when an outlet disposes of a component's contents.
* This method in turn is responsible for calling the `routerOnDeactivate` hook of its child.
*/
deactivate(nextInstruction: ComponentInstruction): Promise<any> {
var next = _resolveToTrue;
if (isPresent(this._componentRef) && isPresent(this._currentInstruction) &&
hasLifecycleHook(hookMod.routerOnDeactivate, this._currentInstruction.componentType)) {
next = this._componentRef.then(
(ref: ComponentRef<any>) =>
(<OnDeactivate>ref.instance)
.routerOnDeactivate(nextInstruction, this._currentInstruction));
}
return next.then((_) => {
if (isPresent(this._componentRef)) {
var onDispose = this._componentRef.then((ref: ComponentRef<any>) => ref.destroy());
this._componentRef = null;
return onDispose;
}
});
}
/**
* Called by the {@link Router} during recognition phase of a navigation.
*
* If this resolves to `false`, the given navigation is cancelled.
*
* This method delegates to the child component's `routerCanDeactivate` hook if it exists,
* and otherwise resolves to true.
*/
routerCanDeactivate(nextInstruction: ComponentInstruction): Promise<boolean> {
if (isBlank(this._currentInstruction)) {
return _resolveToTrue;
}
if (hasLifecycleHook(hookMod.routerCanDeactivate, this._currentInstruction.componentType)) {
return this._componentRef.then(
(ref: ComponentRef<any>) =>
(<CanDeactivate>ref.instance)
.routerCanDeactivate(nextInstruction, this._currentInstruction));
} else {
return _resolveToTrue;
}
}
/**
* Called by the {@link Router} during recognition phase of a navigation.
*
* If the new child component has a different Type than the existing child component,
* this will resolve to `false`. You can't reuse an old component when the new component
* is of a different Type.
*
* Otherwise, this method delegates to the child component's `routerCanReuse` hook if it exists,
* or resolves to true if the hook is not present.
*/
routerCanReuse(nextInstruction: ComponentInstruction): Promise<boolean> {
var result;
if (isBlank(this._currentInstruction) ||
this._currentInstruction.componentType != nextInstruction.componentType) {
result = false;
} else if (hasLifecycleHook(hookMod.routerCanReuse, this._currentInstruction.componentType)) {
result = this._componentRef.then(
(ref: ComponentRef<any>) =>
(<CanReuse>ref.instance).routerCanReuse(nextInstruction, this._currentInstruction));
} else {
result = nextInstruction == this._currentInstruction ||
(isPresent(nextInstruction.params) && isPresent(this._currentInstruction.params) &&
StringMapWrapper.equals(nextInstruction.params, this._currentInstruction.params));
}
return <Promise<boolean>>PromiseWrapper.resolve(result);
}
ngOnDestroy(): void { this._parentRouter.unregisterPrimaryOutlet(this); }
}