/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=2 et tw=80: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Pierre Phaneuf * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsIDOMHTMLTextAreaElement.h" #include "nsIDOMNSHTMLTextAreaElement.h" #include "nsITextControlElement.h" #include "nsIDOMNSEditableElement.h" #include "nsIControllers.h" #include "nsContentCID.h" #include "nsCOMPtr.h" #include "nsIComponentManager.h" #include "nsIDOMHTMLFormElement.h" #include "nsIFormControl.h" #include "nsIForm.h" #include "nsIFormSubmission.h" #include "nsIDOMEventReceiver.h" #include "nsGenericHTMLElement.h" #include "nsHTMLAtoms.h" #include "nsStyleConsts.h" #include "nsPresContext.h" #include "nsMappedAttributes.h" #include "nsIFormControlFrame.h" #include "nsITextControlFrame.h" #include "nsIEventStateManager.h" #include "nsLinebreakConverter.h" #include "nsIDocument.h" #include "nsIPresShell.h" #include "nsIFrame.h" #include "nsIFormControlFrame.h" #include "nsIPrivateDOMEvent.h" #include "nsGUIEvent.h" #include "nsLinebreakConverter.h" #include "nsPresState.h" #include "nsIDOMText.h" #include "nsReadableUtils.h" #include "nsITextContent.h" static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID); class nsHTMLTextAreaElement : public nsGenericHTMLFormElement, public nsIDOMHTMLTextAreaElement, public nsIDOMNSHTMLTextAreaElement, public nsITextControlElement, public nsIDOMNSEditableElement { public: nsHTMLTextAreaElement(nsINodeInfo *aNodeInfo, PRBool aFromParser = PR_FALSE); virtual ~nsHTMLTextAreaElement(); // nsISupports NS_DECL_ISUPPORTS_INHERITED // nsIDOMNode NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLFormElement::) // nsIDOMElement NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::) // nsIDOMHTMLElement NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::) // nsIDOMHTMLTextAreaElement NS_DECL_NSIDOMHTMLTEXTAREAELEMENT // nsIDOMNSHTMLTextAreaElement NS_DECL_NSIDOMNSHTMLTEXTAREAELEMENT // nsIDOMNSEditableElement NS_FORWARD_NSIDOMNSEDITABLEELEMENT(nsGenericHTMLElement::) // nsIFormControl NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_TEXTAREA; } NS_IMETHOD Reset(); NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission, nsIContent* aSubmitElement); NS_IMETHOD SaveState(); virtual PRBool RestoreState(nsPresState* aState); // nsITextControlElemet NS_IMETHOD TakeTextFrameValue(const nsAString& aValue); NS_IMETHOD SetValueChanged(PRBool aValueChanged); // nsIContent virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex, PRBool aNotify); virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify); virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify); virtual PRBool ParseAttribute(nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult); virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, PRInt32 aModType) const; NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const; virtual nsresult HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags, nsEventStatus* aEventStatus); virtual void SetFocus(nsPresContext* aPresContext); virtual void DoneAddingChildren(PRBool aHaveNotified); virtual PRBool IsDoneAddingChildren(); protected: nsCOMPtr mControllers; /** The current value. This is null if the frame owns the value. */ char* mValue; /** Whether or not the value has changed since its default value was given. */ PRPackedBool mValueChanged; /** Whether or not we are already handling select event. */ PRPackedBool mHandlingSelect; /** Whether or not we are done adding children (always PR_TRUE if not created by a parser */ PRPackedBool mDoneAddingChildren; NS_IMETHOD SelectAll(nsPresContext* aPresContext); /** * Get the value, whether it is from the content or the frame. * @param aValue the value [out] * @param aIgnoreWrap whether to ignore the wrap attribute when getting the * value. If this is true, linebreaks will not be inserted even if * wrap=hard. */ void GetValueInternal(nsAString& aValue, PRBool aIgnoreWrap); nsresult SetValueInternal(const nsAString& aValue, nsITextControlFrame* aFrame); nsresult GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd); }; NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(TextArea) nsHTMLTextAreaElement::nsHTMLTextAreaElement(nsINodeInfo *aNodeInfo, PRBool aFromParser) : nsGenericHTMLFormElement(aNodeInfo), mValue(nsnull), mValueChanged(PR_FALSE), mHandlingSelect(PR_FALSE), mDoneAddingChildren(!aFromParser) { } nsHTMLTextAreaElement::~nsHTMLTextAreaElement() { if (mValue) { nsMemory::Free(mValue); } } NS_IMPL_ADDREF_INHERITED(nsHTMLTextAreaElement, nsGenericElement) NS_IMPL_RELEASE_INHERITED(nsHTMLTextAreaElement, nsGenericElement) // QueryInterface implementation for nsHTMLTextAreaElement NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLTextAreaElement, nsGenericHTMLFormElement) NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLTextAreaElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLTextAreaElement) NS_INTERFACE_MAP_ENTRY(nsITextControlElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSEditableElement) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLTextAreaElement) NS_HTML_CONTENT_INTERFACE_MAP_END // nsIDOMHTMLTextAreaElement NS_IMPL_DOM_CLONENODE(nsHTMLTextAreaElement) NS_IMETHODIMP nsHTMLTextAreaElement::GetForm(nsIDOMHTMLFormElement** aForm) { return nsGenericHTMLFormElement::GetForm(aForm); } // nsIContent NS_IMETHODIMP nsHTMLTextAreaElement::Blur() { if (ShouldFocus(this)) { SetElementFocus(PR_FALSE); } return NS_OK; } NS_IMETHODIMP nsHTMLTextAreaElement::Focus() { if (ShouldFocus(this)) { SetElementFocus(PR_TRUE); } return NS_OK; } void nsHTMLTextAreaElement::SetFocus(nsPresContext* aPresContext) { if (!aPresContext) return; // first see if we are disabled or not. If disabled then do nothing. if (HasAttr(kNameSpaceID_None, nsHTMLAtoms::disabled)) { return; } nsIEventStateManager *esm = aPresContext->EventStateManager(); if (esm->SetContentState(this, NS_EVENT_STATE_FOCUS)) { nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); if (formControlFrame) { formControlFrame->SetFocus(PR_TRUE, PR_TRUE); formControlFrame->ScrollIntoView(aPresContext); } } } NS_IMETHODIMP nsHTMLTextAreaElement::Select() { nsresult rv = NS_OK; // first see if we are disabled or not. If disabled then do nothing. if (HasAttr(kNameSpaceID_None, nsHTMLAtoms::disabled)) { return rv; } // XXX Bug? We have to give the input focus before contents can be // selected // Just like SetFocus() but without the ScrollIntoView()! nsCOMPtr presContext = GetPresContext(); nsEventStatus status = nsEventStatus_eIgnore; nsGUIEvent event(PR_TRUE, NS_FORM_SELECTED, nsnull); rv = HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); // If the DOM event was not canceled (e.g. by a JS event handler // returning false) if (status == nsEventStatus_eIgnore) { PRBool shouldFocus = ShouldFocus(this); if (shouldFocus && !presContext->EventStateManager()->SetContentState(this, NS_EVENT_STATE_FOCUS)) { return rv; // We ended up unfocused, e.g. due to a DOM event handler. } nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); if (formControlFrame) { if (shouldFocus) { formControlFrame->SetFocus(PR_TRUE, PR_TRUE); } // Now Select all the text! SelectAll(presContext); } } return rv; } NS_IMETHODIMP nsHTMLTextAreaElement::SelectAll(nsPresContext* aPresContext) { nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); if (formControlFrame) { formControlFrame->SetProperty(aPresContext, nsHTMLAtoms::select, EmptyString()); } return NS_OK; } NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, AccessKey, accesskey) NS_IMPL_INT_ATTR(nsHTMLTextAreaElement, Cols, cols) NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, Disabled, disabled) NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, Name, name) NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, ReadOnly, readonly) NS_IMPL_INT_ATTR(nsHTMLTextAreaElement, Rows, rows) NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTextAreaElement, TabIndex, tabindex, 0) NS_IMETHODIMP nsHTMLTextAreaElement::GetType(nsAString& aType) { aType.AssignLiteral("textarea"); return NS_OK; } NS_IMETHODIMP nsHTMLTextAreaElement::GetValue(nsAString& aValue) { GetValueInternal(aValue, PR_TRUE); return NS_OK; } void nsHTMLTextAreaElement::GetValueInternal(nsAString& aValue, PRBool aIgnoreWrap) { // Get the frame. // No need to flush here, if there is no frame yet for this textarea // there won't be a value in it we don't already have even if we // force the frame to be created. nsIFrame* primaryFrame = GetPrimaryFrame(PR_FALSE); nsITextControlFrame* textControlFrame = nsnull; if (primaryFrame) { CallQueryInterface(primaryFrame, &textControlFrame); } // If the frame exists and owns the value, get it from the frame. Otherwise // get it from content. PRBool frameOwnsValue = PR_FALSE; if (textControlFrame) { textControlFrame->OwnsValue(&frameOwnsValue); } if (frameOwnsValue) { textControlFrame->GetValue(aValue, aIgnoreWrap); } else { if (!mValueChanged || !mValue) { GetDefaultValue(aValue); } else { CopyUTF8toUTF16(mValue, aValue); } } } NS_IMETHODIMP nsHTMLTextAreaElement::TakeTextFrameValue(const nsAString& aValue) { if (mValue) { nsMemory::Free(mValue); } mValue = ToNewUTF8String(aValue); SetValueChanged(PR_TRUE); return NS_OK; } nsresult nsHTMLTextAreaElement::SetValueInternal(const nsAString& aValue, nsITextControlFrame* aFrame) { nsITextControlFrame* textControlFrame = aFrame; nsIFormControlFrame* formControlFrame = textControlFrame; if (!textControlFrame) { // No need to flush here, if there is no frame for this yet forcing // creation of one will not do us any good formControlFrame = GetFormControlFrame(PR_FALSE); if (formControlFrame) { CallQueryInterface(formControlFrame, &textControlFrame); } } PRBool frameOwnsValue = PR_FALSE; if (textControlFrame) { textControlFrame->OwnsValue(&frameOwnsValue); } if (frameOwnsValue) { formControlFrame->SetProperty(GetPresContext(), nsHTMLAtoms::value, aValue); } else { if (mValue) { nsMemory::Free(mValue); } mValue = ToNewUTF8String(aValue); NS_ENSURE_TRUE(mValue, NS_ERROR_OUT_OF_MEMORY); SetValueChanged(PR_TRUE); } return NS_OK; } NS_IMETHODIMP nsHTMLTextAreaElement::SetValue(const nsAString& aValue) { return SetValueInternal(aValue, nsnull); } NS_IMETHODIMP nsHTMLTextAreaElement::SetValueChanged(PRBool aValueChanged) { mValueChanged = aValueChanged; if (!aValueChanged && mValue) { nsMemory::Free(mValue); mValue = nsnull; } return NS_OK; } NS_IMETHODIMP nsHTMLTextAreaElement::GetDefaultValue(nsAString& aDefaultValue) { GetContentsAsText(aDefaultValue); return NS_OK; } NS_IMETHODIMP nsHTMLTextAreaElement::SetDefaultValue(const nsAString& aDefaultValue) { nsresult rv = ReplaceContentsWithText(aDefaultValue, PR_TRUE); if (NS_SUCCEEDED(rv) && !mValueChanged) { Reset(); } return rv; } nsresult nsHTMLTextAreaElement::InsertChildAt(nsIContent* aKid, PRUint32 aIndex, PRBool aNotify) { nsresult rv; rv = nsGenericHTMLFormElement::InsertChildAt(aKid, aIndex, aNotify); if (!mValueChanged && mDoneAddingChildren) { Reset(); } return rv; } nsresult nsHTMLTextAreaElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) { nsresult rv; rv = nsGenericHTMLFormElement::AppendChildTo(aKid, aNotify); if (!mValueChanged && mDoneAddingChildren) { Reset(); } return rv; } nsresult nsHTMLTextAreaElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify) { nsresult rv; rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify); if (!mValueChanged) { NS_ASSERTION(mDoneAddingChildren, "The HTML content sink shouldn't call this"); Reset(); } return rv; } PRBool nsHTMLTextAreaElement::ParseAttribute(nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult) { if (aAttribute == nsHTMLAtoms::cols) { return aResult.ParseIntWithBounds(aValue, 0); } if (aAttribute == nsHTMLAtoms::rows) { return aResult.ParseIntWithBounds(aValue, 0); } return nsGenericHTMLElement::ParseAttribute(aAttribute, aValue, aResult); } static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes, nsRuleData* aData) { nsGenericHTMLFormElement::MapDivAlignAttributeInto(aAttributes, aData); nsGenericHTMLFormElement::MapCommonAttributesInto(aAttributes, aData); } nsChangeHint nsHTMLTextAreaElement::GetAttributeChangeHint(const nsIAtom* aAttribute, PRInt32 aModType) const { nsChangeHint retval = nsGenericHTMLFormElement::GetAttributeChangeHint(aAttribute, aModType); if (aAttribute == nsHTMLAtoms::rows || aAttribute == nsHTMLAtoms::cols) { NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW); } return retval; } NS_IMETHODIMP_(PRBool) nsHTMLTextAreaElement::IsAttributeMapped(const nsIAtom* aAttribute) const { static const MappedAttributeEntry* const map[] = { sDivAlignAttributeMap, sCommonAttributeMap, }; return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map)); } nsMapRuleToAttributesFunc nsHTMLTextAreaElement::GetAttributeMappingFunction() const { return &MapAttributesIntoRule; } nsresult nsHTMLTextAreaElement::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags, nsEventStatus* aEventStatus) { // Do not process any DOM events if the element is disabled PRBool disabled; nsresult rv = GetDisabled(&disabled); if (NS_FAILED(rv) || disabled) { return rv; } nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE); nsIFrame* formFrame = nsnull; if (formControlFrame && NS_SUCCEEDED(CallQueryInterface(formControlFrame, &formFrame)) && formFrame) { const nsStyleUserInterface* uiStyle = formFrame->GetStyleUserInterface(); if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE || uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED) { return NS_OK; } } PRBool isSelectEvent = (aEvent->message == NS_FORM_SELECTED); // Don't dispatch a second select event if we are already handling // one. if (isSelectEvent && mHandlingSelect) { return NS_OK; } // If NS_EVENT_FLAG_NO_CONTENT_DISPATCH is set we will not allow content to handle // this event. But to allow middle mouse button paste to work we must allow // middle clicks to go to text fields anyway. PRBool noContentDispatch = aEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH; if (aEvent->message == NS_MOUSE_MIDDLE_CLICK) { aEvent->flags &= ~NS_EVENT_FLAG_NO_CONTENT_DISPATCH; } if (isSelectEvent) { mHandlingSelect = PR_TRUE; } rv = nsGenericHTMLFormElement::HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); if (isSelectEvent) { mHandlingSelect = PR_FALSE; } // Reset the flag for other content besides this text field aEvent->flags |= noContentDispatch ? NS_EVENT_FLAG_NO_CONTENT_DISPATCH : NS_EVENT_FLAG_NONE; return rv; } void nsHTMLTextAreaElement::DoneAddingChildren(PRBool 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(); } RestoreFormControlState(this, this); } mDoneAddingChildren = PR_TRUE; } PRBool nsHTMLTextAreaElement::IsDoneAddingChildren() { return mDoneAddingChildren; } // Controllers Methods NS_IMETHODIMP nsHTMLTextAreaElement::GetControllers(nsIControllers** aResult) { NS_ENSURE_ARG_POINTER(aResult); if (!mControllers) { nsresult rv; mControllers = do_CreateInstance(kXULControllersCID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr controller = do_CreateInstance("@mozilla.org/editor/editorcontroller;1", &rv); if (NS_FAILED(rv)) return rv; mControllers->AppendController(controller); } *aResult = mControllers; NS_IF_ADDREF(*aResult); return NS_OK; } NS_IMETHODIMP nsHTMLTextAreaElement::GetTextLength(PRInt32 *aTextLength) { NS_ENSURE_ARG_POINTER(aTextLength); nsAutoString val; nsresult rv = GetValue(val); *aTextLength = val.Length(); return rv; } NS_IMETHODIMP nsHTMLTextAreaElement::GetSelectionStart(PRInt32 *aSelectionStart) { NS_ENSURE_ARG_POINTER(aSelectionStart); PRInt32 selEnd; return GetSelectionRange(aSelectionStart, &selEnd); } NS_IMETHODIMP nsHTMLTextAreaElement::SetSelectionStart(PRInt32 aSelectionStart) { nsresult rv = NS_ERROR_FAILURE; nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); if (formControlFrame){ nsITextControlFrame* textControlFrame = nsnull; CallQueryInterface(formControlFrame, &textControlFrame); if (textControlFrame) rv = textControlFrame->SetSelectionStart(aSelectionStart); } return rv; } NS_IMETHODIMP nsHTMLTextAreaElement::GetSelectionEnd(PRInt32 *aSelectionEnd) { NS_ENSURE_ARG_POINTER(aSelectionEnd); PRInt32 selStart; return GetSelectionRange(&selStart, aSelectionEnd); } NS_IMETHODIMP nsHTMLTextAreaElement::SetSelectionEnd(PRInt32 aSelectionEnd) { nsresult rv = NS_ERROR_FAILURE; nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); if (formControlFrame) { nsITextControlFrame* textControlFrame = nsnull; CallQueryInterface(formControlFrame, &textControlFrame); if (textControlFrame) rv = textControlFrame->SetSelectionEnd(aSelectionEnd); } return rv; } nsresult nsHTMLTextAreaElement::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd) { nsresult rv = NS_ERROR_FAILURE; nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); if (formControlFrame) { nsITextControlFrame* textControlFrame = nsnull; CallQueryInterface(formControlFrame, &textControlFrame); if (textControlFrame) rv = textControlFrame->GetSelectionRange(aSelectionStart, aSelectionEnd); } return rv; } NS_IMETHODIMP nsHTMLTextAreaElement::SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelectionEnd) { nsresult rv = NS_ERROR_FAILURE; nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE); if (formControlFrame) { nsITextControlFrame* textControlFrame = nsnull; CallQueryInterface(formControlFrame, &textControlFrame); if (textControlFrame) rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd); } return rv; } nsresult nsHTMLTextAreaElement::Reset() { nsresult rv; // If the frame is there, we have to set the value so that it will show up. nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE); if (formControlFrame) { nsAutoString resetVal; GetDefaultValue(resetVal); rv = SetValue(resetVal); NS_ENSURE_SUCCESS(rv, rv); formControlFrame->OnContentReset(); } SetValueChanged(PR_FALSE); return NS_OK; } NS_IMETHODIMP nsHTMLTextAreaElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission, nsIContent* aSubmitElement) { nsresult rv = NS_OK; // // Disabled elements don't submit // PRBool disabled; rv = GetDisabled(&disabled); if (NS_FAILED(rv) || disabled) { return rv; } // // Get the name (if no name, no submit) // nsAutoString name; if (!GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, name)) { return NS_OK; } // // Get the value // nsAutoString value; GetValueInternal(value, PR_FALSE); // // Submit // rv = aFormSubmission->AddNameValuePair(this, name, value); return rv; } NS_IMETHODIMP nsHTMLTextAreaElement::SaveState() { nsresult rv = NS_OK; // Only save if value != defaultValue (bug 62713) if (mValueChanged) { nsPresState *state = nsnull; rv = GetPrimaryPresState(this, &state); if (state) { nsAutoString value; GetValueInternal(value, PR_TRUE); rv = nsLinebreakConverter::ConvertStringLineBreaks( value, nsLinebreakConverter::eLinebreakPlatform, nsLinebreakConverter::eLinebreakContent); NS_ASSERTION(NS_SUCCEEDED(rv), "Converting linebreaks failed!"); rv = state->SetStateProperty(NS_LITERAL_STRING("value"), value); NS_ASSERTION(NS_SUCCEEDED(rv), "value save failed!"); } } return rv; } PRBool nsHTMLTextAreaElement::RestoreState(nsPresState* aState) { nsAutoString value; #ifdef DEBUG nsresult rv = #endif aState->GetStateProperty(NS_LITERAL_STRING("value"), value); NS_ASSERTION(NS_SUCCEEDED(rv), "value restore failed!"); SetValue(value); return PR_FALSE; }