Package Torello.HTML

Class TagNode

  • All Implemented Interfaces:
    java.io.Serializable, java.lang.CharSequence, java.lang.Cloneable, java.lang.Comparable<TagNode>

    public final class TagNode
    extends HTMLNode
    implements java.lang.CharSequence, java.io.Serializable, java.lang.Cloneable, java.lang.Comparable<TagNode>
    Concrete HTMLNode SubClasses:

    The three inherited classes of abstract class HTMLNode are very light-weight, and contain some amount of public methods, but do not have heavy internal-state (either static, or non-static). Below is a list of the internal field's that are added to each of the three instantiations of the ancestor HTMLNode class:

    • class TagNode adds a field public final boolean isClosing - which tells a user if this tag has a forward-slash immediately following the '<' (less-than symbol) at character position 2. This is how one identifies a 'closing-version' of the element, for instance: '</DIV>' and '</SPAN>' would both have their public final boolean isClosing fields set to TRUE. There is also a public final String tok field added to instances of TagNode that identify what html element the TagNode represents. For example an HTML Element such as: <A HREF="http://My.URL.com" TARGET=_blank>, would have it's String 'tok' field set to 'a'

    • class TextNode this inherited class from class HTMLNode does not add any internal state at all. It has the exact same internally-maintained fields as its parent-class. The public final String str field merely states what text this text-node actually represents.

    • class CommentNode for searching-purposes, and ease-of-use, class CommentNode, which is the third and final class to inherit HTMLNode keeps one extra internal-field, which is public final String body. This field is a redundant, duplicate, of the internal string public final String str - which is inherited from the HTML Node class. The subtle difference is that, since comment nodes represent the HTML <!-- and --> symbols, the 'body' of the comment sometimes needs to be searched, quickly. The public final String body leaves off these leading and ending comment delimiter symbols: <!-- and -->
    Represents an HTML Element Tag, and is the flagship class of the Java-HTML Library.

    This class is intended to represent HTMLNode's that are Tags. These are sometimes referred to as 'elements.' Here, below, are just simple examples of what constitute an instance of this class TagNode:

    HTML Elements:
    <!-- An HTML Anchor Tag (a link) -->
    <A HREF="http://some.url.com/index.html">
    
    <!-- A Picture that has been inlined onto a page, using the 'Image' Element -->
    <IMG SRC="https://some.image.url.net/image.jpg">
    
    <!-- An HTML Block-Element, also known as a 'divider' -->
    <DIV ID="MainDivClass">
    
    <!-- The Main Page 'Body' Tag / Element.  There should only be one of these -->
    <BODY ONLOAD="callInit();">
    
    <!-- The Main Page 'Header' Element, and the associated 'Title' Tag -->
    <HEAD>, <TITLE>
    
    <!-- Table's can be great for rendering lists of data on a page. -->
    <TABLE CLASS="DataTables" ID="Weights" STYLE="width: 80%; color: red; background: black">
    
    <!--
         Closing off an Open-Tag is important in order for the
         element to be properly rendered in the browser.
         These are all "Closing-Versions" of the above listed HTML Elements.
    -->
    </TABLE>
    </SPAN>
    </A>
    </BODY>
    
    <!-- All tolled, there are over 100 different HTML 5 Tags. -->
    


    Technically speaking, each of these String's (above) would be stored in the abstract ancestor / parent class-field HTMLNode.str. To retrieve the actual text-String of an HTML Element, just reference this field.


    Inheritance Tree Diagram:
    Below is the inheritance diagram (with fields) of the three concrete-classes that extend the abstract class HTMLNode:

    HTMLNode Inheritance Diagram
    See Also:
    TextNode, CommentNode, HTMLNode, Serialized Form


    • Field Summary

       
      Serializable ID
      Modifier and Type Field
      static long serialVersionUID
       
      Data Fields
      Modifier and Type Field
      boolean isClosing
      String tok
    • Constructor Summary

      Constructors 
      Constructor Description
      TagNode​(String s)
      TagNode​(String tok, Properties attributes, Iterable<String> keyOnlyAttributes, SD quotes, boolean addEndingForwardSlash)
      TagNode​(String tok, Properties attributes, SD quotes, boolean addEndingForwardSlash)
      Convenience Constructor.
    • Method Summary

       
      Obtain a Java Singleton-Instance of a TagNode, One with Zero-Attributes
      Modifier and Type Method
      static TagNode getInstance​(String tok, TC openOrClosed)
       
      HTML Element, .tok Field Test
      Modifier and Type Method
      boolean isTag​(String... possibleTags)
      boolean isTag​(TC tagCriteria, String... possibleTags)
      boolean isTagExcept​(String... possibleTags)
      boolean isTagExcept​(TC tagCriteria, String... possibleTags)
       
      Attribute Tests: Has an Attribute-Name
      Modifier and Type Method
      boolean has​(String attributeName)
      boolean has​(Predicate<String> attributeNameTest)
      boolean has​(Pattern attributeNameRegExTest)
      boolean has​(TextComparitor tc, String... compareStrs)
       
      Attribute Tests: Has an Attribute-Name, Multiple Tokens
      Modifier and Type Method
      boolean hasAND​(boolean checkAttributeStringsForErrors, String... attributes)
      boolean hasNAND​(boolean checkAttributeStringsForErrors, String... attributes)
      boolean hasOR​(boolean checkAttributeStringsForErrors, String... attributes)
      boolean hasXOR​(boolean checkAttributeStringsForErrors, String... attributes)
       
      Attribute Tests: Test an Attribute-Value
      Modifier and Type Method
      boolean testAV​(String attributeName, String attributeValue)
      boolean testAV​(String attributeName, Predicate<String> attributeValueTest)
      boolean testAV​(String attributeName, Pattern attributeValueTest)
      boolean testAV​(String attributeName, TextComparitor attributeValueTester, String... compareStrs)
       
      Attribute Tests: Has a Key-Only / Boolean Attribute
      Modifier and Type Method
      boolean hasKeyOnlyAttribute​(String keyOnlyAttribute)
       
      Attribute Modify & Update: Set Attribute-Value
      Modifier and Type Method
      TagNode setAV​(String attribute, String value, SD quote)
      TagNode setAV​(Properties attributes, SD defaultQuote)
       
      Attribute Modify & Update: Append to Attribute-Value
      Modifier and Type Method
      TagNode appendToAV​(String attribute, String appendStr, boolean startOrEnd, SD quote)
       
      Attribute Modify & Update: Remove Attributes
      Modifier and Type Method
      TagNode remove​(String attributeName)
      TagNode removeAllAV()
      TagNode removeAttributes​(String... attributes)
      TagNode removeAttributes​(Predicate<String> attrNameTest)
      TagNode removeDataAttributes()
       
      Attribute Modify & Update: CSS-Attributes
      Modifier and Type Method
      TagNode appendCSSClass​(String cssClass, SD quote)
      TagNode setCSSClasses​(SD quote, boolean appendOrClobber, String... cssClasses)
      TagNode setCSSStyle​(Properties p, SD quote, boolean appendOrClobber)
      TagNode setID​(String id, SD quote)
       
      Attribute Modify & Update: To Upper Case
      Modifier and Type Method
      TagNode toUpperCase​(boolean justTag_Or_TagAndAttributeNames)
      TagNode toUpperCase​(boolean tag, String... attributeNames)
      TagNode toUpperCase​(boolean tag, Predicate<String> attrNameTest)
       
      Attribute Modify & Update: To Lower Case
      Modifier and Type Method
      TagNode toLowerCase​(boolean justTag_Or_TagAndAttributeNames)
      TagNode toLowerCase​(boolean tag, String... attributeNames)
      TagNode toLowerCase​(boolean tag, Predicate<String> attrNameTest)
       
      Attribute Retrieve: Attribute-Names Only
      Modifier and Type Method
      Stream<String> allAN()
      Stream<String> allAN​(boolean preserveKeysCase, boolean includeKeyOnlyAttributes)
      Stream<String> allKeyOnlyAttributes​(boolean preserveKeysCase)
       
      Attribute Retrieve: Attribute-Names and Values
      Modifier and Type Method
      Properties allAV()
      Properties allAV​(boolean keepQuotes, boolean preserveKeysCase)
      String AV​(String innerTagAttribute)
       
      Attribute Retrieve: CSS-Attributes
      Modifier and Type Method
      Stream<String> cssClasses()
      Stream<String> cssClassesNOCSE()
      Properties cssStyle()
      String getID()
       
      Attribute Retrieve: DATA-* Attributes
      Modifier and Type Method
      String dataAV​(String dataName)
      Stream<String> getDataAN()
      Stream<String> getDataAN​(boolean preserveKeysCase)
      Properties getDataAV()
      Properties getDataAV​(boolean preserveKeysCase)
       
      Attribute Retrieve: Retrieve By Value
      Modifier and Type Method
      Map.Entry<String,​String> hasValue​(boolean retainQuotes, boolean preserveKeysCase, TextComparitor attributeValueTester, String... compareStrs)
      Map.Entry<String,​String> hasValue​(String attributeValue, boolean retainQuotes, boolean preserveKeysCase)
      Map.Entry<String,​String> hasValue​(Predicate<String> attributeValueTest, boolean retainQuotes, boolean preserveKeysCase)
      Map.Entry<String,​String> hasValue​(Pattern attributeValueRegExTest, boolean retainQuotes, boolean preserveKeysCase)
       
      Quotation Marks: Replace / Set
      Modifier and Type Method
      TagNode setAllAVQuotes​(SD quote)
      TagNode setAVQuotes​(String attributeName, SD quote)
      TagNode setAVQuotes​(Predicate<String> attrNameTest, SD quote)
       
      Quotation Marks: Remove
      Modifier and Type Method
      TagNode removeAllAVQuotes()
      TagNode removeAVQuotes​(String attributeName)
      TagNode removeAVQuotes​(Predicate<String> attrNameTest)
       
      Loop Optimization & 'instanceof' Operator Replacement Methods
      Modifier and Type Method
      String AVOPT​(String innerTagAttribute)
      TagNode ifTagNode()
      boolean isOpenTag()
      boolean isOpenTagPWA()
      boolean isTagNode()
      TagNode openTag()
      TagNode openTagPWA()
       
      Methods: interface java.lang.Comparable<TagNode>
      Modifier and Type Method
      int compareTo​(TagNode n)
       
      Methods: interface java.lang.Cloneable
      Modifier and Type Method
      TagNode clone()
       
      Methods: class java.lang.Object
      Modifier and Type Method
      String toStringAV()
      • Methods inherited from class java.lang.Object

        finalize, getClass, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.lang.CharSequence

        charAt, chars, codePoints, length, subSequence, toString
    • Field Detail

      • serialVersionUID

        🡇     🗕  🗗  🗖
        public static final long serialVersionUID
        This fulfils the SerialVersion UID requirement for all classes that implement Java's interface java.io.Serializable. Using the Serializable Implementation offered by java is very easy, and can make saving program state when debugging a lot easier. It can also be used in place of more complicated systems like "hibernate" to store data as well.
        See Also:
        Constant Field Values
        Code:
        Exact Field Declaration Expression:
         public static final long serialVersionUID = 1;
        
      • tok

        🡅  🡇     🗕  🗗  🗖
        public final java.lang.String tok
        This variable is declared final and it stores the 'token' or Tag-Name of the HTML-Element. The complete HTML-Tag is retained in the HTMLNode.str field which is also a public & final member field of that class. Class HTMLNode is the parent class of this class.

        Always Lower-Case & Immutable
        As mentioned, this class' String-Field 'tok' is declared public & final. It is always stored here with lower-case characters. Furthermore, since TagNode's are an immutable class (there are no fields or methods that may be modified inside of an instance of TagNode) once the object has been constructed. This 'tok' field also may not be changed after the object is constructed.

        Example Values of 'tok'
        Here is a table of some common HTML Elements found on web-pages. In each row of this table, the HTML-Tag, is shown in the first column of the table. The second column shows what the tok-Field (this field) would contain, given the value of the str-Field which is listed in column 1.

        Field: 'str' Field: 'tok'
        <A HREF="http://some.url.com"> "a"(all lower-case).
        <div class="MyFavoriteClass"> "div"(all lower-case).
        <IMG SRC="MyImage.jpg"> "img"(all lower-case).
        </body> "body"(all lower-case).
        </SPAN> "span"(all lower-case).

        This 'tok' field always keeps a copy of the "separated HTML-Tag" (first few characters of the constructor-passed-string) from the rest of the inner-tag information. This allows the programmer to quickly and efficiently ask this class what type of HTML-Element this is, without having to do more complicated String-Query Operations using field 'str'.
      • isClosing

        🡅  🡇     🗕  🗗  🗖
        public final boolean isClosing
        If the 'str'' Field of 'this' instance begins with the character "</" (which 'identifies' 'this' as an HTML Closing-tag), then this boolean-Field will contain TRUE.

        If the 'str'' Field of 'this' instance does not begin with "</", (leaves off the beginning forward-slash), then this boolean-Field will contain FALSE.

        Examples:
        The table below shows a few examples of what an HTML-Tag with a 'str' Field assigned tot he values listed in Column 1 of the table below would be. The values in Column 2 show the value of the 'isClosing' Field for any instance having the assigned 'str'.

        Field: 'str' Field: 'isClosing'
        <A HREF="http://some.url.com"> FALSE
        <IMG SRC="MyImage.jpg"> FALSE
        </body> TRUE - Note that the tag begins with a forward-slash '/' character.
        </SPAN> TRUE - Note that the tag begins with a forward-slash '/' character.
    • Constructor Detail

      • TagNode

        🡅  🡇     🗕  🗗  🗖
        public TagNode​(java.lang.String s)
        Creates a TagNode, an inherited class of HTMLNode, that can be used as an element of Vectorized-HTML.

        Example:
        TagNode tn = new TagNode("<DIV CLASS='SUMMARY' onmouseover=\"alert('Hello!');\">");
        System.out.println(tn.str);
        
        // Prints to Terminal: <DIV CLASS='SUMMARY' onmouseover="alert('Hello!');">
        
        Parameters:
        s - Any valid HTML tag, for instance: <H1>, <A HREF="somoe url">, <DIV ID="some id"> etc...
        Throws:
        MalformedTagNodeException - If the passed String wasn't valid - meaning it did not match the regular-expression parser.
        HTMLTokException - If the String found where the usual HTML token-element is situated is not a valid HTML element then the HTMLTokException will be thrown.
        See Also:
        HTMLTags.getTag_MEM_HEAP_CHECKOUT_COPY(String)
        Code:
        Exact Constructor Body:
         super(s);
        
         // If the second character of the string is a forward-slash, this must be a closing-element
         // For Example: </SPAN>, </DIV>, </A>, etc...
        
         isClosing = s.charAt(1) == '/';
        
         // This is the Element & Attribute Matcher used by the RegEx Parser.  If this Matcher
         // doesn't find a match, the parameter 's' cannot be a valid HTML Element.  NOTE: The
         // results of this matcher are also used to retrieve attribute-values, but here below,
         // its results are ignored.
        
         Matcher m = HTMLRegEx.P1.matcher(s);
        
         if (! m.find()) throw new MalformedTagNodeException(
             "The parser's regular-expression did not match the constructor-string.\n" +
             "The exact input-string was: [" + s + "]\n" +
             "NOTE:  The parameter-string is included as a field (ex.str) to this Exception.", s
         );
        
         if ((m.start() != 0) || (m.end() != s.length()))
        
             throw new MalformedTagNodeException(
                 "The parser's regular-expression did not match the entire-string-length of the " +
                 "string-parameter to this constructor: m.start()=" + m.start() + ", m.end()=" + 
                 m.end() + ".\nHowever, the length of the Input-Parameter String was " +
                 '[' + s.length() + "]\nThe exact input-string was: [" + s + "]\nNOTE: The " +
                 "parameter-string is included as a field (ex.str) to this Exception.", s
             );
        
         // MINOR/MAJOR IMPROVEMENT... REUSE THE "ALLOCATED STRING TOKEN" from HTMLTag's class
         // THINK: Let the Garbage Collector take out as many duplicate-strings as is possible..
         // AND SOONER.  DECEMBER 2019: "Optimization" or ... "Improvement"
         // 
         // Get a copy of the 'tok' string that was already allocated on the heap; (OPTIMIZATON)
         //
         // NOTE: There are already myriad strings for the '.str' field.
         // 
         // ALSO: Don't pay much attention to this line if it doesn't make sense... it's not
         //       that important.  If the HTML Token found was not a valid HTML5 token, this field
         //       will be null.
         // 
         // Java 14+ has String.intern() - that's what this is....
        
         this.tok = HTMLTags.getTag_MEM_HEAP_CHECKOUT_COPY(m.group(1));
        
         // Now do the usual error check.
         if (this.tok == null) throw new HTMLTokException(
             "The HTML Tag / Token Element that is specified by the input string " +
             "[" + m.group(1).toLowerCase() + "] is not a valid HTML Element Name.\n" +
             "The exact input-string was: [" + s + "]"
         );
        
      • TagNode

        🡅  🡇     🗕  🗗  🗖
        public TagNode​(java.lang.String tok,
                       java.util.Properties attributes,
                       java.lang.Iterable<java.lang.String> keyOnlyAttributes,
                       SD quotes,
                       boolean addEndingForwardSlash)
        This will build a new TagNode that contains the inner tag attributes specified here. It is some-what checked for validity - though not all possible error cases are listed. If a major issue is discovered an exception is thrown.

        Example:
        Properties attributes = new Properties();
        attributes.put("CLASS", "SUMMARY");
        attributes.put("onmouseover", "alert('Hello');");
        
        Vector<String> booleanAttributes = new Vector<>();
        booleanAttributes.add("HIDDEN");
        
        TagNode tn = new TagNode("DIV", attributes, booleanAttributes, SD.DoubleQuotes, false);
        
        System.out.println(tn);
        // Prints To Terminal: <DIV CLASS="SUMMARY" onmouseover="alert('Hello');" HIDDEN>
        


        Key-Value and Key-Only Attributes:
        This constructor accepts both key-value attributes, and boolean / key-only attributes as input. These two lists are passed through separate parameters having those names.
        Parameters:
        tok - This is the HTML Tag-Name. String's that this parameter would often be passed include 'div', 'img', 'span', 'a', etc... If this parameter does not contain a valid HTML Tag-Name, an exception will be thrown.
        attributes - This must be a table of HTML inner-tag key-values (a.k.a. HTML Attributes) that are acceptable for using with the HTML element that is being created. Validity checking includes *only* the following tests:

        • If any key of Properties parameter 'p' contains characters outside of this ASCII-subset: [A..Za..z0..9_-]
        • If any key of 'p' does not start with attributes a character from this subset: [A..Za..z]
        • If any value of 'p' has a "quote within quote" problem - a 'value' that contains quotation marks that are the same as the quotation-parameter SD quotes

        If any of these requirements fail, the exceptions listed below will throw.

        NOTE: When specifying a java.util.Properties parameter for which quotation-marks have already been added to the values inside the table, parameter SD quote must be set to null. In such cases, if 'quote' were not null, a second set of surrounding quotes would be appended each attribute-value in the output HTML-Element - and this would likely force a QuotesException to throw, due to the "quotes within quotes" issue.

        NOTE: The 'attributes' parameter may be null, and if so, it will be ignored. In this case, no key-value attributes will be incorporated into the TagNode.
        keyOnlyAttributes - This should be a valid list of "Attribute-Only" Inner-Tags. Such attributes are often called "Boolean Attributes." They are just a stand-alone keywords, without any value assignment. The CSS keyword 'HIDDEN', for example, is a commonly used Boolean-Attribute.

        NOTE: This parameter may be null, and if so, no boolean-attributes will be included in the HTML Element.
        quotes - This is either a single-quote (') or a double-quote ("). It uses the Enumerated Type: 'SD' from this package.

        NOTE: This parameter (quotes) may be null. If 'null' is passed, then it should be expected that the contents of the Properties parameter ('p') contains values that obey these rules:

        • Either: The values in Properties parameter 'p' already have quotes surrounding their String contents.
        • Or: The values in 'p' do not contain any white-space. HTML rules state that in such cases, say quotes are actually optional.

        These quotes are used to encapsulate the value String of all key-value pairs when building the HTML Element.

        IMPORTANT: If different quotes-selections are to be used for different attribute key-value pairs, then those quotes should be provided inside the Properties data-structure - already pre-wrapped. In these cases (when individualized quotes choices are necessary), this parameter must be passed null.
        addEndingForwardSlash - There are a few (very few) instances where an "ending forward-slash" is expected at the end of the HTML -Tag. If this is desired, set this value to TRUE.

        EXAMPLE: <IMG SRC='img/myPhoto1.png' /> - Note the tag ends with a '/' (forward-slash) character.
        Throws:
        InnerTagKeyException - This exception will throw if any of the keys in the Properties parameter contain non-standard HTML Attribute / Inner-Tag key Strings.

        HTML expects that Attribute-Names conform to a set of rules in order to be processed properly by a Web-Browser. There is a check method in class InnerTagKeyException which delineates the exact requirements made by HTML for Attribute-Names. This method uses a Regular-Expression to do its checks.
        QuotesException - If there are "quotes within quotes" problems when invoking the TagNode constructor, this exception will throw. The problem occurs when one or more of the Attribute Key-Value Pairs have a quotation-choice such that the chosen quotation-mark is also found within the Attribute-Value.

        QuotesException will also throw in the case that an Attribute Key-Value Pair has elected to use the "No Quotes" option, but the attribute-value contains white-space.
        HTMLTokException - if an invalid HTML 4 or 5 token is not present (check is CASE_INSENSITIVE), or a token which has been registered with class HTMLTags.
        See Also:
        InnerTagKeyException.check(String, String), QuotesException.check(String, SD, String)
        Code:
        Exact Constructor Body:
         this(
             tok,
             GeneralPurpose.generateElementString
                 (tok, attributes, keyOnlyAttributes, quotes, addEndingForwardSlash)
         );
        
    • Method Detail

      • isTagNode

        🡅  🡇     🗕  🗗  🗖
        public final boolean isTagNode()
        This method identifies that 'this' instance of (abstract parent-class) HTMLNode is, indeed, an instance of sub-class TagNode.

        Final Method:
        This method is final, and cannot be modified by sub-classes.
        Overrides:
        isTagNode in class HTMLNode
        Returns:
        This method shall always return TRUE It overrides the parent-class HTMLNode method isTagNode(), which always returns FALSE.
        See Also:
        isTagNode()
      • ifTagNode

        🡅  🡇     🗕  🗗  🗖
        public final TagNode ifTagNode()
        This method identifies that 'this' instance of (abstract parent-class) HTMLNode is, indeed, an instance of sub-class TagNode.

        Final Method:
        This method is final, and cannot be modified by sub-classes.
        Overrides:
        ifTagNode in class HTMLNode
        Returns:
        'this' reference. This method can be used inside loops for improving the readability of loop-condition expressions. See example below:

        Example:
        Vector<HTMLNode> fileVec = HTMLPage.getPageTokens(new URL("http://some.url.com"), false);
        TagNode tn;
        
        // NOTE: The casting to class TagNode is automatically acheived with this method,
        //       which can make loops a lot easier to read.  Only a TagNode instance is allowed
        //       to have attributes - such as the CSS "Class" attribute.  Invoking method "AV(..)"
        //       on an instance of HTMLNode would cause a compile-time error.
        
        for (HTMLNode n : fileVec)
            if ((tn = fileVec.elementAt(i).ifTagNode()) != null)
                System.out.println("The CSS Class Attribute is: " + tn.AV("class"));
        


        This method-version overrides the parent-class-version, which always returns null. This method is not overriden by other HTMLNode sub-classes.
        See Also:
        ifTagNode()
      • openTagPWA

        🡅  🡇     🗕  🗗  🗖
        public final TagNode openTagPWA()
        This is a loop-optimization method that makes finding opening TagNode's - with attribute-values - quites a bit faster. All HTMLNode subclasses implement this method, but only TagNode instances will ever return a non-null value.

        Example:
        // Download a web-page, and parse it into a vector
        Vector<HTMLNode> someWebPage = HTMLPage.getPageTokens(pageURL, false);
        
        TagNode tn;
        
        // Search for a TagNode that has a CSS class, in a quick and efficient way.
        // NOTE: A temporary 'tn' / TagNode Variable is required in this loop.
        
        for (HTMLNode n : someWebPage)
        
            // Here, this invokation shall always receive 'null' - unless the node being asked
            // is an opening-tag, whose 'str' is guaranteed to be long enough to possibly have a
            // CSS 'CLASS' attribute.
            //
            // UNLESS 'tn' receives a non-null value, there is no need to proceed with this check.
        
            if ((tn = n.openTagNodePWA()) != null)
        
                // HERE, WE CAN INVOKE AV("class")
                if (tn.AV("class").contains("someCSSClass")
                { handle_TagNode(tn); }
        


        Computation Heuristic:
        The exact computation for determining whether this method returns null is to check whether the internal HTMLNode.str field is at least 5 characters longer than the this class' .tok field. This number, '5', is determined by the additional characters '<', '>', ' ', '=' and one character of attribute-name. These characters are the additional characters other than the 'tok' field of the HTML tag / token itself.

        Final Method:
        This method is final, and cannot be modified by sub-classes.
        Overrides:
        openTagPWA in class HTMLNode
        Returns:
        This method returns exactly 'this' instance, but only if 'this' instance's isClosing field is FALSE, and if 'this' instance has an internal .str field that is long enough to (possibly) have inner-tag attributes. This is an optimization-routine for search loops that have to iterate all types of nodes.
        See Also:
        openTagPWA(), HTMLNode.isOpenTagPWA()
      • openTag

        🡅  🡇     🗕  🗗  🗖
        public final TagNode openTag()
        This is a loop-optimization method that makes finding opening TagNode's - with attribute-values - quites a bit faster. All HTMLNode subclasses implement this method, but only TagNode instances will ever return a non-null value.

        Final Method:
        This method is final, and cannot be modified by sub-classes.
        Overrides:
        openTag in class HTMLNode
        Returns:
        Returns null if and only if 'this' instance' isClosing field is false. When a non-null return-value is acheived, that value will always be 'this' instance.
        See Also:
        openTag()
      • isOpenTagPWA

        🡅  🡇     🗕  🗗  🗖
        public boolean isOpenTagPWA()
        This method is an optimization method that overrides the one by the same name in class HTMLNode.
        Overrides:
        isOpenTagPWA in class HTMLNode
        Returns:
        This method shall always return FALSE, unless it has been overriden by a subclass. Subclass TagNode overrides this, and will return TRUE if and only if the following conditions hold:

        • If 'this' instance is a TagNode
        • If 'this' instance' isClosing field is false.
        • If the 'length()' of the str field is at least equal to the 'length()' of the tok field plus 4.


        AGAIN: These conditions should imply that 'this' is not only an instance of the TagNode subclass of HTMLNode, but furthermore that this is an Opening-Tag, whose internal String is long enough to "Possibly Contain Attributes" (hence the name-acronym).

        This is a much more efficient and elegant way to optimize code when searching for tags that have attribute / inner-tag key-value pairs.
        See Also:
        isOpenTagPWA(), HTMLNode.openTagPWA()
      • isOpenTag

        🡅  🡇     🗕  🗗  🗖
        public boolean isOpenTag()
        This method is an optimization method that overrides the one by the same name in class HTMLNode.
        Overrides:
        isOpenTag in class HTMLNode
        Returns:
        This method shall always return FALSE, unless it has been overriden by a subclass. Subclass TagNode overrides this, and will return TRUE if and only if the following conditions hold:

        • If 'this' instance is a TagNode
        • If 'this' instance' isClosing field is false.


        AGAIN: These conditions should imply that 'this' is not only an instance of the TagNode subclass of HTMLNode, but furthermore that this is an opening tag, rather than a closing.
        See Also:
        isOpenTag(), HTMLNode.openTag()
      • isTag

        🡅  🡇     🗕  🗗  🗖
        public boolean isTag​(java.lang.String... possibleTags)
        Accepts a list of HTML-Tag's as input via a Var-Args String[]-Array parameter 'possibleTags'. Then, 'this' instance' tok-Field is checked against the contents of the array for matches.

        This method returns TRUE if any match is found.

        example
        Parameters:
        possibleTags - A non-null list of potential HTML tags to be checked again tok
        Returns:
        TRUE If 'this' instance' tok-Field matches at least one of these tags.
        See Also:
        tok
      • isTagExcept

        🡅  🡇     🗕  🗗  🗖
        public boolean isTagExcept​(java.lang.String... possibleTags)
        Accepts a list of HTML-Tag's as input via a Var-Args String[]-Array parameter 'possibleTags'. Then, 'this' instance' tok-Field is checked against the contents of the array for matches. This list indicates values which 'tok' MAY NOT match.

        This method returns FALSE if any match is found.
        Parameters:
        possibleTags - A non-null list of potential HTML tags to be checked again tok
        Returns:
        FALSE If this.tok matches any one of these tags, and TRUE otherwise.
        See Also:
        tok, isTag(String[])
      • isTag

        🡅  🡇     🗕  🗗  🗖
        public boolean isTag​(TC tagCriteria,
                             java.lang.String... possibleTags)
        Receives two "criteria-specifier" parameters. This method shall return TRUE if:

        • Field isClosing is equal-to / consistent-with TC-Parameter 'tagCriteria'

        • Field tok is equal to at least one of the Var-Args String[]-Array Parameter 'possibleTags'


        example
        Parameters:
        tagCriteria - This ought to be either 'TC.OpeningTags' or TC.ClosingTags'. This parameter specifies what 'this' instance of TagNode is expected to contain, as this.isClosing field shall be compared against it.
        possibleTags - A non-null list of potential HTML tags to be checked again tok
        Returns:
        TRUE If 'this' matches the specified criteria, and FALSE otherwise.
        See Also:
        tok
      • isTagExcept

        🡅  🡇     🗕  🗗  🗖
        public boolean isTagExcept​(TC tagCriteria,
                                   java.lang.String... possibleTags)
        * Receives a {@code TagNode} and then two "criteria-specifier" parameters. This method shall * return {@code FALSE} if: * *

          *
        • Field {@code 'isClosing'} is not equal-to / * not consistent-with {@code TC tagCriteria} *
        • * *
        • Field {@code 'tok'} is equal-to any of the {@code 'possibleTags'}
        • *
        *
        Parameters:
        tagCriteria - tagCriteria This ought to be either {@code 'TC.OpeningTags'} or * {@code TC.ClosingTags'} This parameter specifies what {@code 'this'} instance of * {@code TagNode} is expected to contain, as {@code this.isClosing} field shall be compared * against it. *
        possibleTags - A non-null list of potential HTML tags to be checked again tok
        Returns:
        {@code TRUE} If this {@code TagNode 'n'} matches the specified criteria explained * above, and {@code FALSE} otherwise. *
        See Also:
        tok
      • AV

        🡅  🡇     🗕  🗗  🗖
        public java.lang.String AV​(java.lang.String innerTagAttribute)
        AV: Attribute Value

        In the Java-HTML JAR Library, many attempts are made to use the words attribute and inner-tag synonymously.

        This will return the value of any Inner Tag inside this TagNode instance.

        example

        The following example will hilite what this method can achieve. The output that is generated has been transcribed to the next window (after the one below).

        Example:
        // This field prints its output both to the terminal, and to an internal string-buffer.
        static final StorageWriter sw = new StorageWriter();
        
        // Load a page from a "reputable" news-source, and parse it into a vectorized-html page.
        Vector<HTMLNode> page = HTMLPage.getPageTokens(new URL("https://foxnews.com"), false);
        
        // Select all HTMLNodes that are "instanceof" TagNode, where the Element is "IMG" and,
        // also, only select images that have an "ALT" text-string inner-tag (a.k.a.
        // english-description string).
        int[] imgPosArr = InnerTagFind.all(page, "img", "alt");
        
        // This uses the "Attribute Update Mode" (AUM) 'Replace' to convert the (very-long,
        // very-unreadable) variable Image-URL's to just say the word "REPLACED" when printing
        // the node.
        //
        // NOTE: They could easily be retrieved and saved, if needed.
        
        Attributes.update(page, AUM.Replace, imgPosArr, "data-src", "REMOVED", null);
        Attributes.update(page, AUM.Replace, imgPosArr, "data-srcset", "REMOVED", null);
        
        for (int pos : imgPosArr)
        {
            // Retrieves an HTML '<IMG SRC=...>' TagNode
            TagNode tn = (TagNode) page.elementAt(pos);
        
            // Retrieves the 'IMG' ALT=... text
            String altText = tn.AV("alt");
        
            // Clean up some of the HTML 'escape' characters (for readability-printing purposes)
            altText = Escape.replaceAll(altText).replace("&apos;","'");
        
            // Print out the TagNode.  Use UNIX Color-Code "bright-yellow" (for readability),
            // and the "ALT" attribute
            sw.println(C.BYELLOW + tn + C.RESET + "\nALT: [" + C.BRED + altText + C.RESET + "]\n");
        }
        FileRW.writeFile(C.toHTML(sw.getString(), true, true), "alt-text.txt");
        

        The following text was generated by the above program, scraping Yahoo! News. It prints out the 'alt' attribute for all HTML <IMG> elements.

        UNIX Shell Command Output:
        <img src="//static.foxnews.com/static/orion/styles/img/fox-news/bg/fn-logo-watch-now.png" alt="Fox News"> ALT: [Fox News] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/b6a0e412-d473-4dab-b498-335e45d4c2e2/f65a1645-8c2d-4358-ae27-475863ff0098/1280x720/match/480/270/image.jpg" alt="Easter Sunday at Washington National Cathedral"> ALT: [Easter Sunday at Washington National Cathedral] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/957bd65c-090d-4a21-a3ce-c2a96ad810f3/fcb61255-7f3c-4011-b969-4baa7eb1a501/1280x720/match/480/270/image.jpg" alt="Easter Sunday at Saddleback Church with Rick Warren"> ALT: [Easter Sunday at Saddleback Church with Rick Warren] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/21388d3a-2474-45b0-a426-c6216579e628/6f4f9f8f-686e-41e2-859a-2b0173ec396c/1280x720/match/480/270/image.jpg" alt="Easter Sunday at First Baptist Dallas with Dr. Robert Jeffress"> ALT: [Easter Sunday at First Baptist Dallas with Dr. Robert Jeffress] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/d1edbbd6-4d73-4c15-914e-79c93a9f4292/73e97a51-0eff-4a5c-a5c6-3bdcf46db949/1280x720/match/480/270/image.jpg" alt="Easter Sunday Mass at St. Patrick's Cathedral"> ALT: [Easter Sunday Mass at St. Patrick's Cathedral] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/a34386a0-1571-47f2-af4c-3b939ae1933a/666dcd16-b5fd-49a3-89b6-98e8c738989e/1280x720/match/480/270/image.jpg" alt="Easter service at Lakewood Church with Joel Osteen"> ALT: [Easter service at Lakewood Church with Joel Osteen] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/a65bd207-e193-4dac-a22b-9befbb2277a1/dc0a4684-b98d-439f-9137-771fc7651420/1280x720/match/480/270/image.jpg" alt="Pope Francis gives Urbi et Orbi blessing"> ALT: [Pope Francis gives Urbi et Orbi blessing] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/11b72aee-0f98-4ab6-9a5f-ffbdab2eaab3/6338cc80-9038-47e8-b417-41252465ea38/1280x720/match/480/270/image.jpg" alt="Pope Francis presides over Easter Mass"> ALT: [Pope Francis presides over Easter Mass] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/53ee3ae5-c56d-4004-8fc4-deaed9a81f1d/ee9ac8f8-7c88-4d36-911f-4bb709846561/1280x720/match/480/270/image.jpg" alt="Pope Francis presides over Easter vigil ceremony"> ALT: [Pope Francis presides over Easter vigil ceremony] <img src="//a57.foxnews.com/hp.foxnews.com/images/2020/04/480/270/b0ac3b9b6689b080244fb89788ee7f0e.jpg" alt="President Trump tells Judge Jeanine that America will be back bigger, better and stronger than ever before"> ALT: [President Trump tells Judge Jeanine that America will be back bigger, better and stronger than ever before] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/97fc9be6-aaf0-4fe0-91d3-3a46f2b11443/f1955d76-1bc4-4b23-8161-74a2ab6f6bf5/1280x720/match/480/270/image.jpg" alt="Rudy Giuliani hits back at Democrats' pandemic politics"> ALT: [Rudy Giuliani hits back at Democrats' pandemic politics] <img src="//a57.foxnews.com/hp.foxnews.com/images/2020/04/1280/533/52d91505f5ca105624f439a86e062ced.jpg?tl=1&ve=1" alt="Country of coronavirus' origin blocks research on outbreak, deleted posts show"> ALT: [Country of coronavirus' origin blocks research on outbreak, deleted posts show] <img src="//a57.foxnews.com/static.foxnews.com/foxnews.com/content/uploads/2020/04/1024/576/AP20103813232544.jpg?tl=1&ve=1" alt="Tornadoes kill at least 6 in Mississippi, damage homes, buildings in Louisiana"/> ALT: [Tornadoes kill at least 6 in Mississippi, damage homes, buildings in Louisiana] <img src="//a57.foxnews.com/hp.foxnews.com/images/2020/04/1024/576/362782ebab386b42da12b464073f9395.jpg?tl=1&ve=1" alt="Dad, 20-year-old son laid to rest after losing coronavirus battles 3 days apart"/> ALT: [Dad, 20-year-old son laid to rest after losing coronavirus battles 3 days apart] <img src="//a57.foxnews.com/static.foxnews.com/foxnews.com/content/uploads/2020/04/1024/576/marylou-amer.jpg?tl=1&ve=1" alt="Detective died from coronavirus after twice being denied test, sister says"/> ALT: [Detective died from coronavirus after twice being denied test, sister says] <img src="//a57.foxnews.com/static.foxnews.com/foxnews.com/content/uploads/2020/04/1024/576/WisconsinFirefigther_1.jpg?tl=1&ve=1" alt="Check out how these firefighters paid tribute to health-care workers"/> ALT: [Check out how these firefighters paid tribute to health-care workers] <img src="//static.foxnews.com/static/orion/styles/img/fox-news/bg/fn-logo-watch-now.png" alt="Fox News"> ALT: [Fox News] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/b6a0e412-d473-4dab-b498-335e45d4c2e2/f65a1645-8c2d-4358-ae27-475863ff0098/1280x720/match/480/270/image.jpg" alt="Easter Sunday at Washington National Cathedral"> ALT: [Easter Sunday at Washington National Cathedral] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/957bd65c-090d-4a21-a3ce-c2a96ad810f3/fcb61255-7f3c-4011-b969-4baa7eb1a501/1280x720/match/480/270/image.jpg" alt="Easter Sunday at Saddleback Church with Rick Warren"> ALT: [Easter Sunday at Saddleback Church with Rick Warren] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/21388d3a-2474-45b0-a426-c6216579e628/6f4f9f8f-686e-41e2-859a-2b0173ec396c/1280x720/match/480/270/image.jpg" alt="Easter Sunday at First Baptist Dallas with Dr. Robert Jeffress"> ALT: [Easter Sunday at First Baptist Dallas with Dr. Robert Jeffress] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/d1edbbd6-4d73-4c15-914e-79c93a9f4292/73e97a51-0eff-4a5c-a5c6-3bdcf46db949/1280x720/match/480/270/image.jpg" alt="Easter Sunday Mass at St. Patrick's Cathedral"> ALT: [Easter Sunday Mass at St. Patrick's Cathedral] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/a34386a0-1571-47f2-af4c-3b939ae1933a/666dcd16-b5fd-49a3-89b6-98e8c738989e/1280x720/match/480/270/image.jpg" alt="Easter service at Lakewood Church with Joel Osteen"> ALT: [Easter service at Lakewood Church with Joel Osteen] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/a65bd207-e193-4dac-a22b-9befbb2277a1/dc0a4684-b98d-439f-9137-771fc7651420/1280x720/match/480/270/image.jpg" alt="Pope Francis gives Urbi et Orbi blessing"> ALT: [Pope Francis gives Urbi et Orbi blessing] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/11b72aee-0f98-4ab6-9a5f-ffbdab2eaab3/6338cc80-9038-47e8-b417-41252465ea38/1280x720/match/480/270/image.jpg" alt="Pope Francis presides over Easter Mass"> ALT: [Pope Francis presides over Easter Mass] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/53ee3ae5-c56d-4004-8fc4-deaed9a81f1d/ee9ac8f8-7c88-4d36-911f-4bb709846561/1280x720/match/480/270/image.jpg" alt="Pope Francis presides over Easter vigil ceremony"> ALT: [Pope Francis presides over Easter vigil ceremony] <img src="//a57.foxnews.com/hp.foxnews.com/images/2020/04/480/270/b0ac3b9b6689b080244fb89788ee7f0e.jpg" alt="President Trump tells Judge Jeanine that America will be back bigger, better and stronger than ever before"> ALT: [President Trump tells Judge Jeanine that America will be back bigger, better and stronger than ever before] <img src="//a57.foxnews.com/cf-images.us-east-1.prod.boltdns.net/v1/static/694940094001/97fc9be6-aaf0-4fe0-91d3-3a46f2b11443/f1955d76-1bc4-4b23-8161-74a2ab6f6bf5/1280x720/match/480/270/image.jpg" alt="Rudy Giuliani hits back at Democrats' pandemic politics"> ALT: [Rudy Giuliani hits back at Democrats' pandemic politics] <img data-src="REMOVED" alt="Pope Francis presides over Easter Mass" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Pope Francis presides over Easter Mass] <img data-src="REMOVED" alt="Oil surges after Saudi Arabia, Russia end price war with historic deal" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Oil surges after Saudi Arabia, Russia end price war with historic deal] <img data-src="REMOVED" alt="Broadway star in 'very critical condition' amid possible coronavirus fight" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Broadway star in 'very critical condition' amid possible coronavirus fight] <img data-src="REMOVED" alt="Rev. Franklin Graham's Easter Sunday message from NYC's Central Park" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Rev. Franklin Graham's Easter Sunday message from NYC's Central Park] <img data-src="REMOVED" alt="6 shot at California party that violated stay-at-home order, drew hundreds" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [6 shot at California party that violated stay-at-home order, drew hundreds] <img data-src="REMOVED" alt="JUSTIN HASKINS: AOC and friends peddling false cure for what ails US" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [JUSTIN HASKINS: AOC and friends peddling false cure for what ails US] <img data-src="REMOVED" alt="Cuban predicts new post-virus business models, talks of possible WH run" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Cuban predicts new post-virus business models, talks of possible WH run] <img data-src="REMOVED" alt="Police attacked with stones, iron bars while enforcing social distance measures" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Police attacked with stones, iron bars while enforcing social distance measures] <img data-src="REMOVED" alt="KFC mocks fans' homemade attempts to recreate fried chicken during coronavirus shutdown" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [KFC mocks fans' homemade attempts to recreate fried chicken during coronavirus shutdown] <img data-src="REMOVED" alt="Nurse confronts 'stupid' men defying coronavirus social distancing" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Nurse confronts 'stupid' men defying coronavirus social distancing] <img data-src="REMOVED" alt="What's coming to and leaving Hulu in April amid the coronavirus pandemic" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [What's coming to and leaving Hulu in April amid the coronavirus pandemic] <img data-src="REMOVED" alt="Nurses treating coronavirus patients find tires slashed" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Nurses treating coronavirus patients find tires slashed] <img data-src="REMOVED" alt="SEE IT: Woman, 93, makes coronavirus plea for more beer amid lockdown in viral photo" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [SEE IT: Woman, 93, makes coronavirus plea for more beer amid lockdown in viral photo] <img data-src="REMOVED" alt="'Tiger King': Carole, Howard Baskin say they feel 'betrayal' from filmmakers, are getting death threats" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: ['Tiger King': Carole, Howard Baskin say they feel 'betrayal' from filmmakers, are getting death threats] <img data-src="REMOVED" alt="Woman arrested for entering New Orleans airport naked amidst coronavirus lockdown" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Woman arrested for entering New Orleans airport naked amidst coronavirus lockdown] <img data-src="REMOVED" alt="Students in this country are protesting schools reopening" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Students in this country are protesting schools reopening] <img data-src="REMOVED" alt="‘Huge influx’ of COVID-19 patients putting strain on Moscow hospitals, Kremlin says" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [‘Huge influx’ of COVID-19 patients putting strain on Moscow hospitals, Kremlin says] <img data-src="REMOVED" alt="Olivia Munn on getting married someday: 'I never have ever been that girl'" src="//static.foxnews.com/static/orion/img/clear-16x9.gif" /> ALT: [Olivia Munn on getting married someday: 'I never have ever been that girl'] <img src="//a57.foxnews.com/hp.foxnews.com/images/2020/04/480/270/dd3f0280320f00471aa6e99ac2d14b8e.jpg" alt="Join Pete Hegseth as he focuses on one of the most important moments of the year for Christianity: Easter Sunday."> ALT: [Join Pete Hegseth as he focuses on one of the most important moments of the year for Christianity: Easter Sunday.] <img src="//a57.foxnews.com/hp.foxnews.com/images/2020/04/320/180/1c0802431b0b4b32b2cc72b49995772d.png" alt="America Together Category Page"> ALT: [America Together Category Page] <img src="//a57.foxnews.com/static.foxbusiness.com/foxbusiness.com/content/uploads/2020/04/480/270/Credible-no-cost-loan-thumbnail-1069166364.jpg" alt="How to refinance your mortgage without paying upfront closing costs"> ALT: [How to refinance your mortgage without paying upfront closing costs] <img data-src="REMOVED" alt="Paul Batura" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Paul Batura] <img data-src="REMOVED" alt="Scott Gunn" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Scott Gunn] <img data-src="REMOVED" alt="Jim Daly" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Jim Daly] <img src="//a57.foxnews.com/hp.foxnews.com/images/2017/10/128/128/63ba2426c69bdae0a03232c5b547f162.jpg" alt="Podcast Logo"> ALT: [Podcast Logo] <img data-src="REMOVED" alt="7 cool desserts to make with PEEPS" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [7 cool desserts to make with PEEPS] <img data-src="REMOVED" alt="Prankster costs pizzerias THOUSANDS" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Prankster costs pizzerias THOUSANDS] <img data-src="REMOVED" alt="Dolly's SPECIAL Easter message" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Dolly's SPECIAL Easter message] <img data-src="REMOVED" alt="'Tiger King' star getting DEATH threats" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: ['Tiger King' star getting DEATH threats] <img data-src="REMOVED" alt="Singer SLAMS Trump" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Singer SLAMS Trump] <img data-src="REMOVED" alt="Actor in 'VERY critical condition'" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Actor in 'VERY critical condition'] <img data-src="REMOVED" alt="Home tanning attempt goes WRONG" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Home tanning attempt goes WRONG] <img data-src="REMOVED" alt="Coronavirus ‘achilles heel’ FOUND?" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Coronavirus ‘achilles heel’ FOUND?] <img data-src="REMOVED" alt="Are 5G towers spreading COVID-19?" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Are 5G towers spreading COVID-19?] <img data-src="REMOVED" alt="10 tech spring cleaning tips for the quarantine era" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [10 tech spring cleaning tips for the quarantine era] <img data-src="REMOVED" alt="Can THIS slow coronavirus’ spread?" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Can THIS slow coronavirus’ spread?] <img data-src="REMOVED" alt="Iconic singer: 'Music doesn't mean ANYTHING'" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Iconic singer: 'Music doesn't mean ANYTHING'] <img data-src="REMOVED" alt="'Tiger King' star tells ALL" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: ['Tiger King' star tells ALL] <img data-src="REMOVED" alt="Hanks hosts SPECIAL show" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Hanks hosts SPECIAL show] <img data-src="REMOVED" alt="Best dramas to STREAM" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Best dramas to STREAM] <img data-src="REMOVED" alt="BEST idea for a quarantine birthday?" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [BEST idea for a quarantine birthday?] <img data-src="REMOVED" alt="WWI grenade found WHERE?" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [WWI grenade found WHERE?] <img data-src="REMOVED" alt="What to do for EASTER during coronavirus crisis" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [What to do for EASTER during coronavirus crisis] <img data-src="REMOVED" alt="Adopting RABBITS the new quarantine thing?" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [Adopting RABBITS the new quarantine thing?] <img data-src="REMOVED" alt="New CANNONBALL RUN record set?" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [New CANNONBALL RUN record set?] <img data-src="REMOVED" alt="America Together: YOUR inspiring pics" src="//global.fncstatic.com/static/orion/img/clear.gif" /> ALT: [America Together: YOUR inspiring pics] <img data-srcset="REMOVED" data-src="REMOVED" alt="Charlie Kirk fires back at Trump critics over economic shutdown: Time to stop 'crisis in America'" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Charlie Kirk fires back at Trump critics over economic shutdown: Time to stop 'crisis in America'] <img data-srcset="REMOVED" data-src="REMOVED" alt="Charlie Kirk fires back at Trump critics over economic shutdown: Time to stop 'crisis in America'" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Charlie Kirk fires back at Trump critics over economic shutdown: Time to stop 'crisis in America'] <img data-srcset="REMOVED" data-src="REMOVED" alt="Reporter's Notebook: How Congress may proceed in the 'After Coronavirus' era" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Reporter's Notebook: How Congress may proceed in the 'After Coronavirus' era] <img data-srcset="REMOVED" data-src="REMOVED" alt="Tornadoes raging across South kill at least 6 in Mississippi, damage hundreds of buildings in Louisiana" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Tornadoes raging across South kill at least 6 in Mississippi, damage hundreds of buildings in Louisiana] <img data-srcset="REMOVED" data-src="REMOVED" alt="Justin Haskins: Coronavirus and socialism – AOC and friends peddling false cure for what ails US" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Justin Haskins: Coronavirus and socialism – AOC and friends peddling false cure for what ails US] <img data-srcset="REMOVED" data-src="REMOVED" alt="Kathie Lee Gifford says her kids 'insisted' she self-isolate in Florida: ‘It’s quite beautiful’" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Kathie Lee Gifford says her kids 'insisted' she self-isolate in Florida: ‘It’s quite beautiful’] <img data-srcset="REMOVED" data-src="REMOVED" alt="Matthew McConaughey, wife Camila donate 80K face masks to coronavirus first-responders in Texas, Louisiana" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Matthew McConaughey, wife Camila donate 80K face masks to coronavirus first-responders in Texas, Louisiana] <img data-srcset="REMOVED" data-src="REMOVED" alt="Gov. DeSantis on protecting senior citizens, expanding coronavirus testing and supporting health care workers" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Gov. DeSantis on protecting senior citizens, expanding coronavirus testing and supporting health care workers] <img data-srcset="REMOVED" data-src="REMOVED" alt="First coronavirus relief checks deposited to Americans: IRS" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [First coronavirus relief checks deposited to Americans: IRS] <img data-srcset="REMOVED" data-src="REMOVED" alt="FBI exposes coronavirus scam after 39M masks promised from overseas fail to reach California hospitals" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [FBI exposes coronavirus scam after 39M masks promised from overseas fail to reach California hospitals] <img data-srcset="REMOVED" data-src="REMOVED" alt="Mustang crashes off California cliff during coronavirus lockdown, gets pulled out by 'Hulk' wrecker" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Mustang crashes off California cliff during coronavirus lockdown, gets pulled out by 'Hulk' wrecker] <img data-srcset="REMOVED" data-src="REMOVED" alt="Trump administration plans to open 2.3 million acres of wildlife refuges to hunting and fishing" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Trump administration plans to open 2.3 million acres of wildlife refuges to hunting and fishing] <img data-srcset="REMOVED" data-src="REMOVED" alt="Many restaurants weather coronavirus storm by converting to grocery stores" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Many restaurants weather coronavirus storm by converting to grocery stores] <img data-srcset="REMOVED" data-src="REMOVED" alt="Coronavirus: How to celebrate a birthday during the pandemic" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Coronavirus: How to celebrate a birthday during the pandemic] <img data-srcset="REMOVED" data-src="REMOVED" alt="Woman accidentally tans company logo onto her leg during coronavirus lockdown" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Woman accidentally tans company logo onto her leg during coronavirus lockdown] <img data-srcset="REMOVED" data-src="REMOVED" alt="Petition calling for WHO boss Tedros to resign nears 1M signatures" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Petition calling for WHO boss Tedros to resign nears 1M signatures] <img data-srcset="REMOVED" data-src="REMOVED" alt="REPAYE could lower your student loan payments — here's how" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [REPAYE could lower your student loan payments — here's how] <img data-srcset="REMOVED" data-src="REMOVED" alt="Matthew McConaughey, wife Camila donate 80K face masks to coronavirus first-responders in Texas, Louisiana" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Matthew McConaughey, wife Camila donate 80K face masks to coronavirus first-responders in Texas, Louisiana] <img data-srcset="REMOVED" data-src="REMOVED" alt="Fox News Sunday - Sunday, April 12" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Fox News Sunday - Sunday, April 12] <img data-srcset="REMOVED" data-src="REMOVED" alt="Dolly Parton shares special Easter message: It's 'a little different this year' with coronavirus" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: [Dolly Parton shares special Easter message: It's 'a little different this year' with coronavirus] <img data-srcset="REMOVED" data-src="REMOVED" alt="'Tiger King': Carole, Howard Baskin say they feel 'betrayal' from filmmakers, are getting death threats" src="//global.fncstatic.com/static/orion/img/clear.gif"> ALT: ['Tiger King': Carole, Howard Baskin say they feel 'betrayal' from filmmakers, are getting death threats]
        Parameters:
        innerTagAttribute - This may be any Java-String, but very common examples of HTML attributes (and their values) include:
        Attribute / Inner-Tag Commonly Found Attribute-Values
        HREF="..." where the attribute value ("...") - is a URL
        SRC='...' and the attribute value specified ('...') - is usually an Image-URL (like a "pic.jpg")
        ID=... where the attribute value (...) - would be a "CSS Identifier Tag"
        CLASS='...' and the attribute value ('...') - is the "CSS Class" to which the particular HTML element belongs
        OnClick="..." and the attribute value ("...") - is often a function call to a Java-Script module, or actual Java-Script
        href="..." SAME AS ABOVE! - Remember an "inner-tag" or "attribute" name is CASE-INSENSITIVE
        src='...' SAME AS ABOVE! - Remember an "inner-tag" or "attribute" name is CASE-INSENSITIVE
        Returns:
        The Attribute Value, which for the inner-tag named by the input String-parameter. Null is returned if 'this' instance does not have such an Attribute.

        NOTE: If 'this' TagNode instance is a Closing-Tag (specifically, if its isClosing Field is TRUE), this method will exit immediately, and return null. No exceptions shall throw; however, bear in mind that valid HTML pages do not allow attributes inside of Closing HTML-Tags.

        OPTIMIZATION: If 'this' instance' str-Field has a length that isn't greater than the following: 3 + tok.length() + innerTagAttribute.trim().length()), then in this will return null quickly, and exit. Viewing this method's code snippet (below), the heuristic may be readily apparent.

        The rational for exiting quickly is that the internal str-Field simply does not have enough characters to contain the specified attribute.
        See Also:
        StringParse.ifQuotesStripQuotes(String)
      • AVOPT

        🡅  🡇     🗕  🗗  🗖
        public java.lang.String AVOPT​(java.lang.String innerTagAttribute)
        AVOPT: Attribute-Value - Optimized

        This is an "optimized" version of method AV(String). This method does the exact same thing as AV(...), but leaves out parameter-checking and error-checking. This is used internally (and repeatedly) by the NodeSearch Package Search Loops.
        Parameters:
        innerTagAttribute - This is the inner-tag / attribute name whose value is hereby being requested.
        Returns:
        String-value of this inner-tag / attribute.
        See Also:
        StringParse.ifQuotesStripQuotes(String), HTMLNode.str
      • setAV

        🡅  🡇     🗕  🗗  🗖
        public TagNode setAV​(java.lang.String attribute,
                             java.lang.String value,
                             SD quote)
        This function will instantiate a new TagNode which contains this newly added attribute-value pair. It uses the constructor listed above, and furthermore does some error-handling checks. It will throw an exception if the inner-tag / value pairs do not pass inspection on quotes-error cases, or contain invalid characters.

        example
        Parameters:
        attribute - Any valid HTML attribute-name. This parameter may not be null, or a NullPointerException will throw.

        NOTE: If the attribute that is specified is already contained within this tag (where a CASE-INSENSITIVE comparison to the inner-tag's returned by allAV() gets a match), then the original attribute is simply over-written. A Duplicate HTML-Element attribute will not be added.
        value - Any valid attribute-value. This parameter may not be null, or a NullPointerException will throw.
        quote - This is either a single-quote, double-quote, or null.

        • When parameter 'quote' is SingleQuotes, a single-quote is prepended and appended to the beginning and ending (respectively) of the value parameter before inserting or replacing the inner-tag of this HTML (TagNode) Element.

        • When parameter 'quote' is Doubleuotes, a double-quote is added to the beginning and ending of the value-parameter before inserting (or re-inserting, if this attribute as already present).

        • When 'quote' is null, two are three alternative results, depending on the TagNode:

          1. If the TagNode already has an inner-tag name that is equal (CASE_INSENSITIVE) to the 'key' parameter, then the original quote found in 'this' Element is used.

          2. If a new attribute, not already found in 'this' TagNode is being inserted, and parameter 'quote' is null, then no quotes will be used at all - which is a scenario sometimes found in HTML documents. In this case, the key-value inner-tag will simply contain the String <HTML-ELEMENT ... key=value ...> without any quotes present, at all.
        Returns:
        An HTML TagNode instance with updated attribute information.

        IMPORTANT: Because TagNode's are immutable (since they are just wrapped Java-Strings, which are also immutable), it is important to remember that this method does not change the contents of a TagNode, but rather returns an entirely new TagNode instance as a result instead.
        Throws:
        InnerTagKeyException - This exception will throw if a non-standard String-value is passed to String-Parameter 'attribute'. HTML expects that an Attribute-Name conform to a set of rules in order to be processed by a Web-Browser.
        QuotesException - If there are "quotes within quotes" problems when invoking the TagNode constructor, this exception will throw. The problem occurs when one or more of the Attribute Key-Value Pairs have a quotation-choice such that the chosen quotation-mark is also found within the Attribute-Value.

        QuotesException will also throw in the case that an Attribute Key-Value Pair has elected to use the "No Quotes" option, but the attribute-value contains white-space.
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        HTMLTokException - If an invalid HTML 4 or 5 token is not present (CASE_INSENSITIVE).
        See Also:
        ClosingTagNodeException.check(TagNode), setAV(Properties, SD), HTMLNode.str, isClosing
      • setAV

        🡅  🡇     🗕  🗗  🗖
        public TagNode setAV​(java.util.Properties attributes,
                             SD defaultQuote)
        This allows for inserting or updating multiple TagNode inner-tag key-value pairs with a single method invocation.
        Parameters:
        attributes - These are the new attribute key-value pairs to be inserted.
        defaultQuote - This is the default quotation mark to use, if the 'attribute' themselves do not already have quotations.

        IMPORTANT: If this value is used, then none of the provided Property-values of the input java.lang.Properties instance should have quotes already. Each of these new-values will be wrapped in the quote that is provided as the value to this parameter.

        HOWEVER: If this parameter is passed a value of 'null', then no quotes will be added to the new keys - unless the attribute being inserted is replacing a previous attribute that was already present in the element. In this case, the original quotation shall be used. If this parameter receives 'null' and any of the new Properties were not already present in the original ('this') element, then no quotation marks will be used, which may throw a QuotesException if the attribute value contains any white-space.
        Returns:
        An HTML TagNode instance with updated TagNode information.

        IMPORTANT: Because TagNode's are immutable (since they are just wrapped-java-String's, which are also immutable), it is important to remember that this method does not change the content of a TagNode, but rather returns an entirely new TagNode as a result instead.
        Throws:
        InnerTagKeyException - This exception will throw if any of the keys in the Properties parameter contain non-standard HTML Attribute / Inner-Tag key Strings.

        HTML expects that Attribute-Names conform to a set of rules in order to be processed properly by a Web-Browser. There is a check method in class InnerTagKeyException which delineates the exact requirements made by HTML for Attribute-Names. This method uses a Regular-Expression to do its checks.
        QuotesException - if there are "quotes within quotes" problems, due to the values of the key-value pairs.
        HTMLTokException - if an invalid HTML 4 or 5 token is not present (CASE_INSENSITIVE)
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        See Also:
        ClosingTagNodeException.check(TagNode), setAV(String, String, SD), isClosing
      • appendToAV

        🡅  🡇     🗕  🗗  🗖
        public TagNode appendToAV​(java.lang.String attribute,
                                  java.lang.String appendStr,
                                  boolean startOrEnd,
                                  SD quote)
        This will append a substring to the attribute value of an HTML TagNode. This method can be very useful, for instance when dealing with CSS tags that are inserted inside the HTML node itself. For example, in order to add a 'color: red; background: white;' portion to the CSS 'style' tag of an HTML <TABLE STYLE="..."> element, without clobbering the style-information that is already inside the element, using this method will achieve that.
        Parameters:
        attribute - The name of the attribute to which the value must be appended. This parameter may not be null, or a NullPointerException will throw.
        appendStr - The String to be appended to the attribute-value.
        startOrEnd - If this parameter is TRUE then the append-String will be inserted at the beginning (before) whatever the current attribute- value is. If this parameter is FALSE then the append-String will be inserted at the end (after) the current attribute-value String.

        NOTE: If tag element currently does not posses this attribute, then the attribute/value pair will be created and inserted with its value set to the value of 'appendStr'.
        quote - This is the quote that will be used when defining the attribute's key-value pair inside the tag element. The programmer is expected to decide between using: SingleQuotes, DoubleQuotes or none / no-quotes (by passing null, with caveats). If null is passed to this parameter, then the complete list of rules that are applied, as explained in detail in method setAV.

        Please review the complete delineation of the rules for how quotation marks are added and used in an HTML Tag Attribute, vis-a-vis the 'quote' parameter.

        It is important to note that "appending" a String to an attribute's value will often (but not always) mean that the new attribute-value will have a space character. If this parameter were passed null, and if the original tag had a value, but did not use any quotes, then the attribute's ultimate inclusion into the tag would generate invalid HTML, and the invocation of setAV(String, String, SD) would throw a QuotesException.
        Returns:
        Since all instances of TagNode are immutable, this method will not actually alter the TagNode element, but rather create a new object reference that contains the updated attribute.
        Throws:
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        QuotesException - The rules for quotation usage apply here too, and see that explanation for how how this exception could be thrown.
        See Also:
        AV(String), setAV(String, String, SD), ClosingTagNodeException.check(TagNode)
      • removeAttributes

        🡅  🡇     🗕  🗗  🗖
        public TagNode removeAttributes​(java.lang.String... attributes)
        This will remove all inner-tag's whose names match (using CASE-INSENSITIVE comparisons) the specified attribute-names in this input parameter list 'attributes'.

        NOTE: This will remove all inner-tags that match the listed attributes provided. This means removing BOTH boolean 'key-only' attributes, AND any key-value inner-tags that have names which match the requested remove-list of names.
        Parameters:
        attributes - This is a list of attribute-names (inner-tags) to be removed from 'this' instance of TagNode. Each String in this var-args String... parameter will have String.toLowerCase() invoked before performing these attribute-name comparisons.

        NOTE: If 'this' instance of TagNode node does not contain any of these attributes, then nothing shall happen; however, a new TagNode instance shall still be constructed and returned.
        Returns:
        An HTML TagNode instance with updated TagNode information.

        IMPORTANT: Because TagNode's are immutable (since they are just wrapped-java-String's, which are also immutable), it is important to remember that this method does not change the contents of a TagNode, but rather returns an entirely new TagNode as a result instead.
        Throws:
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        See Also:
        ClosingTagNodeException.check(TagNode)
      • removeAttributes

        🡅  🡇     🗕  🗗  🗖
        public TagNode removeAttributes​
                    (java.util.function.Predicate<java.lang.String> attrNameTest)
        
        Filter's attributes using an Attribute-Name String-Predicate
        Parameters:
        attrNameTest - Any Java String-Predicate. It will be used to test whether or not to keep or filter/reject an attribute from 'this' TagNode.

        NOTE: Like all filter-Predicate's, this test's expected behavior is such that it should return TRUE when it would like to keep an attribute having a particular name, and return FALSE when it would like to see the attribute removed from the HTML Tag.
        Returns:
        Removes any Attributes whoe name as per the rules of the User-Provided String-Predicate parameter 'attrNameTest'. As with all TagNode modification operations, if any changes are, indeed, made to a new instance of TagNode will be created and returned.
      • removeAllAV

        🡅  🡇     🗕  🗗  🗖
        public TagNode removeAllAV()
        TagNode's are immutable. And because of this, calling removeAllAV() is actually the same as retrieving the standard, zero-attribute, pre-instantiated instance of an HTML Element. Pre-instantiated factory-instances of Class TagNode for every HTML-Element are stored by Class HTMLTags inside of a Java Hashtable. They can be retrieved in multiple ways, two of which are found in methods in this class.

        Point of Interest:
        Calling these three different methods will all return identical Object references:

        • TagNode v1 = myTagNode.removeAllAV();
        • TagNode v2 = TagNode.getInstance(myTagToken, openOrClosed);
        • TagNode v3 = HTMLTag.hasTag(myTagToken, openOrClosed);
        • assert((v1 == v2) && (v2 == v3));


        example
        Returns:
        An HTML TagNode instance with all inner attributes removed.

        NOTE: If this tag contains an "ending forward slash" that ending slash will not be included in the output TagNode.

        IMPORTANT: Because TagNode's are immutable (since they are just wrapped-Java-String's, which are also immutable), it is important to remember that this method does not change the content of a TagNode, but rather returns an entirely new TagNode as a result, instead.
        Throws:
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        See Also:
        ClosingTagNodeException.check(TagNode), getInstance(String, TC), TC.OpeningTags
      • allAV

        🡅  🡇     🗕  🗗  🗖
        public java.util.Properties allAV​(boolean keepQuotes,
                                          boolean preserveKeysCase)
        This will copy every attribute key-value pair inside 'this' HTML TagNode element into a java.util.Properties instance.

        Attributes not Included:
        This method shall not return any Key-Only Attributes (a.k.a. "Boolean Attributes"). The most commonly used "Boolean Attribute" example is the 'HIDDEN' key-word that is used to prevent a Browser from displaying an HTML Element onto the page at all.

        Attributes / Inner-tags that represent Attribute key-value pairs are the only Attributes that are permitted for inclusion in the 'Properties' instance returned by this method.

        example
        Parameters:
        keepQuotes - If this parameter is passed TRUE, then any surrounding quotation marks will be included for each the values of each attribute key-value pair.
        preserveKeysCase - If this parameter is passed TRUE, then the Java String-Class method toLowerCase() will not be invoked on any of the keys (attribute-names) of each inner-tag key-value pair.

        HTML expects that all attribute names function in a CASE INSENSITIVE fashion. Java, however, makes no such expectations on it's class java.util.Properties tables, or most other String-containers. Preserving the case of an attribute-name will produce more consistent looking HTML. But for more easily-searchable java-Strings, converting to lower-case can make coding easier.
        Returns:
        This returns a list of each and every attribute-name - and the associated value of the attribute - found in 'this' instance of TagNode. An instance of Class java.util.Properties is used to store the attribute key-value pairs.

        NOTE: This method will NOT return any boolean, key-only attributes present in 'this' TagNode.

        ALSO: This method shall not return 'null'. If there do not exist any Attribute-Value Pairs, or if 'this' node is a closing-element, then an empty 'Properties' instance shall be returned.
        See Also:
        StringParse.ifQuotesStripQuotes(String)
      • allAN

        🡅  🡇     🗕  🗗  🗖
        public java.util.stream.Stream<java.lang.String> allAN​
                    (boolean preserveKeysCase,
                     boolean includeKeyOnlyAttributes)
        
        This method will only return a list of attribute-names. The attribute-values shall NOT be included in the result. The String's returned can have their "case-preserved" by passing TRUE to the input boolean parameter 'preserveKeysCase'.
        Parameters:
        preserveKeysCase - If this is parameter receives TRUE then the case of the attribute-names shall be preserved.

        HTML expects that all attribute names function in a CASE INSENSITIVE fashion. Java, however, makes no such expectations on it's class java.util.Properties tables, or most other String-containers. Preserving the case of an attribute-name will produce more consistent looking HTML. But for more easily-searchable java-Strings, converting to lower-case can make coding easier.
        includeKeyOnlyAttributes - When this parameter receives TRUE, then any "Boolean Attributes" or "Key-Only, No-Value-Assignment" Inner-Tags will ALSO be included in the Stream<String> returned by this method.
        Returns:
        an instance of Stream<String> containing all attribute-names identified in 'this' instance of TagNode. A java.util.stream.Stream is used because it's contents can easily be converted to just about any data-type.

        Conversion-Target Stream-Method Invocation
        String[] Stream.toArray(String[]::new);
        List<String> Stream.collect(Collectors.toList());
        Vector<String> Stream.collect(Collectors.toCollection(Vector::new));
        TreeSet<String> Stream.collect(Collectors.toCollection(TreeSet::new));
        Iterator<String> Stream.iterator();

        NOTE: This method shall never return 'null' - even if there are no attribute key-value pairs contained by 'this' TagNode. If there are strictly zero attributes, an empty Stream shall be returned, instead.
        See Also:
        allKeyOnlyAttributes(boolean), allAN()
      • allKeyOnlyAttributes

        🡅  🡇     🗕  🗗  🗖
        public java.util.stream.Stream<java.lang.String> allKeyOnlyAttributes​
                    (boolean preserveKeysCase)
        
        This method returns a Stream<String> of all token-String's that are found between attribute key-value pairs in 'this' TagNode instance. The attribute-names which are returned will be the ones to which no values have been assigned.

        Inner-Tags with value-assignments are inelligible for being included in the returned result-set.

        example
        Parameters:
        preserveKeysCase - If this parameter is passed TRUE, then the method String.toLowerCase() will not be invoked on any of the key's (attribute-names) returned by this method.

        HTML expects that all attribute names function in a CASE INSENSITIVE fashion. Java, however, makes no such expectations on it's class java.util.Properties tables, or most other String-containers. Preserving the case of an attribute-name will produce more consistent looking HTML. But for more easily-searchable java-Strings, converting to lower-case can make coding easier.
        Returns:
        a java Stream that contains any and all character text that resides in-between attribute key-value pairs that have matched. Generally, in well formed HTML, this should correspond directly to what are normally called "Boolean Attributes." Boolean Attributes are just words inside of an HTML Element that describe the elements contents. The primary issue regarding these types of inner-tags is that they do not have any values - they are strictly a key, alone.
        NOTE: This method shall never return 'null' - even if there are no attribute key-value pairs contained by the TagNode. If there are strictly zero attributes, Stream.empty() shall be returned, instead.

        Conversion-Target Stream-Method Invocation
        String[] Stream.toArray(String[]::new);
        List<String> Stream.collect(Collectors.toList());
        Vector<String> Stream.collect(Collectors.toCollection(Vector::new));
        TreeSet<String> Stream.collect(Collectors.toCollection(TreeSet::new));
        Iterator<String> Stream.iterator();
      • hasKeyOnlyAttribute

        🡅  🡇     🗕  🗗  🗖
        public boolean hasKeyOnlyAttribute​(java.lang.String keyOnlyAttribute)
        Will identify if a Boolean-Attribute - a.k.a. a token-name that exists BETWEEN inner-tag key-value pairs - is present in the TagNode. One of the most common of these Boolean-Attributes ("Key-Word-Only Attributes") is the inner-tag HIDDEN. Hidden HTML Elements have their CSS feature style.display set to none.
        Parameters:
        keyOnlyAttribute - This may be the name of any inner-tag.

        NOTE: This parameter, is not checked for validity against the attribute-name regular-expression.
        Returns:
        Will return TRUE if the named keyOnlyAttribute is present in the HTML Element as a stand-alone inner-tag - i.e., it is lacking any value assignments The comparison performed is case-insensitive, since HTML Attribute-names are considered fundamentally case-insensitive.

        If 'this' instance of TagNode is a closing-version of the element, this method shall return FALSE immediately, and exit.
        Throws:
        java.lang.IllegalArgumentException - If the input-parameter receives a String that contains any white-space itself, an exception will throw. The search-logic splits the String's based on white-space, so if a user passes a white-space containing String, a match would simply never occur.

        IMPORTANT: This method does not check the validity of the 'keyOnlyAttribute' parameter against the Attribute-name regular-expression, because this method uses the 'split(String)' method of the Regular-Expression Matcher. All this means, is that this method may actually be used to check for any-text inside of an HTML Element - so long as that text does not contain white-space. This is not an encouraged use of this method, but it will work.
      • testAV

        🡅  🡇     🗕  🗗  🗖
        public boolean testAV​
                    (java.lang.String attributeName,
                     java.util.function.Predicate<java.lang.String> attributeValueTest)
        
        Test the value of the inner-tag named 'attributeName' (if that attribute exists, and has a non-empty value) using a provided Predicate<String>.

        example
        Parameters:
        attributeName - Any String will suffice - but only valid attribute names will match the internal regular-expression.

        NOTE: The validity of this parameter is not checked with the HTML attribute-name Regular-Expression exception checker.
        attributeValueTest - Any java.util.function.Predicate<String>
        Returns:
        Method will return TRUE if and only if:

        • 'this' instance of TagNode has an inner-tag named 'attributeName'.

        • The results of the provided String-Predicate, when applied against the value of the requested attribute, returns TRUE.
        See Also:
        StringParse.ifQuotesStripQuotes(String)
      • hasXOR

        🡅  🡇     🗕  🗗  🗖
        public boolean hasXOR​(boolean checkAttributeStringsForErrors,
                              java.lang.String... attributes)
        Convenience Method
        Passes: XOR Boolean Logic
        Checks that precisely-one Attribute is found
        Example
        Parameters:
        checkAttributeStringsForErrors - Some may argue this is confusing. The purpose of this boolean is actually somewhat important. People who have written software libraries start to see that "Error Checking" (Proper Exceptions with consistent error messages) is one of the more beneficial features of the library. The catch is that it can add a layer of redundancy and inefficiency - where the same set of data are tested and retested (inside a loop, for instance) over and over.

        If the programmer has already checked the attributes / inner-tags for validity, and intends to use this boolean-method inside of a loop-construct, it should be obvious that FALSE needs to be passed to this parameter. If this test is not within a loop, it is much less of an issue.

        NOTE: When this variable is *FALSE*, the passed attribute parameters will not be checked for validity. When *TRUE* the attributes Strings will be tested on each method invocation. This is included to encourage programmers to check their HTML and avoid invalid attribute strings (has spaces, are null, etc.) earlier.

        NOTE: If this method is passed a zero-length String-array to the 'attributes' parameter, this method shall exit immediately and return FALSE.
        See Also:
        InnerTagKeyException.check(String[])
      • has

        🡅  🡇     🗕  🗗  🗖
        public boolean has​(java.lang.String attributeName)
        Convenience Method
        Passes: String.equalsIgnoreCase(attributeName) as the test-Predicate
        See Also:
        has(Predicate)
      • has

        🡅  🡇     🗕  🗗  🗖
        public boolean has​
                    (java.util.function.Predicate<java.lang.String> attributeNameTest)
        
        Will search this TagNode to determine if any inner-tag key-value pairs have a key (attribute-name) that is accepted by the Predicate<String> parameter 'attributeNameTest'.

        This method will also check the boolean-attributes, which are attributes that include a key, but do not have a value assigned to them (such as the commonly used boolean-attribute 'hidden' - which indicates that a particular element should not be rendered-visible).

        NOTE: If 'this' instance of TagNode is a closing-version of the HTML Tag (SPECIFICALLY: this.isClosing == TRUE), then this method shall exit gracefully - and immediately - returning FALSE. The (sometimes) requisite exception for such cases - OpeningTagNodeExpectedException - shall NOT throw. Remember that HTML does not actually allow for attributes placed inside of closing HTML elements (</DIV>, </TABLE>, or </SPAN> for instance).
        Parameters:
        attributeNameTest - A String Predicate parameter that is used to accept or reject a match with the list of attribute keys (including the Boolean-Attribute keys) in 'this' HTML Tag.

        NOTE: The StrFilter in package Torello.Java is capable of generating a rather wide range of test-Predicate's using regular-expressions. This is one option to think about when using this method.
        Returns:
        Will return TRUE if there are any inner-tag's whose name is accepted by the input-parameter Predicate 'attributeNameTest' (and FALSE otherwise).
        See Also:
        StrFilter
      • hasValue

        🡅  🡇     🗕  🗗  🗖
        public java.util.Map.Entry<java.lang.String,​java.lang.String> hasValue​
                    (java.util.function.Predicate<java.lang.String> attributeValueTest,
                     boolean retainQuotes,
                     boolean preserveKeysCase)
        
        Will search this TagNode to determine if any inner-tag key-value pairs have an attribute-value that is accepted by the String-Predicate parameter 'attributeValueTest'.

        NOTE: If 'this' instance of TagNode is a closing-version of the HTML Tag (SPECIFICALLY: this.isClosing == TRUE), then this method shall exit gracefully - and immediately - returning 'null'. The (sometimes) requisite exception for such cases - OpeningTagNodeExpectedException - shall NOT throw. Remember that HTML will not permit attributes placed inside closing HTML Tags (</DIV>, </TABLE>, or </SPAN> for instance).
        Parameters:
        attributeValueTest - A String-Predicate parameter that is used to accept or reject a match with the list of all attribute values in 'this' HTML Element

        NOTE: The class StrFilter s capable of generating a rather wide range of test-Predicate's using regular-expressions. This is one option to think about when using this method.
        retainQuotes - The parameter is required to inform the program whether or not the quotation marks should be included along with the returned value inside the Map.Entry. This can sometimes be useful, for example, when complicated script-containing TagNode's are involved.
        preserveKeysCase - When this parameter is TRUE, the program will not invoke String.toLowerCase() on the Map.Entry's key. If FALSE, then the returned Map.Entry will have a key (attribute-name) that is strictly in lower-case format.

        HTML expects that all attribute names function in a CASE INSENSITIVE fashion. Java, however, makes no such expectations on it's class java.util.Properties tables, or most other String-containers. Preserving the case of an attribute-name will produce more consistent looking HTML. But for more easily-searchable java-Strings, converting to lower-case can make coding easier.
        Returns:
        Returns a Map.Entry<String, String> Key-Value Pair - if and only if there are any inner-tag's whose value is accepted by the input-parameter Predicate-test 'attributeNameTest'.

        If no such match is found, this method will return 'null'
        See Also:
        StrFilter
      • getInstance

        🡅  🡇     🗕  🗗  🗖
        public static TagNode getInstance​(java.lang.String tok,
                                          TC openOrClosed)
        This is an "identical" method to HTMLTags.hasTag, except that this method will do some parameter error-checking, and throw exceptions if possible, rather than simply returning null.

        NOTE: All three classes which inherit HTMLNode - TagNode, TextNode and CommentNode - are immutable. The instances cannot be changed. In order to update, tweak, or modify an HTML page, you must instantiate or retrieve another instance of HTMLNode, and replace the position in the containing-Vector with a new node.

        This method, 'getInstance' interacts with the class HTMLTags to retrieve one of the pre-instantiated OpeningTags or ClosingTags. It is possible to 're-use' the same instance of a TagNode in different pages and different Vector's in the same way that Java String's can be re-used, exactly because they are immutable.

        If a TagNode instance is used in different pages, the in-ability to change a TagNode's contents is what allows multiple, different pages to use them in multiple Vector's without worrying about their contents becoming affected by concurrency issues. class HTMLTags maintains 4 complete lists of already-instantiated TagNode's (upper-case, lower-case, opening-tag, closing-tag) in a java.util.TreeMap<String, TagNode> since usually a very high percentage of HTML Element's are elements with no attribute information at all.

        ALSO: It should be obvious to the reader, by now, that keeping 'pre-instantiated' TagNode elements that do contain attributes would be orders of magnitude more costly (and difficult}. This practice is not performed by the Java-HTML library.

        SIMILARLY: All pre-instantiated HTML TagNode's have ZERO attributes or "inner-tags" inside. To generate a TagNode with attributes, use the class TagNode constructor. Make sure not to leave out the rest of the inner-tags from the element-body String.
        Parameters:
        tok - Any valid HTML tag.
        openOrClosed - If TC.OpeningTags is passed, then an "open" version of the HTML tag will be returned,
        If TC.ClosingTags is passed, then a closing version will be returned.
        If TC.Both is accidentally passed - an IllegalArgumentException is thrown.
        Returns:
        An instance of this class
        Throws:
        java.lang.IllegalArgumentException - If parameter TC openOrClose is null or TC.Both
        HTMLTokException - If the parameter String tok is not a valid HTML-tag
        SingletonException - If the token requested is a singleton (self-closing) tag, but the Tag-Criteria 'TC' parameter is requesting a closing-version of the tag.
        See Also:
        HTMLTags.hasTag(String, TC), HTMLTags.isSingleton(String)
      • cssClasses

        🡅  🡇     🗕  🗗  🗖
        public java.util.stream.Stream<java.lang.String> cssClasses()
        Method cssClasses is to be used as a tool for splitting the results of invoking method TagNode.AV("class") into String's - separating it by white-space. The code here is a rather 'naïve' attempt to retrieve CSS classes, because it follows the 95% percent rule: 95% of the time there should be no problems! More advanced HTML Generator Tools have taken advantage of HTML's 'flexibility' and have created CSS classes that my contain anything from parenthesis '(' and ')', to semi-colons ';', to many other formats that proprietary web-developers so choose. And rather than attempting to 'predict' all future changes to CSS Class-Names, this method is intended to help developers retrieve basic (READ: 'non-preprocessor') CSS class-information. This is the nature of changing web-internet tools.

        Primarily, recognizing that dynamically, script and pre-processor generated class information, cannot be known, without having script-processing performed. This package is designed for parsing, searching, and updating HTML Pages, but it does not execute script (at least not now). Therefore, rather than returning possibly fallacious results - an exception throws when non-standard HTML CSS Classes are used, instead. This does not mean that the CSS String 'attribute-value' cannot be retrieved, but rather just that the method TagNode.AV("class") should always work and be used instead.

        If a return value is provided, it is guaranteed to be correct.

        COUNTER-EXAMPLE: The following output was generated by a small, 8-line program that scrapes a web-page from 'Yahoo! News', and then prints out the CSS Class Information by invoking this, 'cssClasses(...)' method. Notice, that after the very fourth iteration of the loop (which iterates over instances of 'TagNode' - skipping TextNode and HTMLNode instances), the exception 'CSSStrException' is thrown. This is because Yahoo! uses something known as "CSS Pre-Processor" and "SCSS", and though the scrape-functions, themselves, cannot interpret the script-generted CSS Class-Names in this example, React-JS is able to update the class-strings (after-download, and in-the-browser) easily. The first text-box, below, contains the hilited source-code that produced the output. The next text-box contains the ouptut of this short program to the terminal-shell window.

        Counter Example:
         1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        // Load the top-level news page for Yahoo! news
        Vector<HTMLNode> v = HTMLPage.getPageTokens(new URL("https://news.yahoo.com"), false);
        
        // Iterate through each and every "TagNode" element that contains a CSS "Class" Attribute
        for (TagNode tn : InnerTagGet.all(v, "class"))
        {
            // Print out the actual 'text' of the TagNode.  Use the "Shell.C" Unix-Colors class to print them in "Bright Red"
            System.out.println(C.BRED + tn.str + C.RESET);
        
            // Retrieve each / all / any of the CSS 'class' attributes, and print them.
            tn.cssClasses().forEach(c -> System.out.print("[" + c + "],\t"));
        
            // Before starting next TagNode class-attribute information, send a CRLF to the terminal
            System.out.println();
        }
        

        The following text was generated by the above short program, scraping Yahoo! News. It prints out relevant CSS Class Information. Notice, perhaps, the EXCEPTION which is eventually thrown is due to complicated Dynamically-Loaded CSS classes. Do keep in mind that their are simple alternatives, though.

        UNIX or DOS Shell Command:
        Downloading, Scraping HTTPS://news.yahoo.com/, Printing all TagNode Elements, and their CSS-Classes by invoking (and printing) the results of: TagNode.cssClasses() <html id="atomic" class="NoJs chrome featurephone" lang="en-US"> [nojs], [chrome], [featurephone], <div class="render-target-active render-target-default" id="render-target-default" data-reactid="2"> [render-target-active], [render-target-default], <div class="news US en-US" data-reactid="3"> [news], [us], [en-us], <div id="YDC-MainCanvas" class="YDC-MainCanvas Bgc($bg-body) Bxz(bb) Mih(100%) W(100%) Pos(a) lightweight_Miw(1247px)" data-reactid="4"> Exception in thread "main" Torello.HTML.NodeSearch.CSSStrException: One of the compare-strings passed to a search-method's var-args String parameter 'compareStr': [bgc($bg-body)] Did not pass the CSS Token-Naming Testing Regular-Expression: [^-?[_a-zA-Z]+[_\-a-zA-Z0-9]*$] And this means it has been identified as an invalid CSS Token. This is not allowed here. If you are using TagNode.cssClasses(), switch to TagNode.AV('class'). If you are using TextComparitor.CONTAINS_CSS_CLASS*, switch to TextComparitor.EQ_CI_TRM
        Returns:
        The String-Value of the Attribute-Name 'class' where that String has been 'split' - using String.split(...) and a Match-White-Space Regular-Expression. This is a method that will work just fine, unless proprietary non-standard HTML 5 CSS Class-Names have been used.

        NOTE: This method shall never return 'null' - even if there are no attribute key-value pairs contained by the TagNode. If there are strictly zero classes, Stream.empty() shall be returned, instead.

        Conversion-Target Stream-Method Invocation
        String[] Stream.toArray(String[]::new);
        List<String> Stream.collect(Collectors.toList());
        Vector<String> Stream.collect(Collectors.toCollection(Vector::new));
        TreeSet<String> Stream.collect(Collectors.toCollection(TreeSet::new));
        Iterator<String> Stream.iterator();
        Throws:
        CSSStrException - IMPORTANT: This exception will throw if *any* of the identified sub-String's of the CSS 'class' attributes contain non-standard characters, or do not meet the requirements of a standard CSS class name. The Regular-Expression describing a properly-formed CSS Name can be viewed on the internet, or in class CSSStrException field VALID_CSS_CLASS_OR_NAME_TOKEN. This is an unchecked-RuntimeException. Beware before using this method on pages generated by different, proprietary, Web-Design Tools.

        NOTE: To avoid an exception throw and retrieve the CSS 'class' attribute, regardless of whether it is standard CSS, use TagNode.AV("class"). This will return the raw-contents of the 'class' inner-tag inside 'this' HTML Element
        See Also:
        cssClasses(), AV(String), StringParse.WHITE_SPACE_REGEX, CSSStrException.check(Stream)
      • setCSSClasses

        🡅  🡇     🗕  🗗  🗖
        public TagNode setCSSClasses​(SD quote,
                                     boolean appendOrClobber,
                                     java.lang.String... cssClasses)
        This method sets the CSS Class attribute-value, applying either one, or many, CSS Class-Names.

        example
        Parameters:
        quote - This is the quote that will be used when defining the attribute's key-value pair inside the tag element. The programmer is expected to decide between using: SingleQuotes, DoubleQuotes or none / no-quotes (by passing null, with caveats). If null is passed to this parameter, then the complete list of rules that are applied, as explained in detail in method setAV.

        Please review the complete delineation of the rules for how quotation marks are added and used in an HTML Tag Attribute, vis-a-vis the 'quote' parameter.
        appendOrClobber - When this parameter is TRUE, new class-names will be appended to any, already-existing, class-names in the TagNode 'class' attribute-value. When this parameter is FALSE, the new class-names will replace the current TagNode's 'class' attribute's value/definition. If FALSE is used, and this TagNode does not have a 'class' attribute-value assigned to it yet, a new one will be created.
        cssClasses - This var-args (String[] array, or 'list-of-String's) will accept any combination of valid CSS Class-Names. It is important to know that the elements of the input-parameter 'cssClasses' will each be checked for validity based on the standard CSS Class-Naming Rules. There is a regular-expression in the exception class CSSStrException that depicts exactly what constitutes a valid CSS Class-Name.

        NOTE: If the programmer is using a web-development tool that relies on bypassing the browser's CSS Styling Rules, and intends to dynamically update class-names (using some form of CSS pre-processor), then perhaps he/she may wish to use non-standard CSS class-names in his TagNode elements. If so, inserting non-standard names into the 'class' attribute-value of a TagNode should be done by calling the general-purpose method TagNode.setAV("class", "any-CSS-Class-String").

        The user may also use the general-purpose TagNode.appendAV("class", "any-CSS-Class-String", boolean, SD) , if appending a non-standard CSS class-name String, rather than clobbering or setting it is the desired result. In this way, the programmer can avoid the "Invalid CSS Class" Exception, which would certainly be thrown for most pre-processor CSS directives.
        Returns:
        This will return an updated TagNode. TagNode's are immutable, and cannot be changed. This is identical behavior to Java's class String Libraries and Classes. The updated TagNode that is returned will have it's original 'class' attribute eliminated (if it had one), and a new 'class' attribute-value will be assigned to contain the CSS classes named by the var-args String-parameter, each separated by a space character.
        Throws:
        CSSStrException - This exception shall throw if any of the 'cssClasses' in the var-args String... parameter do not meet the HTML 5 CSS Class naming rules.
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        QuotesException - Quotation marks are not intended to be used in a class inner-tag definition. However, if there happened to be one in a non-standard class-attribute definition and the same quote is selected to wrap the updated class definition, this exception will throw. If this parameter is passed 'null', and the updated HTML Element class-attribute definition would require quotation marks, then this exception will also throw - because an unquoted attribute-value would have white-space in its definition, which is not allowed either.
        See Also:
        CSSStrException.check(String[]), CSSStrException.VALID_CSS_CLASS_OR_NAME_TOKEN, appendToAV(String, String, boolean, SD), setAV(String, String, SD)
      • appendCSSClass

        🡅  🡇     🗕  🗗  🗖
        public TagNode appendCSSClass​(java.lang.String cssClass,
                                      SD quote)
        Adds another CSS Class Name into 'this' TagNode

        example
        Parameters:
        cssClass - This is the CSS-Class name that is being inserted into 'this' instance of TagNode
        quote - This is the quote that will be used when defining the attribute's key-value pair inside the tag element. The programmer is expected to decide between using: SingleQuotes, DoubleQuotes or none / no-quotes (by passing null, with caveats). If null is passed to this parameter, then the complete list of rules that are applied, as explained in detail in method setAV.

        Please review the complete delineation of the rules for how quotation marks are added and used in an HTML Tag Attribute, vis-a-vis the 'quote' parameter.
        Returns:
        A new TagNode with updated CSS Class Name(s)
        Throws:
        CSSStrException - This exception shall throw if any of the 'cssClasses' in the var-args String... parameter do not meet the HTML 5 CSS Class naming rules.
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        QuotesException - Quotation marks within the provided CSS Class are not compapitable with the quotation marks used by the attribute, itself. Generally, quotations are not used with CSS Classes; however, if a proprietary-implementation requires them, it becomes necessary to heed the requirements set forth by a browser's parser.
        See Also:
        CSSStrException.check(String[]), setAV(String, String, SD), appendToAV(String, String, boolean, SD)
      • cssStyle

        🡅  🡇     🗕  🗗  🗖
        public java.util.Properties cssStyle()
        This is a regular-expression matching for picking out all CSS Style Elements. There are myriad 'ways and means' when it comes to CSS style elements. The official line is that CSS declarations and definitions, when inside an HTML TagNode Element, all 'style' attribute-names must obey a few simple rules.

        First, the declaration-name - for example CSS Properties such as width, height, font-weight, border etc... - are listed. Then that style-declaration must be followed by a colon ':' character followed by the definition for that . Finally, the Style-Definition itself must either end, or be followed by a semi-colon ';' and another property definition may follow.

        Some examples of HTML Tags with "In-Line CSS Properties" are listed here:

        • <DIV ID=MainDIV STYLE='background: black; color: white;'>
        • <UL STYLE='font-family: monospace; font-size: 110%;'>
        • <IMG CLASS=MyPhotos STYLE='border: 1px solid red; padding 1em;'>


        SANITY-CHECK: At any point, an invocation of method AV("style"), should always return the complete inline CSS-Style Attribute Value as a String.

        Because of the sheer-number of style-property variations, this method refrains from any validity-checking. So long as the rules declared by the CSS-Style Regular-Expression parser are obeyed (defined in CSS_INLINE_STYLE_REGEX ) this method will always return a usable Properties instance.

        The following example will hilite what this method "cssStyle()" can achieve. The output that is generated has been transcribed to the next window (after the one below).

        Example:
        // Load a page, and parse it into a vectorized-html page.
        Vector<HTMLNode> page = HTMLPage.getPageTokens(new URL("https://news.yahoo.com"), false);
        
        // Select all HTMLNodes that are "instanceof" TagNode, and have a STYLE="..." inner-tag
        Vector<TagNode> withStyle = InnerTagGet.all(page, "style");
        
        // The 'class' Attribute on Yahoo! News is exceptionally long.
        // For 'readability' (here), remove those attributes.
        // This removes all 'class' attributes in the 'withStyle' TagNode-Vector
        Attributes.remove(withStyle, "class");
        
        for (TagNode tn : withStyle)
        {
            // retrieve all CSS Style-Properties from the TagNode
            Properties styleProps = tn.cssStyle();
        
            // Print out the TagNode.  Use UNIX Color-Code "bright-yellow" (for readability)
            System.out.println(C.BYELLOW + tn + C.RESET);
        
            // Temp loop variable
            String s;
        
            // Iterate through every property key-value definition found in 'styleProps'.
            for (String property : styleProps.stringPropertyNames())
        
                System.out.println(
                    "\t" +  // make output readable
                    String.format("%-" + 30 + "s", (C.BCYAN + property + C.RESET + " : ")) +
                        // Print the Property 'Name' with some 'right-padding' and UNIX color "Bright-Cyan"
                    (s=styleProps.get(property).toString()).substring(0, Math.min(s.length(), 75))
                        // For the Property "value" - only print the first 75 characters...
                );
        }
        

        The following text was generated by the above short program, scraping Yahoo! News. It prints out relevant CSS Style Information. Each CSS Attribute that has been defined within-the-confines of the Element itself (via the 'STYLE' inner-tag) is printed out to the UNIX terminal.

        UNIX Shell Command Output:
        <div style="height:86px;" data-reactid="5" id="YDC-UH"> height : 86px <div style="background-color:transparent;" data-reactid="8"> background-color : transparent <input autocomplete="off" style="-webkit-appearance:none;" name="p" data-reactid="19" aria-label="Search" autocorrect="off" type="text" placeholder="Search" value="" autocapitalize="off" /> -webkit-appearance : none <button style="filter:chroma(color=#000);" type="submit" aria-label="Search" data-reactid="22" id="search-button"> filter : chroma(color=#000) <svg height="34" viewbox="0 0 48 48" width="34" style="fill:#400090;stroke:#400090;stroke-width:0;vertical-align:bottom;" data-icon="profile" data-reactid="27"> stroke-width : 0 vertical-align : bottom fill : #400090 stroke : #400090 <svg height="35" viewbox="0 0 512 512" width="30" style="fill:#400090;stroke:#400090;stroke-width:0;vertical-align:bottom;" data-icon="NavMail" data-reactid="31"> stroke-width : 0 vertical-align : bottom fill : #400090 stroke : #400090 <nav style="width:auto;" data-reactid="14" role="navigation"> width : auto <svg height="20" viewbox="0 0 96 96" width="20" style="vertical-align:middle;cursor:pointer;margin-top:-2px;color:#26282a;fill:#26282a;stroke:#26282a;stroke-width:0;" data-icon="StreamShare" data-reactid="51"> color : #26282a vertical-align : middle stroke-width : 0 margin-top : -2px fill : #26282a stroke : #26282a cursor : pointer <div id="defaultdestMAST" style=""> <div id="defaultdestLDRB" style=""> <div style="position:relative;top:0px;" data-reactid="22"> position : relative top : 0px <div style="max-width:900px;" data-reactid="2" id="YDC-Stream"> max-width : 900px <div tabindex="-1" style="padding-bottom:56.3%;" data-reactid="9"> padding-bottom : 56.3% <div style="-webkit-tap-highlight-color:transparent;" data-reactid="21"> -webkit-tap-highlight-color : transparent <div style="margin:-10px;" data-reactid="22"> margin : -10px <button style="padding:10px;" aria-label="Share Menu" data-reactid="23"> padding : 10px <svg height="20" viewbox="0 0 48 48" width="20" style="fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="share" data-reactid="24"> stroke-width : 0 vertical-align : bottom fill : #fff stroke : #fff <svg height="20" viewbox="0 0 16 16" width="20" style="position:relative;top:1px;margin:auto;vertical-align:middle;fill:#fff;stroke:#fff;stroke-width:0;" data-icon="comments" data-reactid="27"> position : relative vertical-align : middle stroke-width : 0 margin : auto top : 1px fill : #fff stroke : #fff <ul style="top:0;transition:top .4s;" data-reactid="30"> top : 0 transition : top .4s <div data-test-locator="streamhero-controls" style="height:26px;" data-reactid="49"> height : 26px <svg height="23" viewbox="0 0 48 48" width="23" style="margin-left:12px;opacity:0.6;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="caret-up" data-reactid="52"> margin-left : 12px opacity : 0.6 stroke-width : 0 vertical-align : bottom fill : #fff stroke : #fff <svg height="23" viewbox="0 0 48 48" width="23" style="margin-left:12px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="caret-down" data-reactid="55"> margin-left : 12px stroke-width : 0 vertical-align : bottom fill : #fff stroke : #fff <div style="padding-bottom:56%;" data-reactid="61"> padding-bottom : 56% <div style="padding-bottom:88%;" data-reactid="75"> padding-bottom : 88% <div style="padding-bottom:56%;" data-reactid="113"> padding-bottom : 56% <div style="padding-bottom:88%;" data-reactid="127"> padding-bottom : 88% <div style="padding-bottom:88%;" data-reactid="154"> padding-bottom : 88% <div style="padding-bottom:56%;" data-reactid="181"> padding-bottom : 56% <div style="padding-bottom:88%;" data-reactid="195"> padding-bottom : 88% <div style="padding-bottom:88%;" data-reactid="222"> padding-bottom : 88% <div style="padding-bottom:88%;" data-reactid="248"> padding-bottom : 88% <div style="padding-bottom:56%;" data-reactid="275"> padding-bottom : 56% <div style="padding-bottom:56%;" data-reactid="289"> padding-bottom : 56% <div style="padding-bottom:56%;" data-reactid="303"> padding-bottom : 56% <div style="padding-bottom:88%;" data-reactid="317"> padding-bottom : 88% <div style="padding-bottom:88%;" data-reactid="344"> padding-bottom : 88% <div style="padding-bottom:88%;" data-reactid="371"> padding-bottom : 88% <div style="padding-bottom:56%;" data-reactid="398"> padding-bottom : 56% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="400"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="401"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:56%;" data-reactid="415"> padding-bottom : 56% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="417"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 48 48" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="gallery" data-reactid="418"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:88%;" data-reactid="432"> padding-bottom : 88% <div style="padding-bottom:88%;" data-reactid="459"> padding-bottom : 88% <div style="padding-bottom:56%;" data-reactid="486"> padding-bottom : 56% <div style="padding-bottom:88%;" data-reactid="500"> padding-bottom : 88% <div style="padding-bottom:56%;" data-reactid="527"> padding-bottom : 56% <div style="padding-bottom:56%;" data-reactid="541"> padding-bottom : 56% <div style="padding-bottom:56%;" data-reactid="555"> padding-bottom : 56% <div style="height:0;width:0;" data-reactid="3" id="defaultFOOT-sizer"> height : 0 width : 0 <div id="defaultdestFOOT" style=""> <div style="height:0;width:0;" data-reactid="3" id="defaultFSRVY-sizer"> height : 0 width : 0 <div id="defaultdestFSRVY" style=""> <div style="position:relative;top:0px;" data-reactid="39"> position : relative top : 0px <div id="defaultdestLREC" style=""> <div style="max-width:900px;" data-reactid="2" id="Col2-1-Stream"> max-width : 900px <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/zHVKAUu2r5TTwV6qakrkGA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/2UIXIIqm4LTnxZg0X5i.yA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-images/2020-04/6f703ff0-7d04-11ea-beef-801a4e71e676);" data-reactid="10"> background-image : url(https://s.yimg.com/ny/api/res/1.2/zHVKAUu2r5TTwV6qakrkGA--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/Ys5hJWbOLmM_KAo5BwK0BQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/gqSAvUFANziiTJbCyeJmqw--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/os/creatr-images/2019-11/38e0d390-fcd6-11e9-9dbf-19fe4fa04817);" data-reactid="22"> background-image : url(https://s.yimg.com/ny/api/res/1.2/Ys5hJWbOLmM_KAo5BwK0BQ--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/G5wdl.JqIzh2ahAdWE.1tA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/4TK6IvbcM6B2WT8aN60UKg--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-US/reuters-finance.com/6203123d7024cdfb221604ba4a7b8aa0);" data-reactid="34"> background-image : url(https://s.yimg.com/ny/api/res/1.2/G5wdl.JqIzh2ahAdWE.1tA--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/5fhqXTevZUHU.nbsEW7dpQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/UI0jsUElQl1vdfCIvRVrJg--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-us/insidermonkey.com/f32ccf5bbd02501b27ef965a1a7aad26);" data-reactid="46"> background-image : url(https://s.yimg.com/ny/api/res/1.2/5fhqXTevZUHU.nbsEW7dpQ--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/a42nb3icSWNkNKgdFIe4Rg--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/bddUizWuPmPkXWok0myBOg--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/os/creatr-uploaded-images/2020-04/f1a6a890-7b76-11ea-b7ab-69a6e125abb4);" data-reactid="58"> background-image : url(https://s.yimg.com/ny/api/res/1.2/a42nb3icSWNkNKgdFIe4Rg--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/y9Bfyy_r5d0fClE.ibKusQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/ua9rm3_4SLLffTmAoSvmvA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/uu/api/res/1.2/VDzkhWpF77whaWcOA1yXPA--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e937918b43fec6780d02a0f/5e937918b43fec6780d02a10_o_U_v2.jpg);" data-reactid="70"> background-image : url(https://s.yimg.com/ny/api/res/1.2/y9Bfyy_r5d0fClE.ibKusQ--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="71"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="72"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/QVFAZDpObZQbly2hVJFTtQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/oyvxAW4tgdtJIKnCZL29wQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-images/2020-04/991c2290-79b9-11ea-be7f-c79a30d5ee49);" data-reactid="85"> background-image : url(https://s.yimg.com/ny/api/res/1.2/QVFAZDpObZQbly2hVJFTtQ--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/EX.pCQqbU3p6B6WUj.NaaA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/hKCLVgBst8AbLJPMxG5jgQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-images/2020-04/f337b140-7aa4-11ea-a7bd-b72f2d3182a5);" data-reactid="97"> background-image : url(https://s.yimg.com/ny/api/res/1.2/EX.pCQqbU3p6B6WUj.NaaA--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/CwPc0kK56oBN0mhFxrRieA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/M5DLYlWDOnTYEM0vNum_ow--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-US/reuters.com/637ba4f5a27bbf8ff710aff35be65228);" data-reactid="109"> background-image : url(https://s.yimg.com/ny/api/res/1.2/CwPc0kK56oBN0mhFxrRieA--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/Q.id3lA_2RVHUipYYwwsIA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/7I4Kuij80NUX0cESxgrbyA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/os/creatr-images/2020-04/89c52ea0-7c15-11ea-a77d-36d3c609ef8a);" data-reactid="121"> background-image : url(https://s.yimg.com/ny/api/res/1.2/Q.id3lA_2RVHUipYYwwsIA--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/ePSJEsrMO0RGuQ4zmFlz0w--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/xaPl5Hb_YfC7WgER0wse9Q--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/uu/api/res/1.2/hQHVFPzBzVVtEbOx2hMNqg--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e93679884a08c660eef5be7/5e93679884a08c660eef5be8_o_U_v2.jpg);" data-reactid="133"> background-image : url(https://s.yimg.com/ny/api/res/1.2/ePSJEsrMO0RGuQ4zmFlz0w--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="134"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="135"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/mRRPKIyX0R7oo73K8vfstw--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/8ge4QvIM3jGA1QvKW0fZTw--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-US/reuters-finance.com/601f4a3964811a269aca0168f2f7c0f0);" data-reactid="148"> background-image : url(https://s.yimg.com/ny/api/res/1.2/mRRPKIyX0R7oo73K8vfstw--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/N9h9d6z6dhQzREy.jTeqKQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/0SF8UZWrj81i6jkuKcScJQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-images/2020-04/b97691d0-784a-11ea-b7fe-3877f2dd45e0);" data-reactid="160"> background-image : url(https://s.yimg.com/ny/api/res/1.2/N9h9d6z6dhQzREy.jTeqKQ--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/19PqKm5gqlAMpJyAvSVRxg--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/gdmNOvRuw_vkH8Z.3ldbQw--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en/Benzinga/af3b980f0214633c97c8d1f5f6b8d8e2);" data-reactid="172"> background-image : url(https://s.yimg.com/ny/api/res/1.2/19PqKm5gqlAMpJyAvSVRxg--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/i047mKFU5JlnMz5secHo5w--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/igypgBdqYfdqBDzF63ucUQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/os/creatr-images/2020-04/b8c9afa0-7ce2-11ea-be7d-2d4971ed799b);" data-reactid="184"> background-image : url(https://s.yimg.com/ny/api/res/1.2/i047mKFU5JlnMz5secHo5w--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/bznBrHaGLHNUpRfgWb6fiA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/RMNQiT657O98l17qpLRdHA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/uu/api/res/1.2/7zVY3vVQ9.6pXGCkzSopig--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e93679484a08c660eef5be5/5e93679484a08c660eef5be6_o_U_v2.jpg);" data-reactid="196"> background-image : url(https://s.yimg.com/ny/api/res/1.2/bznBrHaGLHNUpRfgWb6fiA--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="197"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="198"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/M44IU2wp144myS9tImV5Bw--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/P7Pp2DyLpAD70AwYWF0H1A--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-us/kiplinger.com/d4bcd9f2a6ca8fde407b4053ec26eb2f);" data-reactid="211"> background-image : url(https://s.yimg.com/ny/api/res/1.2/M44IU2wp144myS9tImV5Bw--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/yMDGmcU5O6POWraLEe9QCg--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/iXVvN_KBUDNiisYS9nwhyA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/09/5e8e0ed96ca6be6d5fb31241/5e8e799e549920624eefd3b9_o_U_v3.jpg);" data-reactid="223"> background-image : url(https://s.yimg.com/ny/api/res/1.2/yMDGmcU5O6POWraLEe9QCg--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="224"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="225"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/uSq36UD_AsyJ6WberW8Ggw--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/Wa_XWc8qgTfYTG.smVQl4g--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/hd/cp-video-transcode/prod/2020-03/26/5e7cfc135f6f6542b5f1b0b0/5e7d0b6a6ca6be4217587c49_o_U_v4.jpg);" data-reactid="238"> background-image : url(https://s.yimg.com/ny/api/res/1.2/uSq36UD_AsyJ6WberW8Ggw--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="239"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="240"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/apIwx3T.jLSqpz3t6UNKgQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/wTkDXBHN2KmyTuC5OUdylA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/os/creatr-uploaded-images/2020-04/8e406100-7cda-11ea-a7fd-1c1af5d5aef1);" data-reactid="253"> background-image : url(https://s.yimg.com/ny/api/res/1.2/apIwx3T.jLSqpz3t6UNKgQ--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/yZpN1gdQt6vdqr3kPuAQ3g--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/QFEsHBuvrVZCGcF6iUAypg--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/uu/api/res/1.2/Q0NsiY9KtIUJhPYY_P6opw--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e935f4292fc28752b7df245/5e935f4525ffdb000102745c_1280x720_FES_v1.jpg);" data-reactid="265"> background-image : url(https://s.yimg.com/ny/api/res/1.2/yZpN1gdQt6vdqr3kPuAQ3g--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="266"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="267"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/5kA1NwyfUsX2ayNbkc4.bw--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/EnKSPWKjn4VFfYlO7bZ3KA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-us/usa_today_money_325/6e7e2347716edec37842707988d62d02);" data-reactid="280"> background-image : url(https://s.yimg.com/ny/api/res/1.2/5kA1NwyfUsX2ayNbkc4.bw--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/j7U2HxAm1fBqgijDZQ_G6A--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/IIiNwcYu3W1X_c5r2NryvQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-us/kiplinger.com/852b73caf9727bab7320b50cd15c4adf);" data-reactid="292"> background-image : url(https://s.yimg.com/ny/api/res/1.2/j7U2HxAm1fBqgijDZQ_G6A--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/uHKZoXXRPlg3I0SJ.Sd7SA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/4iDa4lNkS3R_BZBueOsd7g--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-images/2020-03/910edf60-705a-11ea-8b77-8ac3eef493cf);" data-reactid="304"> background-image : url(https://s.yimg.com/ny/api/res/1.2/uHKZoXXRPlg3I0SJ.Sd7SA--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/5YLdKjYKMGL0UTdt.TvcwA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/pt.rGJPR5grq4xye.U9uwQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-us/usa_today_money_325/fe2532294f100b45f097dd6e7bb17be7);" data-reactid="316"> background-image : url(https://s.yimg.com/ny/api/res/1.2/5YLdKjYKMGL0UTdt.TvcwA--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/vE19PDNIRyV3iCxoLhMX5A--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/l.DYogf.Ixzc8XTQ.4.9Kw--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/03/5e879dce5f6f65601e7e592a/5e879dce5f6f65601e7e592b_o_U_v2.jpg);" data-reactid="328"> background-image : url(https://s.yimg.com/ny/api/res/1.2/vE19PDNIRyV3iCxoLhMX5A--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="329"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="330"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/eYIUwigcXI9U4rBnTiyNsA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/TLJkSQf78GxPiW.aGhKwrw--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/uu/api/res/1.2/kdrZPJoCx_t5tcxtWPWpEQ--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e93555a90a80d79a635231b/5e93555a90a80d79a635231c_o_U_v2.jpg);" data-reactid="343"> background-image : url(https://s.yimg.com/ny/api/res/1.2/eYIUwigcXI9U4rBnTiyNsA--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="344"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="345"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/qb6TUw7SrnCAr9HIPjnmjQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/hKr9PAu0Pe5YralkmbEAHQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en/fx_empire_176/7487ed84f0b1640fcfe8e7b1872a1881);" data-reactid="358"> background-image : url(https://s.yimg.com/ny/api/res/1.2/qb6TUw7SrnCAr9HIPjnmjQ--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/Z9lqib01GToEG0diuwJQVg--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/yURaMJJjbFn.vHqiJjyWdg--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-images/2020-01/eccde4d0-43a6-11ea-bb75-e378299e78d9);" data-reactid="370"> background-image : url(https://s.yimg.com/ny/api/res/1.2/Z9lqib01GToEG0diuwJQVg--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/F7Kzs5KAyEiqSQEw1lMA0w--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/BQhLWVPcIJZu0E_8.S0svA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en/fx_empire_176/f9c062884e57ad93391eb3b680a419b9);" data-reactid="382"> background-image : url(https://s.yimg.com/ny/api/res/1.2/F7Kzs5KAyEiqSQEw1lMA0w--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/36NzXnShtJF9otBOdCqX2w--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/3nrr93yHkmoalfbGb9rsSA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s1.yimg.com/uu/api/res/1.2/cXtj3GsNYMhGTr0c5QBq9Q--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e93465e549920624eefde60/5e9346623260720001fd89bc_1280x720_FES_v1.jpg);" data-reactid="394"> background-image : url(https://s.yimg.com/ny/api/res/1.2/36NzXnShtJF9otBOdCqX2w--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="395"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="396"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/7jUts.to8VGXohMjcw2c0A--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/L4Trp2E6Gld.gpEE8sbrGQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/hd/cp-video-transcode/prod/2020-03/24/5e7a3e11da8e831cd730e3da/5e7a3e11da8e831cd730e3db_o_U_v2.jpg);" data-reactid="409"> background-image : url(https://s.yimg.com/ny/api/res/1.2/7jUts.to8VGXohMjcw2c0A--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="410"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="411"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/uPL33Yks5vrekTM0apCTOg--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/WGPamrfVQ3HzXf2AQ6DipQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-us/usa_today_money_325/9f41ba2e34b0dfb012e3e38b461bdff5);" data-reactid="424"> background-image : url(https://s.yimg.com/ny/api/res/1.2/uPL33Yks5vrekTM0apCTOg--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/haQWWFistKffxTQb.LI8fA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l2.yimg.com/uu/api/res/1.2/C3aCT3_5CjlznKD38Nx_jA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media-mbst-pub-ue1.s3.amazonaws.com/creatr-uploaded-images/2019-09/1af93af0-db18-11e9-bff7-e34690b9be52);" data-reactid="436"> background-image : url(https://s.yimg.com/ny/api/res/1.2/haQWWFistKffxTQb.LI8fA--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="437"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="438"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/B__47T2HNVGCd8y4oJ1Sww--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/LXPYkIG9XVOhLwFXsRKYTA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/uu/api/res/1.2/b7F3OOxxajxDuM_JODhS3w--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e93397b9bb2c06b40c89e33/5e93397b9bb2c06b40c89e34_o_U_v2.jpg);" data-reactid="451"> background-image : url(https://s.yimg.com/ny/api/res/1.2/B__47T2HNVGCd8y4oJ1Sww--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="452"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="453"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/Uo5MF7aeN.kqQZBectYv6Q--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/L0huYimDIMz4wbWlMdb_1Q--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en-US/the_block_83/dfc4cd7cac9a2413be149f9d69d34c6d);" data-reactid="466"> background-image : url(https://s.yimg.com/ny/api/res/1.2/Uo5MF7aeN.kqQZBectYv6Q--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/ackt9j5fZ48Wwcv8ZFExWg--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l.yimg.com/uu/api/res/1.2/at5cquxDMds8sMRsc_NRsA--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/hd/cp-video-transcode/prod/2020-03/25/5e7b5d75da8e831cd730e6bd/5e7b5d75da8e831cd730e6be_o_U_v2.jpg);" data-reactid="478"> background-image : url(https://s.yimg.com/ny/api/res/1.2/ackt9j5fZ48Wwcv8ZFExWg--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="479"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="480"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/x3lcnEBxqUd6XfpTruJHbw--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/fq3eSPTj3sVy5009DEM3ug--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://media.zenfs.com/en/bloomberg_opinion_268/3305b3219b8ca4274de1ce2d105a4665);" data-reactid="493"> background-image : url(https://s.yimg.com/ny/api/res/1.2/x3lcnEBxqUd6XfpTruJHbw--~A/YXBwaWQ9aG padding-bottom : 52% <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/amaw5PNz2O5GGD2ylfgAqA--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/nTGrYvbX9LdQZop5GNlb2A--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/uu/api/res/1.2/aOJYFJ3Aouv7clfF0BcVSQ--~B/dz0xMjgwO2g9NzIwO2FwcGlkPXl0YWNoeW9u/https://s.yimg.com/hd/cp-video-transcode/prod/2020-04/12/5e932c7284a08c660eef5b98/5e932c7b25ffdb000102713c_1280x720_FES_v1.jpg);" data-reactid="505"> background-image : url(https://s.yimg.com/ny/api/res/1.2/amaw5PNz2O5GGD2ylfgAqA--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="506"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="507"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div style="padding-bottom:52%;background-image:url(https://s.yimg.com/ny/api/res/1.2/wtFH3BocnUekbSQZLOEcAQ--~A/YXBwaWQ9aGlnaGxhbmRlcjtoPTMxMjt3PTYwMDtxPTc1O2ZpPXN0cmlt/http://l1.yimg.com/uu/api/res/1.2/7geayxyFnaPr5ozhWsIWqQ--/YXBwaWQ9eXRhY2h5b247cT03NTs-/https://s.yimg.com/hd/cp-video-transcode/prod/2020-03/23/5e78faffcbde734796205b1e/5e7916f969e6c577d70ae714_o_U_v4.jpg);" data-reactid="520"> background-image : url(https://s.yimg.com/ny/api/res/1.2/wtFH3BocnUekbSQZLOEcAQ--~A/YXBwaWQ9aG padding-bottom : 52% <span dir="ltr" style="height:50px;width:50px;background-size:50px;background-image:url(https://s.yimg.com/dh/ap/default/150604/orb.png);" data-reactid="521"> height : 50px background-image : url(https://s.yimg.com/dh/ap/default/150604/orb.png) background-size : 50px width : 50px <svg height="20" viewbox="0 0 512 512" width="20" style="left:15px;top:15px;fill:#fff;stroke:#fff;stroke-width:0;vertical-align:bottom;" data-icon="CorePlay" data-reactid="522"> stroke-width : 0 vertical-align : bottom left : 15px top : 15px fill : #fff stroke : #fff <div id="defaultdestLREC2" style="">
        Returns:
        This shall return an instance of Java's 'Properties' class, and it will contain all the style definitions and their values.

        NOTE: All style-declaration names shall be saved using lower-case. The style attribute-values, however, will not be converted to lower-case.

        NULL NOTE: This method will not return null. Rather, if 'this' instance of TagNode Element does not have a style attribute, an empty (non-null) instance of Properties which contains zero CSS Style-Declaration Key-Value Pairs will be returned instead.
      • setCSSStyle

        🡅  🡇     🗕  🗗  🗖
        public TagNode setCSSStyle​(java.util.Properties p,
                                   SD quote,
                                   boolean appendOrClobber)
        This will set 'this' instance of TagNode's CSS-Style Attribute such that it contains the CSS Definition Property-Value Pairs that are contained in the Properties parameter 'p'
        Parameters:
        p - This should be a map between CSS Definition Property-Names to Property-Values. Some examples would include (below):
        Property-Name Property-Value
        font-weight bold
        background lightyellow
        width 200px
        border 5px 10px 5px 15px
        box-shadow inset 0 0 1em brown
        quote - This is the quote that will be used when defining the attribute's key-value pair inside the tag element. The programmer is expected to decide between using: SingleQuotes, DoubleQuotes or none / no-quotes (by passing null, with caveats). If null is passed to this parameter, then the complete list of rules that are applied, as explained in detail in method setAV.

        Please review the complete delineation of the rules for how quotation marks are added and used in an HTML Tag Attribute, vis-a-vis the 'quote' parameter.
        appendOrClobber - When this parameter is TRUE new style-definitions will be appended to any, already-existing, style-definitions in the TagNode 'style' attribute-value. When this parameter is FALSE, the new style-definitions will replace the HTML Element 'style' attributes current-definition (or build a new one, if 'this' TagNode does not have a 'style' attribute).
        Returns:
        This will return a new, updated HTML TagNode that has its style-attribute inserted (or replaced). The class TagNode is immutable (the original TagNode will be unmodified).
        Throws:
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        CSSStrException - If there is an invalid CSS Style Property Name.
        QuotesException - If the style-element's quotation marks are incompatible with any and all quotation marks employed by the style-element definitions.
        See Also:
        CSSStrException.VALID_CSS_CLASS_OR_NAME_TOKEN, appendToAV(String, String, boolean, SD), setAV(String, String, SD)
      • setID

        🡅  🡇     🗕  🗗  🗖
        public TagNode setID​(java.lang.String id,
                             SD quote)
        This merely sets the current CSS 'ID' Attribute Value.
        Parameters:
        id - This is the new CSS 'ID' attribute-value that the user would like applied to 'this' instance of TagNode.
        quote - This is the quote that will be used when defining the attribute's key-value pair inside the tag element. The programmer is expected to decide between using: SingleQuotes, DoubleQuotes or none / no-quotes (by passing null, with caveats). If null is passed to this parameter, then the complete list of rules that are applied, as explained in detail in method setAV.

        Please review the complete delineation of the rules for how quotation marks are added and used in an HTML Tag Attribute, vis-a-vis the 'quote' parameter.
        Returns:
        Returns a new instance of TagNode that has an updated 'ID' attribute-value.
        Throws:
        java.lang.IllegalArgumentException - This exception shall throw if an invalid String-token has been passed to parameter 'id'.

        BYPASS NOTE: If the user would like to bypass this exception-check, for instance because he / she is using a CSS Pre-Processor, then applying the general-purpose method TagNode.setAV("id", "some-new-id") ought to suffice. This other method will not apply validity checking, beyond scanning for the usual "quotes-within-quotes" problems, which is always disallowed.
        ClosingTagNodeException - This exception will throw if an attempt is made to invoke this method on a TagNode whose isClosing-Field is set to TRUE. The exception throws because HTML browsers do not permit the closing-versions of any TagNode to contain inner-tags (attributes).
        See Also:
        CSSStrException.VALID_CSS_CLASS_OR_NAME_TOKEN, setAV(String, String, SD)
      • dataAV

        🡅  🡇     🗕  🗗  🗖
        public java.lang.String dataAV​(java.lang.String dataName)
        Convenience Method
        Invokes: AV(String)
        Passes: "data-" prepended to parameter 'dataName' for the attribute-name
      • removeDataAttributes

        🡅  🡇     🗕  🗗  🗖
        public TagNode removeDataAttributes()
        This method will remove any HTML 'data' Attributes - if there are any present. "Data Inner-Tags" are simply the attributes inside of HTML Elements whose names begin with "data-".

        Since Class TagNode is immutable, a new TagNode must be instantiated, if any data-inner-tags are removed. If no data-attributes are removed, 'this' instance of TagNode shall be returned instead.
        Returns:
        This will return a newly constructed 'TagNode' instance, if there were any "Data Attributes" that were removed by request. If the original TagNode has remained unchanged, a reference to 'this' shall be returned.
        Throws:
        ClosingTagNodeException - This exception throws if 'this' instance of TagNode is a closing-version of the HTML Element. Closing HTML Elements may not have data attributes, because they simply are not intended to contain any attributes.
      • getDataAV

        🡅  🡇     🗕  🗗  🗖
        public java.util.Properties getDataAV​(boolean preserveKeysCase)
        This will retrieve and return any/all 'data' HTML Attributes. "Data Inner-Tags" are simply the attributes inside of HTML Elements whose names begin with "data-".
        Parameters:
        preserveKeysCase - When this parameter is passed TRUE, the case of the attribute names in the returned Properties table will have been preserved. When FALSE is passed, all Properties keys shall have been converted to lower-case first.

        HTML expects that all attribute names function in a CASE INSENSITIVE fashion. Java, however, makes no such expectations on it's class java.util.Properties tables, or most other String-containers. Preserving the case of an attribute-name will produce more consistent looking HTML. But for more easily-searchable java-Strings, converting to lower-case can make coding easier.
        Returns:
        This will return a java.util.Properties of all data-attributes which are found in 'this' HTML Element. If no such attributes were found, 'null' shall not be returned by this method, but rather an empty Properties instance will be provided, instead.
      • getDataAN

        🡅  🡇     🗕  🗗  🗖
        public java.util.stream.Stream<java.lang.String> getDataAN​
                    (boolean preserveKeysCase)
        
        This method will only return a list of all data-attribute names. The data-attribute values shall not be included in the result. An HTML Element "data-attribute" is any attribute inside of an HTML TagNode whose key-value pair uses a key that begins with "data-"... It is that simple!
        Parameters:
        preserveKeysCase - When this parameter is passed TRUE, the case of the attribute names that are returned by this method will have been preserved. When FALSE is passed, they shall be converted to lower-case first.

        HTML expects that all attribute names function in a CASE INSENSITIVE fashion. Java, however, makes no such expectations on it's class java.util.Properties tables, or most other String-containers. Preserving the case of an attribute-name will produce more consistent looking HTML. But for more easily-searchable java-Strings, converting to lower-case can make coding easier.
        Returns:
        Returns an instance of Stream<String>. The attribute names that are returned, are all converted to lower-case.
        NOTE: This method shall never return 'null' - even if there are no data-attribute key-value pairs contained by the TagNode. If there are strictly zero such attributes, (Stream.empty()) shall be returned, instead.

        A return type of Stream<String> is used. Please see the list below for how to convert a Stream to another data-type.

        Conversion-Target Stream-Method Invocation
        String[] Stream.toArray(String[]::new);
        List<String> Stream.collect(Collectors.toList());
        Vector<String> Stream.collect(Collectors.toCollection(Vector::new));
        TreeSet<String> Stream.collect(Collectors.toCollection(TreeSet::new));
        Iterator<String> Stream.iterator();
      • toStringAV

        🡅  🡇     🗕  🗗  🗖
        public java.lang.String toStringAV()
        This does a "longer version" of the parent-class' HTMLNode toString> method. This is because it also parses and prints inner-tag key-value pairs. The standard toString method that is inherited will just return the value of the public field 'str'
        Returns:
        A String with the inner-tag key-value pairs specified.

        Example:
        // The following code, would output the text below
        TagNode tn = new TagNode("<BUTTON CLASS='MyButtons' ONCLICK='MyListener();'>");
        System.out.println(tn.toStringAV());
        
        // Outputs the following Text:
        
        // TagNode.str: [<BUTTON class='MyButtons' onclick='MyListener();'>], TagNode.tok: [button],
        //      TagNode.isClosing: [false]
        // CONTAINS a total of (2) attributes / inner-tag key-value pairs:
        // (KEY, VALUE):   [onclick], [MyListener();]
        // (KEY, VALUE):   [class], [MyButtons]
        
        See Also:
        HTMLNode.toString()
      • clone

        🡅  🡇     🗕  🗗  🗖
        public TagNode clone()
        Java's interface Cloneable requirements. This instantiates a new TagNode with identical String str fields, and also identical boolean isClosing and String tok fields.
        Specified by:
        clone in class HTMLNode
        Returns:
        A new TagNode whose internal fields are identical to this one.
      • compareTo

        🡅  🡇     🗕  🗗  🗖
        public int compareTo​(TagNode n)
        This sorts by:

        1. by tok field's character-order (ASCII-alphabetical).
          The following 'tok' fields are ASCII ordered: 'a', 'button', 'canvas', 'div', 'em', 'figure' ...

        2. then (if the 'tok' fields are equal) by the isClosing field.
          TagNode's that have an 'isClosing field set to FALSE come before TagNode's whose 'isClosing' field is set to TRUE

        3. finally, if the 'tok' and the 'isClosing' fields are both equal, then the nodes are sorted by the integer-length of str field.
        Specified by:
        compareTo in interface java.lang.Comparable<TagNode>
        Parameters:
        n - Any other TagNode to be compared to 'this' TagNode
        Returns:
        An integer that fulfils Java's Comparable interface-method requirements.
      • toUpperCase

        🡅  🡇     🗕  🗗  🗖
        public TagNode toUpperCase​(boolean justTag_Or_TagAndAttributeNames)
        Generates a capitalized (Upper-Case) instance of the String-Contents of this TagNode.

        The user has the option of capitalizing the Tag-Name only, or the Tag-Name and the Attribute-Names.

        White-space and Attribute-Values. shall remain unchanged by this method.
        Parameters:
        justTag_Or_TagAndAttributeNames - When this parameter is passed TRUE, only the Element-Name will be converted to Upper-Case. This is the tok field of this TagNode.

        If this parameter receives FALSE, then BOTH the Tag-Name AND the Attribute-Names are capitalized.
        Returns:
        A capitalized version of 'this' instance. The Case-Modifications made to the returned TagNode will be as follows:

        • If the 'tag' parameter has been passed TRUE, then the Tag-Name itself will have been capitalized.
        • If input parameter 'justTag_Or_TagAndAttributeNames' has been passed FALSE, then all Attribute-Names will have also been capitalized. If the parameter were passed TRUE, then Attribute-Names will remain unmodified.
        • Attributte-Values will always remain unmodified.
        • If 'this' instance of TagNode contained any DATA-xx Attributes, the 'xx' portion of the Attribute-Name will also remain unmodified.
      • toUpperCase

        🡅  🡇     🗕  🗗  🗖
        public TagNode toUpperCase​
                    (boolean tag,
                     java.util.function.Predicate<java.lang.String> attrNameTest)
        
        Generates a capitalized (Upper-Case) instance of the String-Contents of 'this' instance of TagNode.

        This variant of 'toUpperCase' allows for providing a Java String-Predicate to decide which Attribute-Names are to be capitalized.

        As with all Upper & Lower Case-Changing Methods, White-space, Attribute-Values, and DATA-xxx Attributes will not be modified by this method.
        Parameters:
        tag - Indicates whether or not the Tag-Name should be capitalized
        attrNameTest - This Java String-Predicate is to be used for deciding which Attribute-Names are to have their case modified.

        The decision-Predicate's behavior should be such that the Predicate returns TRUE whenever an attribute is to be capitalized, and FALSE when the attribute should remain unchanged.
        Returns:
        A capitalized version of 'this' instance. The Case-Modifications made to the returned TagNode will be as follows:

        • If the 'tag' parameter has been passed TRUE, then the Tag-Name itself will have been capitalized.
        • Any Attribute-Names which, when presented to the input String-Predicate generated a TRUE return-value, will have also been capitalized.
        • Attributte-Values will always remain unmodified.
        • If 'this' instance of TagNode contained any DATA-xx Attributes, the 'xx' portion of the Attribute-Name will also remain unmodified.
      • toLowerCase

        🡅  🡇     🗕  🗗  🗖
        public TagNode toLowerCase​(boolean justTag_Or_TagAndAttributeNames)
        Generates a de-capitalized (Lower-Case) instance of the String-Contents of this TagNode.

        The user has the option of de-capitalizing the Tag-Name only, or the Tag-Name and the Attribute-Names.

        White-space and Attribute-Values. shall remain unchanged by this method.
        Parameters:
        justTag_Or_TagAndAttributeNames - When this parameter is passed TRUE, only the Element-Name will be converted to Lower-Case. This is the tok field of this TagNode.

        If this parameter receives FALSE, then BOTH the Tag-Name AND the Attribute-Names are de-capitalized.
        Returns:
        A de-capitalized version of 'this' instance. The Case-Modifications made to the returned TagNode will be as follows:

        • If the 'tag' parameter has been passed TRUE, then the Tag-Name itself will have been de-capitalized.
        • If input parameter 'justTag_Or_TagAndAttributeNames' has been passed FALSE, then all Attribute-Names will have also been de-capitalized. If the parameter were passed TRUE, then Attribute-Names will remain unmodified.
        • Attributte-Values will always remain unmodified.
        • If 'this' instance of TagNode contained any DATA-xx Attributes, the 'xx' portion of the Attribute-Name will also remain unmodified.
      • toLowerCase

        🡅  🡇     🗕  🗗  🗖
        public TagNode toLowerCase​
                    (boolean tag,
                     java.util.function.Predicate<java.lang.String> attrNameTest)
        
        Generates a de-capitalized (Lower-Case) instance of the String-Contents of 'this' instance of TagNode.

        This variant of 'toLowerCase' allows for providing a Java String-Predicate to decide which Attribute-Names are to be de-capitalized.

        As with all Upper & Lower Case-Changing Methods, White-space, Attribute-Values, and DATA-xxx Attributes will not be modified by this method.
        Parameters:
        tag - Indicates whether or not the Tag-Name should be decapitalized
        attrNameTest - This Java String-Predicate is to be used for deciding which Attribute-Names are to have their case modified.

        The decision-Predicate's behavior should be such that the Predicate returns TRUE whenever an attribute is to be de-capitalized, and FALSE when the attribute should remain unchanged.
        Returns:
        A de-capitalized version of 'this' instance. The Case-Modifications made to the returned TagNode will be as follows:

        • If the 'tag' parameter has been passed TRUE, then the Tag-Name itself will have been de-capitalized.
        • Any Attribute-Names which, when presented to the input String-Predicate generated a TRUE return-value, will have also been de-capitalized.
        • Attributte-Values will always remain unmodified.
        • If 'this' instance of TagNode contained any DATA-xx Attributes, the 'xx' portion of the Attribute-Name will also remain unmodified.
      • removeAVQuotes

        🡅  🡇     🗕  🗗  🗖
        public TagNode removeAVQuotes​
                    (java.util.function.Predicate<java.lang.String> attrNameTest)
        
        Removes Quotation-Marks that have been placed around Attribute-Values, whose Attribute-Name matches the User-Provided String-Predicate parameter 'attrNameTest'
        Parameters:
        attrNameTest - This Java String-Predicate is to be used for deciding which Attribute-Names are to have surrounding Quotation-Marks removed from their Values.

        The decision-Predicate's behavior should be such that the Predicate returns TRUE whenever an attribute is to have its quotations removed, and FALSE when the quotes should remain unchanged.
        Returns:
        An identical TagNode instance in which all indicated attributes have had Quotation-Marks removed from their Values.
        Throws:
        QuotesException - If the resulting TagNode contains Quotation-Errors
      • setAVQuotes

        🡅     🗕  🗗  🗖
        public TagNode setAVQuotes​
                    (java.util.function.Predicate<java.lang.String> attrNameTest,
                     SD quote)
        
        Modifies which Quotation-Marks are used to surround Attribute-Values. This method will only modify quotations for Values whose Attribute-Name matches the User-Provided String-Predicate parameter 'attrNameTest'
        Parameters:
        attrNameTest - This Java String-Predicate is to be used for deciding which Attribute-Names are to have whichever surrounding Quotation-Marks already placed around their Values modified / swapped.

        The decision-Predicate's behavior should be such that the Predicate returns TRUE whenever an attribute is to have its quotations changed, and FALSE if its quotes shouldn't be swapped.
        quote - The new Quotation-Mark to apply
        Returns:
        An identical TagNode instance in all indicated attributes have had their Quotation-Marks modified according to the 'quote' parameter.
        Throws:
        QuotesException - If the resulting TagNode contains Quotation-Errors
        java.lang.NullPointerException - If either parameter is passed null.