Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/SVGScriptElement.cpp
Line
Count
Source (jump to first uncovered line)
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 "nsGkAtoms.h"
8
#include "nsNetUtil.h"
9
#include "nsContentUtils.h"
10
#include "mozilla/dom/SVGScriptElement.h"
11
#include "mozilla/dom/SVGScriptElementBinding.h"
12
#include "nsIScriptError.h"
13
14
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT_CHECK_PARSER(Script)
15
16
namespace mozilla {
17
namespace dom {
18
19
JSObject*
20
SVGScriptElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
21
0
{
22
0
  return SVGScriptElement_Binding::Wrap(aCx, this, aGivenProto);
23
0
}
24
25
nsSVGElement::StringInfo SVGScriptElement::sStringInfo[2] =
26
{
27
  { &nsGkAtoms::href, kNameSpaceID_None, false },
28
  { &nsGkAtoms::href, kNameSpaceID_XLink, false }
29
};
30
31
//----------------------------------------------------------------------
32
// nsISupports methods
33
34
NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement, SVGScriptElementBase,
35
                            nsIScriptLoaderObserver,
36
                            nsIScriptElement, nsIMutationObserver)
37
38
//----------------------------------------------------------------------
39
// Implementation
40
41
SVGScriptElement::SVGScriptElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
42
                                   FromParser aFromParser)
43
  : SVGScriptElementBase(std::move(aNodeInfo))
44
  , ScriptElement(aFromParser)
45
0
{
46
0
  AddMutationObserver(this);
47
0
}
48
49
SVGScriptElement::~SVGScriptElement()
50
0
{
51
0
}
52
53
//----------------------------------------------------------------------
54
// nsINode methods
55
56
nsresult
57
SVGScriptElement::Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const
58
0
{
59
0
  *aResult = nullptr;
60
0
61
0
  SVGScriptElement* it =
62
0
    new SVGScriptElement(do_AddRef(aNodeInfo), NOT_FROM_PARSER);
63
0
64
0
  nsCOMPtr<nsINode> kungFuDeathGrip = it;
65
0
  nsresult rv1 = it->Init();
66
0
  nsresult rv2 = const_cast<SVGScriptElement*>(this)->CopyInnerTo(it);
67
0
  NS_ENSURE_SUCCESS(rv1, rv1);
68
0
  NS_ENSURE_SUCCESS(rv2, rv2);
69
0
70
0
  // The clone should be marked evaluated if we are.
71
0
  it->mAlreadyStarted = mAlreadyStarted;
72
0
  it->mLineNumber = mLineNumber;
73
0
  it->mMalformed = mMalformed;
74
0
75
0
  kungFuDeathGrip.swap(*aResult);
76
0
77
0
  return NS_OK;
78
0
}
79
80
//----------------------------------------------------------------------
81
void
82
SVGScriptElement::GetType(nsAString & aType)
83
0
{
84
0
  GetScriptType(aType);
85
0
}
86
87
void
88
SVGScriptElement::SetType(const nsAString & aType, ErrorResult& rv)
89
0
{
90
0
  rv = SetAttr(kNameSpaceID_None, nsGkAtoms::type, aType, true);
91
0
}
92
93
void
94
SVGScriptElement::GetCrossOrigin(nsAString & aCrossOrigin)
95
0
{
96
0
  // Null for both missing and invalid defaults is ok, since we
97
0
  // always parse to an enum value, so we don't need an invalid
98
0
  // default, and we _want_ the missing default to be null.
99
0
  GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aCrossOrigin);
100
0
}
101
102
void
103
SVGScriptElement::SetCrossOrigin(const nsAString & aCrossOrigin,
104
                                 ErrorResult& aError)
105
0
{
106
0
  SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
107
0
}
108
109
already_AddRefed<SVGAnimatedString>
110
SVGScriptElement::Href()
111
0
{
112
0
  return mStringAttributes[HREF].IsExplicitlySet()
113
0
         ? mStringAttributes[HREF].ToDOMAnimatedString(this)
114
0
         : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this);
115
0
}
116
117
//----------------------------------------------------------------------
118
// nsIScriptElement methods
119
120
bool
121
SVGScriptElement::GetScriptType(nsAString& type)
122
0
{
123
0
  return GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
124
0
}
125
126
void
127
SVGScriptElement::GetScriptText(nsAString& text)
128
0
{
129
0
  nsContentUtils::GetNodeTextContent(this, false, text);
130
0
}
131
132
void
133
SVGScriptElement::GetScriptCharset(nsAString& charset)
134
0
{
135
0
  charset.Truncate();
136
0
}
137
138
void
139
SVGScriptElement::FreezeExecutionAttrs(nsIDocument* aOwnerDoc)
140
0
{
141
0
  if (mFrozen) {
142
0
    return;
143
0
  }
144
0
145
0
  if (mStringAttributes[HREF].IsExplicitlySet() ||
146
0
      mStringAttributes[XLINK_HREF].IsExplicitlySet()) {
147
0
    // variation of this code in nsHTMLScriptElement - check if changes
148
0
    // need to be transferred when modifying
149
0
    bool isHref = false;
150
0
    nsAutoString src;
151
0
    if (mStringAttributes[HREF].IsExplicitlySet()) {
152
0
      mStringAttributes[HREF].GetAnimValue(src, this);
153
0
      isHref = true;
154
0
    } else {
155
0
      mStringAttributes[XLINK_HREF].GetAnimValue(src, this);
156
0
    }
157
0
158
0
    // Empty src should be treated as invalid URL.
159
0
    if (!src.IsEmpty()) {
160
0
      nsCOMPtr<nsIURI> baseURI = GetBaseURI();
161
0
      NS_NewURI(getter_AddRefs(mUri), src, nullptr, baseURI);
162
0
163
0
      if (!mUri) {
164
0
        const char16_t* params[] = { isHref ? u"href" : u"xlink:href", src.get() };
165
0
166
0
        nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
167
0
          NS_LITERAL_CSTRING("SVG"), OwnerDoc(),
168
0
          nsContentUtils::eDOM_PROPERTIES, "ScriptSourceInvalidUri",
169
0
          params, ArrayLength(params), nullptr,
170
0
          EmptyString(), GetScriptLineNumber(), GetScriptColumnNumber());
171
0
      }
172
0
    } else {
173
0
      const char16_t* params[] = { isHref ? u"href" : u"xlink:href" };
174
0
175
0
      nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
176
0
        NS_LITERAL_CSTRING("SVG"), OwnerDoc(),
177
0
        nsContentUtils::eDOM_PROPERTIES, "ScriptSourceEmpty",
178
0
        params, ArrayLength(params), nullptr,
179
0
        EmptyString(), GetScriptLineNumber(), GetScriptColumnNumber());
180
0
    }
181
0
182
0
    // At this point mUri will be null for invalid URLs.
183
0
    mExternal = true;
184
0
  }
185
0
186
0
  mFrozen = true;
187
0
}
188
189
//----------------------------------------------------------------------
190
// ScriptElement methods
191
192
bool
193
SVGScriptElement::HasScriptContent()
194
0
{
195
0
  return (mFrozen ? mExternal
196
0
                  : mStringAttributes[HREF].IsExplicitlySet() ||
197
0
                    mStringAttributes[XLINK_HREF].IsExplicitlySet()) ||
198
0
         nsContentUtils::HasNonEmptyTextContent(this);
199
0
}
200
201
//----------------------------------------------------------------------
202
// nsSVGElement methods
203
204
nsSVGElement::StringAttributesInfo
205
SVGScriptElement::GetStringInfo()
206
0
{
207
0
  return StringAttributesInfo(mStringAttributes, sStringInfo,
208
0
                              ArrayLength(sStringInfo));
209
0
}
210
211
//----------------------------------------------------------------------
212
// nsIContent methods
213
214
nsresult
215
SVGScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
216
                             nsIContent* aBindingParent)
217
0
{
218
0
  nsresult rv = SVGScriptElementBase::BindToTree(aDocument, aParent,
219
0
                                                 aBindingParent);
220
0
  NS_ENSURE_SUCCESS(rv, rv);
221
0
222
0
  if (aDocument) {
223
0
    MaybeProcessScript();
224
0
  }
225
0
226
0
  return NS_OK;
227
0
}
228
229
nsresult
230
SVGScriptElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
231
                               const nsAttrValue* aValue,
232
                               const nsAttrValue* aOldValue,
233
                               nsIPrincipal* aSubjectPrincipal,
234
                               bool aNotify)
235
0
{
236
0
  if ((aNamespaceID == kNameSpaceID_XLink ||
237
0
       aNamespaceID == kNameSpaceID_None) &&
238
0
      aName == nsGkAtoms::href) {
239
0
    MaybeProcessScript();
240
0
  }
241
0
  return SVGScriptElementBase::AfterSetAttr(aNamespaceID, aName,
242
0
                                            aValue, aOldValue,
243
0
                                            aSubjectPrincipal, aNotify);
244
0
}
245
246
bool
247
SVGScriptElement::ParseAttribute(int32_t aNamespaceID,
248
                                 nsAtom* aAttribute,
249
                                 const nsAString& aValue,
250
                                 nsIPrincipal* aMaybeScriptedPrincipal,
251
                                 nsAttrValue& aResult)
252
0
{
253
0
  if (aNamespaceID == kNameSpaceID_None &&
254
0
      aAttribute == nsGkAtoms::crossorigin) {
255
0
    ParseCORSValue(aValue, aResult);
256
0
    return true;
257
0
  }
258
0
259
0
  return SVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute,
260
0
                                              aValue,
261
0
                                              aMaybeScriptedPrincipal,
262
0
                                              aResult);
263
0
}
264
265
CORSMode
266
SVGScriptElement::GetCORSMode() const
267
0
{
268
0
  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
269
0
}
270
271
} // namespace dom
272
} // namespace mozilla