This commit is contained in:
Phil Ringnalda 2015-03-08 13:32:55 -07:00
Родитель 0386dd7ae3 71741ed376
Коммит c2b01bae2f
163 изменённых файлов: 5109 добавлений и 1761 удалений

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

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Merge day clobber
Bug 1137470 NSS update required a clobber to fully rebuild

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

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "InterfaceInitFuncs.h"
#include "mozilla/a11y/PDocAccessible.h"
#include "Accessible-inl.h"
#include "HyperTextAccessible-inl.h"
#include "nsMai.h"
@ -22,6 +22,65 @@ using namespace mozilla::a11y;
static const char* sAtkTextAttrNames[ATK_TEXT_ATTR_LAST_DEFINED];
void
ConvertTextAttributeToAtkAttribute(const nsACString& aName,
const nsAString& aValue,
AtkAttributeSet** aAttributeSet)
{
// Handle attributes where atk has its own name.
const char* atkName = nullptr;
nsAutoString atkValue;
if (aName.EqualsLiteral("color")) {
// The format of the atk attribute is r,g,b and the gecko one is
// rgb(r,g,b).
atkValue = Substring(aValue, 5, aValue.Length() - 1);
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
} else if (aName.EqualsLiteral("background-color")) {
// The format of the atk attribute is r,g,b and the gecko one is
// rgb(r,g,b).
atkValue = Substring(aValue, 5, aValue.Length() - 1);
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
} else if (aName.EqualsLiteral("font-family")) {
atkValue = aValue;
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
} else if (aName.EqualsLiteral("font-size")) {
// ATK wants the number of pixels without px at the end.
atkValue = StringHead(aValue, aValue.Length() - 2);
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
} else if (aName.EqualsLiteral("font-weight")) {
atkValue = aValue;
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT];
} else if (aName.EqualsLiteral("invalid")) {
atkValue = aValue;
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID];
}
if (atkName) {
AtkAttribute* objAttr =
static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
objAttr->name = g_strdup(atkName);
objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get());
*aAttributeSet = g_slist_prepend(*aAttributeSet, objAttr);
}
}
static AtkAttributeSet*
ConvertToAtkTextAttributeSet(nsTArray<Attribute>& aAttributes)
{
AtkAttributeSet* objAttributeSet = nullptr;
for (size_t i = 0; i < aAttributes.Length(); ++i) {
AtkAttribute* objAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
objAttr->name = g_strdup(aAttributes[i].Name().get());
objAttr->value =
g_strdup(NS_ConvertUTF16toUTF8(aAttributes[i].Value()).get());
objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
ConvertTextAttributeToAtkAttribute(aAttributes[i].Name(),
aAttributes[i].Value(),
&objAttributeSet);
}
return objAttributeSet;
}
static AtkAttributeSet*
ConvertToAtkTextAttributeSet(nsIPersistentProperties* aAttributes)
{
@ -55,40 +114,7 @@ ConvertToAtkTextAttributeSet(nsIPersistentProperties* aAttributes)
objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(value).get());
objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
// Handle attributes where atk has its own name.
const char* atkName = nullptr;
nsAutoString atkValue;
if (name.EqualsLiteral("color")) {
// The format of the atk attribute is r,g,b and the gecko one is
// rgb(r,g,b).
atkValue = Substring(value, 5, value.Length() - 1);
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
} else if (name.EqualsLiteral("background-color")) {
// The format of the atk attribute is r,g,b and the gecko one is
// rgb(r,g,b).
atkValue = Substring(value, 5, value.Length() - 1);
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
} else if (name.EqualsLiteral("font-family")) {
atkValue = value;
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
} else if (name.EqualsLiteral("font-size")) {
// ATK wants the number of pixels without px at the end.
atkValue = StringHead(value, value.Length() - 2);
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
} else if (name.EqualsLiteral("font-weight")) {
atkValue = value;
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT];
} else if (name.EqualsLiteral("invalid")) {
atkValue = value;
atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID];
}
if (atkName) {
objAttr = static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
objAttr->name = g_strdup(atkName);
objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get());
objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
}
ConvertTextAttributeToAtkAttribute(name, value, &objAttributeSet);
}
// libatk-adaptor will free it
@ -183,15 +209,21 @@ static gunichar
getCharacterAtOffsetCB(AtkText* aText, gint aOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return 0;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return 0;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return 0;
// char16_t is unsigned short in Mozilla, gnuichar is guint32 in glib.
return static_cast<gunichar>(text->CharAt(aOffset));
}
// char16_t is unsigned short in Mozilla, gnuichar is guint32 in glib.
return static_cast<gunichar>(text->CharAt(aOffset));
if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
return static_cast<gunichar>(proxy->CharAt(aOffset));
}
return 0;
}
static gchar*
@ -223,14 +255,20 @@ static gint
getCaretOffsetCB(AtkText *aText)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return 0;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return 0;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return 0;
return static_cast<gint>(text->CaretOffset());
}
return static_cast<gint>(text->CaretOffset());
if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
return static_cast<gint>(proxy->CaretOffset());
}
return 0;
}
static AtkAttributeSet*
@ -240,38 +278,58 @@ getRunAttributesCB(AtkText *aText, gint aOffset,
{
*aStartOffset = -1;
*aEndOffset = -1;
int32_t startOffset = 0, endOffset = 0;
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return nullptr;
}
nsCOMPtr<nsIPersistentProperties> attributes =
text->TextAttributes(false, aOffset, &startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
return ConvertToAtkTextAttributeSet(attributes);
}
ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
if (!proxy) {
return nullptr;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
int32_t startOffset = 0, endOffset = 0;
nsCOMPtr<nsIPersistentProperties> attributes =
text->TextAttributes(false, aOffset, &startOffset, &endOffset);
nsAutoTArray<Attribute, 10> attrs;
proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
return ConvertToAtkTextAttributeSet(attributes);
return ConvertToAtkTextAttributeSet(attrs);
}
static AtkAttributeSet*
getDefaultAttributesCB(AtkText *aText)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return nullptr;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
return ConvertToAtkTextAttributeSet(attributes);
}
nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
return ConvertToAtkTextAttributeSet(attributes);
ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
if (!proxy) {
return nullptr;
}
nsAutoTArray<Attribute, 10> attrs;
proxy->DefaultTextAttributes(&attrs);
return ConvertToAtkTextAttributeSet(attrs);
}
static void
@ -280,21 +338,32 @@ getCharacterExtentsCB(AtkText *aText, gint aOffset,
gint *aWidth, gint *aHeight,
AtkCoordType aCoords)
{
if(!aX || !aY || !aWidth || !aHeight) {
return;
}
nsIntRect rect;
uint32_t geckoCoordType;
if (aCoords == ATK_XY_SCREEN) {
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
} else {
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
}
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if(!accWrap || !aX || !aY || !aWidth || !aHeight)
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
rect = text->CharBounds(aOffset, geckoCoordType);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
rect = proxy->CharBounds(aOffset, geckoCoordType);
} else {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
uint32_t geckoCoordType;
if (aCoords == ATK_XY_SCREEN)
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
nsIntRect rect = text->CharBounds(aOffset, geckoCoordType);
*aX = rect.x;
*aY = rect.y;
*aWidth = rect.width;
@ -305,21 +374,32 @@ static void
getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset,
AtkCoordType aCoords, AtkTextRectangle *aRect)
{
if (!aRect) {
return;
}
nsIntRect rect;
uint32_t geckoCoordType;
if (aCoords == ATK_XY_SCREEN) {
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
} else {
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
}
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if(!accWrap || !aRect)
if(accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
rect = proxy->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
} else {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
uint32_t geckoCoordType;
if (aCoords == ATK_XY_SCREEN)
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
nsIntRect rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
aRect->x = rect.x;
aRect->y = rect.y;
aRect->width = rect.width;
@ -349,18 +429,28 @@ getOffsetAtPointCB(AtkText *aText,
AtkCoordType aCoords)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return -1;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return -1;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return -1;
return static_cast<gint>(
text->OffsetAtPoint(aX, aY,
(aCoords == ATK_XY_SCREEN ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
}
return static_cast<gint>(
text->OffsetAtPoint(aX, aY,
(aCoords == ATK_XY_SCREEN ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
return static_cast<gint>(
proxy->OffsetAtPoint(aX, aY,
(aCoords == ATK_XY_SCREEN ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
}
return -1;
}
static gint
@ -455,15 +545,23 @@ static gboolean
setCaretOffsetCB(AtkText *aText, gint aOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset)) {
return FALSE;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset))
return FALSE;
text->SetCaretOffset(aOffset);
return TRUE;
}
text->SetCaretOffset(aOffset);
return TRUE;
if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
if (proxy->SetCaretOffset(aOffset)) {
return TRUE;
}
}
return FALSE;
}
}

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

@ -7,7 +7,7 @@
MARKUPMAP(a,
New_HTMLLink,
0)
roles::LINK)
MARKUPMAP(abbr,
New_HyperText,
@ -19,7 +19,8 @@ MARKUPMAP(acronym,
MARKUPMAP(article,
New_HyperText,
roles::DOCUMENT)
roles::DOCUMENT,
Attr(xmlroles, article))
MARKUPMAP(aside,
New_HyperText,
@ -47,11 +48,12 @@ MARKUPMAP(dt,
MARKUPMAP(figcaption,
New_HTMLFigcaption,
0)
roles::CAPTION)
MARKUPMAP(figure,
New_HTMLFigure,
0)
roles::FIGURE,
Attr(xmlroles, figure))
MARKUPMAP(form,
New_HyperText,
@ -91,11 +93,11 @@ MARKUPMAP(h6,
MARKUPMAP(label,
New_HTMLLabel,
0)
roles::LABEL)
MARKUPMAP(legend,
New_HTMLLegend,
0)
roles::LABEL)
MARKUPMAP(li,
New_HTMLListitem,
@ -107,7 +109,7 @@ MARKUPMAP(nav,
MARKUPMAP(ol,
New_HTMLList,
0)
roles::LIST)
MARKUPMAP(option,
New_HTMLOption,
@ -119,7 +121,8 @@ MARKUPMAP(optgroup,
MARKUPMAP(output,
New_HTMLOutput,
0)
roles::SECTION,
Attr(live, polite))
MARKUPMAP(progress,
New_HTMLProgress,
@ -131,11 +134,14 @@ MARKUPMAP(q,
MARKUPMAP(section,
New_HyperText,
roles::SECTION)
roles::SECTION,
Attr(xmlroles, region))
MARKUPMAP(time,
New_HyperText,
0)
0,
Attr(xmlroles, time),
AttrFromDOM(datetime, datetime))
MARKUPMAP(td,
New_HTMLTableHeaderCellIfScope,
@ -147,4 +153,4 @@ MARKUPMAP(th,
MARKUPMAP(ul,
New_HTMLList,
0)
roles::LIST)

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

@ -220,13 +220,25 @@ New_HTMLTableHeaderCellIfScope(nsIContent* aContent, Accessible* aContext)
////////////////////////////////////////////////////////////////////////////////
// Markup maps array.
#define MARKUPMAP(atom, new_func, r) \
{ &nsGkAtoms::atom, new_func, static_cast<a11y::role>(r) },
#define Attr(name, value) \
{ &nsGkAtoms::name, &nsGkAtoms::value }
#define AttrFromDOM(name, DOMAttrName) \
{ &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName }
#define AttrFromDOMIf(name, DOMAttrName, DOMAttrValue) \
{ &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName, &nsGkAtoms::DOMAttrValue }
#define MARKUPMAP(atom, new_func, r, ... ) \
{ &nsGkAtoms::atom, new_func, static_cast<a11y::role>(r), { __VA_ARGS__ } },
static const MarkupMapInfo sMarkupMapList[] = {
#include "MarkupMap.h"
};
#undef Attr
#undef AttrFromDOM
#undef AttrFromDOMIf
#undef MARKUPMAP
////////////////////////////////////////////////////////////////////////////////
@ -1610,6 +1622,41 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
return newAcc.forget();
}
void
nsAccessibilityService::MarkupAttributes(const nsIContent* aContent,
nsIPersistentProperties* aAttributes) const
{
const mozilla::a11y::MarkupMapInfo* markupMap =
mMarkupMaps.Get(aContent->NodeInfo()->NameAtom());
if (!markupMap)
return;
for (uint32_t i = 0; i < ArrayLength(markupMap->attrs); i++) {
const MarkupAttrInfo* info = markupMap->attrs + i;
if (!info->name)
break;
if (info->DOMAttrName) {
if (info->DOMAttrValue) {
if (aContent->AttrValueIs(kNameSpaceID_None, *info->DOMAttrName,
*info->DOMAttrValue, eCaseMatters)) {
nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->DOMAttrValue);
}
continue;
}
nsAutoString value;
aContent->GetAttr(kNameSpaceID_None, *info->DOMAttrName, value);
if (!value.IsEmpty())
nsAccUtils::SetAccAttr(aAttributes, *info->name, value);
continue;
}
nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->value);
}
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibilityService (DON'T put methods here)

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

@ -17,6 +17,7 @@
#include "nsIObserver.h"
class nsImageFrame;
class nsIPersistentProperties;
class nsPluginFrame;
class nsITreeView;
@ -44,10 +45,19 @@ xpcAccessibleApplication* XPCApplicationAcc();
typedef Accessible* (New_Accessible)(nsIContent* aContent, Accessible* aContext);
struct MarkupAttrInfo {
nsIAtom** name;
nsIAtom** value;
nsIAtom** DOMAttrName;
nsIAtom** DOMAttrValue;
};
struct MarkupMapInfo {
nsIAtom** tag;
New_Accessible* new_func;
a11y::role role;
MarkupAttrInfo attrs[2];
};
} // namespace a11y
@ -182,6 +192,12 @@ public:
return markupMap ? markupMap->role : mozilla::a11y::roles::NOTHING;
}
/**
* Set the object attribute defined by markup for the given element.
*/
void MarkupAttributes(const nsIContent* aContent,
nsIPersistentProperties* aAttributes) const;
private:
// nsAccessibilityService creation is controlled by friend
// NS_GetAccessibilityService, keep constructors private.

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

@ -977,25 +977,8 @@ HyperTextAccessible::NativeAttributes()
}
}
if (!HasOwnContent())
return attributes.forget();
if (mContent->IsHTMLElement(nsGkAtoms::section)) {
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("region"));
} else if (mContent->IsHTMLElement(nsGkAtoms::article)) {
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("article"));
} else if (mContent->IsHTMLElement(nsGkAtoms::time)) {
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("time"));
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::datetime)) {
nsAutoString datetime;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::datetime, datetime);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::datetime, datetime);
}
}
if (HasOwnContent())
GetAccService()->MarkupAttributes(mContent, attributes);
return attributes.forget();
}

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

