This commit is contained in:
Ryan VanderMeulen 2012-06-16 09:38:43 -04:00
Родитель cd123e7b32 5634536dc6
Коммит a1cab9283c
165 изменённых файлов: 4635 добавлений и 3162 удалений

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

@ -165,114 +165,58 @@ ARIAGridAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
return NS_OK;
}
NS_IMETHODIMP
ARIAGridAccessible::GetColumnDescription(PRInt32 aColumn,
nsAString& aDescription)
bool
ARIAGridAccessible::IsColSelected(PRUint32 aColIdx)
{
aDescription.Truncate();
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidColumn(aColumn));
// XXX: not implemented
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ARIAGridAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription)
{
aDescription.Truncate();
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidRow(aRow));
// XXX: not implemented
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
ARIAGridAccessible::IsColumnSelected(PRInt32 aColumn, bool* aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidColumn(aColumn));
AccIterator rowIter(this, filters::GetRow);
Accessible* row = rowIter.Next();
if (!row)
return NS_OK;
return false;
do {
if (!nsAccUtils::IsARIASelected(row)) {
Accessible* cell = GetCellInRowAt(row, aColumn);
if (!cell) // Do not fail due to wrong markup
return NS_OK;
if (!nsAccUtils::IsARIASelected(cell))
return NS_OK;
Accessible* cell = GetCellInRowAt(row, aColIdx);
if (!cell || !nsAccUtils::IsARIASelected(cell))
return false;
}
} while ((row = rowIter.Next()));
*aIsSelected = true;
return NS_OK;
return true;
}
NS_IMETHODIMP
ARIAGridAccessible::IsRowSelected(PRInt32 aRow, bool* aIsSelected)
bool
ARIAGridAccessible::IsRowSelected(PRUint32 aRowIdx)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
Accessible* row = GetRowAt(aRow);
NS_ENSURE_ARG(row);
Accessible* row = GetRowAt(aRowIdx);
if(!row)
return false;
if (!nsAccUtils::IsARIASelected(row)) {
AccIterator cellIter(row, filters::GetCell);
Accessible* cell = nsnull;
while ((cell = cellIter.Next())) {
if (!nsAccUtils::IsARIASelected(cell))
return NS_OK;
return false;
}
}
*aIsSelected = true;
return NS_OK;
return true;
}
NS_IMETHODIMP
ARIAGridAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
bool* aIsSelected)
bool
ARIAGridAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
Accessible* row = GetRowAt(aRow);
NS_ENSURE_ARG(row);
Accessible* row = GetRowAt(aRowIdx);
if(!row)
return false;
if (!nsAccUtils::IsARIASelected(row)) {
Accessible* cell = GetCellInRowAt(row, aColumn);
NS_ENSURE_ARG(cell);
if (!nsAccUtils::IsARIASelected(cell))
return NS_OK;
Accessible* cell = GetCellInRowAt(row, aColIdx);
if (!cell || !nsAccUtils::IsARIASelected(cell))
return false;
}
*aIsSelected = true;
return NS_OK;
return true;
}
NS_IMETHODIMP

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

@ -33,7 +33,7 @@ public:
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
// Accessible
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
virtual TableAccessible* AsTable() { return this; }
// nsAccessNode
virtual void Shutdown();
@ -42,6 +42,9 @@ public:
virtual PRUint32 ColCount();
virtual PRUint32 RowCount();
virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
virtual bool IsColSelected(PRUint32 aColIdx);
virtual bool IsRowSelected(PRUint32 aRowIdx);
virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
virtual void SelectCol(PRUint32 aColIdx);
virtual void SelectRow(PRUint32 aRowIdx);
virtual void UnselectCol(PRUint32 aColIdx);

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

