vaadin / flow-components

Java counterpart of Vaadin Web Components
101 stars 66 forks source link

Vaadin RTE can't set HTML content with <img src='image url'> tag #1200

Open bishwajitcse opened 4 years ago

bishwajitcse commented 4 years ago

We have some html contents with image tag and image getting from url link. But when trying to set this html content in RTE, the image is missing in editor. Here my code:

@Route("") @PWA(name = "Project Base for Vaadin", shortName = "Project Base") public class MainView extends VerticalLayout {

String htmlContent = "<div> Vaadin RTE can't set html content with image link "
        + "<img width='300px' height='200px' src='https://images.unsplash.com/photo-1521478413868-1bbd982fa4a5?ixlib=rb-1.2.1&w=1000&q=80' /> </div>";

Div imgContent= new Div();
RichTextEditor rte = new RichTextEditor();

public MainView() {

    Button button = new Button("Set Html Content with Image Link",
            event -> {
                rte.asHtml().setValue(htmlContent);
            });

    rte.asHtml().setValue(htmlContent);
    imgContent.add(new Html("<span>" + htmlContent + "</span>"));

    add(button);
    add(imgContent);
    add(rte);
}

}

I also attached a sample demo project here. vaadinrte.zip

Haprog commented 4 years ago

I think this is due to the default (pretty strict) sanitization that is done for the HTML string by RichTextEditor here: RichTextEditor.java#L253-L260

I'm not too familiar with how this Jsoup whitelisting works but I think this .addProtocols("img", "src", "data") only allows images which define the src as a data URI e.g. <img src="data:image/jpeg;base64,...

This is in line with how the vaadin-rich-text-editor web component works since if you add an image to it using the image button on the toolbar it will add it as a data URI. As far as I see there is no way to add or edit an image with a URL using the editor UI. I think the only way to do that would be using the JS method dangerouslySetHtmlValue() to set the HTML value of the editor (which can be a security risk in case the HTML value used is not fully trusted).

Currently there is no similar "dangerous" (unsanitized) version of this on the Java API but you could workaround it by calling the above JS method directly from Java. Something like this:

rte.getElement().executeJs("this.dangerouslySetHtmlValue($0)", htmlContent);
Haprog commented 4 years ago

But even if you set the HTML value as above containing an image with a URL source, it might not satisfy you since you can't edit the image URL in the RTE UI anyway.

Other option you have would be to first convert the image you want to a data URI and pass that in the HTML value for the image (download the image on the server side and use some library or your own method to convert it to a data URI).