tor-browser

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

SVGScriptElement.cpp (7985B)


      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/SVGScriptElement.h"
      8 
      9 #include "mozilla/dom/Document.h"
     10 #include "mozilla/dom/FetchPriority.h"
     11 #include "mozilla/dom/SVGScriptElementBinding.h"
     12 #include "nsContentUtils.h"
     13 #include "nsGkAtoms.h"
     14 #include "nsIScriptError.h"
     15 #include "nsNetUtil.h"
     16 
     17 NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(Script)
     18 
     19 using JS::loader::ScriptKind;
     20 
     21 namespace mozilla::dom {
     22 
     23 JSObject* SVGScriptElement::WrapNode(JSContext* aCx,
     24                                     JS::Handle<JSObject*> aGivenProto) {
     25  return SVGScriptElement_Binding::Wrap(aCx, this, aGivenProto);
     26 }
     27 
     28 SVGElement::StringInfo SVGScriptElement::sStringInfo[2] = {
     29    {nsGkAtoms::href, kNameSpaceID_None, false},
     30    {nsGkAtoms::href, kNameSpaceID_XLink, false}};
     31 
     32 //----------------------------------------------------------------------
     33 // nsISupports methods
     34 
     35 NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement, SVGScriptElementBase,
     36                            nsIScriptLoaderObserver, nsIScriptElement,
     37                            nsIMutationObserver)
     38 
     39 //----------------------------------------------------------------------
     40 // Implementation
     41 
     42 SVGScriptElement::SVGScriptElement(
     43    already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     44    FromParser aFromParser)
     45    : SVGScriptElementBase(std::move(aNodeInfo)), ScriptElement(aFromParser) {
     46  AddMutationObserver(this);
     47 }
     48 
     49 //----------------------------------------------------------------------
     50 // nsINode methods
     51 
     52 nsresult SVGScriptElement::Clone(dom::NodeInfo* aNodeInfo,
     53                                 nsINode** aResult) const {
     54  *aResult = nullptr;
     55 
     56  SVGScriptElement* it = new (aNodeInfo->NodeInfoManager())
     57      SVGScriptElement(do_AddRef(aNodeInfo), NOT_FROM_PARSER);
     58 
     59  nsCOMPtr<nsINode> kungFuDeathGrip = it;
     60  nsresult rv1 = it->Init();
     61  nsresult rv2 = const_cast<SVGScriptElement*>(this)->CopyInnerTo(it);
     62  NS_ENSURE_SUCCESS(rv1, rv1);
     63  NS_ENSURE_SUCCESS(rv2, rv2);
     64 
     65  // The clone should be marked evaluated if we are.
     66  it->mAlreadyStarted = mAlreadyStarted;
     67  it->mLineNumber = mLineNumber;
     68  it->mMalformed = mMalformed;
     69 
     70  kungFuDeathGrip.swap(*aResult);
     71 
     72  return NS_OK;
     73 }
     74 
     75 //----------------------------------------------------------------------
     76 void SVGScriptElement::GetType(nsAString& aType) {
     77  GetAttr(nsGkAtoms::type, aType);
     78 }
     79 
     80 void SVGScriptElement::SetType(const nsAString& aType, ErrorResult& rv) {
     81  rv = SetAttr(kNameSpaceID_None, nsGkAtoms::type, aType, true);
     82 }
     83 
     84 void SVGScriptElement::GetCrossOrigin(nsAString& aCrossOrigin) {
     85  // Null for both missing and invalid defaults is ok, since we
     86  // always parse to an enum value, so we don't need an invalid
     87  // default, and we _want_ the missing default to be null.
     88  GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aCrossOrigin);
     89 }
     90 
     91 void SVGScriptElement::SetCrossOrigin(const nsAString& aCrossOrigin,
     92                                      ErrorResult& aError) {
     93  SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
     94 }
     95 
     96 already_AddRefed<DOMSVGAnimatedString> SVGScriptElement::Href() {
     97  return mStringAttributes[HREF].IsExplicitlySet() ||
     98                 !mStringAttributes[XLINK_HREF].IsExplicitlySet()
     99             ? mStringAttributes[HREF].ToDOMAnimatedString(this)
    100             : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
    101 }
    102 
    103 //----------------------------------------------------------------------
    104 // nsIScriptElement methods
    105 
    106 void SVGScriptElement::GetScriptText(nsAString& text) const {
    107  nsContentUtils::GetNodeTextContent(this, false, text);
    108 }
    109 
    110 void SVGScriptElement::GetScriptCharset(nsAString& charset) {
    111  charset.Truncate();
    112 }
    113 
    114 void SVGScriptElement::FreezeExecutionAttrs(const Document* aOwnerDoc) {
    115  if (mFrozen) {
    116    return;
    117  }
    118 
    119  // Determine whether this is a(n) classic/module/importmap script.
    120  DetermineKindFromType(aOwnerDoc);
    121 
    122  if (mStringAttributes[HREF].IsExplicitlySet() ||
    123      mStringAttributes[XLINK_HREF].IsExplicitlySet()) {
    124    // variation of this code in nsHTMLScriptElement - check if changes
    125    // need to be transferred when modifying
    126    bool isHref = false;
    127    nsAutoString src;
    128    if (mStringAttributes[HREF].IsExplicitlySet()) {
    129      mStringAttributes[HREF].GetAnimValue(src, this);
    130      isHref = true;
    131    } else {
    132      mStringAttributes[XLINK_HREF].GetAnimValue(src, this);
    133    }
    134 
    135    SourceLocation loc{OwnerDoc()->GetDocumentURI(), GetScriptLineNumber(),
    136                       GetScriptColumnNumber().oneOriginValue()};
    137    // Empty src should be treated as invalid URL.
    138    if (!src.IsEmpty()) {
    139      NS_NewURI(getter_AddRefs(mUri), src, nullptr, GetBaseURI());
    140 
    141      if (!mUri) {
    142        AutoTArray<nsString, 2> params = {
    143            isHref ? u"href"_ns : u"xlink:href"_ns, src};
    144 
    145        nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "SVG"_ns,
    146                                        OwnerDoc(),
    147                                        nsContentUtils::eDOM_PROPERTIES,
    148                                        "ScriptSourceInvalidUri", params, loc);
    149      }
    150    } else {
    151      AutoTArray<nsString, 1> params = {isHref ? u"href"_ns : u"xlink:href"_ns};
    152 
    153      nsContentUtils::ReportToConsole(
    154          nsIScriptError::warningFlag, "SVG"_ns, OwnerDoc(),
    155          nsContentUtils::eDOM_PROPERTIES, "ScriptSourceEmpty", params, loc);
    156    }
    157 
    158    // At this point mUri will be null for invalid URLs.
    159    mExternal = true;
    160  }
    161 
    162  bool async = (mExternal || mKind == ScriptKind::eModule) && Async();
    163  bool defer = mExternal && Defer();
    164 
    165  mDefer = !async && defer;
    166  mAsync = async;
    167 
    168  mFrozen = true;
    169 }
    170 
    171 //----------------------------------------------------------------------
    172 // ScriptElement methods
    173 bool SVGScriptElement::HasExternalScriptContent() {
    174  return mFrozen ? mExternal
    175                 : (mStringAttributes[HREF].IsExplicitlySet() ||
    176                    mStringAttributes[XLINK_HREF].IsExplicitlySet());
    177 }
    178 
    179 //----------------------------------------------------------------------
    180 // SVGElement methods
    181 
    182 SVGElement::StringAttributesInfo SVGScriptElement::GetStringInfo() {
    183  return StringAttributesInfo(mStringAttributes, sStringInfo,
    184                              std::size(sStringInfo));
    185 }
    186 
    187 //----------------------------------------------------------------------
    188 // nsIContent methods
    189 
    190 nsresult SVGScriptElement::BindToTree(BindContext& aContext, nsINode& aParent) {
    191  nsresult rv = SVGScriptElementBase::BindToTree(aContext, aParent);
    192  NS_ENSURE_SUCCESS(rv, rv);
    193 
    194  if (IsInComposedDoc()) {
    195    MaybeProcessScript(nullptr /* aParser */);
    196  }
    197 
    198  return NS_OK;
    199 }
    200 
    201 bool SVGScriptElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
    202                                      const nsAString& aValue,
    203                                      nsIPrincipal* aMaybeScriptedPrincipal,
    204                                      nsAttrValue& aResult) {
    205  if (aNamespaceID == kNameSpaceID_None) {
    206    if (aAttribute == nsGkAtoms::crossorigin) {
    207      ParseCORSValue(aValue, aResult);
    208      return true;
    209    }
    210    if (aAttribute == nsGkAtoms::fetchpriority) {
    211      ParseFetchPriority(aValue, aResult);
    212      return true;
    213    }
    214  }
    215 
    216  return SVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
    217                                              aMaybeScriptedPrincipal, aResult);
    218 }
    219 
    220 CORSMode SVGScriptElement::GetCORSMode() const {
    221  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
    222 }
    223 
    224 void SVGScriptElement::GetFetchPriority(nsAString& aFetchPriority) const {
    225  GetEnumAttr(nsGkAtoms::fetchpriority, kFetchPriorityAttributeValueAuto,
    226              aFetchPriority);
    227 }
    228 
    229 FetchPriority SVGScriptElement::GetFetchPriority() const {
    230  return Element::GetFetchPriority();
    231 }
    232 
    233 }  // namespace mozilla::dom