/* -*- 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/. */
// Set up our default state. By default we're enabled (since we're // a control type that can be disabled but not actually disabled right now), // optional, read-write, and valid. Also by default we don't have to show // validity UI and so forth.
AddStatesSilently(ElementState::ENABLED | ElementState::OPTIONAL_ |
ElementState::READWRITE | ElementState::VALID |
ElementState::VALUE_EMPTY);
RemoveStatesSilently(ElementState::READONLY);
}
void HTMLTextAreaElement::SelectAll() { // FIXME(emilio): Should we try to call Select(), which will avoid flushing? if (nsTextControlFrame* tf =
do_QueryFrame(GetPrimaryFrame(FlushType::Frames))) {
tf->SelectAll();
}
}
// Need to set the value changed flag here if our value has in fact changed // (i.e. if ValueSetterOption::SetValueChanged is in aOptions), so that // retrieves the correct value if needed. if (aOptions.contains(ValueSetterOption::SetValueChanged)) {
SetValueChanged(true);
}
if (!mState->SetValue(aValue, aOptions)) { return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
void HTMLTextAreaElement::SetValue(const nsAString& aValue,
ErrorResult& aError) { // If the value has been set by a script, we basically want to keep the // current change event state. If the element is ready to fire a change // event, we should keep it that way. Otherwise, we should make sure the // element will not fire any event because of the script interaction. // // NOTE: this is currently quite expensive work (too much string // manipulation). We should probably optimize that.
nsAutoString currentValue;
GetValueInternal(currentValue, true);
void HTMLTextAreaElement::SetDefaultValue(const nsAString& aDefaultValue,
ErrorResult& aError) { // setting the value of an textarea element using `.defaultValue = "foo"` // must be interpreted as a two-step operation: // 1. clearing all child nodes // 2. adding a new text node with the new content // Step 1 must therefore collapse the Selection to 0. // Calling `SetNodeTextContent()` with an empty string will do that for us.
nsContentUtils::SetNodeTextContent(this, EmptyString(), true);
nsresult rv = nsContentUtils::SetNodeTextContent(this, aDefaultValue, true); if (NS_SUCCEEDED(rv) && !mValueChanged) {
Reset();
} if (NS_FAILED(rv)) {
aError.Throw(rv);
}
}
// Don't dispatch a second select event if we are already handling // one. if (aVisitor.mEvent->mMessage == eFormSelect) { if (mHandlingSelect) { return;
}
mHandlingSelect = true;
}
if (aVisitor.mEvent->mMessage == eBlur) { // Set mWantsPreHandleEvent and fire change event in PreHandleEvent to // prevent it breaks event target chain creation.
aVisitor.mWantsPreHandleEvent = true;
}
nsresult HTMLTextAreaElement::PreHandleEvent(EventChainVisitor& aVisitor) { if (aVisitor.mEvent->mMessage == eBlur) { // Fire onchange (if necessary), before we do the blur, bug 370521.
FireChangeEventIfNeeded();
} return nsGenericHTMLFormControlElementWithState::PreHandleEvent(aVisitor);
}
void HTMLTextAreaElement::DoneAddingChildren(bool aHaveNotified) { if (!mValueChanged) { if (!mDoneAddingChildren) { // Reset now that we're done adding children if the content sink tried to // sneak some text in without calling AppendChildTo.
Reset();
}
if (!mInhibitStateRestoration) {
GenerateStateKey();
RestoreFormControlState();
}
}
mDoneAddingChildren = true;
}
// Controllers Methods
nsIControllers* HTMLTextAreaElement::GetControllers(ErrorResult& aError) { if (!mControllers) {
mControllers = new nsXULControllers(); if (!mControllers) {
aError.Throw(NS_ERROR_FAILURE); return nullptr;
}
NS_IMETHODIMP
HTMLTextAreaElement::SubmitNamesValues(FormData* aFormData) { // // Get the name (if no name, no submit) //
nsAutoString name;
GetAttr(nsGkAtoms::name, name); if (name.IsEmpty()) { return NS_OK;
}
// // Get the value //
nsAutoString value;
GetValueInternal(value, false);
void HTMLTextAreaElement::SaveState() { // Only save if value != defaultValue (bug 62713)
PresState* state = nullptr; if (mValueChanged) {
state = GetPrimaryPresState(); if (state) {
nsAutoString value;
GetValueInternal(value, true);
if (mDisabledChanged) { if (!state) {
state = GetPrimaryPresState();
} if (state) { // We do not want to save the real disabled state but the disabled // attribute.
state->disabled() = HasAttr(nsGkAtoms::disabled);
state->disabledSet() = true;
}
}
}
bool HTMLTextAreaElement::RestoreState(PresState* aState) { const PresContentData& state = aState->contentData();
if (state.type() == PresContentData::TTextContentData) {
ErrorResult rv;
SetValue(state.get_TextContentData().value(), rv); if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException(); returnfalse;
} if (state.get_TextContentData().lastValueChangeWasInteractive()) {
SetLastValueChangeWasInteractive(true);
}
} if (aState->disabledSet() && !aState->disabled()) {
SetDisabled(false, IgnoreErrors());
}
returnfalse;
}
void HTMLTextAreaElement::UpdateValidityElementStates(bool aNotify) {
AutoStateChangeNotifier notifier(*this, aNotify);
RemoveStatesSilently(ElementState::VALIDITY_STATES); if (!IsCandidateForConstraintValidation()) { return;
}
ElementState state; if (IsValid()) {
state |= ElementState::VALID; if (mUserInteracted) {
state |= ElementState::USER_VALID;
}
} else {
state |= ElementState::INVALID; if (mUserInteracted) {
state |= ElementState::USER_INVALID;
}
}
AddStatesSilently(state);
}
// Set direction based on value if dir=auto
ResetDirFormAssociatedElement(this, false, HasDirAuto());
// If there is a disabled fieldset in the parent chain, the element is now // barred from constraint validation and can't suffer from value missing.
UpdateValueMissingValidityState();
UpdateBarredFromConstraintValidation();
// And now make sure our state is up to date
UpdateValidityElementStates(false);
void HTMLTextAreaElement::ContentWillBeRemoved(
nsIContent* aChild, const BatchRemovalState* aState) { if (mValueChanged || !mDoneAddingChildren || (aState && !aState->mIsFirst) ||
!nsContentUtils::IsInSameAnonymousTree(this, aChild)) { return;
} if (mState->IsSelectionCached()) { // Collapse the selection when removing nodes if necessary, see bug 1818686. auto& props = mState->GetSelectionProperties();
props.CollapseToStart();
}
nsContentUtils::AddScriptRunner(
NewRunnableMethod("HTMLTextAreaElement::ResetIfUnchanged", this,
&HTMLTextAreaElement::ResetIfUnchanged));
}
void HTMLTextAreaElement::ContentChanged(nsIContent* aContent) { if (mValueChanged || !mDoneAddingChildren ||
!nsContentUtils::IsInSameAnonymousTree(this, aContent)) { return;
} // We should wait all ranges finish handling the mutation before updating // the anonymous subtree with a call of Reset.
nsContentUtils::AddScriptRunner(
NewRunnableMethod("HTMLTextAreaElement::ResetIfUnchanged", this,
&HTMLTextAreaElement::ResetIfUnchanged));
}
void HTMLTextAreaElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAttrValue* aValue, const nsAttrValue* aOldValue,
nsIPrincipal* aSubjectPrincipal, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled ||
aName == nsGkAtoms::readonly) { if (aName == nsGkAtoms::disabled) { // This *has* to be called *before* validity state check because // UpdateBarredFromConstraintValidation and // UpdateValueMissingValidityState depend on our disabled state.
UpdateDisabledState(aNotify);
}
if (aName == nsGkAtoms::required) { // This *has* to be called *before* UpdateValueMissingValidityState // because UpdateValueMissingValidityState depends on our required // state.
UpdateRequiredState(!!aValue, aNotify);
}
// SetValueInternal handles setting mValueChanged for us. dest is a fresh // element so setting its value can't really run script. if (NS_WARN_IF(
NS_FAILED(rv = MOZ_KnownLive(dest)->SetValueInternal(
value, {ValueSetterOption::SetValueChanged})))) { return rv;
}
}
void HTMLTextAreaElement::FieldSetDisabledChanged(bool aNotify) { // This *has* to be called before UpdateBarredFromConstraintValidation and // UpdateValueMissingValidityState because these two functions depend on our // disabled state.
nsGenericHTMLFormControlElementWithState::FieldSetDisabledChanged(aNotify);
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.