magnars / optimus

A Ring middleware for frontend performance optimization.
364 stars 23 forks source link

Can't bundle CSS containing behavior:url(#id) #41

Closed arohner closed 9 years ago

arohner commented 9 years ago

Try to bundle https://github.com/mapbox/mapbox.js/ 's css, which contains:

.foo { behavior:url(#default#VML); } [1]

When trying to load the bundle, you'll get an exception like:

Caused by: java.io.FileNotFoundException: /home/ubuntu/rasterize/resources/public/bower/mapbox.js (Is a directory)
 at java.io.FileInputStream.open0 (FileInputStream.java:-2)
    java.io.FileInputStream.open (FileInputStream.java:195)
    java.io.FileInputStream.<init> (FileInputStream.java:138)
    clojure.java.io/fn (io.clj:238)
    clojure.java.io$fn__9102$G__9095__9109.invoke (io.clj:69)
    clojure.java.io/fn (io.clj:165)
    clojure.java.io$fn__9115$G__9091__9122.invoke (io.clj:69)
    clojure.java.io$reader.doInvoke (io.clj:102)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invoke (core.clj:632)
    clojure.core$slurp.doInvoke (core.clj:6653)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    optimus.optimizations.add_cache_busted_expires_headers$get_contents.invoke (add_cache_busted_expires_headers.clj:18)
    optimus.optimizations.add_cache_busted_expires_headers$add_cache_busted_expires_header.invoke (add_cache_busted_expires_headers.clj:23)
    optimus.optimizations.add_cache_busted_expires_headers$add_cache_busted_expires_headers_in_order.invoke (add_cache_busted_expires_headers.clj:68)
    optimus.optimizations.add_cache_busted_expires_headers$add_cache_busted_expires_headers.invoke (add_cache_busted_expires_headers.clj:74)
    rasterize.http.assets$full_optimizations.invoke (assets.clj:30)
    optimus.strategies$serve_frozen_assets.invoke (strategies.clj:40)
    optimus.prime$wrap.doInvoke (prime.clj:4)
    clojure.lang.RestFn.invoke (RestFn.java:470)
    rasterize.http.assets$wrap_assets.invoke (assets.clj:38)
    rasterize.http.app.WebApp.start (app.clj:94)

It looks like what's happening is that optimus.assets.load-css first converts url(#default#VML) to an absolute url: "/bower/mapbox.js/#default#VML", and then calls remove-url-appendages which leaves "/bower/mapbox.js/"as an asset path. Code downstream tries to slurp, and throws the 'is a directory' exception.

[1] - This appears to be an IE CSS extension: http://stackoverflow.com/questions/26339276/what-is-behavior-url-property-in-css

magnars commented 9 years ago

Wow, that is a peculiar use of url - targeting a DOM element. Even IE has stopped supporting it. I'm inclined to say "won't fix", in particular because behavior URLs can also be actual URLs - and because load-css doesn't do any CSS-parsing (it leaves that to clean-css). I guess the code could know that, while "#foo" is a valid relative url, it does not make sense as a CSS url, so leave it alone.

Any thoughts?

magnars commented 9 years ago

I came to the conclusion that it was safe to just leave URLs starting with # alone. 0.17.2 is released. Please let me know if that solved your issue.

arohner commented 9 years ago

I came to the conclusion that it was safe to just leave URLs starting with # alone

That's the solution I was going to propose. Looks like 0.17.2 works for me. Thanks for the quick turnaround!

magnars commented 9 years ago

:+1: