/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 sw=2 et tw=78: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsGkAtoms.h" #include "nsNetUtil.h" #include "nsContentUtils.h" #include "mozilla/dom/SVGScriptElement.h" #include "mozilla/dom/SVGScriptElementBinding.h" NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT_CHECK_PARSER(Script) namespace mozilla { namespace dom { JSObject* SVGScriptElement::WrapNode(JSContext *aCx) { return SVGScriptElementBinding::Wrap(aCx, this); } nsSVGElement::StringInfo SVGScriptElement::sStringInfo[1] = { { &nsGkAtoms::href, kNameSpaceID_XLink, false } }; //---------------------------------------------------------------------- // nsISupports methods NS_IMPL_ISUPPORTS_INHERITED(SVGScriptElement, SVGScriptElementBase, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIScriptLoaderObserver, nsIScriptElement, nsIMutationObserver) //---------------------------------------------------------------------- // Implementation SVGScriptElement::SVGScriptElement(already_AddRefed& aNodeInfo, FromParser aFromParser) : SVGScriptElementBase(aNodeInfo) , nsScriptElement(aFromParser) { AddMutationObserver(this); } SVGScriptElement::~SVGScriptElement() { } //---------------------------------------------------------------------- // nsIDOMNode methods nsresult SVGScriptElement::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const { *aResult = nullptr; already_AddRefed ni = nsRefPtr(aNodeInfo).forget(); SVGScriptElement* it = new SVGScriptElement(ni, NOT_FROM_PARSER); nsCOMPtr kungFuDeathGrip = it; nsresult rv1 = it->Init(); nsresult rv2 = const_cast(this)->CopyInnerTo(it); NS_ENSURE_SUCCESS(rv1, rv1); NS_ENSURE_SUCCESS(rv2, rv2); // The clone should be marked evaluated if we are. it->mAlreadyStarted = mAlreadyStarted; it->mLineNumber = mLineNumber; it->mMalformed = mMalformed; kungFuDeathGrip.swap(*aResult); return NS_OK; } //---------------------------------------------------------------------- void SVGScriptElement::GetType(nsAString & aType) { GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType); } void SVGScriptElement::SetType(const nsAString & aType, ErrorResult& rv) { rv = SetAttr(kNameSpaceID_None, nsGkAtoms::type, aType, true); } void SVGScriptElement::GetCrossOrigin(nsAString & aCrossOrigin) { // Null for both missing and invalid defaults is ok, since we // always parse to an enum value, so we don't need an invalid // default, and we _want_ the missing default to be null. GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aCrossOrigin); } void SVGScriptElement::SetCrossOrigin(const nsAString & aCrossOrigin, ErrorResult& aError) { SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError); } already_AddRefed SVGScriptElement::Href() { return mStringAttributes[HREF].ToDOMAnimatedString(this); } //---------------------------------------------------------------------- // nsIScriptElement methods void SVGScriptElement::GetScriptType(nsAString& type) { GetType(type); } void SVGScriptElement::GetScriptText(nsAString& text) { if (!nsContentUtils::GetNodeTextContent(this, false, text)) { NS_RUNTIMEABORT("OOM"); } } void SVGScriptElement::GetScriptCharset(nsAString& charset) { charset.Truncate(); } void SVGScriptElement::FreezeUriAsyncDefer() { if (mFrozen) { return; } if (mStringAttributes[HREF].IsExplicitlySet()) { // variation of this code in nsHTMLScriptElement - check if changes // need to be transfered when modifying nsAutoString src; mStringAttributes[HREF].GetAnimValue(src, this); nsCOMPtr baseURI = GetBaseURI(); NS_NewURI(getter_AddRefs(mUri), src, nullptr, baseURI); // At this point mUri will be null for invalid URLs. mExternal = true; } mFrozen = true; } //---------------------------------------------------------------------- // nsScriptElement methods bool SVGScriptElement::HasScriptContent() { return (mFrozen ? mExternal : mStringAttributes[HREF].IsExplicitlySet()) || nsContentUtils::HasNonEmptyTextContent(this); } //---------------------------------------------------------------------- // nsSVGElement methods nsSVGElement::StringAttributesInfo SVGScriptElement::GetStringInfo() { return StringAttributesInfo(mStringAttributes, sStringInfo, ArrayLength(sStringInfo)); } //---------------------------------------------------------------------- // nsIContent methods nsresult SVGScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, bool aCompileEventHandlers) { nsresult rv = SVGScriptElementBase::BindToTree(aDocument, aParent, aBindingParent, aCompileEventHandlers); NS_ENSURE_SUCCESS(rv, rv); if (aDocument) { MaybeProcessScript(); } return NS_OK; } nsresult SVGScriptElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) { if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) { MaybeProcessScript(); } return SVGScriptElementBase::AfterSetAttr(aNamespaceID, aName, aValue, aNotify); } bool SVGScriptElement::ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult) { if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::crossorigin) { ParseCORSValue(aValue, aResult); return true; } return SVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue, aResult); } CORSMode SVGScriptElement::GetCORSMode() const { return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)); } } // namespace dom } // namespace mozilla