All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.elemento.Elements Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright 2023 Red Hat
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.jboss.elemento;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.gwtproject.event.shared.HandlerRegistration;
import org.gwtproject.safehtml.shared.SafeHtml;

import elemental2.core.JsArray;
import elemental2.dom.CSSStyleDeclaration;
import elemental2.dom.DOMRect;
import elemental2.dom.Element;
import elemental2.dom.HTMLAnchorElement;
import elemental2.dom.HTMLAreaElement;
import elemental2.dom.HTMLAudioElement;
import elemental2.dom.HTMLBRElement;
import elemental2.dom.HTMLBodyElement;
import elemental2.dom.HTMLButtonElement;
import elemental2.dom.HTMLCanvasElement;
import elemental2.dom.HTMLDListElement;
import elemental2.dom.HTMLDataListElement;
import elemental2.dom.HTMLDivElement;
import elemental2.dom.HTMLElement;
import elemental2.dom.HTMLEmbedElement;
import elemental2.dom.HTMLFieldSetElement;
import elemental2.dom.HTMLFormElement;
import elemental2.dom.HTMLHRElement;
import elemental2.dom.HTMLHeadingElement;
import elemental2.dom.HTMLIFrameElement;
import elemental2.dom.HTMLImageElement;
import elemental2.dom.HTMLInputElement;
import elemental2.dom.HTMLLIElement;
import elemental2.dom.HTMLLabelElement;
import elemental2.dom.HTMLLegendElement;
import elemental2.dom.HTMLMapElement;
import elemental2.dom.HTMLMeterElement;
import elemental2.dom.HTMLModElement;
import elemental2.dom.HTMLOListElement;
import elemental2.dom.HTMLObjectElement;
import elemental2.dom.HTMLOptGroupElement;
import elemental2.dom.HTMLOptionElement;
import elemental2.dom.HTMLOutputElement;
import elemental2.dom.HTMLParagraphElement;
import elemental2.dom.HTMLParamElement;
import elemental2.dom.HTMLPictureElement;
import elemental2.dom.HTMLPreElement;
import elemental2.dom.HTMLProgressElement;
import elemental2.dom.HTMLQuoteElement;
import elemental2.dom.HTMLScriptElement;
import elemental2.dom.HTMLSelectElement;
import elemental2.dom.HTMLSourceElement;
import elemental2.dom.HTMLTableCaptionElement;
import elemental2.dom.HTMLTableCellElement;
import elemental2.dom.HTMLTableColElement;
import elemental2.dom.HTMLTableElement;
import elemental2.dom.HTMLTableRowElement;
import elemental2.dom.HTMLTableSectionElement;
import elemental2.dom.HTMLTextAreaElement;
import elemental2.dom.HTMLTrackElement;
import elemental2.dom.HTMLUListElement;
import elemental2.dom.HTMLVideoElement;
import elemental2.dom.Node;
import elemental2.dom.NodeList;
import jsinterop.base.Js;
import jsinterop.base.JsArrayLike;

import static elemental2.dom.DomGlobal.document;
import static elemental2.dom.DomGlobal.window;
import static java.util.Collections.emptyIterator;
import static java.util.Collections.emptyList;
import static java.util.Spliterators.spliteratorUnknownSize;
import static jsinterop.base.Js.cast;
import static jsinterop.base.Js.isTripleEqual;
import static jsinterop.base.Js.undefined;
import static org.jboss.elemento.BodyObserver.addAttachObserver;
import static org.jboss.elemento.EventType.bind;
import static org.jboss.elemento.EventType.resize;

