1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package Torello.HTML;

import Torello.HTML.helper.AttrRegEx;

import Torello.Java.StringParse;

import java.util.Properties;
import java.util.regex.Matcher;
import java.util.stream.Stream;

class DataAttributes
{
    static Properties getDataAV(
            final TagNode tn,
            final boolean preserveKeysCase
        ) 
    {
        Properties ret = new Properties();


        // NOTE: OPTIMIZED, "closing-versions" of the TagNode, and TagNode's whose 'str'
        //       field is only longer than the token, itself, by 3 or less characters cannot have
        //       attributes.v In that case, just return an empty 'Properties' instance.

        if (tn.isClosing || (tn.str.length() <= (tn.tok.length() + 3))) return ret;


        // This RegEx Matcher 'matches' against Attribute/InnerTag Key-Value Pairs
        //      ONLY PAIRS WHOSE KEY BEGINS WITH "data-" WILL MATCH
        //
        // m.group(2): returns the 'key' portion of the key-value pair, before an '=' (equals-sign)
        // m.group(3): returns the 'value' portion of the key-value pair, after an '='

        Matcher m = AttrRegEx.DATA_ATTRIBUTE_REGEX.matcher(tn.str);


        // NOTE: HTML mandates attributes must be 'case-insensitive' to the attribute 'key-part'
        //      (but not necessarily the 'value-part')
        //
        // HOWEVER: Java does not require anything for the 'Properties' class.
        // ALSO:    Case is PRESERVED for the 'value-part' of the key-value pair.

        if (preserveKeysCase)
            while (m.find())
                ret.put(m.group(2), StringParse.ifQuotesStripQuotes(m.group(3)));

        else
            while (m.find())
                ret.put(m.group(2).toLowerCase(), StringParse.ifQuotesStripQuotes(m.group(3)));
 
        return ret;
    }

    static Stream<String> getDataAN(
            final TagNode tn,
            final boolean preserveKeysCase
        ) 
    {
        // NOTE: OPTIMIZED, "closing-versions" of the TagNode, and TagNode's whose 'str'
        //       field is only longer than the token, itself, by 3 or less characters cannot have
        //       attributes.  In that case, just return an empty 'Properties' instance.

        if (tn.isClosing || (tn.str.length() <= (tn.tok.length() + 3))) return Stream.empty();

        // Java Stream's can be quickly and easily converted to any data-structure the user needs.
        Stream.Builder<String> b = Stream.builder();


        // This RegEx Matcher 'matches' against Attribute/InnerTag Key-Value Pairs
        //      ONLY PAIRS WHOSE KEY BEGINS WITH "data-" WILL MATCH
        // m.group(2): returns the 'key' portion of the key-value pair, before an '=' (equals-sign).
        // m.group(3): returns the 'value' portion of the key-value pair, after an '='

        Matcher m = AttrRegEx.DATA_ATTRIBUTE_REGEX.matcher(tn.str);


        // NOTE: HTML mandates attributes must be 'case-insensitive' to the attribute 'key-part'
        //      (but not necessarily the 'value-part')
        // HOWEVER: Java does not require anything for the 'Properties' class.
        // ALSO: Case is PRESERVED for the 'value-part' of the key-value pair.

        if (preserveKeysCase)   while (m.find()) b.accept(m.group(2));
        else                    while (m.find()) b.accept(m.group(2).toLowerCase());
 
        return b.build();
    }
}