Skip to content

Commit

Permalink
feat(app): @HostBinding & @HostListener support
Browse files Browse the repository at this point in the history
fix #277
  • Loading branch information
vogloblinsky committed Aug 21, 2017
1 parent b7d3406 commit 1ab4311
Show file tree
Hide file tree
Showing 12 changed files with 418 additions and 121 deletions.
133 changes: 96 additions & 37 deletions dist/index-cli.js

Large diffs are not rendered by default.

133 changes: 96 additions & 37 deletions dist/index.js

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion src/app/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,8 @@ export class Application {
_.forEach(list, (element) => {
if (!element.propertiesClass ||
!element.methodsClass ||
!element.hostBindings ||
!element.hostListeners ||
!element.inputsClass ||
!element.outputsClass) {
return;
Expand All @@ -971,7 +973,7 @@ export class Application {
name: element.name
},
totalStatementDocumented = 0,
totalStatements = element.propertiesClass.length + element.methodsClass.length + element.inputsClass.length + element.outputsClass.length + 1; // +1 for element decorator comment
totalStatements = element.propertiesClass.length + element.methodsClass.length + element.inputsClass.length + element.hostBindings.length + element.hostListeners.length + element.outputsClass.length + 1; // +1 for element decorator comment

if (element.constructorObj) {
totalStatements += 1;
Expand Down Expand Up @@ -999,6 +1001,22 @@ export class Application {
totalStatementDocumented += 1;
}
});
_.forEach(element.hostBindings, (property) => {
if (property.modifierKind === 111) { // Doesn't handle private for coverage
totalStatements -= 1;
}
if(property.description && property.description !== '' && property.modifierKind !== 111) {
totalStatementDocumented += 1;
}
});
_.forEach(element.hostListeners, (method) => {
if (method.modifierKind === 111) { // Doesn't handle private for coverage
totalStatements -= 1;
}
if(method.description && method.description !== '' && method.modifierKind !== 111) {
totalStatementDocumented += 1;
}
});
_.forEach(element.inputsClass, (input) => {
if (input.modifierKind === 111) { // Doesn't handle private for coverage
totalStatements -= 1;
Expand Down
122 changes: 86 additions & 36 deletions src/app/compiler/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ interface Deps {
propertiesClass?: Object[];
methodsClass?: Object[];

hostBindings?: Object[];
hostListeners?: Object[];

//common
providers?: Deps[];

Expand Down Expand Up @@ -349,6 +352,10 @@ export class Dependencies {
outputsClass: IO.outputs,
propertiesClass: IO.properties,
methodsClass: IO.methods,

hostBindings: IO.hostBindings,
hostListeners: IO.hostListeners,

description: IO.description,
type: 'component',
sourceCode: srcFile.getText(),
Expand Down Expand Up @@ -420,6 +427,9 @@ export class Dependencies {
inputsClass: IO.inputs,
outputsClass: IO.outputs,

hostBindings: IO.hostBindings,
hostListeners: IO.hostListeners,

propertiesClass: IO.properties,
methodsClass: IO.methods,
exampleUrls: _this.getComponentExampleUrls(srcFile.getText())
Expand Down Expand Up @@ -908,7 +918,65 @@ export class Dependencies {
return null;
}

private visitInput(property, inDecorator, sourceFile?) {
private visitOutput(property, outDecorator, sourceFile?) {
var inArgs = outDecorator.expression.arguments,
_return = {};
_return.name = (inArgs.length > 0) ? inArgs[0].text : property.name.text;
_return.defaultValue = property.initializer ? this.stringifyDefaultValue(property.initializer) : undefined;
if (property.symbol) {
_return.description = marked(ts.displayPartsToString(property.symbol.getDocumentationComment()))
}
if (!_return.description) {
if (property.jsDoc) {
if (property.jsDoc.length > 0) {
if (typeof property.jsDoc[0].comment !== 'undefined') {
_return.description = marked(property.jsDoc[0].comment);
}
}
}
}
_return.line = this.getPosition(property, sourceFile).line + 1;

if (property.type) {
_return.type = this.visitType(property);
} else {
// handle NewExpression
if (property.initializer) {
if (property.initializer.kind === ts.SyntaxKind.NewExpression) {
if (property.initializer.expression) {
_return.type = property.initializer.expression.text;
}
}
}
}
return _return;
}

private visitHostListener(property, hostListenerDecorator, sourceFile?) {
var inArgs = hostListenerDecorator.expression.arguments,
_return = {};
_return.name = (inArgs.length > 0) ? inArgs[0].text : property.name.text;
_return.args = property.parameters ? property.parameters.map((prop) => this.visitArgument(prop)) : [];
_return.argsDecorator = (inArgs.length > 1) ? inArgs[1].elements.map((prop) => {
return prop.text;
}) : [];
if (property.symbol) {
_return.description = marked(ts.displayPartsToString(property.symbol.getDocumentationComment()));
}
if (!_return.description) {
if (property.jsDoc) {
if (property.jsDoc.length > 0) {
if (typeof property.jsDoc[0].comment !== 'undefined') {
_return.description = marked(property.jsDoc[0].comment);
}
}
}
}
_return.line = this.getPosition(property, sourceFile).line + 1;
return _return;
}

private visitInputAndHostBinding(property, inDecorator, sourceFile?) {
var inArgs = inDecorator.expression.arguments,
_return = {};
_return.name = (inArgs.length > 0) ? inArgs[0].text : property.name.text;
Expand Down Expand Up @@ -1013,40 +1081,6 @@ export class Dependencies {
return _return;
}

private visitOutput(property, outDecorator, sourceFile?) {
var inArgs = outDecorator.expression.arguments,
_return = {};
_return.name = (inArgs.length > 0) ? inArgs[0].text : property.name.text;
_return.defaultValue = property.initializer ? this.stringifyDefaultValue(property.initializer) : undefined;
if (property.symbol) {
_return.description = marked(ts.displayPartsToString(property.symbol.getDocumentationComment()))
}
if (!_return.description) {
if (property.jsDoc) {
if (property.jsDoc.length > 0) {
if (typeof property.jsDoc[0].comment !== 'undefined') {
_return.description = marked(property.jsDoc[0].comment);
}
}
}
}
_return.line = this.getPosition(property, sourceFile).line + 1;

if (property.type) {
_return.type = this.visitType(property);
} else {
// handle NewExpression
if (property.initializer) {
if (property.initializer.kind === ts.SyntaxKind.NewExpression) {
if (property.initializer.expression) {
_return.type = property.initializer.expression.text;
}
}
}
}
return _return;
}

private isPublic(member): boolean {
if (member.modifiers) {
const isPublic: boolean = member.modifiers.some(function(modifier) {
Expand Down Expand Up @@ -1353,24 +1387,34 @@ export class Dependencies {
*/
var inputs = [],
outputs = [],
hostBindings = [],
hostListeners = [],
methods = [],
properties = [],
indexSignatures = [],
kind,
inputDecorator,
hostBinding,
hostListener,
constructor,
outDecorator;

for (var i = 0; i < members.length; i++) {
inputDecorator = this.getDecoratorOfType(members[i], 'Input');
outDecorator = this.getDecoratorOfType(members[i], 'Output');
hostBinding = this.getDecoratorOfType(members[i], 'HostBinding');
hostListener = this.getDecoratorOfType(members[i], 'HostListener');

kind = members[i].kind;

if (inputDecorator) {
inputs.push(this.visitInput(members[i], inputDecorator, sourceFile));
inputs.push(this.visitInputAndHostBinding(members[i], inputDecorator, sourceFile));
} else if (outDecorator) {
outputs.push(this.visitOutput(members[i], outDecorator, sourceFile));
} else if (hostBinding) {
hostBindings.push(this.visitInputAndHostBinding(members[i], hostBinding, sourceFile));
} else if (hostListener) {
hostListeners.push(this.visitHostListener(members[i], hostListener, sourceFile));
} else if (!this.isHiddenMember(members[i])) {

if ( (this.isPrivate(members[i]) || this.isInternal(members[i])) && this.configuration.mainData.disablePrivateOrInternalSupport) {} else {
Expand Down Expand Up @@ -1400,13 +1444,17 @@ export class Dependencies {

inputs.sort(getNamesCompareFn());
outputs.sort(getNamesCompareFn());
hostBindings.sort(getNamesCompareFn());
hostListeners.sort(getNamesCompareFn());
properties.sort(getNamesCompareFn());
methods.sort(getNamesCompareFn());
indexSignatures.sort(getNamesCompareFn());

return {
inputs,
outputs,
hostBindings,
hostListeners,
methods,
properties,
indexSignatures,
Expand Down Expand Up @@ -1518,6 +1566,8 @@ export class Dependencies {
description,
inputs: members.inputs,
outputs: members.outputs,
hostBindings: members.hostBindings,
hostListeners: members.hostListeners,
properties: members.properties,
methods: members.methods,
indexSignatures: members.indexSignatures,
Expand Down
15 changes: 13 additions & 2 deletions src/templates/partials/block-method.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<section>
{{#compare title "===" 'false' }}{{else}}
{{#if title}}
<h3>
{{title}}
</h3>
{{else}}
<h3 id="methods">
Methods
</h3>
{{/compare}}
{{/if}}
{{#each methods}}
<table class="table table-sm table-bordered">
<tbody>
Expand All @@ -20,6 +24,13 @@
</td>
</tr>
{{/if}}
{{#if argsDecorator}}
<tr>
<td class="col-md-4">
<i>Arguments : </i><code>{{#each argsDecorator}}'{{this}}' {{/each}}</code>
</td>
</tr>
{{/if}}
<tr>
<td class="col-md-4">
{{#if modifierKind}}
Expand Down
8 changes: 6 additions & 2 deletions src/templates/partials/block-property.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<section>
{{#compare title "===" 'false' }}{{else}}
{{#if title}}
<h3>
{{title}}
</h3>
{{else}}
<h3 id="inputs">
Properties
</h3>
{{/compare}}
{{/if}}
{{#each properties}}
<table class="table table-sm table-bordered">
<tbody>
Expand Down
12 changes: 10 additions & 2 deletions src/templates/partials/component-detail.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@
</table>
</section>

{{#orLength component.propertiesClass component.methodsClass component.inputsClass component.outputClass}}
{{> index-directive methods=component.methodsClass properties=component.propertiesClass inputs=component.inputsClass outputs=component.outputsClass }}
{{#orLength component.propertiesClass component.methodsClass component.inputsClass component.outputClass component.hostBindings component.hostListeners}}
{{> index-directive methods=component.methodsClass properties=component.propertiesClass inputs=component.inputsClass outputs=component.outputsClass hostBindings=component.hostBindings hostListeners=component.hostListeners }}
{{/orLength}}

{{#if component.constructorObj}}
Expand Down Expand Up @@ -280,6 +280,14 @@
</section>
{{/if}}

{{#if component.hostBindings}}
{{> block-property properties=component.hostBindings file=component.file title="HostBindings" }}
{{/if}}

{{#if component.hostListeners}}
{{> block-method methods=component.hostListeners file=component.file title="HostListeners" }}
{{/if}}

{{#if component.methodsClass}}
{{> block-method methods=component.methodsClass file=component.file }}
{{/if}}
Expand Down
12 changes: 10 additions & 2 deletions src/templates/partials/directive.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@
</table>
</section>

{{#orLength directive.propertiesClass directive.methodsClass directive.inputsClass directive.outputClass}}
{{> index-directive methods=directive.methodsClass properties=directive.propertiesClass inputs=directive.inputsClass directive=component.outputsClass }}
{{#orLength directive.propertiesClass directive.methodsClass directive.inputsClass directive.outputClass directive.hostBindings directive.hostListeners}}
{{> index-directive methods=directive.methodsClass properties=directive.propertiesClass inputs=directive.inputsClass outputs=directive.outputsClass hostBindings=directive.hostBindings hostListeners=directive.hostListeners }}
{{/orLength}}

{{#if directive.constructorObj}}
Expand Down Expand Up @@ -184,6 +184,14 @@
</section>
{{/if}}

{{#if directive.hostBindings}}
{{> block-property properties=directive.hostBindings file=directive.file title="HostBindings" }}
{{/if}}

{{#if directive.hostListeners}}
{{> block-method methods=directive.hostListeners file=directive.file title="HostListeners" }}
{{/if}}

{{#if directive.methodsClass}}
{{> block-method methods=directive.methodsClass file=directive.file }}
{{/if}}
Expand Down
36 changes: 36 additions & 0 deletions src/templates/partials/index-directive.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,42 @@
</td>
</tr>
{{/compare}}
{{#compare hostBindings.length ">" 0}}
<tr>
<td class="col-md-4">
<h6><b>HostBindings</b></h6>
</td>
</tr>
<tr>
<td class="col-md-4">
<ul class="index-list">
{{#each hostBindings}}
<li>
<a href="#{{name}}">{{name}}</a>
</li>
{{/each}}
</ul>
</td>
</tr>
{{/compare}}
{{#compare hostListeners.length ">" 0}}
<tr>
<td class="col-md-4">
<h6><b>HostListeners</b></h6>
</td>
</tr>
<tr>
<td class="col-md-4">
<ul class="index-list">
{{#each hostListeners}}
<li>
<a href="#{{name}}">{{name}}</a>
</li>
{{/each}}
</ul>
</td>
</tr>
{{/compare}}
</tbody>
</table>
</section>
11 changes: 11 additions & 0 deletions test/src/cli/cli-generation-big-app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,15 @@ describe('CLI simple generation - big app', () => {
expect(file).to.contain('<code>literal type | null');
});

it('should support @HostBindings', () => {
let file = read('documentation/directives/DoNothingDirective.html');
expect(file).to.contain('<code>style.color');
});

it('should support @HostListener', () => {
let file = read('documentation/components/AboutComponent.html');
expect(file).to.contain('<code>mouseup(mouseX');
expect(file).to.contain('i>Arguments : </i><code>\'$event.clientX');
});

});
Loading

0 comments on commit 1ab4311

Please sign in to comment.