/**
 * Builder and helper methods for working with {@link elemental2.dom.HTMLElement}s and/or {@link IsElement}.
 * 

* {@snippet class = ElementsDemo region = builder} * * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element */ @SuppressWarnings({"unused", "ConfusingMainMethod"}) public final class Elements { // ------------------------------------------------------ body /** * Returns an HTML content builder for the document body. */ public static HTMLContainerBuilder body() { return new HTMLContainerBuilder<>(document.body); } // ------------------------------------------------------ content sectioning public static HTMLContainerBuilder address() { return htmlContainer("address", HTMLElement.class); } public static HTMLContainerBuilder address(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder article() { return htmlContainer("article", HTMLElement.class); } public static HTMLContainerBuilder article(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder aside() { return htmlContainer("aside", HTMLElement.class); } public static HTMLContainerBuilder aside(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder footer() { return htmlContainer("footer", HTMLElement.class); } public static HTMLContainerBuilder footer(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder h(int n) { return htmlContainer("h" + n, HTMLHeadingElement.class); } public static HTMLContainerBuilder h(int n, String text) { return h(n).textContent(text); } public static HTMLContainerBuilder h(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder header() { return htmlContainer("header", HTMLElement.class); } public static HTMLContainerBuilder header(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder hgroup() { return htmlContainer("hgroup", HTMLElement.class); } public static HTMLContainerBuilder hgroup(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder nav() { return htmlContainer("nav", HTMLElement.class); } public static HTMLContainerBuilder nav(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder section() { return htmlContainer("section", HTMLElement.class); } public static HTMLContainerBuilder section(Element element) { return wrapHtmlContainer(cast(element)); } // ------------------------------------------------------ text content public static HTMLContainerBuilder blockquote() { return htmlContainer("blockquote", HTMLQuoteElement.class); } public static HTMLContainerBuilder blockquote(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder dd() { return htmlContainer("dd", HTMLElement.class); } public static HTMLContainerBuilder dd(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder div() { return htmlContainer("div", HTMLDivElement.class); } public static HTMLContainerBuilder div(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder dl() { return htmlContainer("dl", HTMLDListElement.class); } public static HTMLContainerBuilder dl(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder dt() { return htmlContainer("dt", HTMLElement.class); } public static HTMLContainerBuilder dt(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder figcaption() { return htmlContainer("figcaption", HTMLElement.class); } public static HTMLContainerBuilder figcaption(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder figure() { return htmlContainer("figure", HTMLElement.class); } public static HTMLContainerBuilder figure(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder hr() { return htmlElement("hr", HTMLHRElement.class); } public static HTMLElementBuilder hr(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder li() { return htmlContainer("li", HTMLLIElement.class); } public static HTMLContainerBuilder li(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder main() { return htmlContainer("main", HTMLElement.class); } public static HTMLContainerBuilder main(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder ol() { return htmlContainer("ol", HTMLOListElement.class); } public static HTMLContainerBuilder ol(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder p() { return htmlContainer("p", HTMLParagraphElement.class); } public static HTMLContainerBuilder p(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder pre() { return htmlContainer("pre", HTMLPreElement.class); } public static HTMLContainerBuilder pre(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder ul() { return htmlContainer("ul", HTMLUListElement.class); } public static HTMLContainerBuilder ul(Element element) { return wrapHtmlContainer(cast(element)); } // ------------------------------------------------------ inline text semantics public static HTMLContainerBuilder a() { return htmlContainer("a", HTMLAnchorElement.class); } public static HTMLContainerBuilder a(String href) { return a().attr("href", href); } public static HTMLContainerBuilder a(String href, String target) { return a().attr("href", href).attr("target", target); } public static HTMLContainerBuilder a(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder abbr() { return htmlContainer("abbr", HTMLElement.class); } public static HTMLContainerBuilder abbr(String text) { return htmlContainer("abbr", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder abbr(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder b() { return htmlContainer("b", HTMLElement.class); } public static HTMLContainerBuilder b(String text) { return htmlContainer("b", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder b(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder br() { return htmlElement("br", HTMLBRElement.class); } public static HTMLElementBuilder br(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder cite() { return htmlContainer("cite", HTMLElement.class); } public static HTMLContainerBuilder cite(String text) { return htmlContainer("cite", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder cite(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder code() { return htmlContainer("code", HTMLElement.class); } public static HTMLContainerBuilder code(String text) { return htmlContainer("code", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder code(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder dfn() { return htmlContainer("dfn", HTMLElement.class); } public static HTMLContainerBuilder dfn(String text) { return htmlContainer("dfn", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder dfn(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder em() { return htmlContainer("em", HTMLElement.class); } public static HTMLContainerBuilder em(String text) { return htmlContainer("em", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder em(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder i() { return htmlContainer("i", HTMLElement.class); } public static HTMLContainerBuilder i(String text) { return htmlContainer("i", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder i(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder kbd() { return htmlContainer("kbd", HTMLElement.class); } public static HTMLContainerBuilder kbd(String text) { return htmlContainer("kbd", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder kbd(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder mark() { return htmlContainer("mark", HTMLElement.class); } public static HTMLContainerBuilder mark(String text) { return htmlContainer("mark", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder mark(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder q() { return htmlContainer("q", HTMLQuoteElement.class); } public static HTMLContainerBuilder q(String text) { return htmlContainer("q", HTMLQuoteElement.class).textContent(text); } public static HTMLContainerBuilder q(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder small() { return htmlContainer("small", HTMLElement.class); } public static HTMLContainerBuilder small(String text) { return htmlContainer("small", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder small(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder span() { return htmlContainer("span", HTMLElement.class); } public static HTMLContainerBuilder span(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder strong() { return htmlContainer("strong", HTMLElement.class); } public static HTMLContainerBuilder strong(String text) { return htmlContainer("strong", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder strong(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder sub() { return htmlContainer("sub", HTMLElement.class); } public static HTMLContainerBuilder sub(String text) { return htmlContainer("sub", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder sub(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder sup() { return htmlContainer("sup", HTMLElement.class); } public static HTMLContainerBuilder sup(String text) { return htmlContainer("sup", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder sup(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder time() { return htmlContainer("time", HTMLElement.class); } public static HTMLContainerBuilder time(String text) { return htmlContainer("time", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder time(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder u() { return htmlContainer("u", HTMLElement.class); } public static HTMLContainerBuilder u(String text) { return htmlContainer("u", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder u(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder var() { return htmlContainer("var", HTMLElement.class); } public static HTMLContainerBuilder var(String text) { return htmlContainer("var", HTMLElement.class).textContent(text); } public static HTMLContainerBuilder var(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder wbr() { return htmlElement("wbr", HTMLElement.class); } public static HTMLElementBuilder wbr(Element element) { return wrapHtmlElement(cast(element)); } // ------------------------------------------------------ image and multimedia public static HTMLElementBuilder area() { return htmlElement("area", HTMLAreaElement.class); } public static HTMLElementBuilder area(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder audio() { return htmlContainer("audio", HTMLAudioElement.class); } public static HTMLContainerBuilder audio(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder img() { return htmlElement("img", HTMLImageElement.class); } public static HTMLElementBuilder img(String src) { return htmlElement("img", HTMLImageElement.class).attr("src", src); } public static HTMLElementBuilder img(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder map() { return htmlContainer("map", HTMLMapElement.class); } public static HTMLContainerBuilder map(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder picture() { return htmlContainer("picture", HTMLPictureElement.class); } public static HTMLContainerBuilder picture(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder track() { return htmlElement("track", HTMLTrackElement.class); } public static HTMLElementBuilder track(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder video() { return htmlContainer("video", HTMLVideoElement.class); } public static HTMLContainerBuilder video(Element element) { return wrapHtmlContainer(cast(element)); } // ------------------------------------------------------ embedded content public static HTMLContainerBuilder canvas() { return htmlContainer("canvas", HTMLCanvasElement.class); } public static HTMLContainerBuilder canvas(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder embed() { return htmlElement("embed", HTMLEmbedElement.class); } public static HTMLElementBuilder embed(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder iframe() { return htmlContainer("iframe", HTMLIFrameElement.class); } public static HTMLContainerBuilder iframe(String src) { return iframe().attr("src", src); } public static HTMLContainerBuilder iframe(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder object() { return htmlContainer("object", HTMLObjectElement.class); } public static HTMLContainerBuilder object(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder param() { return htmlElement("param", HTMLParamElement.class); } public static HTMLElementBuilder param(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLElementBuilder source() { return htmlElement("source", HTMLSourceElement.class); } public static HTMLElementBuilder source(Element element) { return wrapHtmlElement(cast(element)); } // ------------------------------------------------------ scripting public static HTMLContainerBuilder noscript() { return htmlContainer("noscript", HTMLElement.class); } public static HTMLContainerBuilder noscript(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder script() { return htmlElement("script", HTMLScriptElement.class); } public static HTMLElementBuilder script(Element element) { return wrapHtmlElement(cast(element)); } // ------------------------------------------------------ demarcating edits public static HTMLContainerBuilder del() { return htmlContainer("del", HTMLModElement.class); } public static HTMLContainerBuilder del(String text) { return htmlContainer("del", HTMLModElement.class).textContent(text); } public static HTMLContainerBuilder del(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder ins() { return htmlContainer("ins", HTMLModElement.class); } public static HTMLContainerBuilder ins(String text) { return htmlContainer("ins", HTMLModElement.class).textContent(text); } public static HTMLContainerBuilder ins(Element element) { return wrapHtmlContainer(cast(element)); } // ------------------------------------------------------ table content public static HTMLContainerBuilder caption() { return htmlContainer("caption", HTMLTableCaptionElement.class); } public static HTMLContainerBuilder caption(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder col() { return htmlElement("col", HTMLTableColElement.class); } public static HTMLElementBuilder col(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder colgroup() { return htmlContainer("colgroup", HTMLTableColElement.class); } public static HTMLContainerBuilder colgroup(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder table() { return htmlContainer("table", HTMLTableElement.class); } public static HTMLContainerBuilder table(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder tbody() { return htmlContainer("tbody", HTMLTableSectionElement.class); } public static HTMLContainerBuilder tbody(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder td() { return htmlContainer("td", HTMLTableCellElement.class); } public static HTMLContainerBuilder td(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder tfoot() { return htmlContainer("tfoot", HTMLTableSectionElement.class); } public static HTMLContainerBuilder tfoot(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder th() { return htmlContainer("th", HTMLTableCellElement.class); } public static HTMLContainerBuilder th(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder thead() { return htmlContainer("thead", HTMLTableSectionElement.class); } public static HTMLContainerBuilder thead(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder tr() { return htmlContainer("tr", HTMLTableRowElement.class); } public static HTMLContainerBuilder tr(Element element) { return wrapHtmlContainer(cast(element)); } // ------------------------------------------------------ forms public static HTMLContainerBuilder button() { return htmlContainer("button", HTMLButtonElement.class); } public static HTMLContainerBuilder button(ButtonType type) { HTMLButtonElement button = createHtmlElement("button", HTMLButtonElement.class); button.type = type.name(); return new HTMLContainerBuilder<>(button); } public static HTMLContainerBuilder button(String text) { return button().textContent(text); } public static HTMLContainerBuilder button(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder datalist() { return htmlContainer("datalist", HTMLDataListElement.class); } public static HTMLContainerBuilder datalist(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder fieldset() { return htmlContainer("fieldset", HTMLFieldSetElement.class); } public static HTMLContainerBuilder fieldset(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder form() { return htmlContainer("form", HTMLFormElement.class); } public static HTMLContainerBuilder form(Element element) { return wrapHtmlContainer(cast(element)); } public static InputElementBuilder input(InputType type) { return input(type.name()); } public static InputElementBuilder input(String type) { return input(type, HTMLInputElement.class); } public static InputElementBuilder input(String type, Class jType) { E el = createHtmlElement("input", jType); el.type = type; return new InputElementBuilder<>(el); } public static InputElementBuilder input(Element element) { return wrapInputElement(cast(element)); } public static HTMLContainerBuilder label() { return htmlContainer("label", HTMLLabelElement.class); } public static HTMLContainerBuilder label(String text) { return label().textContent(text); } public static HTMLContainerBuilder label(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder legend() { return htmlContainer("legend", HTMLLegendElement.class); } public static HTMLContainerBuilder legend(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder meter() { return htmlContainer("meter", HTMLMeterElement.class); } public static HTMLContainerBuilder meter(String text) { return htmlContainer("meter", HTMLMeterElement.class).textContent(text); } public static HTMLContainerBuilder meter(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder optgroup() { return htmlContainer("optgroup", HTMLOptGroupElement.class); } public static HTMLContainerBuilder optgroup(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder option() { return htmlElement("option", HTMLOptionElement.class); } public static HTMLElementBuilder option(String text) { return option().textContent(text); } public static HTMLElementBuilder option(Element element) { return wrapHtmlElement(cast(element)); } public static HTMLContainerBuilder output() { return htmlContainer("output", HTMLOutputElement.class); } public static HTMLContainerBuilder output(String text) { return htmlContainer("output", HTMLOutputElement.class).textContent(text); } public static HTMLContainerBuilder output(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder progress() { return htmlContainer("progress", HTMLProgressElement.class); } public static HTMLContainerBuilder progress(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLContainerBuilder select() { return htmlContainer("select", HTMLSelectElement.class); } public static HTMLContainerBuilder select(Element element) { return wrapHtmlContainer(cast(element)); } public static HTMLElementBuilder textarea() { return htmlElement("textarea", HTMLTextAreaElement.class); } public static HTMLElementBuilder textarea(Element element) { return wrapHtmlElement(cast(element)); } // ------------------------------------------------------ factories & wrappers /** * Returns a builder to collect {@link HTMLElement}s. *

* {@snippet class = ElementsBagDemo region = bag} */ public static ElementsBag bag() { return new ElementsBag(); } /** * Returns a builder for the specified HTML element. */ public static HTMLElementBuilder htmlElement(String element, Class type) { return new HTMLElementBuilder<>(createHtmlElement(element, type)); } /** * Returns a builder for the existing HTML element. */ public static HTMLElementBuilder wrapHtmlElement(E element) { return new HTMLElementBuilder<>(element); } /** * Returns a builder for the specified input element. */ public static InputElementBuilder inputElement(String type, Class jType) { E input = createHtmlElement("input", jType); input.type = type; return new InputElementBuilder<>(input); } /** * Returns a builder for the existing input element. */ public static InputElementBuilder wrapInputElement(E element) { return new InputElementBuilder<>(element); } /** * Returns a builder for the specified HTML element. */ public static HTMLContainerBuilder htmlContainer(String element, Class type) { return new HTMLContainerBuilder<>(createHtmlElement(element, type)); } /** * Returns a builder for the existing HTML element. */ public static HTMLContainerBuilder wrapHtmlContainer(E element) { return new HTMLContainerBuilder<>(element); } /** * Creates the specified HTML element. */ public static E createHtmlElement(String element, Class type) { return cast(document.createElement(element)); } // ------------------------------------------------------ finder methods /** * Finds all HTML elements for the given selector. */ public static Iterable findAll(Node node, By selector) { if (node != null) { NodeList nodes = node.querySelectorAll(selector.selector()); JsArray htmlElements = new JsArray<>(); for (int i = 0; i < nodes.length; i++) { Element element = nodes.getAt(i); if (element instanceof HTMLElement) { htmlElements.push((HTMLElement) element); } } return () -> iterator(htmlElements); } return emptyList(); } /** * Finds all HTML elements for the given selector. */ public static Iterable findAll(IsElement element, By selector) { if (element != null) { return findAll(element.element(), selector); } return emptyList(); } /** * Finds a single HTML elements for the given selector. */ public static E find(Node node, By selector) { if (node != null) { return cast(node.querySelector(selector.selector())); } return null; } /** * Finds a single HTML elements for the given selector. */ public static F find(IsElement element, By selector) { if (element != null) { return find(element.element(), selector); } return null; } /** * Finds the closest HTML elements for the given selector. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest */ public static E closest(Element element, By selector) { if (element != null) { return cast(element.closest(selector.selector())); } return null; } /** * Finds the closest HTML elements for the given selector. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest */ public static F closest(IsElement element, By selector) { if (element != null) { return cast(element.element().closest(selector.selector())); } return null; } // ------------------------------------------------------ iterator methods /** * Returns an iterator over the given array-like. The iterator does not support the * {@link Iterator#remove()} operation. */ public static Iterator iterator(JsArrayLike data) { return data != null ? new JsArrayLikeIterator<>(data) : emptyIterator(); } /** * Returns an iterator over the children of the given parent node. The iterator supports the {@link Iterator#remove()} * operation, which removes the current node from its parent. */ public static Iterator iterator(Node parent) { return parent != null ? new JsArrayNodeIterator(parent) : emptyIterator(); } /** * Returns an iterator over the children of the given parent element. The iterator supports the {@link Iterator#remove()} * operation, which removes the current node from its parent. */ public static Iterator iterator(HTMLElement parent) { return parent != null ? new JsArrayElementIterator(parent) : emptyIterator(); } /** * Returns an iterator over the children of the given parent element. The iterator supports the {@link Iterator#remove()} * operation, which removes the current node from its parent. */ public static Iterator iterator(IsElement parent) { return parent != null ? iterator(parent.element()) : emptyIterator(); } // ------------------------------------------------------ iterable methods /** * Returns an iterable for the elements in the given array-like. */ public static Iterable elements(JsArrayLike nodes) { return () -> iterator(nodes); } /** * Returns an iterable for the child nodes of the given parent node. */ public static Iterable children(Node parent) { return () -> iterator(parent); } /** * Returns an iterable for the child elements of the given parent element. */ public static Iterable children(HTMLElement parent) { return () -> iterator(parent); } /** * Returns an iterable for the child elements of the given parent element. */ public static Iterable children(IsElement parent) { return () -> iterator(parent); } // ------------------------------------------------------ predicates and functions /** * Returns a predicate for {@linkplain HTMLElement HTML elements}. Useful in streams of {@linkplain Node nodes} or * {@linkplain Element elements}. */ public static Predicate htmlElements() { return new FilterHTMLElements<>(); } /** * Casts to {@link HTMLElement}. Make sure to {@linkplain #htmlElements() filter} for HTML elements before using this * function. */ public static Function asHtmlElement() { return new AsHTMLElement<>(); } // ------------------------------------------------------ stream methods /** * Returns a stream for the elements in the given array-like. *

* {@snippet class = ElementsDemo region = stream} */ public static Stream stream(JsArrayLike nodes) { if (nodes == null) { return Stream.empty(); } else { return StreamSupport.stream(spliteratorUnknownSize(iterator(nodes), 0), false); } } /** * Returns a stream for the child nodes of the given parent node. *

* {@snippet class = ElementsDemo region = stream} */ public static Stream stream(Node parent) { if (parent == null) { return Stream.empty(); } else { return StreamSupport.stream(spliteratorUnknownSize(iterator(parent), 0), false); } } /** * Returns a stream for the child elements of the given parent element. *

* {@snippet class = ElementsDemo region = stream} */ public static Stream stream(HTMLElement parent) { if (parent == null) { return Stream.empty(); } else { return StreamSupport.stream(spliteratorUnknownSize(iterator(parent), 0), false); } } /** * Returns a stream for the child elements of the given parent element. *

* {@snippet class = ElementsDemo region = stream} */ public static Stream stream(IsElement parent) { if (parent == null) { return Stream.empty(); } else { return StreamSupport.stream(spliteratorUnknownSize(iterator(parent), 0), false); } } // ------------------------------------------------------ append, insert & remove methods /** * Appends element {@code child} to element {@code parent} if not already present. If parent already contains child, this * method does nothing. */ public static void lazyAppend(Element parent, Element child) { if (parent != null && child != null && !parent.contains(child)) { parent.appendChild(child); } } /** * Appends element {@code child} to element {@code parent} if not already present. If parent already contains child, this * method does nothing. */ public static void lazyAppend(Element parent, IsElement child) { if (parent != null && child != null) { lazyAppend(parent, child.element()); } } /** * Inserts element {@code newElement} into the parent after element {@code after}. */ public static void insertAfter(Element newElement, Element after) { if (newElement != null && after != null) { after.parentNode.insertBefore(newElement, after.nextSibling); } } /** * Inserts element {@code newElement} into the parent after element {@code after}. */ public static void insertAfter(IsElement newElement, Element after) { if (newElement != null && after != null) { insertAfter(newElement.element(), after); } } /** * Inserts element {@code newElement} into the parent after element {@code after} if not already present. If parent already * contains {@code newElement}, this method does nothing. */ public static void lazyInsertAfter(Element newElement, Element after) { if (newElement != null && after != null && !after.parentNode.contains(newElement)) { after.parentNode.insertBefore(newElement, after.nextSibling); } } /** * Inserts element {@code newElement} into the parent after element {@code after} if not already present. If parent already * contains {@code newElement}, this method does nothing. */ public static void lazyInsertAfter(IsElement newElement, Element after) { if (newElement != null && after != null) { lazyInsertAfter(newElement.element(), after); } } /** * Inserts element {@code newElement} into the parent after element {@code after} if not already present. If parent already * contains {@code newElement}, this method does nothing. */ public static void lazyInsertAfter(Element parent, Element newElement, Element after) { if (parent != null && newElement != null && after != null && !parent.contains(newElement)) { parent.insertBefore(newElement, after.nextSibling); } } /** * Inserts element {@code newElement} into the parent after element {@code after} if not already present. If parent already * contains {@code newElement}, this method does nothing. */ public static void lazyInsertAfter(Element parent, IsElement newElement, Element after) { if (parent != null && newElement != null && after != null) { lazyInsertAfter(parent, newElement.element(), after); } } /** * Inserts element {@code newElement} into the parent before element {@code before}. */ public static void insertBefore(Element newElement, Element before) { if (newElement != null && before != null) { before.parentNode.insertBefore(newElement, before); } } /** * Inserts element {@code newElement} into the parent before element {@code before}. */ public static void insertBefore(IsElement newElement, Element before) { if (newElement != null && before != null) { insertBefore(newElement.element(), before); } } /** * Inserts element {@code newElement} into the parent before element {@code before} if not already present. If parent * already contains {@code newElement}, this method does nothing. */ public static void lazyInsertBefore(Element newElement, Element before) { if (newElement != null && before != null && !before.parentNode.contains(newElement)) { before.parentNode.insertBefore(newElement, before); } } /** * Inserts element {@code newElement} into the parent before element {@code before} if not already present. If parent * already contains {@code newElement}, this method does nothing. */ public static void lazyInsertBefore(IsElement newElement, Element before) { if (newElement != null && before != null) { lazyInsertBefore(newElement.element(), before); } } /** * Inserts element {@code newElement} into the parent before element {@code before} if not already present. If parent * already contains {@code newElement}, this method does nothing. */ public static void lazyInsertBefore(Element parent, Element newElement, Element before) { if (parent != null && newElement != null && before != null && !parent.contains(newElement)) { parent.insertBefore(newElement, before); } } /** * Inserts element {@code newElement} into the parent before element {@code before} if not already present. If parent * already contains {@code newElement}, this method does nothing. */ public static void lazyInsertBefore(Element parent, IsElement newElement, Element before) { if (parent != null && newElement != null && before != null) { lazyInsertBefore(parent, newElement.element(), before); } } /** * Inserts element {@code newElement} as first element into {@code parent}. */ public static void insertFirst(Element parent, Element newElement) { if (parent != null && newElement != null) { parent.insertBefore(newElement, parent.firstChild); } } /** * Inserts element {@code newElement} as first element into {@code parent}. */ public static void insertFirst(Element parent, IsElement newElement) { if (parent != null && newElement != null) { insertFirst(parent, newElement.element()); } } /** * Removes all child elements from {@code element} */ public static void removeChildrenFrom(Element element) { if (element != null) { while (element.firstChild != null) { element.removeChild(element.firstChild); } } } /** * Removes all child elements from {@code element} */ public static void removeChildrenFrom(IsElement element) { if (element != null) { removeChildrenFrom(element.element()); } } /** * Removes the element from its parent if the element is not null and has a parent. * * @return {@code true} if the element has been removed from its parent, {@code false} otherwise. */ public static boolean failSafeRemoveFromParent(Element element) { return failSafeRemove(element != null ? element.parentNode : null, element); } /** * Removes the element from its parent if the element is not null and has a parent. * * @return {@code true} if the element has been removed from its parent, {@code false} otherwise. */ public static boolean failSafeRemoveFromParent(IsElement element) { if (element != null) { return failSafeRemoveFromParent(element.element()); } return false; } /** * Removes the child from parent if both parent and child are not null and parent contains child. * * @return {@code true} if the element has been removed from its parent, {@code false} otherwise. */ public static boolean failSafeRemove(Node parent, Element child) { if (parent != null && child != null && parent.contains(child)) { return parent.removeChild(child) != null; } return false; } /** * Removes the child from parent if both parent and child are not null and parent contains child. * * @return {@code true} if the element has been removed from its parent, {@code false} otherwise. */ public static boolean failSafeRemove(Node parent, IsElement child) { if (child != null) { return failSafeRemove(parent, child.element()); } return false; } // ------------------------------------------------------ attach / detach /** * Returns {@code true} if the element is connected by calling {@link Node#isConnected} on the element's * {@link IsElement#element()}. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected * @see https://dom.spec.whatwg.org/#dom-node-isconnected */ public static boolean isAttached(IsElement element) { if (element != null) { return isAttached(element.element()); } return false; } /** * Fail-safe shortcut for {@link Node#isConnected} * * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected * @see https://dom.spec.whatwg.org/#dom-node-isconnected */ public static boolean isAttached(Node node) { if (node != null) { return node.isConnected; } return false; } /** * Registers a callback when an element is appended to the document body. Note that the callback will be called only once, * if the element is appended more than once a new callback should be registered. * * @param element the HTML element which is going to be added to the body * @param callback {@link ObserverCallback} */ public static void onAttach(HTMLElement element, ObserverCallback callback) { if (element != null) { addAttachObserver(element, callback); } } /** * Registers a callback when an element is appended to the document body. Note that the callback will be called only once, * if the element is appended more than once a new callback should be registered. * * @param element the element which is going to be added to the body * @param callback {@link ObserverCallback} */ public static void onAttach(IsElement element, ObserverCallback callback) { if (element != null) { onAttach(element.element(), callback); } } /** * Registers a callback when an element is removed from the document body. Note that the callback will be called only once, * if the element is removed and re-appended a new callback should be registered. * * @param element the HTML element which is going to be removed from the body * @param callback {@link ObserverCallback} */ public static void onDetach(HTMLElement element, ObserverCallback callback) { if (element != null) { BodyObserver.addDetachObserver(element, callback); } } /** * Registers a callback when an element is removed from the document body. Note that the callback will be called only once, * if the element is removed and re-appended a new callback should be registered. * * @param element the element which is going to be removed from the body * @param callback {@link ObserverCallback} */ public static void onDetach(IsElement element, ObserverCallback callback) { if (element != null) { onDetach(element.element(), callback); } } // ------------------------------------------------------ visibility /** * Checks whether the given element is visible (i.e. {@code display} is not {@code none}) */ public static boolean isVisible(HTMLElement element) { return element != null && !"none".equals(element.style.display); } /** * Checks whether the given element is visible (i.e. {@code display} is not {@code none}) */ public static boolean isVisible(IsElement element) { return element != null && isVisible(element.element()); } /** * Shows / hide the specified element by modifying the {@code display} property. */ public static void setVisible(HTMLElement element, boolean visible) { if (element != null) { element.style.display = visible ? "" : "none"; } } /** * Shows / hide the specified element by modifying the {@code display} property. */ public static void setVisible(IsElement element, boolean visible) { if (element != null) { setVisible(element.element(), visible); } } public static boolean isElementInView(IsElement container, HTMLElement element, boolean partial) { return isElementInView(container.element(), element, partial); } public static boolean isElementInView(IsElement element) { return isElementInView(element.element()); } public static boolean isElementInView(HTMLElement element) { // implementation taken from // https://gist.github.com/Marco-Prontera/6d9d1a9cead48f44e8dabd8ff5310ecf CSSStyleDeclaration elementStyle = DomGlobal.window.getComputedStyle(element); // Particular cases when the element is not visible at all if (elementStyle.height.asString().startsWith("0") || elementStyle.display.equals("none") || elementStyle.opacity.asString().equals("0") || elementStyle.visibility.equals("hidden") || elementStyle.clipPath.equals("circle(0px at 50% 50%)") || elementStyle.transform.equals("scale(0)") || element.hasAttribute("hidden")) { return false; } DOMRect rect = element.getBoundingClientRect(); int elementLeft = (int) Math.ceil(rect.left); int elementRight = (int) Math.ceil(rect.right); int elementTop = (int) Math.ceil(rect.top); int elementBottom = (int) Math.ceil(rect.bottom); return elementTop >= 0 && elementLeft >= 0 && elementBottom <= window.innerHeight && elementRight <= window.innerWidth; } public static boolean isElementInView(HTMLElement container, IsElement element, boolean partial) { return isElementInView(container, element.element(), partial); } public static boolean isElementInView(IsElement container, IsElement element, boolean partial) { return isElementInView(container.element(), element.element(), partial); } /** * This function returns whether an element is within the viewable area of a container. If partial is true, then this * function will return true even if only part of the element is in view. * * @param container The container to check if the element is in view of. * @param element The element to check if it is view * @param partial true if partial view is allowed * @return {@code true} if the component is in view. */ public static boolean isElementInView(HTMLElement container, HTMLElement element, boolean partial) { if (container != null && element != null) { DOMRect containerBounds = container.getBoundingClientRect(); DOMRect elementBounds = element.getBoundingClientRect(); int containerBoundsLeft = (int) Math.ceil(containerBounds.left); int containerBoundsRight = (int) Math.floor(containerBounds.right); int elementBoundsLeft = (int) Math.ceil(elementBounds.left); int elementBoundsRight = (int) Math.floor(elementBounds.right); boolean isTotallyInView = elementBoundsLeft >= containerBoundsLeft && elementBoundsRight <= containerBoundsRight; boolean isPartiallyInView = (partial || (containerBounds.width < elementBounds.width)) && ((elementBoundsLeft < containerBoundsLeft && elementBoundsRight > containerBoundsLeft) || (elementBoundsRight > containerBoundsRight && elementBoundsLeft < containerBoundsRight)); return isTotallyInView || isPartiallyInView; } return false; } // ------------------------------------------------------ resize /** * Register a resize observer for the given element. The observer will call the provided callback whenever the size of the * element changes. *

* Uses the native {@link ResizeObserver} if available. Falls back to {@code window.addEventListener("resize", callback)}, * otherwise. * * @param element The element to observe for size changes. * @param callback The callback function to be called when the size of the element changes. * @param The type of element being observed, which must extend from HTMLElement. * @return A cleanup function that can be used to unregister the observer. */ public static ResizeObserverCleanup resizeObserver(IsElement element, ResizeCallback callback) { return resizeObserver(element.element(), callback); } /** * Register a resize observer for the given element. The observer will call the provided callback whenever the size of the * element changes. *

* Uses the native {@link ResizeObserver} if available. Falls back to {@code window.addEventListener("resize", callback)}, * otherwise. * * @param element The element to observe for size changes. * @param callback The callback function to be called when the size of the element changes. * @param The type of element being observed, which must extend from HTMLElement. * @return A cleanup function that can be used to unregister the observer. */ public static ResizeObserverCleanup resizeObserver(E element, ResizeCallback callback) { ResizeObserverCleanup cleanup; if (isTripleEqual(Js.global().getAsAny("ResizeObserver"), undefined())) { HandlerRegistration registration = bind(window, resize, e -> callback.onResize()); cleanup = registration::removeHandler; } else { ResizeObserver observer = new ResizeObserver((entries, obs) -> { if (entries != null && entries.length != 0) { callback.onResize(); } }); observer.observe(element); cleanup = () -> observer.unobserve(element); } return cleanup; } // ------------------------------------------------------ CSS /** * Adds the specified CSS class to the element if {@code condition} is {@code true}, removes it otherwise. */ public static void toggle(HTMLElement element, String css, boolean condition) { if (element != null) { element.classList.toggle(css, condition); } } /** * Adds the specified CSS class to the element if {@code condition} is {@code true}, removes it otherwise. */ public static void toggle(IsElement element, String css, boolean condition) { if (element != null) { toggle(element.element(), css, condition); } } /** * Adds the specified CSS class to the element if {@code condition} is {@code true}, removes it otherwise. */ public static void toggle(HTMLElement element, String css, Supplier condition) { if (element != null) { element.classList.toggle(css, condition.get()); } } /** * Adds the specified CSS class to the element if {@code condition} is {@code true}, removes it otherwise. */ public static void toggle(IsElement element, String css, Supplier condition) { if (element != null) { element.element().classList.toggle(css, condition.get()); } } // ------------------------------------------------------ inner HTML, text /** * Convenience method to set the inner HTML of the given element. */ public static void innerHtml(HTMLElement element, SafeHtml html) { if (element != null) { element.innerHTML = html.asString(); } } /** * Convenience method to set the inner HTML of the given element. */ public static void innerHtml(IsElement element, SafeHtml html) { if (element != null) { innerHtml(element.element(), html); } } /** * Returns the text content of the given HTMLElement. * * @param element The HTMLElement to retrieve the text content from. * @return The text content of the HTMLElement. If there is a text node present, returns the value of the text node. If * there is no text node, returns the text content of the element. */ public static String textNode(Element element) { Node textNode = firstTextNode(element); if (textNode != null) { return textNode.nodeValue; } else { return element.textContent; } } /** * Returns the text content of the given element. * * @param element the element from which to extract the text content * @param the type constraint for the element * @return the text content of the element, or null if the element is null */ public static String textNode(IsElement element) { if (element != null) { return textNode(element.element()); } return null; } /** * Changes the text of the first text node (if any) or adds the given text as a new text node. Use this method instead of * {@link Element#textContent} if you want to preserve existing child elements. * * @param element The HTMLElement to retrieve the text content from. * @param text The text to set */ public static void textNode(Element element, String text) { Node textNode = firstTextNode(element); if (textNode != null) { textNode.nodeValue = text; } else { element.appendChild(element.ownerDocument.createTextNode(text)); } } /** * Changes the text of the first text node (if any) or adds the given text as a new text node. Use this method instead of * {@link Element#textContent} if you want to preserve existing child elements. * * @param element The HTMLElement to retrieve the text content from. * @param text The text to set * @param the type constraint for the element */ public static void textNode(IsElement element, String text) { if (element != null) { textNode(element.element(), text); } } private static Node firstTextNode(Element element) { NodeList nodes = element.childNodes; for (int i = 0; i < nodes.length; i++) { Node node = nodes.getAt(i); if (node.nodeType == Node.TEXT_NODE) { return node; } } return null; } // ------------------------------------------------------ debug public static String toString(IsElement element) { if (element != null) { return toString(element.element()); } return ""; } public static String toString(Element element) { if (element != null) { String tag = element.tagName.toLowerCase(); StringBuilder builder = new StringBuilder("<").append(tag); JsArray names = element.getAttributeNames(); if (names != null) { for (int i = 0; i < names.length; i++) { String name = names.getAt(i); String value = element.getAttribute(name); builder.append(" ").append(name).append("='").append(value).append("'"); } } if (element.childElementCount == 0) { builder.append("/>"); } else { builder.append(">[") .append(element.childElementCount) .append(" child element"); if (element.childElementCount > 1) { builder.append("s"); } builder.append("]>"); } return builder.toString(); } return ""; } // ------------------------------------------------------ deprecated /** * @deprecated Replaced bv {@link Id#unique()} */ @Deprecated public static String uniqueId() { return Id.unique(); } /** * @deprecated Replaced bv {@link Id#unique(String, String...)} */ @Deprecated public static String uniqueId(String id, String... additionalIds) { return Id.unique(id, additionalIds); } /** * @deprecated Replaced bv {@link Id#build(String, String...)} */ @Deprecated public static String buildId(String id, String... additionalIds) { return Id.build(id, additionalIds); } // ------------------------------------------------------ instance // this is a static helper class, which must never be instantiated! private Elements() { } // ------------------------------------------------------ inner classes private static class AsHTMLElement implements Function { @Override public HTMLElement apply(T t) { return Js.uncheckedCast(t); } } private static class FilterHTMLElements implements Predicate { @Override public boolean test(T t) { return t instanceof HTMLElement; } } private static class JsArrayLikeIterator implements Iterator { private final JsArrayLike data; private int pos = 0; JsArrayLikeIterator(JsArrayLike nodes) { this.data = nodes; } @Override public boolean hasNext() { return pos < data.getLength(); } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } return data.getAt(pos++); } } private static class JsArrayNodeIterator implements Iterator { private final Node parent; private Node last; private Node next; public JsArrayNodeIterator(Node parent) { this.parent = parent; next = parent.firstChild; } @Override public boolean hasNext() { return next != null; } @Override public Node next() { if (!hasNext()) { throw new NoSuchElementException(); } last = next; next = last.nextSibling; return last; } @Override public void remove() { if (last == null) { throw new IllegalStateException(); } parent.removeChild(last); last = null; } } // This should be Iterator, but it was used frequently as HTMLElement, so to be more user-friendly the // cast is forced, not sure about the implication bc not sure what elements can be Element and no HTMLElement private static class JsArrayElementIterator implements Iterator { private final HTMLElement parent; private HTMLElement last; private HTMLElement next; public JsArrayElementIterator(HTMLElement parent) { this.parent = parent; next = (HTMLElement) parent.firstElementChild; } @Override public boolean hasNext() { return next != null; } @Override public HTMLElement next() { if (!hasNext()) { throw new NoSuchElementException(); } last = next; next = (HTMLElement) last.nextElementSibling; return last; } @Override public void remove() { if (last == null) { throw new IllegalStateException(); } parent.removeChild(last); last = null; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy