vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
618 stars 167 forks source link

Static resources are not found if referenced from frontend folder #2644

Closed SomeoneToIgnore closed 7 years ago

SomeoneToIgnore commented 7 years ago

Take the skeleton app, modify src/main/webapp/frontend/ExampleTemplate.html file to reference something in the same folder.

For instance, if we add src/main/webapp/frontend/images/puppy.jpg file and have ExampleTemplate.html contents as

<!-- Dependency resources -->
<link rel="import" href="./bower_components/polymer/polymer-element.html">

<!-- Defines the example-template element -->
<dom-module id="example-template">
    <template>
        <style>
            .puppy {
                width: 300px;
                height: 300px;
                background-image: url("images/puppy.jpg");
                background-size: 300px 300px;
            }
        </style>
        <div class="puppy"></div>
        <img src="images/puppy.jpg">
    </template>

    <!-- Polymer boilerplate to register the example-template element -->
    <script>
        class ExampleTemplate extends Polymer.Element {
            static get is() {
                return 'example-template'
            }
        }
        customElements.define(ExampleTemplate.is, ExampleTemplate);
    </script>
</dom-module>

the background-image: url("images/puppy.jpg"); works and shows the image, but <img src="images/puppy.jpg"> does not.

This is wrong and should be behaving the similar way.

The root cause with <img src="images/puppy.jpg"> is in StaticFileServer#isStaticResourceRequest method: request.getServletContext().getResource(requestFilename); returns null for request Request(GET //localhost:8080/images/puppy.jpg), since the image in context is actually located at /frontend/images/puppy.jpg, but we look it as /images/puppy.jpg in the context.

Legioth commented 7 years ago

What would the expected behaviour be?

SomeoneToIgnore commented 7 years ago

I would prefer the img url to be resolved correctly with the help of the framework.

Legioth commented 7 years ago

What does "correctly" mean in this context?

SomeoneToIgnore commented 7 years ago

I would expect it to find the image in both cases.

Legioth commented 7 years ago

Please elaborate

SomeoneToIgnore commented 7 years ago

In the example above, both background-image: url("images/puppy.jpg"); and <img src="images/puppy.jpg"> in the same file should behave the same way: either display the image in both cases or not display image in both cases.

For now we get that background-image: url("images/puppy.jpg"); displays the image and <img src="images/puppy.jpg"> does not which some people find confusing.

Legioth commented 7 years ago

That's the way browsers, HTML and CSS are specified, even though it gets slightly confusing in the case <style> inside an HTML import.

URLs in CSS are relative to the location of the file containing the CSS (ish) whereas URLs in HTML are relative to the base URI of the HTML document (except other HTML imports).

I see two ways of "fixing" that

SomeoneToIgnore commented 7 years ago

I don't really find the first solution confusing (since we do something similar with es6/es5 already) and that's what I've expected to be done.

My idea was that we might cause a lot of questions for users that won't understand why the same urls in the same files behave differently. For instance, users that have almost no frontend background at all. And them would be the ones you'd be forced to explain these things to. If you're fine with this, the ticket can be closed.

Legioth commented 7 years ago

We are not rewriting any HTML to change semantics, only to package them more efficiently. If we were to do that, we also have to define exactly under which conditions what kinds of changes are done, so that we don't break any expectations of e.g. templates implemented for standalone use and then imported into a Flow project.

SomeoneToIgnore commented 7 years ago

Sorry, got the wrong answer, I think it's the 2nd one. What I mean is that we can modify StaticFileServer to be able to find those files and serve them.

Legioth commented 7 years ago

My guess that it would in the long run be much more confusing that the same resource would in some cases be available through multiple URLs, but then there would inevitably be cases where that isn't the case (e.g. if different files with the same name are present in the same location or in a production deployment when static files are served from a dedicated frontend server instead of going through to the app server / servlet).

There are simply some frontend things that developers might have to learn if they want to fully utilize the template functionality. I'd say that someone using something like <style> with a background-image in their template is already way beyond that level.