@ -972,108 +972,62 @@ HTMLTableAccessible::RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx)
return rowExtent;
}
NS_IMETHODIMP
HTMLTableAccessible::GetColumnDescription(PRInt32 aColumn, nsAString& _retval)
bool
HTMLTableAccessible::IsColSelected(PRUint32 aColIdx)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
bool isSelected = false;
NS_IMETHODIMP
HTMLTableAccessible::GetRowDescription(PRInt32 aRow, nsAString& _retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
HTMLTableAccessible::IsColumnSelected(PRInt32 aColumn, bool* aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
PRInt32 colCount = 0;
nsresult rv = GetColumnCount(&colCount);
NS_ENSURE_SUCCESS(rv, rv);
if (aColumn < 0 || aColumn >= colCount)
return NS_ERROR_INVALID_ARG;
PRInt32 rowCount = 0;
rv = GetRowCount(&rowCount);
NS_ENSURE_SUCCESS(rv, rv);
for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
bool isSelected = false;
rv = IsCellSelected(rowIdx, aColumn, &isSelected);
if (NS_SUCCEEDED(rv)) {
*aIsSelected = isSelected;
if (!isSelected)
break;
}
PRUint32 rowCount = RowCount();
for (PRUint32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
isSelected = IsCellSelected(rowIdx, aColIdx);
if (!isSelected)
return false;
}
return NS_OK;
return isSelected;
}
NS_IMETHODIMP
HTMLTableAccessible::IsRowSelected(PRInt32 aRow, bool* aIsSelected)
bool
HTMLTableAccessible::IsRowSelected(PRUint32 aRowIdx)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
bool isSelected = false;
PRInt32 rowCount = 0;
nsresult rv = GetRowCount(&rowCount);
NS_ENSURE_SUCCESS(rv, rv);
if (aRow < 0 || aRow >= rowCount)
return NS_ERROR_INVALID_ARG;
PRInt32 colCount = 0;
rv = GetColumnCount(&colCount);
NS_ENSURE_SUCCESS(rv, rv);
for (PRInt32 colIdx = 0; colIdx < colCount; colIdx++) {
bool isSelected = false;
rv = IsCellSelected(aRow, colIdx, &isSelected);
if (NS_SUCCEEDED(rv)) {
*aIsSelected = isSelected;
if (!isSelected)
break;
}
PRUint32 colCount = ColCount();
for (PRUint32 colIdx = 0; colIdx < colCount; colIdx++) {
isSelected = IsCellSelected(aRowIdx, colIdx);
if (!isSelected)
return false;
}
return NS_OK;
return isSelected;
}
NS_IMETHODIMP
HTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
bool* aIsSelected)
bool
HTMLTableAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
nsITableLayout *tableLayout = GetTableLayout();
NS_ENSURE_STATE(tableLayout);
if (!tableLayout)
return false;
nsCOMPtr<nsIDOMElement> domElement;
PRInt32 startRowIndex = 0, startColIndex = 0,
rowSpan, colSpan, actualRowSpan, actualColSpan;
bool isSelected = false;
nsresult rv = tableLayout->
GetCellDataAt(aRow, aColumn, *getter_AddRefs(domElement),
startRowIndex, startColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, *aIsSelected);
tableLayout->GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
startRowIndex, startColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
return NS_ERROR_INVALID_ARG;
return rv;
return isSelected;
}
void
HTMLTableAccessible::SelectRow(PRUint32 aRowIdx)
{
nsresult rv = RemoveRowsOrColumnsFromSelection(aRowIdx,
nsISelectionPrivate::TABLESELECTION_ROW,
true);
nsresult rv =
RemoveRowsOrColumnsFromSelection(aRowIdx,
nsISelectionPrivate::TABLESELECTION_ROW,
true);
NS_ASSERTION(NS_SUCCEEDED(rv),
"RemoveRowsOrColumnsFromSelection() Shouldn't fail!");
@ -1083,9 +1037,10 @@ HTMLTableAccessible::SelectRow(PRUint32 aRowIdx)
void
HTMLTableAccessible::SelectCol(PRUint32 aColIdx)
{
nsresult rv = RemoveRowsOrColumnsFromSelection(aColIdx,
nsISelectionPrivate::TABLESELECTION_COLUMN,
true);
nsresult rv =
RemoveRowsOrColumnsFromSelection(aColIdx,
nsISelectionPrivate::TABLESELECTION_COLUMN,
true);
NS_ASSERTION(NS_SUCCEEDED(rv),
"RemoveRowsOrColumnsFromSelection() Shouldn't fail!");

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

@ -106,6 +106,9 @@ public:
virtual PRInt32 CellIndexAt(PRUint32 aRowIdx, PRUint32 aColIdx);
virtual PRUint32 ColExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
virtual PRUint32 RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
virtual bool IsColSelected(PRUint32 aColIdx);
virtual bool IsRowSelected(PRUint32 aRowIdx);
virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
virtual void SelectCol(PRUint32 aColIdx);
virtual void SelectRow(PRUint32 aRowIdx);
virtual void UnselectCol(PRUint32 aColIdx);
@ -116,7 +119,7 @@ public:
virtual void Shutdown();
// Accessible
virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
virtual TableAccessible* AsTable() { return this; }
virtual void Description(nsString& aDescription);
virtual nsresult GetNameInternal(nsAString& aName);
virtual a11y::role NativeRole();

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

@ -304,7 +304,9 @@ AndroidPresenter.prototype = {
type: 'Accessibility:Event',
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
text: [aText],
fromIndex: aStart
fromIndex: aStart,
removedCount: 0,
addedCount: 0
};
if (aIsInserted) {

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

@ -15,7 +15,7 @@ NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessibleWrap,
IMPL_IUNKNOWN_INHERITED2(HyperTextAccessibleWrap,
AccessibleWrap,
ia2AccessibleHypertext,
CAccessibleEditableText);
ia2AccessibleEditableText);
nsresult
HyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent)

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

@ -9,13 +9,12 @@
#define mozilla_a11y_HyperTextAccessibleWrap_h__
#include "HyperTextAccessible.h"
#include "CAccessibleText.h"
#include "CAccessibleEditableText.h"
#include "ia2AccessibleEditableText.h"
#include "ia2AccessibleHyperText.h"
class HyperTextAccessibleWrap : public HyperTextAccessible,
public ia2AccessibleHypertext,
public CAccessibleEditableText
public ia2AccessibleEditableText
{
public:
HyperTextAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :

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

@ -26,8 +26,6 @@ CPPSRCS = \
nsAccessNodeWrap.cpp \
nsHTMLWin32ObjectAccessible.cpp \
nsWinUtils.cpp \
CAccessibleText.cpp \
CAccessibleEditableText.cpp \
CAccessibleHyperlink.cpp \
CAccessibleTable.cpp \
CAccessibleTableCell.cpp \
@ -36,9 +34,11 @@ CPPSRCS = \
EnumVariant.cpp \
ia2AccessibleAction.cpp \
ia2AccessibleComponent.cpp \
ia2AccessibleEditableText.cpp \
ia2AccessibleImage.cpp \
ia2AccessibleHypertext.cpp \
ia2AccessibleRelation.cpp \
ia2AccessibleText.cpp \
RootAccessibleWrap.cpp \
TextLeafAccessibleWrap.cpp \
$(NULL)

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

@ -5,10 +5,10 @@
* 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 "CAccessibleEditableText.h"
#include "ia2AccessibleEditableText.h"
#include "AccessibleEditableText_i.c"
#include "HyperTextAccessible.h"
#include "HyperTextAccessibleWrap.h"
#include "nsCOMPtr.h"
#include "nsString.h"
@ -16,7 +16,7 @@
// IUnknown
STDMETHODIMP
CAccessibleEditableText::QueryInterface(REFIID iid, void** ppv)
ia2AccessibleEditableText::QueryInterface(REFIID iid, void** ppv)
{
*ppv = NULL;
@ -35,10 +35,10 @@ CAccessibleEditableText::QueryInterface(REFIID iid, void** ppv)
// IAccessibleEditableText
STDMETHODIMP
CAccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -50,10 +50,10 @@ __try {
}
STDMETHODIMP
CAccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -65,10 +65,10 @@ __try {
}
STDMETHODIMP
CAccessibleEditableText::insertText(long aOffset, BSTR *aText)
ia2AccessibleEditableText::insertText(long aOffset, BSTR *aText)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -83,10 +83,10 @@ __try {
}
STDMETHODIMP
CAccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -98,10 +98,10 @@ __try {
}
STDMETHODIMP
CAccessibleEditableText::pasteText(long aOffset)
ia2AccessibleEditableText::pasteText(long aOffset)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -113,11 +113,11 @@ __try {
}
STDMETHODIMP
CAccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
BSTR *aText)
ia2AccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
BSTR *aText)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -136,8 +136,8 @@ __try {
}
STDMETHODIMP
CAccessibleEditableText::setAttributes(long aStartOffset, long aEndOffset,
BSTR *aAttributes)
ia2AccessibleEditableText::setAttributes(long aStartOffset, long aEndOffset,
BSTR *aAttributes)
{
__try {

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

@ -13,7 +13,7 @@
#include "AccessibleEditableText.h"
class CAccessibleEditableText: public IAccessibleEditableText
class ia2AccessibleEditableText: public IAccessibleEditableText
{
public:

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

@ -27,7 +27,7 @@ ia2AccessibleHypertext::QueryInterface(REFIID iid, void** ppv)
return E_NOINTERFACE;
}
return CAccessibleText::QueryInterface(iid, ppv);
return ia2AccessibleText::QueryInterface(iid, ppv);
}
// IAccessibleHypertext

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

@ -10,10 +10,10 @@
#include "nsISupports.h"
#include "CAccessibleText.h"
#include "ia2AccessibleText.h"
#include "AccessibleHypertext.h"
class ia2AccessibleHypertext : public CAccessibleText,
class ia2AccessibleHypertext : public ia2AccessibleText,
public IAccessibleHypertext
{
public:
@ -22,7 +22,7 @@ public:
STDMETHODIMP QueryInterface(REFIID, void**);
// IAccessibleText
FORWARD_IACCESSIBLETEXT(CAccessibleText)
FORWARD_IACCESSIBLETEXT(ia2AccessibleText)
// IAccessibleHypertext
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nHyperlinks(

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

@ -5,19 +5,19 @@
* 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 "CAccessibleText.h"
#include "ia2AccessibleText.h"
#include "Accessible2.h"
#include "AccessibleText_i.c"
#include "HyperTextAccessible.h"
#include "HyperTextAccessibleWrap.h"
#include "nsIPersistentProperties2.h"
// IUnknown
STDMETHODIMP
CAccessibleText::QueryInterface(REFIID iid, void** ppv)
ia2AccessibleText::QueryInterface(REFIID iid, void** ppv)
{
*ppv = NULL;
@ -37,10 +37,10 @@ CAccessibleText::QueryInterface(REFIID iid, void** ppv)
// IAccessibleText
STDMETHODIMP
CAccessibleText::addSelection(long aStartOffset, long aEndOffset)
ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -52,8 +52,8 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_attributes(long aOffset, long *aStartOffset,
long *aEndOffset, BSTR *aTextAttributes)
ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
long *aEndOffset, BSTR *aTextAttributes)
{
__try {
if (!aStartOffset || !aEndOffset || !aTextAttributes)
@ -63,7 +63,7 @@ __try {
*aEndOffset = 0;
*aTextAttributes = NULL;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -90,12 +90,12 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_caretOffset(long *aOffset)
ia2AccessibleText::get_caretOffset(long *aOffset)
{
__try {
*aOffset = -1;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -112,10 +112,10 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_characterExtents(long aOffset,
enum IA2CoordinateType aCoordType,
long *aX, long *aY,
long *aWidth, long *aHeight)
ia2AccessibleText::get_characterExtents(long aOffset,
enum IA2CoordinateType aCoordType,
long *aX, long *aY,
long *aWidth, long *aHeight)
{
__try {
*aX = 0;
@ -123,7 +123,7 @@ __try {
*aWidth = 0;
*aHeight = 0;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -148,12 +148,12 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_nSelections(long *aNSelections)
ia2AccessibleText::get_nSelections(long *aNSelections)
{
__try {
*aNSelections = 0;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -170,14 +170,14 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_offsetAtPoint(long aX, long aY,
enum IA2CoordinateType aCoordType,
long *aOffset)
ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
enum IA2CoordinateType aCoordType,
long *aOffset)
{
__try {
*aOffset = 0;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -198,14 +198,14 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_selection(long aSelectionIndex, long *aStartOffset,
long *aEndOffset)
ia2AccessibleText::get_selection(long aSelectionIndex, long *aStartOffset,
long *aEndOffset)
{
__try {
*aStartOffset = 0;
*aEndOffset = 0;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -224,12 +224,12 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
{
__try {
*aText = NULL;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -249,17 +249,17 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_textBeforeOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
ia2AccessibleText::get_textBeforeOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
{
__try {
*aStartOffset = 0;
*aEndOffset = 0;
*aText = NULL;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -296,17 +296,17 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_textAfterOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
ia2AccessibleText::get_textAfterOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
{
__try {
*aStartOffset = 0;
*aEndOffset = 0;
*aText = NULL;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -343,17 +343,17 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_textAtOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
ia2AccessibleText::get_textAtOffset(long aOffset,
enum IA2TextBoundaryType aBoundaryType,
long *aStartOffset, long *aEndOffset,
BSTR *aText)
{
__try {
*aStartOffset = 0;
*aEndOffset = 0;
*aText = NULL;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -390,10 +390,10 @@ __try {
}
STDMETHODIMP
CAccessibleText::removeSelection(long aSelectionIndex)
ia2AccessibleText::removeSelection(long aSelectionIndex)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -405,10 +405,10 @@ __try {
}
STDMETHODIMP
CAccessibleText::setCaretOffset(long aOffset)
ia2AccessibleText::setCaretOffset(long aOffset)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -420,11 +420,11 @@ __try {
}
STDMETHODIMP
CAccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
long aEndOffset)
ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
long aEndOffset)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -437,12 +437,12 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_nCharacters(long *aNCharacters)
ia2AccessibleText::get_nCharacters(long *aNCharacters)
{
__try {
*aNCharacters = 0;
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -454,11 +454,11 @@ __try {
}
STDMETHODIMP
CAccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
enum IA2ScrollType aScrollType)
ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
enum IA2ScrollType aScrollType)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -470,12 +470,12 @@ __try {
}
STDMETHODIMP
CAccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
enum IA2CoordinateType aCoordType,
long aX, long aY)
ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
enum IA2CoordinateType aCoordType,
long aX, long aY)
{
__try {
nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
if (textAcc->IsDefunct())
return CO_E_OBJNOTCONNECTED;
@ -492,7 +492,7 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_newText(IA2TextSegment *aNewText)
ia2AccessibleText::get_newText(IA2TextSegment *aNewText)
{
__try {
return GetModifiedText(true, aNewText);
@ -502,7 +502,7 @@ __try {
}
STDMETHODIMP
CAccessibleText::get_oldText(IA2TextSegment *aOldText)
ia2AccessibleText::get_oldText(IA2TextSegment *aOldText)
{
__try {
return GetModifiedText(false, aOldText);
@ -511,11 +511,11 @@ __try {
return E_FAIL;
}
// CAccessibleText
// ia2AccessibleText
HRESULT
CAccessibleText::GetModifiedText(bool aGetInsertedText,
IA2TextSegment *aText)
ia2AccessibleText::GetModifiedText(bool aGetInsertedText,
IA2TextSegment *aText)
{
PRUint32 startOffset = 0, endOffset = 0;
nsAutoString text;
@ -536,7 +536,7 @@ CAccessibleText::GetModifiedText(bool aGetInsertedText,
}
AccessibleTextBoundary
CAccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType)
ia2AccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType)
{
switch (aBoundaryType) {
case IA2_TEXT_BOUNDARY_CHAR:

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

@ -13,7 +13,7 @@
#include "AccessibleText.h"
class CAccessibleText: public IAccessibleText
class ia2AccessibleText: public IAccessibleText
{
public:

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

@ -119,6 +119,89 @@ xpcAccessibleTable::GetRowExtentAt(PRInt32 aRowIdx, PRInt32 aColIdx,
return NS_OK;
}
nsresult
xpcAccessibleTable::GetColumnDescription(PRInt32 aColIdx,
nsAString& aDescription)
{
if (!mTable)
return NS_ERROR_FAILURE;
if (aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
return NS_ERROR_INVALID_ARG;
nsAutoString description;
mTable->ColDescription(aColIdx, description);
aDescription.Assign(description);
return NS_OK;
}
nsresult
xpcAccessibleTable::GetRowDescription(PRInt32 aRowIdx, nsAString& aDescription)
{
if (!mTable)
return NS_ERROR_FAILURE;
if (aRowIdx < 0 || static_cast<PRUint32>(aRowIdx) >= mTable->ColCount())
return NS_ERROR_INVALID_ARG;
nsAutoString description;
mTable->RowDescription(aRowIdx, description);
aDescription.Assign(description);
return NS_OK;
}
nsresult
xpcAccessibleTable::IsColumnSelected(PRInt32 aColIdx, bool* aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (!mTable)
return NS_ERROR_FAILURE;
if (aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
return NS_ERROR_INVALID_ARG;
*aIsSelected = mTable->IsColSelected(aColIdx);
return NS_OK;
}
nsresult
xpcAccessibleTable::IsRowSelected(PRInt32 aRowIdx, bool* aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (!mTable)
return NS_ERROR_FAILURE;
if (aRowIdx < 0 || static_cast<PRUint32>(aRowIdx) >= mTable->RowCount())
return NS_ERROR_INVALID_ARG;
*aIsSelected = mTable->IsRowSelected(aRowIdx);
return NS_OK;
}
nsresult
xpcAccessibleTable::IsCellSelected(PRInt32 aRowIdx, PRInt32 aColIdx,
bool* aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (!mTable)
return NS_ERROR_FAILURE;
if (aRowIdx < 0 || static_cast<PRUint32>(aRowIdx) >= mTable->RowCount() ||
aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
return NS_ERROR_INVALID_ARG;
*aIsSelected = mTable->IsCellSelected(aRowIdx, aColIdx);
return NS_OK;
}
nsresult
xpcAccessibleTable::GetSummary(nsAString& aSummary)
{

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

@ -34,6 +34,11 @@ public:
PRInt32* aColumnExtent);
nsresult GetRowExtentAt(PRInt32 row, PRInt32 column,
PRInt32* aRowExtent);
nsresult GetColumnDescription(PRInt32 aColIdx, nsAString& aDescription);
nsresult GetRowDescription(PRInt32 aRowIdx, nsAString& aDescription);
nsresult IsColumnSelected(PRInt32 aColIdx, bool* _retval);
nsresult IsRowSelected(PRInt32 aRowIdx, bool* _retval);
nsresult IsCellSelected(PRInt32 aRowIdx, PRInt32 aColIdx, bool* _retval);
nsresult SelectColumn(PRInt32 aColIdx);
nsresult SelectRow(PRInt32 aRowIdx);
nsresult UnselectColumn(PRInt32 aColIdx);
@ -64,11 +69,16 @@ protected:
{ return xpcAccessibleTable::GetColumnExtentAt(row, column, _retval); } \
NS_SCRIPTABLE NS_IMETHOD GetRowExtentAt(PRInt32 row, PRInt32 column, PRInt32* _retval NS_OUTPARAM) \
{ return xpcAccessibleTable::GetRowExtentAt(row, column, _retval); } \
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 GetColumnDescription(PRInt32 columnIndex, nsAString& _retval NS_OUTPARAM) \
{ return xpcAccessibleTable::GetColumnDescription(columnIndex, _retval); } \
NS_SCRIPTABLE NS_IMETHOD GetRowDescription(PRInt32 rowIndex, nsAString& _retval NS_OUTPARAM) \
{ return xpcAccessibleTable::GetRowDescription(rowIndex, _retval); } \
NS_SCRIPTABLE NS_IMETHOD IsColumnSelected(PRInt32 colIdx, bool* _retval NS_OUTPARAM) \
{ return xpcAccessibleTable::IsColumnSelected(colIdx, _retval); } \
NS_SCRIPTABLE NS_IMETHOD IsRowSelected(PRInt32 rowIdx, bool* _retval NS_OUTPARAM) \
{ return xpcAccessibleTable::IsRowSelected(rowIdx, _retval); } \
NS_SCRIPTABLE NS_IMETHOD IsCellSelected(PRInt32 rowIdx, PRInt32 colIdx, bool* _retval NS_OUTPARAM) \
{ return xpcAccessibleTable::IsCellSelected(rowIdx, colIdx, _retval); } \
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellCount(PRUint32 *aSelectedCellCount); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnCount(PRUint32 *aSelectedColumnCount); \
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowCount(PRUint32 *aSelectedRowCount); \

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

@ -316,30 +316,9 @@ XULListboxAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
return NS_OK;
}
NS_IMETHODIMP
XULListboxAccessible::GetColumnDescription(PRInt32 aColumn,
nsAString& aDescription)
bool
XULListboxAccessible::IsColSelected(PRUint32 aColIdx)
{
aDescription.Truncate();
return NS_OK;
}
NS_IMETHODIMP
XULListboxAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription)
{
aDescription.Truncate();
return NS_OK;
}
NS_IMETHODIMP
XULListboxAccessible::IsColumnSelected(PRInt32 aColumn, bool* aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
do_QueryInterface(mContent);
NS_ASSERTION(control,
@ -347,42 +326,32 @@ XULListboxAccessible::IsColumnSelected(PRInt32 aColumn, bool* aIsSelected)
PRInt32 selectedrowCount = 0;
nsresult rv = control->GetSelectedCount(&selectedrowCount);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, false);
PRInt32 rowCount = 0;
rv = GetRowCount(&rowCount);
NS_ENSURE_SUCCESS(rv, rv);
*aIsSelected = (selectedrowCount == rowCount);
return NS_OK;
return selectedrowCount == RowCount();
}
NS_IMETHODIMP
XULListboxAccessible::IsRowSelected(PRInt32 aRow, bool* aIsSelected)
bool
XULListboxAccessible::IsRowSelected(PRUint32 aRowIdx)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMXULSelectControlElement> control =
do_QueryInterface(mContent);
NS_ASSERTION(control,
"Doesn't implement nsIDOMXULSelectControlElement.");
nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
control->GetItemAtIndex(aRow, getter_AddRefs(item));
NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
nsresult rv = control->GetItemAtIndex(aRowIdx, getter_AddRefs(item));
NS_ENSURE_SUCCESS(rv, false);
return item->GetSelected(aIsSelected);
bool isSelected = false;
item->GetSelected(&isSelected);
return isSelected;
}
NS_IMETHODIMP
XULListboxAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
bool* aIsSelected)
bool
XULListboxAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
{
return IsRowSelected(aRowIndex, aIsSelected);
return IsRowSelected(aRowIdx);
}
NS_IMETHODIMP

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

@ -76,6 +76,9 @@ public:
virtual PRUint32 ColCount();
virtual PRUint32 RowCount();
virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
virtual bool IsColSelected(PRUint32 aColIdx);
virtual bool IsRowSelected(PRUint32 aRowIdx);
virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
virtual void SelectRow(PRUint32 aRowIdx);
virtual void UnselectRow(PRUint32 aRowIdx);

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

@ -553,6 +553,11 @@ XULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
if (IsDefunct())
return;
if (!mTreeView) {
ClearCache(mAccessibleCache);
return;
}
// Do not invalidate the cache if rows have been inserted.
if (aCount > 0)
return;

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

@ -368,83 +368,53 @@ XULTreeGridAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
return NS_OK;
}
NS_IMETHODIMP
XULTreeGridAccessible::GetColumnDescription(PRInt32 aColumnIndex,
nsAString& aDescription)
void
XULTreeGridAccessible::ColDescription(PRUint32 aColIdx, nsString& aDescription)
{
aDescription.Truncate();
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAccessible> treeColumns;
Accessible::GetFirstChild(getter_AddRefs(treeColumns));
if (treeColumns) {
nsCOMPtr<nsIAccessible> treeColumnItem;
treeColumns->GetChildAt(aColumnIndex, getter_AddRefs(treeColumnItem));
treeColumns->GetChildAt(aColIdx, getter_AddRefs(treeColumnItem));
if (treeColumnItem)
return treeColumnItem->GetName(aDescription);
treeColumnItem->GetName(aDescription);
}
return NS_OK;
}
NS_IMETHODIMP
XULTreeGridAccessible::GetRowDescription(PRInt32 aRowIndex,
nsAString& aDescription)
bool
XULTreeGridAccessible::IsColSelected(PRUint32 aColIdx)
{
aDescription.Truncate();
return NS_OK;
}
NS_IMETHODIMP
XULTreeGridAccessible::IsColumnSelected(PRInt32 aColumnIndex, bool* aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
// If all the row has been selected, then all the columns are selected.
// Because we can't select a column alone.
PRInt32 rowCount = 0;
nsresult rv = GetRowCount(&rowCount);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 selectedrowCount = 0;
rv = GetSelectionCount(&selectedrowCount);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = GetSelectionCount(&selectedrowCount);
NS_ENSURE_SUCCESS(rv, false);
*aIsSelected = rowCount == selectedrowCount;
return NS_OK;
return selectedrowCount == RowCount();
}
NS_IMETHODIMP
XULTreeGridAccessible::IsRowSelected(PRInt32 aRowIndex, bool* aIsSelected)
bool
XULTreeGridAccessible::IsRowSelected(PRUint32 aRowIdx)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = false;
if (IsDefunct())
return NS_ERROR_FAILURE;
if (!mTreeView)
return NS_ERROR_INVALID_ARG;
return false;
nsCOMPtr<nsITreeSelection> selection;
nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, false);
return selection->IsSelected(aRowIndex, aIsSelected);
bool isSelected = false;
selection->IsSelected(aRowIdx, &isSelected);
return isSelected;
}
NS_IMETHODIMP
XULTreeGridAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
bool* aIsSelected)
bool
XULTreeGridAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
{
return IsRowSelected(aRowIndex, aIsSelected);
return IsRowSelected(aRowIdx);
}
void

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

@ -34,6 +34,10 @@ public:
virtual PRUint32 ColCount();
virtual PRUint32 RowCount();
virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
virtual void ColDescription(PRUint32 aColIdx, nsString& aDescription);
virtual bool IsColSelected(PRUint32 aColIdx);
virtual bool IsRowSelected(PRUint32 aRowIdx);
virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
virtual void SelectRow(PRUint32 aRowIdx);
virtual void UnselectRow(PRUint32 aRowIdx);

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

@ -50,25 +50,9 @@ function doTest()
is(accTable.selectedRowCount, 1, "no cells selected");
var columnDescription;
works = true;
try{
columnDescription = accTable.getColumnDescription(1);
}
catch (e) {
works = false;
}
todo(works, "columnDescription should not throw");
var columnDescription = accTable.getColumnDescription(1);
var rowDescription = accTable.getRowDescription(1);
var rowDescription;
works = true;
try {
rowDescription = accTable.getRowDescription(1);
}
catch (e) {
works = false;
}
todo(works, "rowDescription should not throw");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
@ -78,6 +62,12 @@ addA11yLoadEvent(doTest);
<body >
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=760878"
title="decomtaminate Get Row / Column Description() on accessible tables">
Mozilla Bug 760878
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">

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

@ -6,35 +6,6 @@
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.xul");
pref("browser.chromeURL", "chrome://browser/content/");
#ifdef MOZ_OFFICIAL_BRANDING
pref("browser.homescreenURL", "http://homescreen.gaiamobile.org/");
#else
pref("browser.homescreenURL", "http://homescreen.gaiamobile.org/");
#endif
// All the privileged domains
// XXX TODO : we should read them from a file somewhere
pref("b2g.privileged.domains", "http://browser.gaiamobile.org,
http://calculator.gaiamobile.org,
http://contacts.gaiamobile.org,
http://camera.gaiamobile.org,
http://clock.gaiamobile.org,
http://crystalskull.gaiamobile.org,
http://cubevid.gaiamobile.org,
http://dialer.gaiamobile.org,
http://gallery.gaiamobile.org,
http://homescreen.gaiamobile.org,
http://maps.gaiamobile.org,
http://market.gaiamobile.org,
http://music.gaiamobile.org,
http://penguinpop.gaiamobile.org,
http://settings.gaiamobile.org,
http://sms.gaiamobile.org,
http://towerjelly.gaiamobile.org,
http://video.gaiamobile.org");
// URL for the dialer application.
pref("dom.telephony.app.phone.url", "http://dialer.gaiamobile.org,http://homescreen.gaiamobile.org");
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
pref("browser.viewport.scaleRatio", -1);
@ -395,7 +366,6 @@ pref("browser.link.open_newwindow.restriction", 0);
// Enable browser frames (including OOP, except on Windows, where it doesn't
// work), but make in-process browser frames the default.
pref("dom.mozBrowserFramesEnabled", true);
pref("dom.mozBrowserFramesWhitelist", "http://homescreen.gaiamobile.org,http://browser.gaiamobile.org");
pref("dom.ipc.tabs.disabled", false);
@ -403,14 +373,9 @@ pref("dom.ipc.browser_frames.oop_by_default", false);
// Temporary permission hack for WebSMS
pref("dom.sms.enabled", true);
pref("dom.sms.whitelist", "file://,http://homescreen.gaiamobile.org,http://sms.gaiamobile.org");
// Temporary permission hack for WebMobileConnection
pref("dom.mobileconnection.whitelist", "http://system.gaiamobile.org,http://homescreen.gaiamobile.org,http://dialer.gaiamobile.org");
// Temporary permission hack for WebContacts
pref("dom.mozContacts.enabled", true);
pref("dom.mozContacts.whitelist", "http://dialer.gaiamobile.org,http://sms.gaiamobile.org");
// WebSettings
pref("dom.mozSettings.enabled", true);
@ -439,9 +404,8 @@ pref("b2g.remote-js.port", 9999);
pref("b2g.keys.menu.enabled", true);
pref("b2g.keys.search.enabled", false);
// Screen timeout in minutes
// Screen timeout in seconds
pref("power.screen.timeout", 60);
pref("dom.power.whitelist", "http://homescreen.gaiamobile.org,http://settings.gaiamobile.org");
pref("full-screen-api.enabled", true);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -24,7 +24,7 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="BrowserStartup()" onunload="BrowserShutdown()" onclose="return WindowIsClosing();"
onload="gBrowserInit.onLoad()" onunload="gBrowserInit.onUnload()" onclose="return WindowIsClosing();"
title="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
title_normal="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
#ifdef XP_MACOSX

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

@ -34,8 +34,8 @@
return OpenBrowserWindow();
}
addEventListener("load", nonBrowserWindowStartup, false);
addEventListener("unload", nonBrowserWindowShutdown, false);
addEventListener("load", function() { gBrowserInit.nonBrowserWindowStartup() }, false);
addEventListener("unload", function() { gBrowserInit.nonBrowserWindowShutdown() }, false);
</script>
# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the

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

@ -42,7 +42,8 @@ function test1a() {
ok(!popupNotification, "Test 1a, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentWindow.addPlugin();
setTimeout(test1b, 500);
var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin notification");
}
function test1b() {
@ -53,7 +54,7 @@ function test1b() {
ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated");
popupNotification.mainAction.callback();
setTimeout(test1c, 500);
test1c();
}
function test1c() {
@ -61,7 +62,9 @@ function test1c() {
ok(!popupNotification, "Test 1c, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentWindow.addPlugin();
setTimeout(test1d, 500);
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test1d, "Test 1c, Waited too long for plugin activation");
}
function test1d() {
@ -82,7 +85,9 @@ function test1e() {
ok(!popupNotification, "Test 1e, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentWindow.addPlugin();
setTimeout(test1f, 500);
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test1f, "Test 1e, Waited too long for plugin activation");
}
function test1f() {
@ -93,8 +98,10 @@ function test1f() {
ok(objLoadingContent.activated, "Test 1f, Plugin should be activated");
gTestBrowser.contentWindow.history.replaceState({}, "", "replacedState");
gTestBrowser.contentWindow.addPlugin();
setTimeout(test1g, 500);
var plugin = gTestBrowser.contentWindow.addPlugin();
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test1g, "Test 1f, Waited too long for plugin activation");
}
function test1g() {

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

@ -213,21 +213,6 @@ function test8() {
prepareTest(test9a, gTestRoot + "plugin_test2.html");
}
function waitForCondition(condition, nextTest, errorMsg) {
var tries = 0;
var interval = setInterval(function() {
if (tries >= 500) {
ok(false, errorMsg);
moveOn();
}
if (condition()) {
moveOn();
}
tries++;
}, 10);
var moveOn = function() { clearInterval(interval); nextTest(); };
}
// Tests that activating one click-to-play plugin will activate only that plugin (part 1/3)
function test9a() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);

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

@ -72,3 +72,18 @@ function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
button.focus();
button.doCommand();
}
function waitForCondition(condition, nextTest, errorMsg) {
var tries = 0;
var interval = setInterval(function() {
if (tries >= 30) {
ok(false, errorMsg);
moveOn();
}
if (condition()) {
moveOn();
}
tries++;
}, 100);
var moveOn = function() { clearInterval(interval); nextTest(); };
}

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

@ -245,7 +245,7 @@ function openWindow(parent, url, target, features, args, noExternalArgs) {
}
// Pass these as null to ensure that we always trigger the "single URL"
// behavior in browser.js's BrowserStartup (which handles the window
// behavior in browser.js's gBrowserInit.onLoad (which handles the window
// arguments)
argArray.AppendElement(null); // charset
argArray.AppendElement(null); // referer

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

@ -35,7 +35,8 @@ EXTRA_COMPONENTS = nsSetDefaultBrowser.js nsSetDefaultBrowser.manifest
include $(topsrcdir)/config/rules.mk
DEFINES += -DMOZ_APP_NAME=\"$(MOZ_APP_NAME)\"
DEFINES += -DMOZ_APP_NAME=\"$(MOZ_APP_NAME)\" \
-DMOZ_APP_VERSION=\"$(MOZ_APP_VERSION)\"
CXXFLAGS += $(TK_CFLAGS)

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

@ -201,7 +201,8 @@ static SETTING gDDESettings[] = {
#include "updatehelper.h"
#include "updatehelper.cpp"
static const char kPrefetchClearedPref[] = "app.update.service.prefetchCleared";
static const char *kPrefetchClearedPref =
"app.update.service.lastVersionPrefetchCleared";
static nsCOMPtr<nsIThread> sThread;
#endif
@ -1016,17 +1017,20 @@ nsWindowsShellService::nsWindowsShellService() :
}
// check to see if we have attempted to do the one time operation of clearing
// the prefetch.
bool prefetchCleared;
// the prefetch. We do it once per version upgrade.
nsCString lastClearedVer;
nsCOMPtr<nsIPrefBranch> prefBranch;
nsCOMPtr<nsIPrefService> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs ||
NS_FAILED(prefs->GetBranch(nsnull, getter_AddRefs(prefBranch))) ||
(NS_SUCCEEDED(prefBranch->GetBoolPref(kPrefetchClearedPref,
&prefetchCleared)) &&
prefetchCleared)) {
return;
(NS_SUCCEEDED(prefBranch->GetCharPref(kPrefetchClearedPref,
getter_Copies(lastClearedVer))))) {
// If the versions are the same, then bail out early. We only want to clear
// once per version.
if (!strcmp(MOZ_APP_VERSION, lastClearedVer.get())) {
return;
}
}
// In a minute after startup is definitely complete, launch the
@ -1097,7 +1101,7 @@ nsWindowsShellService::LaunchPrefetchClearCommand(nsITimer *aTimer, void*)
do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs) {
if (NS_SUCCEEDED(prefs->GetBranch(nsnull, getter_AddRefs(prefBranch)))) {
prefBranch->SetBoolPref(kPrefetchClearedPref, true);
prefBranch->SetCharPref(kPrefetchClearedPref, MOZ_APP_VERSION);
}
}

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

@ -1234,7 +1234,7 @@ InspectorUI.prototype = {
/**
* Destroy the InspectorUI instance. This is called by the InspectorUI API
* "user", see BrowserShutdown() in browser.js.
* "user", see gBrowserInit.onUnload() in browser.js.
*/
destroy: function IUI_destroy()
{

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

@ -17,6 +17,7 @@ public class FindProcThread extends Thread {
boolean bStillRunning = true;
public FindProcThread(ContextWrapper ctx, String sProcessName) {
super("FindProcThread");
this.contextWrapper = ctx;
this.sProcNameToFind = sProcessName;
this.bFoundIt = false;

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

@ -20,6 +20,7 @@ public class RedirOutputThread extends Thread
public RedirOutputThread(Process pProc, OutputStream out)
{
super("RedirOutputThread");
if (pProc != null)
{
this.pProc = pProc;
@ -50,6 +51,13 @@ public class RedirOutputThread extends Thread
{
try
{
// If there's no output to collect, sleep for a while
// rather than checking again immediately, to avoid
// using up cpu capacity in a tight loop.
if (sutOut.available() == 0 && sutErr.available() == 0)
{
Thread.sleep(50);
}
if ((nBytesOut = sutOut.available()) > 0)
{
if (nBytesOut > buffer.length)
@ -109,6 +117,10 @@ public class RedirOutputThread extends Thread
// Bug 743766: InputStream.available() unexpectedly throws this sometimes
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
pProc.destroy();

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -4419,12 +4419,6 @@ nsDocument::CreateComment(const nsAString& aData, nsIDOMComment** aReturn)
{
*aReturn = nsnull;
// Make sure the substring "--" is not present in aData. Otherwise
// we'll create a document that can't be serialized.
if (FindInReadable(NS_LITERAL_STRING("--"), aData)) {
return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
}
nsCOMPtr<nsIContent> comment;
nsresult rv = NS_NewCommentNode(getter_AddRefs(comment), mNodeInfoManager);
@ -9614,6 +9608,14 @@ nsIDocument::DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
&aWindowSizes->mLayoutPresContext);
}
aWindowSizes->mPropertyTables +=
mPropertyTable.SizeOfExcludingThis(aWindowSizes->mMallocSizeOf);
for (PRUint32 i = 0, count = mExtraPropertyTables.Length();
i < count; ++i) {
aWindowSizes->mPropertyTables +=
mExtraPropertyTables[i]->SizeOfExcludingThis(aWindowSizes->mMallocSizeOf);
}
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - many!

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

@ -4098,7 +4098,9 @@ bool IsAllowedAsChild(nsIContent* aNewChild, nsINode* aParent,
{
// Note that for now we only allow nodes inside document fragments if
// they're allowed inside elements. If we ever change this to allow
// doctype nodes in document fragments, we'll need to update this code
// doctype nodes in document fragments, we'll need to update this code.
// Also, there's a version of this code in ReplaceOrInsertBefore. If you
// change this code, change that too.
if (!aParent->IsNodeOfType(nsINode::eDOCUMENT)) {
// All good here
return true;
@ -4159,6 +4161,11 @@ nsresult
nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
nsINode* aRefChild)
{
// XXXbz I wish I could assert that nsContentUtils::IsSafeToRunScript() so we
// could rely on scriptblockers going out of scope to actually run XBL
// teardown, but various crud adds nodes under scriptblockers (e.g. native
// anonymous content). The only good news is those insertions can't trigger
// the bad XBL cases.
if (!aNewChild || (aReplace && !aRefChild)) {
return NS_ERROR_NULL_POINTER;
}
@ -4235,6 +4242,8 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
nodeToInsertBefore = nodeToInsertBefore->GetNextSibling();
}
Maybe<nsAutoTArray<nsCOMPtr<nsIContent>, 50> > fragChildren;
// Remove the new child from the old parent if one exists
nsCOMPtr<nsINode> oldParent = newContent->GetNodeParent();
if (oldParent) {
@ -4254,7 +4263,8 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
// Scope for the mutation batch and scriptblocker, so they go away
// while kungFuDeathGrip is still alive.
{
mozAutoDocUpdate batch(GetCurrentDoc(), UPDATE_CONTENT_MODEL, true);
mozAutoDocUpdate batch(newContent->GetCurrentDoc(),
UPDATE_CONTENT_MODEL, true);
nsAutoMutationBatch mb(oldParent, true, true);
oldParent->RemoveChildAt(removeIndex, true);
if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
@ -4299,6 +4309,98 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
}
}
}
} else if (nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
// Make sure to remove all the fragment's kids. We need to do this before
// we start inserting anything, so we will run out XBL destructors and
// binding teardown (GOD, I HATE THESE THINGS) before we insert anything
// into the DOM.
PRUint32 count = newContent->GetChildCount();
fragChildren.construct();
// Copy the children into a separate array to avoid having to deal with
// mutations to the fragment later on here.
fragChildren.ref().SetCapacity(count);
for (nsIContent* child = newContent->GetFirstChild();
child;
child = child->GetNextSibling()) {
NS_ASSERTION(child->GetCurrentDoc() == nsnull,
"How did we get a child with a current doc?");
fragChildren.ref().AppendElement(child);
}
// Hold a strong ref to nodeToInsertBefore across the removals
nsCOMPtr<nsINode> kungFuDeathGrip = nodeToInsertBefore;
nsMutationGuard guard;
// Scope for the mutation batch and scriptblocker, so they go away
// while kungFuDeathGrip is still alive.
{
mozAutoDocUpdate batch(newContent->GetCurrentDoc(),
UPDATE_CONTENT_MODEL, true);
nsAutoMutationBatch mb(newContent, false, true);
for (PRUint32 i = count; i > 0;) {
newContent->RemoveChildAt(--i, true);
}
}
// We expect |count| removals
if (guard.Mutated(count)) {
// XBL destructors, yuck.
// Verify that nodeToInsertBefore, if non-null, is still our child. If
// it's not, there's no way we can do this insert sanely; just bail out.
if (nodeToInsertBefore && nodeToInsertBefore->GetParent() != this) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
// Verify that all the things in fragChildren have no parent.
for (PRUint32 i = 0; i < count; ++i) {
if (fragChildren.ref().ElementAt(i)->GetParent()) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
}
// Note that unlike the single-element case above, none of our kids can
// be aRefChild, so we can always pass through aReplace in the
// IsAllowedAsChild checks below and don't have to worry about whether
// recomputing nodeToInsertBefore is OK.
// Verify that our aRefChild is still sensible
if (aRefChild && aRefChild->GetParent() != this) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
// Recompute nodeToInsertBefore, just in case.
if (aReplace) {
nodeToInsertBefore = aRefChild->GetNextSibling();
} else {
nodeToInsertBefore = aRefChild;
}
// And verify that newContent is still allowed as our child. Sadly, we
// need to reimplement the relevant part of IsAllowedAsChild() because
// now our nodes are in an array and all. If you change this code,
// change the code there.
if (IsNodeOfType(nsINode::eDOCUMENT)) {
bool sawElement = false;
for (PRUint32 i = 0; i < count; ++i) {
nsIContent* child = fragChildren.ref().ElementAt(i);
if (child->IsElement()) {
if (sawElement) {
// No good
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
sawElement = true;
}
if (!IsAllowedAsChild(child, this, aReplace, aRefChild)) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
}
}
}
}
mozAutoDocUpdate batch(GetCurrentDoc(), UPDATE_CONTENT_MODEL, true);
@ -4349,36 +4451,15 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
/*
* Check if we're inserting a document fragment. If we are, we need
* to remove the children of the document fragment and add them
* individually (i.e. we don't add the actual document fragment).
* to actually add its children individually (i.e. we don't add the
* actual document fragment).
*/
if (nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
PRUint32 count = newContent->GetChildCount();
PRUint32 count = fragChildren.ref().Length();
if (!count) {
return NS_OK;
}
// Copy the children into a separate array to avoid having to deal with
// mutations to the fragment while we're inserting.
nsAutoTArray<nsCOMPtr<nsIContent>, 50> fragChildren;
fragChildren.SetCapacity(count);
for (nsIContent* child = newContent->GetFirstChild();
child;
child = child->GetNextSibling()) {
NS_ASSERTION(child->GetCurrentDoc() == nsnull,
"How did we get a child with a current doc?");
fragChildren.AppendElement(child);
}
// Remove the children from the fragment.
{
nsAutoMutationBatch mb(newContent, false, true);
for (PRUint32 i = count; i > 0;) {
newContent->RemoveChildAt(--i, true);
}
}
if (!aReplace) {
mb.Init(this, true, true);
}
@ -4392,14 +4473,14 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
bool appending =
!IsNodeOfType(eDOCUMENT) && PRUint32(insPos) == GetChildCount();
PRInt32 firstInsPos = insPos;
nsIContent* firstInsertedContent = fragChildren[0];
nsIContent* firstInsertedContent = fragChildren.ref().ElementAt(0);
// Iterate through the fragment's children, and insert them in the new
// parent
for (PRUint32 i = 0; i < count; ++i, ++insPos) {
// XXXbz how come no reparenting here? That seems odd...
// Insert the child.
res = InsertChildAt(fragChildren[i], insPos, !appending);
res = InsertChildAt(fragChildren.ref().ElementAt(i), insPos, !appending);
if (NS_FAILED(res)) {
// Make sure to notify on any children that we did succeed to insert
if (appending && i != 0) {
@ -4425,7 +4506,7 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
// Optimize for the case when there are no listeners
if (nsContentUtils::
HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
nsGenericElement::FireNodeInserted(doc, this, fragChildren);
nsGenericElement::FireNodeInserted(doc, this, fragChildren.ref());
}
}
}

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

@ -52,6 +52,8 @@ public:
return mName == aPropertyName;
}
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf);
nsCOMPtr<nsIAtom> mName; // property name
PLDHashTable mObjectValueMap; // map of object/value pairs
NSPropertyDtorFunc mDtorFunc; // property specific value dtor function
@ -337,6 +339,26 @@ nsPropertyTable::PropertyList::DeletePropertyFor(nsPropertyOwner aObject)
return true;
}
size_t
nsPropertyTable::PropertyList::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf)
{
size_t n = aMallocSizeOf(this);
n += PL_DHashTableSizeOfExcludingThis(&mObjectValueMap, NULL, aMallocSizeOf);
return n;
}
size_t
nsPropertyTable::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
{
size_t n = 0;
for (PropertyList *prop = mPropertyList; prop; prop = prop->mNext) {
n += prop->SizeOfIncludingThis(aMallocSizeOf);
}
return n;
}
/* static */
void
nsPropertyTable::SupportsDtorFunc(void *aObject, nsIAtom *aPropertyName,

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

@ -177,6 +177,8 @@ class nsPropertyTable
class PropertyList;
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
private:
NS_HIDDEN_(void) DestroyPropertyList();
NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom *aPropertyName) const;

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

@ -1076,14 +1076,14 @@ nsXMLHttpRequest::StaticAssertions()
#_uc " should match")
ASSERT_ENUM_EQUAL(_empty, DEFAULT);
ASSERT_ENUM_EQUAL(arraybuffer, ARRAYBUFFER);
ASSERT_ENUM_EQUAL(blob, BLOB);
ASSERT_ENUM_EQUAL(document, DOCUMENT);
ASSERT_ENUM_EQUAL(json, JSON);
ASSERT_ENUM_EQUAL(text, TEXT);
ASSERT_ENUM_EQUAL(moz_chunked_text, CHUNKED_TEXT);
ASSERT_ENUM_EQUAL(moz_chunked_arraybuffer, CHUNKED_ARRAYBUFFER);
ASSERT_ENUM_EQUAL(moz_blob, MOZ_BLOB);
ASSERT_ENUM_EQUAL(Arraybuffer, ARRAYBUFFER);
ASSERT_ENUM_EQUAL(Blob, BLOB);
ASSERT_ENUM_EQUAL(Document, DOCUMENT);
ASSERT_ENUM_EQUAL(Json, JSON);
ASSERT_ENUM_EQUAL(Text, TEXT);
ASSERT_ENUM_EQUAL(Moz_chunked_text, CHUNKED_TEXT);
ASSERT_ENUM_EQUAL(Moz_chunked_arraybuffer, CHUNKED_ARRAYBUFFER);
ASSERT_ENUM_EQUAL(Moz_blob, MOZ_BLOB);
#undef ASSERT_ENUM_EQUAL
}
#endif

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

@ -44,7 +44,7 @@ function testCharacterData(aNode, aText)
is(aNode.namespaceURI, null, "Check namespaceURI");
}
function testComment(aText, aShouldSucceed)
function testComment(aText)
{
try {
var comment = document.createComment(aText);
@ -58,18 +58,8 @@ function testComment(aText, aShouldSucceed)
testCharacterData(comment, aText);
is(comment.nodeName, "#comment", "Check nodeName");
is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType");
if (!aShouldSucceed) {
ok(0, "Invalid comment creation",
"Shouldn't create comment with embedded \"--\"");
}
} catch (e) {
if (aShouldSucceed) {
ok(0, "Correct functioning of comment stuff", "something broke: " + e);
} else {
is(e.name, "InvalidCharacterError", "Check exception");
is(e.code, DOMException.INVALID_CHARACTER_ERR, "Check exception code");
}
ok(0, "Correct functioning of comment stuff", "something broke: " + e);
}
}
@ -119,11 +109,11 @@ function testPI(aTarget, aData, aShouldSucceed, aReason)
}
}
testComment("Some text", true);
testComment("Some text with a '-' in it", true);
testComment("Some text with a '-' and a '-' and another '-'", true);
testComment("Some text -- this shouldn't create a node!", false);
testComment("<!-- This is an HTML comment -->", false);
testComment("Some text");
testComment("Some text with a '-' in it");
testComment("Some text with a '-' and a '-' and another '-'");
testComment("Some text -- this shouldn't create a node!");
testComment("<!-- This is an HTML comment -->");
testCDATASection("Some text", true);
testCDATASection("Some text with a '?' in it", true);

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

@ -68,7 +68,7 @@ function testCharacterData(aNode, aText)
is(aNode.namespaceURI, null, "Check namespaceURI");
}
function testComment(aText, aShouldSucceed)
function testComment(aText)
{
try {
var comment = document.createComment(aText);
@ -82,18 +82,8 @@ function testComment(aText, aShouldSucceed)
testCharacterData(comment, aText);
is(comment.nodeName, "#comment", "Check nodeName");
is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType");
if (!aShouldSucceed) {
ok(0, "Invalid comment creation",
"Shouldn't create comment with embedded \"--\"");
}
} catch (e) {
if (aShouldSucceed) {
ok(0, "Correct functioning of comment stuff", "something broke: " + e);
} else {
is(e.name, "InvalidCharacterError", "Check exception");
is(e.code, DOMException.INVALID_CHARACTER_ERR, "Check exception code");
}
ok(0, "Correct functioning of comment stuff", "something broke: " + e);
}
}
@ -163,11 +153,11 @@ function testPI(aTarget, aData, aShouldSucceed, aReason)
}
}
testComment("Some text", true);
testComment("Some text with a '-' in it", true);
testComment("Some text with a '-' and a '-' and another '-'", true);
testComment("Some text -- this shouldn't create a node!", false);
testComment("<!-- This is an HTML comment -->", false);
testComment("Some text");
testComment("Some text with a '-' in it");
testComment("Some text with a '-' and a '-' and another '-'");
testComment("Some text -- this should create a node!");
testComment("<!-- This is an HTML comment -->");
testCDATASection("Some text", true);
testCDATASection("Some text with a '?' in it", true);

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

@ -76,7 +76,7 @@ WebGLContext::WebGLContext()
: gl(nsnull)
{
SetIsDOMBinding();
mEnabledExtensions.SetLength(WebGLExtensionID_Max);
mExtensions.SetLength(WebGLExtensionID_number_of_extensions);
mGeneration = 0;
mInvalidated = false;
@ -840,37 +840,35 @@ WebGLContext::MozGetUnderlyingParamString(PRUint32 pname, nsAString& retval)
return NS_OK;
}
bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext)
{
bool isSupported;
bool isSupported = false;
switch (ei) {
case WebGL_OES_texture_float:
switch (ext) {
case OES_standard_derivatives:
case WEBGL_lose_context:
// We always support these extensions.
isSupported = true;
break;
case OES_texture_float:
isSupported = gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float
: GLContext::ARB_texture_float);
break;
case WebGL_OES_standard_derivatives:
// We always support this extension.
isSupported = true;
break;
case WebGL_EXT_texture_filter_anisotropic:
case EXT_texture_filter_anisotropic:
isSupported = gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
break;
case WebGL_WEBGL_lose_context:
// We always support this extension.
isSupported = true;
break;
case WebGL_WEBGL_compressed_texture_s3tc:
case WEBGL_compressed_texture_s3tc:
if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_s3tc)) {
isSupported = true;
} else {
isSupported = gl->IsExtensionSupported(GLContext::EXT_texture_compression_dxt1) &&
gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt3) &&
gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt5);
} else if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_dxt1) &&
gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt3) &&
gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt5))
{
isSupported = true;
}
break;
default:
isSupported = false;
MOZ_ASSERT(false, "should not get there.");
}
return isSupported;
@ -889,62 +887,73 @@ WebGLContext::GetExtension(const nsAString& aName)
{
if (!IsContextStable())
return nsnull;
if (mDisableExtensions) {
return nsnull;
}
nsString lowerCaseName(aName);
ToLowerCase(lowerCaseName);
WebGLExtensionID ext = WebGLExtensionID_unknown_extension;
WebGLExtensionID ei = WebGLExtensionID_Max;
if (lowerCaseName.EqualsLiteral("oes_texture_float")) {
if (IsExtensionSupported(WebGL_OES_texture_float))
ei = WebGL_OES_texture_float;
if (aName.Equals(NS_LITERAL_STRING("OES_texture_float"),
nsCaseInsensitiveStringComparator()))
{
if (IsExtensionSupported(OES_texture_float))
ext = OES_texture_float;
}
else if (lowerCaseName.EqualsLiteral("oes_standard_derivatives")) {
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
ei = WebGL_OES_standard_derivatives;
else if (aName.Equals(NS_LITERAL_STRING("OES_standard_derivatives"),
nsCaseInsensitiveStringComparator()))
{
if (IsExtensionSupported(OES_standard_derivatives))
ext = OES_standard_derivatives;
}
else if (lowerCaseName.EqualsLiteral("moz_ext_texture_filter_anisotropic")) {
if (IsExtensionSupported(WebGL_EXT_texture_filter_anisotropic))
ei = WebGL_EXT_texture_filter_anisotropic;
else if (aName.Equals(NS_LITERAL_STRING("MOZ_EXT_texture_filter_anisotropic"),
nsCaseInsensitiveStringComparator()))
{
if (IsExtensionSupported(EXT_texture_filter_anisotropic))
ext = EXT_texture_filter_anisotropic;
}
else if (lowerCaseName.EqualsLiteral("moz_webgl_lose_context")) {
if (IsExtensionSupported(WebGL_WEBGL_lose_context))
ei = WebGL_WEBGL_lose_context;
else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"),
nsCaseInsensitiveStringComparator()))
{
if (IsExtensionSupported(WEBGL_lose_context))
ext = WEBGL_lose_context;
}
else if (lowerCaseName.EqualsLiteral("moz_webgl_compressed_texture_s3tc")) {
if (IsExtensionSupported(WebGL_WEBGL_compressed_texture_s3tc))
ei = WebGL_WEBGL_compressed_texture_s3tc;
else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_s3tc"),
nsCaseInsensitiveStringComparator()))
{
if (IsExtensionSupported(WEBGL_compressed_texture_s3tc))
ext = WEBGL_compressed_texture_s3tc;
}
if (ei != WebGLExtensionID_Max) {
if (!IsExtensionEnabled(ei)) {
switch (ei) {
case WebGL_OES_standard_derivatives:
mEnabledExtensions[ei] = new WebGLExtensionStandardDerivatives(this);
break;
case WebGL_EXT_texture_filter_anisotropic:
mEnabledExtensions[ei] = new WebGLExtensionTextureFilterAnisotropic(this);
break;
case WebGL_WEBGL_lose_context:
mEnabledExtensions[ei] = new WebGLExtensionLoseContext(this);
break;
case WebGL_WEBGL_compressed_texture_s3tc:
mEnabledExtensions[ei] = new WebGLExtensionCompressedTextureS3TC(this);
break;
// create an extension for any types that don't
// have any additional tokens or methods
default:
mEnabledExtensions[ei] = new WebGLExtension(this);
break;
}
if (ext == WebGLExtensionID_unknown_extension) {
return nsnull;
}
if (!mExtensions[ext]) {
switch (ext) {
case OES_standard_derivatives:
mExtensions[ext] = new WebGLExtensionStandardDerivatives(this);
break;
case EXT_texture_filter_anisotropic:
mExtensions[ext] = new WebGLExtensionTextureFilterAnisotropic(this);
break;
case WEBGL_lose_context:
mExtensions[ext] = new WebGLExtensionLoseContext(this);
break;
case WEBGL_compressed_texture_s3tc:
mExtensions[ext] = new WebGLExtensionCompressedTextureS3TC(this);
break;
default:
// create a generic WebGLExtension object for any extensions that don't
// have any additional tokens or methods. We still need these to be separate
// objects in case the user might extend the corresponding JS objects with custom
// properties.
mExtensions[ext] = new WebGLExtension(this);
break;
}
return mEnabledExtensions[ei];
}
return nsnull;
return mExtensions[ext];
}
void
@ -1211,13 +1220,13 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebGLContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCanvasElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mEnabledExtensions)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mExtensions)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WebGLContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mCanvasElement, nsINode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mEnabledExtensions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mExtensions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -1312,6 +1321,12 @@ NS_INTERFACE_MAP_BEGIN(WebGLUniformLocation)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLUniformLocation)
NS_INTERFACE_MAP_END
JSObject*
WebGLUniformLocation::WrapObject(JSContext *cx, JSObject *scope)
{
return dom::WebGLUniformLocationBinding::Wrap(cx, scope, this);
}
NS_IMPL_ADDREF(WebGLShaderPrecisionFormat)
NS_IMPL_RELEASE(WebGLShaderPrecisionFormat)
@ -1491,15 +1506,15 @@ WebGLContext::GetSupportedExtensions(Nullable< nsTArray<nsString> > &retval)
nsTArray<nsString>& arr = retval.SetValue();
if (IsExtensionSupported(WebGL_OES_texture_float))
if (IsExtensionSupported(OES_texture_float))
arr.AppendElement(NS_LITERAL_STRING("OES_texture_float"));
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
if (IsExtensionSupported(OES_standard_derivatives))
arr.AppendElement(NS_LITERAL_STRING("OES_standard_derivatives"));
if (IsExtensionSupported(WebGL_EXT_texture_filter_anisotropic))
if (IsExtensionSupported(EXT_texture_filter_anisotropic))
arr.AppendElement(NS_LITERAL_STRING("MOZ_EXT_texture_filter_anisotropic"));
if (IsExtensionSupported(WebGL_WEBGL_lose_context))
if (IsExtensionSupported(WEBGL_lose_context))
arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"));
if (IsExtensionSupported(WebGL_WEBGL_compressed_texture_s3tc))
if (IsExtensionSupported(WEBGL_compressed_texture_s3tc))
arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_s3tc"));
}

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

@ -1156,19 +1156,23 @@ protected:
// extensions
enum WebGLExtensionID {
WebGL_OES_texture_float,
WebGL_OES_standard_derivatives,
WebGL_EXT_texture_filter_anisotropic,
WebGL_WEBGL_lose_context,
WebGL_WEBGL_compressed_texture_s3tc,
WebGLExtensionID_Max
OES_texture_float,
OES_standard_derivatives,
EXT_texture_filter_anisotropic,
WEBGL_lose_context,
WEBGL_compressed_texture_s3tc,
WebGLExtensionID_number_of_extensions,
WebGLExtensionID_unknown_extension
};
nsAutoTArray<nsRefPtr<WebGLExtension>, WebGLExtensionID_Max> mEnabledExtensions;
bool IsExtensionEnabled(WebGLExtensionID ext) const {
NS_ABORT_IF_FALSE(ext >= 0 && ext < WebGLExtensionID_Max, "bogus index!");
return mEnabledExtensions[ext] != nsnull;
nsAutoTArray<nsRefPtr<WebGLExtension>, WebGLExtensionID_number_of_extensions> mExtensions;
// returns true if the extension has been enabled by calling getExtension.
bool IsExtensionEnabled(WebGLExtensionID ext) {
return mExtensions[ext];
}
bool IsExtensionSupported(WebGLExtensionID ei);
// returns true if the extension is supported (as returned by getSupportedExtensions)
bool IsExtensionSupported(WebGLExtensionID ext);
nsTArray<WebGLenum> mCompressedTextureFormats;
@ -2200,7 +2204,11 @@ protected:
*/
static bool SplitLastSquareBracket(nsACString& string, nsCString& bracketPart)
{
NS_ABORT_IF_FALSE(bracketPart.Length() == 0, "SplitLastSquareBracket must be called with empty bracketPart string");
MOZ_ASSERT(bracketPart.IsEmpty(), "SplitLastSquareBracket must be called with empty bracketPart string");
if (string.IsEmpty())
return false;
char *string_start = string.BeginWriting();
char *s = string_start + string.Length() - 1;
@ -2996,6 +3004,8 @@ public:
uint32_t ProgramGeneration() const { return mProgramGeneration; }
int ElementSize() const { return mElementSize; }
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope);
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLUNIFORMLOCATION
protected:

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

@ -2423,7 +2423,7 @@ WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv)
return JS::Int32Value(i);
}
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
if (mEnabledExtensions[WebGL_OES_standard_derivatives]) {
if (IsExtensionEnabled(OES_standard_derivatives)) {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
@ -2470,7 +2470,7 @@ WebGLContext::GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv)
// float
case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
GLfloat f = 0.f;
gl->fGetFloatv(pname, &f);
return JS::DoubleValue(f);
@ -3114,7 +3114,7 @@ void WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname,
}
break;
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
if (floatParamPtr && floatParam < 1.f)
paramValueInvalid = true;
else if (intParamPtr && intParam < 1)
@ -3198,7 +3198,7 @@ WebGLContext::GetTexParameter(WebGLenum target, WebGLenum pname)
return JS::NumberValue(uint32_t(i));
}
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
GLfloat f = 0.f;
gl->fGetTexParameterfv(target, pname, &f);
return JS::DoubleValue(f);
@ -3529,7 +3529,7 @@ WebGLContext::Hint(WebGLenum target, WebGLenum mode)
isValid = true;
break;
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
if (mEnabledExtensions[WebGL_OES_standard_derivatives])
if (IsExtensionEnabled(OES_standard_derivatives))
isValid = true;
break;
}
@ -3849,6 +3849,9 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
if (width < 0 || height < 0)
return ErrorInvalidValue("readPixels: negative size passed");
if (!pixels)
return ErrorInvalidValue("readPixels: null destination buffer");
const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
@ -4915,7 +4918,7 @@ WebGLContext::CompileShader(WebGLShader *shader)
resources.MaxTextureImageUnits = mGLMaxTextureImageUnits;
resources.MaxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
resources.MaxDrawBuffers = 1;
if (mEnabledExtensions[WebGL_OES_standard_derivatives])
if (IsExtensionEnabled(OES_standard_derivatives))
resources.OES_standard_derivatives = 1;
// We're storing an actual instance of StripComments because, if we don't, the

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

@ -311,6 +311,9 @@ bool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info)
bool WebGLContext::ValidateGLSLVariableName(const nsAString& name, const char *info)
{
if (name.IsEmpty())
return false;
const uint32_t maxSize = 256;
if (name.Length() > maxSize) {
ErrorInvalidValue("%s: identifier is %d characters long, exceeds the maximum allowed length of %d characters",
@ -483,7 +486,7 @@ bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, in
uint32_t *texelSize, const char *info)
{
if (type == LOCAL_GL_UNSIGNED_BYTE ||
(IsExtensionEnabled(WebGL_OES_texture_float) && type == LOCAL_GL_FLOAT))
(IsExtensionEnabled(OES_texture_float) && type == LOCAL_GL_FLOAT))
{
if (jsArrayType != -1) {
if ((type == LOCAL_GL_UNSIGNED_BYTE && jsArrayType != js::ArrayBufferView::TYPE_UINT8) ||

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

@ -1534,7 +1534,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLRenderbuffer, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLUniformLocation, nsDOMGenericSH,
NS_DEFINE_CLASSINFO_DATA(WebGLUniformLocation,
nsNewDOMBindingNoWrapperCacheSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebGLShaderPrecisionFormat, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -9095,9 +9096,10 @@ nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHan
void
nsHTMLDocumentSH::ReleaseDocument(JSFreeOp *fop, JSObject *obj)
{
nsIHTMLDocument *doc = (nsIHTMLDocument *)::JS_GetPrivate(obj);
NS_IF_RELEASE(doc);
nsIHTMLDocument *doc = static_cast<nsIHTMLDocument *>(JS_GetPrivate(obj));
if (doc) {
xpc::DeferredRelease(doc);
}
}
JSBool
@ -10899,6 +10901,16 @@ WebGLExtensionSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
return WrapNativeParent(cx, globalObj, node, node, parentObj);
}
nsresult
nsNewDOMBindingNoWrapperCacheSH::PreCreate(nsISupports *nativeObj,
JSContext *cx,
JSObject *globalObj,
JSObject **parentObj)
{
// We don't allow this
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsWebGLViewportHandlerSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)

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

@ -486,6 +486,28 @@ public:
}
};
// scriptable helper for new-binding objects without wrapper caches
class nsNewDOMBindingNoWrapperCacheSH : public nsDOMGenericSH
{
protected:
nsNewDOMBindingNoWrapperCacheSH(nsDOMClassInfoData* aData) : nsDOMGenericSH(aData)
{
}
virtual ~nsNewDOMBindingNoWrapperCacheSH()
{
}
public:
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj);
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
{
return new nsNewDOMBindingNoWrapperCacheSH(aData);
}
};
// DOM Node helper, this class deals with setting the parent for the
// wrappers

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

@ -56,11 +56,7 @@ DOMCI_CASTABLE_INTERFACE(nsGenericHTMLElement, nsGenericHTMLElement, 6, \
DOMCI_CASTABLE_INTERFACE(nsHTMLDocument, nsIDocument, 7, _extra) \
DOMCI_CASTABLE_INTERFACE(nsStyledElement, nsStyledElement, 8, _extra) \
DOMCI_CASTABLE_INTERFACE(nsSVGStylableElement, nsIContent, 9, _extra) \
DOMCI_CASTABLE_INTERFACE(nsIWebGLUniformLocation, \
nsIWebGLUniformLocation, 11, _extra) \
DOMCI_CASTABLE_INTERFACE(nsIDOMImageData, nsIDOMImageData, 12, _extra) \
DOMCI_CASTABLE_NAMESPACED_INTERFACE(mozilla, WebGLUniformLocation, \
nsIWebGLUniformLocation, 13, _extra)
DOMCI_CASTABLE_INTERFACE(nsIDOMImageData, nsIDOMImageData, 12, _extra)
// Make sure all classes mentioned in DOMCI_CASTABLE_INTERFACES
// have been declared.

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

@ -177,6 +177,11 @@ CollectWindowReports(nsGlobalWindow *aWindow,
"Memory used by the comment nodes in a window's DOM.");
aWindowTotalSizes->mDOMCommentNodes += windowSizes.mDOMCommentNodes;
REPORT("/property-tables",
windowSizes.mPropertyTables,
"Memory used for the property tables within a window.");
aWindowTotalSizes->mPropertyTables += windowSizes.mPropertyTables;
REPORT("/style-sheets", windowSizes.mStyleSheets,
"Memory used by style sheets within a window.");
aWindowTotalSizes->mStyleSheets += windowSizes.mStyleSheets;
@ -328,6 +333,11 @@ nsWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
"Memory used for DOM comment nodes within windows. "
"This is the sum of all windows' 'dom/comment-nodes' numbers.");
REPORT("window-objects/property-tables",
windowTotalSizes.mPropertyTables,
"Memory used for property tables within windows. "
"This is the sum of all windows' 'property-tables' numbers.");
REPORT("window-objects/style-sheets", windowTotalSizes.mStyleSheets,
"Memory used for style sheets within windows. "
"This is the sum of all windows' 'style-sheets' numbers.");

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

@ -39,6 +39,7 @@ public:
size_t mLayoutStyleSets;
size_t mLayoutTextRuns;
size_t mLayoutPresContext;
size_t mPropertyTables;
};
/**

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

@ -249,4 +249,19 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(_class, _field1,\
_field2) \
NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_field1) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_field2) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_field1) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_field2) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
#endif /* nsWrapperCache_h___ */

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

@ -339,6 +339,42 @@ WrapNewBindingObject(JSContext* cx, JSObject* scope, const SmartPtr<T>& value,
return WrapNewBindingObject(cx, scope, value.get(), vp);
}
template <class T>
inline bool
WrapNewBindingNonWrapperCachedObject(JSContext* cx, JSObject* scope, T* value,
JS::Value* vp)
{
// We try to wrap in the compartment of the underlying object of "scope"
JSObject* obj;
{
// scope for the JSAutoEnterCompartment so that we restore the
// compartment before we call JS_WrapValue.
JSAutoEnterCompartment ac;
if (js::IsWrapper(scope)) {
scope = xpc::Unwrap(cx, scope, false);
if (!scope || !ac.enter(cx, scope)) {
return false;
}
}
obj = value->WrapObject(cx, scope);
}
// We can end up here in all sorts of compartments, per above. Make
// sure to JS_WrapValue!
*vp = JS::ObjectValue(*obj);
return JS_WrapValue(cx, vp);
}
// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
template <template <typename> class SmartPtr, typename T>
inline bool
WrapNewBindingNonWrapperCachedObject(JSContext* cx, JSObject* scope,
const SmartPtr<T>& value, JS::Value* vp)
{
return WrapNewBindingNonWrapperCachedObject(cx, scope, value.get(), vp);
}
/**
* A method to handle new-binding wrap failure, by possibly falling back to
* wrapping as a non-new-binding object.

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

@ -34,6 +34,11 @@
# dict). The keys are the property names as they appear in the
# .webidl file and the values are the names as they should be
# in the WebIDL.
# * wrapperCache: True if this object is a wrapper cache. Objects that are
# not can only be returned from a limited set of methods,
# cannot be prefable, and must ensure that they disallow
# XPConnect wrapping. Always true for worker descriptors.
# Defaults to true.
#
# The following fields are either a string, an array (defaults to an empty
# array) or a dictionary with three possible keys (all, getterOnly and
@ -221,6 +226,12 @@ DOMInterfaces = {
]
},
'WebGLUniformLocation': {
'nativeType': 'mozilla::WebGLUniformLocation',
'headerFile': 'WebGLContext.h',
'wrapperCache': False
},
'XMLHttpRequest': [
{
'nativeType': 'nsXMLHttpRequest',
@ -312,12 +323,18 @@ DOMInterfaces = {
},
'TestExternalInterface' : {
'nativeType': 'mozilla::dom::TestExternalInterface',
'headerFile': 'TestBindingHeader.h',
'register': False,
'castable': False
},
'nativeType': 'mozilla::dom::TestExternalInterface',
'headerFile': 'TestBindingHeader.h',
'register': False,
'castable': False
},
'TestNonWrapperCacheInterface' : {
'nativeType': 'mozilla::dom::TestNonWrapperCacheInterface',
'headerFile': 'TestBindingHeader.h',
'register': False,
'wrapperCache': False
},
}
# These are temporary, until they've been converted to use new DOM bindings
@ -366,6 +383,3 @@ addExternalIface('WebGLShaderPrecisionFormat',
headerFile='WebGLContext.h')
addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
headerFile='WebGLContext.h')
addExternalIface('WebGLUniformLocation',
nativeType='mozilla::WebGLUniformLocation',
headerFile='WebGLContext.h')

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

@ -121,7 +121,7 @@ DOMJSClass Class = {
%s
};
""" % (self.descriptor.interface.identifier.name,
ADDPROPERTY_HOOK_NAME if self.descriptor.concrete and not self.descriptor.workers else 'JS_PropertyStub',
ADDPROPERTY_HOOK_NAME if self.descriptor.concrete and not self.descriptor.workers and self.descriptor.wrapperCache else 'JS_PropertyStub',
FINALIZE_HOOK_NAME, traceHook, prototypeChainString,
str(self.descriptor.nativeIsISupports).lower(),
nativeHooks)
@ -518,20 +518,19 @@ class CGClassFinalizeHook(CGAbstractClassHook):
return """ if (self) {
self->%s(%s);
}""" % (self.name, self.args[0].name)
clearWrapper = "self->ClearWrapper();\n " if self.descriptor.wrapperCache else ""
if self.descriptor.workers:
release = "self->Release();"
else:
assert self.descriptor.nativeIsISupports
release = """
XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
release = """XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
if (rt) {
rt->DeferredRelease(reinterpret_cast<nsISupports*>(self));
} else {
NS_RELEASE(self);
}"""
return """
self->ClearWrapper();
%s""" % (release)
%s%s""" % (clearWrapper, release)
class CGClassTraceHook(CGAbstractClassHook):
"""
@ -1212,6 +1211,32 @@ class CGWrapMethod(CGAbstractMethod):
return obj;""" % (CheckPref(self.descriptor, "global", "*aTriedToWrap", "NULL", "aObject"))
class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
def __init__(self, descriptor):
# XXX can we wrap if we don't have an interface prototype object?
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
Argument(descriptor.nativeType + '*', 'aObject')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
def definition_body(self):
return """
JSObject* global = JS_GetGlobalForObject(aCx, aScope);
JSObject* proto = GetProtoObject(aCx, global, global);
if (!proto) {
return NULL;
}
JSObject* obj = JS_NewObject(aCx, &Class.mBase, proto, global);
if (!obj) {
return NULL;
}
js::SetReservedSlot(obj, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
NS_ADDREF(aObject);
return obj;"""
builtinNames = {
IDLType.Tags.bool: 'bool',
IDLType.Tags.int8: 'int8_t',
@ -1506,6 +1531,11 @@ for (uint32_t i = 0; i < length; ++i) {
templateBody = ""
if descriptor.castable:
if descriptor.prefable:
raise TypeError("We don't support prefable castable object "
"arguments (like %s), because we don't know "
"how to handle them being preffed off" %
descriptor.interface.identifier.name)
if failureCode is not None:
templateBody += str(CastableObjectUnwrapper(
descriptor,
@ -1923,7 +1953,8 @@ class CGArgumentConverter(CGThing):
self.replacementVariables,
self.argcAndIndex).define()
def getWrapTemplateForType(type, descriptorProvider, result, successCode):
def getWrapTemplateForType(type, descriptorProvider, result, successCode,
isCreator):
"""
Reflect a C++ value stored in "result", of IDL type "type" into JS. The
"successCode" is the code to run once we have successfully done the
@ -1981,7 +2012,8 @@ if (%s.IsNull()) {
}
%s""" % (result, CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define(),
getWrapTemplateForType(type.inner, descriptorProvider,
"%s.Value()" % result, successCode))
"%s.Value()" % result, successCode,
isCreator))
# Now do non-nullable sequences. We use setting the element
# in the array as our succcess code because when we succeed in
@ -1994,7 +2026,8 @@ if (%s.IsNull()) {
" return false;\n"
"}"),
'jsvalRef': "tmp",
'jsvalPtr': "&tmp"
'jsvalPtr': "&tmp",
'isCreator': isCreator
}
)
innerTemplate = CGIndenter(CGGeneric(innerTemplate)).define()
@ -2018,7 +2051,13 @@ for (uint32_t i = 0; i < length; ++i) {
else:
wrappingCode = ""
if descriptor.castable and not type.unroll().inner.isExternal():
wrap = "WrapNewBindingObject(cx, ${obj}, %s, ${jsvalPtr})" % result
if descriptor.wrapperCache:
wrapMethod = "WrapNewBindingObject"
else:
if not isCreator:
raise MethodNotCreatorError(descriptor.interface.identifier.name)
wrapMethod = "WrapNewBindingNonWrapperCachedObject"
wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, result)
# We don't support prefable stuff in workers.
assert(not descriptor.prefable or not descriptor.workers)
if not descriptor.prefable:
@ -2088,7 +2127,8 @@ if (!%(resultStr)s) {
CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
"}\n" +
getWrapTemplateForType(type.inner, descriptorProvider,
"%s.Value()" % result, successCode))
"%s.Value()" % result, successCode,
isCreator))
tag = type.tag()
@ -2129,10 +2169,13 @@ def wrapForType(type, descriptorProvider, templateValues):
* 'successCode' (optional): the code to run once we have successfully done
the conversion, if not supplied 'return true;'
will be used as the code
* 'isCreator' (optional): If true, we're wrapping for the return value of
a [Creator] method. Assumed false if not set.
"""
wrap = getWrapTemplateForType(type, descriptorProvider,
templateValues.get('result', 'result'),
templateValues.get('successCode', None))
templateValues.get('successCode', None),
templateValues.get('isCreator', False))
defaultValues = {'obj': 'obj'}
return string.Template(wrap).substitute(defaultValues, **templateValues)
@ -2261,6 +2304,10 @@ class CGCallGenerator(CGThing):
def define(self):
return self.cgRoot.define()
class MethodNotCreatorError(Exception):
def __init__(self, typename):
self.typename = typename
class CGPerSignatureCall(CGThing):
"""
This class handles the guts of generating code for a particular
@ -2324,9 +2371,23 @@ class CGPerSignatureCall(CGThing):
return not 'infallible' in self.extendedAttributes
def wrap_return_value(self):
resultTemplateValues = {'jsvalRef': '*vp', 'jsvalPtr': 'vp'}
return wrapForType(self.returnType, self.descriptor,
resultTemplateValues)
isCreator = self.idlNode.getExtendedAttribute("Creator") is not None
if isCreator:
# We better be returning addrefed things!
assert isResultAlreadyAddRefed(self.descriptor,
self.extendedAttributes)
resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp',
'isCreator': isCreator}
try:
return wrapForType(self.returnType, self.descriptor,
resultTemplateValues)
except MethodNotCreatorError, err:
assert not isCreator
raise TypeError("%s being returned from non-creator method or property %s.%s" %
(err.typename,
self.descriptor.interface.identifier.name,
self.idlNode.identifier.name))
def getErrorReport(self):
return 'return ThrowMethodFailedWithDetails<%s>(cx, rv, "%s", "%s");'\
@ -2842,7 +2903,7 @@ def getEnumValueName(value):
if not re.match("^[a-z_]+$", value):
raise SyntaxError('Enum value "' + value + '" contains characters '
'outside [a-z_]')
return value
return MakeNativeName(value)
class CGEnum(CGThing):
def __init__(self, enum):
@ -2925,8 +2986,7 @@ class ClassMethod(ClassItem):
if self.bodyInHeader and self.templateArgs else ''
args = ', '.join([str(a) for a in self.args])
if self.bodyInHeader:
body = ' ' + self.getBody();
body = body.replace('\n', '\n ').rstrip(' ')
body = CGIndenter(CGGeneric(self.getBody())).define()
body = '\n{\n' + body + '\n}'
else:
body = ';'
@ -2959,8 +3019,7 @@ ${name}(${args})${const}${body}
args = ', '.join([str(a) for a in self.args])
body = ' ' + self.getBody()
body = body.replace('\n', '\n ').rstrip(' ')
body = CGIndenter(CGGeneric(self.getBody())).define()
return string.Template("""${templateClause}${decorators}${returnType}
${className}::${name}(${args})${const}
@ -3105,13 +3164,10 @@ class CGClass(CGThing):
result = result + visibility + ':\n'
itemCount = 0
for member in list:
if itemCount == 0:
result = result + ' '
else:
result = result + separator + ' '
if itemCount != 0:
result = result + separator
declaration = member.declare(cgClass)
declaration = declaration.replace('\n', '\n ')
declaration = declaration.rstrip(' ')
declaration = CGIndenter(CGGeneric(declaration)).define()
result = result + declaration
itemCount = itemCount + 1
lastVisibility = visibility
@ -3127,9 +3183,8 @@ class CGClass(CGThing):
declareMembers(self, memberList, lastVisibility, itemCount,
separator)
if self.indent:
memberString = self.indent + memberString
memberString = memberString.replace('\n', '\n' + self.indent)
memberString = memberString.rstrip(' ')
memberString = CGIndenter(CGGeneric(memberString),
len(self.indent)).define()
result = result + memberString
result = result + self.indent + '};\n\n'
@ -3331,7 +3386,7 @@ class CGDescriptor(CGThing):
a.isAttr() and not a.readonly])
if descriptor.concrete:
if not descriptor.workers:
if not descriptor.workers and descriptor.wrapperCache:
cgThings.append(CGAddPropertyHook(descriptor))
# Always have a finalize hook, regardless of whether the class wants a
@ -3375,7 +3430,10 @@ class CGDescriptor(CGThing):
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
if descriptor.concrete:
cgThings.append(CGWrapMethod(descriptor))
if descriptor.wrapperCache:
cgThings.append(CGWrapMethod(descriptor))
else:
cgThings.append(CGWrapNonWrapperCacheMethod(descriptor))
cgThings = CGList(cgThings)
cgThings = CGWrapper(cgThings, post='\n')

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

@ -113,6 +113,11 @@ class Descriptor:
self.nativeIsISupports = not self.workers
self.customTrace = desc.get('customTrace', self.workers)
self.customFinalize = desc.get('customFinalize', self.workers)
self.wrapperCache = self.workers or desc.get('wrapperCache', True)
if not self.wrapperCache and self.prefable:
raise TypeError("Descriptor for %s is prefable but not wrappercached" %
self.interface.identifier.name)
def make_name(name):
return name + "_workers" if self.workers else name

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

@ -554,6 +554,9 @@ class IDLInterface(IDLObjectWithScope):
allowForbidden=True)
method = IDLMethod(self.location, identifier, retType, args)
# Constructors are always Creators and never have any
# other extended attributes.
method.addExtendedAttributes(["Creator"])
method.resolve(self)
self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True

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

@ -45,6 +45,14 @@ public:
NS_DECL_ISUPPORTS
};
class TestNonWrapperCacheInterface : public nsISupports
{
public:
NS_DECL_ISUPPORTS
virtual JSObject* WrapObject(JSContext* cx, JSObject* scope);
};
class TestInterface : public nsISupports,
public nsWrapperCache
{
@ -156,6 +164,13 @@ public:
void PassOptionalNonNullSelf(const Optional<NonNull<TestInterface> >&, ErrorResult&);
void PassOptionalSelfWithDefault(TestInterface*, ErrorResult&);
already_AddRefed<TestNonWrapperCacheInterface> ReceiveNonWrapperCacheInterface(ErrorResult&);
already_AddRefed<TestNonWrapperCacheInterface> ReceiveNullableNonWrapperCacheInterface(ErrorResult&);
void ReceiveNonWrapperCacheInterfaceSequence(nsTArray<nsRefPtr<TestNonWrapperCacheInterface> >&, ErrorResult&);
void ReceiveNullableNonWrapperCacheInterfaceSequence(nsTArray<nsRefPtr<TestNonWrapperCacheInterface> >&, ErrorResult&);
void ReceiveNonWrapperCacheInterfaceNullableSequence(Nullable<nsTArray<nsRefPtr<TestNonWrapperCacheInterface> > >&, ErrorResult&);
void ReceiveNullableNonWrapperCacheInterfaceNullableSequence(Nullable<nsTArray<nsRefPtr<TestNonWrapperCacheInterface> > >&, ErrorResult&);
already_AddRefed<TestNonCastableInterface> ReceiveOther(ErrorResult&);
already_AddRefed<TestNonCastableInterface> ReceiveNullableOther(ErrorResult&);
TestNonCastableInterface* ReceiveWeakOther(ErrorResult&);

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

@ -102,6 +102,20 @@ interface TestInterface {
void passOptionalNonNullSelf(optional TestInterface arg);
void passOptionalSelfWithDefault(optional TestInterface? arg = null);
// Non-wrapper-cache interface types
[Creator]
TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
[Creator]
TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
[Creator]
sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
[Creator]
sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
[Creator]
sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
[Creator]
sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
// Non-castable interface types
TestNonCastableInterface receiveOther();
TestNonCastableInterface? receiveNullableOther();
@ -236,6 +250,9 @@ interface TestInterface {
void passSequenceOfDictionaries(sequence<Dict> x);
};
interface TestNonWrapperCacheInterface {
};
interface ImplementedInterfaceParent {
void implementedParentMethod();
attribute boolean implementedParentProperty;

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

@ -18,25 +18,24 @@ function debug(msg) {
//dump("BrowserElementParent - " + msg + "\n");
}
function sendAsyncMsg(frameElement, msg, data) {
let mm = frameElement.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader
.messageManager;
mm.sendAsyncMessage('browser-element-api:' + msg, data);
}
/**
* The BrowserElementParent implements one half of <iframe mozbrowser>.
* (The other half is, unsurprisingly, BrowserElementChild.)
* BrowserElementParent implements one half of <iframe mozbrowser>. (The other
* half is, unsurprisingly, BrowserElementChild.)
*
* We detect windows and docshells contained inside <iframe mozbrowser>s and
* inject script to listen for certain events in the child. We then listen to
* messages from the child script and take appropriate action here.
* BrowserElementParentFactory detects when we create a windows or docshell
* contained inside a <iframe mozbrowser> and creates a BrowserElementParent
* object for that window.
*
* BrowserElementParent injects script to listen for certain events in the
* child. We then listen to messages from the child script and take
* appropriate action here in the parent.
*/
function BrowserElementParent() {}
BrowserElementParent.prototype = {
function BrowserElementParentFactory() {
this._initialized = false;
}
BrowserElementParentFactory.prototype = {
classID: Components.ID("{ddeafdac-cb39-47c4-9cb8-c9027ee36d26}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
@ -61,8 +60,10 @@ BrowserElementParent.prototype = {
debug("_init");
this._initialized = true;
this._screenshotListeners = {};
this._screenshotReqCounter = 0;
// Maps frame elements to BrowserElementParent objects. We never look up
// anything in this map; the purpose is to keep the BrowserElementParent
// alive for as long as its frame element lives.
this._bepMap = new WeakMap();
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.addObserver(this, 'remote-browser-frame-shown', /* ownsWeak = */ true);
@ -81,175 +82,17 @@ BrowserElementParent.prototype = {
_observeInProcessBrowserFrameShown: function(frameLoader) {
debug("In-process browser frame shown " + frameLoader);
this._setUpMessageManagerListeners(frameLoader);
this._createBrowserElementParent(frameLoader);
},
_observeRemoteBrowserFrameShown: function(frameLoader) {
debug("Remote browser frame shown " + frameLoader);
this._setUpMessageManagerListeners(frameLoader);
this._createBrowserElementParent(frameLoader);
},
_setUpMessageManagerListeners: function(frameLoader) {
_createBrowserElementParent: function(frameLoader) {
let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
if (!frameElement) {
debug("No frame element?");
return;
}
let mm = frameLoader.messageManager;
// Messages we receive are handled by functions with parameters
// (frameElement, data), where |data| is the message manager's data object.
let self = this;
function addMessageListener(msg, handler) {
mm.addMessageListener('browser-element-api:' + msg, handler.bind(self, frameElement));
}
addMessageListener("hello", this._recvHello);
addMessageListener("locationchange", this._fireEventFromMsg);
addMessageListener("loadstart", this._fireEventFromMsg);
addMessageListener("loadend", this._fireEventFromMsg);
addMessageListener("titlechange", this._fireEventFromMsg);
addMessageListener("iconchange", this._fireEventFromMsg);
addMessageListener("close", this._fireEventFromMsg);
addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
addMessageListener("keyevent", this._fireKeyEvent);
addMessageListener("showmodalprompt", this._handleShowModalPrompt);
mm.addMessageListener('browser-element-api:got-screenshot',
this._recvGotScreenshot.bind(this));
XPCNativeWrapper.unwrap(frameElement).getScreenshot =
this._getScreenshot.bind(this, mm, frameElement);
XPCNativeWrapper.unwrap(frameElement).setVisible =
this._setVisible.bind(this, mm, frameElement);
mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
/* allowDelayedLoad = */ true);
},
_recvHello: function(frameElement, data) {
debug("recvHello " + frameElement);
},
/**
* Fire either a vanilla or a custom event, depending on the contents of
* |data|.
*/
_fireEventFromMsg: function(frameElement, data) {
let name = data.name.substring('browser-element-api:'.length);
let detail = data.json;
debug('fireEventFromMsg: ' + name + ', ' + detail);
let evt = this._createEvent(frameElement, name, detail,
/* cancelable = */ false);
frameElement.dispatchEvent(evt);
},
_handleShowModalPrompt: function(frameElement, data) {
// Fire a showmodalprmopt event on the iframe. When this method is called,
// the child is spinning in a nested event loop waiting for an
// unblock-modal-prompt message.
//
// If the embedder calls preventDefault() on the showmodalprompt event,
// we'll block the child until event.detail.unblock() is called.
//
// Otherwise, if preventDefault() is not called, we'll send the
// unblock-modal-prompt message to the child as soon as the event is done
// dispatching.
let detail = data.json;
debug('handleShowPrompt ' + JSON.stringify(detail));
// Strip off the windowID property from the object we send along in the
// event.
let windowID = detail.windowID;
delete detail.windowID;
debug("Event will have detail: " + JSON.stringify(detail));
let evt = this._createEvent(frameElement, 'showmodalprompt', detail,
/* cancelable = */ true);
let unblockMsgSent = false;
function sendUnblockMsg() {
if (unblockMsgSent) {
return;
}
unblockMsgSent = true;
// We don't need to sanitize evt.detail.returnValue (e.g. converting the
// return value of confirm() to a boolean); Gecko does that for us.
let data = { windowID: windowID,
returnValue: evt.detail.returnValue };
sendAsyncMsg(frameElement, 'unblock-modal-prompt', data);
}
XPCNativeWrapper.unwrap(evt.detail).unblock = function() {
sendUnblockMsg();
};
frameElement.dispatchEvent(evt);
if (!evt.defaultPrevented) {
// Unblock the inner frame immediately. Otherwise we'll unblock upon
// evt.detail.unblock().
sendUnblockMsg();
}
},
_createEvent: function(frameElement, evtName, detail, cancelable) {
let win = frameElement.ownerDocument.defaultView;
let evt;
// This will have to change if we ever want to send a CustomEvent with null
// detail. For now, it's OK.
if (detail !== undefined && detail !== null) {
evt = new win.CustomEvent('mozbrowser' + evtName,
{bubbles: true, cancelable: cancelable,
detail: detail});
}
else {
evt = new win.Event('mozbrowser' + evtName,
{bubbles: true, cancelable: cancelable});
}
return evt;
},
_sendMozAppManifestURL: function(frameElement, data) {
return frameElement.getAttribute('mozapp');
},
_recvGotScreenshot: function(data) {
var req = this._screenshotListeners[data.json.id];
delete this._screenshotListeners[data.json.id];
Services.DOMRequest.fireSuccess(req, data.json.screenshot);
},
_getScreenshot: function(mm, frameElement) {
let id = 'req_' + this._screenshotReqCounter++;
let req = Services.DOMRequest
.createRequest(frameElement.ownerDocument.defaultView);
this._screenshotListeners[id] = req;
mm.sendAsyncMessage('browser-element-api:get-screenshot', {id: id});
return req;
},
_setVisible: function(mm, frameElement, visible) {
mm.sendAsyncMessage('browser-element-api:set-visible', {visible: visible});
},
_fireKeyEvent: function(frameElement, data) {
let win = frameElement.ownerDocument.defaultView;
let evt = frameElement.ownerDocument.createEvent("KeyboardEvent");
evt.initKeyEvent(data.json.type, true, true, win,
false, false, false, false, // modifiers
data.json.keyCode,
data.json.charCode);
frameElement.dispatchEvent(evt);
this._bepMap.set(frameElement, new BrowserElementParent(frameLoader));
},
observe: function(subject, topic, data) {
@ -275,4 +118,180 @@ BrowserElementParent.prototype = {
},
};
var NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParent]);
function BrowserElementParent(frameLoader) {
debug("Creating new BrowserElementParent object for " + frameLoader);
this._screenshotListeners = {};
this._screenshotReqCounter = 0;
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
if (!this._frameElement) {
debug("No frame element?");
return;
}
this._mm = frameLoader.messageManager;
// Messages we receive are handed to functions which take a (data) argument,
// where |data| is the message manager's data object.
let self = this;
function addMessageListener(msg, handler) {
self._mm.addMessageListener('browser-element-api:' + msg, handler.bind(self));
}
addMessageListener("hello", this._recvHello);
addMessageListener("locationchange", this._fireEventFromMsg);
addMessageListener("loadstart", this._fireEventFromMsg);
addMessageListener("loadend", this._fireEventFromMsg);
addMessageListener("titlechange", this._fireEventFromMsg);
addMessageListener("iconchange", this._fireEventFromMsg);
addMessageListener("close", this._fireEventFromMsg);
addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
addMessageListener("keyevent", this._fireKeyEvent);
addMessageListener("showmodalprompt", this._handleShowModalPrompt);
addMessageListener('got-screenshot', this._recvGotScreenshot);
function defineMethod(name, fn) {
XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self);
}
// Define methods on the frame element.
defineMethod('getScreenshot', this._getScreenshot);
defineMethod('setVisible', this._setVisible);
self._mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
/* allowDelayedLoad = */ true);
}
BrowserElementParent.prototype = {
get _window() {
return this._frameElement.ownerDocument.defaultView;
},
_sendAsyncMsg: function(msg, data) {
this._frameElement.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader
.messageManager
.sendAsyncMessage('browser-element-api:' + msg, data);
},
_recvHello: function(data) {
debug("recvHello");
},
/**
* Fire either a vanilla or a custom event, depending on the contents of
* |data|.
*/
_fireEventFromMsg: function(data) {
let name = data.name.substring('browser-element-api:'.length);
let detail = data.json;
debug('fireEventFromMsg: ' + name + ', ' + detail);
let evt = this._createEvent(name, detail,
/* cancelable = */ false);
this._frameElement.dispatchEvent(evt);
},
_handleShowModalPrompt: function(data) {
// Fire a showmodalprmopt event on the iframe. When this method is called,
// the child is spinning in a nested event loop waiting for an
// unblock-modal-prompt message.
//
// If the embedder calls preventDefault() on the showmodalprompt event,
// we'll block the child until event.detail.unblock() is called.
//
// Otherwise, if preventDefault() is not called, we'll send the
// unblock-modal-prompt message to the child as soon as the event is done
// dispatching.
let detail = data.json;
debug('handleShowPrompt ' + JSON.stringify(detail));
// Strip off the windowID property from the object we send along in the
// event.
let windowID = detail.windowID;
delete detail.windowID;
debug("Event will have detail: " + JSON.stringify(detail));
let evt = this._createEvent('showmodalprompt', detail,
/* cancelable = */ true);
let self = this;
let unblockMsgSent = false;
function sendUnblockMsg() {
if (unblockMsgSent) {
return;
}
unblockMsgSent = true;
// We don't need to sanitize evt.detail.returnValue (e.g. converting the
// return value of confirm() to a boolean); Gecko does that for us.
let data = { windowID: windowID,
returnValue: evt.detail.returnValue };
self._sendAsyncMsg('unblock-modal-prompt', data);
}
XPCNativeWrapper.unwrap(evt.detail).unblock = function() {
sendUnblockMsg();
};
this._frameElement.dispatchEvent(evt);
if (!evt.defaultPrevented) {
// Unblock the inner frame immediately. Otherwise we'll unblock upon
// evt.detail.unblock().
sendUnblockMsg();
}
},
_createEvent: function(evtName, detail, cancelable) {
// This will have to change if we ever want to send a CustomEvent with null
// detail. For now, it's OK.
if (detail !== undefined && detail !== null) {
return new this._window.CustomEvent('mozbrowser' + evtName,
{ bubbles: true,
cancelable: cancelable,
detail: detail });
}
return new this._window.Event('mozbrowser' + evtName,
{ bubbles: true,
cancelable: cancelable });
},
_sendMozAppManifestURL: function(data) {
return this._frameElement.getAttribute('mozapp');
},
_getScreenshot: function() {
let id = 'req_' + this._screenshotReqCounter++;
let req = Services.DOMRequest.createRequest(this._window);
this._screenshotListeners[id] = req;
this._sendAsyncMsg('get-screenshot', {id: id});
return req;
},
_recvGotScreenshot: function(data) {
var req = this._screenshotListeners[data.json.id];
delete this._screenshotListeners[data.json.id];
Services.DOMRequest.fireSuccess(req, data.json.screenshot);
},
_setVisible: function(visible) {
this._sendAsyncMsg('set-visible', {visible: visible});
},
_fireKeyEvent: function(data) {
let evt = this._window.document.createEvent("KeyboardEvent");
evt.initKeyEvent(data.json.type, true, true, this._window,
false, false, false, false, // modifiers
data.json.keyCode,
data.json.charCode);
this._frameElement.dispatchEvent(evt);
},
};
var NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParentFactory]);

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

@ -1,3 +1,3 @@
component {ddeafdac-cb39-47c4-9cb8-c9027ee36d26} BrowserElementParent.js
contract @mozilla.org/browser-element-parent;1 {ddeafdac-cb39-47c4-9cb8-c9027ee36d26}
category app-startup BrowserElementParent service,@mozilla.org/browser-element-parent;1
contract @mozilla.org/browser-element-parent-factory;1 {ddeafdac-cb39-47c4-9cb8-c9027ee36d26}
category app-startup BrowserElementParentFactory service,@mozilla.org/browser-element-parent-factory;1

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

@ -18,7 +18,6 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_contacts_basics.html \
test_contacts_events.html \
$(NULL)
_CHROME_TEST_FILES = \

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

@ -48,7 +48,8 @@ interface WebGLShader;
interface WebGLTexture;
interface WebGLUniformLocation;
interface WebGLUniformLocation {
};
interface WebGLActiveInfo;
@ -589,6 +590,7 @@ interface WebGLRenderingContext {
any getUniform(WebGLProgram? program, WebGLUniformLocation? location);
[Creator]
WebGLUniformLocation? getUniformLocation(WebGLProgram? program, DOMString name);
any getVertexAttrib(unsigned long index, unsigned long pname);

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

@ -1431,7 +1431,7 @@ Proxy::HandleEvent(nsIDOMEvent* aEvent)
XMLHttpRequest::XMLHttpRequest(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
: XMLHttpRequestEventTarget(aCx), mJSObject(NULL), mUpload(NULL),
mWorkerPrivate(aWorkerPrivate),
mResponseType(XMLHttpRequestResponseTypeValues::text), mTimeout(0),
mResponseType(XMLHttpRequestResponseTypeValues::Text), mTimeout(0),
mJSObjectRooted(false), mMultipart(false), mBackgroundRequest(false),
mWithCredentials(false), mCanceled(false)
{
@ -2142,7 +2142,7 @@ XMLHttpRequest::SetResponseType(XMLHttpRequestResponseType aResponseType,
// "document" is fine for the main thread but not for a worker. Short-circuit
// that here.
if (aResponseType == XMLHttpRequestResponseTypeValues::document) {
if (aResponseType == XMLHttpRequestResponseTypeValues::Document) {
return;
}

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

@ -18,11 +18,7 @@
#include "nsIIDNService.h"
#include "nsAppDirectoryServiceDefs.h"
#include "prprf.h"
#include "mozIStorageService.h"
#include "mozIStorageStatement.h"
#include "mozIStorageConnection.h"
#include "mozStorageHelper.h"
#include "mozStorageCID.h"
#include "mozilla/storage.h"
#include "nsXULAppAPI.h"
static nsPermissionManager *gPermissionManager = nsnull;
@ -105,6 +101,115 @@ nsHostEntry::nsHostEntry(const nsHostEntry& toCopy)
{
}
////////////////////////////////////////////////////////////////////////////////
/**
* Simple callback used by |AsyncClose| to trigger a treatment once
* the database is closed.
*
* Note: Beware that, if you hold onto a |CloseDatabaseListener| from a
* |nsPermissionManager|, this will create a cycle.
*
* Note: Once the callback has been called this DeleteFromMozHostListener cannot
* be reused.
*/
class CloseDatabaseListener : public mozIStorageCompletionCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZISTORAGECOMPLETIONCALLBACK
/**
* @param aManager The owning manager.
* @param aRebuildOnSuccess If |true|, reinitialize the database once
* it has been closed. Otherwise, do nothing such.
*/
CloseDatabaseListener(nsPermissionManager* aManager,
bool aRebuildOnSuccess);
protected:
nsRefPtr<nsPermissionManager> mManager;
bool mRebuildOnSuccess;
};
NS_IMPL_ISUPPORTS1(CloseDatabaseListener, mozIStorageCompletionCallback)
CloseDatabaseListener::CloseDatabaseListener(nsPermissionManager* aManager,
bool aRebuildOnSuccess)
: mManager(aManager)
, mRebuildOnSuccess(aRebuildOnSuccess)
{
}
NS_IMETHODIMP
CloseDatabaseListener::Complete()
{
// Help breaking cycles
nsRefPtr<nsPermissionManager> manager = mManager.forget();
if (mRebuildOnSuccess && !manager->mIsShuttingDown) {
return manager->InitDB(true);
}
return NS_OK;
}
/**
* Simple callback used by |RemoveAllInternal| to trigger closing
* the database and reinitializing it.
*
* Note: Beware that, if you hold onto a |DeleteFromMozHostListener| from a
* |nsPermissionManager|, this will create a cycle.
*
* Note: Once the callback has been called this DeleteFromMozHostListener cannot
* be reused.
*/
class DeleteFromMozHostListener : public mozIStorageStatementCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZISTORAGESTATEMENTCALLBACK
/**
* @param aManager The owning manager.
*/
DeleteFromMozHostListener(nsPermissionManager* aManager);
protected:
nsRefPtr<nsPermissionManager> mManager;
};
NS_IMPL_ISUPPORTS1(DeleteFromMozHostListener, mozIStorageStatementCallback)
DeleteFromMozHostListener::
DeleteFromMozHostListener(nsPermissionManager* aManager)
: mManager(aManager)
{
}
NS_IMETHODIMP DeleteFromMozHostListener::HandleResult(mozIStorageResultSet *)
{
MOZ_NOT_REACHED("Should not get any results");
return NS_OK;
}
NS_IMETHODIMP DeleteFromMozHostListener::HandleError(mozIStorageError *)
{
// Errors are handled in |HandleCompletion|
return NS_OK;
}
NS_IMETHODIMP DeleteFromMozHostListener::HandleCompletion(PRUint16 aReason)
{
// Help breaking cycles
nsRefPtr<nsPermissionManager> manager = mManager.forget();
if (aReason == REASON_ERROR) {
manager->CloseDB(true);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsPermissionManager Implementation
@ -119,6 +224,7 @@ NS_IMPL_ISUPPORTS3(nsPermissionManager, nsIPermissionManager, nsIObserver, nsISu
nsPermissionManager::nsPermissionManager()
: mLargestID(0)
, mIsShuttingDown(false)
{
}
@ -578,39 +684,53 @@ NS_IMETHODIMP
nsPermissionManager::RemoveAll()
{
ENSURE_NOT_CHILD_PROCESS;
nsresult rv = RemoveAllInternal();
NotifyObservers(nsnull, NS_LITERAL_STRING("cleared").get());
return rv;
return RemoveAllInternal(true);
}
void
nsPermissionManager::CloseDB()
nsPermissionManager::CloseDB(bool aRebuildOnSuccess)
{
// Null the statements, this will finalize them.
mStmtInsert = nsnull;
mStmtDelete = nsnull;
mStmtUpdate = nsnull;
if (mDBConn) {
mozilla::DebugOnly<nsresult> rv = mDBConn->Close();
mozIStorageCompletionCallback* cb = new CloseDatabaseListener(this,
aRebuildOnSuccess);
mozilla::DebugOnly<nsresult> rv = mDBConn->AsyncClose(cb);
MOZ_ASSERT(NS_SUCCEEDED(rv));
mDBConn = nsnull;
mDBConn = nsnull; // Avoid race conditions
}
}
nsresult
nsPermissionManager::RemoveAllInternal()
nsPermissionManager::RemoveAllInternal(bool aNotifyObservers)
{
// Remove from memory and notify immediately. Since the in-memory
// database is authoritative, we do not need confirmation from the
// on-disk database to notify observers.
RemoveAllFromMemory();
if (aNotifyObservers) {
NotifyObservers(nsnull, NS_LITERAL_STRING("cleared").get());
}
// clear the db
if (mDBConn) {
nsresult rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DELETE FROM moz_hosts"));
if (NS_FAILED(rv)) {
CloseDB();
rv = InitDB(true);
return rv;
nsCOMPtr<mozIStorageAsyncStatement> removeStmt;
nsresult rv = mDBConn->
CreateAsyncStatement(NS_LITERAL_CSTRING(
"DELETE FROM moz_hosts"
), getter_AddRefs(removeStmt));
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (!removeStmt) {
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<mozIStoragePendingStatement> pending;
mozIStorageStatementCallback* cb = new DeleteFromMozHostListener(this);
rv = removeStmt->ExecuteAsync(cb, getter_AddRefs(pending));
MOZ_ASSERT(NS_SUCCEEDED(rv));
return rv;
}
return NS_OK;
@ -761,13 +881,14 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
// The profile is about to change,
// or is going away because the application is shutting down.
mIsShuttingDown = true;
if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
// clear the permissions file
RemoveAllInternal();
// Clear the permissions file and close the db asynchronously
RemoveAllInternal(false);
} else {
RemoveAllFromMemory();
CloseDB(false);
}
CloseDB();
}
else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
// the profile has already changed; init the db from the new location

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

@ -190,9 +190,10 @@ private:
void NotifyObservers(nsIPermission *aPermission, const PRUnichar *aData);
// Finalize all statements, close the DB and null it.
void CloseDB();
// if aRebuildOnSuccess, reinitialize database
void CloseDB(bool aRebuildOnSuccess = false);
nsresult RemoveAllInternal();
nsresult RemoveAllInternal(bool aNotifyObservers);
nsresult RemoveAllFromMemory();
nsresult NormalizeToACE(nsCString &aHost);
nsresult GetHost(nsIURI *aURI, nsACString &aResult);
@ -219,6 +220,13 @@ private:
// An array to store the strings identifying the different types.
nsTArray<nsCString> mTypeArray;
// Initially, |false|. Set to |true| once shutdown has started, to avoid
// reopening the database.
bool mIsShuttingDown;
friend class DeleteFromMozHostListener;
friend class CloseDatabaseListener;
};
// {4F6B5E00-0C36-11d5-A535-0010A401EB10}

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

@ -0,0 +1,29 @@
# HG changeset patch
# Parent 9ded7a9f94a863dfa1f3227d3013367f51b8b522
# User Nicholas Cameron <ncameron@mozilla.com>
Bug 765038; fix a Clang compilation bug in Skia; r=jwatt
diff --git a/gfx/skia/src/sfnt/SkOTTable_head.h b/gfx/skia/src/sfnt/SkOTTable_head.h
--- a/gfx/skia/src/sfnt/SkOTTable_head.h
+++ b/gfx/skia/src/sfnt/SkOTTable_head.h
@@ -109,18 +109,18 @@ struct SkOTTableHead {
} raw;
} macStyle;
SK_OT_USHORT lowestRecPPEM;
struct FontDirectionHint {
SK_TYPED_ENUM(Value, SK_OT_SHORT,
((FullyMixedDirectionalGlyphs, SkTEndian_SwapBE16(0)))
((OnlyStronglyLTR, SkTEndian_SwapBE16(1)))
((StronglyLTR, SkTEndian_SwapBE16(2)))
- ((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-1))))
- ((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-2))))
+ ((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-1)))))
+ ((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-2)))))
SK_SEQ_END,
(value)SK_SEQ_END)
} fontDirectionHint;
struct IndexToLocFormat {
SK_TYPED_ENUM(Value, SK_OT_SHORT,
((ShortOffsets, SkTEndian_SwapBE16(0)))
((LongOffsets, SkTEndian_SwapBE16(1)))
SK_SEQ_END,

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

@ -16,3 +16,4 @@ See the relevant bugs in bugzilla for information on these patches:
0011-Bug-719575-Fix-clang-build.patch
0012-Bug-759683-make-ssse3-conditional.patch
0013-Bug-761890-fonts.patch
0014-Bug-765038-Fix-clang-build.patch

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

@ -114,8 +114,8 @@ struct SkOTTableHead {
((FullyMixedDirectionalGlyphs, SkTEndian_SwapBE16(0)))
((OnlyStronglyLTR, SkTEndian_SwapBE16(1)))
((StronglyLTR, SkTEndian_SwapBE16(2)))
((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-1))))
((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(-2))))
((OnlyStronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-1)))))
((StronglyRTL, static_cast<SK_OT_SHORT>(SkTEndian_SwapBE16(static_cast<SK_OT_USHORT>(-2)))))
SK_SEQ_END,
(value)SK_SEQ_END)
} fontDirectionHint;

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

@ -62,7 +62,7 @@ class HashTableEntry {
JS_ASSERT(isLive()); keyHash |= collisionBit;
}
void unsetCollision() { keyHash &= ~sCollisionBit; }
bool hasCollision() const { JS_ASSERT(isLive()); return keyHash & sCollisionBit; }
bool hasCollision() const { return keyHash & sCollisionBit; }
bool matchHash(HashNumber hn) { return (keyHash & ~sCollisionBit) == hn; }
HashNumber getKeyHash() const { JS_ASSERT(!hasCollision()); return keyHash; }
};
@ -185,7 +185,7 @@ class HashTable : private AllocPolicy
friend class HashTable;
HashTable &table;
bool added;
bool rekeyed;
bool removed;
/* Not copyable. */
@ -194,7 +194,7 @@ class HashTable : private AllocPolicy
public:
template<class Map> explicit
Enum(Map &map) : Range(map.all()), table(map.impl), added(false), removed(false) {}
Enum(Map &map) : Range(map.all()), table(map.impl), rekeyed(false), removed(false) {}
/*
* Removes the |front()| element from the table, leaving |front()|
@ -224,7 +224,7 @@ class HashTable : private AllocPolicy
HashPolicy::setKey(t, const_cast<Key &>(k));
table.remove(*this->cur);
table.putNewInfallible(l, t);
added = true;
rekeyed = true;
this->validEntry = false;
}
@ -234,28 +234,11 @@ class HashTable : private AllocPolicy
/* Potentially rehashes the table. */
~Enum() {
JS_ASSERT(!added);
if (rekeyed)
table.checkOverRemoved();
if (removed)
table.checkUnderloaded();
}
/*
* Can be used to end the enumeration before the destructor. Unlike
* |~Enum()|, this can report OOM on resize, so must be called if
* |rekeyFront()| is used during enumeration.
*/
bool endEnumeration() {
if (added) {
added = false;
if (table.checkOverloaded() == RehashFailed)
return false;
}
if (removed) {
removed = false;
table.checkUnderloaded();
}
return true;
}
};
private:
@ -281,6 +264,7 @@ class HashTable : private AllocPolicy
uint32_t grows; /* table expansions */
uint32_t shrinks; /* table contractions */
uint32_t compresses; /* table compressions */
uint32_t rehashes; /* tombstone decontaminations */
} stats;
# define METER(x) x
#else
@ -601,6 +585,16 @@ class HashTable : private AllocPolicy
return changeTableSize(deltaLog2);
}
/* Infallibly rehash the table if we are overloaded with removals. */
void checkOverRemoved()
{
if (overloaded()) {
METER(stats.rehashes++);
rehashTable();
JS_ASSERT(!overloaded());
}
}
void remove(Entry &e)
{
JS_ASSERT(table);
@ -625,6 +619,52 @@ class HashTable : private AllocPolicy
}
}
/*
* This is identical to changeTableSize(currentSize), but without requiring
* a second table. We do this by recycling the collision bits to tell us if
* the element is already inserted or still waiting to be inserted. Since
* already-inserted elements win any conflicts, we get the same table as we
* would have gotten through random insertion order.
*/
void rehashTable()
{
removedCount = 0;
for (size_t i = 0; i < capacity(); ++i)
table[i].unsetCollision();
for (size_t i = 0; i < capacity();) {
Entry *src = &table[i];
if (!src->isLive() || src->hasCollision()) {
++i;
continue;
}
HashNumber keyHash = src->getKeyHash();
HashNumber h1 = hash1(keyHash, hashShift);
DoubleHash dh = hash2(keyHash, hashShift);
Entry *tgt = &table[h1];
while (true) {
if (!tgt->hasCollision()) {
Swap(*src, *tgt);
tgt->setCollision();
break;
}
h1 = applyDoubleHash(h1, dh);
tgt = &table[h1];
}
}
/*
* TODO: this algorithm leaves collision bits on *all* elements, even if
* they are on no collision path. We have the option of setting the
* collision bits correctly on a subsequent pass or skipping the rehash
* unless we are totally filled with tombstones: benchmark to find out
* which approach is best.
*/
}
public:
void clear()
{

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

@ -572,6 +572,8 @@ static JSFunctionSpecWithHelp TestingFunctions[] = {
" 3: Collect when the window paints (browser only)\n"
" 4: Verify write barriers between instructions\n"
" 5: Verify write barriers between paints\n"
" 6: Verify stack rooting (ignoring XML and Reflect)\n"
" 7: Verify stack rooting (all roots)\n"
" Period specifies that collection happens every n allocations.\n"),
JS_FN_HELP("schedulegc", ScheduleGC, 1, 0,

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

@ -3871,13 +3871,24 @@ dnl ========================================================
dnl = Perform moving GC stack rooting analysis
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(root-analysis,
[ --enable-root-analysis Enable moving GC stack root analysis],
[ --enable-root-analysis Enable moving GC stack root analysis],
JSGC_ROOT_ANALYSIS=1,
JSGC_ROOT_ANALYSIS= )
if test -n "$JSGC_ROOT_ANALYSIS"; then
AC_DEFINE(JSGC_ROOT_ANALYSIS)
fi
dnl ========================================================
dnl = Use exact stack rooting for GC
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(exact-rooting,
[ --enable-exact-rooting Enable use of exact stack roots for GC],
JSGC_USE_EXACT_ROOTING=1,
JSGC_USE_EXACT_ROOTING= )
if test -n "$JSGC_USE_EXACT_ROOTING"; then
AC_DEFINE(JSGC_USE_EXACT_ROOTING)
fi
dnl ========================================================
dnl = Use Valgrind
dnl ========================================================
@ -3974,7 +3985,7 @@ MOZ_ARG_ENABLE_BOOL(gczeal,
[ --enable-gczeal Enable zealous GCing],
JS_GC_ZEAL=1,
JS_GC_ZEAL= )
if test -n "$JS_GC_ZEAL"; then
if test -n "$JS_GC_ZEAL" -o -n "$MOZ_DEBUG"; then
AC_DEFINE(JS_GC_ZEAL)
fi
@ -4129,7 +4140,7 @@ dnl = E4X support (ECMA-357)
dnl ========================================================
JS_HAS_XML_SUPPORT=1
MOZ_ARG_DISABLE_BOOL(e4x,
[ --disable-e4x Disable JS support for XML (ECMA-357)],
[ --disable-e4x Disable JS support for XML (ECMA-357)],
JS_HAS_XML_SUPPORT=0 )
AC_DEFINE_UNQUOTED(JS_HAS_XML_SUPPORT, $JS_HAS_XML_SUPPORT)

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

@ -145,7 +145,7 @@ class Rooted
{
void init(JSContext *cx_, T initial)
{
#ifdef JSGC_ROOT_ANALYSIS
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
ContextFriendFields *cx = ContextFriendFields::get(cx_);
ThingRootKind kind = RootMethods<T>::kind();
@ -174,13 +174,13 @@ class Rooted
~Rooted()
{
#ifdef JSGC_ROOT_ANALYSIS
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
JS_ASSERT(*stack == this);
*stack = prev;
#endif
}
#ifdef JSGC_ROOT_ANALYSIS
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
Rooted<T> *previous() { return prev; }
#endif
@ -206,7 +206,7 @@ class Rooted
private:
#ifdef JSGC_ROOT_ANALYSIS
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
Rooted<T> **stack, *prev;
#endif
T ptr;
@ -309,7 +309,7 @@ class SkipRoot
* Hook for dynamic root analysis. Checks the native stack and poisons
* references to GC things which have not been rooted.
*/
#if defined(JSGC_ROOT_ANALYSIS) && defined(DEBUG) && !defined(JS_THREADSAFE)
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
void CheckStackRoots(JSContext *cx);
inline void MaybeCheckStackRoots(JSContext *cx) { CheckStackRoots(cx); }
#else

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

@ -0,0 +1,5 @@
for (i in ['']) {}
function f(...patterns) {
patterns[i];
};
f('');

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

@ -0,0 +1,20 @@
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
var fscript = null;
dbg.onNewScript = function(script) {
dbg.onNewScript = undefined;
fscript = script.getChildScripts()[0];
assertEq(fscript.staticLevel, 1);
}
g.eval("function f(x) { arguments[0] = 3; return x }");
assertEq(fscript !== null, true);
fscript.setBreakpoint(0, {hit:function(frame) {
assertEq(frame.eval('x').return, 1);
assertEq(frame.arguments[0], 1);
return {return:42};
}});
assertEq(g.f(1), 42);

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

@ -193,13 +193,11 @@ BEGIN_TEST(testHashRekeyManual)
CHECK(AddLowKeys(&am, &bm, i));
CHECK(MapsAreEqual(am, bm));
IntMap::Enum e(am);
for (; !e.empty(); e.popFront()) {
for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
uint32_t tmp = LowToHigh::rekey(e.front().key);
if (tmp != e.front().key)
e.rekeyFront(tmp);
}
CHECK(e.endEnumeration());
CHECK(SlowRekey<LowToHigh>(&bm));
CHECK(MapsAreEqual(am, bm));
@ -217,13 +215,11 @@ BEGIN_TEST(testHashRekeyManual)
CHECK(AddLowKeys(&as, &bs, i));
CHECK(SetsAreEqual(as, bs));
IntSet::Enum e(as);
for (; !e.empty(); e.popFront()) {
for (IntSet::Enum e(as); !e.empty(); e.popFront()) {
uint32_t tmp = LowToHigh::rekey(e.front());
if (tmp != e.front())
e.rekeyFront(tmp);
}
CHECK(e.endEnumeration());
CHECK(SlowRekey<LowToHigh>(&bs));
CHECK(SetsAreEqual(as, bs));
@ -247,8 +243,7 @@ BEGIN_TEST(testHashRekeyManualRemoval)
CHECK(AddLowKeys(&am, &bm, i));
CHECK(MapsAreEqual(am, bm));
IntMap::Enum e(am);
for (; !e.empty(); e.popFront()) {
for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
if (LowToHighWithRemoval::shouldBeRemoved(e.front().key)) {
e.removeFront();
} else {
@ -257,7 +252,6 @@ BEGIN_TEST(testHashRekeyManualRemoval)
e.rekeyFront(tmp);
}
}
CHECK(e.endEnumeration());
CHECK(SlowRekey<LowToHighWithRemoval>(&bm));
CHECK(MapsAreEqual(am, bm));
@ -275,8 +269,7 @@ BEGIN_TEST(testHashRekeyManualRemoval)
CHECK(AddLowKeys(&as, &bs, i));
CHECK(SetsAreEqual(as, bs));
IntSet::Enum e(as);
for (; !e.empty(); e.popFront()) {
for (IntSet::Enum e(as); !e.empty(); e.popFront()) {
if (LowToHighWithRemoval::shouldBeRemoved(e.front())) {
e.removeFront();
} else {
@ -285,7 +278,6 @@ BEGIN_TEST(testHashRekeyManualRemoval)
e.rekeyFront(tmp);
}
}
CHECK(e.endEnumeration());
CHECK(SlowRekey<LowToHighWithRemoval>(&bs));
CHECK(SetsAreEqual(as, bs));
@ -296,4 +288,3 @@ BEGIN_TEST(testHashRekeyManualRemoval)
return true;
}
END_TEST(testHashRekeyManualRemoval)

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

@ -6643,7 +6643,9 @@ JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency)
" 2: GC every F allocations (default: 100)\n"
" 3: GC when the window paints (browser only)\n"
" 4: Verify write barriers between instructions\n"
" 5: Verify write barriers between paints\n");
" 5: Verify write barriers between paints\n"
" 6: Verify stack rooting (ignoring XML and Reflect)\n"
" 7: Verify stack rooting (all roots)\n");
}
const char *p = strchr(env, ',');
zeal = atoi(env);

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

@ -5697,10 +5697,6 @@ JS_NewObjectForConstructor(JSContext *cx, JSClass *clasp, const jsval *vp);
/************************************************************************/
#ifdef DEBUG
#define JS_GC_ZEAL 1
#endif
#ifdef JS_GC_ZEAL
#define JS_DEFAULT_ZEAL_FREQ 100

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

@ -879,6 +879,45 @@ InFreeList(ArenaHeader *aheader, uintptr_t addr)
}
}
#ifdef JSGC_USE_EXACT_ROOTING
static void
MarkExactStackRoots(JSTracer *trc)
{
for (ContextIter cx(trc->runtime); !cx.done(); cx.next()) {
for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
Rooted<void*> *rooter = cx->thingGCRooters[i];
while (rooter) {
void **addr = (void **)rooter->address();
if (*addr) {
if (i == THING_ROOT_OBJECT) {
MarkObjectRoot(trc, (JSObject **)addr, "exact stackroot object");
} else if (i == THING_ROOT_STRING) {
MarkStringRoot(trc, (JSString **)addr, "exact stackroot string");
} else if (i == THING_ROOT_ID) {
MarkIdRoot(trc, (jsid *)addr, "exact stackroot id");
} else if (i == THING_ROOT_VALUE) {
MarkValueRoot(trc, (Value *)addr, "exact stackroot value");
} else if (i == THING_ROOT_SHAPE) {
MarkShapeRoot(trc, (Shape **)addr, "exact stackroot shape");
} else if (i == THING_ROOT_BASE_SHAPE) {
MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact stackroot baseshape");
} else if (i == THING_ROOT_TYPE_OBJECT) {
MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact stackroot typeobject");
} else if (i == THING_ROOT_SCRIPT) {
MarkScriptRoot(trc, (JSScript **)addr, "exact stackroot script");
} else if (i == THING_ROOT_XML) {
MarkXMLRoot(trc, (JSXML **)addr, "exact stackroot xml");
} else {
JS_NOT_REACHED("Invalid thing root kind.");
}
}
rooter = rooter->previous();
}
}
}
}
#endif /* JSGC_USE_EXACT_ROOTING */
enum ConservativeGCTest
{
CGCT_VALID,
@ -1038,6 +1077,8 @@ MarkRangeConservatively(JSTracer *trc, const uintptr_t *begin, const uintptr_t *
MarkWordConservatively(trc, *i);
}
#ifndef JSGC_USE_EXACT_ROOTING
static JS_NEVER_INLINE void
MarkConservativeStackRoots(JSTracer *trc, bool useSavedRoots)
{
@ -1083,6 +1124,8 @@ MarkConservativeStackRoots(JSTracer *trc, bool useSavedRoots)
ArrayEnd(cgcd->registerSnapshot.words));
}
#endif /* JSGC_USE_EXACT_ROOTING */
void
MarkStackRangeConservatively(JSTracer *trc, Value *beginv, Value *endv)
{
@ -1101,8 +1144,6 @@ MarkStackRangeConservatively(JSTracer *trc, Value *beginv, Value *endv)
#endif
}
JS_NEVER_INLINE void
ConservativeGCData::recordStackTop()
{
@ -2299,8 +2340,13 @@ MarkRuntime(JSTracer *trc, bool useSavedRoots = false)
AutoGCRooter::traceAll(trc);
if (rt->hasContexts())
if (rt->hasContexts()) {
#ifdef JSGC_USE_EXACT_ROOTING
MarkExactStackRoots(trc);
#else
MarkConservativeStackRoots(trc, useSavedRoots);
#endif
}
for (RootRange r = rt->gcRootsHash.all(); !r.empty(); r.popFront())
gc_root_traversal(trc, r.front());
@ -4086,7 +4132,7 @@ SetDeterministicGC(JSContext *cx, bool enabled)
} /* namespace gc */
} /* namespace js */
#if defined(DEBUG) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
static void
CheckStackRoot(JSTracer *trc, uintptr_t *w)
@ -4146,7 +4192,9 @@ JS::CheckStackRoots(JSContext *cx)
{
JSRuntime *rt = cx->runtime;
if (!rt->gcExactScanningEnabled)
if (rt->gcZeal_ != ZealStackRootingSafeValue && rt->gcZeal_ != ZealStackRootingValue)
return;
if (rt->gcZeal_ == ZealStackRootingSafeValue && !rt->gcExactScanningEnabled)
return;
AutoCopyFreeListToArenas copy(rt);
@ -4206,7 +4254,7 @@ JS::CheckStackRoots(JSContext *cx)
ArrayEnd(cgcd->registerSnapshot.words));
}
#endif /* DEBUG && JSGC_ROOT_ANALYSIS && !JS_THREADSAFE */
#endif /* DEBUG && JS_GC_ZEAL && JSGC_ROOT_ANALYSIS && !JS_THREADSAFE */
namespace js {
namespace gc {

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

@ -1067,6 +1067,8 @@ const int ZealAllocValue = 2;
const int ZealFrameGCValue = 3;
const int ZealVerifierValue = 4;
const int ZealFrameVerifierValue = 5;
const int ZealStackRootingSafeValue = 6;
const int ZealStackRootingValue = 7;
#ifdef JS_GC_ZEAL

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

@ -3651,15 +3651,21 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
case JSOP_REST: {
TypeSet *types = script->analysis()->bytecodeTypes(pc);
types->addSubset(cx, &pushed[0]);
if (script->hasGlobal()) {
TypeObject *rest = TypeScript::InitObject(cx, script, pc, JSProto_Array);
if (!rest)
return false;
types->addType(cx, Type::ObjectType(rest));
// Simulate setting a element.
TypeSet *propTypes = rest->getProperty(cx, JSID_VOID, true);
if (!propTypes)
return false;
propTypes->addType(cx, Type::UnknownType());
} else {
types->addType(cx, Type::UnknownType());
}
types->addSubset(cx, &pushed[0]);
break;
}

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

@ -248,15 +248,15 @@ struct ContextFriendFields {
return reinterpret_cast<ContextFriendFields *>(cx);
}
#ifdef JSGC_ROOT_ANALYSIS
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
/*
* Stack allocated GC roots for stack GC heap pointers, which may be
* overwritten if moved during a GC.
*/
Rooted<void*> *thingGCRooters[THING_ROOT_LIMIT];
#endif
#ifdef DEBUG
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
/*
* Stack allocated list of stack locations which hold non-relocatable
* GC heap pointers (where the target is rooted somewhere else) or integer
@ -267,8 +267,6 @@ struct ContextFriendFields {
*/
SkipRoot *skipGCRooters;
#endif
#endif /* JSGC_ROOT_ANALYSIS */
};
} /* namespace JS */

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

