--- a/accessible/public/nsIAccessibleTreeCache.idl
+++ b/accessible/public/nsIAccessibleTreeCache.idl
@@ -32,22 +32,39 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#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);
};
+
--- a/accessible/src/atk/nsXULTreeAccessibleWrap.cpp
+++ b/accessible/src/atk/nsXULTreeAccessibleWrap.cpp
@@ -442,17 +442,17 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::C
NS_IMETHODIMP nsXULTreeAccessibleWrap::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
{
*aIsProbablyForLayout = PR_FALSE;
return NS_OK;
}
// --------------------------------------------------------
-// nsXULTreeAccessibleWrap Accessible
+// nsXULTreeColumnsAccessibleWrap Accessible
// --------------------------------------------------------
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeColumnsAccessibleWrap, nsXULTreeColumnsAccessible, nsIAccessibleTable)
nsXULTreeColumnsAccessibleWrap::nsXULTreeColumnsAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
nsXULTreeColumnsAccessible(aDOMNode, aShell)
{
}
--- a/accessible/src/atk/nsXULTreeAccessibleWrap.h
+++ b/accessible/src/atk/nsXULTreeAccessibleWrap.h
@@ -50,18 +50,22 @@ class nsXULTreeAccessibleWrap : public n
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLETABLE
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,
public nsIAccessibleTable
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLETABLE
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -48,16 +48,17 @@
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLSelectElement.h"
+#include "nsIDOMDataContainerEvent.h"
#include "nsIDOMNSEvent.h"
#include "nsIDOMXULMenuListElement.h"
#include "nsIDOMXULMultSelectCntrlEl.h"
#include "nsIDOMXULSelectCntrlItemEl.h"
#include "nsIDOMXULPopupElement.h"
#include "nsIDocument.h"
#include "nsIEventListenerManager.h"
#include "nsIFocusController.h"
@@ -282,16 +283,17 @@ const char* const docEvents[] = {
// capture NameChange events (fired whenever name changes, immediately after, whether focus moves or not)
"NameChange",
// capture ValueChange events (fired whenever value changes, immediately after, whether focus moves or not)
"ValueChange",
// capture AlertActive events (fired whenever alert pops up)
"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)
"CheckboxStateChange",
// add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp & radio.xml)
"RadioStateChange",
"popupshown",
"popuphiding",
@@ -636,30 +638,59 @@ nsresult nsRootAccessible::HandleEventWi
// Don't create the doc accessible until load scripts have a chance to set
// role attribute for <body> or <html> element, because the value of
// role attribute will be cached when the doc accessible is Init()'d
TryFireEarlyLoadEvent(aTargetNode);
return NS_OK;
}
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,
nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE);
}
nsCOMPtr<nsIAccessible> accessible;
accService->GetAccessibleInShell(aTargetNode, eventShell,
getter_AddRefs(accessible));
nsCOMPtr<nsPIAccessible> privAcc(do_QueryInterface(accessible));
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);
// radiogroup in prefWindow is exposed as a list,
// and panebutton is exposed as XULListitem in A11y.
// nsXULListitemAccessible::GetState uses STATE_SELECTED in this case,
// so we need to check nsIAccessibleStates::STATE_SELECTED also.
PRBool isEnabled = (state & (nsIAccessibleStates::STATE_CHECKED |
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -44,18 +44,16 @@
#include "nsXULTreeAccessibleWrap.h"
#include "nsIMutableArray.h"
#include "nsComponentManagerUtils.h"
#ifdef MOZ_ACCESSIBILITY_ATK
#include "nsIAccessibleTable.h"
#endif
-#define kMaxTreeColumns 100
-
/* static */
PRBool nsXULTreeAccessible::IsColumnHidden(nsITreeColumn *aColumn)
{
nsCOMPtr<nsIDOMElement> element;
aColumn->GetElement(getter_AddRefs(element));
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
return content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::hidden,
nsAccessibilityAtoms::_true, eCaseMatters);
@@ -501,16 +499,18 @@ NS_IMETHODIMP nsXULTreeAccessible::Selec
if (selection)
selection->SelectAll();
}
}
return NS_OK;
}
+// nsIAccessible nsIAccessibleTreeCache::
+// GetCachedTreeitemAccessible(in long aRow, nsITreeColumn* aColumn)
NS_IMETHODIMP
nsXULTreeAccessible::GetCachedTreeitemAccessible(PRInt32 aRow,
nsITreeColumn* aColumn,
nsIAccessible** aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
@@ -549,16 +549,87 @@ nsXULTreeAccessible::GetCachedTreeitemAc
NS_ENSURE_SUCCESS(rv, rv);
PutCacheEntry(*mAccessNodeCache, (void*)(aRow * kMaxTreeColumns + columnIndex), accessNode);
}
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode));
NS_IF_ADDREF(*aAccessible = accessible);
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);
nsCOMPtr<nsITreeColumns> treeColumns;
aBoxObject->GetColumns(getter_AddRefs(treeColumns));
NS_ENSURE_TRUE(treeColumns, NS_ERROR_FAILURE);
return treeColumns->GetCount(aCount);
}
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -39,20 +39,20 @@
#define __nsXULTreeAccessible_h__
#include "nsITreeBoxObject.h"
#include "nsITreeView.h"
#include "nsITreeColumns.h"
#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,
public nsIAccessibleTreeCache
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLESELECTABLE
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -70,16 +70,18 @@ public:
NS_IMETHOD SetTrusted(PRBool aTrusted)=0;
};
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);
nsresult
NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsKeyEvent *aEvent);
nsresult
NS_NewDOMMutationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
nsresult
--- a/content/events/public/nsPLDOMEvent.h
+++ b/content/events/public/nsPLDOMEvent.h
@@ -54,17 +54,22 @@
* structure used with the old eventing system. See bug 334573.
*/
class nsPLDOMEvent : public nsRunnable {
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
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -64,16 +64,17 @@ REQUIRES = xpcom \
unicharutil \
imglib2 \
$(NULL)
CPPSRCS = \
nsEventListenerManager.cpp \
nsEventStateManager.cpp \
nsDOMEvent.cpp \
+ nsDOMDataContainerEvent.cpp \
nsDOMUIEvent.cpp \
nsDOMKeyboardEvent.cpp \
nsDOMTextEvent.cpp \
nsDOMMouseEvent.cpp \
nsDOMMutationEvent.cpp \
nsDOMPopupBlockedEvent.cpp \
nsDOMBeforeUnloadEvent.cpp \
nsDOMPageTransitionEvent.cpp \
new file mode 100644
--- /dev/null
+++ b/content/events/src/nsDOMDataContainerEvent.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;
+}
+
new file mode 100644
--- /dev/null
+++ b/content/events/src/nsDOMDataContainerEvent.h
@@ -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
+
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -643,11 +643,14 @@ nsEventDispatcher::CreateEvent(nsPresCon
return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext, nsnull);
#endif // MOZ_SVG
if (aEventType.LowerCaseEqualsLiteral("xulcommandevent") ||
aEventType.LowerCaseEqualsLiteral("xulcommandevents"))
return NS_NewDOMXULCommandEvent(aDOMEvent, aPresContext, nsnull);
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;
}
--- a/content/events/src/nsPLDOMEvent.cpp
+++ b/content/events/src/nsPLDOMEvent.cpp
@@ -42,34 +42,37 @@
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMEventTarget.h"
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;
}
nsresult nsPLDOMEvent::PostDOMEvent()
{
return NS_DispatchToCurrentThread(this);
}
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -46,16 +46,17 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_bug238987.html \
test_bug288392.html \
test_bug336682_1.html \
test_bug336682_2.xul \
test_bug336682.js \
test_bug367781.html \
+ test_bug368835.html \
test_bug379120.html \
test_bug391568.xhtml \
test_bug402089.html \
test_bug405632.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug368835.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>
+
--- a/dom/public/idl/events/Makefile.in
+++ b/dom/public/idl/events/Makefile.in
@@ -56,16 +56,17 @@ SDK_XPIDLSRCS =
nsIDOMEventGroup.idl \
nsIDOMCustomEvent.idl \
nsIDOMMouseEvent.idl \
nsIDOMUIEvent.idl \
$(NULL)
XPIDLSRCS = \
nsIDOMNSEvent.idl \
+ nsIDOMDataContainerEvent.idl \
nsIDOMKeyEvent.idl \
nsIDOMMutationEvent.idl \
nsIDOMNSUIEvent.idl \
nsIDOMPopupBlockedEvent.idl \
nsIDOMBeforeUnloadEvent.idl \
nsIDOMNSEventTarget.idl \
nsIDOMSmartCardEvent.idl \
nsIDOMPageTransitionEvent.idl \
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/events/nsIDOMDataContainerEvent.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);
+};
+
--- a/dom/public/nsDOMClassInfoID.h
+++ b/dom/public/nsDOMClassInfoID.h
@@ -348,17 +348,17 @@ enum nsDOMClassInfoID {
// Canvas
eDOMClassInfo_HTMLCanvasElement_id,
#ifdef MOZ_ENABLE_CANVAS
eDOMClassInfo_CanvasRenderingContext2D_id,
eDOMClassInfo_CanvasGradient_id,
eDOMClassInfo_CanvasPattern_id,
#endif
-
+
// SmartCard Events
eDOMClassInfo_SmartCardEvent_id,
// PageTransition Events
eDOMClassInfo_PageTransitionEvent_id,
// WindowUtils
eDOMClassInfo_WindowUtils_id,
@@ -411,16 +411,19 @@ enum nsDOMClassInfoID {
eDOMClassInfo_FileList_id,
eDOMClassInfo_File_id,
eDOMClassInfo_FileException_id,
// 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
};
/**
* nsIClassInfo helper macros
*/
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -221,16 +221,17 @@
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMAttr.h"
#include "nsIDOMText.h"
#include "nsIDOMComment.h"
#include "nsIDOMCDATASection.h"
#include "nsIDOMProcessingInstruction.h"
#include "nsIDOMNotation.h"
#include "nsIDOMNSEvent.h"
+#include "nsIDOMDataContainerEvent.h"
#include "nsIDOMKeyEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMCommandEvent.h"
#include "nsIDOMPopupBlockedEvent.h"
#include "nsIDOMBeforeUnloadEvent.h"
#include "nsIDOMMutationEvent.h"
#include "nsIDOMSmartCardEvent.h"
#include "nsIDOMXULCommandEvent.h"
@@ -1216,16 +1217,19 @@ static nsDOMClassInfoData sClassInfoData
NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(FileException, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
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();|
struct nsContractIDMapData
{
PRInt32 mDOMClassInfoID;
const char *mContractID;
};
@@ -3344,16 +3348,20 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowInternal)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMViewCSS)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMAbstractView)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorageWindow)
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);
if (i != eDOMClassInfoIDCount) {
NS_ERROR("The number of items in sClassInfoData doesn't match the "
"number of nsIDOMClassInfo ID's, this is bad! Fix it!");
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -56,20 +56,25 @@
#include "nsGkAtoms.h"
#include "nsCSSAnonBoxes.h"
#include "nsIContent.h"
#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"
#include "nsICSSStyleRule.h"
#include "nsCSSRendering.h"
#include "nsIFontMetrics.h"
#include "nsIDeviceContext.h"
#include "nsIXULTemplateBuilder.h"
@@ -1785,16 +1790,22 @@ nsTreeBodyFrame::CreateTimer(const nsILo
return NS_OK;
}
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));
if (sel)
sel->AdjustSelection(aIndex, aCount);
if (mUpdateBatchNest)
return NS_OK;
@@ -4360,16 +4371,73 @@ nsTreeBodyFrame::PostScrollEvent()
nsRefPtr<ScrollEvent> ev = new ScrollEvent(this);
if (NS_FAILED(NS_DispatchToCurrentThread(ev))) {
NS_WARNING("failed to dispatch ScrollEvent");
} else {
mScrollEvent = ev;
}
}
+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)
{
ScrollParts parts = GetScrollParts();
nsWeakFrame weakFrame(this);
UpdateScrollbars(parts);
NS_ENSURE_TRUE(weakFrame.IsAlive(), PR_FALSE);
if (aNeedsFullInvalidation) {
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h
@@ -408,16 +408,27 @@ protected:
void Revoke() { mInner = nsnull; }
private:
nsTreeBodyFrame* mInner;
};
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;
// Cached column information.
nsRefPtr<nsTreeColumns> mColumns;
// The current view for this tree widget. We get all of our row and cell data
--- a/layout/xul/test/Makefile.in
+++ b/layout/xul/test/Makefile.in
@@ -39,17 +39,19 @@ DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
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 \
test_bug398982-2.xul \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/layout/xul/test/test_bug368835.xul
@@ -0,0 +1,158 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
+
+<!--
+ Bug 368835 - fire TreeViewChanged/TreeRowCountChanged events.
+-->
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Mozilla Bug 368835">
+
+ <script type="application/javascript" src="/MochiKit/packed.js"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
+ <script type="application/javascript">
+ <![CDATA[
+ function inTreeView() { }
+
+ inTreeView.prototype =
+ {
+ mRowCount: 0,
+ mTree: null,
+
+ get rowCount() { return this.mRowCount; },
+ setTree: function(aTree) { this.mTree = aTree; },
+ getCellText: function(aRow, aCol) { return "hello"; },
+ getRowProperties: function(aIndex, aProperties) {},
+ getCellProperties: function(aIndex, aCol, aProperties) {},
+ getColumnProperties: function(aCol, aProperties) {},
+ getParentIndex: function(aRowIndex) { },
+ hasNextSibling: function(aRowIndex, aAfterIndex) { },
+ getLevel: function(aIndex) {},
+ getImageSrc: function(aRow, aCol) {},
+ getProgressMode: function(aRow, aCol) {},
+ getCellValue: function(aRow, aCol) {},
+ isContainer: function(aIndex) {},
+ isContainerOpen: function(aIndex) {},
+ isContainerEmpty: function(aIndex) {},
+ isSeparator: function(aIndex) {},
+ isSorted: function() {},
+ toggleOpenState: function(aIndex) {},
+ selectionChanged: function() {},
+ cycleHeader: function(aCol) {},
+ cycleCell: function(aRow, aCol) {},
+ isEditable: function(aRow, aCol) {},
+ isSelectable: function(aRow, aCol) {},
+ setCellValue: function(aRow, aCol, aValue) {},
+ setCellText: function(aRow, aCol, aValue) { },
+ performAction: function(aAction) {},
+ performActionOnRow: function(aAction, aRow) {},
+ performActionOnCell: function(aAction, aRow, aCol) {}
+ };
+
+ var gTreeViewChanged = false;
+ function TreeViewChangedHandler(aEvent)
+ {
+ gTreeViewChanged = true;
+ }
+
+ var gTreeRowCountChanged = false;
+ function TreeRowCountChangedHandler(aEvent)
+ {
+ netscape.security.PrivilegeManager.
+ enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
+
+ gTreeRowCountChanged = true;
+
+ var index = aEvent.getData("index");
+ ok(index == 0, "Wrong 'index' data of 'treeRowCountChanged' event.");
+
+ var count = aEvent.getData("count");
+ ok(count == 1, "Wrong 'count' data of 'treeRowCountChanged' event.");
+ }
+
+ function CheckEvents()
+ {
+ netscape.security.PrivilegeManager.
+ enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
+
+ // If these fail then it doesn't mean actually events are not fired,
+ // possibly setTimeout was executed earlier than events have beenS fired.
+
+ ok(gTreeViewChanged, "TreeViewChanged event should have been fired.")
+ ok(gTreeRowCountChanged, "TreeRowCountChanged event should have been fired.");
+
+ document.removeEventListener("TreeViewChanged",
+ TreeViewChangedHandler, true);
+
+ document.removeEventListener("TreeRowCountChanged",
+ TreeRowCountChangedHandler, true);
+
+ SimpleTest.finish();
+ }
+
+ var gAccService = null;
+
+ function doTest()
+ {
+ netscape.security.PrivilegeManager.
+ enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
+
+ // Check whether accessbility support is enabled.
+ if (!("@mozilla.org/accessibleRetrieval;1" in Components.classes)) {
+ SimpleTest.finish();
+ return;
+ }
+
+ // Activate accessibility, otherwise events aren't fired.
+ gAccService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
+ getService(Components.interfaces.nsIAccessibleRetrieval);
+
+ document.addEventListener("TreeViewChanged",
+ TreeViewChangedHandler, true);
+ document.addEventListener("TreeRowCountChanged",
+ TreeRowCountChangedHandler, true);
+
+ var tree = document.getElementById("tree");
+ var treeBox = tree.treeBoxObject;
+
+ var view = new inTreeView();
+ view.mRowCount = 5;
+
+ treeBox.view = view;
+
+ view.selection.currentIndex = 0;
+ view.selection.selectAll();
+
+ ++view.mRowCount;
+ treeBox.rowCountChanged(0, 1);
+
+ if (gTreeViewChanged && gTreeRowCountChanged)
+ CheckEvents();
+ else
+ window.setTimeout(CheckEvents, 1000);
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(doTest);
+ ]]>
+ </script>
+
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <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>
+ </body>
+
+ <tree id="tree" flex="1">
+ <treecols>
+ <treecol id="col" flex="1" primary="true" label="column"/>
+ </treecols>
+ <treechildren id="treechildren"/>
+ </tree>
+</window>
+