From 18b336134b5d90ba7eca3dea25dec456768b3b8e Mon Sep 17 00:00:00 2001 From: "Olli.Pettay%helsinki.fi" Date: Sun, 26 Jun 2005 18:30:17 +0000 Subject: [PATCH] Bug 289434 xbl-ized widgets for xforms r=doron+allan, a=mkaply, NPOTB git-svn-id: svn://10.0.0.236/trunk@175154 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/extensions/xforms/Makefile.in | 3 + mozilla/extensions/xforms/jar.mn | 1 + .../extensions/xforms/nsIXFormsDelegate.idl | 83 ++++ .../extensions/xforms/nsIXFormsUIWidget.idl | 62 +++ .../xforms/nsXFormsDelegateStub.cpp | 238 +++++++++++ .../extensions/xforms/nsXFormsDelegateStub.h | 103 +++++ .../xforms/nsXFormsInputElement.cpp | 336 +--------------- .../xforms/nsXFormsLabelElement.cpp | 136 ++----- .../xforms/nsXFormsMessageElement.cpp | 19 +- .../xforms/nsXFormsModelElement.cpp | 77 +++- .../extensions/xforms/nsXFormsModelElement.h | 16 + .../xforms/nsXFormsOutputElement.cpp | 264 ++++--------- .../xforms/nsXFormsRepeatElement.cpp | 1 + .../xforms/nsXFormsTriggerElement.cpp | 280 +------------ mozilla/extensions/xforms/nsXFormsUtils.cpp | 45 ++- mozilla/extensions/xforms/nsXFormsUtils.h | 3 +- mozilla/extensions/xforms/xforms.css | 38 ++ mozilla/extensions/xforms/xforms.xml | 371 ++++++++++++++++++ 18 files changed, 1175 insertions(+), 901 deletions(-) create mode 100644 mozilla/extensions/xforms/nsIXFormsDelegate.idl create mode 100644 mozilla/extensions/xforms/nsIXFormsUIWidget.idl create mode 100644 mozilla/extensions/xforms/nsXFormsDelegateStub.cpp create mode 100644 mozilla/extensions/xforms/nsXFormsDelegateStub.h create mode 100644 mozilla/extensions/xforms/xforms.xml diff --git a/mozilla/extensions/xforms/Makefile.in b/mozilla/extensions/xforms/Makefile.in index d255b3d5dcd..20fc57fdb73 100644 --- a/mozilla/extensions/xforms/Makefile.in +++ b/mozilla/extensions/xforms/Makefile.in @@ -89,6 +89,8 @@ XPIDLSRCS = \ nsIXFormsSubmitElement.idl \ nsIXFormsSubmissionElement.idl \ nsIXFormsControlBase.idl \ + nsIXFormsDelegate.idl \ + nsIXFormsUIWidget.idl \ $(NULL) CPPSRCS = \ @@ -141,6 +143,7 @@ CPPSRCS = \ nsXFormsNodeState.cpp \ nsXFormsControlStub.cpp \ nsXFormsUtilityService.cpp \ + nsXFormsDelegateStub.cpp \ $(NULL) EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS) diff --git a/mozilla/extensions/xforms/jar.mn b/mozilla/extensions/xforms/jar.mn index d5bac9b2be4..1fd9945ba1b 100755 --- a/mozilla/extensions/xforms/jar.mn +++ b/mozilla/extensions/xforms/jar.mn @@ -1,5 +1,6 @@ xforms.jar: content/xforms/contents.rdf + content/xforms/xforms.xml * content/xforms/xforms.css * locale/en-US/xforms/contents.rdf (resources/locale/en-US/contents.rdf) locale/en-US/xforms/xforms.properties (resources/locale/en-US/xforms.properties) diff --git a/mozilla/extensions/xforms/nsIXFormsDelegate.idl b/mozilla/extensions/xforms/nsIXFormsDelegate.idl new file mode 100644 index 00000000000..2b1c5fa04f7 --- /dev/null +++ b/mozilla/extensions/xforms/nsIXFormsDelegate.idl @@ -0,0 +1,83 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XForms support. + * + * The Initial Developer of the Original Code is + * Novell, Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Allan Beaufour + * Olli Pettay + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +/** + * Interface implemented by XForms controls that delegates the UI to an + * external entity. + */ +[scriptable, uuid(3b2300dc-9311-4eb7-a5c9-ca2ee4064de6)] +interface nsIXFormsDelegate : nsISupports +{ + /** + * The value bound to the XForms control. + */ + attribute DOMString value; + + /** + * @see http://www.w3.org/TR/xforms/slice6.html#model-prop-readOnly + */ + readonly attribute boolean isReadonly; + + /** + * @see http://www.w3.org/TR/xforms/slice6.html#model-prop-relevant + */ + readonly attribute boolean isEnabled; + + /** + * @see http://www.w3.org/TR/xforms/slice6.html#model-prop-required + */ + readonly attribute boolean isRequired; + + /** + * Tells whether the XForms control is valid. + */ + readonly attribute boolean isValid; + + /** + * true, if XForms control is bound to a node in a data model. + */ + readonly attribute boolean hasBoundNode; + + /** + * This should be called by XBL widgets, when they are created. + */ + void widgetAttached(); +}; diff --git a/mozilla/extensions/xforms/nsIXFormsUIWidget.idl b/mozilla/extensions/xforms/nsIXFormsUIWidget.idl new file mode 100644 index 00000000000..afad9351582 --- /dev/null +++ b/mozilla/extensions/xforms/nsIXFormsUIWidget.idl @@ -0,0 +1,62 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XForms support. + * + * The Initial Developer of the Original Code is + * Novell, Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Allan Beaufour + * Olli Pettay + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIDOMElement.idl" + +/** + * Interface implemented by XForms UI widgets. + */ +[scriptable, uuid(b88a1c27-47a2-4c25-be7c-170501a93643)] +interface nsIXFormsUIWidget : nsIDOMElement +{ + /** + * Called, when UI Widget should refresh itself. + */ + void refresh(); + + /** + * Tries to focus the UI Widget. Returns true, if focusing succeeded. + */ + boolean focus(); + + /** + * During submission, the \ should be disabled. + */ + void disable(in boolean disable); // for +}; diff --git a/mozilla/extensions/xforms/nsXFormsDelegateStub.cpp b/mozilla/extensions/xforms/nsXFormsDelegateStub.cpp new file mode 100644 index 00000000000..4ae206ff3b7 --- /dev/null +++ b/mozilla/extensions/xforms/nsXFormsDelegateStub.cpp @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XForms support. + * + * The Initial Developer of the Original Code is + * Novell, Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Allan Beaufour + * Olli Pettay + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsIDOMDocument.h" +#include "nsIDOM3Node.h" +#include "nsIDOMEventTarget.h" +#include "nsIDOMEvent.h" +#include "nsIDOMUIEvent.h" +#include "nsIDOMDocumentView.h" +#include "nsIDOMAbstractView.h" +#include "nsIDOMDocumentEvent.h" +#include "nsDOMString.h" +#include "nsIModelElementPrivate.h" +#include "nsIXFormsUIWidget.h" +#include "nsXFormsAtoms.h" +#include "nsXFormsDelegateStub.h" +#include "nsXFormsUtils.h" +#include "nsIServiceManager.h" +#include "nsXFormsModelElement.h" + +NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsDelegateStub, + nsXFormsBindableControlStub, + nsIXFormsDelegate) + + +NS_IMETHODIMP +nsXFormsDelegateStub::WillChangeDocument(nsIDOMDocument *aNewDocument) +{ + mRepeatState = eType_Unknown; + return nsXFormsBindableControlStub::WillChangeDocument(aNewDocument); +} + +NS_IMETHODIMP +nsXFormsDelegateStub::WillChangeParent(nsIDOMElement *aNewParent) +{ + mRepeatState = eType_Unknown; + return nsXFormsBindableControlStub::WillChangeParent(aNewParent); +} + +NS_IMETHODIMP +nsXFormsDelegateStub::OnCreated(nsIXTFBindableElementWrapper *aWrapper) +{ + nsresult rv = nsXFormsBindableControlStub::OnCreated(aWrapper); + NS_ENSURE_SUCCESS(rv, rv); + aWrapper->SetNotificationMask(kStandardNotificationMask | + nsIXTFElement::NOTIFY_WILL_CHANGE_DOCUMENT | + nsIXTFElement::NOTIFY_WILL_CHANGE_PARENT); + return rv; +} + +NS_IMETHODIMP +nsXFormsDelegateStub::OnDestroyed() +{ + nsXFormsModelElement::CancelPostRefresh(this); + return nsXFormsBindableControlStub::OnDestroyed(); +} + +// nsIXFormsControl + +NS_IMETHODIMP +nsXFormsDelegateStub::Refresh() +{ + if (mRepeatState == eType_Template) + return NS_OK; + + SetMozTypeAttribute(); + + nsCOMPtr widget = do_QueryInterface(mElement); + if (!widget) + return NS_OK; + + return widget->Refresh(); +} + +NS_IMETHODIMP +nsXFormsDelegateStub::TryFocus(PRBool* aOK) +{ + *aOK = PR_FALSE; + if (GetRelevantState()) { + nsCOMPtr widget = do_QueryInterface(mElement); + if (widget) { + widget->Focus(aOK); + } + } + + return NS_OK; +} + +// nsIXFormsDelegate + +NS_IMETHODIMP +nsXFormsDelegateStub::GetValue(nsAString& aValue) +{ + SetDOMStringToNull(aValue); + if (mBoundNode) { + nsXFormsUtils::GetNodeValue(mBoundNode, aValue); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsDelegateStub::SetValue(const nsAString& aValue) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult +nsXFormsDelegateStub::GetState(const nsAString &aState, PRBool *aStateVal) +{ + NS_ENSURE_ARG_POINTER(aStateVal); + + if (mElement) { + mElement->HasAttribute(aState, aStateVal); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsDelegateStub::GetIsReadonly(PRBool *aStateVal) +{ + return GetState(NS_LITERAL_STRING("read-only"), aStateVal); +} + +NS_IMETHODIMP +nsXFormsDelegateStub::GetIsEnabled(PRBool *aStateVal) +{ + return GetState(NS_LITERAL_STRING("enabled"), aStateVal); +} + +NS_IMETHODIMP +nsXFormsDelegateStub::GetIsRequired(PRBool *aStateVal) +{ + return GetState(NS_LITERAL_STRING("required"), aStateVal); +} + +NS_IMETHODIMP +nsXFormsDelegateStub::GetIsValid(PRBool *aStateVal) +{ + return GetState(NS_LITERAL_STRING("valid"), aStateVal); +} + +NS_IMETHODIMP +nsXFormsDelegateStub::GetHasBoundNode(PRBool *aHasBoundNode) +{ + *aHasBoundNode = mBoundNode ? PR_TRUE : PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsDelegateStub::WidgetAttached() +{ + if (UpdateRepeatState() != eType_Template) + nsXFormsModelElement::NeedsPostRefresh(this); + + return NS_OK; +} + +nsRepeatState +nsXFormsDelegateStub::UpdateRepeatState() +{ + mRepeatState = eType_NotApplicable; + nsCOMPtr parent; + mElement->GetParentNode(getter_AddRefs(parent)); + while (parent) { + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("contextcontainer"))) { + mRepeatState = eType_GeneratedContent; + break; + } + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("repeat"))) { + mRepeatState = eType_Template; + break; + } + nsCOMPtr tmp; + parent->GetParentNode(getter_AddRefs(tmp)); + parent = tmp; + } + return mRepeatState; +} + +void +nsXFormsDelegateStub::SetMozTypeAttribute() +{ + NS_NAMED_LITERAL_STRING(mozTypeNs, NS_NAMESPACE_MOZ_XFORMS_TYPE); + NS_NAMED_LITERAL_STRING(mozType, "type"); + + if (mModel && mBoundNode) { + nsAutoString type, ns; + if (NS_FAILED(mModel->GetTypeAndNSFromNode(mBoundNode, type, ns))) { + mElement->RemoveAttributeNS(mozTypeNs, mozType); + return; + } + + ns.AppendLiteral("#"); + ns.Append(type); + mElement->SetAttributeNS(mozTypeNs, mozType, ns); + } else { + mElement->RemoveAttributeNS(mozTypeNs, mozType); + } +} diff --git a/mozilla/extensions/xforms/nsXFormsDelegateStub.h b/mozilla/extensions/xforms/nsXFormsDelegateStub.h new file mode 100644 index 00000000000..dbb181154d0 --- /dev/null +++ b/mozilla/extensions/xforms/nsXFormsDelegateStub.h @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XForms support. + * + * The Initial Developer of the Original Code is + * Novell, Inc. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Allan Beaufour + * Olli Pettay + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __NSXFORMSDELEGATESTUB_H__ +#define __NSXFORMSDELEGATESTUB_H__ + +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsIDOMElement.h" +#include "nsIXFormsDelegate.h" +#include "nsXFormsControlStub.h" +#include "nsIXFormsUIWidget.h" + +class nsIAtom; + +/** + * nsRepeatState is used to indicate whether the element + * is inside \'s template. If it is, there is no need + * to refresh the widget bound to the element. + */ +enum nsRepeatState { + eType_Unknown, + eType_Template, + eType_GeneratedContent, + eType_NotApplicable +}; + +/** + * Stub implementation of the nsIXFormsDelegate interface. + */ +class nsXFormsDelegateStub : public nsXFormsBindableControlStub, + public nsIXFormsDelegate +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIXFORMSDELEGATE + + NS_IMETHOD OnCreated(nsIXTFBindableElementWrapper *aWrapper); + NS_IMETHOD OnDestroyed(); + NS_IMETHOD WillChangeParent(nsIDOMElement *aNewParent); + NS_IMETHOD WillChangeDocument(nsIDOMDocument *aNewDocument); + + // nsIXFormsControl + NS_IMETHOD TryFocus(PRBool* aOK); + NS_IMETHOD Refresh(); + + nsXFormsDelegateStub(const nsAString& aType = EmptyString()) + : mControlType(aType), mRepeatState(eType_Unknown) {} + +protected: + // Checks the status of the model item properties. + nsresult GetState(const nsAString &aState, PRBool *aStateVal); + + // This is called when XBL widget is attached to the XForms control. + // It checks the ancestors of the element and returns an nsRepeatState + // depending on the elements place in the document. + nsRepeatState UpdateRepeatState(); + + // Sets/removes the moz:type attribute. The attribute can be used to detect the + // type of the node, which is bound the the control. + void SetMozTypeAttribute(); + + nsString mControlType; + nsRepeatState mRepeatState; +}; + +#endif diff --git a/mozilla/extensions/xforms/nsXFormsInputElement.cpp b/mozilla/extensions/xforms/nsXFormsInputElement.cpp index 7994de80596..139eb044557 100644 --- a/mozilla/extensions/xforms/nsXFormsInputElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInputElement.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Brian Ryner + * Allan Beaufour * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -57,39 +58,17 @@ #include "nsIContent.h" #include "nsIDOMXPathExpression.h" #include "nsXFormsAtoms.h" +#include "nsXFormsDelegateStub.h" /** * Implementation of the \, \, and \ elements. */ -class nsXFormsInputElement : public nsIDOMFocusListener, - public nsXFormsControlStub +class nsXFormsInputElement : public nsXFormsDelegateStub { public: - NS_DECL_ISUPPORTS_INHERITED - // nsIXTFXMLVisual overrides - NS_IMETHOD OnCreated(nsIXTFXMLVisualWrapper *aWrapper); - - // nsIXTFVisual overrides - NS_IMETHOD GetVisualContent(nsIDOMElement **aElement); - NS_IMETHOD GetInsertionPoint(nsIDOMElement **aPoint); - - // nsIXTFElement overrides - NS_IMETHOD OnDestroyed(); - NS_IMETHOD AttributeSet(nsIAtom *aName, const nsAString &aValue); - NS_IMETHOD AttributeRemoved(nsIAtom *aName); - NS_IMETHOD HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled); - - // nsIXFormsControl - NS_IMETHOD Refresh(); - NS_IMETHOD TryFocus(PRBool* aOK); - - // nsIDOMEventListener - NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent); - - // nsIDOMFocusListener - NS_IMETHOD Focus(nsIDOMEvent *aEvent); - NS_IMETHOD Blur(nsIDOMEvent *aEvent); + // nsIXFormsDelegate + NS_IMETHOD SetValue(const nsAString& aValue); enum ControlType { eType_Input, @@ -102,242 +81,22 @@ public: #endif // nsXFormsInputElement - nsXFormsInputElement(ControlType aType) - : mType(aType), mIncremental(PR_FALSE) + nsXFormsInputElement(const nsAString& aType) + : nsXFormsDelegateStub(aType) {} - -private: - // Updates the instance data node bound to this form control. - nsresult UpdateInstanceData(); - - nsCOMPtr mLabel; - nsCOMPtr mControl; - ControlType mType; - PRBool mIncremental; }; -NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsInputElement, - nsXFormsControlStub, - nsIDOMFocusListener, - nsIDOMEventListener) -// nsIXTFXMLVisual +// nsIXFormsDelegate NS_IMETHODIMP -nsXFormsInputElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper) +nsXFormsInputElement::SetValue(const nsAString& aValue) { - nsresult rv = nsXFormsControlStub::OnCreated(aWrapper); - NS_ENSURE_SUCCESS(rv, rv); - - // Our anonymous content structure will look like this: - // - //