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

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: Add support for minlength in remaining places and stop clasping it with maxlength Created 6 years, 2 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // get rather sluggish when a text field has a larger number of characters than 103 // get rather sluggish when a text field has a larger number of characters than
104 // this, even when just clicking in the text field. 104 // this, even when just clicking in the text field.
105 const int HTMLInputElement::maximumLength = 524288; 105 const int HTMLInputElement::maximumLength = 524288;
106 const int defaultSize = 20; 106 const int defaultSize = 20;
107 const int maxSavedResults = 256; 107 const int maxSavedResults = 256;
108 108
109 HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo ol createdByParser) 109 HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo ol createdByParser)
110 : HTMLTextFormControlElement(inputTag, document, form) 110 : HTMLTextFormControlElement(inputTag, document, form)
111 , m_size(defaultSize) 111 , m_size(defaultSize)
112 , m_maxLength(maximumLength) 112 , m_maxLength(maximumLength)
113 , m_minLength(0)
113 , m_maxResults(-1) 114 , m_maxResults(-1)
114 , m_isChecked(false) 115 , m_isChecked(false)
115 , m_reflectsCheckedAttribute(true) 116 , m_reflectsCheckedAttribute(true)
116 , m_isIndeterminate(false) 117 , m_isIndeterminate(false)
117 , m_isActivatedSubmit(false) 118 , m_isActivatedSubmit(false)
118 , m_autocomplete(Uninitialized) 119 , m_autocomplete(Uninitialized)
119 , m_hasNonEmptyList(false) 120 , m_hasNonEmptyList(false)
120 , m_stateRestored(false) 121 , m_stateRestored(false)
121 , m_parsingInProgress(createdByParser) 122 , m_parsingInProgress(createdByParser)
122 , m_valueAttributeWasUpdatedAfterParsing(false) 123 , m_valueAttributeWasUpdatedAfterParsing(false)
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 { 204 {
204 if (!m_inputType->canSetStringValue()) { 205 if (!m_inputType->canSetStringValue()) {
205 ASSERT_NOT_REACHED(); 206 ASSERT_NOT_REACHED();
206 return false; 207 return false;
207 } 208 }
208 return !m_inputType->typeMismatchFor(value) 209 return !m_inputType->typeMismatchFor(value)
209 && !m_inputType->stepMismatch(value) 210 && !m_inputType->stepMismatch(value)
210 && !m_inputType->rangeUnderflow(value) 211 && !m_inputType->rangeUnderflow(value)
211 && !m_inputType->rangeOverflow(value) 212 && !m_inputType->rangeOverflow(value)
212 && !tooLong(value, IgnoreDirtyFlag) 213 && !tooLong(value, IgnoreDirtyFlag)
214 && !tooShort(value, IgnoreDirtyFlag)
213 && !m_inputType->patternMismatch(value) 215 && !m_inputType->patternMismatch(value)
214 && !m_inputType->valueMissing(value); 216 && !m_inputType->valueMissing(value);
215 } 217 }
216 218
217 bool HTMLInputElement::tooLong() const 219 bool HTMLInputElement::tooLong() const
218 { 220 {
219 return willValidate() && tooLong(value(), CheckDirtyFlag); 221 return willValidate() && tooLong(value(), CheckDirtyFlag);
220 } 222 }
221 223
224 bool HTMLInputElement::tooShort() const
225 {
226 return willValidate() && tooShort(value(), CheckDirtyFlag);
227 }
228
222 bool HTMLInputElement::typeMismatch() const 229 bool HTMLInputElement::typeMismatch() const
223 { 230 {
224 return willValidate() && m_inputType->typeMismatch(); 231 return willValidate() && m_inputType->typeMismatch();
225 } 232 }
226 233
227 bool HTMLInputElement::valueMissing() const 234 bool HTMLInputElement::valueMissing() const
228 { 235 {
229 return willValidate() && m_inputType->valueMissing(value()); 236 return willValidate() && m_inputType->valueMissing(value());
230 } 237 }
231 238
232 bool HTMLInputElement::hasBadInput() const 239 bool HTMLInputElement::hasBadInput() const
233 { 240 {
234 return willValidate() && m_inputType->hasBadInput(); 241 return willValidate() && m_inputType->hasBadInput();
235 } 242 }
236 243
237 bool HTMLInputElement::patternMismatch() const 244 bool HTMLInputElement::patternMismatch() const
238 { 245 {
239 return willValidate() && m_inputType->patternMismatch(value()); 246 return willValidate() && m_inputType->patternMismatch(value());
240 } 247 }
241 248
242 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const 249 bool HTMLInputElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const
243 { 250 {
244 return m_inputType->tooLong(value, check); 251 return m_inputType->tooLong(value, check);
245 } 252 }
246 253
254 bool HTMLInputElement::tooShort(const String& value, NeedsToCheckDirtyFlag check ) const
255 {
256 return m_inputType->tooShort(value, check);
257 }
258
247 bool HTMLInputElement::rangeUnderflow() const 259 bool HTMLInputElement::rangeUnderflow() const
248 { 260 {
249 return willValidate() && m_inputType->rangeUnderflow(value()); 261 return willValidate() && m_inputType->rangeUnderflow(value());
250 } 262 }
251 263
252 bool HTMLInputElement::rangeOverflow() const 264 bool HTMLInputElement::rangeOverflow() const
253 { 265 {
254 return willValidate() && m_inputType->rangeOverflow(value()); 266 return willValidate() && m_inputType->rangeOverflow(value());
255 } 267 }
256 268
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 m_inputTypeView->valueAttributeChanged(); 676 m_inputTypeView->valueAttributeChanged();
665 } else if (name == checkedAttr) { 677 } else if (name == checkedAttr) {
666 // Another radio button in the same group might be checked by state 678 // Another radio button in the same group might be checked by state
667 // restore. We shouldn't call setChecked() even if this has the checked 679 // restore. We shouldn't call setChecked() even if this has the checked
668 // attribute. So, delay the setChecked() call until 680 // attribute. So, delay the setChecked() call until
669 // finishParsingChildren() is called if parsing is in progress. 681 // finishParsingChildren() is called if parsing is in progress.
670 if (!m_parsingInProgress && m_reflectsCheckedAttribute) { 682 if (!m_parsingInProgress && m_reflectsCheckedAttribute) {
671 setChecked(!value.isNull()); 683 setChecked(!value.isNull());
672 m_reflectsCheckedAttribute = true; 684 m_reflectsCheckedAttribute = true;
673 } 685 }
674 } else if (name == maxlengthAttr) 686 } else if (name == maxlengthAttr) {
675 parseMaxLengthAttribute(value); 687 parseMaxLengthAttribute(value);
676 else if (name == sizeAttr) { 688 } else if (name == minlengthAttr) {
689 parseMinLengthAttribute(value);
690 } else if (name == sizeAttr) {
677 int oldSize = m_size; 691 int oldSize = m_size;
678 int valueAsInteger = value.toInt(); 692 int valueAsInteger = value.toInt();
679 m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize; 693 m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize;
680 if (m_size != oldSize && renderer()) 694 if (m_size != oldSize && renderer())
681 renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidatio n(); 695 renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidatio n();
682 } else if (name == altAttr) 696 } else if (name == altAttr)
683 m_inputTypeView->altAttributeChanged(); 697 m_inputTypeView->altAttributeChanged();
684 else if (name == srcAttr) 698 else if (name == srcAttr)
685 m_inputTypeView->srcAttributeChanged(); 699 m_inputTypeView->srcAttributeChanged();
686 else if (name == usemapAttr || name == accesskeyAttr) { 700 else if (name == usemapAttr || name == accesskeyAttr) {
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 const AtomicString& HTMLInputElement::alt() const 1298 const AtomicString& HTMLInputElement::alt() const
1285 { 1299 {
1286 return fastGetAttribute(altAttr); 1300 return fastGetAttribute(altAttr);
1287 } 1301 }
1288 1302
1289 int HTMLInputElement::maxLength() const 1303 int HTMLInputElement::maxLength() const
1290 { 1304 {
1291 return m_maxLength; 1305 return m_maxLength;
1292 } 1306 }
1293 1307
1308 int HTMLInputElement::minLength() const
1309 {
1310 return m_minLength;
1311 }
1312
1294 void HTMLInputElement::setMaxLength(int maxLength, ExceptionState& exceptionStat e) 1313 void HTMLInputElement::setMaxLength(int maxLength, ExceptionState& exceptionStat e)
1295 { 1314 {
1296 if (maxLength < 0) 1315 if (maxLength < 0)
1297 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(maxLength) + ") is negative."); 1316 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(maxLength) + ") is negative.");
1317 else if (maxLength < m_minLength)
1318 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(maxLength) + ") is less than minlength" + String::number(m_minL ength) + ".");
keishi 2014/10/06 03:58:23 nit: Maybe we can use indexExceedsMinimumBound so
Bartek Nowierski 2014/10/06 13:18:16 Done.
1298 else 1319 else
1299 setIntegralAttribute(maxlengthAttr, maxLength); 1320 setIntegralAttribute(maxlengthAttr, maxLength);
1300 } 1321 }
1301 1322
1323 void HTMLInputElement::setMinLength(int minLength, ExceptionState& exceptionStat e)
1324 {
1325 if (minLength < 0)
1326 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(minLength) + ") is negative.");
1327 else if (minLength > m_maxLength)
1328 exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(minLength) + ") is more than maxlength" + String::number(m_maxL ength) + ".");
keishi 2014/10/06 03:58:23 Ditto.
Bartek Nowierski 2014/10/06 13:18:16 Done.
1329 else
1330 setIntegralAttribute(minlengthAttr, minLength);
1331 }
1332
1302 bool HTMLInputElement::multiple() const 1333 bool HTMLInputElement::multiple() const
1303 { 1334 {
1304 return fastHasAttribute(multipleAttr); 1335 return fastHasAttribute(multipleAttr);
1305 } 1336 }
1306 1337
1307 void HTMLInputElement::setSize(unsigned size) 1338 void HTMLInputElement::setSize(unsigned size)
1308 { 1339 {
1309 setUnsignedIntegralAttribute(sizeAttr, size); 1340 setUnsignedIntegralAttribute(sizeAttr, size);
1310 } 1341 }
1311 1342
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 if (maxLength < 0 || maxLength > maximumLength) 1621 if (maxLength < 0 || maxLength > maximumLength)
1591 maxLength = maximumLength; 1622 maxLength = maximumLength;
1592 int oldMaxLength = m_maxLength; 1623 int oldMaxLength = m_maxLength;
1593 m_maxLength = maxLength; 1624 m_maxLength = maxLength;
1594 if (oldMaxLength != maxLength) 1625 if (oldMaxLength != maxLength)
1595 updateValueIfNeeded(); 1626 updateValueIfNeeded();
1596 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::fromAtt ribute(maxlengthAttr)); 1627 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::fromAtt ribute(maxlengthAttr));
1597 setNeedsValidityCheck(); 1628 setNeedsValidityCheck();
1598 } 1629 }
1599 1630
1631 void HTMLInputElement::parseMinLengthAttribute(const AtomicString& value)
1632 {
1633 int minLength;
1634 if (!parseHTMLInteger(value, minLength))
1635 minLength = 0;
1636 if (minLength < 0)
1637 minLength = 0;
1638 m_minLength = minLength;
1639 setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::fromAtt ribute(minlengthAttr));
1640 setNeedsValidityCheck();
1641 }
1642
1600 void HTMLInputElement::updateValueIfNeeded() 1643 void HTMLInputElement::updateValueIfNeeded()
1601 { 1644 {
1602 String newValue = sanitizeValue(m_valueIfDirty); 1645 String newValue = sanitizeValue(m_valueIfDirty);
1603 ASSERT(!m_valueIfDirty.isNull() || newValue.isNull()); 1646 ASSERT(!m_valueIfDirty.isNull() || newValue.isNull());
1604 if (newValue != m_valueIfDirty) 1647 if (newValue != m_valueIfDirty)
1605 setValue(newValue); 1648 setValue(newValue);
1606 } 1649 }
1607 1650
1608 String HTMLInputElement::defaultToolTip() const 1651 String HTMLInputElement::defaultToolTip() const
1609 { 1652 {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 { 1847 {
1805 listAttributeTargetChanged(); 1848 listAttributeTargetChanged();
1806 } 1849 }
1807 1850
1808 AXObject* HTMLInputElement::popupRootAXObject() 1851 AXObject* HTMLInputElement::popupRootAXObject()
1809 { 1852 {
1810 return m_inputTypeView->popupRootAXObject(); 1853 return m_inputTypeView->popupRootAXObject();
1811 } 1854 }
1812 1855
1813 } // namespace 1856 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698