зеркало из https://github.com/mozilla/pjs.git
Bug 368835 No focus events from xul tree table when a row is deleted, r=evan.yan, Olli.Pettay, sr=jonas, a=beltzner
This commit is contained in:
Родитель
e831b176af
Коммит
37ce265df2
|
@ -37,17 +37,34 @@
|
|||
#include "nsITreeColumns.idl"
|
||||
|
||||
interface nsIAccessible;
|
||||
|
||||
/**
|
||||
* A cross-platform interface that supports cache for tree item
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(CC742DA2-9C25-4D04-96CD-DA407D676C6D)]
|
||||
[uuid(7cdad914-948b-4bbc-9c47-ee5e1ae6b148)]
|
||||
interface nsIAccessibleTreeCache : nsISupports
|
||||
{
|
||||
/**
|
||||
* Get tree item from cache according to row and column, create if doesn't exist in cache
|
||||
* "aColumn" can be nsnull
|
||||
* Get tree item from cache according to row and column, create if doesn't
|
||||
* exist in cache.
|
||||
*
|
||||
* @param aRow the given row index
|
||||
* @param aColumn the given column object. If is is nsnull then primary
|
||||
* column is used. It makes sense for ATK only.
|
||||
*/
|
||||
[noscript] nsIAccessible getCachedTreeitemAccessible(in PRInt32 aRow, in nsITreeColumn aColumn);
|
||||
nsIAccessible getCachedTreeitemAccessible(in long aRow,
|
||||
in nsITreeColumn aColumn);
|
||||
|
||||
/**
|
||||
* Invalidates the number of cached treeitem accessibles.
|
||||
*
|
||||
* @param aRow row index the invalidation starts from
|
||||
* @param aCount the number of treeitem accessibles to invalidate,
|
||||
* the number sign specifies whether rows have been
|
||||
* inserted (plus) or removed (minus)
|
||||
*/
|
||||
void invalidateCache(in long aRow, in long aCount);
|
||||
};
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::IsProbablyForLayout(PRBool *aIsProbablyFo
|
|||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// nsXULTreeAccessibleWrap Accessible
|
||||
// nsXULTreeColumnsAccessibleWrap Accessible
|
||||
// --------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeColumnsAccessibleWrap, nsXULTreeColumnsAccessible, nsIAccessibleTable)
|
||||
|
||||
|
|
|
@ -55,8 +55,12 @@ public:
|
|||
nsXULTreeAccessibleWrap(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsXULTreeAccessibleWrap() {}
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
|
||||
|
||||
protected:
|
||||
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod,
|
||||
PRBool *aSelState);
|
||||
};
|
||||
|
||||
class nsXULTreeColumnsAccessibleWrap : public nsXULTreeColumnsAccessible,
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIDOMHTMLSelectElement.h"
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMXULMenuListElement.h"
|
||||
#include "nsIDOMXULMultSelectCntrlEl.h"
|
||||
|
@ -287,6 +288,7 @@ const char* const docEvents[] = {
|
|||
"AlertActive",
|
||||
// add ourself as a TreeViewChanged listener (custom event fired in nsTreeBodyFrame.cpp)
|
||||
"TreeViewChanged",
|
||||
"TreeRowCountChanged",
|
||||
// add ourself as a OpenStateChange listener (custom event fired in tree.xml)
|
||||
"OpenStateChange",
|
||||
// add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp)
|
||||
|
@ -641,7 +643,9 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
|
||||
if (eventType.EqualsLiteral("TreeViewChanged")) { // Always asynch, always from user input
|
||||
NS_ENSURE_TRUE(localName.EqualsLiteral("tree"), NS_OK);
|
||||
if (!localName.EqualsLiteral("tree"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> treeContent = do_QueryInterface(aTargetNode);
|
||||
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
|
||||
return accService->InvalidateSubtreeFor(eventShell, treeContent,
|
||||
|
@ -655,6 +659,33 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
if (!privAcc)
|
||||
return NS_OK;
|
||||
|
||||
if (eventType.EqualsLiteral("TreeRowCountChanged")) {
|
||||
if (!localName.EqualsLiteral("tree"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMDataContainerEvent> dataEvent(do_QueryInterface(aEvent));
|
||||
NS_ENSURE_STATE(dataEvent);
|
||||
|
||||
nsCOMPtr<nsIVariant> indexVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("index"),
|
||||
getter_AddRefs(indexVariant));
|
||||
NS_ENSURE_STATE(indexVariant);
|
||||
|
||||
nsCOMPtr<nsIVariant> countVariant;
|
||||
dataEvent->GetData(NS_LITERAL_STRING("count"),
|
||||
getter_AddRefs(countVariant));
|
||||
NS_ENSURE_STATE(countVariant);
|
||||
|
||||
PRInt32 index, count;
|
||||
indexVariant->GetAsInt32(&index);
|
||||
countVariant->GetAsInt32(&count);
|
||||
|
||||
nsCOMPtr<nsIAccessibleTreeCache> treeAccCache(do_QueryInterface(accessible));
|
||||
NS_ENSURE_STATE(treeAccCache);
|
||||
|
||||
return treeAccCache->InvalidateCache(index, count);
|
||||
}
|
||||
|
||||
if (eventType.EqualsLiteral("RadioStateChange")) {
|
||||
PRUint32 state = State(accessible);
|
||||
|
||||
|
|
|
@ -49,8 +49,6 @@
|
|||
#include "nsIAccessibleTable.h"
|
||||
#endif
|
||||
|
||||
#define kMaxTreeColumns 100
|
||||
|
||||
/* static */
|
||||
PRBool nsXULTreeAccessible::IsColumnHidden(nsITreeColumn *aColumn)
|
||||
{
|
||||
|
@ -506,6 +504,8 @@ NS_IMETHODIMP nsXULTreeAccessible::SelectAllSelection(PRBool *_retval)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessible nsIAccessibleTreeCache::
|
||||
// GetCachedTreeitemAccessible(in long aRow, nsITreeColumn* aColumn)
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessible::GetCachedTreeitemAccessible(PRInt32 aRow,
|
||||
nsITreeColumn* aColumn,
|
||||
|
@ -554,6 +554,77 @@ nsXULTreeAccessible::GetCachedTreeitemAccessible(PRInt32 aRow,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// void nsIAccessibleTreeCache::
|
||||
// invalidateCache(in PRInt32 aRow, in PRInt32 aCount)
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
|
||||
{
|
||||
// Do not invalidate the cache if rows have been inserted.
|
||||
if (aCount > 0)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeColumns> cols;
|
||||
nsresult rv = mTree->GetColumns(getter_AddRefs(cols));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
PRInt32 colsCount = 0;
|
||||
rv = cols->GetCount(&colsCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
#else
|
||||
nsCOMPtr<nsITreeColumn> col;
|
||||
rv = cols->GetKeyColumn(getter_AddRefs(col));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 colIdx = 0;
|
||||
rv = col->GetIndex(&colIdx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
#endif
|
||||
|
||||
for (PRInt32 rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) {
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
for (PRInt32 colIdx = 0; colIdx < colsCount; ++colIdx) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
|
||||
void *key = reinterpret_cast<void*>(rowIdx * kMaxTreeColumns + colIdx);
|
||||
|
||||
nsCOMPtr<nsIAccessNode> accessNode;
|
||||
GetCacheEntry(*mAccessNodeCache, key, getter_AddRefs(accessNode));
|
||||
|
||||
if (accessNode) {
|
||||
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode));
|
||||
nsCOMPtr<nsIAccessibleEvent> event =
|
||||
new nsAccEvent(nsIAccessibleEvent::EVENT_DOM_DESTROY,
|
||||
accessible, nsnull, PR_FALSE);
|
||||
FireAccessibleEvent(event);
|
||||
|
||||
mAccessNodeCache->Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 newRowCount = 0;
|
||||
rv = mTreeView->GetRowCount(&newRowCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 oldRowCount = newRowCount - aCount;
|
||||
|
||||
for (PRInt32 rowIdx = newRowCount; rowIdx < oldRowCount; ++rowIdx) {
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
for (PRInt32 colIdx = 0; colIdx < colsCount; ++colIdx) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
void *key = reinterpret_cast<void*>(rowIdx * kMaxTreeColumns + colIdx);
|
||||
mAccessNodeCache->Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXULTreeAccessible::GetColumnCount(nsITreeBoxObject* aBoxObject, PRInt32* aCount)
|
||||
{
|
||||
NS_ENSURE_TRUE(aBoxObject, NS_ERROR_FAILURE);
|
||||
|
|
|
@ -44,10 +44,10 @@
|
|||
#include "nsXULSelectAccessible.h"
|
||||
#include "nsIAccessibleTreeCache.h"
|
||||
|
||||
|
||||
/*
|
||||
* A class the represents the XUL Tree widget.
|
||||
*/
|
||||
const PRUint32 kMaxTreeColumns = 100;
|
||||
const PRUint32 kDefaultTreeCacheSize = 256;
|
||||
|
||||
class nsXULTreeAccessible : public nsXULSelectableAccessible,
|
||||
|
|
|
@ -75,6 +75,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateDOMEvent, NS_IPRIVATEDOMEVENT_IID)
|
|||
nsresult
|
||||
NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsGUIEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
|
||||
|
|
|
@ -59,12 +59,17 @@ public:
|
|||
nsPLDOMEvent (nsIDOMNode *aEventNode, const nsAString& aEventType)
|
||||
: mEventNode(aEventNode), mEventType(aEventType)
|
||||
{ }
|
||||
|
||||
|
||||
nsPLDOMEvent(nsIDOMNode *aEventNode, nsIDOMEvent *aEvent)
|
||||
: mEventNode(aEventNode), mEvent(aEvent)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run();
|
||||
nsresult PostDOMEvent();
|
||||
|
||||
nsCOMPtr<nsIDOMNode> mEventNode;
|
||||
nsString mEventType;
|
||||
nsCOMPtr<nsIDOMNode> mEventNode;
|
||||
nsCOMPtr<nsIDOMEvent> mEvent;
|
||||
nsString mEventType;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,6 +69,7 @@ CPPSRCS = \
|
|||
nsEventListenerManager.cpp \
|
||||
nsEventStateManager.cpp \
|
||||
nsDOMEvent.cpp \
|
||||
nsDOMDataContainerEvent.cpp \
|
||||
nsDOMUIEvent.cpp \
|
||||
nsDOMKeyboardEvent.cpp \
|
||||
nsDOMTextEvent.cpp \
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
|
||||
*
|
||||
* 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 "nsDOMDataContainerEvent.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
nsDOMDataContainerEvent::nsDOMDataContainerEvent(nsPresContext *aPresContext,
|
||||
nsEvent *aEvent)
|
||||
: nsDOMEvent(aPresContext, aEvent)
|
||||
{
|
||||
mData.Init();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataContainerEvent)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDataContainerEvent,
|
||||
nsDOMEvent)
|
||||
if (tmp->mData.IsInitialized())
|
||||
tmp->mData.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataContainerEvent,
|
||||
nsDOMEvent)
|
||||
tmp->mData.EnumerateRead(TraverseEntry, &cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMDataContainerEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMDataContainerEvent, nsDOMEvent)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDataContainerEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDataContainerEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DataContainerEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataContainerEvent::GetData(const nsAString& aKey, nsIVariant **aData)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aData);
|
||||
|
||||
NS_ENSURE_STATE(mData.IsInitialized());
|
||||
|
||||
mData.Get(aKey, aData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataContainerEvent::SetData(const nsAString& aKey, nsIVariant *aData)
|
||||
{
|
||||
NS_ENSURE_ARG(aData);
|
||||
|
||||
// Make sure this event isn't already being dispatched.
|
||||
NS_ENSURE_STATE(!(NS_IS_EVENT_IN_DISPATCH(mEvent) ||
|
||||
(mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY)));
|
||||
|
||||
NS_ENSURE_STATE(mData.IsInitialized());
|
||||
return mData.Put(aKey, aData) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewDOMDataContainerEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent)
|
||||
{
|
||||
nsDOMDataContainerEvent* it =
|
||||
new nsDOMDataContainerEvent(aPresContext, aEvent);
|
||||
NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(it, aInstancePtrResult);
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
nsDOMDataContainerEvent::TraverseEntry(const nsAString& aKey,
|
||||
nsIVariant *aDataItem,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsCycleCollectionTraversalCallback *cb =
|
||||
static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
|
||||
cb->NoteXPCOMChild(aDataItem);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#ifndef nsDOMDataContainerEvent_h___
|
||||
#define nsDOMDataContainerEvent_h___
|
||||
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsDOMEvent.h"
|
||||
|
||||
class nsDOMDataContainerEvent : public nsDOMEvent,
|
||||
public nsIDOMDataContainerEvent
|
||||
{
|
||||
public:
|
||||
nsDOMDataContainerEvent(nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDataContainerEvent, nsDOMEvent)
|
||||
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
NS_DECL_NSIDOMDATACONTAINEREVENT
|
||||
|
||||
private:
|
||||
static PLDHashOperator PR_CALLBACK
|
||||
TraverseEntry(const nsAString& aKey, nsIVariant *aDataItem, void* aUserArg);
|
||||
|
||||
nsInterfaceHashtable<nsStringHashKey, nsIVariant> mData;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -648,6 +648,9 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
if (aEventType.LowerCaseEqualsLiteral("commandevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("commandevents"))
|
||||
return NS_NewDOMCommandEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("datacontainerevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("datacontainerevents"))
|
||||
return NS_NewDOMDataContainerEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
|
|
@ -47,25 +47,28 @@ NS_IMETHODIMP nsPLDOMEvent::Run()
|
|||
if (!mEventNode) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mEventNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDOMDocumentEvent> domEventDoc = do_QueryInterface(domDoc);
|
||||
if (domEventDoc) {
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
domEventDoc->CreateEvent(NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(domEvent));
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(domEvent));
|
||||
if (privateEvent && NS_SUCCEEDED(domEvent->InitEvent(mEventType, PR_TRUE, PR_TRUE))) {
|
||||
privateEvent->SetTrusted(PR_TRUE);
|
||||
nsCOMPtr<nsIDOMEvent> domEvent(mEvent);
|
||||
if (!domEvent) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mEventNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDOMDocumentEvent> domEventDoc = do_QueryInterface(domDoc);
|
||||
if (domEventDoc) {
|
||||
domEventDoc->CreateEvent(NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(domEvent));
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mEventNode);
|
||||
PRBool defaultActionEnabled; // This is not used because the caller is async
|
||||
target->DispatchEvent(domEvent, &defaultActionEnabled);
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(domEvent));
|
||||
if (privateEvent &&
|
||||
NS_SUCCEEDED(domEvent->InitEvent(mEventType, PR_TRUE, PR_TRUE))) {
|
||||
privateEvent->SetTrusted(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mEventNode);
|
||||
PRBool defaultActionEnabled; // This is not used because the caller is async
|
||||
target->DispatchEvent(domEvent, &defaultActionEnabled);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ _TEST_FILES = \
|
|||
test_bug336682_2.xul \
|
||||
test_bug336682.js \
|
||||
test_bug367781.html \
|
||||
test_bug368835.html \
|
||||
test_bug379120.html \
|
||||
test_bug391568.xhtml \
|
||||
test_bug402089.html \
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=368835
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 368835</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=368835">
|
||||
Mozilla Bug 368835
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function dataContainerEventHandler(aEvent)
|
||||
{
|
||||
var value = "";
|
||||
var isPassed = true;
|
||||
try {
|
||||
value = aEvent.getData("data1");
|
||||
isPassed = true;
|
||||
} catch (e) {
|
||||
isPassed = false;
|
||||
}
|
||||
|
||||
ok(isPassed, "getData shouldn't fail.");
|
||||
ok(value == "data1", "Wrong value of data.");
|
||||
|
||||
try {
|
||||
aEvent.setData("data3", "data3");
|
||||
isPassed = false;
|
||||
} catch (e) {
|
||||
isPassed = true;
|
||||
}
|
||||
|
||||
ok(isPassed, "setData should fail during event dispatching.");
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var isPassed;
|
||||
var event = null;
|
||||
|
||||
try {
|
||||
event = document.createEvent("datacontainerevents");
|
||||
isPassed = true;
|
||||
} catch (e) {
|
||||
isPassed = false;
|
||||
}
|
||||
|
||||
ok(isPassed, "Document should know about 'datacontainerevents' event class.");
|
||||
ok(("setData" in event), "nsIDOMDataContainerEvent isn't available.");
|
||||
|
||||
event.initEvent("dataContainerEvent", true, true);
|
||||
|
||||
try {
|
||||
event.setData("data1", "data1");
|
||||
isPassed = true;
|
||||
} catch (e) {
|
||||
isPassed = false;
|
||||
}
|
||||
|
||||
ok(isPassed, "setData shouldn't fail when event is initialized.");
|
||||
|
||||
document.body.addEventListener("dataContainerEvent",
|
||||
dataContainerEventHandler, true);
|
||||
document.body.dispatchEvent(event);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -61,6 +61,7 @@ SDK_XPIDLSRCS = \
|
|||
|
||||
XPIDLSRCS = \
|
||||
nsIDOMNSEvent.idl \
|
||||
nsIDOMDataContainerEvent.idl \
|
||||
nsIDOMKeyEvent.idl \
|
||||
nsIDOMMutationEvent.idl \
|
||||
nsIDOMNSUIEvent.idl \
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
|
||||
*
|
||||
* 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 "nsIDOMEvent.idl"
|
||||
#include "nsIVariant.idl"
|
||||
|
||||
[scriptable, uuid(3600d66c-b9ac-4c22-b39a-d64cce619921)]
|
||||
interface nsIDOMDataContainerEvent : nsIDOMEvent
|
||||
{
|
||||
/**
|
||||
* Return the data associated with the given key.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the data associated with the key
|
||||
*/
|
||||
nsIVariant getData(in DOMString key);
|
||||
|
||||
/**
|
||||
* Set the data for the given key.
|
||||
*
|
||||
* @param key the data key
|
||||
* @param data the data
|
||||
* @throws NS_ERROR_UNEXPECTED if the method is called during event
|
||||
* dispatch
|
||||
*/
|
||||
void setData(in DOMString key, in nsIVariant data);
|
||||
};
|
||||
|
|
@ -353,7 +353,7 @@ enum nsDOMClassInfoID {
|
|||
eDOMClassInfo_CanvasGradient_id,
|
||||
eDOMClassInfo_CanvasPattern_id,
|
||||
#endif
|
||||
|
||||
|
||||
// SmartCard Events
|
||||
eDOMClassInfo_SmartCardEvent_id,
|
||||
|
||||
|
@ -416,6 +416,9 @@ enum nsDOMClassInfoID {
|
|||
// DOM modal content window class, almost identical to Window
|
||||
eDOMClassInfo_ModalContentWindow_id,
|
||||
|
||||
// Data Events
|
||||
eDOMClassInfo_DataContainerEvent_id,
|
||||
|
||||
// This one better be the last one in this list
|
||||
eDOMClassInfoIDCount
|
||||
};
|
||||
|
|
|
@ -226,6 +226,7 @@
|
|||
#include "nsIDOMProcessingInstruction.h"
|
||||
#include "nsIDOMNotation.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMCommandEvent.h"
|
||||
|
@ -1221,6 +1222,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
|
||||
DEFAULT_SCRIPTABLE_FLAGS |
|
||||
WINDOW_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
};
|
||||
|
||||
// Objects that shuld be constructable through |new Name();|
|
||||
|
@ -3349,6 +3353,10 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(DataContainerEvent, nsIDOMDataContainerEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataContainerEvent)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
{
|
||||
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
||||
|
|
|
@ -61,10 +61,15 @@
|
|||
#include "nsStyleContext.h"
|
||||
#include "nsIBoxObject.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsPLDOMEvent.h"
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
|
@ -1790,6 +1795,12 @@ NS_IMETHODIMP nsTreeBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCount)
|
|||
if (aCount == 0 || !mView)
|
||||
return NS_OK; // Nothing to do.
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsIPresShell *presShell = PresContext()->PresShell();
|
||||
if (presShell->IsAccessibilityActive())
|
||||
FireRowCountChangedEvent(aIndex, aCount);
|
||||
#endif
|
||||
|
||||
// Adjust our selection.
|
||||
nsCOMPtr<nsITreeSelection> sel;
|
||||
mView->GetSelection(getter_AddRefs(sel));
|
||||
|
@ -4365,6 +4376,63 @@ nsTreeBodyFrame::PostScrollEvent()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTreeBodyFrame::FireRowCountChangedEvent(PRInt32 aIndex, PRInt32 aCount)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content(GetBaseElement());
|
||||
if (!content)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
node->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDOMDocumentEvent> domEventDoc(do_QueryInterface(domDoc));
|
||||
if (!domEventDoc)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
domEventDoc->CreateEvent(NS_LITERAL_STRING("datacontainerevents"),
|
||||
getter_AddRefs(event));
|
||||
|
||||
event->InitEvent(NS_LITERAL_STRING("TreeRowCountChanged"), PR_TRUE, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIDOMDataContainerEvent> treeEvent(do_QueryInterface(event));
|
||||
if (!treeEvent)
|
||||
return;
|
||||
|
||||
// Set 'index' data - the row index rows are changed from.
|
||||
nsCOMPtr<nsIWritableVariant> indexVariant(
|
||||
do_CreateInstance("@mozilla.org/variant;1"));
|
||||
if (!indexVariant)
|
||||
return;
|
||||
|
||||
indexVariant->SetAsInt32(aIndex);
|
||||
treeEvent->SetData(NS_LITERAL_STRING("index"), indexVariant);
|
||||
|
||||
// Set 'count' data - the number of changed rows.
|
||||
nsCOMPtr<nsIWritableVariant> countVariant(
|
||||
do_CreateInstance("@mozilla.org/variant;1"));
|
||||
if (!countVariant)
|
||||
return;
|
||||
|
||||
countVariant->SetAsInt32(aCount);
|
||||
treeEvent->SetData(NS_LITERAL_STRING("count"), countVariant);
|
||||
|
||||
// Fire an event.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
if (!privateEvent)
|
||||
return;
|
||||
|
||||
privateEvent->SetTrusted(PR_TRUE);
|
||||
|
||||
nsRefPtr<nsPLDOMEvent> plevent = new nsPLDOMEvent(node, event);
|
||||
if (!plevent)
|
||||
return;
|
||||
|
||||
plevent->PostDOMEvent();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTreeBodyFrame::FullScrollbarsUpdate(PRBool aNeedsFullInvalidation)
|
||||
{
|
||||
|
|
|
@ -413,6 +413,17 @@ protected:
|
|||
void PostScrollEvent();
|
||||
void FireScrollEvent();
|
||||
|
||||
/**
|
||||
* Fires 'treeRowCountChanged' event asynchronously. The event supports
|
||||
* nsIDOMDataContainerEvent interface that is used to expose the following
|
||||
* information structures.
|
||||
*
|
||||
* @param aIndex the row index rows are added/removed from
|
||||
* @param aCount the number of added/removed rows (the sign points to
|
||||
* an operation, plus - addition, minus - removing)
|
||||
*/
|
||||
void FireRowCountChangedEvent(PRInt32 aIndex, PRInt32 aCount);
|
||||
|
||||
protected: // Data Members
|
||||
// The cached box object parent.
|
||||
nsCOMPtr<nsITreeBoxObject> mTreeBoxObject;
|
||||
|
|
|
@ -44,7 +44,9 @@ relativesrcdir = layout/xul/test
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = test_bug372685.xul \
|
||||
_TEST_FILES =\
|
||||
test_bug368835.xul \
|
||||
test_bug372685.xul \
|
||||
test_bug386386.html \
|
||||
test_bug394800.xhtml \
|
||||
test_bug398982-1.xul \
|
||||
|
|
Загрузка…
Ссылка в новой задаче