Back to index

lightning-sunbird  0.9+nobinonly
nsXFormsCopyElement.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 XForms support.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * IBM Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2005
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *  Aaron Reed <aaronr@us.ibm.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsIXFormsCopyElement.h"
00040 #include "nsXFormsStubElement.h"
00041 #include "nsIXTFGenericElementWrapper.h"
00042 #include "nsXFormsUtils.h"
00043 #include "nsIDOMElement.h"
00044 #include "nsString.h"
00045 #include "nsIXFormsItemElement.h"
00046 
00055 class nsXFormsCopyElement : public nsXFormsStubElement,
00056                             public nsIXFormsCopyElement
00057 {
00058 public:
00059   nsXFormsCopyElement() : mElement(nsnull) {}
00060 
00061   NS_DECL_ISUPPORTS_INHERITED
00062 
00063   // nsIXTFGenericElement overrides
00064   NS_IMETHOD OnCreated(nsIXTFGenericElementWrapper *aWrapper);
00065 
00066   // nsIXTFElement overrides
00067   NS_IMETHOD ParentChanged(nsIDOMElement *aNewParent);
00068   NS_IMETHOD DocumentChanged(nsIDOMDocument *aNewParent);
00069 
00070   // nsIXFormsCopyElement
00071   NS_DECL_NSIXFORMSCOPYELEMENT
00072 
00073 private:
00074   nsIDOMElement *mElement;
00075 };
00076 
00077 NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsCopyElement,
00078                              nsXFormsStubElement,
00079                              nsIXFormsCopyElement)
00080 
00081 NS_IMETHODIMP
00082 nsXFormsCopyElement::OnCreated(nsIXTFGenericElementWrapper *aWrapper)
00083 {
00084   aWrapper->SetNotificationMask(nsIXTFElement::NOTIFY_PARENT_CHANGED |
00085                                 nsIXTFElement::NOTIFY_DOCUMENT_CHANGED);
00086 
00087   nsCOMPtr<nsIDOMElement> node;
00088   aWrapper->GetElementNode(getter_AddRefs(node));
00089 
00090   // It's ok to keep pointer to mElement.  mElement will have an
00091   // owning reference to this object, so as long as we null out mElement in
00092   // OnDestroyed, it will always be valid.
00093 
00094   mElement = node;
00095   NS_ASSERTION(mElement, "Wrapper is not an nsIDOMElement, we'll crash soon");
00096 
00097   return NS_OK;
00098 }
00099 
00100 // nsIXTFElement
00101 
00102 NS_IMETHODIMP
00103 nsXFormsCopyElement::ParentChanged(nsIDOMElement *aNewParent)
00104 {
00105   if (aNewParent) {
00106     if (!nsXFormsUtils::IsXFormsElement(aNewParent, 
00107                                         NS_LITERAL_STRING("itemset")) &&
00108         !nsXFormsUtils::IsXFormsElement(aNewParent, 
00109           NS_LITERAL_STRING("item"))) {
00110 
00111         // Parent of a copy element must always be an itemset.  We really can't
00112         // enforce this all that well until we have full schema support but for
00113         // now we'll at least warn the author.  We are also checking for
00114         // item because under Mozilla, the children of an itemset
00115         // element are cloned underneath an nsXFormsItemElement.  Each such
00116         // item element is then appended as anonymous content of the itemset.
00117         nsXFormsUtils::ReportError(NS_LITERAL_STRING("copyError"), mElement);
00118     }
00119   }
00120   return NS_OK;
00121 }
00122 
00123 NS_IMETHODIMP
00124 nsXFormsCopyElement::DocumentChanged(nsIDOMDocument* aNewDocument)
00125 {
00126   if (!aNewDocument)
00127     return NS_OK;
00128   
00129   // tell parent (xf:item) that it contains a xf:copy element and
00130   // not a xf:value element.
00131   nsCOMPtr<nsIDOMNode> itemNode;
00132   nsresult rv = mElement->GetParentNode(getter_AddRefs(itemNode));
00133   NS_ENSURE_TRUE(itemNode, rv);
00134 
00135   nsCOMPtr<nsIXFormsItemElement> item = do_QueryInterface(itemNode);
00136 
00137   // It is possible that the grandparent ISN'T an xf:item, if this is the
00138   // original template copy element whose parent is the xf:itemset and
00139   // grandparent is the xf:select.  We'll ignore a copy element in that case
00140   // since it really isn't in play.
00141   if (item) {
00142     item->SetIsCopyItem(PR_TRUE);
00143   }
00144   return NS_OK;
00145 }
00146 
00147 // nsIXFormsCopyElement
00148 
00149 NS_IMETHODIMP
00150 nsXFormsCopyElement::GetCopyNode(nsIDOMNode **aNode)
00151 {
00152   NS_ENSURE_ARG_POINTER(aNode);
00153   *aNode = nsnull;
00154 
00155   nsCOMPtr<nsIDOMNode> singleNode;
00156   nsCOMPtr<nsIModelElementPrivate> model;
00157   PRBool succeeded =
00158     nsXFormsUtils::GetSingleNodeBinding(mElement,
00159                                         getter_AddRefs(singleNode),
00160                                         getter_AddRefs(model));
00161 
00162   if (succeeded && singleNode)
00163     NS_ADDREF(*aNode = singleNode);
00164 
00165   return NS_OK;
00166 }
00167 
00168 NS_HIDDEN_(nsresult)
00169 NS_NewXFormsCopyElement(nsIXTFElement **aResult)
00170 {
00171   *aResult = new nsXFormsCopyElement();
00172   if (!*aResult)
00173     return NS_ERROR_OUT_OF_MEMORY;
00174 
00175   NS_ADDREF(*aResult);
00176   return NS_OK;
00177 }