From f438de611c9221342e7ed2d0eefb58a18f9cbe70 Mon Sep 17 00:00:00 2001 From: Martin Hochel Date: Thu, 16 Jun 2016 23:17:08 +0200 Subject: [PATCH] feat(core/directives): add moduleId support for ComponentMetadata Closes #96 --- src/core/directives/decorators.ts | 2 + src/core/directives/directive_provider.ts | 3 +- src/core/directives/metadata_directives.ts | 20 ++++---- src/core/linker/directive_resolver.ts | 21 ++++++++- test/core/linker/directive_resolver.spec.ts | 52 +++++++++++++++++++++ 5 files changed, 87 insertions(+), 11 deletions(-) diff --git a/src/core/directives/decorators.ts b/src/core/directives/decorators.ts index f419ae5..7ae2db6 100644 --- a/src/core/directives/decorators.ts +++ b/src/core/directives/decorators.ts @@ -80,6 +80,7 @@ export interface ComponentMetadataFactory { host?: {[key: string]: string}, providers?: any[], exportAs?: string, + moduleId?: string, queries?: {[key: string]: any}, viewProviders?: any[], changeDetection?: ChangeDetectionStrategy, @@ -99,6 +100,7 @@ export interface ComponentMetadataFactory { host?: {[key: string]: string}, providers?: any[], exportAs?: string, + moduleId?: string, queries?: {[key: string]: any}, viewProviders?: any[], changeDetection?: ChangeDetectionStrategy, diff --git a/src/core/directives/directive_provider.ts b/src/core/directives/directive_provider.ts index 1d9da69..50f21e3 100644 --- a/src/core/directives/directive_provider.ts +++ b/src/core/directives/directive_provider.ts @@ -83,6 +83,7 @@ export class DirectiveProvider { // specific DDO augmentation for @Component if ( metadata instanceof ComponentMetadata ) { + const assetsPath = this.directiveResolver.parseAssetUrl( metadata ); const componentSpecificDDO = { scope: {}, bindToController: {}, @@ -97,7 +98,7 @@ export class DirectiveProvider { componentSpecificDDO.template = metadata.template; } if ( metadata.templateUrl ) { - componentSpecificDDO.templateUrl = metadata.templateUrl; + componentSpecificDDO.templateUrl = `${assetsPath}${metadata.templateUrl}`; } StringMapWrapper.assign( _ddo, componentSpecificDDO ); diff --git a/src/core/directives/metadata_directives.ts b/src/core/directives/metadata_directives.ts index 601e2ca..72a3f9b 100644 --- a/src/core/directives/metadata_directives.ts +++ b/src/core/directives/metadata_directives.ts @@ -918,21 +918,21 @@ export class ComponentMetadata extends DirectiveMetadata { /** * The module id of the module that contains the component. * Needed to be able to resolve relative urls for templates and styles. - * In Dart, this can be determined automatically and does not need to be set. - * In CommonJS, this can always be set to `module.id`. + * In CommonJS, this can always be set to `module.id`, similarly SystemJS exposes `__moduleName` + * variable within each module. * * ## Simple Example * * ``` - * @Directive({ - * selector: 'someDir', - * moduleId: module.id + * @Component({ + * selector: 'my-hello', + * moduleId: module.id, + * templateUrl: './my-hello.component.ts * }) - * class SomeDir { - * } - * + * class MyHelloComponent {} * ``` */ + moduleId: string; templateUrl: string; template: string; @@ -942,7 +942,7 @@ export class ComponentMetadata extends DirectiveMetadata { pipes: Array; constructor({ - selector, inputs, attrs, outputs, host, exportAs, providers, viewProviders, + selector, inputs, attrs, outputs, host, exportAs, moduleId, providers, viewProviders, changeDetection = ChangeDetectionStrategy.Default, queries, templateUrl, template, styleUrls, styles, directives, pipes, legacy }: { @@ -953,6 +953,7 @@ export class ComponentMetadata extends DirectiveMetadata { host?: {[key: string]: string}, providers?: any[], exportAs?: string, + moduleId?: string, viewProviders?: any[], changeDetection?: ChangeDetectionStrategy, queries?: {[key: string]: any}, @@ -984,6 +985,7 @@ export class ComponentMetadata extends DirectiveMetadata { this.styles = styles; this.directives = directives; this.pipes = pipes; + this.moduleId = moduleId; } } diff --git a/src/core/linker/directive_resolver.ts b/src/core/linker/directive_resolver.ts index de41bcd..f0df4a7 100644 --- a/src/core/linker/directive_resolver.ts +++ b/src/core/linker/directive_resolver.ts @@ -1,4 +1,4 @@ -import { Type, isPresent, stringify, assign, isType, getFuncName } from '../../facade/lang'; +import { Type, isPresent, stringify, assign, isType, getFuncName, isBlank } from '../../facade/lang'; import { StringMapWrapper, ListWrapper } from '../../facade/collections'; import { reflector } from '../reflection/reflection'; import { @@ -22,6 +22,12 @@ import { resolveForwardRef } from '../di/forward_ref'; import { getErrorMsg } from '../../facade/exceptions'; import { ChangeDetectionStrategy } from '../change_detection/constants'; + +// asset:// +// var _ASSET_URL_RE = /asset:([^\/]+)\/([^\/]+)\/(.+)/g; +// /filename.js +const ASSET_URL_RE = /^(.+)\/.+\.js$/; + function _isDirectiveMetadata( type: any ): boolean { return type instanceof DirectiveMetadata; } @@ -217,6 +223,18 @@ export class DirectiveResolver { } + parseAssetUrl( cmpMetadata: ComponentMetadata ): string { + + if ( isBlank( cmpMetadata.moduleId ) ) { + return ''; + } + + const moduleId = cmpMetadata.moduleId; + const [,urlPathMatch=''] = moduleId.match( ASSET_URL_RE ) || []; + return `${urlPathMatch}/`; + + } + /** * * @param type @@ -373,6 +391,7 @@ export class DirectiveResolver { {}, directiveSettings as ComponentMetadata, { + moduleId: dm.moduleId, template: dm.template, templateUrl: dm.templateUrl, changeDetection: isPresent(dm.changeDetection) ? dm.changeDetection : ChangeDetectionStrategy.Default diff --git a/test/core/linker/directive_resolver.spec.ts b/test/core/linker/directive_resolver.spec.ts index b0a5a65..cb5e8e6 100644 --- a/test/core/linker/directive_resolver.spec.ts +++ b/test/core/linker/directive_resolver.spec.ts @@ -391,5 +391,57 @@ describe( `linker/directive_resolver`, ()=> { } ); + describe( `#componentModuleUrl`, () => { + + const resolver = new DirectiveResolver(); + + function getComponentMetadata( modulePath: string ) { + @Component( { + selector: 'test', + moduleId: modulePath, + template: '...' + } ) + class TestComponent { + } + + return resolver.resolve( TestComponent ) as ComponentMetadata; + } + + it( `should properly resolve module path`, () => { + + let metadata = getComponentMetadata( 'app/foo/bar/test.component.js' ); + let absolutePath = resolver.parseAssetUrl( metadata ); + + expect( absolutePath ).to.equal( 'app/foo/bar/' ); + + metadata = getComponentMetadata( 'https://foo-bar.com/foo/bar/test.js' ); + absolutePath = resolver.parseAssetUrl( metadata ); + + expect( absolutePath ).to.equal( 'https://foo-bar.com/foo/bar/' ); + + metadata = getComponentMetadata( 'test.js' ); + absolutePath = resolver.parseAssetUrl( metadata ); + + expect( absolutePath ).to.equal( '/' ); + + metadata = getComponentMetadata( '/test.js' ); + absolutePath = resolver.parseAssetUrl( metadata ); + + expect( absolutePath ).to.equal( '/' ); + + metadata = getComponentMetadata( '/app/test.js' ); + absolutePath = resolver.parseAssetUrl( metadata ); + + expect( absolutePath ).to.equal( '/app/' ); + + metadata = getComponentMetadata( 'https://foo-bar.com/foo?q=123/bar.js' ); + absolutePath = resolver.parseAssetUrl( metadata ); + + expect( absolutePath ).to.equal( 'https://foo-bar.com/foo?q=123/' ); + + } ); + + } ); + } );