зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to s-c.
This commit is contained in:
Коммит
17241c85b5
|
@ -10,6 +10,15 @@ VPATH = @srcdir@
|
|||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
A11Y_LOG = 0
|
||||
ifdef MOZ_DEBUG
|
||||
A11Y_LOG = 1
|
||||
endif
|
||||
ifeq (,$(filter aurora beta release esr,$(MOZ_UPDATE_CHANNEL)))
|
||||
A11Y_LOG = 1
|
||||
endif
|
||||
export A11Y_LOG
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
PLATFORM_DIR = atk
|
||||
else
|
||||
|
|
|
@ -406,13 +406,9 @@ AccessibleWrap::CreateMaiInterfaces(void)
|
|||
|
||||
if (!nsAccUtils::MustPrune(this)) { // These interfaces require children
|
||||
// Table interface.
|
||||
nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
|
||||
QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accessInterfaceTable));
|
||||
if (accessInterfaceTable) {
|
||||
if (AsTable())
|
||||
interfacesBits |= 1 << MAI_INTERFACE_TABLE;
|
||||
}
|
||||
|
||||
|
||||
// Selection interface.
|
||||
if (IsSelect()) {
|
||||
interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
|
||||
|
|
|
@ -68,3 +68,7 @@ LOCAL_INCLUDES += \
|
|||
-I$(srcdir)/../xul \
|
||||
-I$(topsrcdir)/other-licenses/atk-1.0 \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include "AccessibleWrap.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsIAccessibleTable.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "TableCellAccessible.h"
|
||||
#include "nsMai.h"
|
||||
|
||||
#include "nsArrayUtils.h"
|
||||
|
@ -18,78 +18,51 @@ using namespace mozilla::a11y;
|
|||
|
||||
extern "C" {
|
||||
static AtkObject*
|
||||
refAtCB(AtkTable *aTable, gint aRow, gint aColumn)
|
||||
refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
if (!accWrap || aRowIdx < 0 || aColIdx < 0)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, nullptr);
|
||||
Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
|
||||
if (!cell)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAccessible> cell;
|
||||
nsresult rv = accTable->GetCellAt(aRow, aColumn,getter_AddRefs(cell));
|
||||
if (NS_FAILED(rv) || !cell)
|
||||
return nullptr;
|
||||
AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
|
||||
if (cellAtkObj)
|
||||
g_object_ref(cellAtkObj);
|
||||
|
||||
AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
|
||||
if (cellAtkObj) {
|
||||
g_object_ref(cellAtkObj);
|
||||
}
|
||||
return cellAtkObj;
|
||||
return cellAtkObj;
|
||||
}
|
||||
|
||||
static gint
|
||||
getIndexAtCB(AtkTable* aTable, gint aRow, gint aColumn)
|
||||
getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
if (!accWrap || aRowIdx < 0 || aColIdx < 0)
|
||||
return -1;
|
||||
|
||||
TableAccessible* table = accWrap->AsTable();
|
||||
NS_ENSURE_TRUE(table, -1);
|
||||
|
||||
return static_cast<gint>(table->CellIndexAt(aRow, aColumn));
|
||||
return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
|
||||
}
|
||||
|
||||
static gint
|
||||
getColumnAtIndexCB(AtkTable *aTable, gint aIndex)
|
||||
getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
if (!accWrap || aIdx < 0)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, -1);
|
||||
|
||||
int32_t col;
|
||||
nsresult rv = accTable->GetColumnIndexAt(aIndex, &col);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return static_cast<gint>(col);
|
||||
return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
|
||||
}
|
||||
|
||||
static gint
|
||||
getRowAtIndexCB(AtkTable *aTable, gint aIndex)
|
||||
getRowAtIndexCB(AtkTable *aTable, gint aIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
if (!accWrap || aIdx < 0)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, -1);
|
||||
|
||||
int32_t row;
|
||||
nsresult rv = accTable->GetRowIndexAt(aIndex, &row);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return static_cast<gint>(row);
|
||||
return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
|
||||
}
|
||||
|
||||
static gint
|
||||
|
@ -99,16 +72,7 @@ getColumnCountCB(AtkTable *aTable)
|
|||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, -1);
|
||||
|
||||
int32_t count;
|
||||
nsresult rv = accTable->GetColumnCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return static_cast<gint>(count);
|
||||
return static_cast<gint>(accWrap->AsTable()->ColCount());
|
||||
}
|
||||
|
||||
static gint
|
||||
|
@ -118,56 +82,27 @@ getRowCountCB(AtkTable *aTable)
|
|||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, -1);
|
||||
|
||||
int32_t count;
|
||||
nsresult rv = accTable->GetRowCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return static_cast<gint>(count);
|
||||
return static_cast<gint>(accWrap->AsTable()->RowCount());
|
||||
}
|
||||
|
||||
static gint
|
||||
getColumnExtentAtCB(AtkTable *aTable,
|
||||
gint aRow, gint aColumn)
|
||||
getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap || aRowIdx < 0 || aColIdx < 0)
|
||||
return -1;
|
||||
|
||||
return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
|
||||
}
|
||||
|
||||
static gint
|
||||
getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, -1);
|
||||
|
||||
int32_t extent;
|
||||
nsresult rv = accTable->GetColumnExtentAt(aRow, aColumn, &extent);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return static_cast<gint>(extent);
|
||||
}
|
||||
|
||||
static gint
|
||||
getRowExtentAtCB(AtkTable *aTable,
|
||||
gint aRow, gint aColumn)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, -1);
|
||||
|
||||
int32_t extent;
|
||||
nsresult rv = accTable->GetRowExtentAt(aRow, aColumn, &extent);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return static_cast<gint>(extent);
|
||||
return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
|
@ -177,10 +112,7 @@ getCaptionCB(AtkTable* aTable)
|
|||
if (!accWrap)
|
||||
return nullptr;
|
||||
|
||||
TableAccessible* table = accWrap->AsTable();
|
||||
NS_ENSURE_TRUE(table, nullptr);
|
||||
|
||||
Accessible* caption = table->Caption();
|
||||
Accessible* caption = accWrap->AsTable()->Caption();
|
||||
return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
|
||||
}
|
||||
|
||||
|
@ -191,58 +123,39 @@ getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
|
|||
if (!accWrap)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, nullptr);
|
||||
nsAutoString autoStr;
|
||||
accWrap->AsTable()->ColDescription(aColumn, autoStr);
|
||||
|
||||
nsAutoString autoStr;
|
||||
nsresult rv = accTable->GetColumnDescription(aColumn, autoStr);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return AccessibleWrap::ReturnString(autoStr);
|
||||
return AccessibleWrap::ReturnString(autoStr);
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
getColumnHeaderCB(AtkTable *aTable, gint aColumn)
|
||||
getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, nullptr);
|
||||
|
||||
nsCOMPtr<nsIAccessible> accCell;
|
||||
accTable->GetCellAt(0, aColumn, getter_AddRefs(accCell));
|
||||
if (!accCell)
|
||||
return nullptr;
|
||||
|
||||
// If the cell at the first row is column header then assume it is column
|
||||
// header for all rows,
|
||||
if (nsAccUtils::Role(accCell) == nsIAccessibleRole::ROLE_COLUMNHEADER)
|
||||
return AccessibleWrap::GetAtkObject(accCell);
|
||||
|
||||
// otherwise get column header for the data cell at the first row.
|
||||
nsCOMPtr<nsIAccessibleTableCell> accTableCell =
|
||||
do_QueryInterface(accCell);
|
||||
|
||||
if (accTableCell) {
|
||||
nsCOMPtr<nsIArray> headerCells;
|
||||
accTableCell->GetColumnHeaderCells(getter_AddRefs(headerCells));
|
||||
if (headerCells) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAccessible> accHeaderCell =
|
||||
do_QueryElementAt(headerCells, 0, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return AccessibleWrap::GetAtkObject(accHeaderCell);
|
||||
}
|
||||
}
|
||||
|
||||
Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx);
|
||||
if (!cell)
|
||||
return nullptr;
|
||||
|
||||
// If the cell at the first row is column header then assume it is column
|
||||
// header for all rows,
|
||||
if (cell->Role() == roles::COLUMNHEADER)
|
||||
return AccessibleWrap::GetAtkObject(cell);
|
||||
|
||||
// otherwise get column header for the data cell at the first row.
|
||||
TableCellAccessible* tableCell = cell->AsTableCell();
|
||||
if (!tableCell)
|
||||
return nullptr;
|
||||
|
||||
nsAutoTArray<Accessible*, 10> headerCells;
|
||||
tableCell->ColHeaderCells(&headerCells);
|
||||
if (headerCells.IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
return AccessibleWrap::GetAtkObject(headerCells[0]);
|
||||
}
|
||||
|
||||
static const gchar*
|
||||
|
@ -252,58 +165,39 @@ getRowDescriptionCB(AtkTable *aTable, gint aRow)
|
|||
if (!accWrap)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, nullptr);
|
||||
nsAutoString autoStr;
|
||||
accWrap->AsTable()->RowDescription(aRow, autoStr);
|
||||
|
||||
nsAutoString autoStr;
|
||||
nsresult rv = accTable->GetRowDescription(aRow, autoStr);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return AccessibleWrap::ReturnString(autoStr);
|
||||
return AccessibleWrap::ReturnString(autoStr);
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
getRowHeaderCB(AtkTable *aTable, gint aRow)
|
||||
getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, nullptr);
|
||||
|
||||
nsCOMPtr<nsIAccessible> accCell;
|
||||
accTable->GetCellAt(aRow, 0, getter_AddRefs(accCell));
|
||||
if (!accCell)
|
||||
return nullptr;
|
||||
|
||||
// If the cell at the first column is row header then assume it is row
|
||||
// header for all columns,
|
||||
if (nsAccUtils::Role(accCell) == nsIAccessibleRole::ROLE_ROWHEADER)
|
||||
return AccessibleWrap::GetAtkObject(accCell);
|
||||
|
||||
// otherwise get row header for the data cell at the first column.
|
||||
nsCOMPtr<nsIAccessibleTableCell> accTableCell =
|
||||
do_QueryInterface(accCell);
|
||||
|
||||
if (accTableCell) {
|
||||
nsCOMPtr<nsIArray> headerCells;
|
||||
accTableCell->GetRowHeaderCells(getter_AddRefs(headerCells));
|
||||
if (headerCells) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAccessible> accHeaderCell =
|
||||
do_QueryElementAt(headerCells, 0, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return AccessibleWrap::GetAtkObject(accHeaderCell);
|
||||
}
|
||||
}
|
||||
|
||||
Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0);
|
||||
if (!cell)
|
||||
return nullptr;
|
||||
|
||||
// If the cell at the first column is row header then assume it is row
|
||||
// header for all columns,
|
||||
if (cell->Role() == roles::ROWHEADER)
|
||||
return AccessibleWrap::GetAtkObject(cell);
|
||||
|
||||
// otherwise get row header for the data cell at the first column.
|
||||
TableCellAccessible* tableCell = cell->AsTableCell();
|
||||
if (!tableCell)
|
||||
return nullptr;
|
||||
|
||||
nsAutoTArray<Accessible*, 10> headerCells;
|
||||
tableCell->RowHeaderCells(&headerCells);
|
||||
if (headerCells.IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
return AccessibleWrap::GetAtkObject(headerCells[0]);
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
|
@ -311,130 +205,86 @@ getSummaryCB(AtkTable *aTable)
|
|||
{
|
||||
// Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
|
||||
// link an accessible object to specify a summary. There is closes method
|
||||
// in nsIAccessibleTable::summary to get a summary as a string which is not
|
||||
// in TableAccessible::summary to get a summary as a string which is not
|
||||
// mapped directly to ATK.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static gint
|
||||
getSelectedColumnsCB(AtkTable *aTable, gint **aSelected)
|
||||
getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
|
||||
{
|
||||
*aSelected = nullptr;
|
||||
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, 0);
|
||||
nsAutoTArray<uint32_t, 10> cols;
|
||||
accWrap->AsTable()->SelectedColIndices(&cols);
|
||||
if (cols.IsEmpty())
|
||||
return 0;
|
||||
|
||||
uint32_t size = 0;
|
||||
int32_t *columns = NULL;
|
||||
nsresult rv = accTable->GetSelectedColumnIndices(&size, &columns);
|
||||
if (NS_FAILED(rv) || (size == 0) || !columns) {
|
||||
*aSelected = nullptr;
|
||||
return 0;
|
||||
}
|
||||
gint* atkColumns = g_new(gint, cols.Length());
|
||||
if (!atkColumns) {
|
||||
NS_WARNING("OUT OF MEMORY");
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint *atkColumns = g_new(gint, size);
|
||||
if (!atkColumns) {
|
||||
NS_WARNING("OUT OF MEMORY");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//copy
|
||||
for (uint32_t index = 0; index < size; ++index)
|
||||
atkColumns[index] = static_cast<gint>(columns[index]);
|
||||
nsMemory::Free(columns);
|
||||
|
||||
*aSelected = atkColumns;
|
||||
return size;
|
||||
memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
|
||||
*aSelected = atkColumns;
|
||||
return cols.Length();
|
||||
}
|
||||
|
||||
static gint
|
||||
getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return 0;
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, 0);
|
||||
nsAutoTArray<uint32_t, 10> rows;
|
||||
accWrap->AsTable()->SelectedRowIndices(&rows);
|
||||
|
||||
uint32_t size = 0;
|
||||
int32_t *rows = NULL;
|
||||
nsresult rv = accTable->GetSelectedRowIndices(&size, &rows);
|
||||
if (NS_FAILED(rv) || (size == 0) || !rows) {
|
||||
*aSelected = nullptr;
|
||||
return 0;
|
||||
}
|
||||
gint* atkRows = g_new(gint, rows.Length());
|
||||
if (!atkRows) {
|
||||
NS_WARNING("OUT OF MEMORY");
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint *atkRows = g_new(gint, size);
|
||||
if (!atkRows) {
|
||||
NS_WARNING("OUT OF MEMORY");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//copy
|
||||
for (uint32_t index = 0; index < size; ++index)
|
||||
atkRows[index] = static_cast<gint>(rows[index]);
|
||||
nsMemory::Free(rows);
|
||||
|
||||
*aSelected = atkRows;
|
||||
return size;
|
||||
memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
|
||||
*aSelected = atkRows;
|
||||
return rows.Length();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
isColumnSelectedCB(AtkTable *aTable, gint aColumn)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return FALSE;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, FALSE);
|
||||
|
||||
bool outValue;
|
||||
nsresult rv = accTable->IsColumnSelected(aColumn, &outValue);
|
||||
return NS_FAILED(rv) ? FALSE : static_cast<gboolean>(outValue);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
isRowSelectedCB(AtkTable *aTable, gint aRow)
|
||||
isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return FALSE;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, FALSE);
|
||||
|
||||
bool outValue;
|
||||
nsresult rv = accTable->IsRowSelected(aRow, &outValue);
|
||||
return NS_FAILED(rv) ? FALSE : static_cast<gboolean>(outValue);
|
||||
return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
isCellSelectedCB(AtkTable *aTable, gint aRow, gint aColumn)
|
||||
isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return FALSE;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, FALSE);
|
||||
return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
|
||||
}
|
||||
|
||||
bool outValue;
|
||||
nsresult rv = accTable->IsCellSelected(aRow, aColumn, &outValue);
|
||||
return NS_FAILED(rv) ? FALSE : static_cast<gboolean>(outValue);
|
||||
static gboolean
|
||||
isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return FALSE;
|
||||
|
||||
return static_cast<gboolean>(accWrap->AsTable()->
|
||||
IsCellSelected(aRowIdx, aColIdx));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ FocusManager::IsInOrContainsFocus(const Accessible* aAccessible) const
|
|||
void
|
||||
FocusManager::NotifyOfDOMFocus(nsISupports* aTarget)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::FocusNotificationTarget("DOM focus", "Target", aTarget);
|
||||
#endif
|
||||
|
@ -142,7 +142,7 @@ FocusManager::NotifyOfDOMFocus(nsISupports* aTarget)
|
|||
void
|
||||
FocusManager::NotifyOfDOMBlur(nsISupports* aTarget)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::FocusNotificationTarget("DOM blur", "Target", aTarget);
|
||||
#endif
|
||||
|
@ -166,7 +166,7 @@ FocusManager::NotifyOfDOMBlur(nsISupports* aTarget)
|
|||
void
|
||||
FocusManager::ActiveItemChanged(Accessible* aItem, bool aCheckIfActive)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::FocusNotificationTarget("active item changed", "Item", aItem);
|
||||
#endif
|
||||
|
@ -179,7 +179,7 @@ FocusManager::ActiveItemChanged(Accessible* aItem, bool aCheckIfActive)
|
|||
|
||||
if (aItem && aCheckIfActive) {
|
||||
Accessible* widget = aItem->ContainerWidget();
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveWidget(widget);
|
||||
#endif
|
||||
|
@ -221,7 +221,7 @@ FocusManager::DispatchFocusEvent(DocAccessible* aDocument,
|
|||
eAutoDetect, AccEvent::eCoalesceOfSameType);
|
||||
aDocument->FireDelayedAccessibleEvent(event);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::FocusDispatched(aTarget);
|
||||
#endif
|
||||
|
@ -231,7 +231,7 @@ FocusManager::DispatchFocusEvent(DocAccessible* aDocument,
|
|||
void
|
||||
FocusManager::ProcessDOMFocus(nsINode* aTarget)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::FocusNotificationTarget("process DOM focus", "Target", aTarget);
|
||||
#endif
|
||||
|
@ -322,7 +322,7 @@ FocusManager::ProcessFocusEvent(AccEvent* aEvent)
|
|||
mActiveARIAMenubar = nullptr;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::FocusNotificationTarget("fire focus event", "Target", target);
|
||||
#endif
|
||||
|
|
|
@ -40,7 +40,7 @@ CPPSRCS = \
|
|||
TextUpdater.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_DEBUG
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
CPPSRCS += \
|
||||
Logging.cpp \
|
||||
$(NULL)
|
||||
|
@ -106,3 +106,7 @@ LOCAL_INCLUDES += \
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "TextLeafAccessible.h"
|
||||
#include "TextUpdater.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
|
@ -198,7 +198,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree)) {
|
||||
logging::MsgBegin("TREE", "initial tree created");
|
||||
logging::Address("document", mDocument);
|
||||
|
@ -303,7 +303,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
events.SwapElements(mEvents);
|
||||
|
||||
uint32_t eventCount = events.Length();
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (eventCount > 0 && logging::IsEnabled(logging::eEvents)) {
|
||||
logging::MsgBegin("EVENTS", "events processing");
|
||||
logging::Address("document", mDocument);
|
||||
|
@ -728,7 +728,7 @@ NotificationController::TextEnumerator(nsCOMPtrHashKey<nsIContent>* aEntry,
|
|||
// Remove text accessible if rendered text is empty.
|
||||
if (textAcc) {
|
||||
if (text.IsEmpty()) {
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree | logging::eText)) {
|
||||
logging::MsgBegin("TREE", "text node lost its content");
|
||||
logging::Node("container", containerElm);
|
||||
|
@ -742,7 +742,7 @@ NotificationController::TextEnumerator(nsCOMPtrHashKey<nsIContent>* aEntry,
|
|||
}
|
||||
|
||||
// Update text of the accessible and fire text change events.
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eText)) {
|
||||
logging::MsgBegin("TEXT", "text may be changed");
|
||||
logging::Node("container", containerElm);
|
||||
|
@ -761,7 +761,7 @@ NotificationController::TextEnumerator(nsCOMPtrHashKey<nsIContent>* aEntry,
|
|||
|
||||
// Append an accessible if rendered text is not empty.
|
||||
if (!text.IsEmpty()) {
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree | logging::eText)) {
|
||||
logging::MsgBegin("TREE", "text node gains new content");
|
||||
logging::Node("container", containerElm);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
|
@ -136,7 +136,7 @@ public:
|
|||
Arg* aArg)
|
||||
{
|
||||
if (!IsUpdatePending()) {
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (mozilla::a11y::logging::IsEnabled(mozilla::a11y::logging::eNotifications))
|
||||
mozilla::a11y::logging::Text("sync notification processing");
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "RootAccessibleWrap.h"
|
||||
#include "States.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
|
@ -145,7 +145,7 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
|||
|
||||
// Document was loaded.
|
||||
if (aStateFlags & STATE_STOP) {
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoad("document loaded", aWebProgress, aRequest, aStateFlags);
|
||||
#endif
|
||||
|
@ -174,7 +174,7 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
|||
}
|
||||
|
||||
// Document loading was started.
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoad("start document loading", aWebProgress, aRequest, aStateFlags);
|
||||
#endif
|
||||
|
@ -263,7 +263,7 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
|
|||
// accessible and all its sub document accessible are shutdown as result of
|
||||
// processing.
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocDestroy))
|
||||
logging::DocDestroy("received 'pagehide' event", document);
|
||||
#endif
|
||||
|
@ -289,7 +289,7 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
|
|||
// webprogress notifications nor 'pageshow' event.
|
||||
if (type.EqualsLiteral("DOMContentLoaded") &&
|
||||
nsCoreUtils::IsErrorPage(document)) {
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoad("handled 'DOMContentLoaded' event", document);
|
||||
#endif
|
||||
|
@ -330,7 +330,7 @@ nsAccDocManager::AddListeners(nsIDocument *aDocument,
|
|||
elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
|
||||
NS_EVENT_FLAG_CAPTURE);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::Text("added 'pagehide' listener");
|
||||
#endif
|
||||
|
@ -338,7 +338,7 @@ nsAccDocManager::AddListeners(nsIDocument *aDocument,
|
|||
if (aAddDOMContentLoadedListener) {
|
||||
elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
|
||||
NS_EVENT_FLAG_CAPTURE);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::Text("added 'DOMContentLoaded' listener");
|
||||
#endif
|
||||
|
@ -411,7 +411,7 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
|||
parentDocAcc->BindChildDocument(docAcc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocCreate)) {
|
||||
logging::DocCreate("document creation finished", aDocument);
|
||||
logging::Stack();
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#endif
|
||||
#include "TextLeafAccessibleWrap.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
|
@ -470,7 +470,7 @@ nsAccessibilityService::ContentRangeInserted(nsIPresShell* aPresShell,
|
|||
nsIContent* aStartChild,
|
||||
nsIContent* aEndChild)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree)) {
|
||||
logging::MsgBegin("TREE", "content inserted");
|
||||
logging::Node("container", aContainer);
|
||||
|
@ -492,7 +492,7 @@ nsAccessibilityService::ContentRemoved(nsIPresShell* aPresShell,
|
|||
nsIContent* aContainer,
|
||||
nsIContent* aChild)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree)) {
|
||||
logging::MsgBegin("TREE", "content removed");
|
||||
logging::Node("container", aContainer);
|
||||
|
@ -843,7 +843,7 @@ nsAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
|
|||
NS_IMETHODIMP
|
||||
nsAccessibilityService::SetLogging(const nsACString& aModules)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
logging::Enable(PromiseFlatCString(aModules));
|
||||
#endif
|
||||
return NS_OK;
|
||||
|
@ -901,26 +901,22 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||
if (!content)
|
||||
if (!aNode->IsContent())
|
||||
return nullptr;
|
||||
|
||||
// Frames can be deallocated when we flush layout, or when we call into code
|
||||
// that can flush layout, either directly, or via DOM manipulation, or some
|
||||
// CSS styles like :hover. We use the weak frame checks to avoid calling
|
||||
// methods on a dead frame pointer.
|
||||
nsWeakFrame weakFrame = content->GetPrimaryFrame();
|
||||
nsIContent* content = aNode->AsContent();
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
|
||||
// Check frame and its visibility. Note, hidden frame allows visible
|
||||
// elements in subtree.
|
||||
if (!weakFrame.GetFrame() || !weakFrame->GetStyleVisibility()->IsVisible()) {
|
||||
if (aIsSubtreeHidden && !weakFrame.GetFrame())
|
||||
if (!frame || !frame->GetStyleVisibility()->IsVisible()) {
|
||||
if (aIsSubtreeHidden && !frame)
|
||||
*aIsSubtreeHidden = true;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (weakFrame.GetFrame()->GetContent() != content) {
|
||||
if (frame->GetContent() != content) {
|
||||
// Not the main content for this frame. This happens because <area>
|
||||
// elements return the image frame as their primary frame. The main content
|
||||
// for the image frame is the image content. If the frame is not an image
|
||||
|
@ -929,7 +925,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
// create area accessible here. Hopefully assertion below will handle that.
|
||||
|
||||
#ifdef DEBUG
|
||||
nsImageFrame* imageFrame = do_QueryFrame(weakFrame.GetFrame());
|
||||
nsImageFrame* imageFrame = do_QueryFrame(frame);
|
||||
NS_ASSERTION(imageFrame && content->IsHTML() && content->Tag() == nsGkAtoms::area,
|
||||
"Unknown case of not main content for the frame!");
|
||||
#endif
|
||||
|
@ -937,25 +933,18 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsImageFrame* imageFrame = do_QueryFrame(weakFrame.GetFrame());
|
||||
nsImageFrame* imageFrame = do_QueryFrame(frame);
|
||||
NS_ASSERTION(!imageFrame || !content->IsHTML() || content->Tag() != nsGkAtoms::area,
|
||||
"Image map manages the area accessible creation!");
|
||||
#endif
|
||||
|
||||
DocAccessible* docAcc =
|
||||
GetAccService()->GetDocAccessible(aNode->OwnerDoc());
|
||||
if (!docAcc) {
|
||||
NS_NOTREACHED("Node has no host document accessible!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Attempt to create an accessible based on what we know.
|
||||
nsRefPtr<Accessible> newAcc;
|
||||
|
||||
// Create accessible for visible text frames.
|
||||
if (content->IsNodeOfType(nsINode::eTEXT)) {
|
||||
nsAutoString text;
|
||||
weakFrame->GetRenderedText(&text, nullptr, nullptr, 0, UINT32_MAX);
|
||||
frame->GetRenderedText(&text, nullptr, nullptr, 0, UINT32_MAX);
|
||||
if (text.IsEmpty()) {
|
||||
if (aIsSubtreeHidden)
|
||||
*aIsSubtreeHidden = true;
|
||||
|
@ -963,8 +952,8 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
newAcc = weakFrame->CreateAccessible();
|
||||
if (docAcc->BindToDocument(newAcc, nullptr)) {
|
||||
newAcc = frame->CreateAccessible();
|
||||
if (aDoc->BindToDocument(newAcc, nullptr)) {
|
||||
newAcc->AsTextLeaf()->SetText(text);
|
||||
return newAcc;
|
||||
}
|
||||
|
@ -982,16 +971,16 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
// HTML area (HTMLAreaAccessible) the map contains are attached as
|
||||
// children of the appropriate accessible for HTML image
|
||||
// (ImageAccessible).
|
||||
if (nsLayoutUtils::GetAllInFlowRectsUnion(weakFrame,
|
||||
weakFrame->GetParent()).IsEmpty()) {
|
||||
if (nsLayoutUtils::GetAllInFlowRectsUnion(frame,
|
||||
frame->GetParent()).IsEmpty()) {
|
||||
if (aIsSubtreeHidden)
|
||||
*aIsSubtreeHidden = true;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
newAcc = new HyperTextAccessibleWrap(content, docAcc);
|
||||
if (docAcc->BindToDocument(newAcc, aria::GetRoleMap(aNode)))
|
||||
newAcc = new HyperTextAccessibleWrap(content, aDoc);
|
||||
if (aDoc->BindToDocument(newAcc, aria::GetRoleMap(aNode)))
|
||||
return newAcc;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1009,8 +998,8 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
roleMapEntry = nullptr;
|
||||
}
|
||||
|
||||
if (weakFrame.IsAlive() && !newAcc && isHTML) { // HTML accessibles
|
||||
nsIAtom *frameType = weakFrame.GetFrame()->GetType();
|
||||
if (!newAcc && isHTML) { // HTML accessibles
|
||||
nsIAtom* frameType = frame->GetType();
|
||||
|
||||
bool partOfHTMLTable =
|
||||
frameType == nsGkAtoms::tableCaptionFrame ||
|
||||
|
@ -1083,12 +1072,12 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
|
||||
if (roleMapEntry->role == roles::TABLE ||
|
||||
roleMapEntry->role == roles::TREE_TABLE) {
|
||||
newAcc = new ARIAGridAccessibleWrap(content, docAcc);
|
||||
newAcc = new ARIAGridAccessibleWrap(content, aDoc);
|
||||
|
||||
} else if (roleMapEntry->role == roles::GRID_CELL ||
|
||||
roleMapEntry->role == roles::ROWHEADER ||
|
||||
roleMapEntry->role == roles::COLUMNHEADER) {
|
||||
newAcc = new ARIAGridCellAccessibleWrap(content, docAcc);
|
||||
newAcc = new ARIAGridCellAccessibleWrap(content, aDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1099,8 +1088,8 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
// The method creates accessibles for table related content too therefore
|
||||
// we do not call it if accessibles for table related content are
|
||||
// prevented above.
|
||||
newAcc = CreateHTMLAccessibleByMarkup(weakFrame.GetFrame(), content,
|
||||
docAcc, legalPartOfHTMLTable);
|
||||
newAcc = CreateHTMLAccessibleByMarkup(frame, content, aDoc,
|
||||
legalPartOfHTMLTable);
|
||||
|
||||
if (!newAcc && (!partOfHTMLTable || legalPartOfHTMLTable)) {
|
||||
// Do not create accessible object subtrees for non-rendered table
|
||||
|
@ -1109,12 +1098,8 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
// the table caption would still be created. By setting
|
||||
// *aIsSubtreeHidden = true we ensure that no descendant accessibles
|
||||
// are created.
|
||||
nsIFrame* f = weakFrame.GetFrame();
|
||||
if (!f) {
|
||||
f = aDoc->PresShell()->GetRealPrimaryFrameFor(content);
|
||||
}
|
||||
if (f->GetType() == nsGkAtoms::tableCaptionFrame &&
|
||||
f->GetRect().IsEmpty()) {
|
||||
if (frame->GetType() == nsGkAtoms::tableCaptionFrame &&
|
||||
frame->GetRect().IsEmpty()) {
|
||||
// XXX This is not the ideal place for this code, but right now there
|
||||
// is no better place:
|
||||
if (aIsSubtreeHidden)
|
||||
|
@ -1124,7 +1109,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
}
|
||||
|
||||
// Try using frame to do it.
|
||||
newAcc = f->CreateAccessible();
|
||||
newAcc = frame->CreateAccessible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1132,7 +1117,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
if (!newAcc) {
|
||||
// Elements may implement nsIAccessibleProvider via XBL. This allows them to
|
||||
// say what kind of accessible to create.
|
||||
newAcc = CreateAccessibleByType(content, docAcc);
|
||||
newAcc = CreateAccessibleByType(content, aDoc);
|
||||
}
|
||||
|
||||
if (!newAcc) {
|
||||
|
@ -1140,25 +1125,23 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
// on HTML elements
|
||||
nsIAtom* tag = content->Tag();
|
||||
if ((tag == nsGkAtoms::deck) || (tag == nsGkAtoms::tabpanels)) {
|
||||
newAcc = new XULDeckAccessible(content, docAcc);
|
||||
newAcc = new XULDeckAccessible(content, aDoc);
|
||||
} else if (content->IsSVG(nsGkAtoms::svg)) {
|
||||
newAcc = new EnumRoleAccessible(content, docAcc, roles::DIAGRAM);
|
||||
newAcc = new EnumRoleAccessible(content, aDoc, roles::DIAGRAM);
|
||||
} else if (content->IsMathML(nsGkAtoms::math)) {
|
||||
newAcc = new EnumRoleAccessible(content, docAcc, roles::EQUATION);
|
||||
newAcc = new EnumRoleAccessible(content, aDoc, roles::EQUATION);
|
||||
}
|
||||
}
|
||||
|
||||
if (!newAcc) {
|
||||
newAcc = CreateAccessibleForDeckChild(weakFrame.GetFrame(), content,
|
||||
docAcc);
|
||||
}
|
||||
if (!newAcc)
|
||||
newAcc = CreateAccessibleForDeckChild(frame, content, aDoc);
|
||||
|
||||
// If no accessible, see if we need to create a generic accessible because
|
||||
// of some property that makes this object interesting
|
||||
// We don't do this for <body>, <html>, <window>, <dialog> etc. which
|
||||
// correspond to the doc accessible and will be created in any case
|
||||
if (!newAcc && content->Tag() != nsGkAtoms::body && content->GetParent() &&
|
||||
((weakFrame.GetFrame() && weakFrame.GetFrame()->IsFocusable()) ||
|
||||
(frame->IsFocusable() ||
|
||||
(isHTML && nsCoreUtils::HasClickListener(content)) ||
|
||||
HasUniversalAriaProperty(content) || roleMapEntry ||
|
||||
HasRelatedContent(content) || nsCoreUtils::IsXLink(content))) {
|
||||
|
@ -1167,15 +1150,14 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
// other accessibles can point to it, or so that it can hold a state, etc.
|
||||
if (isHTML) {
|
||||
// Interesting HTML container which may have selectable text and/or embedded objects
|
||||
newAcc = new HyperTextAccessibleWrap(content, docAcc);
|
||||
}
|
||||
else { // XUL, SVG, MathML etc.
|
||||
newAcc = new HyperTextAccessibleWrap(content, aDoc);
|
||||
} else { // XUL, SVG, MathML etc.
|
||||
// Interesting generic non-HTML container
|
||||
newAcc = new AccessibleWrap(content, docAcc);
|
||||
newAcc = new AccessibleWrap(content, aDoc);
|
||||
}
|
||||
}
|
||||
|
||||
return docAcc->BindToDocument(newAcc, roleMapEntry) ? newAcc : nullptr;
|
||||
return aDoc->BindToDocument(newAcc, roleMapEntry) ? newAcc : nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1199,7 +1181,7 @@ nsAccessibilityService::Init()
|
|||
static const PRUnichar kInitIndicator[] = { '1', 0 };
|
||||
observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kInitIndicator);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
logging::CheckEnv();
|
||||
#endif
|
||||
|
||||
|
@ -1293,7 +1275,7 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
|
|||
|
||||
if (type == nsIAccessibleProvider::OuterDoc) {
|
||||
Accessible* accessible = new OuterDocAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
|
@ -1573,7 +1555,7 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
|||
if (nsCoreUtils::IsHTMLTableHeader(aContent)) {
|
||||
Accessible* accessible =
|
||||
new HTMLTableHeaderCellAccessibleWrap(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
|
@ -1584,38 +1566,38 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
|||
nsIAtom* tag = aContent->Tag();
|
||||
if (tag == nsGkAtoms::figcaption) {
|
||||
Accessible* accessible = new HTMLFigcaptionAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::figure) {
|
||||
Accessible* accessible = new HTMLFigureAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::legend) {
|
||||
Accessible* accessible = new HTMLLegendAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::option) {
|
||||
Accessible* accessible = new HTMLSelectOptionAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::optgroup) {
|
||||
Accessible* accessible = new HTMLSelectOptGroupAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::ul || tag == nsGkAtoms::ol ||
|
||||
tag == nsGkAtoms::dl) {
|
||||
Accessible* accessible = new HTMLListAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
|
@ -1626,12 +1608,12 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
|||
if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
|
||||
roleMapEntry->role != roles::LINK) {
|
||||
Accessible* accessible = new HyperTextAccessibleWrap(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
Accessible* accessible = new HTMLLinkAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
|
@ -1639,7 +1621,7 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
|||
// Create list item accessible unconditionally by tag name. nsBlockFrame
|
||||
// creates the list item accessible for other elements styled as list items.
|
||||
Accessible* accessible = new HTMLLIAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
|
@ -1656,20 +1638,20 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
|||
tag == nsGkAtoms::h6 ||
|
||||
tag == nsGkAtoms::q) {
|
||||
Accessible* accessible = new HyperTextAccessibleWrap(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::output) {
|
||||
Accessible* accessible = new HTMLOutputAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::progress) {
|
||||
Accessible* accessible =
|
||||
new HTMLProgressMeterAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
|
@ -1759,18 +1741,18 @@ nsAccessibilityService::CreateAccessibleForDeckChild(nsIFrame* aFrame,
|
|||
if (parentFrame && parentFrame->GetType() == nsGkAtoms::deckFrame) {
|
||||
// If deck frame is for xul:tabpanels element then the given node has
|
||||
// tabpanel accessible.
|
||||
nsCOMPtr<nsIContent> parentContent = parentFrame->GetContent();
|
||||
nsIContent* parentContent = parentFrame->GetContent();
|
||||
#ifdef MOZ_XUL
|
||||
if (parentContent->NodeInfo()->Equals(nsGkAtoms::tabpanels,
|
||||
kNameSpaceID_XUL)) {
|
||||
Accessible* accessible = new XULTabpanelAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
#endif
|
||||
Accessible* accessible = new EnumRoleAccessible(aContent, aDoc,
|
||||
roles::PROPERTYPAGE);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
}
|
||||
|
@ -1798,13 +1780,13 @@ nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
|
|||
// Outline of list accessible.
|
||||
if (count == 1) {
|
||||
Accessible* accessible = new XULTreeAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
// Table or tree table accessible.
|
||||
Accessible* accessible = new XULTreeGridAccessibleWrap(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -95,10 +95,8 @@ nsCaretAccessible::SetControlSelectionListener(nsIContent *aCurrentNode)
|
|||
|
||||
nsCOMPtr<nsISelectionController> controller =
|
||||
GetSelectionControllerForNode(mCurrentControl);
|
||||
#ifdef DEBUG
|
||||
NS_ASSERTION(controller || aCurrentNode->IsNodeOfType(nsINode::eDOCUMENT),
|
||||
"No selection controller for non document node!");
|
||||
#endif
|
||||
if (!controller)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -180,7 +178,7 @@ nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
|
|||
nsCOMPtr<nsIDocument> documentNode(do_QueryInterface(aDOMDocument));
|
||||
DocAccessible* document = GetAccService()->GetDocAccessible(documentNode);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eSelection))
|
||||
logging::SelChange(aSelection, document);
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "nsFocusManager.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
|
@ -607,7 +607,7 @@ DocAccessible::GetAccessible(nsINode* aNode) const
|
|||
void
|
||||
DocAccessible::Init()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::DocCreate("document initialize", mDocument, this);
|
||||
#endif
|
||||
|
@ -630,7 +630,7 @@ DocAccessible::Shutdown()
|
|||
if (!mPresShell) // already shutdown
|
||||
return;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocDestroy))
|
||||
logging::DocDestroy("document shutdown", mDocument, this);
|
||||
#endif
|
||||
|
@ -856,7 +856,7 @@ DocAccessible::AddScrollListener()
|
|||
nsIScrollableFrame* sf = mPresShell->GetRootScrollFrameAsScrollableExternal();
|
||||
if (sf) {
|
||||
sf->AddScrollPositionListener(this);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::Text("add scroll listener");
|
||||
#endif
|
||||
|
@ -1230,7 +1230,7 @@ DocAccessible::ARIAActiveDescendantChanged(nsIContent* aElm)
|
|||
Accessible* activeDescendant = GetAccessible(activeDescendantElm);
|
||||
if (activeDescendant) {
|
||||
FocusMgr()->ActiveItemChanged(activeDescendant, false);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("ARIA activedescedant changed",
|
||||
activeDescendant);
|
||||
|
@ -1318,7 +1318,7 @@ DocAccessible::ParentChainChanged(nsIContent* aContent)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
nsresult
|
||||
DocAccessible::HandleAccEvent(AccEvent* aEvent)
|
||||
{
|
||||
|
@ -1416,7 +1416,7 @@ DocAccessible::UnbindFromDocument(Accessible* aAccessible)
|
|||
// from the tree.
|
||||
if (FocusMgr()->IsActiveItem(aAccessible)) {
|
||||
FocusMgr()->ActiveItemChanged(nullptr);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("tree shutdown", aAccessible);
|
||||
#endif
|
||||
|
@ -1764,7 +1764,7 @@ DocAccessible::FireDelayedAccessibleEvent(AccEvent* aEvent)
|
|||
{
|
||||
NS_ENSURE_ARG(aEvent);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoadEventFired(aEvent);
|
||||
#endif
|
||||
|
@ -1855,7 +1855,7 @@ DocAccessible::UpdateTree(Accessible* aContainer, nsIContent* aChildNode,
|
|||
|
||||
// If child node is not accessible then look for its accessible children.
|
||||
Accessible* child = GetAccessible(aChildNode);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree)) {
|
||||
logging::MsgBegin("TREE", "process content %s",
|
||||
(aIsInsert ? "insertion" : "removal"));
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
|
||||
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
virtual nsresult HandleAccEvent(AccEvent* aEvent);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -74,3 +74,7 @@ LOCAL_INCLUDES += \
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "Role.h"
|
||||
#include "States.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
|
@ -123,14 +123,14 @@ OuterDocAccessible::Shutdown()
|
|||
// change however the presshell of underlying document isn't destroyed and
|
||||
// the document doesn't get pagehide events. Shutdown underlying document if
|
||||
// any to avoid hanging document accessible.
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocDestroy))
|
||||
logging::OuterDocDestroy(this);
|
||||
#endif
|
||||
|
||||
Accessible* childAcc = mChildren.SafeElementAt(0, nullptr);
|
||||
if (childAcc) {
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocDestroy)) {
|
||||
logging::DocDestroy("outerdoc's child document shutdown",
|
||||
childAcc->GetDocumentNode());
|
||||
|
@ -174,7 +174,7 @@ OuterDocAccessible::AppendChild(Accessible* aAccessible)
|
|||
if (!AccessibleWrap::AppendChild(aAccessible))
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocCreate)) {
|
||||
logging::DocCreate("append document to outerdoc",
|
||||
aAccessible->GetDocumentNode());
|
||||
|
@ -194,7 +194,7 @@ OuterDocAccessible::RemoveChild(Accessible* aAccessible)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDocDestroy)) {
|
||||
logging::DocDestroy("remove document from outerdoc", child->GetDocumentNode(),
|
||||
child->AsDoc());
|
||||
|
|
|
@ -262,7 +262,7 @@ RootAccessible::HandleEvent(nsIDOMEvent* aDOMEvent)
|
|||
GetAccService()->GetDocAccessible(origTargetNode->OwnerDoc());
|
||||
|
||||
if (document) {
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eDOMEvents)) {
|
||||
nsAutoString eventType;
|
||||
aDOMEvent->GetType(eventType);
|
||||
|
@ -342,7 +342,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
|
|||
|
||||
if (isEnabled) {
|
||||
FocusMgr()->ActiveItemChanged(accessible);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("RadioStateChange", accessible);
|
||||
#endif
|
||||
|
@ -424,7 +424,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
|
|||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
|
||||
FocusMgr()->ActiveItemChanged(accessible);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("DOMMenuItemActive", accessible);
|
||||
#endif
|
||||
|
@ -438,7 +438,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
|
|||
accessible->IsWidget() ? accessible : accessible->ContainerWidget();
|
||||
if (widget && widget->IsAutoCompletePopup()) {
|
||||
FocusMgr()->ActiveItemChanged(nullptr);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("DOMMenuItemInactive", accessible);
|
||||
#endif
|
||||
|
@ -457,7 +457,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
|
|||
Accessible* activeItem = accessible->CurrentItem();
|
||||
if (activeItem) {
|
||||
FocusMgr()->ActiveItemChanged(activeItem);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("DOMMenuBarActive", accessible);
|
||||
#endif
|
||||
|
@ -468,7 +468,7 @@ RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
|
|||
accessible, eFromUserInput);
|
||||
|
||||
FocusMgr()->ActiveItemChanged(nullptr);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("DOMMenuBarInactive", accessible);
|
||||
#endif
|
||||
|
@ -662,7 +662,7 @@ RootAccessible::HandlePopupHidingEvent(nsINode* aPopupNode)
|
|||
// Restore focus to where it was.
|
||||
if (notifyOf & kNotifyOfFocus) {
|
||||
FocusMgr()->ActiveItemChanged(nullptr);
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eFocus))
|
||||
logging::ActiveItemChangeCausedBy("popuphiding", popup);
|
||||
#endif
|
||||
|
|
|
@ -63,3 +63,7 @@ LOCAL_INCLUDES += \
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -57,3 +57,6 @@ LOCAL_INCLUDES += \
|
|||
-I$(topsrcdir)/layout/generic \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "States.h"
|
||||
#include "uiaRawElmProvider.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
|
@ -1577,7 +1577,7 @@ AccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
|
|||
aid->ToUTF8String(id);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::ePlatforms)) {
|
||||
printf("\n\nMSAA event: event: %d, target: %s@id='%s', childid: %d, hwnd: %d\n\n",
|
||||
eventType, NS_ConvertUTF16toUTF8(tag).get(), id.get(),
|
||||
|
|
|
@ -88,3 +88,7 @@ LOCAL_INCLUDES += \
|
|||
-I$(srcdir)/../../../content/base/src \
|
||||
-I$(srcdir)/../../../content/events/src \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -44,3 +44,6 @@ LOCAL_INCLUDES += \
|
|||
-I$(srcdir)/../xul \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -14,3 +14,7 @@ DIRS += uia \
|
|||
$(null)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -34,3 +34,7 @@ LOCAL_INCLUDES += \
|
|||
-I$(srcdir)/../../xpcom \
|
||||
-I$(srcdir)/../../xul \
|
||||
$(NULL)
|
||||
|
||||
ifdef A11Y_LOG
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -55,3 +55,7 @@ LOCAL_INCLUDES += \
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -52,3 +52,7 @@ LOCAL_INCLUDES += \
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -67,3 +67,7 @@ LOCAL_INCLUDES += \
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(A11Y_LOG),0)
|
||||
DEFINES += -DA11Y_LOG
|
||||
endif
|
||||
|
|
|
@ -38,6 +38,6 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
libs::
|
||||
$(GAIA_MAKE) -j1 -C $(GAIADIR) clean
|
||||
$(GAIA_MAKE) -j1 -C $(GAIADIR) profile GAIA_DOMAIN=desktop-builds.$(MOZ_APP_NAME).mozilla.org
|
||||
$(GAIA_MAKE) -j1 -C $(GAIADIR) profile
|
||||
(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
|
||||
|
||||
|
|
|
@ -69,32 +69,3 @@ $(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) FORCE
|
|||
|
||||
GARBAGE += $(MOZ_PKG_MANIFEST)
|
||||
endif
|
||||
|
||||
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
||||
PACKAGE_XULRUNNER =
|
||||
UNPACKAGE =
|
||||
else
|
||||
PACKAGE_XULRUNNER = package-xulrunner
|
||||
UNPACKAGE = $(LIBXUL_DIST)/xulrunner*$(PKG_SUFFIX)
|
||||
endif
|
||||
|
||||
ifdef LIBXUL_SDK
|
||||
MOZ_GRE_PKG_DIR=$(MOZ_PKG_DIR)/xulrunner
|
||||
else
|
||||
MOZ_GRE_PKG_DIR=$(MOZ_PKG_DIR)
|
||||
endif
|
||||
|
||||
package-xulrunner:
|
||||
ifdef LIBXUL_SDK
|
||||
ifndef SYSTEM_LIBXUL
|
||||
@echo "Packaging xulrunner..."
|
||||
@rm -rf $(LIBXUL_DIST)/xulrunner*
|
||||
@$(MAKE) -C $(LIBXUL_DIST)/.. package || echo "Perhaps you're trying to package a prebuilt SDK. See 'https://wiki.mozilla.org/B2G' for more information."
|
||||
@cd $(DIST)/$(MOZ_PKG_DIR); $(UNMAKE_PACKAGE)
|
||||
@echo "Removing unpackaged files... (the ones xulrunner/installer keeps)"
|
||||
@cd $(DIST)/$(MOZ_PKG_DIR)/xulrunner; rm -rf $(NO_PKG_FILES)
|
||||
else
|
||||
@echo "Using system xulrunner..."
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -532,11 +532,6 @@ pref("mousewheel.with_control.action",3);
|
|||
pref("mousewheel.with_meta.action", 1); // command key on Mac
|
||||
pref("mousewheel.with_win.action", 1);
|
||||
|
||||
// pref to control the alert notification
|
||||
pref("alerts.slideIncrement", 1);
|
||||
pref("alerts.slideIncrementTime", 10);
|
||||
pref("alerts.totalOpenTime", 4000);
|
||||
|
||||
pref("browser.xul.error_pages.enabled", true);
|
||||
pref("browser.xul.error_pages.expert_bad_cert", false);
|
||||
|
||||
|
|
|
@ -67,37 +67,6 @@ const SEARCH_ENGINES = {
|
|||
"7GUnpHbrbG8EzsfWfwgwAEfC/ToQIhkhAAAAAElFTkSuQmCC"
|
||||
, params: "source=hp&channel=np"
|
||||
}
|
||||
|
||||
, "Яндекс":
|
||||
{
|
||||
image: "data:image/png;base64," +
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAEYAAAAcCAYAAADcO8kVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ" +
|
||||
"bWFnZVJlYWR5ccllPAAABWFJREFUeNrsWWtsVEUUnltLH7tbaeuDbfCBojUoBTGmooLE+Igx+gON" +
|
||||
"RvEJhEQNUdEYA0Ji4xNf2Bg1iBJJrGBC+CEBNYoxxmh94CMKRE2MitBqoZRi6bbdZT3TfhM/TmZ2" +
|
||||
"u5jGsOEkX8/0ztzp3HPP4zu3UTabNUfEI9YwgzAxjUbBGkG7IAv0CwYE53rWC+KChFloRh329igN" +
|
||||
"zD8keJR+P2DvEbgnrjp4eWT65GerSZuU6FWii9Fj5pGHvC6ow/WpdP1C7SV3Bm18eNpDG2a0oA0P" +
|
||||
"v0qFSn3IMPOKxChsmBJ1/TpBEuNn1NxRB8XOoJSYRabfrCiG0FGiDXMZ9HeC73PfGpkOST0vmYGi" +
|
||||
"LEraMCdB/5jP46xhnhaj7C3Sal2qjFSDcU8eb4m2m4xpHvKWYwSTBd2Cr1HBrIwVnCXYIdiiNrDh" +
|
||||
"Wi8YQLVzZ+mDt/ar9acK5gqOE6wTvKvmE4JzsN83ghSu1+AMMcGngr/pnnHYM4nzrRX8EapKm5Fc" +
|
||||
"3/bwlAn/Jt/EtJdNmdvidjxcpyrjT+D6Fx7LPoA5jf3ktU5metY9rtZcRHNn0vV3cO0rtf6GwN9v" +
|
||||
"DCXfX6AbVLL1hJJOxIM6UtwnJG7ORuIaMl5W7W297g2MmwR3YLxQcDmty3jOdongCrrXyRTBaoyf" +
|
||||
"x5qdgjZ4qzfHbCQ3mzXcChcYH8hhIGf0zwQ3Ch6k8/Ae9yEM3hc8LFguWIm5uwIvwYXhPdA2RNbT" +
|
||||
"/BLoFsECwXsw1gUIZa9h7NvZivGLgkk010eHjv5jbitXD1HiWVMhuB7jDXR9E/R0Qa3nPvvmTxZc" +
|
||||
"7fGWyQhNK6/R9b8Ev4aSr0HyunWQ3Q/li8/hdh8JTiOD+DpPa7jegHtriUN35zDMRMEJGH9J17dB" +
|
||||
"18KzO9V9NvndjbH1sB9objp0u+CT4VYlJ5txKLvpDMFsIJ/EwYOs9bsEp+RYeyz0nx7y6ORsGu8K" +
|
||||
"EM2kx1ts7rkXL+YxNd8I/TOcoCDDOB5jY/Fj/P4cEmVTjr0SlKNCOcjJ8fQgodAcQ/d/i/BLK8Oo" +
|
||||
"ZtYcLVgGD1wq2K7mx0LvKITHaFlCbny/oI4M43uQDJJkL3KH5RWnB/auh96ax9AGnKQdoZNAyO4T" +
|
||||
"VHv4VobC+XzPntWUMgpivtwzufbgWbVpSHYh4V0DnrA6YETrCWdgvGUYIboX9KEahqlFcq0GT2HZ" +
|
||||
"jwrXBW4zJ/C8FYdqmEWUb94aZniUUbXJVbmm0N6/5zjbPnohcfKePiDlSfBJeO0r9Bx8pi7oEw/F" +
|
||||
"MPMp8S0roARHar+QYS6FXp9nv230dicVcA7LaZoxHo/ncfIbEdi6Qgxje4vFRL5aRqA/uxn6Vc9c" +
|
||||
"muK/lXqeuQXsPwZMdi0RPedxH1AFva0QwyygavDkCBjlFuy/HJWhksLQgOVyxWqh3mYx7RND2Pi8" +
|
||||
"0n1+baawmU9e2o6x/XR7raIQVb4mskGQQaO4ydNENlATeTE1kXOQc/agXDpZqhq42dQL2US9G1Wl" +
|
||||
"G5XEzaWJbyTBddzcTuSmAYTMOKybQWsmeppIbk5nqcbxJ1RHO37B10TeRL3KU543kUKF0J8leqgq" +
|
||||
"8ae8PdAd6ltPL954LXQV/m4HEbgaYqjT6KNZHWhAKd5+mzpDN4WflUdw5koweitv4lldX2QpxQSc" +
|
||||
"/UOfx9jvvTHBKP+/RmKRoHwIiYg8pgQJsszTKFYSV2qC0VcShyqnqlEKRpolqsAyFfnpKmLOnOgr" +
|
||||
"VAVirhYnYzsZLbgSe57nwtL375N8H+Oy3H2qKpAKEL5eVc65E04rD2NW66uWrUDobKnAnPs7PR5+" +
|
||||
"tLFQHjMS0knhEZLdim/8bxId+RetX/4RYACXlwEEPBQycwAAAABJRU5ErkJggg=="
|
||||
}
|
||||
};
|
||||
|
||||
// The process of adding a new default snippet involves:
|
||||
|
|
|
@ -535,11 +535,15 @@ let SocialShareButton = {
|
|||
var SocialToolbar = {
|
||||
// Called once, after window load, when the Social.provider object is initialized
|
||||
init: function SocialToolbar_init() {
|
||||
document.getElementById("social-provider-button").setAttribute("image", Social.provider.iconURL);
|
||||
this.button.setAttribute("image", Social.provider.iconURL);
|
||||
this.updateButton();
|
||||
this.updateProfile();
|
||||
},
|
||||
|
||||
get button() {
|
||||
return document.getElementById("social-provider-button");
|
||||
},
|
||||
|
||||
updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
|
||||
let tbi = document.getElementById("social-toolbar-item");
|
||||
tbi.hidden = !Social.uiVisible;
|
||||
|
@ -727,7 +731,7 @@ var SocialSidebar = {
|
|||
get chromeless() {
|
||||
let docElem = document.documentElement;
|
||||
return docElem.getAttribute('disablechrome') ||
|
||||
docElem.getAttribute('chromehidden').indexOf("extrachrome") >= 0;
|
||||
docElem.getAttribute('chromehidden').contains("toolbar");
|
||||
},
|
||||
|
||||
// Whether the user has toggled the sidebar on (for windows where it can appear)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
|
@ -226,7 +227,7 @@ PlacesController.prototype = {
|
|||
}
|
||||
else
|
||||
host = NetUtil.newURI(this._view.selectedNode.uri).host;
|
||||
PlacesUIUtils.privateBrowsing.removeDataFromDomain(host);
|
||||
ClearRecentHistory.removeDataFromDomain(host);
|
||||
break;
|
||||
case "cmd_selectAll":
|
||||
this.selectAll();
|
||||
|
|
|
@ -10,6 +10,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
Cu.import("resource://gre/modules/PluralForm.jsm");
|
||||
Cu.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
let gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
|
||||
getService(Ci.nsIFaviconService);
|
||||
|
@ -231,9 +232,7 @@ Site.prototype = {
|
|||
* Removes all data from the browser corresponding to the site.
|
||||
*/
|
||||
forgetSite: function Site_forgetSite() {
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
pb.removeDataFromDomain(this.host);
|
||||
ClearRecentHistory.removeDataFromDomain(this.host);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
Components.utils.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
const ABOUT_PERMISSIONS_SPEC = "about:permissions";
|
||||
|
||||
|
@ -115,9 +116,7 @@ var tests = [
|
|||
{
|
||||
desc: "test removing from sites-list before it is fully constructed.",
|
||||
preInit: function() {
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
pb.removeDataFromDomain(TEST_URI_2.host);
|
||||
ClearRecentHistory.removeDataFromDomain(TEST_URI_2.host);
|
||||
},
|
||||
run: function() {
|
||||
let testSite1 = getSiteItem(TEST_URI_1.host);
|
||||
|
|
|
@ -0,0 +1,226 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["ClearRecentHistory"];
|
||||
|
||||
/**
|
||||
* Returns true if the string passed in is part of the root domain of the
|
||||
* current string. For example, if this is "www.mozilla.org", and we pass in
|
||||
* "mozilla.org", this will return true. It would return false the other way
|
||||
* around.
|
||||
*/
|
||||
function hasRootDomain(str, aDomain)
|
||||
{
|
||||
let index = str.indexOf(aDomain);
|
||||
// If aDomain is not found, we know we do not have it as a root domain.
|
||||
if (index == -1)
|
||||
return false;
|
||||
|
||||
// If the strings are the same, we obviously have a match.
|
||||
if (str == aDomain)
|
||||
return true;
|
||||
|
||||
// Otherwise, we have aDomain as our root domain iff the index of aDomain is
|
||||
// aDomain.length subtracted from our length and (since we do not have an
|
||||
// exact match) the character before the index is a dot or slash.
|
||||
let prevChar = str[index - 1];
|
||||
return (index == (str.length - aDomain.length)) &&
|
||||
(prevChar == "." || prevChar == "/");
|
||||
}
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
var ClearRecentHistory = {
|
||||
removeDataFromDomain: function CRH_removeDataFromDomain(aDomain)
|
||||
{
|
||||
// clear any and all network geolocation provider sessions
|
||||
try {
|
||||
Services.prefs.deleteBranch("geo.wifi.access_token.");
|
||||
} catch (e) {}
|
||||
|
||||
// History
|
||||
let (bh = Cc["@mozilla.org/browser/global-history;2"].
|
||||
getService(Ci.nsIBrowserHistory)) {
|
||||
bh.removePagesFromHost(aDomain, true);
|
||||
}
|
||||
|
||||
// Cache
|
||||
let (cs = Cc["@mozilla.org/network/cache-service;1"].
|
||||
getService(Ci.nsICacheService)) {
|
||||
// NOTE: there is no way to clear just that domain, so we clear out
|
||||
// everything)
|
||||
try {
|
||||
cs.evictEntries(Ci.nsICache.STORE_ANYWHERE);
|
||||
} catch (ex) {
|
||||
Cu.reportError("Exception thrown while clearing the cache: " +
|
||||
ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Image Cache
|
||||
let (imageCache = Cc["@mozilla.org/image/tools;1"].
|
||||
getService(Ci.imgITools).getImgCacheForDocument(null)) {
|
||||
try {
|
||||
imageCache.clearCache(false); // true=chrome, false=content
|
||||
} catch (ex) {
|
||||
Cu.reportError("Exception thrown while clearing the image cache: " +
|
||||
ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Cookies
|
||||
let (cm = Cc["@mozilla.org/cookiemanager;1"].
|
||||
getService(Ci.nsICookieManager2)) {
|
||||
let enumerator = cm.getCookiesFromHost(aDomain);
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
|
||||
cm.remove(cookie.host, cookie.name, cookie.path, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin data
|
||||
const phInterface = Ci.nsIPluginHost;
|
||||
const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
|
||||
let (ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface)) {
|
||||
let tags = ph.getPluginTags();
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
try {
|
||||
ph.clearSiteData(tags[i], aDomain, FLAG_CLEAR_ALL, -1);
|
||||
} catch (e) {
|
||||
// Ignore errors from the plugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Downloads
|
||||
let (dm = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager)) {
|
||||
// Active downloads
|
||||
let enumerator = dm.activeDownloads;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
|
||||
if (hasRootDomain(dl.source.host, aDomain)) {
|
||||
dm.cancelDownload(dl.id);
|
||||
dm.removeDownload(dl.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Completed downloads
|
||||
let db = dm.DBConnection;
|
||||
// NOTE: This is lossy, but we feel that it is OK to be lossy here and not
|
||||
// invoke the cost of creating a URI for each download entry and
|
||||
// ensure that the hostname matches.
|
||||
let stmt = db.createStatement(
|
||||
"DELETE FROM moz_downloads " +
|
||||
"WHERE source LIKE ?1 ESCAPE '/' " +
|
||||
"AND state NOT IN (?2, ?3, ?4)"
|
||||
);
|
||||
let pattern = stmt.escapeStringForLIKE(aDomain, "/");
|
||||
stmt.bindByIndex(0, "%" + pattern + "%");
|
||||
stmt.bindByIndex(1, Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING);
|
||||
stmt.bindByIndex(2, Ci.nsIDownloadManager.DOWNLOAD_PAUSED);
|
||||
stmt.bindByIndex(3, Ci.nsIDownloadManager.DOWNLOAD_QUEUED);
|
||||
try {
|
||||
stmt.execute();
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
// We want to rebuild the list if the UI is showing, so dispatch the
|
||||
// observer topic
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "download-manager-remove-download", null);
|
||||
}
|
||||
|
||||
// Passwords
|
||||
let (lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager)) {
|
||||
// Clear all passwords for domain
|
||||
try {
|
||||
let logins = lm.getAllLogins();
|
||||
for (let i = 0; i < logins.length; i++)
|
||||
if (hasRootDomain(logins[i].hostname, aDomain))
|
||||
lm.removeLogin(logins[i]);
|
||||
}
|
||||
// XXXehsan: is there a better way to do this rather than this
|
||||
// hacky comparison?
|
||||
catch (ex if ex.message.indexOf("User canceled Master Password entry") != -1) { }
|
||||
|
||||
// Clear any "do not save for this site" for this domain
|
||||
let disabledHosts = lm.getAllDisabledHosts();
|
||||
for (let i = 0; i < disabledHosts.length; i++)
|
||||
if (hasRootDomain(disabledHosts[i], aDomain))
|
||||
lm.setLoginSavingEnabled(disabledHosts, true);
|
||||
}
|
||||
|
||||
// Permissions
|
||||
let (pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager)) {
|
||||
// Enumerate all of the permissions, and if one matches, remove it
|
||||
let enumerator = pm.enumerator;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
|
||||
if (hasRootDomain(perm.host, aDomain))
|
||||
pm.remove(perm.host, perm.type);
|
||||
}
|
||||
}
|
||||
|
||||
// Content Preferences
|
||||
let (cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService)) {
|
||||
let db = cp.DBConnection;
|
||||
// First we need to get the list of "groups" which are really just domains
|
||||
let names = [];
|
||||
let stmt = db.createStatement(
|
||||
"SELECT name " +
|
||||
"FROM groups " +
|
||||
"WHERE name LIKE ?1 ESCAPE '/'"
|
||||
);
|
||||
let pattern = stmt.escapeStringForLIKE(aDomain, "/");
|
||||
stmt.bindByIndex(0, "%" + pattern);
|
||||
try {
|
||||
while (stmt.executeStep())
|
||||
if (hasRootDomain(stmt.getString(0), aDomain))
|
||||
names.push(stmt.getString(0));
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
// Now, for each name we got back, remove all of its prefs.
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
let uri = names[i];
|
||||
let enumerator = cp.getPrefs(uri).enumerator;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let pref = enumerator.getNext().QueryInterface(Ci.nsIProperty);
|
||||
cp.removePref(uri, pref.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Indexed DB
|
||||
let (idbm = Cc["@mozilla.org/dom/indexeddb/manager;1"].
|
||||
getService(Ci.nsIIndexedDatabaseManager)) {
|
||||
// delete data from both HTTP and HTTPS sites
|
||||
let caUtils = {};
|
||||
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
getService(Ci.mozIJSSubScriptLoader);
|
||||
scriptLoader.loadSubScript("chrome://global/content/contentAreaUtils.js",
|
||||
caUtils);
|
||||
let httpURI = caUtils.makeURI("http://" + aDomain);
|
||||
let httpsURI = caUtils.makeURI("https://" + aDomain);
|
||||
idbm.clearDatabasesForURI(httpURI);
|
||||
idbm.clearDatabasesForURI(httpsURI);
|
||||
}
|
||||
|
||||
// Everybody else (including extensions)
|
||||
Services.obs.notifyObservers(null, "browser:purge-domain-data", aDomain);
|
||||
}
|
||||
};
|
|
@ -29,4 +29,8 @@ EXTRA_PP_COMPONENTS = \
|
|||
nsPrivateBrowsingService.js \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
ClearRecentHistory.jsm \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -9,34 +9,6 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
|||
#define BROKEN_WM_Z_ORDER
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Utilities
|
||||
|
||||
/**
|
||||
* Returns true if the string passed in is part of the root domain of the
|
||||
* current string. For example, if this is "www.mozilla.org", and we pass in
|
||||
* "mozilla.org", this will return true. It would return false the other way
|
||||
* around.
|
||||
*/
|
||||
String.prototype.hasRootDomain = function hasRootDomain(aDomain)
|
||||
{
|
||||
let index = this.indexOf(aDomain);
|
||||
// If aDomain is not found, we know we do not have it as a root domain.
|
||||
if (index == -1)
|
||||
return false;
|
||||
|
||||
// If the strings are the same, we obviously have a match.
|
||||
if (this == aDomain)
|
||||
return true;
|
||||
|
||||
// Otherwise, we have aDomain as our root domain iff the index of aDomain is
|
||||
// aDomain.length subtracted from our length and (since we do not have an
|
||||
// exact match) the character before the index is a dot or slash.
|
||||
let prevChar = this[index - 1];
|
||||
return (index == (this.length - aDomain.length)) &&
|
||||
(prevChar == "." || prevChar == "/");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Constants
|
||||
|
||||
|
@ -106,7 +78,7 @@ PrivateBrowsingService.prototype = {
|
|||
// XPCOM registration
|
||||
classID: Components.ID("{c31f4883-839b-45f6-82ad-a6a9bc5ad599}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrivateBrowsingService,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrivateBrowsingService,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsICommandLineHandler]),
|
||||
|
@ -608,195 +580,6 @@ PrivateBrowsingService.prototype = {
|
|||
*/
|
||||
get lastChangedByCommandLine() {
|
||||
return this._lastChangedByCommandLine;
|
||||
},
|
||||
|
||||
removeDataFromDomain: function PBS_removeDataFromDomain(aDomain)
|
||||
{
|
||||
|
||||
// clear any and all network geolocation provider sessions
|
||||
try {
|
||||
this._prefs.deleteBranch("geo.wifi.access_token.");
|
||||
} catch (e) {}
|
||||
|
||||
// History
|
||||
let (bh = Cc["@mozilla.org/browser/global-history;2"].
|
||||
getService(Ci.nsIBrowserHistory)) {
|
||||
bh.removePagesFromHost(aDomain, true);
|
||||
}
|
||||
|
||||
// Cache
|
||||
let (cs = Cc["@mozilla.org/network/cache-service;1"].
|
||||
getService(Ci.nsICacheService)) {
|
||||
// NOTE: there is no way to clear just that domain, so we clear out
|
||||
// everything)
|
||||
try {
|
||||
cs.evictEntries(Ci.nsICache.STORE_ANYWHERE);
|
||||
} catch (ex) {
|
||||
Cu.reportError("Exception thrown while clearing the cache: " +
|
||||
ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Image Cache
|
||||
let (imageCache = Cc["@mozilla.org/image/tools;1"].
|
||||
getService(Ci.imgITools).getImgCacheForDocument(null)) {
|
||||
try {
|
||||
imageCache.clearCache(false); // true=chrome, false=content
|
||||
} catch (ex) {
|
||||
Cu.reportError("Exception thrown while clearing the image cache: " +
|
||||
ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Cookies
|
||||
let (cm = Cc["@mozilla.org/cookiemanager;1"].
|
||||
getService(Ci.nsICookieManager2)) {
|
||||
let enumerator = cm.getCookiesFromHost(aDomain);
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
|
||||
cm.remove(cookie.host, cookie.name, cookie.path, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin data
|
||||
const phInterface = Ci.nsIPluginHost;
|
||||
const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
|
||||
let (ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface)) {
|
||||
let tags = ph.getPluginTags();
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
try {
|
||||
ph.clearSiteData(tags[i], aDomain, FLAG_CLEAR_ALL, -1);
|
||||
} catch (e) {
|
||||
// Ignore errors from the plugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Downloads
|
||||
let (dm = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager)) {
|
||||
// Active downloads
|
||||
let enumerator = dm.activeDownloads;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
|
||||
if (dl.source.host.hasRootDomain(aDomain)) {
|
||||
dm.cancelDownload(dl.id);
|
||||
dm.removeDownload(dl.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Completed downloads
|
||||
let db = dm.DBConnection;
|
||||
// NOTE: This is lossy, but we feel that it is OK to be lossy here and not
|
||||
// invoke the cost of creating a URI for each download entry and
|
||||
// ensure that the hostname matches.
|
||||
let stmt = db.createStatement(
|
||||
"DELETE FROM moz_downloads " +
|
||||
"WHERE source LIKE ?1 ESCAPE '/' " +
|
||||
"AND state NOT IN (?2, ?3, ?4)"
|
||||
);
|
||||
let pattern = stmt.escapeStringForLIKE(aDomain, "/");
|
||||
stmt.bindByIndex(0, "%" + pattern + "%");
|
||||
stmt.bindByIndex(1, Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING);
|
||||
stmt.bindByIndex(2, Ci.nsIDownloadManager.DOWNLOAD_PAUSED);
|
||||
stmt.bindByIndex(3, Ci.nsIDownloadManager.DOWNLOAD_QUEUED);
|
||||
try {
|
||||
stmt.execute();
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
// We want to rebuild the list if the UI is showing, so dispatch the
|
||||
// observer topic
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "download-manager-remove-download", null);
|
||||
}
|
||||
|
||||
// Passwords
|
||||
let (lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager)) {
|
||||
// Clear all passwords for domain
|
||||
try {
|
||||
let logins = lm.getAllLogins();
|
||||
for (let i = 0; i < logins.length; i++)
|
||||
if (logins[i].hostname.hasRootDomain(aDomain))
|
||||
lm.removeLogin(logins[i]);
|
||||
}
|
||||
// XXXehsan: is there a better way to do this rather than this
|
||||
// hacky comparison?
|
||||
catch (ex if ex.message.indexOf("User canceled Master Password entry") != -1) { }
|
||||
|
||||
// Clear any "do not save for this site" for this domain
|
||||
let disabledHosts = lm.getAllDisabledHosts();
|
||||
for (let i = 0; i < disabledHosts.length; i++)
|
||||
if (disabledHosts[i].hasRootDomain(aDomain))
|
||||
lm.setLoginSavingEnabled(disabledHosts, true);
|
||||
}
|
||||
|
||||
// Permissions
|
||||
let (pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager)) {
|
||||
// Enumerate all of the permissions, and if one matches, remove it
|
||||
let enumerator = pm.enumerator;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
|
||||
if (perm.host.hasRootDomain(aDomain))
|
||||
pm.remove(perm.host, perm.type);
|
||||
}
|
||||
}
|
||||
|
||||
// Content Preferences
|
||||
let (cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService)) {
|
||||
let db = cp.DBConnection;
|
||||
// First we need to get the list of "groups" which are really just domains
|
||||
let names = [];
|
||||
let stmt = db.createStatement(
|
||||
"SELECT name " +
|
||||
"FROM groups " +
|
||||
"WHERE name LIKE ?1 ESCAPE '/'"
|
||||
);
|
||||
let pattern = stmt.escapeStringForLIKE(aDomain, "/");
|
||||
stmt.bindByIndex(0, "%" + pattern);
|
||||
try {
|
||||
while (stmt.executeStep())
|
||||
if (stmt.getString(0).hasRootDomain(aDomain))
|
||||
names.push(stmt.getString(0));
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
// Now, for each name we got back, remove all of its prefs.
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
let uri = names[i];
|
||||
let enumerator = cp.getPrefs(uri).enumerator;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let pref = enumerator.getNext().QueryInterface(Ci.nsIProperty);
|
||||
cp.removePref(uri, pref.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Indexed DB
|
||||
let (idbm = Cc["@mozilla.org/dom/indexeddb/manager;1"].
|
||||
getService(Ci.nsIIndexedDatabaseManager)) {
|
||||
// delete data from both HTTP and HTTPS sites
|
||||
let caUtils = {};
|
||||
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
getService(Ci.mozIJSSubScriptLoader);
|
||||
scriptLoader.loadSubScript("chrome://global/content/contentAreaUtils.js",
|
||||
caUtils);
|
||||
let httpURI = caUtils.makeURI("http://" + aDomain);
|
||||
let httpsURI = caUtils.makeURI("https://" + aDomain);
|
||||
idbm.clearDatabasesForURI(httpURI);
|
||||
idbm.clearDatabasesForURI(httpsURI);
|
||||
}
|
||||
|
||||
// Everybody else (including extensions)
|
||||
this._obs.notifyObservers(null, "browser:purge-domain-data", aDomain);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -83,13 +83,6 @@ nsPrivateBrowsingServiceWrapper::GetLastChangedByCommandLine(bool *aReason)
|
|||
return mPBService->GetLastChangedByCommandLine(aReason);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrivateBrowsingServiceWrapper::RemoveDataFromDomain(const nsACString & aDomain)
|
||||
{
|
||||
JSStackGuard guard;
|
||||
return mPBService->RemoveDataFromDomain(aDomain);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrivateBrowsingServiceWrapper::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
// Test clearing plugin data by domain using nsPrivateBrowsingService.
|
||||
const testURL = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_clearplugindata.html";
|
||||
|
||||
|
@ -66,25 +68,22 @@ function do_test()
|
|||
ok(stored(["192.168.1.1","foo.com","nonexistent.foo.com","bar.com","localhost"]),
|
||||
"Data stored for sites");
|
||||
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
|
||||
// Clear data for "foo.com" and its subdomains.
|
||||
pb.removeDataFromDomain("foo.com");
|
||||
ClearRecentHistory.removeDataFromDomain("foo.com");
|
||||
ok(stored(["bar.com","192.168.1.1","localhost"]), "Data stored for sites");
|
||||
ok(!stored(["foo.com"]), "Data cleared for foo.com");
|
||||
ok(!stored(["bar.foo.com"]), "Data cleared for subdomains of foo.com");
|
||||
|
||||
// Clear data for "bar.com" using a subdomain.
|
||||
pb.removeDataFromDomain("foo.bar.com");
|
||||
ClearRecentHistory.removeDataFromDomain("foo.bar.com");
|
||||
ok(!stored(["bar.com"]), "Data cleared for bar.com");
|
||||
|
||||
// Clear data for "192.168.1.1".
|
||||
pb.removeDataFromDomain("192.168.1.1");
|
||||
ClearRecentHistory.removeDataFromDomain("192.168.1.1");
|
||||
ok(!stored(["192.168.1.1"]), "Data cleared for 192.168.1.1");
|
||||
|
||||
// Clear data for "localhost".
|
||||
pb.removeDataFromDomain("localhost");
|
||||
ClearRecentHistory.removeDataFromDomain("localhost");
|
||||
ok(!stored(null), "All data cleared");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
|
|
|
@ -1,630 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test added with bug 460086 to test the behavior of the new API that was added
|
||||
* to remove all traces of visiting a site.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
|
||||
const COOKIE_EXPIRY = Math.round(Date.now() / 1000) + 60;
|
||||
const COOKIE_NAME = "testcookie";
|
||||
const COOKIE_PATH = "/";
|
||||
|
||||
const LOGIN_USERNAME = "username";
|
||||
const LOGIN_PASSWORD = "password";
|
||||
const LOGIN_USERNAME_FIELD = "username_field";
|
||||
const LOGIN_PASSWORD_FIELD = "password_field";
|
||||
|
||||
const PERMISSION_TYPE = "test-perm";
|
||||
const PERMISSION_VALUE = Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||
|
||||
const PREFERENCE_NAME = "test-pref";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Utility Functions
|
||||
|
||||
/**
|
||||
* Creates an nsIURI object for the given string representation of a URI.
|
||||
*
|
||||
* @param aURIString
|
||||
* The spec of the URI to create.
|
||||
* @returns an nsIURI representing aURIString.
|
||||
*/
|
||||
function uri(aURIString)
|
||||
{
|
||||
return Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService).
|
||||
newURI(aURIString, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a visit to history.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add.
|
||||
*/
|
||||
function add_visit(aURI)
|
||||
{
|
||||
check_visited(aURI, false);
|
||||
PlacesUtils.history.addVisit(aURI, Date.now() * 1000, null,
|
||||
Ci.nsINavHistoryService.TRANSITION_LINK, false,
|
||||
0);
|
||||
check_visited(aURI, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure a URI string is visited or not.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check.
|
||||
* @param aIsVisited
|
||||
* True if the URI should be visited, false otherwise.
|
||||
*/
|
||||
function check_visited(aURI, aIsVisited)
|
||||
{
|
||||
let checker = aIsVisited ? do_check_true : do_check_false;
|
||||
checker(PlacesUtils.ghistory2.isVisited(aURI));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cookie to the cookie service.
|
||||
*
|
||||
* @param aDomain
|
||||
*/
|
||||
function add_cookie(aDomain)
|
||||
{
|
||||
check_cookie_exists(aDomain, false);
|
||||
let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
|
||||
cm.add(aDomain, COOKIE_PATH, COOKIE_NAME, "", false, false, false,
|
||||
COOKIE_EXPIRY);
|
||||
check_cookie_exists(aDomain, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure that a cookie exists or not for a domain.
|
||||
*
|
||||
* @param aDomain
|
||||
* The domain to check for the cookie.
|
||||
* @param aExists
|
||||
* True if the cookie should exist, false otherwise.
|
||||
*/
|
||||
function check_cookie_exists(aDomain, aExists)
|
||||
{
|
||||
let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
|
||||
let cookie = {
|
||||
host: aDomain,
|
||||
name: COOKIE_NAME,
|
||||
path: COOKIE_PATH
|
||||
}
|
||||
let checker = aExists ? do_check_true : do_check_false;
|
||||
checker(cm.cookieExists(cookie));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a download to download history.
|
||||
*
|
||||
* @param aURIString
|
||||
* The string of the URI to add.
|
||||
* @param aIsActive
|
||||
* If it should be set to an active state in the database. This does not
|
||||
* make it show up in the list of active downloads however!
|
||||
*/
|
||||
function add_download(aURIString, aIsActive)
|
||||
{
|
||||
check_downloaded(aURIString, false);
|
||||
let db = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager).
|
||||
DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"INSERT INTO moz_downloads (source, state) " +
|
||||
"VALUES (:source, :state)"
|
||||
);
|
||||
stmt.params.source = aURIString;
|
||||
stmt.params.state = aIsActive ? Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING :
|
||||
Ci.nsIDownloadManager.DOWNLOAD_FINISHED;
|
||||
try {
|
||||
stmt.execute();
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
check_downloaded(aURIString, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure a URI string is in download history or not.
|
||||
*
|
||||
* @param aURIString
|
||||
* The string of the URI to check.
|
||||
* @param aIsDownloaded
|
||||
* True if the URI should be downloaded, false otherwise.
|
||||
*/
|
||||
function check_downloaded(aURIString, aIsDownloaded)
|
||||
{
|
||||
let db = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager).
|
||||
DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT * " +
|
||||
"FROM moz_downloads " +
|
||||
"WHERE source = :source"
|
||||
);
|
||||
stmt.params.source = aURIString;
|
||||
|
||||
let checker = aIsDownloaded ? do_check_true : do_check_false;
|
||||
try {
|
||||
checker(stmt.executeStep());
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a disabled host to the login manager.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to add to the list of disabled hosts.
|
||||
*/
|
||||
function add_disabled_host(aHost)
|
||||
{
|
||||
check_disabled_host(aHost, false);
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.setLoginSavingEnabled(aHost, false);
|
||||
check_disabled_host(aHost, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a host is disabled for storing logins or not.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to check if it is disabled.
|
||||
* @param aIsDisabled
|
||||
* True if the host should be disabled, false otherwise.
|
||||
*/
|
||||
function check_disabled_host(aHost, aIsDisabled)
|
||||
{
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
let checker = aIsDisabled ? do_check_false : do_check_true;
|
||||
checker(lm.getLoginSavingEnabled(aHost));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a login for the specified host to the login manager.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to add the login for.
|
||||
*/
|
||||
function add_login(aHost)
|
||||
{
|
||||
check_login_exists(aHost, false);
|
||||
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
login.init(aHost, "", null, LOGIN_USERNAME, LOGIN_PASSWORD,
|
||||
LOGIN_USERNAME_FIELD, LOGIN_PASSWORD_FIELD);
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.addLogin(login);
|
||||
check_login_exists(aHost, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a login exists for a host.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to check for the test login.
|
||||
* @param aExists
|
||||
* True if the login should exist, false otherwise.
|
||||
*/
|
||||
function check_login_exists(aHost, aExists)
|
||||
{
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
let count = { value: 0 };
|
||||
lm.findLogins(count, aHost, "", null);
|
||||
do_check_eq(count.value, aExists ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a permission for the specified URI to the permission manager.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add the test permission for.
|
||||
*/
|
||||
function add_permission(aURI)
|
||||
{
|
||||
check_permission_exists(aURI, false);
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager);
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getNoAppCodebasePrincipal(aURI);
|
||||
|
||||
pm.addFromPrincipal(principal, PERMISSION_TYPE, PERMISSION_VALUE);
|
||||
check_permission_exists(aURI, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a permission exists for the given URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check if a permission exists.
|
||||
* @param aExists
|
||||
* True if the permission should exist, false otherwise.
|
||||
*/
|
||||
function check_permission_exists(aURI, aExists)
|
||||
{
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager);
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getNoAppCodebasePrincipal(aURI);
|
||||
|
||||
let perm = pm.testExactPermissionFromPrincipal(principal, PERMISSION_TYPE);
|
||||
let checker = aExists ? do_check_eq : do_check_neq;
|
||||
checker(perm, PERMISSION_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a content preference for the specified URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add a preference for.
|
||||
*/
|
||||
function add_preference(aURI)
|
||||
{
|
||||
check_preference_exists(aURI, false);
|
||||
let cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
cp.setPref(aURI, PREFERENCE_NAME, "foo");
|
||||
check_preference_exists(aURI, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a preference exists for the given URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check if a preference exists.
|
||||
* @param aExists
|
||||
* True if the permission should exist, false otherwise.
|
||||
*/
|
||||
function check_preference_exists(aURI, aExists)
|
||||
{
|
||||
let cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
let checker = aExists ? do_check_true : do_check_false;
|
||||
checker(cp.hasPref(aURI, PREFERENCE_NAME));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Functions
|
||||
|
||||
// History
|
||||
function test_history_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = uri("http://mozilla.org/foo");
|
||||
add_visit(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_visited(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_history_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = uri("http://www.mozilla.org/foo");
|
||||
add_visit(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_visited(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_history_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_URI = uri("http://ilovemozilla.org/foo");
|
||||
add_visit(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_visited(TEST_URI, true);
|
||||
|
||||
// Clear history since we left something there from this test.
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
||||
// Cookie Service
|
||||
function test_cookie_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_DOMAIN = "mozilla.org";
|
||||
add_cookie(TEST_DOMAIN);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_cookie_exists(TEST_DOMAIN, false);
|
||||
}
|
||||
|
||||
function test_cookie_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_DOMAIN = "www.mozilla.org";
|
||||
add_cookie(TEST_DOMAIN);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_cookie_exists(TEST_DOMAIN, false);
|
||||
}
|
||||
|
||||
function test_cookie_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_DOMAIN = "ilovemozilla.org";
|
||||
add_cookie(TEST_DOMAIN);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_cookie_exists(TEST_DOMAIN, true);
|
||||
}
|
||||
|
||||
// Download Manager
|
||||
function test_download_history_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = "http://mozilla.org/foo";
|
||||
add_download(TEST_URI, false);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_downloaded(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_download_history_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = "http://www.mozilla.org/foo";
|
||||
add_download(TEST_URI, false);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_downloaded(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_download_history_not_cleared_with_active_direct_match()
|
||||
{
|
||||
// Tests that downloads marked as active in the db are not deleted from the db
|
||||
const TEST_URI = "http://mozilla.org/foo";
|
||||
add_download(TEST_URI, true);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_downloaded(TEST_URI, true);
|
||||
|
||||
// Reset state
|
||||
let db = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager).
|
||||
DBConnection;
|
||||
db.executeSimpleSQL("DELETE FROM moz_downloads");
|
||||
check_downloaded(TEST_URI, false);
|
||||
}
|
||||
|
||||
// Login Manager
|
||||
function test_login_manager_disabled_hosts_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_HOST = "http://mozilla.org";
|
||||
add_disabled_host(TEST_HOST);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_disabled_host(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_disabled_hosts_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_HOST = "http://www.mozilla.org";
|
||||
add_disabled_host(TEST_HOST);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_disabled_host(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_HOST = "http://ilovemozilla.org";
|
||||
add_disabled_host(TEST_HOST);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_disabled_host(TEST_HOST, true);
|
||||
|
||||
// Reset state
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.setLoginSavingEnabled(TEST_HOST, true);
|
||||
check_disabled_host(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_logins_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_HOST = "http://mozilla.org";
|
||||
add_login(TEST_HOST);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_login_exists(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_logins_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_HOST = "http://www.mozilla.org";
|
||||
add_login(TEST_HOST);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_login_exists(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function tets_login_manager_logins_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_HOST = "http://ilovemozilla.org";
|
||||
add_login(TEST_HOST);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_login_exists(TEST_HOST, true);
|
||||
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.removeAllLogins();
|
||||
check_login_exists(TEST_HOST, false);
|
||||
}
|
||||
|
||||
// Permission Manager
|
||||
function test_permission_manager_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = uri("http://mozilla.org");
|
||||
add_permission(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_permission_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_permission_manager_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = uri("http://www.mozilla.org");
|
||||
add_permission(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_permission_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_permission_manager_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_URI = uri("http://ilovemozilla.org");
|
||||
add_permission(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_permission_exists(TEST_URI, true);
|
||||
|
||||
// Reset state
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager);
|
||||
pm.removeAll();
|
||||
check_permission_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
// Content Preferences
|
||||
function test_content_preferences_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = uri("http://mozilla.org");
|
||||
add_preference(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_preference_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_content_preferences_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = uri("http://www.mozilla.org");
|
||||
add_preference(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_preference_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_content_preferecnes_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_URI = uri("http://ilovemozilla.org");
|
||||
add_preference(TEST_URI);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
check_preference_exists(TEST_URI, true);
|
||||
|
||||
// Reset state
|
||||
let cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
cp.removePref(TEST_URI, PREFERENCE_NAME);
|
||||
check_preference_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
// Cache
|
||||
function test_cache_cleared()
|
||||
{
|
||||
// Because this test is asynchronous, it should be the last test
|
||||
do_check_eq(tests[tests.length - 1], arguments.callee);
|
||||
|
||||
// NOTE: We could be more extensive with this test and actually add an entry
|
||||
// to the cache, and then make sure it is gone. However, we trust that
|
||||
// the API is well tested, and that when we get the observer
|
||||
// notification, we have actually cleared the cache.
|
||||
// This seems to happen asynchronously...
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
os.removeObserver(observer, "cacheservice:empty-cache");
|
||||
do_test_finished();
|
||||
}
|
||||
};
|
||||
os.addObserver(observer, "cacheservice:empty-cache", false);
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_storage_cleared()
|
||||
{
|
||||
function getStorageForURI(aURI)
|
||||
{
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Ci.nsIScriptSecurityManager).
|
||||
getNoAppCodebasePrincipal(aURI);
|
||||
let dsm = Cc["@mozilla.org/dom/storagemanager;1"].
|
||||
getService(Ci.nsIDOMStorageManager);
|
||||
return dsm.getLocalStorageForPrincipal(principal, "");
|
||||
}
|
||||
|
||||
let s = [
|
||||
getStorageForURI(uri("http://mozilla.org")),
|
||||
getStorageForURI(uri("http://my.mozilla.org")),
|
||||
getStorageForURI(uri("http://ilovemozilla.org")),
|
||||
];
|
||||
|
||||
for (let i = 0; i < s.length; ++i) {
|
||||
let storage = s[i];
|
||||
storage.setItem("test", "value" + i);
|
||||
do_check_eq(storage.length, 1);
|
||||
do_check_eq(storage.key(0), "test");
|
||||
do_check_eq(storage.getItem("test"), "value" + i);
|
||||
}
|
||||
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
|
||||
do_check_eq(s[0].getItem("test"), null);
|
||||
do_check_eq(s[0].length, 0);
|
||||
do_check_eq(s[1].getItem("test"), null);
|
||||
do_check_eq(s[1].length, 0);
|
||||
do_check_eq(s[2].getItem("test"), "value2");
|
||||
do_check_eq(s[2].length, 1);
|
||||
}
|
||||
|
||||
let tests = [
|
||||
// History
|
||||
test_history_cleared_with_direct_match,
|
||||
test_history_cleared_with_subdomain,
|
||||
test_history_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Cookie Service
|
||||
test_cookie_cleared_with_direct_match,
|
||||
test_cookie_cleared_with_subdomain,
|
||||
test_cookie_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Download Manager
|
||||
// Note: active downloads tested in test_removeDataFromDomain_activeDownloads.js
|
||||
test_download_history_cleared_with_direct_match,
|
||||
test_download_history_cleared_with_subdomain,
|
||||
test_download_history_not_cleared_with_active_direct_match,
|
||||
|
||||
// Login Manager
|
||||
test_login_manager_disabled_hosts_cleared_with_direct_match,
|
||||
test_login_manager_disabled_hosts_cleared_with_subdomain,
|
||||
test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain,
|
||||
test_login_manager_logins_cleared_with_direct_match,
|
||||
test_login_manager_logins_cleared_with_subdomain,
|
||||
tets_login_manager_logins_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Permission Manager
|
||||
test_permission_manager_cleared_with_direct_match,
|
||||
test_permission_manager_cleared_with_subdomain,
|
||||
test_permission_manager_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Content Preferences
|
||||
test_content_preferences_cleared_with_direct_match,
|
||||
test_content_preferences_cleared_with_subdomain,
|
||||
test_content_preferecnes_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Storage
|
||||
test_storage_cleared,
|
||||
|
||||
// Cache
|
||||
test_cache_cleared,
|
||||
];
|
||||
|
||||
function do_test()
|
||||
{
|
||||
for (let i = 0; i < tests.length; i++)
|
||||
tests[i]();
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test added with bug 460086 to test the behavior of the new API that was added
|
||||
* to remove all traces of visiting a site.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Constants
|
||||
|
||||
let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Utility Functions
|
||||
|
||||
/**
|
||||
* Creates an nsIURI object for the given file.
|
||||
*
|
||||
* @param aFile
|
||||
* The nsIFile of the URI to create.
|
||||
* @returns an nsIURI representing aFile.
|
||||
*/
|
||||
function uri(aFile)
|
||||
{
|
||||
return Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService).
|
||||
newFileURI(aFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure a URI string is in download history or not.
|
||||
*
|
||||
* @param aURIString
|
||||
* The string of the URI to check.
|
||||
* @param aIsActive
|
||||
* True if the URI should be actively downloaded, false otherwise.
|
||||
*/
|
||||
function check_active_download(aURIString, aIsActive)
|
||||
{
|
||||
let dm = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager);
|
||||
let enumerator = dm.activeDownloads;
|
||||
let found = false;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
|
||||
if (dl.source.spec == aURIString)
|
||||
found = true;
|
||||
}
|
||||
let checker = aIsActive ? do_check_true : do_check_false;
|
||||
checker(found);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Functions
|
||||
|
||||
let destFile = dirSvc.get("TmpD", Ci.nsIFile);
|
||||
destFile.append("dm-test-file");
|
||||
destFile = uri(destFile);
|
||||
let data = [
|
||||
{ source: "http://mozilla.org/direct_match",
|
||||
target: destFile.spec,
|
||||
removed: true
|
||||
},
|
||||
{ source: "http://www.mozilla.org/subdomain",
|
||||
target: destFile.spec,
|
||||
removed: true
|
||||
},
|
||||
{ source: "http://ilovemozilla.org/contains_domain",
|
||||
target: destFile.spec,
|
||||
removed: false
|
||||
},
|
||||
];
|
||||
|
||||
function do_test()
|
||||
{
|
||||
// We add this data to the database first, but we cannot instantiate the
|
||||
// download manager service, otherwise these downloads will not be placed in
|
||||
// the active downloads array.
|
||||
|
||||
// Copy the empty downloads database to our profile directory
|
||||
let downloads = do_get_file("downloads.empty.sqlite");
|
||||
downloads.copyTo(dirSvc.get("ProfD", Ci.nsIFile), "downloads.sqlite");
|
||||
|
||||
// Open the database
|
||||
let ss = Cc["@mozilla.org/storage/service;1"].
|
||||
getService(Ci.mozIStorageService);
|
||||
let file = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
file.append("downloads.sqlite");
|
||||
let db = ss.openDatabase(file);
|
||||
|
||||
// Insert the data
|
||||
let stmt = db.createStatement(
|
||||
"INSERT INTO moz_downloads (source, target, state, autoResume, entityID) " +
|
||||
"VALUES (:source, :target, :state, :autoResume, :entityID)"
|
||||
);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
stmt.params.source = data[i].source;
|
||||
stmt.params.target = data[i].target;
|
||||
stmt.params.state = Ci.nsIDownloadManager.DOWNLOAD_PAUSED;
|
||||
stmt.params.autoResume = 0; // DONT_RESUME is 0
|
||||
stmt.params.entityID = "foo" // just has to be non-null for our test
|
||||
stmt.execute();
|
||||
stmt.reset();
|
||||
}
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
db.close();
|
||||
db = null;
|
||||
|
||||
// Check to make sure it's all there
|
||||
for (let i = 0; i < data.length; i++)
|
||||
check_active_download(data[i].source, true);
|
||||
|
||||
// Dispatch the remove call
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
|
||||
// And check our data
|
||||
for (let i = 0; i < data.length; i++)
|
||||
check_active_download(data[i].source, !data[i].removed);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test added with bug 460086 to test the behavior of the new API that was added
|
||||
* to remove all traces of visiting a site.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function run_test() {
|
||||
PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing-wrapper;1";
|
||||
load("do_test_removeDataFromDomain.js");
|
||||
do_test();
|
||||
|
||||
// Shutdown the download manager.
|
||||
Services.obs.notifyObservers(null, "quit-application", null);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* Test added with bug 460086 to test the behavior of the new API that was added
|
||||
* to remove all traces of visiting a site.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function run_test() {
|
||||
PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
|
||||
load("do_test_removeDataFromDomain_activeDownloads.js");
|
||||
do_test();
|
||||
|
||||
// Shutdown the download manager.
|
||||
Services.obs.notifyObservers(null, "quit-application", null);
|
||||
}
|
|
@ -9,12 +9,623 @@
|
|||
* to remove all traces of visiting a site.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
|
||||
function run_test() {
|
||||
PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
|
||||
load("do_test_removeDataFromDomain.js");
|
||||
do_test();
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
const COOKIE_EXPIRY = Math.round(Date.now() / 1000) + 60;
|
||||
const COOKIE_NAME = "testcookie";
|
||||
const COOKIE_PATH = "/";
|
||||
|
||||
const LOGIN_USERNAME = "username";
|
||||
const LOGIN_PASSWORD = "password";
|
||||
const LOGIN_USERNAME_FIELD = "username_field";
|
||||
const LOGIN_PASSWORD_FIELD = "password_field";
|
||||
|
||||
const PERMISSION_TYPE = "test-perm";
|
||||
const PERMISSION_VALUE = Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||
|
||||
const PREFERENCE_NAME = "test-pref";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Utility Functions
|
||||
|
||||
/**
|
||||
* Creates an nsIURI object for the given string representation of a URI.
|
||||
*
|
||||
* @param aURIString
|
||||
* The spec of the URI to create.
|
||||
* @returns an nsIURI representing aURIString.
|
||||
*/
|
||||
function uri(aURIString)
|
||||
{
|
||||
return Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService).
|
||||
newURI(aURIString, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a visit to history.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add.
|
||||
*/
|
||||
function add_visit(aURI)
|
||||
{
|
||||
check_visited(aURI, false);
|
||||
PlacesUtils.history.addVisit(aURI, Date.now() * 1000, null,
|
||||
Ci.nsINavHistoryService.TRANSITION_LINK, false,
|
||||
0);
|
||||
check_visited(aURI, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure a URI string is visited or not.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check.
|
||||
* @param aIsVisited
|
||||
* True if the URI should be visited, false otherwise.
|
||||
*/
|
||||
function check_visited(aURI, aIsVisited)
|
||||
{
|
||||
let checker = aIsVisited ? do_check_true : do_check_false;
|
||||
checker(PlacesUtils.ghistory2.isVisited(aURI));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cookie to the cookie service.
|
||||
*
|
||||
* @param aDomain
|
||||
*/
|
||||
function add_cookie(aDomain)
|
||||
{
|
||||
check_cookie_exists(aDomain, false);
|
||||
let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
|
||||
cm.add(aDomain, COOKIE_PATH, COOKIE_NAME, "", false, false, false,
|
||||
COOKIE_EXPIRY);
|
||||
check_cookie_exists(aDomain, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure that a cookie exists or not for a domain.
|
||||
*
|
||||
* @param aDomain
|
||||
* The domain to check for the cookie.
|
||||
* @param aExists
|
||||
* True if the cookie should exist, false otherwise.
|
||||
*/
|
||||
function check_cookie_exists(aDomain, aExists)
|
||||
{
|
||||
let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
|
||||
let cookie = {
|
||||
host: aDomain,
|
||||
name: COOKIE_NAME,
|
||||
path: COOKIE_PATH
|
||||
}
|
||||
let checker = aExists ? do_check_true : do_check_false;
|
||||
checker(cm.cookieExists(cookie));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a download to download history.
|
||||
*
|
||||
* @param aURIString
|
||||
* The string of the URI to add.
|
||||
* @param aIsActive
|
||||
* If it should be set to an active state in the database. This does not
|
||||
* make it show up in the list of active downloads however!
|
||||
*/
|
||||
function add_download(aURIString, aIsActive)
|
||||
{
|
||||
check_downloaded(aURIString, false);
|
||||
let db = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager).
|
||||
DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"INSERT INTO moz_downloads (source, state) " +
|
||||
"VALUES (:source, :state)"
|
||||
);
|
||||
stmt.params.source = aURIString;
|
||||
stmt.params.state = aIsActive ? Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING :
|
||||
Ci.nsIDownloadManager.DOWNLOAD_FINISHED;
|
||||
try {
|
||||
stmt.execute();
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
check_downloaded(aURIString, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure a URI string is in download history or not.
|
||||
*
|
||||
* @param aURIString
|
||||
* The string of the URI to check.
|
||||
* @param aIsDownloaded
|
||||
* True if the URI should be downloaded, false otherwise.
|
||||
*/
|
||||
function check_downloaded(aURIString, aIsDownloaded)
|
||||
{
|
||||
let db = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager).
|
||||
DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT * " +
|
||||
"FROM moz_downloads " +
|
||||
"WHERE source = :source"
|
||||
);
|
||||
stmt.params.source = aURIString;
|
||||
|
||||
let checker = aIsDownloaded ? do_check_true : do_check_false;
|
||||
try {
|
||||
checker(stmt.executeStep());
|
||||
}
|
||||
finally {
|
||||
stmt.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a disabled host to the login manager.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to add to the list of disabled hosts.
|
||||
*/
|
||||
function add_disabled_host(aHost)
|
||||
{
|
||||
check_disabled_host(aHost, false);
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.setLoginSavingEnabled(aHost, false);
|
||||
check_disabled_host(aHost, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a host is disabled for storing logins or not.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to check if it is disabled.
|
||||
* @param aIsDisabled
|
||||
* True if the host should be disabled, false otherwise.
|
||||
*/
|
||||
function check_disabled_host(aHost, aIsDisabled)
|
||||
{
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
let checker = aIsDisabled ? do_check_false : do_check_true;
|
||||
checker(lm.getLoginSavingEnabled(aHost));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a login for the specified host to the login manager.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to add the login for.
|
||||
*/
|
||||
function add_login(aHost)
|
||||
{
|
||||
check_login_exists(aHost, false);
|
||||
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
login.init(aHost, "", null, LOGIN_USERNAME, LOGIN_PASSWORD,
|
||||
LOGIN_USERNAME_FIELD, LOGIN_PASSWORD_FIELD);
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.addLogin(login);
|
||||
check_login_exists(aHost, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a login exists for a host.
|
||||
*
|
||||
* @param aHost
|
||||
* The host to check for the test login.
|
||||
* @param aExists
|
||||
* True if the login should exist, false otherwise.
|
||||
*/
|
||||
function check_login_exists(aHost, aExists)
|
||||
{
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
let count = { value: 0 };
|
||||
lm.findLogins(count, aHost, "", null);
|
||||
do_check_eq(count.value, aExists ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a permission for the specified URI to the permission manager.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add the test permission for.
|
||||
*/
|
||||
function add_permission(aURI)
|
||||
{
|
||||
check_permission_exists(aURI, false);
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager);
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getNoAppCodebasePrincipal(aURI);
|
||||
|
||||
pm.addFromPrincipal(principal, PERMISSION_TYPE, PERMISSION_VALUE);
|
||||
check_permission_exists(aURI, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a permission exists for the given URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check if a permission exists.
|
||||
* @param aExists
|
||||
* True if the permission should exist, false otherwise.
|
||||
*/
|
||||
function check_permission_exists(aURI, aExists)
|
||||
{
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager);
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getNoAppCodebasePrincipal(aURI);
|
||||
|
||||
let perm = pm.testExactPermissionFromPrincipal(principal, PERMISSION_TYPE);
|
||||
let checker = aExists ? do_check_eq : do_check_neq;
|
||||
checker(perm, PERMISSION_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a content preference for the specified URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add a preference for.
|
||||
*/
|
||||
function add_preference(aURI)
|
||||
{
|
||||
check_preference_exists(aURI, false);
|
||||
let cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
cp.setPref(aURI, PREFERENCE_NAME, "foo");
|
||||
check_preference_exists(aURI, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a preference exists for the given URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to check if a preference exists.
|
||||
* @param aExists
|
||||
* True if the permission should exist, false otherwise.
|
||||
*/
|
||||
function check_preference_exists(aURI, aExists)
|
||||
{
|
||||
let cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
let checker = aExists ? do_check_true : do_check_false;
|
||||
checker(cp.hasPref(aURI, PREFERENCE_NAME));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Functions
|
||||
|
||||
// History
|
||||
function test_history_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = uri("http://mozilla.org/foo");
|
||||
add_visit(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_visited(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_history_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = uri("http://www.mozilla.org/foo");
|
||||
add_visit(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_visited(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_history_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_URI = uri("http://ilovemozilla.org/foo");
|
||||
add_visit(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_visited(TEST_URI, true);
|
||||
|
||||
// Clear history since we left something there from this test.
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
||||
// Cookie Service
|
||||
function test_cookie_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_DOMAIN = "mozilla.org";
|
||||
add_cookie(TEST_DOMAIN);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_cookie_exists(TEST_DOMAIN, false);
|
||||
}
|
||||
|
||||
function test_cookie_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_DOMAIN = "www.mozilla.org";
|
||||
add_cookie(TEST_DOMAIN);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_cookie_exists(TEST_DOMAIN, false);
|
||||
}
|
||||
|
||||
function test_cookie_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_DOMAIN = "ilovemozilla.org";
|
||||
add_cookie(TEST_DOMAIN);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_cookie_exists(TEST_DOMAIN, true);
|
||||
}
|
||||
|
||||
// Download Manager
|
||||
function test_download_history_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = "http://mozilla.org/foo";
|
||||
add_download(TEST_URI, false);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_downloaded(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_download_history_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = "http://www.mozilla.org/foo";
|
||||
add_download(TEST_URI, false);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_downloaded(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_download_history_not_cleared_with_active_direct_match()
|
||||
{
|
||||
// Tests that downloads marked as active in the db are not deleted from the db
|
||||
const TEST_URI = "http://mozilla.org/foo";
|
||||
add_download(TEST_URI, true);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_downloaded(TEST_URI, true);
|
||||
|
||||
// Reset state
|
||||
let db = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager).
|
||||
DBConnection;
|
||||
db.executeSimpleSQL("DELETE FROM moz_downloads");
|
||||
check_downloaded(TEST_URI, false);
|
||||
}
|
||||
|
||||
// Login Manager
|
||||
function test_login_manager_disabled_hosts_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_HOST = "http://mozilla.org";
|
||||
add_disabled_host(TEST_HOST);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_disabled_host(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_disabled_hosts_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_HOST = "http://www.mozilla.org";
|
||||
add_disabled_host(TEST_HOST);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_disabled_host(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_HOST = "http://ilovemozilla.org";
|
||||
add_disabled_host(TEST_HOST);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_disabled_host(TEST_HOST, true);
|
||||
|
||||
// Reset state
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.setLoginSavingEnabled(TEST_HOST, true);
|
||||
check_disabled_host(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_logins_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_HOST = "http://mozilla.org";
|
||||
add_login(TEST_HOST);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_login_exists(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function test_login_manager_logins_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_HOST = "http://www.mozilla.org";
|
||||
add_login(TEST_HOST);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_login_exists(TEST_HOST, false);
|
||||
}
|
||||
|
||||
function tets_login_manager_logins_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_HOST = "http://ilovemozilla.org";
|
||||
add_login(TEST_HOST);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_login_exists(TEST_HOST, true);
|
||||
|
||||
let lm = Cc["@mozilla.org/login-manager;1"].
|
||||
getService(Ci.nsILoginManager);
|
||||
lm.removeAllLogins();
|
||||
check_login_exists(TEST_HOST, false);
|
||||
}
|
||||
|
||||
// Permission Manager
|
||||
function test_permission_manager_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = uri("http://mozilla.org");
|
||||
add_permission(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_permission_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_permission_manager_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = uri("http://www.mozilla.org");
|
||||
add_permission(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_permission_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_permission_manager_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_URI = uri("http://ilovemozilla.org");
|
||||
add_permission(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_permission_exists(TEST_URI, true);
|
||||
|
||||
// Reset state
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager);
|
||||
pm.removeAll();
|
||||
check_permission_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
// Content Preferences
|
||||
function test_content_preferences_cleared_with_direct_match()
|
||||
{
|
||||
const TEST_URI = uri("http://mozilla.org");
|
||||
add_preference(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_preference_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_content_preferences_cleared_with_subdomain()
|
||||
{
|
||||
const TEST_URI = uri("http://www.mozilla.org");
|
||||
add_preference(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_preference_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
function test_content_preferecnes_not_cleared_with_uri_contains_domain()
|
||||
{
|
||||
const TEST_URI = uri("http://ilovemozilla.org");
|
||||
add_preference(TEST_URI);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
check_preference_exists(TEST_URI, true);
|
||||
|
||||
// Reset state
|
||||
let cp = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
cp.removePref(TEST_URI, PREFERENCE_NAME);
|
||||
check_preference_exists(TEST_URI, false);
|
||||
}
|
||||
|
||||
// Cache
|
||||
function test_cache_cleared()
|
||||
{
|
||||
// Because this test is asynchronous, it should be the last test
|
||||
do_check_eq(tests[tests.length - 1], arguments.callee);
|
||||
|
||||
// NOTE: We could be more extensive with this test and actually add an entry
|
||||
// to the cache, and then make sure it is gone. However, we trust that
|
||||
// the API is well tested, and that when we get the observer
|
||||
// notification, we have actually cleared the cache.
|
||||
// This seems to happen asynchronously...
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
os.removeObserver(observer, "cacheservice:empty-cache");
|
||||
do_test_finished();
|
||||
}
|
||||
};
|
||||
os.addObserver(observer, "cacheservice:empty-cache", false);
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_storage_cleared()
|
||||
{
|
||||
function getStorageForURI(aURI)
|
||||
{
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Ci.nsIScriptSecurityManager).
|
||||
getNoAppCodebasePrincipal(aURI);
|
||||
let dsm = Cc["@mozilla.org/dom/storagemanager;1"].
|
||||
getService(Ci.nsIDOMStorageManager);
|
||||
return dsm.getLocalStorageForPrincipal(principal, "");
|
||||
}
|
||||
|
||||
let s = [
|
||||
getStorageForURI(uri("http://mozilla.org")),
|
||||
getStorageForURI(uri("http://my.mozilla.org")),
|
||||
getStorageForURI(uri("http://ilovemozilla.org")),
|
||||
];
|
||||
|
||||
for (let i = 0; i < s.length; ++i) {
|
||||
let storage = s[i];
|
||||
storage.setItem("test", "value" + i);
|
||||
do_check_eq(storage.length, 1);
|
||||
do_check_eq(storage.key(0), "test");
|
||||
do_check_eq(storage.getItem("test"), "value" + i);
|
||||
}
|
||||
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
|
||||
do_check_eq(s[0].getItem("test"), null);
|
||||
do_check_eq(s[0].length, 0);
|
||||
do_check_eq(s[1].getItem("test"), null);
|
||||
do_check_eq(s[1].length, 0);
|
||||
do_check_eq(s[2].getItem("test"), "value2");
|
||||
do_check_eq(s[2].length, 1);
|
||||
}
|
||||
|
||||
let tests = [
|
||||
// History
|
||||
test_history_cleared_with_direct_match,
|
||||
test_history_cleared_with_subdomain,
|
||||
test_history_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Cookie Service
|
||||
test_cookie_cleared_with_direct_match,
|
||||
test_cookie_cleared_with_subdomain,
|
||||
test_cookie_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Download Manager
|
||||
// Note: active downloads tested in test_removeDataFromDomain_activeDownloads.js
|
||||
test_download_history_cleared_with_direct_match,
|
||||
test_download_history_cleared_with_subdomain,
|
||||
test_download_history_not_cleared_with_active_direct_match,
|
||||
|
||||
// Login Manager
|
||||
test_login_manager_disabled_hosts_cleared_with_direct_match,
|
||||
test_login_manager_disabled_hosts_cleared_with_subdomain,
|
||||
test_login_manager_disabled_hosts_not_cleared_with_uri_contains_domain,
|
||||
test_login_manager_logins_cleared_with_direct_match,
|
||||
test_login_manager_logins_cleared_with_subdomain,
|
||||
tets_login_manager_logins_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Permission Manager
|
||||
test_permission_manager_cleared_with_direct_match,
|
||||
test_permission_manager_cleared_with_subdomain,
|
||||
test_permission_manager_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Content Preferences
|
||||
test_content_preferences_cleared_with_direct_match,
|
||||
test_content_preferences_cleared_with_subdomain,
|
||||
test_content_preferecnes_not_cleared_with_uri_contains_domain,
|
||||
|
||||
// Storage
|
||||
test_storage_cleared,
|
||||
|
||||
// Cache
|
||||
test_cache_cleared,
|
||||
];
|
||||
|
||||
function run_test()
|
||||
{
|
||||
for (let i = 0; i < tests.length; i++)
|
||||
tests[i]();
|
||||
|
||||
// Shutdown the download manager.
|
||||
Services.obs.notifyObservers(null, "quit-application", null);
|
||||
|
|
|
@ -10,11 +10,115 @@
|
|||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
function run_test() {
|
||||
PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
|
||||
load("do_test_removeDataFromDomain_activeDownloads.js");
|
||||
do_test();
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Utility Functions
|
||||
|
||||
/**
|
||||
* Creates an nsIURI object for the given file.
|
||||
*
|
||||
* @param aFile
|
||||
* The nsIFile of the URI to create.
|
||||
* @returns an nsIURI representing aFile.
|
||||
*/
|
||||
function uri(aFile)
|
||||
{
|
||||
return Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService).
|
||||
newFileURI(aFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure a URI string is in download history or not.
|
||||
*
|
||||
* @param aURIString
|
||||
* The string of the URI to check.
|
||||
* @param aIsActive
|
||||
* True if the URI should be actively downloaded, false otherwise.
|
||||
*/
|
||||
function check_active_download(aURIString, aIsActive)
|
||||
{
|
||||
let dm = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager);
|
||||
let enumerator = dm.activeDownloads;
|
||||
let found = false;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
|
||||
if (dl.source.spec == aURIString)
|
||||
found = true;
|
||||
}
|
||||
let checker = aIsActive ? do_check_true : do_check_false;
|
||||
checker(found);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Functions
|
||||
|
||||
let destFile = dirSvc.get("TmpD", Ci.nsIFile);
|
||||
destFile.append("dm-test-file");
|
||||
destFile = uri(destFile);
|
||||
let data = [
|
||||
{ source: "http://mozilla.org/direct_match",
|
||||
target: destFile.spec,
|
||||
removed: true
|
||||
},
|
||||
{ source: "http://www.mozilla.org/subdomain",
|
||||
target: destFile.spec,
|
||||
removed: true
|
||||
},
|
||||
{ source: "http://ilovemozilla.org/contains_domain",
|
||||
target: destFile.spec,
|
||||
removed: false
|
||||
},
|
||||
];
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// We add this data to the database first, but we cannot instantiate the
|
||||
// download manager service, otherwise these downloads will not be placed in
|
||||
// the active downloads array.
|
||||
|
||||
// Copy the empty downloads database to our profile directory
|
||||
let downloads = do_get_file("downloads.empty.sqlite");
|
||||
downloads.copyTo(dirSvc.get("ProfD", Ci.nsIFile), "downloads.sqlite");
|
||||
|
||||
// Open the database
|
||||
let ss = Cc["@mozilla.org/storage/service;1"].
|
||||
getService(Ci.mozIStorageService);
|
||||
let file = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
file.append("downloads.sqlite");
|
||||
let db = ss.openDatabase(file);
|
||||
|
||||
// Insert the data
|
||||
let stmt = db.createStatement(
|
||||
"INSERT INTO moz_downloads (source, target, state, autoResume, entityID) " +
|
||||
"VALUES (:source, :target, :state, :autoResume, :entityID)"
|
||||
);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
stmt.params.source = data[i].source;
|
||||
stmt.params.target = data[i].target;
|
||||
stmt.params.state = Ci.nsIDownloadManager.DOWNLOAD_PAUSED;
|
||||
stmt.params.autoResume = 0; // DONT_RESUME is 0
|
||||
stmt.params.entityID = "foo" // just has to be non-null for our test
|
||||
stmt.execute();
|
||||
stmt.reset();
|
||||
}
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
db.close();
|
||||
db = null;
|
||||
|
||||
// Check to make sure it's all there
|
||||
for (let i = 0; i < data.length; i++)
|
||||
check_active_download(data[i].source, true);
|
||||
|
||||
// Dispatch the remove call
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
|
||||
// And check our data
|
||||
for (let i = 0; i < data.length; i++)
|
||||
check_active_download(data[i].source, !data[i].removed);
|
||||
|
||||
// Shutdown the download manager.
|
||||
Services.obs.notifyObservers(null, "quit-application", null);
|
||||
|
|
|
@ -16,8 +16,6 @@ tail = tail_privatebrowsing.js
|
|||
[test_privatebrowsingwrapper_commandline.js]
|
||||
[test_privatebrowsingwrapper_exit.js]
|
||||
[test_privatebrowsingwrapper_placesTitleNoUpdate.js]
|
||||
[test_privatebrowsingwrapper_removeDataFromDomain.js]
|
||||
[test_privatebrowsingwrapper_removeDataFromDomain_activeDownloads.js]
|
||||
[test_privatebrowsingwrapper_telemetry.js]
|
||||
[test_removeDataFromDomain.js]
|
||||
[test_removeDataFromDomain_activeDownloads.js]
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function test() {
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].getService(Ci.nsIPrivateBrowsingService);
|
||||
Components.utils.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
function test() {
|
||||
// utility functions
|
||||
function countClosedTabsByTitle(aClosedTabList, aTitle)
|
||||
aClosedTabList.filter(function (aData) aData.title == aTitle).length;
|
||||
|
@ -79,7 +79,7 @@ function test() {
|
|||
ss.setBrowserState(JSON.stringify(testState));
|
||||
|
||||
// purge domain & check that we purged correctly for closed windows
|
||||
pb.removeDataFromDomain("mozilla.org");
|
||||
ClearRecentHistory.removeDataFromDomain("mozilla.org");
|
||||
|
||||
let closedWindowData = JSON.parse(ss.getClosedWindowData());
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 464199 **/
|
||||
|
||||
|
@ -56,9 +58,7 @@ function test() {
|
|||
is(countByTitle(closedTabs, REMEMBER), remember_count,
|
||||
"Everything is set up.");
|
||||
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
pb.removeDataFromDomain("example.net");
|
||||
ClearRecentHistory.removeDataFromDomain("example.net");
|
||||
|
||||
closedTabs = JSON.parse(ss.getClosedTabData(newWin));
|
||||
is(closedTabs.length, remember_count,
|
||||
|
|
|
@ -1480,7 +1480,7 @@ window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][s
|
|||
richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
|
||||
list-style-image: url("chrome://browser/skin/actionicon-tab@2x.png");
|
||||
-moz-image-region: rect(0, 32px, 22px, 0);
|
||||
width: 16px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
|
||||
|
|
|
@ -4206,7 +4206,7 @@ ENABLE_SYSTEM_EXTENSION_DIRS=1
|
|||
MOZ_BRANDING_DIRECTORY=
|
||||
MOZ_OFFICIAL_BRANDING=
|
||||
MOZ_FEEDS=1
|
||||
MOZ_FLEXBOX=
|
||||
MOZ_FLEXBOX=1
|
||||
MOZ_WEBAPP_RUNTIME=
|
||||
MOZ_JSDEBUGGER=1
|
||||
MOZ_AUTH_EXTENSION=1
|
||||
|
|
|
@ -65,6 +65,7 @@ SDK_XPIDLSRCS = \
|
|||
XPIDLSRCS = \
|
||||
nsIContentPolicy.idl \
|
||||
nsIDocumentEncoder.idl \
|
||||
nsIDOMDataChannel.idl \
|
||||
nsIDOMFile.idl \
|
||||
nsIDOMFileReader.idl \
|
||||
nsIDOMFileList.idl \
|
||||
|
|
|
@ -1765,6 +1765,10 @@ public:
|
|||
static nsresult CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
|
||||
JSObject** aResult);
|
||||
|
||||
static nsresult CreateBlobBuffer(JSContext* aCx,
|
||||
const nsACString& aData,
|
||||
jsval& aBlob);
|
||||
|
||||
static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#include "domstubs.idl"
|
||||
|
||||
#include "nsIDOMEventTarget.idl"
|
||||
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, builtinclass, uuid(fb7a8ec4-c1eb-4d9f-b927-fbb8b4493e6d)]
|
||||
interface nsIDOMDataChannel : nsIDOMEventTarget
|
||||
{
|
||||
readonly attribute DOMString label;
|
||||
readonly attribute boolean reliable;
|
||||
readonly attribute boolean ordered;
|
||||
|
||||
readonly attribute DOMString readyState;
|
||||
readonly attribute unsigned long bufferedAmount;
|
||||
|
||||
[implicit_jscontext] attribute jsval onopen;
|
||||
[implicit_jscontext] attribute jsval onerror;
|
||||
[implicit_jscontext] attribute jsval onclose;
|
||||
[implicit_jscontext] attribute jsval onmessage;
|
||||
|
||||
attribute DOMString binaryType;
|
||||
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Transmits data to other end of the connection.
|
||||
* @param data The data to be transmitted. Arraybuffers and Blobs are sent as
|
||||
* binary data. Strings are sent as UTF-8 text data. Other types are
|
||||
* converted to a String and sent as a String.
|
||||
* @return if the connection is still established and the data was queued or
|
||||
* sent successfully.
|
||||
*/
|
||||
[implicit_jscontext] void send(in nsIVariant data);
|
||||
};
|
|
@ -137,6 +137,14 @@ CPPSRCS = \
|
|||
nsMixedContentBlocker.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_WEBRTC
|
||||
EXPORTS += nsDOMDataChannel.h
|
||||
CPPSRCS += nsDOMDataChannel.cpp
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/netwerk/sctp/datachannel \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
# Are we targeting x86-32 or x86-64? If so, we want to include SSE2 code for
|
||||
# nsTextFragment.cpp
|
||||
ifneq (,$(INTEL_ARCHITECTURE))
|
||||
|
|
|
@ -900,7 +900,7 @@ WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData,
|
|||
JSAutoRequest ar(cx);
|
||||
if (isBinary) {
|
||||
if (mBinaryType == BinaryTypeValues::Blob) {
|
||||
rv = CreateResponseBlob(aData, cx, jsData);
|
||||
rv = nsContentUtils::CreateBlobBuffer(cx, aData, jsData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (mBinaryType == BinaryTypeValues::Arraybuffer) {
|
||||
JSObject* arrayBuf;
|
||||
|
@ -943,26 +943,6 @@ WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData,
|
|||
return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Initial implementation: only stores to RAM, not file
|
||||
// TODO: bug 704447: large file support
|
||||
nsresult
|
||||
WebSocket::CreateResponseBlob(const nsACString& aData,
|
||||
JSContext *aCx,
|
||||
jsval &jsData)
|
||||
{
|
||||
uint32_t blobLen = aData.Length();
|
||||
void* blobData = PR_Malloc(blobLen);
|
||||
nsCOMPtr<nsIDOMBlob> blob;
|
||||
if (blobData) {
|
||||
memcpy(blobData, aData.BeginReading(), blobLen);
|
||||
blob = new nsDOMMemoryFile(blobData, blobLen, EmptyString());
|
||||
} else {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
JSObject* scope = JS_GetGlobalForScopeChain(aCx);
|
||||
return nsContentUtils::WrapNative(aCx, scope, blob, &jsData, nullptr, true);
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebSocket::CreateAndDispatchCloseEvent(bool aWasClean,
|
||||
uint16_t aCode,
|
||||
|
|
|
@ -228,9 +228,6 @@ protected:
|
|||
nsresult CreateAndDispatchCloseEvent(bool aWasClean,
|
||||
uint16_t aCode,
|
||||
const nsString& aReason);
|
||||
nsresult CreateResponseBlob(const nsACString& aData,
|
||||
JSContext* aCx,
|
||||
jsval& jsData);
|
||||
|
||||
// if there are "strong event listeners" (see comment in WebSocket.cpp) or
|
||||
// outgoing not sent messages then this method keeps the object alive
|
||||
|
|
|
@ -2695,11 +2695,7 @@ nsContentUtils::GetImgLoaderForDocument(nsIDocument* aDoc)
|
|||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIChannel> channel = aDoc->GetChannel();
|
||||
if (channel) {
|
||||
nsCOMPtr<nsILoadContext> context;
|
||||
NS_QueryNotificationCallbacks(channel, context);
|
||||
isPrivate = context && context->UsePrivateBrowsing();
|
||||
}
|
||||
isPrivate = channel && NS_UsePrivateBrowsing(channel);
|
||||
}
|
||||
return isPrivate ? sPrivateImgLoader : sImgLoader;
|
||||
}
|
||||
|
@ -6207,6 +6203,26 @@ nsContentUtils::CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Initial implementation: only stores to RAM, not file
|
||||
// TODO: bug 704447: large file support
|
||||
nsresult
|
||||
nsContentUtils::CreateBlobBuffer(JSContext* aCx,
|
||||
const nsACString& aData,
|
||||
jsval& aBlob)
|
||||
{
|
||||
uint32_t blobLen = aData.Length();
|
||||
void* blobData = PR_Malloc(blobLen);
|
||||
nsCOMPtr<nsIDOMBlob> blob;
|
||||
if (blobData) {
|
||||
memcpy(blobData, aData.BeginReading(), blobLen);
|
||||
blob = new nsDOMMemoryFile(blobData, blobLen, EmptyString());
|
||||
} else {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
JSObject* scope = JS_GetGlobalForScopeChain(aCx);
|
||||
return nsContentUtils::WrapNative(aCx, scope, blob, &aBlob, nullptr, true);
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::StripNullChars(const nsAString& aInStr, nsAString& aOutStr)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,512 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
#define FORCE_PR_LOG
|
||||
#endif
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
extern PRLogModuleInfo* dataChannelLog;
|
||||
#endif
|
||||
#undef LOG
|
||||
#define LOG(args) PR_LOG(dataChannelLog, PR_LOG_DEBUG, args)
|
||||
|
||||
|
||||
#include "nsDOMDataChannel.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsIDOMDataChannel.h"
|
||||
#include "nsIDOMMessageEvent.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
|
||||
#include "jsval.h"
|
||||
|
||||
#include "nsError.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsDOMFile.h"
|
||||
|
||||
#include "DataChannel.h"
|
||||
|
||||
#ifdef GetBinaryType
|
||||
// Windows apparently has a #define for GetBinaryType...
|
||||
#undef GetBinaryType
|
||||
#endif
|
||||
|
||||
class nsDOMDataChannel : public nsDOMEventTargetHelper,
|
||||
public nsIDOMDataChannel,
|
||||
public mozilla::DataChannelListener
|
||||
{
|
||||
public:
|
||||
nsDOMDataChannel(mozilla::DataChannel* aDataChannel)
|
||||
: mDataChannel(aDataChannel)
|
||||
, mBinaryType(DC_BINARY_TYPE_BLOB)
|
||||
{}
|
||||
|
||||
nsresult Init(nsPIDOMWindow* aDOMWindow);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMDATACHANNEL
|
||||
|
||||
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDataChannel,
|
||||
nsDOMEventTargetHelper)
|
||||
|
||||
nsresult
|
||||
DoOnMessageAvailable(const nsACString& aMessage, bool aBinary);
|
||||
|
||||
virtual nsresult
|
||||
OnMessageAvailable(nsISupports* aContext, const nsACString& aMessage);
|
||||
|
||||
virtual nsresult
|
||||
OnBinaryMessageAvailable(nsISupports* aContext, const nsACString& aMessage);
|
||||
|
||||
virtual nsresult OnSimpleEvent(nsISupports* aContext, const nsAString& aName);
|
||||
|
||||
virtual nsresult
|
||||
OnChannelConnected(nsISupports* aContext);
|
||||
|
||||
virtual nsresult
|
||||
OnChannelClosed(nsISupports* aContext);
|
||||
|
||||
virtual void
|
||||
AppReady();
|
||||
|
||||
private:
|
||||
// Get msg info out of JS variable being sent (string, arraybuffer, blob)
|
||||
nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
|
||||
nsCOMPtr<nsIInputStream> &aStreamOut,
|
||||
bool &aIsBinary, uint32_t &aOutgoingLength,
|
||||
JSContext *aCx);
|
||||
|
||||
// Owning reference
|
||||
nsAutoPtr<mozilla::DataChannel> mDataChannel;
|
||||
nsString mOrigin;
|
||||
enum
|
||||
{
|
||||
DC_BINARY_TYPE_ARRAYBUFFER,
|
||||
DC_BINARY_TYPE_BLOB,
|
||||
} mBinaryType;
|
||||
};
|
||||
|
||||
DOMCI_DATA(DataChannel, nsDOMDataChannel)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataChannel)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataChannel,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDataChannel,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDataChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDataChannel)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DataChannel)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
|
||||
nsresult
|
||||
nsDOMDataChannel::Init(nsPIDOMWindow* aDOMWindow)
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoString urlParam;
|
||||
|
||||
nsDOMEventTargetHelper::Init();
|
||||
|
||||
MOZ_ASSERT(mDataChannel);
|
||||
mDataChannel->SetListener(this, nullptr);
|
||||
|
||||
// Now grovel through the objects to get a usable origin for onMessage
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aDOMWindow);
|
||||
NS_ENSURE_STATE(sgo);
|
||||
nsCOMPtr<nsIScriptContext> scriptContext = sgo->GetContext();
|
||||
NS_ENSURE_STATE(scriptContext);
|
||||
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal(do_QueryInterface(aDOMWindow));
|
||||
NS_ENSURE_STATE(scriptPrincipal);
|
||||
nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal();
|
||||
NS_ENSURE_STATE(principal);
|
||||
|
||||
if (aDOMWindow) {
|
||||
BindToOwner(aDOMWindow->IsOuterWindow() ?
|
||||
aDOMWindow->GetCurrentInnerWindow() : aDOMWindow);
|
||||
} else {
|
||||
BindToOwner(aDOMWindow);
|
||||
}
|
||||
|
||||
// Attempt to kill "ghost" DataChannel (if one can happen): but usually too early for check to fail
|
||||
rv = CheckInnerWindowCorrectness();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// See bug 696085
|
||||
// We don't need to observe for window destroyed or frozen; but PeerConnection needs
|
||||
// to not allow itself to be bfcached (and get destroyed on navigation).
|
||||
|
||||
rv = nsContentUtils::GetUTFOrigin(principal,mOrigin);
|
||||
LOG(("%s: origin = %s\n",__FUNCTION__,NS_LossyConvertUTF16toASCII(mOrigin).get()));
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, open)
|
||||
NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, error)
|
||||
NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, close)
|
||||
NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, message)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::GetLabel(nsAString& aLabel)
|
||||
{
|
||||
mDataChannel->GetLabel(aLabel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX should be GetType()? Open question for the spec
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::GetReliable(bool* aReliable)
|
||||
{
|
||||
*aReliable = (mDataChannel->GetType() == mozilla::DataChannelConnection::RELIABLE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::GetOrdered(bool* aOrdered)
|
||||
{
|
||||
*aOrdered = mDataChannel->GetOrdered();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::GetReadyState(nsAString& aReadyState)
|
||||
{
|
||||
uint16_t readyState = mDataChannel->GetReadyState();
|
||||
const char * stateName[] = {
|
||||
"Connecting",
|
||||
"Open",
|
||||
"Closing",
|
||||
"Closed"
|
||||
};
|
||||
MOZ_ASSERT(/*readyState >= mozilla::DataChannel::CONNECTING && */ // Always true due to datatypes
|
||||
readyState <= mozilla::DataChannel::CLOSED);
|
||||
aReadyState.AssignASCII(stateName[readyState]);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::GetBufferedAmount(uint32_t* aBufferedAmount)
|
||||
{
|
||||
*aBufferedAmount = mDataChannel->GetBufferedAmount();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDOMDataChannel::GetBinaryType(nsAString & aBinaryType)
|
||||
{
|
||||
switch (mBinaryType) {
|
||||
case DC_BINARY_TYPE_ARRAYBUFFER:
|
||||
aBinaryType.AssignLiteral("arraybuffer");
|
||||
break;
|
||||
case DC_BINARY_TYPE_BLOB:
|
||||
aBinaryType.AssignLiteral("blob");
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Should not happen");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::SetBinaryType(const nsAString& aBinaryType)
|
||||
{
|
||||
if (aBinaryType.EqualsLiteral("arraybuffer")) {
|
||||
mBinaryType = DC_BINARY_TYPE_ARRAYBUFFER;
|
||||
} else if (aBinaryType.EqualsLiteral("blob")) {
|
||||
mBinaryType = DC_BINARY_TYPE_BLOB;
|
||||
} else {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::Close()
|
||||
{
|
||||
mDataChannel->Close();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Almost a clone of nsWebSocketChannel::Send()
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataChannel::Send(nsIVariant* aData, JSContext* aCx)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
uint16_t state = mDataChannel->GetReadyState();
|
||||
|
||||
// In reality, the DataChannel protocol allows this, but we want it to
|
||||
// look like WebSockets
|
||||
if (state == mozilla::DataChannel::CONNECTING) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
nsCString msgString;
|
||||
nsCOMPtr<nsIInputStream> msgStream;
|
||||
bool isBinary;
|
||||
uint32_t msgLen;
|
||||
nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen, aCx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (state == mozilla::DataChannel::CLOSING ||
|
||||
state == mozilla::DataChannel::CLOSED) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state == mozilla::DataChannel::OPEN,
|
||||
"Unknown state in nsWebSocket::Send");
|
||||
|
||||
int32_t sent;
|
||||
if (msgStream) {
|
||||
sent = mDataChannel->SendBinaryStream(msgStream, msgLen);
|
||||
} else {
|
||||
if (isBinary) {
|
||||
sent = mDataChannel->SendBinaryMsg(msgString);
|
||||
} else {
|
||||
sent = mDataChannel->SendMsg(msgString);
|
||||
}
|
||||
}
|
||||
return sent >= 0 ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// XXX Exact clone of nsWebSocketChannel::GetSendParams() - find a way to share!
|
||||
nsresult
|
||||
nsDOMDataChannel::GetSendParams(nsIVariant* aData, nsCString& aStringOut,
|
||||
nsCOMPtr<nsIInputStream>& aStreamOut,
|
||||
bool& aIsBinary, uint32_t& aOutgoingLength,
|
||||
JSContext* aCx)
|
||||
{
|
||||
// Get type of data (arraybuffer, blob, or string)
|
||||
uint16_t dataType;
|
||||
nsresult rv = aData->GetDataType(&dataType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (dataType == nsIDataType::VTYPE_INTERFACE ||
|
||||
dataType == nsIDataType::VTYPE_INTERFACE_IS) {
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsID* iid;
|
||||
rv = aData->GetAsInterface(&iid, getter_AddRefs(supports));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsMemory::Free(iid);
|
||||
|
||||
// ArrayBuffer?
|
||||
jsval realVal;
|
||||
JSObject* obj;
|
||||
nsresult rv = aData->GetAsJSVal(&realVal);
|
||||
if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
|
||||
(obj = JSVAL_TO_OBJECT(realVal)) &&
|
||||
(JS_IsArrayBufferObject(obj, aCx))) {
|
||||
int32_t len = JS_GetArrayBufferByteLength(obj, aCx);
|
||||
char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx));
|
||||
|
||||
aStringOut.Assign(data, len);
|
||||
aIsBinary = true;
|
||||
aOutgoingLength = len;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Blob?
|
||||
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
|
||||
if (blob) {
|
||||
rv = blob->GetInternalStream(getter_AddRefs(aStreamOut));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// GetSize() should not perform blocking I/O (unlike Available())
|
||||
uint64_t blobLen;
|
||||
rv = blob->GetSize(&blobLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (blobLen > PR_UINT32_MAX) {
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
aOutgoingLength = static_cast<uint32_t>(blobLen);
|
||||
|
||||
aIsBinary = true;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Text message: if not already a string, turn it into one.
|
||||
// TODO: bug 704444: Correctly coerce any JS type to string
|
||||
//
|
||||
PRUnichar* data = nullptr;
|
||||
uint32_t len = 0;
|
||||
rv = aData->GetAsWStringWithSize(&len, &data);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsString text;
|
||||
text.Adopt(data, len);
|
||||
|
||||
CopyUTF16toUTF8(text, aStringOut);
|
||||
|
||||
aIsBinary = false;
|
||||
aOutgoingLength = aStringOut.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataChannel::DoOnMessageAvailable(const nsACString& aData,
|
||||
bool aBinary)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
LOG(("DoOnMessageAvailable%s\n",aBinary ? ((mBinaryType == DC_BINARY_TYPE_BLOB) ? " (blob)" : " (binary)") : ""));
|
||||
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner());
|
||||
NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE);
|
||||
|
||||
nsIScriptContext* sc = sgo->GetContext();
|
||||
NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
|
||||
|
||||
JSContext* cx = sc->GetNativeContext();
|
||||
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
jsval jsData;
|
||||
|
||||
if (aBinary) {
|
||||
if (mBinaryType == DC_BINARY_TYPE_BLOB) {
|
||||
rv = nsContentUtils::CreateBlobBuffer(cx, aData, jsData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (mBinaryType == DC_BINARY_TYPE_ARRAYBUFFER) {
|
||||
JSObject* arrayBuf;
|
||||
rv = nsContentUtils::CreateArrayBuffer(cx, aData, &arrayBuf);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
jsData = OBJECT_TO_JSVAL(arrayBuf);
|
||||
} else {
|
||||
NS_RUNTIMEABORT("Unknown binary type!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
} else {
|
||||
NS_ConvertUTF8toUTF16 utf16data(aData);
|
||||
JSString* jsString = JS_NewUCStringCopyN(cx, utf16data.get(), utf16data.Length());
|
||||
NS_ENSURE_TRUE(jsString, NS_ERROR_FAILURE);
|
||||
|
||||
jsData = STRING_TO_JSVAL(jsString);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
rv = NS_NewDOMMessageEvent(getter_AddRefs(event), nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsIDOMMessageEvent> messageEvent = do_QueryInterface(event);
|
||||
rv = messageEvent->InitMessageEvent(NS_LITERAL_STRING("message"),
|
||||
false, false,
|
||||
jsData, mOrigin, EmptyString(),
|
||||
nullptr);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
event->SetTrusted(true);
|
||||
|
||||
LOG(("%p(%p): %s - Dispatching\n",this,(void*)mDataChannel,__FUNCTION__));
|
||||
rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the message event!!!");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataChannel::OnMessageAvailable(nsISupports* aContext,
|
||||
const nsACString& aMessage)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return DoOnMessageAvailable(aMessage, false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataChannel::OnBinaryMessageAvailable(nsISupports* aContext,
|
||||
const nsACString& aMessage)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return DoOnMessageAvailable(aMessage, true);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataChannel::OnSimpleEvent(nsISupports* aContext, const nsAString& aName)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = event->InitEvent(aName, false, false);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
event->SetTrusted(true);
|
||||
|
||||
return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataChannel::OnChannelConnected(nsISupports* aContext)
|
||||
{
|
||||
LOG(("%p(%p): %s - Dispatching\n",this,(void*)mDataChannel,__FUNCTION__));
|
||||
|
||||
return OnSimpleEvent(aContext, NS_LITERAL_STRING("open"));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataChannel::OnChannelClosed(nsISupports* aContext)
|
||||
{
|
||||
LOG(("%p(%p): %s - Dispatching\n",this,(void*)mDataChannel,__FUNCTION__));
|
||||
|
||||
return OnSimpleEvent(aContext, NS_LITERAL_STRING("close"));
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataChannel::AppReady()
|
||||
{
|
||||
mDataChannel->AppReady();
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
NS_NewDOMDataChannel(mozilla::DataChannel* aDataChannel,
|
||||
nsPIDOMWindow* aWindow,
|
||||
nsIDOMDataChannel** aDomDataChannel)
|
||||
{
|
||||
nsRefPtr<nsDOMDataChannel> domdc = new nsDOMDataChannel(aDataChannel);
|
||||
|
||||
nsresult rv = domdc->Init(aWindow);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return CallQueryInterface(domdc, aDomDataChannel);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
NS_DataChannelAppReady(nsIDOMDataChannel* aDomDataChannel)
|
||||
{
|
||||
((nsDOMDataChannel *)aDomDataChannel)->AppReady();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsDOMDataChannel_h__
|
||||
#define nsDOMDataChannel_h__
|
||||
|
||||
// This defines only what's necessary to create nsDOMDataChannels, since this
|
||||
// gets used with MOZ_INTERNAL_API not set for media/webrtc/signaling/testing
|
||||
|
||||
#include "nsIDOMDataChannel.h"
|
||||
|
||||
namespace mozilla {
|
||||
class DataChannel;
|
||||
}
|
||||
|
||||
class nsPIDOMWindow;
|
||||
|
||||
nsresult
|
||||
NS_NewDOMDataChannel(mozilla::DataChannel* dataChannel,
|
||||
nsPIDOMWindow* aWindow,
|
||||
nsIDOMDataChannel** domDataChannel);
|
||||
|
||||
// Tell DataChannel it's ok to deliver open and message events
|
||||
void NS_DataChannelAppReady(nsIDOMDataChannel* domDataChannel);
|
||||
|
||||
#endif
|
|
@ -16,14 +16,4 @@ DOMCI_DATA(WebGLProgram, void)
|
|||
DOMCI_DATA(WebGLShader, void)
|
||||
DOMCI_DATA(WebGLFramebuffer, void)
|
||||
DOMCI_DATA(WebGLRenderbuffer, void)
|
||||
DOMCI_DATA(WebGLUniformLocation, void)
|
||||
DOMCI_DATA(WebGLShaderPrecisionFormat, void)
|
||||
DOMCI_DATA(WebGLActiveInfo, void)
|
||||
DOMCI_DATA(WebGLExtension, void)
|
||||
DOMCI_DATA(WebGLExtensionStandardDerivatives, void)
|
||||
DOMCI_DATA(WebGLExtensionTextureFilterAnisotropic, void)
|
||||
DOMCI_DATA(WebGLExtensionLoseContext, void)
|
||||
DOMCI_DATA(WebGLExtensionCompressedTextureS3TC, void)
|
||||
DOMCI_DATA(WebGLExtensionCompressedTextureATC, void)
|
||||
DOMCI_DATA(WebGLExtensionCompressedTexturePVRTC, void)
|
||||
DOMCI_DATA(WebGLExtensionDepthTexture, void)
|
||||
DOMCI_DATA(WebGLActiveInfo, void)
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
function boom()
|
||||
{
|
||||
var a = document.getElementById("a");
|
||||
a.play();
|
||||
a.onplaying = function () { document.documentElement.className = ""; }
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<video id="a" src="cors.webm" crossorigin onloadedmetadata="boom();">
|
||||
</body>
|
||||
</html>
|
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
Access-Control-Allow-Origin: *
|
|
@ -10,3 +10,4 @@ load 492286-1.xhtml
|
|||
load 576612-1.html
|
||||
skip-if(Android) load 691096-1.html # Android sound API can't handle playing large number of sounds at once.
|
||||
load 752784-1.html
|
||||
HTTP load 795892-1.html
|
||||
|
|
|
@ -550,6 +550,10 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
|
|||
#include "mozilla/Likely.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
#include "nsIDOMDataChannel.h"
|
||||
#endif
|
||||
|
||||
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
|
||||
#include "WebGLContext.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
|
@ -1707,6 +1711,11 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
|
||||
NS_DEFINE_CLASSINFO_DATA(MozTimeManager, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
NS_DEFINE_CLASSINFO_DATA(DataChannel, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Objects that should be constructable through |new Name();|
|
||||
|
@ -4510,6 +4519,13 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozTimeManager)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
DOM_CLASSINFO_MAP_BEGIN(DataChannel, nsIDOMDataChannel)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataChannel)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
uint32_t i = ArrayLength(sClassInfoData);
|
||||
|
|
|
@ -537,3 +537,7 @@ DOMCI_CLASS(LockedFile)
|
|||
DOMCI_CLASS(MozActivity)
|
||||
|
||||
DOMCI_CLASS(MozTimeManager)
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
DOMCI_CLASS(DataChannel)
|
||||
#endif
|
||||
|
|
|
@ -6548,9 +6548,10 @@ nsGlobalWindow::Close()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't allow scripts from content to close windows
|
||||
// that were not opened by script
|
||||
if (!mHadOriginalOpener && !nsContentUtils::IsCallerTrustedForWrite()) {
|
||||
// Don't allow scripts from content to close non-app windows that were not
|
||||
// opened by script.
|
||||
if (!mDocShell->GetIsApp() &&
|
||||
!mHadOriginalOpener && !nsContentUtils::IsCallerTrustedForWrite()) {
|
||||
bool allowClose =
|
||||
Preferences::GetBool("dom.allow_scripts_to_close_windows", true);
|
||||
if (!allowClose) {
|
||||
|
|
|
@ -61,17 +61,6 @@ BluetoothDevice::BluetoothDevice(nsPIDOMWindow* aOwner,
|
|||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
for (uint32_t i = 0; i < values.Length(); ++i) {
|
||||
SetPropertyByValue(values[i]);
|
||||
if (values[i].name().EqualsLiteral("Path")) {
|
||||
// Since this is our signal handler string, set it as we set the property
|
||||
// in the object. Odd place to do it, but makes more sense than in
|
||||
// SetPropertyByValue.
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
NS_WARNING("BluetoothService not available!");
|
||||
} else {
|
||||
bs->RegisterBluetoothSignalHandler(mPath, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "BluetoothScoManager.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothServiceUuid.h"
|
||||
#include "BluetoothUtils.h"
|
||||
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
@ -20,9 +21,6 @@
|
|||
#include "nsIAudioManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIRadioInterfaceLayer.h"
|
||||
#include "nsISystemMessagesInternal.h"
|
||||
#include "BluetoothUtils.h"
|
||||
|
||||
#include "nsVariant.h"
|
||||
|
||||
#include <unistd.h> /* usleep() */
|
||||
|
@ -212,39 +210,6 @@ BluetoothHfpManager::Get()
|
|||
return gBluetoothHfpManager;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::BroadcastSystemMessage(const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData)
|
||||
{
|
||||
JSContext* cx = nsContentUtils::GetSafeJSContext();
|
||||
NS_ASSERTION(!::JS_IsExceptionPending(cx),
|
||||
"Shouldn't get here when an exception is pending!");
|
||||
|
||||
JSAutoRequest jsar(cx);
|
||||
JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
if (!obj) {
|
||||
NS_WARNING("Failed to new JSObject for system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetJsObject(cx, obj, aData)) {
|
||||
NS_WARNING("Failed to set properties of system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
|
||||
do_GetService("@mozilla.org/system-message-internal;1");
|
||||
|
||||
if (!systemMessenger) {
|
||||
NS_WARNING("Failed to get SystemMessenger service!");
|
||||
return false;
|
||||
}
|
||||
|
||||
systemMessenger->BroadcastMessage(aType, OBJECT_TO_JSVAL(obj));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::NotifySettings(const bool aConnected)
|
||||
{
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothReplyRunnable;
|
||||
class BluetoothNamedValue;
|
||||
|
||||
class BluetoothHfpManager : public mozilla::ipc::UnixSocketConsumer
|
||||
, public nsIObserver
|
||||
|
@ -41,8 +40,6 @@ private:
|
|||
void Cleanup();
|
||||
nsresult HandleVolumeChanged(const nsAString& aData);
|
||||
nsresult HandleShutdown();
|
||||
bool BroadcastSystemMessage(const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData);
|
||||
void NotifyDialer(const nsAString& aCommand);
|
||||
void NotifySettings(const bool aConnected);
|
||||
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothServiceUuid.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "ObexBase.h"
|
||||
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
|
@ -20,7 +22,8 @@ using namespace mozilla::ipc;
|
|||
|
||||
static mozilla::RefPtr<BluetoothOppManager> sInstance;
|
||||
static nsCOMPtr<nsIInputStream> stream = nullptr;
|
||||
static uint64_t sSentFileSize = 0;
|
||||
static uint32_t sSentFileSize = 0;
|
||||
static nsString sFileName;
|
||||
|
||||
class ReadFileTask : public nsRunnable
|
||||
{
|
||||
|
@ -207,13 +210,12 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||
*/
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(mBlob);
|
||||
nsString fileName;
|
||||
if (file) {
|
||||
rv = file->GetName(fileName);
|
||||
rv = file->GetName(sFileName);
|
||||
}
|
||||
|
||||
if (!file || fileName.IsEmpty()) {
|
||||
fileName.AssignLiteral("Unknown");
|
||||
if (!file || sFileName.IsEmpty()) {
|
||||
sFileName.AssignLiteral("Unknown");
|
||||
}
|
||||
|
||||
uint64_t fileSize;
|
||||
|
@ -231,7 +233,7 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||
|
||||
sSentFileSize = 0;
|
||||
mAbortFlag = false;
|
||||
sInstance->SendPutHeaderRequest(fileName, fileSize);
|
||||
sInstance->SendPutHeaderRequest(sFileName, fileSize);
|
||||
}
|
||||
}
|
||||
} else if (mLastCommand == ObexRequestCode::Disconnect) {
|
||||
|
@ -263,6 +265,7 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||
// FIXME: Needs error handling here
|
||||
NS_WARNING("[OPP] PutFinal failed");
|
||||
} else {
|
||||
FileTransferComplete(true, false, sFileName, sSentFileSize);
|
||||
SendDisconnectRequest();
|
||||
}
|
||||
} else if (mLastCommand == ObexRequestCode::Abort) {
|
||||
|
@ -270,6 +273,7 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
|
|||
NS_WARNING("[OPP] Abort failed");
|
||||
}
|
||||
|
||||
FileTransferComplete(false, false, sFileName, sSentFileSize);
|
||||
SendDisconnectRequest();
|
||||
}
|
||||
}
|
||||
|
@ -397,3 +401,36 @@ BluetoothOppManager::SendAbortRequest()
|
|||
memcpy(s->mData, req, s->mSize);
|
||||
SendSocketData(s);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::FileTransferComplete(bool aSuccess,
|
||||
bool aReceived,
|
||||
const nsString& aFileName,
|
||||
uint32_t aFileLength)
|
||||
{
|
||||
nsString type, name;
|
||||
BluetoothValue v;
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
type.AssignLiteral("bluetooth-opp-transfer-complete");
|
||||
|
||||
name.AssignLiteral("success");
|
||||
v = aSuccess;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("received");
|
||||
v = aReceived;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("filename");
|
||||
v = aFileName;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("filelength");
|
||||
v = aFileLength;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
if (!BroadcastSystemMessage(type, parameters)) {
|
||||
NS_WARNING("Failed to broadcast [bluetooth-opp-transfer-complete]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,9 @@ public:
|
|||
|
||||
private:
|
||||
BluetoothOppManager();
|
||||
void UpdateProgress(uint32_t aTotalBytes, uint32_t aSentBytes);
|
||||
void FileTransferComplete(bool aSuccess, bool aReceived,
|
||||
const nsString& aFileName, uint32_t aFileLength);
|
||||
|
||||
bool mConnected;
|
||||
int mConnectionId;
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include "BluetoothUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "BluetoothDevice.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsISystemMessagesInternal.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
nsresult
|
||||
mozilla::dom::bluetooth::StringArrayToJSArray(JSContext* aCx, JSObject* aGlobal,
|
||||
|
@ -166,3 +169,37 @@ mozilla::dom::bluetooth::GetAddressFromObjectPath(const nsAString& aObjectPath)
|
|||
return address;
|
||||
}
|
||||
|
||||
bool
|
||||
mozilla::dom::bluetooth::BroadcastSystemMessage(
|
||||
const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData)
|
||||
{
|
||||
JSContext* cx = nsContentUtils::GetSafeJSContext();
|
||||
NS_ASSERTION(!::JS_IsExceptionPending(cx),
|
||||
"Shouldn't get here when an exception is pending!");
|
||||
|
||||
JSAutoRequest jsar(cx);
|
||||
JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
if (!obj) {
|
||||
NS_WARNING("Failed to new JSObject for system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetJsObject(cx, obj, aData)) {
|
||||
NS_WARNING("Failed to set properties of system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
|
||||
do_GetService("@mozilla.org/system-message-internal;1");
|
||||
|
||||
if (!systemMessenger) {
|
||||
NS_WARNING("Failed to get SystemMessenger service!");
|
||||
return false;
|
||||
}
|
||||
|
||||
systemMessenger->BroadcastMessage(aType, OBJECT_TO_JSVAL(obj));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,10 @@ GetObjectPathFromAddress(const nsAString& aAdapterPath,
|
|||
nsString
|
||||
GetAddressFromObjectPath(const nsAString& aObjectPath);
|
||||
|
||||
bool
|
||||
BroadcastSystemMessage(const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData);
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1260,16 +1260,6 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
|||
signalName = NS_LITERAL_STRING("PairedStatusChanged");
|
||||
signalPath = NS_LITERAL_STRING(LOCAL_AGENT_PATH);
|
||||
v.get_ArrayOfBluetoothNamedValue()[0].name() = NS_LITERAL_STRING("paired");
|
||||
} else {
|
||||
/*
|
||||
* This is a workaround for Bug 795458. We avoid sending events whose
|
||||
* signalPath is "device object path" (formatted as "/org/bluez/
|
||||
* [pid]/hci0/dev_xx_xx_xx_xx_xx_xx". It's because those corresponding
|
||||
* BluetoothDevice objects may have been garbage-collected. Since we
|
||||
* don't need to know any propert changed except 'paired', this should
|
||||
* work for now.
|
||||
*/
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
} else if (dbus_message_is_signal(aMsg, DBUS_MANAGER_IFACE, "AdapterAdded")) {
|
||||
const char* str;
|
||||
|
@ -1642,7 +1632,8 @@ public:
|
|||
}
|
||||
NS_ASSERTION(i != properties.Length(), "failed to get device name");
|
||||
} else {
|
||||
// Return all device properties for event "DeviceCreated"
|
||||
// Return all device properties for event "DeviceCreated", including device path
|
||||
properties.AppendElement(BluetoothNamedValue(NS_LITERAL_STRING("Path"), mSignal.value()));
|
||||
mSignal.value() = properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,9 @@ MOCHITEST_FILES = \
|
|||
browserElement_CloseFromOpener.js \
|
||||
test_browserElement_inproc_CloseFromOpener.html \
|
||||
file_browserElement_CloseFromOpener.html \
|
||||
browserElement_CloseApp.js \
|
||||
test_browserElement_inproc_CloseApp.html \
|
||||
file_browserElement_CloseApp.html \
|
||||
browserElement_OpenWindow.js \
|
||||
test_browserElement_inproc_OpenWindow.html \
|
||||
file_browserElement_Open1.html \
|
||||
|
@ -181,6 +184,7 @@ MOCHITEST_FILES += \
|
|||
test_browserElement_oop_PromptConfirm.html \
|
||||
test_browserElement_oop_Close.html \
|
||||
test_browserElement_oop_CloseFromOpener.html \
|
||||
test_browserElement_oop_CloseApp.html \
|
||||
test_browserElement_oop_OpenWindow.html \
|
||||
test_browserElement_oop_OpenWindowInFrame.html \
|
||||
test_browserElement_oop_OpenWindowRejected.html \
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 789392 - Test that apps frames can trigger mozbrowserclose by calling
|
||||
// window.close(), but browser frames cannot.
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
SpecialPowers.addPermission("embed-apps", true, window.document);
|
||||
|
||||
addEventListener('unload', function() {
|
||||
SpecialPowers.removePermission("embed-apps", window.document);
|
||||
});
|
||||
|
||||
// Our app frame and browser frame load the same content. That content calls
|
||||
// window.close() and then alert(). We should get a mozbrowserclose event on
|
||||
// the app frame before the mozbrowsershowmodalprompt, but not on the browser
|
||||
// frame.
|
||||
|
||||
var appFrame = document.createElement('iframe');
|
||||
appFrame.mozbrowser = true;
|
||||
appFrame.setAttribute('mozapp', 'http://example.org/manifest.webapp');
|
||||
|
||||
var browserFrame = document.createElement('iframe');
|
||||
browserFrame.mozbrowser = true;
|
||||
|
||||
var gotAppFrameClose = false;
|
||||
appFrame.addEventListener('mozbrowserclose', function() {
|
||||
ok(true, "Got close from app frame.");
|
||||
gotAppFrameClose = true;
|
||||
});
|
||||
|
||||
var gotAppFrameAlert = false;
|
||||
appFrame.addEventListener('mozbrowsershowmodalprompt', function() {
|
||||
ok(gotAppFrameClose, "Should have gotten app frame close by now.");
|
||||
ok(!gotAppFrameAlert, "Just one alert from the app frame.");
|
||||
gotAppFrameAlert = true;
|
||||
if (gotBrowserFrameAlert && gotAppFrameAlert) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
|
||||
browserFrame.addEventListener('mozbrowserclose', function() {
|
||||
ok(false, "Got close from browser frame.");
|
||||
});
|
||||
|
||||
var gotBrowserFrameAlert = false;
|
||||
browserFrame.addEventListener('mozbrowsershowmodalprompt', function() {
|
||||
ok(!gotBrowserFrameAlert, "Just one browser frame alert.");
|
||||
gotBrowserFrameAlert = true;
|
||||
if (gotBrowserFrameAlert && gotAppFrameAlert) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(appFrame);
|
||||
document.body.appendChild(browserFrame);
|
||||
|
||||
appFrame.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_CloseApp.html';
|
||||
browserFrame.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_CloseApp.html';
|
||||
}
|
||||
|
||||
// The test harness sets dom.allow_scripts_to_close_windows to true (as of
|
||||
// writing, anyway). But that means that browser tabs can close themselves,
|
||||
// which is what we want to test /can't/ happen! For the purposes of this
|
||||
// test (and normal browser operation), this pref should be false.
|
||||
SpecialPowers.pushPrefEnv({'set': [['dom.allow_scripts_to_close_windows', false]]}, runTest);
|
|
@ -0,0 +1,12 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
file_browserElement_CloseApp.html
|
||||
|
||||
<script>
|
||||
window.close();
|
||||
alert('called close');
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 789392</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_CloseApp.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 789392</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_CloseApp.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -3,6 +3,8 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/ClearRecentHistory.jsm");
|
||||
|
||||
const domains = [
|
||||
"mochi.test:8888",
|
||||
"www.example.com"
|
||||
|
@ -64,9 +66,7 @@ function test2()
|
|||
function test3()
|
||||
{
|
||||
// Remove database from domain 2
|
||||
Components.classes["@mozilla.org/privatebrowsing;1"]
|
||||
.getService(Components.interfaces.nsIPrivateBrowsingService)
|
||||
.removeDataFromDomain(domains[1]);
|
||||
ClearRecentHistory.removeDataFromDomain(domains[1]);
|
||||
setPermission(testPageURL4, "indexedDB", "unknown");
|
||||
executeSoon(test4);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* http://www.w3.org/TR/DOM-Level-2-Style
|
||||
*/
|
||||
|
||||
[builtinclass, scriptable, uuid(243898eb-0e13-416d-9a2e-33af084985ed)]
|
||||
[builtinclass, scriptable, uuid(2ae61565-1a66-4e6e-960d-b999c631e5c6)]
|
||||
interface nsIDOMCSS2Properties : nsISupports
|
||||
{
|
||||
attribute DOMString background;
|
||||
|
@ -803,10 +803,6 @@ interface nsIDOMCSS2Properties : nsISupports
|
|||
attribute DOMString MozBorderImage;
|
||||
// raises(DOMException) on setting
|
||||
|
||||
/* XXXdholbert NOTE: Flexbox properties are commented out here, until our
|
||||
layout engine responds to them. In builds with MOZ_FLEXBOX enabled, this
|
||||
block should be uncommented (and this interface's uuid should be revved).
|
||||
(This would be #ifdef MOZ_FLEXBOX, if that worked in IDL files.)
|
||||
attribute DOMString MozAlignItems;
|
||||
// raises(DOMException) on setting
|
||||
|
||||
|
@ -833,5 +829,4 @@ interface nsIDOMCSS2Properties : nsISupports
|
|||
|
||||
attribute DOMString MozJustifyContent;
|
||||
// raises(DOMException) on setting
|
||||
*/
|
||||
};
|
||||
|
|
|
@ -774,8 +774,12 @@ ContentParent::~ContentParent()
|
|||
MOZ_ASSERT(!gNonAppContentParents ||
|
||||
!gNonAppContentParents->Contains(this));
|
||||
} else {
|
||||
// In general, we expect gAppContentParents->Get(mAppManifestURL) to be
|
||||
// NULL. But it could be that we created another ContentParent for this
|
||||
// app after we did this->ActorDestroy(), so the right check is that
|
||||
// gAppContentParent->Get(mAppManifestURL) != this.
|
||||
MOZ_ASSERT(!gAppContentParents ||
|
||||
!gAppContentParents->Get(mAppManifestURL));
|
||||
gAppContentParents->Get(mAppManifestURL) != this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,11 +262,12 @@ nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
|
|||
// Certain assistive technologies don't want oop Flash, thus we have a special
|
||||
// pref for them to disable oop Flash (refer to bug 785047 for details).
|
||||
bool useA11yPref = false;
|
||||
#ifdef XP_WIN
|
||||
useA11yPref = a11y::Compatibility::IsJAWS();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
useA11yPref = a11y::Compatibility::IsJAWS();
|
||||
|
||||
// On Windows Vista+, we force Flash to run in OOPP mode because Adobe
|
||||
// doesn't test Flash in-process and there are known stability bugs.
|
||||
if (aPluginTag->mIsFlashPlugin && IsVistaOrLater()) {
|
||||
|
|
|
@ -694,7 +694,7 @@ nsresult nsPluginNativeWindowWin::SubclassAndAssociateWindow()
|
|||
if (!mPluginWinProc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsPluginNativeWindowWin * win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
|
||||
DebugOnly<nsPluginNativeWindowWin *> win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
|
||||
NS_ASSERTION(!win || (win == this), "plugin window already has property and this is not us");
|
||||
|
||||
if (!::SetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION, (HANDLE)this))
|
||||
|
|
|
@ -280,7 +280,7 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
|||
}
|
||||
|
||||
if (restoreOrigDir) {
|
||||
BOOL bCheck = SetCurrentDirectoryW(aOrigDir);
|
||||
DebugOnly<BOOL> bCheck = SetCurrentDirectoryW(aOrigDir);
|
||||
NS_ASSERTION(bCheck, "Error in Loading plugin");
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
|||
if (!verbuf)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (::GetFileVersionInfoW(lpFilepath, NULL, versionsize, verbuf))
|
||||
if (::GetFileVersionInfoW(lpFilepath, 0, versionsize, verbuf))
|
||||
{
|
||||
// TODO: get appropriately-localized info from plugin file
|
||||
UINT lang = 1033; // language = English
|
||||
|
|
|
@ -98,7 +98,7 @@ struct ParamTraits<mozilla::plugins::NPRemoteEvent>
|
|||
|
||||
default:
|
||||
// RegisterWindowMessage events should be passed.
|
||||
if (paramCopy.event.event >= 0xC000 && paramCopy.event.event <= 0xFFFF)
|
||||
if (paramCopy.event.event >= 0xC000)
|
||||
break;
|
||||
|
||||
// FIXME/bug 567465: temporarily work around unhandled
|
||||
|
|
|
@ -1455,8 +1455,10 @@ PluginModuleParent::InitializeInjector()
|
|||
void
|
||||
PluginModuleParent::OnCrash(DWORD processID)
|
||||
{
|
||||
GetIPCChannel()->CloseWithError();
|
||||
KillProcess(OtherProcess(), 1, false);
|
||||
if (!mShutdown) {
|
||||
GetIPCChannel()->CloseWithError();
|
||||
KillProcess(OtherProcess(), 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MOZ_CRASHREPORTER_INJECTOR
|
||||
|
|
|
@ -37,7 +37,10 @@ using namespace mozilla;
|
|||
|
||||
static const int kDefaultPeriod = 1000; // ms
|
||||
|
||||
NS_IMPL_ISUPPORTS2(GonkGPSGeolocationProvider, nsIGeolocationProvider, nsIRILDataCallback)
|
||||
// While most methods of GonkGPSGeolocationProvider should only be
|
||||
// called from main thread, we deliberately put the Init and ShutdownGPS
|
||||
// methods off main thread to avoid blocking.
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(GonkGPSGeolocationProvider, nsIGeolocationProvider, nsIRILDataCallback)
|
||||
|
||||
GonkGPSGeolocationProvider* GonkGPSGeolocationProvider::sSingleton;
|
||||
GpsCallbacks GonkGPSGeolocationProvider::mCallbacks = {
|
||||
|
@ -126,19 +129,29 @@ GonkGPSGeolocationProvider::NmeaCallback(GpsUtcTime timestamp, const char* nmea,
|
|||
void
|
||||
GonkGPSGeolocationProvider::SetCapabilitiesCallback(uint32_t capabilities)
|
||||
{
|
||||
// Called by GPS engine in init(), hence we don't have to
|
||||
// protect the memebers
|
||||
class UpdateCapabilitiesEvent : public nsRunnable {
|
||||
public:
|
||||
UpdateCapabilitiesEvent(uint32_t aCapabilities)
|
||||
: mCapabilities(aCapabilities)
|
||||
{}
|
||||
NS_IMETHOD Run() {
|
||||
nsRefPtr<GonkGPSGeolocationProvider> provider =
|
||||
GonkGPSGeolocationProvider::GetSingleton();
|
||||
|
||||
nsRefPtr<GonkGPSGeolocationProvider> provider =
|
||||
GonkGPSGeolocationProvider::GetSingleton();
|
||||
|
||||
provider->mSupportsScheduling = capabilities & GPS_CAPABILITY_SCHEDULING;
|
||||
provider->mSupportsMSB = capabilities & GPS_CAPABILITY_MSB;
|
||||
provider->mSupportsMSA = capabilities & GPS_CAPABILITY_MSA;
|
||||
provider->mSupportsSingleShot = capabilities & GPS_CAPABILITY_SINGLE_SHOT;
|
||||
provider->mSupportsScheduling = mCapabilities & GPS_CAPABILITY_SCHEDULING;
|
||||
provider->mSupportsMSB = mCapabilities & GPS_CAPABILITY_MSB;
|
||||
provider->mSupportsMSA = mCapabilities & GPS_CAPABILITY_MSA;
|
||||
provider->mSupportsSingleShot = mCapabilities & GPS_CAPABILITY_SINGLE_SHOT;
|
||||
#ifdef GPS_CAPABILITY_ON_DEMAND_TIME
|
||||
provider->mSupportsTimeInjection = capabilities & GPS_CAPABILITY_ON_DEMAND_TIME;
|
||||
provider->mSupportsTimeInjection = mCapabilities & GPS_CAPABILITY_ON_DEMAND_TIME;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
uint32_t mCapabilities;
|
||||
};
|
||||
|
||||
NS_DispatchToMainThread(new UpdateCapabilitiesEvent(capabilities));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -181,21 +194,30 @@ GonkGPSGeolocationProvider::AGPSStatusCallback(AGpsStatus* status)
|
|||
{
|
||||
MOZ_ASSERT(status);
|
||||
|
||||
nsRefPtr<GonkGPSGeolocationProvider> provider =
|
||||
GonkGPSGeolocationProvider::GetSingleton();
|
||||
class AGPSStatusEvent : public nsRunnable {
|
||||
public:
|
||||
AGPSStatusEvent(AGpsStatusValue aStatus)
|
||||
: mStatus(aStatus)
|
||||
{}
|
||||
NS_IMETHOD Run() {
|
||||
nsRefPtr<GonkGPSGeolocationProvider> provider =
|
||||
GonkGPSGeolocationProvider::GetSingleton();
|
||||
|
||||
nsCOMPtr<nsIRunnable> event;
|
||||
switch (status->status) {
|
||||
case GPS_REQUEST_AGPS_DATA_CONN:
|
||||
event = NS_NewRunnableMethod(provider, &GonkGPSGeolocationProvider::RequestDataConnection);
|
||||
break;
|
||||
case GPS_RELEASE_AGPS_DATA_CONN:
|
||||
event = NS_NewRunnableMethod(provider, &GonkGPSGeolocationProvider::ReleaseDataConnection);
|
||||
break;
|
||||
}
|
||||
if (event) {
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
switch (mStatus) {
|
||||
case GPS_REQUEST_AGPS_DATA_CONN:
|
||||
provider->RequestDataConnection();
|
||||
break;
|
||||
case GPS_RELEASE_AGPS_DATA_CONN:
|
||||
provider->ReleaseDataConnection();
|
||||
break;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
AGpsStatusValue mStatus;
|
||||
};
|
||||
|
||||
NS_DispatchToMainThread(new AGPSStatusEvent(status->status));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -245,13 +267,17 @@ GonkGPSGeolocationProvider::GonkGPSGeolocationProvider()
|
|||
|
||||
GonkGPSGeolocationProvider::~GonkGPSGeolocationProvider()
|
||||
{
|
||||
ShutdownNow();
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mStarted, "Must call Shutdown before destruction");
|
||||
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<GonkGPSGeolocationProvider>
|
||||
GonkGPSGeolocationProvider::GetSingleton()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!sSingleton)
|
||||
sSingleton = new GonkGPSGeolocationProvider();
|
||||
|
||||
|
@ -283,6 +309,8 @@ GonkGPSGeolocationProvider::GetGPSInterface()
|
|||
void
|
||||
GonkGPSGeolocationProvider::RequestDataConnection()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mRIL) {
|
||||
return;
|
||||
}
|
||||
|
@ -304,6 +332,8 @@ GonkGPSGeolocationProvider::RequestDataConnection()
|
|||
void
|
||||
GonkGPSGeolocationProvider::ReleaseDataConnection()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mRIL) {
|
||||
return;
|
||||
}
|
||||
|
@ -421,6 +451,7 @@ GonkGPSGeolocationProvider::Init()
|
|||
void
|
||||
GonkGPSGeolocationProvider::StartGPS()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mGpsInterface);
|
||||
|
||||
int32_t update = Preferences::GetInt("geo.default.update", kDefaultPeriod);
|
||||
|
@ -457,7 +488,7 @@ void
|
|||
GonkGPSGeolocationProvider::SetupAGPS()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mAGpsRilInterface);
|
||||
MOZ_ASSERT(mAGpsInterface);
|
||||
|
||||
const nsAdoptingCString& suplServer = Preferences::GetCString("geo.gps.supl_server");
|
||||
int32_t suplPort = Preferences::GetInt("geo.gps.supl_port", -1);
|
||||
|
@ -483,6 +514,8 @@ GonkGPSGeolocationProvider::SetupAGPS()
|
|||
NS_IMETHODIMP
|
||||
GonkGPSGeolocationProvider::Startup()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mStarted) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -502,6 +535,8 @@ GonkGPSGeolocationProvider::Startup()
|
|||
NS_IMETHODIMP
|
||||
GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mLocationCallback = aCallback;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -509,30 +544,29 @@ GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
|
|||
NS_IMETHODIMP
|
||||
GonkGPSGeolocationProvider::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mInitThread);
|
||||
|
||||
if (!mStarted) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownNow),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GonkGPSGeolocationProvider::ShutdownNow()
|
||||
{
|
||||
if (!mStarted) {
|
||||
return;
|
||||
}
|
||||
mStarted = false;
|
||||
|
||||
if (mRIL) {
|
||||
mRIL->UnregisterDataCallCallback(this);
|
||||
}
|
||||
|
||||
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GonkGPSGeolocationProvider::ShutdownGPS()
|
||||
{
|
||||
MOZ_ASSERT(!mStarted, "Should only be called after Shutdown");
|
||||
|
||||
if (mGpsInterface) {
|
||||
mGpsInterface->stop();
|
||||
mGpsInterface->cleanup();
|
||||
|
@ -552,6 +586,7 @@ GonkGPSGeolocationProvider::SetHighAccuracy(bool)
|
|||
NS_IMETHODIMP
|
||||
GonkGPSGeolocationProvider::DataCallStateChanged(nsIRILDataCallInfo* aDataCall)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aDataCall);
|
||||
MOZ_ASSERT(mAGpsInterface);
|
||||
nsCOMPtr<nsIRILDataCallInfo> datacall = aDataCall;
|
||||
|
|
|
@ -63,7 +63,7 @@ private:
|
|||
void Init();
|
||||
void SetupAGPS();
|
||||
void StartGPS();
|
||||
void ShutdownNow();
|
||||
void ShutdownGPS();
|
||||
void RequestDataConnection();
|
||||
void ReleaseDataConnection();
|
||||
void RequestSetID(uint32_t flags);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "SystemWorkerManager.h"
|
||||
#include "nsRadioInterfaceLayer.h"
|
||||
#include "nsTArrayHelpers.h"
|
||||
|
||||
#include "CallEvent.h"
|
||||
#include "TelephonyCall.h"
|
||||
|
@ -33,49 +34,6 @@ typedef nsAutoTArray<Telephony*, 2> TelephonyList;
|
|||
|
||||
TelephonyList* gTelephonyList;
|
||||
|
||||
template <class T>
|
||||
inline nsresult
|
||||
nsTArrayToJSArray(JSContext* aCx, JSObject* aGlobal,
|
||||
const nsTArray<nsRefPtr<T> >& aSourceArray,
|
||||
JSObject** aResultArray)
|
||||
{
|
||||
NS_ASSERTION(aCx, "Null context!");
|
||||
NS_ASSERTION(aGlobal, "Null global!");
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
JSAutoCompartment ac(aCx, aGlobal);
|
||||
|
||||
JSObject* arrayObj;
|
||||
|
||||
if (aSourceArray.IsEmpty()) {
|
||||
arrayObj = JS_NewArrayObject(aCx, 0, nullptr);
|
||||
} else {
|
||||
uint32_t valLength = aSourceArray.Length();
|
||||
mozilla::ScopedDeleteArray<jsval> valArray(new jsval[valLength]);
|
||||
JS::AutoArrayRooter tvr(aCx, 0, valArray);
|
||||
for (uint32_t index = 0; index < valLength; index++) {
|
||||
nsISupports* obj = aSourceArray[index]->ToISupports();
|
||||
nsresult rv =
|
||||
nsContentUtils::WrapNative(aCx, aGlobal, obj, &valArray[index]);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
tvr.changeLength(index + 1);
|
||||
}
|
||||
arrayObj = JS_NewArrayObject(aCx, valLength, valArray);
|
||||
}
|
||||
|
||||
if (!arrayObj) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// XXX This is not what Jonas wants. He wants it to be live.
|
||||
if (!JS_FreezeObject(aCx, arrayObj)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aResultArray = arrayObj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
Telephony::Telephony()
|
||||
|
@ -334,9 +292,7 @@ Telephony::GetCalls(jsval* aCalls)
|
|||
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (sc) {
|
||||
rv =
|
||||
nsTArrayToJSArray(sc->GetNativeContext(),
|
||||
sc->GetNativeGlobal(), mCalls, &calls);
|
||||
rv = nsTArrayToJSArray(sc->GetNativeContext(), mCalls, &calls);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mRooted) {
|
||||
|
|
|
@ -537,7 +537,8 @@ var interfaceNamesInGlobalScope =
|
|||
"MozTimeManager",
|
||||
"MozNavigatorTime",
|
||||
"PermissionSettings",
|
||||
"DataErrorEvent"
|
||||
"DataErrorEvent",
|
||||
"DataChannel"
|
||||
]
|
||||
|
||||
for (var i in SpecialPowers.Components.interfaces) {
|
||||
|
|
|
@ -55,5 +55,8 @@ if (window.opener) {
|
|||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
SimpleTest.waitForFocus(start);
|
||||
if (typeof start !== 'undefined') {
|
||||
SimpleTest.waitForFocus(start);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -409,7 +409,7 @@ static PropKeyInfo gAllPropKeys[] = {
|
|||
{"asLaidOutWindows", rad4},
|
||||
{"selectedFrameWindows", rad5},
|
||||
{"separateFramesWindows", rad6},
|
||||
{NULL, NULL}};
|
||||
{NULL, 0}};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
|
@ -883,7 +883,7 @@ ShowNativePrintDialog(HWND aHWnd,
|
|||
prntdlg.lpPrintTemplateName = NULL;
|
||||
|
||||
if (!ShouldExtendPrintDialog()) {
|
||||
prntdlg.lCustData = NULL;
|
||||
prntdlg.lCustData = 0;
|
||||
prntdlg.lpfnPrintHook = NULL;
|
||||
} else {
|
||||
// Set up print dialog "hook" procedure for extending the dialog
|
||||
|
|
|
@ -41,9 +41,6 @@ static const char *kPrintProgressDialogURL = "chrome://global/content/printProg
|
|||
static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul";
|
||||
static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul";
|
||||
|
||||
// Static Data
|
||||
static HINSTANCE gInstance;
|
||||
|
||||
/****************************************************************
|
||||
************************* ParamBlock ***************************
|
||||
****************************************************************/
|
||||
|
@ -96,7 +93,6 @@ HWND
|
|||
nsPrintingPromptService::GetHWNDForDOMWindow(nsIDOMWindow *aWindow)
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowserChrome> chrome;
|
||||
HWND hWnd = NULL;
|
||||
|
||||
// We might be embedded so check this path first
|
||||
if (mWatcher) {
|
||||
|
|
|
@ -19,15 +19,13 @@ class PathBuilderCG : public PathBuilder
|
|||
public:
|
||||
// absorbs a reference of aPath
|
||||
PathBuilderCG(CGMutablePathRef aPath, FillRule aFillRule)
|
||||
: mFigureActive(false)
|
||||
, mFillRule(aFillRule)
|
||||
: mFillRule(aFillRule)
|
||||
{
|
||||
mCGPath = aPath;
|
||||
}
|
||||
|
||||
PathBuilderCG(FillRule aFillRule)
|
||||
: mFigureActive(false)
|
||||
, mFillRule(aFillRule)
|
||||
: mFillRule(aFillRule)
|
||||
{
|
||||
mCGPath = CGPathCreateMutable();
|
||||
}
|
||||
|
@ -54,7 +52,6 @@ private:
|
|||
void EnsureActive(const Point &aPoint);
|
||||
|
||||
CGMutablePathRef mCGPath;
|
||||
bool mFigureActive;
|
||||
Point mCurrentPoint;
|
||||
Point mBeginPoint;
|
||||
FillRule mFillRule;
|
||||
|
|
|
@ -219,7 +219,7 @@ WGLLibrary::EnsureInitialized(bool aUseMesaLlvmPipe)
|
|||
int attribs[] = {
|
||||
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
NULL
|
||||
0
|
||||
};
|
||||
|
||||
mWindowGLContext = fCreateContextAttribs(mWindowDC, NULL, attribs);
|
||||
|
@ -503,10 +503,8 @@ GLContextWGL::ResizeOffscreen(const gfxIntSize& aNewSize)
|
|||
if (!newbuf)
|
||||
return false;
|
||||
|
||||
bool isCurrent = false;
|
||||
if (sWGLLib[mLibType].fGetCurrentContext() == mContext) {
|
||||
sWGLLib[mLibType].fMakeCurrent(NULL, NULL);
|
||||
isCurrent = true;
|
||||
}
|
||||
|
||||
sWGLLib[mLibType].fDestroyPbuffer(mPBuffer);
|
||||
|
@ -558,7 +556,7 @@ GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
|
|||
int attribs[] = {
|
||||
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
NULL
|
||||
0
|
||||
};
|
||||
|
||||
context = sWGLLib[libToUse].fCreateContextAttribs(dc,
|
||||
|
@ -678,7 +676,7 @@ CreatePBufferOffscreenContext(const gfxIntSize& aSize,
|
|||
int attribs[] = {
|
||||
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
NULL
|
||||
0
|
||||
};
|
||||
|
||||
context = sWGLLib[aLibToUse].fCreateContextAttribs(pbdc, nullptr, attribs);
|
||||
|
@ -688,7 +686,7 @@ CreatePBufferOffscreenContext(const gfxIntSize& aSize,
|
|||
|
||||
if (!context) {
|
||||
sWGLLib[aLibToUse].fDestroyPbuffer(pbuffer);
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<GLContextWGL> glContext = new GLContextWGL(aFormat,
|
||||
|
@ -724,7 +722,7 @@ CreateWindowOffscreenContext(const ContextFormat& aFormat,
|
|||
int attribs[] = {
|
||||
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
|
||||
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
|
||||
NULL
|
||||
0
|
||||
};
|
||||
|
||||
context = sWGLLib[libToUse].fCreateContextAttribs(dc, shareContext->Context(), attribs);
|
||||
|
@ -821,7 +819,7 @@ GLContextProviderWGL::GetGlobalContext(const ContextFlags aFlags)
|
|||
if (!gGlobalContext[libToUse]->Init()) {
|
||||
NS_WARNING("Global context GLContext initialization failed?");
|
||||
gGlobalContext[libToUse] = nullptr;
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gGlobalContext[libToUse]->SetIsGlobalSharedContext(true);
|
||||
|
|
|
@ -46,10 +46,16 @@ public:
|
|||
|
||||
bool operator==(const FrameMetrics& aOther) const
|
||||
{
|
||||
return (mViewport.IsEqualEdges(aOther.mViewport) &&
|
||||
mScrollOffset == aOther.mScrollOffset &&
|
||||
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
|
||||
mScrollId == aOther.mScrollId);
|
||||
return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
|
||||
mContentRect.IsEqualEdges(aOther.mContentRect) &&
|
||||
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
|
||||
mViewport.IsEqualEdges(aOther.mViewport) &&
|
||||
mScrollOffset == aOther.mScrollOffset &&
|
||||
mScrollId == aOther.mScrollId &&
|
||||
mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
|
||||
mResolution == aOther.mResolution &&
|
||||
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
|
||||
mMayHaveTouchListeners == aOther.mMayHaveTouchListeners;
|
||||
}
|
||||
bool operator!=(const FrameMetrics& aOther) const
|
||||
{
|
||||
|
|
|
@ -498,6 +498,15 @@ Layer::SetAnimations(const AnimationArray& aAnimations)
|
|||
Mutated();
|
||||
}
|
||||
|
||||
void
|
||||
Layer::ApplyPendingUpdatesToSubtree()
|
||||
{
|
||||
ApplyPendingUpdatesForThisTransaction();
|
||||
for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||
child->ApplyPendingUpdatesToSubtree();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Layer::CanUseOpaqueSurface()
|
||||
{
|
||||
|
@ -665,6 +674,16 @@ Layer::GetLocalTransform()
|
|||
return transform;
|
||||
}
|
||||
|
||||
void
|
||||
Layer::ApplyPendingUpdatesForThisTransaction()
|
||||
{
|
||||
if (mPendingTransform && *mPendingTransform != mTransform) {
|
||||
mTransform = *mPendingTransform;
|
||||
Mutated();
|
||||
}
|
||||
mPendingTransform = nullptr;
|
||||
}
|
||||
|
||||
const float
|
||||
Layer::GetLocalOpacity()
|
||||
{
|
||||
|
|
|
@ -701,6 +701,7 @@ public:
|
|||
*/
|
||||
void SetBaseTransform(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
mPendingTransform = nullptr;
|
||||
if (mTransform == aMatrix) {
|
||||
return;
|
||||
}
|
||||
|
@ -708,6 +709,19 @@ public:
|
|||
Mutated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be called at any time.
|
||||
*
|
||||
* Like SetBaseTransform(), but can be called before the next
|
||||
* transform (i.e. outside an open transaction). Semantically, this
|
||||
* method enqueues a new transform value to be set immediately after
|
||||
* the next transaction is opened.
|
||||
*/
|
||||
void SetBaseTransformForNextTransaction(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
mPendingTransform = new gfx3DMatrix(aMatrix);
|
||||
}
|
||||
|
||||
void SetPostScale(float aXScale, float aYScale)
|
||||
{
|
||||
mPostXScale = aXScale;
|
||||
|
@ -763,6 +777,15 @@ public:
|
|||
|
||||
AnimationArray& GetAnimations() { return mAnimations; }
|
||||
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
|
||||
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
*
|
||||
* Apply pending changes to layers before drawing them, if those
|
||||
* pending changes haven't been overridden by later changes.
|
||||
*/
|
||||
void ApplyPendingUpdatesToSubtree();
|
||||
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
*
|
||||
|
@ -979,6 +1002,7 @@ public:
|
|||
*/
|
||||
void ClearInvalidRect() { mInvalidRegion.SetEmpty(); }
|
||||
|
||||
void ApplyPendingUpdatesForThisTransaction();
|
||||
|
||||
#ifdef DEBUG
|
||||
void SetDebugColorIndex(uint32_t aIndex) { mDebugColorIndex = aIndex; }
|
||||
|
@ -1033,6 +1057,10 @@ protected:
|
|||
gfx::UserData mUserData;
|
||||
nsIntRegion mVisibleRegion;
|
||||
gfx3DMatrix mTransform;
|
||||
// A mutation of |mTransform| that we've queued to be applied at the
|
||||
// end of the next transaction (if nothing else overrides it in the
|
||||
// meantime).
|
||||
nsAutoPtr<gfx3DMatrix> mPendingTransform;
|
||||
float mPostXScale;
|
||||
float mPostYScale;
|
||||
gfx3DMatrix mEffectiveTransform;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче