Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLSharedElement.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 Communicator client 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 #include "nsIDOMHTMLEmbedElement.h"
00038 #include "nsIDOMHTMLIsIndexElement.h"
00039 #include "nsIDOMHTMLParamElement.h"
00040 #include "nsIDOMHTMLBaseElement.h"
00041 #include "nsIDOMHTMLDirectoryElement.h"
00042 #include "nsIDOMHTMLMenuElement.h"
00043 #include "nsIDOMHTMLQuoteElement.h"
00044 #include "nsIDOMHTMLBaseFontElement.h"
00045 #include "nsIDOMEventReceiver.h"
00046 #include "nsGenericHTMLElement.h"
00047 #include "nsImageLoadingContent.h"
00048 #include "nsHTMLAtoms.h"
00049 #include "nsStyleConsts.h"
00050 #include "nsPresContext.h"
00051 #include "nsRuleData.h"
00052 #include "nsMappedAttributes.h"
00053 #include "nsStyleContext.h"
00054 #include "nsIPluginElement.h"
00055 
00056 #ifdef MOZ_SVG
00057 #include "nsIDOMGetSVGDocument.h"
00058 #include "nsIDOMSVGDocument.h"
00059 #include "nsIDocument.h"
00060 #endif
00061 
00062 // XXX nav4 has type= start= (same as OL/UL)
00063 extern nsAttrValue::EnumTable kListTypeTable[];
00064 
00065 class nsHTMLSharedElement : public nsGenericHTMLElement,
00066                             public nsImageLoadingContent,
00067                             public nsIPluginElement,
00068                             public nsIDOMHTMLEmbedElement,
00069 #ifdef MOZ_SVG
00070                             public nsIDOMGetSVGDocument,
00071 #endif
00072                             public nsIDOMHTMLIsIndexElement,
00073                             public nsIDOMHTMLParamElement,
00074                             public nsIDOMHTMLBaseElement,
00075                             public nsIDOMHTMLDirectoryElement,
00076                             public nsIDOMHTMLMenuElement,
00077                             public nsIDOMHTMLQuoteElement,
00078                             public nsIDOMHTMLBaseFontElement
00079 {
00080 public:
00081   nsHTMLSharedElement(nsINodeInfo *aNodeInfo);
00082   virtual ~nsHTMLSharedElement();
00083 
00084   // nsISupports
00085   NS_DECL_ISUPPORTS_INHERITED
00086 
00087   // nsIPluginElement
00088   NS_DECL_NSIPLUGINELEMENT
00089 
00090   // nsIDOMNode
00091   NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLElement::)
00092 
00093   // nsIDOMElement
00094   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
00095 
00096   // nsIDOMHTMLElement
00097   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
00098 
00099   // nsIDOMHTMLEmbedElement
00100   NS_DECL_NSIDOMHTMLEMBEDELEMENT
00101 
00102 #ifdef MOZ_SVG
00103   // nsIDOMGetSVGDocument
00104   NS_DECL_NSIDOMGETSVGDOCUMENT
00105 #endif
00106 
00107   // nsIDOMHTMLIsIndexElement
00108   NS_DECL_NSIDOMHTMLISINDEXELEMENT
00109 
00110   // nsIDOMHTMLParamElement Can't use the macro
00111   // NS_DECL_NSIDOMHTMLPARAMELEMENT since some of the methods in
00112   // nsIDOMHTMLParamElement clashes with methods in
00113   // nsIDOMHTMLEmbedElement
00114   NS_IMETHOD GetValue(nsAString& aValue);
00115   NS_IMETHOD SetValue(const nsAString& aValue);
00116   NS_IMETHOD GetValueType(nsAString& aValueType);
00117   NS_IMETHOD SetValueType(const nsAString& aValueType);
00118 
00119   // nsIDOMHTMLBaseElement
00120   NS_DECL_NSIDOMHTMLBASEELEMENT
00121 
00122   // nsIDOMHTMLDirectoryElement
00123   NS_DECL_NSIDOMHTMLDIRECTORYELEMENT
00124 
00125   // nsIDOMHTMLMenuElement
00126   // Same as directoryelement
00127 
00128   // nsIDOMHTMLQuoteElement
00129   NS_DECL_NSIDOMHTMLQUOTEELEMENT
00130 
00131   // nsIDOMHTMLBaseFontElement
00132   NS_DECL_NSIDOMHTMLBASEFONTELEMENT
00133 
00134   // nsIContent
00135   // Have to override tabindex for <embed> to act right
00136   NS_IMETHOD GetTabIndex(PRInt32* aTabIndex);
00137   NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
00138   virtual void SetFocus(nsPresContext* aPresContext);
00139   // Let plugin decide whether it wants focus from mouse clicks
00140   virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
00141   
00142   virtual PRBool ParseAttribute(nsIAtom* aAttribute,
00143                                 const nsAString& aValue,
00144                                 nsAttrValue& aResult);
00145   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
00146   NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
00147 
00148 protected:
00149   nsCString mActualType;
00150   PRPackedBool mInSetFocus; // Used in SetFocus(nsPresContext*)
00151 };
00152 
00153 
00154 NS_IMPL_NS_NEW_HTML_ELEMENT(Shared)
00155 
00156 
00157 nsHTMLSharedElement::nsHTMLSharedElement(nsINodeInfo *aNodeInfo)
00158   : nsGenericHTMLElement(aNodeInfo), mInSetFocus(PR_FALSE)
00159 {
00160 }
00161 
00162 nsHTMLSharedElement::~nsHTMLSharedElement()
00163 {
00164 }
00165 
00166 
00167 NS_IMPL_ADDREF_INHERITED(nsHTMLSharedElement, nsGenericElement)
00168 NS_IMPL_RELEASE_INHERITED(nsHTMLSharedElement, nsGenericElement)
00169 
00170 
00171 // QueryInterface implementation for nsHTMLSharedElement
00172 NS_HTML_CONTENT_INTERFACE_MAP_AMBIGOUS_BEGIN(nsHTMLSharedElement,
00173                                              nsGenericHTMLElement,
00174                                              nsIDOMHTMLEmbedElement)
00175   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLEmbedElement, embed)
00176 #ifdef MOZ_SVG
00177   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMGetSVGDocument, embed)
00178 #endif
00179   NS_INTERFACE_MAP_ENTRY_IF_TAG(imgIDecoderObserver, embed)
00180   NS_INTERFACE_MAP_ENTRY_IF_TAG(imgIDecoderObserver_MOZILLA_1_8_BRANCH, embed)
00181   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIImageLoadingContent, embed)
00182   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIPluginElement, embed)
00183   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLParamElement, param)
00184   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLIsIndexElement, isindex)
00185   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLBaseElement, base)
00186   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLDirectoryElement, dir)
00187   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLMenuElement, menu)
00188   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, q)
00189   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLQuoteElement, blockquote)
00190   NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLBaseFontElement, basefont)
00191 
00192   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLEmbedElement, embed)
00193   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLParamElement, param)
00194   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLWBRElement, wbr)
00195   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLIsIndexElement, isindex)
00196   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLBaseElement, base)
00197   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLSpacerElement, spacer)
00198   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLDirectoryElement, dir)
00199   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLMenuElement, menu)
00200   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLQuoteElement, q)
00201   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLQuoteElement, blockquote)
00202   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLBaseFontElement, basefont)
00203 NS_HTML_CONTENT_INTERFACE_MAP_END
00204 
00205 
00206 NS_IMPL_DOM_CLONENODE_AMBIGUOUS(nsHTMLSharedElement, nsIDOMHTMLEmbedElement)
00207 
00208 
00210 // Implement nsIDOMHTMLEmbedElement interface
00211 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Align, align)
00212 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Height, height)
00213 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Width, width)
00214 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Name, name)
00215 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Type, type)
00216 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Src, src)
00217 
00218 NS_IMETHODIMP
00219 nsHTMLSharedElement::SetActualType(const nsACString& aActualType)
00220 {
00221   mActualType = aActualType;
00222 
00223   return NS_OK;
00224 }
00225 
00226 NS_IMETHODIMP
00227 nsHTMLSharedElement::GetActualType(nsACString& aActualType)
00228 {
00229   aActualType = mActualType;
00230 
00231   return NS_OK;
00232 }
00233 
00234 #ifdef MOZ_SVG
00235 // nsIDOMGetSVGDocument
00236 NS_IMETHODIMP
00237 nsHTMLSharedElement::GetSVGDocument(nsIDOMSVGDocument** aResult)
00238 {
00239   NS_ENSURE_ARG_POINTER(aResult);
00240 
00241   *aResult = nsnull;
00242 
00243   if (!mNodeInfo->Equals(nsHTMLAtoms::embed) || !IsInDoc())
00244     return NS_OK;
00245 
00246   nsIDocument *sub_doc = GetOwnerDoc()->GetSubDocumentFor(this);
00247   if (sub_doc)
00248     CallQueryInterface(sub_doc, aResult);
00249 
00250   return NS_OK;
00251 }
00252 #endif
00253 
00254 // nsIDOMHTMLParamElement
00255 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Value, value)
00256 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, ValueType, valuetype)
00257 
00258 // nsIDOMHTMLIsIndexElement
00259 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Prompt, prompt)
00260 
00261 // nsIDOMHTMLDirectoryElement
00262 NS_IMPL_BOOL_ATTR(nsHTMLSharedElement, Compact, compact)
00263 
00264 // nsIDOMHTMLMenuElement
00265 //NS_IMPL_BOOL_ATTR(nsHTMLSharedElement, Compact, compact)
00266 
00267 // nsIDOMHTMLQuoteElement
00268 NS_IMPL_URI_ATTR(nsHTMLSharedElement, Cite, cite)
00269 
00270 // nsIDOMHTMLBaseFontElement
00271 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Color, color)
00272 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Face, face)
00273 NS_IMPL_INT_ATTR(nsHTMLSharedElement, Size, size)
00274 
00275 // TabIndex for embed
00276 NS_IMPL_INT_ATTR(nsHTMLSharedElement, TabIndex, tabindex)
00277 
00278   
00279 NS_IMETHODIMP
00280 nsHTMLSharedElement::GetForm(nsIDOMHTMLFormElement** aForm)
00281 {
00282   *aForm = FindForm().get();
00283 
00284   return NS_OK;
00285 }
00286 
00287 // nsIDOMHTMLBaseElement
00288 NS_IMPL_URI_ATTR(nsHTMLSharedElement, Href, href)
00289 NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Target, target)
00290 
00291 PRBool
00292 nsHTMLSharedElement::ParseAttribute(nsIAtom* aAttribute,
00293                                     const nsAString& aValue,
00294                                     nsAttrValue& aResult)
00295 {
00296   if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
00297     if (aAttribute == nsHTMLAtoms::align) {
00298       return ParseAlignValue(aValue, aResult);
00299     }
00300     if (ParseImageAttribute(aAttribute, aValue, aResult)) {
00301       return PR_TRUE;
00302     }
00303   }
00304   else if (mNodeInfo->Equals(nsHTMLAtoms::spacer)) {
00305     if (aAttribute == nsHTMLAtoms::size) {
00306       return aResult.ParseIntWithBounds(aValue, 0);
00307     }
00308     if (aAttribute == nsHTMLAtoms::align) {
00309       return ParseAlignValue(aValue, aResult);
00310     }
00311     if (aAttribute == nsHTMLAtoms::width ||
00312         aAttribute == nsHTMLAtoms::height) {
00313       return aResult.ParseSpecialIntValue(aValue, PR_TRUE, PR_FALSE);
00314     }
00315   }
00316   else if (mNodeInfo->Equals(nsHTMLAtoms::dir) ||
00317            mNodeInfo->Equals(nsHTMLAtoms::menu)) {
00318     if (aAttribute == nsHTMLAtoms::type) {
00319       return aResult.ParseEnumValue(aValue, kListTypeTable);
00320     }
00321     if (aAttribute == nsHTMLAtoms::start) {
00322       return aResult.ParseIntWithBounds(aValue, 1);
00323     }
00324   }
00325   else if (mNodeInfo->Equals(nsHTMLAtoms::basefont)) {
00326     if (aAttribute == nsHTMLAtoms::size) {
00327       return aResult.ParseIntValue(aValue);
00328     }
00329   }
00330 
00331   return nsGenericHTMLElement::ParseAttribute(aAttribute, aValue, aResult);
00332 }
00333 
00334 // spacer element code
00335 
00336 static void
00337 SpacerMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
00338                             nsRuleData* aData)
00339 {
00340   nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
00341   nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
00342 
00343   if (aData->mSID == eStyleStruct_Position) {
00344     const nsStyleDisplay* display = aData->mStyleContext->GetStyleDisplay();
00345 
00346     PRBool typeIsBlock = (display->mDisplay == NS_STYLE_DISPLAY_BLOCK);
00347 
00348     if (typeIsBlock) {
00349       // width: value
00350       if (aData->mPositionData->mWidth.GetUnit() == eCSSUnit_Null) {
00351         const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::width);
00352         if (value && value->Type() == nsAttrValue::eInteger) {
00353           aData->mPositionData->
00354             mWidth.SetFloatValue((float)value->GetIntegerValue(),
00355                                  eCSSUnit_Pixel);
00356         } else if (value && value->Type() == nsAttrValue::ePercent) {
00357           aData->mPositionData->
00358             mWidth.SetPercentValue(value->GetPercentValue());
00359         }
00360       }
00361 
00362       // height: value
00363       if (aData->mPositionData->mHeight.GetUnit() == eCSSUnit_Null) {
00364         const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::height);
00365         if (value && value->Type() == nsAttrValue::eInteger) {
00366           aData->mPositionData->
00367             mHeight.SetFloatValue((float)value->GetIntegerValue(),
00368                                   eCSSUnit_Pixel);
00369         } else if (value && value->Type() == nsAttrValue::ePercent) {
00370           aData->mPositionData->
00371             mHeight.SetPercentValue(value->GetPercentValue());
00372         }
00373       }
00374     } else {
00375       // size: value
00376       if (aData->mPositionData->mWidth.GetUnit() == eCSSUnit_Null) {
00377         const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::size);
00378         if (value && value->Type() == nsAttrValue::eInteger)
00379           aData->mPositionData->
00380             mWidth.SetFloatValue((float)value->GetIntegerValue(),
00381                                  eCSSUnit_Pixel);
00382       }
00383     }
00384   } else if (aData->mSID == eStyleStruct_Display) {
00385     const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::align);
00386     if (value && value->Type() == nsAttrValue::eEnum) {
00387       PRInt32 align = value->GetEnumValue();
00388       if (aData->mDisplayData->mFloat.GetUnit() == eCSSUnit_Null) {
00389         if (align == NS_STYLE_TEXT_ALIGN_LEFT)
00390           aData->mDisplayData->mFloat.SetIntValue(NS_STYLE_FLOAT_LEFT,
00391                                                   eCSSUnit_Enumerated);
00392         else if (align == NS_STYLE_TEXT_ALIGN_RIGHT)
00393           aData->mDisplayData->mFloat.SetIntValue(NS_STYLE_FLOAT_RIGHT,
00394                                                   eCSSUnit_Enumerated);
00395       }
00396     }
00397 
00398     if (aData->mDisplayData->mDisplay.GetUnit() == eCSSUnit_Null) {
00399       const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::type);
00400       if (value && value->Type() == nsAttrValue::eString) {
00401         nsAutoString tmp(value->GetStringValue());
00402         if (tmp.LowerCaseEqualsLiteral("line") ||
00403             tmp.LowerCaseEqualsLiteral("vert") ||
00404             tmp.LowerCaseEqualsLiteral("vertical") ||
00405             tmp.LowerCaseEqualsLiteral("block")) {
00406           // This is not strictly 100% compatible: if the spacer is given
00407           // a width of zero then it is basically ignored.
00408           aData->mDisplayData->mDisplay.SetIntValue(NS_STYLE_DISPLAY_BLOCK,
00409                                                     eCSSUnit_Enumerated);
00410         }
00411       }
00412     }
00413   }
00414 
00415   nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
00416 }
00417 
00418 static void
00419 EmbedMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
00420                            nsRuleData* aData)
00421 {
00422   nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aData);
00423   nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
00424   nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
00425   nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
00426   nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
00427 }
00428 
00429 static void
00430 DirectoryMenuMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
00431                                nsRuleData* aData)
00432 {
00433   if (aData->mSID == eStyleStruct_List) {
00434     if (aData->mListData->mType.GetUnit() == eCSSUnit_Null) {
00435       // type: enum
00436       const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::type);
00437       if (value) {
00438         if (value->Type() == nsAttrValue::eEnum)
00439           aData->mListData->mType.SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
00440         else
00441           aData->mListData->mType.SetIntValue(NS_STYLE_LIST_STYLE_DISC, eCSSUnit_Enumerated);
00442       }
00443     }
00444   }
00445 
00446   nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
00447 }
00448 
00449 NS_IMETHODIMP_(PRBool)
00450 nsHTMLSharedElement::IsAttributeMapped(const nsIAtom* aAttribute) const
00451 {
00452   if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
00453     static const MappedAttributeEntry* const map[] = {
00454       sCommonAttributeMap,
00455       sImageMarginSizeAttributeMap,
00456       sImageAlignAttributeMap,
00457       sImageBorderAttributeMap
00458     };
00459 
00460     return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
00461   }
00462 
00463   if (mNodeInfo->Equals(nsHTMLAtoms::spacer)) {
00464     static const MappedAttributeEntry attributes[] = {
00465       // XXXldb This is just wrong.
00466       { &nsHTMLAtoms::usemap },
00467       { &nsHTMLAtoms::ismap },
00468       { &nsHTMLAtoms::align },
00469       { nsnull }
00470     };
00471 
00472     static const MappedAttributeEntry* const map[] = {
00473       attributes,
00474       sCommonAttributeMap,
00475       sImageMarginSizeAttributeMap,
00476       sImageBorderAttributeMap,
00477     };
00478 
00479     return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
00480   }
00481 
00482   if (mNodeInfo->Equals(nsHTMLAtoms::dir)) {
00483     static const MappedAttributeEntry attributes[] = {
00484       { &nsHTMLAtoms::type },
00485       // { &nsHTMLAtoms::compact }, // XXX
00486       { nsnull} 
00487     };
00488   
00489     static const MappedAttributeEntry* const map[] = {
00490       attributes,
00491       sCommonAttributeMap,
00492     };
00493 
00494     return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
00495   }
00496 
00497   return nsGenericHTMLElement::IsAttributeMapped(aAttribute);
00498 }
00499 
00500 nsMapRuleToAttributesFunc
00501 nsHTMLSharedElement::GetAttributeMappingFunction() const
00502 {
00503   if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
00504     return &EmbedMapAttributesIntoRule;
00505   }
00506   if (mNodeInfo->Equals(nsHTMLAtoms::spacer)) {
00507     return &SpacerMapAttributesIntoRule;
00508   }
00509   else if (mNodeInfo->Equals(nsHTMLAtoms::dir) ||
00510            mNodeInfo->Equals(nsHTMLAtoms::menu)) {
00511     return &DirectoryMenuMapAttributesIntoRule;
00512   }
00513 
00514   return nsGenericHTMLElement::GetAttributeMappingFunction();
00515 }
00516 
00517 void
00518 nsHTMLSharedElement::SetFocus(nsPresContext* aPresContext)
00519 {
00520   if (mInSetFocus) {
00521     NS_WARNING("nsHTMLSharedElement::SetFocus() called recursively on same element");
00522     return;
00523   }
00524   mInSetFocus = PR_TRUE;
00525   nsGenericHTMLElement::SetFocus(aPresContext);
00526   mInSetFocus = PR_FALSE;
00527 }
00528 
00529 PRBool
00530 nsHTMLSharedElement::IsFocusable(PRInt32 *aTabIndex)
00531 {
00532   if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
00533     // Let plugin decide whether it wants focus from mouse clicks
00534     if (aTabIndex) {
00535       GetTabIndex(aTabIndex);
00536     }
00537     return PR_TRUE;
00538   }
00539 
00540   return nsGenericHTMLElement::IsFocusable(aTabIndex);
00541 }