@ -75,12 +75,6 @@ HTMLLabelAccessible::RelationByType(RelationType aType)
return rel;
}
role
HTMLLabelAccessible::NativeRole()
{
return roles::LABEL;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLOuputAccessible
////////////////////////////////////////////////////////////////////////////////
@ -96,21 +90,3 @@ HTMLOutputAccessible::RelationByType(RelationType aType)
return rel;
}
role
HTMLOutputAccessible::NativeRole()
{
return roles::SECTION;
}
already_AddRefed<nsIPersistentProperties>
HTMLOutputAccessible::NativeAttributes()
{
nsCOMPtr<nsIPersistentProperties> attributes =
AccessibleWrap::NativeAttributes();
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::live,
NS_LITERAL_STRING("polite"));
return attributes.forget();
}

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

@ -60,7 +60,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// Accessible
virtual a11y::role NativeRole() MOZ_OVERRIDE;
virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
protected:
@ -81,8 +80,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// Accessible
virtual a11y::role NativeRole() MOZ_OVERRIDE;
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
protected:

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

@ -89,7 +89,7 @@ HTMLCheckboxAccessible::NativeState()
if (input->Checked())
return state | states::CHECKED;
return state;
}
@ -762,12 +762,6 @@ HTMLLegendAccessible::RelationByType(RelationType aType)
return rel;
}
role
HTMLLegendAccessible::NativeRole()
{
return roles::LABEL;
}
////////////////////////////////////////////////////////////////////////////////
// HTMLFigureAccessible
////////////////////////////////////////////////////////////////////////////////
@ -778,24 +772,6 @@ HTMLFigureAccessible::
{
}
already_AddRefed<nsIPersistentProperties>
HTMLFigureAccessible::NativeAttributes()
{
nsCOMPtr<nsIPersistentProperties> attributes =
HyperTextAccessibleWrap::NativeAttributes();
// Expose figure xml-role.
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("figure"));
return attributes.forget();
}
role
HTMLFigureAccessible::NativeRole()
{
return roles::FIGURE;
}
ENameValueFlag
HTMLFigureAccessible::NativeName(nsString& aName)
{
@ -844,12 +820,6 @@ HTMLFigcaptionAccessible::
{
}
role
HTMLFigcaptionAccessible::NativeRole()
{
return roles::CAPTION;
}
Relation
HTMLFigcaptionAccessible::RelationByType(RelationType aType)
{

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

@ -243,7 +243,6 @@ public:
HTMLLegendAccessible(nsIContent* aContent, DocAccessible* aDoc);
// Accessible
virtual mozilla::a11y::role NativeRole() MOZ_OVERRIDE;
virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
};
@ -256,8 +255,6 @@ public:
HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc);
// Accessible
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual mozilla::a11y::role NativeRole() MOZ_OVERRIDE;
virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
protected:
@ -278,7 +275,6 @@ public:
HTMLFigcaptionAccessible(nsIContent* aContent, DocAccessible* aDoc);
// Accessible
virtual mozilla::a11y::role NativeRole() MOZ_OVERRIDE;
virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
};

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

@ -9,7 +9,7 @@
#include "Accessible-inl.h"
#include "ProxyAccessible.h"
#include "Relation.h"
#include "HyperTextAccessible-inl.h"
#include "nsIPersistentProperties2.h"
#include "nsISimpleEnumerator.h"
@ -127,11 +127,18 @@ DocAccessibleChild::RecvAttributes(const uint64_t& aID, nsTArray<Attribute>* aAt
return true;
nsCOMPtr<nsIPersistentProperties> props = acc->Attributes();
if (!props)
return true;
return PersistentPropertiesToArray(props, aAttributes);
}
bool
DocAccessibleChild::PersistentPropertiesToArray(nsIPersistentProperties* aProps,
nsTArray<Attribute>* aAttributes)
{
if (!aProps) {
return true;
}
nsCOMPtr<nsISimpleEnumerator> propEnum;
nsresult rv = props->Enumerate(getter_AddRefs(propEnum));
nsresult rv = aProps->Enumerate(getter_AddRefs(propEnum));
NS_ENSURE_SUCCESS(rv, false);
bool hasMore;
@ -207,6 +214,28 @@ DocAccessibleChild::RecvRelations(const uint64_t& aID,
return true;
}
bool
DocAccessibleChild::RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
*aOffset = acc && acc->IsTextRole() ? acc->CaretOffset() : 0;
return true;
}
bool
DocAccessibleChild::RecvSetCaretOffset(const uint64_t& aID,
const int32_t& aOffset,
bool* aRetVal)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
*aRetVal = false;
if (acc && acc->IsTextRole() && acc->IsValidOffset(aOffset)) {
*aRetVal = true;
acc->SetCaretOffset(aOffset);
}
return true;
}
bool
DocAccessibleChild::RecvCharacterCount(const uint64_t& aID, int32_t* aCount)
{
@ -292,5 +321,91 @@ DocAccessibleChild::RecvGetTextBeforeOffset(const uint64_t& aID,
return true;
}
bool
DocAccessibleChild::RecvCharAt(const uint64_t& aID,
const int32_t& aOffset,
uint16_t* aChar)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
*aChar = acc && acc->IsTextRole() ?
static_cast<uint16_t>(acc->CharAt(aOffset)) : 0;
return true;
}
bool
DocAccessibleChild::RecvTextAttributes(const uint64_t& aID,
const bool& aIncludeDefAttrs,
const int32_t& aOffset,
nsTArray<Attribute>* aAttributes,
int32_t* aStartOffset,
int32_t* aEndOffset)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (!acc || !acc->IsTextRole()) {
return true;
}
nsCOMPtr<nsIPersistentProperties> props =
acc->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset);
return PersistentPropertiesToArray(props, aAttributes);
}
bool
DocAccessibleChild::RecvDefaultTextAttributes(const uint64_t& aID,
nsTArray<Attribute> *aAttributes)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (!acc || !acc->IsTextRole()) {
return true;
}
nsCOMPtr<nsIPersistentProperties> props = acc->DefaultTextAttributes();
return PersistentPropertiesToArray(props, aAttributes);
}
bool
DocAccessibleChild::RecvTextBounds(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
const uint32_t& aCoordType,
nsIntRect* aRetVal)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
*aRetVal = acc->TextBounds(aStartOffset, aEndOffset, aCoordType);
}
return true;
}
bool
DocAccessibleChild::RecvCharBounds(const uint64_t& aID,
const int32_t& aOffset,
const uint32_t& aCoordType,
nsIntRect* aRetVal)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
*aRetVal = acc->CharBounds(aOffset, aCoordType);
}
return true;
}
bool
DocAccessibleChild::RecvOffsetAtPoint(const uint64_t& aID,
const int32_t& aX,
const int32_t& aY,
const uint32_t& aCoordType,
int32_t* aRetVal)
{
*aRetVal = -1;
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
*aRetVal = acc->OffsetAtPoint(aX, aY, aCoordType);
}
return true;
}
}
}

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

@ -64,6 +64,11 @@ public:
virtual bool RecvAttributes(const uint64_t& aID,
nsTArray<Attribute> *aAttributes) MOZ_OVERRIDE;
virtual bool RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
MOZ_OVERRIDE;
virtual bool RecvSetCaretOffset(const uint64_t& aID, const int32_t& aOffset,
bool* aValid) MOZ_OVERRIDE;
virtual bool RecvCharacterCount(const uint64_t& aID, int32_t* aCount)
MOZ_OVERRIDE;
virtual bool RecvSelectionCount(const uint64_t& aID, int32_t* aCount)
@ -90,7 +95,42 @@ public:
nsString* aText, int32_t* aStartOffset,
int32_t* aEndOffset) MOZ_OVERRIDE;
virtual bool RecvCharAt(const uint64_t& aID,
const int32_t& aOffset,
uint16_t* aChar) MOZ_OVERRIDE;
virtual bool RecvTextAttributes(const uint64_t& aID,
const bool& aIncludeDefAttrs,
const int32_t& aOffset,
nsTArray<Attribute>* aAttributes,
int32_t* aStartOffset,
int32_t* aEndOffset)
MOZ_OVERRIDE;
virtual bool RecvDefaultTextAttributes(const uint64_t& aID,
nsTArray<Attribute>* aAttributes)
MOZ_OVERRIDE;
virtual bool RecvTextBounds(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
const uint32_t& aCoordType,
nsIntRect* aRetVal) MOZ_OVERRIDE;
virtual bool RecvCharBounds(const uint64_t& aID,
const int32_t& aOffset,
const uint32_t& aCoordType,
nsIntRect* aRetVal) MOZ_OVERRIDE;
virtual bool RecvOffsetAtPoint(const uint64_t& aID,
const int32_t& aX,
const int32_t& aY,
const uint32_t& aCoordType,
int32_t* aRetVal) MOZ_OVERRIDE;
private:
bool PersistentPropertiesToArray(nsIPersistentProperties* aProps,
nsTArray<Attribute>* aAttributes);
DocAccessible* mDoc;
};

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

@ -6,6 +6,8 @@
include protocol PContent;
using struct nsIntRect from "nsRect.h";
namespace mozilla {
namespace a11y {
@ -65,6 +67,8 @@ child:
// AccessibleText
// TextSubstring is getText in IDL.
prio(high) sync CaretOffset(uint64_t aID) returns(int32_t aOffset);
prio(high) sync SetCaretOffset(uint64_t aID, int32_t aOffset) returns (bool aValid);
prio(high) sync CharacterCount(uint64_t aID) returns(int32_t aCount);
prio(high) sync SelectionCount(uint64_t aID) returns(int32_t aCount);
prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t
@ -73,8 +77,23 @@ child:
returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
prio(high) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
prio(high) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
prio(high) sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar);
prio(high) sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset)
returns(Attribute[] aAttributes, int32_t aStartOffset, int32_t aEndOffset);
prio(high) sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes);
prio(high) sync TextBounds(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
uint32_t aCoordType)
returns(nsIntRect aRetVal);
prio(high) sync CharBounds(uint64_t aID, int32_t aOffset, uint32_t aCoordType)
returns(nsIntRect aRetVal);
prio(high) sync OffsetAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aCoordType)
returns(int32_t aRetVal);
};
}

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

@ -149,6 +149,22 @@ ProxyAccessible::Relations(nsTArray<RelationType>* aTypes,
}
}
int32_t
ProxyAccessible::CaretOffset()
{
int32_t offset = 0;
unused << mDoc->SendCaretOffset(mID, &offset);
return offset;
}
bool
ProxyAccessible::SetCaretOffset(int32_t aOffset)
{
bool valid = false;
unused << mDoc->SendSetCaretOffset(mID, aOffset, &valid);
return valid;
}
int32_t
ProxyAccessible::CharacterCount()
{
@ -202,5 +218,57 @@ ProxyAccessible::GetTextBeforeOffset(int32_t aOffset,
&aText, aStartOffset, aEndOffset);
}
char16_t
ProxyAccessible::CharAt(int32_t aOffset)
{
uint16_t retval = 0;
unused << mDoc->SendCharAt(mID, aOffset, &retval);
return static_cast<char16_t>(retval);
}
void
ProxyAccessible::TextAttributes(bool aIncludeDefAttrs,
int32_t aOffset,
nsTArray<Attribute>* aAttributes,
int32_t* aStartOffset,
int32_t* aEndOffset)
{
unused << mDoc->SendTextAttributes(mID, aIncludeDefAttrs, aOffset,
aAttributes, aStartOffset, aEndOffset);
}
void
ProxyAccessible::DefaultTextAttributes(nsTArray<Attribute>* aAttrs)
{
unused << mDoc->SendDefaultTextAttributes(mID, aAttrs);
}
nsIntRect
ProxyAccessible::TextBounds(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aCoordType)
{
nsIntRect rect;
unused <<
mDoc->SendTextBounds(mID, aStartOffset, aEndOffset, aCoordType, &rect);
return rect;
}
nsIntRect
ProxyAccessible::CharBounds(int32_t aOffset, uint32_t aCoordType)
{
nsIntRect rect;
unused <<
mDoc->SendCharBounds(mID, aOffset, aCoordType, &rect);
return rect;
}
int32_t
ProxyAccessible::OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType)
{
int32_t retVal = -1;
unused << mDoc->SendOffsetAtPoint(mID, aX, aY, aCoordType, &retVal);
return retVal;
}
}
}

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

