1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  package org.htmlunit.html;
16  
17  import static org.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_MONTH_SUPPORTED;
18  import static org.htmlunit.BrowserVersionFeatures.JS_INPUT_CHANGE_TYPE_DROPS_VALUE_WEEK_MONTH;
19  
20  import java.time.YearMonth;
21  import java.time.format.DateTimeFormatter;
22  import java.time.format.DateTimeParseException;
23  import java.util.Map;
24  
25  import org.htmlunit.BrowserVersion;
26  import org.htmlunit.SgmlPage;
27  import org.htmlunit.util.StringUtils;
28  
29  
30  
31  
32  
33  
34  
35  
36  public class HtmlMonthInput extends HtmlInput implements LabelableElement {
37  
38      private static final DateTimeFormatter FORMATTER_ = DateTimeFormatter.ofPattern("yyyy-MM");
39  
40      
41  
42  
43  
44  
45  
46  
47      HtmlMonthInput(final String qualifiedName, final SgmlPage page,
48              final Map<String, DomAttr> attributes) {
49          super(qualifiedName, page, attributes);
50      }
51  
52      
53  
54  
55      @Override
56      public void setDefaultChecked(final boolean defaultChecked) {
57          
58      }
59  
60      
61  
62  
63      @Override
64      public void setValue(final String newValue) {
65          try {
66              if (hasFeature(HTMLINPUT_TYPE_MONTH_SUPPORTED) && !StringUtils.isEmptyOrNull(newValue)) {
67                  FORMATTER_.parse(newValue);
68              }
69              super.setValue(newValue);
70          }
71          catch (final DateTimeParseException ignored) {
72              
73          }
74      }
75  
76      
77  
78  
79      @Override
80      public boolean isValid() {
81          return super.isValid() && isMaxValid() && isMinValid();
82      }
83  
84      
85  
86  
87  
88  
89  
90  
91      private boolean isMinValid() {
92          if (hasFeature(HTMLINPUT_TYPE_MONTH_SUPPORTED) && !getMin().isEmpty()) {
93              try {
94                  final YearMonth dateValue = YearMonth.parse(getRawValue(), FORMATTER_);
95                  final YearMonth minDate = YearMonth.parse(getMin(), FORMATTER_);
96                  return minDate.equals(dateValue) || minDate.isBefore(dateValue);
97              }
98              catch (final DateTimeParseException ignored) {
99                  
100             }
101         }
102         return true;
103     }
104 
105     
106 
107 
108 
109 
110 
111 
112     private boolean isMaxValid() {
113         if (hasFeature(HTMLINPUT_TYPE_MONTH_SUPPORTED) && !getMax().isEmpty()) {
114             try {
115                 final YearMonth dateValue = YearMonth.parse(getRawValue(), FORMATTER_);
116                 final YearMonth maxDate = YearMonth.parse(getMax(), FORMATTER_);
117                 return maxDate.equals(dateValue) || maxDate.isAfter(dateValue);
118             }
119             catch (final DateTimeParseException ignored) {
120                 
121             }
122         }
123         return true;
124     }
125 
126     @Override
127     protected void adjustValueAfterTypeChange(final HtmlInput oldInput, final BrowserVersion browserVersion) {
128         if (browserVersion.hasFeature(JS_INPUT_CHANGE_TYPE_DROPS_VALUE_WEEK_MONTH)) {
129             setValue("");
130             return;
131         }
132         super.adjustValueAfterTypeChange(oldInput, browserVersion);
133     }
134 }