From f287a5b5c840e293ca955003462937ab2adbd26c Mon Sep 17 00:00:00 2001 From: "bryner%brianryner.com" Date: Sat, 29 Jan 2005 23:53:32 +0000 Subject: [PATCH] Implement XForms message element (bug 269428). Patch by smaug@welho.com, r=allan@beaufour.dk, sr=bryner. --- extensions/xforms/Makefile.in | 2 + extensions/xforms/nsXFormsActionElement.cpp | 66 +- extensions/xforms/nsXFormsActionElement.h | 14 +- extensions/xforms/nsXFormsAtoms.cpp | 2 + extensions/xforms/nsXFormsAtoms.h | 1 + extensions/xforms/nsXFormsControlStub.cpp | 67 ++ extensions/xforms/nsXFormsControlStub.h | 9 + extensions/xforms/nsXFormsElementFactory.cpp | 12 + extensions/xforms/nsXFormsMessageElement.cpp | 852 +++++++++++++++++++ extensions/xforms/nsXFormsTriggerElement.cpp | 2 + extensions/xforms/xforms.css | 7 + 11 files changed, 1027 insertions(+), 7 deletions(-) create mode 100644 extensions/xforms/nsXFormsMessageElement.cpp diff --git a/extensions/xforms/Makefile.in b/extensions/xforms/Makefile.in index 6b864ffabbf..7ac3d8c1765 100644 --- a/extensions/xforms/Makefile.in +++ b/extensions/xforms/Makefile.in @@ -69,6 +69,7 @@ REQUIRES = \ layout \ transformiix \ schemavalidation \ + intl \ $(NULL) XPIDLSRCS = \ @@ -119,6 +120,7 @@ CPPSRCS = \ nsXFormsSetFocusElement.cpp \ nsXFormsSetValueElement.cpp \ nsXFormsLoadElement.cpp \ + nsXFormsMessageElement.cpp \ nsXFormsLabelElement.cpp \ nsXFormsToggleElement.cpp \ nsXFormsCaseElement.cpp \ diff --git a/extensions/xforms/nsXFormsActionElement.cpp b/extensions/xforms/nsXFormsActionElement.cpp index e7ac7a571aa..5f21d5f147b 100644 --- a/extensions/xforms/nsXFormsActionElement.cpp +++ b/extensions/xforms/nsXFormsActionElement.cpp @@ -42,6 +42,10 @@ #include "nsIDOMDocument.h" #include "nsIDOMEvent.h" #include "nsIDOMElement.h" +#include "nsIXTFXMLVisualWrapper.h" + +#define ACTION_STYLE_HIDDEN \ + "position:absolute;z-index:2147483647;visibility:hidden;" #define DEFERRED_REBUILD 0x01 #define DEFERRED_RECALCULATE 0x02 @@ -52,11 +56,63 @@ nsXFormsActionElement::nsXFormsActionElement() { } -NS_IMPL_ISUPPORTS_INHERITED3(nsXFormsActionElement, - nsXFormsActionModuleBase, - nsIXTFElement, - nsIXTFGenericElement, - nsIXFormsActionElement) +NS_IMPL_ADDREF_INHERITED(nsXFormsActionElement, nsXFormsXMLVisualStub) +NS_IMPL_RELEASE_INHERITED(nsXFormsActionElement, nsXFormsXMLVisualStub) + +NS_INTERFACE_MAP_BEGIN(nsXFormsActionElement) + NS_INTERFACE_MAP_ENTRY(nsIXFormsActionModuleElement) + NS_INTERFACE_MAP_ENTRY(nsIXFormsActionElement) + NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) +NS_INTERFACE_MAP_END_INHERITING(nsXFormsXMLVisualStub) + +NS_IMETHODIMP +nsXFormsActionElement::OnCreated(nsIXTFXMLVisualWrapper *aWrapper) +{ + nsresult rv; + rv = aWrapper->GetElementNode(getter_AddRefs(mElement)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr domDoc; + mElement->GetOwnerDocument(getter_AddRefs(domDoc)); + rv = domDoc->CreateElementNS(NS_LITERAL_STRING(NS_NAMESPACE_XHTML), + NS_LITERAL_STRING("div"), + getter_AddRefs(mVisualElement)); + NS_ENSURE_SUCCESS(rv, rv); + if (mVisualElement) + mVisualElement->SetAttribute(NS_LITERAL_STRING("style"), + NS_LITERAL_STRING(ACTION_STYLE_HIDDEN)); + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsActionElement::GetVisualContent(nsIDOMElement **aElement) +{ + NS_IF_ADDREF(*aElement = mVisualElement); + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsActionElement::GetInsertionPoint(nsIDOMElement **aElement) +{ + NS_IF_ADDREF(*aElement = mVisualElement); + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsActionElement::OnDestroyed() { + mParentAction = nsnull; + mVisualElement = nsnull; + mElement = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsXFormsActionElement::HandleEvent(nsIDOMEvent* aEvent) +{ + if (!aEvent) + return NS_ERROR_INVALID_ARG; + return HandleAction(aEvent, nsnull); +} PR_STATIC_CALLBACK(PLDHashOperator) DoDeferredActions(nsISupports * aModel, PRUint32 aDeferred, diff --git a/extensions/xforms/nsXFormsActionElement.h b/extensions/xforms/nsXFormsActionElement.h index 613d6679e65..54cf7ec6e87 100644 --- a/extensions/xforms/nsXFormsActionElement.h +++ b/extensions/xforms/nsXFormsActionElement.h @@ -42,16 +42,26 @@ #include "nsIXFormsActionElement.h" #include "nsXFormsActionModuleBase.h" #include "nsDataHashtable.h" +#include "nsXFormsStubElement.h" -class nsXFormsActionElement : public nsXFormsActionModuleBase, - public nsIXFormsActionElement +class nsXFormsActionElement : public nsIXFormsActionElement, + public nsXFormsXMLVisualStub, + public nsIXFormsActionModuleElement, + public nsIDOMEventListener { public: nsXFormsActionElement(); NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIDOMEVENTLISTENER NS_DECL_NSIXFORMSACTIONELEMENT NS_DECL_NSIXFORMSACTIONMODULEELEMENT + NS_IMETHOD OnCreated(nsIXTFXMLVisualWrapper *aWrapper); + NS_IMETHOD GetVisualContent(nsIDOMElement **aElement); + NS_IMETHOD GetInsertionPoint(nsIDOMElement **aElement); + NS_IMETHOD OnDestroyed(); private: + nsCOMPtr mElement; + nsCOMPtr mVisualElement; nsCOMPtr mParentAction; nsDataHashtable mDeferredUpdates; }; diff --git a/extensions/xforms/nsXFormsAtoms.cpp b/extensions/xforms/nsXFormsAtoms.cpp index ed30d59a5b6..f005cc214e8 100644 --- a/extensions/xforms/nsXFormsAtoms.cpp +++ b/extensions/xforms/nsXFormsAtoms.cpp @@ -50,6 +50,7 @@ nsIAtom* nsXFormsAtoms::constraint; nsIAtom* nsXFormsAtoms::p3ptype; nsIAtom* nsXFormsAtoms::modelListProperty; nsIAtom* nsXFormsAtoms::uploadFileProperty; +nsIAtom* nsXFormsAtoms::messageProperty; nsIAtom *nsXFormsAtoms::ref; nsIAtom *nsXFormsAtoms::value; nsIAtom *nsXFormsAtoms::nodeset; @@ -69,6 +70,7 @@ const nsStaticAtom nsXFormsAtoms::Atoms_info[] = { { "p3ptype", &nsXFormsAtoms::p3ptype }, { "ModelListProperty", &nsXFormsAtoms::modelListProperty }, { "UploadFileProperty", &nsXFormsAtoms::uploadFileProperty }, + { "messageProperty", &nsXFormsAtoms::messageProperty }, { "ref", &nsXFormsAtoms::ref }, { "value", &nsXFormsAtoms::value }, { "nodeset", &nsXFormsAtoms::nodeset }, diff --git a/extensions/xforms/nsXFormsAtoms.h b/extensions/xforms/nsXFormsAtoms.h index c4129a4dd8f..b6384ac6a94 100644 --- a/extensions/xforms/nsXFormsAtoms.h +++ b/extensions/xforms/nsXFormsAtoms.h @@ -55,6 +55,7 @@ class nsXFormsAtoms static NS_HIDDEN_(nsIAtom *) p3ptype; static NS_HIDDEN_(nsIAtom *) modelListProperty; static NS_HIDDEN_(nsIAtom *) uploadFileProperty; + static NS_HIDDEN_(nsIAtom *) messageProperty; static NS_HIDDEN_(nsIAtom *) ref; static NS_HIDDEN_(nsIAtom *) nodeset; static NS_HIDDEN_(nsIAtom *) model; diff --git a/extensions/xforms/nsXFormsControlStub.cpp b/extensions/xforms/nsXFormsControlStub.cpp index de7066a47e2..aaeaf8c5701 100644 --- a/extensions/xforms/nsXFormsControlStub.cpp +++ b/extensions/xforms/nsXFormsControlStub.cpp @@ -42,9 +42,43 @@ #include "nsXFormsMDGEngine.h" #include "nsIDOMEvent.h" +#include "nsIDOMKeyEvent.h" +#include "nsIDOMEventTarget.h" #include "nsIDOMXPathResult.h" #include "nsIXTFXMLVisualWrapper.h" +/** This class is used to generate xforms-hint and xforms-help events.*/ +class nsXFormsHintHelpListener : public nsIDOMEventListener { +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDOMEVENTLISTENER +}; + +NS_IMPL_ISUPPORTS1(nsXFormsHintHelpListener, nsIDOMEventListener) + +NS_IMETHODIMP +nsXFormsHintHelpListener::HandleEvent(nsIDOMEvent* aEvent) +{ + if (!aEvent) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr target; + aEvent->GetCurrentTarget(getter_AddRefs(target)); + nsCOMPtr targetNode(do_QueryInterface(target)); + + nsCOMPtr keyEvent(do_QueryInterface(aEvent)); + if (keyEvent) { + PRUint32 code = 0; + keyEvent->GetKeyCode(&code); + if (code == nsIDOMKeyEvent::DOM_VK_F1) + nsXFormsUtils::DispatchEvent(targetNode, eEvent_Help); + } else { + nsXFormsUtils::DispatchEvent(targetNode, eEvent_Hint); + } + + return NS_OK; +} + NS_IMETHODIMP nsXFormsControlStub::GetBoundNode(nsIDOMNode **aBoundNode) { @@ -120,6 +154,35 @@ nsXFormsControlStub::ProcessNodeBinding(const nsString &aBindingAttr, return NS_OK; } +void +nsXFormsControlStub::ResetHelpAndHint(PRBool aInitialize) +{ + nsCOMPtr targ(do_QueryInterface(mElement)); + if (!targ) + return; + + NS_NAMED_LITERAL_STRING(mouseover, "mouseover"); + NS_NAMED_LITERAL_STRING(focus, "focus"); + NS_NAMED_LITERAL_STRING(keypress, "keypress"); + + if (mEventListener) { + targ->RemoveEventListener(mouseover, mEventListener, PR_TRUE); + targ->RemoveEventListener(focus, mEventListener, PR_TRUE); + targ->RemoveEventListener(keypress, mEventListener, PR_TRUE); + mEventListener = nsnull; + } + + if (aInitialize) { + mEventListener = new nsXFormsHintHelpListener(); + if (!mEventListener) + return; + + targ->AddEventListener(mouseover, mEventListener, PR_TRUE); + targ->AddEventListener(focus, mEventListener, PR_TRUE); + targ->AddEventListener(keypress, mEventListener, PR_TRUE); + } +} + PRBool nsXFormsControlStub::GetReadOnlyState() { @@ -207,12 +270,16 @@ nsXFormsControlStub::OnCreated(nsIXTFXMLVisualWrapper *aWrapper) aWrapper->GetElementNode(getter_AddRefs(mElement)); NS_ASSERTION(mElement, "Wrapper is not an nsIDOMElement, we'll crash soon"); + ResetHelpAndHint(PR_TRUE); + return NS_OK; } NS_IMETHODIMP nsXFormsControlStub::OnDestroyed() { + ResetHelpAndHint(PR_FALSE); + if (mModel) { mModel->RemoveFormControl(this); mModel = nsnull; diff --git a/extensions/xforms/nsXFormsControlStub.h b/extensions/xforms/nsXFormsControlStub.h index 17bfd2fb2c7..2241a06df02 100644 --- a/extensions/xforms/nsXFormsControlStub.h +++ b/extensions/xforms/nsXFormsControlStub.h @@ -46,6 +46,7 @@ #include "nsIDOMElement.h" #include "nsIDOMNode.h" #include "nsIXTFElement.h" +#include "nsIDOMEventListener.h" #include "nsIModelElementPrivate.h" #include "nsIXFormsControl.h" @@ -131,6 +132,9 @@ protected: /** The model for the control */ nsCOMPtr mModel; + /** This event listener is used to create xforms-hint and xforms-help events. */ + nsCOMPtr mEventListener; + /** Returns the read only state of the control (ie. mBoundNode) */ PRBool GetReadOnlyState(); @@ -156,6 +160,11 @@ protected: void ToggleProperty(const nsAString &aOn, const nsAString &aOff); + /** + * Reset (and reinitialize) the event listener, which is used to create + * xforms-hint and xforms-help events. + */ + void ResetHelpAndHint(PRBool aInitialize); }; #endif diff --git a/extensions/xforms/nsXFormsElementFactory.cpp b/extensions/xforms/nsXFormsElementFactory.cpp index a4c2712b32e..210e8881c51 100644 --- a/extensions/xforms/nsXFormsElementFactory.cpp +++ b/extensions/xforms/nsXFormsElementFactory.cpp @@ -78,7 +78,11 @@ NS_HIDDEN_(nsresult) NS_NewXFormsRefreshElement(nsIXTFElement **aResult); NS_HIDDEN_(nsresult) NS_NewXFormsActionElement(nsIXTFElement **aResult); NS_HIDDEN_(nsresult) NS_NewXFormsLoadElement(nsIXTFElement **aResult); NS_HIDDEN_(nsresult) NS_NewXFormsSetValueElement(nsIXTFElement **aResult); +NS_HIDDEN_(nsresult) NS_NewXFormsMessageElement(nsIXTFElement **aResult); +NS_HIDDEN_(nsresult) NS_NewXFormsHintElement(nsIXTFElement **aResult); +NS_HIDDEN_(nsresult) NS_NewXFormsHelpElement(nsIXTFElement **aResult); +NS_HIDDEN_(nsresult) NS_NewXFormsAlertElement(nsIXTFElement **aResult); NS_HIDDEN_(nsresult) NS_NewXFormsToggleElement(nsIXTFElement **aResult); NS_HIDDEN_(nsresult) NS_NewXFormsCaseElement(nsIXTFElement **aResult); NS_HIDDEN_(nsresult) NS_NewXFormsSwitchElement(nsIXTFElement **aResult); @@ -144,6 +148,14 @@ nsXFormsElementFactory::CreateElement(const nsAString& aTagName, return NS_NewXFormsLoadElement(aElement); if (aTagName.EqualsLiteral("setvalue")) return NS_NewXFormsSetValueElement(aElement); + if (aTagName.EqualsLiteral("message")) + return NS_NewXFormsMessageElement(aElement); + if (aTagName.EqualsLiteral("hint")) + return NS_NewXFormsHintElement(aElement); + if (aTagName.EqualsLiteral("help")) + return NS_NewXFormsHelpElement(aElement); + if (aTagName.EqualsLiteral("alert")) + return NS_NewXFormsAlertElement(aElement); if (aTagName.EqualsLiteral("submission")) return NS_NewXFormsSubmissionElement(aElement); if (aTagName.EqualsLiteral("trigger")) diff --git a/extensions/xforms/nsXFormsMessageElement.cpp b/extensions/xforms/nsXFormsMessageElement.cpp new file mode 100644 index 00000000000..34ca15bf63e --- /dev/null +++ b/extensions/xforms/nsXFormsMessageElement.cpp @@ -0,0 +1,852 @@ +/* -*- 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 + * Olli Pettay. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Olli Pettay (original author) + * + * 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 "nsXFormsAtoms.h" +#include "nsXFormsStubElement.h" +#include "nsXFormsActionElement.h" +#include "nsIXFormsActionModuleElement.h" + +#include "nsIXTFXMLVisual.h" +#include "nsIXTFXMLVisualWrapper.h" + +#include "nsIDOM3Node.h" +#include "nsIDOMElement.h" +#include "nsIDOMNodeList.h" +#include "nsIDOMDocument.h" +#include "nsIDOMNSDocument.h" +#include "nsIDOMDocumentView.h" +#include "nsIDOMAbstractView.h" +#include "nsIDOMHTMLDocument.h" +#include "nsIDOMWindowInternal.h" +#include "nsIDOMDOMImplementation.h" + +#include "nsIDOMEvent.h" +#include "nsIDOMMouseEvent.h" +#include "nsIDOMEventTarget.h" +#include "nsIDOMEventListener.h" + +#include "nsIDOMViewCSS.h" +#include "nsIDOMCSSValue.h" +#include "nsIDOMCSSPrimitiveValue.h" +#include "nsIDOMCSSStyleDeclaration.h" + +#include "nsITimer.h" +#include "nsIDocument.h" +#include "nsIBoxObject.h" +#include "nsIServiceManager.h" + +#include "prmem.h" +#include "plbase64.h" +#include "nsAutoPtr.h" +#include "nsIStringBundle.h" +#include "nsIDOMSerializer.h" +#include "nsIServiceManager.h" + +#define EPHEMERAL_STYLE \ + "position:absolute;z-index:2147483647; \ + background:inherit;color:inherit; \ + border:inherit;visibility:visible;" + +#define EPHEMERAL_STYLE_HIDDEN \ + "position:absolute;z-index:2147483647;visibility:hidden;" + +#define MESSAGE_WINDOW_PROPERTIES \ + "location=false,scrollbars=yes" + + +// Defining a simple dialog for modeless and modal messages. + +#define MESSAGE_WINDOW_UI_PART1 \ + " \ + \ + " + +#define MESSAGE_WINDOW_UI_PART2 \ + "