@ -11,6 +11,7 @@
#include "nsIAccessibleText.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsRect.h"
namespace mozilla {
namespace a11y {
@ -99,6 +100,9 @@ public:
void Relations(nsTArray<RelationType>* aTypes,
nsTArray<nsTArray<ProxyAccessible*>>* aTargetSets) const;
int32_t CaretOffset();
bool SetCaretOffset(int32_t aOffset);
int32_t CharacterCount();
int32_t SelectionCount();
@ -120,6 +124,22 @@ public:
nsString& aText, int32_t* aStartOffset,
int32_t* aEndOffset);
char16_t CharAt(int32_t aOffset);
void TextAttributes(bool aIncludeDefAttrs,
const int32_t aOffset,
nsTArray<Attribute>* aAttributes,
int32_t* aStartOffset,
int32_t* aEndOffset);
void DefaultTextAttributes(nsTArray<Attribute>* aAttrs);
nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aCoordType);
nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType);
int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
/**
* Allow the platform to store a pointers worth of data on us.
*/

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

@ -118,6 +118,7 @@ loop.conversation = (function(mozL10n) {
var dispatcher = new loop.Dispatcher();
var client = new loop.Client();
var sdkDriver = new loop.OTSdkDriver({
isDesktop: true,
dispatcher: dispatcher,
sdk: OT
});
@ -137,10 +138,12 @@ loop.conversation = (function(mozL10n) {
});
var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: client,
isDesktop: true,
mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});
var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
isDesktop: true,
mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});

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

@ -118,6 +118,7 @@ loop.conversation = (function(mozL10n) {
var dispatcher = new loop.Dispatcher();
var client = new loop.Client();
var sdkDriver = new loop.OTSdkDriver({
isDesktop: true,
dispatcher: dispatcher,
sdk: OT
});
@ -137,10 +138,12 @@ loop.conversation = (function(mozL10n) {
});
var conversationStore = new loop.store.ConversationStore(dispatcher, {
client: client,
isDesktop: true,
mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});
var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
isDesktop: true,
mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});

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

