@@ -28,6 +28,7 @@ import "../template_ast.dart"
2828 DirectiveAst,
2929 BoundDirectivePropertyAst,
3030 templateVisitAll;
31+ import '../expression_parser/parser.dart' show Parser;
3132import "compile_element.dart" show CompileElement, CompileNode;
3233import "compile_method.dart" ;
3334import "compile_view.dart" show CompileView;
@@ -36,11 +37,15 @@ import "constants.dart"
3637 ChangeDetectionStrategyEnum,
3738 ChangeDetectorStateEnum,
3839 DetectChangesVars,
40+ EventHandlerVars,
3941 InjectMethodVars,
4042 ViewConstructorVars,
4143 ViewEncapsulationEnum,
4244 ViewProperties,
4345 ViewTypeEnum;
46+ import 'expression_converter.dart' ;
47+ import 'event_binder.dart' show convertStmtIntoExpression;
48+ import 'parse_utils.dart' ;
4449import 'property_binder.dart' ;
4550import "view_compiler_utils.dart"
4651 show
@@ -69,6 +74,7 @@ class ViewCompileDependency {
6974
7075class ViewBuilderVisitor implements TemplateAstVisitor {
7176 final CompileView view;
77+ final Parser parser;
7278 final List <ViewCompileDependency > targetDependencies;
7379 final StylesCompileResult stylesCompileResult;
7480 static Map <String , CompileIdentifierMetadata > tagNameToIdentifier;
@@ -79,8 +85,8 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
7985 static final defaultDocVarName = 'doc' ;
8086 String docVarName;
8187
82- ViewBuilderVisitor (
83- this .view, this .targetDependencies, this . stylesCompileResult) {
88+ ViewBuilderVisitor (this .view, this .parser, this .targetDependencies,
89+ this .stylesCompileResult) {
8490 tagNameToIdentifier ?? = {
8591 'a' : Identifiers .HTML_ANCHOR_ELEMENT ,
8692 'area' : Identifiers .HTML_AREA_ELEMENT ,
@@ -495,7 +501,7 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
495501
496502 // Create a visitor for embedded view and visit all nodes.
497503 var embeddedViewVisitor = new ViewBuilderVisitor (
498- embeddedView, targetDependencies, stylesCompileResult);
504+ embeddedView, parser, targetDependencies, stylesCompileResult);
499505 templateVisitAll (
500506 embeddedViewVisitor,
501507 ast.children,
@@ -725,10 +731,11 @@ o.Expression createStaticNodeDebugInfo(CompileNode node) {
725731
726732/// Generates output ast for a CompileView and returns a [ClassStmt] for the
727733/// view of embedded template.
728- o.ClassStmt createViewClass (CompileView view, o.Expression nodeDebugInfosVar) {
734+ o.ClassStmt createViewClass (
735+ CompileView view, o.Expression nodeDebugInfosVar, Parser parser) {
729736 var viewConstructor = _createViewClassConstructor (view, nodeDebugInfosVar);
730737 var viewMethods = (new List .from ([
731- new o.ClassMethod ("build" , [], generateCreateMethod (view),
738+ new o.ClassMethod ("build" , [], generateCreateMethod (view, parser ),
732739 o.importType (Identifiers .ComponentRef , null )),
733740 new o.ClassMethod (
734741 "injectorGetInternal" ,
@@ -922,7 +929,7 @@ o.Statement createViewFactory(CompileView view, o.ClassStmt viewClass) {
922929 .toDeclStmt (view.viewFactory.name, [o.StmtModifier .Final ]);
923930}
924931
925- List <o.Statement > generateCreateMethod (CompileView view) {
932+ List <o.Statement > generateCreateMethod (CompileView view, Parser parser ) {
926933 o.Expression parentRenderNodeExpr = o.NULL_EXPR ;
927934 var parentRenderNodeStmts = < o.Statement > [];
928935 bool isComponent = view.viewType == ViewType .COMPONENT ;
@@ -954,8 +961,13 @@ List<o.Statement> generateCreateMethod(CompileView view) {
954961 o.literalArr (view.subscriptions)
955962 ]).toStmt ());
956963
957- if (isComponent &&
958- view.viewIndex == 0 &&
964+ bool isComponentRoot = isComponent && view.viewIndex == 0 ;
965+
966+ if (isComponentRoot) {
967+ _writeComponentHostEventListeners (view, parser, statements);
968+ }
969+
970+ if (isComponentRoot &&
959971 view.component.changeDetection == ChangeDetectionStrategy .Stateful ) {
960972 // Connect ComponentState callback to view.
961973 statements.add ((new o.ReadClassMemberExpr ('ctx' )
@@ -980,6 +992,56 @@ List<o.Statement> generateCreateMethod(CompileView view) {
980992 return statements;
981993}
982994
995+ /// Writes shared event handler wiring for events that are directly defined
996+ /// on host property of @Component annotation.
997+ void _writeComponentHostEventListeners (
998+ CompileView view, Parser parser, List <o.Statement > statements) {
999+ CompileDirectiveMetadata component = view.component;
1000+ for (String eventName in component.hostListeners.keys) {
1001+ String handlerSource = component.hostListeners[eventName];
1002+ var handlerAst = parser.parseAction (handlerSource, '' );
1003+ HandlerType handlerType = handlerTypeFromExpression (handlerAst);
1004+
1005+ var context = new o.ReadClassMemberExpr ('ctx' );
1006+ var actionExpr = convertStmtIntoExpression (
1007+ convertCdStatementToIr (view, context, handlerAst, false ).last);
1008+ if (handlerType == HandlerType .notSimple) {
1009+ List <o.Statement > stmts = < o.Statement > [
1010+ new o.InvokeMemberMethodExpr ('markPathToRootAsCheckOnce' , []).toStmt (),
1011+ new o.ReturnStatement (actionExpr)
1012+ ];
1013+ String methodName = '_handle_${sanitizeEventName (eventName )}__' ;
1014+ view.eventHandlerMethods.add (new o.ClassMethod (
1015+ methodName,
1016+ [new o.FnParam (EventHandlerVars .event.name, o.importType (null ))],
1017+ stmts,
1018+ o.BOOL_TYPE ,
1019+ [o.StmtModifier .Private ]));
1020+
1021+ o.Expression handlerExpr = new o.InvokeMemberMethodExpr (
1022+ 'evt' , [new o.ReadClassMemberExpr (methodName)]);
1023+ o.Expression listenExpr = new o.InvokeMemberMethodExpr ('listen' , [
1024+ new o.ReadClassMemberExpr (appViewRootElementName),
1025+ o.literal (eventName),
1026+ handlerExpr
1027+ ]);
1028+ statements.add (listenExpr.toStmt ());
1029+ } else {
1030+ assert (actionExpr is o.InvokeMethodExpr );
1031+ var callExpr = actionExpr as o.InvokeMethodExpr ;
1032+ var eventListener = new o.InvokeMemberMethodExpr (
1033+ 'eventHandler${handlerType == HandlerType .simpleNoArgs ? 0 : 1 }' ,
1034+ [new o.ReadPropExpr (callExpr.receiver, callExpr.name)]);
1035+ o.Expression listenExpr = new o.InvokeMemberMethodExpr ('listen' , [
1036+ new o.ReadClassMemberExpr (appViewRootElementName),
1037+ o.literal (eventName),
1038+ eventListener
1039+ ]);
1040+ statements.add (listenExpr.toStmt ());
1041+ }
1042+ }
1043+ }
1044+
9831045List <o.Statement > generateDetectChangesMethod (CompileView view) {
9841046 var stmts = < o.Statement > [];
9851047 if (view.detectChangesInInputsMethod.isEmpty &&
0 commit comments