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

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

Issue 2796853002: Update text field 'change' event logic to match to Firefox. (Closed)
Patch Set: . Created 3 years, 8 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 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
6 * rights reserved. 6 * rights reserved.
7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 7 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
8 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) 8 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
9 * Copyright (C) 2010 Google Inc. All rights reserved. 9 * Copyright (C) 2010 Google Inc. All rights reserved.
10 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. 10 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved.
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 if (m_inputType->valueMode() == ValueMode::kValue) 380 if (m_inputType->valueMode() == ValueMode::kValue)
381 m_nonAttributeValue = sanitizeValue(defaultValue); 381 m_nonAttributeValue = sanitizeValue(defaultValue);
382 ensureUserAgentShadowRoot(); 382 ensureUserAgentShadowRoot();
383 383
384 setNeedsWillValidateCheck(); 384 setNeedsWillValidateCheck();
385 385
386 if (!defaultValue.isNull()) 386 if (!defaultValue.isNull())
387 m_inputType->warnIfValueIsInvalid(defaultValue); 387 m_inputType->warnIfValueIsInvalid(defaultValue);
388 388
389 m_inputTypeView->updateView(); 389 m_inputTypeView->updateView();
390 setTextAsOfLastFormControlChangeEvent(value());
391 setChangedSinceLastFormControlChangeEvent(false);
392 } 390 }
393 391
394 void HTMLInputElement::updateType() { 392 void HTMLInputElement::updateType() {
395 DCHECK(m_inputType); 393 DCHECK(m_inputType);
396 DCHECK(m_inputTypeView); 394 DCHECK(m_inputTypeView);
397 395
398 const AtomicString& newTypeName = 396 const AtomicString& newTypeName =
399 InputType::normalizeTypeName(fastGetAttribute(typeAttr)); 397 InputType::normalizeTypeName(fastGetAttribute(typeAttr));
400 if (m_inputType->formControlType() == newTypeName) 398 if (m_inputType->formControlType() == newTypeName)
401 return; 399 return;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 AttributeModificationParams(alignAttr, align->value(), align->value(), 495 AttributeModificationParams(alignAttr, align->value(), align->value(),
498 AttributeModificationReason::kDirectly)); 496 AttributeModificationReason::kDirectly));
499 } 497 }
500 } 498 }
501 499
502 // UA Shadow tree was recreated. We need to set selection again. We do it 500 // UA Shadow tree was recreated. We need to set selection again. We do it
503 // later in order to avoid force layout. 501 // later in order to avoid force layout.
504 if (document().focusedElement() == this) 502 if (document().focusedElement() == this)
505 document().updateFocusAppearanceLater(); 503 document().updateFocusAppearanceLater();
506 504
507 setTextAsOfLastFormControlChangeEvent(value()); 505 // TODO(tkent): Should we dispatch a change event?
508 setChangedSinceLastFormControlChangeEvent(false); 506 clearValueBeforeFirstUserEdit();
509 507
510 addToRadioButtonGroup(); 508 addToRadioButtonGroup();
511 509
512 setNeedsValidityCheck(); 510 setNeedsValidityCheck();
513 if ((couldBeSuccessfulSubmitButton || canBeSuccessfulSubmitButton()) && 511 if ((couldBeSuccessfulSubmitButton || canBeSuccessfulSubmitButton()) &&
514 formOwner() && isConnected()) 512 formOwner() && isConnected())
515 formOwner()->invalidateDefaultButtonStyle(); 513 formOwner()->invalidateDefaultButtonStyle();
516 notifyFormStateChanged(); 514 notifyFormStateChanged();
517 } 515 }
518 516
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 m_autocomplete = Uninitialized; 704 m_autocomplete = Uninitialized;
707 else 705 else
708 m_autocomplete = On; 706 m_autocomplete = On;
709 } 707 }
710 } else if (name == typeAttr) { 708 } else if (name == typeAttr) {
711 updateType(); 709 updateType();
712 } else if (name == valueAttr) { 710 } else if (name == valueAttr) {
713 // We only need to setChanged if the form is looking at the default value 711 // We only need to setChanged if the form is looking at the default value
714 // right now. 712 // right now.
715 if (!hasDirtyValue()) { 713 if (!hasDirtyValue()) {
716 if (m_inputType->valueMode() == ValueMode::kValue) { 714 if (m_inputType->valueMode() == ValueMode::kValue)
717 m_nonAttributeValue = sanitizeValue(value); 715 m_nonAttributeValue = sanitizeValue(value);
718 setTextAsOfLastFormControlChangeEvent(m_nonAttributeValue);
719 }
720 updatePlaceholderVisibility(); 716 updatePlaceholderVisibility();
721 setNeedsStyleRecalc( 717 setNeedsStyleRecalc(
722 SubtreeStyleChange, 718 SubtreeStyleChange,
723 StyleChangeReasonForTracing::fromAttribute(valueAttr)); 719 StyleChangeReasonForTracing::fromAttribute(valueAttr));
724 } 720 }
725 m_needsToUpdateViewValue = true; 721 m_needsToUpdateViewValue = true;
726 setNeedsValidityCheck(); 722 setNeedsValidityCheck();
727 m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress; 723 m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
728 m_inputType->warnIfValueIsInvalidAndElementIsVisible(value); 724 m_inputType->warnIfValueIsInvalidAndElementIsVisible(value);
729 m_inputType->inRangeChanged(); 725 m_inputType->inRangeChanged();
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 cache->checkedStateChanged(this); 941 cache->checkedStateChanged(this);
946 } 942 }
947 943
948 // Only send a change event for items in the document (avoid firing during 944 // Only send a change event for items in the document (avoid firing during
949 // parsing) and don't send a change event for a radio button that's getting 945 // parsing) and don't send a change event for a radio button that's getting
950 // unchecked to match other browsers. DOM is not a useful standard for this 946 // unchecked to match other browsers. DOM is not a useful standard for this
951 // because it says only to fire change events at "lose focus" time, which is 947 // because it says only to fire change events at "lose focus" time, which is
952 // definitely wrong in practice for these types of elements. 948 // definitely wrong in practice for these types of elements.
953 if (eventBehavior != DispatchNoEvent && isConnected() && 949 if (eventBehavior != DispatchNoEvent && isConnected() &&
954 m_inputType->shouldSendChangeEventAfterCheckedChanged()) { 950 m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
955 setTextAsOfLastFormControlChangeEvent(String());
956 if (eventBehavior == DispatchInputAndChangeEvent) 951 if (eventBehavior == DispatchInputAndChangeEvent)
957 dispatchFormControlInputEvent(); 952 dispatchFormControlInputEvent();
958 } 953 }
959 954
960 pseudoStateChanged(CSSSelector::PseudoChecked); 955 pseudoStateChanged(CSSSelector::PseudoChecked);
961 } 956 }
962 957
963 void HTMLInputElement::setIndeterminate(bool newValue) { 958 void HTMLInputElement::setIndeterminate(bool newValue) {
964 if (indeterminate() == newValue) 959 if (indeterminate() == newValue)
965 return; 960 return;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 1093
1099 void HTMLInputElement::setNonAttributeValue(const String& sanitizedValue) { 1094 void HTMLInputElement::setNonAttributeValue(const String& sanitizedValue) {
1100 // This is a common code for ValueMode::kValue. 1095 // This is a common code for ValueMode::kValue.
1101 DCHECK_EQ(m_inputType->valueMode(), ValueMode::kValue); 1096 DCHECK_EQ(m_inputType->valueMode(), ValueMode::kValue);
1102 m_nonAttributeValue = sanitizedValue; 1097 m_nonAttributeValue = sanitizedValue;
1103 m_hasDirtyValue = true; 1098 m_hasDirtyValue = true;
1104 setNeedsValidityCheck(); 1099 setNeedsValidityCheck();
1105 m_inputType->inRangeChanged(); 1100 m_inputType->inRangeChanged();
1106 } 1101 }
1107 1102
1103 void HTMLInputElement::setNonAttributeValueByUserEdit(
1104 const String& sanitizedValue) {
1105 setValueBeforeFirstUserEditIfNotSet();
1106 setNonAttributeValue(sanitizedValue);
1107 checkIfValueWasReverted(sanitizedValue);
1108 }
1109
1108 void HTMLInputElement::setNonDirtyValue(const String& newValue) { 1110 void HTMLInputElement::setNonDirtyValue(const String& newValue) {
1109 setValue(newValue); 1111 setValue(newValue);
1110 m_hasDirtyValue = false; 1112 m_hasDirtyValue = false;
1111 } 1113 }
1112 1114
1113 bool HTMLInputElement::hasDirtyValue() const { 1115 bool HTMLInputElement::hasDirtyValue() const {
1114 return m_hasDirtyValue; 1116 return m_hasDirtyValue;
1115 } 1117 }
1116 1118
1117 void HTMLInputElement::updateView() { 1119 void HTMLInputElement::updateView() {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 // File upload controls will never use this. 1152 // File upload controls will never use this.
1151 DCHECK_NE(type(), InputTypeNames::file); 1153 DCHECK_NE(type(), InputTypeNames::file);
1152 1154
1153 m_suggestedValue = String(); 1155 m_suggestedValue = String();
1154 1156
1155 // Renderer and our event handler are responsible for sanitizing values. 1157 // Renderer and our event handler are responsible for sanitizing values.
1156 DCHECK(value == m_inputType->sanitizeUserInputValue(value) || 1158 DCHECK(value == m_inputType->sanitizeUserInputValue(value) ||
1157 m_inputType->sanitizeUserInputValue(value).isEmpty()); 1159 m_inputType->sanitizeUserInputValue(value).isEmpty());
1158 1160
1159 DCHECK(!value.isNull()); 1161 DCHECK(!value.isNull());
1162 setValueBeforeFirstUserEditIfNotSet();
1160 m_nonAttributeValue = value; 1163 m_nonAttributeValue = value;
1161 m_hasDirtyValue = true; 1164 m_hasDirtyValue = true;
1162 m_needsToUpdateViewValue = false; 1165 m_needsToUpdateViewValue = false;
1166 checkIfValueWasReverted(value);
1163 1167
1164 // Input event is fired by the Node::defaultEventHandler for editable 1168 // Input event is fired by the Node::defaultEventHandler for editable
1165 // controls. 1169 // controls.
1166 if (!isTextField()) 1170 if (!isTextField())
1167 dispatchInputEvent(); 1171 dispatchInputEvent();
1168 notifyFormStateChanged(); 1172 notifyFormStateChanged();
1169 1173
1170 setNeedsValidityCheck(); 1174 setNeedsValidityCheck();
1171 1175
1172 // Clear autofill flag (and yellow background) on user edit. 1176 // Clear autofill flag (and yellow background) on user edit.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 1257
1254 if (m_inputTypeView->shouldSubmitImplicitly(evt)) { 1258 if (m_inputTypeView->shouldSubmitImplicitly(evt)) {
1255 // FIXME: Remove type check. 1259 // FIXME: Remove type check.
1256 if (type() == InputTypeNames::search) { 1260 if (type() == InputTypeNames::search) {
1257 TaskRunnerHelper::get(TaskType::UserInteraction, &document()) 1261 TaskRunnerHelper::get(TaskType::UserInteraction, &document())
1258 ->postTask(BLINK_FROM_HERE, WTF::bind(&HTMLInputElement::onSearch, 1262 ->postTask(BLINK_FROM_HERE, WTF::bind(&HTMLInputElement::onSearch,
1259 wrapPersistent(this))); 1263 wrapPersistent(this)));
1260 } 1264 }
1261 // Form submission finishes editing, just as loss of focus does. 1265 // Form submission finishes editing, just as loss of focus does.
1262 // If there was a change, send the event now. 1266 // If there was a change, send the event now.
1263 if (wasChangedSinceLastFormControlChangeEvent()) 1267 dispatchFormControlChangeEvent();
1264 dispatchFormControlChangeEvent();
1265 1268
1266 HTMLFormElement* formForSubmission = m_inputTypeView->formForSubmission(); 1269 HTMLFormElement* formForSubmission = m_inputTypeView->formForSubmission();
1267 // Form may never have been present, or may have been destroyed by code 1270 // Form may never have been present, or may have been destroyed by code
1268 // responding to the change event. 1271 // responding to the change event.
1269 if (formForSubmission) 1272 if (formForSubmission)
1270 formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission()); 1273 formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
1271
1272 // We treat implicit submission is something like blur()-then-focus(). So
1273 // we reset the last value. crbug.com/695349 and crbug.com/700842.
1274 setTextAsOfLastFormControlChangeEvent(value());
1275
1276 evt->setDefaultHandled(); 1274 evt->setDefaultHandled();
1277 return; 1275 return;
1278 } 1276 }
1279 1277
1280 if (evt->isBeforeTextInsertedEvent()) 1278 if (evt->isBeforeTextInsertedEvent())
1281 m_inputTypeView->handleBeforeTextInsertedEvent( 1279 m_inputTypeView->handleBeforeTextInsertedEvent(
1282 static_cast<BeforeTextInsertedEvent*>(evt)); 1280 static_cast<BeforeTextInsertedEvent*>(evt));
1283 1281
1284 if (evt->isMouseEvent() && evt->type() == EventTypeNames::mousedown) { 1282 if (evt->isMouseEvent() && evt->type() == EventTypeNames::mousedown) {
1285 m_inputTypeView->handleMouseDownEvent(toMouseEvent(evt)); 1283 m_inputTypeView->handleMouseDownEvent(toMouseEvent(evt));
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1883 1881
1884 bool HTMLInputElement::hasFallbackContent() const { 1882 bool HTMLInputElement::hasFallbackContent() const {
1885 return m_inputTypeView->hasFallbackContent(); 1883 return m_inputTypeView->hasFallbackContent();
1886 } 1884 }
1887 1885
1888 void HTMLInputElement::setFilesFromPaths(const Vector<String>& paths) { 1886 void HTMLInputElement::setFilesFromPaths(const Vector<String>& paths) {
1889 return m_inputType->setFilesFromPaths(paths); 1887 return m_inputType->setFilesFromPaths(paths);
1890 } 1888 }
1891 1889
1892 } // namespace blink 1890 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLInputElement.h ('k') | third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698