kangax / html-minifier

Javascript-based HTML compressor/minifier (with Node.js support)
http://kangax.github.io/html-minifier/
MIT License
4.94k stars 571 forks source link

Angular 2 support #289

Closed duncanbeevers closed 8 years ago

duncanbeevers commented 10 years ago

Angular 2 adds some new warts to its pseudo-HTML

<div [ng-repeat|todo]="todosOf('good')"></div>
<button (click)="deleteTodo(todo)">X</button>
kangax commented 10 years ago

Damn... what does this do, out of curiosity?

duncanbeevers commented 10 years ago

I'm not certain since Angular 2 is still very nebulous. The [ng-repeat|todo] seems like an attribute-style directive which will iterate over the collection yielded by the attribute value todosOf('good') referencing the individual items as todo.

The (click) looks like some kind of event-binding.

In the Angular design documents there is an AngularJS Design Doc Templating whose examples all use a more pedestrian-looking on-click, bind-value, and ng-repeat (and kin).

I've only seen this new syntax in blog posts such as this one concerning details revealed at ng-europe.

angular2directive-1024x618

andreialecu commented 8 years ago

Bump. now with angular2 being in beta this is a big problem when using webpack + html-loader, when in minification mode. It will fail the build.

doxavore commented 8 years ago

I know of customAttrSurround which works for things like:

<button (click)="deleteTodo(todo)">X</button>
<input [(ngModel)]="todoTitle">

using this config:

htmlmin({
  collapseWhitespace: true,
  customAttrSurround: [
    [/\[/, /\]/],
    [/\(/, /\)/],
    [/\[\(/, /\)\]/]
  ]
})

However, I'm not sure how to handle the case of Angular 2's local variables and templates:

<video #videoLocalVar>
<li *nfFor="#item in list">

Are we able to allow prefixes without suffixes? I haven't had any progress after several attempts, such as adding [ /\*/, new RegExp('') ] to the customAttrSurround.

andreialecu commented 8 years ago

I didn't try this, but maybe [ /\*/, /[^=]/ ] might work?

Another idea might be /[^a-zA-Z\-]/

alexlamsl commented 8 years ago

Taking the examples from here

> minify(`
... <template ngFor #hero [ngForOf]="heroes">
...   <hero-detail *ngIf="hero" [hero]="hero"></hero-detail>
... </template>
... <form (ngSubmit)="onSubmit(theForm)" #theForm="ngForm">
...   <div class="form-group">
...     <label for="name">Name</label>
...     <input class="form-control" required ngControl="firstName"
...       [(ngModel)]="currentHero.firstName">
...   </div>
...   <button type="submit" [disabled]="!theForm.form.valid">Submit</button>
... </form>
... `, { customAttrSurround: [ [/#/, /(?:)/], [/\*/, /(?:)/], [/\[?\(?/, /(?:)/] ], customAttrAssign: [ /\)?\]?=/ ] })

`<template ngfor #hero [ngforof]="heroes">
<hero-detail *ngif="hero" [hero]="hero"></hero-detail>
</template>
<form (ngsubmit)="onSubmit(theForm)" #theform="ngForm">
<div class="form-group">
<label for="name">Name</label>
<input class="form-control" required ngcontrol="firstName" [(ngmodel)]="currentHero.firstName">
</div>
<button type="submit" [disabled]="!theForm.form.valid">Submit</button>
</form>`
alexlamsl commented 8 years ago

@duncanbeevers do we still need to implement anything beyond the example above to make Angular 2 work?

uglow commented 8 years ago

I've documented a configuration that seems to work with Angular2.0.0-beta6

alexlamsl commented 8 years ago

@uglow looks the same as the one I gave in https://github.com/kangax/html-minifier/issues/289#issuecomment-180971821 ?

Unless they are planning on introducing new syntaxes, I think we have resolved this one.

uglow commented 8 years ago

@alexlamsl - yes, it is similar to your config but with 2 extra config flags: removeAttributeQuotes and caseSensitive. These flags are also necessary (at least when using html-minifier via html-loader). Just thought this note might help someone else.

andreialecu commented 8 years ago

@alexlamsl shouldn't html-minifier work with this syntax by default without custom workarounds?

As far as I know those characters are legal in attributes: https://html.spec.whatwg.org/multipage/syntax.html#attributes-2

alexlamsl commented 8 years ago

@andreialecu wow, that's... crazy :see_no_evil:

alexlamsl commented 8 years ago

@kangax if I am reading what @andreialecu refers to correctly, things like a?="b" never needed customAttrAssign as a? is just a valid attribute name on its own...

kangax commented 8 years ago

Originally we followed HTML4 semantics, which is defined via SGML and lists specific attributes for specific tags. While HTML5 (seems to) specify attribute names more loosely, I still see that validator (https://validator.w3.org/nu/#textarea) complains with foo?=bar. It even complains with data-foo?=bar.

I'm guessing if we were to follow HTML5 behavior strictly, we could tolerate things like that (assuming that browsers tolerate them too).

code-tree commented 8 years ago

So AFAIK, after this patch, the current requirement for Angular 2 is:

removeAttributeQuotes: false, caseSensitive: true

This test probably then needs to be corrected? As it doesn't look like Angular supports removeAttributeQuotes: true.