зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
2f417022fb
2
CLOBBER
2
CLOBBER
|
@ -15,4 +15,4 @@
|
|||
#
|
||||
# Note: The description below will be part of the error message shown to users.
|
||||
#
|
||||
Bug 829832 - BackgroundFileSaver xpcshell failures without clobber
|
||||
Bug 845063 needs clobber
|
||||
|
|
|
@ -10,37 +10,62 @@ interface nsIAccessible;
|
|||
|
||||
/**
|
||||
* This interface gives access to an accessible's set of relations.
|
||||
* Be carefull, do not change constants until ATK has a structure to map gecko
|
||||
* constants into ATK constants.
|
||||
*/
|
||||
[scriptable, uuid(f42a1589-70ab-4704-877f-4a9162bbe188)]
|
||||
[scriptable, uuid(9f85fc0d-2969-48e6-b822-68140f7e5770)]
|
||||
interface nsIAccessibleRelation : nsISupports
|
||||
{
|
||||
|
||||
const unsigned long RELATION_NUL = 0x00;
|
||||
|
||||
/**
|
||||
* Some attribute of this object is affected by a target object.
|
||||
* This object is labelled by a target object.
|
||||
*/
|
||||
const unsigned long RELATION_CONTROLLED_BY = 0x01;
|
||||
|
||||
// First relation
|
||||
const unsigned long RELATION_FIRST = RELATION_CONTROLLED_BY;
|
||||
|
||||
/**
|
||||
* This object is interactive and controls some attribute of a target object.
|
||||
*/
|
||||
const unsigned long RELATION_CONTROLLER_FOR = 0x02;
|
||||
const unsigned long RELATION_LABELLED_BY = 0x00;
|
||||
|
||||
/**
|
||||
* This object is label for a target object.
|
||||
*/
|
||||
const unsigned long RELATION_LABEL_FOR = 0x03;
|
||||
const unsigned long RELATION_LABEL_FOR = 0x01;
|
||||
|
||||
/**
|
||||
* This object is labelled by a target object.
|
||||
* This object is described by the target object.
|
||||
*/
|
||||
const unsigned long RELATION_LABELLED_BY = 0x04;
|
||||
const unsigned long RELATION_DESCRIBED_BY = 0x02;
|
||||
|
||||
/**
|
||||
* This object is describes the target object.
|
||||
*/
|
||||
const unsigned long RELATION_DESCRIPTION_FOR = 0x3;
|
||||
|
||||
/**
|
||||
* This object is a child of a target object.
|
||||
*/
|
||||
const unsigned long RELATION_NODE_CHILD_OF = 0x4;
|
||||
|
||||
/**
|
||||
* This object is a parent of a target object. A dual relation to
|
||||
* RELATION_NODE_CHILD_OF
|
||||
*/
|
||||
const unsigned long RELATION_NODE_PARENT_OF = 0x5;
|
||||
|
||||
/**
|
||||
* Some attribute of this object is affected by a target object.
|
||||
*/
|
||||
const unsigned long RELATION_CONTROLLED_BY = 0x06;
|
||||
|
||||
/**
|
||||
* This object is interactive and controls some attribute of a target object.
|
||||
*/
|
||||
const unsigned long RELATION_CONTROLLER_FOR = 0x07;
|
||||
|
||||
/**
|
||||
* Content flows from this object to a target object, i.e. has content that
|
||||
* flows logically to another object in a sequential way, e.g. text flow.
|
||||
*/
|
||||
const unsigned long RELATION_FLOWS_TO = 0x08;
|
||||
|
||||
/**
|
||||
* Content flows to this object from a target object, i.e. has content that
|
||||
* flows logically from another object in a sequential way, e.g. text flow.
|
||||
*/
|
||||
const unsigned long RELATION_FLOWS_FROM = 0x09;
|
||||
|
||||
/**
|
||||
* This object is a member of a group of one or more objects. When there is
|
||||
|
@ -48,71 +73,41 @@ interface nsIAccessibleRelation : nsISupports
|
|||
* target, e.g. a grouping object. It is also possible that each member has
|
||||
* multiple additional targets, e.g. one for every other member in the group.
|
||||
*/
|
||||
const unsigned long RELATION_MEMBER_OF = 0x05;
|
||||
|
||||
/**
|
||||
* This object is a child of a target object.
|
||||
*/
|
||||
const unsigned long RELATION_NODE_CHILD_OF = 0x06;
|
||||
|
||||
/**
|
||||
* Content flows from this object to a target object, i.e. has content that
|
||||
* flows logically to another object in a sequential way, e.g. text flow.
|
||||
*/
|
||||
const unsigned long RELATION_FLOWS_TO = 0x07;
|
||||
|
||||
/**
|
||||
* Content flows to this object from a target object, i.e. has content that
|
||||
* flows logically from another object in a sequential way, e.g. text flow.
|
||||
*/
|
||||
const unsigned long RELATION_FLOWS_FROM = 0x08;
|
||||
const unsigned long RELATION_MEMBER_OF = 0x0a;
|
||||
|
||||
/**
|
||||
* This object is a sub window of a target object.
|
||||
*/
|
||||
const unsigned long RELATION_SUBWINDOW_OF = 0x09;
|
||||
const unsigned long RELATION_SUBWINDOW_OF = 0x0b;
|
||||
|
||||
/**
|
||||
* This object embeds a target object. This relation can be used on the
|
||||
* OBJID_CLIENT accessible for a top level window to show where the content
|
||||
* areas are.
|
||||
*/
|
||||
const unsigned long RELATION_EMBEDS = 0x0a;
|
||||
const unsigned long RELATION_EMBEDS = 0x0c;
|
||||
|
||||
/**
|
||||
* This object is embedded by a target object.
|
||||
*/
|
||||
const unsigned long RELATION_EMBEDDED_BY = 0x0b;
|
||||
const unsigned long RELATION_EMBEDDED_BY = 0x0d;
|
||||
|
||||
/**
|
||||
* This object is a transient component related to the target object. When
|
||||
* this object is activated the target object doesn't lose focus.
|
||||
*/
|
||||
const unsigned long RELATION_POPUP_FOR = 0x0c;
|
||||
const unsigned long RELATION_POPUP_FOR = 0x0e;
|
||||
|
||||
/**
|
||||
* This object is a parent window of the target object.
|
||||
*/
|
||||
const unsigned long RELATION_PARENT_WINDOW_OF = 0x0d;
|
||||
|
||||
/**
|
||||
* This object is described by the target object.
|
||||
*/
|
||||
const unsigned long RELATION_DESCRIBED_BY = 0x0e;
|
||||
|
||||
/**
|
||||
* This object is describes the target object.
|
||||
*/
|
||||
const unsigned long RELATION_DESCRIPTION_FOR = 0x0f;
|
||||
|
||||
// Last relation that is standard to desktop accessibility APIs
|
||||
const unsigned long RELATION_LAST = RELATION_DESCRIPTION_FOR;
|
||||
const unsigned long RELATION_PARENT_WINDOW_OF = 0x0f;
|
||||
|
||||
/**
|
||||
* Part of a form/dialog with a related default button. It is used for
|
||||
* MSAA only, no for IA2 nor ATK.
|
||||
* MSAA/XPCOM, it isn't for IA2 or ATK.
|
||||
*/
|
||||
const unsigned long RELATION_DEFAULT_BUTTON = 0x4000;
|
||||
const unsigned long RELATION_DEFAULT_BUTTON = 0x10;
|
||||
|
||||
/**
|
||||
* Returns the type of the relation.
|
||||
|
|
|
@ -853,21 +853,29 @@ refRelationSetCB(AtkObject *aAtkObj)
|
|||
if (!accWrap)
|
||||
return relation_set;
|
||||
|
||||
uint32_t relationTypes[] = {
|
||||
nsIAccessibleRelation::RELATION_LABELLED_BY,
|
||||
nsIAccessibleRelation::RELATION_LABEL_FOR,
|
||||
nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
|
||||
// Keep in sync with AtkRelationType enum.
|
||||
static const uint32_t relationTypes[] = {
|
||||
nsIAccessibleRelation::RELATION_CONTROLLED_BY,
|
||||
nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
|
||||
nsIAccessibleRelation::RELATION_EMBEDS,
|
||||
nsIAccessibleRelation::RELATION_LABEL_FOR,
|
||||
nsIAccessibleRelation::RELATION_LABELLED_BY,
|
||||
nsIAccessibleRelation::RELATION_MEMBER_OF,
|
||||
nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
|
||||
nsIAccessibleRelation::RELATION_FLOWS_TO,
|
||||
nsIAccessibleRelation::RELATION_FLOWS_FROM,
|
||||
nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
|
||||
nsIAccessibleRelation::RELATION_EMBEDS,
|
||||
nsIAccessibleRelation::RELATION_EMBEDDED_BY,
|
||||
nsIAccessibleRelation::RELATION_POPUP_FOR,
|
||||
nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF,
|
||||
nsIAccessibleRelation::RELATION_DESCRIBED_BY,
|
||||
nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
|
||||
nsIAccessibleRelation::RELATION_NODE_PARENT_OF
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < ArrayLength(relationTypes); i++) {
|
||||
AtkRelationType atkType = static_cast<AtkRelationType>(relationTypes[i]);
|
||||
// Shift to 1 to skip ATK_RELATION_NULL.
|
||||
AtkRelationType atkType = static_cast<AtkRelationType>(i + 1);
|
||||
AtkRelation* atkRelation =
|
||||
atk_relation_set_get_relation_by_type(relation_set, atkType);
|
||||
if (atkRelation)
|
||||
|
|
|
@ -138,6 +138,55 @@ AccGroupInfo::AccGroupInfo(Accessible* aItem, role aRole) :
|
|||
mParent = parentPrevSibling;
|
||||
}
|
||||
|
||||
Accessible*
|
||||
AccGroupInfo::FirstItemOf(Accessible* aContainer)
|
||||
{
|
||||
// ARIA trees can be arranged by ARIA groups, otherwise aria-level works.
|
||||
a11y::role containerRole = aContainer->Role();
|
||||
Accessible* item = aContainer->NextSibling();
|
||||
if (item) {
|
||||
if (containerRole == roles::OUTLINEITEM && item->Role() == roles::GROUPING)
|
||||
item = item->FirstChild();
|
||||
|
||||
AccGroupInfo* itemGroupInfo = item->GetGroupInfo();
|
||||
if (itemGroupInfo && itemGroupInfo->ConceptualParent() == aContainer)
|
||||
return item;
|
||||
}
|
||||
|
||||
// Otherwise it can be a direct child.
|
||||
item = aContainer->FirstChild();
|
||||
if (item && IsConceptualParent(BaseRole(item->Role()), containerRole))
|
||||
return item;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Accessible*
|
||||
AccGroupInfo::NextItemTo(Accessible* aItem)
|
||||
{
|
||||
AccGroupInfo* groupInfo = aItem->GetGroupInfo();
|
||||
if (!groupInfo)
|
||||
return nullptr;
|
||||
|
||||
// If the item in middle of the group then search next item in siblings.
|
||||
if (groupInfo->PosInSet() >= groupInfo->SetSize())
|
||||
return nullptr;
|
||||
|
||||
Accessible* parent = aItem->Parent();
|
||||
uint32_t childCount = parent->ChildCount();
|
||||
for (int32_t idx = aItem->IndexInParent() + 1; idx < childCount; idx++) {
|
||||
Accessible* nextItem = parent->GetChildAt(idx);
|
||||
AccGroupInfo* nextGroupInfo = nextItem->GetGroupInfo();
|
||||
if (nextGroupInfo &&
|
||||
nextGroupInfo->ConceptualParent() == groupInfo->ConceptualParent()) {
|
||||
return nextItem;
|
||||
}
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Item in the midle of the group but there's no next item!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
AccGroupInfo::IsConceptualParent(role aRole, role aParentRole)
|
||||
{
|
||||
|
|
|
@ -17,11 +17,22 @@ namespace a11y {
|
|||
class AccGroupInfo
|
||||
{
|
||||
public:
|
||||
AccGroupInfo(Accessible* aItem, mozilla::a11y::role aRole);
|
||||
~AccGroupInfo() { MOZ_COUNT_DTOR(AccGroupInfo); }
|
||||
|
||||
int32_t PosInSet() const { return mPosInSet; }
|
||||
/**
|
||||
* Return 1-based position in the group.
|
||||
*/
|
||||
uint32_t PosInSet() const { return mPosInSet; }
|
||||
|
||||
/**
|
||||
* Return a number of items in the group.
|
||||
*/
|
||||
uint32_t SetSize() const { return mSetSize; }
|
||||
|
||||
/**
|
||||
* Return a direct or logical parent of the accessible that this group info is
|
||||
* created for.
|
||||
*/
|
||||
Accessible* ConceptualParent() const { return mParent; }
|
||||
|
||||
/**
|
||||
|
@ -50,9 +61,23 @@ public:
|
|||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a first item for the given container.
|
||||
*/
|
||||
static Accessible* FirstItemOf(Accessible* aContainer);
|
||||
|
||||
/**
|
||||
* Return next item of the same group to the given item.
|
||||
*/
|
||||
static Accessible* NextItemTo(Accessible* aItem);
|
||||
|
||||
protected:
|
||||
AccGroupInfo(Accessible* aItem, a11y::role aRole);
|
||||
|
||||
private:
|
||||
AccGroupInfo(const AccGroupInfo&);
|
||||
AccGroupInfo& operator =(const AccGroupInfo&);
|
||||
AccGroupInfo() MOZ_DELETE;
|
||||
AccGroupInfo(const AccGroupInfo&) MOZ_DELETE;
|
||||
AccGroupInfo& operator =(const AccGroupInfo&) MOZ_DELETE;
|
||||
|
||||
static mozilla::a11y::role BaseRole(mozilla::a11y::role aRole)
|
||||
{
|
||||
|
@ -71,8 +96,7 @@ private:
|
|||
* Return true if the given parent role is conceptual parent of the given
|
||||
* role.
|
||||
*/
|
||||
static bool IsConceptualParent(mozilla::a11y::role aRole,
|
||||
mozilla::a11y::role aParentRole);
|
||||
static bool IsConceptualParent(a11y::role aRole, a11y::role aParentRole);
|
||||
|
||||
uint32_t mPosInSet;
|
||||
uint32_t mSetSize;
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
#include "AccIterator.h"
|
||||
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "AccGroupInfo.h"
|
||||
#include "Accessible-inl.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "XULTreeAccessible.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsBindingManager.h"
|
||||
|
@ -329,6 +333,11 @@ IDRefsIterator::Next()
|
|||
return nextElm ? mDoc->GetAccessible(nextElm) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SingleAccIterator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Accessible*
|
||||
SingleAccIterator::Next()
|
||||
{
|
||||
|
@ -337,3 +346,56 @@ SingleAccIterator::Next()
|
|||
return (nextAcc && !nextAcc->IsDefunct()) ? nextAcc : nullptr;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ItemIterator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Accessible*
|
||||
ItemIterator::Next()
|
||||
{
|
||||
if (mContainer) {
|
||||
mAnchor = AccGroupInfo::FirstItemOf(mContainer);
|
||||
mContainer = nullptr;
|
||||
return mAnchor;
|
||||
}
|
||||
|
||||
return mAnchor ? (mAnchor = AccGroupInfo::NextItemTo(mAnchor)) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTreeItemIterator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
XULTreeItemIterator::XULTreeItemIterator(XULTreeAccessible* aXULTree,
|
||||
nsITreeView* aTreeView,
|
||||
int32_t aRowIdx) :
|
||||
mXULTree(aXULTree), mTreeView(aTreeView), mRowCount(-1),
|
||||
mContainerLevel(-1), mCurrRowIdx(aRowIdx + 1)
|
||||
{
|
||||
mTreeView->GetRowCount(&mRowCount);
|
||||
if (aRowIdx != -1)
|
||||
mTreeView->GetLevel(aRowIdx, &mContainerLevel);
|
||||
}
|
||||
|
||||
Accessible*
|
||||
XULTreeItemIterator::Next()
|
||||
{
|
||||
while (mCurrRowIdx < mRowCount) {
|
||||
int32_t level = 0;
|
||||
mTreeView->GetLevel(mCurrRowIdx, &level);
|
||||
|
||||
if (level == mContainerLevel + 1)
|
||||
return mXULTree->GetTreeItemAccessible(mCurrRowIdx++);
|
||||
|
||||
if (level <= mContainerLevel) { // got level up
|
||||
mCurrRowIdx = mRowCount;
|
||||
break;
|
||||
}
|
||||
|
||||
mCurrRowIdx++;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -266,6 +266,53 @@ private:
|
|||
nsRefPtr<Accessible> mAcc;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to iterate items of the given item container.
|
||||
*/
|
||||
class ItemIterator : public AccIterable
|
||||
{
|
||||
public:
|
||||
ItemIterator(Accessible* aItemContainer) :
|
||||
mContainer(aItemContainer), mAnchor(nullptr) { }
|
||||
virtual ~ItemIterator() { }
|
||||
|
||||
virtual Accessible* Next();
|
||||
|
||||
private:
|
||||
ItemIterator() MOZ_DELETE;
|
||||
ItemIterator(const ItemIterator&) MOZ_DELETE;
|
||||
ItemIterator& operator = (const ItemIterator&) MOZ_DELETE;
|
||||
|
||||
Accessible* mContainer;
|
||||
Accessible* mAnchor;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used to iterate through XUL tree items of the same level.
|
||||
*/
|
||||
class XULTreeItemIterator : public AccIterable
|
||||
{
|
||||
public:
|
||||
XULTreeItemIterator(XULTreeAccessible* aXULTree, nsITreeView* aTreeView,
|
||||
int32_t aRowIdx);
|
||||
virtual ~XULTreeItemIterator() { }
|
||||
|
||||
virtual Accessible* Next();
|
||||
|
||||
private:
|
||||
XULTreeItemIterator() MOZ_DELETE;
|
||||
XULTreeItemIterator(const XULTreeItemIterator&) MOZ_DELETE;
|
||||
XULTreeItemIterator& operator = (const XULTreeItemIterator&) MOZ_DELETE;
|
||||
|
||||
XULTreeAccessible* mXULTree;
|
||||
nsITreeView* mTreeView;
|
||||
int32_t mRowCount;
|
||||
int32_t mContainerLevel;
|
||||
int32_t mCurrRowIdx;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -19,12 +19,11 @@ namespace a11y {
|
|||
*/
|
||||
struct RelationCopyHelper
|
||||
{
|
||||
RelationCopyHelper(mozilla::a11y::AccIterable* aFirstIter,
|
||||
mozilla::a11y::AccIterable* aLastIter) :
|
||||
RelationCopyHelper(AccIterable* aFirstIter, AccIterable* aLastIter) :
|
||||
mFirstIter(aFirstIter), mLastIter(aLastIter) { }
|
||||
|
||||
mozilla::a11y::AccIterable* mFirstIter;
|
||||
mozilla::a11y::AccIterable* mLastIter;
|
||||
AccIterable* mFirstIter;
|
||||
AccIterable* mLastIter;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -39,7 +38,7 @@ public:
|
|||
Relation(const RelationCopyHelper aRelation) :
|
||||
mFirstIter(aRelation.mFirstIter), mLastIter(aRelation.mLastIter) { }
|
||||
|
||||
Relation(mozilla::a11y::AccIterable* aIter) :
|
||||
Relation(AccIterable* aIter) :
|
||||
mFirstIter(aIter), mLastIter(aIter) { }
|
||||
|
||||
Relation(Accessible* aAcc) :
|
||||
|
@ -69,7 +68,7 @@ public:
|
|||
return RelationCopyHelper(mFirstIter.forget(), mLastIter);
|
||||
}
|
||||
|
||||
inline void AppendIter(mozilla::a11y::AccIterable* aIter)
|
||||
inline void AppendIter(AccIterable* aIter)
|
||||
{
|
||||
if (mLastIter)
|
||||
mLastIter->mNextIter = aIter;
|
||||
|
@ -85,7 +84,7 @@ public:
|
|||
inline void AppendTarget(Accessible* aAcc)
|
||||
{
|
||||
if (aAcc)
|
||||
AppendIter(new mozilla::a11y::SingleAccIterator(aAcc));
|
||||
AppendIter(new SingleAccIterator(aAcc));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,8 +117,8 @@ public:
|
|||
private:
|
||||
Relation& operator = (const Relation&);
|
||||
|
||||
nsAutoPtr<mozilla::a11y::AccIterable> mFirstIter;
|
||||
mozilla::a11y::AccIterable* mLastIter;
|
||||
nsAutoPtr<AccIterable> mFirstIter;
|
||||
AccIterable* mLastIter;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
|
|
@ -587,9 +587,8 @@ enum Role {
|
|||
TOGGLE_BUTTON = 93,
|
||||
|
||||
/**
|
||||
* Representas a control that is capable of expanding and collapsing rows as
|
||||
* Represent a control that is capable of expanding and collapsing rows as
|
||||
* well as showing multiple columns of data.
|
||||
* XXX: it looks like this role is dupe of OUTLINE.
|
||||
*/
|
||||
TREE_TABLE = 94,
|
||||
|
||||
|
|
|
@ -318,22 +318,22 @@ static const char kEventTypeNames[][40] = {
|
|||
* nsIAccessibleRetrieval::getStringRelationType() method.
|
||||
*/
|
||||
static const char kRelationTypeNames[][20] = {
|
||||
"unknown", // RELATION_NUL
|
||||
"labelled by", // RELATION_LABELLED_BY
|
||||
"label for", // RELATION_LABEL_FOR
|
||||
"described by", // RELATION_DESCRIBED_BY
|
||||
"description for", // RELATION_DESCRIPTION_FOR
|
||||
"node child of", // RELATION_NODE_CHILD_OF
|
||||
"node parent of", // RELATION_NODE_PARENT_OF
|
||||
"controlled by", // RELATION_CONTROLLED_BY
|
||||
"controller for", // RELATION_CONTROLLER_FOR
|
||||
"label for", // RELATION_LABEL_FOR
|
||||
"labelled by", // RELATION_LABELLED_BY
|
||||
"member of", // RELATION_MEMBER_OF
|
||||
"node child of", // RELATION_NODE_CHILD_OF
|
||||
"flows to", // RELATION_FLOWS_TO
|
||||
"flows from", // RELATION_FLOWS_FROM
|
||||
"member of", // RELATION_MEMBER_OF
|
||||
"subwindow of", // RELATION_SUBWINDOW_OF
|
||||
"embeds", // RELATION_EMBEDS
|
||||
"embedded by", // RELATION_EMBEDDED_BY
|
||||
"popup for", // RELATION_POPUP_FOR
|
||||
"parent window of", // RELATION_PARENT_WINDOW_OF
|
||||
"described by", // RELATION_DESCRIBED_BY
|
||||
"description for", // RELATION_DESCRIPTION_FOR
|
||||
"default button" // RELATION_DEFAULT_BUTTON
|
||||
};
|
||||
|
||||
|
|
|
@ -1967,16 +1967,6 @@ Accessible::RelationByType(uint32_t aType)
|
|||
// Relationships are defined on the same content node that the role would be
|
||||
// defined on.
|
||||
switch (aType) {
|
||||
case nsIAccessibleRelation::RELATION_LABEL_FOR: {
|
||||
Relation rel(new RelatedAccIterator(Document(), mContent,
|
||||
nsGkAtoms::aria_labelledby));
|
||||
if (mContent->Tag() == nsGkAtoms::label)
|
||||
rel.AppendIter(new IDRefsIterator(mDoc, mContent, mContent->IsHTML() ?
|
||||
nsGkAtoms::_for :
|
||||
nsGkAtoms::control));
|
||||
|
||||
return rel;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_LABELLED_BY: {
|
||||
Relation rel(new IDRefsIterator(mDoc, mContent,
|
||||
nsGkAtoms::aria_labelledby));
|
||||
|
@ -1988,6 +1978,18 @@ Accessible::RelationByType(uint32_t aType)
|
|||
|
||||
return rel;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_LABEL_FOR: {
|
||||
Relation rel(new RelatedAccIterator(Document(), mContent,
|
||||
nsGkAtoms::aria_labelledby));
|
||||
if (mContent->Tag() == nsGkAtoms::label)
|
||||
rel.AppendIter(new IDRefsIterator(mDoc, mContent, mContent->IsHTML() ?
|
||||
nsGkAtoms::_for :
|
||||
nsGkAtoms::control));
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_DESCRIBED_BY: {
|
||||
Relation rel(new IDRefsIterator(mDoc, mContent,
|
||||
nsGkAtoms::aria_describedby));
|
||||
|
@ -1996,6 +1998,7 @@ Accessible::RelationByType(uint32_t aType)
|
|||
|
||||
return rel;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR: {
|
||||
Relation rel(new RelatedAccIterator(Document(), mContent,
|
||||
nsGkAtoms::aria_describedby));
|
||||
|
@ -2010,6 +2013,7 @@ Accessible::RelationByType(uint32_t aType)
|
|||
|
||||
return rel;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_NODE_CHILD_OF: {
|
||||
Relation rel(new RelatedAccIterator(Document(), mContent,
|
||||
nsGkAtoms::aria_owns));
|
||||
|
@ -2018,11 +2022,7 @@ Accessible::RelationByType(uint32_t aType)
|
|||
// get the parent the hard way.
|
||||
if (mRoleMapEntry && (mRoleMapEntry->role == roles::OUTLINEITEM ||
|
||||
mRoleMapEntry->role == roles::ROW)) {
|
||||
AccGroupInfo* groupInfo = GetGroupInfo();
|
||||
if (!groupInfo)
|
||||
return rel;
|
||||
|
||||
rel.AppendTarget(groupInfo->ConceptualParent());
|
||||
rel.AppendTarget(GetGroupInfo()->ConceptualParent());
|
||||
}
|
||||
|
||||
// If accessible is in its own Window, or is the root of a document,
|
||||
|
@ -2043,21 +2043,52 @@ Accessible::RelationByType(uint32_t aType)
|
|||
|
||||
return rel;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_NODE_PARENT_OF: {
|
||||
Relation rel(new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_owns));
|
||||
|
||||
// ARIA tree or treegrid can do the hierarchy by @aria-level, ARIA trees
|
||||
// also can be organized by groups.
|
||||
if (mRoleMapEntry &&
|
||||
(mRoleMapEntry->role == roles::OUTLINEITEM ||
|
||||
mRoleMapEntry->role == roles::ROW ||
|
||||
mRoleMapEntry->role == roles::OUTLINE ||
|
||||
mRoleMapEntry->role == roles::TREE_TABLE)) {
|
||||
rel.AppendIter(new ItemIterator(this));
|
||||
}
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
|
||||
return Relation(new RelatedAccIterator(Document(), mContent,
|
||||
nsGkAtoms::aria_controls));
|
||||
|
||||
case nsIAccessibleRelation::RELATION_CONTROLLER_FOR: {
|
||||
Relation rel(new IDRefsIterator(mDoc, mContent,
|
||||
nsGkAtoms::aria_controls));
|
||||
rel.AppendIter(new HTMLOutputIterator(Document(), mContent));
|
||||
return rel;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_FLOWS_TO:
|
||||
return Relation(new IDRefsIterator(mDoc, mContent,
|
||||
nsGkAtoms::aria_flowto));
|
||||
|
||||
case nsIAccessibleRelation::RELATION_FLOWS_FROM:
|
||||
return Relation(new RelatedAccIterator(Document(), mContent,
|
||||
nsGkAtoms::aria_flowto));
|
||||
|
||||
case nsIAccessibleRelation::RELATION_MEMBER_OF:
|
||||
return Relation(mDoc, GetAtomicRegion());
|
||||
|
||||
case nsIAccessibleRelation::RELATION_SUBWINDOW_OF:
|
||||
case nsIAccessibleRelation::RELATION_EMBEDS:
|
||||
case nsIAccessibleRelation::RELATION_EMBEDDED_BY:
|
||||
case nsIAccessibleRelation::RELATION_POPUP_FOR:
|
||||
case nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF:
|
||||
return Relation();
|
||||
|
||||
case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON: {
|
||||
if (mContent->IsHTML()) {
|
||||
// HTML form controls implements nsIFormControl interface.
|
||||
|
@ -2105,13 +2136,7 @@ Accessible::RelationByType(uint32_t aType)
|
|||
}
|
||||
return Relation();
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_MEMBER_OF:
|
||||
return Relation(mDoc, GetAtomicRegion());
|
||||
case nsIAccessibleRelation::RELATION_SUBWINDOW_OF:
|
||||
case nsIAccessibleRelation::RELATION_EMBEDS:
|
||||
case nsIAccessibleRelation::RELATION_EMBEDDED_BY:
|
||||
case nsIAccessibleRelation::RELATION_POPUP_FOR:
|
||||
case nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF:
|
||||
|
||||
default:
|
||||
return Relation();
|
||||
}
|
||||
|
@ -2129,12 +2154,29 @@ Accessible::GetRelations(nsIArray **aRelations)
|
|||
nsCOMPtr<nsIMutableArray> relations = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
NS_ENSURE_TRUE(relations, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
for (uint32_t relType = nsIAccessibleRelation::RELATION_FIRST;
|
||||
relType < nsIAccessibleRelation::RELATION_LAST;
|
||||
++relType) {
|
||||
static const uint32_t relationTypes[] = {
|
||||
nsIAccessibleRelation::RELATION_LABELLED_BY,
|
||||
nsIAccessibleRelation::RELATION_LABEL_FOR,
|
||||
nsIAccessibleRelation::RELATION_DESCRIBED_BY,
|
||||
nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
|
||||
nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
|
||||
nsIAccessibleRelation::RELATION_NODE_PARENT_OF,
|
||||
nsIAccessibleRelation::RELATION_CONTROLLED_BY,
|
||||
nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
|
||||
nsIAccessibleRelation::RELATION_FLOWS_TO,
|
||||
nsIAccessibleRelation::RELATION_FLOWS_FROM,
|
||||
nsIAccessibleRelation::RELATION_MEMBER_OF,
|
||||
nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
|
||||
nsIAccessibleRelation::RELATION_EMBEDS,
|
||||
nsIAccessibleRelation::RELATION_EMBEDDED_BY,
|
||||
nsIAccessibleRelation::RELATION_POPUP_FOR,
|
||||
nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF,
|
||||
nsIAccessibleRelation::RELATION_DEFAULT_BUTTON
|
||||
};
|
||||
|
||||
for (uint32_t idx = 0; idx < ArrayLength(relationTypes); idx++) {
|
||||
nsCOMPtr<nsIAccessibleRelation> relation;
|
||||
nsresult rv = GetRelationByType(relType, getter_AddRefs(relation));
|
||||
nsresult rv = GetRelationByType(relationTypes[idx], getter_AddRefs(relation));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && relation) {
|
||||
uint32_t targets = 0;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "nsAccUtils.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsIAccessibleRelation.h"
|
||||
#include "nsWinUtils.h"
|
||||
#include "ServiceProvider.h"
|
||||
#include "Relation.h"
|
||||
|
@ -1048,9 +1047,8 @@ AccessibleWrap::get_nRelations(long *aNRelations)
|
|||
if (IsDefunct())
|
||||
return CO_E_OBJNOTCONNECTED;
|
||||
|
||||
for (uint32_t relType = nsIAccessibleRelation::RELATION_FIRST;
|
||||
relType <= nsIAccessibleRelation::RELATION_LAST; relType++) {
|
||||
Relation rel = RelationByType(relType);
|
||||
for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) {
|
||||
Relation rel = RelationByType(sRelationTypesForIA2[idx]);
|
||||
if (rel.Next())
|
||||
(*aNRelations)++;
|
||||
}
|
||||
|
@ -1074,8 +1072,8 @@ AccessibleWrap::get_relation(long aRelationIndex,
|
|||
return CO_E_OBJNOTCONNECTED;
|
||||
|
||||
long relIdx = 0;
|
||||
for (uint32_t relType = nsIAccessibleRelation::RELATION_FIRST;
|
||||
relType <= nsIAccessibleRelation::RELATION_LAST; relType++) {
|
||||
for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) {
|
||||
uint32_t relType = sRelationTypesForIA2[idx];
|
||||
Relation rel = RelationByType(relType);
|
||||
nsRefPtr<ia2AccessibleRelation> ia2Relation =
|
||||
new ia2AccessibleRelation(relType, &rel);
|
||||
|
@ -1109,9 +1107,9 @@ AccessibleWrap::get_relations(long aMaxRelations,
|
|||
if (IsDefunct())
|
||||
return CO_E_OBJNOTCONNECTED;
|
||||
|
||||
for (uint32_t relType = nsIAccessibleRelation::RELATION_FIRST;
|
||||
relType <= nsIAccessibleRelation::RELATION_LAST &&
|
||||
*aNRelations < aMaxRelations; relType++) {
|
||||
for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2) &&
|
||||
*aNRelations < aMaxRelations; idx++) {
|
||||
uint32_t relType = sRelationTypesForIA2[idx];
|
||||
Relation rel = RelationByType(relType);
|
||||
nsRefPtr<ia2AccessibleRelation> ia2Rel =
|
||||
new ia2AccessibleRelation(relType, &rel);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define _NS_ACCESSIBLE_RELATION_WRAP_H
|
||||
|
||||
#include "Accessible.h"
|
||||
#include "nsIAccessibleRelation.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -60,6 +61,28 @@ private:
|
|||
ULONG mReferences;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Relations exposed to IAccessible2.
|
||||
*/
|
||||
static const uint32_t sRelationTypesForIA2[] = {
|
||||
nsIAccessibleRelation::RELATION_LABELLED_BY,
|
||||
nsIAccessibleRelation::RELATION_LABEL_FOR,
|
||||
nsIAccessibleRelation::RELATION_DESCRIBED_BY,
|
||||
nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
|
||||
nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
|
||||
nsIAccessibleRelation::RELATION_CONTROLLED_BY,
|
||||
nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
|
||||
nsIAccessibleRelation::RELATION_FLOWS_TO,
|
||||
nsIAccessibleRelation::RELATION_FLOWS_FROM,
|
||||
nsIAccessibleRelation::RELATION_MEMBER_OF,
|
||||
nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
|
||||
nsIAccessibleRelation::RELATION_EMBEDS,
|
||||
nsIAccessibleRelation::RELATION_EMBEDDED_BY,
|
||||
nsIAccessibleRelation::RELATION_POPUP_FOR,
|
||||
nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -437,6 +437,19 @@ XULTreeAccessible::ChildCount() const
|
|||
return childCount;
|
||||
}
|
||||
|
||||
Relation
|
||||
XULTreeAccessible::RelationByType(uint32_t aType)
|
||||
{
|
||||
if (aType == nsIAccessibleRelation::RELATION_NODE_PARENT_OF) {
|
||||
if (mTreeView)
|
||||
return Relation(new XULTreeItemIterator(this, mTreeView, -1));
|
||||
|
||||
return Relation();
|
||||
}
|
||||
|
||||
return Accessible::RelationByType(aType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTreeAccessible: Widgets
|
||||
|
||||
|
@ -798,9 +811,8 @@ XULTreeItemAccessibleBase::RelationByType(uint32_t aType)
|
|||
if (!mTreeView)
|
||||
return Relation();
|
||||
|
||||
if (aType != nsIAccessibleRelation::RELATION_NODE_CHILD_OF)
|
||||
return Relation();
|
||||
|
||||
switch (aType) {
|
||||
case nsIAccessibleRelation::RELATION_NODE_CHILD_OF: {
|
||||
int32_t parentIndex = -1;
|
||||
if (!NS_SUCCEEDED(mTreeView->GetParentIndex(mRow, &parentIndex)))
|
||||
return Relation();
|
||||
|
@ -812,6 +824,23 @@ XULTreeItemAccessibleBase::RelationByType(uint32_t aType)
|
|||
return Relation(treeAcc->GetTreeItemAccessible(parentIndex));
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_NODE_PARENT_OF: {
|
||||
bool isTrue = false;
|
||||
if (NS_FAILED(mTreeView->IsContainerEmpty(mRow, &isTrue)) || isTrue)
|
||||
return Relation();
|
||||
|
||||
if (NS_FAILED(mTreeView->IsContainerOpen(mRow, &isTrue)) || !isTrue)
|
||||
return Relation();
|
||||
|
||||
XULTreeAccessible* tree = mParent->AsXULTree();
|
||||
return Relation(new XULTreeItemIterator(tree, mTreeView, mRow));
|
||||
}
|
||||
|
||||
default:
|
||||
return Relation();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
XULTreeItemAccessibleBase::ActionCount()
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
|
||||
virtual Accessible* GetChildAt(uint32_t aIndex);
|
||||
virtual uint32_t ChildCount() const;
|
||||
virtual Relation RelationByType(uint32_t aType);
|
||||
|
||||
// SelectAccessible
|
||||
virtual already_AddRefed<nsIArray> SelectedItems();
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var actionsArray = [
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
src="../actions.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(13);
|
||||
} else if (navigator.platform.indexOf("Linux") == 0) {
|
||||
SimpleTest.expectAssertions(18);
|
||||
} else if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 14);
|
||||
}
|
||||
|
||||
function getAnchorTargetDocumentAcc()
|
||||
{
|
||||
var thisTabDocAcc = getTabDocAccessible();
|
||||
|
|
|
@ -19,6 +19,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
src="../attributes.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Linux") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// aria
|
||||
|
|
|
@ -610,6 +610,17 @@ function getTextFromClipboard()
|
|||
*/
|
||||
function prettyName(aIdentifier)
|
||||
{
|
||||
if (aIdentifier instanceof Array) {
|
||||
var msg = "";
|
||||
for (var idx = 0; idx < aIdentifier.length; idx++) {
|
||||
if (msg != "")
|
||||
msg += ", ";
|
||||
|
||||
msg += prettyName(aIdentifier[idx]);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (aIdentifier instanceof nsIAccessible) {
|
||||
var acc = getAccessible(aIdentifier);
|
||||
var msg = "[" + getNodePrettyName(acc.DOMNode);
|
||||
|
|
|
@ -19,6 +19,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452161
|
|||
src="editabletext.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 3);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(3);
|
||||
}
|
||||
|
||||
function addTestEditable(aID, aTestRun, aTrailChar)
|
||||
{
|
||||
var et = new editableTextTest(aID);
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
if (navigator.platform.indexOf("Mac") != 0) {
|
||||
SimpleTest.expectAssertions(2);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Hacky stuffs
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
if (navigator.platform.indexOf("Linux") == 0) {
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
|
|
|
@ -21,6 +21,14 @@
|
|||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(1, 2);
|
||||
} else if (navigator.platform.indexOf("Linux") == 0) {
|
||||
SimpleTest.expectAssertions(1);
|
||||
} else if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
//var gA11yEventDumpID = "eventdump";
|
||||
|
|
|
@ -14,6 +14,7 @@ const RELATION_LABEL_FOR = nsIAccessibleRelation.RELATION_LABEL_FOR;
|
|||
const RELATION_LABELLED_BY = nsIAccessibleRelation.RELATION_LABELLED_BY;
|
||||
const RELATION_MEMBER_OF = nsIAccessibleRelation.RELATION_MEMBER_OF;
|
||||
const RELATION_NODE_CHILD_OF = nsIAccessibleRelation.RELATION_NODE_CHILD_OF;
|
||||
const RELATION_NODE_PARENT_OF = nsIAccessibleRelation.RELATION_NODE_PARENT_OF;
|
||||
const RELATION_PARENT_WINDOW_OF = nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF;
|
||||
const RELATION_POPUP_FOR = nsIAccessibleRelation.RELATION_POPUP_FOR;
|
||||
const RELATION_SUBWINDOW_OF = nsIAccessibleRelation.RELATION_SUBWINDOW_OF;
|
||||
|
|
|
@ -71,7 +71,8 @@
|
|||
testRelation("treeitem3", RELATION_NODE_CHILD_OF, "tree");
|
||||
testRelation("treeitem4", RELATION_NODE_CHILD_OF, "tree");
|
||||
testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4");
|
||||
testRelation("treeitem6", RELATION_NODE_CHILD_OF, "treeitem5");
|
||||
testRelation("treeitem6", RELATION_NODE_CHILD_OF, "tree");
|
||||
testRelation("treeitem7", RELATION_NODE_CHILD_OF, "treeitem6");
|
||||
|
||||
// 'node child of' relation for row role of treegrid
|
||||
testRelation("treegridrow1", RELATION_NODE_CHILD_OF, "treegrid");
|
||||
|
@ -86,6 +87,19 @@
|
|||
var iframeDocAcc = getAccessible(iframeDoc);
|
||||
testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
|
||||
|
||||
// 'node parent of' relation on ARIA tree and treegrid.
|
||||
testRelation("tree", RELATION_NODE_PARENT_OF,
|
||||
["treeitem1", "treeitem2", // aria-owns
|
||||
"treeitem3", "treeitem4", "treeitem6"]); // children
|
||||
testRelation("treeitem4", RELATION_NODE_PARENT_OF,
|
||||
"treeitem5"); // aria-level
|
||||
testRelation("treeitem6", RELATION_NODE_PARENT_OF,
|
||||
"treeitem7"); // // group role
|
||||
|
||||
testRelation("treegridrow2", RELATION_NODE_PARENT_OF, "treegridrow3");
|
||||
testRelation("treegrid", RELATION_NODE_PARENT_OF,
|
||||
["treegridrow1", "treegridrow2"]);
|
||||
|
||||
// aria-controls
|
||||
getAccessible("tab");
|
||||
todo(false,
|
||||
|
@ -141,22 +155,27 @@
|
|||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=475298"
|
||||
title="mochitests for accessible relations">
|
||||
Mozilla Bug 475298
|
||||
Bug 475298
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=527461"
|
||||
title="Implement RELATION_NODE_PARENT_OF">
|
||||
Bug 527461
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=558036"
|
||||
title="make HTML <output> accessible">
|
||||
Mozilla Bug 558036
|
||||
Bug 558036
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=682790"
|
||||
title="Ignore implicit label association when it's associated explicitly">
|
||||
Mozilla Bug 682790
|
||||
Bug 682790
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=687393"
|
||||
title="HTML select options gets relation from containing label">
|
||||
Mozilla Bug 687393
|
||||
Bug 687393
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
@ -227,8 +246,9 @@
|
|||
<div role="treeitem" id="treeitem3">Blue</div>
|
||||
<div role="treeitem" id="treeitem4" aria-level="1">Green</div>
|
||||
<div role="treeitem" id="treeitem5" aria-level="2">Light green</div>
|
||||
<div role="treeitem" id="treeitem6" aria-level="1">Green2</div>
|
||||
<div role="group">
|
||||
<div role="treeitem" id="treeitem6">Super light green</div>
|
||||
<div role="treeitem" id="treeitem7">Super light green</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -47,6 +47,11 @@
|
|||
var treeitem6 = treeitem5.nextSibling;
|
||||
testRelation(treeitem6, RELATION_NODE_CHILD_OF, [tree]);
|
||||
|
||||
testRelation(tree, RELATION_NODE_PARENT_OF,
|
||||
[treeitem1, treeitem2, treeitem5, treeitem6]);
|
||||
testRelation(treeitem2, RELATION_NODE_PARENT_OF,
|
||||
[treeitem3, treeitem4]);
|
||||
|
||||
// treeitems and treecells shouldn't pick up relations from tree
|
||||
testRelation(treeitem1, RELATION_LABELLED_BY, null);
|
||||
testRelation(treeitem1.firstChild, RELATION_LABELLED_BY, null);
|
||||
|
@ -64,12 +69,17 @@
|
|||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
Bug 503727
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=527461"
|
||||
title="Implement RELATION_NODE_PARENT_OF">
|
||||
Bug 527461
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=691248"
|
||||
title="XUL tree items shouldn't pick up relations from XUL tree">
|
||||
Mozilla Bug 691248
|
||||
Bug 691248
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
src="../browser.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
|
||||
function hasTabModalPrompts() {
|
||||
try {
|
||||
return SpecialPowers.getBoolPref("prompts.tab_modal.enabled");
|
||||
|
|
|
@ -11,6 +11,11 @@
|
|||
<script type="application/javascript"
|
||||
src="../text.js"></script>
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 23);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(23);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
<script type="application/javascript"
|
||||
src="../text.js"></script>
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 10);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(10);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
<script type="application/javascript"
|
||||
src="../text.js"></script>
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var tree =
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
|
|
|
@ -657,3 +657,5 @@ pref("memory_info_dumper.watch_fifo.directory", "/data/local");
|
|||
pref("dom.disable_input_file", true);
|
||||
|
||||
pref("general.useragent.enable_overrides", true);
|
||||
|
||||
pref("b2g.version", @MOZ_B2G_VERSION@);
|
||||
|
|
|
@ -48,6 +48,7 @@ DirectoryProvider.prototype = {
|
|||
classID: Components.ID("{9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider]),
|
||||
_xpcom_factory: XPCOMUtils.generateSingletonFactory(DirectoryProvider),
|
||||
|
||||
getFile: function dp_getFile(prop, persistent) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
@ -105,6 +106,7 @@ DirectoryProvider.prototype = {
|
|||
if (!Services.volumeService) {
|
||||
return this.createUpdatesDir(LOCAL_DIR, subdir);
|
||||
}
|
||||
|
||||
let activeUpdate = Services.um.activeUpdate;
|
||||
if (gUseSDCard) {
|
||||
if (this.volumeHasFreeSpace(gExtStorage, requiredSpace)) {
|
||||
|
@ -158,7 +160,8 @@ DirectoryProvider.prototype = {
|
|||
// error and let upstream code handle it more gracefully.
|
||||
log("Error: No volume found with " + requiredSpace + " bytes for downloading"+
|
||||
" update " + activeUpdate.name);
|
||||
throw Cr.NS_ERROR_FILE_TOO_BIG;
|
||||
activeUpdate.errorCode = Cr.NS_ERROR_FILE_TOO_BIG;
|
||||
return null;
|
||||
},
|
||||
|
||||
createUpdatesDir: function dp_createUpdatesDir(root, subdir) {
|
||||
|
|
|
@ -25,7 +25,6 @@ const PREF_DOWNLOAD_WATCHDOG_TIMEOUT = "b2g.update.download-watchdog-timeout
|
|||
const PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES = "b2g.update.download-watchdog-max-retries";
|
||||
|
||||
const NETWORK_ERROR_OFFLINE = 111;
|
||||
const FILE_ERROR_TOO_BIG = 112;
|
||||
const HTTP_ERROR_OFFSET = 1000;
|
||||
|
||||
const STATE_DOWNLOADING = 'downloading';
|
||||
|
@ -314,7 +313,8 @@ UpdatePrompt.prototype = {
|
|||
}
|
||||
|
||||
log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
|
||||
if (aUpdate.errorCode == FILE_ERROR_TOO_BIG) {
|
||||
let errorCode = aUpdate.errorCode >>> 0;
|
||||
if (errorCode == Cr.NS_ERROR_FILE_TOO_BIG) {
|
||||
aUpdate.statusText = "file-too-big";
|
||||
}
|
||||
this.showUpdateError(aUpdate);
|
||||
|
|
|
@ -363,8 +363,6 @@
|
|||
@BINPATH@/components/nsSetDefaultBrowser.manifest
|
||||
@BINPATH@/components/nsSetDefaultBrowser.js
|
||||
@BINPATH@/components/BrowserPlaces.manifest
|
||||
@BINPATH@/components/nsPrivateBrowsingService.manifest
|
||||
@BINPATH@/components/nsPrivateBrowsingService.js
|
||||
@BINPATH@/components/toolkitsearch.manifest
|
||||
@BINPATH@/components/nsTryToClose.manifest
|
||||
@BINPATH@/components/nsTryToClose.js
|
||||
|
|
|
@ -88,12 +88,10 @@ var FullScreen = {
|
|||
|
||||
handleEvent: function (event) {
|
||||
switch (event.type) {
|
||||
case "deactivate":
|
||||
// We must call exitDomFullScreen asynchronously, since "deactivate" is
|
||||
// dispatched in the middle of the focus manager's window lowering code,
|
||||
// and the focus manager gets confused if we exit fullscreen mode in the
|
||||
// middle of window lowering. See bug 729872.
|
||||
setTimeout(this.exitDomFullScreen.bind(this), 0);
|
||||
case "activate":
|
||||
if (document.mozFullScreen) {
|
||||
this.showWarning(this.fullscreenDoc);
|
||||
}
|
||||
break;
|
||||
case "transitionend":
|
||||
if (event.propertyName == "opacity")
|
||||
|
@ -138,10 +136,11 @@ var FullScreen = {
|
|||
gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
|
||||
|
||||
// Exit DOM full-screen mode when the browser window loses focus (ALT+TAB, etc).
|
||||
if (!this.useLionFullScreen &&
|
||||
gPrefService.getBoolPref("full-screen-api.exit-on-deactivate")) {
|
||||
window.addEventListener("deactivate", this);
|
||||
// Add listener to detect when the fullscreen window is re-focused.
|
||||
// If a fullscreen window loses focus, we show a warning when the
|
||||
// fullscreen window is refocused.
|
||||
if (!this.useLionFullScreen) {
|
||||
window.addEventListener("activate", this);
|
||||
}
|
||||
|
||||
// Cancel any "hide the toolbar" animation which is in progress, and make
|
||||
|
@ -171,7 +170,8 @@ var FullScreen = {
|
|||
gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
|
||||
if (!this.useLionFullScreen)
|
||||
window.removeEventListener("deactivate", this);
|
||||
window.removeEventListener("activate", this);
|
||||
this.fullscreenDoc = null;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -307,7 +307,6 @@ var FullScreen = {
|
|||
cancelWarning: function(event) {
|
||||
if (!this.warningBox)
|
||||
return;
|
||||
this.fullscreenDoc = null;
|
||||
this.warningBox.removeEventListener("transitionend", this);
|
||||
if (this.warningFadeOutTimeout) {
|
||||
clearTimeout(this.warningFadeOutTimeout);
|
||||
|
|
|
@ -397,6 +397,14 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
|||
opacity: 0.0;
|
||||
}
|
||||
|
||||
/* When the modal fullscreen approval UI is showing, don't allow interaction
|
||||
with the page, but when we're just showing the warning upon entering
|
||||
fullscreen on an already approved page, do allow interaction with the page.
|
||||
*/
|
||||
#full-screen-warning-container:not([obscure-browser]) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#full-screen-warning-message {
|
||||
/* We must specify a max-width, otherwise word-wrap:break-word doesn't
|
||||
work in descendant <description> and <label> elements. Bug 630864. */
|
||||
|
|
|
@ -953,7 +953,7 @@ function startTest() {
|
|||
return;
|
||||
}
|
||||
|
||||
subwindow.allowfullscreen = true;
|
||||
subwindow.allowFullscreen = true;
|
||||
lastElement = null;
|
||||
|
||||
text = subwindow.document.getElementById("test-text");
|
||||
|
|
|
@ -11,8 +11,6 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MODULE = privatebrowsing
|
||||
|
||||
DIRS = src
|
||||
|
||||
TEST_DIRS += test
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = privatebrowsing
|
||||
LIBRARY_NAME = privatebrowsing_s
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
USE_STATIC_LIBS = 1
|
||||
|
||||
EXTRA_COMPONENTS = \
|
||||
nsPrivateBrowsingServiceObsolete.manifest \
|
||||
nsPrivateBrowsingServiceObsolete.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -1,21 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// This dummy object just emulates the old nsIPrivateBrowsingService, and is
|
||||
// non-functional in every aspect. It is only used to make Jetpack work
|
||||
// again.
|
||||
|
||||
function PrivateBrowsingService() {
|
||||
}
|
||||
|
||||
PrivateBrowsingService.prototype = {
|
||||
classID: Components.ID("{ba0e4d3d-7be2-41a0-b723-a7c16b22ebe9}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrivateBrowsingService])
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PrivateBrowsingService]);
|
|
@ -1,15 +0,0 @@
|
|||
# WebappRT doesn't need these instructions, and they don't necessarily work
|
||||
# with it, but it does use a GRE directory that the GRE shares with Firefox,
|
||||
# so in order to prevent the instructions from being processed for WebappRT,
|
||||
# we need to restrict them to the applications that depend on them, i.e.:
|
||||
#
|
||||
# b2g: {3c2e2abc-06d4-11e1-ac3b-374f68613e61}
|
||||
# browser: {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
# mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
|
||||
# mobile/xul: {a23983c0-fd0e-11dc-95ff-0800200c9a66}
|
||||
#
|
||||
# In theory we should do this for all these instructions, but in practice it is
|
||||
# sufficient to do it for the app-startup one, and the file is simpler that way.
|
||||
|
||||
component {ba0e4d3d-7be2-41a0-b723-a7c16b22ebe9} nsPrivateBrowsingServiceObsolete.js
|
||||
contract @mozilla.org/privatebrowsing;1 {ba0e4d3d-7be2-41a0-b723-a7c16b22ebe9}
|
|
@ -349,8 +349,6 @@
|
|||
@BINPATH@/browser/components/DownloadsUI.js
|
||||
@BINPATH@/browser/components/BrowserPlaces.manifest
|
||||
@BINPATH@/components/BrowserPageThumbs.manifest
|
||||
@BINPATH@/browser/components/nsPrivateBrowsingServiceObsolete.manifest
|
||||
@BINPATH@/browser/components/nsPrivateBrowsingServiceObsolete.js
|
||||
@BINPATH@/components/SiteSpecificUserAgent.js
|
||||
@BINPATH@/components/SiteSpecificUserAgent.manifest
|
||||
@BINPATH@/components/toolkitsearch.manifest
|
||||
|
|
|
@ -27,7 +27,6 @@ browser/components/places/Makefile
|
|||
browser/components/places/src/Makefile
|
||||
browser/components/preferences/Makefile
|
||||
browser/components/privatebrowsing/Makefile
|
||||
browser/components/privatebrowsing/src/Makefile
|
||||
browser/components/search/Makefile
|
||||
browser/components/sessionstore/Makefile
|
||||
browser/components/sessionstore/src/Makefile
|
||||
|
|
|
@ -106,7 +106,32 @@
|
|||
<handler event="dblclick" action="this._onDoubleClick();"/>
|
||||
</handlers>
|
||||
|
||||
<implementation>
|
||||
<implementation implements="nsIDOMEventListener">
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
window.addEventListener("MozContextUIExpand", this, true);
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
<destructor>
|
||||
<![CDATA[
|
||||
window.removeEventListener("MozContextUIExpand", this, true);
|
||||
]]>
|
||||
</destructor>
|
||||
|
||||
<method name="handleEvent">
|
||||
<parameter name="event"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
switch (event.type) {
|
||||
case "MozContextUIExpand":
|
||||
this.strip.ensureElementIsVisible(this.selectedTab, false);
|
||||
break;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<field name="strip">document.getAnonymousElementByAttribute(this, "anonid", "tabs-scrollbox");</field>
|
||||
<field name="_selectedTab">null</field>
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ pymake.pth:build/pymake
|
|||
optional:setup.py:python/psutil:build_ext:--inplace
|
||||
optional:psutil.pth:python/psutil
|
||||
which.pth:python/which
|
||||
ply.pth:other-licenses/ply/
|
||||
codegen.pth:python/codegen/
|
||||
mock.pth:python/mock-1.0.0
|
||||
mozilla.pth:build
|
||||
mozilla.pth:config
|
||||
|
|
|
@ -22,6 +22,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=758258
|
|||
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
if (navigator.platform.indexOf("Linux") == 0) {
|
||||
SimpleTest.expectAssertions(2);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/*
|
||||
|
|
17
configure.in
17
configure.in
|
@ -4673,7 +4673,7 @@ then
|
|||
|
||||
if test -z "$QTDIR"; then
|
||||
PKG_CHECK_MODULES(MOZ_QT, QtGui QtNetwork QtCore QtOpenGL)
|
||||
PKG_CHECK_MODULES(MOZ_QT5, QtWidgets QtMultimedia QtPrintSupport,
|
||||
PKG_CHECK_MODULES(MOZ_QT5, Qt5Widgets Qt5Multimedia Qt5PrintSupport,
|
||||
MOZ_ENABLE_QT5=1,
|
||||
MOZ_ENABLE_QT5=)
|
||||
if test "$MOZ_ENABLE_QT5"; then
|
||||
|
@ -4685,25 +4685,28 @@ then
|
|||
AC_CHECK_PROGS(HOST_MOC, $MOC moc, "")
|
||||
AC_CHECK_PROGS(HOST_RCC, $RCC rcc, "")
|
||||
else
|
||||
MOZ_QT_LIBS="-L$QTDIR/lib/ -lQtGui -lQtNetwork -lQtCore -lQtXml -lQtOpenGL"
|
||||
|
||||
MOZ_QT_CFLAGS="-DQT_SHARED"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/Qt"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtGui"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtCore"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtNetwork"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtXml"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtDeclarative"
|
||||
HOST_MOC="$QTDIR/bin/moc"
|
||||
HOST_RCC="$QTDIR/bin/rcc"
|
||||
|
||||
# QtWidgets was introduced only in Qt5
|
||||
if test -d $QTDIR/include/QtWidgets; then
|
||||
echo "Using qt5"
|
||||
MOZ_QT_LIBS="-L$QTDIR/lib/ -lQt5Gui -lQt5Network -lQt5Core -lQt5Xml -lQt5OpenGL"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtGui/5.0.1/QtGui"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtWidgets"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/QtPrintSupport"
|
||||
MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtWidgets -lQtPrintSupport"
|
||||
MOZ_QT_LIBS="$MOZ_QT_LIBS -lQt5Widgets -lQt5PrintSupport"
|
||||
else
|
||||
MOZ_QT_LIBS="-L$QTDIR/lib/ -lQtGui -lQtNetwork -lQtCore -lQtXml -lQtOpenGL"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I$QTDIR/include/Qt"
|
||||
fi
|
||||
HOST_MOC="$QTDIR/bin/moc"
|
||||
HOST_RCC="$QTDIR/bin/rcc"
|
||||
fi
|
||||
if test -z "$HOST_MOC"; then
|
||||
AC_MSG_ERROR([No acceptable moc preprocessor found. Qt SDK is not installed or --with-qt is
|
||||
|
|
|
@ -102,8 +102,8 @@ template<typename> class Sequence;
|
|||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x4e6f7d97, 0x091e, 0x4eda, \
|
||||
{ 0xb7, 0xd6, 0xfe, 0xb0, 0xb8, 0x01, 0x2a, 0x93 } }
|
||||
{ 0x45ce048f, 0x5970, 0x411e, \
|
||||
{ 0xaa, 0x99, 0x12, 0xed, 0x3a, 0x55, 0xc9, 0xc3 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -886,7 +886,7 @@ public:
|
|||
* so that all its fullscreen element stacks are empty; we must continue the
|
||||
* rollback in this parent process' doc tree branch which is fullscreen.
|
||||
* Note that only one branch of the document tree can have its documents in
|
||||
* fullscreen state at one time. We're in inconsistent state if the a
|
||||
* fullscreen state at one time. We're in inconsistent state if a
|
||||
* fullscreen document has a parent and that parent isn't fullscreen. We
|
||||
* preserve this property across process boundaries.
|
||||
*/
|
||||
|
@ -904,6 +904,25 @@ public:
|
|||
*/
|
||||
virtual bool IsFullScreenDoc() = 0;
|
||||
|
||||
/**
|
||||
* Returns true if this document is a fullscreen leaf document, i.e. it
|
||||
* is in fullscreen mode and has no fullscreen children.
|
||||
*/
|
||||
virtual bool IsFullscreenLeaf() = 0;
|
||||
|
||||
/**
|
||||
* Returns the document which is at the root of this document's branch
|
||||
* in the in-process document tree. Returns nullptr if the document isn't
|
||||
* fullscreen.
|
||||
*/
|
||||
virtual nsIDocument* GetFullscreenRoot() = 0;
|
||||
|
||||
/**
|
||||
* Sets the fullscreen root to aRoot. This stores a weak reference to aRoot
|
||||
* in this document.
|
||||
*/
|
||||
virtual void SetFullscreenRoot(nsIDocument* aRoot) = 0;
|
||||
|
||||
/**
|
||||
* Sets whether this document is approved for fullscreen mode.
|
||||
* Documents aren't approved for fullscreen until chrome has sent a
|
||||
|
@ -913,12 +932,14 @@ public:
|
|||
virtual void SetApprovedForFullscreen(bool aIsApproved) = 0;
|
||||
|
||||
/**
|
||||
* Exits all documents from DOM full-screen mode, and moves the top-level
|
||||
* browser window out of full-screen mode. If aRunAsync is true, this runs
|
||||
* asynchronously.
|
||||
* Exits documents out of DOM fullscreen mode. If aDocument is non null,
|
||||
* only its ancestors and descendants exit fullscreen, i.e. if there are
|
||||
* multiple windows/doctrees in fullscreen mode, only the one containing
|
||||
* aDocument exits fullscreen mode. If aDocument is null, all windows
|
||||
* and documents exit fullscreen. If aRunAsync is true, fullscreen is
|
||||
* executed asynchronously.
|
||||
*/
|
||||
static void ExitFullScreen(bool aRunAsync);
|
||||
|
||||
static void ExitFullscreen(nsIDocument* aDocument, bool aRunAsync);
|
||||
|
||||
virtual void RequestPointerLock(Element* aElement) = 0;
|
||||
|
||||
|
|
|
@ -1298,7 +1298,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"RemovedFullScreenElement");
|
||||
// Fully exit full-screen.
|
||||
nsIDocument::ExitFullScreen(false);
|
||||
nsIDocument::ExitFullscreen(OwnerDoc(), /* async */ false);
|
||||
}
|
||||
if (HasPointerLock()) {
|
||||
nsIDocument::UnlockPointer();
|
||||
|
|
|
@ -195,13 +195,6 @@ using namespace mozilla::dom;
|
|||
|
||||
typedef nsTArray<Link*> LinkArray;
|
||||
|
||||
// Reference to the document which requested DOM full-screen mode.
|
||||
nsWeakPtr nsDocument::sFullScreenDoc = nullptr;
|
||||
|
||||
// Reference to the root document of the branch containing the document
|
||||
// which requested DOM full-screen mode.
|
||||
nsWeakPtr nsDocument::sFullScreenRootDoc = nullptr;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gDocumentLeakPRLog;
|
||||
static PRLogModuleInfo* gCspPRLog;
|
||||
|
@ -7782,18 +7775,26 @@ nsDocument::OnPageHide(bool aPersisted,
|
|||
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
|
||||
|
||||
if (IsFullScreenDoc()) {
|
||||
// A full-screen doc has been hidden. We need to ensure we exit
|
||||
// full-screen, i.e. remove full-screen state from all full-screen
|
||||
// documents, and exit the top-level window from full-screen mode.
|
||||
// By the time a doc is hidden, it has been removed from the doc tree,
|
||||
// so nsIDocument::ExitFullScreen() won't be able to traverse to this
|
||||
// document to reset its state, so reset full-screen state in *this*
|
||||
// document. OnPageHide() is called in every hidden document, so doing
|
||||
// this ensures all hidden documents have their full-screen state reset.
|
||||
CleanupFullscreenState();
|
||||
// If this document was fullscreen, we should exit fullscreen in this
|
||||
// doctree branch. This ensures that if the user navigates while in
|
||||
// fullscreen mode we don't leave its still visible ancestor documents
|
||||
// in fullscreen mode. So exit fullscreen in the document's fullscreen
|
||||
// root document, as this will exit fullscreen in all the root's
|
||||
// descendant documents. Note that documents are removed from the
|
||||
// doctree by the time OnPageHide() is called, so we must store a
|
||||
// reference to the root (in nsDocument::mFullscreenRoot) since we can't
|
||||
// just traverse the doctree to get the root.
|
||||
nsIDocument::ExitFullscreen(this, /* async */ false);
|
||||
|
||||
// Next reset full-screen state in all visible documents in the doctree.
|
||||
nsIDocument::ExitFullScreen(false);
|
||||
// Since the document is removed from the doctree before OnPageHide() is
|
||||
// called, ExitFullscreen() can't traverse from the root down to *this*
|
||||
// document, so we must manually call CleanupFullscreenState() below too.
|
||||
// Note that CleanupFullscreenState() clears nsDocument::mFullscreenRoot,
|
||||
// so we *must* call it after ExitFullscreen(), not before.
|
||||
// OnPageHide() is called in every hidden (i.e. descendant) document,
|
||||
// so calling CleanupFullscreenState() here will ensure all hidden
|
||||
// documents have their fullscreen state reset.
|
||||
CleanupFullscreenState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8966,136 +8967,6 @@ nsIDocument::CreateTouchList(const Sequence<nsRefPtr<nsIDOMTouch> >& aTouches)
|
|||
return retval.forget();
|
||||
}
|
||||
|
||||
static void
|
||||
DispatchFullScreenChange(nsIDocument* aTarget)
|
||||
{
|
||||
nsRefPtr<nsAsyncDOMEvent> e =
|
||||
new nsAsyncDOMEvent(aTarget,
|
||||
NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::MozCancelFullScreen()
|
||||
{
|
||||
nsIDocument::MozCancelFullScreen();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::MozCancelFullScreen()
|
||||
{
|
||||
// Only perform fullscreen changes if we're running in a webapp
|
||||
// same-origin to the web app, or if we're in a user generated event
|
||||
// handler.
|
||||
if (NodePrincipal()->GetAppStatus() >= nsIPrincipal::APP_STATUS_INSTALLED ||
|
||||
nsContentUtils::IsRequestFullScreenAllowed()) {
|
||||
RestorePreviousFullScreenState();
|
||||
}
|
||||
}
|
||||
|
||||
// Runnable to set window full-screen mode. Used as a script runner
|
||||
// to ensure we only call nsGlobalWindow::SetFullScreen() when it's safe to
|
||||
// run script. nsGlobalWindow::SetFullScreen() dispatches a synchronous event
|
||||
// (handled in chome code) which is unsafe to run if this is called in
|
||||
// Element::UnbindFromTree().
|
||||
class nsSetWindowFullScreen : public nsRunnable {
|
||||
public:
|
||||
nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue)
|
||||
: mDoc(aDoc), mValue(aValue) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mDoc->GetWindow()) {
|
||||
mDoc->GetWindow()->SetFullScreenInternal(mValue, false);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
bool mValue;
|
||||
};
|
||||
|
||||
static void
|
||||
SetWindowFullScreen(nsIDocument* aDoc, bool aValue)
|
||||
{
|
||||
nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue));
|
||||
}
|
||||
|
||||
class nsCallExitFullScreen : public nsRunnable {
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsDocument::ExitFullScreen();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsIDocument::ExitFullScreen(bool aRunAsync)
|
||||
{
|
||||
if (aRunAsync) {
|
||||
NS_DispatchToCurrentThread(new nsCallExitFullScreen());
|
||||
return;
|
||||
}
|
||||
nsDocument::ExitFullScreen();
|
||||
}
|
||||
|
||||
// Returns true if the document is a direct child of a cross process parent
|
||||
// mozbrowser iframe. This is the case when the document has a null parent,
|
||||
// and its DocShell reports that it is a browser frame.
|
||||
static bool
|
||||
HasCrossProcessParent(nsIDocument* aDocument)
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Content) {
|
||||
return false;
|
||||
}
|
||||
if (aDocument->GetParentDocument() != nullptr) {
|
||||
return false;
|
||||
}
|
||||
nsPIDOMWindow* win = aDocument->GetWindow();
|
||||
if (!win) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
|
||||
if (!docShell) {
|
||||
return false;
|
||||
}
|
||||
return docShell->GetIsBrowserOrApp();
|
||||
}
|
||||
|
||||
static bool
|
||||
ResetFullScreen(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
if (aDocument->IsFullScreenDoc()) {
|
||||
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
|
||||
NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
|
||||
nsTArray<nsIDocument*>* changed = reinterpret_cast<nsTArray<nsIDocument*>*>(aData);
|
||||
changed->AppendElement(aDocument);
|
||||
|
||||
if (HasCrossProcessParent(aDocument)) {
|
||||
// We're at the top of the content-process side doc tree. Ask the parent
|
||||
// process to exit fullscreen.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(aDocument, "ask-parent-to-exit-fullscreen", nullptr);
|
||||
}
|
||||
|
||||
// Dispatch a notification so that if this document has any
|
||||
// cross-process subdocuments, they'll be notified to exit fullscreen.
|
||||
// The BrowserElementParent listens for this event and performs the
|
||||
// cross process notification if it has a remote child process.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(aDocument, "ask-children-to-exit-fullscreen", nullptr);
|
||||
|
||||
aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<nsDOMCaretPosition>
|
||||
nsIDocument::CaretPositionFromPoint(float aX, float aY)
|
||||
{
|
||||
|
@ -9158,34 +9029,351 @@ nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Singleton class to manage the list of fullscreen documents which are the
|
||||
// root of a branch which contains fullscreen documents. We maintain this list
|
||||
// so that we can easily exit all windows from fullscreen when the user
|
||||
// presses the escape key.
|
||||
class FullscreenRoots {
|
||||
public:
|
||||
// Adds a root to the manager. Adding a root multiple times does not result
|
||||
// in duplicate entries for that item, only one.
|
||||
static void Add(nsIDocument* aRoot);
|
||||
|
||||
// Iterates over every root in the root list, and calls aFunction, passing
|
||||
// each root once to aFunction. It is safe to call Add() and Remove() while
|
||||
// iterating over the list (i.e. in aFunction). Documents that are removed
|
||||
// from the manager during traversal are not traversed, and documents that
|
||||
// are added to the manager during traversal are also not traversed.
|
||||
static void ForEach(void(*aFunction)(nsIDocument* aDoc));
|
||||
|
||||
// Removes a specific root from the manager.
|
||||
static void Remove(nsIDocument* aRoot);
|
||||
|
||||
// Returns true if all roots added to the list have been removed.
|
||||
static bool IsEmpty();
|
||||
|
||||
private:
|
||||
|
||||
FullscreenRoots() {
|
||||
MOZ_COUNT_CTOR(FullscreenRoots);
|
||||
}
|
||||
~FullscreenRoots() {
|
||||
MOZ_COUNT_DTOR(FullscreenRoots);
|
||||
}
|
||||
|
||||
enum {
|
||||
NotFound = uint32_t(-1)
|
||||
};
|
||||
// Looks in mRoots for aRoot. Returns the index if found, otherwise NotFound.
|
||||
static uint32_t Find(nsIDocument* aRoot);
|
||||
|
||||
// Returns true if aRoot is in the list of fullscreen roots.
|
||||
static bool Contains(nsIDocument* aRoot);
|
||||
|
||||
// Singleton instance of the FullscreenRoots. This is instantiated when a
|
||||
// root is added, and it is deleted when the last root is removed.
|
||||
static FullscreenRoots* sInstance;
|
||||
|
||||
// List of weak pointers to roots.
|
||||
nsTArray<nsWeakPtr> mRoots;
|
||||
};
|
||||
|
||||
FullscreenRoots* FullscreenRoots::sInstance = nullptr;
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsDocument::ExitFullScreen()
|
||||
FullscreenRoots::ForEach(void(*aFunction)(nsIDocument* aDoc))
|
||||
{
|
||||
// Clear full-screen stacks in all descendant documents.
|
||||
nsCOMPtr<nsIDocument> root(do_QueryReferent(sFullScreenRootDoc));
|
||||
if (!sInstance) {
|
||||
return;
|
||||
}
|
||||
// Create a copy of the roots array, and iterate over the copy. This is so
|
||||
// that if an element is removed from mRoots we don't mess up our iteration.
|
||||
nsTArray<nsWeakPtr> roots(sInstance->mRoots);
|
||||
// Call aFunction on all entries.
|
||||
for (uint32_t i = 0; i < roots.Length(); i++) {
|
||||
nsCOMPtr<nsIDocument> root = do_QueryReferent(roots[i]);
|
||||
// Check that the root isn't in the manager. This is so that new additions
|
||||
// while we were running don't get traversed.
|
||||
if (root && FullscreenRoots::Contains(root)) {
|
||||
aFunction(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
FullscreenRoots::Contains(nsIDocument* aRoot)
|
||||
{
|
||||
return FullscreenRoots::Find(aRoot) != NotFound;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
FullscreenRoots::Add(nsIDocument* aRoot)
|
||||
{
|
||||
if (!FullscreenRoots::Contains(aRoot)) {
|
||||
if (!sInstance) {
|
||||
sInstance = new FullscreenRoots();
|
||||
}
|
||||
sInstance->mRoots.AppendElement(do_GetWeakReference(aRoot));
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
uint32_t
|
||||
FullscreenRoots::Find(nsIDocument* aRoot)
|
||||
{
|
||||
if (!sInstance) {
|
||||
return NotFound;
|
||||
}
|
||||
nsTArray<nsWeakPtr>& roots = sInstance->mRoots;
|
||||
for (uint32_t i = 0; i < roots.Length(); i++) {
|
||||
nsCOMPtr<nsIDocument> otherRoot(do_QueryReferent(roots[i]));
|
||||
if (otherRoot == aRoot) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return NotFound;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
FullscreenRoots::Remove(nsIDocument* aRoot)
|
||||
{
|
||||
uint32_t index = Find(aRoot);
|
||||
NS_ASSERTION(index != NotFound,
|
||||
"Should only try to remove roots which are still added!");
|
||||
if (index == NotFound || !sInstance) {
|
||||
return;
|
||||
}
|
||||
sInstance->mRoots.RemoveElementAt(index);
|
||||
if (sInstance->mRoots.IsEmpty()) {
|
||||
delete sInstance;
|
||||
sInstance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
FullscreenRoots::IsEmpty()
|
||||
{
|
||||
return !sInstance;
|
||||
}
|
||||
|
||||
} // end namespace mozilla.
|
||||
using mozilla::FullscreenRoots;
|
||||
|
||||
nsIDocument*
|
||||
nsDocument::GetFullscreenRoot()
|
||||
{
|
||||
nsCOMPtr<nsIDocument> root = do_QueryReferent(mFullscreenRoot);
|
||||
return root;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetFullscreenRoot(nsIDocument* aRoot)
|
||||
{
|
||||
mFullscreenRoot = do_GetWeakReference(aRoot);
|
||||
}
|
||||
|
||||
static void
|
||||
DispatchFullScreenChange(nsIDocument* aTarget)
|
||||
{
|
||||
nsRefPtr<nsAsyncDOMEvent> e =
|
||||
new nsAsyncDOMEvent(aTarget,
|
||||
NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::MozCancelFullScreen()
|
||||
{
|
||||
nsIDocument::MozCancelFullScreen();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::MozCancelFullScreen()
|
||||
{
|
||||
// Only perform fullscreen changes if we're running in a webapp
|
||||
// same-origin to the web app, or if we're in a user generated event
|
||||
// handler.
|
||||
if (NodePrincipal()->GetAppStatus() >= nsIPrincipal::APP_STATUS_INSTALLED ||
|
||||
nsContentUtils::IsRequestFullScreenAllowed()) {
|
||||
RestorePreviousFullScreenState();
|
||||
}
|
||||
}
|
||||
|
||||
// Runnable to set window full-screen mode. Used as a script runner
|
||||
// to ensure we only call nsGlobalWindow::SetFullScreen() when it's safe to
|
||||
// run script. nsGlobalWindow::SetFullScreen() dispatches a synchronous event
|
||||
// (handled in chome code) which is unsafe to run if this is called in
|
||||
// Element::UnbindFromTree().
|
||||
class nsSetWindowFullScreen : public nsRunnable {
|
||||
public:
|
||||
nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue)
|
||||
: mDoc(aDoc), mValue(aValue) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mDoc->GetWindow()) {
|
||||
mDoc->GetWindow()->SetFullScreenInternal(mValue, false);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
bool mValue;
|
||||
};
|
||||
|
||||
static void
|
||||
SetWindowFullScreen(nsIDocument* aDoc, bool aValue)
|
||||
{
|
||||
// Maintain list of fullscreen root documents.
|
||||
nsCOMPtr<nsIDocument> root = nsContentUtils::GetRootDocument(aDoc);
|
||||
if (aValue) {
|
||||
FullscreenRoots::Add(root);
|
||||
} else {
|
||||
FullscreenRoots::Remove(root);
|
||||
}
|
||||
nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue));
|
||||
}
|
||||
|
||||
class nsCallExitFullscreen : public nsRunnable {
|
||||
public:
|
||||
nsCallExitFullscreen(nsIDocument* aDoc)
|
||||
: mDoc(aDoc) {}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsDocument::ExitFullscreen(mDoc);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
};
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsIDocument::ExitFullscreen(nsIDocument* aDoc, bool aRunAsync)
|
||||
{
|
||||
if (aDoc && !aDoc->IsFullScreenDoc()) {
|
||||
return;
|
||||
}
|
||||
if (aRunAsync) {
|
||||
NS_DispatchToCurrentThread(new nsCallExitFullscreen(aDoc));
|
||||
return;
|
||||
}
|
||||
nsDocument::ExitFullscreen(aDoc);
|
||||
}
|
||||
|
||||
// Returns true if the document is a direct child of a cross process parent
|
||||
// mozbrowser iframe. This is the case when the document has a null parent,
|
||||
// and its DocShell reports that it is a browser frame.
|
||||
static bool
|
||||
HasCrossProcessParent(nsIDocument* aDocument)
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Content) {
|
||||
return false;
|
||||
}
|
||||
if (aDocument->GetParentDocument() != nullptr) {
|
||||
return false;
|
||||
}
|
||||
nsPIDOMWindow* win = aDocument->GetWindow();
|
||||
if (!win) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
|
||||
if (!docShell) {
|
||||
return false;
|
||||
}
|
||||
return docShell->GetIsBrowserOrApp();
|
||||
}
|
||||
|
||||
static bool
|
||||
CountFullscreenSubDocuments(nsIDocument* aDoc, void* aData)
|
||||
{
|
||||
if (aDoc->IsFullScreenDoc()) {
|
||||
uint32_t* count = static_cast<uint32_t*>(aData);
|
||||
(*count)++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
CountFullscreenSubDocuments(nsIDocument* aDoc)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
aDoc->EnumerateSubDocuments(CountFullscreenSubDocuments, &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::IsFullscreenLeaf()
|
||||
{
|
||||
// A fullscreen leaf document is fullscreen, and has no fullscreen
|
||||
// subdocuments.
|
||||
if (!IsFullScreenDoc()) {
|
||||
return false;
|
||||
}
|
||||
return CountFullscreenSubDocuments(this) == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
ResetFullScreen(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
if (aDocument->IsFullScreenDoc()) {
|
||||
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
|
||||
"Should have at most 1 fullscreen subdocument.");
|
||||
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
|
||||
NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
|
||||
nsTArray<nsIDocument*>* changed = reinterpret_cast<nsTArray<nsIDocument*>*>(aData);
|
||||
changed->AppendElement(aDocument);
|
||||
|
||||
if (HasCrossProcessParent(aDocument)) {
|
||||
// We're at the top of the content-process side doc tree. Ask the parent
|
||||
// process to exit fullscreen.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(aDocument, "ask-parent-to-exit-fullscreen", nullptr);
|
||||
}
|
||||
|
||||
// Dispatch a notification so that if this document has any
|
||||
// cross-process subdocuments, they'll be notified to exit fullscreen.
|
||||
// The BrowserElementParent listens for this event and performs the
|
||||
// cross process notification if it has a remote child process.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
os->NotifyObservers(aDocument, "ask-children-to-exit-fullscreen", nullptr);
|
||||
|
||||
aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
|
||||
{
|
||||
MOZ_ASSERT(aMaybeNotARootDoc);
|
||||
nsCOMPtr<nsIDocument> root = aMaybeNotARootDoc->GetFullscreenRoot();
|
||||
NS_ASSERTION(root, "Should have root when in fullscreen!");
|
||||
if (!root) {
|
||||
// Not in full-screen mode.
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(root->IsFullScreenDoc(),
|
||||
"Full-screen root should be a full-screen doc...");
|
||||
"Fullscreen root should be a fullscreen doc...");
|
||||
|
||||
// Stores a list of documents to which we must dispatch "mozfullscreenchange".
|
||||
// We're required by the spec to dispatch the events in leaf-to-root
|
||||
// order when exiting full-screen, but we traverse the doctree in a
|
||||
// order when exiting fullscreen, but we traverse the doctree in a
|
||||
// root-to-leaf order, so we save references to the documents we must
|
||||
// dispatch to so that we dispatch in the specified order.
|
||||
nsAutoTArray<nsIDocument*, 8> changed;
|
||||
|
||||
// We may also need to unlock the pointer, if it's locked.
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (pointerLockedElement) {
|
||||
UnlockPointer();
|
||||
}
|
||||
|
||||
// Walk the tree of full-screen documents, and reset their full-screen state.
|
||||
// Walk the tree of fullscreen documents, and reset their fullscreen state.
|
||||
ResetFullScreen(root, static_cast<void*>(&changed));
|
||||
|
||||
// Dispatch "mozfullscreenchange" events. Note this loop is in reverse
|
||||
|
@ -9195,23 +9383,75 @@ nsDocument::ExitFullScreen()
|
|||
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
|
||||
}
|
||||
|
||||
// Reset global state. Do this before we move the window out of full-screen
|
||||
// mode, as that calls nsGlobalWindow::SetFullScreen() which calls back into
|
||||
// nsIDocument::ExitFullScreen().
|
||||
sFullScreenRootDoc = nullptr;
|
||||
sFullScreenDoc = nullptr;
|
||||
NS_ASSERTION(!root->IsFullScreenDoc(),
|
||||
"Fullscreen root should no longer be a fullscreen doc...");
|
||||
|
||||
// Move the top-level window out of full-screen mode.
|
||||
// Move the top-level window out of fullscreen mode.
|
||||
SetWindowFullScreen(root, false);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsDocument::ExitFullscreen(nsIDocument* aDoc)
|
||||
{
|
||||
// Unlock the pointer, if it's locked.
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (pointerLockedElement) {
|
||||
UnlockPointer();
|
||||
}
|
||||
|
||||
if (aDoc) {
|
||||
ExitFullscreenInDocTree(aDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear fullscreen stacks in all fullscreen roots' descendant documents.
|
||||
FullscreenRoots::ForEach(&ExitFullscreenInDocTree);
|
||||
NS_ASSERTION(FullscreenRoots::IsEmpty(),
|
||||
"Should have exited all fullscreen roots from fullscreen");
|
||||
}
|
||||
|
||||
bool
|
||||
GetFullscreenLeaf(nsIDocument* aDoc, void* aData)
|
||||
{
|
||||
if (aDoc->IsFullscreenLeaf()) {
|
||||
nsIDocument** result = static_cast<nsIDocument**>(aData);
|
||||
*result = aDoc;
|
||||
return false;
|
||||
} else if (aDoc->IsFullScreenDoc()) {
|
||||
aDoc->EnumerateSubDocuments(GetFullscreenLeaf, aData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static nsIDocument*
|
||||
GetFullscreenLeaf(nsIDocument* aDoc)
|
||||
{
|
||||
nsIDocument* leaf = nullptr;
|
||||
GetFullscreenLeaf(aDoc, &leaf);
|
||||
if (leaf) {
|
||||
return leaf;
|
||||
}
|
||||
// Otherwise we could be either in a non-fullscreen doc tree, or we're
|
||||
// below the fullscreen doc. Start the search from the root.
|
||||
nsIDocument* root = nsContentUtils::GetRootDocument(aDoc);
|
||||
// Check that the root is actually fullscreen so we don't waste time walking
|
||||
// around its descendants.
|
||||
if (!root->IsFullScreenDoc()) {
|
||||
return nullptr;
|
||||
}
|
||||
GetFullscreenLeaf(root, &leaf);
|
||||
return leaf;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RestorePreviousFullScreenState()
|
||||
{
|
||||
NS_ASSERTION(!IsFullScreenDoc() || sFullScreenDoc != nullptr,
|
||||
"Should have a full-screen doc when full-screen!");
|
||||
NS_ASSERTION(!IsFullScreenDoc() || !FullscreenRoots::IsEmpty(),
|
||||
"Should have at least 1 fullscreen root when fullscreen!");
|
||||
|
||||
if (!IsFullScreenDoc() || !GetWindow() || !sFullScreenDoc) {
|
||||
if (!IsFullScreenDoc() || !GetWindow() || FullscreenRoots::IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -9222,7 +9462,7 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
UnlockPointer();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
|
||||
nsCOMPtr<nsIDocument> fullScreenDoc = GetFullscreenLeaf(this);
|
||||
|
||||
// The fullscreen document may contain a <iframe mozbrowser> element which
|
||||
// has a cross process child. So send a notification so that its browser
|
||||
|
@ -9289,18 +9529,15 @@ nsDocument::RestorePreviousFullScreenState()
|
|||
os->NotifyObservers(root, "fullscreen-origin-change", origin.get());
|
||||
}
|
||||
|
||||
sFullScreenDoc = do_GetWeakReference(doc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (doc == nullptr) {
|
||||
// We moved all documents out of full-screen mode, reset global full-screen
|
||||
// state and move the top-level window out of full-screen mode.
|
||||
DebugOnly< nsCOMPtr<nsIDocument> > root(do_QueryReferent(sFullScreenRootDoc));
|
||||
NS_ASSERTION(!root->IsFullScreenDoc(), "Should have cleared all docs' stacks");
|
||||
sFullScreenDoc = nullptr;
|
||||
sFullScreenRootDoc = nullptr;
|
||||
// We moved all documents in this doctree out of fullscreen mode,
|
||||
// move the top-level window out of fullscreen mode.
|
||||
NS_ASSERTION(!nsContentUtils::GetRootDocument(this)->IsFullScreenDoc(),
|
||||
"Should have cleared all docs' stacks");
|
||||
SetWindowFullScreen(this, false);
|
||||
}
|
||||
}
|
||||
|
@ -9369,24 +9606,33 @@ LogFullScreenDenied(bool aLogFailure, const char* aMessage, nsIDocument* aDoc)
|
|||
nsresult
|
||||
nsDocument::AddFullscreenApprovedObserver()
|
||||
{
|
||||
NS_ASSERTION(!mHasFullscreenApprovedObserver, "Don't add observer twice.");
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->AddObserver(this, "fullscreen-approved", true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
mHasFullscreenApprovedObserver = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::RemoveFullscreenApprovedObserver()
|
||||
{
|
||||
if (!mHasFullscreenApprovedObserver) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->RemoveObserver(this, "fullscreen-approved");
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
mHasFullscreenApprovedObserver = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -9406,6 +9652,7 @@ nsDocument::CleanupFullscreenState()
|
|||
}
|
||||
SetApprovedForFullscreen(false);
|
||||
RemoveFullscreenApprovedObserver();
|
||||
mFullscreenRoot = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -9584,7 +9831,7 @@ nsDocument::RequestFullScreen(Element* aElement,
|
|||
if (GetFullScreenElement() &&
|
||||
!nsContentUtils::ContentIsDescendantOf(aElement, GetFullScreenElement())) {
|
||||
// If this document is full-screen, only grant full-screen requests from
|
||||
// a descendent of the current full-screen element.
|
||||
// a descendant of the current full-screen element.
|
||||
LogFullScreenDenied(true, "FullScreenDeniedNotDescendant", this);
|
||||
return;
|
||||
}
|
||||
|
@ -9608,6 +9855,10 @@ nsDocument::RequestFullScreen(Element* aElement,
|
|||
}
|
||||
}
|
||||
|
||||
// Stash a reference to any existing fullscreen doc, we'll use this later
|
||||
// to detect if the origin which is fullscreen has changed.
|
||||
nsCOMPtr<nsIDocument> previousFullscreenDoc = GetFullscreenLeaf(this);
|
||||
|
||||
AddFullscreenApprovedObserver();
|
||||
|
||||
// Stores a list of documents which we must dispatch "mozfullscreenchange"
|
||||
|
@ -9620,11 +9871,9 @@ nsDocument::RequestFullScreen(Element* aElement,
|
|||
// Remember the root document, so that if a full-screen document is hidden
|
||||
// we can reset full-screen state in the remaining visible full-screen documents.
|
||||
nsIDocument* fullScreenRootDoc = nsContentUtils::GetRootDocument(this);
|
||||
sFullScreenRootDoc = do_GetWeakReference(fullScreenRootDoc);
|
||||
|
||||
// If a document is already in fullscreen, then unlock the mouse pointer
|
||||
if (fullScreenRootDoc->IsFullScreenDoc()) {
|
||||
// A document is already in fullscreen, unlock the mouse pointer
|
||||
// before setting a new document to fullscreen
|
||||
if (sFullScreenDoc) {
|
||||
UnlockPointer();
|
||||
}
|
||||
|
||||
|
@ -9650,6 +9899,9 @@ nsDocument::RequestFullScreen(Element* aElement,
|
|||
// visible there. Stop when we reach the root document.
|
||||
nsIDocument* child = this;
|
||||
while (true) {
|
||||
child->SetFullscreenRoot(fullScreenRootDoc);
|
||||
NS_ASSERTION(child->GetFullscreenRoot() == fullScreenRootDoc,
|
||||
"Fullscreen root should be set!");
|
||||
nsIDocument* parent = child->GetParentDocument();
|
||||
if (!parent) {
|
||||
break;
|
||||
|
@ -9689,7 +9941,6 @@ nsDocument::RequestFullScreen(Element* aElement,
|
|||
// If this document, or a document with the same principal has not
|
||||
// already been approved for fullscreen this fullscreen-session, dispatch
|
||||
// an event so that chrome knows to pop up a warning/approval UI.
|
||||
nsCOMPtr<nsIDocument> previousFullscreenDoc(do_QueryReferent(sFullScreenDoc));
|
||||
// Note previousFullscreenDoc=nullptr upon first entry, so we always
|
||||
// take this path on the first time we enter fullscreen in a fullscreen
|
||||
// session.
|
||||
|
@ -9703,10 +9954,6 @@ nsDocument::RequestFullScreen(Element* aElement,
|
|||
e->PostDOMEvent();
|
||||
}
|
||||
|
||||
// Remember this is the requesting full-screen document.
|
||||
sFullScreenDoc = do_GetWeakReference(static_cast<nsIDocument*>(this));
|
||||
NS_ASSERTION(sFullScreenDoc, "nsDocument should support weak ref!");
|
||||
|
||||
#ifdef DEBUG
|
||||
// Note assertions must run before SetWindowFullScreen() as that does
|
||||
// synchronous event dispatch which can run script which exits full-screen!
|
||||
|
@ -9802,24 +10049,12 @@ nsDocument::MozFullScreenEnabled()
|
|||
return IsFullScreenEnabled(nsContentUtils::IsCallerChrome(), false);
|
||||
}
|
||||
|
||||
static bool
|
||||
HasFullScreenSubDocument(nsIDocument* aDoc, void* aData)
|
||||
{
|
||||
if (aDoc->IsFullScreenDoc()) {
|
||||
// This subdocument is full-screen. Set result and return false to
|
||||
// stop iteration.
|
||||
*static_cast<bool*>(aData) = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
HasFullScreenSubDocument(nsIDocument* aDoc)
|
||||
{
|
||||
bool result = false;
|
||||
aDoc->EnumerateSubDocuments(&HasFullScreenSubDocument, static_cast<void*>(&result));
|
||||
return result;
|
||||
uint32_t count = CountFullscreenSubDocuments(aDoc);
|
||||
NS_ASSERTION(count <= 1, "Fullscreen docs should have at most 1 fullscreen child!");
|
||||
return count >= 1;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -943,14 +943,17 @@ public:
|
|||
virtual Element* GetFullScreenElement();
|
||||
virtual void AsyncRequestFullScreen(Element* aElement);
|
||||
virtual void RestorePreviousFullScreenState();
|
||||
virtual bool IsFullscreenLeaf();
|
||||
virtual bool IsFullScreenDoc();
|
||||
virtual void SetApprovedForFullscreen(bool aIsApproved);
|
||||
virtual nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
|
||||
const nsAString& aNewOrigin);
|
||||
|
||||
virtual nsresult RemoteFrameFullscreenReverted();
|
||||
virtual nsIDocument* GetFullscreenRoot();
|
||||
virtual void SetFullscreenRoot(nsIDocument* aRoot);
|
||||
|
||||
static void ExitFullScreen();
|
||||
static void ExitFullscreen(nsIDocument* aDoc);
|
||||
|
||||
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
|
||||
// to move this document into full-screen mode if allowed. aWasCallerChrome
|
||||
|
@ -1163,17 +1166,6 @@ protected:
|
|||
// is a weak reference to avoid leaks due to circular references.
|
||||
nsWeakPtr mScopeObject;
|
||||
|
||||
// The document which requested (and was granted) full-screen. All ancestors
|
||||
// of this document will also be full-screen.
|
||||
static nsWeakPtr sFullScreenDoc;
|
||||
|
||||
// The root document of the doctree containing the document which requested
|
||||
// full-screen. This root document will also be in full-screen state, as will
|
||||
// all the descendents down to the document which requested full-screen. This
|
||||
// reference allows us to reset full-screen state on all documents when a
|
||||
// document is hidden/navigation occurs.
|
||||
static nsWeakPtr sFullScreenRootDoc;
|
||||
|
||||
// Weak reference to the document which owned the pending pointer lock
|
||||
// element, at the time it requested pointer lock.
|
||||
static nsWeakPtr sPendingPointerLockDoc;
|
||||
|
@ -1188,6 +1180,10 @@ protected:
|
|||
// pop one off this stack, restoring the previous full-screen state
|
||||
nsTArray<nsWeakPtr> mFullScreenStack;
|
||||
|
||||
// The root of the doc tree in which this document is in. This is only
|
||||
// non-null when this document is in fullscreen mode.
|
||||
nsWeakPtr mFullscreenRoot;
|
||||
|
||||
nsRefPtr<nsEventListenerManager> mListenerManager;
|
||||
nsCOMPtr<nsIDOMStyleSheetList> mDOMStyleSheets;
|
||||
nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
|
||||
|
@ -1257,6 +1253,11 @@ protected:
|
|||
// permissions in the permission manager) have been approved for fullscreen.
|
||||
bool mIsApprovedForFullscreen:1;
|
||||
|
||||
// Whether this document has a fullscreen approved observer. Only documents
|
||||
// which request fullscreen and which don't have a pre-existing approval for
|
||||
// fullscreen will have an observer.
|
||||
bool mHasFullscreenApprovedObserver:1;
|
||||
|
||||
uint8_t mXMLDeclarationBits;
|
||||
|
||||
nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;
|
||||
|
|
|
@ -22,6 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=527896
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
var docWrittenSrcExecuted = false;
|
||||
var scriptInsertedSrcExecuted = false;
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
<iframe style="width:200px;height:200px;" id='cspframe'></iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
// This is used to watch requests go out so we can see if the report is
|
||||
// sent correctly
|
||||
function examiner() {
|
||||
|
|
|
@ -16,6 +16,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=638112
|
|||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 638112 **/
|
||||
|
||||
function run_test() {
|
||||
|
|
|
@ -18,6 +18,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=641821
|
|||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") != 0) {
|
||||
// for non-Windows
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
|
||||
/** Test for Bug 641821 **/
|
||||
|
||||
var div = document.createElement("div");
|
||||
|
|
|
@ -17,6 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=457672
|
|||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 457672 **/
|
||||
|
||||
var windowBlurCount = 0;
|
||||
|
|
|
@ -56,7 +56,7 @@ NS_IMPL_STRING_ATTR(HTMLIFrameElement, Name, name)
|
|||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Scrolling, scrolling)
|
||||
NS_IMPL_URI_ATTR(HTMLIFrameElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Width, width)
|
||||
NS_IMPL_BOOL_ATTR(HTMLIFrameElement, Allowfullscreen, allowfullscreen)
|
||||
NS_IMPL_BOOL_ATTR(HTMLIFrameElement, AllowFullscreen, allowfullscreen)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Sandbox, sandbox)
|
||||
|
||||
void
|
||||
|
|
|
@ -2359,6 +2359,9 @@ nsresult nsHTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
|
|||
aDecoder->SetAudioChannelType(mAudioChannelType);
|
||||
aDecoder->SetAudioCaptured(mAudioCaptured);
|
||||
aDecoder->SetVolume(mMuted ? 0.0 : mVolume);
|
||||
aDecoder->SetPreservesPitch(mPreservesPitch);
|
||||
aDecoder->SetPlaybackRate(mPlaybackRate);
|
||||
|
||||
for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
|
||||
OutputMediaStream* ms = &mOutputStreams[i];
|
||||
aDecoder->AddOutputStream(ms->mStream->GetStream()->AsProcessedStream(),
|
||||
|
@ -3581,7 +3584,9 @@ NS_IMETHODIMP nsHTMLMediaElement::GetMozPreservesPitch(bool* aPreservesPitch)
|
|||
NS_IMETHODIMP nsHTMLMediaElement::SetMozPreservesPitch(bool aPreservesPitch)
|
||||
{
|
||||
mPreservesPitch = aPreservesPitch;
|
||||
mDecoder->SetPreservesPitch(aPreservesPitch);
|
||||
if (mDecoder) {
|
||||
mDecoder->SetPreservesPitch(mPreservesPitch);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,6 +255,8 @@ MOCHITEST_FILES = \
|
|||
file_fullscreen-esc-exit-inner.html \
|
||||
file_fullscreen-rollback.html \
|
||||
file_fullscreen-svg-element.html \
|
||||
file_fullscreen-multiple.html \
|
||||
file_fullscreen-multiple-inner.html \
|
||||
test_li_attributes_reflection.html \
|
||||
test_link_attributes_reflection.html \
|
||||
test_ol_attributes_reflection.html \
|
||||
|
|
|
@ -78,7 +78,7 @@ function exit1(event) {
|
|||
is(event.target, document, "10. Event target should be full-screen document #2");
|
||||
is(document.mozFullScreenElement, null, "11. Full-screen element should be null.");
|
||||
iframe = document.createElement("iframe");
|
||||
iframe.allowfullscreen = true;
|
||||
iframe.allowFullscreen = true;
|
||||
addFullscreenChangeContinuation("enter", enter2);
|
||||
document.body.appendChild(iframe);
|
||||
iframe.src = iframeContents;
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 724554</title>
|
||||
<script type="application/javascript" src="file_fullscreen-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
|
||||
/** Test for Bug 545812 **/
|
||||
function begin(id) {
|
||||
addFullscreenErrorContinuation(function() {
|
||||
opener.ok(false, "Fullscreen denied " + id);
|
||||
});
|
||||
addFullscreenChangeContinuation("enter",
|
||||
function() {
|
||||
opener.enteredFullscreen(id);
|
||||
});
|
||||
document.body.mozRequestFullScreen();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=724554
|
||||
|
||||
Test that multiple windows can be fullscreen at the same time.
|
||||
|
||||
Open one window, focus it and enter fullscreen, then open another, focus
|
||||
it and enter fullscreen, and check that both are still fullscreen.
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 724554</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="file_fullscreen-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 545812 **/
|
||||
|
||||
function ok(condition, msg) {
|
||||
opener.ok(condition, "[multiple] " + msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
opener.is(a, b, "[multiple] " + msg);
|
||||
}
|
||||
|
||||
var window1, window2;
|
||||
|
||||
function openWindow(id) {
|
||||
var w = window.open("file_fullscreen-multiple-inner.html", "", "width=500,height=500");
|
||||
w.addEventListener("load", function onload() {
|
||||
w.focus();
|
||||
SimpleTest.waitForFocus(function(){w.begin(id)}, w);
|
||||
});
|
||||
return w;
|
||||
}
|
||||
|
||||
function begin() {
|
||||
window1 = openWindow("one");
|
||||
}
|
||||
|
||||
function enteredFullscreen(id) {
|
||||
if (id == "one") {
|
||||
window2 = openWindow("two");
|
||||
} else if (id == "two") {
|
||||
ok(window1.document.mozFullScreenElement &&
|
||||
window2.document.mozFullScreenElement,
|
||||
"Both windows should be fullscreen concurrently");
|
||||
window1.close();
|
||||
window2.close();
|
||||
opener.nextTest();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="full-screen-element"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -21,6 +21,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=657938
|
|||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
|
||||
/** Test for <meter> **/
|
||||
|
||||
function checkFormIDLAttribute(aElement)
|
||||
|
|
|
@ -23,6 +23,8 @@ and
|
|||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for progress element content and layout **/
|
||||
|
||||
function checkFormIDLAttribute(aElement)
|
||||
|
|
|
@ -17,6 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=242709
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 242709 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -17,6 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=277890
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 277890 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -19,6 +19,13 @@ method="POST" enctype="multipart/form-data">
|
|||
</form>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
} else {
|
||||
SimpleTest.expectAssertions(1);
|
||||
}
|
||||
|
||||
var filesToKill = [];
|
||||
singleFileInput = document.getElementById('singleFile');
|
||||
multiFileInput = document.getElementById('multiFile');
|
||||
|
|
|
@ -34,6 +34,7 @@ SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
|
|||
// run in an iframe, which by default will not have the allowfullscreen
|
||||
// attribute set, so full-screen won't work.
|
||||
var gTestWindows = [
|
||||
"file_fullscreen-multiple.html",
|
||||
"file_fullscreen-rollback.html",
|
||||
"file_fullscreen-esc-exit.html",
|
||||
"file_fullscreen-denied.html",
|
||||
|
|
|
@ -12,6 +12,9 @@ Implement HTML5 sandbox attribute for IFRAMEs - general tests
|
|||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs - general tests **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -12,6 +12,9 @@ Implement HTML5 sandbox attribute for IFRAMEs
|
|||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1, 2);
|
||||
|
||||
/** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs **/
|
||||
/** Navigation tests **/
|
||||
|
||||
|
|
|
@ -13,6 +13,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=391777
|
|||
<p id="display"></p>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") != 0) {
|
||||
// not Windows
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
/** Test for Bug 391777 **/
|
||||
var arg = {};
|
||||
arg.testVal = "foo";
|
||||
|
|
|
@ -21,6 +21,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=402680
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
/** Test for Bug 402680 **/
|
||||
|
||||
ok(activeElementIsNull,
|
||||
|
|
|
@ -17,6 +17,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=403868
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
/** Test for Bug 403868 **/
|
||||
function createSpan(id, insertionPoint) {
|
||||
var s = document.createElement("span");
|
||||
|
|
|
@ -17,6 +17,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=446483
|
|||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") != 0) {
|
||||
// not Windows
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
/** Test for Bug 446483 **/
|
||||
|
||||
function gc() {
|
||||
|
|
|
@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=448564
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(3);
|
||||
|
||||
/** Test for Bug 448564 **/
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478251
|
|||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(10);
|
||||
|
||||
/** Test for Bug 478251 **/
|
||||
var doc = $("t").contentDocument;
|
||||
doc.open();
|
||||
|
|
|
@ -18,6 +18,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741266
|
|||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 741266 **/
|
||||
var w = window.open("", "", "width=100,height=100");
|
||||
is(w.innerHeight, 100, "Popup height should be 100 when opened with window.open");
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
</iframe>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 4);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var loc;
|
||||
|
||||
|
|
|
@ -327,6 +327,8 @@ MediaDecoder::MediaDecoder() :
|
|||
mPlaybackPosition(0),
|
||||
mCurrentTime(0.0),
|
||||
mInitialVolume(0.0),
|
||||
mInitialPlaybackRate(1.0),
|
||||
mInitialPreservesPitch(true),
|
||||
mRequestedSeekTime(-1.0),
|
||||
mDuration(-1),
|
||||
mTransportSeekable(true),
|
||||
|
@ -468,6 +470,8 @@ nsresult MediaDecoder::InitializeStateMachine(MediaDecoder* aCloneDonor)
|
|||
mDecoderStateMachine->SetDuration(mDuration);
|
||||
mDecoderStateMachine->SetVolume(mInitialVolume);
|
||||
mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
|
||||
SetPlaybackRate(mInitialPlaybackRate);
|
||||
mDecoderStateMachine->SetPreservesPitch(mInitialPreservesPitch);
|
||||
|
||||
if (mFrameBufferLength > 0) {
|
||||
// The valid mFrameBufferLength value was specified earlier
|
||||
|
@ -1401,6 +1405,8 @@ void MediaDecoder::SetPlaybackRate(double aPlaybackRate)
|
|||
|
||||
if (mDecoderStateMachine) {
|
||||
mDecoderStateMachine->SetPlaybackRate(aPlaybackRate);
|
||||
} else {
|
||||
mInitialPlaybackRate = aPlaybackRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1408,6 +1414,8 @@ void MediaDecoder::SetPreservesPitch(bool aPreservesPitch)
|
|||
{
|
||||
if (mDecoderStateMachine) {
|
||||
mDecoderStateMachine->SetPreservesPitch(aPreservesPitch);
|
||||
} else {
|
||||
mInitialPreservesPitch = aPreservesPitch;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -901,6 +901,11 @@ public:
|
|||
// volume. Readable/Writeable from the main thread.
|
||||
double mInitialVolume;
|
||||
|
||||
// PlaybackRate and pitch preservation status we should start at.
|
||||
// Readable/Writeable from the main thread.
|
||||
double mInitialPlaybackRate;
|
||||
bool mInitialPreservesPitch;
|
||||
|
||||
// Position to seek to when the seek notification is received by the
|
||||
// decode thread. Written by the main thread and read via the
|
||||
// decode thread. Synchronised using mReentrantMonitor. If the
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<script>
|
||||
var a = document.createElementNS("http://www.w3.org/1999/xhtml", "audio");
|
||||
a.mozPreservesPitch = a;
|
||||
</script>
|
||||
|
|
@ -12,3 +12,4 @@ skip-if(Android) load 691096-1.html # Android sound API can't handle playing lar
|
|||
load 752784-1.html
|
||||
skip-if(Android||B2G) HTTP load 795892-1.html # load failed, bug 833371 for B2G
|
||||
skip-if(Android||B2G) load 789075-1.html # load failed, bug 833371 for B2G
|
||||
load 844563.html
|
||||
|
|
|
@ -15,6 +15,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=495300
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Mac") != 0) {
|
||||
// not Mac
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function filename(uri) {
|
||||
|
|
|
@ -15,6 +15,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=686942
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function onloaded(event) {
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
<pre id="test">
|
||||
<script class="testbody" type='application/javascript;version=1.8'>
|
||||
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
let manager = new MediaTestManager;
|
||||
|
||||
function rangeCheck(lhs, rhs, threshold) {
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(120, 400);
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
const NUM_SEEK_TESTS = 13;
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
// Test if the ended event works correctly.
|
||||
|
|
|
@ -45,6 +45,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=378518
|
|||
<!-- test code goes here -->
|
||||
<script type="application/javascript"> <![CDATA[
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
var myBoxClicked = false;
|
||||
var myCheckBoxClicked = false;
|
||||
var myExtendedBoxClicked = false;
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
|
||||
<script>
|
||||
<![CDATA[
|
||||
SimpleTest.expectAssertions(4);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var testid ="listbox element";
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
<script>
|
||||
<![CDATA[
|
||||
SimpleTest.expectAssertions(1, 2);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
copyToProfile('animals.sqlite');
|
||||
|
|
|
@ -28,6 +28,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=303267.xul
|
|||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
|
||||
/** Test for Bug 303267 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=456980
|
|||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
|
|
|
@ -39,6 +39,7 @@ function setCachePref(enabled) {
|
|||
}
|
||||
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
/** Test for Bug 608669 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -27,6 +27,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=769771
|
|||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
if (navigator.platform.indexOf("Win") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
/** Test for Bug 769771 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
iframe { width: 90%; height: 50px; }
|
||||
</style>
|
||||
<script>
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
navigateByLocation(frames[0]);
|
||||
navigateByOpen("child1");
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
iframe { width: 90%; height: 200px; }
|
||||
</style>
|
||||
<script>
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
navigateByLocation(frames[0].frames[0]);
|
||||
navigateByOpen("child1_child0");
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
iframe { width: 90%; height: 200px; }
|
||||
</style>
|
||||
<script>
|
||||
if (navigator.platform.indexOf("Mac") == 0) {
|
||||
SimpleTest.expectAssertions(0, 2);
|
||||
}
|
||||
|
||||
function testTop() {
|
||||
window0 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#top,location", "_blank", "width=10,height=10");
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=580069
|
|||
<iframe id='iframe' src='file_bug580069_1.html'></iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.expectAssertions(1);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var iframe = document.getElementById('iframe');
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче