mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
Merge mozilla-central to tracemonkey.
This commit is contained in:
commit
6a6c2fc430
@ -43,7 +43,11 @@ VPATH = @srcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = accessibility
|
||||
DIRS = public src build tests
|
||||
DIRS = public src build
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += tests
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -58,7 +58,6 @@ XPIDLSRCS = \
|
||||
nsIAccessibleRelation.idl \
|
||||
nsIAccessibleRole.idl \
|
||||
nsIAccessibleStates.idl \
|
||||
nsPIAccessible.idl \
|
||||
nsIAccessibleDocument.idl \
|
||||
nsPIAccessibleDocument.idl \
|
||||
nsIAccessibleProvider.idl \
|
||||
|
@ -1,119 +0,0 @@
|
||||
/* -*- 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
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIAccessible;
|
||||
interface nsIAccessibleEvent;
|
||||
%{C++
|
||||
struct nsRoleMapEntry;
|
||||
%}
|
||||
[ptr] native nsRoleMapEntryPtr(nsRoleMapEntry);
|
||||
|
||||
[uuid(ed61e5cd-283a-42df-9599-765e0e27f4d9)]
|
||||
interface nsPIAccessible : nsISupports
|
||||
{
|
||||
/**
|
||||
* Set accessible parent.
|
||||
*/
|
||||
void setParent(in nsIAccessible aAccParent);
|
||||
|
||||
/**
|
||||
* Set first accessible child.
|
||||
*/
|
||||
void setFirstChild(in nsIAccessible aAccFirstChild);
|
||||
|
||||
/**
|
||||
* Set next sibling accessible.
|
||||
*/
|
||||
void setNextSibling(in nsIAccessible aAccNextSibling);
|
||||
|
||||
/**
|
||||
* Return parent accessible only if cached.
|
||||
*/
|
||||
void getCachedParent(out nsIAccessible aAccParent);
|
||||
|
||||
/**
|
||||
* Return first child accessible only if cached.
|
||||
*/
|
||||
void getCachedFirstChild(out nsIAccessible aAccFirstChild);
|
||||
|
||||
/**
|
||||
* Set the child count to -1 (unknown) and null out cached child pointers
|
||||
*/
|
||||
void invalidateChildren();
|
||||
|
||||
/**
|
||||
* Fire accessible event.
|
||||
*/
|
||||
void fireAccessibleEvent(in nsIAccessibleEvent aAccEvent);
|
||||
|
||||
/**
|
||||
* Return true if there are accessible children in anonymous content
|
||||
*/
|
||||
readonly attribute boolean allowsAnonChildAccessibles;
|
||||
|
||||
/**
|
||||
* Assert if child not in parent's cache.
|
||||
*/
|
||||
void testChildCache(in nsIAccessible aCachedChild);
|
||||
|
||||
/**
|
||||
* Returns text of accessible if accessible has text role otherwise empty
|
||||
* string.
|
||||
*/
|
||||
void appendTextTo(out AString aString, in unsigned long aStartOffset,
|
||||
in unsigned long aLength);
|
||||
|
||||
/**
|
||||
* Set the ARIA role map entry for a new accessible.
|
||||
* For a newly created accessible, specify which role map entry should be used.
|
||||
* @param aRoleMapEntry The ARIA nsRoleMapEntry* for the accessible, or
|
||||
* nsnull if none.
|
||||
*/
|
||||
void setRoleMapEntry(in nsRoleMapEntryPtr aRoleMapEntry);
|
||||
|
||||
/**
|
||||
* Maps ARIA state attributes to state of accessible. Note the given state
|
||||
* argument should hold states for accessible before you pass it into this
|
||||
* method.
|
||||
* @param in/out where to fill the states into.
|
||||
*/
|
||||
void getARIAState(out unsigned long aState);
|
||||
};
|
||||
|
@ -75,4 +75,4 @@ endif
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
$(NSINSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) .
|
||||
$(INSTALL) $(PLATFORM_DIR)/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) .
|
||||
|
@ -91,6 +91,7 @@ endif
|
||||
|
||||
EXPORTS = \
|
||||
nsAccessNodeWrap.h \
|
||||
nsARIAGridAccessibleWrap.h \
|
||||
nsAccessibleWrap.h \
|
||||
nsDocAccessibleWrap.h \
|
||||
nsRootAccessibleWrap.h \
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -12,14 +14,15 @@
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SVG Project code.
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Jonathan Watt.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonathan Watt <jonathan.watt@strath.ac.uk> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -35,27 +38,12 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __NS_SVGZOOMEVENT_H__
|
||||
#define __NS_SVGZOOMEVENT_H__
|
||||
#ifndef _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
#define _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsARIAGridAccessible.h"
|
||||
|
||||
class nsIDOMEvent;
|
||||
typedef class nsARIAGridAccessible nsARIAGridAccessibleWrap;
|
||||
|
||||
/*
|
||||
* SVG zoom event listener interface.
|
||||
*/
|
||||
#endif
|
||||
|
||||
#define NS_IDOMSVGZOOMLISTENER_IID \
|
||||
{ 0xccbeadab, 0xb3fe, 0x42f7, { 0x90, 0xed, 0xd6, 0xe4, 0x0f, 0x71, 0x2c, 0x29 } }
|
||||
|
||||
class nsIDOMSVGZoomListener : public nsIDOMEventListener {
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMSVGZOOMLISTENER_IID)
|
||||
NS_IMETHOD Zoom (nsIDOMEvent* aEvent) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMSVGZoomListener,
|
||||
NS_IDOMSVGZOOMLISTENER_IID)
|
||||
|
||||
#endif // __NS_SVGZOOMEVENT_H__
|
@ -262,26 +262,6 @@ mai_atk_object_get_type(void)
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must keep sychronization with enumerate AtkProperty in
|
||||
* accessible/src/base/nsAccessibleEventData.h
|
||||
*/
|
||||
static char * sAtkPropertyNameArray[PROP_LAST] = {
|
||||
0,
|
||||
"accessible-name",
|
||||
"accessible-description",
|
||||
"accessible-parent",
|
||||
"accessible-role",
|
||||
"accessible-layer",
|
||||
"accessible-mdi-zorder",
|
||||
"accessible-table-caption",
|
||||
"accessible-table-column-description",
|
||||
"accessible-table-column-header",
|
||||
"accessible-table-row-description",
|
||||
"accessible-table-row-header",
|
||||
"accessible-table-summary"
|
||||
};
|
||||
|
||||
#ifdef MAI_LOGGING
|
||||
PRInt32 nsAccessibleWrap::mAccWrapCreated = 0;
|
||||
PRInt32 nsAccessibleWrap::mAccWrapDeleted = 0;
|
||||
@ -1126,7 +1106,7 @@ nsAccessibleWrap *GetAccessibleWrap(AtkObject *aAtkObj)
|
||||
return tmpAccWrap;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
||||
{
|
||||
nsresult rv = nsAccessible::FireAccessibleEvent(aEvent);
|
||||
|
@ -97,28 +97,10 @@ nsARIAGridAccessible::GetColumns(PRInt32 *aColumns)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAccessible> row, nextChild;
|
||||
GetFirstChild(getter_AddRefs(row));
|
||||
while (row && nsAccUtils::Role(row) != nsIAccessibleRole::ROLE_ROW) {
|
||||
row->GetNextSibling(getter_AddRefs(nextChild));
|
||||
row.swap(nextChild);
|
||||
}
|
||||
|
||||
if (!row)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAccessible> row = GetNextRow();
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
row->GetFirstChild(getter_AddRefs(cell));
|
||||
while (cell) {
|
||||
PRUint32 role = nsAccUtils::Role(cell);
|
||||
if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
role == nsIAccessibleRole::ROLE_COLUMNHEADER)
|
||||
(*aColumns)++;
|
||||
|
||||
cell->GetNextSibling(getter_AddRefs(nextChild));
|
||||
cell.swap(nextChild);
|
||||
}
|
||||
while ((cell = GetNextCellInRow(row, cell)))
|
||||
(*aColumns)++;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -145,15 +127,9 @@ nsARIAGridAccessible::GetRows(PRInt32 *aRows)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAccessible> row, nextRow;
|
||||
GetFirstChild(getter_AddRefs(row));
|
||||
while (row) {
|
||||
if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW)
|
||||
(*aRows)++;
|
||||
|
||||
row->GetNextSibling(getter_AddRefs(nextRow));
|
||||
row.swap(nextRow);
|
||||
}
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
while ((row = GetNextRow(row)))
|
||||
(*aRows)++;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -181,40 +157,11 @@ nsARIAGridAccessible::CellRefAt(PRInt32 aRow, PRInt32 aColumn,
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 rowIdx = aRow + 1;
|
||||
nsCOMPtr<nsIAccessible> row, nextChild;
|
||||
GetFirstChild(getter_AddRefs(row));
|
||||
while (row) {
|
||||
if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW)
|
||||
rowIdx--;
|
||||
nsCOMPtr<nsIAccessible> row = GetRowAt(aRow);
|
||||
NS_ENSURE_ARG(row);
|
||||
|
||||
if (rowIdx == 0)
|
||||
break;
|
||||
|
||||
row->GetNextSibling(getter_AddRefs(nextChild));
|
||||
row.swap(nextChild);
|
||||
}
|
||||
|
||||
NS_ENSURE_ARG(row && rowIdx == 0);
|
||||
|
||||
PRInt32 colIdx = aColumn + 1;
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
row->GetFirstChild(getter_AddRefs(cell));
|
||||
while (cell) {
|
||||
PRUint32 role = nsAccUtils::Role(cell);
|
||||
if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
role == nsIAccessibleRole::ROLE_COLUMNHEADER)
|
||||
colIdx--;
|
||||
|
||||
if (colIdx == 0)
|
||||
break;
|
||||
|
||||
cell->GetNextSibling(getter_AddRefs(nextChild));
|
||||
cell.swap(nextChild);
|
||||
}
|
||||
|
||||
NS_ENSURE_ARG(cell && colIdx == 0);
|
||||
nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumn);
|
||||
NS_ENSURE_ARG(cell);
|
||||
|
||||
NS_ADDREF(*aAccessible = cell);
|
||||
return NS_OK;
|
||||
@ -361,8 +308,23 @@ nsARIAGridAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected)
|
||||
|
||||
NS_ENSURE_ARG(IsValidColumn(aColumn));
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsCOMPtr<nsIAccessible> row = GetNextRow();
|
||||
if (!row)
|
||||
return NS_OK;
|
||||
|
||||
do {
|
||||
if (!IsARIASelected(row)) {
|
||||
nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumn);
|
||||
if (!cell) // Do not fail due to wrong markup
|
||||
return NS_OK;
|
||||
|
||||
if (!IsARIASelected(cell))
|
||||
return NS_OK;
|
||||
}
|
||||
} while ((row = GetNextRow(row)));
|
||||
|
||||
*aIsSelected = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -374,10 +336,19 @@ nsARIAGridAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ENSURE_ARG(IsValidRow(aRow));
|
||||
nsCOMPtr<nsIAccessible> row = GetRowAt(aRow);
|
||||
NS_ENSURE_ARG(row);
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (!IsARIASelected(row)) {
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
while ((cell = GetNextCellInRow(row, cell))) {
|
||||
if (!IsARIASelected(cell))
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*aIsSelected = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -390,10 +361,19 @@ nsARIAGridAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ENSURE_ARG(IsValidRowNColumn(aRow, aColumn));
|
||||
nsCOMPtr<nsIAccessible> row(GetRowAt(aRow));
|
||||
NS_ENSURE_ARG(row);
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (!IsARIASelected(row)) {
|
||||
nsCOMPtr<nsIAccessible> cell(GetCellInRowAt(row, aColumn));
|
||||
NS_ENSURE_ARG(cell);
|
||||
|
||||
if (!IsARIASelected(cell))
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aIsSelected = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -405,21 +385,30 @@ nsARIAGridAccessible::GetSelectedCellsCount(PRUint32* aCount)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
PRInt32 colCount = 0;
|
||||
GetColumns(&colCount);
|
||||
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
while ((row = GetNextRow(row))) {
|
||||
if (IsARIASelected(row)) {
|
||||
(*aCount) += colCount;
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
while ((cell = GetNextCellInRow(row, cell))) {
|
||||
if (IsARIASelected(cell))
|
||||
(*aCount)++;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsARIAGridAccessible::GetSelectedColumnsCount(PRUint32* aCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCount);
|
||||
*aCount = 0;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return GetSelectedColumnsArray(aCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -431,8 +420,30 @@ nsARIAGridAccessible::GetSelectedRowsCount(PRUint32* aCount)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
while ((row = GetNextRow(row))) {
|
||||
if (IsARIASelected(row)) {
|
||||
(*aCount)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> cell = GetNextCellInRow(row);
|
||||
if (!cell)
|
||||
continue;
|
||||
|
||||
PRBool isRowSelected = PR_TRUE;
|
||||
do {
|
||||
if (!IsARIASelected(cell)) {
|
||||
isRowSelected = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
} while ((cell = GetNextCellInRow(row, cell)));
|
||||
|
||||
if (isRowSelected)
|
||||
(*aCount)++;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -446,24 +457,49 @@ nsARIAGridAccessible::GetSelectedCells(PRUint32 *aCellsCount, PRInt32 **aCells)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
PRInt32 rowCount = 0;
|
||||
GetRows(&rowCount);
|
||||
|
||||
PRInt32 colCount = 0;
|
||||
GetColumns(&colCount);
|
||||
|
||||
nsTArray<PRInt32> selCells(rowCount * colCount);
|
||||
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
for (PRInt32 rowIdx = 0; row = GetNextRow(row); rowIdx++) {
|
||||
if (IsARIASelected(row)) {
|
||||
for (PRInt32 colIdx = 0; colIdx < colCount; colIdx++)
|
||||
selCells.AppendElement(rowIdx * colCount + colIdx);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
for (PRInt32 colIdx = 0; cell = GetNextCellInRow(row, cell); colIdx++) {
|
||||
if (IsARIASelected(cell))
|
||||
selCells.AppendElement(rowIdx * colCount + colIdx);
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 selCellsCount = selCells.Length();
|
||||
if (!selCellsCount)
|
||||
return NS_OK;
|
||||
|
||||
*aCells = static_cast<PRInt32*>(
|
||||
nsMemory::Clone(selCells.Elements(), selCellsCount * sizeof(PRInt32)));
|
||||
NS_ENSURE_TRUE(*aCells, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aCellsCount = selCellsCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsARIAGridAccessible::GetSelectedColumns(PRUint32 *aColumnsCount,
|
||||
PRInt32 **aColumns)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aColumnsCount);
|
||||
*aColumnsCount = 0;
|
||||
NS_ENSURE_ARG_POINTER(aColumns);
|
||||
*aColumns = nsnull;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return GetSelectedColumnsArray(aColumnsCount, aColumns);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -477,8 +513,46 @@ nsARIAGridAccessible::GetSelectedRows(PRUint32 *aRowsCount, PRInt32 **aRows)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
PRInt32 rowCount = 0;
|
||||
GetRows(&rowCount);
|
||||
if (!rowCount)
|
||||
return NS_OK;
|
||||
|
||||
nsTArray<PRInt32> selRows(rowCount);
|
||||
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
for (PRInt32 rowIdx = 0; row = GetNextRow(row); rowIdx++) {
|
||||
if (IsARIASelected(row)) {
|
||||
selRows.AppendElement(rowIdx);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> cell = GetNextCellInRow(row);
|
||||
if (!cell)
|
||||
continue;
|
||||
|
||||
PRBool isRowSelected = PR_TRUE;
|
||||
do {
|
||||
if (!IsARIASelected(cell)) {
|
||||
isRowSelected = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
} while ((cell = GetNextCellInRow(row, cell)));
|
||||
|
||||
if (isRowSelected)
|
||||
selRows.AppendElement(rowIdx);
|
||||
}
|
||||
|
||||
PRUint32 selRowsCount = selRows.Length();
|
||||
if (!selRowsCount)
|
||||
return NS_OK;
|
||||
|
||||
*aRows = static_cast<PRInt32*>(
|
||||
nsMemory::Clone(selRows.Elements(), selRowsCount * sizeof(PRInt32)));
|
||||
NS_ENSURE_TRUE(*aRows, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aRowsCount = selRowsCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -489,8 +563,13 @@ nsARIAGridAccessible::SelectRow(PRInt32 aRow)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
for (PRInt32 rowIdx = 0; row = GetNextRow(row); rowIdx++) {
|
||||
nsresult rv = SetARIASelected(row, rowIdx == aRow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -501,20 +580,33 @@ nsARIAGridAccessible::SelectColumn(PRInt32 aColumn)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
while ((row = GetNextRow(row))) {
|
||||
// Unselect all cells in the row.
|
||||
nsresult rv = SetARIASelected(row, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Select cell at the column index.
|
||||
nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumn);
|
||||
if (cell) {
|
||||
rv = SetARIASelected(cell, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsARIAGridAccessible::UnselectRow(PRInt32 aRow)
|
||||
{
|
||||
NS_ENSURE_ARG(IsValidRow(aRow));
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsCOMPtr<nsIAccessible> row = GetRowAt(aRow);
|
||||
NS_ENSURE_ARG(row);
|
||||
|
||||
return SetARIASelected(row, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -525,8 +617,16 @@ nsARIAGridAccessible::UnselectColumn(PRInt32 aColumn)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should we rely on aria-selected or DOM selection?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
while ((row = GetNextRow(row))) {
|
||||
nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumn);
|
||||
if (cell) {
|
||||
nsresult rv = SetARIASelected(cell, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -579,6 +679,228 @@ nsARIAGridAccessible::IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn)
|
||||
return aColumn < colCount;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsARIAGridAccessible::GetRowAt(PRInt32 aRow)
|
||||
{
|
||||
PRInt32 rowIdx = aRow;
|
||||
nsCOMPtr<nsIAccessible> row(GetNextRow());
|
||||
while (rowIdx != 0 && (row = GetNextRow(row)))
|
||||
rowIdx--;
|
||||
|
||||
return row.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsARIAGridAccessible::GetCellInRowAt(nsIAccessible *aRow, PRInt32 aColumn)
|
||||
{
|
||||
PRInt32 colIdx = aColumn;
|
||||
nsCOMPtr<nsIAccessible> cell(GetNextCellInRow(aRow));
|
||||
while (colIdx != 0 && (cell = GetNextCellInRow(aRow, cell)))
|
||||
colIdx--;
|
||||
|
||||
return cell.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsARIAGridAccessible::GetNextRow(nsIAccessible *aRow)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> nextRow, tmpAcc;
|
||||
if (!aRow)
|
||||
GetFirstChild(getter_AddRefs(nextRow));
|
||||
else
|
||||
aRow->GetNextSibling(getter_AddRefs(nextRow));
|
||||
|
||||
while (nextRow) {
|
||||
if (nsAccUtils::Role(nextRow) == nsIAccessibleRole::ROLE_ROW)
|
||||
return nextRow.forget();
|
||||
|
||||
nextRow->GetNextSibling(getter_AddRefs(tmpAcc));
|
||||
tmpAcc.swap(nextRow);
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsARIAGridAccessible::GetNextCellInRow(nsIAccessible *aRow, nsIAccessible *aCell)
|
||||
{
|
||||
if (!aRow)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessible> nextCell, tmpAcc;
|
||||
if (!aCell)
|
||||
aRow->GetFirstChild(getter_AddRefs(nextCell));
|
||||
else
|
||||
aCell->GetNextSibling(getter_AddRefs(nextCell));
|
||||
|
||||
while (nextCell) {
|
||||
PRUint32 role = nsAccUtils::Role(nextCell);
|
||||
if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
role == nsIAccessibleRole::ROLE_COLUMNHEADER)
|
||||
return nextCell.forget();
|
||||
|
||||
nextCell->GetNextSibling(getter_AddRefs(tmpAcc));
|
||||
tmpAcc.swap(nextCell);
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsARIAGridAccessible::IsARIASelected(nsIAccessible *aAccessible)
|
||||
{
|
||||
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessible);
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
acc->GetDOMNode(getter_AddRefs(node));
|
||||
NS_ASSERTION(node, "No DOM node!");
|
||||
|
||||
if (node) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
||||
if (content->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_selected,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters))
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsARIAGridAccessible::SetARIASelected(nsIAccessible *aAccessible,
|
||||
PRBool aIsSelected, PRBool aNotify)
|
||||
{
|
||||
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessible);
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
acc->GetDOMNode(getter_AddRefs(node));
|
||||
NS_ENSURE_STATE(node);
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
if (aIsSelected)
|
||||
rv = content->SetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_selected,
|
||||
NS_LITERAL_STRING("true"), aNotify);
|
||||
else
|
||||
rv = content->UnsetAttr(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_selected, aNotify);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// No "smart" select/unselect for internal call.
|
||||
if (!aNotify)
|
||||
return NS_OK;
|
||||
|
||||
// If row or cell accessible was selected then we're able to not bother about
|
||||
// selection of its cells or its row because our algorithm is row oriented,
|
||||
// i.e. we check selection on row firstly and then on cells.
|
||||
if (aIsSelected)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
|
||||
// If the given accessible is row that was unselected then remove
|
||||
// aria-selected from cell accessible.
|
||||
if (role == nsIAccessibleRole::ROLE_ROW) {
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
while ((cell = GetNextCellInRow(aAccessible, cell))) {
|
||||
rv = SetARIASelected(cell, PR_FALSE, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the given accessible is cell that was unselected and its row is selected
|
||||
// then remove aria-selected from row and put aria-selected on
|
||||
// siblings cells.
|
||||
if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
|
||||
nsCOMPtr<nsIAccessible> row;
|
||||
aAccessible->GetParent(getter_AddRefs(row));
|
||||
|
||||
if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW &&
|
||||
IsARIASelected(row)) {
|
||||
rv = SetARIASelected(row, PR_FALSE, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
while ((cell = GetNextCellInRow(row, cell))) {
|
||||
if (cell != aAccessible) {
|
||||
rv = SetARIASelected(cell, PR_TRUE, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsARIAGridAccessible::GetSelectedColumnsArray(PRUint32 *aColumnsCount,
|
||||
PRInt32 **aColumns)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aColumnsCount);
|
||||
*aColumnsCount = 0;
|
||||
if (aColumns)
|
||||
*aColumns = nsnull;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAccessible> row = GetNextRow();
|
||||
if (!row)
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 colCount = 0;
|
||||
GetColumns(&colCount);
|
||||
if (!colCount)
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 selColCount = colCount;
|
||||
|
||||
nsTArray<PRBool> isColSelArray(selColCount);
|
||||
isColSelArray.AppendElements(selColCount);
|
||||
for (PRInt32 i = 0; i < selColCount; i++)
|
||||
isColSelArray[i] = PR_TRUE;
|
||||
|
||||
do {
|
||||
if (IsARIASelected(row))
|
||||
continue;
|
||||
|
||||
PRInt32 colIdx = 0;
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
for (colIdx = 0; cell = GetNextCellInRow(row, cell); colIdx++) {
|
||||
if (isColSelArray.SafeElementAt(colIdx, PR_FALSE) &&
|
||||
!IsARIASelected(cell)) {
|
||||
isColSelArray[colIdx] = PR_FALSE;
|
||||
selColCount--;
|
||||
}
|
||||
}
|
||||
} while ((row = GetNextRow(row)));
|
||||
|
||||
if (!selColCount)
|
||||
return NS_OK;
|
||||
|
||||
if (!aColumns) {
|
||||
*aColumnsCount = selColCount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aColumns = static_cast<PRInt32*>(
|
||||
nsMemory::Alloc(selColCount * sizeof(PRInt32)));
|
||||
NS_ENSURE_TRUE(*aColumns, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aColumnsCount = selColCount;
|
||||
for (PRInt32 colIdx = 0, idx = 0; colIdx < colCount; colIdx++) {
|
||||
if (isColSelArray[colIdx])
|
||||
(*aColumns)[idx++] = colIdx;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsARIAGridCellAccessible
|
||||
|
@ -59,11 +59,75 @@ public:
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return true if the given row index is valid.
|
||||
*/
|
||||
PRBool IsValidRow(PRInt32 aRow);
|
||||
|
||||
/**
|
||||
* Retrn true if the given column index is valid.
|
||||
*/
|
||||
PRBool IsValidColumn(PRInt32 aColumn);
|
||||
|
||||
/**
|
||||
* Retrun true if given row and column indexes are valid.
|
||||
*/
|
||||
PRBool IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn);
|
||||
|
||||
/**
|
||||
* Return row accessible at the given row index.
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetRowAt(PRInt32 aRow);
|
||||
|
||||
/**
|
||||
* Return cell accessible at the given column index in the row.
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetCellInRowAt(nsIAccessible *aRow,
|
||||
PRInt32 aColumn);
|
||||
|
||||
/**
|
||||
* Return next row accessible relative given row accessible or first row
|
||||
* accessible if it is null.
|
||||
*
|
||||
* @param aRow [in, optional] row accessible
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetNextRow(nsIAccessible *aRow = nsnull);
|
||||
|
||||
/**
|
||||
* Return next cell accessible relative given cell accessible or first cell
|
||||
* in the given row accessible if given cell accessible is null.
|
||||
*
|
||||
* @param aRow [in] row accessible
|
||||
* @param aCell [in, optional] cell accessible
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetNextCellInRow(nsIAccessible *aRow,
|
||||
nsIAccessible *aCell = nsnull);
|
||||
|
||||
/**
|
||||
* Return true if the DOM node of given accessible has aria-selected="true"
|
||||
* attribute.
|
||||
*/
|
||||
PRBool IsARIASelected(nsIAccessible *aAccessible);
|
||||
|
||||
/**
|
||||
* Set aria-selected attribute value on DOM node of the given accessible.
|
||||
*
|
||||
* @param aAccessible [in] accessible
|
||||
* @param aIsSelected [in] new value of aria-selected attribute
|
||||
* @param aNotify [in, optional] specifies if DOM should be notified
|
||||
* about attribute change (used internally).
|
||||
*/
|
||||
nsresult SetARIASelected(nsIAccessible *aAccessible, PRBool aIsSelected,
|
||||
PRBool aNotify = PR_TRUE);
|
||||
|
||||
/**
|
||||
* Helper method for GetSelectedColumnsCount and GetSelectedColumns.
|
||||
*/
|
||||
nsresult GetSelectedColumnsArray(PRUint32 *aColumnsCount,
|
||||
PRInt32 **aColumns = nsnull);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Accessible for ARIA gridcell and rowheader/columnheader.
|
||||
*/
|
||||
|
@ -63,6 +63,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"alert",
|
||||
nsIAccessibleRole::ROLE_ALERT,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -72,6 +73,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"alertdialog",
|
||||
nsIAccessibleRole::ROLE_DIALOG,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -81,6 +83,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"application",
|
||||
nsIAccessibleRole::ROLE_APPLICATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -90,6 +93,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"article",
|
||||
nsIAccessibleRole::ROLE_DOCUMENT,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -99,6 +103,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"button",
|
||||
nsIAccessibleRole::ROLE_PUSHBUTTON,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
@ -110,6 +115,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"checkbox",
|
||||
nsIAccessibleRole::ROLE_CHECKBUTTON,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eCheckUncheckAction,
|
||||
eNoLiveAttr,
|
||||
@ -122,6 +128,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"columnheader",
|
||||
nsIAccessibleRole::ROLE_COLUMNHEADER,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eSortAction,
|
||||
eNoLiveAttr,
|
||||
@ -134,6 +141,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"combobox",
|
||||
nsIAccessibleRole::ROLE_COMBOBOX,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
eOpenCloseAction,
|
||||
eNoLiveAttr,
|
||||
@ -145,6 +153,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"dialog",
|
||||
nsIAccessibleRole::ROLE_DIALOG,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -154,6 +163,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"document",
|
||||
nsIAccessibleRole::ROLE_DOCUMENT,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -163,6 +173,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"grid",
|
||||
nsIAccessibleRole::ROLE_TABLE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -174,6 +185,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"gridcell",
|
||||
nsIAccessibleRole::ROLE_GRID_CELL,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -186,6 +198,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"group",
|
||||
nsIAccessibleRole::ROLE_GROUPING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -195,6 +208,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"heading",
|
||||
nsIAccessibleRole::ROLE_HEADING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -204,6 +218,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"img",
|
||||
nsIAccessibleRole::ROLE_GRAPHIC,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -213,6 +228,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"label",
|
||||
nsIAccessibleRole::ROLE_LABEL,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -222,6 +238,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"link",
|
||||
nsIAccessibleRole::ROLE_LINK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eJumpAction,
|
||||
eNoLiveAttr,
|
||||
@ -231,6 +248,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"list",
|
||||
nsIAccessibleRole::ROLE_LIST,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -241,6 +259,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"listbox",
|
||||
nsIAccessibleRole::ROLE_LISTBOX,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -252,6 +271,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"listitem",
|
||||
nsIAccessibleRole::ROLE_LISTITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction, // XXX: should depend on state, parent accessible
|
||||
eNoLiveAttr,
|
||||
@ -266,6 +286,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"log",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
ePoliteLiveAttr,
|
||||
@ -275,6 +296,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"marquee",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eOffLiveAttr,
|
||||
@ -284,6 +306,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"math",
|
||||
nsIAccessibleRole::ROLE_FLAT_EQUATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -293,6 +316,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"menu",
|
||||
nsIAccessibleRole::ROLE_MENUPOPUP,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction, // XXX: technically accessibles of menupopup role haven't
|
||||
// any action, but menu can be open or close.
|
||||
@ -303,6 +327,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"menubar",
|
||||
nsIAccessibleRole::ROLE_MENUBAR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -312,6 +337,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"menuitem",
|
||||
nsIAccessibleRole::ROLE_MENUITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
@ -324,6 +350,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"menuitemcheckbox",
|
||||
nsIAccessibleRole::ROLE_CHECK_MENU_ITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
@ -335,6 +362,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"menuitemradio",
|
||||
nsIAccessibleRole::ROLE_RADIO_MENU_ITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
@ -345,6 +373,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"option",
|
||||
nsIAccessibleRole::ROLE_OPTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eSelectAction,
|
||||
eNoLiveAttr,
|
||||
@ -359,6 +388,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"presentation",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -368,6 +398,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"progressbar",
|
||||
nsIAccessibleRole::ROLE_PROGRESSBAR,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -377,6 +408,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"radio",
|
||||
nsIAccessibleRole::ROLE_RADIOBUTTON,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eSelectAction,
|
||||
eNoLiveAttr,
|
||||
@ -387,6 +419,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"radiogroup",
|
||||
nsIAccessibleRole::ROLE_GROUPING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -396,6 +429,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"region",
|
||||
nsIAccessibleRole::ROLE_PANE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -405,6 +439,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"row",
|
||||
nsIAccessibleRole::ROLE_ROW,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -416,6 +451,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"rowheader",
|
||||
nsIAccessibleRole::ROLE_ROWHEADER,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eSortAction,
|
||||
eNoLiveAttr,
|
||||
@ -428,6 +464,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"section",
|
||||
nsIAccessibleRole::ROLE_SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -437,6 +474,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"separator",
|
||||
nsIAccessibleRole::ROLE_SEPARATOR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -446,6 +484,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"slider",
|
||||
nsIAccessibleRole::ROLE_SLIDER,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -456,6 +495,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"spinbutton",
|
||||
nsIAccessibleRole::ROLE_SPINBUTTON,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -466,6 +506,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"status",
|
||||
nsIAccessibleRole::ROLE_STATUSBAR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
ePoliteLiveAttr,
|
||||
@ -475,6 +516,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"tab",
|
||||
nsIAccessibleRole::ROLE_PAGETAB,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eSwitchAction,
|
||||
eNoLiveAttr,
|
||||
@ -484,6 +526,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"tablist",
|
||||
nsIAccessibleRole::ROLE_PAGETABLIST,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
ePoliteLiveAttr,
|
||||
@ -493,6 +536,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"tabpanel",
|
||||
nsIAccessibleRole::ROLE_PROPERTYPAGE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -502,6 +546,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"textbox",
|
||||
nsIAccessibleRole::ROLE_ENTRY,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eActivateAction,
|
||||
eNoLiveAttr,
|
||||
@ -516,6 +561,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"timer",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eOffLiveAttr,
|
||||
@ -525,6 +571,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"toolbar",
|
||||
nsIAccessibleRole::ROLE_TOOLBAR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -534,6 +581,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"tooltip",
|
||||
nsIAccessibleRole::ROLE_TOOLTIP,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -543,6 +591,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"tree",
|
||||
nsIAccessibleRole::ROLE_OUTLINE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -554,6 +603,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"treegrid",
|
||||
nsIAccessibleRole::ROLE_TREE_TABLE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -565,6 +615,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
"treeitem",
|
||||
nsIAccessibleRole::ROLE_OUTLINEITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eActivateAction, // XXX: should expose second 'expand/collapse' action based
|
||||
// on states
|
||||
@ -584,6 +635,7 @@ PRUint32 nsARIAMap::gWAIRoleMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIRoleMap);
|
||||
nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = {
|
||||
"",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
@ -594,6 +646,7 @@ nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = {
|
||||
nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
|
||||
"",
|
||||
nsIAccessibleRole::ROLE_NOTHING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
|
@ -72,6 +72,10 @@ enum ELiveAttrRule
|
||||
ePoliteLiveAttr
|
||||
};
|
||||
|
||||
// Role mapping rule
|
||||
const PRBool kUseMapRole = PR_TRUE;
|
||||
const PRBool kUseNativeRole = PR_FALSE;
|
||||
|
||||
// ARIA attribute characteristic masks, grow as needed
|
||||
|
||||
/**
|
||||
@ -119,6 +123,9 @@ struct nsRoleMapEntry
|
||||
// Role mapping rule: maps to this nsIAccessibleRole
|
||||
PRUint32 role;
|
||||
|
||||
// Role rule: whether to use mapped role or native semantics
|
||||
PRBool roleRule;
|
||||
|
||||
// Value mapping rule: how to compute nsIAccessible value
|
||||
EValueRule valueRule;
|
||||
|
||||
|
@ -41,7 +41,6 @@
|
||||
|
||||
#include "nsIAccessibleStates.h"
|
||||
#include "nsIAccessibleTypes.h"
|
||||
#include "nsPIAccessible.h"
|
||||
|
||||
#include "nsAccessibleEventData.h"
|
||||
#include "nsHyperTextAccessible.h"
|
||||
@ -280,20 +279,23 @@ nsAccUtils::SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerRelevant, relevant);
|
||||
|
||||
// container-live attribute
|
||||
// container-live, and container-live-role attributes
|
||||
if (live.IsEmpty()) {
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(ancestor));
|
||||
nsRoleMapEntry *role = GetRoleMapEntry(node);
|
||||
if (nsAccUtils::HasDefinedARIAToken(ancestor,
|
||||
nsAccessibilityAtoms::aria_live)) {
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live,
|
||||
live);
|
||||
} else if (role) {
|
||||
GetLiveAttrValue(role->liveAttRule, live);
|
||||
}
|
||||
if (!live.IsEmpty()) {
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerLive, live);
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(ancestor));
|
||||
nsRoleMapEntry *role = GetRoleMapEntry(node);
|
||||
if (role) {
|
||||
nsAutoString live;
|
||||
GetLiveAttrValue(role->liveAttRule, live);
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerLive, live);
|
||||
nsAccUtils::SetAccAttr(aAttributes,
|
||||
nsAccessibilityAtoms::containerLiveRole,
|
||||
NS_ConvertASCIItoUTF16(role->roleString));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,14 +342,13 @@ nsAccUtils::FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
{
|
||||
NS_ENSURE_ARG(aAccessible);
|
||||
|
||||
nsCOMPtr<nsPIAccessible> pAccessible(do_QueryInterface(aAccessible));
|
||||
NS_ASSERTION(pAccessible, "Accessible doesn't implement nsPIAccessible");
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(aAccessible));
|
||||
|
||||
nsCOMPtr<nsIAccessibleEvent> event =
|
||||
new nsAccEvent(aEventType, aAccessible, aIsAsynch);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return pAccessible->FireAccessibleEvent(event);
|
||||
return acc->FireAccessibleEvent(event);
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -719,11 +720,21 @@ nsAccUtils::GetLiveAttrValue(PRUint32 aRule, nsAString& aValue)
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccUtils::QueryAccessible(nsIAccessible *aAccessible)
|
||||
{
|
||||
nsAccessible* accessible = nsnull;
|
||||
nsAccessible* acc = nsnull;
|
||||
if (aAccessible)
|
||||
CallQueryInterface(aAccessible, &accessible);
|
||||
|
||||
return accessible;
|
||||
CallQueryInterface(aAccessible, &acc);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccUtils::QueryAccessible(nsIAccessNode *aAccessNode)
|
||||
{
|
||||
nsAccessible* acc = nsnull;
|
||||
if (aAccessNode)
|
||||
CallQueryInterface(aAccessNode, &acc);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
already_AddRefed<nsHTMLTableAccessible>
|
||||
@ -797,10 +808,10 @@ nsAccUtils::TextLength(nsIAccessible *aAccessible)
|
||||
// text. They don't have their own frame.
|
||||
// XXX In the future, list bullets may have frame and anon content, so
|
||||
// we should be able to remove this at that point
|
||||
nsCOMPtr<nsPIAccessible> pAcc(do_QueryInterface(aAccessible));
|
||||
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(aAccessible));
|
||||
|
||||
nsAutoString text;
|
||||
pAcc->AppendTextTo(text, 0, PR_UINT32_MAX); // Get all the text
|
||||
acc->AppendTextTo(text, 0, PR_UINT32_MAX); // Get all the text
|
||||
return text.Length();
|
||||
}
|
||||
|
||||
|
@ -329,6 +329,12 @@ public:
|
||||
static already_AddRefed<nsAccessible>
|
||||
QueryAccessible(nsIAccessible *aAccessible);
|
||||
|
||||
/**
|
||||
* Query nsAccessible from the given nsIAccessNode.
|
||||
*/
|
||||
static already_AddRefed<nsAccessible>
|
||||
QueryAccessible(nsIAccessNode *aAccessNode);
|
||||
|
||||
/**
|
||||
* Query nsHTMLTableAccessible from the given nsIAccessibleTable.
|
||||
*/
|
||||
|
@ -66,7 +66,7 @@
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsRootAccessible.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
@ -776,33 +776,24 @@ already_AddRefed<nsIDOMNode> nsAccessNode::GetCurrentFocus()
|
||||
nsCOMPtr<nsIDocument> doc = shell->GetDocument();
|
||||
NS_ENSURE_TRUE(doc, nsnull);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> privateDOMWindow(do_QueryInterface(doc->GetWindow()));
|
||||
if (!privateDOMWindow) {
|
||||
return nsnull;
|
||||
}
|
||||
nsIFocusController *focusController = privateDOMWindow->GetRootFocusController();
|
||||
if (!focusController) {
|
||||
return nsnull;
|
||||
}
|
||||
nsIDOMWindow* win = doc->GetWindow();
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> focusedWindow;
|
||||
nsCOMPtr<nsIDOMElement> focusedElement;
|
||||
focusController->GetFocusedElement(getter_AddRefs(focusedElement));
|
||||
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
||||
if (fm)
|
||||
fm->GetFocusedElementForWindow(win, PR_TRUE, getter_AddRefs(focusedWindow),
|
||||
getter_AddRefs(focusedElement));
|
||||
|
||||
nsIDOMNode *focusedNode = nsnull;
|
||||
if (!focusedElement) {
|
||||
// Document itself has focus
|
||||
nsCOMPtr<nsIDOMWindowInternal> focusedWinInternal;
|
||||
focusController->GetFocusedWindow(getter_AddRefs(focusedWinInternal));
|
||||
if (!focusedWinInternal) {
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument> focusedDOMDocument;
|
||||
focusedWinInternal->GetDocument(getter_AddRefs(focusedDOMDocument));
|
||||
if (!focusedDOMDocument) {
|
||||
return nsnull;
|
||||
}
|
||||
focusedDOMDocument->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&focusedNode);
|
||||
if (focusedElement) {
|
||||
CallQueryInterface(focusedElement, &focusedNode);
|
||||
}
|
||||
else {
|
||||
focusedElement->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&focusedNode);
|
||||
else if (focusedWindow) {
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
focusedWindow->GetDocument(getter_AddRefs(doc));
|
||||
if (doc)
|
||||
CallQueryInterface(doc, &focusedNode);
|
||||
}
|
||||
|
||||
return focusedNode;
|
||||
|
@ -164,6 +164,7 @@ ACCESSIBILITY_ATOM(_class, "class")
|
||||
ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
|
||||
ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
|
||||
ACCESSIBILITY_ATOM(data, "data")
|
||||
ACCESSIBILITY_ATOM(draggable, "draggable")
|
||||
ACCESSIBILITY_ATOM(droppable, "droppable") // XUL combo box
|
||||
ACCESSIBILITY_ATOM(editable, "editable")
|
||||
ACCESSIBILITY_ATOM(_for, "for")
|
||||
@ -259,6 +260,7 @@ ACCESSIBILITY_ATOM(tableCellIndex, "table-cell-index")
|
||||
ACCESSIBILITY_ATOM(containerAtomic, "container-atomic")
|
||||
ACCESSIBILITY_ATOM(containerBusy, "container-busy")
|
||||
ACCESSIBILITY_ATOM(containerLive, "container-live")
|
||||
ACCESSIBILITY_ATOM(containerLiveRole, "container-live-role")
|
||||
ACCESSIBILITY_ATOM(containerRelevant, "container-relevant")
|
||||
ACCESSIBILITY_ATOM(level, "level")
|
||||
ACCESSIBILITY_ATOM(live, "live")
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsARIAGridAccessible.h"
|
||||
#include "nsARIAGridAccessibleWrap.h"
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsCURILoader.h"
|
||||
@ -458,12 +458,11 @@ nsAccessibilityService::CreateRootAccessible(nsIPresShell *aShell,
|
||||
if (!*aRootAcc)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsRefPtr<nsAccessNode> rootAcc = nsAccUtils::QueryAccessNode(*aRootAcc);
|
||||
nsRefPtr<nsAccessible> rootAcc = nsAccUtils::QueryAccessible(*aRootAcc);
|
||||
rootAcc->Init();
|
||||
|
||||
nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(rootNode);
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible(do_QueryInterface(*aRootAcc));
|
||||
privateAccessible->SetRoleMapEntry(roleMapEntry);
|
||||
rootAcc->SetRoleMapEntry(roleMapEntry);
|
||||
|
||||
NS_ADDREF(*aRootAcc);
|
||||
|
||||
@ -558,6 +557,10 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
|
||||
tag == nsAccessibilityAtoms::q) {
|
||||
return CreateHyperTextAccessible(aFrame, aAccessible);
|
||||
}
|
||||
else if (tag == nsAccessibilityAtoms::tr) {
|
||||
*aAccessible = new nsEnumRoleAccessible(aNode, aWeakShell,
|
||||
nsIAccessibleRole::ROLE_ROW);
|
||||
}
|
||||
else if (nsCoreUtils::IsHTMLTableHeader(content)) {
|
||||
*aAccessible = new nsHTMLTableHeaderAccessible(aNode, aWeakShell);
|
||||
}
|
||||
@ -1262,13 +1265,11 @@ nsresult nsAccessibilityService::InitAccessible(nsIAccessible *aAccessibleIn,
|
||||
}
|
||||
NS_ASSERTION(aAccessibleOut && !*aAccessibleOut, "Out param should already be cleared out");
|
||||
|
||||
nsRefPtr<nsAccessNode> acc = nsAccUtils::QueryAccessNode(aAccessibleIn);
|
||||
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessibleIn);
|
||||
nsresult rv = acc->Init(); // Add to cache, etc.
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible =
|
||||
do_QueryInterface(aAccessibleIn);
|
||||
privateAccessible->SetRoleMapEntry(aRoleMapEntry);
|
||||
acc->SetRoleMapEntry(aRoleMapEntry);
|
||||
NS_ADDREF(*aAccessibleOut = aAccessibleIn);
|
||||
|
||||
return NS_OK;
|
||||
@ -1550,16 +1551,21 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
||||
tryTagNameOrFrame = PR_FALSE;
|
||||
}
|
||||
|
||||
if (roleMapEntry && (!partOfHTMLTable || !tryTagNameOrFrame ||
|
||||
frameType != nsAccessibilityAtoms::tableOuterFrame)) {
|
||||
// Try to create ARIA grid/treegrid accessibles.
|
||||
if (roleMapEntry->role == nsIAccessibleRole::ROLE_TABLE ||
|
||||
roleMapEntry->role == nsIAccessibleRole::ROLE_TREE_TABLE) {
|
||||
newAcc = new nsARIAGridAccessible(aNode, aWeakShell);
|
||||
} else if (roleMapEntry->role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
roleMapEntry->role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
roleMapEntry->role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
|
||||
newAcc = new nsARIAGridCellAccessible(aNode, aWeakShell);
|
||||
if (roleMapEntry) {
|
||||
// Create ARIA grid/treegrid accessibles if node is not of a child or
|
||||
// valid child of HTML table and is not a HTML table.
|
||||
if ((!partOfHTMLTable || !tryTagNameOrFrame) &&
|
||||
frameType != nsAccessibilityAtoms::tableOuterFrame) {
|
||||
|
||||
if (roleMapEntry->role == nsIAccessibleRole::ROLE_TABLE ||
|
||||
roleMapEntry->role == nsIAccessibleRole::ROLE_TREE_TABLE) {
|
||||
newAcc = new nsARIAGridAccessibleWrap(aNode, aWeakShell);
|
||||
|
||||
} else if (roleMapEntry->role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
roleMapEntry->role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
roleMapEntry->role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
|
||||
newAcc = new nsARIAGridCellAccessible(aNode, aWeakShell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1715,10 +1721,9 @@ nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
|
||||
rv = GetAccessibleByType(bindingNode, getter_AddRefs(accessible));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsPIAccessible> paccessible(do_QueryInterface(accessible));
|
||||
if (paccessible) {
|
||||
PRBool allowsAnonChildren = PR_FALSE;
|
||||
paccessible->GetAllowsAnonChildAccessibles(&allowsAnonChildren);
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(accessible));
|
||||
if (acc) {
|
||||
PRBool allowsAnonChildren = acc->GetAllowsAnonChildAccessibles();
|
||||
if (!allowsAnonChildren) {
|
||||
NS_ADDREF(*aRelevantNode = bindingNode);
|
||||
return NS_OK;
|
||||
|
@ -74,6 +74,7 @@
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
@ -179,12 +180,6 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if(aIID.Equals(NS_GET_IID(nsPIAccessible))) {
|
||||
*aInstancePtr = static_cast<nsPIAccessible*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsAccessible))) {
|
||||
*aInstancePtr = static_cast<nsAccessible*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
@ -266,10 +261,10 @@ nsAccessible::~nsAccessible()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
void
|
||||
nsAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
{
|
||||
mRoleMapEntry = aRoleMapEntry;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -488,34 +483,32 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::SetParent(nsIAccessible *aParent)
|
||||
void
|
||||
nsAccessible::SetParent(nsIAccessible *aParent)
|
||||
{
|
||||
if (mParent != aParent) {
|
||||
// Adopt a child -- we allow this now. the new parent
|
||||
// may be a dom node which wasn't previously accessible but now is.
|
||||
// The old parent's children now need to be invalidated, since
|
||||
// it no longer owns the child, the new parent does
|
||||
nsCOMPtr<nsPIAccessible> privOldParent = do_QueryInterface(mParent);
|
||||
if (privOldParent) {
|
||||
privOldParent->InvalidateChildren();
|
||||
}
|
||||
nsRefPtr<nsAccessible> oldParent = nsAccUtils::QueryAccessible(mParent);
|
||||
if (oldParent)
|
||||
oldParent->InvalidateChildren();
|
||||
}
|
||||
|
||||
mParent = aParent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::SetFirstChild(nsIAccessible *aFirstChild)
|
||||
void
|
||||
nsAccessible::SetFirstChild(nsIAccessible *aFirstChild)
|
||||
{
|
||||
mFirstChild = aFirstChild;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::SetNextSibling(nsIAccessible *aNextSibling)
|
||||
void
|
||||
nsAccessible::SetNextSibling(nsIAccessible *aNextSibling)
|
||||
{
|
||||
mNextSibling = aNextSibling;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -527,15 +520,16 @@ nsAccessible::Shutdown()
|
||||
// sure none of its children point to this parent
|
||||
InvalidateChildren();
|
||||
if (mParent) {
|
||||
nsCOMPtr<nsPIAccessible> privateParent(do_QueryInterface(mParent));
|
||||
privateParent->InvalidateChildren();
|
||||
nsRefPtr<nsAccessible> parent(nsAccUtils::QueryAccessible(mParent));
|
||||
parent->InvalidateChildren();
|
||||
mParent = nsnull;
|
||||
}
|
||||
|
||||
return nsAccessNodeWrap::Shutdown();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::InvalidateChildren()
|
||||
void
|
||||
nsAccessible::InvalidateChildren()
|
||||
{
|
||||
// Document has transformed, reset our invalid children and child count
|
||||
|
||||
@ -543,25 +537,29 @@ NS_IMETHODIMP nsAccessible::InvalidateChildren()
|
||||
// CacheChildren() is called.
|
||||
// Note: we don't want to start creating accessibles at this point,
|
||||
// so don't use GetNextSibling() here. (bug 387252)
|
||||
nsAccessible* child = static_cast<nsAccessible*>(mFirstChild.get());
|
||||
nsRefPtr<nsAccessible> child = nsAccUtils::QueryAccessible(mFirstChild);
|
||||
while (child) {
|
||||
child->mParent = nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessible> next = child->mNextSibling;
|
||||
child->mNextSibling = nsnull;
|
||||
child = static_cast<nsAccessible*>(next.get());
|
||||
child = nsAccUtils::QueryAccessible(next);
|
||||
}
|
||||
|
||||
mAccChildCount = eChildCountUninitialized;
|
||||
mFirstChild = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::GetParent(nsIAccessible ** aParent)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetParent(nsIAccessible **aParent)
|
||||
{
|
||||
nsresult rv = GetCachedParent(aParent);
|
||||
if (NS_FAILED(rv) || *aParent) {
|
||||
return rv;
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAccessible> cachedParent = GetCachedParent();
|
||||
if (cachedParent) {
|
||||
cachedParent.swap(*aParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
|
||||
@ -570,26 +568,24 @@ NS_IMETHODIMP nsAccessible::GetParent(nsIAccessible ** aParent)
|
||||
return docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE, aParent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::GetCachedParent(nsIAccessible ** aParent)
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsAccessible::GetCachedParent()
|
||||
{
|
||||
*aParent = nsnull;
|
||||
if (!mWeakShell) {
|
||||
// This node has been shut down
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
NS_IF_ADDREF(*aParent = mParent);
|
||||
return NS_OK;
|
||||
if (IsDefunct())
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessible> cachedParent = mParent;
|
||||
return cachedParent.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::GetCachedFirstChild(nsIAccessible ** aFirstChild)
|
||||
already_AddRefed<nsIAccessible>
|
||||
nsAccessible::GetCachedFirstChild()
|
||||
{
|
||||
*aFirstChild = nsnull;
|
||||
if (!mWeakShell) {
|
||||
// This node has been shut down
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
NS_IF_ADDREF(*aFirstChild = mFirstChild);
|
||||
return NS_OK;
|
||||
if (IsDefunct())
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessible> cachedFirstChild = mFirstChild;
|
||||
return cachedFirstChild.forget();
|
||||
}
|
||||
|
||||
/* readonly attribute nsIAccessible nextSibling; */
|
||||
@ -659,10 +655,9 @@ NS_IMETHODIMP nsAccessible::GetFirstChild(nsIAccessible * *aFirstChild)
|
||||
GetChildCount(&numChildren); // Make sure we cache all of the children
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsPIAccessible> firstChild(do_QueryInterface(mFirstChild));
|
||||
nsRefPtr<nsAccessible> firstChild(nsAccUtils::QueryAccessible(mFirstChild));
|
||||
if (firstChild) {
|
||||
nsCOMPtr<nsIAccessible> realParent;
|
||||
firstChild->GetCachedParent(getter_AddRefs(realParent));
|
||||
nsCOMPtr<nsIAccessible> realParent = firstChild->GetCachedParent();
|
||||
NS_ASSERTION(!realParent || realParent == this,
|
||||
"Two accessibles have the same first child accessible.");
|
||||
}
|
||||
@ -751,34 +746,33 @@ void nsAccessible::CacheChildren()
|
||||
|
||||
if (mAccChildCount == eChildCountUninitialized) {
|
||||
mAccChildCount = 0;// Prevent reentry
|
||||
PRBool allowsAnonChildren = PR_FALSE;
|
||||
GetAllowsAnonChildAccessibles(&allowsAnonChildren);
|
||||
PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles();
|
||||
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren);
|
||||
// Seed the frame hint early while we're still on a container node.
|
||||
// This is better than doing the GetPrimaryFrameFor() later on
|
||||
// a text node, because text nodes aren't in the frame map.
|
||||
walker.mState.frame = GetFrame();
|
||||
|
||||
nsCOMPtr<nsPIAccessible> privatePrevAccessible;
|
||||
nsRefPtr<nsAccessible> prevAcc;
|
||||
PRInt32 childCount = 0;
|
||||
walker.GetFirstChild();
|
||||
SetFirstChild(walker.mState.accessible);
|
||||
|
||||
while (walker.mState.accessible) {
|
||||
++ childCount;
|
||||
privatePrevAccessible = do_QueryInterface(walker.mState.accessible);
|
||||
privatePrevAccessible->SetParent(this);
|
||||
prevAcc = nsAccUtils::QueryAccessible(walker.mState.accessible);
|
||||
prevAcc->SetParent(this);
|
||||
walker.GetNextSibling();
|
||||
privatePrevAccessible->SetNextSibling(walker.mState.accessible);
|
||||
prevAcc->SetNextSibling(walker.mState.accessible);
|
||||
}
|
||||
mAccChildCount = childCount;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
*aAllowsAnonChildren = PR_TRUE;
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* readonly attribute long childCount; */
|
||||
@ -825,30 +819,29 @@ NS_IMETHODIMP nsAccessible::GetIndexInParent(PRInt32 *aIndexInParent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::TestChildCache(nsIAccessible *aCachedChild)
|
||||
void
|
||||
nsAccessible::TestChildCache(nsIAccessible *aCachedChild)
|
||||
{
|
||||
#ifndef DEBUG_A11Y
|
||||
return NS_OK;
|
||||
#else
|
||||
#ifdef DEBUG_A11Y
|
||||
// All cached accessible nodes should be in the parent
|
||||
// It will assert if not all the children were created
|
||||
// when they were first cached, and no invalidation
|
||||
// ever corrected parent accessible's child cache.
|
||||
if (mAccChildCount <= 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (mAccChildCount <= 0)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIAccessible> sibling = mFirstChild;
|
||||
|
||||
while (sibling != aCachedChild) {
|
||||
NS_ASSERTION(sibling, "[TestChildCache] Never ran into the same child that we started from");
|
||||
if (!sibling)
|
||||
return NS_ERROR_FAILURE;
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIAccessible> tempAccessible;
|
||||
sibling->GetNextSibling(getter_AddRefs(tempAccessible));
|
||||
sibling = tempAccessible;
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1469,14 +1462,11 @@ nsAccessible::TakeFocus()
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNSHTMLElement> htmlElement(do_QueryInterface(content));
|
||||
if (htmlElement) {
|
||||
// HTML Elements also set the caret position
|
||||
// in order to affect tabbing order
|
||||
return htmlElement->Focus();
|
||||
}
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(content));
|
||||
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
||||
if (fm)
|
||||
fm->SetFocus(element, 0);
|
||||
|
||||
content->SetFocus(GetPresContext());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1591,7 +1581,7 @@ nsAccessible::GetXULName(nsAString& aLabel)
|
||||
return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsAccessible::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEvent);
|
||||
@ -1610,8 +1600,12 @@ NS_IMETHODIMP
|
||||
nsAccessible::GetRole(PRUint32 *aRole)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRole);
|
||||
|
||||
*aRole = nsIAccessibleRole::ROLE_NOTHING;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (mRoleMapEntry) {
|
||||
*aRole = mRoleMapEntry->role;
|
||||
|
||||
@ -1653,21 +1647,12 @@ nsAccessible::GetRole(PRUint32 *aRole)
|
||||
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_OPTION;
|
||||
}
|
||||
|
||||
// gLandmarkRoleMap: can use role of accessible class impl
|
||||
// gEmptyRoleMap and all others: cannot use role of accessible class impl
|
||||
if (mRoleMapEntry != &nsARIAMap::gLandmarkRoleMap) {
|
||||
// We can now expose ROLE_NOTHING when there is a role map entry or used
|
||||
// role is nothing, which
|
||||
// will cause ATK to use ROLE_UNKNOWN and MSAA to use a BSTR role with
|
||||
// the ARIA role or element's tag. In either case the AT can also use
|
||||
// the object attributes tag and xml-roles to find out more.
|
||||
// We are done if the mapped role trumps native semantics
|
||||
if (mRoleMapEntry->roleRule == kUseMapRole)
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return mDOMNode ?
|
||||
GetRoleInternal(aRole) :
|
||||
NS_ERROR_FAILURE; // Node already shut down
|
||||
return GetRoleInternal(aRole);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1852,6 +1837,17 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::textIndent,
|
||||
value);
|
||||
|
||||
// Expose draggable object attribute?
|
||||
nsCOMPtr<nsIDOMNSHTMLElement> htmlElement = do_QueryInterface(content);
|
||||
if (htmlElement) {
|
||||
PRBool draggable = PR_FALSE;
|
||||
htmlElement->GetDraggable(&draggable);
|
||||
if (draggable) {
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::draggable,
|
||||
NS_LITERAL_STRING("true"));
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1939,6 +1935,14 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
|
||||
if (!IsDefunct()) {
|
||||
// Flush layout so that all the frame construction, reflow, and styles are
|
||||
// up-to-date since we rely on frames, and styles when calculating state.
|
||||
// We don't flush the display because we don't care about painting.
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
presShell->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsresult rv = GetStateInternal(aState, aExtraState);
|
||||
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
||||
|
||||
@ -3111,7 +3115,7 @@ nsresult nsAccessible::GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength)
|
||||
{
|
||||
return NS_OK;
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "nsTextEquivUtils.h"
|
||||
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsPIAccessible.h"
|
||||
#include "nsIAccessibleHyperLink.h"
|
||||
#include "nsIAccessibleSelectable.h"
|
||||
#include "nsIAccessibleValue.h"
|
||||
@ -104,16 +103,15 @@ private:
|
||||
|
||||
|
||||
#define NS_ACCESSIBLE_IMPL_CID \
|
||||
{ /* 16917f1e-6cee-4cde-be3f-8bb5943f506c */ \
|
||||
0x16917f1e, \
|
||||
0x6cee, \
|
||||
0x4cde, \
|
||||
{ 0xbe, 0x3f, 0x8b, 0xb5, 0x94, 0x3F, 0x50, 0x6c } \
|
||||
{ /* 53cfa871-be42-47fc-b416-0033653b3151 */ \
|
||||
0x53cfa871, \
|
||||
0xbe42, \
|
||||
0x47fc, \
|
||||
{ 0xb4, 0x16, 0x00, 0x33, 0x65, 0x3b, 0x31, 0x51 } \
|
||||
}
|
||||
|
||||
class nsAccessible : public nsAccessNodeWrap,
|
||||
public nsIAccessible,
|
||||
public nsPIAccessible,
|
||||
public nsIAccessibleHyperLink,
|
||||
public nsIAccessibleSelectable,
|
||||
public nsIAccessibleValue
|
||||
@ -126,7 +124,6 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsAccessible, nsAccessNode)
|
||||
|
||||
NS_DECL_NSIACCESSIBLE
|
||||
NS_DECL_NSPIACCESSIBLE
|
||||
NS_DECL_NSIACCESSIBLEHYPERLINK
|
||||
NS_DECL_NSIACCESSIBLESELECTABLE
|
||||
NS_DECL_NSIACCESSIBLEVALUE
|
||||
@ -145,6 +142,15 @@ public:
|
||||
*/
|
||||
nsresult GetARIAName(nsAString& aName);
|
||||
|
||||
/**
|
||||
* Maps ARIA state attributes to state of accessible. Note the given state
|
||||
* argument should hold states for accessible before you pass it into this
|
||||
* method.
|
||||
*
|
||||
* @param [in/out] where to fill the states into.
|
||||
*/
|
||||
virtual nsresult GetARIAState(PRUint32 *aState);
|
||||
|
||||
/**
|
||||
* Returns the accessible name provided by native markup. It doesn't take
|
||||
* into account ARIA markup used to specify the name.
|
||||
@ -191,6 +197,78 @@ public:
|
||||
PRBool aDeepestChild,
|
||||
nsIAccessible **aChild);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Initializing and cache methods
|
||||
|
||||
/**
|
||||
* Set accessible parent.
|
||||
* XXX: shouldn't be virtual, bug 496783
|
||||
*/
|
||||
virtual void SetParent(nsIAccessible *aParent);
|
||||
|
||||
/**
|
||||
* Set first accessible child.
|
||||
*/
|
||||
void SetFirstChild(nsIAccessible *aFirstChild);
|
||||
|
||||
/**
|
||||
* Set next sibling accessible.
|
||||
*/
|
||||
void SetNextSibling(nsIAccessible *aNextSibling);
|
||||
|
||||
/**
|
||||
* Set the ARIA role map entry for a new accessible.
|
||||
* For a newly created accessible, specify which role map entry should be used.
|
||||
*
|
||||
* @param aRoleMapEntry The ARIA nsRoleMapEntry* for the accessible, or
|
||||
* nsnull if none.
|
||||
*/
|
||||
virtual void SetRoleMapEntry(nsRoleMapEntry *aRoleMapEntry);
|
||||
|
||||
/**
|
||||
* Set the child count to -1 (unknown) and null out cached child pointers
|
||||
*/
|
||||
virtual void InvalidateChildren();
|
||||
|
||||
/**
|
||||
* Return parent accessible only if cached.
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetCachedParent();
|
||||
|
||||
/**
|
||||
* Return first child accessible only if cached.
|
||||
*/
|
||||
already_AddRefed<nsIAccessible> GetCachedFirstChild();
|
||||
|
||||
/**
|
||||
* Assert if child not in parent's cache.
|
||||
*/
|
||||
void TestChildCache(nsIAccessible *aCachedChild);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Miscellaneous methods.
|
||||
|
||||
/**
|
||||
* Fire accessible event.
|
||||
*/
|
||||
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aAccEvent);
|
||||
|
||||
/**
|
||||
* Return true if there are accessible children in anonymous content
|
||||
*/
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
||||
/**
|
||||
* Returns text of accessible if accessible has text role otherwise empty
|
||||
* string.
|
||||
*
|
||||
* @param aText returned text of the accessible
|
||||
* @param aStartOffset start offset inside of the accesible
|
||||
* @param aLength required lenght of text
|
||||
*/
|
||||
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Helper methods
|
||||
|
||||
|
@ -76,15 +76,19 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
|
||||
// nsAccEvent. Constructors
|
||||
|
||||
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
PRBool aIsAsynch, EEventRule aEventRule):
|
||||
mEventType(aEventType), mAccessible(aAccessible), mEventRule(aEventRule)
|
||||
PRBool aIsAsynch, EEventRule aEventRule)
|
||||
: mEventType(aEventType)
|
||||
, mEventRule(aEventRule)
|
||||
, mAccessible(aAccessible)
|
||||
{
|
||||
CaptureIsFromUserInput(aIsAsynch);
|
||||
}
|
||||
|
||||
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
|
||||
PRBool aIsAsynch, EEventRule aEventRule):
|
||||
mEventType(aEventType), mDOMNode(aDOMNode), mEventRule(aEventRule)
|
||||
PRBool aIsAsynch, EEventRule aEventRule)
|
||||
: mEventType(aEventType)
|
||||
, mEventRule(aEventRule)
|
||||
, mDOMNode(aDOMNode)
|
||||
{
|
||||
CaptureIsFromUserInput(aIsAsynch);
|
||||
}
|
||||
|
@ -236,20 +236,21 @@ nsApplicationAccessible::CacheChildren()
|
||||
|
||||
nsCOMPtr<nsIWeakReference> childWeakRef;
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
nsCOMPtr<nsPIAccessible> previousAccessible;
|
||||
nsRefPtr<nsAccessible> prevAcc;
|
||||
PRBool hasMoreElements;
|
||||
while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements))
|
||||
&& hasMoreElements) {
|
||||
|
||||
while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) &&
|
||||
hasMoreElements) {
|
||||
enumerator->GetNext(getter_AddRefs(childWeakRef));
|
||||
accessible = do_QueryReferent(childWeakRef);
|
||||
if (accessible) {
|
||||
if (previousAccessible)
|
||||
previousAccessible->SetNextSibling(accessible);
|
||||
if (prevAcc)
|
||||
prevAcc->SetNextSibling(accessible);
|
||||
else
|
||||
SetFirstChild(accessible);
|
||||
|
||||
previousAccessible = do_QueryInterface(accessible);
|
||||
previousAccessible->SetParent(this);
|
||||
prevAcc = nsAccUtils::QueryAccessible(accessible);
|
||||
prevAcc->SetParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,12 +86,11 @@ NS_IMETHODIMP nsLeafAccessible::GetChildCount(PRInt32 *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute boolean allowsAnonChildAccessibles; */
|
||||
NS_IMETHODIMP
|
||||
nsLeafAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
// nsAccessible::GetAllowsAnonChildAccessibles()
|
||||
PRBool
|
||||
nsLeafAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
*aAllowsAnonChildren = PR_FALSE;
|
||||
return NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// nsAccessible::GetChildAtPoint()
|
||||
|
@ -67,13 +67,11 @@ public:
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
PRBool aDeepestChild,
|
||||
nsIAccessible **aChild);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -78,8 +78,8 @@ PRBool
|
||||
nsCoreUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
|
||||
{
|
||||
NS_ENSURE_TRUE(aContent, PR_FALSE);
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
aContent->GetListenerManager(PR_FALSE, getter_AddRefs(listenerManager));
|
||||
nsIEventListenerManager* listenerManager =
|
||||
aContent->GetListenerManager(PR_FALSE);
|
||||
|
||||
return listenerManager && listenerManager->HasListenersFor(aEventType);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsFocusManager.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIXULDocument.h"
|
||||
#endif
|
||||
@ -236,15 +236,21 @@ nsDocAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
void
|
||||
nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
{
|
||||
NS_ENSURE_STATE(mDocument);
|
||||
NS_ASSERTION(mDocument, "No document during initialization!");
|
||||
if (!mDocument)
|
||||
return;
|
||||
|
||||
mRoleMapEntry = aRoleMapEntry;
|
||||
|
||||
// Allow use of ARIA role from outer to override
|
||||
nsIDocument *parentDoc = mDocument->GetParentDocument();
|
||||
NS_ENSURE_TRUE(parentDoc, NS_ERROR_FAILURE);
|
||||
NS_ASSERTION(parentDoc, "No parent document during initialization!");
|
||||
if (!parentDoc)
|
||||
return;
|
||||
|
||||
nsIContent *ownerContent = parentDoc->FindContentForSubDocument(mDocument);
|
||||
nsCOMPtr<nsIDOMNode> ownerNode(do_QueryInterface(ownerContent));
|
||||
if (ownerNode) {
|
||||
@ -252,8 +258,6 @@ NS_IMETHODIMP nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
if (roleMapEntry)
|
||||
mRoleMapEntry = roleMapEntry; // Override
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -323,7 +327,7 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsDocAccessible::GetARIAState(PRUint32 *aState)
|
||||
{
|
||||
// Combine with states from outer doc
|
||||
@ -331,9 +335,9 @@ nsDocAccessible::GetARIAState(PRUint32 *aState)
|
||||
nsresult rv = nsAccessible::GetARIAState(aState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsPIAccessible> privateParentAccessible = do_QueryInterface(mParent);
|
||||
if (privateParentAccessible) // Allow iframe/frame etc. to have final state override via ARIA
|
||||
return privateParentAccessible->GetARIAState(aState);
|
||||
nsRefPtr<nsAccessible> parent = nsAccUtils::QueryAccessible(mParent);
|
||||
if (parent) // Allow iframe/frame etc. to have final state override via ARIA
|
||||
return parent->GetARIAState(aState);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -350,6 +354,7 @@ nsDocAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetFocusedChild(nsIAccessible **aFocusedChild)
|
||||
{
|
||||
// XXXndeakin P3 accessibility shouldn't be caching the focus
|
||||
if (!gLastFocusedNode) {
|
||||
*aFocusedChild = nsnull;
|
||||
return NS_OK;
|
||||
@ -371,25 +376,20 @@ NS_IMETHODIMP nsDocAccessible::TakeFocus()
|
||||
return NS_ERROR_FAILURE; // Not focusable
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(treeItem);
|
||||
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell(GetPresShell());
|
||||
if (!shell) {
|
||||
NS_WARNING("Was not shutdown properly via InvalidateCacheSubtree()");
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
||||
if (fm) {
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
mDOMNode->GetOwnerDocument(getter_AddRefs(domDocument));
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
|
||||
if (document) {
|
||||
// focus the document
|
||||
nsCOMPtr<nsIDOMElement> newFocus;
|
||||
return fm->MoveFocus(document->GetWindow(), nsnull,
|
||||
nsIFocusManager::MOVEFOCUS_ROOT, 0,
|
||||
getter_AddRefs(newFocus));
|
||||
}
|
||||
}
|
||||
nsIEventStateManager *esm = shell->GetPresContext()->EventStateManager();
|
||||
NS_ENSURE_TRUE(esm, NS_ERROR_FAILURE);
|
||||
|
||||
// Focus the document
|
||||
nsresult rv = docShell->SetHasFocus(PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Clear out any existing focus state
|
||||
return esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// ------- nsIAccessibleDocument Methods (5) ---------------
|
||||
@ -542,14 +542,12 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod
|
||||
// when they were first cached, and no invalidation
|
||||
// ever corrected parent accessible's child cache.
|
||||
nsCOMPtr<nsIAccessible> accessible = do_QueryInterface(*aAccessNode);
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible = do_QueryInterface(accessible);
|
||||
if (privateAccessible) {
|
||||
nsCOMPtr<nsIAccessible> parent;
|
||||
privateAccessible->GetCachedParent(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsPIAccessible> privateParent(do_QueryInterface(parent));
|
||||
if (privateParent) {
|
||||
privateParent->TestChildCache(accessible);
|
||||
}
|
||||
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(accessible);
|
||||
if (acc) {
|
||||
nsCOMPtr<nsIAccessible> parent = acc->GetCachedParent();
|
||||
nsRefPtr<nsAccessible> parentAcc(nsAccUtils::QueryAccessible(parent));
|
||||
if (parentAcc)
|
||||
parentAcc->TestChildCache(accessible);
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
@ -889,11 +887,12 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
||||
// Need to wait until scrollable view is available
|
||||
AddScrollListener();
|
||||
nsCOMPtr<nsIAccessible> parent(nsAccessible::GetParent());
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible(do_QueryInterface(parent));
|
||||
if (privateAccessible) {
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(parent));
|
||||
if (acc) {
|
||||
// Make the parent forget about the old document as a child
|
||||
privateAccessible->InvalidateChildren();
|
||||
acc->InvalidateChildren();
|
||||
}
|
||||
|
||||
if (sameTypeRoot != treeItem) {
|
||||
// Fire show/hide events to indicate frame/iframe content is new, rather than
|
||||
// doc load event which causes screen readers to act is if entire page is reloaded
|
||||
@ -1289,9 +1288,16 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
|
||||
return;
|
||||
}
|
||||
|
||||
if (aAttribute == nsAccessibilityAtoms::aria_valuenow) {
|
||||
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
|
||||
targetNode);
|
||||
// Fire value change event whenever aria-valuetext is changed, or
|
||||
// when aria-valuenow is changed and aria-valuetext is empty
|
||||
if (aAttribute == nsAccessibilityAtoms::aria_valuetext ||
|
||||
(aAttribute == nsAccessibilityAtoms::aria_valuenow &&
|
||||
(!aContent->HasAttr(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_valuetext) ||
|
||||
aContent->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_valuetext, nsAccessibilityAtoms::_empty,
|
||||
eCaseMatters)))) {
|
||||
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, targetNode);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1578,8 +1584,17 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
if (!presShell)
|
||||
length = 0; // The doc is now shut down, don't fire events in it anymore
|
||||
else
|
||||
else {
|
||||
// Flush layout so that all the frame construction, reflow, and styles are
|
||||
// up-to-date. This will ensure we can get frames for the related nodes, as
|
||||
// well as get the most current information for calculating things like
|
||||
// visibility. We don't flush the display because we don't care about
|
||||
// painting. If no flush is necessary the method will simple return.
|
||||
presShell->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
// filter events
|
||||
nsAccEvent::ApplyEventRules(mEventsToFire);
|
||||
}
|
||||
|
||||
for (PRUint32 index = 0; index < length; index ++) {
|
||||
nsCOMPtr<nsIAccessibleEvent> accessibleEvent(
|
||||
@ -1635,10 +1650,10 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
|
||||
|
||||
if (eventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW) {
|
||||
// For asynch show, delayed invalidatation of parent's children
|
||||
nsCOMPtr<nsPIAccessible> privateContainerAccessible =
|
||||
do_QueryInterface(containerAccessible);
|
||||
if (privateContainerAccessible)
|
||||
privateContainerAccessible->InvalidateChildren();
|
||||
nsRefPtr<nsAccessible> containerAcc =
|
||||
nsAccUtils::QueryAccessible(containerAccessible);
|
||||
if (containerAcc)
|
||||
containerAcc->InvalidateChildren();
|
||||
|
||||
// Some show events in the subtree may have been removed to
|
||||
// avoid firing redundant events. But, we still need to make sure any
|
||||
@ -1762,9 +1777,9 @@ void nsDocAccessible::InvalidateChildrenInSubtree(nsIDOMNode *aStartNode)
|
||||
{
|
||||
nsCOMPtr<nsIAccessNode> accessNode;
|
||||
GetCachedAccessNode(aStartNode, getter_AddRefs(accessNode));
|
||||
nsCOMPtr<nsPIAccessible> accessible(do_QueryInterface(accessNode));
|
||||
if (accessible)
|
||||
accessible->InvalidateChildren();
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(accessNode));
|
||||
if (acc)
|
||||
acc->InvalidateChildren();
|
||||
|
||||
// Invalidate accessible children in the DOM subtree
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aStartNode);
|
||||
@ -1802,12 +1817,11 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
|
||||
accessible);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible = do_QueryInterface(accessible);
|
||||
NS_ASSERTION(privateAccessible, "No nsPIAccessible for nsIAccessible");
|
||||
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(accessible);
|
||||
|
||||
nsCOMPtr<nsIAccessible> childAccessible;
|
||||
// we only need to shutdown the accessibles here if one of them has been created
|
||||
privateAccessible->GetCachedFirstChild(getter_AddRefs(childAccessible));
|
||||
// We only need to shutdown the accessibles here if one of them has been
|
||||
// created.
|
||||
nsCOMPtr<nsIAccessible> childAccessible = acc->GetCachedFirstChild();
|
||||
if (childAccessible) {
|
||||
nsCOMPtr<nsIArray> children;
|
||||
// use GetChildren() to fetch children at one time, instead of using
|
||||
@ -1910,7 +1924,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
||||
// document and listen to these changes until after the page is first loaded
|
||||
// Leave early, and ensure mAccChildCount stays uninitialized instead of 0,
|
||||
// which it is if anyone asks for its children right now.
|
||||
return InvalidateChildren();
|
||||
InvalidateChildren();
|
||||
return NS_OK;
|
||||
}
|
||||
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
|
||||
NS_ENSURE_TRUE(esm, NS_ERROR_FAILURE);
|
||||
@ -1923,8 +1938,11 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
||||
if (!containerAccessible) {
|
||||
containerAccessible = this;
|
||||
}
|
||||
nsCOMPtr<nsPIAccessible> privateContainer = do_QueryInterface(containerAccessible);
|
||||
return privateContainer->InvalidateChildren();
|
||||
|
||||
nsRefPtr<nsAccessible> containerAcc =
|
||||
nsAccUtils::QueryAccessible(containerAccessible);
|
||||
containerAcc->InvalidateChildren();
|
||||
return NS_OK;
|
||||
}
|
||||
// else: user input, so we must fall through and for full handling,
|
||||
// e.g. fire the mutation events. Note: user input could cause DOM_CREATE
|
||||
@ -2019,11 +2037,11 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
||||
if (!isAsynch) {
|
||||
// DOM already updated with new objects -- invalidate parent's children now
|
||||
// For asynch we must wait until layout updates before we invalidate the children
|
||||
nsCOMPtr<nsPIAccessible> privateContainerAccessible =
|
||||
do_QueryInterface(containerAccessible);
|
||||
if (privateContainerAccessible) {
|
||||
privateContainerAccessible->InvalidateChildren();
|
||||
}
|
||||
nsRefPtr<nsAccessible> containerAcc =
|
||||
nsAccUtils::QueryAccessible(containerAccessible);
|
||||
if (containerAcc)
|
||||
containerAcc->InvalidateChildren();
|
||||
|
||||
}
|
||||
// Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content.
|
||||
// Fire after a short timer, because we want to make sure the view has been
|
||||
|
@ -76,10 +76,8 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
||||
virtual ~nsDocAccessible();
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
NS_IMETHOD GetARIAState(PRUint32 *aState);
|
||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParent);
|
||||
@ -103,6 +101,8 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetARIAState(PRUint32 *aState);
|
||||
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
|
||||
// nsIAccessibleText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
|
@ -137,17 +137,15 @@ void nsOuterDocAccessible::CacheChildren()
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService("@mozilla.org/accessibilityService;1");
|
||||
accService->GetAccessibleFor(innerNode, getter_AddRefs(innerAccessible));
|
||||
nsCOMPtr<nsPIAccessible> privateInnerAccessible =
|
||||
do_QueryInterface(innerAccessible);
|
||||
if (!privateInnerAccessible) {
|
||||
nsRefPtr<nsAccessible> innerAcc(nsAccUtils::QueryAccessible(innerAccessible));
|
||||
if (!innerAcc)
|
||||
return;
|
||||
}
|
||||
|
||||
// Success getting inner document as first child -- now we cache it.
|
||||
mAccChildCount = 1;
|
||||
SetFirstChild(innerAccessible); // weak ref
|
||||
privateInnerAccessible->SetParent(this);
|
||||
privateInnerAccessible->SetNextSibling(nsnull);
|
||||
innerAcc->SetParent(this);
|
||||
innerAcc->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -60,7 +60,6 @@
|
||||
#include "nsIDOMXULPopupElement.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIMenuFrame.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
@ -75,6 +74,7 @@
|
||||
#include "nsRootAccessible.h"
|
||||
#include "nsIDOMNSEventTarget.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULTreeAccessible.h"
|
||||
@ -234,16 +234,18 @@ nsRootAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> domWin;
|
||||
GetWindow(getter_AddRefs(domWin));
|
||||
nsCOMPtr<nsPIDOMWindow> privateDOMWindow(do_QueryInterface(domWin));
|
||||
if (privateDOMWindow) {
|
||||
nsIFocusController *focusController =
|
||||
privateDOMWindow->GetRootFocusController();
|
||||
if (focusController) {
|
||||
PRBool isActive = PR_FALSE;
|
||||
focusController->GetActive(&isActive);
|
||||
if (isActive) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> dsti = do_GetInterface(domWin);
|
||||
if (dsti) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
dsti->GetRootTreeItem(getter_AddRefs(root));
|
||||
nsCOMPtr<nsIDOMWindow> rootWindow = do_GetInterface(root);
|
||||
|
||||
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
||||
if (fm && rootWindow) {
|
||||
nsCOMPtr<nsIDOMWindow> activeWindow;
|
||||
fm->GetActiveWindow(getter_AddRefs(activeWindow));
|
||||
if (activeWindow == rootWindow)
|
||||
*aExtraState |= nsIAccessibleStates::EXT_STATE_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef MOZ_XUL
|
||||
@ -661,8 +663,8 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
||||
if (eventType.EqualsLiteral("popuphiding"))
|
||||
return HandlePopupHidingEvent(aTargetNode, accessible);
|
||||
|
||||
nsCOMPtr<nsPIAccessible> privAcc(do_QueryInterface(accessible));
|
||||
if (!privAcc)
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(accessible));
|
||||
if (!acc)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
@ -697,7 +699,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
||||
nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
|
||||
new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_CHECKED,
|
||||
PR_FALSE, isEnabled);
|
||||
privAcc->FireAccessibleEvent(accEvent);
|
||||
acc->FireAccessibleEvent(accEvent);
|
||||
|
||||
if (isEnabled)
|
||||
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
|
||||
@ -715,7 +717,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
||||
nsIAccessibleStates::STATE_CHECKED,
|
||||
PR_FALSE, isEnabled);
|
||||
|
||||
return privAcc->FireAccessibleEvent(accEvent);
|
||||
return acc->FireAccessibleEvent(accEvent);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> treeItemAccessible;
|
||||
@ -1126,9 +1128,8 @@ nsRootAccessible::HandlePopupShownEvent(nsIAccessible *aAccessible)
|
||||
PR_FALSE, PR_TRUE);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsPIAccessible> pComboboxAcc(do_QueryInterface(comboboxAcc));
|
||||
|
||||
return pComboboxAcc->FireAccessibleEvent(event);
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(comboboxAcc));
|
||||
return acc->FireAccessibleEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1171,9 +1172,8 @@ nsRootAccessible::HandlePopupHidingEvent(nsIDOMNode *aNode,
|
||||
PR_FALSE, PR_FALSE);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsPIAccessible> pComboboxAcc(do_QueryInterface(comboboxAcc));
|
||||
|
||||
return pComboboxAcc->FireAccessibleEvent(event);
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(comboboxAcc));
|
||||
return acc->FireAccessibleEvent(event);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -53,8 +53,8 @@ nsLinkableAccessible(aDOMNode, aShell)
|
||||
// Make sure we don't support text or other irrelevant interfaces.
|
||||
// We have nsLinkableAccessible in our inheritance chain as a convenience in order to
|
||||
// get link actions and states on the text accessibles. Windows screen readers expect that.
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsTextAccessible, nsAccessNode,
|
||||
nsAccessible, nsIAccessible, nsPIAccessible)
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsTextAccessible, nsAccessNode,
|
||||
nsAccessible, nsIAccessible)
|
||||
|
||||
/**
|
||||
* We are text
|
||||
@ -93,7 +93,7 @@ NS_IMETHODIMP nsTextAccessible::GetChildCount(PRInt32 *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsTextAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength)
|
||||
{
|
||||
nsIFrame *frame = GetFrame();
|
||||
|
@ -58,11 +58,10 @@ public:
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHOD AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength);
|
||||
};
|
||||
|
||||
|
||||
|
@ -531,8 +531,8 @@ nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
|
||||
{
|
||||
const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
|
||||
|
||||
if (NS_GET_A(styleBackground->mFallbackBackgroundColor) > 0) {
|
||||
*aColor = styleBackground->mFallbackBackgroundColor;
|
||||
if (NS_GET_A(styleBackground->mBackgroundColor) > 0) {
|
||||
*aColor = styleBackground->mBackgroundColor;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,8 @@ nsTextEquivUtils::GetNameFromSubtree(nsIAccessible *aAccessible,
|
||||
nsAutoString name;
|
||||
AppendFromAccessibleChildren(aAccessible, &name);
|
||||
name.CompressWhitespace();
|
||||
aName = name;
|
||||
if (!IsWhitespaceString(name))
|
||||
aName = name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,6 +420,27 @@ nsTextEquivUtils::AppendString(nsAString *aString,
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTextEquivUtils::IsWhitespaceString(const nsSubstring& aString)
|
||||
{
|
||||
nsSubstring::const_char_iterator iterBegin, iterEnd;
|
||||
|
||||
aString.BeginReading(iterBegin);
|
||||
aString.EndReading(iterEnd);
|
||||
|
||||
while (iterBegin != iterEnd && IsWhitespace(*iterBegin))
|
||||
++iterBegin;
|
||||
|
||||
return iterBegin == iterEnd;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTextEquivUtils::IsWhitespace(PRUnichar aChar)
|
||||
{
|
||||
return aChar == ' ' || aChar == '\n' ||
|
||||
aChar == '\r' || aChar == '\t' || aChar == 0xa0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Name rules to role map.
|
||||
|
||||
|
@ -159,6 +159,18 @@ private:
|
||||
static PRBool AppendString(nsAString *aString,
|
||||
const nsAString& aTextEquivalent);
|
||||
|
||||
/**
|
||||
* Returns true if the given string is empty or contains whitespace symbols
|
||||
* only. In contrast to nsWhitespaceTokenizer class it takes into account
|
||||
* non-breaking space (0xa0).
|
||||
*/
|
||||
static PRBool IsWhitespaceString(const nsSubstring& aString);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is whitespace symbol.
|
||||
*/
|
||||
static PRBool IsWhitespace(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* Map array from roles to name rules (constants of ETextEquivRule).
|
||||
*/
|
||||
|
@ -177,21 +177,18 @@ void nsHTMLImageAccessible::CacheChildren()
|
||||
PRInt32 childCount = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessible> areaAccessible;
|
||||
nsCOMPtr<nsPIAccessible> privatePrevAccessible;
|
||||
nsRefPtr<nsAccessible> prevAcc;
|
||||
while (childCount < (PRInt32)numMapAreas &&
|
||||
(areaAccessible = GetAreaAccessible(mapAreas, childCount)) != nsnull) {
|
||||
if (privatePrevAccessible) {
|
||||
privatePrevAccessible->SetNextSibling(areaAccessible);
|
||||
}
|
||||
else {
|
||||
if (prevAcc)
|
||||
prevAcc->SetNextSibling(areaAccessible);
|
||||
else
|
||||
SetFirstChild(areaAccessible);
|
||||
}
|
||||
|
||||
++ childCount;
|
||||
|
||||
privatePrevAccessible = do_QueryInterface(areaAccessible);
|
||||
NS_ASSERTION(privatePrevAccessible, "nsIAccessible impl's should always support nsPIAccessible as well");
|
||||
privatePrevAccessible->SetParent(this);
|
||||
prevAcc = nsAccUtils::QueryAccessible(areaAccessible);
|
||||
prevAcc->SetParent(this);
|
||||
}
|
||||
mAccChildCount = childCount;
|
||||
}
|
||||
|
@ -377,23 +377,21 @@ nsHTMLSelectListAccessible::AccessibleForOption(nsIAccessibilityService *aAccSer
|
||||
// Accessibility service will initialize & cache any accessibles created
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
aAccService->GetAccessibleInWeakShell(domNode, mWeakShell, getter_AddRefs(accessible));
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible(do_QueryInterface(accessible));
|
||||
if (!privateAccessible) {
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(accessible));
|
||||
if (!acc)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
++ *aChildCount;
|
||||
privateAccessible->SetParent(this);
|
||||
nsCOMPtr<nsPIAccessible> privatePrevAccessible(do_QueryInterface(aLastGoodAccessible));
|
||||
if (privatePrevAccessible) {
|
||||
privatePrevAccessible->SetNextSibling(accessible);
|
||||
}
|
||||
if (!mFirstChild) {
|
||||
acc->SetParent(this);
|
||||
nsRefPtr<nsAccessible> prevAcc =
|
||||
nsAccUtils::QueryAccessible(aLastGoodAccessible);
|
||||
if (prevAcc)
|
||||
prevAcc->SetNextSibling(accessible);
|
||||
|
||||
if (!mFirstChild)
|
||||
mFirstChild = accessible;
|
||||
}
|
||||
nsIAccessible *returnAccessible = accessible;
|
||||
NS_ADDREF(returnAccessible);
|
||||
return returnAccessible;
|
||||
|
||||
return accessible.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
@ -431,13 +429,14 @@ nsHTMLSelectListAccessible::CacheOptSiblings(nsIAccessibilityService *aAccServic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastGoodAccessible) {
|
||||
nsCOMPtr<nsPIAccessible> privateLastAcc =
|
||||
do_QueryInterface(lastGoodAccessible);
|
||||
privateLastAcc->SetNextSibling(nsnull);
|
||||
NS_ADDREF(aLastGoodAccessible = lastGoodAccessible);
|
||||
nsRefPtr<nsAccessible> lastAcc =
|
||||
nsAccUtils::QueryAccessible(lastGoodAccessible);
|
||||
lastAcc->SetNextSibling(nsnull);
|
||||
}
|
||||
return aLastGoodAccessible;
|
||||
|
||||
return lastGoodAccessible.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -845,18 +844,14 @@ void nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibl
|
||||
|
||||
nsCOMPtr<nsIAccessible> multiSelect =
|
||||
nsAccUtils::GetMultiSelectFor(optionNode);
|
||||
nsCOMPtr<nsPIAccessible> privateMultiSelect = do_QueryInterface(multiSelect);
|
||||
if (!privateMultiSelect) {
|
||||
if (!multiSelect)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService("@mozilla.org/accessibilityService;1");
|
||||
nsCOMPtr<nsIAccessible> optionAccessible;
|
||||
accService->GetAccessibleFor(optionNode, getter_AddRefs(optionAccessible));
|
||||
if (!optionAccessible) {
|
||||
GetAccService()->GetAccessibleFor(optionNode,
|
||||
getter_AddRefs(optionAccessible));
|
||||
if (!optionAccessible)
|
||||
return;
|
||||
}
|
||||
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
|
||||
multiSelect);
|
||||
@ -1250,10 +1245,10 @@ void nsHTMLComboboxTextFieldAccessible::CacheChildren()
|
||||
|
||||
walker.GetFirstChild();
|
||||
SetFirstChild(walker.mState.accessible);
|
||||
nsCOMPtr<nsPIAccessible> privateChild =
|
||||
do_QueryInterface(walker.mState.accessible);
|
||||
privateChild->SetParent(this);
|
||||
privateChild->SetNextSibling(nsnull);
|
||||
nsRefPtr<nsAccessible> child =
|
||||
nsAccUtils::QueryAccessible(walker.mState.accessible);
|
||||
child->SetParent(this);
|
||||
child->SetNextSibling(nsnull);
|
||||
mAccChildCount = 1;
|
||||
}
|
||||
}
|
||||
|
@ -420,14 +420,18 @@ void nsHTMLTableAccessible::CacheChildren()
|
||||
captionAccessible->GetPreviousSibling(getter_AddRefs(beforeCaptionAccessible));
|
||||
if (beforeCaptionAccessible) {
|
||||
// Move caption accessible so that it's the first child
|
||||
nsRefPtr<nsAccessible> acc =
|
||||
nsAccUtils::QueryAccessible(beforeCaptionAccessible);
|
||||
|
||||
nsCOMPtr<nsIAccessible> afterCaptionAccessible;
|
||||
captionAccessible->GetNextSibling(getter_AddRefs(afterCaptionAccessible));
|
||||
nsCOMPtr<nsPIAccessible> privateAcc = do_QueryInterface(beforeCaptionAccessible);
|
||||
privateAcc->SetNextSibling(afterCaptionAccessible);
|
||||
acc->SetNextSibling(afterCaptionAccessible);
|
||||
|
||||
GetFirstChild(getter_AddRefs(afterCaptionAccessible));
|
||||
SetFirstChild(captionAccessible);
|
||||
privateAcc = do_QueryInterface(captionAccessible);
|
||||
privateAcc->SetNextSibling(afterCaptionAccessible);
|
||||
|
||||
acc = nsAccUtils::QueryAccessible(captionAccessible);
|
||||
acc->SetNextSibling(afterCaptionAccessible);
|
||||
}
|
||||
// Don't check for more captions, because nsAccessibilityService ensures
|
||||
// we don't create accessibles for the other captions, since only the
|
||||
@ -1237,7 +1241,7 @@ NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsHTMLTableAccessible::HasDescendant(char *aTagName, PRBool aAllowEmpty)
|
||||
PRBool nsHTMLTableAccessible::HasDescendant(const char *aTagName, PRBool aAllowEmpty)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_TRUE(tableElt, PR_FALSE);
|
||||
@ -1385,7 +1389,7 @@ NS_IMETHODIMP nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForL
|
||||
PRUint32 length;
|
||||
nodeList->GetLength(&length);
|
||||
nsAutoString color, lastRowColor;
|
||||
for (PRInt32 rowCount = 0; rowCount < rows; rowCount ++) {
|
||||
for (PRInt32 rowCount = 0; rowCount < length; rowCount ++) {
|
||||
nsCOMPtr<nsIDOMNode> rowNode;
|
||||
nodeList->Item(rowCount, getter_AddRefs(rowNode));
|
||||
|
||||
|
@ -210,7 +210,7 @@ protected:
|
||||
virtual void CacheChildren();
|
||||
nsresult GetTableNode(nsIDOMNode **_retval);
|
||||
nsresult GetTableLayout(nsITableLayout **aLayoutObject);
|
||||
PRBool HasDescendant(char *aTagName, PRBool aAllowEmpty = PR_TRUE);
|
||||
PRBool HasDescendant(const char *aTagName, PRBool aAllowEmpty = PR_TRUE);
|
||||
#ifdef SHOW_LAYOUT_HEURISTIC
|
||||
nsAutoString mLayoutHeuristic;
|
||||
#endif
|
||||
|
@ -343,12 +343,11 @@ nsHTMLListBulletAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraS
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLListBulletAccessible::SetParent(nsIAccessible *aParentAccessible)
|
||||
void
|
||||
nsHTMLListBulletAccessible::SetParent(nsIAccessible *aParent)
|
||||
{
|
||||
mParent = nsnull;
|
||||
mWeakParent = aParentAccessible;
|
||||
return NS_OK;
|
||||
mWeakParent = aParent;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -358,7 +357,7 @@ nsHTMLListBulletAccessible::GetParent(nsIAccessible **aParentAccessible)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
|
@ -113,7 +113,6 @@ public:
|
||||
// Don't cache via unique ID -- bullet accessible shares the same dom node as
|
||||
// this LI accessible. Also, don't cache via mParent/SetParent(), prevent
|
||||
// circular reference since li holds onto us.
|
||||
NS_IMETHOD SetParent(nsIAccessible *aParentAccessible);
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParentAccessible);
|
||||
|
||||
// nsAccessNode
|
||||
@ -122,9 +121,9 @@ public:
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHOD AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength);
|
||||
virtual void SetParent(nsIAccessible *aParent);
|
||||
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength);
|
||||
|
||||
protected:
|
||||
// XXX: Ideally we'd get the bullet text directly from the bullet frame via
|
||||
|
@ -231,17 +231,17 @@ void nsHyperTextAccessible::CacheChildren()
|
||||
return;
|
||||
}
|
||||
nsAccessibleTreeWalker walker(mWeakShell, editorRootDOMNode, PR_TRUE);
|
||||
nsCOMPtr<nsPIAccessible> privatePrevAccessible;
|
||||
nsRefPtr<nsAccessible> prevAcc;
|
||||
PRInt32 childCount = 0;
|
||||
walker.GetFirstChild();
|
||||
SetFirstChild(walker.mState.accessible);
|
||||
|
||||
while (walker.mState.accessible) {
|
||||
++ childCount;
|
||||
privatePrevAccessible = do_QueryInterface(walker.mState.accessible);
|
||||
privatePrevAccessible->SetParent(this);
|
||||
prevAcc = nsAccUtils::QueryAccessible(walker.mState.accessible);
|
||||
prevAcc->SetParent(this);
|
||||
walker.GetNextSibling();
|
||||
privatePrevAccessible->SetNextSibling(walker.mState.accessible);
|
||||
prevAcc->SetNextSibling(walker.mState.accessible);
|
||||
}
|
||||
mAccChildCount = childCount;
|
||||
}
|
||||
@ -439,9 +439,9 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset,
|
||||
*aText += '*'; // Show *'s only for password text
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsPIAccessible> pAcc(do_QueryInterface(accessible));
|
||||
pAcc->AppendTextTo(*aText, startOffset,
|
||||
substringEndOffset - startOffset);
|
||||
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(accessible));
|
||||
acc->AppendTextTo(*aText, startOffset,
|
||||
substringEndOffset - startOffset);
|
||||
}
|
||||
}
|
||||
if (aBoundsRect) { // Caller wants the bounds of the text
|
||||
|
@ -77,6 +77,7 @@ EXPORTS = \
|
||||
nsAccessNodeWrap.h \
|
||||
nsTextAccessibleWrap.h \
|
||||
nsAccessibleWrap.h \
|
||||
nsARIAGridAccessibleWrap.h \
|
||||
nsDocAccessibleWrap.h \
|
||||
nsRootAccessibleWrap.h \
|
||||
nsXULMenuAccessibleWrap.h \
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -15,15 +17,16 @@
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* 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"),
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
@ -35,22 +38,12 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsWrapUtils_h__
|
||||
#define nsWrapUtils_h__
|
||||
#ifndef _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
#define _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsARIAGridAccessible.h"
|
||||
|
||||
/** Static class to handle wrapping functions.
|
||||
*/
|
||||
class nsWrapUtils
|
||||
{
|
||||
public:
|
||||
static nsresult Rewrap(const nsAString& aInString,
|
||||
PRUint32 aWrapCol, PRUint32 aFirstLineOffset,
|
||||
PRBool aRespectNewlines,
|
||||
const nsAString &aLineStartStr,
|
||||
nsAString& aOutString);
|
||||
};
|
||||
typedef class nsARIAGridAccessible nsARIAGridAccessibleWrap;
|
||||
|
||||
#endif //nsWrapUtils_h__
|
||||
#endif
|
||||
|
@ -75,10 +75,10 @@ class nsAccessibleWrap : public nsAccessible
|
||||
void GetNativeWindow (void **aOutNativeWindow);
|
||||
|
||||
virtual nsresult Shutdown ();
|
||||
virtual nsresult InvalidateChildren ();
|
||||
virtual void InvalidateChildren();
|
||||
|
||||
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
|
||||
NS_IMETHOD FireAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
|
||||
// ignored means that the accessible might still have children, but is not displayed
|
||||
// to the user. it also has no native accessible object represented for it.
|
||||
PRBool IsIgnored();
|
||||
|
@ -159,7 +159,7 @@ nsAccessibleWrap::Shutdown ()
|
||||
return nsAccessible::Shutdown();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
@ -211,18 +211,18 @@ nsAccessibleWrap::FirePlatformEvent(nsIAccessibleEvent *aEvent)
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccessibleWrap::InvalidateChildren ()
|
||||
void
|
||||
nsAccessibleWrap::InvalidateChildren()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mNativeWrapper) {
|
||||
mozAccessible *object = mNativeWrapper->getNativeObject();
|
||||
[object invalidateChildren];
|
||||
}
|
||||
return nsAccessible::InvalidateChildren();
|
||||
nsAccessible::InvalidateChildren();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -74,6 +74,7 @@ CPPSRCS = \
|
||||
nsDocAccessibleWrap.cpp \
|
||||
nsRootAccessibleWrap.cpp \
|
||||
nsHTMLWin32ObjectAccessible.cpp \
|
||||
nsARIAGridAccessibleWrap.cpp \
|
||||
nsXULMenuAccessibleWrap.cpp \
|
||||
nsXULTreeAccessibleWrap.cpp \
|
||||
nsHyperTextAccessibleWrap.cpp \
|
||||
@ -99,6 +100,7 @@ EXPORTS = \
|
||||
nsDocAccessibleWrap.h \
|
||||
nsRootAccessibleWrap.h \
|
||||
nsHTMLWin32ObjectAccessible.h \
|
||||
nsARIAGridAccessibleWrap.h \
|
||||
nsXULMenuAccessibleWrap.h \
|
||||
nsXULTreeAccessibleWrap.h \
|
||||
nsHyperTextAccessibleWrap.h \
|
||||
|
48
accessible/src/msaa/nsARIAGridAccessibleWrap.cpp
Normal file
48
accessible/src/msaa/nsARIAGridAccessibleWrap.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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 Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* 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 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 "nsARIAGridAccessibleWrap.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsARIAGridAccessibleWrap,
|
||||
nsARIAGridAccessible)
|
||||
|
||||
IMPL_IUNKNOWN_INHERITED1(nsARIAGridAccessibleWrap,
|
||||
nsAccessibleWrap,
|
||||
CAccessibleTable);
|
@ -1,4 +1,6 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -15,11 +17,12 @@
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2000
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* 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 the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -35,25 +38,28 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
#define _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
|
||||
#include "nsARIAGridAccessible.h"
|
||||
#include "CAccessibleTable.h"
|
||||
|
||||
/**
|
||||
* Interface for exposing scriptable plugin methods to JavaScript via XPConnect.
|
||||
* Accessible for ARIA grid and treegrid implementing IAccessibleTable
|
||||
* interface.
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[uuid(f1a12bba-1dd1-11b2-a95f-cdc118605e92)]
|
||||
interface nsIScriptablePlugin : nsISupports
|
||||
class nsARIAGridAccessibleWrap : public nsARIAGridAccessible,
|
||||
public CAccessibleTable
|
||||
{
|
||||
/**
|
||||
* The object to be wrapped and exposed to JavaScript. It should
|
||||
* be an XPCOM object, and it can be the same object as the plugin.
|
||||
*/
|
||||
readonly attribute nsQIResult scriptablePeer;
|
||||
public:
|
||||
nsARIAGridAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsARIAGridAccessible(aNode, aShell) {}
|
||||
|
||||
/**
|
||||
* The interface that XPConnect should use when exposing the peer
|
||||
* object to JavaScript. All scriptable methods on the interface
|
||||
* will be available to JavaScript.
|
||||
*/
|
||||
readonly attribute nsIIDPtr scriptableInterface;
|
||||
// IUnknown
|
||||
DECL_IUNKNOWN_INHERITED
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
};
|
||||
|
||||
#endif
|
@ -203,8 +203,13 @@ __try {
|
||||
if (widget) {
|
||||
hwnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
NS_ASSERTION(hwnd, "No window handle for window");
|
||||
|
||||
nsIViewManager* viewManager = view->GetViewManager();
|
||||
if (!viewManager)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
nsIView *rootView;
|
||||
view->GetViewManager()->GetRootView(rootView);
|
||||
viewManager->GetRootView(rootView);
|
||||
if (rootView == view) {
|
||||
// If the current object has a widget but was created by an
|
||||
// outer object with its own outer window, then
|
||||
@ -1618,9 +1623,9 @@ NS_IMETHODIMP nsAccessibleWrap::GetNativeInterface(void **aOutAccessible)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsPIAccessible
|
||||
// nsAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
||||
{
|
||||
NS_ENSURE_ARG(aEvent);
|
||||
|
@ -290,8 +290,8 @@ class nsAccessibleWrap : public nsAccessible,
|
||||
LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
|
||||
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHOD FireAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
// nsAccessible
|
||||
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
|
||||
// Helper methods
|
||||
static PRInt32 GetChildIDFor(nsIAccessible* aAccessible);
|
||||
|
@ -48,7 +48,7 @@ IMPL_IUNKNOWN_INHERITED2(nsHyperTextAccessibleWrap,
|
||||
CAccessibleHypertext,
|
||||
CAccessibleEditableText);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsHyperTextAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
|
||||
{
|
||||
PRUint32 eventType;
|
||||
|
@ -60,8 +60,9 @@ public:
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD FireAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
// nsAccessible
|
||||
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
|
||||
protected:
|
||||
virtual nsresult GetModifiedText(PRBool aGetInsertedText, nsAString& aText,
|
||||
PRUint32 *aStartOffset,
|
||||
|
@ -75,6 +75,7 @@ CPPSRCS = \
|
||||
|
||||
EXPORTS = \
|
||||
nsAccessNodeWrap.h \
|
||||
nsARIAGridAccessibleWrap.h \
|
||||
nsTextAccessibleWrap.h \
|
||||
nsAccessibleWrap.h \
|
||||
nsDocAccessibleWrap.h \
|
||||
|
49
accessible/src/other/nsARIAGridAccessibleWrap.h
Normal file
49
accessible/src/other/nsARIAGridAccessibleWrap.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=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 Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* 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 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 _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
#define _NSARIAGRIDACCESSIBLEWRAP_H
|
||||
|
||||
#include "nsARIAGridAccessible.h"
|
||||
|
||||
typedef class nsARIAGridAccessible nsARIAGridAccessibleWrap;
|
||||
|
||||
#endif
|
||||
|
@ -133,8 +133,7 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
|
||||
children->GetLength(&length);
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
nsCOMPtr<nsPIAccessible> currAccessible;
|
||||
nsCOMPtr<nsPIAccessible> prevAccessible;
|
||||
nsRefPtr<nsAccessible> currAccessible, prevAccessible;
|
||||
|
||||
PRUint32 childLength = 0;
|
||||
for (PRUint32 index = 0; index < length; index++) {
|
||||
@ -144,7 +143,7 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
|
||||
continue;
|
||||
|
||||
accService->GetAttachedAccessibleFor(child, getter_AddRefs(accessible));
|
||||
currAccessible = do_QueryInterface(accessible);
|
||||
currAccessible = nsAccUtils::QueryAccessible(accessible);
|
||||
if (!currAccessible)
|
||||
continue;
|
||||
|
||||
@ -247,13 +246,10 @@ nsXFormsAccessible::GetDescription(nsAString& aDescription)
|
||||
return GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXFormsAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAllowsAnonChildren);
|
||||
|
||||
*aAllowsAnonChildren = PR_FALSE;
|
||||
return NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// nsXFormsContainerAccessible
|
||||
@ -271,13 +267,10 @@ nsXFormsContainerAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsContainerAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXFormsContainerAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAllowsAnonChildren);
|
||||
|
||||
*aAllowsAnonChildren = PR_TRUE;
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// nsXFormsEditableAccessible
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
|
||||
// Denies accessible nodes in anonymous content of xforms element by
|
||||
// always returning PR_FALSE value.
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
||||
protected:
|
||||
// Returns value of first child xforms element by tagname that is bound to
|
||||
@ -127,12 +127,12 @@ class nsXFormsContainerAccessible : public nsXFormsAccessible
|
||||
public:
|
||||
nsXFormsContainerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
||||
// Allows accessible nodes in anonymous content of xforms element by
|
||||
// always returning PR_TRUE value.
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
|
||||
// Allows accessible nodes in anonymous content of xforms element by
|
||||
// always returning PR_TRUE value.
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
};
|
||||
|
||||
|
||||
|
@ -586,13 +586,10 @@ nsXFormsSelectComboboxAccessible::GetStateInternal(PRUint32 *aState,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsSelectComboboxAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXFormsSelectComboboxAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAllowsAnonChildren);
|
||||
|
||||
*aAllowsAnonChildren = PR_TRUE;
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -281,13 +281,10 @@ class nsXFormsSelectComboboxAccessible : public nsXFormsSelectableAccessible
|
||||
public:
|
||||
nsXFormsSelectComboboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
||||
// Allows accessible nodes in anonymous content of xforms element by
|
||||
// always returning PR_TRUE value.
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
};
|
||||
|
||||
|
||||
|
@ -179,8 +179,7 @@ void nsXULButtonAccessible::CacheChildren()
|
||||
if (mAccChildCount == eChildCountUninitialized) {
|
||||
mAccChildCount = 0; // Avoid reentry
|
||||
SetFirstChild(nsnull);
|
||||
PRBool allowsAnonChildren = PR_FALSE;
|
||||
GetAllowsAnonChildAccessibles(&allowsAnonChildren);
|
||||
PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles();
|
||||
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren);
|
||||
walker.GetFirstChild();
|
||||
nsCOMPtr<nsIAccessible> dropMarkerAccessible;
|
||||
@ -197,9 +196,10 @@ void nsXULButtonAccessible::CacheChildren()
|
||||
if (nsAccUtils::RoleInternal(dropMarkerAccessible) ==
|
||||
nsIAccessibleRole::ROLE_PUSHBUTTON) {
|
||||
SetFirstChild(dropMarkerAccessible);
|
||||
nsCOMPtr<nsPIAccessible> privChildAcc = do_QueryInterface(dropMarkerAccessible);
|
||||
privChildAcc->SetNextSibling(nsnull);
|
||||
privChildAcc->SetParent(this);
|
||||
nsRefPtr<nsAccessible> childAcc =
|
||||
nsAccUtils::QueryAccessible(dropMarkerAccessible);
|
||||
childAcc->SetNextSibling(nsnull);
|
||||
childAcc->SetParent(this);
|
||||
mAccChildCount = 1;
|
||||
}
|
||||
}
|
||||
@ -989,11 +989,10 @@ NS_IMETHODIMP nsXULTextFieldAccessible::DoAction(PRUint8 index)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTextFieldAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXULTextFieldAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
*aAllowsAnonChildren = PR_FALSE;
|
||||
return NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
|
@ -199,7 +199,6 @@ public:
|
||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
@ -207,6 +206,7 @@ public:
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
||||
protected:
|
||||
already_AddRefed<nsIDOMNode> GetInputField();
|
||||
|
@ -515,12 +515,11 @@ nsXULMenuitemAccessible::GetAttributesInternal(nsIPersistentProperties *aAttribu
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULMenuitemAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXULMenuitemAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
// That indicates we don't walk anonymous children for menuitems
|
||||
*aAllowsAnonChildren = PR_FALSE;
|
||||
return NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULMenuitemAccessible::DoAction(PRUint8 index)
|
||||
|
@ -94,7 +94,7 @@ public:
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
};
|
||||
|
||||
class nsXULMenuSeparatorAccessible : public nsXULMenuitemAccessible
|
||||
|
@ -959,12 +959,11 @@ NS_IMETHODIMP nsXULListitemAccessible::GetActionName(PRUint8 aIndex, nsAString&
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULListitemAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXULListitemAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
// That indicates we should walk anonymous children for listitems
|
||||
*aAllowsAnonChildren = PR_TRUE;
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1106,13 +1105,13 @@ NS_IMETHODIMP nsXULComboboxAccessible::GetDescription(nsAString& aDescription)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULComboboxAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXULComboboxAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
if (!mDOMNode)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
||||
NS_ASSERTION(content, "No content during accessible tree building!");
|
||||
if (!content)
|
||||
return PR_FALSE;
|
||||
|
||||
if (content->NodeInfo()->Equals(nsAccessibilityAtoms::textbox, kNameSpaceID_XUL) ||
|
||||
content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::editable,
|
||||
@ -1120,13 +1119,12 @@ nsXULComboboxAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildr
|
||||
// Both the XUL <textbox type="autocomplete"> and <menulist editable="true"> widgets
|
||||
// use nsXULComboboxAccessible. We need to walk the anonymous children for these
|
||||
// so that the entry field is a child
|
||||
*aAllowsAnonChildren = PR_TRUE;
|
||||
} else {
|
||||
// Argument of PR_FALSE indicates we don't walk anonymous children for
|
||||
// menuitems
|
||||
*aAllowsAnonChildren = PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
// Argument of PR_FALSE indicates we don't walk anonymous children for
|
||||
// menuitems
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/** Just one action ( click ). */
|
||||
|
@ -141,13 +141,13 @@ public:
|
||||
NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
|
||||
// Don't use XUL menuitems's description attribute
|
||||
NS_IMETHOD GetDescription(nsAString& aDesc) { return nsAccessibleWrap::GetDescription(aDesc); }
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetNameInternal(nsAString& aName);
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
||||
protected:
|
||||
already_AddRefed<nsIAccessible> GetListAccessible();
|
||||
@ -183,10 +183,9 @@ public:
|
||||
nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsXULComboboxAccessible() {}
|
||||
|
||||
/* ----- nsIAccessible ----- */
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetValue(nsAString& _retval);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
|
||||
@ -197,6 +196,7 @@ public:
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -188,15 +188,11 @@ nsXULSliderAccessible::SetCurrentValue(double aValue)
|
||||
return SetSliderAttr(nsAccessibilityAtoms::curpos, aValue);
|
||||
}
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHODIMP
|
||||
nsXULSliderAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
|
||||
PRBool
|
||||
nsXULSliderAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAllowsAnonChildren);
|
||||
|
||||
// Do not allow anonymous xul:slider be accessible.
|
||||
*aAllowsAnonChildren = PR_FALSE;
|
||||
return NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Utils
|
||||
|
@ -63,9 +63,7 @@ public:
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
// nsPIAccessible
|
||||
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
||||
protected:
|
||||
already_AddRefed<nsIContent> GetSliderNode();
|
||||
|
@ -45,9 +45,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = test_accessibility
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += mochitest
|
||||
endif
|
||||
DIRS = mochitest
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
@ -75,6 +75,7 @@ _TEST_FILES =\
|
||||
test_aria_role_article.html \
|
||||
test_aria_role_equation.html \
|
||||
test_aria_role_grid.html \
|
||||
test_aria_roles.html \
|
||||
test_aria_token_attrs.html \
|
||||
test_bug420863.html \
|
||||
$(warning test_childAtPoint.html temporarily disabled) \
|
||||
@ -83,11 +84,13 @@ _TEST_FILES =\
|
||||
test_descr.html \
|
||||
test_elm_filectrl.html \
|
||||
$(warning test_elm_media.html temporarily disabled) \
|
||||
test_elm_table.html \
|
||||
test_elm_txtcntnr.html \
|
||||
test_events_caretmove.html \
|
||||
test_events_focus.xul \
|
||||
test_events_mutation.html \
|
||||
test_events_tree.xul \
|
||||
test_events_valuechange.html \
|
||||
test_groupattrs.xul \
|
||||
test_groupattrs.html \
|
||||
test_name.html \
|
||||
@ -125,6 +128,7 @@ _TEST_FILES =\
|
||||
test_table_4.html \
|
||||
$(warning test_table_indexes.html temporarily disabled) \
|
||||
test_table_indexes_ariagrid.html \
|
||||
test_table_sels_ariagrid.html \
|
||||
test_textattrs.html \
|
||||
test_textboxes.html \
|
||||
test_textboxes.xul \
|
||||
|
@ -60,6 +60,7 @@ const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
|
||||
const STATE_LINKED = nsIAccessibleStates.STATE_LINKED;
|
||||
const STATE_MIXED = nsIAccessibleStates.STATE_MIXED;
|
||||
const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
|
||||
const STATE_OFFSCREEN = nsIAccessibleStates.STATE_OFFSCREEN;
|
||||
const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED;
|
||||
const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
|
||||
const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
|
||||
|
@ -90,7 +90,7 @@ const INVOKER_ACTION_FAILED = 1;
|
||||
* Creates event queue for the given event type. The queue consists of invoker
|
||||
* objects, each of them generates the event of the event type. When queue is
|
||||
* started then every invoker object is asked to generate event after timeout.
|
||||
* When event is caught then current invoker object is asked to check wether
|
||||
* When event is caught then current invoker object is asked to check whether
|
||||
* event was handled correctly.
|
||||
*
|
||||
* Invoker interface is:
|
||||
|
@ -78,7 +78,7 @@ function grid(aTableIdentifier)
|
||||
|
||||
this.handleKeyEvent = function handleKeyEvent(aEvent)
|
||||
{
|
||||
if (aEvent.target.localName != "TD")
|
||||
if (aEvent.target.localName != "td")
|
||||
return;
|
||||
|
||||
var cell = aEvent.target;
|
||||
@ -131,7 +131,7 @@ function grid(aTableIdentifier)
|
||||
|
||||
this.handleClickEvent = function handleClickEvent(aEvent)
|
||||
{
|
||||
if (aEvent.target.localName != "TD")
|
||||
if (aEvent.target.localName != "td")
|
||||
return;
|
||||
|
||||
var curCell = this.getCurrentCell();
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Role constants
|
||||
|
||||
const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
|
||||
const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION;
|
||||
const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
|
||||
const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
|
||||
const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
|
||||
|
@ -21,13 +21,13 @@ function testTableIndexes(aIdentifier, aLen, aRowIdxes, aColIdxes)
|
||||
try {
|
||||
row = tableAcc.getRowAtIndex(i);
|
||||
} catch (e) {
|
||||
ok(false, id + ": can't get row index for cell index " + i + ".");
|
||||
ok(false, id + ": can't get row index for cell index " + i + "," + e);
|
||||
}
|
||||
|
||||
try {
|
||||
column = tableAcc.getColumnAtIndex(i);
|
||||
} catch (e) {
|
||||
ok(false, id + ": can't get column index for cell index " + i + ".");
|
||||
ok(false, id + ": can't get column index for cell index " + i + "," + e);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -35,7 +35,7 @@ function testTableIndexes(aIdentifier, aLen, aRowIdxes, aColIdxes)
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
id + ": can't get cell index by row index " + aRowIdxes[i] +
|
||||
" and column index: " + aColIdxes[i] + ".");
|
||||
" and column index: " + aColIdxes[i] + ", " + e);
|
||||
}
|
||||
|
||||
is(row, aRowIdxes[i], id + ": row for index " + i +" is nor correct");
|
||||
@ -69,3 +69,214 @@ function testTableIndexes(aIdentifier, aLen, aRowIdxes, aColIdxes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test table getters selection methods.
|
||||
*
|
||||
* @param aIdentifier [in] table accessible identifier
|
||||
* @param aCellsArray [in] two dimensional array (row X columns) of selected
|
||||
* cells states.
|
||||
* @param aMsg [in] text appended before every message
|
||||
*/
|
||||
function testTableSelection(aIdentifier, aCellsArray, aMsg)
|
||||
{
|
||||
var msg = aMsg ? aMsg : "";
|
||||
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
var rowsCount = aCellsArray.length;
|
||||
var colsCount = aCellsArray[0].length;
|
||||
|
||||
// Columns selection tests.
|
||||
var selCols = new Array();
|
||||
|
||||
// isColumnSelected test
|
||||
for (var colIdx = 0; colIdx < colsCount; colIdx++) {
|
||||
var isColSelected = true;
|
||||
for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
|
||||
if (!aCellsArray[rowIdx][colIdx]) {
|
||||
isColSelected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
is(acc.isColumnSelected(colIdx), isColSelected,
|
||||
msg + "Wrong selection state of " + colIdx + " column for " +
|
||||
prettyName(aIdentifier));
|
||||
|
||||
if (isColSelected)
|
||||
selCols.push(colIdx);
|
||||
}
|
||||
|
||||
// selectedColsCount test
|
||||
is(acc.selectedColumnsCount, selCols.length,
|
||||
msg + "Wrong count of selected columns for " + prettyName(aIdentifier));
|
||||
|
||||
// getSelectedColumns test
|
||||
var actualSelColsCountObj = { value: null };
|
||||
var actualSelCols = acc.getSelectedColumns(actualSelColsCountObj);
|
||||
|
||||
var actualSelColsCount = actualSelColsCountObj.value;
|
||||
is (actualSelColsCount, selCols.length,
|
||||
msg + "Wrong count of selected columns for " + prettyName(aIdentifier) +
|
||||
"from getSelectedColumns.");
|
||||
|
||||
for (var i = 0; i < actualSelColsCount; i++) {
|
||||
is (actualSelCols[i], selCols[i],
|
||||
msg + "Column at index " + selCols[i] + " should be selected.");
|
||||
}
|
||||
|
||||
// Rows selection tests.
|
||||
var selRows = new Array();
|
||||
|
||||
// isRowSelected test
|
||||
var selRowsCount = 0;
|
||||
for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
|
||||
var isRowSelected = true;
|
||||
for (var colIdx = 0; colIdx < colsCount; colIdx++) {
|
||||
if (!aCellsArray[rowIdx][colIdx]) {
|
||||
isRowSelected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
is(acc.isRowSelected(rowIdx), isRowSelected,
|
||||
msg + "Wrong selection state of " + rowIdx + " row for " +
|
||||
prettyName(aIdentifier));
|
||||
|
||||
if (isRowSelected)
|
||||
selRows.push(rowIdx);
|
||||
}
|
||||
|
||||
// selectedRowsCount test
|
||||
is(acc.selectedRowsCount, selRows.length,
|
||||
msg + "Wrong count of selected rows for " + prettyName(aIdentifier));
|
||||
|
||||
// getSelectedRows test
|
||||
var actualSelRowsCountObj = { value: null };
|
||||
var actualSelRows = acc.getSelectedRows(actualSelRowsCountObj);
|
||||
|
||||
var actualSelRowsCount = actualSelRowsCountObj.value;
|
||||
is (actualSelRowsCount, selRows.length,
|
||||
msg + "Wrong count of selected rows for " + prettyName(aIdentifier) +
|
||||
"from getSelectedRows.");
|
||||
|
||||
for (var i = 0; i < actualSelRowsCount; i++) {
|
||||
is (actualSelRows[i], selRows[i],
|
||||
msg + "Row at index " + selRows[i] + " should be selected.");
|
||||
}
|
||||
|
||||
// Cells selection tests.
|
||||
var selCells = new Array();
|
||||
|
||||
// isCellSelected test
|
||||
for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
|
||||
for (var colIdx = 0; colIdx < colsCount; colIdx++) {
|
||||
is(acc.isCellSelected(rowIdx, colIdx), aCellsArray[rowIdx][colIdx],
|
||||
msg + "Wrong selection state of cell at " + rowIdx + " row and " +
|
||||
colIdx + " column for " + prettyName(aIdentifier));
|
||||
|
||||
if (aCellsArray[rowIdx][colIdx])
|
||||
selCells.push(acc.getIndexAt(rowIdx, colIdx));
|
||||
}
|
||||
}
|
||||
|
||||
// selectedCellsCount tests
|
||||
is(acc.selectedCellsCount, selCells.length,
|
||||
msg + "Wrong count of selected cells for " + prettyName(aIdentifier));
|
||||
|
||||
// getSelectedCells test
|
||||
var actualSelCellsCountObj = { value: null };
|
||||
var actualSelCells = acc.getSelectedCells(actualSelCellsCountObj);
|
||||
|
||||
var actualSelCellsCount = actualSelCellsCountObj.value;
|
||||
is (actualSelCellsCount, selCells.length,
|
||||
msg + "Wrong count of selected cells for " + prettyName(aIdentifier) +
|
||||
"from getSelectedCells.");
|
||||
|
||||
for (var i = 0; i < actualSelCellsCount; i++) {
|
||||
is (actualSelCells[i], selCells[i],
|
||||
msg + "Cell at index " + selCells[i] + " should be selected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test unselectColumn method of accessible table.
|
||||
*/
|
||||
function testUnselectTableColumn(aIdentifier, aColIdx, aCellsArray)
|
||||
{
|
||||
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
var rowsCount = aCellsArray.length;
|
||||
for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++)
|
||||
aCellsArray[rowIdx][aColIdx] = false;
|
||||
|
||||
acc.unselectColumn(aColIdx);
|
||||
testTableSelection(aIdentifier, aCellsArray,
|
||||
"Unselect " + aColIdx + " column: ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test selectColumn method of accessible table.
|
||||
*/
|
||||
function testSelectTableColumn(aIdentifier, aColIdx, aCellsArray)
|
||||
{
|
||||
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
var rowsCount = aCellsArray.length;
|
||||
var colsCount = aCellsArray[0].length;
|
||||
|
||||
for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
|
||||
for (var colIdx = 0; colIdx < colsCount; colIdx++)
|
||||
aCellsArray[rowIdx][colIdx] = (colIdx == aColIdx);
|
||||
}
|
||||
|
||||
acc.selectColumn(aColIdx);
|
||||
testTableSelection(aIdentifier, aCellsArray,
|
||||
"Select " + aColIdx + " column: ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test unselectRow method of accessible table.
|
||||
*/
|
||||
function testUnselectTableRow(aIdentifier, aRowIdx, aCellsArray)
|
||||
{
|
||||
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
var colsCount = aCellsArray[0].length;
|
||||
for (var colIdx = 0; colIdx < colsCount; colIdx++)
|
||||
aCellsArray[aRowIdx][colIdx] = false;
|
||||
|
||||
acc.unselectRow(aRowIdx);
|
||||
testTableSelection(aIdentifier, aCellsArray,
|
||||
"Unselect " + aRowIdx + " row: ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test selectRow method of accessible table.
|
||||
*/
|
||||
function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray)
|
||||
{
|
||||
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
var rowsCount = aCellsArray.length;
|
||||
var colsCount = aCellsArray[0].length;
|
||||
|
||||
for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
|
||||
for (var colIdx = 0; colIdx < colsCount; colIdx++)
|
||||
aCellsArray[rowIdx][colIdx] = (rowIdx == aRowIdx);
|
||||
}
|
||||
|
||||
acc.selectRow(aRowIdx);
|
||||
testTableSelection(aIdentifier, aCellsArray,
|
||||
"Select " + aRowIdx + " row: ");
|
||||
}
|
||||
|
84
accessible/tests/mochitest/test_aria_roles.html
Normal file
84
accessible/tests/mochitest/test_aria_roles.html
Normal file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=481114
|
||||
-->
|
||||
<head>
|
||||
<title>Test weak ARIA roles</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
// Note:
|
||||
// The phrase "weak foo" here means that there is no good foo-to-platform
|
||||
// role mapping. Similarly "strong foo" means there is a good foo-to-
|
||||
// platform role mapping.
|
||||
|
||||
// weak roles that are forms of "live regions"
|
||||
testRole("log_table", ROLE_TABLE);
|
||||
testRole("marquee_h1", ROLE_HEADING);
|
||||
testRole("timer_div", ROLE_SECTION);
|
||||
|
||||
// strong landmark
|
||||
testRole("application", ROLE_APPLICATION);
|
||||
|
||||
// weak landmarks
|
||||
var weak_landmarks = ["banner", "complementary", "contentinfo",
|
||||
"main", "navigation", "search"];
|
||||
for (l in weak_landmarks)
|
||||
testRole(weak_landmarks[l], ROLE_SECTION);
|
||||
|
||||
// test gEmptyRoleMap
|
||||
testRole("cell", ROLE_NOTHING);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481114">Mozilla Bug 481114</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<!-- "live" roles -->
|
||||
<table role="log" id="log_table">
|
||||
<tr><td>Table based log</td></tr>
|
||||
</table>
|
||||
<h1 role="marquee" id="marquee_h1">marquee</h1>
|
||||
<div role="timer" id="timer_div">timer</div>
|
||||
|
||||
<!-- landmarks -->
|
||||
<div role="application" id="application">application</div>
|
||||
<div role="banner" id="banner">banner</div>
|
||||
<div role="complementary" id="complementary">complementary</div>
|
||||
<div role="contentinfo" id="contentinfo">contentinfo</div>
|
||||
<div role="main" id="main">main</div>
|
||||
<div role="navigation" id="navigation">navigation</div>
|
||||
<div role="search" id="search">search</div>
|
||||
|
||||
<!-- test gEmptyRoleMap -->
|
||||
<table role="label">
|
||||
<tr>
|
||||
<td id="cell">cell</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
117
accessible/tests/mochitest/test_elm_table.html
Normal file
117
accessible/tests/mochitest/test_elm_table.html
Normal file
@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
||||
-->
|
||||
<head>
|
||||
<title>File Input Control tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
var accTree = {
|
||||
role: ROLE_TABLE, // table
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_CONTAINER, // thead
|
||||
children: [
|
||||
{
|
||||
role: ROLE_ROW,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COLUMNHEADER
|
||||
},
|
||||
{
|
||||
role: ROLE_COLUMNHEADER
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_TEXT_CONTAINER, // tbody
|
||||
children: [
|
||||
{
|
||||
role: ROLE_ROW,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_CELL
|
||||
},
|
||||
{
|
||||
role: ROLE_CELL
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_TEXT_CONTAINER, // tfoot
|
||||
children: [
|
||||
{
|
||||
role: ROLE_ROW,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COLUMNHEADER
|
||||
},
|
||||
{
|
||||
role: ROLE_COLUMNHEADER
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
if (LINUX)
|
||||
todo(false, "No tests on linux because of different hierarchies.");
|
||||
else
|
||||
testAccessibleTree("table", accTree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="create accessibles for HTML tr"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=493695">Mozilla Bug 493695</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<table id="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>col1</th><th>col2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>cell1</td><td>cell2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>col1</th><th>col2</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -206,7 +206,7 @@
|
||||
|
||||
this.getID = function removeFromDOM_getID()
|
||||
{
|
||||
return aNodeOrID + " remove from DOM.";
|
||||
return prettyName(aNodeOrID) + " remove from DOM.";
|
||||
}
|
||||
|
||||
if (aTargetsFunc && (eventTypes & kHideEvent))
|
||||
|
109
accessible/tests/mochitest/test_events_valuechange.html
Normal file
109
accessible/tests/mochitest/test_events_valuechange.html
Normal file
@ -0,0 +1,109 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible value change events testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/value.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
// Value change invoker
|
||||
function changeValue(aNodeOrID, aValuenow, aValuetext)
|
||||
{
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
|
||||
this.invoke = function changeValue_invoke() {
|
||||
|
||||
// Note: this should not fire an EVENT_VALUE_CHANGE when aria-valuetext
|
||||
// is not empty
|
||||
if (aValuenow != undefined)
|
||||
this.DOMNode.setAttribute("aria-valuenow", aValuenow);
|
||||
|
||||
// Note: this should always fire an EVENT_VALUE_CHANGE
|
||||
if (aValuetext != undefined)
|
||||
this.DOMNode.setAttribute("aria-valuetext", aValuetext);
|
||||
}
|
||||
|
||||
this.check = function changeValue_check() {
|
||||
var acc = getAccessible(aNodeOrID, [nsIAccessibleValue]);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
// Note: always test against valuetext first because the existence of
|
||||
// aria-valuetext takes precedence over aria-valuenow in gecko.
|
||||
is(acc.value, (aValuetext != undefined)? aValuetext : aValuenow,
|
||||
"Wrong value of " + prettyName(aNodeOrID));
|
||||
}
|
||||
|
||||
this.getID = function changeValue_getID() {
|
||||
return prettyName(aNodeOrID) + " value changed";
|
||||
}
|
||||
}
|
||||
|
||||
function doTests()
|
||||
{
|
||||
// Test initial values
|
||||
testValue("slider_vn", "5", 5, 0, 1000, 0);
|
||||
testValue("slider_vnvt", "plain", 0, 0, 5, 0);
|
||||
testValue("slider_vt", "hi", 0, 0, 3, 0);
|
||||
|
||||
// Test value change events
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_VALUE_CHANGE);
|
||||
|
||||
gQueue.push(new changeValue("slider_vn", "6", undefined));
|
||||
gQueue.push(new changeValue("slider_vt", undefined, "hey!"));
|
||||
gQueue.push(new changeValue("slider_vnvt", "3", "sweet"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=478032"
|
||||
title=" Fire delayed value changed event for aria-valuetext changes">
|
||||
Mozilla Bug 478032
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<!-- ARIA sliders -->
|
||||
<div id="slider_vn" role="slider" aria-valuenow="5"
|
||||
aria-valuemin="0" aria-valuemax="1000">slider</div>
|
||||
|
||||
<div id="slider_vt" role="slider" aria-valuetext="hi"
|
||||
aria-valuemin="0" aria-valuemax="3">greeting slider</div>
|
||||
|
||||
<div id="slider_vnvt" role="slider" aria-valuenow="0" aria-valuetext="plain"
|
||||
aria-valuemin="0" aria-valuemax="5">sweetness slider</div>
|
||||
</body>
|
||||
</html>
|
@ -92,6 +92,9 @@
|
||||
// Gets the name from html:input value, ignore @title attribute on input
|
||||
testName("from_input_ignoretitle", "Custom country");
|
||||
|
||||
// Gets the name from @title, ignore whitespace content
|
||||
testName("from_label_ignore_ws_subtree", "about");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// label element
|
||||
|
||||
@ -303,6 +306,9 @@
|
||||
value="Custom country"
|
||||
title="Input your country of origin"/ >
|
||||
|
||||
<!-- no name from subtree because it holds whitespaces only -->
|
||||
<a id="from_label_ignore_ws_subtree" href="about:" title="about"> </a>
|
||||
|
||||
<!-- label element, label contains the button -->
|
||||
<label>text<button id="btn_label_inside">10</button>text</label>
|
||||
<br/>
|
||||
|
@ -168,6 +168,10 @@
|
||||
testName("lb_opt1_children_hidden", "i am visible");
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Name from aria-labelledby: menuitem label+ listitem label
|
||||
testName("li_labelledby", "Show an Alert The moment the event starts");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -184,7 +188,13 @@
|
||||
title="mochitest for accessible name calculating">
|
||||
Mozilla Bug 444279
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=441991"
|
||||
title="nsXULListitemAccessible::GetName prefers label \
|
||||
attribute over aria-labelledby and doesn't allow recursion">
|
||||
Mozilla Bug 441991
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
@ -328,5 +338,24 @@
|
||||
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<!-- bug 441991; create name from other menuitem label listitem's own label -->
|
||||
<hbox>
|
||||
<listbox>
|
||||
<listitem id="li_labelledby"
|
||||
label="The moment the event starts"
|
||||
aria-labelledby="menuitem-DISPLAY li_labelledby"/>
|
||||
</listbox>
|
||||
<menulist>
|
||||
<menupopup>
|
||||
<menuitem id="menuitem-DISPLAY"
|
||||
value="DISPLAY"
|
||||
label="Show an Alert"/>
|
||||
<menuitem id="menuitem-EMAIL"
|
||||
value="EMAIL"
|
||||
label="Send an E-mail"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</window>
|
||||
|
||||
|
@ -68,7 +68,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
var normalHyperlinkAcc = getAccessible("NormalHyperlink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("NormalHyperlink", normalHyperlinkAcc, ROLE_LINK, 1,
|
||||
"Mozilla Foundation", true, 18, 19);
|
||||
"Mozilla Foundation", true, 17, 18);
|
||||
is(normalHyperlinkAcc.getURI(0).spec, "http://www.mozilla.org/",
|
||||
"URI wrong for normalHyperlinkElement!");
|
||||
testStates(normalHyperlinkAcc,
|
||||
@ -84,7 +84,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
var ariaHyperlinkAcc = getAccessible("AriaHyperlink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("AriaHyperlink", ariaHyperlinkAcc, ROLE_LINK, 1,
|
||||
"Mozilla Foundation Home", true, 32, 33);
|
||||
"Mozilla Foundation Home", true, 30, 31);
|
||||
testStates(ariaHyperlinkAcc,
|
||||
(STATE_FOCUSABLE | STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
@ -110,7 +110,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
var imageMapHyperlinkAcc = getAccessible("imgmap",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("imgmap", imageMapHyperlinkAcc, ROLE_IMAGE_MAP, 2, "b", true,
|
||||
83, 84);
|
||||
79, 80);
|
||||
is(imageMapHyperlinkAcc.getURI(0).spec,
|
||||
"http://www.bbc.co.uk/radio4/atoz/index.shtml#b", "URI wrong!");
|
||||
is(imageMapHyperlinkAcc.getURI(1).spec,
|
||||
@ -137,7 +137,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
// empty hyperlink
|
||||
var EmptyHLAcc = getAccessible("emptyLink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("emptyLink", EmptyHLAcc, ROLE_LINK, 1, null, true, 98, 99);
|
||||
testThis("emptyLink", EmptyHLAcc, ROLE_LINK, 1, null, true, 93, 94);
|
||||
testStates(EmptyHLAcc,
|
||||
(STATE_FOCUSABLE | STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
@ -148,7 +148,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
var hyperlinkWithSpanAcc = getAccessible("LinkWithSpan",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("LinkWithSpan", hyperlinkWithSpanAcc, ROLE_LINK, 1,
|
||||
"Heise Online", true, 124, 125);
|
||||
"Heise Online", true, 119, 120);
|
||||
is(hyperlinkWithSpanAcc.getURI(0).spec, "http://www.heise.de/",
|
||||
"URI wrong for hyperlinkElementWithSpan!");
|
||||
testStates(hyperlinkWithSpanAcc,
|
||||
@ -165,7 +165,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
var namedAnchorAcc = getAccessible("namedAnchor",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("namedAnchor", namedAnchorAcc, ROLE_LINK, 1,
|
||||
"This should never be of state_linked", true, 202, 203);
|
||||
"This should never be of state_linked", true, 196, 197);
|
||||
testStates(namedAnchorAcc,
|
||||
(STATE_SELECTABLE),
|
||||
(EXT_STATE_HORIZONTAL), (STATE_FOCUSABLE | STATE_LINKED));
|
||||
@ -176,7 +176,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
var noLinkAcc = getAccessible("noLink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("noLink", noLinkAcc, ROLE_LINK, 1,
|
||||
"This should never be of state_linked", true, 262, 263);
|
||||
"This should never be of state_linked", true, 254, 255);
|
||||
testStates(noLinkAcc,
|
||||
0,
|
||||
(EXT_STATE_HORIZONTAL), (STATE_FOCUSABLE | STATE_LINKED));
|
||||
@ -187,7 +187,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
var linkWithClickAcc = getAccessible("linkWithClick",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("linkWithClick", linkWithClickAcc, ROLE_LINK, 1,
|
||||
"This should have state_linked", true, 301, 302);
|
||||
"This should have state_linked", true, 292, 293);
|
||||
testStates(linkWithClickAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
@ -201,7 +201,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
// Link with title attribute, no name from the subtree (bug 438325).
|
||||
var id = "linkWithTitleNoNameFromSubtree";
|
||||
var linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "Link with title", true, 354, 355);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "Link with title", true, 344, 345);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
@ -212,8 +212,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
// (bug 438325).
|
||||
id = "linkWithTitleNameFromSubtree";
|
||||
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "the name from subtree", true, 403,
|
||||
404);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "the name from subtree", true, 393,
|
||||
394);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
@ -223,8 +223,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
// Link with title attribute, name from the nested html:img (bug 438325).
|
||||
id = "linkWithTitleNameFromImg";
|
||||
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "The title for link", true, 458,
|
||||
459);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "The title for link", true, 447,
|
||||
448);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
@ -235,7 +235,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
id = "linkWithLabelNoNameFromSubtree";
|
||||
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "Link with label and nested image:",
|
||||
true, 462, 463);
|
||||
true, 450, 451);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
@ -250,78 +250,64 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<br>Simple link:<br>
|
||||
<a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a>
|
||||
<br>ARIA link:<br>
|
||||
<span id="AriaHyperlink" role="link"
|
||||
<body><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a
|
||||
><p id="display"></p
|
||||
><div id="content" style="display: none"></div
|
||||
><pre id="test">
|
||||
</pre
|
||||
><br
|
||||
>Simple link:<br
|
||||
><a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a
|
||||
><br>ARIA link:<br
|
||||
><span id="AriaHyperlink" role="link"
|
||||
onclick="window.open('http://www.mozilla.org/');"
|
||||
tabindex="0">Mozilla Foundation Home</span>
|
||||
<br>Invalid, non-focusable hyperlink:<br>
|
||||
<span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span>
|
||||
<br>Image map:<br>
|
||||
<map name="atoz_map">
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
tabindex="0">Mozilla Foundation Home</span
|
||||
><br
|
||||
>Invalid, non-focusable hyperlink:<br
|
||||
><span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span
|
||||
><br>Image map:<br
|
||||
><map name="atoz_map"
|
||||
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
coords="17,0,30,14"
|
||||
alt="b"
|
||||
shape="rect"></area>
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area>
|
||||
</map>
|
||||
<img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"></img>
|
||||
|
||||
<br>Empty link:<br>
|
||||
<a id="emptyLink" href=""><img src=""></img></a>
|
||||
|
||||
<br>Link with embedded span<br>
|
||||
<a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a>
|
||||
|
||||
<br>Named anchor, must not have "linked" state for it to be exposed correctly:<br>
|
||||
<a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
|
||||
|
||||
<br>Link having no attributes, must not have "linked" state:</br>
|
||||
<a id="noLink">This should never be of state_linked</a>
|
||||
|
||||
<br>Link with registered 'click' event: </br>
|
||||
<a id="linkWithClick" onclick="var clicked = true;">This should have state_linked</a>
|
||||
|
||||
<br>Link with title attribute (no name from subtree): </br>
|
||||
<a id="linkWithTitleNoNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title"><img src=""/></a>
|
||||
|
||||
<br>Link with title attribute (name from subtree): </br>
|
||||
<a id="linkWithTitleNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title">the name from subtree</a>
|
||||
|
||||
<br>Link with title attribute (name from nested image): </br>
|
||||
<a id="linkWithTitleNameFromImg" href="http://www.heise.de/"
|
||||
title="Link with title"><img src="" alt="The title for link"/></a>
|
||||
|
||||
<br><label for="linkWithLabelNoNameFromSubtree">Link with label and nested image: </label></br>
|
||||
<a id="linkWithLabelNoNameFromSubtree"
|
||||
href="http://www.heise.de/"><img src=""/></a>
|
||||
|
||||
<br>Map that is used to group links (www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass),
|
||||
also see the bug 431615:<br>
|
||||
<map id="linksmap" title="Site navigation">
|
||||
<ul>
|
||||
<li><a href="http://mozilla.org">About the project</a></li>
|
||||
<li><a href="http://mozilla.org">Sites and sounds</a></li>
|
||||
</ul>
|
||||
</map>
|
||||
|
||||
</body>
|
||||
shape="rect"></area
|
||||
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area
|
||||
></map
|
||||
><img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"></img
|
||||
><br>Empty link:<br
|
||||
><a id="emptyLink" href=""><img src=""></img></a
|
||||
><br>Link with embedded span<br
|
||||
><a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a
|
||||
><br>Named anchor, must not have "linked" state for it to be exposed correctly:<br
|
||||
><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a
|
||||
><br>Link having no attributes, must not have "linked" state:</br
|
||||
><a id="noLink">This should never be of state_linked</a
|
||||
><br>Link with registered 'click' event: </br
|
||||
><a id="linkWithClick" onclick="var clicked = true;">This should have state_linked</a
|
||||
><br>Link with title attribute (no name from subtree): </br
|
||||
><a id="linkWithTitleNoNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title"><img src=""/></a
|
||||
><br>Link with title attribute (name from subtree): </br
|
||||
><a id="linkWithTitleNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title">the name from subtree</a
|
||||
><br>Link with title attribute (name from nested image): </br
|
||||
><a id="linkWithTitleNameFromImg" href="http://www.heise.de/"
|
||||
title="Link with title"><img src="" alt="The title for link"/></a
|
||||
><br><label for="linkWithLabelNoNameFromSubtree">Link with label and nested image: </label></br
|
||||
><a id="linkWithLabelNoNameFromSubtree"
|
||||
href="http://www.heise.de/"><img src=""/></a
|
||||
><br>Map that is used to group links (www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass), also see the bug 431615:<br
|
||||
><map id="linksmap" title="Site navigation"><ul
|
||||
><li><a href="http://mozilla.org">About the project</a></li
|
||||
><li><a href="http://mozilla.org">Sites and sounds</a></li
|
||||
></ul
|
||||
></map
|
||||
></body>
|
||||
</html>
|
||||
|
@ -43,22 +43,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
testThis("NormalHyperlink", 14, 0, "Mozilla Foundation");
|
||||
|
||||
// ARIA hyperlink
|
||||
testThis("AriaHyperlink", 28, 1, "Mozilla Foundation Home");
|
||||
testThis("AriaHyperlink", 27, 1, "Mozilla Foundation Home");
|
||||
|
||||
// ARIA hyperlink with status invalid
|
||||
testThis("InvalidAriaHyperlink", 64, 2, "Invalid link");
|
||||
testThis("InvalidAriaHyperlink", 63, 2, "Invalid link");
|
||||
|
||||
// image map, but not its link children. They are not part of hypertext.
|
||||
testThis("imgmap", 78, 3, "b");
|
||||
testThis("imgmap", 76, 3, "b");
|
||||
|
||||
// empty hyperlink
|
||||
testThis("emptyLink", 93, 4, null);
|
||||
testThis("emptyLink", 90, 4, null);
|
||||
|
||||
// normal hyperlink with embedded span
|
||||
testThis("LinkWithSpan", 119, 5, "Heise Online");
|
||||
testThis("LinkWithSpan", 116, 5, "Heise Online");
|
||||
|
||||
// Named anchor
|
||||
testThis("namedAnchor", 197, 6, "This should never be of state_linked");
|
||||
testThis("namedAnchor", 193, 6, "This should never be of state_linked");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
@ -74,37 +74,35 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<p id="testParagraph">
|
||||
<br>Simple link:<br>
|
||||
<a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a>
|
||||
<br>ARIA link:<br>
|
||||
<span id="AriaHyperlink" role="link"
|
||||
onclick="window.open('http://www.mozilla.org/');"
|
||||
tabindex="0">Mozilla Foundation Home</span>
|
||||
<br>Invalid, non-focusable hyperlink:<br>
|
||||
<span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span>
|
||||
<br>Image map:<br>
|
||||
<map name="atoz_map">
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
coords="17,0,30,14"
|
||||
alt="b"
|
||||
shape="rect"></area>
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area>
|
||||
</map>
|
||||
<img width="447" id="imgmap"
|
||||
<p id="testParagraph"><br
|
||||
>Simple link:<br
|
||||
><a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a><br
|
||||
>ARIA link:<br
|
||||
><span id="AriaHyperlink" role="link"
|
||||
onclick="window.open('http://www.mozilla.org/');"
|
||||
tabindex="0">Mozilla Foundation Home</span><br
|
||||
>Invalid, non-focusable hyperlink:<br
|
||||
><span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span><br
|
||||
>Image map:<br
|
||||
><map name="atoz_map"><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
coords="17,0,30,14"
|
||||
alt="b"
|
||||
shape="rect"></area
|
||||
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area></map
|
||||
><img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"></img>
|
||||
<br>Empty link:<br>
|
||||
<a id="emptyLink" href=""><img src=""></img></a>
|
||||
<br>Link with embedded span<br>
|
||||
<a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a>
|
||||
<br>Named anchor, must not have "linked" state for it to be exposed correctly:<br>
|
||||
<a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
|
||||
src="letters.gif"></img><br
|
||||
>Empty link:<br
|
||||
><a id="emptyLink" href=""><img src=""></img></a><br
|
||||
>Link with embedded span<br
|
||||
><a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a><br
|
||||
>Named anchor, must not have "linked" state for it to be exposed correctly:<br
|
||||
><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=475006
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=391829
|
||||
-->
|
||||
<head>
|
||||
<title>Group attributes tests</title>
|
||||
@ -29,6 +30,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=475006
|
||||
testAttrs("checkedOption", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedRadio", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedTreeitem", {"checkable" : "true"}, true);
|
||||
testAttrs("grabbed", {"grabbed" : "true"}, true);
|
||||
testAttrs("dropeffect", {"dropeffect" : "copy"}, true);
|
||||
testAttrs("sortAscending", {"sort" : "ascending"}, true);
|
||||
testAttrs("sortDescending", {"sort" : "descending"}, true);
|
||||
@ -39,6 +41,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=475006
|
||||
testAttrs("live", {"live" : "polite"}, true);
|
||||
testAttrs("live2", {"live" : "polite"}, true);
|
||||
testAttrs("log", {"live" : "polite"}, true);
|
||||
testAttrs("logAssertive", {"live" : "assertive"}, true);
|
||||
testAttrs("marquee", {"live" : "off"}, true);
|
||||
testAttrs("status", {"live" : "polite"}, true);
|
||||
testAttrs("timer", {"live" : "off"}, true);
|
||||
@ -47,13 +50,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=475006
|
||||
testAttrs("liveChild", {"container-live" : "polite"}, true);
|
||||
testAttrs("live2Child", {"container-live" : "polite"}, true);
|
||||
testAttrs("logChild", {"container-live" : "polite"}, true);
|
||||
testAttrs("logAssertiveChild", {"container-live" : "assertive"}, true);
|
||||
testAttrs("marqueeChild", {"container-live" : "off"}, true);
|
||||
testAttrs("statusChild", {"container-live" : "polite"}, true);
|
||||
testAttrs("timerChild", {"container-live" : "off"}, true);
|
||||
|
||||
// container-live-role object attribute
|
||||
testAttrs("log", {"container-live-role" : "log"}, true);
|
||||
testAttrs("logAssertive", {"container-live-role" : "log"}, true);
|
||||
testAttrs("marquee", {"container-live-role" : "marquee"}, true);
|
||||
testAttrs("status", {"container-live-role" : "status"}, true);
|
||||
testAttrs("timer", {"container-live-role" : "timer"}, true);
|
||||
testAttrs("logChild", {"container-live-role" : "log"}, true);
|
||||
testAttrs("logAssertive", {"container-live-role" : "log"}, true);
|
||||
testAttrs("logAssertiveChild", {"container-live-role" : "log"}, true);
|
||||
testAttrs("marqueeChild", {"container-live-role" : "marquee"}, true);
|
||||
testAttrs("statusChild", {"container-live-role" : "status"}, true);
|
||||
testAttrs("timerChild", {"container-live-role" : "timer"}, true);
|
||||
|
||||
// container that has no default live attribute
|
||||
testAttrs("liveGroup", {"live" : "polite"}, true);
|
||||
testAttrs("liveGroupChild", {"container-live" : "polite"}, true);
|
||||
testAttrs("liveGroup", {"container-live-role" : "group"}, true);
|
||||
testAttrs("liveGroupChild", {"container-live-role" : "group"}, true);
|
||||
|
||||
// html
|
||||
testAttrs("radio", {"checkable" : "true"}, true);
|
||||
testAttrs("checkbox", {"checkable" : "true"}, true);
|
||||
testAttrs("draggable", {"draggable" : "true"}, true);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
@ -68,6 +92,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=475006
|
||||
title="Extend nsARIAMap to capture ARIA attribute characteristics">
|
||||
Mozilla Bug 475006
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=391829"
|
||||
title="Add support for container-live-role to object attributes">
|
||||
Mozilla Bug 391829
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
@ -83,6 +112,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=475006
|
||||
<div id="checkedOption" role="option" aria-checked="true"></div>
|
||||
<div id="checkedRadio" role="radio" aria-checked="true"></div>
|
||||
<div id="checkedTreeitem" role="treeitem" aria-checked="true"></div>
|
||||
<div id="grabbed" aria-grabbed="true"></div>
|
||||
<div id="dropeffect" aria-dropeffect="copy"></div>
|
||||
<div id="sortAscending" role="columnheader" aria-sort="ascending"></div>
|
||||
<div id="sortDescending" role="columnheader" aria-sort="descending"></div>
|
||||
@ -92,12 +122,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=475006
|
||||
<div id="live" aria-live="polite">excuse <div id="liveChild">me</div></div>
|
||||
<div id="live2" role="marquee" aria-live="polite">excuse <div id="live2Child">me</div></div>
|
||||
<div id="log" role="log">excuse <div id="logChild">me</div></div>
|
||||
<div id="logAssertive" role="log" aria-live="assertive">excuse <div id="logAssertiveChild">me</div></div>
|
||||
<div id="marquee" role="marquee">excuse <div id="marqueeChild">me</div></div>
|
||||
<div id="status" role="status">excuse <div id="statusChild">me</div></div>
|
||||
<div id="timer" role="timer">excuse <div id="timerChild">me</div></div>
|
||||
|
||||
<!-- unusual live case -->
|
||||
<div id="liveGroup" role="group" aria-live="polite">
|
||||
excuse <div id="liveGroupChild">me</div>
|
||||
</div>
|
||||
|
||||
<!-- html -->
|
||||
<input id="radio" type="radio"/>
|
||||
<input id="checkbox" type="checkbox"/>
|
||||
<div id="draggable" draggable="true">Draggable div</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,6 +6,16 @@
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<style type="text/css">
|
||||
.offscreen {
|
||||
position: absolute;
|
||||
left: -5000px;
|
||||
top: -5000px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
@ -40,12 +50,15 @@
|
||||
// disabled, too. See bug 429285.
|
||||
testStatesInSubtree("group", STATE_UNAVAILABLE);
|
||||
|
||||
testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -91,5 +104,9 @@
|
||||
</div>
|
||||
<div role="slider" tabindex="0">A slider</div>
|
||||
</div>
|
||||
|
||||
<div id="offscreen_log" role="log" class="offscreen">
|
||||
<div id="aria_offscreen_textbox" role="textbox" aria-readonly="true">This text should be offscreen</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -60,7 +60,7 @@ function doTest()
|
||||
accNotCreated = (!isAccessible("tr"));
|
||||
ok(!accNotCreated, "missed tr accessible");
|
||||
|
||||
testRole(accTable4, ROLE_NOTHING); // XXX: it's a bug, should be ROLE_TABLE
|
||||
testRole(accTable4, ROLE_TABLE);
|
||||
|
||||
is(accTable4.cellRefAt(0,0).firstChild.name, "cell0", "wrong cell");
|
||||
is(accTable4.cellRefAt(0,1).firstChild.name, "cell1", "wrong cell");
|
||||
|
@ -31,7 +31,7 @@
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
92
accessible/tests/mochitest/test_table_sels_ariagrid.html
Normal file
92
accessible/tests/mochitest/test_table_sels_ariagrid.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=410052
|
||||
-->
|
||||
<head>
|
||||
<title>Table indexes chrome tests</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/table.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// table
|
||||
var cellsArray =
|
||||
[
|
||||
[ true, true, false, true],
|
||||
[ true, false, true, true],
|
||||
[ true, false, false, true],
|
||||
[ true, true, true, true],
|
||||
[ true, true, true, true]
|
||||
];
|
||||
|
||||
testTableSelection("table", cellsArray);
|
||||
testUnselectTableColumn("table", 3, cellsArray);
|
||||
testUnselectTableRow("table", 3, cellsArray);
|
||||
testSelectTableColumn("table", 0, cellsArray);
|
||||
testSelectTableRow("table", 0, cellsArray);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="implement nsIAccessibleTable selection methods for ARIA grids"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div role="grid" id="table">
|
||||
<div role="row">
|
||||
<span role="gridcell" aria-selected="true">cell1</span>
|
||||
<span role="gridcell" aria-selected="true">cell2</span>
|
||||
<span role="gridcell">cell3</span>
|
||||
<span role="gridcell" aria-selected="true">cell4</span>
|
||||
</div>
|
||||
<div role="row">
|
||||
<span role="gridcell" aria-selected="true">cell5</span>
|
||||
<span role="gridcell">cell6</span>
|
||||
<span role="gridcell" aria-selected="true">cell7</span>
|
||||
<span role="gridcell" aria-selected="true">cell8</span>
|
||||
</div>
|
||||
<div role="row">
|
||||
<span role="gridcell" aria-selected="true">cell9</span>
|
||||
<span role="gridcell">cell10</span>
|
||||
<span role="gridcell">cell11</span>
|
||||
<span role="gridcell" aria-selected="true">cell12</span>
|
||||
</div>
|
||||
<div role="row" aria-selected="true">
|
||||
<span role="gridcell">cell13</span>
|
||||
<span role="gridcell">cell14</span>
|
||||
<span role="gridcell">cell15</span>
|
||||
<span role="gridcell">cell16</span>
|
||||
</div>
|
||||
<div role="row">
|
||||
<span role="gridcell" aria-selected="true">cell17</span>
|
||||
<span role="gridcell" aria-selected="true">cell18</span>
|
||||
<span role="gridcell" aria-selected="true">cell19</span>
|
||||
<span role="gridcell" aria-selected="true">cell20</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -197,7 +197,6 @@ pref("browser.startup.homepage", "resource:/browserconfig.properties"
|
||||
pref("browser.enable_automatic_image_resizing", true);
|
||||
pref("browser.chrome.site_icons", true);
|
||||
pref("browser.chrome.favicons", true);
|
||||
pref("browser.formfill.enable", true);
|
||||
pref("browser.warnOnQuit", true);
|
||||
pref("browser.warnOnRestart", true);
|
||||
pref("browser.fullscreen.autohide", true);
|
||||
@ -228,6 +227,10 @@ pref("browser.urlbar.maxRichResults", 12);
|
||||
// be waiting on the timeout too often without many results.
|
||||
pref("browser.urlbar.search.chunkSize", 1000);
|
||||
pref("browser.urlbar.search.timeout", 100);
|
||||
// The amount of time (ms) to wait after the user has stopped typing
|
||||
// before starting to perform autocomplete. 50 is the default set in
|
||||
// autocomplete.xml.
|
||||
pref("browser.urlbar.delay", 50);
|
||||
|
||||
// The special characters below can be typed into the urlbar to either restrict
|
||||
// the search to visited history, bookmarked, tagged pages; or force a match on
|
||||
|
@ -451,7 +451,8 @@
|
||||
accesskey="&historyMenu.accesskey;">
|
||||
<menupopup id="goPopup"
|
||||
type="places"
|
||||
onpopupshowing="HistoryMenu.onPopupShowing(this);"
|
||||
onpopupshowing="HistoryMenu.onPopupShowing(event);"
|
||||
onpopuphidden="HistoryMenu.onPopupHidden(event);"
|
||||
place="place:redirectsMode=2&sort=4&maxResults=10"
|
||||
tooltip="btTooltip">
|
||||
<menuitem id="historyMenuBack"
|
||||
|
@ -580,33 +580,193 @@ var PlacesCommandHook = {
|
||||
}
|
||||
};
|
||||
|
||||
// Functions for the history menu.
|
||||
// Helper object for the history menu.
|
||||
var HistoryMenu = {
|
||||
get _ss() {
|
||||
delete this._ss;
|
||||
return this._ss = Components.classes["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Components.interfaces.nsISessionStore);
|
||||
return this._ss = Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
},
|
||||
|
||||
toggleRecentlyClosedTabs: function PHM_toggleRecentlyClosedTabs() {
|
||||
// enable/disable the Recently Closed Tabs sub menu
|
||||
var undoPopup = document.getElementById("historyUndoPopup");
|
||||
|
||||
// no restorable tabs, so disable menu
|
||||
if (this._ss.getClosedTabCount(window) == 0)
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
else
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
},
|
||||
|
||||
/**
|
||||
* Re-open a closed tab and put it to the end of the tab strip.
|
||||
* Used for a middle click.
|
||||
* @param aEvent
|
||||
* The event when the user clicks the menu item
|
||||
*/
|
||||
_undoCloseMiddleClick: function PHM__undoCloseMiddleClick(aEvent) {
|
||||
if (aEvent.button != 1)
|
||||
return;
|
||||
|
||||
undoCloseTab(aEvent.originalTarget.value);
|
||||
gBrowser.moveTabToEnd();
|
||||
},
|
||||
|
||||
/**
|
||||
* Populate when the history menu is opened
|
||||
*/
|
||||
populateUndoSubmenu: function PHM_populateUndoSubmenu() {
|
||||
var undoPopup = document.getElementById("historyUndoPopup");
|
||||
|
||||
// remove existing menu items
|
||||
while (undoPopup.hasChildNodes())
|
||||
undoPopup.removeChild(undoPopup.firstChild);
|
||||
|
||||
// no restorable tabs, so make sure menu is disabled, and return
|
||||
if (this._ss.getClosedTabCount(window) == 0) {
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
return;
|
||||
}
|
||||
|
||||
// enable menu
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
|
||||
// populate menu
|
||||
var undoItems = eval("(" + this._ss.getClosedTabData(window) + ")");
|
||||
for (var i = 0; i < undoItems.length; i++) {
|
||||
var m = document.createElement("menuitem");
|
||||
m.setAttribute("label", undoItems[i].title);
|
||||
if (undoItems[i].image) {
|
||||
let iconURL = undoItems[i].image;
|
||||
// don't initiate a connection just to fetch a favicon (see bug 467828)
|
||||
if (/^https?:/.test(iconURL))
|
||||
iconURL = "moz-anno:favicon:" + iconURL;
|
||||
m.setAttribute("image", iconURL);
|
||||
}
|
||||
m.setAttribute("class", "menuitem-iconic bookmark-item");
|
||||
m.setAttribute("value", i);
|
||||
m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
|
||||
m.addEventListener("click", this._undoCloseMiddleClick, false);
|
||||
if (i == 0)
|
||||
m.setAttribute("key", "key_undoCloseTab");
|
||||
undoPopup.appendChild(m);
|
||||
}
|
||||
|
||||
// "Open All in Tabs"
|
||||
var strings = gNavigatorBundle;
|
||||
undoPopup.appendChild(document.createElement("menuseparator"));
|
||||
m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.setAttribute("label", strings.getString("menuOpenAllInTabs.label"));
|
||||
m.setAttribute("accesskey", strings.getString("menuOpenAllInTabs.accesskey"));
|
||||
m.addEventListener("command", function() {
|
||||
for (var i = 0; i < undoItems.length; i++)
|
||||
undoCloseTab();
|
||||
}, false);
|
||||
},
|
||||
|
||||
toggleRecentlyClosedWindows: function PHM_toggleRecentlyClosedWindows() {
|
||||
// enable/disable the Recently Closed Windows sub menu
|
||||
let undoPopup = document.getElementById("historyUndoWindowPopup");
|
||||
|
||||
// no restorable windows, so disable menu
|
||||
if (this._ss.getClosedWindowCount() == 0)
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
else
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
},
|
||||
|
||||
/**
|
||||
* Populate when the history menu is opened
|
||||
*/
|
||||
populateUndoWindowSubmenu: function PHM_populateUndoWindowSubmenu() {
|
||||
let undoPopup = document.getElementById("historyUndoWindowPopup");
|
||||
let menuLabelString = gNavigatorBundle.getString("menuUndoCloseWindowLabel");
|
||||
let menuLabelStringSingleTab =
|
||||
gNavigatorBundle.getString("menuUndoCloseWindowSingleTabLabel");
|
||||
|
||||
// remove existing menu items
|
||||
while (undoPopup.hasChildNodes())
|
||||
undoPopup.removeChild(undoPopup.firstChild);
|
||||
|
||||
// no restorable windows, so make sure menu is disabled, and return
|
||||
if (this._ss.getClosedWindowCount() == 0) {
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
return;
|
||||
}
|
||||
|
||||
// enable menu
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
|
||||
// populate menu
|
||||
let undoItems = JSON.parse(this._ss.getClosedWindowData());
|
||||
for (let i = 0; i < undoItems.length; i++) {
|
||||
let undoItem = undoItems[i];
|
||||
let otherTabsCount = undoItem.tabs.length - 1;
|
||||
let label = (otherTabsCount == 0) ? menuLabelStringSingleTab
|
||||
: PluralForm.get(otherTabsCount, menuLabelString);
|
||||
let menuLabel = label.replace("#1", undoItem.title)
|
||||
.replace("#2", otherTabsCount);
|
||||
let m = document.createElement("menuitem");
|
||||
m.setAttribute("label", menuLabel);
|
||||
let selectedTab = undoItem.tabs[undoItem.selected - 1];
|
||||
if (selectedTab.attributes.image) {
|
||||
let iconURL = selectedTab.attributes.image;
|
||||
// don't initiate a connection just to fetch a favicon (see bug 467828)
|
||||
if (/^https?:/.test(iconURL))
|
||||
iconURL = "moz-anno:favicon:" + iconURL;
|
||||
m.setAttribute("image", iconURL);
|
||||
}
|
||||
m.setAttribute("class", "menuitem-iconic bookmark-item");
|
||||
m.setAttribute("oncommand", "undoCloseWindow(" + i + ");");
|
||||
if (i == 0)
|
||||
m.setAttribute("key", "key_undoCloseWindow");
|
||||
undoPopup.appendChild(m);
|
||||
}
|
||||
|
||||
// "Open All in Windows"
|
||||
undoPopup.appendChild(document.createElement("menuseparator"));
|
||||
let m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
|
||||
m.setAttribute("accesskey", gNavigatorBundle.getString("menuRestoreAllWindows.accesskey"));
|
||||
m.setAttribute("oncommand",
|
||||
"for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
|
||||
},
|
||||
|
||||
/**
|
||||
* popupshowing handler for the history menu.
|
||||
* @param aMenuPopup
|
||||
* XULNode for the history menupopup
|
||||
* @param aEvent
|
||||
* The popupshowing event.
|
||||
*/
|
||||
onPopupShowing: function PHM_onPopupShowing(aMenuPopup) {
|
||||
var resultNode = aMenuPopup.getResultNode();
|
||||
var wasOpen = resultNode.containerOpen;
|
||||
onPopupShowing: function PHM_onPopupShowing(aEvent) {
|
||||
// Don't handle events for submenus.
|
||||
if (aEvent.target != aEvent.currentTarget)
|
||||
return;
|
||||
|
||||
var menuPopup = aEvent.target;
|
||||
var resultNode = menuPopup.getResultNode();
|
||||
resultNode.containerOpen = true;
|
||||
document.getElementById("endHistorySeparator").hidden =
|
||||
resultNode.childCount == 0;
|
||||
|
||||
if (!wasOpen)
|
||||
resultNode.containerOpen = false;
|
||||
|
||||
// HistoryMenu.toggleRecentlyClosedTabs, HistoryMenu.toggleRecentlyClosedWindows
|
||||
// are defined in browser.js
|
||||
this.toggleRecentlyClosedTabs();
|
||||
this.toggleRecentlyClosedWindows();
|
||||
},
|
||||
|
||||
/**
|
||||
* popuphidden handler for the history menu.
|
||||
* @param aEvent
|
||||
* The popuphidden event.
|
||||
*/
|
||||
onPopupHidden: function PHM_onPopupHidden(aEvent) {
|
||||
// Don't handle events for submenus.
|
||||
if (aEvent.target != aEvent.currentTarget)
|
||||
return;
|
||||
|
||||
var menuPopup = aEvent.target;
|
||||
var resultNode = menuPopup.getResultNode();
|
||||
if (resultNode.containerOpen)
|
||||
resultNode.containerOpen = false;
|
||||
}
|
||||
};
|
||||
|
||||
@ -699,7 +859,7 @@ var BookmarksEventHandler = {
|
||||
|
||||
var itemId = target._resultNode.itemId;
|
||||
var siteURIString = "";
|
||||
if (itemId != -1 && PlacesUtils.livemarks.isLivemark(itemId)) {
|
||||
if (itemId != -1 && PlacesUtils.itemIsLivemark(itemId)) {
|
||||
var siteURI = PlacesUtils.livemarks.getSiteURI(itemId);
|
||||
if (siteURI)
|
||||
siteURIString = siteURI.spec;
|
||||
|
@ -1077,7 +1077,8 @@ function BrowserStartup() {
|
||||
document.documentElement.setAttribute("height", defaultHeight);
|
||||
}
|
||||
|
||||
if (gURLBar && document.documentElement.getAttribute("chromehidden").indexOf("toolbar") != -1) {
|
||||
if (gURLBar &&
|
||||
document.documentElement.getAttribute("chromehidden").indexOf("toolbar") != -1) {
|
||||
gURLBar.setAttribute("readonly", "true");
|
||||
gURLBar.setAttribute("enablehistory", "false");
|
||||
}
|
||||
@ -1237,7 +1238,7 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
focusElement(content);
|
||||
|
||||
if (gURLBar)
|
||||
gURLBar.setAttribute("emptytext", gURLBarEmptyText.value);
|
||||
gURLBar.emptyText = gURLBarEmptyText.value;
|
||||
|
||||
gNavToolbox.customizeDone = BrowserToolboxCustomizeDone;
|
||||
gNavToolbox.customizeChange = BrowserToolboxCustomizeChange;
|
||||
@ -1590,7 +1591,10 @@ function initializeSanitizer()
|
||||
var clearOnShutdownBranch = prefService.getBranch("privacy.clearOnShutdown.");
|
||||
itemArray.forEach(function (name) {
|
||||
try {
|
||||
cpdBranch.setBoolPref(name, itemBranch.getBoolPref(name));
|
||||
// don't migrate password or offlineApps clearing in the CRH dialog since
|
||||
// there's no UI for those anymore. They default to false. bug 497656
|
||||
if (name != "passwords" && name != "offlineApps")
|
||||
cpdBranch.setBoolPref(name, itemBranch.getBoolPref(name));
|
||||
clearOnShutdownBranch.setBoolPref(name, itemBranch.getBoolPref(name));
|
||||
}
|
||||
catch(e) {
|
||||
@ -2298,16 +2302,6 @@ function PageProxyClearIcon ()
|
||||
gProxyFavIcon.removeAttribute("src");
|
||||
}
|
||||
|
||||
|
||||
function PageProxyDragGesture(aEvent)
|
||||
{
|
||||
if (gProxyFavIcon.getAttribute("pageproxystate") == "valid") {
|
||||
nsDragAndDrop.startDrag(aEvent, proxyIconDNDObserver);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function PageProxyClickHandler(aEvent)
|
||||
{
|
||||
if (aEvent.button == 1 && gPrefService.getBoolPref("middlemouse.paste"))
|
||||
@ -2664,56 +2658,88 @@ function FillInHTMLTooltip(tipElement)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
var browserDragAndDrop = {
|
||||
getDragURLFromDataTransfer : function (dt)
|
||||
{
|
||||
var types = dt.types;
|
||||
for (var t = 0; t < types.length; t++) {
|
||||
var type = types[t];
|
||||
switch (type) {
|
||||
case "text/uri-list":
|
||||
var url = dt.getData("URL").replace(/^\s+|\s+$/g, "");
|
||||
return [url, url];
|
||||
case "text/plain":
|
||||
case "text/x-moz-text-internal":
|
||||
var url = dt.getData(type).replace(/^\s+|\s+$/g, "");
|
||||
return [url, url];
|
||||
case "text/x-moz-url":
|
||||
var split = dt.getData(type).split("\n");
|
||||
return [split[0], split[1]];
|
||||
case "application/x-moz-file":
|
||||
var file = dt.mozGetDataAt(type, 0);
|
||||
var name = file instanceof Components.interfaces.nsIFile ? file.leafName : "";
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
var fileHandler = ioService.getProtocolHandler("file")
|
||||
.QueryInterface(Components.interfaces.nsIFileProtocolHandler);
|
||||
return [fileHandler.getURLSpecFromFile(file), name];
|
||||
}
|
||||
}
|
||||
return [ , ];
|
||||
},
|
||||
|
||||
dragOver : function (aEvent, statusString)
|
||||
{
|
||||
var types = aEvent.dataTransfer.types;
|
||||
if (types.contains("application/x-moz-file") ||
|
||||
types.contains("text/x-moz-url") ||
|
||||
types.contains("text/uri-list") ||
|
||||
types.contains("text/plain")) {
|
||||
aEvent.preventDefault();
|
||||
|
||||
if (statusString) {
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = gNavigatorBundle.getString(statusString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var proxyIconDNDObserver = {
|
||||
onDragStart: function (aEvent, aXferData, aDragAction)
|
||||
{
|
||||
if (gProxyFavIcon.getAttribute("pageproxystate") != "valid")
|
||||
return;
|
||||
|
||||
var value = content.location.href;
|
||||
var urlString = value + "\n" + content.document.title;
|
||||
var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
|
||||
|
||||
aXferData.data = new TransferData();
|
||||
aXferData.data.addDataForFlavour("text/x-moz-url", urlString);
|
||||
aXferData.data.addDataForFlavour("text/unicode", value);
|
||||
aXferData.data.addDataForFlavour("text/html", htmlString);
|
||||
|
||||
// we're copying the URL from the proxy icon, not moving
|
||||
// we specify all of them though, because d&d sucks and OS's
|
||||
// get confused if they don't get the one they want
|
||||
aDragAction.action =
|
||||
Components.interfaces.nsIDragService.DRAGDROP_ACTION_COPY |
|
||||
Components.interfaces.nsIDragService.DRAGDROP_ACTION_MOVE |
|
||||
Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
||||
var dt = aEvent.dataTransfer;
|
||||
dt.setData("text/x-moz-url", urlString);
|
||||
dt.setData("text/uri-list", value);
|
||||
dt.setData("text/plain", value);
|
||||
dt.setData("text/html", htmlString);
|
||||
}
|
||||
}
|
||||
|
||||
var homeButtonObserver = {
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
onDrop: function (aEvent)
|
||||
{
|
||||
var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
|
||||
let url = browserDragAndDrop.getDragURLFromDataTransfer(aEvent.dataTransfer)[0];
|
||||
setTimeout(openHomeDialog, 0, url);
|
||||
},
|
||||
|
||||
onDragOver: function (aEvent, aFlavour, aDragSession)
|
||||
onDragOver: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = gNavigatorBundle.getString("droponhomebutton");
|
||||
aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
||||
browserDragAndDrop.dragOver(aEvent, "droponhomebutton");
|
||||
aEvent.dropEffect = "link";
|
||||
},
|
||||
|
||||
onDragExit: function (aEvent, aDragSession)
|
||||
onDragLeave: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = "";
|
||||
},
|
||||
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
flavourSet.appendFlavour("text/x-moz-text-internal"); // for tabs
|
||||
return flavourSet;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2742,136 +2768,100 @@ function openHomeDialog(aURL)
|
||||
}
|
||||
|
||||
var bookmarksButtonObserver = {
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
onDrop: function (aEvent)
|
||||
{
|
||||
var split = aXferData.data.split("\n");
|
||||
var url = split[0];
|
||||
if (url != aXferData.data) // do nothing if it's not a valid URL
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(url), split[1]);
|
||||
let [url, name] = browserDragAndDrop.getDragURLFromDataTransfer(aEvent.dataTransfer);
|
||||
try {
|
||||
PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(url), name);
|
||||
} catch(ex) { }
|
||||
},
|
||||
|
||||
onDragOver: function (aEvent, aFlavour, aDragSession)
|
||||
onDragOver: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = gNavigatorBundle.getString("droponbookmarksbutton");
|
||||
aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
||||
browserDragAndDrop.dragOver(aEvent, "droponbookmarksbutton");
|
||||
aEvent.dropEffect = "link";
|
||||
},
|
||||
|
||||
onDragExit: function (aEvent, aDragSession)
|
||||
onDragLeave: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = "";
|
||||
},
|
||||
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
return flavourSet;
|
||||
}
|
||||
}
|
||||
|
||||
var newTabButtonObserver = {
|
||||
onDragOver: function(aEvent, aFlavour, aDragSession) {
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = gNavigatorBundle.getString("droponnewtabbutton");
|
||||
return true;
|
||||
onDragOver: function (aEvent)
|
||||
{
|
||||
browserDragAndDrop.dragOver(aEvent, "droponnewtabbutton");
|
||||
},
|
||||
onDragExit: function (aEvent, aDragSession) {
|
||||
|
||||
onDragLeave: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = "";
|
||||
},
|
||||
onDrop: function (aEvent, aXferData, aDragSession) {
|
||||
var xferData = aXferData.data.split("\n");
|
||||
var draggedText = xferData[0] || xferData[1];
|
||||
|
||||
onDrop: function (aEvent)
|
||||
{
|
||||
let url = browserDragAndDrop.getDragURLFromDataTransfer(aEvent.dataTransfer)[0];
|
||||
var postData = {};
|
||||
var url = getShortcutOrURI(draggedText, postData);
|
||||
url = getShortcutOrURI(url, postData);
|
||||
if (url) {
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, null, url);
|
||||
// allow third-party services to fixup this URL
|
||||
openNewTabWith(url, null, postData.value, aEvent, true);
|
||||
}
|
||||
},
|
||||
getSupportedFlavours: function () {
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
return flavourSet;
|
||||
}
|
||||
}
|
||||
|
||||
var newWindowButtonObserver = {
|
||||
onDragOver: function(aEvent, aFlavour, aDragSession)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = gNavigatorBundle.getString("droponnewwindowbutton");
|
||||
return true;
|
||||
},
|
||||
onDragExit: function (aEvent, aDragSession)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = "";
|
||||
},
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
{
|
||||
var xferData = aXferData.data.split("\n");
|
||||
var draggedText = xferData[0] || xferData[1];
|
||||
var postData = {};
|
||||
var url = getShortcutOrURI(draggedText, postData);
|
||||
if (url) {
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
|
||||
// allow third-party services to fixup this URL
|
||||
openNewWindowWith(url, null, postData.value, true);
|
||||
}
|
||||
},
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
flavourSet.appendFlavour("text/x-moz-text-internal"); // for tabs
|
||||
return flavourSet;
|
||||
onDragOver: function (aEvent)
|
||||
{
|
||||
browserDragAndDrop.dragOver(aEvent, "droponnewwindowbutton");
|
||||
},
|
||||
onDragLeave: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = "";
|
||||
},
|
||||
onDrop: function (aEvent)
|
||||
{
|
||||
let url = browserDragAndDrop.getDragURLFromDataTransfer(aEvent.dataTransfer)[0];
|
||||
var postData = {};
|
||||
url = getShortcutOrURI(url, postData);
|
||||
if (url) {
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, null, url);
|
||||
// allow third-party services to fixup this URL
|
||||
openNewWindowWith(url, null, postData.value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var DownloadsButtonDNDObserver = {
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsDragAndDrop
|
||||
onDragOver: function (aEvent, aFlavour, aDragSession)
|
||||
onDragOver: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = gNavigatorBundle.getString("dropondownloadsbutton");
|
||||
aDragSession.canDrop = (aFlavour.contentType == "text/x-moz-url" ||
|
||||
aFlavour.contentType == "text/unicode");
|
||||
var types = aEvent.dataTransfer.types;
|
||||
if (types.contains("text/x-moz-url") ||
|
||||
types.contains("text/uri-list") ||
|
||||
types.contains("text/plain"))
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
onDragExit: function (aEvent, aDragSession)
|
||||
onDragLeave: function (aEvent)
|
||||
{
|
||||
var statusTextFld = document.getElementById("statusbar-display");
|
||||
statusTextFld.label = "";
|
||||
},
|
||||
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
onDrop: function (aEvent)
|
||||
{
|
||||
var split = aXferData.data.split("\n");
|
||||
var url = split[0];
|
||||
if (url != aXferData.data) { //do nothing, not a valid URL
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
|
||||
|
||||
var name = split[1];
|
||||
saveURL(url, name, null, true, true);
|
||||
}
|
||||
},
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("text/unicode");
|
||||
return flavourSet;
|
||||
let [url, name] = browserDragAndDrop.getDragURLFromDataTransfer(aEvent.dataTransfer);
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, null, url);
|
||||
saveURL(url, name, null, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4527,14 +4517,15 @@ function onViewToolbarsPopupShowing(aEvent)
|
||||
for (i = 0; i < gNavToolbox.childNodes.length; ++i) {
|
||||
var toolbar = gNavToolbox.childNodes[i];
|
||||
var toolbarName = toolbar.getAttribute("toolbarname");
|
||||
var type = toolbar.getAttribute("type");
|
||||
if (toolbarName && type != "menubar") {
|
||||
var menuItem = document.createElement("menuitem");
|
||||
if (toolbarName) {
|
||||
let menuItem = document.createElement("menuitem");
|
||||
let hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
|
||||
"autohide" : "collapsed";
|
||||
menuItem.setAttribute("toolbarindex", i);
|
||||
menuItem.setAttribute("type", "checkbox");
|
||||
menuItem.setAttribute("label", toolbarName);
|
||||
menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
|
||||
menuItem.setAttribute("checked", toolbar.getAttribute("collapsed") != "true");
|
||||
menuItem.setAttribute("checked", toolbar.getAttribute(hidingAttribute) != "true");
|
||||
popup.insertBefore(menuItem, firstMenuItem);
|
||||
|
||||
menuItem.addEventListener("command", onViewToolbarCommand, false);
|
||||
@ -4547,9 +4538,12 @@ function onViewToolbarCommand(aEvent)
|
||||
{
|
||||
var index = aEvent.originalTarget.getAttribute("toolbarindex");
|
||||
var toolbar = gNavToolbox.childNodes[index];
|
||||
var hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
|
||||
"autohide" : "collapsed";
|
||||
|
||||
toolbar.collapsed = aEvent.originalTarget.getAttribute("checked") != "true";
|
||||
document.persist(toolbar.id, "collapsed");
|
||||
toolbar.setAttribute(hidingAttribute,
|
||||
aEvent.originalTarget.getAttribute("checked") != "true");
|
||||
document.persist(toolbar.id, hidingAttribute);
|
||||
}
|
||||
|
||||
function displaySecurityInfo()
|
||||
@ -4960,13 +4954,7 @@ function handleLinkClick(event, href, linkNode)
|
||||
|
||||
return false;
|
||||
case 1: // if middle button clicked
|
||||
var tab;
|
||||
try {
|
||||
tab = gPrefService.getBoolPref("browser.tabs.opentabfor.middleclick")
|
||||
}
|
||||
catch(ex) {
|
||||
tab = true;
|
||||
}
|
||||
var tab = gPrefService.getBoolPref("browser.tabs.opentabfor.middleclick");
|
||||
if (tab)
|
||||
openNewTabWith(href, doc, null, event, false);
|
||||
else
|
||||
@ -5013,15 +5001,21 @@ function middleMousePaste(event)
|
||||
*/
|
||||
|
||||
var contentAreaDNDObserver = {
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
onDragOver: function (aEvent)
|
||||
{
|
||||
var types = aEvent.dataTransfer.types;
|
||||
if (types.contains("application/x-moz-file") ||
|
||||
types.contains("text/x-moz-url") ||
|
||||
types.contains("text/uri-list") ||
|
||||
types.contains("text/plain"))
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
onDrop: function (aEvent)
|
||||
{
|
||||
if (aEvent.getPreventDefault())
|
||||
return;
|
||||
|
||||
var dragType = aXferData.flavour.contentType;
|
||||
var dragData = aXferData.data;
|
||||
|
||||
var url = transferUtils.retrieveURLFromData(dragData, dragType);
|
||||
let [url, name] = browserDragAndDrop.getDragURLFromDataTransfer(aEvent.dataTransfer);
|
||||
|
||||
// valid urls don't contain spaces ' '; if we have a space it
|
||||
// isn't a valid url, or if it's a javascript: or data: url,
|
||||
@ -5030,7 +5024,7 @@ var contentAreaDNDObserver = {
|
||||
/^\s*(javascript|data):/.test(url))
|
||||
return;
|
||||
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
|
||||
nsDragAndDrop.dragDropSecurityCheck(aEvent, null, url);
|
||||
|
||||
switch (document.documentElement.getAttribute('windowtype')) {
|
||||
case "navigator:browser":
|
||||
@ -5046,18 +5040,7 @@ var contentAreaDNDObserver = {
|
||||
// keep the event from being handled by the dragDrop listeners
|
||||
// built-in to gecko if they happen to be above us.
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
var flavourSet = new FlavourSet();
|
||||
flavourSet.appendFlavour(TAB_DROP_TYPE);
|
||||
flavourSet.appendFlavour("text/x-moz-url");
|
||||
flavourSet.appendFlavour("text/plain");
|
||||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
return flavourSet;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function MultiplexHandler(event)
|
||||
@ -6248,151 +6231,6 @@ var FeedHandler = {
|
||||
|
||||
#include browser-tabPreviews.js
|
||||
|
||||
HistoryMenu.toggleRecentlyClosedTabs = function PHM_toggleRecentlyClosedTabs() {
|
||||
// enable/disable the Recently Closed Tabs sub menu
|
||||
var undoPopup = document.getElementById("historyUndoPopup");
|
||||
|
||||
// no restorable tabs, so disable menu
|
||||
if (this._ss.getClosedTabCount(window) == 0)
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
else
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate when the history menu is opened
|
||||
*/
|
||||
HistoryMenu.populateUndoSubmenu = function PHM_populateUndoSubmenu() {
|
||||
var undoPopup = document.getElementById("historyUndoPopup");
|
||||
|
||||
// remove existing menu items
|
||||
while (undoPopup.hasChildNodes())
|
||||
undoPopup.removeChild(undoPopup.firstChild);
|
||||
|
||||
// no restorable tabs, so make sure menu is disabled, and return
|
||||
if (this._ss.getClosedTabCount(window) == 0) {
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
return;
|
||||
}
|
||||
|
||||
// enable menu
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
|
||||
// populate menu
|
||||
var undoItems = eval("(" + this._ss.getClosedTabData(window) + ")");
|
||||
for (var i = 0; i < undoItems.length; i++) {
|
||||
var m = document.createElement("menuitem");
|
||||
m.setAttribute("label", undoItems[i].title);
|
||||
if (undoItems[i].image) {
|
||||
let iconURL = undoItems[i].image;
|
||||
// don't initiate a connection just to fetch a favicon (see bug 467828)
|
||||
if (/^https?:/.test(iconURL))
|
||||
iconURL = "moz-anno:favicon:" + iconURL;
|
||||
m.setAttribute("image", iconURL);
|
||||
}
|
||||
m.setAttribute("class", "menuitem-iconic bookmark-item");
|
||||
m.setAttribute("value", i);
|
||||
m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
|
||||
m.addEventListener("click", undoCloseMiddleClick, false);
|
||||
if (i == 0)
|
||||
m.setAttribute("key", "key_undoCloseTab");
|
||||
undoPopup.appendChild(m);
|
||||
}
|
||||
|
||||
// "Open All in Tabs"
|
||||
var strings = gNavigatorBundle;
|
||||
undoPopup.appendChild(document.createElement("menuseparator"));
|
||||
m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.setAttribute("label", strings.getString("menuOpenAllInTabs.label"));
|
||||
m.setAttribute("accesskey", strings.getString("menuOpenAllInTabs.accesskey"));
|
||||
m.addEventListener("command", function() {
|
||||
for (var i = 0; i < undoItems.length; i++)
|
||||
undoCloseTab();
|
||||
}, false);
|
||||
}
|
||||
|
||||
HistoryMenu.toggleRecentlyClosedWindows = function PHM_toggleRecentlyClosedWindows() {
|
||||
// enable/disable the Recently Closed Windows sub menu
|
||||
let undoPopup = document.getElementById("historyUndoWindowPopup");
|
||||
|
||||
// no restorable windows, so disable menu
|
||||
if (this._ss.getClosedWindowCount() == 0)
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
else
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate when the history menu is opened
|
||||
*/
|
||||
HistoryMenu.populateUndoWindowSubmenu = function PHM_populateUndoWindowSubmenu() {
|
||||
let undoPopup = document.getElementById("historyUndoWindowPopup");
|
||||
let menuLabelString = gNavigatorBundle.getString("menuUndoCloseWindowLabel");
|
||||
let menuLabelStringSingleTab =
|
||||
gNavigatorBundle.getString("menuUndoCloseWindowSingleTabLabel");
|
||||
|
||||
// remove existing menu items
|
||||
while (undoPopup.hasChildNodes())
|
||||
undoPopup.removeChild(undoPopup.firstChild);
|
||||
|
||||
// no restorable windows, so make sure menu is disabled, and return
|
||||
if (this._ss.getClosedWindowCount() == 0) {
|
||||
undoPopup.parentNode.setAttribute("disabled", true);
|
||||
return;
|
||||
}
|
||||
|
||||
// enable menu
|
||||
undoPopup.parentNode.removeAttribute("disabled");
|
||||
|
||||
// populate menu
|
||||
let undoItems = JSON.parse(this._ss.getClosedWindowData());
|
||||
for (let i = 0; i < undoItems.length; i++) {
|
||||
let undoItem = undoItems[i];
|
||||
let otherTabsCount = undoItem.tabs.length - 1;
|
||||
let label = (otherTabsCount == 0) ? menuLabelStringSingleTab
|
||||
: PluralForm.get(otherTabsCount, menuLabelString);
|
||||
let menuLabel = label.replace("#1", undoItem.title)
|
||||
.replace("#2", otherTabsCount);
|
||||
let m = document.createElement("menuitem");
|
||||
m.setAttribute("label", menuLabel);
|
||||
let selectedTab = undoItem.tabs[undoItem.selected - 1];
|
||||
if (selectedTab.attributes.image) {
|
||||
let iconURL = selectedTab.attributes.image;
|
||||
// don't initiate a connection just to fetch a favicon (see bug 467828)
|
||||
if (/^https?:/.test(iconURL))
|
||||
iconURL = "moz-anno:favicon:" + iconURL;
|
||||
m.setAttribute("image", iconURL);
|
||||
}
|
||||
m.setAttribute("class", "menuitem-iconic bookmark-item");
|
||||
m.setAttribute("oncommand", "undoCloseWindow(" + i + ");");
|
||||
if (i == 0)
|
||||
m.setAttribute("key", "key_undoCloseWindow");
|
||||
undoPopup.appendChild(m);
|
||||
}
|
||||
|
||||
// "Open All in Windows"
|
||||
undoPopup.appendChild(document.createElement("menuseparator"));
|
||||
let m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
|
||||
m.setAttribute("accesskey", gNavigatorBundle.getString("menuRestoreAllWindows.accesskey"));
|
||||
m.setAttribute("oncommand",
|
||||
"for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-open a closed tab and put it to the end of the tab strip.
|
||||
* Used for a middle click.
|
||||
* @param aEvent
|
||||
* The event when the user clicks the menu item
|
||||
*/
|
||||
function undoCloseMiddleClick(aEvent) {
|
||||
if (aEvent.button != 1)
|
||||
return;
|
||||
|
||||
undoCloseTab(aEvent.originalTarget.value);
|
||||
gBrowser.moveTabToEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-open a closed tab.
|
||||
* @param aIndex
|
||||
|
@ -284,6 +284,10 @@
|
||||
<toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
|
||||
defaultset="menubar-items"
|
||||
mode="icons" iconsize="small" defaulticonsize="small"
|
||||
#ifdef XP_WIN
|
||||
toolbarname="&menubarCmd.label;"
|
||||
accesskey="&menubarCmd.accesskey;"
|
||||
#endif
|
||||
context="toolbar-context-menu">
|
||||
<toolbaritem id="menubar-items" align="center">
|
||||
# The entire main menubar is placed into browser-menubar.inc, so that it can be shared by
|
||||
@ -340,9 +344,10 @@
|
||||
<toolbarbutton id="home-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
persist="class"
|
||||
label="&homeButton.label;"
|
||||
ondragover="nsDragAndDrop.dragOver(event, homeButtonObserver);"
|
||||
ondragdrop="nsDragAndDrop.drop(event, homeButtonObserver);"
|
||||
ondragexit="nsDragAndDrop.dragExit(event, homeButtonObserver);"
|
||||
ondragover="homeButtonObserver.onDragOver(event)"
|
||||
ondragenter="homeButtonObserver.onDragOver(event)"
|
||||
ondrop="homeButtonObserver.onDrop(event)"
|
||||
ondragleave="homeButtonObserver.onDragLeave(event)"
|
||||
onclick="BrowserGoHome(event);"/>
|
||||
|
||||
<toolbaritem id="urlbar-container" align="center" flex="400" persist="width"
|
||||
@ -370,7 +375,7 @@
|
||||
onsearchbegin="LocationBarHelpers._searchBegin();"
|
||||
onsearchcomplete="LocationBarHelpers._searchComplete();"
|
||||
onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
|
||||
onblur="document.getElementById('identity-box').style.MozUserFocus = 'ignore';">
|
||||
onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);">
|
||||
<!-- Use onclick instead of normal popup= syntax since the popup
|
||||
code fires onmousedown, and hence eats our favicon drag events.
|
||||
We only add the identity-box button to the tab order when the location bar
|
||||
@ -385,7 +390,7 @@
|
||||
<image id="urlbar-throbber" busy="false"/>
|
||||
<image id="page-proxy-favicon" validate="never"
|
||||
pageproxystate="invalid"
|
||||
ondraggesture="PageProxyDragGesture(event);"
|
||||
ondragstart="proxyIconDNDObserver.onDragStart(event);"
|
||||
onerror="this.removeAttribute('src');"/>
|
||||
</stack>
|
||||
<label id="identity-icon-label" crop="center" flex="1"/>
|
||||
@ -445,10 +450,10 @@
|
||||
|
||||
<toolbarbutton id="downloads-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
observes="Tools:Downloads"
|
||||
ondragdrop="nsDragAndDrop.drop(event, DownloadsButtonDNDObserver); event.stopPropagation()"
|
||||
ondragover="nsDragAndDrop.dragOver(event, DownloadsButtonDNDObserver); event.stopPropagation()"
|
||||
ondragenter="nsDragAndDrop.dragEnter(event, DownloadsButtonDNDObserver); event.stopPropagation()"
|
||||
ondragexit="nsDragAndDrop.dragExit(event, DownloadsButtonDNDObserver); event.stopPropagation()"
|
||||
ondrop="DownloadsButtonDNDObserver.onDrop(event)"
|
||||
ondragover="DownloadsButtonDNDObserver.onDragOver(event)"
|
||||
ondragenter="DownloadsButtonDNDObserver.onDragOver(event)"
|
||||
ondragleave="DownloadsButtonDNDObserver.onDragLeave(event)"
|
||||
label="&downloads.label;"
|
||||
tooltiptext="&downloads.tooltip;"/>
|
||||
|
||||
@ -459,25 +464,28 @@
|
||||
<toolbarbutton id="bookmarks-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
observes="viewBookmarksSidebar"
|
||||
tooltiptext="&bookmarksButton.tooltip;"
|
||||
ondragover="nsDragAndDrop.dragOver(event, bookmarksButtonObserver);"
|
||||
ondragdrop="nsDragAndDrop.drop(event, bookmarksButtonObserver);"
|
||||
ondragexit="nsDragAndDrop.dragExit(event, bookmarksButtonObserver);"/>
|
||||
ondrop="bookmarksButtonObserver.onDrop(event)"
|
||||
ondragover="bookmarksButtonObserver.onDragOver(event)"
|
||||
ondragenter="bookmarksButtonObserver.onDragOver(event)"
|
||||
ondragleave="bookmarksButtonObserver.onDragLeave(event)"/>
|
||||
|
||||
<toolbarbutton id="new-tab-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&tabCmd.label;"
|
||||
command="cmd_newNavigatorTab"
|
||||
tooltiptext="&newTabButton.tooltip;"
|
||||
ondragover="nsDragAndDrop.dragOver(event, newTabButtonObserver);"
|
||||
ondragdrop="nsDragAndDrop.drop(event, newTabButtonObserver);"
|
||||
ondragexit="nsDragAndDrop.dragExit(event, newTabButtonObserver);"/>
|
||||
ondrop="newTabButtonObserver.onDrop(event)"
|
||||
ondragover="newTabButtonObserver.onDragOver(event)"
|
||||
ondragenter="newTabButtonObserver.onDragOver(event)"
|
||||
ondragleave="newTabButtonObserver.onDragLeave(event)"/>
|
||||
|
||||
<toolbarbutton id="new-window-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&newNavigatorCmd.label;"
|
||||
command="key_newNavigator"
|
||||
tooltiptext="&newWindowButton.tooltip;"
|
||||
ondragover="nsDragAndDrop.dragOver(event, newWindowButtonObserver);"
|
||||
ondragdrop="nsDragAndDrop.drop(event, newWindowButtonObserver);"
|
||||
ondragexit="nsDragAndDrop.dragExit(event, newWindowButtonObserver);"/>
|
||||
ondrop="newWindowButtonObserver.onDrop(event)"
|
||||
ondragover="newWindowButtonObserver.onDragOver(event)"
|
||||
ondragenter="newWindowButtonObserver.onDragOver(event)"
|
||||
ondragleave="newWindowButtonObserver.onDragLeave(event)"/>
|
||||
|
||||
<toolbarbutton id="cut-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&cutCmd.label;"
|
||||
@ -553,7 +561,7 @@
|
||||
contentcontextmenu="contentAreaContextMenu"
|
||||
onnewtab="BrowserOpenTab();"
|
||||
autocompletepopup="PopupAutoComplete"
|
||||
ondrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);"
|
||||
ondrop="contentAreaDNDObserver.onDrop(event)"
|
||||
onclick="return contentAreaClick(event, false);"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
@ -567,7 +575,7 @@
|
||||
<findbar browserid="content" id="FindToolbar"/>
|
||||
|
||||
<statusbar class="chromeclass-status" id="status-bar"
|
||||
ondrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);">
|
||||
ondrop="contentAreaDNDObserver.onDrop(event)">
|
||||
<statusbarpanel id="statusbar-display" label="" flex="1"/>
|
||||
<statusbarpanel class="statusbarpanel-progress" collapsed="true" id="statusbar-progresspanel">
|
||||
<progressmeter class="progressmeter-statusbar" id="statusbar-icon" mode="normal" value="0"/>
|
||||
|
@ -220,19 +220,28 @@
|
||||
<ul>
|
||||
<li>Josh Aas</li>
|
||||
<li>Robert Accettura</li>
|
||||
<li>Lucas Adamski</li>
|
||||
<li>Ehsan Akhgari</li>
|
||||
<li>Sean Alamares</li>
|
||||
<li>Pedro Alves</li>
|
||||
<li>David Anderson</li>
|
||||
<li>Harvey Anderson</li>
|
||||
<li>Smokey Ardisson</li>
|
||||
<li>Rob Arnold</li>
|
||||
<li>Tomoya Asai</li>
|
||||
<li>Chris AtLee</li>
|
||||
<li>Dietrich Ayala</li>
|
||||
<li>Mitchell Baker</li>
|
||||
<li>Rhian Baker</li>
|
||||
<li>Jeff Balogh</li>
|
||||
<li>Honza Bambas</li>
|
||||
<li>Jan Bambas</li>
|
||||
<li>Rey Bango</li>
|
||||
<li>Mark Banner</li>
|
||||
<li>Jason Barnabe</li>
|
||||
<li>David Baron</li>
|
||||
<li>Colin Barrett</li>
|
||||
<li>Curtis Bartley</li>
|
||||
<li>Bo Bayles</li>
|
||||
<li>Christopher Beard</li>
|
||||
<li>Glen Beasley</li>
|
||||
@ -244,16 +253,23 @@
|
||||
<li>Christian Biesinger</li>
|
||||
<li>Al Billings</li>
|
||||
<li>Seth Bindernagel</li>
|
||||
<li>Lukas Blakk</li>
|
||||
<li>Jim Blandy</li>
|
||||
<li>Chris Blizzard</li>
|
||||
<li>Jamey Boje</li>
|
||||
<li>David Bolter</li>
|
||||
<li>Nelson Bolyard</li>
|
||||
<li>Marco Bonardo</li>
|
||||
<li>Carsten Book</li>
|
||||
<li>Paul Booker</li>
|
||||
<li>Jennifer Boriss</li>
|
||||
<li>Dan Born</li>
|
||||
<li>Arpad Borsos</li>
|
||||
<li>David Boswell</li>
|
||||
<li>Ondřej Brablc</li>
|
||||
<li>Catherine Brady</li>
|
||||
<li>Dave Bragsalla</li>
|
||||
<li>Alex Buchanan</li>
|
||||
<li>Igor Bukanov</li>
|
||||
<li>Simon Bünzli</li>
|
||||
<li>Lapo Calamandrei</li>
|
||||
@ -266,6 +282,7 @@
|
||||
<li>Emily Chen</li>
|
||||
<li>Ginn Chen</li>
|
||||
<li>Pascal Chevrel</li>
|
||||
<li>Adam Christian</li>
|
||||
<li>Tony Chung</li>
|
||||
<li>Bob Clary</li>
|
||||
<li>Wil Clouser</li>
|
||||
@ -273,17 +290,25 @@
|
||||
<li>Majken Connor</li>
|
||||
<li>Mike Connor</li>
|
||||
<li>Chris Cooper</li>
|
||||
<li>Eric Cooper</li>
|
||||
<li>Paul Craciunoiu</li>
|
||||
<li>Brian Crowder</li>
|
||||
<li>John Daggett</li>
|
||||
<li>David Dahl</li>
|
||||
<li>Michael Davis</li>
|
||||
<li>Neil Deakin</li>
|
||||
<li>Julie Deroche</li>
|
||||
<li>Aakash Desai</li>
|
||||
<li>Ryan Doherty</li>
|
||||
<li>Justin Dolske</li>
|
||||
<li>Stephen Donner</li>
|
||||
<li>Asa Dotzler</li>
|
||||
<li>Chris Double</li>
|
||||
<li>Joe Drew</li>
|
||||
<li>Jason Duell</li>
|
||||
<li>Karsten Düsterloh</li>
|
||||
<li>Brendan Eich</li>
|
||||
<li>Daniel Einspanjer</li>
|
||||
<li>Kai Engert</li>
|
||||
<li>Steve England</li>
|
||||
<li>Madhava Enros</li>
|
||||
@ -300,7 +325,10 @@
|
||||
<li>Ryan Flint</li>
|
||||
<li>Alix Franquet</li>
|
||||
<li>Eli Friedman</li>
|
||||
<li>Andreas Gal</li>
|
||||
<li>Steven Garrity</li>
|
||||
<li>Armen Zambrano Gasparnian</li>
|
||||
<li>Serge Gautherie</li>
|
||||
<li>Kevin Gerich</li>
|
||||
<li>Taras Glek</li>
|
||||
<li>Aravind Gottipati</li>
|
||||
@ -323,30 +351,42 @@
|
||||
<li>Chris Hofmann</li>
|
||||
<li>Timothy Hogan</li>
|
||||
<li>Daniel Holbert</li>
|
||||
<li>Bobby Holley</li>
|
||||
<li>Mike Hommey</li>
|
||||
<li>Stephen Horlander</li>
|
||||
<li>Barbara Hueppe</li>
|
||||
<li>Anthony Hughes</li>
|
||||
<li>David Humphrey</li>
|
||||
<li>Takeshi Ichimaru</li>
|
||||
<li>Chris Ilias</li>
|
||||
<li>Eri Inoue </li>
|
||||
<li>Eri Inoue</li>
|
||||
<li>Joichi Ito</li>
|
||||
<li>Steven Johnson</li>
|
||||
<li>Laurent Jouanneau</li>
|
||||
<li>Robert Kaiser</li>
|
||||
<li>Gen Kanai</li>
|
||||
<li>Masanori Kaneko</li>
|
||||
<li>Blake Kaplan</li>
|
||||
<li>Mike Kaplinskiy</li>
|
||||
<li>Michael Kaply</li>
|
||||
<li>Mitch Kapor</li>
|
||||
<li>Kazuyoshi Kato</li>
|
||||
<li>Tomomi Kato</li>
|
||||
<li>Alfred Kayser</li>
|
||||
<li>Jonathan Kew</li>
|
||||
<li>Paul Kim</li>
|
||||
<li>Masatoshi Kimura</li>
|
||||
<li>Austin King</li>
|
||||
<li>Ria Klaassen</li>
|
||||
<li>Marcia Knous</li>
|
||||
<li>Nelson Ko</li>
|
||||
<li>Michael Kohler</li>
|
||||
<li>Gary Kwong</li>
|
||||
<li>David Lanham</li>
|
||||
<li>Brad Lassey</li>
|
||||
<li>Delphine Lebédel</li>
|
||||
<li>Edward Lee</li>
|
||||
<li>Neil Lee</li>
|
||||
<li>Raymond Lee</li>
|
||||
<li>Garrett LeSage</li>
|
||||
<li>Aaron Leventhal</li>
|
||||
@ -361,14 +401,19 @@
|
||||
<li>Phil Machalski</li>
|
||||
<li>Joel Maher</li>
|
||||
<li>Ere Maijala</li>
|
||||
<li>David Mandelin</li>
|
||||
<li>Gervase Markham</li>
|
||||
<li>Sean Martell</li>
|
||||
<li>Jim Mathies</li>
|
||||
<li>Erica McClure</li>
|
||||
<li>Graeme McCutcheon</li>
|
||||
<li>Patrick McManus</li>
|
||||
<li>Heather Meeker</li>
|
||||
<li>Walter Meinl</li>
|
||||
<li>Myk Melez</li>
|
||||
<li>Federico Mena-Quintero</li>
|
||||
<li>Mark Mentovai</li>
|
||||
<li>Laura Mesa</li>
|
||||
<li>Steven Michaud</li>
|
||||
<li>Matthew Middleton</li>
|
||||
<li>Ted Mielczarek</li>
|
||||
@ -377,24 +422,35 @@
|
||||
<li>Dan Mills</li>
|
||||
<li>Michael Monreal</li>
|
||||
<li>Simon Montagu</li>
|
||||
<li>Derek Moore</li>
|
||||
<li>Mike Morgan</li>
|
||||
<li>Tiffney Mortensen</li>
|
||||
<li>Dan Mosedale</li>
|
||||
<li>Michael Moy</li>
|
||||
<li>Jeff Muizelaar</li>
|
||||
<li>Masayuki Nakano</li>
|
||||
<li>Murali Nandigama</li>
|
||||
<li>Marria Nazif</li>
|
||||
<li>Kev Needham</li>
|
||||
<li>Kaori Negoro</li>
|
||||
<li>Nicholas Nethercote</li>
|
||||
<li>Ben Newman</li>
|
||||
<li>Nick Nguyen</li>
|
||||
<li>Johnathan Nightingale</li>
|
||||
<li>Timothy Nikkel</li>
|
||||
<li>Andreas Nilsson</li>
|
||||
<li>Tristan Nitot</li>
|
||||
<li>Alice Nodelman</li>
|
||||
<li>Matthew Noorenberghe</li>
|
||||
<li>Michal Novotny</li>
|
||||
<li>Robert O'Callahan</li>
|
||||
<li>John O'Duinn</li>
|
||||
<li>Paul O'Shannessy</li>
|
||||
<li>Jan Odvárko</li>
|
||||
<li>Tomoyuki Okazaki</li>
|
||||
<li>Les Orchard</li>
|
||||
<li>Jeremy Orem</li>
|
||||
<li>Jason Orendorff</li>
|
||||
<li>Hideo Oshima</li>
|
||||
<li>Mats Palmgren</li>
|
||||
<li>Stuart Parmenter</li>
|
||||
@ -407,32 +463,43 @@
|
||||
<li>Ulisse Perusin</li>
|
||||
<li>Olli Pettay</li>
|
||||
<li>Julien Pierre</li>
|
||||
<li>Anthony Piraino</li>
|
||||
<li>Alex Polvi</li>
|
||||
<li>Nickolay Ponomarev</li>
|
||||
<li>Dan Portillo</li>
|
||||
<li>Karen Prescott</li>
|
||||
<li>Florian Quèze</li>
|
||||
<li>Krupa Raj</li>
|
||||
<li>Arun Ranganathan</li>
|
||||
<li>Neil Rashbrook</li>
|
||||
<li>Bret Reckard</li>
|
||||
<li>J. Paul Reed</li>
|
||||
<li>Rick Reitmaier</li>
|
||||
<li>Robert Relyea</li>
|
||||
<li>John Resig</li>
|
||||
<li>Deb Richardson</li>
|
||||
<li>Tim Riley</li>
|
||||
<li>Phil Ringnalda</li>
|
||||
<li>Julien Rivaud</li>
|
||||
<li>Mikeal Rogers</li>
|
||||
<li>David Rolnitzky</li>
|
||||
<li>Asaf Romano</li>
|
||||
<li>Oleg Romashin</li>
|
||||
<li>Paul Rouget</li>
|
||||
<li>Tim Rowley</li>
|
||||
<li>Jesse Ruderman</li>
|
||||
<li>Brian Ryner</li>
|
||||
<li>Alexander Sack</li>
|
||||
<li>Hideo Saito</li>
|
||||
<li>Atsushi Sakai</li>
|
||||
<li>Eiko Sakuma</li>
|
||||
<li>Andrei Saprykin</li>
|
||||
<li>Aki Sasaki</li>
|
||||
<li>Ken Saunders</li>
|
||||
<li>Robert Sayre</li>
|
||||
<li>Mike Schroepfer</li>
|
||||
<li>Kurt Schultz</li>
|
||||
<li>Keith Schwarz</li>
|
||||
<li>Justin Scott</li>
|
||||
<li>Hiroshi Sekiya</li>
|
||||
<li>Tara Shahian</li>
|
||||
@ -451,6 +518,7 @@
|
||||
<li>John Slater</li>
|
||||
<li>Benjamin Smedberg</li>
|
||||
<li>Andrew Smith</li>
|
||||
<li>Edwin Smith</li>
|
||||
<li>Mark Smith</li>
|
||||
<li>Window Snyder</li>
|
||||
<li>Josh Soref</li>
|
||||
@ -463,16 +531,24 @@
|
||||
<li>Brandon Sterne</li>
|
||||
<li>Rob Stradling</li>
|
||||
<li>Robert Strong</li>
|
||||
<li>Jay Sullivan</li>
|
||||
<li>Vicky Sun</li>
|
||||
<li>Alexander Surkov</li>
|
||||
<li>Mark Surman</li>
|
||||
<li>Andrew Sutherland</li>
|
||||
<li>Clint Talbert</li>
|
||||
<li>Margaret Tallman</li>
|
||||
<li>David Tenser</li>
|
||||
<li>Chris Thomas</li>
|
||||
<li>Nick Thomas</li>
|
||||
<li>Laura Thomson</li>
|
||||
<li>Karl Tomlinson</li>
|
||||
<li>Dave Townsend</li>
|
||||
<li>Aaron Train</li>
|
||||
<li>Phong Tran</li>
|
||||
<li>Ben Turner</li>
|
||||
<li>Doug Turner</li>
|
||||
<li>Amié Tyrrel</li>
|
||||
<li>Peter Van der Beken</li>
|
||||
<li>Peter van der Woude</li>
|
||||
<li>Teune van Steeg</li>
|
||||
@ -488,12 +564,16 @@
|
||||
<li>Martijn Wargers</li>
|
||||
<li>Jonathan Watt</li>
|
||||
<li>Peter Weilbacher</li>
|
||||
<li>Zack Weinberg</li>
|
||||
<li>Frédéric Wenzel</li>
|
||||
<li>Steffen Wilberg</li>
|
||||
<li>Drew Willcoxon</li>
|
||||
<li>Shawn Wilsher</li>
|
||||
<li>Kathleen Wilson</li>
|
||||
<li>Dan Witte</li>
|
||||
<li>John Wolfe</li>
|
||||
<li>Steve Won</li>
|
||||
<li>Justin Wood</li>
|
||||
<li>Michael Wu</li>
|
||||
<li>Masahiro Yamada</li>
|
||||
<li>Satoko Takita Yamaguchi (Chibi)</li>
|
||||
|
@ -43,6 +43,8 @@
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Dan Mosedale <dmose@mozilla.org>
|
||||
# Justin Dolske <dolske@mozilla.com>
|
||||
# Kathleen Brade <brade@pearlcrescent.com>
|
||||
# Mark Smith <mcs@pearlcrescent.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -946,8 +948,11 @@ nsContextMenu.prototype = {
|
||||
channel.notificationCallbacks = new callbacks();
|
||||
channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE |
|
||||
Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
|
||||
if (channel instanceof Ci.nsIHttpChannel)
|
||||
if (channel instanceof Ci.nsIHttpChannel) {
|
||||
channel.referrer = doc.documentURIObject;
|
||||
if (channel instanceof Ci.nsIHttpChannelInternal)
|
||||
channel.forceAllowThirdPartyCookie = true;
|
||||
}
|
||||
|
||||
// fallback to the old way if we don't see the headers quickly
|
||||
var timeToWait =
|
||||
@ -1402,5 +1407,11 @@ nsContextMenu.prototype = {
|
||||
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
|
||||
getService(Ci.nsIClipboardHelper);
|
||||
clipboard.copyString(this.mediaURL);
|
||||
},
|
||||
|
||||
get imageURL() {
|
||||
if (this.onImage)
|
||||
return this.mediaURL;
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
@ -216,7 +216,7 @@
|
||||
<!-- Media information -->
|
||||
<vbox id="mediaPanel">
|
||||
<tree id="imagetree" onselect="onImageSelect();" contextmenu="picontext"
|
||||
ondraggesture="onBeginLinkDrag(event,'image-address','image-alt')">
|
||||
ondragstart="onBeginLinkDrag(event,'image-address','image-alt')">
|
||||
<treecols>
|
||||
<treecol sortSeparators="true" persist="hidden width" flex="10"
|
||||
width="10" id="image-address" label="&mediaAddress;"/>
|
||||
|
@ -248,7 +248,7 @@
|
||||
<parameter name="aDocument"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var browsers = this.browsers;
|
||||
var browsers = this.browsers;
|
||||
for (var i = 0; i < browsers.length; i++)
|
||||
if (browsers[i].contentDocument == aDocument)
|
||||
return i;
|
||||
@ -314,29 +314,29 @@
|
||||
return;
|
||||
|
||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
||||
for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onProgressChange(aWebProgress, aRequest,
|
||||
aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onProgressChange(this.mBrowser, aWebProgress, aRequest,
|
||||
aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
@ -432,8 +432,8 @@
|
||||
}
|
||||
|
||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
||||
for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
if (!oldBlank)
|
||||
@ -442,19 +442,19 @@
|
||||
else if ("onUpdateCurrentBrowser" in p)
|
||||
p.onUpdateCurrentBrowser(aStateFlags, aStatus, "", 0);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onStateChange(this.mBrowser, aWebProgress, aRequest, aStateFlags, aStatus);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
@ -486,8 +486,8 @@
|
||||
return;
|
||||
|
||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
||||
for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onLocationChange(aWebProgress, aRequest, aLocation);
|
||||
@ -498,8 +498,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
|
||||
@ -516,25 +516,25 @@
|
||||
return;
|
||||
|
||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
||||
for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onStatusChange(this.mBrowser, aWebProgress, aRequest, aStatus, aMessage);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
@ -545,8 +545,8 @@
|
||||
onSecurityChange : function(aWebProgress, aRequest, aState)
|
||||
{
|
||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
||||
for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onSecurityChange(aWebProgress, aRequest, aState);
|
||||
@ -557,8 +557,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
if (p)
|
||||
try {
|
||||
p.onSecurityChange(this.mBrowser, aWebProgress, aRequest, aState);
|
||||
@ -573,28 +573,28 @@
|
||||
{
|
||||
var allowRefresh = true;
|
||||
if (this.mTabBrowser.mCurrentTab == this.mTab) {
|
||||
for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mProgressListeners[i];
|
||||
if (p && "onRefreshAttempted" in p) {
|
||||
try {
|
||||
if (!p.onRefreshAttempted(aWebProgress, aURI, aDelay, aSameURI))
|
||||
allowRefresh = false;
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
var p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
|
||||
let p = this.mTabBrowser.mTabsProgressListeners[i];
|
||||
if (p && "onRefreshAttempted" in p) {
|
||||
try {
|
||||
if (!p.onRefreshAttempted(this.mBrowser, aWebProgress, aURI, aDelay, aSameURI))
|
||||
allowRefresh = false;
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners or following code
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
@ -638,8 +638,8 @@
|
||||
this.updateIcon(aTab);
|
||||
|
||||
if (browser == this.mCurrentBrowser) {
|
||||
for (var i = 0; i < this.mProgressListeners.length; i++) {
|
||||
var p = this.mProgressListeners[i];
|
||||
for (let i = 0; i < this.mProgressListeners.length; i++) {
|
||||
let p = this.mProgressListeners[i];
|
||||
if ('onLinkIconAvailable' in p)
|
||||
try {
|
||||
p.onLinkIconAvailable(browser);
|
||||
@ -650,8 +650,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.mTabsProgressListeners.length; i++) {
|
||||
var p = this.mTabsProgressListeners[i];
|
||||
for (let i = 0; i < this.mTabsProgressListeners.length; i++) {
|
||||
let p = this.mTabsProgressListeners[i];
|
||||
if ('onLinkIconAvailable' in p)
|
||||
try {
|
||||
p.onLinkIconAvailable(browser);
|
||||
@ -813,62 +813,18 @@
|
||||
if (this.mCurrentTab != this.selectedTab)
|
||||
this.mCurrentTab.owner = null;
|
||||
|
||||
if (this.mCurrentBrowser) {
|
||||
// Only save the focused element if it is in our content window
|
||||
// or in an ancestor window.
|
||||
var focusedWindow = document.commandDispatcher.focusedWindow;
|
||||
var saveFocus = false;
|
||||
var fm = Components.classes["@mozilla.org/focus-manager;1"].
|
||||
getService(Components.interfaces.nsIFocusManager);
|
||||
var focusedChromeElement = fm.getFocusedElementForWindow(window, false, {});
|
||||
|
||||
if (focusedWindow && focusedWindow.top == window.content) {
|
||||
saveFocus = true;
|
||||
} else {
|
||||
var contentWindow = window;
|
||||
|
||||
while (contentWindow) {
|
||||
if (contentWindow == focusedWindow) {
|
||||
saveFocus = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (contentWindow.parent == contentWindow) {
|
||||
break;
|
||||
}
|
||||
|
||||
contentWindow = contentWindow.parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (saveFocus) {
|
||||
// Preserve the currently-focused element or DOM window for
|
||||
// this tab.
|
||||
|
||||
this.mCurrentBrowser.focusedWindow = focusedWindow;
|
||||
this.mCurrentBrowser.focusedElement = document.commandDispatcher.focusedElement;
|
||||
}
|
||||
|
||||
if (this.mCurrentBrowser.focusedElement &&
|
||||
this.mCurrentBrowser.focusedElement.parentNode !=
|
||||
this.mCurrentTab.parentNode) {
|
||||
// Clear focus outline before we draw on top of it.
|
||||
// Only blur the focused element if it isn't a tab,
|
||||
// to avoid breaking keyboard tab navigation
|
||||
var elem = this.mCurrentBrowser.focusedElement;
|
||||
if (elem instanceof HTMLElement || elem instanceof XULElement) {
|
||||
elem.blur();
|
||||
}
|
||||
else {
|
||||
var content = elem.ownerDocument.defaultView;
|
||||
if (content instanceof Components.interfaces.nsIInterfaceRequestor)
|
||||
content.getInterface(Components.interfaces.nsIDOMWindowUtils).focus(null);
|
||||
}
|
||||
}
|
||||
this.mCurrentBrowser.setAttribute("type", "content-targetable");
|
||||
}
|
||||
var oldBrowser = this.mCurrentBrowser;
|
||||
if (oldBrowser)
|
||||
oldBrowser.setAttribute("type", "content-targetable");
|
||||
|
||||
var updatePageReport = false;
|
||||
if (!this.mCurrentBrowser ||
|
||||
(this.mCurrentBrowser.pageReport && !newBrowser.pageReport) ||
|
||||
(!this.mCurrentBrowser.pageReport && newBrowser.pageReport))
|
||||
if (!oldBrowser ||
|
||||
(oldBrowser.pageReport && !newBrowser.pageReport) ||
|
||||
(!oldBrowser.pageReport && newBrowser.pageReport))
|
||||
updatePageReport = true;
|
||||
|
||||
newBrowser.setAttribute("type", "content-primary");
|
||||
@ -951,64 +907,13 @@
|
||||
event.initEvent("TabSelect", true, false);
|
||||
this.mCurrentTab.dispatchEvent(event);
|
||||
|
||||
if (document.commandDispatcher.focusedElement &&
|
||||
document.commandDispatcher.focusedElement.parentNode ==
|
||||
this.mCurrentTab.parentNode) {
|
||||
// The focus is on a tab in the same tab panel
|
||||
return; // If focus was on a tab, switching tabs focuses the new tab
|
||||
}
|
||||
|
||||
var whatToFocus = window.content;
|
||||
|
||||
// Focus the previously focused element or window, but make sure
|
||||
// the focused element is still part of the document
|
||||
let focusedElem = newBrowser.focusedElement;
|
||||
if (focusedElem && focusedElem.ownerDocument &&
|
||||
!(focusedElem.ownerDocument.compareDocumentPosition(focusedElem) &
|
||||
Node.DOCUMENT_POSITION_DISCONNECTED)) {
|
||||
if (newBrowser.focusedElement.parentNode !=
|
||||
this.mCurrentTab.parentNode) {
|
||||
// Focus the remembered element unless it's in the current tab panel
|
||||
whatToFocus = newBrowser.focusedElement;
|
||||
}
|
||||
}
|
||||
else if (newBrowser.focusedWindow) {
|
||||
whatToFocus = newBrowser.focusedWindow;
|
||||
}
|
||||
|
||||
// Change focus for this window to |whatToFocus|, without
|
||||
// focusing the window itself.
|
||||
var cmdDispatcher = document.commandDispatcher;
|
||||
|
||||
var ww =
|
||||
Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Components.interfaces.nsIWindowWatcher);
|
||||
if (ww.activeWindow == window) {
|
||||
cmdDispatcher.suppressFocusScroll = true;
|
||||
if (whatToFocus instanceof HTMLElement ||
|
||||
whatToFocus instanceof XULElement ||
|
||||
whatToFocus instanceof Window) {
|
||||
whatToFocus.focus();
|
||||
}
|
||||
else if (whatToFocus instanceof Node) {
|
||||
var content = window.content;
|
||||
if (content instanceof Components.interfaces.nsIInterfaceRequestor)
|
||||
content.getInterface(Components.interfaces.nsIDOMWindowUtils).focus(whatToFocus);
|
||||
}
|
||||
cmdDispatcher.suppressFocusScroll = false;
|
||||
}
|
||||
else {
|
||||
// set the element in command dispatcher so focus will restore
|
||||
// properly when the window does become active
|
||||
if (whatToFocus instanceof Window) {
|
||||
cmdDispatcher.focusedWindow = whatToFocus;
|
||||
cmdDispatcher.focusedElement = null;
|
||||
}
|
||||
else {
|
||||
cmdDispatcher.focusedWindow = whatToFocus.ownerDocument.defaultView;
|
||||
cmdDispatcher.focusedElement = whatToFocus;
|
||||
}
|
||||
}
|
||||
// change focus to the new tab if nothing is focused, the old tab
|
||||
// is focused or there is something in the new tab to focus. One
|
||||
// specific case where focus is not changed is when the new tab
|
||||
// has no focused element and a chrome element is focused.
|
||||
if (!focusedChromeElement || focusedChromeElement == oldBrowser ||
|
||||
fm.getFocusedElementForWindow(window.content, true, {}))
|
||||
fm.setFocus(newBrowser, fm.FLAG_NOSCROLL);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
@ -1627,9 +1532,7 @@
|
||||
// destroyed until the document goes away. So we force a
|
||||
// cleanup ourselves.
|
||||
// This has to happen before we remove the child so that the
|
||||
// XBL implementation of nsIObserver still works. But
|
||||
// clearing focusedWindow happens below because it gets
|
||||
// reset by updateCurrentBrowser.
|
||||
// XBL implementation of nsIObserver still works.
|
||||
browser.destroy();
|
||||
|
||||
if (browser == this.mCurrentBrowser)
|
||||
@ -1662,10 +1565,6 @@
|
||||
if (this.mTabBox)
|
||||
this.mTabBox.selectedPanel = this.getBrowserForTab(this.mCurrentTab).parentNode;
|
||||
|
||||
// see comment about destroy above
|
||||
browser.focusedWindow = null;
|
||||
browser.focusedElement = null;
|
||||
|
||||
if (aCloseWindow)
|
||||
this._windowIsClosing = closeWindow(true);
|
||||
]]>
|
||||
@ -2997,14 +2896,8 @@
|
||||
tooltiptext="&listAllTabs.label;"
|
||||
oncommand="ctrlTab.open(true);"/>
|
||||
</xul:stack>
|
||||
#ifdef XP_MACOSX
|
||||
<xul:hbox anonid="tabstrip-closebutton" class="tabs-closebutton-box" align="center" pack="end" chromedir="&locale.dir;">
|
||||
#endif
|
||||
<xul:toolbarbutton anonid="tabs-closebutton"
|
||||
class="close-button tabs-closebutton" chromedir="&locale.dir;"/>
|
||||
#ifdef XP_MACOSX
|
||||
</xul:hbox>
|
||||
#endif
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</content>
|
||||
@ -3065,11 +2958,7 @@
|
||||
</field>
|
||||
|
||||
<field name="mTabstripClosebutton">
|
||||
#ifdef XP_MACOSX
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "tabstrip-closebutton");
|
||||
#else
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "tabs-closebutton");
|
||||
#endif
|
||||
</field>
|
||||
|
||||
<field name="_prefObserver">({
|
||||
|
@ -57,6 +57,9 @@ _TEST_FILES = test_feed_discovery.html \
|
||||
offlineChild2.html \
|
||||
offlineChild2.cacheManifest \
|
||||
offlineChild2.cacheManifest^headers^ \
|
||||
offlineEvent.html \
|
||||
offlineEvent.cacheManifest \
|
||||
offlineEvent.cacheManifest^headers^ \
|
||||
$(NULL)
|
||||
|
||||
# The following tests are disabled because they are unreliable:
|
||||
@ -82,7 +85,9 @@ _BROWSER_FILES = browser_sanitize-timespans.js \
|
||||
browser_bug462673.js \
|
||||
browser_bug481560.js \
|
||||
browser_bug477014.js \
|
||||
browser_bug495058.js \
|
||||
browser_discovery.js \
|
||||
browser_tabfocus.js \
|
||||
discovery.html \
|
||||
moz.png \
|
||||
test_bug462673.html \
|
||||
@ -117,6 +122,7 @@ _BROWSER_FILES = browser_sanitize-timespans.js \
|
||||
browser_tabs_owner.js \
|
||||
browser_bug491431.js \
|
||||
browser_bug304198.js \
|
||||
browser_drag.js \
|
||||
$(NULL)
|
||||
|
||||
ifeq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
||||
|
@ -1,19 +1,30 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// focus the url field so that it will can ensure the focus is there when
|
||||
// the window is refocused after the dialog closes
|
||||
gURLBar.focus();
|
||||
|
||||
window.addEventListener("focus", function () {
|
||||
window.removeEventListener("focus", arguments.callee, false);
|
||||
finish();
|
||||
}, false);
|
||||
|
||||
var win = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
|
||||
|
||||
win.addEventListener("load", function () {
|
||||
win.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
win.content.addEventListener("focus", function () {
|
||||
win.content.removeEventListener("focus", arguments.callee, false);
|
||||
|
||||
EventUtils.synthesizeKey("w", { accelKey: true }, win);
|
||||
ok(win.closed, "accel+w closed the window immediately");
|
||||
}, false);
|
||||
|
||||
win.gBrowser.selectedTab.addEventListener("TabClose", function () {
|
||||
ok(false, "shouldn't have gotten the TabClose event for the last tab");
|
||||
}, false);
|
||||
|
||||
EventUtils.synthesizeKey("w", { accelKey: true }, win);
|
||||
|
||||
ok(win.closed, "accel+w closed the window immediately");
|
||||
|
||||
finish();
|
||||
}, false);
|
||||
}
|
||||
|
52
browser/base/content/test/browser_bug495058.js
Normal file
52
browser/base/content/test/browser_bug495058.js
Normal file
@ -0,0 +1,52 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
next();
|
||||
}
|
||||
|
||||
var uris = [
|
||||
"about:blank",
|
||||
"about:sessionrestore",
|
||||
"about:privatebrowsing",
|
||||
];
|
||||
|
||||
function next() {
|
||||
var tab = gBrowser.addTab();
|
||||
var uri = uris.shift();
|
||||
|
||||
if (uri == "about:blank") {
|
||||
detach();
|
||||
} else {
|
||||
let browser = tab.linkedBrowser;
|
||||
browser.addEventListener("load", function () {
|
||||
browser.removeEventListener("load", arguments.callee, true);
|
||||
detach();
|
||||
}, true);
|
||||
browser.loadURI(uri);
|
||||
}
|
||||
|
||||
function detach() {
|
||||
var win = gBrowser.replaceTabWithWindow(tab);
|
||||
win.addEventListener("load", function () {
|
||||
win.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
win.gBrowser.addEventListener("pageshow", function() {
|
||||
win.gBrowser.removeEventListener("pageshow", arguments.callee, false);
|
||||
|
||||
// wait for delayedStartup
|
||||
win.setTimeout(function () {
|
||||
is(win.gBrowser.currentURI.spec, uri, uri + ": uri loaded in detached tab");
|
||||
is(win.document.activeElement, win.gBrowser.selectedBrowser, uri + ": browser is focused");
|
||||
is(win.gURLBar.value, "", uri + ": urlbar is empty");
|
||||
ok(win.gURLBar.emptyText, uri + ": emptytext is present");
|
||||
ok(win.gURLBar.hasAttribute("isempty"), uri + ": emptytext is displayed");
|
||||
|
||||
win.close();
|
||||
if (uris.length)
|
||||
next();
|
||||
else
|
||||
executeSoon(finish);
|
||||
}, 100);
|
||||
}, false);
|
||||
}, false);
|
||||
}
|
||||
}
|
@ -67,7 +67,7 @@ function test() {
|
||||
pressCtrlTab();
|
||||
document.removeEventListener("keypress", detectKeyEvent, false);
|
||||
ok(eventConsumed, "Ctrl+Tab consumed by the tabbed browser if one tab is open");
|
||||
is(focusedWindow.location, document.commandDispatcher.focusedWindow.location,
|
||||
is(focusedWindow, document.commandDispatcher.focusedWindow,
|
||||
"Ctrl+Tab doesn't change focus if one tab is open");
|
||||
}
|
||||
|
||||
|
23
browser/base/content/test/browser_drag.js
Normal file
23
browser/base/content/test/browser_drag.js
Normal file
@ -0,0 +1,23 @@
|
||||
function test()
|
||||
{
|
||||
// ---- Test dragging the proxy icon ---
|
||||
|
||||
var value = content.location.href;
|
||||
var urlString = value + "\n" + content.document.title;
|
||||
var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
|
||||
|
||||
var expected = [ [
|
||||
"text/x-moz-url: " + urlString,
|
||||
"text/uri-list: " + value,
|
||||
"text/plain: " + value,
|
||||
"text/html: " + htmlString
|
||||
] ];
|
||||
|
||||
// set the valid attribute so dropping is allowed
|
||||
var proxyicon = document.getElementById("page-proxy-favicon")
|
||||
var oldstate = proxyicon.getAttribute("pageproxystate");
|
||||
proxyicon.setAttribute("pageproxystate", "valid");
|
||||
var dt = EventUtils.synthesizeDragStart(proxyicon, expected);
|
||||
is(dt, null, "drag on proxy icon");
|
||||
proxyicon.setAttribute("pageproxystate", oldstate);
|
||||
}
|
@ -282,11 +282,11 @@ var gAllTests = [
|
||||
},
|
||||
|
||||
/**
|
||||
* Ensures that toggling details persists across dialog openings.
|
||||
* These next two tests together ensure that toggling details persists
|
||||
* across dialog openings.
|
||||
*/
|
||||
function () {
|
||||
let wh = new WindowHelper();
|
||||
|
||||
wh.onload = function () {
|
||||
// Show details
|
||||
this.toggleDetails();
|
||||
@ -294,7 +294,9 @@ var gAllTests = [
|
||||
this.cancelDialog();
|
||||
};
|
||||
wh.open();
|
||||
|
||||
},
|
||||
function () {
|
||||
let wh = new WindowHelper();
|
||||
wh.onload = function () {
|
||||
// Details should have remained open
|
||||
this.checkDetails(true);
|
||||
|
216
browser/base/content/test/browser_tabfocus.js
Normal file
216
browser/base/content/test/browser_tabfocus.js
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* This test checks that focus is adjusted properly when switching tabs.
|
||||
*/
|
||||
|
||||
let testPage1 = "data:text/html,<html id='tab1'><body><button id='button1'>Tab 1</button></body></html>";
|
||||
let testPage2 = "data:text/html,<html id='tab2'><body><button id='button2'>Tab 2</button></body></html>";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var tab1 = gBrowser.addTab();
|
||||
var tab2 = gBrowser.addTab();
|
||||
var browser1 = gBrowser.getBrowserForTab(tab1);
|
||||
var browser2 = gBrowser.getBrowserForTab(tab2);
|
||||
|
||||
gURLBar.focus();
|
||||
|
||||
var loadCount = 0;
|
||||
function check()
|
||||
{
|
||||
// wait for both tabs to load
|
||||
if (++loadCount != 2)
|
||||
return;
|
||||
|
||||
window.focus();
|
||||
|
||||
_browser_tabfocus_test_lastfocus = gURLBar;
|
||||
_browser_tabfocus_test_lastfocuswindow = window;
|
||||
|
||||
window.addEventListener("focus", _browser_tabfocus_test_eventOccured, true);
|
||||
window.addEventListener("blur", _browser_tabfocus_test_eventOccured, true);
|
||||
|
||||
gBrowser.selectedTab = tab2;
|
||||
|
||||
var fm = Components.classes["@mozilla.org/focus-manager;1"].
|
||||
getService(Components.interfaces.nsIFocusManager);
|
||||
is(fm.focusedWindow, window, "focusedWindow after tab load");
|
||||
is(fm.focusedElement, gURLBar.inputField, "focusedElement after tab load");
|
||||
|
||||
// make sure that the focus initially starts out blank
|
||||
var focusedWindow = {};
|
||||
is(fm.getFocusedElementForWindow(browser1.contentWindow, false, focusedWindow), null, "initial focus in tab 1");
|
||||
is(focusedWindow.value, browser1.contentWindow, "initial frame focus in tab 1");
|
||||
is(fm.getFocusedElementForWindow(browser2.contentWindow, false, focusedWindow), null, "initial focus in tab 2");
|
||||
is(focusedWindow.value, browser2.contentWindow, "initial frame focus in tab 2");
|
||||
|
||||
// switching tabs when the urlbar is focused and nothing in the new tab is focused
|
||||
// should keep focus in the urlbar
|
||||
expectFocusShift(function () gBrowser.selectedTab = tab1,
|
||||
window, gURLBar.inputField, false,
|
||||
"focusedElement after tab change, focus in url field, no focus in new tab");
|
||||
|
||||
// focusing a button in the current tab should focus it
|
||||
var button1 = browser1.contentWindow.document.getElementById("button1");
|
||||
expectFocusShift(function () button1.focus(),
|
||||
browser1.contentWindow, button1, true,
|
||||
"focusedWindow after focus in focused tab");
|
||||
|
||||
// focusing a button in a background tab should not change the actual
|
||||
// focus, but should set the focus that would be in that background tab to
|
||||
// that button.
|
||||
var button2 = browser2.contentWindow.document.getElementById("button2");
|
||||
button2.focus();
|
||||
|
||||
expectFocusShift(function () button2.focus(),
|
||||
browser1.contentWindow, button1, false,
|
||||
"focusedWindow after focus in unfocused tab");
|
||||
is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "focus in unfocused tab");
|
||||
|
||||
// switching tabs should now make the button in the other tab focused
|
||||
expectFocusShift(function () gBrowser.selectedTab = tab2,
|
||||
browser2.contentWindow, button2, true,
|
||||
"focusedWindow after tab change");
|
||||
|
||||
// blurring an element in a background tab should not change the active
|
||||
// focus, but should clear the focus in that tab.
|
||||
expectFocusShift(function () button1.blur(),
|
||||
browser2.contentWindow, button2, false,
|
||||
"focusedWindow after blur in unfocused tab");
|
||||
is(fm.getFocusedElementForWindow(browser1.contentWindow, false, {}), null, "blur in unfocused tab");
|
||||
|
||||
// focusing the url field should switch active focus away from the tab but
|
||||
// not clear what would be the focus in the tab
|
||||
button1.focus();
|
||||
expectFocusShift(function () gURLBar.focus(),
|
||||
window, gURLBar.inputField, true,
|
||||
"focusedWindow after url field focused");
|
||||
is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "url field focused, button in tab");
|
||||
|
||||
// when a chrome element is focused, switching tabs to a tab with a button
|
||||
// with the current focus should focus the button
|
||||
expectFocusShift(function () gBrowser.selectedTab = tab1,
|
||||
browser1.contentWindow, button1, true,
|
||||
"focusedWindow after tab change, focus in url field, button focused in new tab");
|
||||
is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "after switch tab, focus in unfocused tab");
|
||||
|
||||
// blurring an element in the current tab should clear the active focus
|
||||
expectFocusShift(function () button1.blur(),
|
||||
browser1.contentWindow, null, true,
|
||||
"focusedWindow after blur in focused tab");
|
||||
|
||||
// blurring an non-focused url field should have no effect
|
||||
expectFocusShift(function () gURLBar.blur(),
|
||||
browser1.contentWindow, null, false,
|
||||
"focusedWindow after blur in unfocused url field");
|
||||
|
||||
// switch focus to a tab with a currently focused element
|
||||
expectFocusShift(function () gBrowser.selectedTab = tab2,
|
||||
browser2.contentWindow, button2, true,
|
||||
"focusedWindow after switch from unfocused to focused tab");
|
||||
|
||||
// clearing focus on the chrome window should switch the focus to the
|
||||
// chrome window
|
||||
expectFocusShift(function () fm.clearFocus(window),
|
||||
window, null, true,
|
||||
"focusedWindow after switch to chrome with no focused element");
|
||||
|
||||
// switch focus to another tab when neither have an active focus
|
||||
expectFocusShift(function () gBrowser.selectedTab = tab1,
|
||||
browser1.contentWindow, null, true,
|
||||
"focusedWindow after tab switch from no focus to no focus");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
browser1.addEventListener("load", check, true);
|
||||
browser2.addEventListener("load", check, true);
|
||||
browser1.contentWindow.location = testPage1;
|
||||
browser2.contentWindow.location = testPage2;
|
||||
}
|
||||
|
||||
var _browser_tabfocus_test_lastfocus;
|
||||
var _browser_tabfocus_test_lastfocuswindow = null;
|
||||
var _browser_tabfocus_test_events = "";
|
||||
|
||||
function _browser_tabfocus_test_eventOccured(event)
|
||||
{
|
||||
var id;
|
||||
if (event.target instanceof Window)
|
||||
id = event.originalTarget.document.documentElement.id + "-window";
|
||||
else if (event.target instanceof Document)
|
||||
id = event.originalTarget.documentElement.id + "-document";
|
||||
else if (event.target.id == "urlbar" && event.originalTarget.localName == "input")
|
||||
id = "urlbar";
|
||||
else
|
||||
id = event.originalTarget.id;
|
||||
|
||||
if (_browser_tabfocus_test_events)
|
||||
_browser_tabfocus_test_events += " ";
|
||||
_browser_tabfocus_test_events += event.type + ": " + id;
|
||||
}
|
||||
|
||||
function getId(element)
|
||||
{
|
||||
return (element.localName == "input") ? "urlbar" : element.id;
|
||||
}
|
||||
|
||||
function expectFocusShift(callback, expectedWindow, expectedElement, focusChanged, testid)
|
||||
{
|
||||
var expectedEvents = "";
|
||||
if (focusChanged) {
|
||||
if (_browser_tabfocus_test_lastfocus)
|
||||
expectedEvents += "blur: " + getId(_browser_tabfocus_test_lastfocus);
|
||||
|
||||
if (_browser_tabfocus_test_lastfocuswindow &&
|
||||
_browser_tabfocus_test_lastfocuswindow != expectedWindow) {
|
||||
if (expectedEvents)
|
||||
expectedEvents += " ";
|
||||
var windowid = _browser_tabfocus_test_lastfocuswindow.document.documentElement.id;
|
||||
expectedEvents += "blur: " + windowid + "-document " +
|
||||
"blur: " + windowid + "-window";
|
||||
}
|
||||
|
||||
if (expectedWindow && _browser_tabfocus_test_lastfocuswindow != expectedWindow) {
|
||||
if (expectedEvents)
|
||||
expectedEvents += " ";
|
||||
var windowid = expectedWindow.document.documentElement.id;
|
||||
expectedEvents += "focus: " + windowid + "-document " +
|
||||
"focus: " + windowid + "-window";
|
||||
}
|
||||
|
||||
if (expectedElement) {
|
||||
if (expectedEvents)
|
||||
expectedEvents += " ";
|
||||
expectedEvents += "focus: " + getId(expectedElement);
|
||||
}
|
||||
|
||||
_browser_tabfocus_test_lastfocus = expectedElement;
|
||||
_browser_tabfocus_test_lastfocuswindow = expectedWindow;
|
||||
}
|
||||
|
||||
callback();
|
||||
|
||||
is(_browser_tabfocus_test_events, expectedEvents, testid + " events");
|
||||
_browser_tabfocus_test_events = "";
|
||||
|
||||
var fm = Components.classes["@mozilla.org/focus-manager;1"].
|
||||
getService(Components.interfaces.nsIFocusManager);
|
||||
|
||||
var focusedElement = fm.focusedElement;
|
||||
is(focusedElement ? getId(focusedElement) : "none",
|
||||
expectedElement ? getId(expectedElement) : "none", testid + " focusedElement");
|
||||
is(fm.focusedWindow, expectedWindow, testid + " focusedWindow");
|
||||
var focusedWindow = {};
|
||||
is(fm.getFocusedElementForWindow(expectedWindow, false, focusedWindow),
|
||||
expectedElement, testid + " getFocusedElementForWindow");
|
||||
is(focusedWindow.value, expectedWindow, testid + " getFocusedElementForWindow frame");
|
||||
is(expectedWindow.document.hasFocus(), true, testid + " hasFocus");
|
||||
var expectedActive = expectedElement;
|
||||
if (!expectedActive)
|
||||
expectedActive = expectedWindow.document instanceof XULDocument ?
|
||||
expectedWindow.document.documentElement : expectedWindow.document.body;
|
||||
is(expectedWindow.document.activeElement, expectedActive, testid + " activeElement");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user