Class Html
- All Implemented Interfaces:
AttachNotifier,DetachNotifier,HasElement,HasStyle,Serializable
Note that it is the developer's responsibility to sanitize and remove any dangerous parts of the HTML before sending it to the user through this component. Passing raw input data to the user will possibly lead to cross-site scripting attacks.
To help with sanitization, a jsoup Safelist of permitted elements and
attributes can be configured through a safelist-accepting constructor. Once
configured, all content applied to the component — the initial value
and any value later set through setHtmlContent(String) or pushed by
a bound signal — is sanitized with it, so any element or attribute that
the safelist doesn't permit is removed. The safelist is fixed at construction
and cannot be changed afterwards.
jsoup's Safelist is not Serializable, but a
Vaadin component must be serializable (sessions can be persisted to disk or
replicated across a cluster). Storing a Safelist directly would break
session serialization, so the safelist is supplied through a
SerializableSupplier — a serializable factory that is invoked
to build the safelist — rather than as a Safelist instance.
For the supplier to be serializable, it must not capture a (non-serializable)
Safelist instance. Use a method reference to a factory, or a lambda
that builds a new safelist inline:
// Method reference to a standard jsoup factory; relaxed() permits common
// block elements such as <div>:
new Html(untrustedHtml, Safelist::relaxed);
// Lambda that builds a fresh safelist inline (captures nothing); basic()
// does not permit <div>, so it is added explicitly:
new Html(untrustedHtml, () -> Safelist.basic().addTags("div"));
// A reusable supplier kept in a static field:
static final SerializableSupplier<Safelist> SAFELIST = () -> Safelist
.relaxed().addAttributes("a", "target");
new Html(untrustedHtml, SAFELIST);
Do not capture an already-built Safelist in the supplier: that
puts the non-serializable instance back into the component's state and fails
session serialization:
Safelist safelist = Safelist.basic();
// BAD: captures the non-serializable Safelist instance
new Html(untrustedHtml, () -> safelist);
The supplier is invoked when the component is created (and again lazily on
the next sanitization after deserialization, since the cached safelist is
transient), not on every sanitization, so it should return an
equivalent safelist on each call and must not return null.
The safelist must permit the fragment's single root element; otherwise the
root is stripped and the resulting fragment no longer has exactly one root
element. Note that Safelist.basic() does not permit <div>, so
a <div>-rooted fragment requires e.g.
Safelist.basic().addTags("div") or Safelist.relaxed().
This component does not expand the HTML fragment into a server side DOM tree
so you cannot traverse or modify the HTML on the server. The root element can
be accessed through Component.getElement() and the inner HTML through
getInnerHtml().
The inner content and attributes can be changed after creation through
setHtmlContent(String) or by binding a signal, but the root tag
cannot be changed.
Note that this component doesn't support svg element as a root node. See
separate Svg component if you want to display SVG images.
- Since:
- 1.0
- Author:
- Vaadin Ltd
- See Also:
-
Constructor Summary
ConstructorsConstructorDescriptionCreates an instance based on the given HTML fragment signal.Html(Signal<String> htmlSignal, SerializableSupplier<org.jsoup.safety.Safelist> safelistSupplier) Creates an instance based on the given HTML fragment signal, with every value sanitized using the safelist obtained from the given supplier.Html(InputStream stream) Creates an instance based on the HTML fragment read from the stream.Html(InputStream stream, SerializableSupplier<org.jsoup.safety.Safelist> safelistSupplier) Creates an instance based on the HTML fragment read from the stream, sanitized using the safelist obtained from the given supplier.Creates an instance based on the given HTML fragment.Html(String outerHtml, SerializableSupplier<org.jsoup.safety.Safelist> safelistSupplier) Creates an instance based on the given HTML fragment, sanitized using the safelist obtained from the given supplier. -
Method Summary
Modifier and TypeMethodDescriptionbindHtmlContent(Signal<String> htmlSignal) Binds aSignal's value to this component's HTML content (outer HTML).Gets the inner HTML, i.e.voidsetHtmlContent(String html) Sets the content based on the given HTML fragment.Methods inherited from class com.vaadin.flow.component.Component
addListener, bindVisible, findAncestor, fireEvent, from, get, getChildren, getElement, getEventBus, getId, getListeners, getLocale, getParent, getTestId, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getUI, hasListener, isAttached, isTemplateMapped, isVisible, onAttach, onDetach, onEnabledStateChanged, removeFromParent, scrollIntoView, scrollIntoView, set, setElement, setId, setTestId, setVisibleMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface com.vaadin.flow.component.AttachNotifier
addAttachListenerMethods inherited from interface com.vaadin.flow.component.DetachNotifier
addDetachListenerMethods inherited from interface com.vaadin.flow.component.HasStyle
addClassName, addClassNames, bindClassName, bindClassNames, getClassName, getClassNames, getStyle, hasClassName, removeClassName, removeClassNames, setClassName, setClassName
-
Constructor Details
-
Html
Creates an instance based on the HTML fragment read from the stream. The fragment must have exactly one root element.A best effort is done to parse broken HTML but no guarantees are given for how invalid HTML is handled.
Any heading or trailing whitespace is removed while parsing but any whitespace inside the root tag is preserved.
- Parameters:
stream- the input stream which provides the HTML in UTF-8- Throws:
UncheckedIOException- if reading the stream fails
-
Html
Creates an instance based on the HTML fragment read from the stream, sanitized using the safelist obtained from the given supplier. The fragment must have exactly one root element after sanitization.The supplier is also stored on the component, so any later content change via
setHtmlContent(String)or a bound signal is sanitized with it as well. Any element or attribute that the safelist doesn't permit is removed. The safelist must permit the root element.A best effort is done to parse broken HTML but no guarantees are given for how invalid HTML is handled.
Any heading or trailing whitespace is removed while parsing but any whitespace inside the root tag is preserved.
- Parameters:
stream- the input stream which provides the HTML in UTF-8safelistSupplier- supplies the safelist of permitted elements and attributes, notnull- Throws:
UncheckedIOException- if reading the stream failsNullPointerException- if the supplier isnull- Since:
- 25.2
-
Html
Creates an instance based on the given HTML fragment. The fragment must have exactly one root element.A best effort is done to parse broken HTML but no guarantees are given for how invalid HTML is handled.
Any heading or trailing whitespace is removed while parsing but any whitespace inside the root tag is preserved.
- Parameters:
outerHtml- the HTML to wrap
-
Html
Creates an instance based on the given HTML fragment, sanitized using the safelist obtained from the given supplier. The fragment must have exactly one root element after sanitization.The supplier is also stored on the component, so any later content change via
setHtmlContent(String)or a bound signal is sanitized with it as well. Any element or attribute that the safelist doesn't permit is removed. The safelist must permit the root element.A best effort is done to parse broken HTML but no guarantees are given for how invalid HTML is handled.
Any heading or trailing whitespace is removed while parsing but any whitespace inside the root tag is preserved.
- Parameters:
outerHtml- the HTML to wrapsafelistSupplier- supplies the safelist of permitted elements and attributes, notnull- Throws:
NullPointerException- if the supplier isnull- Since:
- 25.2
-
Html
Creates an instance based on the given HTML fragment signal. The signal's current value must have exactly one root element. Subsequent changes to the signal will update the component's content (root tag cannot be changed after creation).- Parameters:
htmlSignal- the signal that provides the HTML outer content- Throws:
IllegalArgumentException- if the signal isnullor its current value is null or empty, or doesn't have exactly one root element- Since:
- 25.1
-
Html
public Html(Signal<String> htmlSignal, SerializableSupplier<org.jsoup.safety.Safelist> safelistSupplier) Creates an instance based on the given HTML fragment signal, with every value sanitized using the safelist obtained from the given supplier. The signal's current value must have exactly one root element after sanitization. Subsequent changes to the signal will update the component's content (root tag cannot be changed after creation).The supplier is stored on the component, so both the initial value and every subsequent value are sanitized with it. Any element or attribute that the safelist doesn't permit is removed. The safelist must permit the root element.
- Parameters:
htmlSignal- the signal that provides the HTML outer contentsafelistSupplier- supplies the safelist of permitted elements and attributes, notnull- Throws:
IllegalArgumentException- if the signal isnullor its current value is null or empty, or doesn't have exactly one root elementNullPointerException- if the supplier isnull- Since:
- 25.2
-
-
Method Details
-
setHtmlContent
Sets the content based on the given HTML fragment. The fragment must have exactly one root element, which matches the existing one.If a safelist supplier was provided at construction, the content is sanitized with it before being used.
A best effort is done to parse broken HTML but no guarantees are given for how invalid HTML is handled.
Any heading or trailing whitespace is removed while parsing but any whitespace inside the root tag is preserved.
- Parameters:
html- the HTML to wrap- Since:
- 23.3
-
getInnerHtml
Gets the inner HTML, i.e. everything inside the root element.- Returns:
- the inner HTML, not
null
-
bindHtmlContent
Binds aSignal's value to this component's HTML content (outer HTML). The content is set immediately with the current signal value when the binding is created, and is kept synchronized with any subsequent signal value changes while the component is attached. When the component is detached, signal value changes have no effect.If a safelist supplier was provided at construction, every value — the initial one and each subsequent change — is sanitized with it, so any element or attribute that the safelist doesn't permit is removed.
While a Signal is bound to the HTML content, any attempt to set the HTML content manually via
setHtmlContent(String)throwsBindingActiveException. The same happens when trying to bind a new Signal while one is already bound.The first value of the signal must have exactly one root element. When updating the content, the root tag name must remain the same as the component's current root tag. A
nullor empty signal value is rejected with anIllegalArgumentException.- Parameters:
htmlSignal- the signal to bind, notnull- Throws:
BindingActiveException- thrown when there is already an existing binding- Since:
- 25.1
-