@ -55,6 +55,8 @@ loop.store.ActiveRoomStore = (function() {
throw new Error("Missing option sdkDriver");
}
this._sdkDriver = options.sdkDriver;
this._isDesktop = options.isDesktop || false;
},
/**
@ -356,6 +358,21 @@ loop.store.ActiveRoomStore = (function() {
* @param {sharedActions.ConnectionFailure} actionData
*/
connectionFailure: function(actionData) {
/**
* XXX This is a workaround for desktop machines that do not have a
* camera installed. As we don't yet have device enumeration, when
* we do, this can be removed (bug 1138851), and the sdk should handle it.
*/
if (this._isDesktop &&
actionData.reason === FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA &&
this.getStoreState().videoMuted === false) {
// We failed to publish with media, so due to the bug, we try again without
// video.
this.setStoreState({videoMuted: true});
this._sdkDriver.retryPublishWithoutVideo();
return;
}
// Treat all reasons as something failed. In theory, clientDisconnected
// could be a success case, but there's no way we should be intentionally
// sending that and still have the window open.

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

@ -10,8 +10,9 @@ loop.store = loop.store || {};
(function() {
var sharedActions = loop.shared.actions;
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
var REST_ERRNOS = loop.shared.utils.REST_ERRNOS;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
/**
* Websocket states taken from:
* https://docs.services.mozilla.com/loop/apis.html#call-progress-state-change-progress
@ -132,6 +133,7 @@ loop.store = loop.store || {};
this.client = options.client;
this.sdkDriver = options.sdkDriver;
this.mozLoop = options.mozLoop;
this._isDesktop = options.isDesktop || false;
},
/**
@ -141,6 +143,21 @@ loop.store = loop.store || {};
* @param {sharedActions.ConnectionFailure} actionData The action data.
*/
connectionFailure: function(actionData) {
/**
* XXX This is a workaround for desktop machines that do not have a
* camera installed. As we don't yet have device enumeration, when
* we do, this can be removed (bug 1138851), and the sdk should handle it.
*/
if (this._isDesktop &&
actionData.reason === FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA &&
this.getStoreState().videoMuted === false) {
// We failed to publish with media, so due to the bug, we try again without
// video.
this.setStoreState({videoMuted: true});
this.sdkDriver.retryPublishWithoutVideo();
return;
}
this._endSession();
this.setStoreState({
callState: CALL_STATES.TERMINATED,

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

@ -33,6 +33,21 @@ loop.OTSdkDriver = (function() {
"setupStreamElements",
"setMute"
]);
/**
* XXX This is a workaround for desktop machines that do not have a
* camera installed. As we don't yet have device enumeration, when
* we do, this can be removed (bug 1138851), and the sdk should handle it.
*/
if ("isDesktop" in options && options.isDesktop &&
!window.MediaStreamTrack.getSources) {
// If there's no getSources function, the sdk defines its own and caches
// the result. So here we define the "normal" one which doesn't get cached, so
// we can change it later.
window.MediaStreamTrack.getSources = function(callback) {
callback([{kind: "audio"}, {kind: "video"}]);
};
}
};
OTSdkDriver.prototype = {
@ -57,9 +72,19 @@ loop.OTSdkDriver = (function() {
this.getRemoteElement = actionData.getRemoteElementFunc;
this.publisherConfig = actionData.publisherConfig;
this.sdk.on("exception", this._onOTException.bind(this));
// At this state we init the publisher, even though we might be waiting for
// the initial connect of the session. This saves time when setting up
// the media.
this._publishLocalStreams();
},
/**
* Internal function to publish a local stream.
* XXX This can be simplified when bug 1138851 is actioned.
*/
_publishLocalStreams: function() {
this.publisher = this.sdk.initPublisher(this.getLocalElement(),
this._getCopyPublisherConfig());
this.publisher.on("streamCreated", this._onLocalStreamCreated.bind(this));
@ -69,6 +94,17 @@ loop.OTSdkDriver = (function() {
this._onAccessDialogOpened.bind(this));
},
/**
* Forces the sdk into not using video, and starts publishing again.
* XXX This is part of the work around that will be removed by bug 1138851.
*/
retryPublishWithoutVideo: function() {
window.MediaStreamTrack.getSources = function(callback) {
callback([{kind: "audio"}]);
};
this._publishLocalStreams();
},
/**
* Handles the setMute action. Informs the published stream to mute
* or unmute audio as appropriate.
@ -436,6 +472,22 @@ loop.OTSdkDriver = (function() {
}));
},
_onOTException: function(event) {
if (event.code === OT.ExceptionCodes.UNABLE_TO_PUBLISH &&
event.message === "GetUserMedia") {
// We free up the publisher here in case the store wants to try
// grabbing the media again.
if (this.publisher) {
this.publisher.off("accessAllowed accessDenied accessDialogOpened streamCreated");
this.publisher.destroy();
delete this.publisher;
}
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA
}));
}
},
/**
* Handles publishing of property changes to a stream.
*/

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

@ -36,6 +36,7 @@ loop.shared.utils = (function(mozL10n) {
var FAILURE_DETAILS = {
MEDIA_DENIED: "reason-media-denied",
UNABLE_TO_PUBLISH_MEDIA: "unable-to-publish-media",
COULD_NOT_CONNECT: "reason-could-not-connect",
NETWORK_DISCONNECTED: "reason-network-disconnected",
EXPIRED_OR_INVALID: "reason-expired-or-invalid",

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

@ -41,6 +41,7 @@ describe("loop.store.ActiveRoomStore", function () {
connectSession: sinon.stub(),
disconnectSession: sinon.stub(),
forceDisconnectAll: sinon.stub().callsArg(0),
retryPublishWithoutVideo: sinon.stub(),
startScreenShare: sinon.stub(),
switchAcquiredWindow: sinon.stub(),
endScreenShare: sinon.stub().returns(true)
@ -609,6 +610,26 @@ describe("loop.store.ActiveRoomStore", function () {
});
});
it("should retry publishing if on desktop, and in the videoMuted state", function() {
store._isDesktop = true;
store.connectionFailure(new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA
}));
sinon.assert.calledOnce(fakeSdkDriver.retryPublishWithoutVideo);
});
it("should set videoMuted to try when retrying publishing", function() {
store._isDesktop = true;
store.connectionFailure(new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA
}));
expect(store.getStoreState().videoMuted).eql(true);
});
it("should store the failure reason", function() {
store.connectionFailure(connectionFailureAction);

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

@ -9,6 +9,7 @@ describe("loop.store.ConversationStore", function () {
var CALL_STATES = loop.store.CALL_STATES;
var WS_STATES = loop.store.WS_STATES;
var WEBSOCKET_REASONS = loop.shared.utils.WEBSOCKET_REASONS;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var sharedActions = loop.shared.actions;
var sharedUtils = loop.shared.utils;
var sandbox, dispatcher, client, store, fakeSessionData, sdkDriver;
@ -56,7 +57,8 @@ describe("loop.store.ConversationStore", function () {
};
sdkDriver = {
connectSession: sinon.stub(),
disconnectSession: sinon.stub()
disconnectSession: sinon.stub(),
retryPublishWithoutVideo: sinon.stub()
};
wsCancelSpy = sinon.spy();
@ -135,6 +137,26 @@ describe("loop.store.ConversationStore", function () {
store.setStoreState({windowId: "42"});
});
it("should retry publishing if on desktop, and in the videoMuted state", function() {
store._isDesktop = true;
store.connectionFailure(new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA
}));
sinon.assert.calledOnce(sdkDriver.retryPublishWithoutVideo);
});
it("should set videoMuted to try when retrying publishing", function() {
store._isDesktop = true;
store.connectionFailure(new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA
}));
expect(store.getStoreState().videoMuted).eql(true);
});
it("should disconnect the session", function() {
store.connectionFailure(
new sharedActions.ConnectionFailure({reason: "fake"}));

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

@ -10,6 +10,7 @@ describe("loop.OTSdkDriver", function () {
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var STREAM_PROPERTIES = loop.shared.utils.STREAM_PROPERTIES;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
var sandbox;
var dispatcher, driver, publisher, sdk, session, sessionData;
var fakeLocalElement, fakeRemoteElement, fakeScreenElement;
@ -52,9 +53,15 @@ describe("loop.OTSdkDriver", function () {
}
}, Backbone.Events);
sdk = {
sdk = _.extend({
initPublisher: sinon.stub().returns(publisher),
initSession: sinon.stub().returns(session)
}, Backbone.Events);
window.OT = {
ExceptionCodes: {
UNABLE_TO_PUBLISH: 1500
}
};
driver = new loop.OTSdkDriver({
@ -94,6 +101,37 @@ describe("loop.OTSdkDriver", function () {
});
});
describe("#retryPublishWithoutVideo", function() {
beforeEach(function() {
sdk.initPublisher.returns(publisher);
driver.setupStreamElements(new sharedActions.SetupStreamElements({
getLocalElementFunc: function() {return fakeLocalElement;},
getRemoteElementFunc: function() {return fakeRemoteElement;},
publisherConfig: publisherConfig
}));
});
it("should make MediaStreamTrack.getSources return without a video source", function(done) {
driver.retryPublishWithoutVideo();
window.MediaStreamTrack.getSources(function(sources) {
expect(sources.some(function(src) {
return src.kind === "video";
})).eql(false);
done();
});
});
it("should call initPublisher", function() {
driver.retryPublishWithoutVideo();
sinon.assert.calledTwice(sdk.initPublisher);
sinon.assert.calledWith(sdk.initPublisher, fakeLocalElement, publisherConfig);
});
});
describe("#setMute", function() {
beforeEach(function() {
sdk.initPublisher.returns(publisher);
@ -627,6 +665,32 @@ describe("loop.OTSdkDriver", function () {
sinon.assert.calledOnce(fakeEvent.preventDefault);
});
});
describe("exception", function() {
describe("Unable to publish (GetUserMedia)", function() {
it("should destroy the publisher", function() {
sdk.trigger("exception", {
code: OT.ExceptionCodes.UNABLE_TO_PUBLISH,
message: "GetUserMedia"
});
sinon.assert.calledOnce(publisher.destroy);
});
it("should dispatch a ConnectionFailure action", function() {
sdk.trigger("exception", {
code: OT.ExceptionCodes.UNABLE_TO_PUBLISH,
message: "GetUserMedia"
});
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.ConnectionFailure({
reason: FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA
}));
});
});
});
});
describe("Events (screenshare)", function() {

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

@ -37,7 +37,7 @@ add_task(function* () {
is(infobox.hidden, false, "Information box visible.");
// Connection
checkLabel("#security-protocol-version-value", "TLSv1");
checkLabel("#security-protocol-version-value", "TLSv1.2");
checkLabel("#security-ciphersuite-value", "TLS_RSA_WITH_AES_128_CBC_SHA");
// Host

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

@ -42,9 +42,9 @@ function spawnTest () {
let firstInterval = OverviewView.getTimeInterval();
info("First interval start time: " + firstInterval.startTime);
info("First interval end time: " + firstInterval.endTime);
ok(firstInterval.startTime - 10 < Number.EPSILON,
is(Math.round(firstInterval.startTime), 10,
"The interval's start time was properly set.");
ok(firstInterval.endTime - 20 < Number.EPSILON,
is(Math.round(firstInterval.endTime), 20,
"The interval's end time was properly set.");
// Get/set another time interval and make sure there's no event propagation.

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

@ -2289,6 +2289,7 @@ GK_ATOM(mixed, "mixed")
GK_ATOM(multiline, "multiline")
GK_ATOM(navigation, "navigation")
GK_ATOM(password, "password")
GK_ATOM(polite, "polite")
GK_ATOM(posinset, "posinset")
GK_ATOM(presentation, "presentation")
GK_ATOM(progressbar, "progressbar")

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

@ -122,9 +122,7 @@ function loadNextTest() {
}
// start running the tests
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, loadNextTest);
loadNextTest();
</script>
</body>

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

@ -338,7 +338,10 @@ class IDLUnresolvedIdentifier(IDLObject):
assert len(name) > 0
if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__" and not allowDoubleUnderscore:
if name == "__noSuchMethod__":
raise WebIDLError("__noSuchMethod__ is deprecated", [location])
if name[:2] == "__" and name != "__content" and not allowDoubleUnderscore:
raise WebIDLError("Identifiers beginning with __ are reserved",
[location])
if name[0] == '_' and not allowDoubleUnderscore:
@ -3825,7 +3828,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
return self._hasOverloads
def isIdentifierLess(self):
return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__"
return self.identifier.name[:2] == "__"
def resolve(self, parentScope):
assert isinstance(parentScope, IDLScope)

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

@ -169,3 +169,16 @@ def WebIDLTest(parser, harness):
except Exception, x:
threw = True
harness.ok(threw, "Should spell [Throws] correctly on methods")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
void __noSuchMethod__();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should not allow __noSuchMethod__ methods")

3
dom/cache/test/mochitest/test_cache.html поставляемый
Просмотреть файл

@ -13,8 +13,7 @@
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({
"set": [["dom.caches.enabled", true],
["dom.fetch.enabled", true]]
"set": [["dom.caches.enabled", true]]
}, function() {
var frame = document.getElementById("frame");
frame.src = "test_cache_frame.html";

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

@ -22,32 +22,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Headers)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
// static
bool
Headers::PrefEnabled(JSContext* aCx, JSObject* aObj)
{
using mozilla::dom::workers::WorkerPrivate;
using mozilla::dom::workers::GetWorkerPrivateFromContext;
if (NS_IsMainThread()) {
static bool sPrefCacheInit = false;
static bool sPrefEnabled = false;
if (sPrefCacheInit) {
return sPrefEnabled;
}
Preferences::AddBoolVarCache(&sPrefEnabled, "dom.fetch.enabled");
sPrefCacheInit = true;
return sPrefEnabled;
}
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
if (!workerPrivate) {
return false;
}
return workerPrivate->DOMFetchEnabled();
}
// static
already_AddRefed<Headers>
Headers::Constructor(const GlobalObject& aGlobal,

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

@ -42,12 +42,8 @@ function testOnWorker(done) {
// Driver
//
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
testOnWorker(function() {
SimpleTest.finish();
});
testOnWorker(function() {
SimpleTest.finish();
});
</script>
</script>

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

@ -42,12 +42,8 @@ function testOnWorker(done) {
// Driver
//
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
testOnWorker(function() {
SimpleTest.finish();
});
testOnWorker(function() {
SimpleTest.finish();
});
</script>
</script>

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

@ -36,11 +36,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
runTest();
});
runTest();
</script>
</pre>
</body>

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

@ -42,12 +42,8 @@ function testOnWorker(done) {
// Driver
//
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
testOnWorker(function() {
SimpleTest.finish();
});
testOnWorker(function() {
SimpleTest.finish();
});
</script>
</script>

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

@ -53,13 +53,9 @@ function testOnMainThread(done) {
// Driver
//
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
testOnMainThread(function() {
testOnWorker(function() {
SimpleTest.finish();
});
testOnMainThread(function() {
testOnWorker(function() {
SimpleTest.finish();
});
});
</script>

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

@ -437,7 +437,7 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer!
"HashChangeEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Headers", pref: "dom.fetch.enabled"},
"Headers",
// IMPORTANT: Do not change this list without review from a DOM peer!
"History",
// IMPORTANT: Do not change this list without review from a DOM peer!
@ -871,9 +871,9 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer!
"Rect",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Request", pref: "dom.fetch.enabled"},
"Request",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "Response", pref: "dom.fetch.enabled"},
"Response",
// IMPORTANT: Do not change this list without review from a DOM peer!
"RGBColor",
// IMPORTANT: Do not change this list without review from a DOM peer!

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

@ -29,7 +29,7 @@ interface Body {
[NoInterfaceObject, Exposed=(Window,Worker)]
interface GlobalFetch {
[Throws, Func="mozilla::dom::Headers::PrefEnabled"]
[Throws]
Promise<Response> fetch(RequestInfo input, optional RequestInit init);
};

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

@ -19,8 +19,7 @@ enum HeadersGuardEnum {
};
[Constructor(optional HeadersInit init),
Exposed=(Window,Worker),
Func="mozilla::dom::Headers::PrefEnabled"]
Exposed=(Window,Worker)]
interface Headers {
[Throws] void append(ByteString name, ByteString value);
[Throws] void delete(ByteString name);

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

@ -10,8 +10,7 @@
typedef (Request or USVString) RequestInfo;
[Constructor(RequestInfo input, optional RequestInit init),
Exposed=(Window,Worker),
Func="mozilla::dom::Headers::PrefEnabled"]
Exposed=(Window,Worker)]
interface Request {
readonly attribute ByteString method;
readonly attribute USVString url;

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

@ -8,8 +8,7 @@
*/
[Constructor(optional BodyInit body, optional ResponseInit init),
Exposed=(Window,Worker),
Func="mozilla::dom::Headers::PrefEnabled"]
Exposed=(Window,Worker)]
interface Response {
[NewObject] static Response error();
[Throws,

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

@ -154,7 +154,6 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
#endif
#define PREF_DOM_FETCH_ENABLED "dom.fetch.enabled"
#define PREF_DOM_CACHES_ENABLED "dom.caches.enabled"
#define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion"
#define PREF_INTL_ACCEPT_LANGUAGES "intl.accept_languages"
@ -1423,6 +1422,13 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
NS_ASSERTION(!sharedWorkerScriptSpec.IsEmpty(), "Empty spec!");
}
bool exemptFromPerDomainMax = false;
if (aWorkerPrivate->IsServiceWorker()) {
AssertIsOnMainThread();
exemptFromPerDomainMax = Preferences::GetBool("dom.serviceWorkers.exemptFromPerDomainMax",
false);
}
const nsCString& domain = aWorkerPrivate->Domain();
WorkerDomainInfo* domainInfo;
@ -1440,7 +1446,8 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
queued = gMaxWorkersPerDomain &&
domainInfo->ActiveWorkerCount() >= gMaxWorkersPerDomain &&
!domain.IsEmpty();
!domain.IsEmpty() &&
!exemptFromPerDomainMax;
if (queued) {
domainInfo->mQueuedWorkers.AppendElement(aWorkerPrivate);
@ -1826,10 +1833,6 @@ RuntimeService::Init()
PREF_DOM_WINDOW_DUMP_ENABLED,
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
#endif
NS_FAILED(Preferences::RegisterCallbackAndCall(
WorkerPrefChanged,
PREF_DOM_FETCH_ENABLED,
reinterpret_cast<void *>(WORKERPREF_DOM_FETCH))) ||
NS_FAILED(Preferences::RegisterCallbackAndCall(
WorkerPrefChanged,
PREF_DOM_CACHES_ENABLED,
@ -2027,10 +2030,6 @@ RuntimeService::Cleanup()
WorkerPrefChanged,
PREF_DOM_CACHES_ENABLED,
reinterpret_cast<void *>(WORKERPREF_DOM_CACHES))) ||
NS_FAILED(Preferences::UnregisterCallback(
WorkerPrefChanged,
PREF_DOM_FETCH_ENABLED,
reinterpret_cast<void *>(WORKERPREF_DOM_FETCH))) ||
#if DUMP_CONTROLLED_BY_PREF
NS_FAILED(Preferences::UnregisterCallback(
WorkerPrefChanged,
@ -2560,18 +2559,11 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
}
#endif
if (key == WORKERPREF_DOM_FETCH) {
key = WORKERPREF_DOM_FETCH;
sDefaultPreferences[WORKERPREF_DOM_FETCH] =
Preferences::GetBool(PREF_DOM_FETCH_ENABLED, false);
}
if (key == WORKERPREF_DOM_CACHES) {
key = WORKERPREF_DOM_CACHES;
sDefaultPreferences[WORKERPREF_DOM_CACHES] =
Preferences::GetBool(PREF_DOM_CACHES_ENABLED, false);
}
// This function should never be registered as a callback for a preference it
// does not handle.
MOZ_ASSERT(key != WORKERPREF_COUNT);

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

@ -1101,13 +1101,6 @@ public:
return mPreferences[WORKERPREF_DUMP];
}
bool
DOMFetchEnabled() const
{
AssertIsOnWorkerThread();
return mPreferences[WORKERPREF_DOM_FETCH];
}
bool
DOMCachesEnabled() const
{

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

@ -194,7 +194,6 @@ struct JSSettings
enum WorkerPreference
{
WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled
WORKERPREF_DOM_FETCH,// dom.fetch.enabled
WORKERPREF_DOM_CACHES, // dom.caches.enabled
WORKERPREF_COUNT
};

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

@ -36,11 +36,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
checkEnabled();
});
checkEnabled();
</script>
</pre>
</body>

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

@ -36,11 +36,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
checkEnabled();
});
checkEnabled();
</script>
</pre>
</body>

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

@ -36,11 +36,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.fetch.enabled", true]
]}, function() {
runTest();
});
runTest();
</script>
</pre>
</body>

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

@ -32,19 +32,15 @@ support-files =
close_test.js
[test_unregister.html]
skip-if = true # Bug 1133805
[test_installation_simple.html]
[test_fetch_event.html]
[test_match_all.html]
[test_install_event.html]
[test_navigator.html]
[test_scopes.html]
skip-if = true # Bug 1037739
[test_controller.html]
[test_workerUpdate.html]
skip-if = true # Bug 1133805
[test_workerUnregister.html]
skip-if = true # Bug 1133805
[test_post_message.html]
[test_post_message_advanced.html]
[test_match_all_client_properties.html]

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

@ -60,6 +60,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -51,9 +51,9 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.fetch.enabled", true]
]}, runTest);
</script>
</pre>

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

@ -102,6 +102,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -177,6 +177,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.messageChannel.enabled", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]

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

@ -67,6 +67,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -27,6 +27,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true]
]}, function() {
checkEnabled();

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

@ -66,6 +66,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -95,6 +95,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -88,6 +88,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -104,7 +104,6 @@
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.fetch.enabled", true],
["dom.caches.enabled", true]
]}, runTest);
};

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

@ -115,7 +115,7 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer!
"FileReaderSync",
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "Headers", pref: "dom.fetch.enabled" },
"Headers",
// IMPORTANT: Do not change this list without review from a DOM peer!
"IDBCursor",
// IMPORTANT: Do not change this list without review from a DOM peer!

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

@ -127,6 +127,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -71,6 +71,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -44,6 +44,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -109,7 +109,7 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer!
"FileReaderSync",
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "Headers", pref: "dom.fetch.enabled" },
"Headers",
// IMPORTANT: Do not change this list without review from a DOM peer!
"IDBCursor",
// IMPORTANT: Do not change this list without review from a DOM peer!
@ -140,6 +140,10 @@ var interfaceNamesInGlobalScope =
"Performance",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Promise",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Request",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Response",
// IMPORTANT: Do not change this list without review from a DOM peer!
"TextDecoder",
// IMPORTANT: Do not change this list without review from a DOM peer!

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

@ -0,0 +1,21 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include PPrintingTypes;
include protocol PPrinting;
namespace mozilla {
namespace embedding {
protocol PPrintSettingsDialog
{
manager PPrinting;
child:
__delete__(nsresult rv, PrintData data);
};
} // namespace embedding
} // namespace mozilla

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

@ -3,92 +3,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include PPrintingTypes;
include protocol PContent;
include protocol PBrowser;
include protocol PPrintProgressDialog;
include protocol PPrintSettingsDialog;
namespace mozilla {
namespace embedding {
struct PrintData {
int32_t startPageRange;
int32_t endPageRange;
double edgeTop;
double edgeLeft;
double edgeBottom;
double edgeRight;
double marginTop;
double marginLeft;
double marginBottom;
double marginRight;
double unwriteableMarginTop;
double unwriteableMarginLeft;
double unwriteableMarginBottom;
double unwriteableMarginRight;
double scaling;
bool printBGColors;
bool printBGImages;
short printRange;
nsString title;
nsString docURL;
nsString headerStrLeft;
nsString headerStrCenter;
nsString headerStrRight;
nsString footerStrLeft;
nsString footerStrCenter;
nsString footerStrRight;
short howToEnableFrameUI;
bool isCancelled;
short printFrameTypeUsage;
short printFrameType;
bool printSilent;
bool shrinkToFit;
bool showPrintProgress;
nsString paperName;
short paperSizeType;
short paperData;
double paperWidth;
double paperHeight;
short paperSizeUnit;
nsString plexName;
nsString colorspace;
nsString resolutionName;
bool downloadFonts;
bool printReversed;
bool printInColor;
int32_t orientation;
nsString printCommand;
int32_t numCopies;
nsString printerName;
bool printToFile;
nsString toFileName;
short outputFormat;
int32_t printPageDelay;
int32_t resolution;
int32_t duplex;
bool isInitializedFromPrinter;
bool isInitializedFromPrefs;
bool persistMarginBoxSettings;
/* Windows-specific things */
nsString driverName;
nsString deviceName;
bool isFramesetDocument;
bool isFramesetFrameSelected;
bool isIFrameSelected;
bool isRangeSelection;
/* TODO: OS X specific things - specifically, an array of names for the
* document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames
*/
};
sync protocol PPrinting
{
manager PContent;
manages PPrintProgressDialog;
manages PPrintSettingsDialog;
parent:
sync ShowProgress(PBrowser browser,
@ -97,10 +25,12 @@ parent:
returns(bool notifyOnOpen,
bool success);
sync ShowPrintDialog(PBrowser browser, PrintData settings)
returns(PrintData modifiedSettings, bool success);
async ShowPrintDialog(PPrintSettingsDialog dialog,
PBrowser browser,
PrintData settings);
PPrintProgressDialog();
PPrintSettingsDialog();
sync SavePrintSettings(PrintData settings, bool usePrinterNamePrefix,
uint32_t flags)

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

@ -0,0 +1,85 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* 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/. */
namespace mozilla {
namespace embedding {
struct PrintData {
int32_t startPageRange;
int32_t endPageRange;
double edgeTop;
double edgeLeft;
double edgeBottom;
double edgeRight;
double marginTop;
double marginLeft;
double marginBottom;
double marginRight;
double unwriteableMarginTop;
double unwriteableMarginLeft;
double unwriteableMarginBottom;
double unwriteableMarginRight;
double scaling;
bool printBGColors;
bool printBGImages;
short printRange;
nsString title;
nsString docURL;
nsString headerStrLeft;
nsString headerStrCenter;
nsString headerStrRight;
nsString footerStrLeft;
nsString footerStrCenter;
nsString footerStrRight;
short howToEnableFrameUI;
bool isCancelled;
short printFrameTypeUsage;
short printFrameType;
bool printSilent;
bool shrinkToFit;
bool showPrintProgress;
nsString paperName;
short paperSizeType;
short paperData;
double paperWidth;
double paperHeight;
short paperSizeUnit;
nsString plexName;
nsString colorspace;
nsString resolutionName;
bool downloadFonts;
bool printReversed;
bool printInColor;
int32_t orientation;
nsString printCommand;
int32_t numCopies;
nsString printerName;
bool printToFile;
nsString toFileName;
short outputFormat;
int32_t printPageDelay;
int32_t resolution;
int32_t duplex;
bool isInitializedFromPrinter;
bool isInitializedFromPrefs;
bool persistMarginBoxSettings;
/* Windows-specific things */
nsString driverName;
nsString deviceName;
bool isFramesetDocument;
bool isFramesetFrameSelected;
bool isIFrameSelected;
bool isRangeSelection;
/* TODO: OS X specific things - specifically, an array of names for the
* document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames
*/
};
} // namespace embedding
} // namespace mozilla

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

@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PrintSettingsDialogChild.h"
using mozilla::unused;
namespace mozilla {
namespace embedding {
MOZ_IMPLICIT PrintSettingsDialogChild::PrintSettingsDialogChild()
: mReturned(false)
{
MOZ_COUNT_CTOR(PrintSettingsDialogChild);
}
MOZ_IMPLICIT PrintSettingsDialogChild::~PrintSettingsDialogChild()
{
MOZ_COUNT_DTOR(PrintSettingsDialogChild);
}
bool
PrintSettingsDialogChild::Recv__delete__(const nsresult& aResult,
const PrintData& aData)
{
mResult = aResult;
mData = aData;
mReturned = true;
return true;
}
} // namespace embedding
} // namespace mozilla

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

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_embedding_PrintSettingsDialogChild_h
#define mozilla_embedding_PrintSettingsDialogChild_h
#include "mozilla/embedding/PPrintSettingsDialogChild.h"
namespace mozilla {
namespace embedding {
class PrintSettingsDialogChild MOZ_FINAL : public PPrintSettingsDialogChild
{
NS_INLINE_DECL_REFCOUNTING(PrintSettingsDialogChild)
public:
MOZ_IMPLICIT PrintSettingsDialogChild();
virtual bool Recv__delete__(const nsresult& aResult,
const PrintData& aData) MOZ_OVERRIDE;
bool returned() { return mReturned; };
nsresult result() { return mResult; };
PrintData data() { return mData; };
private:
virtual ~PrintSettingsDialogChild();
bool mReturned;
nsresult mResult;
PrintData mData;
};
} // namespace embedding
} // namespace mozilla
#endif

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

@ -0,0 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PrintSettingsDialogParent.h"
// C++ file contents
namespace mozilla {
namespace embedding {
MOZ_IMPLICIT PrintSettingsDialogParent::PrintSettingsDialogParent()
{
MOZ_COUNT_CTOR(PrintSettingsDialogParent);
}
MOZ_IMPLICIT PrintSettingsDialogParent::~PrintSettingsDialogParent()
{
MOZ_COUNT_DTOR(PrintSettingsDialogParent);
}
void
PrintSettingsDialogParent::ActorDestroy(ActorDestroyReason aWhy)
{
}
} // namespace embedding
} // namespace mozilla

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

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_embedding_PrintSettingsDialogParent_h
#define mozilla_embedding_PrintSettingsDialogParent_h
#include "mozilla/embedding/PPrintSettingsDialogParent.h"
// Header file contents
namespace mozilla {
namespace embedding {
class PrintSettingsDialogParent MOZ_FINAL : public PPrintSettingsDialogParent
{
public:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
MOZ_IMPLICIT PrintSettingsDialogParent();
private:
virtual ~PrintSettingsDialogParent();
};
} // namespace embedding
} // namespace mozilla
#endif

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

@ -18,6 +18,7 @@
#include "PrintingParent.h"
#include "PrintDataUtils.h"
#include "PrintProgressDialogParent.h"
#include "PrintSettingsDialogParent.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -65,50 +66,58 @@ PrintingParent::RecvShowProgress(PBrowserParent* parent,
return true;
}
bool
PrintingParent::RecvShowPrintDialog(PBrowserParent* parent,
const PrintData& data,
PrintData* retVal,
bool* success)
nsresult
PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
const PrintData& aData,
PrintData* aResult)
{
*success = false;
nsCOMPtr<nsIDOMWindow> parentWin = DOMWindowFromBrowserParent(parent);
nsCOMPtr<nsIDOMWindow> parentWin = DOMWindowFromBrowserParent(aParent);
if (!parentWin) {
return true;
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
if (!pps) {
return true;
return NS_ERROR_FAILURE;
}
// The initSettings we got can be wrapped using
// PrintDataUtils' MockWebBrowserPrint, which implements enough of
// nsIWebBrowserPrint to keep the dialogs happy.
nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(data);
nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(aData);
nsresult rv;
nsCOMPtr<nsIPrintOptions> po = do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
NS_ENSURE_SUCCESS(rv, true);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrintSettings> settings;
rv = po->CreatePrintSettings(getter_AddRefs(settings));
NS_ENSURE_SUCCESS(rv, true);
NS_ENSURE_SUCCESS(rv, rv);
rv = po->DeserializeToPrintSettings(data, settings);
NS_ENSURE_SUCCESS(rv, true);
rv = po->DeserializeToPrintSettings(aData, settings);
NS_ENSURE_SUCCESS(rv, rv);
rv = pps->ShowPrintDialog(parentWin, wbp, settings);
NS_ENSURE_SUCCESS(rv, true);
NS_ENSURE_SUCCESS(rv, rv);
// And send it back.
PrintData result;
rv = po->SerializeToPrintData(settings, nullptr, &result);
NS_ENSURE_SUCCESS(rv, true);
rv = po->SerializeToPrintData(settings, nullptr, aResult);
return rv;
}
*retVal = result;
*success = true;
bool
PrintingParent::RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog,
PBrowserParent* aParent,
const PrintData& aData)
{
PrintData resultData;
nsresult rv = ShowPrintDialog(aParent, aData, &resultData);
// The child has been spinning an event loop while waiting
// to hear about the print settings. We return the results
// with an async message which frees the child process from
// its nested event loop.
mozilla::unused << aDialog->Send__delete__(aDialog, rv, resultData);
return true;
}
@ -157,6 +166,19 @@ PrintingParent::DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* do
return true;
}
PPrintSettingsDialogParent*
PrintingParent::AllocPPrintSettingsDialogParent()
{
return new PrintSettingsDialogParent();
}
bool
PrintingParent::DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aDoomed)
{
delete aDoomed;
return true;
}
void
PrintingParent::ActorDestroy(ActorDestroyReason aWhy)
{

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

@ -9,9 +9,10 @@
#include "mozilla/dom/PBrowserParent.h"
#include "mozilla/embedding/PPrintingParent.h"
#include "mozilla/embedding/PPrintProgressDialogParent.h"
class nsIDOMWindow;
class PPrintProgressDialogParent;
class PPrintSettingsDialogParent;
namespace mozilla {
namespace embedding {
@ -26,16 +27,15 @@ public:
bool* notifyOnOpen,
bool* success);
virtual bool
RecvShowPrintDialog(PBrowserParent* parent,
const PrintData& initSettings,
PrintData* retVal,
bool* success);
RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog,
PBrowserParent* aParent,
const PrintData& aData);
virtual bool
RecvSavePrintSettings(const PrintData& aData,
const bool& aUsePrinterNamePrefix,
const uint32_t& aFlags,
nsresult* aResult);
RecvSavePrintSettings(const PrintData& data,
const bool& usePrinterNamePrefix,
const uint32_t& flags,
nsresult* rv);
virtual PPrintProgressDialogParent*
AllocPPrintProgressDialogParent();
@ -43,6 +43,12 @@ public:
virtual bool
DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* aActor);
virtual PPrintSettingsDialogParent*
AllocPPrintSettingsDialogParent();
virtual bool
DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aActor);
virtual void
ActorDestroy(ActorDestroyReason aWhy);
@ -52,6 +58,11 @@ public:
private:
nsIDOMWindow*
DOMWindowFromBrowserParent(PBrowserParent* parent);
nsresult
ShowPrintDialog(PBrowserParent* parent,
const PrintData& data,
PrintData* result);
};
} // namespace embedding
} // namespace mozilla

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

@ -19,11 +19,15 @@ if CONFIG['NS_PRINTING']:
'PrintingParent.cpp',
'PrintProgressDialogChild.cpp',
'PrintProgressDialogParent.cpp',
'PrintSettingsDialogChild.cpp',
'PrintSettingsDialogParent.cpp',
]
IPDL_SOURCES += [
'PPrinting.ipdl',
'PPrintingTypes.ipdlh',
'PPrintProgressDialog.ipdl',
'PPrintSettingsDialog.ipdl',
]
include('/ipc/chromium/chromium-config.mozbuild')

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

@ -95,17 +95,24 @@ nsPrintingProxy::ShowPrintDialog(nsIDOMWindow *parent,
rv = po->SerializeToPrintData(printSettings, webBrowserPrint, &inSettings);
NS_ENSURE_SUCCESS(rv, rv);
PrintData modifiedSettings;
bool success;
// Now, the waiting game. The parent process should be showing
// the printing dialog soon. In the meantime, we need to spin a
// nested event loop while we wait for the results of the dialog
// to be returned to us.
mozilla::unused << SendShowPrintDialog(pBrowser, inSettings, &modifiedSettings, &success);
nsRefPtr<PrintSettingsDialogChild> dialog = new PrintSettingsDialogChild();
SendPPrintSettingsDialogConstructor(dialog);
if (!success) {
// Something failed in the parent.
return NS_ERROR_FAILURE;
mozilla::unused << SendShowPrintDialog(dialog, pBrowser, inSettings);
while(!dialog->returned()) {
NS_ProcessNextEvent(nullptr, true);
}
rv = po->DeserializeToPrintSettings(modifiedSettings, printSettings);
rv = dialog->result();
NS_ENSURE_SUCCESS(rv, rv);
rv = po->DeserializeToPrintSettings(dialog->data(), printSettings);
return NS_OK;
}
@ -206,3 +213,21 @@ nsPrintingProxy::DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aAc
"called on nsPrintingProxy.");
return false;
}
PPrintSettingsDialogChild*
nsPrintingProxy::AllocPPrintSettingsDialogChild()
{
// The parent process will never initiate the PPrintSettingsDialog
// protocol connection, so no need to provide an allocator here.
NS_NOTREACHED("Allocator for PPrintSettingsDialogChild should not be "
"called on nsPrintingProxy.");
return nullptr;
}
bool
nsPrintingProxy::DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor)
{
// The PrintSettingsDialogChild implements refcounting, and
// will take itself out.
return true;
}

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

@ -33,6 +33,12 @@ public:
virtual bool
DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor) MOZ_OVERRIDE;
virtual PPrintSettingsDialogChild*
AllocPPrintSettingsDialogChild() MOZ_OVERRIDE;
virtual bool
DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor) MOZ_OVERRIDE;
};
#endif

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

@ -1818,8 +1818,7 @@ UpdatePluginWindowState(uint64_t aId)
}
bool shouldComposePlugin = !!lts.mRoot &&
!!lts.mRoot->GetParent() &&
lts.mUpdatedPluginDataAvailable;
!!lts.mRoot->GetParent();
bool shouldHidePlugin = (!lts.mRoot ||
!lts.mRoot->GetParent()) &&
@ -1832,6 +1831,7 @@ UpdatePluginWindowState(uint64_t aId)
// calculating clipping.
nsTArray<uintptr_t> aVisibleIdList;
unused << lts.mParent->SendUpdatePluginVisibility(aVisibleIdList);
lts.mUpdatedPluginDataAvailable = false;
return;
}

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

@ -0,0 +1,12 @@
with({}){}
x = Int8Array(1)
function f(y) {
x[0] = y
}
f()
f(3)
f(7)
x.buffer;
f(0);
assertEq(x[0], 0);

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

@ -2933,6 +2933,9 @@ CanAttachNativeSetProp(JSContext *cx, HandleObject obj, HandleId id, ConstantOrR
if (!shape || (obj != holder && shape->hasDefaultSetter() && shape->hasSlot()))
return SetPropertyIC::MaybeCanAttachAddSlot;
if (IsImplicitNonNativeProperty(shape))
return SetPropertyIC::CanAttachNone;
if (IsCacheableSetPropCallPropertyOp(obj, holder, shape) ||
IsCacheableSetPropCallNative(obj, holder, shape) ||
IsCacheableSetPropCallScripted(obj, holder, shape))

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

@ -3058,7 +3058,7 @@ class MNewObject
bool canRecoverOnBailout() const MOZ_OVERRIDE {
// The template object can safely be used in the recover instruction
// because it can never be mutated by any other function execution.
return true;
return templateObject() != nullptr;
}
};

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

@ -1171,7 +1171,7 @@ RNewObject::RNewObject(CompactBufferReader &reader)
bool
RNewObject::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedPlainObject templateObject(cx, &iter.read().toObject().as<PlainObject>());
RootedObject templateObject(cx, &iter.read().toObject());
RootedValue result(cx);
JSObject *resultObject = nullptr;
@ -1180,7 +1180,7 @@ RNewObject::recover(JSContext *cx, SnapshotIterator &iter) const
resultObject = NewObjectOperationWithTemplate(cx, templateObject);
} else {
MOZ_ASSERT(mode_ == MNewObject::ObjectCreate);
resultObject = ObjectCreateWithTemplate(cx, templateObject);
resultObject = ObjectCreateWithTemplate(cx, templateObject.as<PlainObject>());
}
if (!resultObject)

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

@ -1549,6 +1549,12 @@ IsImplicitDenseOrTypedArrayElement(Shape *prop)
return prop == reinterpret_cast<Shape*>(1);
}
static inline bool
IsImplicitNonNativeProperty(Shape *prop)
{
return prop == reinterpret_cast<Shape*>(1);
}
Shape *
ReshapeForParentAndAllocKind(JSContext *cx, Shape *shape, TaggedProto proto, JSObject *parent,
gc::AllocKind allocKind);

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

@ -120,6 +120,10 @@ TypedArrayObject::ensureHasBuffer(JSContext *cx, Handle<TypedArrayObject *> tarr
tarray->setPrivate(buffer->dataPointer());
tarray->setSlot(TypedArrayLayout::BUFFER_SLOT, ObjectValue(*buffer));
// Notify compiled jit code that the base pointer has moved.
MarkObjectStateChange(cx, tarray);
return true;
}

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

