Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: Source/core/html/HTMLInputElement.cpp

Issue 435753003: Implement minlength for <input> and <textarea>. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved.
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) 7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
8 * Copyright (C) 2010 Google Inc. All rights reserved. 8 * Copyright (C) 2010 Google Inc. All rights reserved.
9 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 9 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
10 * Copyright (C) 2012 Samsung Electronics. All rights reserved. 10 * Copyright (C) 2012 Samsung Electronics. All rights reserved.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 // get rather sluggish when a text field has a larger number of characters than 100 // get rather sluggish when a text field has a larger number of characters than
101 // this, even when just clicking in the text field. 101 // this, even when just clicking in the text field.
102 const int HTMLInputElement::maximumLength = 524288; 102 const int HTMLInputElement::maximumLength = 524288;
103 const int defaultSize = 20; 103 const int defaultSize = 20;
104 const int maxSavedResults = 256; 104 const int maxSavedResults = 256;
105 105
106 HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo ol createdByParser) 106 HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo ol createdByParser)
107 : HTMLTextFormControlElement(inputTag, document, form) 107 : HTMLTextFormControlElement(inputTag, document, form)
108 , m_size(defaultSize) 108 , m_size(defaultSize)
109 , m_maxLength(maximumLength) 109 , m_maxLength(maximumLength)
110 , m_minLength(0)
110 , m_maxResults(-1) 111 , m_maxResults(-1)
111 , m_isChecked(false) 112 , m_isChecked(false)
112 , m_reflectsCheckedAttribute(true) 113 , m_reflectsCheckedAttribute(true)
113 , m_isIndeterminate(false) 114 , m_isIndeterminate(false)
114 , m_isActivatedSubmit(false) 115 , m_isActivatedSubmit(false)
115 , m_autocomplete(Uninitialized) 116 , m_autocomplete(Uninitialized)
116 , m_hasNonEmptyList(false) 117 , m_hasNonEmptyList(false)
117 , m_stateRestored(false) 118 , m_stateRestored(false)
118 , m_parsingInProgress(createdByParser) 119 , m_parsingInProgress(createdByParser)
119 , m_valueAttributeWasUpdatedAfterParsing(false) 120 , m_valueAttributeWasUpdatedAfterParsing(false)
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 && !tooLong(value, IgnoreDirtyFlag) 211 && !tooLong(value, IgnoreDirtyFlag)
211 && !m_inputType->patternMismatch(value) 212 && !m_inputType->patternMismatch(value)
212 && !m_inputType->valueMissing(value); 213 && !m_inputType->valueMissing(value);
213 } 214 }
214 215
215 bool HTMLInputElement::tooLong() const 216 bool HTMLInputElement::tooLong() const
216 { 217 {
217 return willValidate() && tooLong(value(), CheckDirtyFlag); 218 return willValidate() && tooLong(value(), CheckDirtyFlag);
218 } 219 }
219 220
221 bool HTMLInputElement::tooShort() const
222 {
223 bool ret = willValidate() && tooShort(value(), CheckDirtyFlag);
224 return ret;
225 }
226
220 bool HTMLInputElement::typeMismatch() const 227 bool HTMLInputElement::typeMismatch() const
221 { 228 {
222 return willValidate() && m_inputType->typeMismatch(); 229 return willValidate() && m_inputType->typeMismatch();
223 } 230 }
224 231
225 bool HTMLInputElement::valueMissing() const 232 bool HTMLInputElement::valueMissing() const
226 { 233 {
227 return willValidate() && m_inputType->valueMissing(value()); 234 return willValidate() && m_inputType->valueMissing(value());
228 } 235 }
229 236
230 bool HTMLInputElement::hasBadInput() const 237 bool HTMLInputElement::hasBadInput() const
231 { 238 {
232 return willValidate() && m_inputType->hasBadInput(); 239 return willValidate() && m_inputType->hasBadInput();
233 } 240 }
234 241
235 bool HTMLInputElement::patternMismatch() const 242 bool HTMLInputElement::patternMismatch() const
236 { 243 {
237 return willValidate() && m_inputType->patternMismatch(value()); 244 return willValidate() && m_inputType->patternMismatch(value());
238 } 245 }
239 246
240 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const 247 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
241 { 248 {
242 // We use isTextType() instead of supportsMaxLength() because of the
243 // 'virtual' overhead.
244 if (!isTextType()) 249 if (!isTextType())
245 return false; 250 return false;
246 int max = maxLength(); 251 int max = maxLength();
247 if (max < 0) 252 if (max < 0)
248 return false; 253 return false;
249 if (check == CheckDirtyFlag) { 254 if (check == CheckDirtyFlag) {
250 // Return false for the default value or a value set by a script even if 255 // Return false for the default value or a value set by a script even if
251 // it is longer than maxLength. 256 // it is longer than maxLength.
252 if (!hasDirtyValue() || !lastChangeWasUserEdit()) 257 if (!hasDirtyValue() || !lastChangeWasUserEdit())
253 return false; 258 return false;
254 } 259 }
255 return value.length() > static_cast<unsigned>(max); 260 return value.length() > static_cast<unsigned>(max);
256 } 261 }
257 262
263 bool HTMLInputElement::tooShort(const String& value, NeedsToCheckDirtyFlag check ) const
264 {
265 if (!isTextType())
keishi 2014/08/01 03:14:54 We don't have WMLInputElement anymore so I think w
Bartek Nowierski 2014/10/03 12:52:00 The code has been moved to forms/BaseTextInputType
266 return false;
267 int min = minLength();
268 if (min <= 0)
269 return false;
270 if (check == CheckDirtyFlag) {
271 // Return false for the default value or a value set by a script even if
272 // it is shorter than minLength.
273 if (!hasDirtyValue() || !lastChangeWasUserEdit())
274 return false;
275 }
276 // An empty string is excluded from minlength check.
277 unsigned len = value.length();
278 return len > 0 && len < static_cast<unsigned>(min);
279 }
280
258 bool HTMLInputElement::rangeUnderflow() const 281 bool HTMLInputElement::rangeUnderflow() const
259 { 282 {
260 return willValidate() && m_inputType->rangeUnderflow(value()); 283 return willValidate() && m_inputType->rangeUnderflow(value());
261 } 284 }
262 285
263 bool HTMLInputElement::rangeOverflow() const 286 bool HTMLInputElement::rangeOverflow() const
264 { 287 {
265 return willValidate() && m_inputType->rangeOverflow(value()); 288 return willValidate() && m_inputType->rangeOverflow(value());
266 } 289 }
267 290
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 m_inputTypeView->valueAttributeChanged(); 681 m_inputTypeView->valueAttributeChanged();
659 } else if (name == checkedAttr) { 682 } else if (name == checkedAttr) {
660 // Another radio button in the same group might be checked by state 683 // Another radio button in the same group might be checked by state
661 // restore. We shouldn't call setChecked() even if this has the checked 684 // restore. We shouldn't call setChecked() even if this has the checked
662 // attribute. So, delay the setChecked() call until 685 // attribute. So, delay the setChecked() call until
663 // finishParsingChildren() is called if parsing is in progress. 686 // finishParsingChildren() is called if parsing is in progress.
664 if (!m_parsingInProgress && m_reflectsCheckedAttribute) { 687 if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
665 setChecked(!value.isNull()); 688 setChecked(!value.isNull());
666 m_reflectsCheckedAttribute = true; 689 m_reflectsCheckedAttribute = true;
667 } 690 }
668 } else if (name == maxlengthAttr) 691 } else if (name == maxlengthAttr) {
669 parseMaxLengthAttribute(value); 692 parseMaxLengthAttribute(value);
670 else if (name == sizeAttr) { 693 } else if (name == minlengthAttr) {
694 parseMinLengthAttribute(value);
695 } else if (name == sizeAttr) {
671 int oldSize = m_size; 696 int oldSize = m_size;
672 int valueAsInteger = value.toInt(); 697 int valueAsInteger = value.toInt();
673 m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize; 698 m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize;
674 if (m_size != oldSize && renderer()) 699 if (m_size != oldSize && renderer())
675 renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidatio n(); 700 renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidatio n();
676 } else if (name == altAttr) 701 } else if (name == altAttr)
677 m_inputTypeView->altAttributeChanged(); 702 m_inputTypeView->altAttributeChanged();
678 else if (name == srcAttr) 703 else if (name == srcAttr)
679 m_inputTypeView->srcAttributeChanged(); 704 m_inputTypeView->srcAttributeChanged();
680 else if (name == usemapAttr || name == accesskeyAttr) { 705 else if (name == usemapAttr || name == accesskeyAttr) {
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 const AtomicString& HTMLInputElement::alt() const 1306 const AtomicString& HTMLInputElement::alt() const
1282 { 1307 {
1283 return fastGetAttribute(altAttr); 1308 return fastGetAttribute(altAttr);
1284 } 1309 }
1285 1310
1286 int HTMLInputElement::maxLength() const 1311 int HTMLInputElement::maxLength() const
1287 { 1312 {
1288 return m_maxLength; 1313 return m_maxLength;
1289 } 1314 }
1290 1315
1316 int HTMLInputElement::minLength() const
1317 {
1318 return m_minLength;
1319 }
1320
1291 void HTMLInputElement::setMaxLength(int maxLength, ExceptionState& exceptionStat e) 1321 void HTMLInputElement::setMaxLength(int maxLength, ExceptionState& exceptionStat e)
1292 { 1322 {
1293 if (maxLength < 0) 1323 if (maxLength < 0)
1294 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(maxLength) + ") is negative."); 1324 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(maxLength) + ") is negative.");
1325 else if (maxLength < m_minLength)
1326 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(maxLength) + ") is less than minlength" + String::number(m_minL ength) + ".");
1295 else 1327 else
1296 setIntegralAttribute(maxlengthAttr, maxLength); 1328 setIntegralAttribute(maxlengthAttr, maxLength);
1297 } 1329 }
1298 1330
1331 void HTMLInputElement::setMinLength(int minLength, ExceptionState& exceptionStat e)
1332 {
1333 if (minLength < 0)
1334 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(minLength) + ") is negative.");
1335 else if (minLength > m_maxLength)
1336 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(minLength) + ") is more than maxlength" + String::number(m_maxL ength) + ".");
1337 else
1338 setIntegralAttribute(minlengthAttr, minLength);
1339 }
1340
1299 bool HTMLInputElement::multiple() const 1341 bool HTMLInputElement::multiple() const
1300 { 1342 {
1301 return fastHasAttribute(multipleAttr); 1343 return fastHasAttribute(multipleAttr);
1302 } 1344 }
1303 1345
1304 void HTMLInputElement::setSize(unsigned size) 1346 void HTMLInputElement::setSize(unsigned size)
1305 { 1347 {
1306 setUnsignedIntegralAttribute(sizeAttr, size); 1348 setUnsignedIntegralAttribute(sizeAttr, size);
1307 } 1349 }
1308 1350
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 return m_inputTypeView->updatePlaceholderText(); 1709 return m_inputTypeView->updatePlaceholderText();
1668 } 1710 }
1669 1711
1670 void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value) 1712 void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
1671 { 1713 {
1672 int maxLength; 1714 int maxLength;
1673 if (!parseHTMLInteger(value, maxLength)) 1715 if (!parseHTMLInteger(value, maxLength))
1674 maxLength = maximumLength; 1716 maxLength = maximumLength;
1675 if (maxLength < 0 || maxLength > maximumLength) 1717 if (maxLength < 0 || maxLength > maximumLength)
1676 maxLength = maximumLength; 1718 maxLength = maximumLength;
1719 if (m_minLength > maxLength)
keishi 2014/08/01 03:14:54 We should just apply the rules for "parsing non-ne
Bartek Nowierski 2014/10/03 12:52:00 I assume you want me to remove this part. Done.
1720 m_minLength = maxLength;
1677 int oldMaxLength = m_maxLength; 1721 int oldMaxLength = m_maxLength;
1678 m_maxLength = maxLength; 1722 m_maxLength = maxLength;
1679 if (oldMaxLength != maxLength) 1723 if (oldMaxLength != maxLength)
1680 updateValueIfNeeded(); 1724 updateValueIfNeeded();
1681 setNeedsStyleRecalc(SubtreeStyleChange); 1725 setNeedsStyleRecalc(SubtreeStyleChange);
1682 setNeedsValidityCheck(); 1726 setNeedsValidityCheck();
1683 } 1727 }
1684 1728
1729 void HTMLInputElement::parseMinLengthAttribute(const AtomicString& value)
1730 {
1731 int minLength;
1732 if (!parseHTMLInteger(value, minLength))
1733 minLength = 0;
1734 if (minLength < 0)
1735 minLength = 0;
1736 if (minLength > m_maxLength)
keishi 2014/08/01 03:14:54 We should just parse the minLength value here and
Bartek Nowierski 2014/10/03 12:52:00 Done.
1737 minLength = m_maxLength;
1738 m_minLength = minLength;
1739 setNeedsStyleRecalc(SubtreeStyleChange);
1740 setNeedsValidityCheck();
1741 }
1742
1685 void HTMLInputElement::updateValueIfNeeded() 1743 void HTMLInputElement::updateValueIfNeeded()
1686 { 1744 {
1687 String newValue = sanitizeValue(m_valueIfDirty); 1745 String newValue = sanitizeValue(m_valueIfDirty);
1688 ASSERT(!m_valueIfDirty.isNull() || newValue.isNull()); 1746 ASSERT(!m_valueIfDirty.isNull() || newValue.isNull());
1689 if (newValue != m_valueIfDirty) 1747 if (newValue != m_valueIfDirty)
1690 setValue(newValue); 1748 setValue(newValue);
1691 } 1749 }
1692 1750
1693 String HTMLInputElement::defaultToolTip() const 1751 String HTMLInputElement::defaultToolTip() const
1694 { 1752 {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1880 { 1938 {
1881 return m_inputType->shouldDispatchFormControlChangeEvent(oldValue, newValue) ; 1939 return m_inputType->shouldDispatchFormControlChangeEvent(oldValue, newValue) ;
1882 } 1940 }
1883 1941
1884 void HTMLInputElement::didNotifySubtreeInsertionsToDocument() 1942 void HTMLInputElement::didNotifySubtreeInsertionsToDocument()
1885 { 1943 {
1886 listAttributeTargetChanged(); 1944 listAttributeTargetChanged();
1887 } 1945 }
1888 1946
1889 } // namespace 1947 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698