This commit is contained in:
Richard Newman 2012-10-04 11:00:48 -07:00
Родитель 6b64ac8884 e891130972
Коммит 17241c85b5
249 изменённых файлов: 8322 добавлений и 3399 удалений

Просмотреть файл

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

Двоичные данные
content/media/test/crashtests/cors.webm Normal file

Двоичный файл не отображается.

Просмотреть файл

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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше