tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGStyleElement.cpp (7618B)


      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 "mozilla/dom/SVGStyleElement.h"
      8 
      9 #include "mozilla/RefPtr.h"
     10 #include "mozilla/dom/Document.h"
     11 #include "mozilla/dom/Element.h"
     12 #include "mozilla/dom/FetchPriority.h"
     13 #include "mozilla/dom/ReferrerInfo.h"
     14 #include "mozilla/dom/SVGStyleElementBinding.h"
     15 #include "nsCOMPtr.h"
     16 #include "nsContentUtils.h"
     17 
     18 NS_IMPL_NS_NEW_SVG_ELEMENT(Style)
     19 
     20 namespace mozilla::dom {
     21 
     22 JSObject* SVGStyleElement::WrapNode(JSContext* aCx,
     23                                    JS::Handle<JSObject*> aGivenProto) {
     24  return SVGStyleElement_Binding::Wrap(aCx, this, aGivenProto);
     25 }
     26 
     27 //----------------------------------------------------------------------
     28 // nsISupports methods
     29 
     30 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(SVGStyleElement,
     31                                             SVGStyleElementBase,
     32                                             nsIMutationObserver)
     33 
     34 NS_IMPL_CYCLE_COLLECTION_CLASS(SVGStyleElement)
     35 
     36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGStyleElement,
     37                                                  SVGStyleElementBase)
     38  tmp->LinkStyle::Traverse(cb);
     39 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     40 
     41 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGStyleElement,
     42                                                SVGStyleElementBase)
     43  tmp->LinkStyle::Unlink();
     44 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     45 
     46 //----------------------------------------------------------------------
     47 // Implementation
     48 
     49 SVGStyleElement::SVGStyleElement(
     50    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
     51    : SVGStyleElementBase(std::move(aNodeInfo)) {
     52  AddMutationObserver(this);
     53  SetEnabledCallbacks(kCharacterDataChanged | kContentAppended |
     54                      kContentInserted | kContentWillBeRemoved);
     55 }
     56 
     57 //----------------------------------------------------------------------
     58 // nsINode methods
     59 
     60 NS_IMPL_ELEMENT_CLONE(SVGStyleElement)
     61 
     62 //----------------------------------------------------------------------
     63 // nsIContent methods
     64 
     65 nsresult SVGStyleElement::BindToTree(BindContext& aContext, nsINode& aParent) {
     66  nsresult rv = SVGStyleElementBase::BindToTree(aContext, aParent);
     67  NS_ENSURE_SUCCESS(rv, rv);
     68  LinkStyle::BindToTree();
     69  return rv;
     70 }
     71 
     72 void SVGStyleElement::UnbindFromTree(UnbindContext& aContext) {
     73  nsCOMPtr<Document> oldDoc = GetUncomposedDoc();
     74  ShadowRoot* oldShadow = GetContainingShadow();
     75  SVGStyleElementBase::UnbindFromTree(aContext);
     76  (void)UpdateStyleSheetInternal(oldDoc, oldShadow);
     77 }
     78 
     79 void SVGStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
     80                                   const nsAttrValue* aValue,
     81                                   const nsAttrValue* aOldValue,
     82                                   nsIPrincipal* aMaybeScriptedPrincipal,
     83                                   bool aNotify) {
     84  if (aNameSpaceID == kNameSpaceID_None) {
     85    if (aName == nsGkAtoms::title || aName == nsGkAtoms::media ||
     86        aName == nsGkAtoms::type) {
     87      (void)UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
     88    }
     89  }
     90 
     91  return SVGStyleElementBase::AfterSetAttr(
     92      aNameSpaceID, aName, aValue, aOldValue, aMaybeScriptedPrincipal, aNotify);
     93 }
     94 
     95 bool SVGStyleElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
     96                                     const nsAString& aValue,
     97                                     nsIPrincipal* aMaybeScriptedPrincipal,
     98                                     nsAttrValue& aResult) {
     99  if (aNamespaceID == kNameSpaceID_None &&
    100      aAttribute == nsGkAtoms::crossorigin) {
    101    ParseCORSValue(aValue, aResult);
    102    return true;
    103  }
    104 
    105  return SVGStyleElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
    106                                             aMaybeScriptedPrincipal, aResult);
    107 }
    108 
    109 //----------------------------------------------------------------------
    110 // nsIMutationObserver methods
    111 
    112 void SVGStyleElement::CharacterDataChanged(nsIContent* aContent,
    113                                           const CharacterDataChangeInfo&) {
    114  ContentChanged(aContent);
    115 }
    116 
    117 void SVGStyleElement::ContentAppended(nsIContent* aFirstNewContent,
    118                                      const ContentAppendInfo&) {
    119  ContentChanged(aFirstNewContent->GetParent());
    120 }
    121 
    122 void SVGStyleElement::ContentInserted(nsIContent* aChild,
    123                                      const ContentInsertInfo&) {
    124  ContentChanged(aChild);
    125 }
    126 
    127 void SVGStyleElement::ContentWillBeRemoved(nsIContent* aChild,
    128                                           const ContentRemoveInfo& aInfo) {
    129  if (!nsContentUtils::IsInSameAnonymousTree(this, aChild)) {
    130    return;
    131  }
    132  if (aInfo.mBatchRemovalState && !aInfo.mBatchRemovalState->mIsFirst) {
    133    return;
    134  }
    135  // Make sure to run this once the removal has taken place.
    136  nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
    137      "SVGStyleElement::ContentWillBeRemoved",
    138      [self = RefPtr{this}] { self->UpdateStyleSheetInternal(); }));
    139 }
    140 
    141 void SVGStyleElement::ContentChanged(nsIContent* aContent) {
    142  if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
    143    (void)UpdateStyleSheetInternal(nullptr, nullptr);
    144  }
    145 }
    146 
    147 //----------------------------------------------------------------------
    148 
    149 void SVGStyleElement::GetMedia(nsAString& aMedia) {
    150  GetAttr(nsGkAtoms::media, aMedia);
    151 }
    152 
    153 void SVGStyleElement::SetMedia(const nsAString& aMedia, ErrorResult& rv) {
    154  SetAttr(nsGkAtoms::media, aMedia, rv);
    155 }
    156 
    157 void SVGStyleElement::GetType(nsAString& aType) {
    158  GetAttr(nsGkAtoms::type, aType);
    159 }
    160 
    161 void SVGStyleElement::SetType(const nsAString& aType, ErrorResult& rv) {
    162  SetAttr(nsGkAtoms::type, aType, rv);
    163 }
    164 
    165 void SVGStyleElement::GetTitle(nsAString& aTitle) {
    166  GetAttr(nsGkAtoms::title, aTitle);
    167 }
    168 
    169 void SVGStyleElement::SetTitle(const nsAString& aTitle, ErrorResult& rv) {
    170  SetAttr(nsGkAtoms::title, aTitle, rv);
    171 }
    172 
    173 bool SVGStyleElement::Disabled() const {
    174  StyleSheet* ss = GetSheet();
    175  return ss && ss->Disabled();
    176 }
    177 
    178 void SVGStyleElement::SetDisabled(bool aDisabled) {
    179  if (StyleSheet* ss = GetSheet()) {
    180    ss->SetDisabled(aDisabled);
    181  }
    182 }
    183 
    184 //----------------------------------------------------------------------
    185 // nsStyleLinkElement methods
    186 
    187 Maybe<LinkStyle::SheetInfo> SVGStyleElement::GetStyleSheetInfo() {
    188  if (!IsCSSMimeTypeAttributeForStyleElement(*this)) {
    189    return Nothing();
    190  }
    191 
    192  nsAutoString title;
    193  nsAutoString media;
    194  GetTitleAndMediaForElement(*this, title, media);
    195 
    196  return Some(SheetInfo{
    197      *OwnerDoc(),
    198      this,
    199      nullptr,
    200      // FIXME(bug 1459822): Why doesn't this need a principal, but
    201      // HTMLStyleElement does?
    202      nullptr,
    203      // FIXME(bug 1459822): Why does this need a crossorigin attribute, but
    204      // HTMLStyleElement doesn't?
    205      MakeAndAddRef<ReferrerInfo>(*this),
    206      AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)),
    207      title,
    208      media,
    209      /* integrity = */ u""_ns,
    210      /* nsStyleUtil::CSPAllowsInlineStyle takes care of nonce checking for
    211         inline styles. Bug 1607011 */
    212      /* nonce = */ u""_ns,
    213      HasAlternateRel::No,
    214      IsInline::Yes,
    215      IsExplicitlyEnabled::No,
    216      FetchPriority::Auto,
    217  });
    218 }
    219 
    220 nsresult SVGStyleElement::CopyInnerTo(SVGStyleElement* aDest) {
    221  nsresult rv = Element::CopyInnerTo(aDest);
    222  NS_ENSURE_SUCCESS(rv, rv);
    223  MaybeStartCopyStyleSheetTo(aDest, aDest->OwnerDoc());
    224  return NS_OK;
    225 }
    226 
    227 }  // namespace mozilla::dom