LCOV - code coverage report
Current view: top level - dom/html - HTMLBodyElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 69 216 31.9 %
Date: 2017-07-14 16:53:18 Functions: 8 28 28.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "HTMLBodyElement.h"
       8             : #include "mozilla/dom/HTMLBodyElementBinding.h"
       9             : #include "mozilla/GenericSpecifiedValuesInlines.h"
      10             : #include "mozilla/TextEditor.h"
      11             : #include "nsAttrValueInlines.h"
      12             : #include "nsGkAtoms.h"
      13             : #include "nsStyleConsts.h"
      14             : #include "nsPresContext.h"
      15             : #include "nsIPresShell.h"
      16             : #include "nsIDocument.h"
      17             : #include "nsHTMLStyleSheet.h"
      18             : #include "nsIEditor.h"
      19             : #include "nsMappedAttributes.h"
      20             : #include "nsIDocShell.h"
      21             : #include "nsRuleWalker.h"
      22             : #include "nsGlobalWindow.h"
      23             : 
      24          14 : NS_IMPL_NS_NEW_HTML_ELEMENT(Body)
      25             : 
      26             : namespace mozilla {
      27             : namespace dom {
      28             : 
      29             : //----------------------------------------------------------------------
      30             : 
      31           0 : HTMLBodyElement::~HTMLBodyElement()
      32             : {
      33           0 : }
      34             : 
      35             : JSObject*
      36           1 : HTMLBodyElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
      37             : {
      38           1 :   return HTMLBodyElementBinding::Wrap(aCx, this, aGivenProto);
      39             : }
      40             : 
      41         106 : NS_IMPL_ISUPPORTS_INHERITED(HTMLBodyElement, nsGenericHTMLElement,
      42             :                             nsIDOMHTMLBodyElement)
      43             : 
      44           0 : NS_IMPL_ELEMENT_CLONE(HTMLBodyElement)
      45             : 
      46             : NS_IMETHODIMP
      47           0 : HTMLBodyElement::SetBackground(const nsAString& aBackground)
      48             : {
      49           0 :   ErrorResult rv;
      50           0 :   SetBackground(aBackground, rv);
      51           0 :   return rv.StealNSResult();
      52             : }
      53             : 
      54             : NS_IMETHODIMP
      55           0 : HTMLBodyElement::GetBackground(nsAString& aBackground)
      56             : {
      57           0 :   DOMString background;
      58           0 :   GetBackground(background);
      59           0 :   background.ToString(aBackground);
      60           0 :   return NS_OK;
      61             : }
      62             : 
      63             : NS_IMETHODIMP
      64           0 : HTMLBodyElement::SetVLink(const nsAString& aVLink)
      65             : {
      66           0 :   ErrorResult rv;
      67           0 :   SetVLink(aVLink, rv);
      68           0 :   return rv.StealNSResult();
      69             : }
      70             : 
      71             : NS_IMETHODIMP
      72           0 : HTMLBodyElement::GetVLink(nsAString& aVLink)
      73             : {
      74           0 :   DOMString vLink;
      75           0 :   GetVLink(vLink);
      76           0 :   vLink.ToString(aVLink);
      77           0 :   return NS_OK;
      78             : }
      79             : 
      80             : NS_IMETHODIMP
      81           0 : HTMLBodyElement::SetALink(const nsAString& aALink)
      82             : {
      83           0 :   ErrorResult rv;
      84           0 :   SetALink(aALink, rv);
      85           0 :   return rv.StealNSResult();
      86             : }
      87             : 
      88             : NS_IMETHODIMP
      89           0 : HTMLBodyElement::GetALink(nsAString& aALink)
      90             : {
      91           0 :   DOMString aLink;
      92           0 :   GetALink(aLink);
      93           0 :   aLink.ToString(aALink);
      94           0 :   return NS_OK;
      95             : }
      96             : 
      97             : NS_IMETHODIMP
      98           0 : HTMLBodyElement::SetLink(const nsAString& aLink)
      99             : {
     100           0 :   ErrorResult rv;
     101           0 :   SetLink(aLink, rv);
     102           0 :   return rv.StealNSResult();
     103             : }
     104             : 
     105             : NS_IMETHODIMP
     106           0 : HTMLBodyElement::GetLink(nsAString& aLink)
     107             : {
     108           0 :   DOMString link;
     109           0 :   GetLink(link);
     110           0 :   link.ToString(aLink);
     111           0 :   return NS_OK;
     112             : }
     113             : 
     114             : NS_IMETHODIMP
     115           0 : HTMLBodyElement::SetText(const nsAString& aText)
     116             : {
     117           0 :   ErrorResult rv;
     118           0 :   SetText(aText, rv);
     119           0 :   return rv.StealNSResult();
     120             : }
     121             : 
     122             : NS_IMETHODIMP
     123           0 : HTMLBodyElement::GetText(nsAString& aText)
     124             : {
     125           0 :   DOMString text;
     126           0 :   GetText(text);
     127           0 :   text.ToString(aText);
     128           0 :   return NS_OK;
     129             : }
     130             : 
     131             : NS_IMETHODIMP
     132           0 : HTMLBodyElement::SetBgColor(const nsAString& aBgColor)
     133             : {
     134           0 :   ErrorResult rv;
     135           0 :   SetBgColor(aBgColor, rv);
     136           0 :   return rv.StealNSResult();
     137             : }
     138             : 
     139             : NS_IMETHODIMP
     140           0 : HTMLBodyElement::GetBgColor(nsAString& aBgColor)
     141             : {
     142           0 :   DOMString bgColor;
     143           0 :   GetBgColor(bgColor);
     144           0 :   bgColor.ToString(aBgColor);
     145           0 :   return NS_OK;
     146             : }
     147             : 
     148             : bool
     149           0 : HTMLBodyElement::ParseAttribute(int32_t aNamespaceID,
     150             :                                 nsIAtom* aAttribute,
     151             :                                 const nsAString& aValue,
     152             :                                 nsAttrValue& aResult)
     153             : {
     154           0 :   if (aNamespaceID == kNameSpaceID_None) {
     155           0 :     if (aAttribute == nsGkAtoms::bgcolor ||
     156           0 :         aAttribute == nsGkAtoms::text ||
     157           0 :         aAttribute == nsGkAtoms::link ||
     158           0 :         aAttribute == nsGkAtoms::alink ||
     159           0 :         aAttribute == nsGkAtoms::vlink) {
     160           0 :       return aResult.ParseColor(aValue);
     161             :     }
     162           0 :     if (aAttribute == nsGkAtoms::marginwidth ||
     163           0 :         aAttribute == nsGkAtoms::marginheight ||
     164           0 :         aAttribute == nsGkAtoms::topmargin ||
     165           0 :         aAttribute == nsGkAtoms::bottommargin ||
     166           0 :         aAttribute == nsGkAtoms::leftmargin ||
     167           0 :         aAttribute == nsGkAtoms::rightmargin) {
     168           0 :       return aResult.ParseIntWithBounds(aValue, 0);
     169             :     }
     170             :   }
     171             : 
     172           0 :   return nsGenericHTMLElement::ParseBackgroundAttribute(aNamespaceID,
     173             :                                                         aAttribute, aValue,
     174           0 :                                                         aResult) ||
     175           0 :          nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
     176           0 :                                               aResult);
     177             : }
     178             : 
     179             : void
     180          51 : HTMLBodyElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
     181             :                                        GenericSpecifiedValues* aData)
     182             : {
     183          51 :   if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)) {
     184             : 
     185             :     // This is the one place where we try to set the same property
     186             :     // multiple times in presentation attributes. Servo does not support
     187             :     // querying if a property is set (because that is O(n) behavior
     188             :     // in ServoSpecifiedValues). Instead, we use the below values to keep
     189             :     // track of whether we have already set a property, and if so, what value
     190             :     // we set it to (which is used when handling margin
     191             :     // attributes from the containing frame element)
     192             : 
     193           3 :     int32_t bodyMarginWidth  = -1;
     194           3 :     int32_t bodyMarginHeight = -1;
     195           3 :     int32_t bodyTopMargin = -1;
     196           3 :     int32_t bodyBottomMargin = -1;
     197           3 :     int32_t bodyLeftMargin = -1;
     198           3 :     int32_t bodyRightMargin = -1;
     199             : 
     200             :     // check the mode (fortunately, the GenericSpecifiedValues has a presContext for us to use!)
     201           3 :     NS_ASSERTION(aData->mPresContext, "null presContext in MapAttributesIntoRule was unexpected");
     202           3 :     nsCompatibility mode = aData->mPresContext->CompatibilityMode();
     203             : 
     204             : 
     205             :     const nsAttrValue* value;
     206             :     // if marginwidth/marginheight are set, reflect them as 'margin'
     207           3 :     value = aAttributes->GetAttr(nsGkAtoms::marginwidth);
     208           3 :     if (value && value->Type() == nsAttrValue::eInteger) {
     209           0 :       bodyMarginWidth = value->GetIntegerValue();
     210           0 :       if (bodyMarginWidth < 0) {
     211           0 :         bodyMarginWidth = 0;
     212             :       }
     213           0 :       aData->SetPixelValueIfUnset(eCSSProperty_margin_left, (float)bodyMarginWidth);
     214           0 :       aData->SetPixelValueIfUnset(eCSSProperty_margin_right, (float)bodyMarginWidth);
     215             :     }
     216             : 
     217           3 :     value = aAttributes->GetAttr(nsGkAtoms::marginheight);
     218           3 :     if (value && value->Type() == nsAttrValue::eInteger) {
     219           0 :       bodyMarginHeight = value->GetIntegerValue();
     220           0 :       if (bodyMarginHeight < 0) {
     221           0 :         bodyMarginHeight = 0;
     222             :       }
     223           0 :       aData->SetPixelValueIfUnset(eCSSProperty_margin_top, (float)bodyMarginHeight);
     224           0 :       aData->SetPixelValueIfUnset(eCSSProperty_margin_bottom, (float)bodyMarginHeight);
     225             :     }
     226             : 
     227             :       // topmargin (IE-attribute)
     228           3 :     if (bodyMarginHeight == -1) {
     229           3 :       value = aAttributes->GetAttr(nsGkAtoms::topmargin);
     230           3 :       if (value && value->Type() == nsAttrValue::eInteger) {
     231           0 :         bodyTopMargin = value->GetIntegerValue();
     232           0 :         if (bodyTopMargin < 0) {
     233           0 :           bodyTopMargin = 0;
     234             :         }
     235           0 :         aData->SetPixelValueIfUnset(eCSSProperty_margin_top, (float)bodyTopMargin);
     236             :       }
     237             :     }
     238             :       // bottommargin (IE-attribute)
     239             : 
     240           3 :     if (bodyMarginHeight == -1) {
     241           3 :       value = aAttributes->GetAttr(nsGkAtoms::bottommargin);
     242           3 :       if (value && value->Type() == nsAttrValue::eInteger) {
     243           0 :         bodyBottomMargin = value->GetIntegerValue();
     244           0 :         if (bodyBottomMargin < 0) {
     245           0 :           bodyBottomMargin = 0;
     246             :         }
     247           0 :         aData->SetPixelValueIfUnset(eCSSProperty_margin_bottom, (float)bodyBottomMargin);
     248             :       }
     249             :     }
     250             : 
     251             :       // leftmargin (IE-attribute)
     252           3 :     if (bodyMarginWidth == -1) {
     253           3 :       value = aAttributes->GetAttr(nsGkAtoms::leftmargin);
     254           3 :       if (value && value->Type() == nsAttrValue::eInteger) {
     255           0 :         bodyLeftMargin = value->GetIntegerValue();
     256           0 :         if (bodyLeftMargin < 0) {
     257           0 :           bodyLeftMargin = 0;
     258             :         }
     259           0 :         aData->SetPixelValueIfUnset(eCSSProperty_margin_left, (float)bodyLeftMargin);
     260             :       }
     261             :     }
     262             :       // rightmargin (IE-attribute)
     263           3 :     if (bodyMarginWidth == -1) {
     264           3 :       value = aAttributes->GetAttr(nsGkAtoms::rightmargin);
     265           3 :       if (value && value->Type() == nsAttrValue::eInteger) {
     266           0 :         bodyRightMargin = value->GetIntegerValue();
     267           0 :         if (bodyRightMargin < 0) {
     268           0 :           bodyRightMargin = 0;
     269             :         }
     270           0 :         aData->SetPixelValueIfUnset(eCSSProperty_margin_right, (float)bodyRightMargin);
     271             :       }
     272             :     }
     273             : 
     274             :     // if marginwidth or marginheight is set in the <frame> and not set in the <body>
     275             :     // reflect them as margin in the <body>
     276           3 :     if (bodyMarginWidth == -1 || bodyMarginHeight == -1) {
     277           6 :       nsCOMPtr<nsIDocShell> docShell(aData->mPresContext->GetDocShell());
     278           3 :       if (docShell) {
     279           3 :         nscoord frameMarginWidth=-1;  // default value
     280           3 :         nscoord frameMarginHeight=-1; // default value
     281           3 :         docShell->GetMarginWidth(&frameMarginWidth); // -1 indicates not set
     282           3 :         docShell->GetMarginHeight(&frameMarginHeight);
     283           3 :         if (frameMarginWidth >= 0 && bodyMarginWidth == -1) { // set in <frame> & not in <body>
     284           0 :           if (eCompatibility_NavQuirks == mode) {
     285           0 :             if (bodyMarginHeight == -1 && 0 > frameMarginHeight) { // nav quirk
     286           0 :               frameMarginHeight = 0;
     287             :             }
     288             :           }
     289             :         }
     290           3 :         if (frameMarginHeight >= 0 && bodyMarginHeight == -1) { // set in <frame> & not in <body>
     291           0 :           if (eCompatibility_NavQuirks == mode) {
     292           0 :             if (bodyMarginWidth == -1 && 0 > frameMarginWidth) { // nav quirk
     293           0 :               frameMarginWidth = 0;
     294             :             }
     295             :           }
     296             :         }
     297             : 
     298           3 :         if (bodyMarginWidth == -1 && frameMarginWidth >= 0) {
     299           0 :           if (bodyLeftMargin == -1) {
     300           0 :             aData->SetPixelValueIfUnset(eCSSProperty_margin_left, (float)frameMarginWidth);
     301             :           }
     302           0 :           if (bodyRightMargin == -1) {
     303           0 :             aData->SetPixelValueIfUnset(eCSSProperty_margin_right, (float)frameMarginWidth);
     304             :           }
     305             :         }
     306             : 
     307           3 :         if (bodyMarginHeight == -1 && frameMarginHeight >= 0) {
     308           0 :           if (bodyTopMargin == -1) {
     309           0 :             aData->SetPixelValueIfUnset(eCSSProperty_margin_top, (float)frameMarginHeight);
     310             :           }
     311           0 :           if (bodyBottomMargin == -1) {
     312           0 :             aData->SetPixelValueIfUnset(eCSSProperty_margin_bottom, (float)frameMarginHeight);
     313             :           }
     314             :         }
     315             :       }
     316             :     }
     317             :   }
     318             : 
     319          51 :   if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Display))) {
     320             :     // When display if first asked for, go ahead and get our colors set up.
     321           3 :     nsIPresShell *presShell = aData->PresContext()->GetPresShell();
     322           3 :     if (presShell) {
     323           3 :       nsIDocument *doc = presShell->GetDocument();
     324           3 :       if (doc) {
     325           3 :         nsHTMLStyleSheet* styleSheet = doc->GetAttributeStyleSheet();
     326           3 :         if (styleSheet) {
     327             :           const nsAttrValue* value;
     328             :           nscolor color;
     329           3 :           value = aAttributes->GetAttr(nsGkAtoms::link);
     330           3 :           if (value && value->GetColorValue(color)) {
     331           0 :             styleSheet->SetLinkColor(color);
     332             :           }
     333             : 
     334           3 :           value = aAttributes->GetAttr(nsGkAtoms::alink);
     335           3 :           if (value && value->GetColorValue(color)) {
     336           0 :             styleSheet->SetActiveLinkColor(color);
     337             :           }
     338             : 
     339           3 :           value = aAttributes->GetAttr(nsGkAtoms::vlink);
     340           3 :           if (value && value->GetColorValue(color)) {
     341           0 :             styleSheet->SetVisitedLinkColor(color);
     342             :           }
     343             :         }
     344             :       }
     345             :     }
     346             :   }
     347             : 
     348          51 :   if (aData->ShouldComputeStyleStruct(NS_STYLE_INHERIT_BIT(Color))) {
     349           6 :     if (!aData->PropertyIsSet(eCSSProperty_color) &&
     350           3 :         aData->PresContext()->UseDocumentColors()) {
     351             :       // color: color
     352             :       nscolor color;
     353           3 :       const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::text);
     354           3 :       if (value && value->GetColorValue(color))
     355           0 :         aData->SetColorValue(eCSSProperty_color, color);
     356             :     }
     357             :   }
     358             : 
     359          51 :   nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
     360          51 :   nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
     361          51 : }
     362             : 
     363             : nsMapRuleToAttributesFunc
     364           7 : HTMLBodyElement::GetAttributeMappingFunction() const
     365             : {
     366           7 :   return &MapAttributesIntoRule;
     367             : }
     368             : 
     369             : NS_IMETHODIMP_(bool)
     370           0 : HTMLBodyElement::IsAttributeMapped(const nsIAtom* aAttribute) const
     371             : {
     372             :   static const MappedAttributeEntry attributes[] = {
     373             :     { &nsGkAtoms::link },
     374             :     { &nsGkAtoms::vlink },
     375             :     { &nsGkAtoms::alink },
     376             :     { &nsGkAtoms::text },
     377             :     { &nsGkAtoms::marginwidth },
     378             :     { &nsGkAtoms::marginheight },
     379             :     { &nsGkAtoms::topmargin },
     380             :     { &nsGkAtoms::rightmargin },
     381             :     { &nsGkAtoms::bottommargin },
     382             :     { &nsGkAtoms::leftmargin },
     383             :     { nullptr },
     384             :   };
     385             : 
     386             :   static const MappedAttributeEntry* const map[] = {
     387             :     attributes,
     388             :     sCommonAttributeMap,
     389             :     sBackgroundAttributeMap,
     390             :   };
     391             : 
     392           0 :   return FindAttributeDependence(aAttribute, map);
     393             : }
     394             : 
     395             : already_AddRefed<nsIEditor>
     396           0 : HTMLBodyElement::GetAssociatedEditor()
     397             : {
     398           0 :   RefPtr<TextEditor> textEditor = GetTextEditorInternal();
     399           0 :   if (textEditor) {
     400           0 :     return textEditor.forget();
     401             :   }
     402             : 
     403             :   // Make sure this is the actual body of the document
     404           0 :   if (!IsCurrentBodyElement()) {
     405           0 :     return nullptr;
     406             :   }
     407             : 
     408             :   // For designmode, try to get document's editor
     409           0 :   nsPresContext* presContext = GetPresContext(eForComposedDoc);
     410           0 :   if (!presContext) {
     411           0 :     return nullptr;
     412             :   }
     413             : 
     414           0 :   nsCOMPtr<nsIDocShell> docShell = presContext->GetDocShell();
     415           0 :   if (!docShell) {
     416           0 :     return nullptr;
     417             :   }
     418             : 
     419           0 :   nsCOMPtr<nsIEditor> editor;
     420           0 :   docShell->GetEditor(getter_AddRefs(editor));
     421           0 :   return editor.forget();
     422             : }
     423             : 
     424             : bool
     425           0 : HTMLBodyElement::IsEventAttributeNameInternal(nsIAtom *aName)
     426             : {
     427             :   return nsContentUtils::IsEventAttributeName(aName,
     428             :                                               EventNameType_HTML |
     429           0 :                                               EventNameType_HTMLBodyOrFramesetOnly);
     430             : }
     431             : 
     432             : nsresult
     433           7 : HTMLBodyElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
     434             :                             nsIContent* aBindingParent,
     435             :                             bool aCompileEventHandlers)
     436             : {
     437           7 :   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
     438             :                                                  aBindingParent,
     439           7 :                                                  aCompileEventHandlers);
     440           7 :   NS_ENSURE_SUCCESS(rv, rv);
     441           7 :   return mAttrsAndChildren.ForceMapped(this, OwnerDoc());
     442             : }
     443             : 
     444             : nsresult
     445           0 : HTMLBodyElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
     446             :                               const nsAttrValue* aValue,
     447             :                               const nsAttrValue* aOldValue, bool aNotify)
     448             : {
     449           0 :   nsresult rv = nsGenericHTMLElement::AfterSetAttr(aNameSpaceID,
     450             :                                                    aName, aValue, aOldValue,
     451           0 :                                                    aNotify);
     452           0 :   NS_ENSURE_SUCCESS(rv, rv);
     453             :   // if the last mapped attribute was removed, don't clear the
     454             :   // nsMappedAttributes, our style can still depend on the containing frame element
     455           0 :   if (!aValue && IsAttributeMapped(aName)) {
     456           0 :     nsresult rv = mAttrsAndChildren.ForceMapped(this, OwnerDoc());
     457           0 :     NS_ENSURE_SUCCESS(rv, rv);
     458             :   }
     459             : 
     460           0 :   return NS_OK;
     461             : }
     462             : 
     463             : #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the superclass */
     464             : // nsGenericHTMLElement::GetOnError returns
     465             : // already_AddRefed<EventHandlerNonNull> while other getters return
     466             : // EventHandlerNonNull*, so allow passing in the type to use here.
     467             : #define WINDOW_EVENT_HELPER(name_, type_)                                      \
     468             :   type_*                                                                       \
     469             :   HTMLBodyElement::GetOn##name_()                                              \
     470             :   {                                                                            \
     471             :     if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) {              \
     472             :       nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win);                   \
     473             :       return globalWin->GetOn##name_();                                        \
     474             :     }                                                                          \
     475             :     return nullptr;                                                            \
     476             :   }                                                                            \
     477             :   void                                                                         \
     478             :   HTMLBodyElement::SetOn##name_(type_* handler)                                \
     479             :   {                                                                            \
     480             :     nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow();                    \
     481             :     if (!win) {                                                                \
     482             :       return;                                                                  \
     483             :     }                                                                          \
     484             :                                                                                \
     485             :     nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win);                     \
     486             :     return globalWin->SetOn##name_(handler);                                   \
     487             :   }
     488             : #define WINDOW_EVENT(name_, id_, type_, struct_)                               \
     489             :   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
     490             : #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
     491             :   WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
     492             : #include "mozilla/EventNameList.h" // IWYU pragma: keep
     493             : #undef BEFOREUNLOAD_EVENT
     494             : #undef WINDOW_EVENT
     495             : #undef WINDOW_EVENT_HELPER
     496             : #undef EVENT
     497             : 
     498             : } // namespace dom
     499             : } // namespace mozilla

Generated by: LCOV version 1.13