Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2009-06-24 13:16:16 -07:00
commit 6a6c2fc430
1230 changed files with 46061 additions and 61292 deletions

View File

@ -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

View File

@ -58,7 +58,6 @@ XPIDLSRCS = \
nsIAccessibleRelation.idl \
nsIAccessibleRole.idl \
nsIAccessibleStates.idl \
nsPIAccessible.idl \
nsIAccessibleDocument.idl \
nsPIAccessibleDocument.idl \
nsIAccessibleProvider.idl \

View File

@ -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);
};

View File

@ -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) .

View File

@ -91,6 +91,7 @@ endif
EXPORTS = \
nsAccessNodeWrap.h \
nsARIAGridAccessibleWrap.h \
nsAccessibleWrap.h \
nsDocAccessibleWrap.h \
nsRootAccessibleWrap.h \

View File

@ -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__

View File

@ -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);

View File

@ -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

View File

@ -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.
*/

View File

@ -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,

View File

@ -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;

View File

@ -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();
}

View File

@ -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.
*/

View File

@ -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;

View File

@ -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")

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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()

View File

@ -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();
};
/**

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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);
};

View File

@ -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;
}

View File

@ -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.

View File

@ -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).
*/

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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));

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -77,6 +77,7 @@ EXPORTS = \
nsAccessNodeWrap.h \
nsTextAccessibleWrap.h \
nsAccessibleWrap.h \
nsARIAGridAccessibleWrap.h \
nsDocAccessibleWrap.h \
nsRootAccessibleWrap.h \
nsXULMenuAccessibleWrap.h \

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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 \

View 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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -48,7 +48,7 @@ IMPL_IUNKNOWN_INHERITED2(nsHyperTextAccessibleWrap,
CAccessibleHypertext,
CAccessibleEditableText);
NS_IMETHODIMP
nsresult
nsHyperTextAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
{
PRUint32 eventType;

View File

@ -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,

View File

@ -75,6 +75,7 @@ CPPSRCS = \
EXPORTS = \
nsAccessNodeWrap.h \
nsARIAGridAccessibleWrap.h \
nsTextAccessibleWrap.h \
nsAccessibleWrap.h \
nsDocAccessibleWrap.h \

View 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

View File

@ -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

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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)

View File

@ -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();

View File

@ -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)

View File

@ -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

View File

@ -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 ). */

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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 \

View File

@ -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;

View File

@ -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:

View File

@ -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();

View File

@ -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;

View File

@ -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: ");
}

View 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>

View 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>

View File

@ -206,7 +206,7 @@
this.getID = function removeFromDOM_getID()
{
return aNodeOrID + " remove from DOM.";
return prettyName(aNodeOrID) + " remove from DOM.";
}
if (aTargetsFunc && (eventTypes & kHideEvent))

View 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>

View File

@ -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">&nbsp;&nbsp; </a>
<!-- label element, label contains the button -->
<label>text<button id="btn_label_inside">10</button>text</label>
<br/>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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");

View File

@ -31,7 +31,7 @@
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
addA11yLoadEvent(doTest);
</script>
</head>
<body>

View 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>

View File

@ -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

View File

@ -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&amp;sort=4&amp;maxResults=10"
tooltip="btTooltip">
<menuitem id="historyMenuBack"

View File

@ -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;

View File

@ -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

View File

@ -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"/>

View File

@ -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>

View File

@ -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 "";
}
};

View File

@ -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;"/>

View File

@ -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">({

View File

@ -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)))

View File

@ -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);
}

View 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);
}
}

View File

@ -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");
}

View 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);
}

View File

@ -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);

View 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