Back to index

lightning-sunbird  0.9+nobinonly
nsDocumentFragment.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsISupports.h"
00039 #include "nsIContent.h"
00040 #include "nsIDOMDocumentFragment.h"
00041 #include "nsGenericElement.h"
00042 #include "nsINameSpaceManager.h"
00043 #include "nsINodeInfo.h"
00044 #include "nsNodeInfoManager.h"
00045 #include "nsIDocument.h"
00046 #include "nsIDOMDocument.h"
00047 #include "nsIDOMAttr.h"
00048 #include "nsDOMError.h"
00049 #include "nsIDOM3Node.h"
00050 #include "nsLayoutAtoms.h"
00051 #include "nsDOMString.h"
00052 
00053 class nsDocumentFragment : public nsGenericElement,
00054                            public nsIDOMDocumentFragment,
00055                            public nsIDOM3Node
00056 {
00057 public:
00058   nsDocumentFragment(nsINodeInfo *aNodeInfo);
00059   virtual ~nsDocumentFragment();
00060 
00061   // nsISupports
00062   NS_DECL_ISUPPORTS_INHERITED
00063 
00064   // interface nsIDOMDocumentFragment
00065   NS_IMETHOD    GetNodeName(nsAString& aNodeName)
00066   { return nsGenericElement::GetNodeName(aNodeName); }
00067   NS_IMETHOD    GetNodeValue(nsAString& aNodeValue)
00068   { return nsGenericElement::GetNodeValue(aNodeValue); }
00069   NS_IMETHOD    SetNodeValue(const nsAString& aNodeValue)
00070   { return nsGenericElement::SetNodeValue(aNodeValue); }
00071   NS_IMETHOD    GetNodeType(PRUint16* aNodeType);
00072   NS_IMETHOD    GetParentNode(nsIDOMNode** aParentNode)
00073   { return nsGenericElement::GetParentNode(aParentNode); }
00074   NS_IMETHOD    GetChildNodes(nsIDOMNodeList** aChildNodes)
00075   { return nsGenericElement::GetChildNodes(aChildNodes); }
00076   NS_IMETHOD    GetFirstChild(nsIDOMNode** aFirstChild)
00077   { return nsGenericElement::GetFirstChild(aFirstChild); }
00078   NS_IMETHOD    GetLastChild(nsIDOMNode** aLastChild)
00079   { return nsGenericElement::GetLastChild(aLastChild); }
00080   NS_IMETHOD    GetPreviousSibling(nsIDOMNode** aPreviousSibling)
00081   { return nsGenericElement::GetPreviousSibling(aPreviousSibling); }
00082   NS_IMETHOD    GetNextSibling(nsIDOMNode** aNextSibling)
00083   { return nsGenericElement::GetNextSibling(aNextSibling); }
00084   NS_IMETHOD    GetAttributes(nsIDOMNamedNodeMap** aAttributes)
00085     {
00086       *aAttributes = nsnull;
00087       return NS_OK;
00088     }
00089   NS_IMETHOD    GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
00090   { return nsGenericElement::GetOwnerDocument(aOwnerDocument); }
00091   NS_IMETHOD    InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, 
00092                              nsIDOMNode** aReturn)
00093   { return nsGenericElement::InsertBefore(aNewChild, aRefChild, aReturn); }
00094   NS_IMETHOD    ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, 
00095                              nsIDOMNode** aReturn)
00096   { return nsGenericElement::ReplaceChild(aNewChild, aOldChild, aReturn); }
00097   NS_IMETHOD    RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
00098   { return nsGenericElement::RemoveChild(aOldChild, aReturn); }
00099   NS_IMETHOD    AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
00100   { return nsGenericElement::AppendChild(aNewChild, aReturn); }
00101   NS_IMETHOD    HasChildNodes(PRBool* aReturn)
00102   { return nsGenericElement::HasChildNodes(aReturn); }
00103   NS_IMETHOD    HasAttributes(PRBool* aReturn)
00104   { return nsGenericElement::HasAttributes(aReturn); }
00105   NS_IMETHOD    CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
00106   NS_IMETHOD    GetPrefix(nsAString& aPrefix)
00107   { return nsGenericElement::GetPrefix(aPrefix); }
00108   NS_IMETHOD    SetPrefix(const nsAString& aPrefix);
00109   NS_IMETHOD    GetNamespaceURI(nsAString& aNamespaceURI)
00110   { return nsGenericElement::GetNamespaceURI(aNamespaceURI); }
00111   NS_IMETHOD    GetLocalName(nsAString& aLocalName)
00112   { return nsGenericElement::GetLocalName(aLocalName); }
00113   NS_IMETHOD    Normalize()
00114   { return nsGenericElement::Normalize(); }
00115   NS_IMETHOD    IsSupported(const nsAString& aFeature,
00116                             const nsAString& aVersion,
00117                             PRBool* aReturn)
00118   { return nsGenericElement::IsSupported(aFeature, aVersion, aReturn); }
00119 
00120   // nsIDOM3Node
00121   NS_DECL_NSIDOM3NODE
00122 
00123   // nsIContent
00124   virtual void SetParent(nsIContent* aParent) { }
00125   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00126                    const nsAString& aValue, PRBool aNotify)
00127   {
00128     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
00129   }
00130   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
00131                            nsIAtom* aPrefix, const nsAString& aValue,
00132                            PRBool aNotify)
00133   {
00134     return NS_OK;
00135   }
00136   virtual nsresult GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, 
00137                            nsAString& aResult) const
00138   {
00139     return NS_CONTENT_ATTR_NOT_THERE;
00140   }
00141   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute, 
00142                              PRBool aNotify)
00143   {
00144     return NS_OK;
00145   }
00146   virtual nsresult GetAttrNameAt(PRUint32 aIndex, PRInt32* aNameSpaceID,
00147                                  nsIAtom** aName, nsIAtom** aPrefix) const
00148   {
00149     *aNameSpaceID = kNameSpaceID_None;
00150     *aName = nsnull;
00151     *aPrefix = nsnull;
00152     return NS_ERROR_ILLEGAL_VALUE;
00153   }
00154   virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
00155                                   nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
00156                                   PRUint32 aFlags, nsEventStatus* aEventStatus)
00157   {
00158     NS_ENSURE_ARG_POINTER(aEventStatus);
00159     *aEventStatus = nsEventStatus_eIgnore;
00160     return NS_OK;
00161   }
00162 };
00163 
00164 nsresult
00165 NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
00166                        nsNodeInfoManager *aNodeInfoManager)
00167 {
00168   NS_ENSURE_ARG(aNodeInfoManager);
00169 
00170   nsCOMPtr<nsINodeInfo> nodeInfo;
00171   nsresult rv =
00172     aNodeInfoManager->GetNodeInfo(nsLayoutAtoms::documentFragmentNodeName,
00173                                   nsnull, kNameSpaceID_None,
00174                                   getter_AddRefs(nodeInfo));
00175   NS_ENSURE_SUCCESS(rv, rv);
00176 
00177   nsDocumentFragment *it = new nsDocumentFragment(nodeInfo);
00178   if (!it) {
00179     return NS_ERROR_OUT_OF_MEMORY;
00180   }
00181 
00182   *aInstancePtrResult = NS_STATIC_CAST(nsIDOMDocumentFragment *, it);
00183 
00184   NS_ADDREF(*aInstancePtrResult);
00185 
00186   return NS_OK;
00187 }
00188 
00189 nsDocumentFragment::nsDocumentFragment(nsINodeInfo *aNodeInfo)
00190   : nsGenericElement(aNodeInfo)
00191 {
00192 }
00193 
00194 nsDocumentFragment::~nsDocumentFragment()
00195 {
00196 }
00197 
00198 
00199 // QueryInterface implementation for nsDocumentFragment
00200 NS_INTERFACE_MAP_BEGIN(nsDocumentFragment)
00201   NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentFragment)
00202   NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
00203   NS_INTERFACE_MAP_ENTRY(nsIDOM3Node)
00204   NS_INTERFACE_MAP_ENTRY(nsIContent)
00205   NS_INTERFACE_MAP_ENTRY(nsIDOMGCParticipant)
00206   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
00207   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DocumentFragment)
00208 NS_INTERFACE_MAP_END
00209 
00210 
00211 NS_IMPL_ADDREF(nsDocumentFragment)
00212 NS_IMPL_RELEASE(nsDocumentFragment)
00213 
00214 NS_IMETHODIMP    
00215 nsDocumentFragment::GetNodeType(PRUint16* aNodeType)
00216 {
00217   *aNodeType = (PRUint16)nsIDOMNode::DOCUMENT_FRAGMENT_NODE;
00218   return NS_OK;
00219 }
00220 
00221 NS_IMETHODIMP
00222 nsDocumentFragment::SetPrefix(const nsAString& aPrefix)
00223 {
00224   return NS_ERROR_DOM_NAMESPACE_ERR;
00225 }
00226 
00227 NS_IMETHODIMP    
00228 nsDocumentFragment::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
00229 {
00230   NS_ENSURE_ARG_POINTER(aReturn);
00231   *aReturn = nsnull;
00232 
00233   nsresult rv = NS_OK;
00234   nsCOMPtr<nsIDOMDocumentFragment> newFragment;
00235 
00236   rv = NS_NewDocumentFragment(getter_AddRefs(newFragment),
00237                               mNodeInfo->NodeInfoManager());
00238   NS_ENSURE_SUCCESS(rv, rv);
00239 
00240   if (aDeep) {
00241     nsCOMPtr<nsIDOMNodeList> childNodes;
00242 
00243     GetChildNodes(getter_AddRefs(childNodes));
00244     if (childNodes) {
00245       PRUint32 index, count;
00246       childNodes->GetLength(&count);
00247 
00248       for (index = 0; index < count; ++index) {
00249         nsCOMPtr<nsIDOMNode> child;
00250         childNodes->Item(index, getter_AddRefs(child));
00251         if (child) {
00252           nsCOMPtr<nsIDOMNode> newChild;
00253           rv = child->CloneNode(PR_TRUE, getter_AddRefs(newChild));
00254           NS_ENSURE_SUCCESS(rv, rv);
00255 
00256           nsCOMPtr<nsIDOMNode> dummyNode;
00257           rv = newFragment->AppendChild(newChild,
00258                                         getter_AddRefs(dummyNode));
00259           NS_ENSURE_SUCCESS(rv, rv);
00260         }
00261       } // End of for loop
00262     } // if (childNodes)
00263   } // if (aDeep)
00264 
00265   return CallQueryInterface(newFragment, aReturn);
00266 }
00267 
00268 NS_IMETHODIMP
00269 nsDocumentFragment::GetBaseURI(nsAString& aURI)
00270 {
00271   aURI.Truncate();
00272 
00273   return NS_OK;
00274 }
00275 
00276 NS_IMETHODIMP
00277 nsDocumentFragment::LookupPrefix(const nsAString& aNamespaceURI,
00278                                  nsAString& aPrefix)
00279 {
00280   aPrefix.Truncate();
00281 
00282   return NS_OK;
00283 }
00284 
00285 NS_IMETHODIMP
00286 nsDocumentFragment::LookupNamespaceURI(const nsAString& aNamespacePrefix,
00287                                        nsAString& aNamespaceURI)
00288 {
00289   aNamespaceURI.Truncate();
00290 
00291   return NS_OK;
00292 }
00293 
00294 NS_IMETHODIMP
00295 nsDocumentFragment::IsDefaultNamespace(const nsAString& aNamespaceURI,
00296                                        PRBool* aReturn)
00297 {
00298   *aReturn = PR_FALSE;
00299   return NS_OK;
00300 }
00301 
00302 NS_IMETHODIMP
00303 nsDocumentFragment::CompareDocumentPosition(nsIDOMNode* aOther,
00304                                             PRUint16* aReturn)
00305 {
00306   NS_ENSURE_ARG_POINTER(aOther);
00307   NS_PRECONDITION(aReturn, "Must have an out parameter");
00308 
00309   if (this == aOther) {
00310     // If the two nodes being compared are the same node,
00311     // then no flags are set on the return.
00312     *aReturn = 0;
00313     return NS_OK;
00314   }
00315 
00316   PRUint16 mask = 0;
00317 
00318   nsCOMPtr<nsIDOMNode> other(aOther);
00319   do {
00320     nsCOMPtr<nsIDOMNode> tmp(other);
00321     tmp->GetParentNode(getter_AddRefs(other));
00322     if (!other) {
00323       // No parent.  Check to see if we're at an attribute node.
00324       PRUint16 nodeType = 0;
00325       tmp->GetNodeType(&nodeType);
00326       if (nodeType != nsIDOMNode::ATTRIBUTE_NODE) {
00327         // If there is no common container node, then the order
00328         // is based upon order between the root container of each
00329         // node that is in no container. In this case, the result
00330         // is disconnected and implementation-dependent.
00331         mask |= (nsIDOM3Node::DOCUMENT_POSITION_DISCONNECTED |
00332                  nsIDOM3Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
00333 
00334         break;
00335       }
00336 
00337       // If we are, let's get the owner element and continue up the tree
00338       nsCOMPtr<nsIDOMAttr> attr(do_QueryInterface(tmp));
00339       nsCOMPtr<nsIDOMElement> owner;
00340       attr->GetOwnerElement(getter_AddRefs(owner));
00341       other = do_QueryInterface(owner);
00342     }
00343 
00344     if (NS_STATIC_CAST(nsIDOMNode*, this) == other) {
00345       // If the node being compared is contained by our node,
00346       // then it follows it.
00347       mask |= (nsIDOM3Node::DOCUMENT_POSITION_CONTAINED_BY |
00348                nsIDOM3Node::DOCUMENT_POSITION_FOLLOWING);
00349       break;
00350     }
00351   } while (other);
00352 
00353   *aReturn = mask;
00354   return NS_OK;
00355 }
00356 
00357 NS_IMETHODIMP
00358 nsDocumentFragment::IsSameNode(nsIDOMNode* aOther,
00359                                PRBool* aReturn)
00360 {
00361   PRBool sameNode = PR_FALSE;
00362 
00363   if (NS_STATIC_CAST(nsIDOMNode*, this) == aOther) {
00364     sameNode = PR_TRUE;
00365   }
00366 
00367   *aReturn = sameNode;
00368   return NS_OK;
00369 }
00370 
00371 NS_IMETHODIMP
00372 nsDocumentFragment::IsEqualNode(nsIDOMNode* aOther, PRBool* aReturn)
00373 {
00374   NS_NOTYETIMPLEMENTED("nsDocumentFragment::IsEqualNode()");
00375 
00376   return NS_ERROR_NOT_IMPLEMENTED;
00377 }
00378 
00379 NS_IMETHODIMP
00380 nsDocumentFragment::GetFeature(const nsAString& aFeature,
00381                                const nsAString& aVersion,
00382                                nsISupports** aReturn)
00383 {
00384   NS_NOTYETIMPLEMENTED("nsDocumentFragment::GetFeature()");
00385 
00386   return NS_ERROR_NOT_IMPLEMENTED;
00387 }
00388 
00389 NS_IMETHODIMP
00390 nsDocumentFragment::SetUserData(const nsAString& aKey,
00391                                 nsIVariant* aData,
00392                                 nsIDOMUserDataHandler* aHandler,
00393                                 nsIVariant** aReturn)
00394 {
00395   NS_NOTYETIMPLEMENTED("nsDocumentFragment::SetUserData()");
00396 
00397   return NS_ERROR_NOT_IMPLEMENTED;
00398 }
00399 
00400 NS_IMETHODIMP
00401 nsDocumentFragment::GetUserData(const nsAString& aKey,
00402                                 nsIVariant** aReturn)
00403 {
00404   NS_NOTYETIMPLEMENTED("nsDocumentFragment::GetUserData()");
00405 
00406   return NS_ERROR_NOT_IMPLEMENTED;
00407 }
00408 
00409 NS_IMETHODIMP
00410 nsDocumentFragment::GetTextContent(nsAString &aTextContent)
00411 {
00412   return nsNode3Tearoff::GetTextContent(this, aTextContent);
00413 }
00414 
00415 NS_IMETHODIMP
00416 nsDocumentFragment::SetTextContent(const nsAString& aTextContent)
00417 {
00418   return nsNode3Tearoff::SetTextContent(this, aTextContent);
00419 }
00420