Quellcode-Bibliothek TextControlState.h
Sprache: C
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
class nsTextControlFrame; class nsISelectionController; class nsFrameSelection; class nsFrame;
namespace mozilla {
class AutoTextControlHandlingState; class ErrorResult; class IMEContentObserver; class TextEditor; class TextInputListener; class TextInputSelectionController;
namespace dom { enumclass SelectionMode : uint8_t; class Element; class HTMLInputElement;
} // namespace dom
/** * PasswordMaskData stores making information and necessary timer for * `TextEditor` instances.
*/ struct PasswordMaskData final { // Timer to mask unmasked characters automatically. Used only when it's // a password field.
nsCOMPtr<nsITimer> mTimer;
// Unmasked character range. Used only when it's a password field. // If mUnmaskedLength is 0, it means there is no unmasked characters.
uint32_t mUnmaskedStart = UINT32_MAX;
uint32_t mUnmaskedLength = 0;
// Set to true if all characters are masked or waiting notification from // `mTimer`. Otherwise, i.e., part of or all of password is unmasked // without setting `mTimer`, set to false. bool mIsMaskingPassword = true;
// Set to true if a manager of the instance wants to disable echoing // password temporarily. bool mEchoingPasswordPrevented = false;
/** * TextControlState is a class which is responsible for managing the state of * plaintext controls. This currently includes the following HTML elements: * <input type=text> * <input type=search> * <input type=url> * <input type=telephone> * <input type=email> * <input type=password> * <textarea> * * This class is held as a member of HTMLInputElement and HTMLTextAreaElement. * The public functions in this class include the public APIs which dom/ * uses. Layout code uses the TextControlElement interface to invoke * functions on this class. * * The design motivation behind this class is maintaining all of the things * which collectively are considered the "state" of the text control in a single * location. This state includes several things: * * * The control's value. This value is stored in the mValue member, and is * only used when there is no frame for the control, or when the editor object * has not been initialized yet. * * * The control's associated frame. This value is stored in the mBoundFrame * member. A text control might never have an associated frame during its life * cycle, or might have several different ones, but at any given moment in time * there is a maximum of 1 bound frame to each text control. * * * The control's associated editor. This value is stored in the mTextEditor * member. An editor is initialized for the control only when necessary (that * is, when either the user is about to interact with the text control, or when * some other code needs to access the editor object. Without a frame bound to * the control, an editor is never initialized. Once initialized, the editor * might outlive the frame, in which case the same editor will be used if a new * frame gets bound to the text control. * * * The anonymous content associated with the text control's frame, including * the value div (the DIV element responsible for holding the value of the text * control) and the placeholder div (the DIV element responsible for holding the * placeholder value of the text control.) These values are stored in the * mRootNode and mPlaceholderDiv members, respectively. They will be created * when a frame is bound to the text control. They will be destroyed when the * frame is unbound from the object. We could try and hold on to the anonymous * content between different frames, but unfortunately that is not currently * possible because they are not unbound from the document in time. * * * The frame selection controller. This value is stored in the mSelCon * member. The frame selection controller is responsible for maintaining the * selection state on a frame. It is created when a frame is bound to the text * control element, and will be destroy when the frame is being unbound from the * text control element. It is created alongside with the frame selection object * which is stored in the mFrameSel member. * * * The editor text listener. This value is stored in the mTextListener * member. Its job is to listen to selection and keyboard events, and act * accordingly. It is created when an a frame is first bound to the control, and * will be destroyed when the frame is unbound from the text control element. * * * The editor's cached value. This value is stored in the mCachedValue * member. It is used to improve the performance of append operations to the * text control. A mutation observer stored in the mMutationObserver has the * job of invalidating this cache when the anonymous contect containing the * value is changed. * * * The editor's cached selection properties. These vales are stored in the * mSelectionProperties member, and include the selection's start, end and * direction. They are only used when there is no frame available for the * text field. * * * As a general rule, TextControlState objects own the value of the text * control, and any attempt to retrieve or set the value must be made through * those objects. Internally, the value can be represented in several different * ways, based on the state the control is in. * * * When the control is first initialized, its value is equal to the default * value of the DOM node. For <input> text controls, this default value is the * value of the value attribute. For <textarea> elements, this default value is * the value of the text node children of the element. * * * If the value has been changed through the DOM node (before the editor for * the object is initialized), the value is stored as a simple string inside the * mValue member of the TextControlState object. * * * If an editor has been initialized for the control, the value is set and * retrievd via the nsIEditor interface, and is internally managed by the * editor as the native anonymous content tree attached to the control's frame. * * * If the text control state object is unbound from the control's frame, the * value is transferred to the mValue member variable, and will be managed there * until a new frame is bound to the text editor state object.
*/
class RestoreSelectionState;
class TextControlState final : public SupportsWeakPtr { public: using Element = dom::Element; using HTMLInputElement = dom::HTMLInputElement;
// Note that this does not run script actually because of `sHasShutDown` // is set to true before calling `DeleteOrCacheForReuse()`.
MOZ_CAN_RUN_SCRIPT_BOUNDARY staticvoid Shutdown();
/** * Destroy() deletes the instance immediately or later.
*/
MOZ_CAN_RUN_SCRIPT void Destroy();
/** * OnEditActionHandled() is called when mTextEditor handles something * and immediately before dispatching "input" event.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult OnEditActionHandled();
enumclass ValueSetterOption { // The call is for setting value to initial one, computed one, etc.
ByInternalAPI, // The value is changed by a call of setUserInput() API from chrome.
BySetUserInputAPI, // The value is changed by changing value attribute of the element or // something like setRangeText().
ByContentAPI, // The value is changed by setRangeText(). Intended to prevent silent // selection range change.
BySetRangeTextAPI, // Whether SetValueChanged should be called as a result of this value // change.
SetValueChanged, // Whether to move the cursor to end of the value (in the case when we have // cached selection offsets), in the case when the value has changed. If // this is not set and MoveCursorToBeginSetSelectionDirectionForward // is not set, the cached selection offsets will simply be clamped to // be within the length of the new value. In either case, if the value has // not changed the cursor won't move. // TODO(mbrodesser): update comment and enumerator identifier to reflect // that also the direction is set to forward.
MoveCursorToEndIfValueChanged,
// The value change should preserve undo history.
PreserveUndoHistory,
// Whether it should be tried to move the cursor to the beginning of the // text control and set the selection direction to "forward". // TODO(mbrodesser): As soon as "none" is supported // (https://bugzilla.mozilla.org/show_bug.cgi?id=1541454), it should be set // to "none" and only fall back to "forward" if the platform doesn't support // it.
MoveCursorToBeginSetSelectionDirectionForward,
}; using ValueSetterOptions = EnumSet<ValueSetterOption, uint32_t>;
/** * SetValue() sets the value to aValue with replacing \r\n and \r with \n. * * @param aValue The new value. Can contain \r. * @param aOldValue Optional. If you have already know current value, * set this to it. However, this must not contain \r * for the performance. * @param aOptions See ValueSetterOption.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT bool SetValue( const nsAString& aValue, const nsAString* aOldValue, const ValueSetterOptions& aOptions);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT bool SetValue( const nsAString& aValue, const ValueSetterOptions& aOptions) { return SetValue(aValue, nullptr, aOptions);
}
/** * GetValue() returns current value either with or without TextEditor. * The result never includes \r.
*/ void GetValue(nsAString& aValue, bool aIgnoreWrap, bool aForDisplay) const;
/** * ValueEquals() is designed for internal use so that aValue shouldn't * include \r character. It should be handled before calling this with * nsContentUtils::PlatformToDOMLineBreaks().
*/ bool ValueEquals(const nsAString& aValue) const; // The following methods are for textarea element to use whether default // value or not. // XXX We might have to add assertion when it is into editable, // or reconsider fixing bug 597525 to remove these. void EmptyValue() { if (!mValue.IsVoid()) {
mValue.Truncate();
}
} bool IsEmpty() const { return mValue.IsEmpty(); }
const nsAString& LastInteractiveValueIfLastChangeWasNonInteractive() const { return mLastInteractiveValue;
} // When an interactive value change happens, we clear mLastInteractiveValue // because it's not needed (mValue is the new interactive value). void ClearLastInteractiveValue() { mLastInteractiveValue.SetIsVoid(true); }
// return true only if mStart, mEnd, or mDirection have been modified, // or if SetIsDirty() was explicitly called. bool IsDirty() const { return mIsDirty; } void SetIsDirty() { mIsDirty = true; }
bool IsSelectionCached() const { return mSelectionCached; }
SelectionProperties& GetSelectionProperties() { return mSelectionProperties; }
MOZ_CAN_RUN_SCRIPT void SetSelectionProperties(SelectionProperties& aProps); bool HasNeverInitializedBefore() const { return !mEverInited; } // Sync up our selection properties with our editor prior to being destroyed. // This will invoke UnbindFromFrame() to ensure that we grab whatever // selection state may be at the moment.
MOZ_CAN_RUN_SCRIPT void SyncUpSelectionPropertiesBeforeDestruction();
// Get the selection range start and end points in our text. void GetSelectionRange(uint32_t* aSelectionStart, uint32_t* aSelectionEnd,
ErrorResult& aRv);
// Get the selection direction
SelectionDirection GetSelectionDirection(ErrorResult& aRv);
enumclass ScrollAfterSelection { No, Yes };
// Set the selection range (start, end, direction). aEnd is allowed to be // smaller than aStart; in that case aStart will be reset to the same value as // aEnd. This basically implements // https://html.spec.whatwg.org/multipage/forms.html#set-the-selection-range // but with the start/end already coerced to zero if null (and without the // special infinity value), and the direction already converted to a // SelectionDirection. // // If we have a frame, this method will scroll the selection into view.
MOZ_CAN_RUN_SCRIPT void SetSelectionRange(
uint32_t aStart, uint32_t aEnd, SelectionDirection aDirection,
ErrorResult& aRv,
ScrollAfterSelection aScroll = ScrollAfterSelection::Yes);
// Set the selection range, but with an optional string for the direction. // This will convert aDirection to an nsITextControlFrame::SelectionDirection // and then call our other SetSelectionRange overload.
MOZ_CAN_RUN_SCRIPT void SetSelectionRange(
uint32_t aSelectionStart, uint32_t aSelectionEnd, const dom::Optional<nsAString>& aDirection, ErrorResult& aRv,
ScrollAfterSelection aScroll = ScrollAfterSelection::Yes);
// Set the range text. This basically implements // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea/input-setrangetext
MOZ_CAN_RUN_SCRIPT void SetRangeText(const nsAString& aReplacement,
ErrorResult& aRv); // The last two arguments are -1 if we don't know our selection range; // otherwise they're the start and end of our selection range.
MOZ_CAN_RUN_SCRIPT void SetRangeText( const nsAString& aReplacement, uint32_t aStart, uint32_t aEnd,
dom::SelectionMode aSelectMode, ErrorResult& aRv, const Maybe<uint32_t>& aSelectionStart = Nothing(), const Maybe<uint32_t>& aSelectionEnd = Nothing());
/** * SetValueWithTextEditor() modifies the editor value with mTextEditor. * This may cause destroying mTextEditor, mBoundFrame, the TextControlState * itself. Must be called when both mTextEditor and mBoundFrame are not * nullptr. * * @param aHandlingSetValue Must be inner-most handling state for SetValue. * @return false if fallible allocation failed. Otherwise, * true.
*/
MOZ_CAN_RUN_SCRIPT bool SetValueWithTextEditor(
AutoTextControlHandlingState& aHandlingSetValue);
/** * SetValueWithoutTextEditor() modifies the value without editor. I.e., * modifying the value in this instance and mBoundFrame. Must be called * when at least mTextEditor or mBoundFrame is nullptr. * * @param aHandlingSetValue Must be inner-most handling state for SetValue. * @return false if fallible allocation failed. Otherwise, * true.
*/
MOZ_CAN_RUN_SCRIPT bool SetValueWithoutTextEditor(
AutoTextControlHandlingState& aHandlingSetValue);
// When this class handles something which may run script, this should be // set to non-nullptr. If so, this class claims that it's busy and that // prevents destroying TextControlState instance.
AutoTextControlHandlingState* mHandlingState = nullptr;
// The text control element owns this object, and ensures that this object // has a smaller lifetime except the owner releases the instance while it // does something with this.
TextControlElement* MOZ_NON_OWNING_REF mTextCtrlElement;
RefPtr<TextInputSelectionController> mSelCon;
RefPtr<RestoreSelectionState> mRestoringSelection;
RefPtr<TextEditor> mTextEditor;
nsTextControlFrame* mBoundFrame = nullptr;
RefPtr<TextInputListener> mTextListener;
UniquePtr<PasswordMaskData> mPasswordMaskData;
nsString mValue{VoidString()}; // Void if there's no value.
// If our input's last value change was not interactive (as in, the value // change was caused by a ValueChangeKind::UserInteraction), this is the value // that the last interaction had.
nsString mLastInteractiveValue{VoidString()};
SelectionProperties mSelectionProperties;
bool mEverInited : 1; // Have we ever been initialized? bool mEditorInitialized : 1; bool mValueTransferInProgress : 1; // Whether a value is being transferred to // the frame bool mSelectionCached : 1; // Whether mSelectionProperties is valid
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.3Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.