001package org.jsoup.select;
002
003import org.jsoup.nodes.Node;
004
005/**
006 * Node filter interface. Provide an implementing class to {@link NodeTraversor} to iterate through nodes.
007 * <p>
008 * This interface provides two methods, {@code head} and {@code tail}. The head method is called when the node is first
009 * seen, and the tail method when all of the node's children have been visited. As an example, head can be used to
010 * create a start tag for a node, and tail to create the end tag.
011 * </p>
012 * <p>
013 * For every node, the filter has to decide whether to
014 * <ul>
015 * <li>continue ({@link FilterResult#CONTINUE}),</li>
016 * <li>skip all children ({@link FilterResult#SKIP_CHILDREN}),</li>
017 * <li>skip node entirely ({@link FilterResult#SKIP_ENTIRELY}),</li>
018 * <li>remove the subtree ({@link FilterResult#REMOVE}),</li>
019 * <li>interrupt the iteration and return ({@link FilterResult#STOP}).</li>
020 * </ul>
021 * The difference between {@link FilterResult#SKIP_CHILDREN} and {@link FilterResult#SKIP_ENTIRELY} is that the first
022 * will invoke {@link NodeFilter#tail(Node, int)} on the node, while the latter will not.
023 * Within {@link NodeFilter#tail(Node, int)}, both are equivalent to {@link FilterResult#CONTINUE}.
024 * </p>
025 */
026public interface NodeFilter {
027    /**
028     * Filter decision.
029     */
030    enum FilterResult {
031        /** Continue processing the tree */
032        CONTINUE,
033        /** Skip the child nodes, but do call {@link NodeFilter#tail(Node, int)} next. */
034        SKIP_CHILDREN,
035        /** Skip the subtree, and do not call {@link NodeFilter#tail(Node, int)}. */
036        SKIP_ENTIRELY,
037        /** Remove the node and its children */
038        REMOVE,
039        /** Stop processing */
040        STOP
041    }
042
043    /**
044     * Callback for when a node is first visited.
045     * @param node the node being visited.
046     * @param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node of that will have depth 1.
047     * @return Filter decision
048     */
049    FilterResult head(Node node, int depth);
050
051    /**
052     * Callback for when a node is last visited, after all of its descendants have been visited.
053     * @param node the node being visited.
054     * @param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node of that will have depth 1.
055     * @return Filter decision
056     */
057    FilterResult tail(Node node, int depth);
058}