@ -3169,10 +3169,10 @@ DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
if (unsigned(i) < fp->numActualArgs()) {
if (unsigned(i) < fp->numFormalArgs() && fp->script()->formalLivesInCallObject(i))
arg = fp->callObj().arg(i);
else if (fp->script()->argsObjAliasesFormals())
else if (fp->script()->argsObjAliasesFormals() && fp->hasArgsObj())
arg = fp->argsObj().arg(i);
else
arg = fp->unaliasedActual(i);
arg = fp->unaliasedActual(i, DONT_CHECK_ALIASING);
} else {
arg.setUndefined();
}

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

@ -191,10 +191,10 @@ CallObject::copyUnaliasedValues(StackFrame *fp)
/* Copy the unaliased formals. */
for (unsigned i = 0; i < script->bindings.numArgs(); ++i) {
if (!script->formalLivesInCallObject(i)) {
if (script->argsObjAliasesFormals())
if (script->argsObjAliasesFormals() && fp->hasArgsObj())
setArg(i, fp->argsObj().arg(i), DONT_CHECK_ALIASING);
else
setArg(i, fp->unaliasedFormal(i), DONT_CHECK_ALIASING);
setArg(i, fp->unaliasedFormal(i, DONT_CHECK_ALIASING), DONT_CHECK_ALIASING);
}
}
@ -1113,7 +1113,7 @@ class DebugScopeProxy : public BaseProxyHandler
* This function handles access to unaliased locals/formals. If such
* accesses were passed on directly to the DebugScopeObject::scope, they
* would not be reading/writing the canonical location for the variable,
* which is on the stack. Thus, handleUn must translate would-be
* which is on the stack. Thus, handleUnaliasedAccess must translate
* accesses to scope objects into analogous accesses of the stack frame.
*
* handleUnaliasedAccess returns 'true' if the access was unaliased and
@ -1162,16 +1162,16 @@ class DebugScopeProxy : public BaseProxyHandler
return false;
if (maybefp) {
if (script->argsObjAliasesFormals()) {
if (script->argsObjAliasesFormals() && maybefp->hasArgsObj()) {
if (action == GET)
*vp = maybefp->argsObj().arg(i);
else
maybefp->argsObj().setArg(i, *vp);
} else {
if (action == GET)
*vp = maybefp->unaliasedFormal(i);
*vp = maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING);
else
maybefp->unaliasedFormal(i) = *vp;
maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING) = *vp;
}
} else {
if (action == GET)

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

@ -252,10 +252,10 @@ StackFrame::unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing)
}
inline Value &
StackFrame::unaliasedActual(unsigned i)
StackFrame::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing)
{
JS_ASSERT(i < numActualArgs());
JS_ASSERT(!script()->formalIsAliased(i));
JS_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i));
return i < numFormalArgs() ? formals()[i] : actuals()[i];
}

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

