assetgraph/assetgraph — pull request #213 by papandreou (2014-07-28 23:11:08+00:00)
Title: WIP: Use html-minifier instead of homegrown code

I saw http://perfectionkills.com/html-minifier-revisited/ and it seemed like an opportunity to delegate an error-prone task to another module.

It causes some regressions because the extensive test suite for Html.minify is very particular about the preservation of potentially sematics-changing whitespace:

```
1) assets/Html #minify() should remove trailing whitespace in the last text node child of a block-level element with comment in the middle:

Error: expected '

blah

' to minify to '

blah

'
+ expected - actual

+

blah

-

blah

at Context. (/home/andreas/work/assetgraph/test/assets/Html.js:291:13)
at callFn (/home/andreas/work/mocha/lib/runnable.js:247:21)
at Test.Runnable.run (/home/andreas/work/mocha/lib/runnable.js:240:7)
at Runner.runTest (/home/andreas/work/mocha/lib/runner.js:373:10)
at /home/andreas/work/mocha/lib/runner.js:451:12
at next (/home/andreas/work/mocha/lib/runner.js:298:14)
at /home/andreas/work/mocha/lib/runner.js:308:7
at next (/home/andreas/work/mocha/lib/runner.js:246:23)
at Object._onImmediate (/home/andreas/work/mocha/lib/runner.js:275:5)
at processImmediate [as _immediateCallback] (timers.js:330:15)

2) assets/Html #minify() should trim trailing whitespace in inline tag followed by leading whitespace in the next sibling:

Error: expected '

foo bar

' to minify to '

foo bar

'
+ expected - actual

+

foo bar

-

foobar

at Context. (/home/andreas/work/assetgraph/test/assets/Html.js:412:13)
at callFn (/home/andreas/work/mocha/lib/runnable.js:247:21)
at Test.Runnable.run (/home/andreas/work/mocha/lib/runnable.js:240:7)
at Runner.runTest (/home/andreas/work/mocha/lib/runner.js:373:10)
at /home/andreas/work/mocha/lib/runner.js:451:12
at next (/home/andreas/work/mocha/lib/runner.js:298:14)
at /home/andreas/work/mocha/lib/runner.js:308:7
at next (/home/andreas/work/mocha/lib/runner.js:246:23)
at Object._onImmediate (/home/andreas/work/mocha/lib/runner.js:275:5)
at processImmediate [as _immediateCallback] (timers.js:330:15)

3) assets/Html #minify() should trim trailing whitespace in inline tag followed by leading whitespace in the child node of the next sibling:

Error: expected '

foo bar

' to minify to '

foo bar

'
+ expected - actual

+

foo bar

-

foobar

at Context. (/home/andreas/work/assetgraph/test/assets/Html.js:420:13)
at callFn (/home/andreas/work/mocha/lib/runnable.js:247:21)
at Test.Runnable.run (/home/andreas/work/mocha/lib/runnable.js:240:7)
at Runner.runTest (/home/andreas/work/mocha/lib/runner.js:373:10)
at /home/andreas/work/mocha/lib/runner.js:451:12
at next (/home/andreas/work/mocha/lib/runner.js:298:14)
at /home/andreas/work/mocha/lib/runner.js:308:7
at next (/home/andreas/work/mocha/lib/runner.js:246:23)
at Object._onImmediate (/home/andreas/work/mocha/lib/runner.js:275:5)
at processImmediate [as _immediateCallback] (timers.js:330:15)
```

There http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace explains the underlying issue very well and concludes:

> For example, markup like `foo bar` is usually displayed as “foo bar” in browsers, with one space character in between two words. White space in markup is represented as text node in document tree. This text node’s value is a white space (e.g. U+0020), and as long as two adjacent elements are inline-level—as they are in this example—it is this white space that contributes to a gap in between “foo” and “bar”. As soon as we remove that white space (i.e. changing markup to `foobar`), representation changes from “foo bar” to “foobar”.

I remember adding all that code that tries to distinguish between inline and block level contexts and adjust the treatment of whitespace accordingly after we had a bug in an app where the previous, slightly more aggressive algorithm made a space between two words disappear. The question is -- should we

1) Ignore the issue and just remove the failing tests
2) Implement Html.minify's current behavior in html-minifier and try to upstream it
3) follow the author of html-minifier's advice and not "rely on such white space for document representation, and instead style elements to have margins and paddings as needed"