View Javadoc
1   /*
2    * Copyright (c) 2002-2017 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package com.gargoylesoftware.htmlunit.html;
16  
17  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START;
18  
19  import java.util.Map;
20  
21  import com.gargoylesoftware.htmlunit.SgmlPage;
22  import com.gargoylesoftware.htmlunit.html.impl.SelectableTextInput;
23  import com.gargoylesoftware.htmlunit.html.impl.SelectableTextSelectionDelegate;
24  
25  /**
26   * Wrapper for the HTML element "input" with type is "number".
27   *
28   * @author Ahmed Ashour
29   * @author Ronald Brill
30   */
31  public class HtmlNumberInput extends HtmlInput implements SelectableTextInput {
32  
33      private final SelectableTextSelectionDelegate selectionDelegate_ = new SelectableTextSelectionDelegate(this);
34  
35      private final DoTypeProcessor doTypeProcessor_ = new DoTypeProcessor(this);
36  
37      /**
38       * Creates an instance.
39       *
40       * @param qualifiedName the qualified name of the element type to instantiate
41       * @param page the page that contains this element
42       * @param attributes the initial attributes
43       */
44      HtmlNumberInput(final String qualifiedName, final SgmlPage page,
45              final Map<String, DomAttr> attributes) {
46          super(qualifiedName, page, attributes);
47      }
48  
49      /**
50       * {@inheritDoc}
51       */
52      @Override
53      protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
54          if (startAtEnd) {
55              selectionDelegate_.setSelectionStart(getValueAttribute().length());
56          }
57          doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
58      }
59  
60      /**
61       * {@inheritDoc}
62       */
63      @Override
64      protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
65          if (startAtEnd) {
66              selectionDelegate_.setSelectionStart(getValueAttribute().length());
67          }
68          doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
69      }
70  
71      /**
72       * {@inheritDoc}
73       */
74      @Override
75      protected void typeDone(final String newValue, final boolean notifyAttributeChangeListeners) {
76          if (newValue.length() <= getMaxLength()) {
77              setAttributeNS(null, "value", newValue, notifyAttributeChangeListeners, false);
78          }
79      }
80  
81      /**
82       * {@inheritDoc}
83       */
84      @Override
85      protected boolean isSubmittableByEnter() {
86          return true;
87      }
88  
89      /**
90       * {@inheritDoc}
91       */
92      @Override
93      public void select() {
94          selectionDelegate_.select();
95      }
96  
97      /**
98       * {@inheritDoc}
99       */
100     @Override
101     public String getSelectedText() {
102         return selectionDelegate_.getSelectedText();
103     }
104 
105     /**
106      * {@inheritDoc}
107      */
108     @Override
109     public String getText() {
110         return getValueAttribute();
111     }
112 
113     /**
114      * {@inheritDoc}
115      */
116     @Override
117     public void setText(final String text) {
118         setValueAttribute(text);
119     }
120 
121     /**
122      * {@inheritDoc}
123      */
124     @Override
125     public int getSelectionStart() {
126         return selectionDelegate_.getSelectionStart();
127     }
128 
129     /**
130      * {@inheritDoc}
131      */
132     @Override
133     public void setSelectionStart(final int selectionStart) {
134         selectionDelegate_.setSelectionStart(selectionStart);
135     }
136 
137     /**
138      * {@inheritDoc}
139      */
140     @Override
141     public int getSelectionEnd() {
142         return selectionDelegate_.getSelectionEnd();
143     }
144 
145     /**
146      * {@inheritDoc}
147      */
148     @Override
149     public void setSelectionEnd(final int selectionEnd) {
150         selectionDelegate_.setSelectionEnd(selectionEnd);
151     }
152 
153     /**
154      * {@inheritDoc}
155      */
156     @Override
157     protected void setAttributeNS(final String namespaceURI, final String qualifiedName, final String attributeValue,
158             final boolean notifyAttributeChangeListeners, final boolean notifyMutationObservers) {
159         super.setAttributeNS(namespaceURI, qualifiedName, attributeValue, notifyAttributeChangeListeners,
160                 notifyMutationObservers);
161         if ("value".equals(qualifiedName)) {
162             final SgmlPage page = getPage();
163             if (page != null && page.isHtmlPage()) {
164                 int pos = 0;
165                 if (!hasFeature(JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START)) {
166                     pos = attributeValue.length();
167                 }
168                 setSelectionStart(pos);
169                 setSelectionEnd(pos);
170             }
171         }
172     }
173 
174     /**
175      * {@inheritDoc}
176      */
177     @Override
178     protected Object clone() throws CloneNotSupportedException {
179         return new HtmlNumberInput(getQualifiedName(), getPage(), getAttributesMap());
180     }
181 
182     /**
183      * {@inheritDoc}
184      */
185     @Override
186     public void setDefaultValue(final String defaultValue) {
187         final boolean modifyValue = getValueAttribute().equals(getDefaultValue());
188         setDefaultValue(defaultValue, modifyValue);
189     }
190 
191     /**
192      * {@inheritDoc}
193      */
194     @Override
195     public void setValueAttribute(final String newValue) {
196         try {
197             if (!newValue.isEmpty()) {
198                 Long.parseLong(newValue);
199             }
200             super.setValueAttribute(newValue);
201         }
202         catch (final NumberFormatException e) {
203             // ignore
204         }
205     }
206 }