vaadin / flow

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

Element.getTextRecursively returns empty string #3668

Open mvysny opened 6 years ago

mvysny commented 6 years ago

Calling getTextRecursively() on an Element always returns an empty string. That is to be expected since it uses getChildren() for recursive traversal, however that method only returns Elements, so a Text node is never found and thus no text is discovered.

mvysny commented 6 years ago

Perhaps I'm wrong and Element can in fact be a Textual node. Regardless, I have an Element whose toString() says <template class="header"> Name </template> (it's basically Grid's header made sortable), but calling getTextRecursively() on this element returns an empty string.

mvysny commented 6 years ago

Workaround: This Kotlin code works properly.

val Element.textRecursively2: String get() {
    val node = ElementUtil.toJsoup(Document(""), this)
    return node.textRecursively
}

val Node.textRecursively: String get() = when (this) {
    is TextNode -> this.text()
    else -> childNodes().joinToString(separator = "", transform = { it.textRecursively })
}
Legioth commented 6 years ago

We have a bunch of tests in com.vaadin.flow.dom.ElementTest that assert that getTextRecursively() returns various non-empty values.

The reason in your case is most likely that the <template> element is configured with an innerHTML property instead of having a proper text node child. <template> elements work in a special way in the browser, so regular child elements are ignored. We must instead pass the contents as innerHTML to make it work.