diff --git a/mozilla/extensions/xforms/jar.mn b/mozilla/extensions/xforms/jar.mn index 98d6f2c646a..0a46b21b6ab 100755 --- a/mozilla/extensions/xforms/jar.mn +++ b/mozilla/extensions/xforms/jar.mn @@ -9,6 +9,9 @@ xforms.jar: * content/xforms/xforms-prefs.js (resources/content/xforms-prefs.js) content/xforms/xforms.xml (resources/content/xforms.xml) content/xforms/select1.xml (resources/content/select1.xml) + content/xforms/select.xml (resources/content/select.xml) + content/xforms/bindingex.css (resources/content/bindingex.css) + content/xforms/bindingex.xul (resources/content/bindingex.xul) * locale/en-US/xforms/contents.rdf (resources/locale/en-US/contents.rdf) locale/en-US/xforms/xforms.properties (resources/locale/en-US/xforms.properties) locale/en-US/xforms/xforms.dtd (resources/locale/en-US/xforms.dtd) diff --git a/mozilla/extensions/xforms/nsIXFormsRepeatElement.idl b/mozilla/extensions/xforms/nsIXFormsRepeatElement.idl index beee24ceaaf..cb1fe94a7be 100644 --- a/mozilla/extensions/xforms/nsIXFormsRepeatElement.idl +++ b/mozilla/extensions/xforms/nsIXFormsRepeatElement.idl @@ -44,6 +44,7 @@ #include "nsISupports.idl" interface nsIXFormsControl; +interface nsIDOMNode; [uuid(419e780d-4f31-4aa4-bae8-a18099d77bb6)] interface nsIXFormsRepeatElement : nsISupports @@ -91,6 +92,13 @@ interface nsIXFormsRepeatElement : nsISupports void setCurrentRepeat(in nsIXFormsRepeatElement aCurrentRepeat, in unsigned long aIndex); + /** + * Get currently selected repeat row + * + * @return The current repeat row + */ + nsIDOMNode getCurrentRepeatRow(); + /** * Add user of repeat-index. The control will have Bind() and Refresh() * called on it, when the index changes. diff --git a/mozilla/extensions/xforms/nsIXFormsSelectChild.idl b/mozilla/extensions/xforms/nsIXFormsSelectChild.idl index 51e900cd317..8ec3355d25c 100644 --- a/mozilla/extensions/xforms/nsIXFormsSelectChild.idl +++ b/mozilla/extensions/xforms/nsIXFormsSelectChild.idl @@ -55,47 +55,10 @@ class nsStringArray; [scriptable, uuid(a29ac2bd-f36a-451e-99e1-0f3bd94ffbef)] interface nsIXFormsSelectChild : nsISupports { - /** - * The DOM elements returned by this attribute are inserted into the select - * element's anonymous content tree. - */ - readonly attribute nsIArray anonymousNodes; - - /** - * selectItemsByValue() handles children that have a value element child. - * If the value element text for this child is contained in the |values| - * array, then the item should select itself. Used in \. - * - */ - [noscript] void selectItemsByValue(in constStringArray values); - - /** - * selectItemsByContent() handles children that have a copy element child. - * If |node| points to the same instance data node as the item, then the - * item should select itself. - */ - void selectItemsByContent(in nsIDOMNode node); - /* * selectItemByValue is used in \. If the XFormsSelectChild is or * contains an \, which has the same value as the parameter |value|, * this method returns that \. */ nsIDOMNode selectItemByValue(in AString value); - - /** - * Instructs the item to serialize its selected elements. - * For children that have a value child, they should append the value of - * any selected items to the provided string buffer. For children - * that have a copy child, they should copy the instance data element into - * |container|. - */ - void writeSelectedItems(in nsIDOMNode container, out AString stringBuffer); - - /** - * Set the context node, position, and size to be used for XPath evaluation. - * This is used by itemset to create a context for its anonymous item - * elements. - */ - void setContext(in nsIDOMElement node, in long position, in long size); }; diff --git a/mozilla/extensions/xforms/nsXFormsAtoms.cpp b/mozilla/extensions/xforms/nsXFormsAtoms.cpp index 98d911cdb9b..5fab5d26f03 100644 --- a/mozilla/extensions/xforms/nsXFormsAtoms.cpp +++ b/mozilla/extensions/xforms/nsXFormsAtoms.cpp @@ -62,6 +62,7 @@ nsIAtom *nsXFormsAtoms::clazz; nsIAtom *nsXFormsAtoms::deferredBindListProperty; nsIAtom *nsXFormsAtoms::readyForBindProperty; nsIAtom *nsXFormsAtoms::accesskey; +nsIAtom *nsXFormsAtoms::fatalError; const nsStaticAtom nsXFormsAtoms::Atoms_info[] = { { "src", &nsXFormsAtoms::src }, @@ -86,7 +87,8 @@ const nsStaticAtom nsXFormsAtoms::Atoms_info[] = { { "class", &nsXFormsAtoms::clazz }, { "DeferredBindListProperty", &nsXFormsAtoms::deferredBindListProperty }, { "ReadyForBindProperty", &nsXFormsAtoms::readyForBindProperty }, - { "accesskey", &nsXFormsAtoms::accesskey } + { "accesskey", &nsXFormsAtoms::accesskey }, + { "fatalError", &nsXFormsAtoms::fatalError } }; void diff --git a/mozilla/extensions/xforms/nsXFormsAtoms.h b/mozilla/extensions/xforms/nsXFormsAtoms.h index 1f173232c11..7e1d76b71f7 100644 --- a/mozilla/extensions/xforms/nsXFormsAtoms.h +++ b/mozilla/extensions/xforms/nsXFormsAtoms.h @@ -70,6 +70,7 @@ class nsXFormsAtoms static NS_HIDDEN_(nsIAtom *) deferredBindListProperty; static NS_HIDDEN_(nsIAtom *) readyForBindProperty; static NS_HIDDEN_(nsIAtom *) accesskey; + static NS_HIDDEN_(nsIAtom *) fatalError; static NS_HIDDEN_(void) InitAtoms(); diff --git a/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp b/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp index 3f7570b5ce5..4bde0d6151f 100644 --- a/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsChoicesElement.cpp @@ -44,21 +44,16 @@ #include "nsIXTFBindableElementWrapper.h" #include "nsIDOMDocument.h" #include "nsIDOMNodeList.h" +#include "nsIXFormsControl.h" #include "nsXFormsUtils.h" #include "nsArray.h" #include "nsIXTFXMLVisualWrapper.h" -/** - * Implementation of XForms \ element. This creates an HTML - * optgroup element and inserts any childrens' anonymous content as children - * of the optgroup. - */ - class nsXFormsChoicesElement : public nsXFormsBindableStub, public nsIXFormsSelectChild { public: - nsXFormsChoicesElement() : mElement(nsnull) {} + nsXFormsChoicesElement() : mElement(nsnull), mDoneAddingChildren(PR_FALSE) {} NS_DECL_ISUPPORTS_INHERITED @@ -72,16 +67,15 @@ public: NS_IMETHOD BeginAddingChildren(); NS_IMETHOD DoneAddingChildren(); - // nsIXFormsControlBase overrides - NS_IMETHOD Refresh(); - // nsIXFormsSelectChild NS_DECL_NSIXFORMSSELECTCHILD private: - nsIDOMElement* mElement; - nsCOMPtr mOptGroup; - PRBool mInsideSelect1; + nsIDOMElement* mElement; + PRBool mDoneAddingChildren; + + void Refresh(); + }; NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsChoicesElement, @@ -100,8 +94,6 @@ nsXFormsChoicesElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper) nsIXTFElement::NOTIFY_CHILD_REMOVED | nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN); - mInsideSelect1 = PR_FALSE; - nsCOMPtr node; aWrapper->GetElementNode(getter_AddRefs(node)); @@ -112,42 +104,13 @@ nsXFormsChoicesElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper) mElement = node; NS_ASSERTION(mElement, "Wrapper is not an nsIDOMElement, we'll crash soon"); - // Our anonymous content structure in . - nsCOMPtr element; - domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML), - NS_LITERAL_STRING("optgroup"), - getter_AddRefs(element)); - - mOptGroup = do_QueryInterface(element); - NS_ENSURE_TRUE(mOptGroup, NS_ERROR_FAILURE); - return NS_OK; } NS_IMETHODIMP nsXFormsChoicesElement::ParentChanged(nsIDOMElement *aNewParent) { - mInsideSelect1 = PR_FALSE; if (aNewParent) { - nsCOMPtr parent, tmp; - mElement->GetParentNode(getter_AddRefs(parent)); - while (parent) { - if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) { - mInsideSelect1 = PR_TRUE; - break; - } - tmp.swap(parent); - tmp->GetParentNode(getter_AddRefs(parent)); - } Refresh(); } return NS_OK; @@ -186,9 +149,7 @@ nsXFormsChoicesElement::ChildAppended(nsIDOMNode *aChild) NS_IMETHODIMP nsXFormsChoicesElement::ChildRemoved(PRUint32 aIndex) { - // TODO: should remove the anonymous content owned by the removed item. - - // TOOD: only need to Refresh() when a label child is removed, but it's + // XXX: only need to Refresh() when a label child is removed, but it's // not possible to get ahold of the actual removed child at this point. Refresh(); @@ -211,6 +172,8 @@ nsXFormsChoicesElement::BeginAddingChildren() NS_IMETHODIMP nsXFormsChoicesElement::DoneAddingChildren() { + mDoneAddingChildren = PR_TRUE; + // Unsuppress notifications nsCOMPtr wrapper = do_QueryInterface(mElement); NS_ASSERTION(wrapper, "huh? our element must be an xtf wrapper"); @@ -220,36 +183,6 @@ nsXFormsChoicesElement::DoneAddingChildren() nsIXTFElement::NOTIFY_CHILD_APPENDED | nsIXTFElement::NOTIFY_CHILD_REMOVED); - // Walk our children and get their anonymous content. - nsCOMPtr children; - nsresult rv = mElement->GetChildNodes(getter_AddRefs(children)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr childNode, childAnonymousNode, nodeReturn; - nsCOMPtr childItem; - - PRUint32 childCount = 0; - children->GetLength(&childCount); - - for (PRUint32 i = 0; i < childCount; ++i) { - children->Item(i, getter_AddRefs(childNode)); - childItem = do_QueryInterface(childNode); - if (childItem) { - nsCOMPtr childItems; - childItem->GetAnonymousNodes(getter_AddRefs(childItems)); - if (childItems) { - PRUint32 childNodesLength = 0; - childItems->GetLength(&childNodesLength); - - for (PRUint32 j = 0; j < childNodesLength; ++j) { - childAnonymousNode = do_QueryElementAt(childItems, j); - mOptGroup->AppendChild(childAnonymousNode, - getter_AddRefs(nodeReturn)); - } - } - } - } - // Assume that we've got something worth refreshing now. Refresh(); return NS_OK; @@ -257,19 +190,6 @@ nsXFormsChoicesElement::DoneAddingChildren() // nsIXFormsSelectChild -NS_IMETHODIMP -nsXFormsChoicesElement::GetAnonymousNodes(nsIArray **aNodes) -{ - nsCOMPtr array; - nsresult rv = NS_NewArray(getter_AddRefs(array)); - NS_ENSURE_SUCCESS(rv, rv); - - array->AppendElement(mOptGroup, PR_FALSE); - - NS_ADDREF(*aNodes = array); - return NS_OK; -} - NS_IMETHODIMP nsXFormsChoicesElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode **aSelected) { @@ -299,122 +219,27 @@ nsXFormsChoicesElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode ** return NS_OK; } -NS_IMETHODIMP -nsXFormsChoicesElement::SelectItemsByValue(const nsStringArray &aValueList) -{ - nsCOMPtr children; - nsresult rv = mElement->GetChildNodes(getter_AddRefs(children)); - NS_ENSURE_SUCCESS(rv, rv); - - PRUint32 childCount = 0; - children->GetLength(&childCount); - - nsCOMPtr childNode; - nsCOMPtr childItem; - - for (PRUint32 i = 0; i < childCount; ++i) { - children->Item(i, getter_AddRefs(childNode)); - childItem = do_QueryInterface(childNode); - if (childItem) { - childItem->SelectItemsByValue(aValueList); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsChoicesElement::SelectItemsByContent(nsIDOMNode *aNode) -{ - // Not applicable for choices element. - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsChoicesElement::WriteSelectedItems(nsIDOMNode *aContainer, - nsAString &aStringBuffer) -{ - nsCOMPtr children; - nsresult rv = mElement->GetChildNodes(getter_AddRefs(children)); - NS_ENSURE_SUCCESS(rv, rv); - - PRUint32 childCount = 0; - children->GetLength(&childCount); - - nsCOMPtr childNode; - nsCOMPtr childItem; - - for (PRUint32 i = 0; i < childCount; ++i) { - children->Item(i, getter_AddRefs(childNode)); - childItem = do_QueryInterface(childNode); - if (childItem) { - childItem->WriteSelectedItems(aContainer, aStringBuffer); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsChoicesElement::SetContext(nsIDOMElement *aContextNode, - PRInt32 aContextPosition, - PRInt32 aContextSize) -{ - // choices cannot be created by an itemset, so we don't need to worry - // about this case. - return NS_OK; -} - // internal methods -NS_IMETHODIMP +void nsXFormsChoicesElement::Refresh() { - if (mInsideSelect1) { - // is XBLized, so there is no need to recreate UI - - // XBL will do it for us. - return NS_OK; + if (mDoneAddingChildren) { + nsCOMPtr parent, current; + current = mElement; + do { + current->GetParentNode(getter_AddRefs(parent)); + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1")) || + nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select"))) { + nsCOMPtr select(do_QueryInterface(parent)); + if (select) { + select->Refresh(); + } + return; + } + current = parent; + } while(current); } - - // Remove any existing first child that is not an option, to clear out - // any existing label. - nsCOMPtr firstChild, child2; - nsresult rv = mOptGroup->GetFirstChild(getter_AddRefs(firstChild)); - NS_ENSURE_SUCCESS(rv, rv); - - nsAutoString value; - - if (firstChild) { - firstChild->GetLocalName(value); - if (!value.EqualsLiteral("option")) { - mOptGroup->RemoveChild(firstChild, getter_AddRefs(child2)); - mOptGroup->GetFirstChild(getter_AddRefs(firstChild)); - } - } - - // We need to find our label element and clone it into the optgroup. - // This content will appear before any of the optgroup's options. - - nsCOMPtr children; - rv = mElement->GetChildNodes(getter_AddRefs(children)); - NS_ENSURE_SUCCESS(rv, rv); - - PRUint32 childCount; - children->GetLength(&childCount); - - nsCOMPtr child; - nsAutoString labelValue; - - for (PRUint32 i = 0; i < childCount; ++i) { - children->Item(i, getter_AddRefs(child)); - if (nsXFormsUtils::IsLabelElement(child)) { - // Clone our label into the optgroup - child->CloneNode(PR_TRUE, getter_AddRefs(child2)); - mOptGroup->InsertBefore(child2, firstChild, getter_AddRefs(child)); - } - } - - return NS_OK; } NS_HIDDEN_(nsresult) diff --git a/mozilla/extensions/xforms/nsXFormsControlStub.cpp b/mozilla/extensions/xforms/nsXFormsControlStub.cpp index f130184315a..4e13523a643 100644 --- a/mozilla/extensions/xforms/nsXFormsControlStub.cpp +++ b/mozilla/extensions/xforms/nsXFormsControlStub.cpp @@ -46,12 +46,17 @@ #include "nsIDOMKeyEvent.h" #include "nsIDOMEventTarget.h" #include "nsIDOMXPathResult.h" +#include "nsIDOMDocumentView.h" +#include "nsIDOMAbstractView.h" #include "nsIXTFXMLVisualWrapper.h" #include "nsIDocument.h" #include "nsXFormsModelElement.h" #include "nsPIDOMWindow.h" #include "nsIFocusController.h" #include "nsIScriptGlobalObject.h" +#include "nsIServiceManager.h" +#include "nsIPrefBranch.h" +#include "nsIPrefService.h" /** This class is used to generate xforms-hint and xforms-help events.*/ class nsXFormsHintHelpListener : public nsIDOMEventListener { @@ -418,12 +423,69 @@ nsXFormsControlStubBase::HandleDefault(nsIDOMEvent *aEvent, } else { focusController->MoveFocus(PR_FALSE, nsnull); } + } else if (type.EqualsASCII(sXFormsEventsEntries[eEvent_BindingException].name)) { + *aHandled = HandleBindingException(); } } return NS_OK; } +PRBool +nsXFormsControlStubBase::HandleBindingException() +{ + if (!mElement) { + return PR_FALSE; + } + nsCOMPtr doc; + mElement->GetOwnerDocument(getter_AddRefs(doc)); + + nsCOMPtr iDoc(do_QueryInterface(doc)); + if (!iDoc) { + return PR_FALSE; + } + + // check for fatalError property, enforcing that only one fatal error will + // be shown to the user + if (iDoc->GetProperty(nsXFormsAtoms::fatalError)) { + return PR_FALSE; + } + iDoc->SetProperty(nsXFormsAtoms::fatalError, iDoc); + + // Check for preference, disabling this popup + PRBool disablePopup = PR_FALSE; + nsresult rv; + nsCOMPtr pref = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv) && pref) { + PRBool val; + if (NS_SUCCEEDED(pref->GetBoolPref("xforms.disablePopup", &val))) + disablePopup = val; + } + if (disablePopup) + return PR_FALSE; + + // Get nsIDOMWindowInternal + nsCOMPtr dview(do_QueryInterface(doc)); + if (!dview) + return PR_FALSE; + + nsCOMPtr aview; + dview->GetDefaultView(getter_AddRefs(aview)); + + nsCOMPtr internal(do_QueryInterface(aview)); + if (!internal) + return PR_FALSE; + + // Show popup + nsCOMPtr messageWindow; + rv = internal->OpenDialog(NS_LITERAL_STRING("chrome://xforms/content/bindingex.xul"), + NS_LITERAL_STRING("XFormsBindingException"), + NS_LITERAL_STRING("modal,dialog,chrome,dependent"), + nsnull, getter_AddRefs(messageWindow)); + return NS_SUCCEEDED(rv); +} + + #ifdef DEBUG_smaug static nsVoidArray* sControlList = nsnull; class ControlDebug diff --git a/mozilla/extensions/xforms/nsXFormsControlStub.h b/mozilla/extensions/xforms/nsXFormsControlStub.h index b57a51b7b1d..943dd102faa 100644 --- a/mozilla/extensions/xforms/nsXFormsControlStub.h +++ b/mozilla/extensions/xforms/nsXFormsControlStub.h @@ -65,11 +65,6 @@ class nsIXTFXMLVisualWrapper; /** * Common stub for all XForms controls that inherit from nsIXFormsControl and * is bound to an instance node. - * - * @bug If a control has a model attribute, but no binding attributes we fail - * to set this as the context for children. We need to return the contextnode - * from EvaluateNodeBinding in that case, and return that in GetContext(). (XXX) - * @see http://bugzilla.mozilla.org/show_bug.cgi?id=280366 */ class nsXFormsControlStubBase : public nsIXFormsControl { @@ -230,6 +225,16 @@ protected: /** Removes the index change event listeners */ void RemoveIndexListeners(); + + /** + * Shows an error dialog for the user the first time an + * xforms-binding-exception event is received by the control. + * + * The dialog can be disabled via the |xforms.disablePopup| preference. + * + * @return Whether handling was successful + */ + PRBool HandleBindingException(); }; diff --git a/mozilla/extensions/xforms/nsXFormsDispatchElement.cpp b/mozilla/extensions/xforms/nsXFormsDispatchElement.cpp index 4b132cc3d8a..1091428335b 100644 --- a/mozilla/extensions/xforms/nsXFormsDispatchElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsDispatchElement.cpp @@ -101,7 +101,8 @@ nsXFormsDispatchElement::HandleAction(nsIDOMEvent* aEvent, return NS_OK; nsCOMPtr el; - doc->GetElementById(target, getter_AddRefs(el)); + nsXFormsUtils::GetElementById(doc, target, PR_FALSE, mElement, + getter_AddRefs(el)); if (!el) return NS_OK; diff --git a/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp b/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp index 4c85d7b44a7..d80151bebf6 100644 --- a/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsInstanceElement.cpp @@ -70,6 +70,12 @@ nsXFormsInstanceElement::nsXFormsInstanceElement() NS_IMETHODIMP nsXFormsInstanceElement::OnDestroyed() { + if (mChannel) { + // better be a good citizen and tell the browser that we don't need this + // resource anymore. + mChannel->Cancel(NS_BINDING_ABORTED); + mChannel = nsnull; + } mListener = nsnull; mElement = nsnull; return NS_OK; @@ -209,9 +215,23 @@ nsXFormsInstanceElement::OnChannelRedirect(nsIChannel *OldChannel, // nsIStreamListener +// It is possible that mListener could be null here. If the document hit a +// parsing error after we've already started to load the external source, then +// Mozilla will destroy all of the elements and the document in order to load +// the parser error page. This will cause mListener to become null but since +// the channel will hold a nsCOMPtr to the nsXFormsInstanceElement preventing +// it from being freed up, the channel will still be able to call the +// nsIStreamListener functions that we implement here. And calling +// mChannel->Cancel() is no guarantee that these other notifications won't come +// through if the timing is wrong. So we need to check for mElement below +// before we handle any of the stream notifications. + NS_IMETHODIMP nsXFormsInstanceElement::OnStartRequest(nsIRequest *request, nsISupports *ctx) { + if (!mElement) { + return NS_OK; + } NS_ASSERTION(mListener, "No stream listener for document!"); return mListener->OnStartRequest(request, ctx); } @@ -223,6 +243,9 @@ nsXFormsInstanceElement::OnDataAvailable(nsIRequest *aRequest, PRUint32 sourceOffset, PRUint32 count) { + if (!mElement) { + return NS_OK; + } NS_ASSERTION(mListener, "No stream listener for document!"); return mListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset, count); } @@ -231,6 +254,12 @@ NS_IMETHODIMP nsXFormsInstanceElement::OnStopRequest(nsIRequest *request, nsISupports *ctx, nsresult status) { + mChannel = nsnull; + if (status == NS_BINDING_ABORTED) { + // looks like our element has already been destroyed. No use continuing on. + return NS_OK; + } + NS_ASSERTION(mListener, "No stream listener for document!"); mListener->OnStopRequest(request, ctx, status); @@ -416,16 +445,15 @@ nsXFormsInstanceElement::LoadExternalInstance(const nsAString &aSrc) // Using the same load group as the main document and creating // the channel with LOAD_NORMAL flag delays the dispatching of // the 'load' event until all instance data documents have been loaded. - nsCOMPtr docChannel; - NS_NewChannel(getter_AddRefs(docChannel), uri, nsnull, loadGroup, + NS_NewChannel(getter_AddRefs(mChannel), uri, nsnull, loadGroup, nsnull, nsIRequest::LOAD_NORMAL); - if (docChannel) { - rv = newDoc->StartDocumentLoad(kLoadAsData, docChannel, loadGroup, nsnull, + if (mChannel) { + rv = newDoc->StartDocumentLoad(kLoadAsData, mChannel, loadGroup, nsnull, getter_AddRefs(mListener), PR_TRUE); if (NS_SUCCEEDED(rv)) { - docChannel->SetNotificationCallbacks(this); - rv = docChannel->AsyncOpen(this, nsnull); + mChannel->SetNotificationCallbacks(this); + rv = mChannel->AsyncOpen(this, nsnull); } } } else { diff --git a/mozilla/extensions/xforms/nsXFormsInstanceElement.h b/mozilla/extensions/xforms/nsXFormsInstanceElement.h index bb3a369bc62..0a40c2d0a46 100644 --- a/mozilla/extensions/xforms/nsXFormsInstanceElement.h +++ b/mozilla/extensions/xforms/nsXFormsInstanceElement.h @@ -93,6 +93,7 @@ private: nsIDOMElement *mElement; nsCOMPtr mListener; PRBool mIgnoreAttributeChanges; + nsCOMPtr mChannel; }; NS_HIDDEN_(nsresult) diff --git a/mozilla/extensions/xforms/nsXFormsItemElement.cpp b/mozilla/extensions/xforms/nsXFormsItemElement.cpp index ee0c14c0bb6..e600a3be58b 100644 --- a/mozilla/extensions/xforms/nsXFormsItemElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsItemElement.cpp @@ -69,10 +69,7 @@ class nsXFormsItemElement : public nsXFormsBindableStub, public nsIXFormsItemElement { public: - nsXFormsItemElement() : mElement(nsnull), - mContextPosition(0), - mContextSize(0), - mInsideSelect1(PR_FALSE) + nsXFormsItemElement() : mElement(nsnull), mDoneAddingChildren(PR_FALSE) { } @@ -89,22 +86,17 @@ public: NS_IMETHOD BeginAddingChildren(); NS_IMETHOD DoneAddingChildren(); - // nsIXFormsControlBase overrides - NS_IMETHOD Refresh(); + void Refresh(); // nsIXFormsSelectChild NS_DECL_NSIXFORMSSELECTCHILD private: - nsIDOMElement* mElement; - nsCOMPtr mOption; + PRBool mDoneAddingChildren; // context node (used by itemset in select) nsCOMPtr mContextNode; - PRInt32 mContextPosition; - PRInt32 mContextSize; - PRBool mInsideSelect1; }; NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsItemElement, @@ -135,42 +127,13 @@ nsXFormsItemElement::OnCreated(nsIXTFBindableElementWrapper *aWrapper) mElement = node; NS_ASSERTION(mElement, "Wrapper is not an nsIDOMElement, we'll crash soon"); - // Our anonymous content structure in - - nsCOMPtr domDoc; - node->GetOwnerDocument(getter_AddRefs(domDoc)); - - nsCOMPtr element; - domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML), - NS_LITERAL_STRING("option"), - getter_AddRefs(element)); - - mOption = do_QueryInterface(element); - NS_ENSURE_TRUE(mOption, NS_ERROR_FAILURE); - return NS_OK; } NS_IMETHODIMP nsXFormsItemElement::ParentChanged(nsIDOMElement *aNewParent) { - mInsideSelect1 = PR_FALSE; if (aNewParent) { - nsCOMPtr parent, tmp; - mElement->GetParentNode(getter_AddRefs(parent)); - while (parent) { - if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) { - mInsideSelect1 = PR_TRUE; - break; - } - tmp.swap(parent); - tmp->GetParentNode(getter_AddRefs(parent)); - } - Refresh(); } @@ -236,6 +199,8 @@ nsXFormsItemElement::BeginAddingChildren() NS_IMETHODIMP nsXFormsItemElement::DoneAddingChildren() { + mDoneAddingChildren = PR_TRUE; + // Unsuppress notifications nsCOMPtr wrapper = do_QueryInterface(mElement); NS_ASSERTION(wrapper, "huh? our element must be an xtf wrapper"); @@ -252,19 +217,6 @@ nsXFormsItemElement::DoneAddingChildren() // nsIXFormsSelectChild -NS_IMETHODIMP -nsXFormsItemElement::GetAnonymousNodes(nsIArray **aNodes) -{ - nsCOMPtr array; - nsresult rv = NS_NewArray(getter_AddRefs(array)); - NS_ENSURE_SUCCESS(rv, rv); - - array->AppendElement(mOption, PR_FALSE); - - NS_ADDREF(*aNodes = array); - return NS_OK; -} - NS_IMETHODIMP nsXFormsItemElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode **aSelected) { @@ -281,64 +233,6 @@ nsXFormsItemElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode **aSe return NS_OK; } -NS_IMETHODIMP -nsXFormsItemElement::SelectItemsByValue(const nsStringArray &aValueList) -{ - nsAutoString value; - nsresult rv = GetValue(value); - NS_ENSURE_SUCCESS(rv, rv); - - PRInt32 count = aValueList.Count(); - for (PRInt32 i = 0; i < count; ++i) { - if (aValueList[i]->Equals(value)) { - mOption->SetSelected(PR_TRUE); - break; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsItemElement::SelectItemsByContent(nsIDOMNode *aNode) -{ - // TODO: implement support for \ element. - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsItemElement::WriteSelectedItems(nsIDOMNode *aContainer, - nsAString &aStringBuffer) -{ - PRBool selected; - mOption->GetSelected(&selected); - if (!selected) - return NS_OK; - - nsAutoString value; - nsresult rv = GetValue(value); - NS_ENSURE_SUCCESS(rv, rv); - - if(aStringBuffer.IsEmpty()){ - aStringBuffer.Append(value); - } - else{ - aStringBuffer.Append(NS_LITERAL_STRING(" ") + value); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsItemElement::SetContext(nsIDOMElement *aContextNode, - PRInt32 aContextPosition, PRInt32 aContextSize) -{ - mContextNode = aContextNode; - mContextPosition = aContextPosition; - mContextSize = aContextSize; - return NS_OK; -} - NS_IMETHODIMP nsXFormsItemElement::GetValue(nsAString &aValue) { @@ -380,67 +274,26 @@ nsXFormsItemElement::GetValue(nsAString &aValue) return NS_OK; } -NS_IMETHODIMP +void nsXFormsItemElement::Refresh() { - if (mInsideSelect1) { - // is XBLized, so there is no need to recreate UI - - // XBL will do it for us. - return NS_OK; - } - - // Clear out all of the existing option text - nsCOMPtr child, child2; - while (NS_SUCCEEDED(mOption->GetFirstChild(getter_AddRefs(child))) && child) - mOption->RemoveChild(child, getter_AddRefs(child2)); - - // We need to find our label child, serialize its contents - // (which can be xtf-generated), and set that as our label attribute. - - nsCOMPtr children; - nsresult rv = mElement->GetChildNodes(getter_AddRefs(children)); - NS_ENSURE_SUCCESS(rv, rv); - - PRUint32 childCount; - children->GetLength(&childCount); - - nsAutoString value; - - nsCOMPtr doc; - mElement->GetOwnerDocument(getter_AddRefs(doc)); - - nsCOMPtr container; - doc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS), - NS_LITERAL_STRING("contextcontainer-inline"), - getter_AddRefs(container)); - - NS_NAMED_LITERAL_STRING(modelStr, "model"); - - nsAutoString modelID; - mElement->GetAttribute(modelStr, modelID); - container->SetAttribute(modelStr, modelID); - - nsCOMPtr context = do_QueryInterface(container); - context->SetContext(mContextNode, 1, 1); - - for (PRUint32 i = 0; i < childCount; ++i) { - children->Item(i, getter_AddRefs(child)); - child->GetLocalName(value); - if (value.EqualsLiteral("label")) { - child->GetNamespaceURI(value); - if (value.EqualsLiteral(NS_NAMESPACE_XFORMS)) { - child->CloneNode(PR_TRUE, getter_AddRefs(child2)); - container->AppendChild(child2, getter_AddRefs(child)); + if (mDoneAddingChildren) { + nsCOMPtr parent, current; + current = mElement; + do { + current->GetParentNode(getter_AddRefs(parent)); + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1")) || + nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select"))) { + nsCOMPtr select(do_QueryInterface(parent)); + if (select) { + select->Refresh(); + } + return; } - } + current = parent; + } while(current); } - - nsCOMPtr childReturn; - mOption->AppendChild(container, getter_AddRefs(childReturn)); - - return NS_OK; } - NS_IMETHODIMP nsXFormsItemElement::SetActive(PRBool aActive) { @@ -514,10 +367,11 @@ nsXFormsItemElement::LabelRefreshed() current = mElement; do { current->GetParentNode(getter_AddRefs(parent)); - if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1"))) { - nsCOMPtr select1(do_QueryInterface(parent)); - if (select1) { - select1->Refresh(); + if (nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select1")) || + nsXFormsUtils::IsXFormsElement(parent, NS_LITERAL_STRING("select"))) { + nsCOMPtr select(do_QueryInterface(parent)); + if (select) { + //select->Refresh(); } return NS_OK; } diff --git a/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp b/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp index 9bade0d216d..caa807b428c 100644 --- a/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp +++ b/mozilla/extensions/xforms/nsXFormsItemSetElement.cpp @@ -175,37 +175,6 @@ nsXFormsItemSetElement::DoneAddingChildren() // nsIXFormsSelectChild -NS_IMETHODIMP -nsXFormsItemSetElement::GetAnonymousNodes(nsIArray **aNodes) -{ - nsCOMPtr array; - nsresult rv = NS_NewArray(getter_AddRefs(array)); - NS_ENSURE_SUCCESS(rv, rv); - - PRInt32 itemCount = mItems.Count(); - nsCOMPtr childNodes; - nsCOMPtr childOption; - - for (PRInt32 i = 0; i < itemCount; ++i) { - mItems[i]->GetAnonymousNodes(getter_AddRefs(childNodes)); - if (!childNodes) - continue; - - PRUint32 anonLength = 0; - childNodes->GetLength(&anonLength); - - for (PRUint32 j = 0; j < anonLength; ++j) { - childOption = do_QueryElementAt(childNodes, j); - NS_ASSERTION(childOption, "invalid nodelist"); - - array->AppendElement(childOption, PR_FALSE); - } - } - - NS_ADDREF(*aNodes = array); - return NS_OK; -} - NS_IMETHODIMP nsXFormsItemSetElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode **aSelected) { @@ -224,7 +193,7 @@ nsXFormsItemSetElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode ** anonContent->GetFirstChild(getter_AddRefs(child)); // Trying to select the first possible (generated) \ element. while (child) { - nsCOMPtr selectChild(do_QueryInterface(tmp)); + nsCOMPtr selectChild(do_QueryInterface(child)); if (selectChild) { selectChild->SelectItemByValue(aValue, aSelected); if (*aSelected) { @@ -237,35 +206,6 @@ nsXFormsItemSetElement::SelectItemByValue(const nsAString &aValue, nsIDOMNode ** return NS_OK; } -NS_IMETHODIMP -nsXFormsItemSetElement::SelectItemsByValue(const nsStringArray &aValueList) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsItemSetElement::SelectItemsByContent(nsIDOMNode *aNode) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsItemSetElement::WriteSelectedItems(nsIDOMNode *aContainer, - nsAString &aStringBuffer) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsItemSetElement::SetContext(nsIDOMElement *aContextNode, - PRInt32 aContextPosition, - PRInt32 aContextSize) -{ - // itemset can't be inside another itemset, so we don't need to worry about - // this. - return NS_OK; -} - // internal methods NS_IMETHODIMP @@ -312,125 +252,82 @@ nsXFormsItemSetElement::Refresh() PRUint32 templateNodeCount = 0; if (templateNodes) templateNodes->GetLength(&templateNodeCount); - - nsCOMPtr document; - mElement->GetOwnerDocument(getter_AddRefs(document)); - if (!document) + + if (!domDoc) return NS_OK; PRUint32 nodeCount; result->GetSnapshotLength(&nodeCount); - // XXX Possibly cleanup this when XBLizing (mSelect) - // - // - - nsCOMPtr domDoc; - mElement->GetOwnerDocument(getter_AddRefs(domDoc)); - - domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML), - NS_LITERAL_STRING("label"), - getter_AddRefs(mLabel)); - NS_ENSURE_TRUE(mLabel, NS_ERROR_FAILURE); - - nsCOMPtr element; - nsCOMPtr childReturn; - domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML), - NS_LITERAL_STRING("span"), - getter_AddRefs(element)); - NS_ENSURE_TRUE(element, NS_ERROR_FAILURE); - - mLabel->AppendChild(element, getter_AddRefs(childReturn)); - - domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML), - NS_LITERAL_STRING("select"), - getter_AddRefs(element)); - - mSelect = do_QueryInterface(element); - NS_ENSURE_TRUE(mSelect, NS_ERROR_FAILURE); - - // Unless we're a select1, set multiple=true - nsAutoString tag; - mElement->GetLocalName(tag); - if (!tag.EqualsLiteral("select1")) { - mSelect->SetMultiple(PR_TRUE); - - // TODO: should leave default size=1 for select1, but options don't - // select correctly if we do that. Need to figure out why. - // mSelect->SetSize(4); - } - - // Default to minimal/compact appearance - mSelect->SetSize(4); - - // TODO: support "selection" and "incremental" attributes. - - mLabel->AppendChild(mSelect, getter_AddRefs(childReturn)); - - nsCOMPtr targ = do_QueryInterface(mSelect); - NS_ASSERTION(targ, "Select must be an event target"); - - // We need an onchange handler to support non-incremental mode, and - // a blur handler to support incremental mode. - targ->AddEventListener(NS_LITERAL_STRING("change"), this, PR_FALSE); - targ->AddEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE); - - return NS_OK; -} - -// nsIXTFVisual - -NS_IMETHODIMP -nsXFormsSelectElement::GetVisualContent(nsIDOMElement **aElement) -{ - NS_ADDREF(*aElement = mLabel); - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsSelectElement::GetInsertionPoint(nsIDOMElement **aPoint) -{ - nsCOMPtr childNode; - mLabel->GetFirstChild(getter_AddRefs(childNode)); - return CallQueryInterface(childNode, aPoint); -} - -// nsIXTFElement - -void -nsXFormsSelectElement::RemoveChildren(nsIDOMNode* aParent) -{ - if (aParent) { - nsCOMPtr childNode, nodeReturn; - while (NS_SUCCEEDED(aParent->GetFirstChild(getter_AddRefs(childNode))) && - childNode) { - aParent->RemoveChild(childNode, getter_AddRefs(nodeReturn)); - - if (nodeReturn) { - RemoveChildren(nodeReturn); - } - } - } -} - -NS_IMETHODIMP -nsXFormsSelectElement::OnDestroyed() -{ - nsCOMPtr targ = do_QueryInterface(mSelect); - if (NS_LIKELY(targ != nsnull)) { - targ->RemoveEventListener(NS_LITERAL_STRING("blur"), this, PR_FALSE); - targ->RemoveEventListener(NS_LITERAL_STRING("change"), this, PR_FALSE); - } - - // XXX For some reason we leak and - //