mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 05:15:45 +00:00
XForms Bug 283219 - trigger with appearance minimal scenario fails. Patch by smaug, r=beaufour,me
This commit is contained in:
parent
523a1ce6f3
commit
0ccb1b812a
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user