Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLAnchorElement.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Daniel Glazman <glazman@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 #include "nsCOMPtr.h"
00040 #include "nsReadableUtils.h"
00041 #include "nsUnicharUtils.h"
00042 #include "nsIDOMHTMLAnchorElement.h"
00043 #include "nsIDOMNSHTMLAnchorElement.h"
00044 #include "nsIDOMEventReceiver.h"
00045 #include "nsIHTMLDocument.h"
00046 #include "nsGenericHTMLElement.h"
00047 #include "nsILink.h"
00048 #include "nsHTMLAtoms.h"
00049 #include "nsStyleConsts.h"
00050 #include "nsPresContext.h"
00051 #include "nsIEventStateManager.h"
00052 #include "nsIURL.h"
00053 #include "nsIEventStateManager.h"
00054 #include "nsIDOMEvent.h"
00055 #include "nsNetUtil.h"
00056 #include "nsCRT.h"
00057 
00058 // For GetText().
00059 #include "nsIContentIterator.h"
00060 #include "nsIDOMText.h"
00061 #include "nsIEnumerator.h"
00062 
00063 #include "nsCOMPtr.h"
00064 #include "nsIPresShell.h"
00065 #include "nsIDocument.h"
00066 
00067 nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
00068 
00069 class nsHTMLAnchorElement : public nsGenericHTMLElement,
00070                             public nsIDOMHTMLAnchorElement,
00071                             public nsIDOMNSHTMLAnchorElement,
00072                             public nsILink
00073 {
00074 public:
00075   nsHTMLAnchorElement(nsINodeInfo *aNodeInfo);
00076   virtual ~nsHTMLAnchorElement();
00077 
00078   // nsISupports
00079   NS_DECL_ISUPPORTS_INHERITED
00080 
00081   // nsIDOMNode
00082   NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLElement::)
00083 
00084   // nsIDOMElement
00085   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
00086 
00087   // nsIDOMHTMLElement
00088   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
00089 
00090   // nsIDOMHTMLAnchorElement
00091   NS_DECL_NSIDOMHTMLANCHORELEMENT  
00092 
00093   // nsIDOMNSHTMLAnchorElement
00094   NS_DECL_NSIDOMNSHTMLANCHORELEMENT
00095 
00096   // nsILink
00097   NS_IMETHOD GetLinkState(nsLinkState &aState);
00098   NS_IMETHOD SetLinkState(nsLinkState aState);
00099   NS_IMETHOD GetHrefURI(nsIURI** aURI);
00100   NS_IMETHOD LinkAdded() { return NS_OK; }
00101   NS_IMETHOD LinkRemoved() { return NS_OK; }
00102 
00103   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
00104                               nsIContent* aBindingParent,
00105                               PRBool aCompileEventHandlers);
00106   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
00107                               PRBool aNullParent = PR_TRUE);
00108   virtual void SetFocus(nsPresContext* aPresContext);
00109   virtual PRBool IsFocusable(PRBool *aTabIndex = nsnull);
00110 
00111   virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
00112                                   nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
00113                                   PRUint32 aFlags,
00114                                   nsEventStatus* aEventStatus);
00115 
00116   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00117                    const nsAString& aValue, PRBool aNotify)
00118   {
00119     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
00120   }
00121   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00122                            nsIAtom* aPrefix, const nsAString& aValue,
00123                            PRBool aNotify);
00124   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00125                              PRBool aNotify);
00126 
00127 protected:
00128   // The cached visited state
00129   nsLinkState mLinkState;
00130 };
00131 
00132 
00133 NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
00134 
00135 
00136 nsHTMLAnchorElement::nsHTMLAnchorElement(nsINodeInfo *aNodeInfo)
00137   : nsGenericHTMLElement(aNodeInfo),
00138     mLinkState(eLinkState_Unknown)
00139 {
00140 }
00141 
00142 nsHTMLAnchorElement::~nsHTMLAnchorElement()
00143 {
00144 }
00145 
00146 
00147 NS_IMPL_ADDREF_INHERITED(nsHTMLAnchorElement, nsGenericElement) 
00148 NS_IMPL_RELEASE_INHERITED(nsHTMLAnchorElement, nsGenericElement) 
00149 
00150 
00151 // QueryInterface implementation for nsHTMLAnchorElement
00152 NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLAnchorElement, nsGenericHTMLElement)
00153   NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLAnchorElement)
00154   NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLAnchorElement)
00155   NS_INTERFACE_MAP_ENTRY(nsILink)
00156   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLAnchorElement)
00157 NS_HTML_CONTENT_INTERFACE_MAP_END
00158 
00159 
00160 NS_IMPL_DOM_CLONENODE(nsHTMLAnchorElement)
00161 
00162 
00163 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Charset, charset)
00164 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Coords, coords)
00165 NS_IMPL_URI_ATTR(nsHTMLAnchorElement, Href, href)
00166 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Hreflang, hreflang)
00167 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Name, name)
00168 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Rel, rel)
00169 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Rev, rev)
00170 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Shape, shape)
00171 NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLAnchorElement, TabIndex, tabindex, 0)
00172 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Type, type)
00173 NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, AccessKey, accesskey)
00174 
00175 
00176 nsresult
00177 nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
00178                                 nsIContent* aBindingParent,
00179                                 PRBool aCompileEventHandlers)
00180 {
00181   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
00182                                                  aBindingParent,
00183                                                  aCompileEventHandlers);
00184   NS_ENSURE_SUCCESS(rv, rv);
00185 
00186   if (aDocument) {
00187     RegUnRegAccessKey(PR_TRUE);
00188   }
00189 
00190   return rv;
00191 }
00192 
00193 void
00194 nsHTMLAnchorElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
00195 {
00196   if (IsInDoc()) {
00197     RegUnRegAccessKey(PR_FALSE);
00198     GetCurrentDoc()->ForgetLink(this);
00199     // If this link is ever reinserted into a document, it might
00200     // be under a different xml:base, so forget the cached state now
00201     mLinkState = eLinkState_Unknown;
00202   }
00203     
00204   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
00205 }
00206 
00207 NS_IMETHODIMP
00208 nsHTMLAnchorElement::Blur()
00209 {
00210   if (ShouldFocus(this)) {
00211     SetElementFocus(PR_FALSE);
00212   }
00213 
00214   return NS_OK;
00215 }
00216 
00217 NS_IMETHODIMP
00218 nsHTMLAnchorElement::Focus()
00219 {
00220   if (ShouldFocus(this)) {
00221     SetElementFocus(PR_TRUE);
00222   }
00223 
00224   return NS_OK;
00225 }
00226 
00227 void
00228 nsHTMLAnchorElement::SetFocus(nsPresContext* aPresContext)
00229 {
00230   if (!aPresContext) {
00231     return;
00232   }
00233 
00234   // don't make the link grab the focus if there is no link handler
00235   nsILinkHandler *handler = aPresContext->GetLinkHandler();
00236   if (handler) {
00237     aPresContext->EventStateManager()->SetContentState(this,
00238                                                        NS_EVENT_STATE_FOCUS);
00239 
00240     // Make sure the presentation is up-to-date
00241     nsIDocument* doc = GetCurrentDoc();
00242     if (doc) {
00243       doc->FlushPendingNotifications(Flush_Layout);
00244     }
00245 
00246     nsIPresShell *presShell = aPresContext->GetPresShell();
00247 
00248     if (presShell) {
00249       nsIFrame* frame = nsnull;
00250       presShell->GetPrimaryFrameFor(this, &frame);
00251       if (frame) {
00252         presShell->ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_ANYWHERE,
00253                                        NS_PRESSHELL_SCROLL_ANYWHERE);
00254       }
00255     }
00256   }
00257 }
00258 
00259 PRBool
00260 nsHTMLAnchorElement::IsFocusable(PRInt32 *aTabIndex)
00261 {
00262   if (!nsGenericHTMLElement::IsFocusable(aTabIndex)) {
00263     return PR_FALSE;
00264   }
00265 
00266   if (!HasAttr(kNameSpaceID_None, nsHTMLAtoms::tabindex)) {
00267     // check whether we're actually a link
00268     nsCOMPtr<nsIURI> linkURI = nsContentUtils::GetLinkURI(this);
00269     if (!linkURI) {
00270       // Not tabbable or focusable without href (bug 17605), unless
00271       // forced to be via presence of nonnegative tabindex attribute
00272       if (aTabIndex) {
00273         *aTabIndex = -1;
00274       }
00275       return PR_FALSE;
00276     }
00277   }
00278 
00279   if (aTabIndex && (sTabFocusModel & eTabFocus_linksMask) == 0) {
00280     *aTabIndex = -1;
00281   }
00282 
00283   return PR_TRUE;
00284 }
00285 
00286 nsresult
00287 nsHTMLAnchorElement::HandleDOMEvent(nsPresContext* aPresContext,
00288                                     nsEvent* aEvent,
00289                                     nsIDOMEvent** aDOMEvent,
00290                                     PRUint32 aFlags,
00291                                     nsEventStatus* aEventStatus)
00292 {
00293   return HandleDOMEventForAnchors(aPresContext, aEvent, aDOMEvent, 
00294                                   aFlags, aEventStatus);
00295 }
00296 
00297 NS_IMETHODIMP
00298 nsHTMLAnchorElement::GetTarget(nsAString& aValue)
00299 {
00300   aValue.Truncate();
00301 
00302   nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, aValue);
00303   if (rv == NS_CONTENT_ATTR_NOT_THERE) {
00304     GetBaseTarget(aValue);
00305   }
00306   return NS_OK;
00307 }
00308 
00309 NS_IMETHODIMP
00310 nsHTMLAnchorElement::SetTarget(const nsAString& aValue)
00311 {
00312   return SetAttr(kNameSpaceID_None, nsHTMLAtoms::target, aValue, PR_TRUE);
00313 }
00314 
00315 NS_IMETHODIMP    
00316 nsHTMLAnchorElement::GetProtocol(nsAString& aProtocol)
00317 {
00318   nsAutoString href;
00319 
00320   nsresult rv = GetHref(href);
00321   if (NS_FAILED(rv))
00322     return rv;
00323 
00324   // XXX this should really use GetHrefURI and not do so much string stuff
00325   return GetProtocolFromHrefString(href, aProtocol, GetOwnerDoc());
00326 }
00327 
00328 NS_IMETHODIMP
00329 nsHTMLAnchorElement::SetProtocol(const nsAString& aProtocol)
00330 {
00331   nsAutoString href, new_href;
00332   nsresult rv = GetHref(href);
00333   if (NS_FAILED(rv))
00334     return rv;
00335 
00336   rv = SetProtocolInHrefString(href, aProtocol, new_href);
00337   if (NS_FAILED(rv))
00338     // Ignore failures to be compatible with NS4
00339     return NS_OK;
00340 
00341   return SetHref(new_href);
00342 }
00343 
00344 NS_IMETHODIMP    
00345 nsHTMLAnchorElement::GetHost(nsAString& aHost)
00346 {
00347   nsAutoString href;
00348   
00349   nsresult rv = GetHref(href);
00350   if (NS_FAILED(rv))
00351     return rv;
00352 
00353   return GetHostFromHrefString(href, aHost);
00354 }
00355 
00356 NS_IMETHODIMP
00357 nsHTMLAnchorElement::SetHost(const nsAString& aHost)
00358 {
00359   nsAutoString href, new_href;
00360   nsresult rv = GetHref(href);
00361   if (NS_FAILED(rv))
00362     return rv;
00363 
00364   rv = SetHostInHrefString(href, aHost, new_href);
00365   if (NS_FAILED(rv))
00366     // Ignore failures to be compatible with NS4
00367     return NS_OK;
00368 
00369   return SetHref(new_href);
00370 }
00371 
00372 NS_IMETHODIMP    
00373 nsHTMLAnchorElement::GetHostname(nsAString& aHostname)
00374 {
00375   nsAutoString href;
00376   nsresult rv = GetHref(href);
00377   if (NS_FAILED(rv))
00378     return rv;
00379 
00380   return GetHostnameFromHrefString(href, aHostname);
00381 }
00382 
00383 NS_IMETHODIMP
00384 nsHTMLAnchorElement::SetHostname(const nsAString& aHostname)
00385 {
00386   nsAutoString href, new_href;
00387   nsresult rv = GetHref(href);
00388   if (NS_FAILED(rv))
00389     return rv;
00390 
00391   rv = SetHostnameInHrefString(href, aHostname, new_href);
00392   if (NS_FAILED(rv))
00393     // Ignore failures to be compatible with NS4
00394     return NS_OK;
00395   
00396   return SetHref(new_href);
00397 }
00398 
00399 NS_IMETHODIMP    
00400 nsHTMLAnchorElement::GetPathname(nsAString& aPathname)
00401 {
00402   nsAutoString href;
00403  
00404   nsresult rv = GetHref(href);
00405   if (NS_FAILED(rv))
00406     return rv;
00407 
00408   return GetPathnameFromHrefString(href, aPathname);
00409 }
00410 
00411 NS_IMETHODIMP
00412 nsHTMLAnchorElement::SetPathname(const nsAString& aPathname)
00413 {
00414   nsAutoString href, new_href;
00415   nsresult rv = GetHref(href);
00416   if (NS_FAILED(rv))
00417     return rv;
00418 
00419   rv = SetPathnameInHrefString(href, aPathname, new_href);
00420   if (NS_FAILED(rv))
00421     // Ignore failures to be compatible with NS4
00422     return NS_OK;
00423 
00424   return SetHref(new_href);
00425 }
00426 
00427 NS_IMETHODIMP    
00428 nsHTMLAnchorElement::GetSearch(nsAString& aSearch)
00429 {
00430   nsAutoString href;
00431 
00432   nsresult rv = GetHref(href);
00433   if (NS_FAILED(rv))
00434     return rv;
00435 
00436   return GetSearchFromHrefString(href, aSearch);
00437 }
00438 
00439 NS_IMETHODIMP
00440 nsHTMLAnchorElement::SetSearch(const nsAString& aSearch)
00441 {
00442   nsAutoString href, new_href;
00443   nsresult rv = GetHref(href);
00444 
00445   if (NS_FAILED(rv))
00446     return rv;
00447 
00448   rv = SetSearchInHrefString(href, aSearch, new_href);
00449   if (NS_FAILED(rv))
00450     // Ignore failures to be compatible with NS4
00451     return NS_OK;
00452 
00453   return SetHref(new_href);
00454 }
00455 
00456 NS_IMETHODIMP    
00457 nsHTMLAnchorElement::GetPort(nsAString& aPort)
00458 {
00459   nsAutoString href;
00460   
00461   nsresult rv = GetHref(href);
00462   if (NS_FAILED(rv))
00463     return rv;
00464 
00465   return GetPortFromHrefString(href, aPort);
00466 }
00467 
00468 NS_IMETHODIMP
00469 nsHTMLAnchorElement::SetPort(const nsAString& aPort)
00470 {
00471   nsAutoString href, new_href;
00472   nsresult rv = GetHref(href);
00473 
00474   if (NS_FAILED(rv))
00475     return rv;
00476 
00477   rv = SetPortInHrefString(href, aPort, new_href);
00478   if (NS_FAILED(rv))
00479     // Ignore failures to be compatible with NS4
00480     return NS_OK;
00481   
00482   return SetHref(new_href);
00483 }
00484 
00485 NS_IMETHODIMP    
00486 nsHTMLAnchorElement::GetHash(nsAString& aHash)
00487 {
00488   nsAutoString href;
00489 
00490   nsresult rv = GetHref(href);
00491   if (NS_FAILED(rv))
00492     return rv;
00493 
00494   return GetHashFromHrefString(href, aHash);
00495 }
00496 
00497 NS_IMETHODIMP
00498 nsHTMLAnchorElement::SetHash(const nsAString& aHash)
00499 {
00500   nsAutoString href, new_href;
00501   nsresult rv = GetHref(href);
00502 
00503   if (NS_FAILED(rv))
00504     return rv;
00505 
00506   rv = SetHashInHrefString(href, aHash, new_href);
00507   if (NS_FAILED(rv))
00508     // Ignore failures to be compatible with NS4
00509     return NS_OK;
00510 
00511   return SetHref(new_href);
00512 }
00513 
00514 NS_IMETHODIMP    
00515 nsHTMLAnchorElement::GetText(nsAString& aText)
00516 {
00517   aText.Truncate();
00518 
00519   // Since this is a Netscape 4 proprietary attribute, we have to implement
00520   // the same behavior. Basically it is returning the last text node of
00521   // of the anchor. Returns an empty string if there is no text node.
00522   // The nsIContentIterator does exactly what we want, if we start the 
00523   // iteration from the end.
00524   nsCOMPtr<nsIContentIterator> iter;
00525   nsresult rv = NS_NewContentIterator(getter_AddRefs(iter));
00526   NS_ENSURE_SUCCESS(rv, rv);
00527 
00528   // Initialize the content iterator with the children of the anchor
00529   iter->Init(this);
00530 
00531   // Position the iterator. Last() is the anchor itself, this is not what we 
00532   // want. Prev() positions the iterator to the last child of the anchor,
00533   // starting at the deepest level of children, just like NS4 does.
00534   iter->Last();
00535   iter->Prev();
00536 
00537   while(!iter->IsDone()) {
00538     nsCOMPtr<nsIDOMText> textNode(do_QueryInterface(iter->GetCurrentNode()));
00539     if(textNode) {
00540       // The current node is a text node. Get its value and break the loop.
00541       textNode->GetData(aText);
00542       break;
00543     }
00544 
00545     iter->Prev();
00546   }
00547 
00548   return NS_OK;
00549 }
00550 
00551 NS_IMETHODIMP
00552 nsHTMLAnchorElement::ToString(nsAString& aSource)
00553 {
00554   return GetHref(aSource);
00555 }
00556 
00557 NS_IMETHODIMP
00558 nsHTMLAnchorElement::GetLinkState(nsLinkState &aState)
00559 {
00560   aState = mLinkState;
00561   return NS_OK;
00562 }
00563 
00564 NS_IMETHODIMP
00565 nsHTMLAnchorElement::SetLinkState(nsLinkState aState)
00566 {
00567   mLinkState = aState;
00568   return NS_OK;
00569 }
00570 
00571 NS_IMETHODIMP
00572 nsHTMLAnchorElement::GetHrefURI(nsIURI** aURI)
00573 {
00574   return GetHrefURIForAnchors(aURI);
00575 }
00576 
00577 nsresult
00578 nsHTMLAnchorElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00579                              nsIAtom* aPrefix, const nsAString& aValue,
00580                              PRBool aNotify)
00581 {
00582   if (aName == nsHTMLAtoms::href && kNameSpaceID_None == aNameSpaceID) {
00583     nsAutoString val;
00584     GetHref(val);
00585     if (!val.Equals(aValue)) {
00586       nsIDocument* doc = GetCurrentDoc();
00587       if (doc) {
00588         doc->ForgetLink(this);
00589         // The change to 'href' will cause style reresolution which will
00590         // eventually recompute the link state and re-add this element
00591         // to the link map if necessary.
00592       }
00593       SetLinkState(eLinkState_Unknown);
00594     }
00595   }
00596 
00597   if (aName == nsHTMLAtoms::accesskey && kNameSpaceID_None == aNameSpaceID) {
00598     RegUnRegAccessKey(PR_FALSE);
00599   }
00600 
00601   nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
00602                                               aValue, aNotify);
00603 
00604   if (aName == nsHTMLAtoms::accesskey && kNameSpaceID_None == aNameSpaceID &&
00605       !aValue.IsEmpty()) {
00606     RegUnRegAccessKey(PR_TRUE);
00607   }
00608 
00609   return rv;
00610 }
00611 
00612 nsresult
00613 nsHTMLAnchorElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00614                                PRBool aNotify)
00615 {
00616   if (aAttribute == nsHTMLAtoms::href && kNameSpaceID_None == aNameSpaceID) {
00617     SetLinkState(eLinkState_Unknown);
00618   }
00619 
00620   if (aAttribute == nsHTMLAtoms::accesskey &&
00621       kNameSpaceID_None == aNameSpaceID) {
00622     RegUnRegAccessKey(PR_FALSE);
00623   }
00624 
00625   return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
00626 }