@ -265,12 +265,13 @@ ActiveLayerTracker::IsStyleAnimated(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsCSSProperty aProperty)
{
// TODO: Add some abuse restrictions
if ((aFrame->StyleDisplay()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) &&
auto willChangeBitField = aFrame->StylePosition()->mWillChangeBitField;
if ((willChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) &&
aProperty == eCSSProperty_transform &&
(!aBuilder || aBuilder->IsInWillChangeBudget(aFrame))) {
return true;
}
if ((aFrame->StyleDisplay()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) &&
if ((willChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) &&
aProperty == eCSSProperty_opacity &&
(!aBuilder || aBuilder->IsInWillChangeBudget(aFrame))) {
return true;

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

@ -332,12 +332,12 @@ ApplyRenderingChangeToTree(nsPresContext* aPresContext,
nsIFrame* aFrame,
nsChangeHint aChange)
{
// We check StyleDisplay()->HasTransformStyle() in addition to checking
// We check StylePosition()->HasTransformStyle() in addition to checking
// IsTransformed() since we can get here for some frames that don't support
// CSS transforms.
NS_ASSERTION(!(aChange & nsChangeHint_UpdateTransformLayer) ||
aFrame->IsTransformed() ||
aFrame->StyleDisplay()->HasTransformStyle(),
aFrame->StylePosition()->HasTransformStyle(),
"Unexpected UpdateTransformLayer hint");
nsIPresShell *shell = aPresContext->PresShell();
@ -2605,7 +2605,7 @@ ElementRestyler::AddLayerChangesForAnimation()
// nsChangeHint_UpdateTransformLayer, ApplyRenderingChangeToTree would
// complain that we're updating a transform layer without a transform).
if (layerInfo[i].mLayerType == nsDisplayItem::TYPE_TRANSFORM &&
!mFrame->StyleDisplay()->HasTransformStyle()) {
!mFrame->StylePosition()->HasTransformStyle()) {
continue;
}
NS_UpdateHint(hint, layerInfo[i].mChangeHint);

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

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
document.documentElement.style.display = "contents";
document.designMode = 'on';
document.documentElement.insertAdjacentHTML("beforeEnd", "<span><optgroup>");
}
</script>
</head>
<body onload="boom();"></body>
</html>

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

@ -458,3 +458,4 @@ load 1061028.html
load 1116104.html
load 1107508-1.html
load 1127198-1.html
load 1140198.html

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

@ -1059,8 +1059,8 @@ nsFrameConstructorState::PushAbsoluteContainingBlock(nsContainerFrame* aNewAbsol
* we're a transformed element.
*/
mFixedPosIsAbsPos = aPositionedFrame &&
(aPositionedFrame->StyleDisplay()->HasTransform(aPositionedFrame) ||
aPositionedFrame->StyleDisplay()->HasPerspectiveStyle());
(aPositionedFrame->StylePosition()->HasTransform(aPositionedFrame) ||
aPositionedFrame->StylePosition()->HasPerspectiveStyle());
if (aNewAbsoluteContainingBlock) {
aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock();
@ -2598,8 +2598,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
newFrame = frameItems.FirstChild();
NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
} else {
MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK ||
display->mDisplay == NS_STYLE_DISPLAY_CONTENTS,
MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK,
"Unhandled display type for root element");
contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
nsFrameItems frameItems;
@ -3472,8 +3471,6 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement,
if (aTag == nsGkAtoms::legend &&
(!aParentFrame ||
!IsFrameForFieldSet(aParentFrame, aParentFrame->GetType()) ||
!aElement->GetParent() ||
!aElement->GetParent()->IsHTMLElement(nsGkAtoms::fieldset) ||
aStyleContext->StyleDisplay()->IsFloatingStyle() ||
aStyleContext->StyleDisplay()->IsAbsolutelyPositionedStyle())) {
// <legend> is only special inside fieldset, check both the frame tree
@ -3791,7 +3788,9 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
// If we need to create a block formatting context to wrap our
// kids, do it now.
const nsStylePosition* position = styleContext->StylePosition();
const nsStyleDisplay* maybeAbsoluteContainingBlockDisplay = display;
const nsStylePosition* maybeAbsoluteContainingBlockPosition = position;
nsIFrame* maybeAbsoluteContainingBlock = newFrame;
nsIFrame* possiblyLeafFrame = newFrame;
if (bits & FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS) {
@ -3817,6 +3816,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
const nsStyleDisplay* blockDisplay = blockContext->StyleDisplay();
if (blockDisplay->IsPositioned(blockFrame)) {
maybeAbsoluteContainingBlockDisplay = blockDisplay;
maybeAbsoluteContainingBlockPosition = blockContext->StylePosition();
maybeAbsoluteContainingBlock = blockFrame;
}
@ -3857,9 +3857,9 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
// make the inner the containing block.
if ((maybeAbsoluteContainingBlockDisplay->IsAbsolutelyPositionedStyle() ||
maybeAbsoluteContainingBlockDisplay->IsRelativelyPositionedStyle() ||
(maybeAbsoluteContainingBlockDisplay->HasTransformStyle() &&
(maybeAbsoluteContainingBlockPosition->HasTransformStyle() &&
cb->IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) ||
maybeAbsoluteContainingBlockDisplay->HasPerspectiveStyle()) &&
maybeAbsoluteContainingBlockPosition->HasPerspectiveStyle()) &&
!cb->IsSVGText()) {
nsContainerFrame* cf = static_cast<nsContainerFrame*>(cb);
aState.PushAbsoluteContainingBlock(cf, cf, absoluteSaveState);
@ -5182,6 +5182,17 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement,
return &sContainerData;
}
// Ensure that a stop frame is a child of a gradient and that gradients
// can only have stop children.
bool parentIsGradient = aParentFrame &&
(aParentFrame->GetType() == nsGkAtoms::svgLinearGradientFrame ||
aParentFrame->GetType() == nsGkAtoms::svgRadialGradientFrame);
bool stop = (aTag == nsGkAtoms::stop);
if ((parentIsGradient && !stop) ||
(!parentIsGradient && stop)) {
return &sSuppressData;
}
// Prevent bad frame types being children of filters or parents of filter
// primitives. If aParentFrame is null, we know that the frame that will
// be created will be an nsInlineFrame, so it can never be a filter.
@ -5975,8 +5986,8 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame,
// not transformed, skip it.
if (!frame->IsPositioned() ||
(aType == FIXED_POS &&
!frame->StyleDisplay()->HasTransform(frame) &&
!frame->StyleDisplay()->HasPerspectiveStyle())) {
!frame->StylePosition()->HasTransform(frame) &&
!frame->StylePosition()->HasPerspectiveStyle())) {
continue;
}
nsIFrame* absPosCBCandidate = frame;
@ -6572,7 +6583,12 @@ nsCSSFrameConstructor::GetInsertionPrevSibling(InsertionPoint* aInsertion,
// the container would be inserted. This is needed when inserting
// into nested display:contents nodes.
nsIContent* child = aInsertion->mContainer;
InsertionPoint fakeInsertion(aInsertion->mParentFrame, child->GetParent());
nsIContent* parent = child->GetParent();
aInsertion->mParentFrame =
::GetAdjustedParentFrame(aInsertion->mParentFrame,
aInsertion->mParentFrame->GetType(),
parent);
InsertionPoint fakeInsertion(aInsertion->mParentFrame, parent);
nsIFrame* result = GetInsertionPrevSibling(&fakeInsertion, child, aIsAppend,
aIsRangeInsertSafe, nullptr, nullptr);
MOZ_ASSERT(aInsertion->mParentFrame == fakeInsertion.mParentFrame);
@ -8913,8 +8929,10 @@ nsCSSFrameConstructor::GetInsertionPoint(nsIContent* aContainer,
InsertionPoint insertion(GetContentInsertionFrameFor(insertionElement),
insertionElement);
// Fieldsets have multiple insertion points.
if (insertionElement->IsHTMLElement(nsGkAtoms::fieldset)) {
// Fieldset frames have multiple normal flow child frame lists so handle it
// the same as if it had multiple content insertion points.
if (insertion.mParentFrame &&
insertion.mParentFrame->GetType() == nsGkAtoms::fieldSetFrame) {
insertion.mMultiple = true;
}

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

@ -522,9 +522,9 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
nscoord perspective = 0.0;
nsStyleContext* parentStyleContext = aFrame->StyleContext()->GetParent();
if (parentStyleContext) {
const nsStyleDisplay* disp = parentStyleContext->StyleDisplay();
if (disp && disp->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
perspective = disp->mChildPerspective.GetCoordValue();
const nsStylePosition* pos = parentStyleContext->StylePosition();
if (pos && pos->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
perspective = pos->mChildPerspective.GetCoordValue();
}
}
nsPoint origin;
@ -5027,8 +5027,8 @@ nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder)
mStoredList.SetVisibleRect(mChildrenVisibleRect);
mMaybePrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame);
const nsStyleDisplay* disp = mFrame->StyleDisplay();
if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) {
const nsStylePosition* pos = mFrame->StylePosition();
if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) {
// We will only pre-render if this will-change is on budget.
mMaybePrerender = true;
}
@ -5082,7 +5082,8 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
const nsRect* aBoundsOverride)
{
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
NS_PRECONDITION(aFrame->IsTransformed() || aFrame->StyleDisplay()->BackfaceIsHidden(),
NS_PRECONDITION(aFrame->IsTransformed() ||
aFrame->StylePosition()->BackfaceIsHidden(),
"Shouldn't get a delta for an untransformed frame!");
if (!aFrame->IsTransformed()) {
@ -5093,7 +5094,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
* percentage, it's relative to the size of the frame. Otherwise, if it's
* a distance, it's already computed for us!
*/
const nsStyleDisplay* display = aFrame->StyleDisplay();
const nsStylePosition* pos = aFrame->StylePosition();
nsRect boundingRect = (aBoundsOverride ? *aBoundsOverride :
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
@ -5106,7 +5107,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
/* If the -moz-transform-origin specifies a percentage, take the percentage
* of the size of the box.
*/
const nsStyleCoord &coord = display->mTransformOrigin[index];
const nsStyleCoord &coord = pos->mTransformOrigin[index];
if (coord.GetUnit() == eStyleUnit_Calc) {
const nsStyleCoord::Calc *calc = coord.GetCalcValue();
coords[index] =
@ -5132,7 +5133,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
}
}
coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(),
coords[2] = NSAppUnitsToFloatPixels(pos->mTransformOrigin[2].GetCoordValue(),
aAppUnitsPerPixel);
/* Adjust based on the origin of the rectangle. */
coords[0] += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
@ -5151,7 +5152,8 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame,
float aAppUnitsPerPixel)
{
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
NS_PRECONDITION(aFrame->IsTransformed() || aFrame->StyleDisplay()->BackfaceIsHidden(),
NS_PRECONDITION(aFrame->IsTransformed() ||
aFrame->StylePosition()->BackfaceIsHidden(),
"Shouldn't get a delta for an untransformed frame!");
if (!aFrame->IsTransformed()) {
@ -5176,7 +5178,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame,
return Point3D();
}
}
const nsStyleDisplay* display = psc->StyleDisplay();
const nsStylePosition* pos = psc->StylePosition();
nsRect boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(parent);
/* Allows us to access named variables by index. */
@ -5190,7 +5192,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame,
/* If the -moz-transform-origin specifies a percentage, take the percentage
* of the size of the box.
*/
const nsStyleCoord &coord = display->mPerspectiveOrigin[index];
const nsStyleCoord &coord = pos->mPerspectiveOrigin[index];
if (coord.GetUnit() == eStyleUnit_Calc) {
const nsStyleCoord::Calc *calc = coord.GetCalcValue();
*coords[index] =
@ -5221,18 +5223,18 @@ nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsI
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride)
: mFrame(aFrame)
, mTransformList(aFrame->StyleDisplay()->mSpecifiedTransform)
, mTransformList(aFrame->StylePosition()->mSpecifiedTransform)
, mToTransformOrigin(GetDeltaToTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride))
, mToPerspectiveOrigin(GetDeltaToPerspectiveOrigin(aFrame, aAppUnitsPerPixel))
, mChildPerspective(0)
{
const nsStyleDisplay* parentDisp = nullptr;
const nsStylePosition* parentPos = nullptr;
nsStyleContext* parentStyleContext = aFrame->StyleContext()->GetParent();
if (parentStyleContext) {
parentDisp = parentStyleContext->StyleDisplay();
parentPos = parentStyleContext->StylePosition();
}
if (parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
mChildPerspective = parentDisp->mChildPerspective.GetCoordValue();
if (parentPos && parentPos->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
mChildPerspective = parentPos->mChildPerspective.GetCoordValue();
}
}
@ -5412,8 +5414,8 @@ nsDisplayTransform::ShouldPrerender(nsDisplayListBuilder* aBuilder) {
return true;
}
const nsStyleDisplay* disp = mFrame->StyleDisplay();
if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) &&
const nsStylePosition* pos = mFrame->StylePosition();
if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) &&
aBuilder->IsInWillChangeBudget(mFrame)) {
return true;
}
@ -5502,7 +5504,8 @@ static bool IsFrameVisible(nsIFrame* aFrame, const Matrix4x4& aMatrix)
if (aMatrix.IsSingular()) {
return false;
}
if (aFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
const nsStylePosition* pos = aFrame->StylePosition();
if (pos->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
aMatrix.IsBackfaceVisible()) {
return false;
}
@ -5550,7 +5553,8 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
{
const Matrix4x4& newTransformMatrix = GetTransform();
if (mFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
const nsStylePosition* pos = mFrame->StylePosition();
if (pos->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
newTransformMatrix.IsBackfaceVisible()) {
return nullptr;
}
@ -5609,8 +5613,8 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
}
}
const nsStyleDisplay* disp = mFrame->StyleDisplay();
if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) {
const nsStylePosition* pos = mFrame->StylePosition();
if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) {
return LAYER_ACTIVE;
}

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

@ -184,13 +184,14 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
aStream << " fixed";
}
if (aItem->Frame()->StyleDisplay()->mWillChange.Length() > 0) {
const nsStylePosition* pos = aItem->Frame()->StylePosition();
if (pos->mWillChange.Length() > 0) {
aStream << " (will-change=";
for (size_t i = 0; i < aItem->Frame()->StyleDisplay()->mWillChange.Length(); i++) {
for (size_t i = 0; i < pos->mWillChange.Length(); i++) {
if (i > 0) {
aStream << ",";
}
aStream << NS_LossyConvertUTF16toASCII(aItem->Frame()->StyleDisplay()->mWillChange[i]).get();
aStream << NS_LossyConvertUTF16toASCII(pos->mWillChange[i]).get();
}
aStream << ")";
}

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

@ -546,12 +546,13 @@ nsFrame::Init(nsIContent* aContent,
NS_FRAME_IN_POPUP |
NS_FRAME_IS_NONDISPLAY);
}
const nsStyleDisplay *disp = StyleDisplay();
if (disp->HasTransform(this)) {
const nsStylePosition* pos = StylePosition();
if (pos->HasTransform(this)) {
// The frame gets reconstructed if we toggle the -moz-transform
// property, so we can set this bit here and then ignore it.
mState |= NS_FRAME_MAY_BE_TRANSFORMED;
}
const nsStyleDisplay *disp = StyleDisplay();
if (disp->mPosition == NS_STYLE_POSITION_STICKY &&
!aPrevInFlow &&
!(mState & NS_FRAME_IS_NONDISPLAY) &&
@ -1075,7 +1076,7 @@ bool
nsIFrame::IsTransformed() const
{
return ((mState & NS_FRAME_MAY_BE_TRANSFORMED) &&
(StyleDisplay()->HasTransform(this) ||
(StylePosition()->HasTransform(this) ||
IsSVGTransformed() ||
(mContent &&
nsLayoutUtils::HasAnimationsForCompositor(mContent,
@ -1088,9 +1089,9 @@ bool
nsIFrame::HasOpacityInternal(float aThreshold) const
{
MOZ_ASSERT(0.0 <= aThreshold && aThreshold <= 1.0, "Invalid argument");
const nsStyleDisplay* displayStyle = StyleDisplay();
const nsStylePosition* pos = StylePosition();
return StyleDisplay()->mOpacity < aThreshold ||
(displayStyle->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) ||
(pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) ||
(mContent &&
nsLayoutUtils::HasAnimationsForCompositor(mContent,
eCSSProperty_opacity) &&
@ -1107,8 +1108,8 @@ nsIFrame::IsSVGTransformed(gfx::Matrix *aOwnTransforms,
bool
nsIFrame::Preserves3DChildren() const
{
const nsStyleDisplay* disp = StyleDisplay();
if (disp->mTransformStyle != NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
const nsStylePosition* pos = StylePosition();
if (pos->mTransformStyle != NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
!IsFrameOfType(nsIFrame::eSupportsCSSTransforms)) {
return false;
}
@ -1119,8 +1120,8 @@ nsIFrame::Preserves3DChildren() const
}
nsRect temp;
return !nsFrame::ShouldApplyOverflowClipping(this, disp) &&
!GetClipPropClipRect(disp, &temp, GetSize()) &&
return !nsFrame::ShouldApplyOverflowClipping(this, StyleDisplay()) &&
!GetClipPropClipRect(&temp, GetSize()) &&
!nsSVGIntegrationUtils::UsingEffectsForFrame(this);
}
@ -1130,7 +1131,8 @@ nsIFrame::Preserves3D() const
if (!GetParent() || !GetParent()->Preserves3DChildren()) {
return false;
}
return StyleDisplay()->HasTransform(this) || StyleDisplay()->BackfaceIsHidden();
const nsStylePosition* pos = StylePosition();
return pos->HasTransform(this) || pos->BackfaceIsHidden();
}
bool
@ -1143,14 +1145,14 @@ nsIFrame::HasPerspective() const
if (!parentStyleContext) {
return false;
}
const nsStyleDisplay* parentDisp = parentStyleContext->StyleDisplay();
return parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord;
const nsStylePosition* parentPos = parentStyleContext->StylePosition();
return parentPos->mChildPerspective.GetUnit() == eStyleUnit_Coord;
}
bool
nsIFrame::ChildrenHavePerspective() const
{
return StyleDisplay()->HasPerspectiveStyle();
return StylePosition()->HasPerspectiveStyle();
}
nsRect
@ -1643,17 +1645,18 @@ inline static bool IsSVGContentWithCSSClip(const nsIFrame *aFrame)
}
bool
nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect,
const nsSize& aSize) const
nsIFrame::GetClipPropClipRect(nsRect* aRect, const nsSize& aSize) const
{
NS_PRECONDITION(aRect, "Must have aRect out parameter");
if (!(aDisp->mClipFlags & NS_STYLE_CLIP_RECT) ||
!(aDisp->IsAbsolutelyPositioned(this) || IsSVGContentWithCSSClip(this))) {
const nsStylePosition* pos = StylePosition();
if (!(pos->mClipFlags & NS_STYLE_CLIP_RECT) ||
!(StyleDisplay()->IsAbsolutelyPositioned(this) ||
IsSVGContentWithCSSClip(this))) {
return false;
}
*aRect = aDisp->mClip;
*aRect = pos->mClip;
if (MOZ_LIKELY(StyleBorder()->mBoxDecorationBreak ==
NS_STYLE_BOX_DECORATION_BREAK_SLICE)) {
// The clip applies to the joined boxes so it's relative the first
@ -1665,10 +1668,10 @@ nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect,
aRect->MoveBy(nsPoint(0, -y));
}
if (NS_STYLE_CLIP_RIGHT_AUTO & aDisp->mClipFlags) {
if (NS_STYLE_CLIP_RIGHT_AUTO & pos->mClipFlags) {
aRect->width = aSize.width - aRect->x;
}
if (NS_STYLE_CLIP_BOTTOM_AUTO & aDisp->mClipFlags) {
if (NS_STYLE_CLIP_BOTTOM_AUTO & pos->mClipFlags) {
aRect->height = aSize.height - aRect->y;
}
return true;
@ -1683,11 +1686,10 @@ nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect,
static bool
ApplyClipPropClipping(nsDisplayListBuilder* aBuilder,
const nsIFrame* aFrame,
const nsStyleDisplay* aDisp,
nsRect* aRect,
DisplayListClipState::AutoSaveRestore& aClipState)
{
if (!aFrame->GetClipPropClipRect(aDisp, aRect, aFrame->GetSize()))
if (!aFrame->GetClipPropClipRect(aRect, aFrame->GetSize()))
return false;
nsRect clipRect = *aRect + aBuilder->ToReferenceFrame(aFrame);
@ -1842,7 +1844,7 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder,
break;
}
default: {
if (childFrame->StyleDisplay()->BackfaceIsHidden()) {
if (childFrame->StylePosition()->BackfaceIsHidden()) {
if (!aTemp->IsEmpty()) {
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder,
aFrame, aTemp, aTemp->GetVisibleRect(), aIndex++));
@ -1933,6 +1935,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
return;
const nsStyleDisplay* disp = StyleDisplay();
const nsStylePosition* pos = StylePosition();
// We can stop right away if this is a zero-opacity stacking context and
// we're painting, and we're not animating opacity. Don't do this
// if we're going to compute plugin geometry, since opacity-0 plugins
@ -1941,13 +1944,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
StyleVisibility()->GetEffectivePointerEvents(this) != NS_STYLE_POINTER_EVENTS_NONE;
if (disp->mOpacity == 0.0 && aBuilder->IsForPainting() &&
!aBuilder->WillComputePluginGeometry() &&
!(disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) &&
!(pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) &&
!nsLayoutUtils::HasAnimations(mContent, eCSSProperty_opacity) &&
!needEventRegions) {
return;
}
if (disp->mWillChangeBitField != 0) {
if (pos->mWillChangeBitField != 0) {
aBuilder->AddToWillChangeBudget(this, GetSize());
}
@ -2027,7 +2030,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
CheckForApzAwareEventHandlers(aBuilder, this);
nsRect clipPropClip;
if (ApplyClipPropClipping(aBuilder, this, disp, &clipPropClip,
if (ApplyClipPropClipping(aBuilder, this, &clipPropClip,
nestedClipState)) {
dirtyRect.IntersectRect(dirtyRect, clipPropClip);
}
@ -2349,7 +2352,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|| child->IsTransformed()
// strictly speaking, 'perspective' doesn't require visual atomicity,
// but the spec says it acts like the rest of these
|| disp->mChildPerspective.GetUnit() == eStyleUnit_Coord
|| pos->mChildPerspective.GetUnit() == eStyleUnit_Coord
|| disp->mMixBlendMode != NS_STYLE_BLEND_NORMAL
|| nsSVGIntegrationUtils::UsingEffectsForFrame(child)
|| (child->GetStateBits() & NS_FRAME_HAS_VR_CONTENT);
@ -2358,15 +2361,15 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
bool isStackingContext =
(isPositioned && (disp->mPosition == NS_STYLE_POSITION_STICKY ||
pos->mZIndex.GetUnit() == eStyleUnit_Integer)) ||
(disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) ||
(pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) ||
disp->mIsolation != NS_STYLE_ISOLATION_AUTO ||
isVisuallyAtomic || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
if (isVisuallyAtomic || isPositioned || (!isSVG && disp->IsFloating(child)) ||
((disp->mClipFlags & NS_STYLE_CLIP_RECT) &&
((pos->mClipFlags & NS_STYLE_CLIP_RECT) &&
IsSVGContentWithCSSClip(child)) ||
disp->mIsolation != NS_STYLE_ISOLATION_AUTO ||
(disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) ||
(pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT) ||
(aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
// If you change this, also change IsPseudoStackingContextFromStyle()
pseudoStackingContext = true;
@ -2410,7 +2413,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
aBuilder->DisplayCaret(child, dirty, &list);
} else {
nsRect clipRect;
if (ApplyClipPropClipping(aBuilder, child, disp, &clipRect, clipState)) {
if (ApplyClipPropClipping(aBuilder, child, &clipRect, clipState)) {
// clipRect is in builder-reference-frame coordinates,
// dirty/clippedDirtyRect are in child coordinates
dirty.IntersectRect(dirty, clipRect);
@ -7282,7 +7285,7 @@ UnionBorderBoxes(nsIFrame* aFrame, bool aApplyTransform,
nsRect clipPropClipRect;
bool hasClipPropClip =
aFrame->GetClipPropClipRect(disp, &clipPropClipRect, bounds.Size());
aFrame->GetClipPropClipRect(&clipPropClipRect, bounds.Size());
// Iterate over all children except pop-ups.
const nsIFrame::ChildListIDs skip(nsIFrame::kPopupList |
@ -7524,7 +7527,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
// Absolute position clipping
nsRect clipPropClipRect;
bool hasClipPropClip = GetClipPropClipRect(disp, &clipPropClipRect, aNewSize);
bool hasClipPropClip = GetClipPropClipRect(&clipPropClipRect, aNewSize);
if (hasClipPropClip) {
NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
nsRect& o = aOverflowAreas.Overflow(otype);
@ -8801,7 +8804,8 @@ nsIFrame::IsPseudoStackingContextFromStyle() {
return disp->mOpacity != 1.0f ||
disp->IsPositioned(this) ||
disp->IsFloating(this) ||
(disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_STACKING_CONTEXT);
(StylePosition()->mWillChangeBitField &
NS_STYLE_WILL_CHANGE_STACKING_CONTEXT);
}
Element*

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

@ -3011,8 +3011,8 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
dirtyRect = ExpandRectToNearlyVisible(dirtyRect);
}
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) {
const nsStylePosition* pos = mOuter->StylePosition();
if (pos && (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) {
aBuilder->AddToWillChangeBudget(mOuter, GetScrollPositionClampingScrollPortSize());
}
@ -4360,8 +4360,8 @@ ScrollFrameHelper::IsScrollbarOnRight() const
bool
ScrollFrameHelper::IsMaybeScrollingActive() const
{
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) {
const nsStylePosition* pos = mOuter->StylePosition();
if (pos && (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) {
return true;
}
@ -4373,9 +4373,9 @@ ScrollFrameHelper::IsMaybeScrollingActive() const
bool
ScrollFrameHelper::IsScrollingActive(nsDisplayListBuilder* aBuilder) const
{
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL) &&
aBuilder->IsInWillChangeBudget(mOuter)) {
const nsStylePosition* pos = mOuter->StylePosition();
if (pos && (pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL) &&
aBuilder->IsInWillChangeBudget(mOuter)) {
return true;
}

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

@ -2631,8 +2631,7 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty()))
* rect, with coordinates relative to this frame's origin. aRect must not be
* null!
*/
bool GetClipPropClipRect(const nsStyleDisplay* aDisp, nsRect* aRect,
const nsSize& aSize) const;
bool GetClipPropClipRect(nsRect* aRect, const nsSize& aSize) const;
/**
* Check if this frame is focusable and in the current tab order.

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

@ -3267,7 +3267,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo
if (pfd->mRecomputeOverflow ||
frame->StyleContext()->HasTextDecorationLines()) {
nsTextFrame* f = static_cast<nsTextFrame*>(frame);
r = f->RecomputeOverflow(*mBlockReflowState);
r = f->RecomputeOverflow(mBlockReflowState->frame);
}
frame->FinishAndStoreOverflow(r, frame->GetSize());
}

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

@ -8672,7 +8672,7 @@ nsTextFrame::TrimTrailingWhiteSpace(nsRenderingContext* aRC)
}
nsOverflowAreas
nsTextFrame::RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState)
nsTextFrame::RecomputeOverflow(nsIFrame* aBlockFrame)
{
nsRect bounds(nsPoint(0, 0), GetSize());
nsOverflowAreas result(bounds, bounds);
@ -8701,8 +8701,7 @@ nsTextFrame::RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState)
}
nsRect &vis = result.VisualOverflow();
vis.UnionRect(vis, boundingBox);
UnionAdditionalOverflow(PresContext(), aBlockReflowState.frame, provider,
&vis, true);
UnionAdditionalOverflow(PresContext(), aBlockFrame, provider, &vis, true);
return result;
}
@ -8997,18 +8996,9 @@ nsTextFrame::HasAnyNoncollapsedCharacters()
bool
nsTextFrame::UpdateOverflow()
{
const nsRect rect(nsPoint(0, 0), GetSize());
nsOverflowAreas overflowAreas(rect, rect);
if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
return false;
}
gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
if (!mTextRun) {
return false;
}
PropertyProvider provider(this, iter, nsTextFrame::eInflated);
provider.InitializeForDisplay(true);
nsIFrame* decorationsBlock;
if (IsFloatingFirstLetterChild()) {
@ -9030,8 +9020,8 @@ nsTextFrame::UpdateOverflow()
}
}
UnionAdditionalOverflow(PresContext(), decorationsBlock, provider,
&overflowAreas.VisualOverflow(), true);
nsOverflowAreas overflowAreas = RecomputeOverflow(decorationsBlock);
return FinishAndStoreOverflow(overflowAreas, GetSize());
}

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

@ -252,8 +252,7 @@ public:
uint32_t aSkippedStartOffset = 0,
uint32_t aSkippedMaxLength = UINT32_MAX) MOZ_OVERRIDE;
nsOverflowAreas
RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState);
nsOverflowAreas RecomputeOverflow(nsIFrame* aBlockFrame);
enum TextRunType {
// Anything in reflow (but not intrinsic width calculation) or

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

@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html><head>
<style>
fieldset { padding:0; }
span { display:block; width:10px; height:10px; background:lime; }
.contents { }
legend { border: 1px solid; }
.test2 legend { }
.test2 legend::after, .test3 legend::after { content:"legend"; }
.test2 legend.static, .test3 legend.static { display:block; }
.test2 legend.static::before, .test3 legend.static::before { content:"static "; }
.test2 legend.static::before { content:"static "; }
.after::after { content:"::after"; }
.before::before { content:"::before"; }
.nb legend.static { border: 1px solid; }
.nb legend { border-style:none; }
.p0 legend { padding:0; }
</style>
</head>
<body>
<fieldset><div class="test contents"></div></fieldset>
<fieldset><div class="test contents">x</div></fieldset>
<fieldset><div class="test contents after"></div></fieldset>
<fieldset><div class="test contents before"></div></fieldset>
<fieldset><div class="test contents before after"></div></fieldset>
<fieldset><legend class="test contents"></legend></fieldset>
<fieldset><legend class="test contents" style="padding:0"></legend></fieldset>
<fieldset><legend class="contents"><div class="test contents"></div></legend></fieldset>
<fieldset class="test2"></fieldset>
<fieldset class="test2 after"></fieldset>
<fieldset class="test2"><legend class="static"></legend></fieldset>
<fieldset class="test2"><legend class="static contents"></legend></fieldset>
<fieldset class="test2"><legend class="static" style="padding:0"></legend></fieldset>
<fieldset class="test2 p0"></fieldset>
<fieldset class="test2 p0"></fieldset>
<fieldset class="test2 p0"><legend class="static"></legend></fieldset>
<fieldset class="test2 p0"><legend class="static"></legend></fieldset>
<script>
document.body.offsetHeight;
var tests = document.querySelectorAll('.test');
for (i=0; i < tests.length; ++i) {
test = tests[i];
test.appendChild(document.createElement('span'));
}
var tests = document.querySelectorAll('.test2,.test3');
for (i=0; i < tests.length; ++i) {
test = tests[i];
test.appendChild(document.createElement('legend'));
}
</script>
</body>
</html>

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

@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html><head>
<style>
fieldset { padding:0; }
span { display:block; width:10px; height:10px; background:lime; }
.contents { display: contents; }
legend { border: 1px solid; }
.test2 legend { display:contents; }
.test2 legend::after, .test3 legend::after { content:"legend"; }
.test2 legend.static, .test3 legend.static { display:block; }
.test2 legend.static::before, .test3 legend.static::before { content:"static "; }
.after::after { content:"::after"; }
.before::before { content:"::before"; }
</style>
</head>
<body>
<fieldset><div class="test contents"></div></fieldset>
<fieldset><div class="test contents">x</div></fieldset>
<fieldset><div class="test contents after"></div></fieldset>
<fieldset><div class="test contents before"></div></fieldset>
<fieldset><div class="test contents before after"></div></fieldset>
<fieldset><legend class="test contents"></legend></fieldset>
<fieldset><div class="contents"><legend class="test contents"></legend></div></fieldset>
<fieldset><legend class="contents"><div class="test contents"></div></legend></fieldset>
<fieldset class="test2"></fieldset>
<fieldset class="test2 after"></fieldset>
<fieldset class="test2"><legend class="static"></legend></fieldset>
<fieldset class="test2"><legend class="static contents"></legend></fieldset>
<fieldset class="test2"><div class="contents"><legend class="static"></legend></div></fieldset>
<fieldset><div class="test2 contents"></div></fieldset>
<fieldset><div class="test3 contents"></div></fieldset>
<fieldset><div class="test2 contents"><legend class="static"></legend></div></fieldset>
<fieldset><div class="test3 contents"><legend class="static"></legend></div></fieldset>
<script>
document.body.offsetHeight;
var tests = document.querySelectorAll('.test');
for (i=0; i < tests.length; ++i) {
test = tests[i];
test.appendChild(document.createElement('span'));
}
var tests = document.querySelectorAll('.test2,.test3');
for (i=0; i < tests.length; ++i) {
test = tests[i];
test.appendChild(document.createElement('legend'));
}
</script>
</body>
</html>

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

@ -22,3 +22,4 @@ skip-if(B2G) pref(layout.css.display-contents.enabled,true) == display-contents-
skip-if(B2G) asserts(1) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-3.xul display-contents-xbl-3-ref.xul # bug 1089223
skip pref(layout.css.display-contents.enabled,true) == display-contents-xbl-4.xul display-contents-xbl-4-ref.xul # fails (not just asserts) due to bug 1089223
skip-if(B2G) asserts(1) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-5.xul display-contents-xbl-3-ref.xul # bug 1089223
asserts(0-1) pref(layout.css.display-contents.enabled,true) == display-contents-fieldset.html display-contents-fieldset-ref.html # bug 1089223

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1114329 testcase</title>
</head>
<body>
<div style="width:0px;height:0px;overflow:visible">
<div style="width:100px;height:120px;background:rgba(0,255,0,0.8);display:inline-block;position:relative;left:200px;"></div>
</div>
<div style="width:0px;height:0px;overflow:visible">
<div style="width:100px;height:150px;background:rgba(255,0,0,0.8);display:inline-block;position:relative;left:100px;"></div>
</div>
<div style="background:silver;padding-right:calc(100% - 100px);">
This text should appear to the LEFT of the red and green blocks.
</div>
</body>
</html>

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