feat(i18n): extract messages
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
<div [attr.array]="[0]" [attr.map]="{a:1}">{{ctxProp}}</div>
|
<div [attr.array]="[0]" [attr.map]="{a:1}" title="translate me" i18n-title="meaning|desc">{{ctxProp}}</div>
|
||||||
<form><input type="button" [(ngModel)]="ctxProp"/></form>
|
<form><input type="button" [(ngModel)]="ctxProp"/></form>
|
||||||
<my-comp *ngIf="ctxBool"></my-comp>
|
<my-comp *ngIf="ctxBool"></my-comp>
|
||||||
<div *ngFor="let x of ctxArr" [attr.value]="x"></div>
|
<div *ngFor="let x of ctxArr" [attr.value]="x"></div>
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
// Only needed to satisfy the check in core/src/util/decorators.ts
|
||||||
|
// TODO(alexeagle): maybe remove that check?
|
||||||
|
require('reflect-metadata');
|
||||||
|
|
||||||
|
require('@angular/platform-server/src/parse5_adapter.js').Parse5DomAdapter.makeCurrent();
|
||||||
|
require('zone.js/dist/zone-node.js');
|
||||||
|
require('zone.js/dist/long-stack-trace-zone.js');
|
||||||
|
let serializer = require('@angular/compiler/src/i18n/xmb_serializer.js');
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
describe("template i18n extraction output", () => {
|
||||||
|
const outDir = '';
|
||||||
|
|
||||||
|
it("should extract i18n messages", () => {
|
||||||
|
const xmbOutput = path.join(outDir, 'messages.xmb');
|
||||||
|
expect(fs.existsSync(xmbOutput)).toBeTruthy();
|
||||||
|
const xmb = fs.readFileSync(xmbOutput, {encoding: 'utf-8'});
|
||||||
|
const res = serializer.deserializeXmb(xmb);
|
||||||
|
const keys = Object.keys(res.messages);
|
||||||
|
expect(keys.length).toEqual(1);
|
||||||
|
expect(res.errors.length).toEqual(0);
|
||||||
|
expect(res.messages[keys[0]][0].value).toEqual('translate me');
|
||||||
|
});
|
||||||
|
});
|
@ -5,7 +5,8 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"typings": "index.d.ts",
|
"typings": "index.d.ts",
|
||||||
"bin": {
|
"bin": {
|
||||||
"ngc": "./src/main.js"
|
"ngc": "./src/main.js",
|
||||||
|
"ng-xi18n": "./src/extract_i18n.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/tsc-wrapped": "^0.1.0",
|
"@angular/tsc-wrapped": "^0.1.0",
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import {__compiler_private__ as _c} from '@angular/compiler';
|
import {__compiler_private__ as _c} from '@angular/compiler';
|
||||||
|
|
||||||
export var AssetUrl: typeof _c.AssetUrl = _c.AssetUrl;
|
|
||||||
export type AssetUrl = _c.AssetUrl;
|
export type AssetUrl = _c.AssetUrl;
|
||||||
|
export var AssetUrl: typeof _c.AssetUrl = _c.AssetUrl;
|
||||||
|
|
||||||
export var ImportGenerator: typeof _c.ImportGenerator = _c.ImportGenerator;
|
|
||||||
export type ImportGenerator = _c.ImportGenerator;
|
export type ImportGenerator = _c.ImportGenerator;
|
||||||
|
export var ImportGenerator: typeof _c.ImportGenerator = _c.ImportGenerator;
|
||||||
|
|
||||||
export type CompileMetadataResolver = _c.CompileMetadataResolver;
|
export type CompileMetadataResolver = _c.CompileMetadataResolver;
|
||||||
export var CompileMetadataResolver: typeof _c.CompileMetadataResolver = _c.CompileMetadataResolver;
|
export var CompileMetadataResolver: typeof _c.CompileMetadataResolver = _c.CompileMetadataResolver;
|
||||||
@ -12,6 +12,25 @@ export var CompileMetadataResolver: typeof _c.CompileMetadataResolver = _c.Compi
|
|||||||
export type HtmlParser = _c.HtmlParser;
|
export type HtmlParser = _c.HtmlParser;
|
||||||
export var HtmlParser: typeof _c.HtmlParser = _c.HtmlParser;
|
export var HtmlParser: typeof _c.HtmlParser = _c.HtmlParser;
|
||||||
|
|
||||||
|
export type I18nHtmlParser = _c.I18nHtmlParser;
|
||||||
|
export var I18nHtmlParser: typeof _c.I18nHtmlParser = _c.I18nHtmlParser;
|
||||||
|
|
||||||
|
export type MessageExtractor = _c.MessageExtractor;
|
||||||
|
export var MessageExtractor: typeof _c.MessageExtractor = _c.MessageExtractor;
|
||||||
|
|
||||||
|
export type ExtractionResult = _c.ExtractionResult;
|
||||||
|
export var ExtractionResult: typeof _c.ExtractionResult = _c.ExtractionResult;
|
||||||
|
|
||||||
|
export type Message = _c.Message;
|
||||||
|
export var Message: typeof _c.Message = _c.Message;
|
||||||
|
|
||||||
|
export var removeDuplicates: typeof _c.removeDuplicates = _c.removeDuplicates;
|
||||||
|
export var serializeXmb: typeof _c.serializeXmb = _c.serializeXmb;
|
||||||
|
export var deserializeXmb: typeof _c.deserializeXmb = _c.deserializeXmb;
|
||||||
|
|
||||||
|
export type ParseError = _c.ParseError;
|
||||||
|
export var ParseError: typeof _c.ParseError = _c.ParseError;
|
||||||
|
|
||||||
export type DirectiveNormalizer = _c.DirectiveNormalizer;
|
export type DirectiveNormalizer = _c.DirectiveNormalizer;
|
||||||
export var DirectiveNormalizer: typeof _c.DirectiveNormalizer = _c.DirectiveNormalizer;
|
export var DirectiveNormalizer: typeof _c.DirectiveNormalizer = _c.DirectiveNormalizer;
|
||||||
|
|
||||||
|
190
modules/@angular/compiler-cli/src/extract_i18n.ts
Normal file
190
modules/@angular/compiler-cli/src/extract_i18n.ts
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract i18n messages from source code
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Must be imported first, because angular2 decorators throws on load.
|
||||||
|
import 'reflect-metadata';
|
||||||
|
|
||||||
|
import * as ts from 'typescript';
|
||||||
|
import * as tsc from '@angular/tsc-wrapped';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as compiler from '@angular/compiler';
|
||||||
|
|
||||||
|
import {StaticReflector} from './static_reflector';
|
||||||
|
import {
|
||||||
|
CompileMetadataResolver,
|
||||||
|
HtmlParser,
|
||||||
|
DirectiveNormalizer,
|
||||||
|
Lexer,
|
||||||
|
Parser,
|
||||||
|
TemplateParser,
|
||||||
|
DomElementSchemaRegistry,
|
||||||
|
StyleCompiler,
|
||||||
|
ViewCompiler,
|
||||||
|
TypeScriptEmitter,
|
||||||
|
MessageExtractor,
|
||||||
|
removeDuplicates,
|
||||||
|
ExtractionResult,
|
||||||
|
Message,
|
||||||
|
ParseError,
|
||||||
|
serializeXmb,
|
||||||
|
} from './compiler_private';
|
||||||
|
|
||||||
|
import {Parse5DomAdapter} from '@angular/platform-server';
|
||||||
|
|
||||||
|
import {NodeReflectorHost} from './reflector_host';
|
||||||
|
import {StaticAndDynamicReflectionCapabilities} from './static_reflection_capabilities';
|
||||||
|
|
||||||
|
|
||||||
|
function extract(ngOptions: tsc.AngularCompilerOptions, program: ts.Program, host: ts.CompilerHost) {
|
||||||
|
return Extractor.create(ngOptions, program, host).extract();
|
||||||
|
}
|
||||||
|
|
||||||
|
const GENERATED_FILES = /\.ngfactory\.ts$|\.css\.ts$|\.css\.shim\.ts$/;
|
||||||
|
|
||||||
|
class Extractor {
|
||||||
|
constructor(private options: tsc.AngularCompilerOptions,
|
||||||
|
private program: ts.Program, public host: ts.CompilerHost,
|
||||||
|
private staticReflector: StaticReflector, private resolver: CompileMetadataResolver,
|
||||||
|
private compiler: compiler.OfflineCompiler,
|
||||||
|
private reflectorHost: NodeReflectorHost, private _extractor: MessageExtractor) {}
|
||||||
|
|
||||||
|
private extractCmpMessages(metadatas: compiler.CompileDirectiveMetadata[]): Promise<ExtractionResult> {
|
||||||
|
if (!metadatas || !metadatas.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalize = (metadata: compiler.CompileDirectiveMetadata) => {
|
||||||
|
const directiveType = metadata.type.runtime;
|
||||||
|
const directives = this.resolver.getViewDirectivesMetadata(directiveType);
|
||||||
|
return Promise.all(directives.map(d => this.compiler.normalizeDirectiveMetadata(d)))
|
||||||
|
.then(normalizedDirectives => {
|
||||||
|
const pipes = this.resolver.getViewPipesMetadata(directiveType);
|
||||||
|
return new compiler.NormalizedComponentWithViewDirectives(metadata,
|
||||||
|
normalizedDirectives, pipes);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise
|
||||||
|
.all(metadatas.map(normalize))
|
||||||
|
.then((cmps: compiler.NormalizedComponentWithViewDirectives[]) => {
|
||||||
|
let messages: Message[] = [];
|
||||||
|
let errors: ParseError[] = [];
|
||||||
|
cmps.forEach(cmp => {
|
||||||
|
// TODO(vicb): url
|
||||||
|
let result = this._extractor.extract(cmp.component.template.template, "url");
|
||||||
|
errors = errors.concat(result.errors);
|
||||||
|
messages = messages.concat(result.messages);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Extraction Result might contain duplicate messages at this point
|
||||||
|
return new ExtractionResult(messages, errors);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private readComponents(absSourcePath: string) {
|
||||||
|
const result: Promise<compiler.CompileDirectiveMetadata>[] = [];
|
||||||
|
const metadata = this.staticReflector.getModuleMetadata(absSourcePath);
|
||||||
|
if (!metadata) {
|
||||||
|
console.log(`WARNING: no metadata found for ${absSourcePath}`);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const symbols = Object.keys(metadata['metadata']);
|
||||||
|
if (!symbols || !symbols.length) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (const symbol of symbols) {
|
||||||
|
const staticType = this.reflectorHost.findDeclaration(absSourcePath, symbol, absSourcePath);
|
||||||
|
let directive: compiler.CompileDirectiveMetadata;
|
||||||
|
directive = this.resolver.maybeGetDirectiveMetadata(<any>staticType);
|
||||||
|
|
||||||
|
if (!directive || !directive.isComponent) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.push(this.compiler.normalizeDirectiveMetadata(directive));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
extract(): Promise<any> {
|
||||||
|
Parse5DomAdapter.makeCurrent();
|
||||||
|
|
||||||
|
const promises = this.program.getSourceFiles()
|
||||||
|
.map(sf => sf.fileName)
|
||||||
|
.filter(f => !GENERATED_FILES.test(f))
|
||||||
|
.map((absSourcePath:string): Promise<any> =>
|
||||||
|
Promise
|
||||||
|
.all(this.readComponents(absSourcePath))
|
||||||
|
.then(metadatas => this.extractCmpMessages(metadatas))
|
||||||
|
.catch(e => console.error(e.stack))
|
||||||
|
);
|
||||||
|
|
||||||
|
let messages: Message[] = [];
|
||||||
|
let errors: ParseError[] = [];
|
||||||
|
|
||||||
|
return Promise.all(promises)
|
||||||
|
.then(extractionResults => {
|
||||||
|
extractionResults
|
||||||
|
.filter(result => !!result)
|
||||||
|
.forEach(result => {
|
||||||
|
messages = messages.concat(result.messages);
|
||||||
|
errors = errors.concat(result.errors);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
throw errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
messages = removeDuplicates(messages);
|
||||||
|
|
||||||
|
let genPath = path.join(this.options.genDir, 'messages.xmb');
|
||||||
|
let msgBundle = serializeXmb(messages);
|
||||||
|
|
||||||
|
this.host.writeFile(genPath, msgBundle, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static create(options: tsc.AngularCompilerOptions, program: ts.Program,
|
||||||
|
compilerHost: ts.CompilerHost): Extractor {
|
||||||
|
const xhr: compiler.XHR = {get: (s: string) => Promise.resolve(compilerHost.readFile(s))};
|
||||||
|
const urlResolver: compiler.UrlResolver = compiler.createOfflineCompileUrlResolver();
|
||||||
|
const reflectorHost = new NodeReflectorHost(program, compilerHost, options);
|
||||||
|
const staticReflector = new StaticReflector(reflectorHost);
|
||||||
|
StaticAndDynamicReflectionCapabilities.install(staticReflector);
|
||||||
|
const htmlParser = new HtmlParser();
|
||||||
|
const config = new compiler.CompilerConfig(true, true, true);
|
||||||
|
const normalizer = new DirectiveNormalizer(xhr, urlResolver, htmlParser, config);
|
||||||
|
const parser = new Parser(new Lexer());
|
||||||
|
const tmplParser = new TemplateParser(parser, new DomElementSchemaRegistry(), htmlParser,
|
||||||
|
/*console*/ null, []);
|
||||||
|
const offlineCompiler = new compiler.OfflineCompiler(
|
||||||
|
normalizer, tmplParser, new StyleCompiler(urlResolver),
|
||||||
|
new ViewCompiler(config),
|
||||||
|
new TypeScriptEmitter(reflectorHost), xhr);
|
||||||
|
const resolver = new CompileMetadataResolver(
|
||||||
|
new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector),
|
||||||
|
new compiler.ViewResolver(staticReflector), null, null, staticReflector);
|
||||||
|
|
||||||
|
// TODO(vicb): handle implicit
|
||||||
|
const extractor = new MessageExtractor(htmlParser, parser, [], {});
|
||||||
|
|
||||||
|
return new Extractor(options, program, compilerHost, staticReflector, resolver,
|
||||||
|
offlineCompiler, reflectorHost, extractor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry point
|
||||||
|
if (require.main === module) {
|
||||||
|
const args = require('minimist')(process.argv.slice(2));
|
||||||
|
tsc.main(args.p || args.project || '.', args.basePath, extract)
|
||||||
|
.then(exitCode => process.exit(exitCode))
|
||||||
|
.catch(e => {
|
||||||
|
console.error(e.stack);
|
||||||
|
console.error("Compilation failed");
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,7 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"index.ts",
|
"index.ts",
|
||||||
"src/main.ts",
|
"src/main.ts",
|
||||||
|
"src/extract_i18n.ts",
|
||||||
"../../../node_modules/@types/node/index.d.ts",
|
"../../../node_modules/@types/node/index.d.ts",
|
||||||
"../../../node_modules/@types/jasmine/index.d.ts",
|
"../../../node_modules/@types/jasmine/index.d.ts",
|
||||||
"../../../node_modules/zone.js/dist/zone.js.d.ts"
|
"../../../node_modules/zone.js/dist/zone.js.d.ts"
|
||||||
|
@ -2,15 +2,19 @@ import * as selector from './src/selector';
|
|||||||
import * as path_util from './src/output/path_util';
|
import * as path_util from './src/output/path_util';
|
||||||
import * as metadata_resolver from './src/metadata_resolver';
|
import * as metadata_resolver from './src/metadata_resolver';
|
||||||
import * as html_parser from './src/html_parser';
|
import * as html_parser from './src/html_parser';
|
||||||
|
import * as i18n_html_parser from './src/i18n/i18n_html_parser';
|
||||||
import * as directive_normalizer from './src/directive_normalizer';
|
import * as directive_normalizer from './src/directive_normalizer';
|
||||||
import * as lexer from './src/expression_parser/lexer';
|
import * as lexer from './src/expression_parser/lexer';
|
||||||
import * as parse_util from './src/parse_util';
|
|
||||||
import * as parser from './src/expression_parser/parser';
|
import * as parser from './src/expression_parser/parser';
|
||||||
import * as template_parser from './src/template_parser';
|
import * as template_parser from './src/template_parser';
|
||||||
import * as dom_element_schema_registry from './src/schema/dom_element_schema_registry';
|
import * as dom_element_schema_registry from './src/schema/dom_element_schema_registry';
|
||||||
import * as style_compiler from './src/style_compiler';
|
import * as style_compiler from './src/style_compiler';
|
||||||
import * as view_compiler from './src/view_compiler/view_compiler';
|
import * as view_compiler from './src/view_compiler/view_compiler';
|
||||||
import * as ts_emitter from './src/output/ts_emitter';
|
import * as ts_emitter from './src/output/ts_emitter';
|
||||||
|
import * as i18n_extractor from './src/i18n/message_extractor';
|
||||||
|
import * as i18n_message from './src/i18n/message';
|
||||||
|
import * as xmb_serializer from './src/i18n/xmb_serializer';
|
||||||
|
import * as parse_util from './src/parse_util';
|
||||||
|
|
||||||
export namespace __compiler_private__ {
|
export namespace __compiler_private__ {
|
||||||
export type SelectorMatcher = selector.SelectorMatcher;
|
export type SelectorMatcher = selector.SelectorMatcher;
|
||||||
@ -31,6 +35,23 @@ export namespace __compiler_private__ {
|
|||||||
export type HtmlParser = html_parser.HtmlParser;
|
export type HtmlParser = html_parser.HtmlParser;
|
||||||
export var HtmlParser = html_parser.HtmlParser;
|
export var HtmlParser = html_parser.HtmlParser;
|
||||||
|
|
||||||
|
export type I18nHtmlParser = i18n_html_parser.I18nHtmlParser;
|
||||||
|
export var I18nHtmlParser = i18n_html_parser.I18nHtmlParser;
|
||||||
|
|
||||||
|
export type ExtractionResult = i18n_extractor.ExtractionResult;
|
||||||
|
export var ExtractionResult = i18n_extractor.ExtractionResult;
|
||||||
|
|
||||||
|
export type Message = i18n_message.Message;
|
||||||
|
export var Message = i18n_message.Message;
|
||||||
|
|
||||||
|
export type MessageExtractor = i18n_extractor.MessageExtractor;
|
||||||
|
export var MessageExtractor = i18n_extractor.MessageExtractor;
|
||||||
|
|
||||||
|
export var removeDuplicates = i18n_extractor.removeDuplicates;
|
||||||
|
|
||||||
|
export var serializeXmb = xmb_serializer.serializeXmb;
|
||||||
|
export var deserializeXmb = xmb_serializer.deserializeXmb;
|
||||||
|
|
||||||
export type DirectiveNormalizer = directive_normalizer.DirectiveNormalizer;
|
export type DirectiveNormalizer = directive_normalizer.DirectiveNormalizer;
|
||||||
export var DirectiveNormalizer = directive_normalizer.DirectiveNormalizer;
|
export var DirectiveNormalizer = directive_normalizer.DirectiveNormalizer;
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ export const HTTP_PROVIDERS: any[] = [
|
|||||||
{provide: XSRFStrategy, useValue: new CookieXSRFStrategy()},
|
{provide: XSRFStrategy, useValue: new CookieXSRFStrategy()},
|
||||||
];
|
];
|
||||||
|
|
||||||
function httpFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions): Http {
|
export function httpFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions): Http {
|
||||||
return new Http(xhrBackend, requestOptions);
|
return new Http(xhrBackend, requestOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,24 +15,24 @@ export const ROUTER_PROVIDERS_COMMON: any[] = /*@ts2dart_const*/[
|
|||||||
provide: Router,
|
provide: Router,
|
||||||
useFactory: routerFactory,
|
useFactory: routerFactory,
|
||||||
deps: /*@ts2dart_const*/
|
deps: /*@ts2dart_const*/
|
||||||
[ApplicationRef, ComponentResolver, RouterUrlSerializer, RouterOutletMap, Location],
|
[ApplicationRef, ComponentResolver, RouterUrlSerializer, RouterOutletMap, Location],
|
||||||
},
|
},
|
||||||
/*@ts2dart_Provider*/ {provide: RouteSegment, useFactory: routeSegmentFactory, deps: [Router]}
|
/*@ts2dart_Provider*/ {provide: RouteSegment, useFactory: routeSegmentFactory, deps: [Router]}
|
||||||
];
|
];
|
||||||
|
|
||||||
function routerFactory(app: ApplicationRef, componentResolver: ComponentResolver,
|
export function routerFactory(app: ApplicationRef, componentResolver: ComponentResolver,
|
||||||
urlSerializer: RouterUrlSerializer, routerOutletMap: RouterOutletMap,
|
urlSerializer: RouterUrlSerializer, routerOutletMap: RouterOutletMap,
|
||||||
location: Location): Router {
|
location: Location): Router {
|
||||||
if (app.componentTypes.length == 0) {
|
if (app.componentTypes.length == 0) {
|
||||||
throw new BaseException("Bootstrap at least one component before injecting Router.");
|
throw new BaseException("Bootstrap at least one component before injecting Router.");
|
||||||
}
|
}
|
||||||
// TODO: vsavkin this should not be null
|
// TODO: vsavkin this should not be null
|
||||||
let router = new Router(null, app.componentTypes[0], componentResolver, urlSerializer,
|
let router = new Router(null, app.componentTypes[0], componentResolver, urlSerializer,
|
||||||
routerOutletMap, location);
|
routerOutletMap, location);
|
||||||
app.registerDisposeListener(() => router.dispose());
|
app.registerDisposeListener(() => router.dispose());
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
function routeSegmentFactory(router: Router): RouteSegment {
|
export function routeSegmentFactory(router: Router): RouteSegment {
|
||||||
return router.routeTree.root;
|
return router.routeTree.root;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
provide,
|
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Injector,
|
Injector,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
@ -7,7 +6,8 @@ import {
|
|||||||
ComponentRef,
|
ComponentRef,
|
||||||
SimpleChange,
|
SimpleChange,
|
||||||
SimpleChanges,
|
SimpleChanges,
|
||||||
ReflectiveInjector
|
ReflectiveInjector,
|
||||||
|
EventEmitter
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {NG1_SCOPE} from './constants';
|
import {NG1_SCOPE} from './constants';
|
||||||
import {ComponentInfo} from './metadata';
|
import {ComponentInfo} from './metadata';
|
||||||
@ -145,11 +145,11 @@ export class DowngradeNg2ComponentAdapter {
|
|||||||
if (assignExpr && !setter) {
|
if (assignExpr && !setter) {
|
||||||
throw new Error(`Expression '${expr}' is not assignable!`);
|
throw new Error(`Expression '${expr}' is not assignable!`);
|
||||||
}
|
}
|
||||||
var emitter = this.component[output.prop];
|
var emitter = this.component[output.prop] as EventEmitter<any>;
|
||||||
if (emitter) {
|
if (emitter) {
|
||||||
emitter.subscribe({
|
emitter.subscribe({
|
||||||
next: assignExpr ? ((setter) => (value) => setter(this.scope, value))(setter) :
|
next: assignExpr ? ((setter: any) => v => setter(this.scope, v))(setter) :
|
||||||
((getter) => (value) => getter(this.scope, {$event: value}))(getter)
|
((getter: any) => v => getter(this.scope, {$event: v}))(getter)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Missing emitter '${output.prop}' on component '${this.info.selector}'!`);
|
throw new Error(`Missing emitter '${output.prop}' on component '${this.info.selector}'!`);
|
||||||
|
@ -9,7 +9,7 @@ declare var System: any;
|
|||||||
writeScriptTag('/all/playground/vendor/system.src.js');
|
writeScriptTag('/all/playground/vendor/system.src.js');
|
||||||
writeScriptTag('/all/playground/vendor/Reflect.js');
|
writeScriptTag('/all/playground/vendor/Reflect.js');
|
||||||
writeScriptTag('/all/playground/vendor/rxjs/bundles/Rx.js', 'playgroundBootstrap()');
|
writeScriptTag('/all/playground/vendor/rxjs/bundles/Rx.js', 'playgroundBootstrap()');
|
||||||
global.playgroundBootstrap = playgroundBootstrap;
|
(<any>global).playgroundBootstrap = playgroundBootstrap;
|
||||||
|
|
||||||
function playgroundBootstrap() {
|
function playgroundBootstrap() {
|
||||||
// check query param
|
// check query param
|
||||||
|
@ -32,6 +32,7 @@ cp -v package.json $TMP
|
|||||||
|
|
||||||
# Compile the compiler-cli integration tests
|
# Compile the compiler-cli integration tests
|
||||||
./node_modules/.bin/ngc
|
./node_modules/.bin/ngc
|
||||||
|
./node_modules/.bin/ng-xi18n
|
||||||
|
|
||||||
./node_modules/.bin/jasmine init
|
./node_modules/.bin/jasmine init
|
||||||
# Run compiler-cli integration tests in node
|
# Run compiler-cli integration tests in node
|
||||||
|
Reference in New Issue
Block a user