@ -591,7 +591,7 @@ class StackFrame
bool hasArgs() const { return isNonEvalFunctionFrame(); }
inline Value &unaliasedFormal(unsigned i, MaybeCheckAliasing = CHECK_ALIASING);
inline Value &unaliasedActual(unsigned i);
inline Value &unaliasedActual(unsigned i, MaybeCheckAliasing = CHECK_ALIASING);
template <class Op> inline void forEachUnaliasedActual(Op op);
inline unsigned numFormalArgs() const;
@ -1011,11 +1011,24 @@ class StackFrame
return !!(flags_ & CONSTRUCTING);
}
/*
* These two queries should not be used in general: the presence/absence of
* the call/args object is determined by the static(ish) properties of the
* JSFunction/JSScript. These queries should only be performed when probing
* a stack frame that may be in the middle of the prologue (during which
* time the call/args object are created).
*/
bool hasCallObj() const {
JS_ASSERT(isStrictEvalFrame() || fun()->isHeavyweight());
return flags_ & HAS_CALL_OBJ;
}
bool hasArgsObj() const {
JS_ASSERT(script()->needsArgsObj());
return flags_ & HAS_ARGS_OBJ;
}
/*
* The method JIT call/apply optimization can erase Function.{call,apply}
* invocations from the stack and push the callee frame directly. The base

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

@ -2128,7 +2128,7 @@ XPCJSRuntime::OnJSContextNew(JSContext *cx)
return true;
}
JSBool
bool
XPCJSRuntime::DeferredRelease(nsISupports* obj)
{
NS_ASSERTION(obj, "bad param");

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

@ -13,12 +13,7 @@
#include "nsHTMLVideoElement.h"
#include "nsHTMLDocument.h"
#include "nsICSSDeclaration.h"
#include "nsIDOMWebGLRenderingContext.h"
#include "nsSVGStylableElement.h"
#include "WebGLContext.h"
// WebGLContext pulls in windows.h, which defines random crap, so nuke
// those defines.
#include "qsWinUndefs.h"
#define DEFINE_UNWRAP_CAST(_interface, _base, _bit) \
template <> \

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

@ -2558,6 +2558,12 @@ nsXPConnect::GetCaller(JSContext **aJSContext, JSObject **aObj)
namespace xpc {
bool
DeferredRelease(nsISupports *obj)
{
return nsXPConnect::GetRuntimeInstance()->DeferredRelease(obj);
}
bool
Base64Encode(JSContext *cx, JS::Value val, JS::Value *out)
{

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

@ -698,7 +698,7 @@ public:
JSBool OnJSContextNew(JSContext* cx);
JSBool DeferredRelease(nsISupports* obj);
bool DeferredRelease(nsISupports* obj);
JSBool GetDoingFinalization() const {return mDoingFinalization;}

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

@ -219,6 +219,8 @@ class nsIMemoryMultiReporterCallback;
namespace xpc {
bool DeferredRelease(nsISupports *obj);
// If these functions return false, then an exception will be set on cx.
bool Base64Encode(JSContext *cx, JS::Value val, JS::Value *out);
bool Base64Decode(JSContext *cx, JS::Value val, JS::Value *out);

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

@ -2545,7 +2545,8 @@ nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement)
/*
how the root frame hierarchy should look
Galley presentation, non-XUL, with scrolling (i.e. not a frameset):
Galley presentation, non-XUL, with scrolling (i.e. not a frameset,
or framesets with async pan/zoom like on Fennec):
ViewportFrame [fixed-cb]
nsHTMLScrollFrame
@ -2553,7 +2554,8 @@ nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement)
root element frame (nsBlockFrame, nsSVGOuterSVGFrame,
nsTableOuterFrame, nsPlaceholderFrame)
Galley presentation, non-XUL, without scrolling (i.e. a frameset):
Galley presentation, non-XUL, without scrolling (i.e. a frameset,
except when async pan/zoom is enabled):
ViewportFrame [fixed-cb]
nsCanvasFrame [abs-cb]
@ -2670,12 +2672,15 @@ nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement)
// Never create scrollbars for XUL documents
bool isScrollable = !isXUL;
// Never create scrollbars for frameset documents.
#ifndef MOZ_WIDGET_ANDROID
// Never create scrollbars for frameset documents, except on android
// where we have async pan/zoom and need a scrollable root frame.
if (isHTML) {
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
if (htmlDoc && htmlDoc->GetIsFrameset())
isScrollable = false;
}
#endif
if (isPaginated) {
isScrollable = presContext->HasPaginatedScrolling();

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

@ -71,7 +71,6 @@ enum Type {
TYPE_WRAP_LIST,
TYPE_ZOOM,
TYPE_EXCLUDE_GLASS_FRAME,
TYPE_SIMPLE_SCROLL_LAYER,
#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
TYPE_REFLOW_COUNT,

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

@ -2072,12 +2072,15 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
nsIContent* content = mScrolledFrame->GetContent();
ViewID scrollId = nsLayoutUtils::FindIDFor(content);
nsRect viewport =
nsRect(aBuilder->ToReferenceFrame(mScrollFrame), mScrollFrame->GetSize());
nsRect viewport = mScrollFrame->GetRect() -
mScrollFrame->GetPosition() +
aBuilder->ToReferenceFrame(mScrollFrame);
bool usingDisplayport = false;
nsRect displayport;
usingDisplayport = nsLayoutUtils::GetDisplayPort(content, &displayport);
if (content) {
usingDisplayport = nsLayoutUtils::GetDisplayPort(content, &displayport);
}
RecordFrameMetrics(mScrolledFrame, mScrollFrame, layer, mVisibleRect, viewport,
(usingDisplayport ? &displayport : nsnull), scrollId,
aContainerParameters);
@ -2230,71 +2233,6 @@ nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
return RemoveScrollLayerCount() == 1;
}
nsDisplaySimpleScrollLayer::nsDisplaySimpleScrollLayer(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
: nsDisplayWrapList(aBuilder, aFrame, aList) {
MOZ_COUNT_CTOR(nsDisplaySimpleScrollLayer);
}
#ifdef NS_BUILD_REFCNT_LOGGING
nsDisplaySimpleScrollLayer::~nsDisplaySimpleScrollLayer() {
MOZ_COUNT_DTOR(nsDisplaySimpleScrollLayer);
}
#endif
already_AddRefed<Layer>
nsDisplaySimpleScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters) {
nsRefPtr<ContainerLayer> layer = aBuilder->LayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nsnull);
// Get the already set unique ID for scrolling this content remotely.
// Or, if not set, generate a new ID.
nsIContent* content = mFrame->PresContext()->Document()->GetRootElement();
ViewID scrollId = nsLayoutUtils::FindIDFor(content);
nsRect viewport = nsRect(ToReferenceFrame(), mFrame->GetSize());
bool usingDisplayport = false;
nsRect displayport;
usingDisplayport = nsLayoutUtils::GetDisplayPort(content, &displayport);
RecordFrameMetrics(mFrame, nsnull, layer, mVisibleRect, viewport,
(usingDisplayport ? &displayport : nsnull), scrollId,
aContainerParameters);
return layer.forget();
}
bool
nsDisplaySimpleScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
nsRect displayport;
if (nsLayoutUtils::GetDisplayPort(mFrame->PresContext()->Document()->GetRootElement(), &displayport)) {
// The visible region for the children may be much bigger than the hole we
// are viewing the children from, so that the compositor process has enough
// content to asynchronously pan while content is being refreshed.
nsRegion childVisibleRegion = displayport + ToReferenceFrame();
nsRect boundedRect =
childVisibleRegion.GetBounds().Intersect(mList.GetBounds(aBuilder));
nsRect allowExpansion = boundedRect.Intersect(aAllowVisibleRegionExpansion);
bool visible = mList.ComputeVisibilityForSublist(
aBuilder, &childVisibleRegion, boundedRect, allowExpansion);
mVisibleRect = boundedRect;
return visible;
} else {
return nsDisplayWrapList::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion);
}
}
nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayItem* aItem,
const nsRect& aRect)

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

@ -2015,39 +2015,6 @@ public:
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder);
};
/**
* A display item that has no purpose but to ensure its contents get
* their own layer and that FrameMetrics are recorded, if the frame's
* document's root element has a displayport.
*/
class nsDisplaySimpleScrollLayer : public nsDisplayWrapList {
public:
nsDisplaySimpleScrollLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplaySimpleScrollLayer();
#endif
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters);
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aParameters)
{
return mozilla::LAYER_ACTIVE;
}
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
{
return false;
}
NS_DISPLAY_DECL_NAME("SimpleScrollLayer", TYPE_SIMPLE_SCROLL_LAYER)
};
/**
* nsDisplayClip can clip a list of items, but we take a single item
* initially and then later merge other items into it when we merge

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

@ -54,7 +54,6 @@
#include "nsObjectFrame.h"
#include "nsIServiceManager.h"
#include "nsContentUtils.h"
#include "nsIHTMLDocument.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
@ -345,27 +344,6 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
if (subdocRootFrame && !aBuilder->IsForEventDelivery()) {
bool framesetUsingDisplayPort = false;
nsIDocument* doc = presContext->Document();
if (doc) {
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
if (htmlDoc && htmlDoc->GetIsFrameset()) {
nsIContent* root = doc->GetRootElement();
if (root) {
framesetUsingDisplayPort = nsLayoutUtils::GetDisplayPort(root, nsnull);
}
}
}
// Frameset document's don't have a scroll frame but we still need to
// communicate the basic metrics of the document.
if (framesetUsingDisplayPort) {
nsDisplaySimpleScrollLayer* item =
new (aBuilder) nsDisplaySimpleScrollLayer(aBuilder, subdocRootFrame, &childItems);
childItems.AppendToTop(item);
}
}
bool addedLayer = false;
if (subdocRootFrame && parentAPD != subdocAPD) {

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

@ -47,14 +47,35 @@ nsSVGClipPathFrame::ClipPaint(nsRenderingContext* aContext,
mClipParentMatrix = new gfxMatrix(aMatrix);
}
bool isTrivial = IsTrivial();
SVGAutoRenderState mode(aContext,
isTrivial ? SVGAutoRenderState::CLIP
: SVGAutoRenderState::CLIP_MASK);
gfxContext *gfx = aContext->ThebesContext();
nsISVGChildFrame *singleClipPathChild = nsnull;
if (IsTrivial(&singleClipPathChild)) {
// Notify our child that it's painting as part of a clipPath, and that
// we only require it to draw its path (it should skip filling, etc.):
SVGAutoRenderState mode(aContext, SVGAutoRenderState::CLIP);
if (!singleClipPathChild) {
// We have no children - the spec says clip away everything:
gfx->Rectangle(gfxRect());
} else {
singleClipPathChild->NotifySVGChanged(
nsISVGChildFrame::DO_NOT_NOTIFY_RENDERING_OBSERVERS |
nsISVGChildFrame::TRANSFORM_CHANGED);
singleClipPathChild->PaintSVG(aContext, nsnull);
}
gfx->Clip();
gfx->NewPath();
return NS_OK;
}
// Seems like this is a non-trivial clipPath, so we need to use a clip mask.
// Notify our children that they're painting into a clip mask:
SVGAutoRenderState mode(aContext, SVGAutoRenderState::CLIP_MASK);
// Check if this clipPath is itself clipped by another clipPath:
nsSVGClipPathFrame *clipPathFrame =
nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nsnull);
bool referencedClipIsTrivial;
@ -134,11 +155,6 @@ nsSVGClipPathFrame::ClipPaint(nsRenderingContext* aContext,
gfx->Restore();
}
if (isTrivial) {
gfx->Clip();
gfx->NewPath();
}
return NS_OK;
}
@ -185,13 +201,17 @@ nsSVGClipPathFrame::ClipHitTest(nsIFrame* aParent,
}
bool
nsSVGClipPathFrame::IsTrivial()
nsSVGClipPathFrame::IsTrivial(nsISVGChildFrame **aSingleChild)
{
// If the clip path is clipped then it's non-trivial
if (nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nsnull))
return false;
bool foundChild = false;
if (aSingleChild) {
*aSingleChild = nsnull;
}
nsISVGChildFrame *foundChild = nsnull;
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
@ -206,9 +226,12 @@ nsSVGClipPathFrame::IsTrivial()
if (nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame(nsnull))
return false;
foundChild = true;
foundChild = svgChild;
}
}
if (aSingleChild) {
*aSingleChild = foundChild;
}
return true;
}

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

@ -11,6 +11,7 @@
#include "nsSVGUtils.h"
class nsRenderingContext;
class nsISVGChildFrame;
typedef nsSVGContainerFrame nsSVGClipPathFrameBase;
@ -41,7 +42,7 @@ public:
// Check if this clipPath is made up of more than one geometry object.
// If so, the clipping API in cairo isn't enough and we need to use
// mask based clipping.
bool IsTrivial();
bool IsTrivial(nsISVGChildFrame **aSingleChild = nsnull);
bool IsValid();

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

@ -317,6 +317,9 @@ nsSVGGlyphFrame::PaintSVG(nsRenderingContext *aContext,
}
if (renderMode != SVGAutoRenderState::NORMAL) {
NS_ABORT_IF_FALSE(renderMode == SVGAutoRenderState::CLIP ||
renderMode == SVGAutoRenderState::CLIP_MASK,
"Unknown render mode");
gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx);
SetupGlobalTransform(gfx);

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