content/base/src/Attr.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  * Implementation of DOM Core's nsIDOMAttr node.
     8  */
    10 #include "mozilla/dom/Attr.h"
    11 #include "mozilla/dom/AttrBinding.h"
    12 #include "mozilla/dom/Element.h"
    13 #include "mozilla/EventDispatcher.h"
    14 #include "mozilla/InternalMutationEvent.h"
    15 #include "nsContentCreatorFunctions.h"
    16 #include "nsError.h"
    17 #include "nsUnicharUtils.h"
    18 #include "nsDOMString.h"
    19 #include "nsIContentInlines.h"
    20 #include "nsIDocument.h"
    21 #include "nsIDOMUserDataHandler.h"
    22 #include "nsGkAtoms.h"
    23 #include "nsCOMArray.h"
    24 #include "nsNameSpaceManager.h"
    25 #include "nsNodeUtils.h"
    26 #include "nsTextNode.h"
    27 #include "mozAutoDocUpdate.h"
    28 #include "nsWrapperCacheInlines.h"
    30 nsIAttribute::nsIAttribute(nsDOMAttributeMap* aAttrMap,
    31                            already_AddRefed<nsINodeInfo>& aNodeInfo,
    32                            bool aNsAware)
    33 : nsINode(aNodeInfo), mAttrMap(aAttrMap), mNsAware(aNsAware)
    34 {
    35 }
    37 nsIAttribute::~nsIAttribute()
    38 {
    39 }
    41 namespace mozilla {
    42 namespace dom {
    44 //----------------------------------------------------------------------
    45 bool Attr::sInitialized;
    47 Attr::Attr(nsDOMAttributeMap *aAttrMap,
    48            already_AddRefed<nsINodeInfo>&& aNodeInfo,
    49            const nsAString  &aValue, bool aNsAware)
    50   : nsIAttribute(aAttrMap, aNodeInfo, aNsAware), mValue(aValue)
    51 {
    52   NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
    53   NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ATTRIBUTE_NODE,
    54                     "Wrong nodeType");
    56   // We don't add a reference to our content. It will tell us
    57   // to drop our reference when it goes away.
    59   SetIsDOMBinding();
    60 }
    62 NS_IMPL_CYCLE_COLLECTION_CLASS(Attr)
    64 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Attr)
    65   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
    67   if (!nsINode::Traverse(tmp, cb)) {
    68     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
    69   }
    70   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAttrMap)
    71 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    73 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Attr)
    75 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Attr)
    76   nsINode::Unlink(tmp);
    77   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAttrMap)
    78 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    80 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(Attr)
    81   Element* ownerElement = tmp->GetElement();
    82   if (tmp->IsBlack()) {
    83     if (ownerElement) {
    84       // The attribute owns the element via attribute map so we can
    85       // mark it when the attribute is certainly alive.
    86       mozilla::dom::FragmentOrElement::MarkNodeChildren(ownerElement);
    87     }
    88     return true;
    89   }
    90   if (ownerElement &&
    91       mozilla::dom::FragmentOrElement::CanSkip(ownerElement, true)) {
    92     return true;
    93   }
    94 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
    96 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(Attr)
    97   return tmp->IsBlackAndDoesNotNeedTracing(static_cast<nsIAttribute*>(tmp));
    98 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
   100 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(Attr)
   101   return tmp->IsBlack();
   102 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
   104 // QueryInterface implementation for Attr
   105 NS_INTERFACE_TABLE_HEAD(Attr)
   106   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   107   NS_INTERFACE_TABLE(Attr, nsINode, nsIDOMAttr, nsIAttribute, nsIDOMNode,
   108                      nsIDOMEventTarget, EventTarget)
   109   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(Attr)
   110   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
   111                                  new nsNodeSupportsWeakRefTearoff(this))
   112   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
   113                                  new nsNode3Tearoff(this))
   114 NS_INTERFACE_MAP_END
   116 NS_IMPL_CYCLE_COLLECTING_ADDREF(Attr)
   117 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(Attr,
   118                                                    nsNodeUtils::LastRelease(this))
   120 void
   121 Attr::SetMap(nsDOMAttributeMap *aMap)
   122 {
   123   if (mAttrMap && !aMap && sInitialized) {
   124     // We're breaking a relationship with content and not getting a new one,
   125     // need to locally cache value. GetValue() does that.
   126     GetValue(mValue);
   127   }
   129   mAttrMap = aMap;
   130 }
   132 Element*
   133 Attr::GetElement() const
   134 {
   135   if (!mAttrMap) {
   136     return nullptr;
   137   }
   138   nsIContent* content = mAttrMap->GetContent();
   139   return content ? content->AsElement() : nullptr;
   140 }
   142 nsresult
   143 Attr::SetOwnerDocument(nsIDocument* aDocument)
   144 {
   145   NS_ASSERTION(aDocument, "Missing document");
   147   nsIDocument *doc = OwnerDoc();
   148   NS_ASSERTION(doc != aDocument, "bad call to Attr::SetOwnerDocument");
   149   doc->DeleteAllPropertiesFor(this);
   151   nsCOMPtr<nsINodeInfo> newNodeInfo;
   152   newNodeInfo = aDocument->NodeInfoManager()->
   153     GetNodeInfo(mNodeInfo->NameAtom(), mNodeInfo->GetPrefixAtom(),
   154                 mNodeInfo->NamespaceID(),
   155                 nsIDOMNode::ATTRIBUTE_NODE);
   156   NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
   157   mNodeInfo.swap(newNodeInfo);
   159   return NS_OK;
   160 }
   162 NS_IMETHODIMP
   163 Attr::GetName(nsAString& aName)
   164 {
   165   aName = NodeName();
   166   return NS_OK;
   167 }
   169 already_AddRefed<nsIAtom>
   170 Attr::GetNameAtom(nsIContent* aContent)
   171 {
   172   if (!mNsAware &&
   173       mNodeInfo->NamespaceID() == kNameSpaceID_None &&
   174       aContent->IsInHTMLDocument() &&
   175       aContent->IsHTML()) {
   176     nsString name;
   177     mNodeInfo->GetName(name);
   178     nsAutoString lowercaseName;
   179     nsContentUtils::ASCIIToLower(name, lowercaseName);
   180     return do_GetAtom(lowercaseName);
   181   }
   182   nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
   183   return nameAtom.forget();
   184 }
   186 NS_IMETHODIMP
   187 Attr::GetValue(nsAString& aValue)
   188 {
   189   Element* element = GetElement();
   190   if (element) {
   191     nsCOMPtr<nsIAtom> nameAtom = GetNameAtom(element);
   192     element->GetAttr(mNodeInfo->NamespaceID(), nameAtom, aValue);
   193   }
   194   else {
   195     aValue = mValue;
   196   }
   198   return NS_OK;
   199 }
   201 void
   202 Attr::SetValue(const nsAString& aValue, ErrorResult& aRv)
   203 {
   204   Element* element = GetElement();
   205   if (!element) {
   206     mValue = aValue;
   207     return;
   208   }
   210   nsCOMPtr<nsIAtom> nameAtom = GetNameAtom(element);
   211   aRv = element->SetAttr(mNodeInfo->NamespaceID(),
   212                          nameAtom,
   213                          mNodeInfo->GetPrefixAtom(),
   214                          aValue,
   215                          true);
   216 }
   218 NS_IMETHODIMP
   219 Attr::SetValue(const nsAString& aValue)
   220 {
   221   ErrorResult rv;
   222   SetValue(aValue, rv);
   223   return rv.ErrorCode();
   224 }
   226 bool
   227 Attr::Specified() const
   228 {
   229   return true;
   230 }
   232 NS_IMETHODIMP
   233 Attr::GetSpecified(bool* aSpecified)
   234 {
   235   NS_ENSURE_ARG_POINTER(aSpecified);
   236   *aSpecified = Specified();
   237   return NS_OK;
   238 }
   240 Element*
   241 Attr::GetOwnerElement(ErrorResult& aRv)
   242 {
   243   OwnerDoc()->WarnOnceAbout(nsIDocument::eOwnerElement);
   244   return GetElement();
   245 }
   247 NS_IMETHODIMP
   248 Attr::GetOwnerElement(nsIDOMElement** aOwnerElement)
   249 {
   250   NS_ENSURE_ARG_POINTER(aOwnerElement);
   251   OwnerDoc()->WarnOnceAbout(nsIDocument::eOwnerElement);
   253   Element* element = GetElement();
   254   if (element) {
   255     return CallQueryInterface(element, aOwnerElement);
   256   }
   258   *aOwnerElement = nullptr;
   260   return NS_OK;
   261 }
   263 void
   264 Attr::GetNodeValueInternal(nsAString& aNodeValue)
   265 {
   266   OwnerDoc()->WarnOnceAbout(nsIDocument::eNodeValue);
   268   GetValue(aNodeValue);
   269 }
   271 void
   272 Attr::SetNodeValueInternal(const nsAString& aNodeValue, ErrorResult& aError)
   273 {
   274   OwnerDoc()->WarnOnceAbout(nsIDocument::eNodeValue);
   276   aError = SetValue(aNodeValue);
   277 }
   279 nsresult
   280 Attr::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
   281 {
   282   nsAutoString value;
   283   const_cast<Attr*>(this)->GetValue(value);
   285   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   286   *aResult = new Attr(nullptr, ni.forget(), value, mNsAware);
   287   if (!*aResult) {
   288     return NS_ERROR_OUT_OF_MEMORY;
   289   }
   291   NS_ADDREF(*aResult);
   293   return NS_OK;
   294 }
   296 already_AddRefed<nsIURI>
   297 Attr::GetBaseURI(bool aTryUseXHRDocBaseURI) const
   298 {
   299   Element* parent = GetElement();
   301   return parent ? parent->GetBaseURI(aTryUseXHRDocBaseURI) : nullptr;
   302 }
   304 void
   305 Attr::GetTextContentInternal(nsAString& aTextContent)
   306 {
   307   OwnerDoc()->WarnOnceAbout(nsIDocument::eTextContent);
   309   GetValue(aTextContent);
   310 }
   312 void
   313 Attr::SetTextContentInternal(const nsAString& aTextContent,
   314                              ErrorResult& aError)
   315 {
   316   OwnerDoc()->WarnOnceAbout(nsIDocument::eTextContent);
   318   SetNodeValueInternal(aTextContent, aError);
   319 }
   321 NS_IMETHODIMP
   322 Attr::GetIsId(bool* aReturn)
   323 {
   324   Element* element = GetElement();
   325   if (!element) {
   326     *aReturn = false;
   327     return NS_OK;
   328   }
   330   nsIAtom* idAtom = element->GetIDAttributeName();
   331   if (!idAtom) {
   332     *aReturn = false;
   333     return NS_OK;
   334   }
   336   *aReturn = mNodeInfo->Equals(idAtom, kNameSpaceID_None);
   337   return NS_OK;
   338 }
   340 bool
   341 Attr::IsNodeOfType(uint32_t aFlags) const
   342 {
   343     return !(aFlags & ~eATTRIBUTE);
   344 }
   346 uint32_t
   347 Attr::GetChildCount() const
   348 {
   349   return 0;
   350 }
   352 nsIContent *
   353 Attr::GetChildAt(uint32_t aIndex) const
   354 {
   355   return nullptr;
   356 }
   358 nsIContent * const *
   359 Attr::GetChildArray(uint32_t* aChildCount) const
   360 {
   361   *aChildCount = 0;
   362   return nullptr;
   363 }
   365 int32_t
   366 Attr::IndexOf(const nsINode* aPossibleChild) const
   367 {
   368   return -1;
   369 }
   371 nsresult
   372 Attr::InsertChildAt(nsIContent* aKid, uint32_t aIndex,
   373                               bool aNotify)
   374 {
   375   return NS_ERROR_NOT_IMPLEMENTED;
   376 }
   378 void
   379 Attr::RemoveChildAt(uint32_t aIndex, bool aNotify)
   380 {
   381 }
   383 nsresult
   384 Attr::PreHandleEvent(EventChainPreVisitor& aVisitor)
   385 {
   386   aVisitor.mCanHandle = true;
   387   return NS_OK;
   388 }
   390 void
   391 Attr::Initialize()
   392 {
   393   sInitialized = true;
   394 }
   396 void
   397 Attr::Shutdown()
   398 {
   399   sInitialized = false;
   400 }
   402 JSObject*
   403 Attr::WrapObject(JSContext* aCx)
   404 {
   405   return AttrBinding::Wrap(aCx, this);
   406 }
   408 } // namespace dom
   409 } // namespace mozilla

mercurial