зеркало из https://github.com/mozilla/pjs.git
[XForms] add in and out of range support. Bug 300248, r=doronr+allan
This commit is contained in:
Родитель
e1c4f6768f
Коммит
39c067bbb6
|
@ -148,6 +148,7 @@ XPIDLSRCS = \
|
|||
nsIXFormsUploadUIElement.idl \
|
||||
nsIXFormsCopyElement.idl \
|
||||
nsIXFormsEphemeralMessageUI.idl \
|
||||
nsIXFormsRangeConditionAccessors.idl \
|
||||
$(NULL)
|
||||
|
||||
# XForms source files
|
||||
|
@ -207,6 +208,7 @@ CPPSRCS = \
|
|||
nsXFormsAccessors.cpp \
|
||||
nsXFormsRangeAccessors.cpp \
|
||||
nsXFormsCopyElement.cpp \
|
||||
nsXFormsRangeConditionAccessors.cpp \
|
||||
$(NULL)
|
||||
|
||||
# Standard Mozilla make rules
|
||||
|
|
|
@ -103,4 +103,11 @@ interface nsIXFormsControl : nsIXFormsContextControl
|
|||
* model bind element, ie. it has a |bind| attribute.
|
||||
*/
|
||||
readonly attribute boolean usesModelBinding;
|
||||
|
||||
/**
|
||||
* These represent the default intrinsic states for controls when they are
|
||||
* enabled and disabled.
|
||||
*/
|
||||
readonly attribute long defaultIntrinsicState;
|
||||
readonly attribute long disabledIntrinsicState;
|
||||
};
|
||||
|
|
|
@ -36,15 +36,15 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIXFormsAccessors.idl"
|
||||
#include "nsIXFormsRangeConditionAccessors.idl"
|
||||
|
||||
/**
|
||||
* Accessors provided by XForms \<range\> controls.
|
||||
*
|
||||
* @see http://www.w3.org/TR/xforms/slice8.html#ui-range
|
||||
*/
|
||||
[scriptable, uuid(8a6c4540-4c2b-4591-af0e-ef147543eee7)]
|
||||
interface nsIXFormsRangeAccessors : nsIXFormsAccessors
|
||||
[scriptable, uuid(8003219f-275f-4e37-a008-76b9ba2e7cee)]
|
||||
interface nsIXFormsRangeAccessors : nsIXFormsRangeConditionAccessors
|
||||
{
|
||||
/** The start of the range interval */
|
||||
DOMString getRangeStart();
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- 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
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 "nsIXFormsAccessors.idl"
|
||||
|
||||
/**
|
||||
* Accessors provided by XForms \<range\>, \<select\> and \<select1\> controls.
|
||||
*
|
||||
*/
|
||||
[scriptable, uuid(5034a86c-083f-47c6-9ff2-74baff8968bc)]
|
||||
interface nsIXFormsRangeConditionAccessors : nsIXFormsAccessors
|
||||
{
|
||||
/**
|
||||
* @see http://www.w3.org/TR/xforms/slice4.html#evt-in-range
|
||||
*/
|
||||
boolean isInRange();
|
||||
|
||||
|
||||
/**
|
||||
* Used to tell the XForms processor whether the control can represent all
|
||||
* of data in the bound node. For example, if there are 3 different
|
||||
* space-seperated values in the instance data bound to a xf:select1 and the
|
||||
* select1 only has one item, then the data must be out of the range of
|
||||
* the control.
|
||||
*
|
||||
* @param aInRange If false, the control should be styled as defined by
|
||||
* out-of-range pseudo-class. If the control was
|
||||
* previously in-range, then the xforms-out-of-range
|
||||
* event should be dispatched.
|
||||
* If true, the control should be styled as defined by
|
||||
* in-range pseudo-class or the default style matching
|
||||
* the control. If the data was previously out-of-range,
|
||||
* then the xforms-in-range event should be dispatched.
|
||||
*/
|
||||
void setInRange(in boolean aInRange);
|
||||
};
|
|
@ -192,7 +192,9 @@ nsXFormsControlStubBase::ResetBoundNode(const nsString &aBindAttribute,
|
|||
nsCOMPtr<nsIXTFElementWrapper> wrapper(do_QueryInterface(mElement));
|
||||
NS_ENSURE_STATE(wrapper);
|
||||
|
||||
return wrapper->SetIntrinsicState(kDisabledIntrinsicState);
|
||||
PRInt32 iState;
|
||||
GetDisabledIntrinsicState(&iState);
|
||||
return wrapper->SetIntrinsicState(iState);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -251,6 +253,22 @@ nsXFormsControlStubBase::SetOnDeferredBindList(PRBool aPutOnList)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsControlStubBase::GetDefaultIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
*aState = kDefaultIntrinsicState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsControlStubBase::GetDisabledIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
*aState = kDisabledIntrinsicState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXFormsControlStubBase::MaybeAddToModel(nsIModelElementPrivate *aOldModel,
|
||||
nsIXFormsControl *aParent)
|
||||
|
@ -622,7 +640,9 @@ nsXFormsControlStubBase::DocumentChanged(nsIDOMDocument *aNewDocument)
|
|||
if (aNewDocument && !mModel && mElement) {
|
||||
nsCOMPtr<nsIXTFElementWrapper> xtfWrap(do_QueryInterface(mElement));
|
||||
NS_ENSURE_STATE(xtfWrap);
|
||||
xtfWrap->SetIntrinsicState(kDefaultIntrinsicState);
|
||||
PRInt32 iState;
|
||||
GetDefaultIntrinsicState(&iState);
|
||||
xtfWrap->SetIntrinsicState(iState);
|
||||
}
|
||||
|
||||
return ForceModelDetach(mHasParent && aNewDocument);
|
||||
|
|
|
@ -94,6 +94,8 @@ public:
|
|||
NS_IMETHOD TryFocus(PRBool* aOK);
|
||||
NS_IMETHOD IsEventTarget(PRBool *aOK);
|
||||
NS_IMETHOD GetUsesModelBinding(PRBool *aRes);
|
||||
NS_IMETHOD GetDefaultIntrinsicState(PRInt32 *aRes);
|
||||
NS_IMETHOD GetDisabledIntrinsicState(PRInt32 *aRes);
|
||||
|
||||
nsresult Create(nsIXTFElementWrapper *aWrapper);
|
||||
// for nsIXTFElement
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#include "nsXFormsControlStub.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
#define XFORMS_LAZY_INSTANCE_BINDING \
|
||||
"chrome://xforms/content/xforms.xml#xforms-lazy-instance"
|
||||
|
@ -1110,8 +1111,13 @@ nsXFormsModelElement::SetStates(nsIXFormsControl *aControl,
|
|||
ns = mMDG.GetNodeState(aNode);
|
||||
NS_ENSURE_STATE(ns);
|
||||
iState = ns->GetIntrinsicState();
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(element));
|
||||
NS_ENSURE_STATE(content);
|
||||
PRInt32 rangeState = content->IntrinsicState() &
|
||||
(NS_EVENT_STATE_INRANGE | NS_EVENT_STATE_OUTOFRANGE);
|
||||
iState = ns->GetIntrinsicState() | rangeState;
|
||||
} else {
|
||||
iState = kDefaultIntrinsicState;
|
||||
aControl->GetDefaultIntrinsicState(&iState);
|
||||
}
|
||||
|
||||
nsresult rv = xtfWrap->SetIntrinsicState(iState);
|
||||
|
@ -1321,19 +1327,26 @@ nsXFormsModelElement::Refresh()
|
|||
#ifdef DEBUG
|
||||
printf("nsXFormsModelElement::Refresh()\n");
|
||||
#endif
|
||||
nsPostRefresh postRefresh = nsPostRefresh();
|
||||
|
||||
if (!mDocumentLoaded) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXXbeaufour: Can we somehow suspend redraw / "screen update" while doing
|
||||
// the refresh? That should save a lot of time, and avoid flickering of
|
||||
// controls.
|
||||
|
||||
// Kick off refreshing on root node
|
||||
nsresult rv = RefreshSubTree(mFormControls.FirstChild(), PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Using brackets here to provide a scope for the
|
||||
// nsPostRefresh. We want to make sure that nsPostRefresh's destructor
|
||||
// runs (and thus processes the postrefresh and containerpostrefresh lists)
|
||||
// before we clear the dispatch flags
|
||||
{
|
||||
nsPostRefresh postRefresh = nsPostRefresh();
|
||||
|
||||
if (!mDocumentLoaded) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Kick off refreshing on root node
|
||||
nsresult rv = RefreshSubTree(mFormControls.FirstChild(), PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Clear refresh structures
|
||||
mChangedNodes.Clear();
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "nsXFormsUtils.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsRangeAccessors,
|
||||
nsXFormsAccessors,
|
||||
nsXFormsRangeConditionAccessors,
|
||||
nsIXFormsRangeAccessors,
|
||||
nsIClassInfo)
|
||||
|
||||
|
@ -95,6 +95,7 @@ nsXFormsRangeAccessors::GetRangeStep(nsAString &aStep)
|
|||
|
||||
static const nsIID sScriptingIIDs[] = {
|
||||
NS_IXFORMSACCESSORS_IID,
|
||||
NS_IXFORMSRANGECONDITIONACCESSORS_IID,
|
||||
NS_IXFORMSRANGEACCESSORS_IID
|
||||
};
|
||||
|
||||
|
|
|
@ -37,26 +37,26 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIXFormsRangeAccessors.h"
|
||||
#include "nsXFormsAccessors.h"
|
||||
#include "nsXFormsRangeConditionAccessors.h"
|
||||
|
||||
/**
|
||||
* Implementation for the accessors for a range element,
|
||||
* nsIXFormsRangeAccessors.
|
||||
*
|
||||
* @todo Support out-of/in-range events (XXX)
|
||||
*/
|
||||
class nsXFormsRangeAccessors : public nsXFormsAccessors,
|
||||
class nsXFormsRangeAccessors : public nsXFormsRangeConditionAccessors,
|
||||
public nsIXFormsRangeAccessors
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIXFORMSRANGEACCESSORS
|
||||
NS_FORWARD_NSIXFORMSRANGECONDITIONACCESSORS(nsXFormsRangeConditionAccessors::)
|
||||
NS_FORWARD_NSIXFORMSACCESSORS(nsXFormsAccessors::)
|
||||
|
||||
// Constructor
|
||||
nsXFormsRangeAccessors(nsIDelegateInternal* aDelegate,
|
||||
nsIDOMElement* aElement)
|
||||
: nsXFormsAccessors(aDelegate, aElement)
|
||||
: nsXFormsRangeConditionAccessors(aDelegate, aElement)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/* -*- 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
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 "nsXFormsRangeConditionAccessors.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIXTFElementWrapper.h"
|
||||
#include "nsIXFormsControl.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsXFormsUtils.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsRangeConditionAccessors,
|
||||
nsXFormsAccessors,
|
||||
nsIXFormsRangeConditionAccessors,
|
||||
nsIClassInfo)
|
||||
|
||||
// nsXFormsRangeConditionAccessors
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsRangeConditionAccessors::IsInRange(PRBool *aInRange)
|
||||
{
|
||||
return GetState(NS_EVENT_STATE_INRANGE, aInRange);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsRangeConditionAccessors::SetInRange(PRBool aInRange)
|
||||
{
|
||||
PRBool currRange;
|
||||
nsresult rv = IsInRange(&currRange);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (currRange == aInRange) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* when this call changes the control's previous in or out of range state,
|
||||
* then we need to set the state to the new value and dispatch
|
||||
* xforms-in-range or xforms-out-of-range
|
||||
*/
|
||||
nsCOMPtr<nsIXFormsControl> control(do_QueryInterface(mDelegate));
|
||||
NS_ENSURE_STATE(control);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
control->GetElement(getter_AddRefs(element));
|
||||
nsCOMPtr<nsIXTFElementWrapper> xtfWrap(do_QueryInterface(element));
|
||||
NS_ENSURE_STATE(xtfWrap);
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(element));
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
PRInt32 state = content->IntrinsicState();
|
||||
if (!aInRange) {
|
||||
state &= ~NS_EVENT_STATE_INRANGE;
|
||||
state |= NS_EVENT_STATE_OUTOFRANGE;
|
||||
} else {
|
||||
state &= ~NS_EVENT_STATE_OUTOFRANGE;
|
||||
state |= NS_EVENT_STATE_INRANGE;
|
||||
}
|
||||
|
||||
rv = xtfWrap->SetIntrinsicState(state);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsXFormsUtils::DispatchEvent(element,
|
||||
aInRange ? eEvent_InRange : eEvent_OutOfRange);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIClassInfo implementation
|
||||
|
||||
static const nsIID sScriptingIIDs[] = {
|
||||
NS_IXFORMSACCESSORS_IID,
|
||||
NS_IXFORMSRANGECONDITIONACCESSORS_IID
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsRangeConditionAccessors::GetInterfaces(PRUint32 *aCount,
|
||||
nsIID * **aArray)
|
||||
{
|
||||
return nsXFormsUtils::CloneScriptingInterfaces(sScriptingIIDs,
|
||||
NS_ARRAY_LENGTH(sScriptingIIDs),
|
||||
aCount, aArray);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- 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
|
||||
* IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Reed <aaronr@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of 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 "nsIXFormsRangeConditionAccessors.h"
|
||||
#include "nsXFormsAccessors.h"
|
||||
|
||||
/**
|
||||
* Implementation for the accessors for elements that can be in or out of
|
||||
* range. Specifically, select, select1 and range.
|
||||
* nsIXFormsRangeConditionAccessors.
|
||||
*
|
||||
*/
|
||||
class nsXFormsRangeConditionAccessors : public nsXFormsAccessors,
|
||||
public nsIXFormsRangeConditionAccessors
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIXFORMSRANGECONDITIONACCESSORS
|
||||
NS_FORWARD_NSIXFORMSACCESSORS(nsXFormsAccessors::)
|
||||
|
||||
// Constructor
|
||||
nsXFormsRangeConditionAccessors(nsIDelegateInternal *aDelegate,
|
||||
nsIDOMElement *aElement)
|
||||
: nsXFormsAccessors(aDelegate, aElement)
|
||||
{
|
||||
}
|
||||
|
||||
// nsIClassInfo overrides
|
||||
NS_IMETHOD GetInterfaces(PRUint32 *aCount, nsIID * **aArray);
|
||||
};
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "nsXFormsDelegateStub.h"
|
||||
#include "nsXFormsRangeAccessors.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
/**
|
||||
* Implementation of the XForms \<range\> element
|
||||
|
@ -49,6 +50,10 @@ class nsXFormsRangeElement : public nsXFormsDelegateStub
|
|||
{
|
||||
public:
|
||||
|
||||
// nsIXFormsControl
|
||||
NS_IMETHOD GetDefaultIntrinsicState(PRInt32 *aState);
|
||||
NS_IMETHOD GetDisabledIntrinsicState(PRInt32 *aState);
|
||||
|
||||
// nsIXFormsDelegate overrides
|
||||
NS_IMETHOD GetXFormsAccessors(nsIXFormsAccessors **aAccessor);
|
||||
|
||||
|
@ -57,6 +62,26 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
// nsIXFormsControl
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsRangeElement::GetDefaultIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsXFormsDelegateStub::GetDefaultIntrinsicState(aState);
|
||||
*aState |= NS_EVENT_STATE_INRANGE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsRangeElement::GetDisabledIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsXFormsDelegateStub::GetDisabledIntrinsicState(aState);
|
||||
*aState |= NS_EVENT_STATE_INRANGE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIXFormsDelegate
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsXFormsModelElement.h"
|
||||
#include "nsXFormsRangeConditionAccessors.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
class nsXFormsSelect1Element : public nsXFormsDelegateStub
|
||||
{
|
||||
|
@ -73,6 +75,11 @@ public:
|
|||
|
||||
// nsIXFormsControl
|
||||
NS_IMETHOD Refresh();
|
||||
NS_IMETHOD GetDefaultIntrinsicState(PRInt32 *aState);
|
||||
NS_IMETHOD GetDisabledIntrinsicState(PRInt32 *aState);
|
||||
|
||||
// nsIXFormsDelegate overrides
|
||||
NS_IMETHOD GetXFormsAccessors(nsIXFormsAccessors **aAccessor);
|
||||
|
||||
nsXFormsSelect1Element(const nsAString& aType)
|
||||
: nsXFormsDelegateStub(aType)
|
||||
|
@ -154,6 +161,39 @@ nsXFormsSelect1Element::Refresh()
|
|||
return nsXFormsDelegateStub::Refresh();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::GetDefaultIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsXFormsDelegateStub::GetDefaultIntrinsicState(aState);
|
||||
*aState |= NS_EVENT_STATE_INRANGE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::GetDisabledIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsXFormsDelegateStub::GetDisabledIntrinsicState(aState);
|
||||
*aState |= NS_EVENT_STATE_INRANGE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIXFormsDelegate
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelect1Element::GetXFormsAccessors(nsIXFormsAccessors **aAccessor)
|
||||
{
|
||||
if (!mAccessor) {
|
||||
mAccessor = new nsXFormsRangeConditionAccessors(this, mElement);
|
||||
if (!mAccessor) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
NS_ADDREF(*aAccessor = mAccessor);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_HIDDEN_(nsresult)
|
||||
NS_NewXFormsSelect1Element(nsIXTFElement **aResult)
|
||||
{
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsXFormsModelElement.h"
|
||||
#include "nsXFormsRangeConditionAccessors.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
class nsXFormsSelectElement : public nsXFormsDelegateStub
|
||||
{
|
||||
|
@ -68,6 +70,11 @@ public:
|
|||
|
||||
// nsIXFormsControl
|
||||
NS_IMETHOD Refresh();
|
||||
NS_IMETHOD GetDefaultIntrinsicState(PRInt32 *aState);
|
||||
NS_IMETHOD GetDisabledIntrinsicState(PRInt32 *aState);
|
||||
|
||||
// nsIXFormsDelegate overrides
|
||||
NS_IMETHOD GetXFormsAccessors(nsIXFormsAccessors **aAccessor);
|
||||
|
||||
#ifdef DEBUG_smaug
|
||||
virtual const char* Name() { return "select"; }
|
||||
|
@ -126,6 +133,39 @@ nsXFormsSelectElement::Refresh()
|
|||
return nsXFormsDelegateStub::Refresh();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelectElement::GetDefaultIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsXFormsDelegateStub::GetDefaultIntrinsicState(aState);
|
||||
*aState |= NS_EVENT_STATE_INRANGE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelectElement::GetDisabledIntrinsicState(PRInt32 *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsXFormsDelegateStub::GetDisabledIntrinsicState(aState);
|
||||
*aState |= NS_EVENT_STATE_INRANGE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIXFormsDelegate
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelectElement::GetXFormsAccessors(nsIXFormsAccessors **aAccessor)
|
||||
{
|
||||
if (!mAccessor) {
|
||||
mAccessor = new nsXFormsRangeConditionAccessors(this, mElement);
|
||||
if (!mAccessor) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
NS_ADDREF(*aAccessor = mAccessor);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_HIDDEN_(nsresult)
|
||||
NS_NewXFormsSelectElement(nsIXTFElement **aResult)
|
||||
{
|
||||
|
|
|
@ -211,12 +211,13 @@
|
|||
this.ctx.fillRect(this.margin, mid - 1, this.barwidth, 3);
|
||||
this.ctx.strokeRect(this.margin, mid - 1, this.barwidth, 3);
|
||||
|
||||
// check whether out-of-range state has changed, and dispatch event if it has
|
||||
// Let the accessor know the outOfRange state. The accessor will
|
||||
// take care of the control styling and dispatching the appropriate
|
||||
// events if the in/out of range condition has changed from its
|
||||
// previous state.
|
||||
if (outOfRange != this.outOfRange) {
|
||||
// XXX we need to set the style too
|
||||
this.outOfRange = outOfRange;
|
||||
var event = outOfRange ? "xforms-out-of-range" : "xforms-in-range";
|
||||
this.dispatchXFormsNotificationEvent(event, this);
|
||||
this.accessors.setInRange(!outOfRange);
|
||||
}
|
||||
|
||||
// if out-of-range, we cannot represent the value
|
||||
|
|
|
@ -244,14 +244,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
var outOfRange = false;
|
||||
var selectionOpen = this.selection == 'open';
|
||||
// check if any default values were not found
|
||||
for (var index in this._defaultHash) {
|
||||
if (this._defaultHash[index].hits == 0) {
|
||||
if (this.selection == 'open') {
|
||||
if (selectionOpen) {
|
||||
this.control.appendFreeEntryItem(index);
|
||||
} else {
|
||||
// XXX: some of default values not found, we need to throw an
|
||||
// some of default values not found, we need to throw an
|
||||
// xforms-out-of-range event, but only if the select is 'closed'.
|
||||
outOfRange = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -259,16 +262,26 @@
|
|||
// check if any default elements were not found
|
||||
for (var j = 0; j < this._selectedElementArray.length; j++) {
|
||||
if (this._selectedElementArray[j].hits == 0) {
|
||||
if (this.selection == 'open') {
|
||||
if (selectionOpen) {
|
||||
// XXX: If the select is open, the missing elements should be added
|
||||
// and selected per 8.1.10 in the spec.
|
||||
} else {
|
||||
// XXX: some of default values not found, we need to throw an
|
||||
// some of default values not found, we need to throw an
|
||||
// xforms-out-of-range event, but only if the select is 'closed'.
|
||||
outOfRange = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a control can't be out of range (or in range for that matter) if
|
||||
// there is no selected value, so make sure that there is a bound
|
||||
// node first.
|
||||
if (!selectionOpen && this.accessors.hasBoundNode() &&
|
||||
(outOfRange != this._outOfRange)) {
|
||||
this._outOfRange = outOfRange;
|
||||
this.accessors.setInRange(!outOfRange);
|
||||
}
|
||||
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
|
@ -301,11 +314,11 @@
|
|||
// get an array of values selected in the bound node
|
||||
var selectedArray = value.split(/\s/);
|
||||
|
||||
if (selectedArray.length == 1 && selectedArray[0] == "") {
|
||||
// when the string is empty, split returns an array containing
|
||||
// one empty string, rather than an empty array.
|
||||
return;
|
||||
}
|
||||
// when the string is empty, split returns an array containing
|
||||
// one empty string, rather than an empty array. We'll allow that
|
||||
// into the defaultHash so that xforms-out-of-range will be
|
||||
// correctly generated if none of the items in the select have
|
||||
// an empty string as a value
|
||||
|
||||
for (var run = 0; run < selectedArray.length; run++) {
|
||||
this._defaultHash[selectedArray[run]] = {hits: 0}
|
||||
|
@ -337,12 +350,12 @@
|
|||
// get an array of values selected in the bound node
|
||||
var selectedArray = value.split(" ");
|
||||
|
||||
if (selectedArray.length == 1 && selectedArray[0] == "") {
|
||||
// when the string is empty, split returns an array containing
|
||||
// one empty string, rather than an empty array.
|
||||
continue;
|
||||
}
|
||||
|
||||
// when the string is empty, split returns an array containing
|
||||
// one empty string, rather than an empty array. We'll allow
|
||||
// that into the defaultHash so that xforms-out-of-range will be
|
||||
// correctly generated if none of the items in the select have
|
||||
// an empty string as a value
|
||||
|
||||
for (var run = 0; run < selectedArray.length; run++) {
|
||||
this._defaultHash[selectedArray[run]] = {hits: 0}
|
||||
}
|
||||
|
@ -513,7 +526,9 @@
|
|||
var item = options[i].control.
|
||||
QueryInterface(Components.interfaces.nsIXFormsSelectChild);
|
||||
if (item.isCopyItem)
|
||||
break;
|
||||
// _updateSelection is used only to select items when _defaultHash
|
||||
// contains only text nodes. So we can ignore copyItems.
|
||||
continue;
|
||||
|
||||
var value = item.value;
|
||||
var selectionValue = value in this._defaultHash;
|
||||
|
@ -521,12 +536,43 @@
|
|||
if (selectionValue) {
|
||||
this.control.addItemToSelection(options[i].option);
|
||||
options[i].wasSelected = true;
|
||||
this._defaultHash[value].hits++;
|
||||
}
|
||||
else {
|
||||
this.control.removeItemFromSelection(options[i].option);
|
||||
options[i].wasSelected = false;
|
||||
}
|
||||
}
|
||||
// see if any of default values are not found. If so, we need to
|
||||
// throw an xforms-out-of-range event and style the control as
|
||||
// being out of range. But only if the select is 'closed'.
|
||||
if (this.selection == 'open') {
|
||||
return;
|
||||
}
|
||||
|
||||
var outOfRange = false;
|
||||
var length = 0;
|
||||
for (var index in this._defaultHash) {
|
||||
length++;
|
||||
if (this._defaultHash[index].hits == 0) {
|
||||
outOfRange = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
// this covers the scenario where some items were previously
|
||||
// selected and the user selected a copyItem, yet because the
|
||||
// bound node wasn't an element node the copyItem was deselected
|
||||
// and the bound node was set to empty. If there is no selected
|
||||
// item, then we must be out of range.
|
||||
outOfRange = true;
|
||||
}
|
||||
|
||||
if (this._outOfRange != outOfRange) {
|
||||
this._outOfRange = outOfRange;
|
||||
this.accessors.setInRange(!outOfRange);
|
||||
}
|
||||
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -542,7 +588,7 @@
|
|||
// store the values in a hash for quick access
|
||||
this._defaultHash = new Object();
|
||||
for (var run = 0; run < selectedArray.length; run++) {
|
||||
this._defaultHash[selectedArray[run]] = {}
|
||||
this._defaultHash[selectedArray[run]] = {hits: 0}
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
|
@ -778,6 +824,7 @@
|
|||
<field name="_selectedElementArray">new Array()</field>
|
||||
<field name="_defaultHash">null</field>
|
||||
<field name="_accessorValueCache">null</field>
|
||||
<field name="_outOfRange">false</field>
|
||||
|
||||
<method name="getControlElement">
|
||||
<body>
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
<field name="_lastSelectedItem">null</field>
|
||||
<field name="popupOpen">false</field>
|
||||
<field name="shouldHandleBlur">true</field>
|
||||
<field name="_outOfRange">false</field>
|
||||
|
||||
<property name="selectionOpen" readonly="true">
|
||||
<getter>
|
||||
|
@ -598,8 +599,6 @@
|
|||
// oh oh! We've already found a selectable node in the
|
||||
// instance data and now we have another. That shouldn't
|
||||
// happen.
|
||||
// XXX generate xforms-out-of-range exception and style
|
||||
// control as out-of-range
|
||||
outOfRange = true;
|
||||
}
|
||||
newValue = string;
|
||||
|
@ -609,11 +608,9 @@
|
|||
// a node worth comparing. As such, look for an
|
||||
// item with a copy element that might match this node.
|
||||
if (newValue || nodeValue) {
|
||||
// oh oh! We've already found a selectable node in the
|
||||
// instance data and now we have another. That shouldn't
|
||||
// happen.
|
||||
// XXX generate xforms-out-of-range exception and style
|
||||
// control as out-of-range
|
||||
// oh oh! We've already found a selectable node in the
|
||||
// instance data and now we have another. That shouldn't
|
||||
// happen.
|
||||
outOfRange = true;
|
||||
}
|
||||
nodeValue = child;
|
||||
|
@ -627,6 +624,14 @@
|
|||
}
|
||||
|
||||
if (outOfRange) {
|
||||
// a control can't be out of range (or in range for that matter)
|
||||
// if there is no selected value, so make sure that there is a
|
||||
// bound node first.
|
||||
if ((outOfRange != this._outOfRange) && boundNode) {
|
||||
this._outOfRange = outOfRange;
|
||||
this.accessors.setInRange(false);
|
||||
}
|
||||
|
||||
// can't possibly work, no sense continuing.
|
||||
this.inputField.value = "";
|
||||
this._selected.setActive(false);
|
||||
|
@ -673,14 +678,23 @@
|
|||
this.selectItemByNode(nodeValue);
|
||||
}
|
||||
|
||||
outOfRange = false;
|
||||
if (this._selected) {
|
||||
this.updateInputField();
|
||||
this._lastSelectedItem = this._selected;
|
||||
} else if (this.selectionOpen) {
|
||||
this.inputField.value = newValue;
|
||||
} else {
|
||||
// @todo out-of-range (XXX)
|
||||
this.inputField.value = "";
|
||||
outOfRange = true;
|
||||
}
|
||||
|
||||
// a control can't be out of range (or in range for that matter)
|
||||
// if there is no selected value, so make sure that there is a
|
||||
// bound node first.
|
||||
if ((outOfRange != this._outOfRange) && boundNode) {
|
||||
this._outOfRange = outOfRange;
|
||||
this.accessors.setInRange(!outOfRange);
|
||||
}
|
||||
this.refreshWidth();
|
||||
} catch (ex) {}
|
||||
|
@ -810,8 +824,9 @@
|
|||
// if aDispatchSelectEvents is true, then we need to make sure to
|
||||
// dispatch the xforms-deselect and xforms-select events before we
|
||||
// change the value of the bound node otherwise we'll get the
|
||||
// event ordering wrong. aDispatchSelectEvents is a REQUIRED
|
||||
// parameter, whether it be true or false.
|
||||
// event ordering wrong. Similar with setting out of/in range (must
|
||||
// happen after dispatch select/deselect). aDispatchSelectEvents is
|
||||
// a REQUIRED parameter, whether it be true or false.
|
||||
|
||||
// aInBlur is not a required parameter. It is true if handleSelection
|
||||
// was called from the blur handler.
|
||||
|
@ -826,6 +841,10 @@
|
|||
this.dispatchSelectEvents();
|
||||
}
|
||||
this.accessors.setValue(this.inputField.value);
|
||||
|
||||
// open selection can't be out of range
|
||||
this._outOfRange = false;
|
||||
this.accessors.setInRange(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -854,6 +873,8 @@
|
|||
this.dispatchSelectEvents();
|
||||
}
|
||||
this.accessors.setValue(envelope.nodeValue);
|
||||
this._outOfRange = false;
|
||||
this.accessors.setInRange(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -872,11 +893,14 @@
|
|||
this._selected.setActive(false);
|
||||
this._selected = null;
|
||||
this.inputField.value = "";
|
||||
this.accessors.setValue("");
|
||||
|
||||
if (aDispatchSelectEvents == true) {
|
||||
this.dispatchSelectEvents();
|
||||
}
|
||||
|
||||
this.accessors.setValue("");
|
||||
this._outOfRange = true;
|
||||
this.accessors.setInRange(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -892,11 +916,15 @@
|
|||
this.dispatchSelectEvents();
|
||||
}
|
||||
this.accessors.setValue(contentEnvelope.textContent);
|
||||
this._outOfRange = false;
|
||||
this.accessors.setInRange(true);
|
||||
} else {
|
||||
if (aDispatchSelectEvents == true) {
|
||||
this.dispatchSelectEvents();
|
||||
}
|
||||
this.accessors.setContent(contentEnvelope, true);
|
||||
this._outOfRange = false;
|
||||
this.accessors.setInRange(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче