XForms Bug 283219 - trigger with appearance minimal scenario fails. Patch by smaug, r=beaufour,me

This commit is contained in:
doronr%us.ibm.com 2005-02-28 20:12:01 +00:00
parent 523a1ce6f3
commit 0ccb1b812a

View File

@ -38,14 +38,18 @@
#include "nsIXTFXMLVisual.h"
#include "nsIDOM3Node.h"
#include "nsIDOMElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMUIEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMHTMLButtonElement.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMAbstractView.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIXTFXMLVisualWrapper.h"
#include "nsXFormsAtoms.h"
#include "nsXFormsUtils.h"
#include "nsXFormsControlStub.h"
#include "nsIXFormsSubmitElement.h"
@ -61,12 +65,27 @@ public:
NS_IMETHOD GetVisualContent(nsIDOMElement **aElement);
NS_IMETHOD GetInsertionPoint(nsIDOMElement **aElement);
// nsIXTFElement overrides
NS_IMETHOD BeginAddingChildren();
NS_IMETHOD DoneAddingChildren();
NS_IMETHOD AttributeRemoved(nsIAtom *aName);
NS_IMETHOD AttributeSet(nsIAtom *aName, const nsAString &aValue);
// nsIXFormsControl
NS_IMETHOD HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled);
NS_IMETHOD Refresh();
NS_IMETHOD TryFocus(PRBool* aOK);
// nsXFormsTriggerElement
nsXFormsTriggerElement() :
mIsMinimal(PR_FALSE), mDoneAddingChildren(PR_TRUE) {}
protected:
nsCOMPtr<nsIDOMHTMLButtonElement> mButton;
nsCOMPtr<nsIDOMElement> mVisualContent;
nsCOMPtr<nsIDOMHTMLElement> mHTMLElement;
nsCOMPtr<nsIDOMHTMLElement> mInsertionPoint;
PRPackedBool mIsMinimal;
PRPackedBool mDoneAddingChildren;
};
// nsIXTFXMLVisual
@ -78,7 +97,10 @@ nsXFormsTriggerElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper)
NS_ENSURE_SUCCESS(rv, rv);
aWrapper->SetNotificationMask(kStandardNotificationMask |
nsIXTFElement::NOTIFY_HANDLE_DEFAULT);
nsIXTFElement::NOTIFY_HANDLE_DEFAULT |
nsIXTFElement::NOTIFY_BEGIN_ADDING_CHILDREN |
nsIXTFElement::NOTIFY_DONE_ADDING_CHILDREN |
nsIXTFElement::NOTIFY_ATTRIBUTE_REMOVED);
ResetHelpAndHint(PR_TRUE);
@ -86,13 +108,34 @@ nsXFormsTriggerElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper)
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_STATE(domDoc);
nsCOMPtr<nsIDOMElement> inputElement;
// Create visual (span + button)
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
NS_LITERAL_STRING("span"),
getter_AddRefs(mVisualContent));
nsCOMPtr<nsIDOMElement> button;
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
NS_LITERAL_STRING("button"),
getter_AddRefs(inputElement));
getter_AddRefs(button));
mButton = do_QueryInterface(inputElement);
NS_ENSURE_STATE(mButton);
nsCOMPtr<nsIDOMNode> insertedButton;
mVisualContent->AppendChild(button, getter_AddRefs(insertedButton));
mHTMLElement = do_QueryInterface(insertedButton);
NS_ENSURE_STATE(mHTMLElement);
// Create insertion point
nsCOMPtr<nsIDOMElement> span;
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
NS_LITERAL_STRING("span"),
getter_AddRefs(span));
NS_ENSURE_STATE(span);
nsCOMPtr<nsIDOMNode> insertedSpan;
rv = mHTMLElement->AppendChild(span, getter_AddRefs(insertedSpan));
NS_ENSURE_SUCCESS(rv, rv);
mInsertionPoint = do_QueryInterface(insertedSpan);
NS_ENSURE_STATE(mInsertionPoint);
return NS_OK;
}
@ -102,17 +145,141 @@ nsXFormsTriggerElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper)
NS_IMETHODIMP
nsXFormsTriggerElement::GetVisualContent(nsIDOMElement **aElement)
{
NS_ADDREF(*aElement = mButton);
NS_ADDREF(*aElement = mVisualContent);
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerElement::GetInsertionPoint(nsIDOMElement **aElement)
{
NS_ADDREF(*aElement = mButton);
NS_ADDREF(*aElement = mInsertionPoint);
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerElement::BeginAddingChildren()
{
mDoneAddingChildren = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerElement::DoneAddingChildren()
{
mDoneAddingChildren = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerElement::AttributeRemoved(nsIAtom *aName)
{
return aName == nsXFormsAtoms::appearance
? AttributeSet(aName, EmptyString())
: nsXFormsControlStub::AttributeRemoved(aName);
}
NS_IMETHODIMP
nsXFormsTriggerElement::AttributeSet(nsIAtom *aName, const nsAString &aValue)
{
if (aName == nsXFormsAtoms::appearance) {
if (mIsMinimal != aValue.EqualsLiteral("minimal")) {
nsCOMPtr<nsIDOMNode> parent, next, tmp;
if (mDoneAddingChildren) {
mElement->GetParentNode(getter_AddRefs(parent));
if (parent) {
mElement->GetNextSibling(getter_AddRefs(next));
// Removing this element temporarily from the document so that
// the UI will be re-created properly later.
parent->RemoveChild(mElement, getter_AddRefs(tmp));
}
}
// Switch state
mIsMinimal = !mIsMinimal;
// Create new element
nsCOMPtr<nsIDOMDocument> domDoc;
mVisualContent->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_STATE(domDoc);
nsCOMPtr<nsIDOMElement> htmlElement;
if (mIsMinimal) {
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
NS_LITERAL_STRING("span"),
getter_AddRefs(htmlElement));
} else {
domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML),
NS_LITERAL_STRING("button"),
getter_AddRefs(htmlElement));
}
NS_ENSURE_STATE(htmlElement);
// Append inner content (insertion point)
nsCOMPtr<nsIDOMNode> newnode;
nsresult rv = htmlElement->AppendChild(mInsertionPoint, getter_AddRefs(newnode));
NS_ENSURE_SUCCESS(rv, rv);
// Replace current visual
rv = mVisualContent->ReplaceChild(htmlElement, mHTMLElement, getter_AddRefs(tmp));
mHTMLElement = do_QueryInterface(htmlElement);
if (mDoneAddingChildren && parent)
parent->InsertBefore(mElement, next, getter_AddRefs(tmp));
}
} else {
nsXFormsControlStub::WillSetAttribute(aName, aValue);
}
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerElement::HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled)
{
nsresult rv;
rv = nsXFormsControlStub::HandleDefault(aEvent, aHandled);
NS_ENSURE_SUCCESS(rv, rv);
if (*aHandled || !mIsMinimal) {
return NS_OK;
}
nsAutoString type;
aEvent->GetType(type);
// Check for click on minimal trigger
if (!(*aHandled = type.EqualsLiteral("click")))
return NS_OK;
// We need to dend DOMActivate
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mElement);
NS_ENSURE_STATE(target);
nsCOMPtr<nsIDOMDocument> domDoc;
mElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMDocumentEvent> doc = do_QueryInterface(domDoc);
NS_ENSURE_STATE(doc);
nsCOMPtr<nsIDOMDocumentView> dView = do_QueryInterface(domDoc);
NS_ENSURE_STATE(dView);
nsCOMPtr<nsIDOMAbstractView> aView;
dView->GetDefaultView(getter_AddRefs(aView));
NS_ENSURE_STATE(aView);
nsCOMPtr<nsIDOMEvent> event;
doc->CreateEvent(NS_LITERAL_STRING("UIEvents"), getter_AddRefs(event));
nsCOMPtr<nsIDOMUIEvent> uiEvent = do_QueryInterface(event);
NS_ENSURE_TRUE(uiEvent, NS_ERROR_OUT_OF_MEMORY);
uiEvent->InitUIEvent(NS_LITERAL_STRING("DOMActivate"),
PR_TRUE,
PR_TRUE,
aView,
1); // Simple click
PRBool cancelled;
return target->DispatchEvent(uiEvent, &cancelled);
}
// nsIXFormsControl
NS_IMETHODIMP
@ -122,9 +289,9 @@ nsXFormsTriggerElement::Refresh()
}
NS_IMETHODIMP
nsXFormsTriggerElement::TryFocus(PRBool* aOK)
nsXFormsTriggerElement::TryFocus(PRBool *aOK)
{
*aOK = GetRelevantState() && nsXFormsUtils::FocusControl(mButton);
*aOK = GetRelevantState() && nsXFormsUtils::FocusControl(mHTMLElement);
return NS_OK;
}
@ -152,7 +319,7 @@ nsXFormsSubmitElement::HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled)
{
nsresult rv;
rv = nsXFormsControlStub::HandleDefault(aEvent, aHandled);
rv = nsXFormsTriggerElement::HandleDefault(aEvent, aHandled);
NS_ENSURE_SUCCESS(rv, rv);
if (*aHandled) {
return NS_OK;
@ -189,8 +356,11 @@ nsXFormsSubmitElement::HandleDefault(nsIDOMEvent *aEvent, PRBool *aHandled)
NS_IMETHODIMP
nsXFormsSubmitElement::SetDisabled(PRBool aDisable)
{
if (mButton)
mButton->SetDisabled(aDisable);
///
/// @todo Fix SetDisabled() behaviour when mIsMinimal == PR_TRUE (XXX)
nsCOMPtr<nsIDOMHTMLButtonElement> button = do_QueryInterface(mHTMLElement);
if (button)
button->SetDisabled(aDisable);
return NS_OK;
}