mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-02 07:05:24 +00:00
Merge from mozilla-central (yay method barrier removal).
This commit is contained in:
commit
4e1a8fb5ae
@ -99,7 +99,9 @@ endif
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../generic \
|
||||
-I$(srcdir)/../html \
|
||||
-I$(srcdir)/../xpcom \
|
||||
-I$(srcdir)/../xul \
|
||||
-I$(topsrcdir)/other-licenses/atk-1.0 \
|
||||
$(NULL)
|
||||
|
@ -42,12 +42,14 @@
|
||||
#include "nsAccessibleWrap.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsIAccessibleTable.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "nsMai.h"
|
||||
|
||||
#include "nsArrayUtils.h"
|
||||
|
||||
extern "C" {
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
extern "C" {
|
||||
static AtkObject*
|
||||
refAtCB(AtkTable *aTable, gint aRow, gint aColumn)
|
||||
{
|
||||
@ -208,23 +210,17 @@ getRowExtentAtCB(AtkTable *aTable,
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
getCaptionCB(AtkTable *aTable)
|
||||
getCaptionCB(AtkTable* aTable)
|
||||
{
|
||||
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return nsnull;
|
||||
nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
|
||||
if (!accWrap)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessibleTable> accTable;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
||||
getter_AddRefs(accTable));
|
||||
NS_ENSURE_TRUE(accTable, nsnull);
|
||||
TableAccessible* table = accWrap->AsTable();
|
||||
NS_ENSURE_TRUE(table, nsnull);
|
||||
|
||||
nsCOMPtr<nsIAccessible> caption;
|
||||
nsresult rv = accTable->GetCaption(getter_AddRefs(caption));
|
||||
if (NS_FAILED(rv) || !caption)
|
||||
return nsnull;
|
||||
|
||||
return nsAccessibleWrap::GetAtkObject(caption);
|
||||
nsAccessible* caption = table->Caption();
|
||||
return caption ? nsAccessibleWrap::GetAtkObject(caption) : nsnull;
|
||||
}
|
||||
|
||||
static const gchar*
|
||||
|
@ -44,9 +44,6 @@
|
||||
#include "nsApplicationAccessibleWrap.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsIAccessibleText.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULTreeAccessible.h"
|
||||
#endif
|
||||
#include "nsAccEvent.h"
|
||||
#include "States.h"
|
||||
|
||||
|
@ -104,8 +104,9 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/../xpcom \
|
||||
-I$(srcdir)/../generic \
|
||||
-I$(srcdir)/../html \
|
||||
-I$(srcdir)/../xpcom \
|
||||
-I$(srcdir)/../xul \
|
||||
-I$(srcdir)/../../../layout/generic \
|
||||
-I$(srcdir)/../../../layout/style \
|
||||
|
@ -58,7 +58,7 @@ using namespace mozilla::a11y;
|
||||
|
||||
nsARIAGridAccessible::
|
||||
nsARIAGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsAccessibleWrap(aContent, aDoc)
|
||||
nsAccessibleWrap(aContent, aDoc), xpcAccessibleTable(this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -70,21 +70,18 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsARIAGridAccessible,
|
||||
nsIAccessibleTable)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleTable
|
||||
//nsAccessNode
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsARIAGridAccessible::GetCaption(nsIAccessible **aCaption)
|
||||
void
|
||||
nsARIAGridAccessible::Shutdown()
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCaption);
|
||||
*aCaption = nsnull;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// XXX: should be pointed by aria-labelledby on grid?
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
mTable = nsnull;
|
||||
nsAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleTable
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsARIAGridAccessible::GetSummary(nsAString &aSummary)
|
||||
{
|
||||
@ -710,15 +707,6 @@ nsARIAGridAccessible::UnselectColumn(PRInt32 aColumn)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsARIAGridAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
|
||||
*aIsProbablyForLayout = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected
|
||||
|
||||
|
@ -42,12 +42,16 @@
|
||||
#include "nsIAccessibleTable.h"
|
||||
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "xpcAccessibleTable.h"
|
||||
|
||||
/**
|
||||
* Accessible for ARIA grid and treegrid.
|
||||
*/
|
||||
class nsARIAGridAccessible : public nsAccessibleWrap,
|
||||
public nsIAccessibleTable
|
||||
public xpcAccessibleTable,
|
||||
public nsIAccessibleTable,
|
||||
public mozilla::a11y::TableAccessible
|
||||
{
|
||||
public:
|
||||
nsARIAGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
@ -56,7 +60,13 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessibleTable
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
|
||||
// nsAccessible
|
||||
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
|
||||
|
||||
// nsAccessNode
|
||||
virtual void Shutdown();
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -47,9 +47,7 @@
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsHyperTextAccessible.h"
|
||||
#include "nsHTMLTableAccessible.h"
|
||||
#include "nsTextAccessible.h"
|
||||
#include "nsXULTreeGridAccessible.h"
|
||||
|
||||
#include "nsIDOMXULContainerElement.h"
|
||||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
|
@ -66,6 +66,11 @@ class nsHTMLImageMapAccessible;
|
||||
class nsHTMLLIAccessible;
|
||||
struct nsRoleMapEntry;
|
||||
class Relation;
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
class TableAccessible;
|
||||
}
|
||||
}
|
||||
class nsTextAccessible;
|
||||
|
||||
struct nsRect;
|
||||
@ -471,6 +476,8 @@ public:
|
||||
inline bool IsRoot() const { return mFlags & eRootAccessible; }
|
||||
nsRootAccessible* AsRoot();
|
||||
|
||||
virtual mozilla::a11y::TableAccessible* AsTable() { return nsnull; }
|
||||
|
||||
inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
|
||||
nsTextAccessible* AsTextLeaf();
|
||||
|
||||
|
@ -41,15 +41,13 @@
|
||||
#include "nsCaretAccessible.h"
|
||||
#include "nsDocAccessibleWrap.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULTreeAccessible.h"
|
||||
#endif
|
||||
|
||||
#include "nsHashtable.h"
|
||||
#include "nsCaretAccessible.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
class nsXULTreeAccessible;
|
||||
class Relation;
|
||||
|
||||
#define NS_ROOTACCESSIBLE_IMPL_CID \
|
||||
|
170
accessible/src/generic/TableAccessible.h
Normal file
170
accessible/src/generic/TableAccessible.h
Normal file
@ -0,0 +1,170 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 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 TABLE_ACCESSIBLE_H
|
||||
#define TABLE_ACCESSIBLE_H
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
class nsAccessible;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* Accessible table interface.
|
||||
*/
|
||||
class TableAccessible
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return the caption accessible if any for this table.
|
||||
*/
|
||||
virtual nsAccessible* Caption() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Get the summary for this table.
|
||||
*/
|
||||
virtual void Summary(nsString& aSummary) { aSummary.Truncate(); }
|
||||
|
||||
/**
|
||||
* Return the number of columns in the table.
|
||||
*/
|
||||
virtual PRUint32 ColCount() { return 0; }
|
||||
|
||||
/**
|
||||
* Return the number of rows in the table.
|
||||
*/
|
||||
virtual PRUint32 RowCount() { return 0; }
|
||||
|
||||
/**
|
||||
* Return the accessible for the cell at the given row and column indices.
|
||||
*/
|
||||
virtual nsAccessible* CellAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return nsnull; }
|
||||
|
||||
/**
|
||||
* Return the index of the cell at the given row and column.
|
||||
*/
|
||||
virtual PRInt32 CellIndexAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return -1; }
|
||||
|
||||
/**
|
||||
* Return the column index of the cell with the given index.
|
||||
*/
|
||||
virtual PRInt32 ColIndexAt(PRUint32 aCellIdx) { return -1; }
|
||||
|
||||
/**
|
||||
* Return the row index of the cell with the given index.
|
||||
*/
|
||||
virtual PRInt32 RowIndexAt(PRUint32 aCellIdx) { return -1; }
|
||||
|
||||
/**
|
||||
* Get the row and column indices for the cell at the given index.
|
||||
*/
|
||||
virtual void RowAndColIndicesAt(PRUint32 aCellIdx, PRInt32* aRowIdx,
|
||||
PRInt32* aColIdx) {}
|
||||
|
||||
/**
|
||||
* Return the number of columns occupied by the cell at the given row and
|
||||
* column indices.
|
||||
*/
|
||||
virtual PRUint32 ColExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return 1; }
|
||||
|
||||
/**
|
||||
* Return the number of rows occupied by the cell at the given row and column
|
||||
* indices.
|
||||
*/
|
||||
virtual PRUint32 RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx) { return 1; }
|
||||
|
||||
/**
|
||||
* Get the description of the given column.
|
||||
*/
|
||||
virtual void ColDescription(PRUint32 aColIdx, nsString& aDescription)
|
||||
{ aDescription.Truncate(); }
|
||||
|
||||
/**
|
||||
* Get the description for the given row.
|
||||
*/
|
||||
virtual void RowDescription(PRUint32 aRowIdx, nsString& aDescription)
|
||||
{ aDescription.Truncate(); }
|
||||
|
||||
/**
|
||||
* Return true if the given column is selected.
|
||||
*/
|
||||
virtual bool IsColSelected(PRUint32 aColIdx) { return false; }
|
||||
|
||||
/**
|
||||
* Return true if the given row is selected.
|
||||
*/
|
||||
virtual bool IsRowSelected(PRUint32 aRowIdx) { return false; }
|
||||
|
||||
/**
|
||||
* Return true if the given cell is selected.
|
||||
*/
|
||||
virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx) { return false; }
|
||||
|
||||
/**
|
||||
* Return the number of selected cells.
|
||||
*/
|
||||
virtual PRUint32 SelectedCellCount() { return 0; }
|
||||
|
||||
/**
|
||||
* Return the number of selected columns.
|
||||
*/
|
||||
virtual PRUint32 SelectedColCount() { return 0; }
|
||||
|
||||
/**
|
||||
* Return the number of selected rows.
|
||||
*/
|
||||
virtual PRUint32 SelectedRowCount() { return 0; }
|
||||
|
||||
/**
|
||||
* Get the set of selected cells.
|
||||
*/
|
||||
virtual void SelectedCells(nsTArray<nsAccessible*>* aCells) {}
|
||||
|
||||
/**
|
||||
* Get the set of selected column indices.
|
||||
*/
|
||||
virtual void SelectedColIndices(nsTArray<PRUint32>* aCols) {}
|
||||
|
||||
/**
|
||||
* Get the set of selected row indices.
|
||||
*/
|
||||
virtual void SelectedRowIndices(nsTArray<PRUint32>* aRows) {}
|
||||
|
||||
/**
|
||||
* Select the given column unselecting any other selected columns.
|
||||
*/
|
||||
virtual void SelectCol(PRUint32 aColIdx) {}
|
||||
|
||||
/**
|
||||
* Select the given row unselecting all other previously selected rows.
|
||||
*/
|
||||
virtual void SelectRow(PRUint32 aRowIdx) {}
|
||||
|
||||
/**
|
||||
* Unselect the given column leaving other selected columns selected.
|
||||
*/
|
||||
virtual void UnselectCol(PRUint32 aColIdx) {}
|
||||
|
||||
/**
|
||||
* Unselect the given row leaving other selected rows selected.
|
||||
*/
|
||||
virtual void UnselectRow(PRUint32 aRowIdx) {}
|
||||
|
||||
/**
|
||||
* Return true if the table is probably for layout.
|
||||
*/
|
||||
virtual bool IsProbablyLayoutTable() { return false; }
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -73,6 +73,8 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../generic \
|
||||
-I$(srcdir)/../xpcom \
|
||||
-I$(srcdir)/../../../layout/generic \
|
||||
-I$(srcdir)/../../../layout/xul/base/src \
|
||||
$(NULL)
|
||||
|
@ -436,7 +436,7 @@ nsHTMLTableHeaderCellAccessible::NativeRole()
|
||||
|
||||
nsHTMLTableAccessible::
|
||||
nsHTMLTableAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsAccessibleWrap(aContent, aDoc)
|
||||
nsAccessibleWrap(aContent, aDoc), xpcAccessibleTable(this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -446,6 +446,16 @@ nsHTMLTableAccessible::
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsHTMLTableAccessible, nsAccessible,
|
||||
nsHTMLTableAccessible, nsIAccessibleTable)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//nsAccessNode
|
||||
|
||||
void
|
||||
nsHTMLTableAccessible::Shutdown()
|
||||
{
|
||||
mTable = nsnull;
|
||||
nsAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLTableAccessible: nsAccessible implementation
|
||||
@ -511,9 +521,7 @@ nsHTMLTableAccessible::GetAttributesInternal(nsIPersistentProperties *aAttribute
|
||||
nsresult rv = nsAccessibleWrap::GetAttributesInternal(aAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool isProbablyForLayout;
|
||||
IsProbablyForLayout(&isProbablyForLayout);
|
||||
if (isProbablyForLayout) {
|
||||
if (IsProbablyLayoutTable()) {
|
||||
nsAutoString oldValueUnused;
|
||||
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
|
||||
NS_LITERAL_STRING("true"), oldValueUnused);
|
||||
@ -538,13 +546,11 @@ nsHTMLTableAccessible::RelationByType(PRUint32 aType)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLTableAccessible: nsIAccessibleTable implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTableAccessible::GetCaption(nsIAccessible **aCaption)
|
||||
nsAccessible*
|
||||
nsHTMLTableAccessible::Caption()
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCaption);
|
||||
|
||||
NS_IF_ADDREF(*aCaption = Caption());
|
||||
return NS_OK;
|
||||
nsAccessible* child = mChildren.SafeElementAt(0, nsnull);
|
||||
return child && child->Role() == roles::CAPTION ? child : nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1307,8 +1313,7 @@ nsHTMLTableAccessible::Description(nsString& aDescription)
|
||||
|
||||
#ifdef SHOW_LAYOUT_HEURISTIC
|
||||
if (aDescription.IsEmpty()) {
|
||||
bool isProbablyForLayout;
|
||||
IsProbablyForLayout(&isProbablyForLayout);
|
||||
bool isProbablyForLayout = IsProbablyLayoutTable();
|
||||
aDescription = mLayoutHeuristic;
|
||||
}
|
||||
#ifdef DEBUG_A11Y
|
||||
@ -1357,8 +1362,8 @@ nsHTMLTableAccessible::HasDescendant(const nsAString& aTagName,
|
||||
return !!foundItem;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
|
||||
bool
|
||||
nsHTMLTableAccessible::IsProbablyLayoutTable()
|
||||
{
|
||||
// Implement a heuristic to determine if table is most likely used for layout
|
||||
// XXX do we want to look for rowspan or colspan, especialy that span all but a couple cells
|
||||
@ -1370,18 +1375,16 @@ nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
|
||||
// Change to |#define SHOW_LAYOUT_HEURISTIC DEBUG| before final release
|
||||
#ifdef SHOW_LAYOUT_HEURISTIC
|
||||
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) \
|
||||
{ *aIsProbablyForLayout = isLayout; \
|
||||
mLayoutHeuristic = isLayout ? NS_LITERAL_STRING("layout table: ") : NS_LITERAL_STRING("data table: "); \
|
||||
mLayoutHeuristic += NS_LITERAL_STRING(heuristic); return NS_OK; }
|
||||
{ \
|
||||
mLayoutHeuristic = isLayout ? \
|
||||
NS_LITERAL_STRING("layout table: " heuristic) : \
|
||||
NS_LITERAL_STRING("data table: " heuristic); \
|
||||
return isLayout; \
|
||||
}
|
||||
#else
|
||||
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) { *aIsProbablyForLayout = isLayout; return NS_OK; }
|
||||
#define RETURN_LAYOUT_ANSWER(isLayout, heuristic) { return isLayout; }
|
||||
#endif
|
||||
|
||||
*aIsProbablyForLayout = false;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsDocAccessible* docAccessible = Document();
|
||||
if (docAccessible) {
|
||||
PRUint64 docState = docAccessible->State();
|
||||
|
@ -41,6 +41,8 @@
|
||||
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
#include "nsIAccessibleTable.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "xpcAccessibleTable.h"
|
||||
|
||||
class nsITableLayout;
|
||||
class nsITableCellLayout;
|
||||
@ -121,16 +123,28 @@ public:
|
||||
}
|
||||
|
||||
class nsHTMLTableAccessible : public nsAccessibleWrap,
|
||||
public nsIAccessibleTable
|
||||
public xpcAccessibleTable,
|
||||
public nsIAccessibleTable,
|
||||
public mozilla::a11y::TableAccessible
|
||||
{
|
||||
public:
|
||||
nsHTMLTableAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_TABLEACCESSIBLE_IMPL_CID)
|
||||
|
||||
// nsIAccessible Table
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
|
||||
// TableAccessible
|
||||
virtual nsAccessible* Caption();
|
||||
virtual bool IsProbablyLayoutTable();
|
||||
|
||||
// nsAccessNode
|
||||
virtual void Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
|
||||
virtual void Description(nsString& aDescription);
|
||||
virtual nsresult GetNameInternal(nsAString& aName);
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
@ -138,13 +152,6 @@ public:
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
virtual Relation RelationByType(PRUint32 aRelationType);
|
||||
|
||||
// TableAccessible
|
||||
inline nsAccessible* Caption() const
|
||||
{
|
||||
nsAccessible* child = mChildren.SafeElementAt(0, nsnull);
|
||||
return child && child->Role() == mozilla::a11y::roles::CAPTION ? child : nsnull;
|
||||
}
|
||||
|
||||
// nsHTMLTableAccessible
|
||||
|
||||
/**
|
||||
|
@ -132,7 +132,7 @@ nsHyperTextAccessible::NativeRole()
|
||||
return roles::FORM;
|
||||
|
||||
if (tag == nsGkAtoms::blockquote || tag == nsGkAtoms::div ||
|
||||
tag == nsGkAtoms::nav)
|
||||
tag == nsGkAtoms::section || tag == nsGkAtoms::nav)
|
||||
return roles::SECTION;
|
||||
|
||||
if (tag == nsGkAtoms::h1 || tag == nsGkAtoms::h2 ||
|
||||
@ -1239,6 +1239,9 @@ nsHyperTextAccessible::GetAttributesInternal(nsIPersistentProperties *aAttribute
|
||||
if (mContent->Tag() == nsGkAtoms::nav)
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
|
||||
NS_LITERAL_STRING("navigation"));
|
||||
else if (mContent->Tag() == nsGkAtoms::section)
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
|
||||
NS_LITERAL_STRING("region"));
|
||||
else if (mContent->Tag() == nsGkAtoms::footer)
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
|
||||
NS_LITERAL_STRING("contentinfo"));
|
||||
|
@ -114,7 +114,9 @@ include $(topsrcdir)/config/rules.mk
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../generic \
|
||||
-I$(srcdir)/../html \
|
||||
-I$(srcdir)/../xpcom \
|
||||
-I$(srcdir)/../xul \
|
||||
-I$(srcdir)/../../../content/base/src \
|
||||
-I$(srcdir)/../../../content/events/src \
|
||||
|
@ -50,6 +50,7 @@ LIBXUL_LIBRARY = 1
|
||||
CPPSRCS = \
|
||||
nsAccEvent.cpp \
|
||||
nsAccessibleRelation.cpp \
|
||||
xpcAccessibleTable.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
@ -59,4 +60,5 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../generic \
|
||||
$(NULL)
|
||||
|
34
accessible/src/xpcom/xpcAccessibleTable.cpp
Normal file
34
accessible/src/xpcom/xpcAccessibleTable.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 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/. */
|
||||
|
||||
#include "xpcAccessibleTable.h"
|
||||
|
||||
#include "nsAccessible.h"
|
||||
#include "TableAccessible.h"
|
||||
|
||||
nsresult
|
||||
xpcAccessibleTable::GetCaption(nsIAccessible** aCaption)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCaption);
|
||||
*aCaption = nsnull;
|
||||
if (!mTable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_IF_ADDREF(*aCaption = mTable->Caption());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
xpcAccessibleTable::IsProbablyForLayout(bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = false;
|
||||
if (!mTable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aResult = mTable->IsProbablyLayoutTable();
|
||||
return NS_OK;
|
||||
}
|
63
accessible/src/xpcom/xpcAccessibleTable.h
Normal file
63
accessible/src/xpcom/xpcAccessibleTable.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 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 MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
|
||||
#define MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIAccessible;
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
class TableAccessible;
|
||||
}
|
||||
}
|
||||
|
||||
class xpcAccessibleTable
|
||||
{
|
||||
public:
|
||||
xpcAccessibleTable(mozilla::a11y::TableAccessible* aTable) : mTable(aTable) { }
|
||||
|
||||
nsresult GetCaption(nsIAccessible** aCaption);
|
||||
nsresult IsProbablyForLayout(bool* aIsForLayout);
|
||||
|
||||
protected:
|
||||
mozilla::a11y::TableAccessible* mTable;
|
||||
};
|
||||
|
||||
#define NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE \
|
||||
NS_IMETHOD GetCaption(nsIAccessible** aCaption) \
|
||||
{ return xpcAccessibleTable::GetCaption(aCaption); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSummary(nsAString & aSummary); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnCount(PRInt32 *aColumnCount); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowCount(PRInt32 *aRowCount); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetCellAt(PRInt32 rowIndex, PRInt32 columnIndex, nsIAccessible * *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetCellIndexAt(PRInt32 rowIndex, PRInt32 columnIndex, PRInt32 *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowAndColumnIndicesAt(PRInt32 cellIndex, PRInt32 *rowIndex NS_OUTPARAM, PRInt32 *columnIndex NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnExtentAt(PRInt32 row, PRInt32 column, PRInt32 *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowExtentAt(PRInt32 row, PRInt32 column, PRInt32 *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnDescription(PRInt32 columnIndex, nsAString & _retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowDescription(PRInt32 rowIndex, nsAString & _retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD IsColumnSelected(PRInt32 columnIndex, bool *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD IsRowSelected(PRInt32 rowIndex, bool *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD IsCellSelected(PRInt32 rowIndex, PRInt32 columnIndex, bool *_retval NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellCount(PRUint32 *aSelectedCellCount); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnCount(PRUint32 *aSelectedColumnCount); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowCount(PRUint32 *aSelectedRowCount); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedCells(nsIArray * *aSelectedCells); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellIndices(PRUint32 *cellsArraySize NS_OUTPARAM, PRInt32 **cellsArray NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectRow(PRInt32 rowIndex); \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectColumn(PRInt32 columnIndex); \
|
||||
NS_SCRIPTABLE NS_IMETHOD UnselectColumn(PRInt32 columnIndex); \
|
||||
NS_IMETHOD UnselectRow(PRInt32 aRowIdx); \
|
||||
NS_IMETHOD IsProbablyForLayout(bool* aResult) \
|
||||
{ return xpcAccessibleTable::IsProbablyForLayout(aResult); } \
|
||||
|
||||
#endif // MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
|
@ -72,7 +72,9 @@ include $(topsrcdir)/config/rules.mk
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../generic \
|
||||
-I$(srcdir)/../html \
|
||||
-I$(srcdir)/../xpcom \
|
||||
-I$(srcdir)/../../../layout/generic \
|
||||
-I$(srcdir)/../../../layout/xul/base/src \
|
||||
$(NULL)
|
||||
|
@ -134,7 +134,7 @@ nsXULColumnItemAccessible::DoAction(PRUint8 aIndex)
|
||||
|
||||
nsXULListboxAccessible::
|
||||
nsXULListboxAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
XULSelectControlAccessible(aContent, aDoc)
|
||||
XULSelectControlAccessible(aContent, aDoc), xpcAccessibleTable(this)
|
||||
{
|
||||
nsIContent* parentContent = mContent->GetParent();
|
||||
if (parentContent) {
|
||||
@ -164,6 +164,16 @@ nsXULListboxAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//nsAccessNode
|
||||
|
||||
void
|
||||
nsXULListboxAccessible::Shutdown()
|
||||
{
|
||||
mTable = nsnull;
|
||||
XULSelectControlAccessible::Shutdown();
|
||||
}
|
||||
|
||||
bool
|
||||
nsXULListboxAccessible::IsMulticolumn()
|
||||
{
|
||||
@ -229,15 +239,6 @@ nsXULListboxAccessible::NativeRole()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULListboxAccessible. nsIAccessibleTable
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULListboxAccessible::GetCaption(nsIAccessible **aCaption)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCaption);
|
||||
*aCaption = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULListboxAccessible::GetSummary(nsAString &aSummary)
|
||||
{
|
||||
@ -820,15 +821,6 @@ nsXULListboxAccessible::UnselectColumn(PRInt32 aColumn)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULListboxAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
|
||||
*aIsProbablyForLayout = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULListboxAccessible: Widgets
|
||||
|
||||
|
@ -40,11 +40,12 @@
|
||||
#ifndef __nsXULListboxAccessible_h__
|
||||
#define __nsXULListboxAccessible_h__
|
||||
|
||||
#include "nsIAccessibleTable.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXULMenuAccessible.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsIAccessibleTable.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "xpcAccessibleTable.h"
|
||||
#include "XULSelectControlAccessible.h"
|
||||
|
||||
class nsIWeakReference;
|
||||
@ -90,19 +91,27 @@ public:
|
||||
* A class the represents the XUL Listbox widget.
|
||||
*/
|
||||
class nsXULListboxAccessible : public XULSelectControlAccessible,
|
||||
public nsIAccessibleTable
|
||||
public xpcAccessibleTable,
|
||||
public nsIAccessibleTable,
|
||||
public mozilla::a11y::TableAccessible
|
||||
{
|
||||
public:
|
||||
nsXULListboxAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
virtual ~nsXULListboxAccessible() {}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
|
||||
// nsIAccessibleTable
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
|
||||
// nsAccessNode
|
||||
virtual void Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
virtual PRUint64 NativeState();
|
||||
|
||||
|
@ -58,7 +58,7 @@ using namespace mozilla::a11y;
|
||||
|
||||
nsXULTreeGridAccessible::
|
||||
nsXULTreeGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsXULTreeAccessible(aContent, aDoc)
|
||||
nsXULTreeAccessible(aContent, aDoc), xpcAccessibleTable(this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -72,15 +72,6 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeGridAccessible,
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeGridAccessible: nsIAccessibleTable implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeGridAccessible::GetCaption(nsIAccessible **aCaption)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCaption);
|
||||
*aCaption = nsnull;
|
||||
|
||||
return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeGridAccessible::GetSummary(nsAString &aSummary)
|
||||
{
|
||||
@ -570,13 +561,14 @@ nsXULTreeGridAccessible::UnselectColumn(PRInt32 aColumnIndex)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeGridAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
|
||||
*aIsProbablyForLayout = false;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeGridAccessible: nsAccessNode implementation
|
||||
|
||||
return NS_OK;
|
||||
void
|
||||
nsXULTreeGridAccessible::Shutdown()
|
||||
{
|
||||
mTable = nsnull;
|
||||
nsXULTreeAccessible::Shutdown();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -39,15 +39,17 @@
|
||||
#ifndef __nsXULTreeGridAccessible_h__
|
||||
#define __nsXULTreeGridAccessible_h__
|
||||
|
||||
#include "nsIAccessibleTable.h"
|
||||
|
||||
#include "nsXULTreeAccessible.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "xpcAccessibleTable.h"
|
||||
|
||||
/**
|
||||
* Represents accessible for XUL tree in the case when it has multiple columns.
|
||||
*/
|
||||
class nsXULTreeGridAccessible : public nsXULTreeAccessible,
|
||||
public nsIAccessibleTable
|
||||
public xpcAccessibleTable,
|
||||
public nsIAccessibleTable,
|
||||
public mozilla::a11y::TableAccessible
|
||||
{
|
||||
public:
|
||||
nsXULTreeGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
@ -56,9 +58,13 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessibleTable
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
|
||||
// nsAccessNode
|
||||
virtual void Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
|
||||
protected:
|
||||
|
@ -24,6 +24,7 @@
|
||||
testRole("footer", ROLE_FOOTER);
|
||||
testRole("article", ROLE_DOCUMENT);
|
||||
testRole("aside", ROLE_NOTE);
|
||||
testRole("section", ROLE_SECTION); // XXX bug 739612: not a landmark
|
||||
|
||||
testRole("main", ROLE_DOCUMENT);
|
||||
testRole("form", ROLE_FORM);
|
||||
@ -32,6 +33,7 @@
|
||||
testAttrs("nav", {"xml-roles" : "navigation"}, true);
|
||||
testAttrs("footer", {"xml-roles" : "contentinfo"}, true);
|
||||
testAttrs("aside", {"xml-roles" : "complementary"}, true);
|
||||
testAttrs("section", {"xml-roles" : "region"}, true);
|
||||
testAttrs("main", {"xml-roles" : "main"}, true); // // ARIA override
|
||||
testAttrs("form", {"xml-roles" : "form"}, true);
|
||||
|
||||
@ -41,6 +43,7 @@
|
||||
testAttrs("footer", {"tag" : "footer"}, true);
|
||||
testAttrs("article", {"tag" : "article"}, true);
|
||||
testAttrs("aside", {"tag" : "aside"}, true);
|
||||
testAttrs("section", {"tag" : "section"}, true);
|
||||
testAttrs("main", {"tag" : "article"}, true);
|
||||
testAttrs("form", {"tag" : "article"}, true);
|
||||
|
||||
@ -68,6 +71,11 @@
|
||||
title="Change implementation of HTML5 landmark elements to conform">
|
||||
Bug 610650
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=614310"
|
||||
title="Map section to pane (like role=region)">
|
||||
Mozilla Bug 614310
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=734982"
|
||||
title="Map ARIA role FORM">
|
||||
@ -82,6 +90,7 @@
|
||||
<header id="header">a header</header>
|
||||
<footer id="footer">a footer</footer>
|
||||
<aside id="aside">by the way I am an aside</aside>
|
||||
<section id="section">a section</section>
|
||||
|
||||
<article id="article">an article</article>
|
||||
<article id="main" role="main">a main area</article>
|
||||
|
@ -53,6 +53,7 @@ const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
|
||||
const ROLE_PROPERTYPAGE = nsIAccessibleRole.ROLE_PROPERTYPAGE;
|
||||
const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
|
||||
const ROLE_RADIOBUTTON = nsIAccessibleRole.ROLE_RADIOBUTTON;
|
||||
const ROLE_RICH_OPTION = nsIAccessibleRole.ROLE_RICH_OPTION;
|
||||
const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
|
||||
const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER;
|
||||
const ROLE_SCROLLBAR = nsIAccessibleRole.ROLE_SCROLLBAR;
|
||||
|
@ -57,6 +57,7 @@ _TEST_FILES =\
|
||||
test_imagemap.html \
|
||||
test_list_editabledoc.html \
|
||||
test_list.html \
|
||||
test_listbox.xul \
|
||||
test_menu.xul \
|
||||
test_menubutton.xul \
|
||||
test_recreation.html \
|
||||
|
180
accessible/tests/mochitest/treeupdate/test_listbox.xul
Normal file
180
accessible/tests/mochitest/treeupdate/test_listbox.xul
Normal file
@ -0,0 +1,180 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL listbox hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function insertListitem(aListboxID)
|
||||
{
|
||||
this.listboxNode = getNode(aListboxID);
|
||||
|
||||
this.listitemNode = document.createElement("listitem");
|
||||
this.listitemNode.setAttribute("label", "item1");
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.listitemNode),
|
||||
new invokerChecker(EVENT_REORDER, this.listboxNode)
|
||||
];
|
||||
|
||||
this.invoke = function insertListitem_invoke()
|
||||
{
|
||||
this.listboxNode.insertBefore(this.listitemNode,
|
||||
this.listboxNode.firstChild);
|
||||
}
|
||||
|
||||
this.finalCheck = function insertListitem_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ LISTBOX: [
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item1"
|
||||
},
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item2"
|
||||
},
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item3"
|
||||
},
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item4"
|
||||
}
|
||||
] };
|
||||
testAccessibleTree(this.listboxNode, tree);
|
||||
}
|
||||
|
||||
this.getID = function insertListitem_getID()
|
||||
{
|
||||
return "insert listitem ";
|
||||
}
|
||||
}
|
||||
|
||||
function removeListitem(aListboxID)
|
||||
{
|
||||
this.listboxNode = getNode(aListboxID);
|
||||
this.listitemNode = null;
|
||||
this.listitem;
|
||||
|
||||
function getListitem(aThisObj)
|
||||
{
|
||||
return aThisObj.listitem;
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getListitem, this),
|
||||
new invokerChecker(EVENT_REORDER, this.listboxNode)
|
||||
];
|
||||
|
||||
this.invoke = function removeListitem_invoke()
|
||||
{
|
||||
this.listitemNode = this.listboxNode.firstChild;
|
||||
this.listitem = getAccessible(this.listitemNode);
|
||||
|
||||
this.listboxNode.removeChild(this.listitemNode);
|
||||
}
|
||||
|
||||
this.finalCheck = function removeListitem_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ LISTBOX: [
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item2"
|
||||
},
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item3"
|
||||
},
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item4"
|
||||
}
|
||||
] };
|
||||
testAccessibleTree(this.listboxNode, tree);
|
||||
}
|
||||
|
||||
this.getID = function removeListitem_getID()
|
||||
{
|
||||
return "remove listitem ";
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
var tree =
|
||||
{ LISTBOX: [
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item2"
|
||||
},
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item3"
|
||||
},
|
||||
{
|
||||
role: ROLE_RICH_OPTION,
|
||||
name: "item4"
|
||||
}
|
||||
] };
|
||||
testAccessibleTree("listbox", tree);
|
||||
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new insertListitem("listbox"));
|
||||
gQueue.push(new removeListitem("listbox"));
|
||||
gQueue.invoke(); // Will call SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=656225"
|
||||
title="XUL listbox accessible tree doesn't get updated">
|
||||
Mozilla Bug 656225
|
||||
</a>
|
||||
<br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<listbox id="listbox" rows="2">
|
||||
<listitem label="item2"/>
|
||||
<listitem label="item3"/>
|
||||
<listitem label="item4"/>
|
||||
</listbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
@ -69,3 +69,4 @@ fi
|
||||
|
||||
MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
MOZ_EXTENSION_MANAGER=1
|
||||
ENABLE_MARIONETTE=1
|
||||
|
@ -56,13 +56,14 @@ DIRS = \
|
||||
app \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
ifdef MAKENSISU
|
||||
DIRS += installer/windows
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
ifdef MAKENSISU
|
||||
|
||||
# For Windows build the uninstaller during the application build since the
|
||||
# uninstaller is included with the application for mar file generation.
|
||||
libs::
|
||||
|
@ -4413,7 +4413,6 @@ var FullScreen = {
|
||||
// and in tabs-on-bottom mode, move them back to the navigation toolbar.
|
||||
// When there is a chance the tab bar may be collapsed, put window
|
||||
// controls on nav bar.
|
||||
var fullscreenflex = document.getElementById("fullscreenflex");
|
||||
var fullscreenctls = document.getElementById("window-controls");
|
||||
var navbar = document.getElementById("nav-bar");
|
||||
var ctlsOnTabbar = window.toolbar.visible &&
|
||||
@ -4421,14 +4420,12 @@ var FullScreen = {
|
||||
(TabsOnTop.enabled &&
|
||||
!gPrefService.getBoolPref("browser.tabs.autoHide")));
|
||||
if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
|
||||
fullscreenctls.removeAttribute("flex");
|
||||
document.getElementById("TabsToolbar").appendChild(fullscreenctls);
|
||||
// we don't need this space in tabs-on-top mode, so prevent it from
|
||||
// being shown
|
||||
fullscreenflex.removeAttribute("fullscreencontrol");
|
||||
}
|
||||
else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
|
||||
fullscreenctls.setAttribute("flex", "1");
|
||||
navbar.appendChild(fullscreenctls);
|
||||
fullscreenflex.setAttribute("fullscreencontrol", "true");
|
||||
}
|
||||
|
||||
var controls = document.getElementsByAttribute("fullscreencontrol", "true");
|
||||
@ -8666,6 +8663,31 @@ let gPrivateBrowsingUI = {
|
||||
|
||||
get privateBrowsingEnabled() {
|
||||
return this._privateBrowsingService.privateBrowsingEnabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* These accessors are used to support per-window Private Browsing mode.
|
||||
* For now the getter returns nsIPrivateBrowsingService.privateBrowsingEnabled,
|
||||
* and the setter should only be used in tests.
|
||||
*/
|
||||
get privateWindow() {
|
||||
return window.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.treeOwner
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIXULWindow)
|
||||
.docShell.QueryInterface(Ci.nsILoadContext)
|
||||
.usePrivateBrowsing;
|
||||
},
|
||||
|
||||
set privateWindow(val) {
|
||||
return window.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.treeOwner
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIXULWindow)
|
||||
.docShell.QueryInterface(Ci.nsILoadContext)
|
||||
.usePrivateBrowsing = val;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -475,7 +475,7 @@
|
||||
toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
|
||||
fullscreentoolbar="true" mode="icons" customizable="true"
|
||||
iconsize="large"
|
||||
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,fullscreenflex,window-controls"
|
||||
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,window-controls"
|
||||
context="toolbar-context-menu">
|
||||
|
||||
<toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"
|
||||
@ -697,8 +697,7 @@
|
||||
</toolbarbutton>
|
||||
</toolbaritem>
|
||||
|
||||
<hbox id="fullscreenflex" flex="1" hidden="true" fullscreencontrol="true"/>
|
||||
<hbox id="window-controls" hidden="true" fullscreencontrol="true">
|
||||
<hbox id="window-controls" hidden="true" fullscreencontrol="true" pack="end">
|
||||
<toolbarbutton id="minimize-button"
|
||||
tooltiptext="&fullScreenMinimize.tooltip;"
|
||||
oncommand="window.minimize();"/>
|
||||
|
@ -44,9 +44,8 @@ let gDrop = {
|
||||
* Handles the 'drop' event.
|
||||
* @param aCell The drop target cell.
|
||||
* @param aEvent The 'dragexit' event.
|
||||
* @param aCallback The callback to call when the drop is finished.
|
||||
*/
|
||||
drop: function Drop_drop(aCell, aEvent, aCallback) {
|
||||
drop: function Drop_drop(aCell, aEvent) {
|
||||
// The cell that is the drop target could contain a pinned site. We need
|
||||
// to find out where that site has gone and re-pin it there.
|
||||
if (aCell.containsPinnedSite())
|
||||
@ -58,7 +57,7 @@ let gDrop = {
|
||||
this._cancelDelayedArrange();
|
||||
|
||||
// Update the grid and move all sites to their new places.
|
||||
gUpdater.updateGrid(aCallback);
|
||||
gUpdater.updateGrid();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -61,13 +61,12 @@ Site.prototype = {
|
||||
|
||||
/**
|
||||
* Unpins the site and calls the given callback when done.
|
||||
* @param aCallback The callback to be called when finished.
|
||||
*/
|
||||
unpin: function Site_unpin(aCallback) {
|
||||
unpin: function Site_unpin() {
|
||||
if (this.isPinned()) {
|
||||
this._updateAttributes(false);
|
||||
gPinnedLinks.unpin(this._link);
|
||||
gUpdater.updateGrid(aCallback);
|
||||
gUpdater.updateGrid();
|
||||
}
|
||||
},
|
||||
|
||||
@ -82,15 +81,14 @@ Site.prototype = {
|
||||
/**
|
||||
* Blocks the site (removes it from the grid) and calls the given callback
|
||||
* when done.
|
||||
* @param aCallback The function to be called when finished.
|
||||
*/
|
||||
block: function Site_block(aCallback) {
|
||||
block: function Site_block() {
|
||||
if (gBlockedLinks.isBlocked(this._link)) {
|
||||
if (aCallback)
|
||||
aCallback();
|
||||
} else {
|
||||
gBlockedLinks.block(this._link);
|
||||
gUpdater.updateGrid(aCallback);
|
||||
gUpdater.updateGrid();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -15,13 +15,13 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
yield blockCell(cells[4]);
|
||||
yield blockCell(4);
|
||||
checkGrid("0,1,2,3,5,6,7,8,9");
|
||||
|
||||
yield blockCell(cells[4]);
|
||||
yield blockCell(4);
|
||||
checkGrid("0,1,2,3,6,7,8,9,");
|
||||
|
||||
yield blockCell(cells[4]);
|
||||
yield blockCell(4);
|
||||
checkGrid("0,1,2,3,7,8,9,,");
|
||||
|
||||
// we removed a pinned site
|
||||
@ -32,7 +32,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1p,2,3,4,5,6,7,8");
|
||||
|
||||
yield blockCell(cells[1]);
|
||||
yield blockCell(1);
|
||||
checkGrid("0,2,3,4,5,6,7,8,");
|
||||
|
||||
// we remove the last site on the grid (which is pinned) and expect the gap
|
||||
@ -44,7 +44,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8p");
|
||||
|
||||
yield blockCell(cells[8]);
|
||||
yield blockCell(8);
|
||||
checkGrid("0,1,2,3,4,5,6,7,9");
|
||||
|
||||
// we remove the first site on the grid with the last one pinned. all cells
|
||||
@ -56,6 +56,6 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8p");
|
||||
|
||||
yield blockCell(cells[0]);
|
||||
yield blockCell(0);
|
||||
checkGrid("1,2,3,4,5,6,7,9,8p");
|
||||
}
|
||||
|
@ -20,21 +20,12 @@ function runTests() {
|
||||
fillHistory();
|
||||
yield addNewTabPageTab();
|
||||
|
||||
is(cells[0].site.url, URL, "first site is our fake site");
|
||||
is(getCell(0).site.url, URL, "first site is our fake site");
|
||||
|
||||
let page = {
|
||||
update: function () {
|
||||
executeSoon(TestRunner.next);
|
||||
},
|
||||
|
||||
observe: function () {}
|
||||
};
|
||||
|
||||
NewTabUtils.allPages.register(page);
|
||||
whenPagesUpdated();
|
||||
yield clearHistory();
|
||||
|
||||
NewTabUtils.allPages.unregister(page);
|
||||
ok(!cells[0].site, "the fake site is gone");
|
||||
ok(!getCell(0).site, "the fake site is gone");
|
||||
}
|
||||
|
||||
function fillHistory() {
|
||||
|
@ -14,5 +14,5 @@ function runTests() {
|
||||
|
||||
ok(NewTabUtils.allPages.enabled, true, "page is enabled");
|
||||
NewTabUtils.allPages.enabled = false;
|
||||
ok(cw.gGrid.node.hasAttribute("page-disabled"), "page is disabled");
|
||||
ok(getGrid().node.hasAttribute("page-disabled"), "page is disabled");
|
||||
}
|
||||
|
@ -8,41 +8,23 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGridLocked(false, "grid is unlocked");
|
||||
|
||||
let cell = cells[0].node;
|
||||
let site = cells[0].site.node;
|
||||
let cell = getCell(0).node;
|
||||
let site = getCell(0).site.node;
|
||||
let link = site.querySelector(".newtab-link");
|
||||
|
||||
sendDragEvent(link, "dragstart");
|
||||
sendDragEvent("dragstart", link);
|
||||
checkGridLocked(true, "grid is now locked");
|
||||
|
||||
sendDragEvent(link, "dragend");
|
||||
sendDragEvent("dragend", link);
|
||||
checkGridLocked(false, "grid isn't locked anymore");
|
||||
|
||||
sendDragEvent(cell, "dragstart");
|
||||
sendDragEvent("dragstart", cell);
|
||||
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
|
||||
|
||||
sendDragEvent(site, "dragstart");
|
||||
sendDragEvent("dragstart", site);
|
||||
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
|
||||
}
|
||||
|
||||
function checkGridLocked(aLocked, aMessage) {
|
||||
is(cw.gGrid.node.hasAttribute("locked"), aLocked, aMessage);
|
||||
}
|
||||
|
||||
function sendDragEvent(aNode, aType) {
|
||||
let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let dataTransfer = {
|
||||
mozUserCancelled: false,
|
||||
setData: function () null,
|
||||
setDragImage: function () null,
|
||||
getData: function () "about:blank"
|
||||
};
|
||||
|
||||
let event = cw.document.createEvent("DragEvents");
|
||||
event.initDragEvent(aType, true, true, cw, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
|
||||
windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
|
||||
is(getGrid().node.hasAttribute("locked"), aLocked, aMessage);
|
||||
}
|
||||
|
@ -8,45 +8,16 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
let cell = cells[0].node;
|
||||
let cell = getCell(0).node;
|
||||
|
||||
sendDropEvent(cell, "about:blank#99\nblank");
|
||||
sendDragEvent("drop", cell, "about:blank#99\nblank");
|
||||
is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
|
||||
"first cell is pinned and contains the dropped site");
|
||||
|
||||
yield whenPagesUpdated();
|
||||
checkGrid("99p,0,1,2,3,4,5,6,7");
|
||||
|
||||
sendDropEvent(cell, "");
|
||||
sendDragEvent("drop", cell, "");
|
||||
is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
|
||||
"first cell is still pinned with the site we dropped before");
|
||||
}
|
||||
|
||||
function sendDropEvent(aNode, aData) {
|
||||
let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let dataTransfer = {
|
||||
mozUserCancelled: false,
|
||||
setData: function () null,
|
||||
setDragImage: function () null,
|
||||
getData: function () aData,
|
||||
|
||||
types: {
|
||||
contains: function (aType) aType == "text/x-moz-url"
|
||||
},
|
||||
|
||||
mozGetDataAt: function (aType, aIndex) {
|
||||
if (aIndex || aType != "text/x-moz-url")
|
||||
return null;
|
||||
|
||||
return aData;
|
||||
},
|
||||
};
|
||||
|
||||
let event = cw.document.createEvent("DragEvents");
|
||||
event.initDragEvent("drop", true, true, cw, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
|
||||
windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
|
||||
}
|
||||
|
@ -9,12 +9,13 @@ function runTests() {
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
let receivedError = false;
|
||||
let block = cw.document.querySelector(".newtab-control-block");
|
||||
let block = getContentDocument().querySelector(".newtab-control-block");
|
||||
|
||||
function onError() {
|
||||
receivedError = true;
|
||||
}
|
||||
|
||||
let cw = getContentWindow();
|
||||
cw.addEventListener("error", onError);
|
||||
|
||||
for (let i = 0; i < 3; i++)
|
||||
|
@ -8,15 +8,15 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
yield simulateDrop(cells[1]);
|
||||
yield simulateDrop(1);
|
||||
checkGrid("0,99p,1,2,3,4,5,6,7");
|
||||
|
||||
yield blockCell(cells[1]);
|
||||
yield blockCell(1);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
yield simulateDrop(cells[1]);
|
||||
yield simulateDrop(1);
|
||||
checkGrid("0,99p,1,2,3,4,5,6,7");
|
||||
|
||||
yield blockCell(cells[1]);
|
||||
yield blockCell(1);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
}
|
||||
|
@ -11,14 +11,14 @@ function runTests() {
|
||||
setPinnedLinks("");
|
||||
|
||||
yield addNewTabPageTab();
|
||||
let gridNode = cw.gGrid.node;
|
||||
let gridNode = getGrid().node;
|
||||
|
||||
ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");
|
||||
|
||||
NewTabUtils.allPages.enabled = false;
|
||||
ok(gridNode.hasAttribute("page-disabled"), "page is disabled");
|
||||
|
||||
let oldGridNode = cw.gGrid.node;
|
||||
let oldGridNode = gridNode;
|
||||
|
||||
// create a second new tage page and make sure it's disabled. enable it
|
||||
// again and check if the former page gets enabled as well.
|
||||
@ -26,7 +26,7 @@ function runTests() {
|
||||
ok(gridNode.hasAttribute("page-disabled"), "page is disabled");
|
||||
|
||||
// check that no sites have been rendered
|
||||
is(0, cw.document.querySelectorAll(".site").length, "no sites have been rendered");
|
||||
is(0, getContentDocument().querySelectorAll(".site").length, "no sites have been rendered");
|
||||
|
||||
NewTabUtils.allPages.enabled = true;
|
||||
ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");
|
||||
|
@ -15,7 +15,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
yield simulateDrop(cells[1], cells[0]);
|
||||
yield simulateDrop(1, 0);
|
||||
checkGrid("1,0p,2,3,4,5,6,7,8");
|
||||
|
||||
// drag a cell to its current cell and make sure it's not pinned afterwards
|
||||
@ -25,7 +25,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
yield simulateDrop(cells[0], cells[0]);
|
||||
yield simulateDrop(0, 0);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
// ensure that pinned pages aren't moved if that's not necessary
|
||||
@ -35,7 +35,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1p,2p,3,4,5,6,7,8");
|
||||
|
||||
yield simulateDrop(cells[3], cells[0]);
|
||||
yield simulateDrop(3, 0);
|
||||
checkGrid("3,1p,2p,0p,4,5,6,7,8");
|
||||
|
||||
// pinned sites should always be moved around as blocks. if a pinned site is
|
||||
@ -46,7 +46,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0p,1p,2,3,4,5,6,7,8");
|
||||
|
||||
yield simulateDrop(cells[0], cells[2]);
|
||||
yield simulateDrop(0, 2);
|
||||
checkGrid("2p,0p,1p,3,4,5,6,7,8");
|
||||
|
||||
// pinned sites should not be pushed out of the grid (unless there are only
|
||||
@ -57,7 +57,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7p,8p");
|
||||
|
||||
yield simulateDrop(cells[8], cells[2]);
|
||||
yield simulateDrop(8, 2);
|
||||
checkGrid("0,1,3,4,5,6,7p,8p,2p");
|
||||
|
||||
// make sure that pinned sites are re-positioned correctly
|
||||
@ -67,7 +67,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0p,1p,2p,3,4,5p,6,7,8");
|
||||
|
||||
yield simulateDrop(cells[4], cells[0]);
|
||||
yield simulateDrop(4, 0);
|
||||
checkGrid("3,1p,2p,4,0p,5p,6,7,8");
|
||||
|
||||
// drag a new site onto the very first cell
|
||||
@ -77,7 +77,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7p,8p");
|
||||
|
||||
yield simulateDrop(cells[0]);
|
||||
yield simulateDrop(0);
|
||||
checkGrid("99p,0,1,2,3,4,5,7p,8p");
|
||||
|
||||
// drag a new site onto the grid and make sure that pinned cells don't get
|
||||
@ -88,7 +88,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7p,8p");
|
||||
|
||||
yield simulateDrop(cells[7]);
|
||||
yield simulateDrop(7);
|
||||
checkGrid("0,1,2,3,4,5,7p,99p,8p");
|
||||
|
||||
// drag a new site beneath a pinned cell and make sure the pinned cell is
|
||||
@ -99,7 +99,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1,2,3,4,5,6,7,8p");
|
||||
|
||||
yield simulateDrop(cells[7]);
|
||||
yield simulateDrop(7);
|
||||
checkGrid("0,1,2,3,4,5,6,99p,8p");
|
||||
|
||||
// drag a new site onto a block of pinned sites and make sure they're shifted
|
||||
@ -110,6 +110,6 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0p,1p,2p");
|
||||
|
||||
yield simulateDrop(cells[1]);
|
||||
yield simulateDrop(1);
|
||||
checkGrid("0p,99p,1p,2p,3,4,5,6,7");
|
||||
}
|
||||
|
@ -13,8 +13,9 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0p,1p,2p,3,4,5p,6,7,8");
|
||||
|
||||
cw.gDrag._draggedSite = cells[0].site;
|
||||
let sites = cw.gDropPreview.rearrange(cells[4]);
|
||||
let cw = getContentWindow();
|
||||
cw.gDrag._draggedSite = getCell(0).site;
|
||||
let sites = cw.gDropPreview.rearrange(getCell(4));
|
||||
cw.gDrag._draggedSite = null;
|
||||
|
||||
checkGrid("3,1p,2p,4,0p,5p,6,7,8", sites);
|
||||
|
@ -16,7 +16,7 @@ function runTests() {
|
||||
ok(!pb.privateBrowsingEnabled, "private browsing is disabled");
|
||||
|
||||
yield addNewTabPageTab();
|
||||
pinCell(cells[0]);
|
||||
pinCell(0);
|
||||
checkGrid("0p,1,2,3,4,5,6,7,8");
|
||||
|
||||
// enter private browsing mode
|
||||
@ -27,10 +27,10 @@ function runTests() {
|
||||
checkGrid("0p,1,2,3,4,5,6,7,8");
|
||||
|
||||
// modify the grid while we're in pb mode
|
||||
yield blockCell(cells[1]);
|
||||
yield blockCell(1);
|
||||
checkGrid("0p,2,3,4,5,6,7,8");
|
||||
|
||||
yield unpinCell(cells[0]);
|
||||
yield unpinCell(0);
|
||||
checkGrid("0,2,3,4,5,6,7,8");
|
||||
|
||||
// exit private browsing mode
|
||||
|
@ -13,16 +13,16 @@ function runTests() {
|
||||
setPinnedLinks("");
|
||||
|
||||
yield addNewTabPageTab();
|
||||
let resetButton = cw.document.getElementById("toolbar-button-reset");
|
||||
let resetButton = getContentDocument().getElementById("toolbar-button-reset");
|
||||
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
ok(!resetButton.hasAttribute("modified"), "page is not modified");
|
||||
|
||||
yield blockCell(cells[4]);
|
||||
yield blockCell(4);
|
||||
checkGrid("0,1,2,3,5,6,7,8,");
|
||||
ok(resetButton.hasAttribute("modified"), "page is modified");
|
||||
|
||||
yield cw.gToolbar.reset(TestRunner.next);
|
||||
yield getContentWindow().gToolbar.reset(TestRunner.next);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
ok(!resetButton.hasAttribute("modified"), "page is not modified");
|
||||
}
|
||||
|
@ -17,45 +17,45 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1p,2,3,4,5,6,7,8");
|
||||
|
||||
let resetButton = cw.document.getElementById("toolbar-button-reset");
|
||||
let resetButton = getContentDocument().getElementById("toolbar-button-reset");
|
||||
ok(!resetButton.hasAttribute("modified"), "page is not modified");
|
||||
|
||||
let oldCw = cw;
|
||||
let oldSites = getGrid().sites;
|
||||
let oldResetButton = resetButton;
|
||||
|
||||
// create the new tab page
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1p,2,3,4,5,6,7,8");
|
||||
|
||||
resetButton = cw.document.getElementById("toolbar-button-reset");
|
||||
resetButton = getContentDocument().getElementById("toolbar-button-reset");
|
||||
ok(!resetButton.hasAttribute("modified"), "page is not modified");
|
||||
|
||||
// unpin a cell
|
||||
yield unpinCell(cells[1]);
|
||||
yield unpinCell(1);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
checkGrid("0,1,2,3,4,5,6,7,8", oldCw.gGrid.sites);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8", oldSites);
|
||||
|
||||
// remove a cell
|
||||
yield blockCell(cells[1]);
|
||||
yield blockCell(1);
|
||||
checkGrid("0,2,3,4,5,6,7,8,9");
|
||||
checkGrid("0,2,3,4,5,6,7,8,9", oldCw.gGrid.sites);
|
||||
checkGrid("0,2,3,4,5,6,7,8,9", oldSites);
|
||||
ok(resetButton.hasAttribute("modified"), "page is modified");
|
||||
ok(oldResetButton.hasAttribute("modified"), "page is modified");
|
||||
|
||||
// insert a new cell by dragging
|
||||
yield simulateDrop(cells[1]);
|
||||
yield simulateDrop(1);
|
||||
checkGrid("0,99p,2,3,4,5,6,7,8");
|
||||
checkGrid("0,99p,2,3,4,5,6,7,8", oldCw.gGrid.sites);
|
||||
checkGrid("0,99p,2,3,4,5,6,7,8", oldSites);
|
||||
|
||||
// drag a cell around
|
||||
yield simulateDrop(cells[1], cells[2]);
|
||||
yield simulateDrop(1, 2);
|
||||
checkGrid("0,2p,99p,3,4,5,6,7,8");
|
||||
checkGrid("0,2p,99p,3,4,5,6,7,8", oldCw.gGrid.sites);
|
||||
checkGrid("0,2p,99p,3,4,5,6,7,8", oldSites);
|
||||
|
||||
// reset the new tab page
|
||||
yield cw.gToolbar.reset(TestRunner.next);
|
||||
yield getContentWindow().gToolbar.reset(TestRunner.next);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
checkGrid("0,1,2,3,4,5,6,7,8", oldCw.gGrid.sites);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8", oldSites);
|
||||
ok(!resetButton.hasAttribute("modified"), "page is not modified");
|
||||
ok(!oldResetButton.hasAttribute("modified"), "page is not modified");
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,1p,2,3,4,5,6,7,8");
|
||||
|
||||
yield unpinCell(cells[1]);
|
||||
yield unpinCell(1);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
// we have a pinned link that is not anymore in the list of the most-visited
|
||||
@ -26,7 +26,7 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("0,99p,1,2,3,4,5,6,7");
|
||||
|
||||
yield unpinCell(cells[1]);
|
||||
yield unpinCell(1);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
|
||||
// we have a pinned link that changed its position since it was pinned. it
|
||||
@ -37,10 +37,10 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("2,1p,3,4,5,6,7,,0p");
|
||||
|
||||
yield unpinCell(cells[1]);
|
||||
yield unpinCell(1);
|
||||
checkGrid("1,2,3,4,5,6,7,,0p");
|
||||
|
||||
yield unpinCell(cells[8]);
|
||||
yield unpinCell(8);
|
||||
checkGrid("0,1,2,3,4,5,6,7,");
|
||||
|
||||
// we have pinned link that changed its position since it was pinned. the
|
||||
@ -51,6 +51,6 @@ function runTests() {
|
||||
yield addNewTabPageTab();
|
||||
checkGrid("9p,0,1,2,3,4,5,6,7");
|
||||
|
||||
yield unpinCell(cells[0]);
|
||||
yield unpinCell(0);
|
||||
checkGrid("0,1,2,3,4,5,6,7,8");
|
||||
}
|
||||
|
@ -16,12 +16,6 @@ registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
|
||||
});
|
||||
|
||||
/**
|
||||
* Global variables that are accessed by tests.
|
||||
*/
|
||||
let cw;
|
||||
let cells;
|
||||
|
||||
/**
|
||||
* We'll want to restore the original links provider later.
|
||||
*/
|
||||
@ -81,6 +75,39 @@ let TestRunner = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the selected tab's content window.
|
||||
* @return The content window.
|
||||
*/
|
||||
function getContentWindow() {
|
||||
return gBrowser.selectedBrowser.contentWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected tab's content document.
|
||||
* @return The content document.
|
||||
*/
|
||||
function getContentDocument() {
|
||||
return gBrowser.selectedBrowser.contentDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the newtab grid of the selected tab.
|
||||
* @return The newtab grid.
|
||||
*/
|
||||
function getGrid() {
|
||||
return getContentWindow().gGrid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cell at the given index of the selected tab's newtab grid.
|
||||
* @param aIndex The cell index.
|
||||
* @return The newtab cell.
|
||||
*/
|
||||
function getCell(aIndex) {
|
||||
return getGrid().cells[aIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to provide a list of links that is used to construct the grid.
|
||||
* @param aLinksPattern the pattern (see below)
|
||||
@ -143,18 +170,14 @@ function addNewTabPageTab() {
|
||||
browser.addEventListener("load", function onLoad() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
|
||||
cw = browser.contentWindow;
|
||||
|
||||
if (NewTabUtils.allPages.enabled) {
|
||||
// Continue when the link cache has been populated.
|
||||
NewTabUtils.links.populateCache(function () {
|
||||
cells = cw.gGrid.cells;
|
||||
executeSoon(TestRunner.next);
|
||||
});
|
||||
} else {
|
||||
TestRunner.next();
|
||||
}
|
||||
|
||||
}, true);
|
||||
}
|
||||
|
||||
@ -169,118 +192,118 @@ function addNewTabPageTab() {
|
||||
* The fourth cell contains the pinned site 'about:blank#4'.
|
||||
*/
|
||||
function checkGrid(aSitesPattern, aSites) {
|
||||
let valid = true;
|
||||
let length = aSitesPattern.split(",").length;
|
||||
let sites = (aSites || getGrid().sites).slice(0, length);
|
||||
let expected = sites.map(function (aSite) {
|
||||
if (!aSite)
|
||||
return "";
|
||||
|
||||
aSites = aSites || cw.gGrid.sites;
|
||||
let pinned = aSite.isPinned();
|
||||
let pinButton = aSite.node.querySelector(".newtab-control-pin");
|
||||
let hasPinnedAttr = pinButton.hasAttribute("pinned");
|
||||
|
||||
aSitesPattern.split(/\s*,\s*/).forEach(function (id, index) {
|
||||
let site = aSites[index];
|
||||
let match = id.match(/^\d+/);
|
||||
if (pinned != hasPinnedAttr)
|
||||
ok(false, "invalid state (site.isPinned() != site[pinned])");
|
||||
|
||||
// We expect the cell to be empty.
|
||||
if (!match) {
|
||||
if (site) {
|
||||
valid = false;
|
||||
ok(false, "expected cell#" + index + " to be empty");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We expect the cell to contain a site.
|
||||
if (!site) {
|
||||
valid = false;
|
||||
ok(false, "didn't expect cell#" + index + " to be empty");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let num = match[0];
|
||||
|
||||
// Check the site's url.
|
||||
if (site.url != "about:blank#" + num) {
|
||||
valid = false;
|
||||
is(site.url, "about:blank#" + num, "cell#" + index + " has the wrong url");
|
||||
}
|
||||
|
||||
let shouldBePinned = /p$/.test(id);
|
||||
let cellContainsPinned = site.isPinned();
|
||||
let cssClassPinned = site.node && site.node.querySelector(".newtab-control-pin").hasAttribute("pinned");
|
||||
|
||||
// Check if the site should be and is pinned.
|
||||
if (shouldBePinned) {
|
||||
if (!cellContainsPinned) {
|
||||
valid = false;
|
||||
ok(false, "expected cell#" + index + " to be pinned");
|
||||
} else if (!cssClassPinned) {
|
||||
valid = false;
|
||||
ok(false, "expected cell#" + index + " to have css class 'pinned'");
|
||||
}
|
||||
} else {
|
||||
if (cellContainsPinned) {
|
||||
valid = false;
|
||||
ok(false, "didn't expect cell#" + index + " to be pinned");
|
||||
} else if (cssClassPinned) {
|
||||
valid = false;
|
||||
ok(false, "didn't expect cell#" + index + " to have css class 'pinned'");
|
||||
}
|
||||
}
|
||||
return aSite.url.replace(/^about:blank#(\d+)$/, "$1") + (pinned ? "p" : "");
|
||||
});
|
||||
|
||||
// If every test passed, say so.
|
||||
if (valid)
|
||||
ok(true, "grid status = " + aSitesPattern);
|
||||
is(aSitesPattern, expected, "grid status = " + aSitesPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks the given cell's site from the grid.
|
||||
* @param aCell the cell that contains the site to block
|
||||
* Blocks a site from the grid.
|
||||
* @param aIndex The cell index.
|
||||
*/
|
||||
function blockCell(aCell) {
|
||||
aCell.site.block(function () executeSoon(TestRunner.next));
|
||||
function blockCell(aIndex) {
|
||||
whenPagesUpdated();
|
||||
getCell(aIndex).site.block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pins a given cell's site on a given position.
|
||||
* @param aCell the cell that contains the site to pin
|
||||
* @param aIndex the index the defines where the site should be pinned
|
||||
* Pins a site on a given position.
|
||||
* @param aIndex The cell index.
|
||||
* @param aPinIndex The index the defines where the site should be pinned.
|
||||
*/
|
||||
function pinCell(aCell, aIndex) {
|
||||
aCell.site.pin(aIndex);
|
||||
function pinCell(aIndex, aPinIndex) {
|
||||
getCell(aIndex).site.pin(aPinIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpins the given cell's site.
|
||||
* @param aCell the cell that contains the site to unpin
|
||||
* @param aIndex The cell index.
|
||||
*/
|
||||
function unpinCell(aCell) {
|
||||
aCell.site.unpin(function () executeSoon(TestRunner.next));
|
||||
function unpinCell(aIndex) {
|
||||
whenPagesUpdated();
|
||||
getCell(aIndex).site.unpin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates a drop and drop operation.
|
||||
* @param aDropTarget the cell that is the drop target
|
||||
* @param aDragSource the cell that contains the dragged site (optional)
|
||||
* @param aDropIndex The cell index of the drop target.
|
||||
* @param aDragIndex The cell index containing the dragged site (optional).
|
||||
*/
|
||||
function simulateDrop(aDropTarget, aDragSource) {
|
||||
let event = {
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
dataTransfer: {
|
||||
mozUserCancelled: false,
|
||||
setData: function () null,
|
||||
setDragImage: function () null,
|
||||
getData: function () "about:blank#99\nblank"
|
||||
function simulateDrop(aDropIndex, aDragIndex) {
|
||||
let draggedSite;
|
||||
let {gDrag: drag, gDrop: drop} = getContentWindow();
|
||||
let event = createDragEvent("drop", "about:blank#99\nblank");
|
||||
|
||||
if (typeof aDragIndex != "undefined")
|
||||
draggedSite = getCell(aDragIndex).site;
|
||||
|
||||
if (draggedSite)
|
||||
drag.start(draggedSite, event);
|
||||
|
||||
whenPagesUpdated();
|
||||
drop.drop(getCell(aDropIndex), event);
|
||||
|
||||
if (draggedSite)
|
||||
drag.end(draggedSite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a custom drag event to a given DOM element.
|
||||
* @param aEventType The drag event's type.
|
||||
* @param aTarget The DOM element that the event is dispatched to.
|
||||
* @param aData The event's drag data (optional).
|
||||
*/
|
||||
function sendDragEvent(aEventType, aTarget, aData) {
|
||||
let event = createDragEvent(aEventType, aData);
|
||||
let ifaceReq = getContentWindow().QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
|
||||
windowUtils.dispatchDOMEventViaPresShell(aTarget, event, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a custom drag event.
|
||||
* @param aEventType The drag event's type.
|
||||
* @param aData The event's drag data (optional).
|
||||
* @return The drag event.
|
||||
*/
|
||||
function createDragEvent(aEventType, aData) {
|
||||
let dataTransfer = {
|
||||
mozUserCancelled: false,
|
||||
setData: function () null,
|
||||
setDragImage: function () null,
|
||||
getData: function () aData,
|
||||
|
||||
types: {
|
||||
contains: function (aType) aType == "text/x-moz-url"
|
||||
},
|
||||
|
||||
mozGetDataAt: function (aType, aIndex) {
|
||||
if (aIndex || aType != "text/x-moz-url")
|
||||
return null;
|
||||
|
||||
return aData;
|
||||
}
|
||||
};
|
||||
|
||||
if (aDragSource)
|
||||
cw.gDrag.start(aDragSource.site, event);
|
||||
let event = getContentDocument().createEvent("DragEvents");
|
||||
event.initDragEvent(aEventType, true, true, getContentWindow(), 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
|
||||
cw.gDrop.drop(aDropTarget, event, function () executeSoon(TestRunner.next));
|
||||
|
||||
if (aDragSource)
|
||||
cw.gDrag.end(aDragSource.site);
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,10 +54,6 @@
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
|
||||
#define MIGRATION_BUNDLE "chrome://browser/locale/migration/migration.properties"
|
||||
|
||||
#define DEFAULT_BOOKMARKS NS_LITERAL_CSTRING("resource:///defaults/profile/bookmarks.html")
|
||||
|
||||
void SetUnicharPref(const char* aPref, const nsAString& aValue,
|
||||
nsIPrefBranch* aPrefs)
|
||||
{
|
||||
|
@ -747,10 +747,6 @@ nsDefaultCommandLineHandler.prototype = {
|
||||
return this;
|
||||
},
|
||||
|
||||
// List of uri's that were passed via the command line without the app
|
||||
// running and have already been handled. This is compared against uri's
|
||||
// opened using DDE on Win32 so we only open one of the requests.
|
||||
_handledURIs: [ ],
|
||||
#ifdef XP_WIN
|
||||
_haveProfile: false,
|
||||
#endif
|
||||
@ -784,25 +780,8 @@ nsDefaultCommandLineHandler.prototype = {
|
||||
try {
|
||||
var ar;
|
||||
while ((ar = cmdLine.handleFlagWithParam("url", false))) {
|
||||
var found = false;
|
||||
var uri = resolveURIInternal(cmdLine, ar);
|
||||
// count will never be greater than zero except on Win32.
|
||||
var count = this._handledURIs.length;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
if (this._handledURIs[i].spec == uri.spec) {
|
||||
this._handledURIs.splice(i, 1);
|
||||
found = true;
|
||||
cmdLine.preventDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
urilist.push(uri);
|
||||
// The requestpending command line flag is only used on Win32.
|
||||
if (cmdLine.handleFlag("requestpending", false) &&
|
||||
cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
|
||||
this._handledURIs.push(uri)
|
||||
}
|
||||
urilist.push(uri);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -1243,13 +1243,7 @@ BrowserGlue.prototype = {
|
||||
// Need to migrate only if toolbar is customized and the element is not found.
|
||||
if (currentset &&
|
||||
currentset.indexOf("bookmarks-menu-button-container") == -1) {
|
||||
if (currentset.indexOf("fullscreenflex") != -1) {
|
||||
currentset = currentset.replace(/(^|,)fullscreenflex($|,)/,
|
||||
"$1bookmarks-menu-button-container,fullscreenflex$2")
|
||||
}
|
||||
else {
|
||||
currentset += ",bookmarks-menu-button-container";
|
||||
}
|
||||
currentset += ",bookmarks-menu-button-container";
|
||||
this._setPersist(toolbarResource, currentsetResource, currentset);
|
||||
}
|
||||
}
|
||||
|
@ -193,9 +193,9 @@ PrivateBrowsingService.prototype = {
|
||||
if (!this._quitting && this._saveSession) {
|
||||
let browserWindow = this._getBrowserWindow();
|
||||
|
||||
// if there are open browser windows, load a dummy session to get a distinct
|
||||
// if there are open browser windows, load a dummy session to get a distinct
|
||||
// separation between private and non-private sessions
|
||||
if (browserWindow) {
|
||||
if (browserWindow) {
|
||||
// set an empty session to transition from/to pb mode, see bug 476463
|
||||
ss.setBrowserState(blankState);
|
||||
|
||||
@ -217,7 +217,9 @@ PrivateBrowsingService.prototype = {
|
||||
.getInterface(Ci.nsIXULWindow)
|
||||
.docShell.contentViewer.resetCloseWindow();
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._quitting) {
|
||||
var windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
var window = windowsEnum.getNext();
|
||||
|
@ -58,21 +58,31 @@ function test() {
|
||||
ok(gPrivateBrowsingUI, "The gPrivateBrowsingUI object exists");
|
||||
is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started initially");
|
||||
is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
|
||||
is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
|
||||
ok(pbMenuItem, "The Private Browsing menu item exists");
|
||||
is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
|
||||
gPrivateBrowsingUI.toggleMode();
|
||||
is(pb.privateBrowsingEnabled, true, "The private browsing mode should be started");
|
||||
is(gPrivateBrowsingUI.privateBrowsingEnabled, true, "gPrivateBrowsingUI should expose the correct private browsing status");
|
||||
is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
|
||||
// check to see if the Private Browsing mode was activated successfully
|
||||
is(observerData, "enter", "Private Browsing mode was activated using the gPrivateBrowsingUI object");
|
||||
is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("stoplabel"), "The Private Browsing menu item should read \"Stop Private Browsing\"");
|
||||
gPrivateBrowsingUI.toggleMode()
|
||||
is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started");
|
||||
is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
|
||||
is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should expose the correct per-window private browsing status");
|
||||
// check to see if the Private Browsing mode was deactivated successfully
|
||||
is(observerData, "exit", "Private Browsing mode was deactivated using the gPrivateBrowsingUI object");
|
||||
is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
|
||||
|
||||
// These are tests for the privateWindow setter. Note that the setter should
|
||||
// not be used anywhere else for now!
|
||||
gPrivateBrowsingUI.privateWindow = true;
|
||||
is(gPrivateBrowsingUI.privateWindow, true, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
|
||||
gPrivateBrowsingUI.privateWindow = false;
|
||||
is(gPrivateBrowsingUI.privateWindow, false, "gPrivateBrowsingUI should accept the correct per-window private browsing status");
|
||||
|
||||
// now, test using the <command> object
|
||||
let cmd = document.getElementById("Tools:PrivateBrowsing");
|
||||
isnot(cmd, null, "XUL command object for the private browsing service exists");
|
||||
|
@ -77,7 +77,10 @@
|
||||
#define INITGUID
|
||||
#include <shlobj.h>
|
||||
|
||||
#pragma comment(lib, "shlwapi.lib") // for SHDeleteKeyW
|
||||
|
||||
#include <mbstring.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#ifndef MAX_BUF
|
||||
#define MAX_BUF 4096
|
||||
@ -129,23 +132,17 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\FirefoxHTML\
|
||||
// DefaultIcon (default) REG_SZ <apppath>,1
|
||||
// shell\open\command (default) REG_SZ <apppath> -requestPending -osint -url "%1"
|
||||
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
|
||||
// shell\open\ddeexec NoActivateHandler REG_SZ
|
||||
// \Application (default) REG_SZ Firefox
|
||||
// \Topic (default) REG_SZ WWW_OpenURL
|
||||
// shell\open\command (default) REG_SZ <apppath> -osint -url "%1"
|
||||
// shell\open\ddeexec (default) REG_SZ <empty string>
|
||||
//
|
||||
// - Windows Vista Protocol Handler
|
||||
// - Windows Vista and above Protocol Handler
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\FirefoxURL\ (default) REG_SZ <appname> URL
|
||||
// EditFlags REG_DWORD 2
|
||||
// FriendlyTypeName REG_SZ <appname> URL
|
||||
// DefaultIcon (default) REG_SZ <apppath>,1
|
||||
// shell\open\command (default) REG_SZ <apppath> -requestPending -osint -url "%1"
|
||||
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
|
||||
// shell\open\ddeexec NoActivateHandler REG_SZ
|
||||
// \Application (default) REG_SZ Firefox
|
||||
// \Topic (default) REG_SZ WWW_OpenURL
|
||||
// shell\open\command (default) REG_SZ <apppath> -osint -url "%1"
|
||||
// shell\open\ddeexec (default) REG_SZ <empty string>
|
||||
//
|
||||
// - Protocol Mappings
|
||||
// -----------------
|
||||
@ -155,13 +152,10 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\<protocol>\
|
||||
// DefaultIcon (default) REG_SZ <apppath>,1
|
||||
// shell\open\command (default) REG_SZ <apppath> -requestPending -osint -url "%1"
|
||||
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
|
||||
// shell\open\ddeexec NoActivateHandler REG_SZ
|
||||
// \Application (default) REG_SZ Firefox
|
||||
// \Topic (default) REG_SZ WWW_OpenURL
|
||||
// shell\open\command (default) REG_SZ <apppath> -osint -url "%1"
|
||||
// shell\open\ddeexec (default) REG_SZ <empty string>
|
||||
//
|
||||
// - Windows Start Menu (Win2K SP2, XP SP1, and newer)
|
||||
// - Windows Start Menu (XP SP1 and newer)
|
||||
// -------------------------------------------------
|
||||
// The following keys are set to make Firefox appear in the Start Menu as the
|
||||
// browser:
|
||||
@ -180,19 +174,22 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
|
||||
// shell\safemode\command (default) REG_SZ <apppath> -safe-mode
|
||||
//
|
||||
|
||||
// The values checked are all default values so the value name is not needed.
|
||||
typedef struct {
|
||||
char* keyName;
|
||||
char* valueName;
|
||||
char* valueData;
|
||||
char* oldValueData;
|
||||
} SETTING;
|
||||
|
||||
#define APP_REG_NAME L"Firefox"
|
||||
#define CLS_HTML "FirefoxHTML"
|
||||
#define CLS_URL "FirefoxURL"
|
||||
#define VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
|
||||
#define VAL_FILE_ICON "%APPPATH%,1"
|
||||
#define VAL_OPEN "\"%APPPATH%\" -osint -url \"%1\""
|
||||
#define OLD_VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
|
||||
#define DI "\\DefaultIcon"
|
||||
#define SOP "\\shell\\open\\command"
|
||||
#define SOC "\\shell\\open\\command"
|
||||
#define SOD "\\shell\\open\\ddeexec"
|
||||
// Used for updating the FTP protocol handler's shell open command under HKCU.
|
||||
#define FTP_SOC L"Software\\Classes\\ftp\\shell\\open\\command"
|
||||
|
||||
#define MAKE_KEY_NAME1(PREFIX, MID) \
|
||||
PREFIX MID
|
||||
@ -201,19 +198,37 @@ typedef struct {
|
||||
// Firefox is the default browser for file handlers since other applications
|
||||
// (e.g. MS Office) may modify the DefaultIcon registry key value to add Icon
|
||||
// Handlers. see http://msdn2.microsoft.com/en-us/library/aa969357.aspx for
|
||||
// more info.
|
||||
// more info. The FTP protocol is not checked so advanced users can set the FTP
|
||||
// handler to another application and still have Firefox check if it is the
|
||||
// default HTTP and HTTPS handler.
|
||||
static SETTING gSettings[] = {
|
||||
// File Handler Class
|
||||
{ MAKE_KEY_NAME1(CLS_HTML, SOP), "", VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("FirefoxHTML", SOC), VAL_OPEN, OLD_VAL_OPEN },
|
||||
|
||||
// Protocol Handler Class - for Vista and above
|
||||
{ MAKE_KEY_NAME1(CLS_URL, SOP), "", VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("FirefoxURL", SOC), VAL_OPEN, OLD_VAL_OPEN },
|
||||
|
||||
// Protocol Handlers
|
||||
{ MAKE_KEY_NAME1("HTTP", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("HTTP", SOP), "", VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("HTTPS", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("HTTPS", SOP), "", VAL_OPEN }
|
||||
{ MAKE_KEY_NAME1("HTTP", DI), VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("HTTP", SOC), VAL_OPEN, OLD_VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("HTTPS", DI), VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("HTTPS", SOC), VAL_OPEN, OLD_VAL_OPEN }
|
||||
};
|
||||
|
||||
// The settings to disable DDE are separate from the default browser settings
|
||||
// since they are only checked when Firefox is the default browser and if they
|
||||
// are incorrect they are fixed without notifying the user.
|
||||
static SETTING gDDESettings[] = {
|
||||
// File Handler Class
|
||||
{ MAKE_KEY_NAME1("Software\\Classes\\FirefoxHTML", SOD) },
|
||||
|
||||
// Protocol Handler Class - for Vista and above
|
||||
{ MAKE_KEY_NAME1("Software\\Classes\\FirefoxURL", SOD) },
|
||||
|
||||
// Protocol Handlers
|
||||
{ MAKE_KEY_NAME1("Software\\Classes\\FTP", SOD) },
|
||||
{ MAKE_KEY_NAME1("Software\\Classes\\HTTP", SOD) },
|
||||
{ MAKE_KEY_NAME1("Software\\Classes\\HTTPS", SOD) }
|
||||
};
|
||||
|
||||
nsresult
|
||||
@ -245,11 +260,10 @@ LaunchHelper(nsAutoString& aPath)
|
||||
STARTUPINFOW si = {sizeof(si), 0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
|
||||
BOOL ok = CreateProcessW(NULL, (LPWSTR)aPath.get(), NULL, NULL,
|
||||
FALSE, 0, NULL, NULL, &si, &pi);
|
||||
|
||||
if (!ok)
|
||||
if (!CreateProcessW(NULL, (LPWSTR)aPath.get(), NULL, NULL, FALSE, 0, NULL,
|
||||
NULL, &si, &pi)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
@ -367,9 +381,6 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
|
||||
if (aStartupCheck)
|
||||
mCheckedThisSession = true;
|
||||
|
||||
SETTING* settings;
|
||||
SETTING* end = gSettings + sizeof(gSettings)/sizeof(SETTING);
|
||||
|
||||
*aIsDefaultBrowser = true;
|
||||
|
||||
PRUnichar exePath[MAX_BUF];
|
||||
@ -383,40 +394,171 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
|
||||
|
||||
nsAutoString appLongPath(exePath);
|
||||
|
||||
HKEY theKey;
|
||||
DWORD res;
|
||||
nsresult rv;
|
||||
PRUnichar currValue[MAX_BUF];
|
||||
for (settings = gSettings; settings < end; ++settings) {
|
||||
NS_ConvertUTF8toUTF16 dataLongPath(settings->valueData);
|
||||
NS_ConvertUTF8toUTF16 key(settings->keyName);
|
||||
NS_ConvertUTF8toUTF16 value(settings->valueName);
|
||||
PRInt32 offset = dataLongPath.Find("%APPPATH%");
|
||||
dataLongPath.Replace(offset, 9, appLongPath);
|
||||
|
||||
::ZeroMemory(currValue, sizeof(currValue));
|
||||
HKEY theKey;
|
||||
rv = OpenKeyForReading(HKEY_CLASSES_ROOT, key, &theKey);
|
||||
SETTING* settings;
|
||||
SETTING* end = gSettings + sizeof(gSettings) / sizeof(SETTING);
|
||||
|
||||
for (settings = gSettings; settings < end; ++settings) {
|
||||
NS_ConvertUTF8toUTF16 keyName(settings->keyName);
|
||||
NS_ConvertUTF8toUTF16 valueData(settings->valueData);
|
||||
PRInt32 offset = valueData.Find("%APPPATH%");
|
||||
valueData.Replace(offset, 9, appLongPath);
|
||||
|
||||
rv = OpenKeyForReading(HKEY_CLASSES_ROOT, keyName, &theKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
::ZeroMemory(currValue, sizeof(currValue));
|
||||
DWORD len = sizeof currValue;
|
||||
DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(value).get(),
|
||||
NULL, NULL, (LPBYTE)currValue, &len);
|
||||
// Close the key we opened.
|
||||
res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue, &len);
|
||||
// Close the key that was opened.
|
||||
::RegCloseKey(theKey);
|
||||
if (REG_FAILED(res) ||
|
||||
!dataLongPath.Equals(currValue, CaseInsensitiveCompare)) {
|
||||
// Key wasn't set, or was set to something other than our registry entry
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
!valueData.Equals(currValue, CaseInsensitiveCompare)) {
|
||||
// Key wasn't set or was set to something other than our registry entry.
|
||||
NS_ConvertUTF8toUTF16 oldValueData(settings->oldValueData);
|
||||
offset = oldValueData.Find("%APPPATH%");
|
||||
oldValueData.Replace(offset, 9, appLongPath);
|
||||
// The current registry value doesn't match the current or the old format.
|
||||
if (!oldValueData.Equals(currValue, CaseInsensitiveCompare)) {
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
res = ::RegOpenKeyExW(HKEY_CLASSES_ROOT, PromiseFlatString(keyName).get(),
|
||||
0, KEY_SET_VALUE, &theKey);
|
||||
if (REG_FAILED(res)) {
|
||||
// If updating the open command fails try to update it using the helper
|
||||
// application when setting Firefox as the default browser.
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const nsString &flatValue = PromiseFlatString(valueData);
|
||||
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
|
||||
(const BYTE *) flatValue.get(),
|
||||
(flatValue.Length() + 1) * sizeof(PRUnichar));
|
||||
// Close the key that was created.
|
||||
::RegCloseKey(theKey);
|
||||
if (REG_FAILED(res)) {
|
||||
// If updating the open command fails try to update it using the helper
|
||||
// application when setting Firefox as the default browser.
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only check if Firefox is the default browser on Vista if the previous
|
||||
// checks show that Firefox is the default browser.
|
||||
if (*aIsDefaultBrowser)
|
||||
// Only check if Firefox is the default browser on Vista and above if the
|
||||
// previous checks show that Firefox is the default browser.
|
||||
if (*aIsDefaultBrowser) {
|
||||
IsDefaultBrowserVista(aIsDefaultBrowser);
|
||||
}
|
||||
|
||||
// To handle the case where DDE isn't disabled due for a user because there
|
||||
// account didn't perform a Firefox update this will check if Firefox is the
|
||||
// default browser and if dde is disabled for each handler
|
||||
// and if it isn't disable it. When Firefox is not the default browser the
|
||||
// helper application will disable dde for each handler.
|
||||
if (*aIsDefaultBrowser) {
|
||||
// Check ftp settings
|
||||
|
||||
end = gDDESettings + sizeof(gDDESettings) / sizeof(SETTING);
|
||||
|
||||
for (settings = gDDESettings; settings < end; ++settings) {
|
||||
NS_ConvertUTF8toUTF16 keyName(settings->keyName);
|
||||
|
||||
rv = OpenKeyForReading(HKEY_CURRENT_USER, keyName, &theKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
::RegCloseKey(theKey);
|
||||
// If disabling DDE fails try to disable it using the helper
|
||||
// application when setting Firefox as the default browser.
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
::ZeroMemory(currValue, sizeof(currValue));
|
||||
DWORD len = sizeof currValue;
|
||||
res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue,
|
||||
&len);
|
||||
// Close the key that was opened.
|
||||
::RegCloseKey(theKey);
|
||||
if (REG_FAILED(res) || PRUnichar('\0') != *currValue) {
|
||||
// Key wasn't set or was set to something other than our registry entry.
|
||||
// Delete the key along with all of its childrean and then recreate it.
|
||||
const nsString &flatName = PromiseFlatString(keyName);
|
||||
::SHDeleteKeyW(HKEY_CURRENT_USER, flatName.get());
|
||||
res = ::RegCreateKeyExW(HKEY_CURRENT_USER, flatName.get(), 0, NULL,
|
||||
REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
|
||||
&theKey, NULL);
|
||||
if (REG_FAILED(res)) {
|
||||
// If disabling DDE fails try to disable it using the helper
|
||||
// application when setting Firefox as the default browser.
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ, (const BYTE *) L"",
|
||||
sizeof(PRUnichar));
|
||||
// Close the key that was created.
|
||||
::RegCloseKey(theKey);
|
||||
if (REG_FAILED(res)) {
|
||||
// If disabling DDE fails try to disable it using the helper
|
||||
// application when setting Firefox as the default browser.
|
||||
*aIsDefaultBrowser = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the FTP protocol handler's shell open command if it is the old
|
||||
// format.
|
||||
res = ::RegOpenKeyExW(HKEY_CURRENT_USER, FTP_SOC, 0, KEY_ALL_ACCESS,
|
||||
&theKey);
|
||||
// Don't update the FTP protocol handler's shell open command when opening
|
||||
// its registry key fails under HKCU since it most likely doesn't exist.
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ConvertUTF8toUTF16 oldValueOpen(OLD_VAL_OPEN);
|
||||
PRInt32 offset = oldValueOpen.Find("%APPPATH%");
|
||||
oldValueOpen.Replace(offset, 9, appLongPath);
|
||||
|
||||
::ZeroMemory(currValue, sizeof(currValue));
|
||||
DWORD len = sizeof currValue;
|
||||
res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue,
|
||||
&len);
|
||||
|
||||
// Don't update the FTP protocol handler's shell open command when the
|
||||
// current registry value doesn't exist or matches the old format.
|
||||
if (REG_FAILED(res) ||
|
||||
!oldValueOpen.Equals(currValue, CaseInsensitiveCompare)) {
|
||||
::RegCloseKey(theKey);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ConvertUTF8toUTF16 valueData(VAL_OPEN);
|
||||
valueData.Replace(offset, 9, appLongPath);
|
||||
const nsString &flatValue = PromiseFlatString(valueData);
|
||||
res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
|
||||
(const BYTE *) flatValue.get(),
|
||||
(flatValue.Length() + 1) * sizeof(PRUnichar));
|
||||
// Close the key that was created.
|
||||
::RegCloseKey(theKey);
|
||||
// If updating the FTP protocol handlers shell open command fails try to
|
||||
// update it using the helper application when setting Firefox as the
|
||||
// default browser.
|
||||
if (REG_FAILED(res)) {
|
||||
*aIsDefaultBrowser = false;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -25,9 +25,6 @@ const Ci = Components.interfaces;
|
||||
Cu.import("resource:///modules/PageThumbs.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
@ -104,268 +101,252 @@ function Channel(aURI) {
|
||||
}
|
||||
|
||||
Channel.prototype = {
|
||||
/**
|
||||
* Tracks if the channel has been opened, yet.
|
||||
*/
|
||||
_uri: null,
|
||||
_referrer: null,
|
||||
_canceled: false,
|
||||
_status: Cr.NS_OK,
|
||||
_isPending: false,
|
||||
_wasOpened: false,
|
||||
_responseText: "OK",
|
||||
_responseStatus: 200,
|
||||
_responseHeaders: null,
|
||||
_requestMethod: "GET",
|
||||
_requestStarted: false,
|
||||
_allowPipelining: true,
|
||||
_requestSucceeded: true,
|
||||
|
||||
/* :::::::: nsIChannel ::::::::::::::: */
|
||||
|
||||
get URI() this._uri,
|
||||
owner: null,
|
||||
notificationCallbacks: null,
|
||||
get securityInfo() null,
|
||||
|
||||
contentType: PageThumbs.contentType,
|
||||
contentCharset: null,
|
||||
contentLength: -1,
|
||||
|
||||
get contentDisposition() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
get contentDispositionFilename() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
get contentDispositionHeader() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
open: function Channel_open() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_IMPLEMENTED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens this channel asynchronously.
|
||||
* @param aListener The listener that receives the channel data when available.
|
||||
* @param aContext A custom context passed to the listener's methods.
|
||||
*/
|
||||
asyncOpen: function Channel_asyncOpen(aListener, aContext) {
|
||||
if (this._isPending)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
|
||||
if (this._wasOpened)
|
||||
throw Cr.NS_ERROR_ALREADY_OPENED;
|
||||
throw (Components.returnCode = Cr.NS_ERROR_ALREADY_OPENED);
|
||||
|
||||
if (this.canceled)
|
||||
return;
|
||||
|
||||
this._listener = aListener;
|
||||
this._context = aContext;
|
||||
if (this._canceled)
|
||||
return (Components.returnCode = this._status);
|
||||
|
||||
this._isPending = true;
|
||||
this._wasOpened = true;
|
||||
|
||||
// Try to read the data from the thumbnail cache.
|
||||
this._readCache(function (aData) {
|
||||
let telemetryThumbnailFound = true;
|
||||
this._listener = aListener;
|
||||
this._context = aContext;
|
||||
|
||||
// Update response if there's no data.
|
||||
if (!aData) {
|
||||
this._responseStatus = 404;
|
||||
this._responseText = "Not Found";
|
||||
telemetryThumbnailFound = false;
|
||||
}
|
||||
if (this.loadGroup)
|
||||
this.loadGroup.addRequest(this, null);
|
||||
|
||||
Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
|
||||
.add(telemetryThumbnailFound);
|
||||
if (this._canceled)
|
||||
return;
|
||||
|
||||
this._startRequest();
|
||||
|
||||
if (!this.canceled) {
|
||||
this._addToLoadGroup();
|
||||
|
||||
if (aData)
|
||||
this._serveData(aData);
|
||||
|
||||
if (!this.canceled)
|
||||
this._stopRequest();
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Reads a data stream from the cache entry.
|
||||
* @param aCallback The callback the data is passed to.
|
||||
*/
|
||||
_readCache: function Channel_readCache(aCallback) {
|
||||
let {url} = parseURI(this._uri);
|
||||
|
||||
// Return early if there's no valid URL given.
|
||||
if (!url) {
|
||||
aCallback(null);
|
||||
this._serveThumbnailNotFound();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get a cache entry.
|
||||
PageThumbsCache.getReadEntry(url, function (aEntry) {
|
||||
let inputStream = aEntry && aEntry.openInputStream(0);
|
||||
|
||||
function closeEntryAndFinish(aData) {
|
||||
if (aEntry) {
|
||||
aEntry.close();
|
||||
}
|
||||
aCallback(aData);
|
||||
}
|
||||
|
||||
// Check if we have a valid entry and if it has any data.
|
||||
if (!inputStream || !inputStream.available()) {
|
||||
closeEntryAndFinish();
|
||||
if (aEntry)
|
||||
aEntry.close();
|
||||
this._serveThumbnailNotFound();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Read the cache entry's data.
|
||||
NetUtil.asyncFetch(inputStream, function (aData, aStatus) {
|
||||
// We might have been canceled while waiting.
|
||||
if (this.canceled)
|
||||
return;
|
||||
this._entry = aEntry;
|
||||
this._pump = Cc["@mozilla.org/network/input-stream-pump;1"].
|
||||
createInstance(Ci.nsIInputStreamPump);
|
||||
|
||||
// Check if we have a valid data stream.
|
||||
if (!Components.isSuccessCode(aStatus) || !aData.available())
|
||||
aData = null;
|
||||
this._pump.init(inputStream, -1, -1, 0, 0, true);
|
||||
this._pump.asyncRead(this, null);
|
||||
|
||||
closeEntryAndFinish(aData);
|
||||
}.bind(this));
|
||||
} catch (e) {
|
||||
closeEntryAndFinish();
|
||||
}
|
||||
this._trackThumbnailHitOrMiss(true);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls onStartRequest on the channel listener.
|
||||
* Serves a "404 Not Found" if we didn't find the requested thumbnail.
|
||||
*/
|
||||
_startRequest: function Channel_startRequest() {
|
||||
try {
|
||||
this._listener.onStartRequest(this, this._context);
|
||||
} catch (e) {
|
||||
// The listener might throw if the request has been canceled.
|
||||
this.cancel(Cr.NS_BINDING_ABORTED);
|
||||
}
|
||||
_serveThumbnailNotFound: function Channel_serveThumbnailNotFound() {
|
||||
this._responseStatus = 404;
|
||||
this._responseText = "Not Found";
|
||||
this._requestSucceeded = false;
|
||||
|
||||
this.onStartRequest(this, null);
|
||||
this.onStopRequest(this, null, Cr.NS_OK);
|
||||
|
||||
this._trackThumbnailHitOrMiss(false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls onDataAvailable on the channel listener and passes the data stream.
|
||||
* @param aData The data to be delivered.
|
||||
* Implements telemetry tracking for thumbnail cache hits and misses.
|
||||
* @param aFound Whether the thumbnail was found.
|
||||
*/
|
||||
_serveData: function Channel_serveData(aData) {
|
||||
try {
|
||||
let available = aData.available();
|
||||
this._listener.onDataAvailable(this, this._context, aData, 0, available);
|
||||
} catch (e) {
|
||||
// The listener might throw if the request has been canceled.
|
||||
this.cancel(Cr.NS_BINDING_ABORTED);
|
||||
}
|
||||
_trackThumbnailHitOrMiss: function Channel_trackThumbnailHitOrMiss(aFound) {
|
||||
Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
|
||||
.add(aFound);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calls onStopRequest on the channel listener.
|
||||
*/
|
||||
_stopRequest: function Channel_stopRequest() {
|
||||
try {
|
||||
this._listener.onStopRequest(this, this._context, this.status);
|
||||
} catch (e) {
|
||||
// This might throw but is generally ignored.
|
||||
}
|
||||
/* :::::::: nsIStreamListener ::::::::::::::: */
|
||||
|
||||
// The request has finished, clean up after ourselves.
|
||||
this._cleanup();
|
||||
onStartRequest: function Channel_onStartRequest(aRequest, aContext) {
|
||||
if (!this.canceled && Components.isSuccessCode(this._status))
|
||||
this._status = aRequest.status;
|
||||
|
||||
this._requestStarted = true;
|
||||
this._listener.onStartRequest(this, this._context);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds this request to the load group, if any.
|
||||
*/
|
||||
_addToLoadGroup: function Channel_addToLoadGroup() {
|
||||
onDataAvailable: function Channel_onDataAvailable(aRequest, aContext,
|
||||
aInStream, aOffset, aCount) {
|
||||
this._listener.onDataAvailable(this, this._context, aInStream, aOffset, aCount);
|
||||
},
|
||||
|
||||
onStopRequest: function Channel_onStopRequest(aRequest, aContext, aStatus) {
|
||||
this._isPending = false;
|
||||
this._status = aStatus;
|
||||
|
||||
this._listener.onStopRequest(this, this._context, aStatus);
|
||||
this._listener = null;
|
||||
this._context = null;
|
||||
|
||||
if (this._entry)
|
||||
this._entry.close();
|
||||
|
||||
if (this.loadGroup)
|
||||
this.loadGroup.addRequest(this, this._context);
|
||||
this.loadGroup.removeRequest(this, null, aStatus);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes this request from its load group, if any.
|
||||
*/
|
||||
_removeFromLoadGroup: function Channel_removeFromLoadGroup() {
|
||||
if (!this.loadGroup)
|
||||
/* :::::::: nsIRequest ::::::::::::::: */
|
||||
|
||||
get status() this._status,
|
||||
get name() this._uri.spec,
|
||||
isPending: function Channel_isPending() this._isPending,
|
||||
|
||||
loadFlags: Ci.nsIRequest.LOAD_NORMAL,
|
||||
loadGroup: null,
|
||||
|
||||
cancel: function Channel_cancel(aStatus) {
|
||||
if (this._canceled)
|
||||
return;
|
||||
|
||||
try {
|
||||
this.loadGroup.removeRequest(this, this._context, this.status);
|
||||
} catch (e) {
|
||||
// This might throw but is ignored.
|
||||
}
|
||||
this._canceled = true;
|
||||
this._status = aStatus;
|
||||
|
||||
if (this._pump)
|
||||
this._pump.cancel(aStatus);
|
||||
},
|
||||
|
||||
/**
|
||||
* Cleans up the channel when the request has finished.
|
||||
*/
|
||||
_cleanup: function Channel_cleanup() {
|
||||
this._removeFromLoadGroup();
|
||||
this.loadGroup = null;
|
||||
|
||||
this._isPending = false;
|
||||
|
||||
delete this._listener;
|
||||
delete this._context;
|
||||
suspend: function Channel_suspend() {
|
||||
if (this._pump)
|
||||
this._pump.suspend();
|
||||
},
|
||||
|
||||
/* :::::::: nsIChannel ::::::::::::::: */
|
||||
|
||||
contentType: PageThumbs.contentType,
|
||||
contentLength: -1,
|
||||
owner: null,
|
||||
contentCharset: null,
|
||||
notificationCallbacks: null,
|
||||
|
||||
get URI() this._uri,
|
||||
get securityInfo() null,
|
||||
|
||||
/**
|
||||
* Opens this channel synchronously. Not supported.
|
||||
*/
|
||||
open: function Channel_open() {
|
||||
// Synchronous data delivery is not implemented.
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
resume: function Channel_resume() {
|
||||
if (this._pump)
|
||||
this._pump.resume();
|
||||
},
|
||||
|
||||
/* :::::::: nsIHttpChannel ::::::::::::::: */
|
||||
|
||||
redirectionLimit: 10,
|
||||
requestMethod: "GET",
|
||||
allowPipelining: true,
|
||||
referrer: null,
|
||||
get referrer() this._referrer,
|
||||
|
||||
get requestSucceeded() true,
|
||||
set referrer(aReferrer) {
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
|
||||
_responseStatus: 200,
|
||||
get responseStatus() this._responseStatus,
|
||||
|
||||
_responseText: "OK",
|
||||
get responseStatusText() this._responseText,
|
||||
|
||||
/**
|
||||
* Checks if the server sent the equivalent of a "Cache-control: no-cache"
|
||||
* response header.
|
||||
* @return Always false.
|
||||
*/
|
||||
isNoCacheResponse: function () false,
|
||||
|
||||
/**
|
||||
* Checks if the server sent the equivalent of a "Cache-control: no-cache"
|
||||
* response header.
|
||||
* @return Always false.
|
||||
*/
|
||||
isNoStoreResponse: function () false,
|
||||
|
||||
/**
|
||||
* Returns the value of a particular request header. Not implemented.
|
||||
*/
|
||||
getRequestHeader: function Channel_getRequestHeader() {
|
||||
throw Cr.NS_ERROR_NOT_AVAILABLE;
|
||||
this._referrer = aReferrer;
|
||||
},
|
||||
|
||||
get requestMethod() this._requestMethod,
|
||||
|
||||
set requestMethod(aMethod) {
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
|
||||
this._requestMethod = aMethod.toUpperCase();
|
||||
},
|
||||
|
||||
get allowPipelining() this._allowPipelining,
|
||||
|
||||
set allowPipelining(aAllow) {
|
||||
if (this._wasOpened)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_FAILURE);
|
||||
|
||||
this._allowPipelining = aAllow;
|
||||
},
|
||||
|
||||
redirectionLimit: 10,
|
||||
|
||||
get responseStatus() {
|
||||
if (this._requestStarted)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return this._responseStatus;
|
||||
},
|
||||
|
||||
get responseStatusText() {
|
||||
if (this._requestStarted)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return this._responseText;
|
||||
},
|
||||
|
||||
get requestSucceeded() {
|
||||
if (this._requestStarted)
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
return this._requestSucceeded;
|
||||
},
|
||||
|
||||
isNoCacheResponse: function Channel_isNoCacheResponse() false,
|
||||
isNoStoreResponse: function Channel_isNoStoreResponse() false,
|
||||
|
||||
getRequestHeader: function Channel_getRequestHeader() {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
/**
|
||||
* This method is called to set the value of a particular request header.
|
||||
* Not implemented.
|
||||
*/
|
||||
setRequestHeader: function Channel_setRequestHeader() {
|
||||
if (this._wasOpened)
|
||||
throw Cr.NS_ERROR_IN_PROGRESS;
|
||||
throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
|
||||
},
|
||||
|
||||
/**
|
||||
* Call this method to visit all request headers. Not implemented.
|
||||
*/
|
||||
visitRequestHeaders: function () {},
|
||||
visitRequestHeaders: function Channel_visitRequestHeaders() {},
|
||||
|
||||
/**
|
||||
* Gets the value of a particular response header.
|
||||
* @param aHeader The case-insensitive name of the response header to query.
|
||||
* @return The header value.
|
||||
*/
|
||||
getResponseHeader: function Channel_getResponseHeader(aHeader) {
|
||||
let name = aHeader.toLowerCase();
|
||||
if (name in this._responseHeaders)
|
||||
return this._responseHeaders[name];
|
||||
|
||||
throw Cr.NS_ERROR_NOT_AVAILABLE;
|
||||
throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
},
|
||||
|
||||
/**
|
||||
* This method is called to set the value of a particular response header.
|
||||
* @param aHeader The case-insensitive name of the response header to query.
|
||||
* @param aValue The response header value to set.
|
||||
*/
|
||||
setResponseHeader: function Channel_setResponseHeader(aHeader, aValue, aMerge) {
|
||||
let name = aHeader.toLowerCase();
|
||||
if (!aValue && !aMerge)
|
||||
@ -374,10 +355,6 @@ Channel.prototype = {
|
||||
this._responseHeaders[name] = aValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* Call this method to visit all response headers.
|
||||
* @param aVisitor The header visitor.
|
||||
*/
|
||||
visitResponseHeaders: function Channel_visitResponseHeaders(aVisitor) {
|
||||
for (let name in this._responseHeaders) {
|
||||
let value = this._responseHeaders[name];
|
||||
@ -391,48 +368,17 @@ Channel.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/* :::::::: nsIRequest ::::::::::::::: */
|
||||
|
||||
loadFlags: Ci.nsIRequest.LOAD_NORMAL,
|
||||
loadGroup: null,
|
||||
|
||||
get name() this._uri.spec,
|
||||
|
||||
_status: Cr.NS_OK,
|
||||
get status() this._status,
|
||||
|
||||
_isPending: false,
|
||||
isPending: function () this._isPending,
|
||||
|
||||
resume: function () {},
|
||||
suspend: function () {},
|
||||
|
||||
/**
|
||||
* Cancels this request.
|
||||
* @param aStatus The reason for cancelling.
|
||||
*/
|
||||
cancel: function Channel_cancel(aStatus) {
|
||||
if (this.canceled)
|
||||
return;
|
||||
|
||||
this._isCanceled = true;
|
||||
this._status = aStatus;
|
||||
|
||||
this._cleanup();
|
||||
},
|
||||
|
||||
/* :::::::: nsIHttpChannelInternal ::::::::::::::: */
|
||||
|
||||
documentURI: null,
|
||||
|
||||
_isCanceled: false,
|
||||
get canceled() this._isCanceled,
|
||||
get canceled() this._canceled,
|
||||
allowSpdy: false,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel,
|
||||
Ci.nsIHttpChannel,
|
||||
Ci.nsIHttpChannelInternal,
|
||||
Ci.nsIRequest])
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given URI and extracts all parameters relevant to this protocol.
|
||||
|
@ -103,7 +103,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
|
||||
; Must be inserted before other macros that use logging
|
||||
!insertmacro _LoggingCommon
|
||||
|
||||
!insertmacro AddDDEHandlerValues
|
||||
!insertmacro AddDisabledDDEHandlerValues
|
||||
!insertmacro ChangeMUIHeaderImage
|
||||
!insertmacro CheckForFilesInUse
|
||||
!insertmacro CleanUpdatesDir
|
||||
@ -352,17 +352,15 @@ Section "-Application" APP_IDX
|
||||
${SetUninstallKeys}
|
||||
|
||||
; On install always add the FirefoxHTML and FirefoxURL keys.
|
||||
; An empty string is used for the 5th param because FirefoxHTML and FirefoxURL
|
||||
; are not protocol handlers.
|
||||
; An empty string is used for the 5th param because FirefoxHTML is not a
|
||||
; protocol handler.
|
||||
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
|
||||
StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
|
||||
StrCpy $3 "$\"%1$\",,0,0,,,,"
|
||||
StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
|
||||
|
||||
${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} Document" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
|
||||
${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
|
||||
"${AppRegName} Document" ""
|
||||
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
|
||||
"true"
|
||||
|
||||
; The following keys should only be set if we can write to HKLM
|
||||
${If} $TmpVal == "HKLM"
|
||||
|
@ -79,7 +79,7 @@
|
||||
${GetLongPath} "$0" $0
|
||||
${EndIf}
|
||||
${If} "$0" == "$INSTDIR"
|
||||
${SetStartMenuInternet}
|
||||
${SetStartMenuInternet} ; Does not use SHCTX
|
||||
${EndIf}
|
||||
|
||||
ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion"
|
||||
@ -156,12 +156,12 @@
|
||||
!define PostUpdate "!insertmacro PostUpdate"
|
||||
|
||||
!macro SetAsDefaultAppGlobal
|
||||
${RemoveDeprecatedKeys}
|
||||
${RemoveDeprecatedKeys} ; Does not use SHCTX
|
||||
|
||||
SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM)
|
||||
${SetHandlers}
|
||||
${SetStartMenuInternet}
|
||||
${FixShellIconHandler}
|
||||
${SetHandlers} ; Uses SHCTX
|
||||
${SetStartMenuInternet} ; Does not use SHCTX
|
||||
${FixShellIconHandler} ; Does not use SHCTX
|
||||
${ShowShortcuts}
|
||||
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
|
||||
WriteRegStr HKLM "Software\Clients\StartMenuInternet" "" "$R9"
|
||||
@ -306,7 +306,7 @@
|
||||
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
|
||||
|
||||
StrCpy $0 "SOFTWARE\Classes"
|
||||
StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
|
||||
StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
|
||||
|
||||
; Associate the file handlers with FirefoxHTML
|
||||
ReadRegStr $6 SHCTX "$0\.htm" ""
|
||||
@ -340,25 +340,20 @@
|
||||
WriteRegStr SHCTX "$0\.webm" "" "FirefoxHTML"
|
||||
${EndIf}
|
||||
|
||||
StrCpy $3 "$\"%1$\",,0,0,,,,"
|
||||
|
||||
; An empty string is used for the 5th param because FirefoxHTML is not a
|
||||
; protocol handler
|
||||
${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
|
||||
"${AppRegName} HTML Document" ""
|
||||
|
||||
${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
|
||||
"true"
|
||||
|
||||
; An empty string is used for the 4th & 5th params because the following
|
||||
; protocol handlers already have a display name and the additional keys
|
||||
; required for a protocol handler.
|
||||
${AddDDEHandlerValues} "ftp" "$2" "$8,1" "" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDDEHandlerValues} "http" "$2" "$8,1" "" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDDEHandlerValues} "https" "$2" "$8,1" "" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" ""
|
||||
${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" ""
|
||||
${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" ""
|
||||
!macroend
|
||||
!define SetHandlers "!insertmacro SetHandlers"
|
||||
|
||||
@ -567,8 +562,7 @@
|
||||
!macro UpdateProtocolHandlers
|
||||
; Store the command to open the app with an url in a register for easy access.
|
||||
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
|
||||
StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
|
||||
StrCpy $3 "$\"%1$\",,0,0,,,,"
|
||||
StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
|
||||
|
||||
; Only set the file and protocol handlers if the existing one under HKCR is
|
||||
; for this install location.
|
||||
@ -577,32 +571,32 @@
|
||||
${If} "$R9" == "true"
|
||||
; An empty string is used for the 5th param because FirefoxHTML is not a
|
||||
; protocol handler.
|
||||
${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
|
||||
"${AppRegName} HTML Document" ""
|
||||
${EndIf}
|
||||
|
||||
${IsHandlerForInstallDir} "FirefoxURL" $R9
|
||||
${If} "$R9" == "true"
|
||||
${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" \
|
||||
"${AppRegName} URL" "true"
|
||||
${EndIf}
|
||||
|
||||
; An empty string is used for the 4th & 5th params because the following
|
||||
; protocol handlers already have a display name and the additional keys
|
||||
; required for a protocol handler.
|
||||
${IsHandlerForInstallDir} "ftp" $R9
|
||||
${If} "$R9" == "true"
|
||||
${AddDDEHandlerValues} "ftp" "$2" "$8,1" "" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" ""
|
||||
${EndIf}
|
||||
|
||||
${IsHandlerForInstallDir} "http" $R9
|
||||
${If} "$R9" == "true"
|
||||
${AddDDEHandlerValues} "http" "$2" "$8,1" "" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" ""
|
||||
${EndIf}
|
||||
|
||||
${IsHandlerForInstallDir} "https" $R9
|
||||
${If} "$R9" == "true"
|
||||
${AddDDEHandlerValues} "https" "$2" "$8,1" "" "" \
|
||||
"${DDEApplication}" "$3" "WWW_OpenURL"
|
||||
${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" ""
|
||||
${EndIf}
|
||||
!macroend
|
||||
!define UpdateProtocolHandlers "!insertmacro UpdateProtocolHandlers"
|
||||
@ -1164,11 +1158,13 @@ Function SetAsDefaultAppUser
|
||||
; b) is not a member of the administrators group and chooses to elevate
|
||||
${ElevateUAC}
|
||||
|
||||
${SetStartMenuInternet}
|
||||
${SetStartMenuInternet} ; Does not use SHCTX
|
||||
|
||||
SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM)
|
||||
${FixShellIconHandler}
|
||||
${RemoveDeprecatedKeys}
|
||||
|
||||
${FixClassKeys} ; Does not use SHCTX
|
||||
${FixShellIconHandler} ; Does not use SHCTX
|
||||
${RemoveDeprecatedKeys} ; Does not use SHCTX
|
||||
|
||||
ClearErrors
|
||||
${GetParameters} $0
|
||||
|
@ -92,7 +92,7 @@ Var MaintCertKey
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
|
||||
VIAddVersionKey "OriginalFilename" "helper.exe"
|
||||
|
||||
!insertmacro AddDDEHandlerValues
|
||||
!insertmacro AddDisabledDDEHandlerValues
|
||||
!insertmacro CleanVirtualStore
|
||||
!insertmacro ElevateUAC
|
||||
!insertmacro GetLongPath
|
||||
|
@ -102,7 +102,7 @@ if [ "$MOZ_SAFE_BROWSING" ]; then
|
||||
"
|
||||
fi
|
||||
|
||||
if [ "$MOZ_WIDGET_TOOLKIT" = "windows" ]; then
|
||||
if [ "$MAKENSISU" ]; then
|
||||
add_makefiles "
|
||||
browser/installer/windows/Makefile
|
||||
"
|
||||
|
@ -1148,7 +1148,7 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
|
||||
/* ::::: fullscreen window controls ::::: */
|
||||
|
||||
#TabsToolbar > #window-controls {
|
||||
#window-controls {
|
||||
-moz-margin-start: 4px;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ package @ANDROID_PACKAGE_NAME@;
|
||||
|
||||
public interface Assert {
|
||||
void dumpLog(String message);
|
||||
void dumpLog(String message, Throwable t);
|
||||
void setLogFile(String filename);
|
||||
void setTestName(String testName);
|
||||
|
||||
|
@ -66,6 +66,11 @@ public class FennecMochitestAssert implements Assert {
|
||||
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message);
|
||||
}
|
||||
|
||||
/** Write information to a logfile and logcat */
|
||||
public void dumpLog(String message, Throwable t) {
|
||||
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t);
|
||||
}
|
||||
|
||||
/** Set the filename used for dumpLog. */
|
||||
public void setLogFile(String filename) {
|
||||
FennecNativeDriver.setLogFile(filename);
|
||||
|
@ -41,7 +41,6 @@ package @ANDROID_PACKAGE_NAME@;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
@ -49,6 +48,7 @@ import java.io.FileWriter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -459,41 +459,48 @@ public class FennecNativeDriver implements Driver {
|
||||
}
|
||||
|
||||
public static void log(LogLevel level, String message) {
|
||||
log(level, message, null);
|
||||
}
|
||||
|
||||
public static void log(LogLevel level, Throwable t) {
|
||||
log(level, null, t);
|
||||
}
|
||||
|
||||
public static void log(LogLevel level, String message, Throwable t) {
|
||||
if (mLogFile == null) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (level.isEnabled(mLogLevel)) {
|
||||
File file = new File(mLogFile);
|
||||
BufferedWriter bw = null;
|
||||
|
||||
PrintWriter pw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter(mLogFile, true));
|
||||
bw.write(message);
|
||||
bw.newLine();
|
||||
} catch(IOException e) {
|
||||
pw = new PrintWriter(new FileWriter(mLogFile, true));
|
||||
if (message != null) {
|
||||
pw.println(message);
|
||||
}
|
||||
if (t != null) {
|
||||
t.printStackTrace(pw);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
Log.e("Robocop", "exception with file writer on: " + mLogFile);
|
||||
} finally {
|
||||
try {
|
||||
if (bw != null) {
|
||||
bw.flush();
|
||||
bw.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
pw.close();
|
||||
}
|
||||
// PrintWriter doesn't throw IOE but sets an error flag instead,
|
||||
// so check for that
|
||||
if (pw.checkError()) {
|
||||
Log.e("Robocop", "exception with file writer on: " + mLogFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (level == LogLevel.LOG_LEVEL_INFO) {
|
||||
Log.i("Robocop", message);
|
||||
Log.i("Robocop", message, t);
|
||||
} else if (level == LogLevel.LOG_LEVEL_DEBUG) {
|
||||
Log.d("Robocop", message);
|
||||
Log.d("Robocop", message, t);
|
||||
} else if (level == LogLevel.LOG_LEVEL_WARN) {
|
||||
Log.w("Robocop", message);
|
||||
Log.w("Robocop", message, t);
|
||||
} else if (level == LogLevel.LOG_LEVEL_ERROR) {
|
||||
Log.e("Robocop", message);
|
||||
Log.e("Robocop", message, t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,6 +49,11 @@ public class FennecTalosAssert implements Assert {
|
||||
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message);
|
||||
}
|
||||
|
||||
/** Write information to a logfile and logcat */
|
||||
public void dumpLog(String message, Throwable t) {
|
||||
FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filename used for dumpLog.
|
||||
*/
|
||||
|
@ -127,8 +127,8 @@ classes.dex: $(_JAVA_TESTS)
|
||||
$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(addprefix $(DEPTH)/mobile/android/base/tests/,$(_JAVA_TESTS))
|
||||
$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH)
|
||||
|
||||
robocop.ap_: AndroidManifest.xml
|
||||
$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -F $@ -J ./
|
||||
robocop.ap_: AndroidManifest.xml $(TESTPATH)/assets/*
|
||||
$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./
|
||||
|
||||
robocop.apk: robocop.ap_ classes.dex
|
||||
cp $(TESTPATH)/robocop.ini robocop.ini
|
||||
|
@ -265,9 +265,9 @@ build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir, True)
|
||||
|
||||
stage1_tool_inst_dir = stage1_dir + '/inst'
|
||||
stage2_dir = build_dir + '/stage2'
|
||||
build_one_stage({"CC" : stage1_tool_inst_dir + "/bin/gcc -fgnu89-inline",
|
||||
"CXX" : stage1_tool_inst_dir + "/bin/g++",
|
||||
"AR" : stage1_tool_inst_dir + "/bin/ar",
|
||||
build_one_stage({"PATH" : stage1_tool_inst_dir + "/bin:/bin:/usr/bin",
|
||||
"CC" : "gcc -fgnu89-inline",
|
||||
"CXX" : "g++",
|
||||
"RANLIB" : "true" },
|
||||
stage2_dir, False)
|
||||
|
||||
|
53
configure.in
53
configure.in
@ -6319,29 +6319,38 @@ dnl ========================================================
|
||||
dnl Installer
|
||||
dnl ========================================================
|
||||
dnl Abort Windows build if the required major version and
|
||||
dnl minimum minor version of Unicode NSIS isn't in the path.
|
||||
dnl minimum minor version of Unicode NSIS isn't in the path
|
||||
dnl (unless in case of cross compiling, for which Unicode
|
||||
dnl is not yet sufficient).
|
||||
if test "$OS_ARCH" = "WINNT"; then
|
||||
REQ_NSIS_MAJOR_VER=2
|
||||
MIN_NSIS_MINOR_VER=33
|
||||
MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensisu-2.46 makensisu makensis)
|
||||
if test -z "$MAKENSISU" -o "$MAKENSISU" = ":"; then
|
||||
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
|
||||
if test -n "$MAKENSISU" -a "$MAKENSISU" != ":"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
changequote(,)
|
||||
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
|
||||
changequote([,])
|
||||
if test ! "$MAKENSISU_VER" = ""; then
|
||||
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
|
||||
MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
|
||||
fi
|
||||
AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
|
||||
if test "$MAKENSISU_VER" = "" || \
|
||||
test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
|
||||
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
|
||||
AC_MSG_RESULT([no])
|
||||
if test -z "$CROSS_COMPILE"; then
|
||||
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
|
||||
else
|
||||
MAKENSISU=
|
||||
fi
|
||||
fi
|
||||
elif test -z "$CROSS_COMPILE"; then
|
||||
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
|
||||
else
|
||||
MAKENSISU=
|
||||
fi
|
||||
changequote(,)
|
||||
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
|
||||
changequote([,])
|
||||
if test ! "$MAKENSISU_VER" = ""; then
|
||||
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
|
||||
MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
|
||||
fi
|
||||
AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
|
||||
if test "$MAKENSISU_VER" = "" ||
|
||||
test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
|
||||
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for tar archiver])
|
||||
@ -6458,14 +6467,6 @@ MOZ_ARG_DISABLE_BOOL(tests,
|
||||
ENABLE_TESTS=,
|
||||
ENABLE_TESTS=1 )
|
||||
|
||||
dnl ========================================================
|
||||
dnl Marionette
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(marionette,
|
||||
[ --enable-marionette Enable Marionette for remote testing and control],
|
||||
ENABLE_MARIONETTE=1,
|
||||
ENABLE_MARIONETTE)
|
||||
|
||||
dnl ========================================================
|
||||
dnl parental controls (for Windows Vista)
|
||||
dnl ========================================================
|
||||
|
@ -19,6 +19,7 @@
|
||||
* Contributor(s):
|
||||
* Sid Stamm <sid@mozilla.com>
|
||||
* Brandon Sterne <bsterne@mozilla.com>
|
||||
* Ian Melven <imelven@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -301,7 +302,7 @@ ContentSecurityPolicy.prototype = {
|
||||
|
||||
var failure = function(aEvt) {
|
||||
if (req.readyState == 4 && req.status != 200) {
|
||||
CSPError("Failed to send report to " + reportURI);
|
||||
CSPError("Failed to send report to " + uris[i]);
|
||||
}
|
||||
};
|
||||
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
@ -313,6 +314,10 @@ ContentSecurityPolicy.prototype = {
|
||||
req.upload.addEventListener("error", failure, false);
|
||||
req.upload.addEventListener("abort", failure, false);
|
||||
|
||||
// we need to set an nsIChannelEventSink on the XHR object
|
||||
// so we can tell it to not follow redirects when posting the reports
|
||||
req.channel.notificationCallbacks = new CSPReportRedirectSink();
|
||||
|
||||
req.send(JSON.stringify(report));
|
||||
CSPdebug("Sent violation report to " + uris[i]);
|
||||
} catch(e) {
|
||||
@ -494,4 +499,54 @@ ContentSecurityPolicy.prototype = {
|
||||
},
|
||||
};
|
||||
|
||||
// The POST of the violation report (if it happens) should not follow
|
||||
// redirects, per the spec. hence, we implement an nsIChannelEventSink
|
||||
// with an object so we can tell XHR to abort if a redirect happens.
|
||||
function CSPReportRedirectSink() {
|
||||
}
|
||||
|
||||
CSPReportRedirectSink.prototype = {
|
||||
QueryInterface: function requestor_qi(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIInterfaceRequestor) ||
|
||||
iid.equals(Ci.nsIChannelEventSink))
|
||||
return this;
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
getInterface: function requestor_gi(iid) {
|
||||
if (iid.equals(Ci.nsIChannelEventSink))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIChannelEventSink
|
||||
asyncOnChannelRedirect: function channel_redirect(oldChannel, newChannel,
|
||||
flags, callback) {
|
||||
CSPWarning("Post of violation report to " + oldChannel.URI.asciiSpec +
|
||||
" failed, as a redirect occurred");
|
||||
|
||||
// cancel the old channel so XHR failure callback happens
|
||||
oldChannel.cancel(Cr.NS_ERROR_ABORT);
|
||||
|
||||
// notify an observer that we have blocked the report POST due to a redirect,
|
||||
// used in testing, do this async since we're in an async call now to begin with
|
||||
Services.tm.mainThread.dispatch(
|
||||
function() {
|
||||
observerSubject = Cc["@mozilla.org/supports-cstring;1"]
|
||||
.createInstance(Ci.nsISupportsCString);
|
||||
observerSubject.data = oldChannel.URI.asciiSpec;
|
||||
|
||||
Services.obs.notifyObservers(observerSubject,
|
||||
CSP_VIOLATION_TOPIC,
|
||||
"denied redirect while sending violation report");
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
|
||||
// throw to stop the redirect happening
|
||||
throw Cr.NS_BINDING_REDIRECTED;
|
||||
}
|
||||
};
|
||||
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentSecurityPolicy]);
|
||||
|
@ -378,3 +378,29 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
TraceActiveWindowGlobal(const PRUint64& aId, nsGlobalWindow*& aWindow, void* aClosure)
|
||||
{
|
||||
if (aWindow->GetDocShell() && aWindow->IsOuterWindow()) {
|
||||
if (JSObject* global = aWindow->FastGetGlobalJSObject()) {
|
||||
JSTracer* trc = static_cast<JSTracer *>(aClosure);
|
||||
JS_CALL_OBJECT_TRACER(trc, global, "active window global");
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
mozilla::dom::TraceBlackJS(JSTracer* aTrc)
|
||||
{
|
||||
if (!nsCCUncollectableMarker::sGeneration) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark globals of active windows black.
|
||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||
nsGlobalWindow::GetWindowsTable();
|
||||
if (windowsById) {
|
||||
windowsById->Enumerate(TraceActiveWindowGlobal, aTrc);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
struct JSTracer;
|
||||
|
||||
class nsCCUncollectableMarker : public nsIObserver
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -56,10 +58,10 @@ class nsCCUncollectableMarker : public nsIObserver
|
||||
return aGeneration && aGeneration == sGeneration;
|
||||
}
|
||||
|
||||
static bool InGeneration(nsCycleCollectionTraversalCallback &cb,
|
||||
static bool InGeneration(nsCycleCollectionTraversalCallback& aCb,
|
||||
PRUint32 aGeneration)
|
||||
{
|
||||
return InGeneration(aGeneration) && !cb.WantAllTraces();
|
||||
return InGeneration(aGeneration) && !aCb.WantAllTraces();
|
||||
}
|
||||
|
||||
static PRUint32 sGeneration;
|
||||
@ -68,3 +70,9 @@ private:
|
||||
nsCCUncollectableMarker() {}
|
||||
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
void TraceBlackJS(JSTracer* aTrc);
|
||||
}
|
||||
}
|
||||
|
@ -2547,6 +2547,7 @@ void
|
||||
nsDocument::StopDocumentLoad()
|
||||
{
|
||||
if (mParser) {
|
||||
mParserAborted = true;
|
||||
mParser->Terminate();
|
||||
}
|
||||
}
|
||||
|
@ -1188,6 +1188,10 @@ protected:
|
||||
// our presshell. This is used to handle flush reentry correctly.
|
||||
bool mInFlush:1;
|
||||
|
||||
// Parser aborted. True if the parser of this document was forcibly
|
||||
// terminated instead of letting it finish at its own pace.
|
||||
bool mParserAborted:1;
|
||||
|
||||
PRUint8 mXMLDeclarationBits;
|
||||
|
||||
nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;
|
||||
|
@ -1935,7 +1935,8 @@ GK_ATOM(VolumeUp, "VolumeUp")
|
||||
GK_ATOM(VolumeDown, "VolumeDown")
|
||||
GK_ATOM(Menu, "Menu")
|
||||
|
||||
// Smooth scroll profiles
|
||||
// Smooth scroll events origins
|
||||
GK_ATOM(mouseWheel, "mouseWheel") // For discrete wheel events (e.g. not OSX magic mouse)
|
||||
GK_ATOM(pixels, "pixels")
|
||||
GK_ATOM(lines, "lines")
|
||||
GK_ATOM(pages, "pages")
|
||||
|
@ -314,42 +314,32 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||
mCurrentRequestNeedsResetAnimation = false;
|
||||
}
|
||||
|
||||
// We just loaded all the data we're going to get. If we haven't done an
|
||||
// initial paint, we want to make sure the image starts decoding for 2
|
||||
// reasons:
|
||||
// We just loaded all the data we're going to get. If we're visible and
|
||||
// haven't done an initial paint (*), we want to make sure the image starts
|
||||
// decoding immediately, for two reasons:
|
||||
//
|
||||
// 1) This image is sitting idle but might need to be decoded as soon as we
|
||||
// start painting, in which case we've wasted time.
|
||||
//
|
||||
// 2) We want to block onload until all visible images are decoded. We do this
|
||||
// by blocking onload until all in progress decodes get at least one frame
|
||||
// by blocking onload until all in-progress decodes get at least one frame
|
||||
// decoded. However, if all the data comes in while painting is suppressed
|
||||
// (ie, before the initial paint delay is finished), we fire onload without
|
||||
// doing a paint first. This means that decode-on-draw images don't start
|
||||
// decoding, so we can't wait for them to finish. See bug 512435.
|
||||
//
|
||||
// (*) IsPaintingSuppressed returns false if we haven't gotten the initial
|
||||
// reflow yet, so we have to test !DidInitialReflow || IsPaintingSuppressed.
|
||||
// It's possible for painting to be suppressed for reasons other than the
|
||||
// initial paint delay (for example, being in the bfcache), but we probably
|
||||
// aren't loading images in those situations.
|
||||
|
||||
// We can only do this if we have a presshell
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
nsIPresShell* shell = doc ? doc->GetShell() : nsnull;
|
||||
if (shell) {
|
||||
// We need to figure out whether to kick off decoding
|
||||
bool doRequestDecode = false;
|
||||
if (shell && shell->IsVisible() &&
|
||||
(!shell->DidInitialReflow() || shell->IsPaintingSuppressed())) {
|
||||
|
||||
// If we haven't got the initial reflow yet, IsPaintingSuppressed actually
|
||||
// returns false
|
||||
if (!shell->DidInitialReflow())
|
||||
doRequestDecode = true;
|
||||
|
||||
// Figure out if painting is suppressed. Note that it's possible for painting
|
||||
// to be suppressed for reasons other than the initial paint delay (for
|
||||
// example - being in the bfcache), but we probably aren't loading images in
|
||||
// those situations.
|
||||
if (shell->IsPaintingSuppressed())
|
||||
doRequestDecode = true;
|
||||
|
||||
// If we're requesting a decode, do it
|
||||
if (doRequestDecode)
|
||||
mCurrentRequest->RequestDecode();
|
||||
mCurrentRequest->RequestDecode();
|
||||
}
|
||||
|
||||
// Fire the appropriate DOM event.
|
||||
|
@ -2768,10 +2768,13 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
||||
// Create our listener
|
||||
nsCOMPtr<nsIStreamListener> listener = this;
|
||||
if (mState & XML_HTTP_REQUEST_MULTIPART) {
|
||||
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 1);
|
||||
listener = new nsMultipartProxyListener(listener);
|
||||
if (!listener) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 0);
|
||||
}
|
||||
|
||||
// Blocking gets are common enough out of XHR that we should mark
|
||||
|
@ -572,6 +572,12 @@ _TEST_FILES2 = \
|
||||
test_bug737612.html \
|
||||
test_bug738108.html \
|
||||
test_bug366944.html \
|
||||
test_bug650386_redirect_301.html \
|
||||
test_bug650386_redirect_302.html \
|
||||
test_bug650386_redirect_303.html \
|
||||
test_bug650386_redirect_307.html \
|
||||
file_bug650386_content.sjs \
|
||||
file_bug650386_report.sjs \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
37
content/base/test/file_bug650386_content.sjs
Normal file
37
content/base/test/file_bug650386_content.sjs
Normal file
@ -0,0 +1,37 @@
|
||||
// SJS file for tests for bug650386, serves file_bug650386_content.html
|
||||
// with a CSP that will trigger a violation and that will report it
|
||||
// to file_bug650386_report.sjs
|
||||
//
|
||||
// This handles 301, 302, 303 and 307 redirects. The HTTP status code
|
||||
// returned/type of redirect to do comes from the query string
|
||||
// parameter passed in from the test_bug650386_* files and then also
|
||||
// uses that value in the report-uri parameter of the CSP
|
||||
function handleRequest(request, response) {
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// this gets used in the CSP as part of the report URI.
|
||||
var redirect = request.queryString;
|
||||
|
||||
if (redirect < 301 || (redirect > 303 && redirect <= 306) || redirect > 307) {
|
||||
// if we somehow got some bogus redirect code here,
|
||||
// do a 302 redirect to the same URL as the report URI
|
||||
// redirects to - this will fail the test.
|
||||
var loc = "http://example.com/some/fake/path";
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
response.setHeader("Location", loc, false);
|
||||
return;
|
||||
}
|
||||
|
||||
var csp = "default-src \'self\';report-uri http://mochi.test:8888/tests/content/base/test/file_bug650386_report.sjs?" + redirect;
|
||||
|
||||
response.setHeader("X-Content-Security-Policy", csp, false);
|
||||
|
||||
// the actual file content.
|
||||
// this image load will (intentionally) fail due to the CSP policy of default-src: 'self'
|
||||
// specified by the CSP string above.
|
||||
var content = "<!DOCTYPE HTML><html><body><img src = \"http://some.other.domain.example.com\"></body></html>";
|
||||
|
||||
response.write(content);
|
||||
|
||||
return;
|
||||
}
|
16
content/base/test/file_bug650386_report.sjs
Normal file
16
content/base/test/file_bug650386_report.sjs
Normal file
@ -0,0 +1,16 @@
|
||||
// SJS file for tests for bug650386, this serves as CSP violation report target
|
||||
// and issues a redirect, to make sure the browser does not post to the target
|
||||
// of the redirect, per CSP spec.
|
||||
// This handles 301, 302, 303 and 307 redirects. The HTTP status code
|
||||
// returned/type of redirect to do comes from the query string
|
||||
// parameter
|
||||
function handleRequest(request, response) {
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
var redirect = request.queryString;
|
||||
|
||||
var loc = "http://example.com/some/fake/path";
|
||||
response.setStatusLine("1.1", redirect, "Found");
|
||||
response.setHeader("Location", loc, false);
|
||||
return;
|
||||
}
|
78
content/base/test/test_bug650386_redirect_301.html
Normal file
78
content/base/test/test_bug650386_redirect_301.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 301 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "http-on-modify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
// subject should be an nsURI
|
||||
if(!SpecialPowers.can_QI(subject))
|
||||
return;
|
||||
|
||||
if (topic === "http-on-modify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
|
||||
|
||||
if (asciiSpec == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "http-on-modify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 301 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?301';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
78
content/base/test/test_bug650386_redirect_302.html
Normal file
78
content/base/test/test_bug650386_redirect_302.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 302 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "http-on-modify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
// subject should be an nsURI
|
||||
if(!SpecialPowers.can_QI(subject))
|
||||
return;
|
||||
|
||||
if (topic === "http-on-modify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
|
||||
|
||||
if (asciiSpec == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "http-on-modify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 302 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?302';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
78
content/base/test/test_bug650386_redirect_303.html
Normal file
78
content/base/test/test_bug650386_redirect_303.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 303 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "http-on-modify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
// subject should be an nsURI
|
||||
if(!SpecialPowers.can_QI(subject))
|
||||
return;
|
||||
|
||||
if (topic === "http-on-modify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
|
||||
|
||||
if (asciiSpec == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "http-on-modify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 303 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?303';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
78
content/base/test/test_bug650386_redirect_307.html
Normal file
78
content/base/test/test_bug650386_redirect_307.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=650386
|
||||
Test that CSP violation reports are not sent when a 307 redirect is encountered
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 650386</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650386">Mozilla Bug 650386</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id = "content_iframe"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 650386 **/
|
||||
|
||||
// This is used to watch the redirect of the report POST get blocked
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "http-on-modify-request", false);
|
||||
}
|
||||
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
// subject should be an nsURI
|
||||
if(!SpecialPowers.can_QI(subject))
|
||||
return;
|
||||
|
||||
if (topic === "http-on-modify-request") {
|
||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||
// we know this is a fail
|
||||
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
|
||||
|
||||
if (asciiSpec == "http://example.com/some/fake/path")
|
||||
window.done(false);
|
||||
}
|
||||
|
||||
if(topic === "csp-on-violate-policy") {
|
||||
// something was blocked, but we are looking specifically for the redirect being blocked
|
||||
if (data == "denied redirect while sending violation report")
|
||||
window.done(true);
|
||||
}
|
||||
},
|
||||
|
||||
// must eventually call this to remove the listener,
|
||||
// or mochitests might get borked.
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "http-on-modify-request");
|
||||
}
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
// result == true if we saw the redirect blocked notify, false if we saw the post
|
||||
// to the redirect target go out
|
||||
window.done = function(result) {
|
||||
ok(result, "a 307 redirect when posting violation report should be blocked");
|
||||
|
||||
// clean up observers and finish the test
|
||||
window.examiner.remove();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
document.getElementById('content_iframe').src = 'file_bug650386_content.sjs?307';
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -2695,7 +2695,8 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame,
|
||||
nsMouseScrollEvent* aMouseEvent,
|
||||
nsIScrollableFrame::ScrollUnit aScrollQuantity,
|
||||
bool aAllowScrollSpeedOverride,
|
||||
nsQueryContentEvent* aQueryEvent)
|
||||
nsQueryContentEvent* aQueryEvent,
|
||||
nsIAtom *aOrigin)
|
||||
{
|
||||
nsIScrollableFrame* frameToScroll = nsnull;
|
||||
nsIFrame* scrollFrame = aTargetFrame;
|
||||
@ -2857,7 +2858,7 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame,
|
||||
|
||||
nsIntPoint overflow;
|
||||
frameToScroll->ScrollBy(nsIntPoint(scrollX, scrollY), aScrollQuantity,
|
||||
mode, &overflow);
|
||||
mode, &overflow, aOrigin);
|
||||
aMouseEvent->scrollOverflow = isHorizontal ? overflow.x : overflow.y;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2867,7 +2868,7 @@ nsEventStateManager::DoScrollText(nsIFrame* aTargetFrame,
|
||||
aTargetFrame->PresContext()->FrameManager()->GetRootFrame());
|
||||
if (newFrame)
|
||||
return DoScrollText(newFrame, aMouseEvent, aScrollQuantity,
|
||||
aAllowScrollSpeedOverride, aQueryEvent);
|
||||
aAllowScrollSpeedOverride, aQueryEvent, aOrigin);
|
||||
}
|
||||
|
||||
aMouseEvent->scrollOverflow = numLines;
|
||||
@ -3213,7 +3214,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
switch (action) {
|
||||
case MOUSE_SCROLL_N_LINES:
|
||||
DoScrollText(aTargetFrame, msEvent, nsIScrollableFrame::LINES,
|
||||
useSysNumLines);
|
||||
useSysNumLines, nsnull, nsGkAtoms::mouseWheel);
|
||||
break;
|
||||
|
||||
case MOUSE_SCROLL_PAGE:
|
||||
@ -3222,8 +3223,11 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
break;
|
||||
|
||||
case MOUSE_SCROLL_PIXELS:
|
||||
DoScrollText(aTargetFrame, msEvent, nsIScrollableFrame::DEVICE_PIXELS,
|
||||
false);
|
||||
{
|
||||
bool fromLines = msEvent->scrollFlags & nsMouseScrollEvent::kFromLines;
|
||||
DoScrollText(aTargetFrame, msEvent, nsIScrollableFrame::DEVICE_PIXELS,
|
||||
false, nsnull, (fromLines ? nsGkAtoms::mouseWheel : nsnull));
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_SCROLL_HISTORY:
|
||||
|
@ -353,7 +353,8 @@ protected:
|
||||
nsMouseScrollEvent* aMouseEvent,
|
||||
nsIScrollableFrame::ScrollUnit aScrollQuantity,
|
||||
bool aAllowScrollSpeedOverride,
|
||||
nsQueryContentEvent* aQueryEvent = nsnull);
|
||||
nsQueryContentEvent* aQueryEvent = nsnull,
|
||||
nsIAtom *aOrigin = nsnull);
|
||||
void DoScrollHistory(PRInt32 direction);
|
||||
void DoScrollZoom(nsIFrame *aTargetFrame, PRInt32 adjustment);
|
||||
nsresult GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv);
|
||||
|
@ -134,6 +134,7 @@
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsHtml5TreeOpExecutor.h"
|
||||
#include "nsHtml5Parser.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -1558,6 +1559,7 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
|
||||
// resetting the document.
|
||||
mSecurityInfo = securityInfo;
|
||||
|
||||
mParserAborted = false;
|
||||
bool loadAsHtml5 = nsHtml5Module::sEnabled;
|
||||
if (loadAsHtml5) {
|
||||
mParser = nsHtml5Module::NewHtml5Parser();
|
||||
@ -1644,8 +1646,8 @@ nsHTMLDocument::Close()
|
||||
}
|
||||
|
||||
++mWriteLevel;
|
||||
nsresult rv = mParser->Parse(EmptyString(), nsnull,
|
||||
GetContentTypeInternal(), true);
|
||||
nsresult rv = (static_cast<nsHtml5Parser*>(mParser.get()))->Parse(
|
||||
EmptyString(), nsnull, GetContentTypeInternal(), true);
|
||||
--mWriteLevel;
|
||||
|
||||
// XXX Make sure that all the document.written content is
|
||||
@ -1701,6 +1703,13 @@ nsHTMLDocument::WriteCommon(JSContext *cx,
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
if (mParserAborted) {
|
||||
// Hixie says aborting the parser doesn't undefine the insertion point.
|
||||
// However, since we null out mParser in that case, we track the
|
||||
// theoretically defined insertion point using mParserAborted.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
void *key = GenerateParserKey();
|
||||
@ -1764,13 +1773,11 @@ nsHTMLDocument::WriteCommon(JSContext *cx,
|
||||
// since the concatenation of strings costs more than we like. And
|
||||
// why pay that price when we don't need to?
|
||||
if (aNewlineTerminate) {
|
||||
rv = mParser->Parse(aText + new_line,
|
||||
key, GetContentTypeInternal(),
|
||||
false);
|
||||
rv = (static_cast<nsHtml5Parser*>(mParser.get()))->Parse(
|
||||
aText + new_line, key, GetContentTypeInternal(), false);
|
||||
} else {
|
||||
rv = mParser->Parse(aText,
|
||||
key, GetContentTypeInternal(),
|
||||
false);
|
||||
rv = (static_cast<nsHtml5Parser*>(mParser.get()))->Parse(
|
||||
aText, key, GetContentTypeInternal(), false);
|
||||
}
|
||||
|
||||
--mWriteLevel;
|
||||
|
@ -8348,13 +8348,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
sameExceptHashes && !newHash.IsEmpty());
|
||||
|
||||
if (doShortCircuitedLoad) {
|
||||
// If our load group contains a LOAD_DOCUMENT_URI request with a
|
||||
// channel which doesn't match our document's channel, cancel it.
|
||||
//
|
||||
// That is, a short-circuited load will cancel a non-short-circuited
|
||||
// load of a different document.
|
||||
StopOutstandingOtherDocumentLoad();
|
||||
|
||||
// Save the current URI; we need it if we fire a hashchange later.
|
||||
nsCOMPtr<nsIURI> oldURI = mCurrentURI;
|
||||
|
||||
@ -8654,47 +8647,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
return rv;
|
||||
}
|
||||
|
||||
// If our load group contains a LOAD_DOCUMENT_URI channel that's not our
|
||||
// document's channel, cancel it.
|
||||
void
|
||||
nsDocShell::StopOutstandingOtherDocumentLoad()
|
||||
{
|
||||
nsCOMPtr<nsIChannel> docChannel = GetCurrentDocChannel();
|
||||
if (!docChannel || !mLoadGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> requests;
|
||||
mLoadGroup->GetRequests(getter_AddRefs(requests));
|
||||
if (!requests) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
bool hasMoreElements = false;
|
||||
requests->HasMoreElements(&hasMoreElements);
|
||||
if (!hasMoreElements) {
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> next;
|
||||
requests->GetNext(getter_AddRefs(next));
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(next);
|
||||
if (!channel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsLoadFlags flags;
|
||||
channel->GetLoadFlags(&flags);
|
||||
|
||||
// As promised, cancel the channel if it's loading a different document.
|
||||
if ((flags & nsIChannel::LOAD_DOCUMENT_URI) && channel != docChannel) {
|
||||
channel->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsDocShell::GetInheritedPrincipal(bool aConsiderCurrentDocument)
|
||||
{
|
||||
|
@ -672,11 +672,6 @@ protected:
|
||||
nsresult EnsureCommandHandler();
|
||||
|
||||
nsIChannel* GetCurrentDocChannel();
|
||||
|
||||
// If our load group contains a LOAD_DOCUMENT_URI channel that's not our
|
||||
// document's channel, cancel it.
|
||||
void StopOutstandingOtherDocumentLoad();
|
||||
|
||||
protected:
|
||||
// Override the parent setter from nsDocLoader
|
||||
virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
|
||||
|
@ -1153,7 +1153,7 @@ Navigator::GetMozBluetooth(nsIDOMBluetoothAdapter** aBluetooth)
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||
|
||||
mBluetooth = new bluetooth::BluetoothAdapter();
|
||||
mBluetooth = new bluetooth::BluetoothAdapter(window);
|
||||
|
||||
bluetooth = mBluetooth;
|
||||
}
|
||||
|
@ -943,16 +943,17 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
nsIScriptGlobalObject *global = context->GetGlobalObject();
|
||||
// XXX should we check for sysprin instead of a chrome window, to make
|
||||
// XXX components be covered by the chrome pref instead of the content one?
|
||||
nsCOMPtr<nsIDOMWindow> contentWindow(do_QueryInterface(global));
|
||||
nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(global));
|
||||
|
||||
bool useMethodJIT = Preferences::GetBool(chromeWindow ?
|
||||
bool useMethodJIT = Preferences::GetBool(chromeWindow || !contentWindow ?
|
||||
js_methodjit_chrome_str :
|
||||
js_methodjit_content_str);
|
||||
bool usePCCounts = Preferences::GetBool(chromeWindow ?
|
||||
bool usePCCounts = Preferences::GetBool(chromeWindow || !contentWindow ?
|
||||
js_pccounts_chrome_str :
|
||||
js_pccounts_content_str);
|
||||
bool useMethodJITAlways = Preferences::GetBool(js_methodjit_always_str);
|
||||
bool useTypeInference = !chromeWindow && Preferences::GetBool(js_typeinfer_str);
|
||||
bool useTypeInference = !chromeWindow && contentWindow && Preferences::GetBool(js_typeinfer_str);
|
||||
bool useHardening = Preferences::GetBool(js_jit_hardening_str);
|
||||
nsCOMPtr<nsIXULRuntime> xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
|
||||
if (xr) {
|
||||
@ -992,7 +993,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
// javascript.options.strict.debug is true
|
||||
bool strictDebug = Preferences::GetBool(js_strict_debug_option_str);
|
||||
if (strictDebug && (newDefaultJSOptions & JSOPTION_STRICT) == 0) {
|
||||
if (chromeWindow)
|
||||
if (chromeWindow || !contentWindow)
|
||||
newDefaultJSOptions |= JSOPTION_STRICT;
|
||||
}
|
||||
#endif
|
||||
@ -2746,7 +2747,7 @@ nsJSContext::InitClasses(JSObject* aGlobalObj)
|
||||
|
||||
JSAutoRequest ar(mContext);
|
||||
|
||||
::JS_SetOptions(mContext, mDefaultJSOptions);
|
||||
JSOptionChangedCallback(js_options_dot_str, this);
|
||||
|
||||
// Attempt to initialize profiling functions
|
||||
::JS_DefineProfilingFunctions(mContext, aGlobalObj);
|
||||
|
@ -85,6 +85,7 @@ nsStructuredCloneContainer::InitFromVariant(nsIVariant *aData, JSContext *aCx)
|
||||
JSAutoRequest ar(aCx);
|
||||
JSAutoEnterCompartment ac;
|
||||
NS_ENSURE_STATE(ac.enter(aCx, JS_GetGlobalObject(aCx)));
|
||||
JS_WrapValue(aCx, &jsData);
|
||||
|
||||
nsCxPusher cxPusher;
|
||||
cxPusher.Push(aCx);
|
||||
|
@ -4,13 +4,33 @@
|
||||
* 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/. */
|
||||
|
||||
#include "BluetoothAdapter.h"
|
||||
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
#include "mozilla/LazyIdleThread.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include <dlfcn.h>
|
||||
#include "BluetoothAdapter.h"
|
||||
|
||||
static void
|
||||
FireEnabled(bool aResult, nsIDOMDOMRequest* aDomRequest)
|
||||
{
|
||||
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
|
||||
|
||||
if (!rs) {
|
||||
NS_WARNING("No DOMRequest Service!");
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::DebugOnly<nsresult> rv = aResult ?
|
||||
rs->FireSuccess(aDomRequest, JSVAL_VOID) :
|
||||
rs->FireError(aDomRequest,
|
||||
NS_LITERAL_STRING("Bluetooth firmware loading failed"));
|
||||
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Bluetooth firmware loading failed");
|
||||
}
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
@ -67,11 +87,16 @@ static bool EnsureBluetoothInit() {
|
||||
class ToggleBtResultTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ToggleBtResultTask(nsRefPtr<BluetoothAdapter>& adapterPtr, bool result)
|
||||
: mResult(result)
|
||||
ToggleBtResultTask(nsRefPtr<BluetoothAdapter>& adapterPtr,
|
||||
nsCOMPtr<nsIDOMDOMRequest>& req,
|
||||
bool enabled,
|
||||
bool result)
|
||||
: mResult(result),
|
||||
mEnabled(enabled)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
mDOMRequest.swap(req);
|
||||
mAdapterPtr.swap(adapterPtr);
|
||||
}
|
||||
|
||||
@ -79,29 +104,35 @@ class ToggleBtResultTask : public nsRunnable
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mResult) {
|
||||
//TODO:Bug-731361
|
||||
NS_WARNING("BT firmware loading fails.\n");
|
||||
// Update bt power status to BluetoothAdapter only if loading bluetooth
|
||||
// firmware succeeds.
|
||||
if (mResult) {
|
||||
mAdapterPtr->SetEnabledInternal(mEnabled);
|
||||
}
|
||||
|
||||
|
||||
FireEnabled(mResult, mDOMRequest);
|
||||
|
||||
//mAdapterPtr must be null before returning to prevent the background
|
||||
//thread from racing to release it during the destruction of this runnable.
|
||||
mAdapterPtr->FirePowered();
|
||||
mAdapterPtr = nsnull;
|
||||
mDOMRequest = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothAdapter> mAdapterPtr;
|
||||
nsCOMPtr<nsIDOMDOMRequest> mDOMRequest;
|
||||
bool mEnabled;
|
||||
bool mResult;
|
||||
};
|
||||
|
||||
class ToggleBtTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr)
|
||||
: mOnOff(onOff),
|
||||
ToggleBtTask(bool enabled, nsIDOMDOMRequest* req, BluetoothAdapter* adapterPtr)
|
||||
: mEnabled(enabled),
|
||||
mDOMRequest(req),
|
||||
mAdapterPtr(adapterPtr)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -111,23 +142,36 @@ class ToggleBtTask : public nsRunnable
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
bool result;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Platform specific check for gonk until object is divided in
|
||||
// different implementations per platform. Linux doesn't require
|
||||
// bluetooth firmware loading, but code should work otherwise.
|
||||
if(!EnsureBluetoothInit()) {
|
||||
NS_ERROR("Failed to load bluedroid library.\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool result;
|
||||
// return 1 if it's enabled, 0 if it's disabled, and -1 on error
|
||||
int isEnabled = sBluedroidFunctions.bt_is_enabled();
|
||||
|
||||
//Toggle BT here
|
||||
|
||||
if (mOnOff) {
|
||||
result = sBluedroidFunctions.bt_enable();
|
||||
if ((isEnabled == 1 && mEnabled) || (isEnabled == 0 && !mEnabled)) {
|
||||
result = true;
|
||||
} else if (isEnabled < 0) {
|
||||
result = false;
|
||||
} else if (mEnabled) {
|
||||
result = (sBluedroidFunctions.bt_enable() == 0) ? true : false;
|
||||
} else {
|
||||
result = sBluedroidFunctions.bt_disable();
|
||||
result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
|
||||
}
|
||||
#else
|
||||
result = true;
|
||||
NS_WARNING("No bluetooth support in this build configuration, faking a success event instead");
|
||||
#endif
|
||||
|
||||
// Create a result thread and pass it to Main Thread,
|
||||
nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(mAdapterPtr, result);
|
||||
nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(mAdapterPtr, mDOMRequest, mEnabled, result);
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(resultRunnable))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
@ -137,8 +181,9 @@ class ToggleBtTask : public nsRunnable
|
||||
}
|
||||
|
||||
private:
|
||||
bool mOnOff;
|
||||
bool mEnabled;
|
||||
nsRefPtr<BluetoothAdapter> mAdapterPtr;
|
||||
nsCOMPtr<nsIDOMDOMRequest> mDOMRequest;
|
||||
};
|
||||
|
||||
DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)
|
||||
@ -147,12 +192,12 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(powered)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(enabled)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(powered)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(enabled)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
|
||||
@ -163,77 +208,43 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
|
||||
BluetoothAdapter::BluetoothAdapter()
|
||||
: mPower(false)
|
||||
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow *aWindow)
|
||||
{
|
||||
BindToOwner(aWindow);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BluetoothAdapter::GetPower(bool* aPower)
|
||||
BluetoothAdapter::SetEnabled(bool aEnabled, nsIDOMDOMRequest** aDomRequest)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if(!EnsureBluetoothInit()) {
|
||||
NS_ERROR("Failed to load bluedroid library.\n");
|
||||
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
|
||||
|
||||
if (!rs) {
|
||||
NS_ERROR("No DOMRequest Service!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*aPower = sBluedroidFunctions.bt_is_enabled();
|
||||
#else
|
||||
*aPower = mPower;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BluetoothAdapter::SetPower(bool aPower)
|
||||
{
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Platform specific check for gonk until object is divided in
|
||||
// different implementations per platform. Linux doesn't require
|
||||
// bluetooth firmware loading, but code should work otherwise.
|
||||
if(!EnsureBluetoothInit()) {
|
||||
NS_ERROR("Failed to load bluedroid library.\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
if (mPower != aPower) {
|
||||
mPower = aPower;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
return ToggleBluetoothAsync();
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothAdapter::ToggleBluetoothAsync()
|
||||
{
|
||||
nsCOMPtr<nsIDOMDOMRequest> request;
|
||||
nsresult rv = rs->CreateRequest(GetOwner(), getter_AddRefs(request));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mToggleBtThread) {
|
||||
mToggleBtThread = new LazyIdleThread(15000);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(mPower, this);
|
||||
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(aEnabled, request, this);
|
||||
|
||||
return mToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothAdapter::FirePowered()
|
||||
{
|
||||
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
|
||||
nsresult rv = event->InitEvent(NS_LITERAL_STRING("powered"), false, false);
|
||||
rv = mToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = event->SetTrusted(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool dummy;
|
||||
rv = DispatchEvent(event, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
request.forget(aDomRequest);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, powered)
|
||||
NS_IMETHODIMP
|
||||
BluetoothAdapter::GetEnabled(bool* aEnabled)
|
||||
{
|
||||
*aEnabled = mEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "BluetoothCommon.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsIDOMBluetoothAdapter.h"
|
||||
#include "nsIDOMDOMRequest.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
||||
@ -27,19 +28,19 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
|
||||
BluetoothAdapter();
|
||||
BluetoothAdapter(nsPIDOMWindow*);
|
||||
|
||||
nsresult FirePowered();
|
||||
inline void SetEnabledInternal(bool aEnabled) {mEnabled = aEnabled;}
|
||||
|
||||
protected:
|
||||
bool mPower;
|
||||
bool mEnabled;
|
||||
|
||||
NS_DECL_EVENT_HANDLER(powered)
|
||||
NS_DECL_EVENT_HANDLER(enabled)
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIEventTarget> mToggleBtThread;
|
||||
nsresult ToggleBluetoothAsync();
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
@ -6,12 +6,13 @@
|
||||
|
||||
#include "nsIDOMEventTarget.idl"
|
||||
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIDOMEventListener;
|
||||
|
||||
[scriptable, builtinclass, uuid(3dbaa9f4-5c93-11e1-8592-ff9bfcc3ab4b)]
|
||||
[scriptable, builtinclass, uuid(ac288eab-dcdb-4f6a-b94d-6c0e286d6a73)]
|
||||
interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
|
||||
{
|
||||
attribute boolean power;
|
||||
readonly attribute bool enabled;
|
||||
|
||||
attribute nsIDOMEventListener onpowered;
|
||||
nsIDOMDOMRequest setEnabled(in boolean enabled);
|
||||
};
|
||||
|
@ -344,6 +344,13 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBKeyRange)
|
||||
|
||||
DOMCI_DATA(IDBKeyRange, IDBKeyRange)
|
||||
|
||||
IDBKeyRange::~IDBKeyRange()
|
||||
{
|
||||
if (mRooted) {
|
||||
NS_DROP_JS_OBJECTS(this, IDBKeyRange);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBKeyRange::GetLower(JSContext* aCx,
|
||||
jsval* aLower)
|
||||
|
@ -170,7 +170,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
~IDBKeyRange() { }
|
||||
~IDBKeyRange();
|
||||
|
||||
Key mLower;
|
||||
Key mUpper;
|
||||
|
@ -1318,8 +1318,6 @@ nsDOMStorage::nsDOMStorage()
|
||||
: mStorageType(nsPIDOMStorage::Unknown)
|
||||
, mEventBroadcaster(nsnull)
|
||||
{
|
||||
mSecurityChecker = this;
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default)
|
||||
mStorageImpl = new StorageChild(this);
|
||||
else
|
||||
@ -1328,10 +1326,9 @@ nsDOMStorage::nsDOMStorage()
|
||||
|
||||
nsDOMStorage::nsDOMStorage(nsDOMStorage& aThat)
|
||||
: mStorageType(aThat.mStorageType)
|
||||
, mPrincipal(aThat.mPrincipal)
|
||||
, mEventBroadcaster(nsnull)
|
||||
{
|
||||
mSecurityChecker = this;
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
StorageChild* other = static_cast<StorageChild*>(aThat.mStorageImpl.get());
|
||||
mStorageImpl = new StorageChild(this, *other);
|
||||
@ -1382,6 +1379,7 @@ nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mDocumentURI = aDocumentURI;
|
||||
mPrincipal = aPrincipal;
|
||||
|
||||
mStorageType = SessionStorage;
|
||||
|
||||
@ -1397,6 +1395,7 @@ nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aD
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mDocumentURI = aDocumentURI;
|
||||
mPrincipal = aPrincipal;
|
||||
|
||||
mStorageType = LocalStorage;
|
||||
|
||||
@ -1495,8 +1494,7 @@ nsDOMStorage::CacheStoragePermissions()
|
||||
nsresult rv = ssm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
NS_ASSERTION(mSecurityChecker, "Has non-null mSecurityChecker");
|
||||
return mSecurityChecker->CanAccess(subjectPrincipal);
|
||||
return CanAccess(subjectPrincipal);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -1729,17 +1727,17 @@ nsDOMStorage::CanAccessSystem(nsIPrincipal *aPrincipal)
|
||||
bool
|
||||
nsDOMStorage::CanAccess(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
// Allow C++/system callers to access the storage
|
||||
if (CanAccessSystem(aPrincipal))
|
||||
// Allow C++ callers to access the storage
|
||||
if (!aPrincipal)
|
||||
return true;
|
||||
|
||||
nsCAutoString domain;
|
||||
nsCOMPtr<nsIURI> unused;
|
||||
nsresult rv = GetPrincipalURIAndHost(aPrincipal,
|
||||
getter_AddRefs(unused), domain);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
// Allow more powerful principals (e.g. system) to access the storage
|
||||
bool subsumes;
|
||||
nsresult rv = aPrincipal->SubsumesIgnoringDomain(mPrincipal, &subsumes);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
return domain.Equals(mStorageImpl->mDomain);
|
||||
return subsumes;
|
||||
}
|
||||
|
||||
nsPIDOMStorage::nsDOMStorageType
|
||||
@ -1797,7 +1795,6 @@ nsDOMStorage2::nsDOMStorage2()
|
||||
nsDOMStorage2::nsDOMStorage2(nsDOMStorage2& aThat)
|
||||
{
|
||||
mStorage = new nsDOMStorage(*aThat.mStorage.get());
|
||||
mStorage->mSecurityChecker = mStorage;
|
||||
mPrincipal = aThat.mPrincipal;
|
||||
}
|
||||
|
||||
@ -1808,7 +1805,6 @@ nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring
|
||||
if (!mStorage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mStorage->mSecurityChecker = this;
|
||||
mPrincipal = aPrincipal;
|
||||
mDocumentURI = aDocumentURI;
|
||||
|
||||
@ -1822,7 +1818,6 @@ nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &a
|
||||
if (!mStorage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mStorage->mSecurityChecker = this;
|
||||
mPrincipal = aPrincipal;
|
||||
mDocumentURI = aDocumentURI;
|
||||
|
||||
@ -1892,20 +1887,7 @@ nsDOMStorage2::Principal()
|
||||
bool
|
||||
nsDOMStorage2::CanAccess(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
if (mStorage->mSecurityChecker != this)
|
||||
return mStorage->mSecurityChecker->CanAccess(aPrincipal);
|
||||
|
||||
// Allow C++ callers to access the storage
|
||||
if (!aPrincipal)
|
||||
return true;
|
||||
|
||||
// Allow more powerful principals (e.g. system) to access the storage
|
||||
bool subsumes;
|
||||
nsresult rv = aPrincipal->SubsumesIgnoringDomain(mPrincipal, &subsumes);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
return subsumes;
|
||||
return mStorage->CanAccess(aPrincipal);
|
||||
}
|
||||
|
||||
nsPIDOMStorage::nsDOMStorageType
|
||||
|
@ -419,7 +419,7 @@ public:
|
||||
nsDOMStorageType mStorageType;
|
||||
|
||||
friend class nsIDOMStorage2;
|
||||
nsPIDOMStorage* mSecurityChecker;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsPIDOMStorage* mEventBroadcaster;
|
||||
};
|
||||
|
||||
|
@ -142,8 +142,8 @@ function RadioInterfaceLayer() {
|
||||
this.worker.onmessage = this.onmessage.bind(this);
|
||||
debug("Starting Worker\n");
|
||||
this.radioState = {
|
||||
radioState: null,
|
||||
cardState: null,
|
||||
radioState: RIL.GECKO_RADIOSTATE_UNAVAILABLE,
|
||||
cardState: RIL.GECKO_CARDSTATE_UNAVAILABLE,
|
||||
connected: null,
|
||||
roaming: null,
|
||||
signalStrength: null,
|
||||
@ -194,15 +194,15 @@ RadioInterfaceLayer.prototype = {
|
||||
// This one will handle its own notifications.
|
||||
this.handleEnumerateCalls(message.calls);
|
||||
break;
|
||||
case "registrationstatechange":
|
||||
this.updateDataConnection(message.registrationState);
|
||||
case "voiceregistrationstatechange":
|
||||
this.updateDataConnection(message.voiceRegistrationState);
|
||||
break;
|
||||
case "gprsregistrationstatechange":
|
||||
let state = message.gprsRegistrationState;
|
||||
case "dataregistrationstatechange":
|
||||
let state = message.dataRegistrationState;
|
||||
this.updateDataConnection(state);
|
||||
|
||||
//TODO for simplicity's sake, for now we only look at
|
||||
// gprsRegistrationState for the radio registration state.
|
||||
// dataRegistrationState for the radio registration state.
|
||||
|
||||
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
|
||||
this.resetRadioState();
|
||||
@ -282,6 +282,9 @@ RadioInterfaceLayer.prototype = {
|
||||
case "siminfo":
|
||||
this.radioState.msisdn = message.msisdn;
|
||||
break;
|
||||
case "error":
|
||||
debug("Received error message: " + JSON.stringify(message));
|
||||
break;
|
||||
default:
|
||||
throw new Error("Don't know about this message type: " + message.type);
|
||||
}
|
||||
@ -1083,7 +1086,8 @@ let RILNetworkInterface = {
|
||||
|
||||
dataCallStateChanged: function dataCallStateChanged(cid, interfaceName, callState) {
|
||||
if (this.connecting &&
|
||||
callState == RIL.GECKO_NETWORK_STATE_CONNECTING) {
|
||||
(callState == RIL.GECKO_NETWORK_STATE_CONNECTING ||
|
||||
callState == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
|
||||
this.connecting = false;
|
||||
this.cid = cid;
|
||||
this.name = interfaceName;
|
||||
|
@ -57,8 +57,8 @@ const REQUEST_CONFERENCE = 16;
|
||||
const REQUEST_UDUB = 17;
|
||||
const REQUEST_LAST_CALL_FAIL_CAUSE = 18;
|
||||
const REQUEST_SIGNAL_STRENGTH = 19;
|
||||
const REQUEST_REGISTRATION_STATE = 20;
|
||||
const REQUEST_GPRS_REGISTRATION_STATE = 21;
|
||||
const REQUEST_VOICE_REGISTRATION_STATE = 20;
|
||||
const REQUEST_DATA_REGISTRATION_STATE = 21;
|
||||
const REQUEST_OPERATOR = 22;
|
||||
const REQUEST_RADIO_POWER = 23;
|
||||
const REQUEST_DTMF = 24;
|
||||
@ -114,7 +114,7 @@ const REQUEST_SET_PREFERRED_NETWORK_TYPE = 73;
|
||||
const REQUEST_GET_PREFERRED_NETWORK_TYPE = 74;
|
||||
const REQUEST_GET_NEIGHBORING_CELL_IDS = 75;
|
||||
const REQUEST_SET_LOCATION_UPDATES = 76;
|
||||
const REQUEST_CDMA_SET_SUBSCRIPTION = 77;
|
||||
const REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE = 77;
|
||||
const REQUEST_CDMA_SET_ROAMING_PREFERENCE = 78;
|
||||
const REQUEST_CDMA_QUERY_ROAMING_PREFERENCE = 79;
|
||||
const REQUEST_SET_TTY_MODE = 80;
|
||||
@ -141,6 +141,28 @@ const REQUEST_GET_SMSC_ADDRESS = 100;
|
||||
const REQUEST_SET_SMSC_ADDRESS = 101;
|
||||
const REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
|
||||
const REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
|
||||
const REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
|
||||
const REQUEST_ISIM_AUTHENTICATION = 105;
|
||||
const REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
|
||||
const REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
|
||||
|
||||
// Akami/Maguro specific parcel types.
|
||||
const REQUEST_VOICE_RADIO_TECH = 105;
|
||||
const REQUEST_IMS_REGISTRATION_STATE = 106;
|
||||
const REQUEST_IMS_SEND_SMS = 107;
|
||||
const REQUEST_GET_DATA_CALL_PROFILE = 108;
|
||||
const REQUEST_SET_UICC_SUBSCRIPTION = 109;
|
||||
const REQUEST_SET_DATA_SUBSCRIPTION = 110;
|
||||
const REQUEST_GET_UICC_SUBSCRIPTION = 111;
|
||||
const REQUEST_GET_DATA_SUBSCRIPTION = 112;
|
||||
const REQUEST_SET_SUBSCRIPTION_MODE = 113;
|
||||
const REQUEST_SET_TRANSMIT_POWER = 114;
|
||||
const REQUEST_SETUP_QOS = 115;
|
||||
const REQUEST_RELEASE_QOS = 116;
|
||||
const REQUEST_GET_QOS_STATUS = 117;
|
||||
const REQUEST_MODIFY_QOS = 118;
|
||||
const REQUEST_SUSPEND_QOS = 119;
|
||||
const REQUEST_RESUME_QOS = 120;
|
||||
|
||||
const RESPONSE_TYPE_SOLICITED = 0;
|
||||
const RESPONSE_TYPE_UNSOLICITED = 1;
|
||||
@ -148,7 +170,7 @@ const RESPONSE_TYPE_UNSOLICITED = 1;
|
||||
const UNSOLICITED_RESPONSE_BASE = 1000;
|
||||
const UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED = 1000;
|
||||
const UNSOLICITED_RESPONSE_CALL_STATE_CHANGED = 1001;
|
||||
const UNSOLICITED_RESPONSE_NETWORK_STATE_CHANGED = 1002;
|
||||
const UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
|
||||
const UNSOLICITED_RESPONSE_NEW_SMS = 1003;
|
||||
const UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
|
||||
const UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM = 1005;
|
||||
@ -177,6 +199,20 @@ const UNSOLICITED_CDMA_INFO_REC = 1027;
|
||||
const UNSOLICITED_OEM_HOOK_RAW = 1028;
|
||||
const UNSOLICITED_RINGBACK_TONE = 1029;
|
||||
const UNSOLICITED_RESEND_INCALL_MUTE = 1030;
|
||||
const UNSOLICITED_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 1031;
|
||||
const UNSOLICITED_CDMA_PRL_CHANGED = 1032;
|
||||
const UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
|
||||
const UNSOLICITED_RIL_CONNECTED = 1034;
|
||||
|
||||
// Akami/Maguro specific parcels.
|
||||
const UNSOLICITED_VOICE_RADIO_TECH_CHANGED = 1034;
|
||||
const UNSOLICITED_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1035;
|
||||
const UNSOLICITED_RESPONSE_TETHERED_MODE_STATE_CHANGED = 1036;
|
||||
const UNSOLICITED_RESPONSE_DATA_NETWORK_STATE_CHANGED = 1037;
|
||||
const UNSOLICITED_ON_SS = 1038;
|
||||
const UNSOLICITED_STK_CC_ALPHA_NOTIFY = 1039;
|
||||
const UNSOLICITED_UICC_SUBSCRIPTION_STATUS_CHANGED = 1040;
|
||||
const UNSOLICITED_QOS_STATE_CHANGED_IND = 1041;
|
||||
|
||||
const ERROR_SUCCESS = 0;
|
||||
const ERROR_RADIO_NOT_AVAILABLE = 1;
|
||||
@ -194,9 +230,22 @@ const ERROR_SUBSCRIPTION_NOT_AVAILABLE = 12;
|
||||
const ERROR_MODE_NOT_SUPPORTED = 13;
|
||||
const ERROR_FDN_CHECK_FAILURE = 14;
|
||||
const ERROR_ILLEGAL_SIM_OR_ME = 15;
|
||||
const ERROR_DIAL_MODIFIED_TO_USSD = 17;
|
||||
const ERROR_DIAL_MODIFIED_TO_SS = 18;
|
||||
const ERROR_DIAL_MODIFIED_TO_DIAL = 19;
|
||||
const ERROR_USSD_MODIFIED_TO_DIAL = 20;
|
||||
const ERROR_USSD_MODIFIED_TO_SS = 21;
|
||||
const ERROR_USSD_MODIFIED_TO_USSD = 22;
|
||||
const ERROR_SS_MODIFIED_TO_DIAL = 23;
|
||||
const ERROR_SS_MODIFIED_TO_USSD = 24;
|
||||
const ERROR_SS_MODIFIED_TO_SS = 25;
|
||||
const ERROR_SUBSCRIPTION_NOT_SUPPORTED = 26;
|
||||
|
||||
const RADIO_STATE_OFF = 0;
|
||||
const RADIO_STATE_UNAVAILABLE = 1;
|
||||
const RADIO_STATE_ON = 2;
|
||||
|
||||
// RIL v5 legacy constants:
|
||||
const RADIO_STATE_SIM_NOT_READY = 2;
|
||||
const RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3;
|
||||
const RADIO_STATE_SIM_READY = 4;
|
||||
@ -210,17 +259,74 @@ const CARD_STATE_ABSENT = 0;
|
||||
const CARD_STATE_PRESENT = 1;
|
||||
const CARD_STATE_ERROR = 2;
|
||||
|
||||
const CARD_APP_STATE_UNKNOWN = 0;
|
||||
const CARD_APP_STATE_DETECTED = 1;
|
||||
const CARD_APP_STATE_PIN = 2; // If PIN1 or UPin is required.
|
||||
const CARD_APP_STATE_PUK = 3; // If PUK1 or Puk for UPin is required.
|
||||
const CARD_APP_STATE_SUBSCRIPTION_PERSO = 4; // perso_substate should be looked
|
||||
// at when app_state is assigned
|
||||
// to this value.
|
||||
const CARD_APP_STATE_READY = 5;
|
||||
const CARD_PERSOSUBSTATE_UNKNOWN = 0;
|
||||
const CARD_PERSOSUBSTATE_IN_PROGRESS = 1;
|
||||
const CARD_PERSOSUBSTATE_READY = 2;
|
||||
const CARD_PERSOSUBSTATE_SIM_NETWORK = 3;
|
||||
const CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET = 4;
|
||||
const CARD_PERSOSUBSTATE_SIM_CORPORATE = 5;
|
||||
const CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER = 6;
|
||||
const CARD_PERSOSUBSTATE_SIM_SIM = 7;
|
||||
const CARD_PERSOSUBSTATE_SIM_NETWORK_PUK = 8;
|
||||
const CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK = 9;
|
||||
const CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK = 10;
|
||||
const CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK = 11;
|
||||
const CARD_PERSOSUBSTATE_SIM_SIM_PUK = 12;
|
||||
const CARD_PERSOSUBSTATE_RUIM_NETWORK1 = 13;
|
||||
const CARD_PERSOSUBSTATE_RUIM_NETWORK2 = 14;
|
||||
const CARD_PERSOSUBSTATE_RUIM_HRPD = 15;
|
||||
const CARD_PERSOSUBSTATE_RUIM_CORPORATE = 16;
|
||||
const CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER = 17;
|
||||
const CARD_PERSOSUBSTATE_RUIM_RUIM = 18;
|
||||
const CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK = 19;
|
||||
const CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK = 20;
|
||||
const CARD_PERSOSUBSTATE_RUIM_HRPD_PUK = 21;
|
||||
const CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK = 22;
|
||||
const CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23;
|
||||
const CARD_PERSOSUBSTATE_RUIM_RUIM_PUK = 24;
|
||||
|
||||
const CARD_APPSTATE_ILLEGAL = -1;
|
||||
const CARD_APPSTATE_UNKNOWN = 0;
|
||||
const CARD_APPSTATE_DETECTED = 1;
|
||||
const CARD_APPSTATE_PIN = 2; // If PIN1 or UPin is required.
|
||||
const CARD_APPSTATE_PUK = 3; // If PUK1 or Puk for UPin is required.
|
||||
const CARD_APPSTATE_SUBSCRIPTION_PERSO = 4; // perso_substate should be looked
|
||||
// at when app_state is assigned
|
||||
// to this value.
|
||||
const CARD_APPSTATE_READY = 5;
|
||||
|
||||
const CARD_PINSTATE_UNKNOWN = 0;
|
||||
const CARD_PINSTATE_ENABLED_NOT_VERIFIED = 1;
|
||||
const CARD_PINSTATE_ENABLED_VERIFIED = 2;
|
||||
const CARD_PINSTATE_DISABLED = 3;
|
||||
const CARD_PINSTATE_ENABLED_BLOCKED = 4;
|
||||
const CARD_PINSTATE_ENABLED_PERM_BLOCKED = 5;
|
||||
|
||||
const CARD_APPTYPE_UNKNOWN = 0;
|
||||
const CARD_APPTYPE_SIM = 1;
|
||||
const CARD_APPTYPE_USIM = 2;
|
||||
const CARD_APPTYPE_RUIM = 3;
|
||||
const CARD_APPTYPE_CSIM = 4;
|
||||
const CARD_APPTYPE_ISIM = 5;
|
||||
|
||||
const CARD_MAX_APPS = 8;
|
||||
|
||||
const NETWORK_SELECTION_MODE_AUTOMATIC = 0;
|
||||
const NETWORK_SELECTION_MODE_MANUAL = 1;
|
||||
|
||||
const PREFERRED_NETWORK_TYPE_GSM_WCDMA = 0;
|
||||
const PREFERRED_NETWORK_TYPE_GSM_ONLY = 1;
|
||||
const PREFERRED_NETWORK_TYPE_WCDMA = 2;
|
||||
const PREFERRED_NETWORK_TYPE_GSM_WCDMA_AUTO = 3;
|
||||
const PREFERRED_NETWORK_TYPE_CDMA_EVDO_AUTO = 4;
|
||||
const PREFERRED_NETWORK_TYPE_CDMA_ONLY = 5;
|
||||
const PREFERRED_NETWORK_TYPE_EVDO_ONLY = 6;
|
||||
const PREFERRED_NETWORK_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7;
|
||||
const PREFERRED_NETWORK_TYPE_LTE_CDMA_EVDO = 8;
|
||||
const PREFERRED_NETWORK_TYPE_LTE_GSM_WCDMA = 9;
|
||||
const PREFERRED_NETWORK_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10;
|
||||
const PREFERRED_NETWORK_TYPE_LTE_ONLY = 11;
|
||||
|
||||
// Network registration states. See TS 27.007 7.2
|
||||
const NETWORK_CREG_STATE_NOT_SEARCHING = 0;
|
||||
const NETWORK_CREG_STATE_REGISTERED_HOME = 1;
|
||||
@ -242,6 +348,9 @@ const NETWORK_CREG_TECH_HSDPA = 9;
|
||||
const NETWORK_CREG_TECH_HSUPA = 10;
|
||||
const NETWORK_CREG_TECH_HSPA = 11;
|
||||
const NETWORK_CREG_TECH_EVDOB = 12;
|
||||
const NETWORK_CREG_TECH_EHRPD = 13;
|
||||
const NETWORK_CREG_TECH_LTE = 14;
|
||||
const NETWORK_CREG_TECH_HSPAP = 15;
|
||||
|
||||
const CALL_STATE_ACTIVE = 0;
|
||||
const CALL_STATE_HOLDING = 1;
|
||||
@ -1094,6 +1203,9 @@ const PDU_NL_SINGLE_SHIFT_TABLES = [
|
||||
+ " "
|
||||
];
|
||||
|
||||
const RADIOTECH_FAMILY_3GPP = 1; // GSM, WCDMA, LTE
|
||||
const RADIOTECH_FAMILY_3GPP2 = 2; // CDMA, EVDO
|
||||
|
||||
const DATACALL_RADIOTECHNOLOGY_CDMA = 0;
|
||||
const DATACALL_RADIOTECHNOLOGY_GSM = 1;
|
||||
|
||||
@ -1114,6 +1226,30 @@ const DATACALL_INACTIVE = 0;
|
||||
const DATACALL_ACTIVE_DOWN = 1;
|
||||
const DATACALL_ACTIVE_UP = 2;
|
||||
|
||||
const DATACALL_FAIL_NONE = 0;
|
||||
const DATACALL_FAIL_OPERATOR_BARRED = 0x08;
|
||||
const DATACALL_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
|
||||
const DATACALL_FAIL_MISSING_UKNOWN_APN = 0x1B;
|
||||
const DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
|
||||
const DATACALL_FAIL_USER_AUTHENTICATION = 0x1D;
|
||||
const DATACALL_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
|
||||
const DATACALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
|
||||
const DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
|
||||
const DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
|
||||
const DATACALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
|
||||
const DATACALL_FAIL_NSAPI_IN_USE = 0x23;
|
||||
const DATACALL_FAIL_ONLY_IPV4_ALLOWED = 0x32;
|
||||
const DATACALL_FAIL_ONLY_IPV6_ALLOWED = 0x33;
|
||||
const DATACALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34;
|
||||
const DATACALL_FAIL_PROTOCOL_ERRORS = 0x6F;
|
||||
const DATACALL_FAIL_VOICE_REGISTRATION_FAIL = -1;
|
||||
const DATACALL_FAIL_DATA_REGISTRATION_FAIL = -2;
|
||||
const DATACALL_FAIL_SIGNAL_LOST = -3;
|
||||
const DATACALL_FAIL_PREF_RADIO_TECH_CHANGED = -4;
|
||||
const DATACALL_FAIL_RADIO_POWER_OFF = -5;
|
||||
const DATACALL_FAIL_TETHERED_CALL_ACTIVE = -6;
|
||||
const DATACALL_FAIL_ERROR_UNSPECIFIED = 0xffff;
|
||||
|
||||
// Keep consistent with nsINetworkManager.NETWORK_STATE_*.
|
||||
const GECKO_NETWORK_STATE_UNKNOWN = -1;
|
||||
const GECKO_NETWORK_STATE_CONNECTING = 0;
|
||||
@ -1123,7 +1259,7 @@ const GECKO_NETWORK_STATE_DISCONNECTING = 3;
|
||||
const GECKO_NETWORK_STATE_DISCONNECTED = 4;
|
||||
|
||||
// Other Gecko-specific constants
|
||||
const GECKO_RADIOSTATE_UNAVAILABLE = "unavailable";
|
||||
const GECKO_RADIOSTATE_UNAVAILABLE = null;
|
||||
const GECKO_RADIOSTATE_OFF = "off";
|
||||
const GECKO_RADIOSTATE_READY = "ready";
|
||||
|
||||
@ -1149,6 +1285,9 @@ const GECKO_RADIO_TECH = [
|
||||
"hsupa",
|
||||
"hspa",
|
||||
"evdob",
|
||||
"ehrpd",
|
||||
"lte",
|
||||
"hspa+",
|
||||
];
|
||||
|
||||
// Allow this file to be imported via Components.utils.import().
|
||||
|
@ -77,6 +77,9 @@ const PARCEL_SIZE_SIZE = UINT32_SIZE;
|
||||
|
||||
let RILQUIRKS_CALLSTATE_EXTRA_UINT32 = false;
|
||||
let RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = false;
|
||||
// This flag defaults to true since on RIL v6 and later, we get the
|
||||
// version number via the UNSOLICITED_RIL_CONNECTED parcel.
|
||||
let RILQUIRKS_V5_LEGACY = true;
|
||||
|
||||
/**
|
||||
* This object contains helpers buffering incoming data & deconstructing it
|
||||
@ -554,7 +557,7 @@ let RIL = {
|
||||
/**
|
||||
* One of the RADIO_STATE_* constants.
|
||||
*/
|
||||
radioState: RADIO_STATE_UNAVAILABLE,
|
||||
radioState: GECKO_RADIOSTATE_UNAVAILABLE,
|
||||
|
||||
/**
|
||||
* ICC status. Keeps a reference of the data response to the
|
||||
@ -576,8 +579,8 @@ let RIL = {
|
||||
SMSC: null,
|
||||
MSISDN: null,
|
||||
|
||||
registrationState: {},
|
||||
gprsRegistrationState: {},
|
||||
voiceRegistrationState: {},
|
||||
dataRegistrationState: {},
|
||||
|
||||
/**
|
||||
* List of strings identifying the network operator.
|
||||
@ -651,6 +654,13 @@ let RIL = {
|
||||
RILQUIRKS_CALLSTATE_EXTRA_UINT32 = true;
|
||||
RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = true;
|
||||
}
|
||||
if (model_id == "I9023" || model_id == "I9020") {
|
||||
if (DEBUG) {
|
||||
debug("Detected I9020/I9023, enabling " +
|
||||
"RILQUIRKS_DATACALLSTATE_DOWN_IS_UP");
|
||||
}
|
||||
RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = true;
|
||||
}
|
||||
|
||||
this.rilQuirksInitialized = true;
|
||||
},
|
||||
@ -820,12 +830,12 @@ let RIL = {
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
getRegistrationState: function getRegistrationState() {
|
||||
Buf.simpleRequest(REQUEST_REGISTRATION_STATE);
|
||||
getVoiceRegistrationState: function getVoiceRegistrationState() {
|
||||
Buf.simpleRequest(REQUEST_VOICE_REGISTRATION_STATE);
|
||||
},
|
||||
|
||||
getGPRSRegistrationState: function getGPRSRegistrationState() {
|
||||
Buf.simpleRequest(REQUEST_GPRS_REGISTRATION_STATE);
|
||||
getDataRegistrationState: function getDataRegistrationState() {
|
||||
Buf.simpleRequest(REQUEST_DATA_REGISTRATION_STATE);
|
||||
},
|
||||
|
||||
getOperator: function getOperator() {
|
||||
@ -836,13 +846,29 @@ let RIL = {
|
||||
Buf.simpleRequest(REQUEST_QUERY_NETWORK_SELECTION_MODE);
|
||||
},
|
||||
|
||||
setNetworkSelectionAutomatic: function setNetworkSelectionAutomatic() {
|
||||
Buf.simpleRequest(REQUEST_SET_NETWORK_SELECTION_AUTOMATIC);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the preferred network type.
|
||||
*
|
||||
* @param network_type
|
||||
* The network type. One of the PREFERRED_NETWORK_TYPE_* constants.
|
||||
*/
|
||||
setPreferredNetworkType: function setPreferredNetworkType(network_type) {
|
||||
Buf.newParcel(REQUEST_SET_PREFERRED_NETWORK_TYPE);
|
||||
Buf.writeUint32(network_type);
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
/**
|
||||
* Request various states about the network.
|
||||
*/
|
||||
requestNetworkInfo: function requestNetworkInfo() {
|
||||
if (DEBUG) debug("Requesting phone state");
|
||||
this.getRegistrationState();
|
||||
this.getGPRSRegistrationState(); //TODO only GSM
|
||||
this.getVoiceRegistrationState();
|
||||
this.getDataRegistrationState(); //TODO only GSM
|
||||
this.getOperator();
|
||||
this.getNetworkSelectionMode();
|
||||
},
|
||||
@ -1168,68 +1194,50 @@ let RIL = {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((this.radioState == RADIO_STATE_OFF) ||
|
||||
(this.radioState == RADIO_STATE_UNAVAILABLE) ||
|
||||
(this.radioState == RADIO_STATE_SIM_NOT_READY) ||
|
||||
(this.radioState == RADIO_STATE_RUIM_NOT_READY) ||
|
||||
(this.radioState == RADIO_STATE_NV_NOT_READY) ||
|
||||
(this.radioState == RADIO_STATE_NV_READY)) {
|
||||
if (DEBUG) debug("ICC not ready");
|
||||
if (this.cardState == GECKO_CARDSTATE_NOT_READY) {
|
||||
let app = iccStatus.apps[iccStatus.gsmUmtsSubscriptionAppIndex];
|
||||
if (!app) {
|
||||
if (DEBUG) {
|
||||
debug("Subscription application is not present in iccStatus.");
|
||||
}
|
||||
if (this.cardState == GECKO_CARDSTATE_ABSENT) {
|
||||
return;
|
||||
}
|
||||
this.cardState = GECKO_CARDSTATE_NOT_READY;
|
||||
this.cardState = GECKO_CARDSTATE_ABSENT;
|
||||
this.operator = null;
|
||||
this.sendDOMMessage({type: "cardstatechange",
|
||||
cardState: this.cardState});
|
||||
return;
|
||||
}
|
||||
|
||||
if ((this.radioState == RADIO_STATE_SIM_LOCKED_OR_ABSENT) ||
|
||||
(this.radioState == RADIO_STATE_SIM_READY) ||
|
||||
(this.radioState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT) ||
|
||||
(this.radioState == RADIO_STATE_RUIM_READY)) {
|
||||
let app = iccStatus.apps[iccStatus.gsmUmtsSubscriptionAppIndex];
|
||||
if (!app) {
|
||||
if (DEBUG) {
|
||||
debug("Subscription application is not present in iccStatus.");
|
||||
}
|
||||
if (this.cardState == GECKO_CARDSTATE_ABSENT) {
|
||||
return;
|
||||
}
|
||||
this.cardState = GECKO_CARDSTATE_ABSENT;
|
||||
this.operator = null;
|
||||
this.sendDOMMessage({type: "cardstatechange",
|
||||
cardState: this.cardState});
|
||||
return;
|
||||
}
|
||||
|
||||
let newCardState;
|
||||
switch (app.app_state) {
|
||||
case CARD_APP_STATE_PIN:
|
||||
newCardState = GECKO_CARDSTATE_PIN_REQUIRED;
|
||||
break;
|
||||
case CARD_APP_STATE_PUK:
|
||||
newCardState = GECKO_CARDSTATE_PUK_REQUIRED;
|
||||
break;
|
||||
case CARD_APP_STATE_SUBSCRIPTION_PERSO:
|
||||
newCardState = GECKO_CARDSTATE_NETWORK_LOCKED;
|
||||
break;
|
||||
case CARD_APP_STATE_READY:
|
||||
newCardState = GECKO_CARDSTATE_READY;
|
||||
break;
|
||||
case CARD_APP_STATE_UNKNOWN:
|
||||
case CARD_APP_STATE_DETECTED:
|
||||
default:
|
||||
newCardState = GECKO_CARDSTATE_NOT_READY;
|
||||
}
|
||||
|
||||
if (this.cardState == newCardState) {
|
||||
return;
|
||||
}
|
||||
this.cardState = newCardState;
|
||||
this.sendDOMMessage({type: "cardstatechange",
|
||||
cardState: this.cardState});
|
||||
let newCardState;
|
||||
switch (app.app_state) {
|
||||
case CARD_APPSTATE_PIN:
|
||||
newCardState = GECKO_CARDSTATE_PIN_REQUIRED;
|
||||
break;
|
||||
case CARD_APPSTATE_PUK:
|
||||
newCardState = GECKO_CARDSTATE_PUK_REQUIRED;
|
||||
break;
|
||||
case CARD_APPSTATE_SUBSCRIPTION_PERSO:
|
||||
newCardState = GECKO_CARDSTATE_NETWORK_LOCKED;
|
||||
break;
|
||||
case CARD_APPSTATE_READY:
|
||||
this.requestNetworkInfo();
|
||||
this.getSignalStrength();
|
||||
this.getMSISDN();
|
||||
newCardState = GECKO_CARDSTATE_READY;
|
||||
break;
|
||||
case CARD_APPSTATE_UNKNOWN:
|
||||
case CARD_APPSTATE_DETECTED:
|
||||
default:
|
||||
newCardState = GECKO_CARDSTATE_NOT_READY;
|
||||
}
|
||||
|
||||
if (this.cardState == newCardState) {
|
||||
return;
|
||||
}
|
||||
this.cardState = newCardState;
|
||||
this.sendDOMMessage({type: "cardstatechange",
|
||||
cardState: this.cardState});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1274,14 +1282,18 @@ let RIL = {
|
||||
}
|
||||
},
|
||||
|
||||
_processRegistrationState: function _processRegistrationState(state) {
|
||||
let rs = this.registrationState;
|
||||
_processVoiceRegistrationState: function _processVoiceRegistrationState(state) {
|
||||
let rs = this.voiceRegistrationState;
|
||||
let stateChanged = false;
|
||||
|
||||
let regState = RIL.parseInt(state[0], NETWORK_CREG_STATE_UNKNOWN);
|
||||
if (rs.regState != regState) {
|
||||
rs.regState = regState;
|
||||
stateChanged = true;
|
||||
if (regState == NETWORK_CREG_STATE_REGISTERED_HOME ||
|
||||
regState == NETWORK_CREG_STATE_REGISTERED_ROAMING) {
|
||||
RIL.getSMSCAddress();
|
||||
}
|
||||
}
|
||||
|
||||
let radioTech = RIL.parseInt(state[3], NETWORK_CREG_TECH_UNKNOWN);
|
||||
@ -1310,13 +1322,13 @@ let RIL = {
|
||||
}
|
||||
|
||||
if (stateChanged) {
|
||||
this.sendDOMMessage({type: "registrationstatechange",
|
||||
registrationState: rs});
|
||||
this.sendDOMMessage({type: "voiceregistrationstatechange",
|
||||
voiceRegistrationState: rs});
|
||||
}
|
||||
},
|
||||
|
||||
_processGPRSRegistrationState: function _processGPRSRegistrationState(state) {
|
||||
let rs = this.gprsRegistrationState;
|
||||
_processDataRegistrationState: function _processDataRegistrationState(state) {
|
||||
let rs = this.dataRegistrationState;
|
||||
let stateChanged = false;
|
||||
|
||||
let regState = RIL.parseInt(state[0], NETWORK_CREG_STATE_UNKNOWN);
|
||||
@ -1332,8 +1344,8 @@ let RIL = {
|
||||
}
|
||||
|
||||
if (stateChanged) {
|
||||
this.sendDOMMessage({type: "gprsregistrationstatechange",
|
||||
gprsRegistrationState: rs});
|
||||
this.sendDOMMessage({type: "dataregistrationstatechange",
|
||||
dataRegistrationState: rs});
|
||||
}
|
||||
},
|
||||
|
||||
@ -1386,6 +1398,72 @@ let RIL = {
|
||||
this.muted = Object.getOwnPropertyNames(this.currentCalls).length == 0;
|
||||
},
|
||||
|
||||
_handleChangedCallState: function _handleChangedCallState(changedCall) {
|
||||
let message = {type: "callStateChange",
|
||||
call: {callIndex: changedCall.callIndex,
|
||||
state: changedCall.state,
|
||||
number: changedCall.number,
|
||||
name: changedCall.name}};
|
||||
this.sendDOMMessage(message);
|
||||
},
|
||||
|
||||
_handleDisconnectedCall: function _handleDisconnectedCall(disconnectedCall) {
|
||||
let message = {type: "callDisconnected",
|
||||
call: {callIndex: disconnectedCall.callIndex}};
|
||||
this.sendDOMMessage(message);
|
||||
},
|
||||
|
||||
_processDataCallList: function _processDataCallList(datacalls) {
|
||||
for each (let currentDataCall in this.currentDataCalls) {
|
||||
let updatedDataCall;
|
||||
if (datacalls) {
|
||||
updatedDataCall = datacalls[currentDataCall.cid];
|
||||
delete datacalls[currentDataCall.cid];
|
||||
}
|
||||
|
||||
if (!updatedDataCall) {
|
||||
delete this.currentDataCalls[currentDataCall.callIndex];
|
||||
currentDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
|
||||
this.sendDOMMessage({type: "datacallstatechange",
|
||||
datacall: currentDataCall});
|
||||
continue;
|
||||
}
|
||||
|
||||
this._setDataCallGeckoState(updatedDataCall);
|
||||
if (updatedDataCall.state != currentDataCall.state) {
|
||||
currentDataCall.status = updatedDataCall.status;
|
||||
currentDataCall.active = updatedDataCall.active;
|
||||
currentDataCall.state = updatedDataCall.state;
|
||||
this.sendDOMMessage({type: "datacallstatechange",
|
||||
datacall: currentDataCall});
|
||||
}
|
||||
}
|
||||
|
||||
for each (let newDataCall in datacalls) {
|
||||
this.currentDataCalls[newDataCall.cid] = newDataCall;
|
||||
this._setDataCallGeckoState(newDataCall);
|
||||
this.sendDOMMessage({type: "datacallstatechange",
|
||||
datacall: newDataCall});
|
||||
}
|
||||
},
|
||||
|
||||
_setDataCallGeckoState: function _setDataCallGeckoState(datacall) {
|
||||
switch (datacall.active) {
|
||||
case DATACALL_INACTIVE:
|
||||
datacall.state = GECKO_NETWORK_STATE_DISCONNECTED;
|
||||
break;
|
||||
case DATACALL_ACTIVE_DOWN:
|
||||
datacall.state = GECKO_NETWORK_STATE_SUSPENDED;
|
||||
if (RILQUIRKS_DATACALLSTATE_DOWN_IS_UP) {
|
||||
datacall.state = GECKO_NETWORK_STATE_CONNECTED;
|
||||
}
|
||||
break;
|
||||
case DATACALL_ACTIVE_UP:
|
||||
datacall.state = GECKO_NETWORK_STATE_CONNECTED;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for processing received multipart SMS.
|
||||
*
|
||||
@ -1439,63 +1517,6 @@ let RIL = {
|
||||
return options;
|
||||
},
|
||||
|
||||
_handleChangedCallState: function _handleChangedCallState(changedCall) {
|
||||
let message = {type: "callStateChange",
|
||||
call: {callIndex: changedCall.callIndex,
|
||||
state: changedCall.state,
|
||||
number: changedCall.number,
|
||||
name: changedCall.name}};
|
||||
this.sendDOMMessage(message);
|
||||
},
|
||||
|
||||
_handleDisconnectedCall: function _handleDisconnectedCall(disconnectedCall) {
|
||||
let message = {type: "callDisconnected",
|
||||
call: {callIndex: disconnectedCall.callIndex}};
|
||||
this.sendDOMMessage(message);
|
||||
},
|
||||
|
||||
_processDataCallList: function _processDataCallList(datacalls) {
|
||||
for each (let currentDataCall in this.currentDataCalls) {
|
||||
let newDataCall;
|
||||
if (datacalls) {
|
||||
newDataCall = datacalls[currentDataCall.cid];
|
||||
delete datacalls[currentDataCall.cid];
|
||||
}
|
||||
|
||||
if (newDataCall) {
|
||||
switch (newDataCall.active) {
|
||||
case DATACALL_INACTIVE:
|
||||
newDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
|
||||
break;
|
||||
case DATACALL_ACTIVE_DOWN:
|
||||
newDataCall.state = GECKO_NETWORK_STATE_SUSPENDED;
|
||||
if (RILQUIRKS_DATACALLSTATE_DOWN_IS_UP) {
|
||||
newDataCall.state = GECKO_NETWORK_STATE_CONNECTED;
|
||||
}
|
||||
break;
|
||||
case DATACALL_ACTIVE_UP:
|
||||
newDataCall.state = GECKO_NETWORK_STATE_CONNECTED;
|
||||
break;
|
||||
}
|
||||
if (newDataCall.state != currentDataCall.state) {
|
||||
currentDataCall.active = newDataCall.active;
|
||||
currentDataCall.state = newDataCall.state;
|
||||
this.sendDOMMessage({type: "datacallstatechange",
|
||||
datacall: currentDataCall});
|
||||
}
|
||||
} else {
|
||||
delete this.currentDataCalls[currentDataCall.callIndex];
|
||||
currentDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
|
||||
this.sendDOMMessage({type: "datacallstatechange",
|
||||
datacall: currentDataCall});
|
||||
}
|
||||
}
|
||||
|
||||
for each (let datacall in datacalls) {
|
||||
if (DEBUG) debug("Unexpected data call: " + JSON.stringify(datacall));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle incoming messages from the main UI thread.
|
||||
*
|
||||
@ -1569,24 +1590,26 @@ let RIL = {
|
||||
};
|
||||
|
||||
RIL[REQUEST_GET_SIM_STATUS] = function REQUEST_GET_SIM_STATUS() {
|
||||
let iccStatus = {
|
||||
cardState: Buf.readUint32(), // CARD_STATE_*
|
||||
universalPINState: Buf.readUint32(), // PINSTATE_*
|
||||
gsmUmtsSubscriptionAppIndex: Buf.readUint32(),
|
||||
setCdmaSubscriptionAppIndex: Buf.readUint32(),
|
||||
apps: []
|
||||
};
|
||||
let iccStatus = {};
|
||||
iccStatus.cardState = Buf.readUint32(); // CARD_STATE_*
|
||||
iccStatus.universalPINState = Buf.readUint32(); // CARD_PINSTATE_*
|
||||
iccStatus.gsmUmtsSubscriptionAppIndex = Buf.readUint32();
|
||||
iccStatus.cdmaSubscriptionAppIndex = Buf.readUint32();
|
||||
if (!RILQUIRKS_V5_LEGACY) {
|
||||
iccStatus.imsSubscriptionAppIndex = Buf.readUint32();
|
||||
}
|
||||
|
||||
let apps_length = Buf.readUint32();
|
||||
if (apps_length > CARD_MAX_APPS) {
|
||||
apps_length = CARD_MAX_APPS;
|
||||
}
|
||||
|
||||
iccStatus.apps = [];
|
||||
for (let i = 0 ; i < apps_length ; i++) {
|
||||
iccStatus.apps.push({
|
||||
app_type: Buf.readUint32(), // APPTYPE_*
|
||||
app_state: Buf.readUint32(), // CARD_APP_STATE_*
|
||||
perso_substate: Buf.readUint32(), // PERSOSUBSTATE_*
|
||||
app_type: Buf.readUint32(), // CARD_APPTYPE_*
|
||||
app_state: Buf.readUint32(), // CARD_APPSTATE_*
|
||||
perso_substate: Buf.readUint32(), // CARD_PERSOSUBSTATE_*
|
||||
aid: Buf.readString(),
|
||||
app_label: Buf.readString(),
|
||||
pin1_replaced: Buf.readUint32(),
|
||||
@ -1673,43 +1696,65 @@ RIL[REQUEST_CONFERENCE] = null;
|
||||
RIL[REQUEST_UDUB] = null;
|
||||
RIL[REQUEST_LAST_CALL_FAIL_CAUSE] = null;
|
||||
RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH() {
|
||||
let signalStrength = Buf.readUint32();
|
||||
let obj = {};
|
||||
|
||||
// GSM
|
||||
// Valid values are (0-31, 99) as defined in TS 27.007 8.5.
|
||||
obj.gsmSignalStrength = Buf.readUint32();
|
||||
// The SGS2 seems to compute the number of bars for us and expose those
|
||||
// instead of the actual signal strength.
|
||||
let bars = signalStrength >> 8;
|
||||
signalStrength = signalStrength & 0xff;
|
||||
let strength = {
|
||||
obj.bars = obj.gsmSignalStrength >> 8; //TODO remove this, see bug 729173
|
||||
obj.gsmSignalStrength = obj.gsmSignalStrength & 0xff;
|
||||
// GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5.
|
||||
obj.gsmBitErrorRate = Buf.readUint32();
|
||||
|
||||
// CDMA
|
||||
// The CDMA RSSI value.
|
||||
obj.cdmaDBM = Buf.readUint32();
|
||||
// The CDMA EC/IO.
|
||||
obj.cdmaECIO = Buf.readUint32();
|
||||
// The EVDO RSSI value.
|
||||
|
||||
// EVDO
|
||||
obj.evdoDBM = Buf.readUint32();
|
||||
// The EVDO EC/IO.
|
||||
obj.evdoECIO = Buf.readUint32();
|
||||
// Signal-to-noise ratio. Valid values are 0 to 8.
|
||||
obj.evdoSNR = Buf.readUint32();
|
||||
|
||||
// LTE
|
||||
if (!RILQUIRKS_V5_LEGACY) {
|
||||
// Valid values are (0-31, 99) as defined in TS 27.007 8.5.
|
||||
gsmSignalStrength: signalStrength,
|
||||
// Non-standard extension by the SGS2.
|
||||
bars: bars,
|
||||
// GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5.
|
||||
gsmBitErrorRate: Buf.readUint32(),
|
||||
// The CDMA RSSI value.
|
||||
cdmaDBM: Buf.readUint32(),
|
||||
// The CDMA EC/IO.
|
||||
cdmaECIO: Buf.readUint32(),
|
||||
// The EVDO RSSI value.
|
||||
evdoDBM: Buf.readUint32(),
|
||||
// The EVDO EC/IO.
|
||||
evdoECIO: Buf.readUint32(),
|
||||
// Valid values are 0-8. 8 is the highest signal to noise ratio
|
||||
evdoSNR: Buf.readUint32()
|
||||
};
|
||||
if (DEBUG) debug("Signal strength " + JSON.stringify(strength));
|
||||
obj.lteSignalStrength = Buf.readUint32();
|
||||
// Reference signal receive power in dBm, multiplied by -1.
|
||||
// Valid values are 44 to 140.
|
||||
obj.lteRSRP = Buf.readUint32();
|
||||
// Reference signal receive quality in dB, multiplied by -1.
|
||||
// Valid values are 3 to 20.
|
||||
obj.lteRSRQ = Buf.readUint32();
|
||||
// Signal-to-noise ratio for the reference signal.
|
||||
// Valid values are -200 (20.0 dB) to +300 (30 dB).
|
||||
obj.lteRSSNR = Buf.readUint32();
|
||||
// Channel Quality Indicator, valid values are 0 to 15.
|
||||
obj.lteCQI = Buf.readUint32();
|
||||
}
|
||||
|
||||
if (DEBUG) debug("Signal strength " + JSON.stringify(obj));
|
||||
this.sendDOMMessage({type: "signalstrengthchange",
|
||||
signalStrength: strength});
|
||||
signalStrength: obj});
|
||||
};
|
||||
RIL[REQUEST_REGISTRATION_STATE] = function REQUEST_REGISTRATION_STATE(length) {
|
||||
RIL[REQUEST_VOICE_REGISTRATION_STATE] = function REQUEST_VOICE_REGISTRATION_STATE(length) {
|
||||
let state = Buf.readStringList();
|
||||
this._processRegistrationState(state);
|
||||
debug("voice registration state: " + state);
|
||||
this._processVoiceRegistrationState(state);
|
||||
};
|
||||
RIL[REQUEST_GPRS_REGISTRATION_STATE] = function REQUEST_GPRS_REGISTRATION_STATE(length) {
|
||||
RIL[REQUEST_DATA_REGISTRATION_STATE] = function REQUEST_DATA_REGISTRATION_STATE(length) {
|
||||
let state = Buf.readStringList();
|
||||
this._processGPRSRegistrationState(state);
|
||||
this._processDataRegistrationState(state);
|
||||
};
|
||||
RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length) {
|
||||
let operator = Buf.readStringList();
|
||||
if (DEBUG) debug("Operator data: " + operator);
|
||||
if (operator.length < 3) {
|
||||
if (DEBUG) debug("Expected at least 3 strings for operator.");
|
||||
}
|
||||
@ -1748,7 +1793,11 @@ RIL[REQUEST_SEND_SMS] = function REQUEST_SEND_SMS(length, options) {
|
||||
this.sendDOMMessage(options);
|
||||
};
|
||||
RIL[REQUEST_SEND_SMS_EXPECT_MORE] = null;
|
||||
RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
|
||||
|
||||
RIL.readSetupDataCall_v5 = function readSetupDataCall_v5(options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
let [cid, ifname, ipaddr, dns, gw] = Buf.readStringList();
|
||||
options.cid = cid;
|
||||
options.ifname = ifname;
|
||||
@ -1757,13 +1806,21 @@ RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options)
|
||||
options.gw = gw;
|
||||
options.active = DATACALL_ACTIVE_UNKNOWN;
|
||||
options.state = GECKO_NETWORK_STATE_CONNECTING;
|
||||
this.currentDataCalls[options.cid] = options;
|
||||
this.sendDOMMessage({type: "datacallstatechange",
|
||||
datacall: options});
|
||||
return options;
|
||||
};
|
||||
|
||||
// Let's get the list of data calls to ensure we know whether it's active
|
||||
// or not.
|
||||
this.getDataCallList();
|
||||
RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
|
||||
if (RILQUIRKS_V5_LEGACY) {
|
||||
this.readSetupDataCall_v5(options);
|
||||
this.currentDataCalls[options.cid] = options;
|
||||
this.sendDOMMessage({type: "datacallstatechange",
|
||||
datacall: options});
|
||||
// Let's get the list of data calls to ensure we know whether it's active
|
||||
// or not.
|
||||
this.getDataCallList();
|
||||
return;
|
||||
}
|
||||
this[REQUEST_DATA_CALL_LIST](length, options);
|
||||
};
|
||||
RIL[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) {
|
||||
switch (options.fileid) {
|
||||
@ -1809,33 +1866,70 @@ RIL[REQUEST_DTMF_START] = null;
|
||||
RIL[REQUEST_DTMF_STOP] = null;
|
||||
RIL[REQUEST_BASEBAND_VERSION] = function REQUEST_BASEBAND_VERSION() {
|
||||
this.basebandVersion = Buf.readString();
|
||||
if (DEBUG) debug("Baseband version: " + this.basebandVersion);
|
||||
};
|
||||
RIL[REQUEST_SEPARATE_CONNECTION] = null;
|
||||
RIL[REQUEST_SET_MUTE] = null;
|
||||
RIL[REQUEST_GET_MUTE] = null;
|
||||
RIL[REQUEST_QUERY_CLIP] = null;
|
||||
RIL[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
|
||||
|
||||
RIL.readDataCall_v5 = function readDataCall_v5() {
|
||||
return {
|
||||
cid: Buf.readUint32().toString(),
|
||||
active: Buf.readUint32(), // DATACALL_ACTIVE_*
|
||||
type: Buf.readString(),
|
||||
apn: Buf.readString(),
|
||||
address: Buf.readString()
|
||||
};
|
||||
};
|
||||
|
||||
RIL.readDataCall_v6 = function readDataCall_v6(obj) {
|
||||
if (!obj) {
|
||||
obj = {};
|
||||
}
|
||||
obj.status = Buf.readUint32(); // DATACALL_FAIL_*
|
||||
obj.suggestedRetryTime = Buf.readUint32();
|
||||
obj.cid = Buf.readUint32().toString();
|
||||
obj.active = Buf.readUint32(); // DATACALL_ACTIVE_*
|
||||
obj.type = Buf.readString();
|
||||
obj.ifname = Buf.readString();
|
||||
obj.ipaddr = Buf.readString();
|
||||
obj.dns = Buf.readString();
|
||||
obj.gw = Buf.readString();
|
||||
if (obj.dns) {
|
||||
obj.dns = obj.dns.split(" ");
|
||||
}
|
||||
//TODO for now we only support one address and gateway
|
||||
if (obj.ipaddr) {
|
||||
obj.ipaddr = obj.ipaddr.split(" ")[0];
|
||||
}
|
||||
if (obj.gw) {
|
||||
obj.gw = obj.gw.split(" ")[0];
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
RIL[REQUEST_DATA_CALL_LIST] = function REQUEST_DATA_CALL_LIST(length) {
|
||||
this.initRILQuirks();
|
||||
|
||||
let num = 0;
|
||||
if (length) {
|
||||
num = Buf.readUint32();
|
||||
}
|
||||
if (!num) {
|
||||
if (!length) {
|
||||
this._processDataCallList(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let version = 0;
|
||||
if (!RILQUIRKS_V5_LEGACY) {
|
||||
version = Buf.readUint32();
|
||||
}
|
||||
let num = num = Buf.readUint32();
|
||||
let datacalls = {};
|
||||
for (let i = 0; i < num; i++) {
|
||||
let datacall = {
|
||||
cid: Buf.readUint32().toString(),
|
||||
active: Buf.readUint32(),
|
||||
type: Buf.readString(),
|
||||
apn: Buf.readString(),
|
||||
address: Buf.readString()
|
||||
};
|
||||
let datacall;
|
||||
if (version < 6) {
|
||||
datacall = this.readDataCall_v5();
|
||||
} else {
|
||||
datacall = this.readDataCall_v6();
|
||||
}
|
||||
datacalls[datacall.cid] = datacall;
|
||||
}
|
||||
|
||||
@ -1860,7 +1954,7 @@ RIL[REQUEST_SET_PREFERRED_NETWORK_TYPE] = null;
|
||||
RIL[REQUEST_GET_PREFERRED_NETWORK_TYPE] = null;
|
||||
RIL[REQUEST_GET_NEIGHBORING_CELL_IDS] = null;
|
||||
RIL[REQUEST_SET_LOCATION_UPDATES] = null;
|
||||
RIL[REQUEST_CDMA_SET_SUBSCRIPTION] = null;
|
||||
RIL[REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE] = null;
|
||||
RIL[REQUEST_CDMA_SET_ROAMING_PREFERENCE] = null;
|
||||
RIL[REQUEST_CDMA_QUERY_ROAMING_PREFERENCE] = null;
|
||||
RIL[REQUEST_SET_TTY_MODE] = null;
|
||||
@ -1899,97 +1993,71 @@ RIL[REQUEST_SET_SMSC_ADDRESS] = null;
|
||||
RIL[REQUEST_REPORT_SMS_MEMORY_STATUS] = null;
|
||||
RIL[REQUEST_REPORT_STK_SERVICE_IS_RUNNING] = null;
|
||||
RIL[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED() {
|
||||
let newState = Buf.readUint32();
|
||||
let radioState = Buf.readUint32();
|
||||
|
||||
let newState;
|
||||
if (radioState == RADIO_STATE_UNAVAILABLE) {
|
||||
newState = GECKO_RADIOSTATE_UNAVAILABLE;
|
||||
} else if (radioState == RADIO_STATE_OFF) {
|
||||
newState = GECKO_RADIOSTATE_OFF;
|
||||
} else {
|
||||
newState = GECKO_RADIOSTATE_READY;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
debug("Radio state changed from " + this.radioState + " to " + newState);
|
||||
debug("Radio state changed from '" + this.radioState +
|
||||
"' to '" + newState + "'");
|
||||
}
|
||||
if (this.radioState == newState) {
|
||||
// No change in state, return.
|
||||
return;
|
||||
}
|
||||
|
||||
let gsm = newState == RADIO_STATE_SIM_NOT_READY ||
|
||||
newState == RADIO_STATE_SIM_LOCKED_OR_ABSENT ||
|
||||
newState == RADIO_STATE_SIM_READY;
|
||||
let cdma = newState == RADIO_STATE_RUIM_NOT_READY ||
|
||||
newState == RADIO_STATE_RUIM_READY ||
|
||||
newState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT ||
|
||||
newState == RADIO_STATE_NV_NOT_READY ||
|
||||
newState == RADIO_STATE_NV_READY;
|
||||
// TODO hardcoded for now (see bug 726098)
|
||||
let cdma = false;
|
||||
|
||||
// Figure out state transitions and send out more RIL requests as necessary
|
||||
// as well as events to the main thread.
|
||||
|
||||
if (this.radioState == RADIO_STATE_UNAVAILABLE &&
|
||||
newState != RADIO_STATE_UNAVAILABLE) {
|
||||
if (this.radioState == GECKO_RADIOSTATE_UNAVAILABLE &&
|
||||
newState != GECKO_RADIOSTATE_UNAVAILABLE) {
|
||||
// The radio became available, let's get its info.
|
||||
if (gsm) {
|
||||
if (cdma) {
|
||||
this.getDeviceIdentity();
|
||||
} else {
|
||||
this.getIMEI();
|
||||
this.getIMEISV();
|
||||
}
|
||||
if (cdma) {
|
||||
this.getDeviceIdentity();
|
||||
}
|
||||
this.getBasebandVersion();
|
||||
this.setScreenState(true);
|
||||
this.sendDOMMessage({
|
||||
type: "radiostatechange",
|
||||
radioState: (newState == RADIO_STATE_OFF) ?
|
||||
GECKO_RADIOSTATE_OFF : GECKO_RADIOSTATE_READY
|
||||
});
|
||||
|
||||
//XXX TODO For now, just turn the radio on if it's off. for the real
|
||||
// deal we probably want to do the opposite: start with a known state
|
||||
// when we boot up and let the UI layer control the radio power.
|
||||
if (newState == RADIO_STATE_OFF) {
|
||||
if (newState == GECKO_RADIOSTATE_OFF) {
|
||||
this.setRadioPower(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (newState == RADIO_STATE_UNAVAILABLE) {
|
||||
// The radio is no longer available, we need to deal with any
|
||||
// remaining pending requests.
|
||||
//TODO do that
|
||||
this.sendDOMMessage({type: "radiostatechange",
|
||||
radioState: GECKO_RADIOSTATE_UNAVAILABLE});
|
||||
}
|
||||
|
||||
if (newState == RADIO_STATE_SIM_READY ||
|
||||
newState == RADIO_STATE_RUIM_READY ||
|
||||
newState == RADIO_STATE_NV_READY) {
|
||||
// The ICC has become available. Get all the things.
|
||||
this.getICCStatus();
|
||||
this.requestNetworkInfo();
|
||||
this.getSignalStrength();
|
||||
this.getSMSCAddress();
|
||||
this.getMSISDN();
|
||||
this.sendDOMMessage({type: "cardstatechange",
|
||||
cardState: GECKO_CARDSTATE_READY});
|
||||
}
|
||||
if (newState == RADIO_STATE_SIM_LOCKED_OR_ABSENT ||
|
||||
newState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT) {
|
||||
this.getICCStatus();
|
||||
this.sendDOMMessage({type: "cardstatechange",
|
||||
cardState: GECKO_CARDSTATE_UNAVAILABLE});
|
||||
}
|
||||
|
||||
let wasOn = this.radioState != RADIO_STATE_OFF &&
|
||||
this.radioState != RADIO_STATE_UNAVAILABLE;
|
||||
let isOn = newState != RADIO_STATE_OFF &&
|
||||
newState != RADIO_STATE_UNAVAILABLE;
|
||||
if (!wasOn && isOn) {
|
||||
//TODO
|
||||
}
|
||||
if (wasOn && !isOn) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
this.radioState = newState;
|
||||
this.sendDOMMessage({
|
||||
type: "radiostatechange",
|
||||
radioState: newState
|
||||
});
|
||||
|
||||
// If the radio is up and on, so let's query the card state.
|
||||
// On older RILs only if the card is actually ready, though.
|
||||
if (radioState == RADIO_STATE_UNAVAILABLE ||
|
||||
radioState == RADIO_STATE_OFF) {
|
||||
return;
|
||||
}
|
||||
if (RILQUIRKS_V5_LEGACY &&
|
||||
(radioState == RADIO_STATE_SIM_NOT_READY ||
|
||||
radioState == RADIO_STATE_RUIM_NOT_READY ||
|
||||
radioState == RADIO_STATE_NV_NOT_READY)) {
|
||||
return;
|
||||
}
|
||||
this.getICCStatus();
|
||||
};
|
||||
RIL[UNSOLICITED_RESPONSE_CALL_STATE_CHANGED] = function UNSOLICITED_RESPONSE_CALL_STATE_CHANGED() {
|
||||
this.getCurrentCalls();
|
||||
};
|
||||
RIL[UNSOLICITED_RESPONSE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RESPONSE_NETWORK_STATE_CHANGED() {
|
||||
RIL[UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED() {
|
||||
if (DEBUG) debug("Network state changed, re-requesting phone state.");
|
||||
this.requestNetworkInfo();
|
||||
};
|
||||
@ -2086,8 +2154,12 @@ RIL[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED()
|
||||
RIL[UNSOLICITED_SIGNAL_STRENGTH] = function UNSOLICITED_SIGNAL_STRENGTH() {
|
||||
this[REQUEST_SIGNAL_STRENGTH]();
|
||||
};
|
||||
RIL[UNSOLICITED_DATA_CALL_LIST_CHANGED] = function UNSOLICITED_DATA_CALL_LIST_CHANGED(length) {
|
||||
this.getDataCallList();
|
||||
RIL[UNSOLICITED_DATA_CALL_LIST_CHANGED] = function UNSOLICITED_DATA_CALL_LIST_CHANGED(length, options) {
|
||||
if (RILQUIRKS_V5_LEGACY) {
|
||||
this.getDataCallList();
|
||||
return;
|
||||
}
|
||||
this[REQUEST_GET_DATA_CALL_LIST](length, options);
|
||||
};
|
||||
RIL[UNSOLICITED_SUPP_SVC_NOTIFICATION] = null;
|
||||
RIL[UNSOLICITED_STK_SESSION_END] = null;
|
||||
@ -2124,6 +2196,14 @@ RIL[UNSOLICITED_CDMA_INFO_REC] = null;
|
||||
RIL[UNSOLICITED_OEM_HOOK_RAW] = null;
|
||||
RIL[UNSOLICITED_RINGBACK_TONE] = null;
|
||||
RIL[UNSOLICITED_RESEND_INCALL_MUTE] = null;
|
||||
RIL[UNSOLICITED_RIL_CONNECTED] = function UNSOLICITED_RIL_CONNECTED(length, options) {
|
||||
let version = Buf.readUint32List()[0];
|
||||
RILQUIRKS_V5_LEGACY = (version < 5);
|
||||
if (DEBUG) {
|
||||
debug("Detected RIL version " + version);
|
||||
debug("RILQUIRKS_V5_LEGACY is " + RILQUIRKS_V5_LEGACY);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user