HTMLInputElement.h (58336B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_HTMLInputElement_h 8 #define mozilla_dom_HTMLInputElement_h 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/Decimal.h" 12 #include "mozilla/Maybe.h" 13 #include "mozilla/TextControlElement.h" 14 #include "mozilla/TextControlState.h" 15 #include "mozilla/UniquePtr.h" 16 #include "mozilla/Variant.h" 17 #include "mozilla/dom/BindingDeclarations.h" 18 #include "mozilla/dom/ButtonInputTypes.h" 19 #include "mozilla/dom/CheckableInputTypes.h" 20 #include "mozilla/dom/ColorInputType.h" 21 #include "mozilla/dom/ConstraintValidation.h" 22 #include "mozilla/dom/DateTimeInputTypes.h" 23 #include "mozilla/dom/FileInputType.h" 24 #include "mozilla/dom/HTMLInputElementBinding.h" 25 #include "mozilla/dom/HiddenInputType.h" 26 #include "mozilla/dom/NumericInputTypes.h" 27 #include "mozilla/dom/Promise.h" 28 #include "mozilla/dom/RadioGroupContainer.h" 29 #include "mozilla/dom/SingleLineTextInputTypes.h" 30 #include "nsCOMPtr.h" 31 #include "nsContentUtils.h" 32 #include "nsGenericHTMLElement.h" 33 #include "nsIContentPrefService2.h" 34 #include "nsIFilePicker.h" 35 #include "nsImageLoadingContent.h" 36 37 class nsIEditor; 38 39 namespace mozilla { 40 41 class EventChainPostVisitor; 42 class EventChainPreVisitor; 43 44 namespace dom { 45 46 class AfterSetFilesOrDirectoriesRunnable; 47 class Date; 48 class DispatchChangeEventCallback; 49 class File; 50 class FileList; 51 class FileSystemEntry; 52 class FormData; 53 class GetFilesHelper; 54 class InputType; 55 class OwningFileOrDirectory; 56 57 /** 58 * A class we use to create a singleton object that is used to keep track of 59 * the last directory from which the user has picked files (via 60 * <input type=file>) on a per-domain basis. The implementation uses 61 * nsIContentPrefService2/NS_CONTENT_PREF_SERVICE_CONTRACTID to store the last 62 * directory per-domain, and to ensure that whether the directories are 63 * persistently saved (saved across sessions) or not honors whether or not the 64 * page is being viewed in private browsing. 65 */ 66 class UploadLastDir final : public nsIObserver, public nsSupportsWeakReference { 67 ~UploadLastDir() = default; 68 69 public: 70 NS_DECL_ISUPPORTS 71 NS_DECL_NSIOBSERVER 72 73 /** 74 * Fetch the last used directory for this location from the content 75 * pref service, and display the file picker opened in that directory. 76 * 77 * @param aDoc current document 78 * @param aFilePicker the file picker to open 79 * @param aFpCallback the callback object to be run when the file is shown. 80 */ 81 nsresult FetchDirectoryAndDisplayPicker( 82 Document* aDoc, nsIFilePicker* aFilePicker, 83 nsIFilePickerShownCallback* aFpCallback); 84 85 /** 86 * Store the last used directory for this location using the 87 * content pref service, if it is available 88 * @param aURI URI of the current page 89 * @param aDir Parent directory of the file(s)/directory chosen by the user 90 */ 91 nsresult StoreLastUsedDirectory(Document* aDoc, nsIFile* aDir); 92 93 class ContentPrefCallback final : public nsIContentPrefCallback2 { 94 virtual ~ContentPrefCallback() = default; 95 96 public: 97 ContentPrefCallback(nsIFilePicker* aFilePicker, 98 nsIFilePickerShownCallback* aFpCallback) 99 : mFilePicker(aFilePicker), mFpCallback(aFpCallback) {} 100 101 NS_DECL_ISUPPORTS 102 NS_DECL_NSICONTENTPREFCALLBACK2 103 104 nsCOMPtr<nsIFilePicker> mFilePicker; 105 nsCOMPtr<nsIFilePickerShownCallback> mFpCallback; 106 nsCOMPtr<nsIContentPref> mResult; 107 }; 108 }; 109 110 class HTMLInputElement final : public TextControlElement, 111 public nsImageLoadingContent, 112 public ConstraintValidation { 113 friend class AfterSetFilesOrDirectoriesCallback; 114 friend class DispatchChangeEventCallback; 115 friend class InputType; 116 117 public: 118 using ConstraintValidation::GetValidationMessage; 119 using nsGenericHTMLFormControlElementWithState::GetForm; 120 using nsGenericHTMLFormControlElementWithState::GetFormAction; 121 using ValueSetterOption = TextControlState::ValueSetterOption; 122 using ValueSetterOptions = TextControlState::ValueSetterOptions; 123 124 enum class FromClone { No, Yes }; 125 126 HTMLInputElement(already_AddRefed<dom::NodeInfo>&& aNodeInfo, 127 FromParser aFromParser, 128 FromClone aFromClone = FromClone::No); 129 130 NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLInputElement, input) 131 132 // nsISupports 133 NS_DECL_ISUPPORTS_INHERITED 134 135 int32_t TabIndexDefault() override; 136 using nsGenericHTMLElement::Focus; 137 138 // nsINode 139 #if !defined(ANDROID) && !defined(XP_MACOSX) 140 bool IsNodeApzAwareInternal() const override; 141 #endif 142 143 // Element 144 bool IsInteractiveHTMLContent() const override; 145 146 // nsGenericHTMLElement 147 bool IsDisabledForEvents(WidgetEvent* aEvent) override; 148 149 // nsGenericHTMLFormElement 150 void SaveState() override; 151 MOZ_CAN_RUN_SCRIPT_BOUNDARY bool RestoreState(PresState* aState) override; 152 153 // EventTarget 154 void AsyncEventRunning(AsyncEventDispatcher* aEvent) override; 155 156 // Overriden nsIFormControl methods 157 MOZ_CAN_RUN_SCRIPT_BOUNDARY 158 NS_IMETHOD Reset() override; 159 NS_IMETHOD SubmitNamesValues(FormData* aFormData) override; 160 161 void FieldSetDisabledChanged(bool aNotify) override; 162 163 // nsIContent 164 bool IsHTMLFocusable(IsFocusableFlags, bool* aIsFocusable, 165 int32_t* aTabIndex) override; 166 167 bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, 168 const nsAString& aValue, 169 nsIPrincipal* aMaybeScriptedPrincipal, 170 nsAttrValue& aResult) override; 171 172 // Note: if this returns false, then attributes may not yet be sanitized 173 // (per SetValueInternal's dependence on mDoneCreating). 174 bool IsDoneCreating() const { return mDoneCreating; } 175 176 bool LastValueChangeWasInteractive() const { 177 return mLastValueChangeWasInteractive; 178 } 179 180 void GetLastInteractiveValue(nsAString&); 181 182 nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute, 183 AttrModType aModType) const override; 184 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override; 185 nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override; 186 187 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override; 188 void LegacyPreActivationBehavior(EventChainVisitor& aVisitor) override; 189 MOZ_CAN_RUN_SCRIPT 190 void ActivationBehavior(EventChainPostVisitor& aVisitor) override; 191 void LegacyCanceledActivationBehavior( 192 EventChainPostVisitor& aVisitor) override; 193 MOZ_CAN_RUN_SCRIPT_BOUNDARY 194 nsresult PreHandleEvent(EventChainVisitor& aVisitor) override; 195 MOZ_CAN_RUN_SCRIPT_BOUNDARY 196 nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override; 197 MOZ_CAN_RUN_SCRIPT 198 nsresult MaybeHandleRadioButtonNavigation(EventChainPostVisitor&, 199 uint32_t aKeyCode); 200 MOZ_CAN_RUN_SCRIPT_BOUNDARY 201 void PostHandleEventForRangeThumb(EventChainPostVisitor& aVisitor); 202 MOZ_CAN_RUN_SCRIPT 203 void StartRangeThumbDrag(WidgetGUIEvent* aEvent); 204 MOZ_CAN_RUN_SCRIPT 205 void FinishRangeThumbDrag(WidgetGUIEvent* aEvent = nullptr); 206 MOZ_CAN_RUN_SCRIPT 207 void CancelRangeThumbDrag(bool aIsForUserEvent = true); 208 MOZ_CAN_RUN_SCRIPT 209 void MaybeDispatchWillBlur(EventChainVisitor&); 210 211 enum class SnapToTickMarks : bool { No, Yes }; 212 MOZ_CAN_RUN_SCRIPT 213 void SetValueOfRangeForUserEvent(Decimal aValue, 214 SnapToTickMarks = SnapToTickMarks::No); 215 216 nsresult BindToTree(BindContext&, nsINode& aParent) override; 217 void UnbindFromTree(UnbindContext&) override; 218 219 MOZ_CAN_RUN_SCRIPT_BOUNDARY 220 void DoneCreatingElement() override; 221 222 void DestroyContent() override; 223 224 void SetLastValueChangeWasInteractive(bool); 225 226 // TextControlElement 227 bool IsSingleLineTextControlOrTextArea() const override { 228 return IsSingleLineTextControl(false); 229 } 230 void SetValueChanged(bool aValueChanged) override; 231 bool IsSingleLineTextControl() const override; 232 bool IsTextArea() const override; 233 bool IsPasswordTextControl() const override; 234 Maybe<int32_t> GetCols() override; 235 int32_t GetWrapCols() override; 236 int32_t GetRows() override; 237 void GetDefaultValueFromContent(nsAString& aValue, bool aForDisplay) override; 238 bool ValueChanged() const override; 239 void GetTextEditorValue(nsAString& aValue) const override; 240 MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditor() override; 241 TextEditor* GetExtantTextEditor() const override; 242 nsISelectionController* GetSelectionController() override; 243 nsFrameSelection* GetIndependentFrameSelection() const override; 244 TextControlState* GetTextControlState() const override { 245 return GetEditorState(); 246 } 247 nsresult BindToFrame(nsTextControlFrame* aFrame) override; 248 MOZ_CAN_RUN_SCRIPT void UnbindFromFrame(nsTextControlFrame* aFrame) override; 249 MOZ_CAN_RUN_SCRIPT nsresult CreateEditor() override; 250 void SetPreviewValue(const nsAString& aValue) override; 251 void GetPreviewValue(nsAString& aValue) override; 252 void SetAutofillState(const nsAString& aState) override { 253 SetFormAutofillState(aState); 254 } 255 void GetAutofillState(nsAString& aState) override { 256 GetFormAutofillState(aState); 257 } 258 void EnablePreview() override; 259 bool IsPreviewEnabled() override; 260 void InitializeKeyboardEventListeners() override; 261 void OnValueChanged(ValueChangeKind, bool aNewValueEmpty, 262 const nsAString* aKnownNewValue) override; 263 void GetValueFromSetRangeText(nsAString& aValue) override; 264 MOZ_CAN_RUN_SCRIPT nsresult 265 SetValueFromSetRangeText(const nsAString& aValue) override; 266 bool HasCachedSelection() override; 267 MOZ_CAN_RUN_SCRIPT void SetRevealPassword(bool aValue); 268 bool RevealPassword() const; 269 270 // Methods for nsFormFillController so it can do selection operations on input 271 // types the HTML spec doesn't support them on, like "email". 272 uint32_t GetSelectionStartIgnoringType(ErrorResult& aRv); 273 uint32_t GetSelectionEndIgnoringType(ErrorResult& aRv); 274 275 void GetDisplayFileName(nsAString& aFileName) const; 276 277 const nsTArray<OwningFileOrDirectory>& GetFilesOrDirectoriesInternal() const; 278 279 void SetFilesOrDirectories( 280 const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories, 281 bool aSetValueChanged); 282 void SetFiles(FileList* aFiles, bool aSetValueChanged); 283 284 // This method is used for test only. Onces the data is set, a 'change' event 285 // is dispatched. 286 void MozSetDndFilesAndDirectories( 287 const nsTArray<OwningFileOrDirectory>& aSequence); 288 289 // Called when a nsIFilePicker or a nsIColorPicker terminate. 290 void PickerClosed(); 291 292 void SetCheckedChangedInternal(bool aCheckedChanged); 293 bool GetCheckedChanged() const { return mCheckedChanged; } 294 void AddToRadioGroup(); 295 void RemoveFromRadioGroup(); 296 void DisconnectRadioGroupContainer(); 297 void UpdateRadioGroupState(); 298 299 /** 300 * Helper function returning the currently selected button in the radio group. 301 * Returning null if the element is not a button or if there is no selectied 302 * button in the group. 303 * 304 * @return the selected button (or null). 305 */ 306 HTMLInputElement* GetSelectedRadioButton() const; 307 308 MOZ_CAN_RUN_SCRIPT_BOUNDARY 309 nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override; 310 311 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLInputElement, TextControlElement) 312 313 static UploadLastDir* gUploadLastDir; 314 // create and destroy the static UploadLastDir object for remembering 315 // which directory was last used on a site-by-site basis 316 static void InitUploadLastDir(); 317 static void DestroyUploadLastDir(); 318 319 // If the valueAsDate attribute should be enabled in webIDL 320 static bool ValueAsDateEnabled(JSContext* cx, JSObject* obj); 321 322 void MaybeLoadImage(); 323 324 bool HasPatternAttribute() const { return mHasPatternAttribute; } 325 326 // nsIConstraintValidation 327 bool IsTooLong(); 328 bool IsTooShort(); 329 bool IsValueMissing() const; 330 bool HasTypeMismatch() const; 331 Maybe<bool> HasPatternMismatch() const; 332 bool IsRangeOverflow() const; 333 bool IsRangeUnderflow() const; 334 bool ValueIsStepMismatch(const Decimal& aValue) const; 335 bool HasStepMismatch() const; 336 bool HasBadInput() const; 337 void UpdateTooLongValidityState(); 338 void UpdateTooShortValidityState(); 339 void UpdateValueMissingValidityState(); 340 void UpdateTypeMismatchValidityState(); 341 void UpdatePatternMismatchValidityState(); 342 void UpdateRangeOverflowValidityState(); 343 void UpdateRangeUnderflowValidityState(); 344 void UpdateStepMismatchValidityState(); 345 void UpdateBadInputValidityState(); 346 void UpdatePlaceholderShownState(); 347 void UpdateCheckedState(bool aNotify); 348 void UpdateIndeterminateState(bool aNotify); 349 // Update all our validity states and then update our element state 350 // as needed. aNotify controls whether the element state update 351 // needs to notify. 352 void UpdateAllValidityStates(bool aNotify); 353 void UpdateValidityElementStates(bool aNotify); 354 MOZ_CAN_RUN_SCRIPT 355 void MaybeUpdateAllValidityStates(bool aNotify) { 356 // If you need to add new type which supports validationMessage, you should 357 // add test cases into test_MozEditableElement_setUserInput.html. 358 if (mType == FormControlType::InputEmail) { 359 UpdateAllValidityStates(aNotify); 360 } 361 } 362 363 // Update all our validity states without updating element state. 364 // This should be called instead of UpdateAllValidityStates any time 365 // we're guaranteed that element state will be updated anyway. 366 void UpdateAllValidityStatesButNotElementState(); 367 void UpdateBarredFromConstraintValidation(); 368 nsresult GetValidationMessage(nsAString& aValidationMessage, 369 ValidityStateType aType) override; 370 371 // Override SetCustomValidity so we update our state properly when it's called 372 // via bindings. 373 void SetCustomValidity(const nsAString& aError); 374 375 /** 376 * Update the value missing validity state for radio elements when they have 377 * a group. 378 * 379 * @param aIgnoreSelf Whether the required attribute and the checked state 380 * of the current radio should be ignored. 381 * @note This method shouldn't be called if the radio element hasn't a group. 382 */ 383 void UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf); 384 385 /** 386 * Set filters to the filePicker according to the accept attribute value. 387 * 388 * See: 389 * http://dev.w3.org/html5/spec/forms.html#attr-input-accept 390 * 391 * @note You should not call this function if the element has no @accept. 392 * @note "All Files" filter is always set, no matter if there is a valid 393 * filter specified or not. 394 * @note If more than one valid filter is found, the "All Supported Types" 395 * filter is added, which is the concatenation of all valid filters. 396 * @note Duplicate filters and similar filters (i.e. filters whose file 397 * extensions already exist in another filter) are ignored. 398 * @note "All Files" filter will be selected by default if unknown mime types 399 * have been specified and no file extension filter has been specified. 400 * Otherwise, specified filter or "All Supported Types" filter will be 401 * selected by default. 402 * The logic behind is that having unknown mime type means we might restrict 403 * user's input too much, as some filters will be missing. 404 * However, if author has also specified some file extension filters, it's 405 * likely those are fallback for the unusual mime type we haven't been able 406 * to resolve; so it's better to select author specified filters in that case. 407 */ 408 void SetFilePickerFiltersFromAccept(nsIFilePicker* filePicker); 409 410 void SetUserInteracted(bool) final; 411 412 /** 413 * Fires change event if mFocusedValue and current value held are unequal and 414 * if a change event may be fired on bluring. 415 * Sets mFocusedValue to value, if a change event is fired. 416 */ 417 void FireChangeEventIfNeeded(); 418 419 /** 420 * Returns the input element's value as a Decimal. 421 * Returns NaN if the current element's value is not a floating point number. 422 * 423 * @return the input element's value as a Decimal. 424 */ 425 Decimal GetValueAsDecimal() const; 426 427 /** 428 * Returns the input's "minimum" (as defined by the HTML5 spec) as a double. 429 * Note this takes account of any default minimum that the type may have. 430 * Returns NaN if the min attribute isn't a valid floating point number and 431 * the input's type does not have a default minimum. 432 * 433 * NOTE: Only call this if you know DoesMinMaxApply() returns true. 434 */ 435 Decimal GetMinimum() const; 436 437 /** 438 * Returns the input's "maximum" (as defined by the HTML5 spec) as a double. 439 * Note this takes account of any default maximum that the type may have. 440 * Returns NaN if the max attribute isn't a valid floating point number and 441 * the input's type does not have a default maximum. 442 * 443 * NOTE:Only call this if you know DoesMinMaxApply() returns true. 444 */ 445 Decimal GetMaximum() const; 446 447 // WebIDL 448 449 void GetAccept(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::accept, aValue); } 450 void SetAccept(const nsAString& aValue, ErrorResult& aRv) { 451 SetHTMLAttr(nsGkAtoms::accept, aValue, aRv); 452 } 453 454 void GetAlt(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::alt, aValue); } 455 void SetAlt(const nsAString& aValue, ErrorResult& aRv) { 456 SetHTMLAttr(nsGkAtoms::alt, aValue, aRv); 457 } 458 459 void GetAutocomplete(nsAString& aValue); 460 void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv) { 461 SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv); 462 } 463 464 void GetAutocompleteInfo(Nullable<AutocompleteInfo>& aInfo); 465 466 void GetCapture(nsAString& aValue); 467 void SetCapture(const nsAString& aValue, ErrorResult& aRv) { 468 SetHTMLAttr(nsGkAtoms::capture, aValue, aRv); 469 } 470 471 bool DefaultChecked() const { return HasAttr(nsGkAtoms::checked); } 472 473 void SetDefaultChecked(bool aValue, ErrorResult& aRv) { 474 SetHTMLBoolAttr(nsGkAtoms::checked, aValue, aRv); 475 } 476 477 bool Checked() const { return mChecked; } 478 void SetChecked(bool aChecked); 479 480 bool IsRadioOrCheckbox() const { 481 return mType == FormControlType::InputCheckbox || 482 mType == FormControlType::InputRadio; 483 } 484 485 bool IsInputColor() const { return mType == FormControlType::InputColor; } 486 487 bool Disabled() const { return GetBoolAttr(nsGkAtoms::disabled); } 488 489 void SetDisabled(bool aValue, ErrorResult& aRv) { 490 SetHTMLBoolAttr(nsGkAtoms::disabled, aValue, aRv); 491 } 492 493 FileList* GetFiles(); 494 void SetFiles(FileList* aFiles); 495 496 void SetFormAction(const nsAString& aValue, ErrorResult& aRv) { 497 SetHTMLAttr(nsGkAtoms::formaction, aValue, aRv); 498 } 499 500 void GetFormEnctype(nsAString& aValue); 501 void SetFormEnctype(const nsAString& aValue, ErrorResult& aRv) { 502 SetHTMLAttr(nsGkAtoms::formenctype, aValue, aRv); 503 } 504 505 void GetFormMethod(nsAString& aValue); 506 void SetFormMethod(const nsAString& aValue, ErrorResult& aRv) { 507 SetHTMLAttr(nsGkAtoms::formmethod, aValue, aRv); 508 } 509 510 bool FormNoValidate() const { return GetBoolAttr(nsGkAtoms::formnovalidate); } 511 512 void SetFormNoValidate(bool aValue, ErrorResult& aRv) { 513 SetHTMLBoolAttr(nsGkAtoms::formnovalidate, aValue, aRv); 514 } 515 516 void GetFormTarget(nsAString& aValue) { 517 GetHTMLAttr(nsGkAtoms::formtarget, aValue); 518 } 519 void SetFormTarget(const nsAString& aValue, ErrorResult& aRv) { 520 SetHTMLAttr(nsGkAtoms::formtarget, aValue, aRv); 521 } 522 523 MOZ_CAN_RUN_SCRIPT uint32_t Height(); 524 525 void SetHeight(uint32_t aValue, ErrorResult& aRv) { 526 SetUnsignedIntAttr(nsGkAtoms::height, aValue, 0, aRv); 527 } 528 529 bool Indeterminate() const { return mIndeterminate; } 530 531 bool IsDraggingRange() const { return mIsDraggingRange; } 532 void SetIndeterminate(bool aValue); 533 534 HTMLDataListElement* GetList() const; 535 536 void GetMax(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::max, aValue); } 537 void SetMax(const nsAString& aValue, ErrorResult& aRv) { 538 SetHTMLAttr(nsGkAtoms::max, aValue, aRv); 539 } 540 541 int32_t MaxLength() const { return GetIntAttr(nsGkAtoms::maxlength, -1); } 542 543 int32_t UsedMaxLength() const final { 544 if (!mInputType->MinAndMaxLengthApply()) { 545 return -1; 546 } 547 return MaxLength(); 548 } 549 550 void SetMaxLength(int32_t aValue, ErrorResult& aRv) { 551 int32_t minLength = MinLength(); 552 if (aValue < 0 || (minLength >= 0 && aValue < minLength)) { 553 aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); 554 return; 555 } 556 557 SetHTMLIntAttr(nsGkAtoms::maxlength, aValue, aRv); 558 } 559 560 int32_t MinLength() const { return GetIntAttr(nsGkAtoms::minlength, -1); } 561 562 void SetMinLength(int32_t aValue, ErrorResult& aRv) { 563 int32_t maxLength = MaxLength(); 564 if (aValue < 0 || (maxLength >= 0 && aValue > maxLength)) { 565 aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); 566 return; 567 } 568 569 SetHTMLIntAttr(nsGkAtoms::minlength, aValue, aRv); 570 } 571 572 void GetMin(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::min, aValue); } 573 void SetMin(const nsAString& aValue, ErrorResult& aRv) { 574 SetHTMLAttr(nsGkAtoms::min, aValue, aRv); 575 } 576 577 bool Multiple() const { return GetBoolAttr(nsGkAtoms::multiple); } 578 579 void SetMultiple(bool aValue, ErrorResult& aRv) { 580 SetHTMLBoolAttr(nsGkAtoms::multiple, aValue, aRv); 581 } 582 583 void GetName(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::name, aValue); } 584 void SetName(const nsAString& aValue, ErrorResult& aRv) { 585 SetHTMLAttr(nsGkAtoms::name, aValue, aRv); 586 } 587 588 void GetPattern(nsAString& aValue) { 589 GetHTMLAttr(nsGkAtoms::pattern, aValue); 590 } 591 void SetPattern(const nsAString& aValue, ErrorResult& aRv) { 592 SetHTMLAttr(nsGkAtoms::pattern, aValue, aRv); 593 } 594 595 void GetPlaceholder(nsAString& aValue) { 596 GetHTMLAttr(nsGkAtoms::placeholder, aValue); 597 } 598 void SetPlaceholder(const nsAString& aValue, ErrorResult& aRv) { 599 SetHTMLAttr(nsGkAtoms::placeholder, aValue, aRv); 600 } 601 602 bool ReadOnly() const { return GetBoolAttr(nsGkAtoms::readonly); } 603 604 void SetReadOnly(bool aValue, ErrorResult& aRv) { 605 SetHTMLBoolAttr(nsGkAtoms::readonly, aValue, aRv); 606 } 607 608 bool Required() const { return GetBoolAttr(nsGkAtoms::required); } 609 610 void SetRequired(bool aValue, ErrorResult& aRv) { 611 SetHTMLBoolAttr(nsGkAtoms::required, aValue, aRv); 612 } 613 614 uint32_t Size() const { 615 return GetUnsignedIntAttr(nsGkAtoms::size, DEFAULT_COLS); 616 } 617 618 void SetSize(uint32_t aValue, ErrorResult& aRv) { 619 if (aValue == 0) { 620 aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); 621 return; 622 } 623 624 SetUnsignedIntAttr(nsGkAtoms::size, aValue, DEFAULT_COLS, aRv); 625 } 626 627 void GetSrc(nsAString& aValue) { 628 GetURIAttr(nsGkAtoms::src, nullptr, aValue); 629 } 630 void SetSrc(const nsAString& aValue, nsIPrincipal* aTriggeringPrincipal, 631 ErrorResult& aRv) { 632 SetHTMLAttr(nsGkAtoms::src, aValue, aTriggeringPrincipal, aRv); 633 } 634 635 void GetStep(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::step, aValue); } 636 void SetStep(const nsAString& aValue, ErrorResult& aRv) { 637 SetHTMLAttr(nsGkAtoms::step, aValue, aRv); 638 } 639 640 void GetType(nsAString& aValue) const; 641 void SetType(const nsAString& aValue, ErrorResult& aRv) { 642 SetHTMLAttr(nsGkAtoms::type, aValue, aRv); 643 } 644 645 void GetDefaultValue(nsAString& aValue) { 646 GetHTMLAttr(nsGkAtoms::value, aValue); 647 } 648 void SetDefaultValue(const nsAString& aValue, ErrorResult& aRv) { 649 SetHTMLAttr(nsGkAtoms::value, aValue, aRv); 650 } 651 652 MOZ_CAN_RUN_SCRIPT_BOUNDARY 653 void SetValue(const nsAString& aValue, CallerType aCallerType, 654 ErrorResult& aRv); 655 void GetValue(nsAString& aValue, CallerType aCallerType); 656 657 // Generic getter for the value that doesn't do experimental control type 658 // sanitization. 659 void GetValueInternal(nsAString& aValue, CallerType aCallerType) const; 660 661 void GetValueAsDate(JSContext* aCx, JS::MutableHandle<JSObject*> aObj, 662 ErrorResult& aRv); 663 664 void SetValueAsDate(JSContext* aCx, JS::Handle<JSObject*> aObj, 665 ErrorResult& aRv); 666 667 double ValueAsNumber() const { 668 return DoesValueAsNumberApply() ? GetValueAsDecimal().toDouble() 669 : UnspecifiedNaN<double>(); 670 } 671 672 void SetValueAsNumber(double aValue, ErrorResult& aRv); 673 674 MOZ_CAN_RUN_SCRIPT uint32_t Width(); 675 676 void SetWidth(uint32_t aValue, ErrorResult& aRv) { 677 SetUnsignedIntAttr(nsGkAtoms::width, aValue, 0, aRv); 678 } 679 680 void StepUp(int32_t aN, ErrorResult& aRv) { ApplyStep(aN, aRv); } 681 void StepDown(int32_t aN, ErrorResult& aRv) { ApplyStep(-aN, aRv); } 682 683 /** 684 * Returns the current step value. 685 * Returns kStepAny if the current step is "any" string. 686 * 687 * @return the current step value. 688 */ 689 Decimal GetStep() const; 690 691 // Returns whether the given keyboard event steps up or down the value of an 692 // <input> element. 693 bool StepsInputValue(const WidgetKeyboardEvent&) const; 694 695 already_AddRefed<nsINodeList> GetLabels(); 696 697 MOZ_CAN_RUN_SCRIPT void Select(); 698 699 Nullable<uint32_t> GetSelectionStart(ErrorResult& aRv); 700 MOZ_CAN_RUN_SCRIPT void SetSelectionStart(const Nullable<uint32_t>& aValue, 701 ErrorResult& aRv); 702 703 Nullable<uint32_t> GetSelectionEnd(ErrorResult& aRv); 704 MOZ_CAN_RUN_SCRIPT void SetSelectionEnd(const Nullable<uint32_t>& aValue, 705 ErrorResult& aRv); 706 707 void GetSelectionDirection(nsAString& aValue, ErrorResult& aRv); 708 MOZ_CAN_RUN_SCRIPT void SetSelectionDirection(const nsAString& aValue, 709 ErrorResult& aRv); 710 711 MOZ_CAN_RUN_SCRIPT void SetSelectionRange( 712 uint32_t aStart, uint32_t aEnd, const Optional<nsAString>& direction, 713 ErrorResult& aRv); 714 715 MOZ_CAN_RUN_SCRIPT void SetRangeText(const nsAString& aReplacement, 716 ErrorResult& aRv); 717 718 MOZ_CAN_RUN_SCRIPT void SetRangeText(const nsAString& aReplacement, 719 uint32_t aStart, uint32_t aEnd, 720 SelectionMode aSelectMode, 721 ErrorResult& aRv); 722 723 MOZ_CAN_RUN_SCRIPT void ShowPicker(ErrorResult& aRv); 724 725 bool WebkitDirectoryAttr() const { 726 return HasAttr(nsGkAtoms::webkitdirectory); 727 } 728 729 void SetWebkitDirectoryAttr(bool aValue, ErrorResult& aRv) { 730 SetHTMLBoolAttr(nsGkAtoms::webkitdirectory, aValue, aRv); 731 } 732 733 void GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence); 734 735 already_AddRefed<Promise> GetFilesAndDirectories(ErrorResult& aRv); 736 737 void GetAlign(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::align, aValue); } 738 void SetAlign(const nsAString& aValue, ErrorResult& aRv) { 739 SetHTMLAttr(nsGkAtoms::align, aValue, aRv); 740 } 741 742 void GetUseMap(nsAString& aValue) { GetHTMLAttr(nsGkAtoms::usemap, aValue); } 743 void SetUseMap(const nsAString& aValue, ErrorResult& aRv) { 744 SetHTMLAttr(nsGkAtoms::usemap, aValue, aRv); 745 } 746 747 void GetDirName(nsAString& aValue) { 748 GetHTMLAttr(nsGkAtoms::dirname, aValue); 749 } 750 void SetDirName(const nsAString& aValue, ErrorResult& aRv) { 751 SetHTMLAttr(nsGkAtoms::dirname, aValue, aRv); 752 } 753 754 nsIControllers* GetControllers(ErrorResult& aRv); 755 nsIControllers* GetExtantControllers() const { return mControllers; } 756 // XPCOM adapter function widely used throughout code, leaving it as is. 757 nsresult GetControllers(nsIControllers** aResult); 758 759 int32_t InputTextLength(CallerType aCallerType); 760 761 void MozGetFileNameArray(nsTArray<nsString>& aFileNames, ErrorResult& aRv); 762 763 void MozSetFileNameArray(const Sequence<nsString>& aFileNames, 764 ErrorResult& aRv); 765 void MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles); 766 void MozSetDirectory(const nsAString& aDirectoryPath, ErrorResult& aRv); 767 768 /* 769 * The following functions are called from datetime picker to let input box 770 * know the current state of the picker or to update the input box on changes. 771 */ 772 void GetDateTimeInputBoxValue(DateTimeValue& aValue); 773 774 /* 775 * This allows chrome JavaScript to dispatch event to the inner datetimebox 776 * anonymous or UA Widget element. 777 */ 778 Element* GetDateTimeBoxElement(); 779 780 /* 781 * The following functions are called from the datetimebox element to control 782 * and update the picker. 783 */ 784 void OpenDateTimePicker(const DateTimeValue& aInitialValue); 785 void CloseDateTimePicker(); 786 787 /** 788 * Sets open state for the input element, depending on whether the picker is 789 * open or closed. 790 */ 791 void SetOpenState(bool aIsOpen); 792 793 void OpenColorPicker(); 794 795 /* 796 * Called from datetime input box binding when inner text fields are focused 797 * or blurred. 798 */ 799 void SetFocusState(bool aIsFocused); 800 801 /* 802 * Called from datetime input box binding when the the user entered value 803 * becomes valid/invalid. 804 */ 805 void UpdateValidityState(); 806 807 /* 808 * The following are called from datetime input box binding to get the 809 * corresponding computed values. 810 */ 811 double GetStepAsDouble() { return GetStep().toDouble(); } 812 double GetStepBaseAsDouble() { return GetStepBase().toDouble(); } 813 double GetMinimumAsDouble() { return GetMinimum().toDouble(); } 814 double GetMaximumAsDouble() { return GetMaximum().toDouble(); } 815 816 /** 817 * Return the current value as InputPickerColor. 818 */ 819 void GetColor(InputPickerColor& aValue); 820 821 /** 822 * Converts the InputPickerColor into a string and set it as user input. 823 */ 824 void SetUserInputColor(const InputPickerColor& aValue); 825 826 void StartNumberControlSpinnerSpin(); 827 enum SpinnerStopState { eAllowDispatchingEvents, eDisallowDispatchingEvents }; 828 void StopNumberControlSpinnerSpin( 829 SpinnerStopState aState = eAllowDispatchingEvents); 830 MOZ_CAN_RUN_SCRIPT 831 void StepNumberControlForUserEvent(int32_t aDirection); 832 833 /** 834 * The callback function used by the nsRepeatService that we use to spin the 835 * spinner for <input type=number>. 836 */ 837 MOZ_CAN_RUN_SCRIPT_BOUNDARY 838 static void HandleNumberControlSpin(void* aData); 839 840 bool NumberSpinnerUpButtonIsDepressed() const { 841 return mNumberControlSpinnerIsSpinning && mNumberControlSpinnerSpinsUp; 842 } 843 844 bool NumberSpinnerDownButtonIsDepressed() const { 845 return mNumberControlSpinnerIsSpinning && !mNumberControlSpinnerSpinsUp; 846 } 847 848 bool MozIsTextField(bool aExcludePassword); 849 850 MOZ_CAN_RUN_SCRIPT nsIEditor* GetEditorForBindings(); 851 // For WebIDL bindings. 852 bool HasEditor() const; 853 854 bool IsInputEventTarget() const { return IsSingleLineTextControl(false); } 855 856 MOZ_CAN_RUN_SCRIPT_BOUNDARY 857 void SetUserInput(const nsAString& aInput, nsIPrincipal& aSubjectPrincipal); 858 859 /** 860 * If aValue contains a valid floating-point number in the format specified 861 * by the HTML 5 spec: 862 * 863 * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#floating-point-numbers 864 * 865 * then this function will return the number parsed as a Decimal, otherwise 866 * it will return a Decimal for which Decimal::isFinite() will return false. 867 */ 868 static Decimal StringToDecimal(const nsAString& aValue); 869 870 void UpdateEntries( 871 const nsTArray<OwningFileOrDirectory>& aFilesOrDirectories); 872 873 /** 874 * Returns if the required attribute applies for the current type. 875 */ 876 bool DoesRequiredApply() const; 877 878 /** 879 * Returns the current required state of the element. This function differs 880 * from Required() in that this function only returns true for input types 881 * that @required attribute applies and the attribute is set; in contrast, 882 * Required() returns true whenever @required attribute is set. 883 */ 884 bool IsRequired() const { return State().HasState(ElementState::REQUIRED); } 885 886 bool HasBeenTypePassword() const { return mHasBeenTypePassword; } 887 888 /** 889 * Returns whether the current value is the empty string. This only makes 890 * sense for some input types; does NOT make sense for file inputs. 891 * 892 * @return whether the current value is the empty string. 893 */ 894 bool IsValueEmpty() const { 895 return State().HasState(ElementState::VALUE_EMPTY); 896 } 897 898 // Parse a simple (hex) color. 899 static mozilla::Maybe<nscolor> ParseSimpleColor(const nsAString& aColor); 900 901 /** 902 * https://html.spec.whatwg.org/#auto-directionality-form-associated-elements 903 */ 904 bool IsAutoDirectionalityAssociated() const { 905 return IsAutoDirectionalityAssociated(mType); 906 } 907 908 protected: 909 MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual ~HTMLInputElement(); 910 911 JSObject* WrapNode(JSContext* aCx, 912 JS::Handle<JSObject*> aGivenProto) override; 913 914 // Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden 915 // by the TextControlElement version. 916 using nsGenericHTMLFormControlElementWithState::IsSingleLineTextControl; 917 918 /** 919 * The ValueModeType specifies how the value IDL attribute should behave. 920 * 921 * See: http://dev.w3.org/html5/spec/forms.html#dom-input-value 922 */ 923 enum ValueModeType { 924 // On getting, returns the value. 925 // On setting, sets value. 926 VALUE_MODE_VALUE, 927 // On getting, returns the value if present or the empty string. 928 // On setting, sets the value. 929 VALUE_MODE_DEFAULT, 930 // On getting, returns the value if present or "on". 931 // On setting, sets the value. 932 VALUE_MODE_DEFAULT_ON, 933 // On getting, returns "C:\fakepath\" followed by the file name of the 934 // first file of the selected files if any. 935 // On setting the empty string, empties the selected files list, otherwise 936 // throw the INVALID_STATE_ERR exception. 937 VALUE_MODE_FILENAME 938 }; 939 940 /** 941 * This helper method convert a sub-string that contains only digits to a 942 * number (unsigned int given that it can't contain a minus sign). 943 * This method will return whether the sub-string is correctly formatted 944 * (ie. contains only digit) and it can be successfuly parsed to generate a 945 * number). 946 * If the method returns true, |aResult| will contained the parsed number. 947 * 948 * @param aValue the string on which the sub-string will be extracted and 949 * parsed. 950 * @param aStart the beginning of the sub-string in aValue. 951 * @param aLen the length of the sub-string. 952 * @param aResult the parsed number. 953 * @return whether the sub-string has been parsed successfully. 954 */ 955 static bool DigitSubStringToNumber(const nsAString& aValue, uint32_t aStart, 956 uint32_t aLen, uint32_t* aResult); 957 958 // Helper method 959 960 /** 961 * Setting the value. 962 * 963 * @param aValue String to set. 964 * @param aOldValue Previous value before setting aValue. 965 If previous value is unknown, aOldValue can be nullptr. 966 * @param aOptions See TextControlState::ValueSetterOption. 967 */ 968 MOZ_CAN_RUN_SCRIPT nsresult 969 SetValueInternal(const nsAString& aValue, const nsAString* aOldValue, 970 const ValueSetterOptions& aOptions); 971 MOZ_CAN_RUN_SCRIPT nsresult SetValueInternal( 972 const nsAString& aValue, const ValueSetterOptions& aOptions) { 973 return SetValueInternal(aValue, nullptr, aOptions); 974 } 975 976 // A getter for callers that know we're not dealing with a file input, so they 977 // don't have to think about the caller type. 978 void GetNonFileValueInternal(nsAString& aValue) const; 979 980 void ClearFiles(bool aSetValueChanged); 981 982 void SetIndeterminateInternal(bool aValue, bool aShouldInvalidate); 983 984 /** 985 * Called when an attribute is about to be changed 986 */ 987 void BeforeSetAttr(int32_t aNameSpaceID, nsAtom* aName, 988 const nsAttrValue* aValue, bool aNotify) override; 989 /** 990 * Called when an attribute has just been changed 991 */ 992 MOZ_CAN_RUN_SCRIPT_BOUNDARY 993 void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, 994 const nsAttrValue* aValue, const nsAttrValue* aOldValue, 995 nsIPrincipal* aSubjectPrincipal, bool aNotify) override; 996 997 void BeforeSetForm(HTMLFormElement* aForm, bool aBindToTree) override; 998 999 void AfterClearForm(bool aUnbindOrDelete) override; 1000 1001 void ResultForDialogSubmit(nsAString& aResult) override; 1002 1003 MOZ_CAN_RUN_SCRIPT void SelectAll(); 1004 bool IsImage() const { 1005 return AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, nsGkAtoms::image, 1006 eIgnoreCase); 1007 } 1008 1009 /** 1010 * Visit the group of radio buttons this radio belongs to 1011 * @param aCallback the callback function to visit the node 1012 */ 1013 template <typename VisitCallback> 1014 void VisitGroup(VisitCallback&& aCallback, bool aSkipThis = true); 1015 1016 /** 1017 * Do all the work that |SetChecked| does (radio button handling, etc.), but 1018 * take an |aNotify| parameter. 1019 */ 1020 void DoSetChecked(bool aValue, bool aNotify, bool aSetValueChanged, 1021 bool aUpdateOtherElement = true); 1022 1023 /** 1024 * Actually set checked and notify the frame of the change. 1025 * @param aValue the value of checked to set 1026 */ 1027 void SetCheckedInternal(bool aValue, bool aNotify); 1028 1029 void RadioSetChecked(bool aNotify, bool aUpdateOtherElement); 1030 void SetCheckedChanged(bool aCheckedChanged); 1031 1032 /** 1033 * MaybeSubmitForm looks for a submit input or a single text control 1034 * and submits the form if either is present. 1035 */ 1036 MOZ_CAN_RUN_SCRIPT void MaybeSubmitForm(nsPresContext* aPresContext); 1037 1038 /** 1039 * Called after calling one of the SetFilesOrDirectories() functions. 1040 * This method can explore the directory recursively if needed. 1041 */ 1042 void AfterSetFilesOrDirectories(bool aSetValueChanged); 1043 1044 /** 1045 * Recursively explore the directory and populate mFileOrDirectories correctly 1046 * for webkitdirectory. 1047 */ 1048 void ExploreDirectoryRecursively(bool aSetValuechanged); 1049 1050 /** 1051 * Determine whether the editor needs to be initialized explicitly for 1052 * a particular event. 1053 */ 1054 bool NeedToInitializeEditorForEvent(EventChainPreVisitor& aVisitor) const; 1055 1056 /** 1057 * Get the value mode of the element, depending of the type. 1058 */ 1059 ValueModeType GetValueMode() const; 1060 1061 /** 1062 * Get the mutable state of the element. 1063 * When the element isn't mutable (immutable), the value or checkedness 1064 * should not be changed by the user. 1065 * 1066 * See: https://html.spec.whatwg.org/#concept-fe-mutable 1067 */ 1068 bool IsMutable() const; 1069 1070 /** 1071 * Returns if the min and max attributes apply for the current type. 1072 */ 1073 bool DoesMinMaxApply() const; 1074 1075 /** 1076 * Returns if the step attribute apply for the current type. 1077 */ 1078 bool DoesStepApply() const { return DoesMinMaxApply(); } 1079 1080 /** 1081 * Returns if stepDown and stepUp methods apply for the current type. 1082 */ 1083 bool DoStepDownStepUpApply() const { return DoesStepApply(); } 1084 1085 /** 1086 * Returns if valueAsNumber attribute applies for the current type. 1087 */ 1088 bool DoesValueAsNumberApply() const { return DoesMinMaxApply(); } 1089 1090 /** 1091 * Returns if autocomplete attribute applies for the current type. 1092 */ 1093 bool DoesAutocompleteApply() const; 1094 1095 MOZ_CAN_RUN_SCRIPT void FreeData(); 1096 TextControlState* GetEditorState() const; 1097 void EnsureEditorState(); 1098 1099 MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditorFromState(); 1100 1101 /** 1102 * Manages the internal data storage across type changes. 1103 */ 1104 MOZ_CAN_RUN_SCRIPT 1105 void HandleTypeChange(FormControlType aNewType, bool aNotify); 1106 1107 /** 1108 * If the input range has a list, this function will snap the given value to 1109 * the nearest tick mark, but only if the given value is close enough to that 1110 * tick mark. 1111 */ 1112 void MaybeSnapToTickMark(Decimal& aValue); 1113 1114 enum class SanitizationKind { ForValueGetter, ForValueSetter, ForDisplay }; 1115 /** 1116 * Sanitize the value of the element depending of its current type. 1117 * See: 1118 * http://www.whatwg.org/specs/web-apps/current-work/#value-sanitization-algorithm 1119 */ 1120 void SanitizeValue(nsAString& aValue, SanitizationKind) const; 1121 1122 /** 1123 * Returns whether the placeholder attribute applies for the current type. 1124 */ 1125 bool PlaceholderApplies() const; 1126 1127 /** 1128 * Set the current default value to the value of the input element. 1129 * @note You should not call this method if GetValueMode() doesn't return 1130 * VALUE_MODE_VALUE. 1131 */ 1132 MOZ_CAN_RUN_SCRIPT 1133 nsresult SetDefaultValueAsValue(); 1134 1135 /** 1136 * Returns the radio group container within the DOM tree that the element 1137 * is currently a member of, if one exists. 1138 */ 1139 RadioGroupContainer* GetCurrentRadioGroupContainer() const; 1140 /** 1141 * Returns the radio group container within the DOM tree that the element 1142 * should be added into, if one exists. 1143 */ 1144 RadioGroupContainer* FindTreeRadioGroupContainer() const; 1145 1146 /** 1147 * Parse a week string of the form yyyy-Www 1148 * @param the string to be parsed. 1149 * @return whether the string is a valid week. 1150 * Note : this function does not consider the empty string as valid. 1151 */ 1152 bool IsValidWeek(const nsAString& aValue) const; 1153 1154 /** 1155 * Parse a month string of the form yyyy-mm 1156 * @param the string to be parsed. 1157 * @return whether the string is a valid month. 1158 * Note : this function does not consider the empty string as valid. 1159 */ 1160 bool IsValidMonth(const nsAString& aValue) const; 1161 1162 /** 1163 * Parse a date string of the form yyyy-mm-dd 1164 * @param the string to be parsed. 1165 * @return whether the string is a valid date. 1166 * Note : this function does not consider the empty string as valid. 1167 */ 1168 bool IsValidDate(const nsAString& aValue) const; 1169 1170 /** 1171 * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or 1172 * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits. 1173 * 1174 * @param the string to be parsed. 1175 * @return whether the string is a valid datetime-local string. 1176 * Note : this function does not consider the empty string as valid. 1177 */ 1178 bool IsValidDateTimeLocal(const nsAString& aValue) const; 1179 1180 /** 1181 * Parse a year string of the form yyyy 1182 * 1183 * @param the string to be parsed. 1184 * 1185 * @return the year in aYear. 1186 * @return whether the parsing was successful. 1187 */ 1188 bool ParseYear(const nsAString& aValue, uint32_t* aYear) const; 1189 1190 /** 1191 * Parse a month string of the form yyyy-mm 1192 * 1193 * @param the string to be parsed. 1194 * @return the year and month in aYear and aMonth. 1195 * @return whether the parsing was successful. 1196 */ 1197 bool ParseMonth(const nsAString& aValue, uint32_t* aYear, 1198 uint32_t* aMonth) const; 1199 1200 /** 1201 * Parse a week string of the form yyyy-Www 1202 * 1203 * @param the string to be parsed. 1204 * @return the year and week in aYear and aWeek. 1205 * @return whether the parsing was successful. 1206 */ 1207 bool ParseWeek(const nsAString& aValue, uint32_t* aYear, 1208 uint32_t* aWeek) const; 1209 /** 1210 * Parse a date string of the form yyyy-mm-dd 1211 * 1212 * @param the string to be parsed. 1213 * @return the date in aYear, aMonth, aDay. 1214 * @return whether the parsing was successful. 1215 */ 1216 bool ParseDate(const nsAString& aValue, uint32_t* aYear, uint32_t* aMonth, 1217 uint32_t* aDay) const; 1218 1219 /** 1220 * Parse a datetime-local string of the form yyyy-mm-ddThh:mm[:ss.s] or 1221 * yyyy-mm-dd hh:mm[:ss.s], where fractions of seconds can be 1 to 3 digits. 1222 * 1223 * @param the string to be parsed. 1224 * @return the date in aYear, aMonth, aDay and time expressed in milliseconds 1225 * in aTime. 1226 * @return whether the parsing was successful. 1227 */ 1228 bool ParseDateTimeLocal(const nsAString& aValue, uint32_t* aYear, 1229 uint32_t* aMonth, uint32_t* aDay, 1230 uint32_t* aTime) const; 1231 1232 /** 1233 * Normalize the datetime-local string following the HTML specifications: 1234 * https://html.spec.whatwg.org/multipage/infrastructure.html#valid-normalised-local-date-and-time-string 1235 */ 1236 void NormalizeDateTimeLocal(nsAString& aValue) const; 1237 1238 /** 1239 * This methods returns the number of days since epoch for a given year and 1240 * week. 1241 */ 1242 double DaysSinceEpochFromWeek(uint32_t aYear, uint32_t aWeek) const; 1243 1244 /** 1245 * This methods returns the number of days in a given month, for a given year. 1246 */ 1247 uint32_t NumberOfDaysInMonth(uint32_t aMonth, uint32_t aYear) const; 1248 1249 /** 1250 * This methods returns the number of months between January 1970 and the 1251 * given year and month. 1252 */ 1253 int32_t MonthsSinceJan1970(uint32_t aYear, uint32_t aMonth) const; 1254 1255 /** 1256 * This methods returns the day of the week given a date. If @isoWeek is true, 1257 * 7=Sunday, otherwise, 0=Sunday. 1258 */ 1259 uint32_t DayOfWeek(uint32_t aYear, uint32_t aMonth, uint32_t aDay, 1260 bool isoWeek) const; 1261 1262 /** 1263 * This methods returns the maximum number of week in a given year, the 1264 * result is either 52 or 53. 1265 */ 1266 uint32_t MaximumWeekInYear(uint32_t aYear) const; 1267 1268 /** 1269 * This methods returns true if it's a leap year. 1270 */ 1271 bool IsLeapYear(uint32_t aYear) const; 1272 1273 /** 1274 * Returns whether aValue is a valid time as described by HTML specifications: 1275 * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-time-string 1276 * 1277 * @param aValue the string to be tested. 1278 * @return Whether the string is a valid time per HTML specifications. 1279 */ 1280 bool IsValidTime(const nsAString& aValue) const; 1281 1282 /** 1283 * Returns the time expressed in milliseconds of |aValue| being parsed as a 1284 * time following the HTML specifications: 1285 * http://www.whatwg.org/specs/web-apps/current-work/#parse-a-time-string 1286 * 1287 * Note: |aResult| can be null. 1288 * 1289 * @param aValue the string to be parsed. 1290 * @param aResult the time expressed in milliseconds representing the time 1291 * [out] 1292 * @return Whether the parsing was successful. 1293 */ 1294 static bool ParseTime(const nsAString& aValue, uint32_t* aResult); 1295 1296 /** 1297 * Sets the value of the element to the string representation of the Decimal. 1298 * 1299 * @param aValue The Decimal that will be used to set the value. 1300 */ 1301 void SetValue(Decimal aValue, CallerType aCallerType); 1302 1303 void UpdateHasRange(bool aNotify); 1304 // Updates the :in-range / :out-of-range states. 1305 void UpdateInRange(bool aNotify); 1306 1307 /** 1308 * Get the step scale value for the current type. 1309 * See: 1310 * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#concept-input-step-scale 1311 */ 1312 Decimal GetStepScaleFactor() const; 1313 1314 /** 1315 * Return the base used to compute if a value matches step. 1316 * Basically, it's the min attribute if present and a default value otherwise. 1317 * 1318 * @return The step base. 1319 */ 1320 Decimal GetStepBase() const; 1321 1322 /** 1323 * Returns the default step for the current type. 1324 * @return the default step for the current type. 1325 */ 1326 Decimal GetDefaultStep() const; 1327 1328 enum class StepCallerType { ForUserEvent, ForScript }; 1329 1330 /** 1331 * Returns the value that this input would take if someone tries to step 1332 * aStepCount steps and this input's value would change as a result, or 1333 * Decimal::nan() otherwise (e.g., if this inputs value would not change due 1334 * to it being already at max, and asking for the next step up). 1335 * 1336 * Negative aStep means step down, positive means step up. 1337 */ 1338 Decimal GetValueIfStepped(int32_t aStepCount, StepCallerType, ErrorResult&); 1339 1340 /** 1341 * Apply a step change from stepUp or stepDown by multiplying aStep by the 1342 * current step value. 1343 * 1344 * @param aStep The value used to be multiplied against the step value. 1345 */ 1346 void ApplyStep(int32_t aStep, ErrorResult&); 1347 1348 /* 1349 * Returns if the current type is one of the date/time input types: date, 1350 * time, month, week and datetime-local. 1351 */ 1352 static bool IsDateTimeInputType(FormControlType); 1353 1354 /** 1355 * Returns whether getting `.value` as a string should sanitize the value. 1356 * 1357 * See SanitizeValue. 1358 */ 1359 bool SanitizesOnValueGetter() const; 1360 1361 /** 1362 * Returns true if the element should prevent dispatching another DOMActivate. 1363 * This is used in situations where the anonymous subtree should already have 1364 * sent a DOMActivate and prevents firing more than once. 1365 */ 1366 bool ShouldPreventDOMActivateDispatch(EventTarget* aOriginalTarget); 1367 1368 /** 1369 * Some input type (color and file) let user choose a value using a picker: 1370 * this function checks if it is needed, and if so, open the corresponding 1371 * picker (color picker or file picker). 1372 */ 1373 nsresult MaybeInitPickers(EventChainPostVisitor& aVisitor); 1374 1375 /** 1376 * Returns all valid colors in the <datalist> for the input with type=color. 1377 */ 1378 nsTArray<nsString> GetColorsFromList(); 1379 1380 enum FilePickerType { FILE_PICKER_FILE, FILE_PICKER_DIRECTORY }; 1381 nsresult InitFilePicker(FilePickerType aType); 1382 nsresult InitColorPicker(); 1383 1384 GetFilesHelper* GetOrCreateGetFilesHelper(bool aRecursiveFlag, 1385 ErrorResult& aRv); 1386 1387 void ClearGetFilesHelpers(); 1388 1389 /** 1390 * nsINode::SetMayBeApzAware() will be invoked in this function if necessary 1391 * to prevent default action of APZC so that we can increase/decrease the 1392 * value of this InputElement when mouse wheel event comes without scrolling 1393 * the page. 1394 * 1395 * SetMayBeApzAware() will set flag MayBeApzAware which is checked by apzc to 1396 * decide whether to add this element into its dispatch-to-content region. 1397 */ 1398 void UpdateApzAwareFlag(); 1399 1400 /** 1401 * A helper to get the current selection range. Will throw on the ErrorResult 1402 * if we have no editor state. 1403 */ 1404 void GetSelectionRange(uint32_t* aSelectionStart, uint32_t* aSelectionEnd, 1405 ErrorResult& aRv); 1406 1407 /** 1408 * Override for nsImageLoadingContent. 1409 */ 1410 nsIContent* AsContent() override { return this; } 1411 1412 void LoadSelectedImage(bool aAlwaysLoad, bool aStopLazyLoading) override { 1413 MOZ_ASSERT_UNREACHABLE("LoadSelectedImage not implemented"); 1414 } 1415 1416 nsCOMPtr<nsIControllers> mControllers; 1417 1418 /* 1419 * In mInputData, the mState field is used if IsSingleLineTextControl returns 1420 * true and mValue is used otherwise. We have to be careful when handling it 1421 * on a type change. 1422 * 1423 * Accessing the mState member should be done using the GetEditorState 1424 * function, which returns null if the state is not present. 1425 */ 1426 union InputData { 1427 /** 1428 * The current value of the input if it has been changed from the default 1429 */ 1430 char16_t* mValue; 1431 /** 1432 * The state of the text editor associated with the text/password input 1433 */ 1434 TextControlState* mState; 1435 } mInputData; 1436 1437 struct FileData; 1438 UniquePtr<FileData> mFileData; 1439 1440 /** 1441 * The value of the input element when first initialized and it is updated 1442 * when the element is either changed through a script, focused or dispatches 1443 * a change event. This is to ensure correct future change event firing. 1444 * NB: This is ONLY applicable where the element is a text control. ie, 1445 * where type= "date", "time", "text", "email", "search", "tel", "url" or 1446 * "password". 1447 */ 1448 nsString mFocusedValue; 1449 1450 /** 1451 * If mIsDraggingRange is true, this is the value that the input had before 1452 * the drag started. Used to reset the input to its old value if the drag is 1453 * canceled. 1454 */ 1455 Decimal mRangeThumbDragStartValue; 1456 1457 /** 1458 * Current value in the input box, in DateTimeValue dictionary format, see 1459 * HTMLInputElement.webidl for details. 1460 */ 1461 UniquePtr<DateTimeValue> mDateTimeInputBoxValue; 1462 1463 /** 1464 * The triggering principal for the src attribute. 1465 */ 1466 nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal; 1467 1468 /* 1469 * InputType object created based on input type. 1470 */ 1471 UniquePtr<InputType, InputType::DoNotDelete> mInputType; 1472 1473 static constexpr size_t INPUT_TYPE_SIZE = 1474 sizeof(Variant<TextInputType, SearchInputType, TelInputType, URLInputType, 1475 EmailInputType, PasswordInputType, NumberInputType, 1476 RangeInputType, RadioInputType, CheckboxInputType, 1477 ButtonInputType, ImageInputType, ResetInputType, 1478 SubmitInputType, DateInputType, TimeInputType, 1479 WeekInputType, MonthInputType, DateTimeLocalInputType, 1480 FileInputType, ColorInputType, HiddenInputType>); 1481 1482 // Memory allocated for mInputType, reused when type changes. 1483 char mInputTypeMem[INPUT_TYPE_SIZE]; 1484 1485 // Step scale factor values, for input types that have one. 1486 static const Decimal kStepScaleFactorDate; 1487 static const Decimal kStepScaleFactorNumberRange; 1488 static const Decimal kStepScaleFactorTime; 1489 static const Decimal kStepScaleFactorMonth; 1490 static const Decimal kStepScaleFactorWeek; 1491 1492 // Default step base value when a type do not have specific one. 1493 static const Decimal kDefaultStepBase; 1494 // Default step base value when type=week does not not have a specific one, 1495 // which is −259200000, the start of week 1970-W01. 1496 static const Decimal kDefaultStepBaseWeek; 1497 1498 // Default step used when there is no specified step. 1499 static const Decimal kDefaultStep; 1500 static const Decimal kDefaultStepTime; 1501 1502 // Float value returned by GetStep() when the step attribute is set to 'any'. 1503 static const Decimal kStepAny; 1504 1505 // Minimum year limited by HTML standard, year >= 1. 1506 static const double kMinimumYear; 1507 // Maximum year limited by ECMAScript date object range, year <= 275760. 1508 static const double kMaximumYear; 1509 // Maximum valid week is 275760-W37. 1510 static const double kMaximumWeekInMaximumYear; 1511 // Maximum valid day is 275760-09-13. 1512 static const double kMaximumDayInMaximumYear; 1513 // Maximum valid month is 275760-09. 1514 static const double kMaximumMonthInMaximumYear; 1515 // Long years in a ISO calendar have 53 weeks in them. 1516 static const double kMaximumWeekInYear; 1517 // Milliseconds in a day. 1518 static const double kMsPerDay; 1519 1520 nsContentUtils::AutocompleteAttrState mAutocompleteAttrState; 1521 nsContentUtils::AutocompleteAttrState mAutocompleteInfoState; 1522 bool mDisabledChanged : 1; 1523 // https://html.spec.whatwg.org/#concept-fe-dirty 1524 // TODO: Maybe rename to match the spec? 1525 bool mValueChanged : 1; 1526 // https://html.spec.whatwg.org/#user-interacted 1527 bool mUserInteracted : 1; 1528 bool mLastValueChangeWasInteractive : 1; 1529 bool mCheckedChanged : 1; 1530 bool mChecked : 1; 1531 bool mShouldInitChecked : 1; 1532 bool mDoneCreating : 1; 1533 bool mInInternalActivate : 1; 1534 bool mCheckedIsToggled : 1; 1535 bool mIndeterminate : 1; 1536 bool mInhibitRestoration : 1; 1537 bool mHasRange : 1; 1538 bool mIsDraggingRange : 1; 1539 bool mNumberControlSpinnerIsSpinning : 1; 1540 bool mNumberControlSpinnerSpinsUp : 1; 1541 bool mPickerRunning : 1; 1542 bool mIsPreviewEnabled : 1; 1543 bool mHasBeenTypePassword : 1; 1544 bool mHasPatternAttribute : 1; 1545 1546 private: 1547 Maybe<int32_t> GetNumberInputCols() const; 1548 static void ImageInputMapAttributesIntoRule(MappedDeclarationsBuilder&); 1549 1550 /** 1551 * Returns true if this input's type will fire a DOM "change" event when it 1552 * loses focus if its value has changed since it gained focus. 1553 */ 1554 bool MayFireChangeOnBlur() const { return MayFireChangeOnBlur(mType); } 1555 1556 /** 1557 * Returns true if selection methods can be called on element 1558 */ 1559 bool SupportsTextSelection() const { 1560 switch (mType) { 1561 case FormControlType::InputText: 1562 case FormControlType::InputSearch: 1563 case FormControlType::InputUrl: 1564 case FormControlType::InputTel: 1565 case FormControlType::InputPassword: 1566 return true; 1567 default: 1568 return false; 1569 } 1570 } 1571 1572 /** 1573 * https://html.spec.whatwg.org/#auto-directionality-form-associated-elements 1574 */ 1575 static bool IsAutoDirectionalityAssociated(FormControlType aType) { 1576 switch (aType) { 1577 case FormControlType::InputHidden: 1578 case FormControlType::InputText: 1579 case FormControlType::InputSearch: 1580 case FormControlType::InputTel: 1581 case FormControlType::InputUrl: 1582 case FormControlType::InputEmail: 1583 case FormControlType::InputPassword: 1584 case FormControlType::InputSubmit: 1585 case FormControlType::InputReset: 1586 case FormControlType::InputButton: 1587 return true; 1588 default: 1589 return false; 1590 } 1591 } 1592 1593 static bool CreatesDateTimeWidget(FormControlType aType) { 1594 return aType == FormControlType::InputDate || 1595 aType == FormControlType::InputTime || 1596 aType == FormControlType::InputDatetimeLocal; 1597 } 1598 1599 bool CreatesDateTimeWidget() const { return CreatesDateTimeWidget(mType); } 1600 1601 static bool MayFireChangeOnBlur(FormControlType aType) { 1602 return IsSingleLineTextControl(false, aType) || 1603 CreatesDateTimeWidget(aType) || 1604 aType == FormControlType::InputRange || 1605 aType == FormControlType::InputNumber; 1606 } 1607 1608 bool CheckActivationBehaviorPreconditions(EventChainVisitor& aVisitor) const; 1609 1610 /** 1611 * Call MaybeDispatchPasswordEvent or MaybeDispatchUsernameEvent 1612 * in order to dispatch LoginManager events. 1613 */ 1614 void MaybeDispatchLoginManagerEvents(HTMLFormElement* aForm); 1615 1616 /** 1617 * Fire an event when the password input field is removed from the DOM tree. 1618 * This is now only used by the password manager and formautofill. 1619 */ 1620 void MaybeFireInputPasswordRemoved(); 1621 1622 /** 1623 * Checks if aDateTimeInputType should be supported. 1624 */ 1625 static bool IsDateTimeTypeSupported(FormControlType); 1626 1627 /** 1628 * The radio group container containing the group the element is a part of. 1629 * This allows the element to only access a container it has been added to. 1630 */ 1631 RadioGroupContainer* mRadioGroupContainer; 1632 1633 struct nsFilePickerFilter { 1634 nsFilePickerFilter() : mFilterMask(0) {} 1635 1636 explicit nsFilePickerFilter(int32_t aFilterMask) 1637 : mFilterMask(aFilterMask) {} 1638 1639 nsFilePickerFilter(const nsString& aTitle, const nsString& aFilter) 1640 : mFilterMask(0), mTitle(aTitle), mFilter(aFilter) {} 1641 1642 nsFilePickerFilter(const nsFilePickerFilter& other) { 1643 mFilterMask = other.mFilterMask; 1644 mTitle = other.mTitle; 1645 mFilter = other.mFilter; 1646 } 1647 1648 bool operator==(const nsFilePickerFilter& other) const { 1649 if ((mFilter == other.mFilter) && (mFilterMask == other.mFilterMask)) { 1650 return true; 1651 } else { 1652 return false; 1653 } 1654 } 1655 1656 // Filter mask, using values defined in nsIFilePicker 1657 int32_t mFilterMask; 1658 // If mFilterMask is defined, mTitle and mFilter are useless and should be 1659 // ignored 1660 nsString mTitle; 1661 nsString mFilter; 1662 }; 1663 1664 class nsFilePickerShownCallback : public nsIFilePickerShownCallback { 1665 virtual ~nsFilePickerShownCallback() = default; 1666 1667 public: 1668 nsFilePickerShownCallback(HTMLInputElement* aInput, 1669 nsIFilePicker* aFilePicker); 1670 NS_DECL_ISUPPORTS 1671 1672 NS_IMETHOD Done(nsIFilePicker::ResultCode aResult) override; 1673 1674 private: 1675 nsCOMPtr<nsIFilePicker> mFilePicker; 1676 const RefPtr<HTMLInputElement> mInput; 1677 }; 1678 }; 1679 1680 } // namespace dom 1681 } // namespace mozilla 1682 1683 #endif