LCOV - code coverage report
Current view: top level - dom/base - nsStyledElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 38 87 43.7 %
Date: 2017-07-14 16:53:18 Functions: 6 9 66.7 %
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 "nsStyledElement.h"
       8             : #include "mozAutoDocUpdate.h"
       9             : #include "nsGkAtoms.h"
      10             : #include "nsAttrValue.h"
      11             : #include "nsAttrValueInlines.h"
      12             : #include "mozilla/dom/ElementInlines.h"
      13             : #include "mozilla/InternalMutationEvent.h"
      14             : #include "nsDOMCSSDeclaration.h"
      15             : #include "nsDOMCSSAttrDeclaration.h"
      16             : #include "nsServiceManagerUtils.h"
      17             : #include "nsIDocument.h"
      18             : #include "mozilla/DeclarationBlockInlines.h"
      19             : #include "nsCSSParser.h"
      20             : #include "mozilla/css/Loader.h"
      21             : #include "nsIDOMMutationEvent.h"
      22             : #include "nsXULElement.h"
      23             : #include "nsContentUtils.h"
      24             : #include "nsStyleUtil.h"
      25             : 
      26             : using namespace mozilla;
      27             : using namespace mozilla::dom;
      28             : 
      29        2354 : NS_IMPL_QUERY_INTERFACE_INHERITED(nsStyledElement,
      30             :                                   nsStyledElementBase,
      31             :                                   nsStyledElement)
      32             : 
      33             : //----------------------------------------------------------------------
      34             : // nsIContent methods
      35             : 
      36             : bool
      37        1190 : nsStyledElement::ParseAttribute(int32_t aNamespaceID,
      38             :                                 nsIAtom* aAttribute,
      39             :                                 const nsAString& aValue,
      40             :                                 nsAttrValue& aResult)
      41             : {
      42        1190 :   if (aAttribute == nsGkAtoms::style && aNamespaceID == kNameSpaceID_None) {
      43           0 :     ParseStyleAttribute(aValue, aResult, false);
      44           0 :     return true;
      45             :   }
      46             : 
      47        1190 :   return nsStyledElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
      48        1190 :                                              aResult);
      49             : }
      50             : 
      51             : nsresult
      52        1548 : nsStyledElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
      53             :                                const nsAttrValueOrString* aValue, bool aNotify)
      54             : {
      55        1548 :   if (aNamespaceID == kNameSpaceID_None) {
      56        1468 :     if (aName == nsGkAtoms::style) {
      57           0 :       if (aValue) {
      58           0 :         SetMayHaveStyle();
      59             :       }
      60             :     }
      61             :   }
      62             : 
      63        1548 :   return nsStyledElementBase::BeforeSetAttr(aNamespaceID, aName, aValue,
      64        1548 :                                             aNotify);
      65             : }
      66             : 
      67             : nsresult
      68           9 : nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
      69             :                                            const nsAString* aSerialized,
      70             :                                            bool aNotify)
      71             : {
      72           9 :   SetMayHaveStyle();
      73           9 :   bool modification = false;
      74          18 :   nsAttrValue oldValue;
      75           9 :   bool oldValueSet = false;
      76             : 
      77          14 :   bool hasListeners = aNotify &&
      78           5 :     nsContentUtils::HasMutationListeners(this,
      79             :                                          NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
      80           9 :                                          this);
      81             : 
      82             :   // There's no point in comparing the stylerule pointers since we're always
      83             :   // getting a new stylerule here. And we can't compare the stringvalues of
      84             :   // the old and the new rules since both will point to the same declaration
      85             :   // and thus will be the same.
      86           9 :   if (hasListeners) {
      87             :     // save the old attribute so we can set up the mutation event properly
      88           0 :     nsAutoString oldValueStr;
      89           0 :     modification = GetAttr(kNameSpaceID_None, nsGkAtoms::style,
      90           0 :                            oldValueStr);
      91           0 :     if (modification) {
      92           0 :       oldValue.SetTo(oldValueStr);
      93           0 :       oldValueSet = true;
      94             :     }
      95             :   }
      96           9 :   else if (aNotify && IsInUncomposedDoc()) {
      97           5 :     modification = !!mAttrsAndChildren.GetAttr(nsGkAtoms::style);
      98             :   }
      99             : 
     100          18 :   nsAttrValue attrValue(do_AddRef(aDeclaration), aSerialized);
     101             : 
     102             :   // XXXbz do we ever end up with ADDITION here?  I doubt it.
     103           9 :   uint8_t modType = modification ?
     104             :     static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) :
     105           9 :     static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
     106             : 
     107           9 :   nsIDocument* document = GetComposedDoc();
     108          18 :   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
     109           9 :   return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr,
     110             :                           oldValueSet ? &oldValue : nullptr, attrValue, modType,
     111             :                           hasListeners, aNotify, kDontCallAfterSetAttr,
     112          18 :                           document, updateBatch);
     113             : }
     114             : 
     115             : // ---------------------------------------------------------------
     116             : // Others and helpers
     117             : 
     118             : nsICSSDeclaration*
     119          19 : nsStyledElement::Style()
     120             : {
     121          19 :   Element::nsDOMSlots *slots = DOMSlots();
     122             : 
     123          19 :   if (!slots->mStyle) {
     124             :     // Just in case...
     125           5 :     ReparseStyleAttribute(true, false);
     126             : 
     127           5 :     slots->mStyle = new nsDOMCSSAttributeDeclaration(this, false);
     128           5 :     SetMayHaveStyle();
     129             :   }
     130             : 
     131          19 :   return slots->mStyle;
     132             : }
     133             : 
     134             : nsresult
     135           5 : nsStyledElement::ReparseStyleAttribute(bool aForceInDataDoc, bool aForceIfAlreadyParsed)
     136             : {
     137           5 :   if (!MayHaveStyle()) {
     138           5 :     return NS_OK;
     139             :   }
     140           0 :   const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
     141           0 :   if (oldVal && (aForceIfAlreadyParsed || oldVal->Type() != nsAttrValue::eCSSDeclaration)) {
     142           0 :     nsAttrValue attrValue;
     143           0 :     nsAutoString stringValue;
     144           0 :     oldVal->ToString(stringValue);
     145           0 :     ParseStyleAttribute(stringValue, attrValue, aForceInDataDoc);
     146             :     // Don't bother going through SetInlineStyleDeclaration; we don't
     147             :     // want to fire off mutation events or document notifications anyway
     148             :     bool oldValueSet;
     149           0 :     nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue,
     150           0 :                                                    &oldValueSet);
     151           0 :     NS_ENSURE_SUCCESS(rv, rv);
     152             :   }
     153             : 
     154           0 :   return NS_OK;
     155             : }
     156             : 
     157             : void
     158           0 : nsStyledElement::NodeInfoChanged(nsIDocument* aOldDoc)
     159             : {
     160           0 :   nsStyledElementBase::NodeInfoChanged(aOldDoc);
     161           0 :   if (OwnerDoc()->GetStyleBackendType() != aOldDoc->GetStyleBackendType()) {
     162           0 :     ReparseStyleAttribute(false, /* aForceIfAlreadyParsed */ true);
     163             :   }
     164           0 : }
     165             : 
     166             : nsICSSDeclaration*
     167           0 : nsStyledElement::GetExistingStyle()
     168             : {
     169           0 :   Element::nsDOMSlots* slots = GetExistingDOMSlots();
     170           0 :   if (!slots) {
     171           0 :     return nullptr;
     172             :   }
     173             : 
     174           0 :   return slots->mStyle;
     175             : }
     176             : 
     177             : void
     178           0 : nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
     179             :                                      nsAttrValue& aResult,
     180             :                                      bool aForceInDataDoc)
     181             : {
     182           0 :   nsIDocument* doc = OwnerDoc();
     183           0 :   bool isNativeAnon = IsInNativeAnonymousSubtree();
     184             : 
     185           0 :   if (!isNativeAnon &&
     186           0 :       !nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(),
     187             :                                          doc->GetDocumentURI(), 0, aValue,
     188             :                                          nullptr))
     189           0 :     return;
     190             : 
     191           0 :   if (aForceInDataDoc ||
     192           0 :       !doc->IsLoadedAsData() ||
     193           0 :       GetExistingStyle() ||
     194           0 :       doc->IsStaticDocument()) {
     195           0 :     bool isCSS = true; // assume CSS until proven otherwise
     196             : 
     197           0 :     if (!isNativeAnon) {  // native anonymous content always assumes CSS
     198           0 :       nsAutoString styleType;
     199           0 :       doc->GetHeaderData(nsGkAtoms::headerContentStyleType, styleType);
     200           0 :       if (!styleType.IsEmpty()) {
     201             :         static const char textCssStr[] = "text/css";
     202           0 :         isCSS = (styleType.EqualsIgnoreCase(textCssStr, sizeof(textCssStr) - 1));
     203             :       }
     204             :     }
     205             : 
     206           0 :     if (isCSS && aResult.ParseStyleAttribute(aValue, this)) {
     207           0 :       return;
     208             :     }
     209             :   }
     210             : 
     211           0 :   aResult.SetTo(aValue);
     212             : }

Generated by: LCOV version 1.13