Back to index

lightning-sunbird  0.9+nobinonly
nsIsIndexFrame.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsIsIndexFrame.h"
00039 
00040 #include "nsIContent.h"
00041 #include "prtypes.h"
00042 #include "nsIAtom.h"
00043 #include "nsPresContext.h"
00044 #include "nsHTMLAtoms.h"
00045 #include "nsPresState.h"
00046 #include "nsWidgetsCID.h"
00047 #include "nsIComponentManager.h"
00048 #include "nsIView.h"
00049 #include "nsHTMLParts.h"
00050 #include "nsIDOMHTMLInputElement.h"
00051 #include "nsINameSpaceManager.h"
00052 #include "nsCOMPtr.h"
00053 #include "nsISupportsArray.h"
00054 #include "nsIDOMElement.h"
00055 #include "nsIDOMDocument.h"
00056 #include "nsIDocument.h"
00057 #include "nsIPresShell.h"
00058 #include "nsIDOMHTMLInputElement.h"
00059 #include "nsIStatefulFrame.h"
00060 #include "nsXPCOM.h"
00061 #include "nsISupportsPrimitives.h"
00062 #include "nsIComponentManager.h"
00063 #include "nsITextContent.h"
00064 #include "nsHTMLParts.h"
00065 #include "nsLinebreakConverter.h"
00066 #include "nsILinkHandler.h"
00067 #include "nsIHTMLDocument.h"
00068 #include "nsXPIDLString.h"
00069 #include "nsReadableUtils.h"
00070 #include "nsNetUtil.h"
00071 #include "nsICharsetConverterManager.h"
00072 #include "nsEscape.h"
00073 #include "nsIDOMKeyListener.h"
00074 #include "nsIDOMKeyEvent.h"
00075 #include "nsIFormControlFrame.h"
00076 #include "nsINodeInfo.h"
00077 #include "nsIDOMEventReceiver.h"
00078 #include "nsContentCID.h"
00079 #include "nsNodeInfoManager.h"
00080 #include "nsContentCreatorFunctions.h"
00081 #include "nsContentUtils.h"
00082 
00083 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
00084 
00085 nsresult
00086 NS_NewIsIndexFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
00087 {
00088   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00089   if (nsnull == aNewFrame) {
00090     return NS_ERROR_NULL_POINTER;
00091   }
00092   nsIsIndexFrame* it = new (aPresShell) nsIsIndexFrame();
00093   if (!it) {
00094     return NS_ERROR_OUT_OF_MEMORY;
00095   }
00096   *aNewFrame = it;
00097   return NS_OK;
00098 }
00099 
00100 nsIsIndexFrame::nsIsIndexFrame()
00101 {
00102     //Shrink the area around it's contents
00103   SetFlags(NS_BLOCK_SHRINK_WRAP | NS_BLOCK_SPACE_MGR);
00104 }
00105 
00106 nsIsIndexFrame::~nsIsIndexFrame()
00107 {
00108   // remove ourself as a listener of the text control (bug 40533)
00109   if (mInputContent) {
00110     nsCOMPtr<nsIDOMEventReceiver> reciever(do_QueryInterface(mInputContent));
00111     reciever->RemoveEventListenerByIID(this, NS_GET_IID(nsIDOMKeyListener));
00112   }
00113 }
00114 
00115 NS_IMETHODIMP
00116 nsIsIndexFrame::Paint(nsPresContext*      aPresContext,
00117                       nsIRenderingContext& aRenderingContext,
00118                       const nsRect&        aDirtyRect,
00119                       nsFramePaintLayer    aWhichLayer,
00120                       PRUint32             aFlags)
00121 {
00122   PRBool isVisible;
00123   if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
00124     return NS_OK;
00125   }
00126   return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
00127 }
00128 
00129 NS_IMETHODIMP
00130 nsIsIndexFrame::UpdatePromptLabel()
00131 {
00132   if (!mTextContent) return NS_ERROR_UNEXPECTED;
00133 
00134   nsresult result = NS_OK;
00135 
00136   // Get the text from the "prompt" attribute.
00137   // If it is zero length, set it to a default value (localized)
00138   nsXPIDLString prompt;
00139   if (mContent)
00140     mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::prompt, prompt);
00141 
00142   if (prompt.IsEmpty()) {
00143     // Generate localized label.
00144     // We can't make any assumption as to what the default would be
00145     // because the value is localized for non-english platforms, thus
00146     // it might not be the string "This is a searchable index. Enter search keywords: "
00147     result =
00148       nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
00149                                          "IsIndexPrompt", prompt);
00150   }
00151 
00152   mTextContent->SetText(prompt, PR_TRUE);
00153 
00154   return NS_OK;
00155 }
00156 
00157 NS_IMETHODIMP
00158 nsIsIndexFrame::GetInputFrame(nsPresContext* aPresContext,
00159                               nsIFormControlFrame** oFrame)
00160 {
00161   nsIPresShell *presShell = aPresContext->GetPresShell();
00162   if (!mInputContent) NS_WARNING("null content - cannot restore state");
00163   if (presShell && mInputContent) {
00164     nsIFrame *frame;
00165     presShell->GetPrimaryFrameFor(mInputContent, &frame);
00166     if (frame) {
00167       return frame->QueryInterface(NS_GET_IID(nsIFormControlFrame), (void**) oFrame);
00168     }
00169   }
00170   return NS_OK;
00171 }
00172 
00173 NS_IMETHODIMP
00174 nsIsIndexFrame::GetInputValue(nsPresContext* aPresContext,
00175                               nsString& oString)
00176 {
00177   nsIFormControlFrame* frame = nsnull;
00178   GetInputFrame(aPresContext, &frame);
00179   if (frame) {
00180     ((nsNewFrame*)frame)->GetValue(oString, PR_FALSE);
00181   }
00182   return NS_OK;
00183 }
00184 
00185 NS_IMETHODIMP
00186 nsIsIndexFrame::SetInputValue(nsPresContext* aPresContext,
00187                               const nsString aString)
00188 {
00189   nsIFormControlFrame* frame = nsnull;
00190   GetInputFrame(aPresContext, &frame);
00191   if (frame) {
00192     ((nsNewFrame*)frame)->SetValue(aString);
00193   }
00194   return NS_OK;
00195 }
00196 
00197 void 
00198 nsIsIndexFrame::SetFocus(PRBool aOn, PRBool aRepaint)
00199 {
00200   nsIFormControlFrame* frame = nsnull;
00201   GetInputFrame(mPresContext, &frame);
00202   if (frame) {
00203     frame->SetFocus(aOn, aRepaint);
00204   }
00205 }
00206 
00207 NS_IMETHODIMP
00208 nsIsIndexFrame::CreateAnonymousContent(nsPresContext* aPresContext,
00209                                        nsISupportsArray& aChildList)
00210 {
00211   nsresult result;
00212 
00213   // Get the node info manager (used to create hr's and input's)
00214   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
00215   nsNodeInfoManager *nimgr = doc->NodeInfoManager();
00216 
00217   // Create an hr
00218   nsCOMPtr<nsINodeInfo> hrInfo;
00219   nimgr->GetNodeInfo(nsHTMLAtoms::hr, nsnull, kNameSpaceID_None,
00220                      getter_AddRefs(hrInfo));
00221 
00222   nsCOMPtr<nsIContent> prehr;
00223   result = NS_NewHTMLElement(getter_AddRefs(prehr), hrInfo);
00224   NS_ENSURE_SUCCESS(result, result);
00225 
00226   result = aChildList.AppendElement(prehr);
00227 
00228   // Add a child text content node for the label
00229   if (NS_SUCCEEDED(result)) {
00230     nsCOMPtr<nsITextContent> labelContent;
00231     NS_NewTextNode(getter_AddRefs(labelContent), nimgr);
00232     if (labelContent) {
00233       // set the value of the text node and add it to the child list
00234       mTextContent.swap(labelContent);
00235       UpdatePromptLabel();
00236       aChildList.AppendElement(mTextContent);
00237     }
00238   }
00239 
00240   // Create text input field
00241   nsCOMPtr<nsINodeInfo> inputInfo;
00242   nimgr->GetNodeInfo(nsHTMLAtoms::input, nsnull, kNameSpaceID_None,
00243                      getter_AddRefs(inputInfo));
00244 
00245   result = NS_NewHTMLElement(getter_AddRefs(mInputContent), inputInfo);
00246   NS_ENSURE_SUCCESS(result, result);
00247 
00248   mInputContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::type, NS_LITERAL_STRING("text"), PR_FALSE);
00249 
00250   aChildList.AppendElement(mInputContent);
00251 
00252   // Register as an event listener to submit on Enter press
00253   nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(mInputContent));
00254   receiver->AddEventListenerByIID(this, NS_GET_IID(nsIDOMKeyListener));
00255 
00256   // Create an hr
00257   nsCOMPtr<nsIContent> posthr;
00258   result = NS_NewHTMLElement(getter_AddRefs(posthr), hrInfo);
00259   NS_ENSURE_SUCCESS(result, result);
00260 
00261   aChildList.AppendElement(posthr);
00262 
00263   return result;
00264 }
00265 
00266 // Frames are not refcounted, no need to AddRef
00267 NS_IMETHODIMP
00268 nsIsIndexFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
00269 {
00270   NS_PRECONDITION(0 != aInstancePtr, "null ptr");
00271   if (NULL == aInstancePtr) {
00272     return NS_ERROR_NULL_POINTER;
00273   } else if (aIID.Equals(NS_GET_IID(nsIAnonymousContentCreator))) {
00274     *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
00275     return NS_OK;
00276   } else  if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
00277     *aInstancePtr = (void*)(nsIStatefulFrame*) this;
00278     return NS_OK;
00279   } else  if (aIID.Equals(NS_GET_IID(nsIDOMKeyListener))) {
00280     *aInstancePtr = (void*)(nsIDOMKeyListener*) this;
00281     return NS_OK;
00282   }
00283   return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
00284 }
00285 
00286 void
00287 nsIsIndexFrame::ScrollIntoView(nsPresContext* aPresContext)
00288 {
00289   if (aPresContext) {
00290     nsIPresShell *presShell = aPresContext->GetPresShell();
00291     if (presShell) {
00292       presShell->ScrollFrameIntoView(this,
00293                    NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
00294     }
00295   }
00296 }
00297 
00298 
00299 NS_IMETHODIMP nsIsIndexFrame::Reflow(nsPresContext*          aPresContext, 
00300                                      nsHTMLReflowMetrics&     aDesiredSize,
00301                                      const nsHTMLReflowState& aReflowState, 
00302                                      nsReflowStatus&          aStatus)
00303 {
00304   DO_GLOBAL_REFLOW_COUNT("nsIsIndexFrame", aReflowState.reason);
00305   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
00306 
00307   // The Areaframe takes care of all our reflow 
00308   // (except for when style is used to change its size?)
00309   nsresult rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
00310   if (aDesiredSize.mComputeMEW) {
00311     aDesiredSize.SetMEWToActualWidth(aReflowState.mStylePosition->mWidth.GetUnit());
00312   }
00313   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
00314   return rv;
00315 }
00316 
00317 PRBool
00318 nsIsIndexFrame::IsLeaf() const
00319 {
00320   return PR_TRUE;
00321 }
00322 
00323 NS_IMETHODIMP
00324 nsIsIndexFrame::AttributeChanged(nsIContent*     aChild,
00325                                  PRInt32         aNameSpaceID,
00326                                  nsIAtom*        aAttribute,
00327                                  PRInt32         aModType)
00328 {
00329   nsresult rv = NS_OK;
00330   if (nsHTMLAtoms::prompt == aAttribute) {
00331     rv = UpdatePromptLabel();
00332   } else {
00333     rv = nsAreaFrame::AttributeChanged(aChild, aNameSpaceID, aAttribute, aModType);
00334   }
00335   return rv;
00336 }
00337 
00338 
00339 nsresult 
00340 nsIsIndexFrame::KeyPress(nsIDOMEvent* aEvent)
00341 {
00342   nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aEvent);
00343   if (keyEvent) {
00344     PRUint32 code;
00345     keyEvent->GetKeyCode(&code);
00346     if (code == 0) {
00347       keyEvent->GetCharCode(&code);
00348     }
00349     if (nsIDOMKeyEvent::DOM_VK_RETURN == code) {
00350       OnSubmit(mPresContext);
00351       aEvent->PreventDefault(); // XXX Needed?
00352     }
00353   }
00354 
00355   return NS_OK;
00356 }
00357 
00358 #ifdef NS_DEBUG
00359 NS_IMETHODIMP
00360 nsIsIndexFrame::GetFrameName(nsAString& aResult) const
00361 {
00362   return MakeFrameName(NS_LITERAL_STRING("IsIndex"), aResult);
00363 }
00364 #endif
00365 
00366 // submission
00367 // much of this is cut and paste from nsFormFrame::OnSubmit
00368 NS_IMETHODIMP
00369 nsIsIndexFrame::OnSubmit(nsPresContext* aPresContext)
00370 {
00371   if (!mContent || !mInputContent) {
00372     return NS_ERROR_UNEXPECTED;
00373   }
00374 
00375   nsresult result = NS_OK;
00376 
00377   // Begin ProcessAsURLEncoded
00378   nsAutoString data;
00379 
00380   nsCOMPtr<nsIUnicodeEncoder> encoder;
00381   if(NS_FAILED(GetEncoder(getter_AddRefs(encoder))))  // Non-fatal error
00382      encoder = nsnull;
00383 
00384   nsAutoString value;
00385   GetInputValue(aPresContext, value);
00386   URLEncode(value, encoder, data);
00387   // End ProcessAsURLEncoded
00388 
00389   // make the url string
00390   nsILinkHandler *handler = aPresContext->GetLinkHandler();
00391 
00392   nsAutoString href;
00393 
00394   // Get the document.
00395   // We'll need it now to form the URL we're submitting to.
00396   // We'll also need it later to get the DOM window when notifying form submit observers (bug 33203)
00397   nsCOMPtr<nsIDocument> document = mContent->GetDocument();
00398   if (!document) return NS_OK; // No doc means don't submit, see Bug 28988
00399 
00400   // Resolve url to an absolute url
00401   nsIURI *baseURI = document->GetBaseURI();
00402   if (!baseURI) {
00403     NS_ERROR("No Base URL found in Form Submit!\n");
00404     return NS_OK; // No base URL -> exit early, see Bug 30721
00405   }
00406 
00407   // If an action is not specified and we are inside 
00408   // a HTML document then reload the URL. This makes us
00409   // compatible with 4.x browsers.
00410   // If we are in some other type of document such as XML or
00411   // XUL, do nothing. This prevents undesirable reloading of
00412   // a document inside XUL.
00413 
00414   nsresult rv;
00415   nsCOMPtr<nsIHTMLDocument> htmlDoc;
00416   htmlDoc = do_QueryInterface(document, &rv);
00417   if (NS_FAILED(rv)) {   
00418     // Must be a XML, XUL or other non-HTML document type
00419     // so do nothing.
00420     return NS_OK;
00421   } 
00422 
00423   // Necko's MakeAbsoluteURI doesn't reuse the baseURL's rel path if it is
00424   // passed a zero length rel path.
00425   nsCAutoString relPath;
00426   baseURI->GetSpec(relPath);
00427   if (!relPath.IsEmpty()) {
00428     CopyUTF8toUTF16(relPath, href);
00429 
00430     // If re-using the same URL, chop off old query string (bug 25330)
00431     PRInt32 queryStart = href.FindChar('?');
00432     if (kNotFound != queryStart) {
00433       href.Truncate(queryStart);
00434     }
00435   } else {
00436     NS_ERROR("Rel path couldn't be formed in form submit!\n");
00437     return NS_ERROR_OUT_OF_MEMORY;
00438   }
00439 
00440   // Add the URI encoded form values to the URI
00441   // Get the scheme of the URI.
00442   nsCOMPtr<nsIURI> actionURL;
00443   nsXPIDLCString scheme;
00444   PRBool isJSURL = PR_FALSE;
00445   const nsACString &docCharset = document->GetDocumentCharacterSet();
00446   const nsPromiseFlatCString& flatDocCharset = PromiseFlatCString(docCharset);
00447 
00448   if (NS_SUCCEEDED(result = NS_NewURI(getter_AddRefs(actionURL), href,
00449                                       flatDocCharset.get(),
00450                                       baseURI))) {
00451     result = actionURL->SchemeIs("javascript", &isJSURL);
00452   }
00453   // Append the URI encoded variable/value pairs for GET's
00454   if (!isJSURL) { // Not for JS URIs, see bug 26917
00455     if (href.FindChar('?') == kNotFound) { // Add a ? if needed
00456       href.Append(PRUnichar('?'));
00457     } else {                              // Adding to existing query string
00458       if (href.Last() != '&' && href.Last() != '?') {   // Add a & if needed
00459         href.Append(PRUnichar('&'));
00460       }
00461     }
00462     href.Append(data);
00463   }
00464   nsCOMPtr<nsIURI> uri;
00465   result = NS_NewURI(getter_AddRefs(uri), href,
00466                      flatDocCharset.get(), baseURI);
00467   if (NS_FAILED(result)) return result;
00468 
00469   // Now pass on absolute url to the click handler
00470   if (handler) {
00471     handler->OnLinkClick(mContent, eLinkVerb_Replace,
00472                          uri,
00473                          nsnull, nsnull);
00474   }
00475   return result;
00476 }
00477 
00478 void nsIsIndexFrame::GetSubmitCharset(nsCString& oCharset)
00479 {
00480   oCharset.AssignLiteral("UTF-8"); // default to utf-8
00481   // XXX
00482   // We may want to get it from the HTML 4 Accept-Charset attribute first
00483   // see 17.3 The FORM element in HTML 4 for details
00484 
00485   // Get the charset from document
00486   nsIDocument* doc = mContent->GetDocument();
00487   if (doc) {
00488     oCharset = doc->GetDocumentCharacterSet();
00489   }
00490 }
00491 
00492 NS_IMETHODIMP nsIsIndexFrame::GetEncoder(nsIUnicodeEncoder** encoder)
00493 {
00494   *encoder = nsnull;
00495   nsCAutoString charset;
00496   nsresult rv = NS_OK;
00497   GetSubmitCharset(charset);
00498   
00499   // Get Charset, get the encoder.
00500   nsICharsetConverterManager * ccm = nsnull;
00501   rv = CallGetService(kCharsetConverterManagerCID, &ccm);
00502   if(NS_SUCCEEDED(rv) && (nsnull != ccm)) {
00503      rv = ccm->GetUnicodeEncoderRaw(charset.get(), encoder);
00504      NS_RELEASE(ccm);
00505      if (nsnull == encoder) {
00506        rv = NS_ERROR_FAILURE;
00507      }
00508      if (NS_SUCCEEDED(rv)) {
00509        rv = (*encoder)->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nsnull, (PRUnichar)'?');
00510      }
00511   }
00512   return NS_OK;
00513 }
00514 
00515 // XXX i18n helper routines
00516 char*
00517 nsIsIndexFrame::UnicodeToNewBytes(const PRUnichar* aSrc, PRUint32 aLen, nsIUnicodeEncoder* encoder)
00518 {
00519    char* res = nsnull;
00520    if(NS_SUCCEEDED(encoder->Reset()))
00521    {
00522       PRInt32 maxByteLen = 0;
00523       if(NS_SUCCEEDED(encoder->GetMaxLength(aSrc, (PRInt32) aLen, &maxByteLen))) 
00524       {
00525           res = new char[maxByteLen+1];
00526           if(nsnull != res) 
00527           {
00528              PRInt32 reslen = maxByteLen;
00529              PRInt32 reslen2 ;
00530              PRInt32 srclen = aLen;
00531              encoder->Convert(aSrc, &srclen, res, &reslen);
00532              reslen2 = maxByteLen-reslen;
00533              encoder->Finish(res+reslen, &reslen2);
00534              res[reslen+reslen2] = '\0';
00535           }
00536       }
00537 
00538    }
00539    return res;
00540 }
00541 
00542 // XXX i18n helper routines
00543 void
00544 nsIsIndexFrame::URLEncode(const nsString& aString, nsIUnicodeEncoder* encoder, nsString& oString) 
00545 {
00546   char* inBuf = nsnull;
00547   if(encoder)
00548     inBuf  = UnicodeToNewBytes(aString.get(), aString.Length(), encoder);
00549 
00550   if(nsnull == inBuf)
00551     inBuf  = ToNewCString(aString);
00552 
00553   // convert to CRLF breaks
00554   char* convertedBuf = nsLinebreakConverter::ConvertLineBreaks(inBuf,
00555                            nsLinebreakConverter::eLinebreakAny, nsLinebreakConverter::eLinebreakNet);
00556   delete [] inBuf;
00557   
00558   char* outBuf = nsEscape(convertedBuf, url_XPAlphas);
00559   oString.AssignASCII(outBuf);
00560   nsMemory::Free(outBuf);
00561   nsMemory::Free(convertedBuf);
00562 }
00563 
00564 //----------------------------------------------------------------------
00565 // nsIStatefulFrame
00566 //----------------------------------------------------------------------
00567 NS_IMETHODIMP
00568 nsIsIndexFrame::SaveState(nsPresContext* aPresContext, nsPresState** aState)
00569 {
00570   NS_ENSURE_ARG_POINTER(aState);
00571 
00572   // Get the value string
00573   nsAutoString stateString;
00574   nsresult res =  GetInputValue(aPresContext, stateString);
00575   NS_ENSURE_SUCCESS(res, res);
00576 
00577   if (! stateString.IsEmpty()) {
00578 
00579     // Construct a pres state and store value in it.
00580     res = NS_NewPresState(aState);
00581     NS_ENSURE_SUCCESS(res, res);
00582     res = (*aState)->SetStateProperty(NS_LITERAL_STRING("value"), stateString);
00583   }
00584 
00585   return res;
00586 }
00587 
00588 NS_IMETHODIMP
00589 nsIsIndexFrame::RestoreState(nsPresContext* aPresContext, nsPresState* aState)
00590 {
00591   NS_ENSURE_ARG_POINTER(aState);
00592 
00593   // Set the value to the stored state.
00594   nsAutoString stateString;
00595   nsresult res = aState->GetStateProperty(NS_LITERAL_STRING("value"), stateString);
00596   NS_ENSURE_SUCCESS(res, res);
00597 
00598   return SetInputValue(aPresContext, stateString);
00599 }