import changes from rmottola/Arctic-Fox:

- Bug 1140767 - Build more files in security/manager in unified mode; r=dkeeler (11ab39c46)
- Bug 1141864. Replace a bunch nsAutoPtr.h includes with nsRefPtr.h (Adapted) (ce31bfbcc)
- Bug 1141689 - use services::GetObserverService more; r=ehsan (22e6fcf7e)
- Bug 1140162 - IPC Proxy for TextAttributes and DefaultTextAttributes, r=tbsaunde (31bb06b0d)
- Bug 1140499 - IPC Proxy for text/char bounds, r=tbsaunde (5441444db)
- Bug 1140534 - IPC Proxy for offsetAtPoint, r=tbsaunde (24ca5c668)
- Bug 1140895 - IPC Proxy for get/set/add/remove Selection, r=tbsaunde (35d3364b8)
- Bug 1140900 - IPC Proxy for ScrollSubstringTo*, r=tbsaunde (1f7de020f)
- Bug 1140917 - IPC Proxy for replace/insert/copy/cut/delete/paste, r=tbsaunde (b6fe2db79)
- Bug 1140917 followup: add missing MOZ_OVERRIDE annotations on new DocAccessibleChild method-decls. r=ehsan (47cce9086)
- Pointer style (b63b44d0a)
- Bug 1140636 - Test CPOW function identity. r=billm (6ada9597c)
- Bug 1134006 - Avoid IPC for domElement.QueryInterface(nsISupports) and nsIClassInfo. r=billm (753758b63)
- Bug 1096488 - Detect and handle switching from remote to non-remote pages and back in marionette.;r=automatedtester (048279bd5)
- Bug 1096488 - Test that switching browser remoteness leaves marionette in a usable state.;r=automatedtester (207aabadb)
- Bug 1138650 - Update remaining callsites to use newChannel2 in toolkit/devtools (r=jryans) (a4ffc704e)
- Bug 1138648 - Update remaining callsites to use newChannel2 in netwerk/ (r=sworkman) (cdf6612a9)
- bug 1135160 - implement link rel=preconnect r=smaug (cfac502ce)
- bug 1135160 - ioservice have speculative connect use proxy-resolve2() r=hurley (238b58f84)
- Bug 1140788 - Set headers to immutable. r=bkelly,ehsan (c48c12acf)
- Bug 1137037 - Determine the inner window ID in imgRequest::Init. r=baku (12aa73a7c)
- Bug 1137019 (Part 1) - Get rid of unused LockImage forwarding methods on imgRequest. r=baku (6ed5c7d25)
- Bug 1137019 (Part 2) - Replace imgRequest's image decoding methods with a single minimal method that updates an atomic. r=baku (adeb8797c)
This commit is contained in:
2019-11-16 06:50:18 +08:00
parent df039285e5
commit f9e56e1ed1
61 changed files with 1827 additions and 483 deletions
+59 -45
View File
@@ -9,7 +9,7 @@
#include "Accessible-inl.h"
#include "HyperTextAccessible-inl.h"
#include "nsMai.h"
#include "ProxyAccessible.h"
#include "nsString.h"
#include "mozilla/Likely.h"
@@ -20,15 +20,18 @@ static void
setTextContentsCB(AtkEditableText *aText, const gchar *aString)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
NS_ConvertUTF8toUTF16 strContent(aString);
text->ReplaceText(strContent);
NS_ConvertUTF8toUTF16 strContent(aString);
text->ReplaceText(strContent);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
NS_ConvertUTF8toUTF16 strContent(aString);
proxy->ReplaceText(strContent);
}
}
static void
@@ -36,71 +39,82 @@ insertTextCB(AtkEditableText *aText,
const gchar *aString, gint aLength, gint *aPosition)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
NS_ConvertUTF8toUTF16 strContent(aString, aLength);
text->InsertText(strContent, *aPosition);
NS_ConvertUTF8toUTF16 strContent(aString);
text->InsertText(strContent, *aPosition);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
NS_ConvertUTF8toUTF16 strContent(aString);
proxy->InsertText(strContent, *aPosition);
}
}
static void
copyTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->CopyText(aStartPos, aEndPos);
text->CopyText(aStartPos, aEndPos);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
proxy->CopyText(aStartPos, aEndPos);
}
}
static void
cutTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->CutText(aStartPos, aEndPos);
text->CutText(aStartPos, aEndPos);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
proxy->CutText(aStartPos, aEndPos);
}
}
static void
deleteTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->DeleteText(aStartPos, aEndPos);
text->DeleteText(aStartPos, aEndPos);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
proxy->DeleteText(aStartPos, aEndPos);
}
}
static void
pasteTextCB(AtkEditableText *aText, gint aPosition)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
text->PasteText(aPosition);
text->PasteText(aPosition);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
proxy->PasteText(aPosition);
}
}
}
+211 -113
View File
@@ -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 goanna 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 goanna 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
@@ -240,38 +266,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 +326,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) {
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
} else {
giabbaCoordType = 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, goannaCoordType);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
rect = proxy->CharBounds(aOffset, goannaCoordType);
} else {
return;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return;
uint32_t goannaCoordType;
if (aCoords == ATK_XY_SCREEN)
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
nsIntRect rect = text->CharBounds(aOffset, goannaCoordType);
*aX = rect.x;
*aY = rect.y;
*aWidth = rect.width;
@@ -305,21 +362,32 @@ static void
getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset,
AtkCoordType aCoords, AtkTextRectangle *aRect)
{
if (!aRect) {
return;
}
nsIntRect rect;
uint32_t goannaCoordType;
if (aCoords == ATK_XY_SCREEN) {
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
} else {
goannaCoordType = 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 goannaCoordType;
if (aCoords == ATK_XY_SCREEN)
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
else
goannaCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
nsIntRect rect = text->TextBounds(aStartOffset, aEndOffset, goannaCoordType);
aRect->x = rect.x;
aRect->y = rect.y;
aRect->width = rect.width;
@@ -349,18 +417,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
@@ -388,20 +466,28 @@ getTextSelectionCB(AtkText *aText, gint aSelectionNum,
gint *aStartOffset, gint *aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return nullptr;
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return nullptr;
int32_t startOffset = 0, endOffset = 0;
text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset);
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return nullptr;
}
text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
return getTextCB(aText, *aStartOffset, *aEndOffset);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
nsString data;
proxy->SelectionBoundsAt(aSelectionNum, data, &startOffset, &endOffset);
*aStartOffset = startOffset;
*aEndOffset = endOffset;
NS_ConvertUTF16toUTF8 dataAsUTF8(data);
return (dataAsUTF8.get()) ? g_strdup(dataAsUTF8.get()) : nullptr;
}
return nullptr;
}
// set methods
@@ -411,14 +497,18 @@ addTextSelectionCB(AtkText *aText,
gint aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return FALSE;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return FALSE;
return text->AddToSelection(aStartOffset, aEndOffset);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
return proxy->AddToSelection(aStartOffset, aEndOffset);
}
return text->AddToSelection(aStartOffset, aEndOffset);
return FALSE;
}
static gboolean
@@ -426,14 +516,18 @@ removeTextSelectionCB(AtkText *aText,
gint aSelectionNum)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return FALSE;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return FALSE;
return text->RemoveFromSelection(aSelectionNum);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
return proxy->RemoveFromSelection(aSelectionNum);
}
return text->RemoveFromSelection(aSelectionNum);
return FALSE;
}
static gboolean
@@ -441,14 +535,18 @@ setTextSelectionCB(AtkText *aText, gint aSelectionNum,
gint aStartOffset, gint aEndOffset)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
if (!accWrap)
return FALSE;
if (accWrap) {
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole()) {
return FALSE;
}
HyperTextAccessible* text = accWrap->AsHyperText();
if (!text || !text->IsTextRole())
return FALSE;
return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
return proxy->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
}
return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
return FALSE;
}
static gboolean
+262 -3
View File
@@ -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;
@@ -292,5 +299,257 @@ DocAccessibleChild::RecvGetTextBeforeOffset(const uint64_t& aID,
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;
}
bool
DocAccessibleChild::RecvSelectionBoundsAt(const uint64_t& aID,
const int32_t& aSelectionNum,
bool* aSucceeded,
nsString* aData,
int32_t* aStartOffset,
int32_t* aEndOffset)
{
*aSucceeded = false;
*aStartOffset = 0;
*aEndOffset = 0;
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
*aSucceeded =
acc->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
if (*aSucceeded) {
acc->TextSubstring(*aStartOffset, *aEndOffset, *aData);
}
}
return true;
}
bool
DocAccessibleChild::RecvSetSelectionBoundsAt(const uint64_t& aID,
const int32_t& aSelectionNum,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
bool* aSucceeded)
{
*aSucceeded = false;
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
*aSucceeded =
acc->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
}
return true;
}
bool
DocAccessibleChild::RecvAddToSelection(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
bool* aSucceeded)
{
*aSucceeded = false;
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
*aSucceeded = acc->AddToSelection(aStartOffset, aEndOffset);
}
return true;
}
bool
DocAccessibleChild::RecvRemoveFromSelection(const uint64_t& aID,
const int32_t& aSelectionNum,
bool* aSucceeded)
{
*aSucceeded = false;
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
*aSucceeded = acc->RemoveFromSelection(aSelectionNum);
}
return true;
}
bool
DocAccessibleChild::RecvScrollSubstringTo(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
const uint32_t& aScrollType)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc) {
acc->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
}
return true;
}
bool
DocAccessibleChild::RecvScrollSubstringToPoint(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
const uint32_t& aCoordinateType,
const int32_t& aX,
const int32_t& aY)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc) {
acc->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType,
aX, aY);
}
return true;
}
bool
DocAccessibleChild::RecvReplaceText(const uint64_t& aID,
const nsString& aText)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
acc->ReplaceText(aText);
}
return true;
}
bool
DocAccessibleChild::RecvInsertText(const uint64_t& aID,
const nsString& aText,
const int32_t& aPosition)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
acc->InsertText(aText, aPosition);
}
return true;
}
bool
DocAccessibleChild::RecvCopyText(const uint64_t& aID,
const int32_t& aStartPos,
const int32_t& aEndPos)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
acc->CopyText(aStartPos, aEndPos);
}
return true;
}
bool
DocAccessibleChild::RecvCutText(const uint64_t& aID,
const int32_t& aStartPos,
const int32_t& aEndPos)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
acc->CutText(aStartPos, aEndPos);
}
return true;
}
bool
DocAccessibleChild::RecvDeleteText(const uint64_t& aID,
const int32_t& aStartPos,
const int32_t& aEndPos)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
acc->DeleteText(aStartPos, aEndPos);
}
return true;
}
bool
DocAccessibleChild::RecvPasteText(const uint64_t& aID,
const int32_t& aPosition)
{
HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
if (acc && acc->IsTextRole()) {
acc->PasteText(aPosition);
}
return true;
}
}
}
+88
View File
@@ -90,7 +90,95 @@ public:
nsString* aText, int32_t* aStartOffset,
int32_t* aEndOffset) override;
virtual bool RecvTextAttributes(const uint64_t& aID,
const bool& aIncludeDefAttrs,
const int32_t& aOffset,
nsTArray<Attribute>* aAttributes,
int32_t* aStartOffset,
int32_t* aEndOffset)
override;
virtual bool RecvDefaultTextAttributes(const uint64_t& aID,
nsTArray<Attribute>* aAttributes)
override;
virtual bool RecvTextBounds(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
const uint32_t& aCoordType,
nsIntRect* aRetVal) override;
virtual bool RecvCharBounds(const uint64_t& aID,
const int32_t& aOffset,
const uint32_t& aCoordType,
nsIntRect* aRetVal) override;
virtual bool RecvOffsetAtPoint(const uint64_t& aID,
const int32_t& aX,
const int32_t& aY,
const uint32_t& aCoordType,
int32_t* aRetVal) override;
virtual bool RecvSelectionBoundsAt(const uint64_t& aID,
const int32_t& aSelectionNum,
bool* aSucceeded,
nsString* aData,
int32_t* aStartOffset,
int32_t* aEndOffset) override;
virtual bool RecvSetSelectionBoundsAt(const uint64_t& aID,
const int32_t& aSelectionNum,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
bool* aSucceeded) override;
virtual bool RecvAddToSelection(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
bool* aSucceeded) override;
virtual bool RecvRemoveFromSelection(const uint64_t& aID,
const int32_t& aSelectionNum,
bool* aSucceeded) override;
virtual bool RecvScrollSubstringTo(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
const uint32_t& aScrollType) override;
virtual bool RecvScrollSubstringToPoint(const uint64_t& aID,
const int32_t& aStartOffset,
const int32_t& aEndOffset,
const uint32_t& aCoordinateType,
const int32_t& aX,
const int32_t& aY) override;
virtual bool RecvReplaceText(const uint64_t& aID,
const nsString& aText) override;
virtual bool RecvInsertText(const uint64_t& aID,
const nsString& aText,
const int32_t& aPosition) override;
virtual bool RecvCopyText(const uint64_t& aID,
const int32_t& aStartPos,
const int32_t& aEndPos) override;
virtual bool RecvCutText(const uint64_t& aID,
const int32_t& aStartPos,
const int32_t& aEndPos) override;
virtual bool RecvDeleteText(const uint64_t& aID,
const int32_t& aStartPos,
const int32_t& aEndPos) override;
virtual bool RecvPasteText(const uint64_t& aID,
const int32_t& aPosition) override;
private:
bool PersistentPropertiesToArray(nsIPersistentProperties* aProps,
nsTArray<Attribute>* aAttributes);
DocAccessible* mDoc;
};
+41
View File
@@ -6,6 +6,8 @@
include protocol PContent;
using struct nsIntRect from "nsRect.h";
namespace mozilla {
namespace a11y {
@@ -73,8 +75,47 @@ 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 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);
prio(high) sync SelectionBoundsAt(uint64_t aID, int32_t aSelectionNum)
returns(bool aSucceeded, nsString aData, int32_t aStartOffset, int32_t aEndOffset);
prio(high) sync SetSelectionBoundsAt(uint64_t aID, int32_t aSelectionNum,
int32_t aStartOffset, int32_t aEndOffset)
returns(bool aSucceeded);
prio(high) sync AddToSelection(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset)
returns(bool aSucceeded);
prio(high) sync RemoveFromSelection(uint64_t aID, int32_t aSelectionNum)
returns(bool aSucceeded);
ScrollSubstringTo(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
uint32_t aScrollType);
ScrollSubstringToPoint(uint64_t aID,
int32_t aStartOffset,
int32_t aEndOffset,
uint32_t aCoordinateType,
int32_t aX, int32_t aY);
prio(high) sync ReplaceText(uint64_t aID, nsString aText);
prio(high) sync InsertText(uint64_t aID, nsString aText, int32_t aPosition);
prio(high) sync CopyText(uint64_t aID, int32_t aStartPos, int32_t aEndPos);
prio(high) sync CutText(uint64_t aID, int32_t aStartPos, int32_t aEndPos);
prio(high) sync DeleteText(uint64_t aID, int32_t aStartPos, int32_t aEndPos);
prio(high) sync PasteText(uint64_t aID, int32_t aPosition);
};
}
+137
View File
@@ -202,5 +202,142 @@ ProxyAccessible::GetTextBeforeOffset(int32_t aOffset,
&aText, aStartOffset, aEndOffset);
}
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;
}
bool
ProxyAccessible::SelectionBoundsAt(int32_t aSelectionNum,
nsString& aData,
int32_t* aStartOffset,
int32_t* aEndOffset)
{
bool retVal = false;
unused << mDoc->SendSelectionBoundsAt(mID, aSelectionNum, &retVal, &aData,
aStartOffset, aEndOffset);
return retVal;
}
bool
ProxyAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
int32_t aStartOffset,
int32_t aEndOffset)
{
bool retVal = false;
unused << mDoc->SendSetSelectionBoundsAt(mID, aSelectionNum, aStartOffset,
aEndOffset, &retVal);
return retVal;
}
bool
ProxyAccessible::AddToSelection(int32_t aStartOffset,
int32_t aEndOffset)
{
bool retVal = false;
unused << mDoc->SendAddToSelection(mID, aStartOffset, aEndOffset, &retVal);
return retVal;
}
bool
ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum)
{
bool retVal = false;
unused << mDoc->SendRemoveFromSelection(mID, aSelectionNum, &retVal);
return retVal;
}
void
ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aScrollType)
{
unused << mDoc->SendScrollSubstringTo(mID, aStartOffset, aEndOffset, aScrollType);
}
void
ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
int32_t aEndOffset,
uint32_t aCoordinateType,
int32_t aX, int32_t aY)
{
unused << mDoc->SendScrollSubstringToPoint(mID, aStartOffset, aEndOffset,
aCoordinateType, aX, aY);
}
void
ProxyAccessible::ReplaceText(const nsString& aText)
{
unused << mDoc->SendReplaceText(mID, aText);
}
void
ProxyAccessible::InsertText(const nsString& aText, int32_t aPosition)
{
unused << mDoc->SendInsertText(mID, aText, aPosition);
}
void
ProxyAccessible::CopyText(int32_t aStartPos, int32_t aEndPos)
{
unused << mDoc->SendCopyText(mID, aStartPos, aEndPos);
}
void
ProxyAccessible::CutText(int32_t aStartPos, int32_t aEndPos)
{
unused << mDoc->SendCutText(mID, aStartPos, aEndPos);
}
void
ProxyAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos)
{
unused << mDoc->SendDeleteText(mID, aStartPos, aEndPos);
}
void
ProxyAccessible::PasteText(int32_t aPosition)
{
unused << mDoc->SendPasteText(mID, aPosition);
}
}
}
+49
View File
@@ -11,6 +11,7 @@
#include "nsIAccessibleText.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsRect.h"
namespace mozilla {
namespace a11y {
@@ -120,6 +121,54 @@ public:
nsString& aText, int32_t* aStartOffset,
int32_t* aEndOffset);
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);
bool SelectionBoundsAt(int32_t aSelectionNum,
nsString& aData,
int32_t* aStartOffset,
int32_t* aEndOffset);
bool SetSelectionBoundsAt(int32_t aSelectionNum,
int32_t aStartOffset,
int32_t aEndOffset);
bool AddToSelection(int32_t aStartOffset,
int32_t aEndOffset);
bool RemoveFromSelection(int32_t aSelectionNum);
void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
uint32_t aScrollType);
void ScrollSubstringToPoint(int32_t aStartOffset,
int32_t aEndOffset,
uint32_t aCoordinateType,
int32_t aX, int32_t aY);
void ReplaceText(const nsString& aText);
void InsertText(const nsString& aText, int32_t aPosition);
void CopyText(int32_t aStartPos, int32_t aEndPos);
void CutText(int32_t aStartPos, int32_t aEndPos);
void DeleteText(int32_t aStartPos, int32_t aEndPos);
void PasteText(int32_t aPosition);
/**
* Allow the platform to store a pointers worth of data on us.
*/
+2 -1
View File
@@ -10,6 +10,7 @@
#include "nsIGlobalHistory2.h"
#include "nsIObserverService.h"
#include "nsIURI.h"
#include "mozilla/Services.h"
////////////////////////////////////////////////////////////////////////////////
//// nsDownloadHistory
@@ -42,7 +43,7 @@ nsDownloadHistory::AddDownload(nsIURI* aSource,
if (!visited) {
nsCOMPtr<nsIObserverService> os =
do_GetService("@mozilla.org/observer-service;1");
mozilla::services::GetObserverService();
if (os) {
os->NotifyObservers(aSource, NS_LINK_VISITED_EVENT_TOPIC, nullptr);
}
+25
View File
@@ -33,6 +33,7 @@
#include "nsIApplicationCacheContainer.h"
#include "nsIApplicationCacheChannel.h"
#include "nsIScriptSecurityManager.h"
#include "nsISpeculativeConnect.h"
#include "nsICookieService.h"
#include "nsContentUtils.h"
#include "nsNodeInfoManager.h"
@@ -691,6 +692,10 @@ nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
PrefetchDNS(aHref);
}
if (!aHref.IsEmpty() && (linkTypes & nsStyleLinkElement::ePRECONNECT)) {
Preconnect(aHref);
}
// is it a stylesheet link?
if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
return NS_OK;
@@ -868,6 +873,26 @@ nsContentSink::PrefetchDNS(const nsAString &aHref)
}
}
void
nsContentSink::Preconnect(const nsAString &aHref)
{
nsCOMPtr<nsISpeculativeConnect>
speculator(do_QueryInterface(nsContentUtils::GetIOService()));
if (!speculator) {
return;
}
// construct URI using document charset
const nsACString& charset = mDocument->GetDocumentCharacterSet();
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), aHref,
charset.IsEmpty() ? nullptr : PromiseFlatCString(charset).get(),
mDocument->GetDocBaseURI());
if (uri) {
speculator->SpeculativeConnect(uri, nullptr);
}
}
nsresult
nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
nsIURI *aManifestURI,
+3 -2
View File
@@ -164,9 +164,10 @@ protected:
void PrefetchHref(const nsAString &aHref, nsINode *aSource,
bool aExplicit);
// aHref can either be the usual URI format or of the form "//www.hostname.com"
// without a scheme.
// For both PrefetchDNS() and Preconnect() aHref can either be the usual
// URI format or of the form "//www.hostname.com" without a scheme.
void PrefetchDNS(const nsAString &aHref);
void Preconnect(const nsAString &aHref);
// Gets the cache key (used to identify items in a cache) of the channel.
nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
+1 -1
View File
@@ -8995,7 +8995,7 @@ public:
NS_IMETHOD Run()
{
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
services::GetObserverService();
if (observerService) {
nsCOMPtr<nsISupportsPRUint64> wrapper =
do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID);
+2
View File
@@ -150,6 +150,8 @@ static uint32_t ToLinkMask(const nsAString& aLink, nsIPrincipal* aPrincipal)
else if (aLink.EqualsLiteral("import") &&
nsStyleLinkElement::IsImportEnabled())
return nsStyleLinkElement::eHTMLIMPORT;
else if (aLink.EqualsLiteral("preconnect"))
return nsStyleLinkElement::ePRECONNECT;
else
return 0;
}
+2 -1
View File
@@ -59,7 +59,8 @@ public:
eSTYLESHEET = 0x00000004,
eNEXT = 0x00000008,
eALTERNATE = 0x00000010,
eHTMLIMPORT = 0x00000020
eHTMLIMPORT = 0x00000020,
ePRECONNECT = 0x00000040
};
// The return value is a bitwise or of 0 or more RelValues.
+28
View File
@@ -206,9 +206,37 @@
function recvDomTest(message) {
savedElement = message.objects.element;
is(savedElement.QueryInterface(Components.interfaces.nsISupports), savedElement,
"QI to nsISupports works");
is(savedElement.QueryInterface(Components.interfaces.nsIDOMNode), savedElement,
"QI to a random (implemented) interface works");
function testNoInterface(savedElement, i) {
try {
savedElement.QueryInterface(i);
ok(false, "should have thrown an exception");
} catch (e) {
is(e.result, Components.results.NS_ERROR_NO_INTERFACE, "threw the right exception");
}
}
testNoInterface(savedElement, Components.interfaces.nsIDOMAttr);
testNoInterface(savedElement, Components.interfaces.nsIClassInfo);
// Test to ensure that we don't pass CPOWs to C++-implemented interfaces.
// See bug 1072980.
if (test_state == "remote") {
// This doesn't work because we intercept toString and QueryInterface specially
// and don't cache the function pointer.
// See bug 1140636.
todo_is(savedElement.toString, savedElement.toString, "toString identity works");
todo_is(savedElement.QueryInterface, savedElement.QueryInterface, "toString identity works");
// This does work because we create a CPOW for isEqualNode that stays
// alive as long as we have a reference to the first CPOW (so as long
// as it's detectable).
is(savedElement.isEqualNode, savedElement.isEqualNode, "webidl function identity works");
let walker = Components.classes["@mozilla.org/inspector/deep-tree-walker;1"]
.createInstance(Components.interfaces.inIDeepTreeWalker);
const SHOW_ELEMENT = Components.interfaces.nsIDOMNodeFilter.SHOW_ELEMENT;
+3
View File
@@ -31,6 +31,9 @@ public:
NetworkError()
{
nsRefPtr<InternalResponse> response = new InternalResponse(0, EmptyCString());
ErrorResult result;
response->Headers()->SetGuard(HeadersGuardEnum::Immutable, result);
MOZ_ASSERT(!result.Failed());
response->mType = ResponseType::Error;
return response.forget();
}
+2
View File
@@ -112,6 +112,8 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl,
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
r->GetInternalHeaders()->SetGuard(HeadersGuardEnum::Immutable, aRv);
MOZ_ASSERT(!aRv.Failed());
return r.forget();
}
+34
View File
@@ -21,6 +21,7 @@
#include "nsIDOMEvent.h"
#include "nsIDOMStyleSheet.h"
#include "nsINode.h"
#include "nsISpeculativeConnect.h"
#include "nsIStyleSheet.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsIURL.h"
@@ -147,6 +148,10 @@ HTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
aDocument->RegisterPendingLinkUpdate(this);
}
if (IsInComposedDoc()) {
UpdatePreconnect();
}
void (HTMLLinkElement::*update)() = &HTMLLinkElement::UpdateStyleSheetInternal;
nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, update));
@@ -292,6 +297,30 @@ HTMLLinkElement::UpdateImport()
}
}
void
HTMLLinkElement::UpdatePreconnect()
{
// rel type should be preconnect
nsAutoString rel;
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel)) {
return;
}
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
if (!(linkTypes & ePRECONNECT)) {
return;
}
nsCOMPtr<nsISpeculativeConnect>
speculator(do_QueryInterface(nsContentUtils::GetIOService()));
if (speculator) {
nsCOMPtr<nsIURI> uri = GetHrefURI();
if (uri) {
speculator->SpeculativeConnect(uri, nullptr);
}
}
}
nsresult
HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify)
@@ -326,11 +355,16 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
dropSheet = !(linkTypes & nsStyleLinkElement::eSTYLESHEET);
} else if (linkTypes & eHTMLIMPORT) {
UpdateImport();
} else if ((linkTypes & ePRECONNECT) && IsInComposedDoc()) {
UpdatePreconnect();
}
}
if (aName == nsGkAtoms::href) {
UpdateImport();
if (IsInComposedDoc()) {
UpdatePreconnect();
}
}
UpdateStyleSheetInternal(nullptr, nullptr,
+1
View File
@@ -43,6 +43,7 @@ public:
void LinkRemoved();
void UpdateImport();
void UpdatePreconnect();
// nsIDOMEventTarget
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) override;
@@ -15,7 +15,7 @@
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/layers/LayersMessages.h" // for TargetConfig
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc
namespace mozilla {
@@ -15,7 +15,7 @@
#include "mozilla/layers/Effects.h" // for EffectChain
#include "mozilla/mozalloc.h" // for operator delete
#include "nsAString.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsPoint.h" // for nsIntPoint
#include "nsString.h" // for nsAutoCString
+1 -1
View File
@@ -13,7 +13,7 @@
#include "TiledContentHost.h" // for TiledContentHost
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/TextureHost.h" // for TextureHost, etc
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsDebug.h" // for NS_WARNING
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "gfxPlatform.h" // for gfxPlatform
@@ -25,7 +25,7 @@
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE
+1 -1
View File
@@ -18,7 +18,7 @@
#include "mozilla/layers/TextureHost.h" // for TextureHost, etc
#include "mozilla/mozalloc.h" // for operator delete
#include "nsAString.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsPoint.h" // for nsIntPoint
@@ -44,7 +44,7 @@
#include "ipc/ShadowLayerUtils.h"
#include "mozilla/mozalloc.h" // for operator new, etc
#include "nsAppRunner.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_WARNING, NS_RUNTIMEABORT, etc
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
+1 -1
View File
@@ -21,7 +21,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsAString.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
@@ -19,7 +19,7 @@
#include "mozilla/layers/Effects.h" // for EffectChain
#include "mozilla/mozalloc.h" // for operator delete
#include "nsAString.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsMathUtils.h" // for NS_lround
#include "nsPoint.h" // for nsIntPoint
+1 -1
View File
@@ -18,7 +18,7 @@
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "nsAString.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "nsPrintfCString.h" // for nsPrintfCString
#include "mozilla/layers/PTextureParent.h"
#include "mozilla/unused.h"
+4 -10
View File
@@ -28,7 +28,6 @@
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIFileURL.h"
#include "nsCRT.h"
#include "nsIDocument.h"
#include "nsINetworkPredictor.h"
#include "nsIApplicationCache.h"
@@ -403,7 +402,7 @@ private:
nsTArray<ImageMemoryCounter>* aArray,
bool aIsUsed)
{
nsRefPtr<Image> image = aRequest->GetImage();
auto image = static_cast<Image*>(aRequest->mImage.get());
if (!image) {
return;
}
@@ -433,7 +432,7 @@ private:
}
nsRefPtr<imgRequest> req = aEntry->GetRequest();
nsRefPtr<Image> image = req->GetImage();
auto image = static_cast<Image*>(req->mImage.get());
if (!image) {
return PL_DHASH_NEXT;
}
@@ -2141,12 +2140,6 @@ nsresult imgLoader::LoadImage(nsIURI *aURI,
timedChannel->SetInitiatorType(initiatorType);
}
// Pass the inner window ID of the loading document, if possible.
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aCX);
if (doc) {
request->SetInnerWindowID(doc->InnerWindowID());
}
// create the proxy listener
nsCOMPtr<nsIStreamListener> pl = new ProxyListener(request.get());
@@ -2791,7 +2784,8 @@ NS_IMPL_ISUPPORTS(imgCacheValidator, nsIStreamListener, nsIRequestObserver,
imgCacheValidator::imgCacheValidator(nsProgressNotificationProxy* progress,
imgLoader* loader, imgRequest *request,
void *aContext, bool forcePrincipalCheckForCacheEntry)
nsISupports* aContext,
bool forcePrincipalCheckForCacheEntry)
: mProgressProxy(progress),
mRequest(request),
mContext(aContext),
+3 -2
View File
@@ -517,7 +517,8 @@ class imgCacheValidator : public nsIStreamListener,
{
public:
imgCacheValidator(nsProgressNotificationProxy* progress, imgLoader* loader,
imgRequest *request, void *aContext, bool forcePrincipalCheckForCacheEntry);
imgRequest* aRequest, nsISupports* aContext,
bool forcePrincipalCheckForCacheEntry);
void AddProxy(imgRequestProxy *aProxy);
void RemoveProxy(imgRequestProxy* aProxy);
@@ -544,7 +545,7 @@ private:
nsRefPtr<imgRequest> mNewRequest;
nsRefPtr<imgCacheEntry> mNewEntry;
void *mContext;
nsCOMPtr<nsISupports> mContext;
imgLoader* mImgLoader;
};
+35 -112
View File
@@ -18,6 +18,7 @@
#include "nsIChannel.h"
#include "nsICachingChannel.h"
#include "nsIDocument.h"
#include "nsIThreadRetargetableRequest.h"
#include "nsIInputStream.h"
#include "nsIMultiPartChannel.h"
@@ -66,7 +67,6 @@ imgRequest::imgRequest(imgLoader* aLoader)
: mLoader(aLoader)
, mProgressTracker(new ProgressTracker())
, mValidator(nullptr)
, mMutex("imgRequest")
, mInnerWindowId(0)
, mCORSMode(imgIRequest::CORS_NONE)
, mReferrerPolicy(mozilla::net::RP_Default)
@@ -96,7 +96,7 @@ nsresult imgRequest::Init(nsIURI *aURI,
nsIRequest *aRequest,
nsIChannel *aChannel,
imgCacheEntry *aCacheEntry,
void *aLoadId,
nsISupports* aCX,
nsIPrincipal* aLoadingPrincipal,
int32_t aCORSMode,
ReferrerPolicy aReferrerPolicy)
@@ -133,7 +133,13 @@ nsresult imgRequest::Init(nsIURI *aURI,
mCacheEntry = aCacheEntry;
SetLoadId(aLoadId);
SetLoadId(aCX);
// Grab the inner window ID of the loading document, if possible.
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aCX);
if (doc) {
mInnerWindowId = doc->InnerWindowID();
}
return NS_OK;
}
@@ -142,20 +148,9 @@ void imgRequest::ClearLoader() {
mLoader = nullptr;
}
already_AddRefed<Image>
imgRequest::GetImage()
{
MutexAutoLock lock(mMutex);
nsRefPtr<Image> image = mImage;
return image.forget();
}
already_AddRefed<ProgressTracker>
imgRequest::GetProgressTracker()
{
MutexAutoLock lock(mMutex);
if (mImage) {
MOZ_ASSERT(!mProgressTracker,
"Should have given mProgressTracker to mImage");
@@ -169,20 +164,6 @@ imgRequest::GetProgressTracker()
}
}
void
imgRequest::SetImage(Image* aImage)
{
MutexAutoLock lock(mMutex);
mImage = aImage;
}
void
imgRequest::SetProgressTracker(ProgressTracker* aProgressTracker)
{
MutexAutoLock lock(mMutex);
mProgressTracker = aProgressTracker;
}
void imgRequest::SetCacheEntry(imgCacheEntry *entry)
{
mCacheEntry = entry;
@@ -485,8 +466,7 @@ void imgRequest::SetIsInCache(bool incache)
void imgRequest::UpdateCacheEntrySize()
{
if (mCacheEntry) {
nsRefPtr<Image> image = GetImage();
size_t size = image->SizeOfSourceWithComputedFallback(moz_malloc_size_of);
size_t size = mImage->SizeOfSourceWithComputedFallback(moz_malloc_size_of);
mCacheEntry->SetDataSize(size);
}
}
@@ -616,50 +596,6 @@ imgRequest::CacheChanged(nsIRequest* aNewRequest)
return true;
}
nsresult
imgRequest::LockImage()
{
nsRefPtr<Image> image = GetImage();
return image->LockImage();
}
nsresult
imgRequest::UnlockImage()
{
nsRefPtr<Image> image = GetImage();
return image->UnlockImage();
}
nsresult
imgRequest::RequestDecode()
{
// If we've initialized our image, we can request a decode.
nsRefPtr<Image> image = GetImage();
if (image) {
return image->RequestDecode();
}
// Otherwise, flag to do it when we get the image
mDecodeRequested = true;
return NS_OK;
}
nsresult
imgRequest::StartDecoding()
{
// If we've initialized our image, we can request a decode.
nsRefPtr<Image> image = GetImage();
if (image) {
return image->StartDecoding();
}
// Otherwise, flag to do it when we get the image
mDecodeRequested = true;
return NS_OK;
}
/** nsIRequestObserver methods **/
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
@@ -679,8 +615,7 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
}
// If we're not multipart, we shouldn't have an image yet
nsRefPtr<Image> image = GetImage();
if (image && !mIsMultiPartChannel) {
if (mImage && !mIsMultiPartChannel) {
MOZ_ASSERT_UNREACHABLE("Already have an image for a non-multipart request");
Cancel(NS_IMAGELIB_ERROR_FAILURE);
return NS_ERROR_FAILURE;
@@ -776,8 +711,7 @@ NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt,
mpchan->GetIsLastPart(&lastPart);
bool isPartial = false;
nsRefPtr<Image> image = GetImage();
if (image && (status == NS_ERROR_NET_PARTIAL_TRANSFER)) {
if (mImage && (status == NS_ERROR_NET_PARTIAL_TRANSFER)) {
isPartial = true;
status = NS_OK; // fake happy face
}
@@ -785,8 +719,8 @@ NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt,
// Tell the image that it has all of the source data. Note that this can
// trigger a failure, since the image might be waiting for more non-optional
// data and this is the point where we break the news that it's not coming.
if (image) {
nsresult rv = image->OnImageDataComplete(aRequest, ctxt, status, lastPart);
if (mImage) {
nsresult rv = mImage->OnImageDataComplete(aRequest, ctxt, status, lastPart);
// If we got an error in the OnImageDataComplete() call, we don't want to
// proceed as if nothing bad happened. However, we also want to give
@@ -798,7 +732,7 @@ NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt,
// If the request went through, update the cache entry size. Otherwise,
// cancel the request, which removes us from the cache.
if (image && NS_SUCCEEDED(status) && !isPartial) {
if (mImage && NS_SUCCEEDED(status) && !isPartial) {
// We update the cache entry size here because this is where we finish
// loading compressed source data, which is part of our size calculus.
UpdateCacheEntrySize();
@@ -815,7 +749,7 @@ NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt,
this->Cancel(status);
}
if (!image) {
if (!mImage) {
// We have to fire the OnStopRequest notifications ourselves because there's
// no image capable of doing so.
Progress progress =
@@ -861,7 +795,6 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
nsresult rv;
mGotData = true;
nsRefPtr<Image> image = GetImage();
if (mNewPartPending) {
LOG_SCOPE(GetImgLog(), "imgRequest::OnDataAvailable |New part; finding MIME type|");
@@ -902,7 +835,7 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
mContentType = newType;
SetProperties(chan);
bool firstPart = !image;
bool firstPart = !mImage;
LOG_MSG_WITH_PARAM(GetImgLog(), "imgRequest::OnDataAvailable", "content type", mContentType.get());
@@ -910,44 +843,34 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
// the data and dispatch back to the main thread, AND tell the channel to
// dispatch there in the future.
nsRefPtr<ProgressTracker> progressTracker;
{
MutexAutoLock lock(mMutex);
progressTracker = mProgressTracker;
}
// Create the new image and give it ownership of our ProgressTracker.
if (mIsMultiPartChannel) {
// Create the ProgressTracker and image for this part.
nsRefPtr<ProgressTracker> partProgressTracker = new ProgressTracker();
nsRefPtr<Image> partImage =
ImageFactory::CreateImage(aRequest, partProgressTracker, mContentType,
nsRefPtr<ProgressTracker> progressTracker = new ProgressTracker();
nsRefPtr<Image> image =
ImageFactory::CreateImage(aRequest, progressTracker, mContentType,
mURI, /* aIsMultipart = */ true,
static_cast<uint32_t>(mInnerWindowId));
if (!image) {
if (!mImage) {
// First part for a multipart channel. Create the MultipartImage wrapper.
MOZ_ASSERT(progressTracker, "Shouldn't have given away tracker yet");
image = new MultipartImage(partImage, progressTracker);
SetImage(image);
progressTracker = nullptr;
SetProgressTracker(nullptr);
MOZ_ASSERT(mProgressTracker, "Shouldn't have given away tracker yet");
mImage = new MultipartImage(image, mProgressTracker);
mProgressTracker = nullptr;
} else {
// Transition to the new part.
static_cast<MultipartImage*>(image.get())->BeginTransitionToPart(partImage);
static_cast<MultipartImage*>(mImage.get())->BeginTransitionToPart(image);
}
} else {
MOZ_ASSERT(!image, "New part for non-multipart channel?");
MOZ_ASSERT(progressTracker, "Shouldn't have given away tracker yet");
MOZ_ASSERT(!mImage, "New part for non-multipart channel?");
MOZ_ASSERT(mProgressTracker, "Shouldn't have given away tracker yet");
// Create an image using our progress tracker.
image =
ImageFactory::CreateImage(aRequest, progressTracker, mContentType,
mImage =
ImageFactory::CreateImage(aRequest, mProgressTracker, mContentType,
mURI, /* aIsMultipart = */ false,
static_cast<uint32_t>(mInnerWindowId));
SetImage(image);
progressTracker = nullptr;
SetProgressTracker(nullptr);
mProgressTracker = nullptr;
}
if (firstPart) {
@@ -957,7 +880,7 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
MOZ_ASSERT(progressTracker->HasImage());
}
if (image->HasError() && !mIsMultiPartChannel) { // Probably bad mimetype
if (mImage->HasError() && !mIsMultiPartChannel) { // Probably bad mimetype
// We allow multipart images to fail to initialize without cancelling the
// load because subsequent images might be fine; thus only single part
// images end up here.
@@ -965,16 +888,16 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
return NS_BINDING_ABORTED;
}
MOZ_ASSERT(!progressTracker, "Should've given tracker to image");
MOZ_ASSERT(image, "Should have image");
MOZ_ASSERT(!mProgressTracker, "Should've given tracker to image");
MOZ_ASSERT(mImage, "Should have image");
if (mDecodeRequested) {
image->StartDecoding();
mImage->StartDecoding();
}
}
// Notify the image that it has new data.
rv = image->OnImageDataAvailable(aRequest, ctxt, inStr, sourceOffset, count);
rv = mImage->OnImageDataAvailable(aRequest, ctxt, inStr, sourceOffset, count);
if (NS_FAILED(rv)) {
PR_LOG(GetImgLog(), PR_LOG_WARNING,
+5 -22
View File
@@ -19,7 +19,7 @@
#include "nsStringGlue.h"
#include "nsError.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "mozilla/Mutex.h"
#include "mozilla/Atomics.h"
#include "mozilla/net/ReferrerPolicy.h"
class imgCacheValidator;
@@ -65,7 +65,7 @@ public:
nsIRequest *aRequest,
nsIChannel *aChannel,
imgCacheEntry *aCacheEntry,
void *aLoadId,
nsISupports* aCX,
nsIPrincipal* aLoadingPrincipal,
int32_t aCORSMode,
ReferrerPolicy aReferrerPolicy);
@@ -88,16 +88,8 @@ public:
// Called or dispatched by EvictFromCache for main thread only execution.
void ContinueEvict();
// Methods that get forwarded to the Image, or deferred until it's
// instantiated.
nsresult LockImage();
nsresult UnlockImage();
nsresult StartDecoding();
nsresult RequestDecode();
inline void SetInnerWindowID(uint64_t aInnerWindowId) {
mInnerWindowId = aInnerWindowId;
}
// Request that we start decoding the image as soon as data becomes available.
void RequestDecode() { mDecodeRequested = true; }
inline uint64_t InnerWindowID() const {
return mInnerWindowId;
@@ -131,8 +123,6 @@ public:
return principal.forget();
}
already_AddRefed<Image> GetImage();
// Return the ProgressTracker associated with this imgRequest. It may live
// in |mProgressTracker| or in |mImage.mProgressTracker|, depending on whether
// mImage has been instantiated yet.
@@ -159,9 +149,6 @@ private:
friend class imgRequestNotifyRunnable;
friend class mozilla::image::ProgressTracker;
void SetImage(Image* aImage);
void SetProgressTracker(ProgressTracker* aProgressTracker);
inline void SetLoadId(void *aLoadId) {
mLoadId = aLoadId;
}
@@ -260,8 +247,6 @@ private:
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
nsCOMPtr<nsIChannel> mNewRedirectChannel;
mozilla::Mutex mMutex;
// The ID of the inner window origin, used for error reporting.
uint64_t mInnerWindowId;
@@ -274,9 +259,7 @@ private:
nsresult mImageErrorCode;
// Sometimes consumers want to do things before the image is ready. Let them,
// and apply the action when the image becomes available.
bool mDecodeRequested : 1;
mozilla::Atomic<bool> mDecodeRequested;
bool mIsMultiPartChannel : 1;
bool mGotData : 1;
+25 -15
View File
@@ -224,8 +224,9 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
// If we were decoded, or if we'd previously requested a decode, request a
// decode on the new image
if (wasDecoded || mDecodeRequested)
GetOwner()->StartDecoding();
if (wasDecoded || mDecodeRequested) {
StartDecoding();
}
return NS_OK;
}
@@ -357,28 +358,38 @@ NS_IMETHODIMP imgRequestProxy::CancelAndForgetObserver(nsresult aStatus)
NS_IMETHODIMP
imgRequestProxy::StartDecoding()
{
if (!GetOwner())
return NS_ERROR_FAILURE;
// Flag this, so we know to transfer the request if our owner changes
mDecodeRequested = true;
// Forward the request
return GetOwner()->StartDecoding();
nsRefPtr<Image> image = GetImage();
if (image) {
return image->StartDecoding();
}
if (GetOwner()) {
GetOwner()->RequestDecode();
}
return NS_OK;
}
/* void requestDecode (); */
NS_IMETHODIMP
imgRequestProxy::RequestDecode()
{
if (!GetOwner())
return NS_ERROR_FAILURE;
// Flag this, so we know to transfer the request if our owner changes
mDecodeRequested = true;
// Forward the request
return GetOwner()->RequestDecode();
nsRefPtr<Image> image = GetImage();
if (image) {
return image->RequestDecode();
}
if (GetOwner()) {
GetOwner()->RequestDecode();
}
return NS_OK;
}
@@ -501,9 +512,8 @@ NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer **aImage)
nsCOMPtr<imgIContainer> imageToReturn;
if (image)
imageToReturn = do_QueryInterface(image);
if (!imageToReturn && GetOwner()) {
imageToReturn = GetOwner()->GetImage();
}
if (!imageToReturn && GetOwner())
imageToReturn = GetOwner()->mImage;
if (!imageToReturn)
return NS_ERROR_FAILURE;
+1
View File
@@ -37,6 +37,7 @@ struct RemoteObject
uint64_t serializedId;
bool isCallable;
bool isConstructor;
bool isDOMObject;
nsCString objectTag;
};
+90 -9
View File
@@ -10,6 +10,7 @@
#include "mozilla/unused.h"
#include "mozilla/dom/BindingUtils.h"
#include "jsfriendapi.h"
#include "js/CharacterEncoding.h"
#include "xpcprivate.h"
#include "CPOWTimer.h"
#include "WrapperFactory.h"
@@ -26,15 +27,21 @@ struct AuxCPOWData
ObjectId id;
bool isCallable;
bool isConstructor;
bool isDOMObject;
// The object tag is just some auxilliary information that clients can use
// however they see fit.
nsCString objectTag;
AuxCPOWData(ObjectId id, bool isCallable, bool isConstructor, const nsACString& objectTag)
AuxCPOWData(ObjectId id,
bool isCallable,
bool isConstructor,
bool isDOMObject,
const nsACString &objectTag)
: id(id),
isCallable(isCallable),
isConstructor(isConstructor),
isDOMObject(isDOMObject),
objectTag(objectTag)
{}
};
@@ -152,8 +159,8 @@ CPOWProxyHandler::getPropertyDescriptor(JSContext* cx, HandleObject proxy, Handl
}
bool
WrapperOwner::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
WrapperOwner::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
ObjectId objId = idOf(proxy);
@@ -175,15 +182,15 @@ WrapperOwner::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId
}
bool
CPOWProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
CPOWProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const
{
FORWARD(getOwnPropertyDescriptor, (cx, proxy, id, desc));
}
bool
WrapperOwner::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
ObjectId objId = idOf(proxy);
@@ -213,8 +220,8 @@ CPOWProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
}
bool
WrapperOwner::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc,
WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc,
ObjectOpResult &result)
{
ObjectId objId = idOf(proxy);
@@ -339,7 +346,20 @@ CPOWProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
}
static bool
CPOWToString(JSContext* cx, unsigned argc, Value* vp)
CPOWDOMQI(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.thisv().isObject() || !IsCPOW(&args.thisv().toObject())) {
JS_ReportError(cx, "bad this object passed to special QI");
return false;
}
RootedObject proxy(cx, &args.thisv().toObject());
FORWARD(DOMQI, (cx, proxy, args));
}
static bool
CPOWToString(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject callee(cx, &args.callee());
@@ -392,6 +412,49 @@ WrapperOwner::toString(JSContext* cx, HandleObject cpow, JS::CallArgs& args)
return true;
}
bool
WrapperOwner::DOMQI(JSContext *cx, JS::HandleObject proxy, JS::CallArgs &args)
{
// Someone's calling us, handle nsISupports specially to avoid unnecessary
// CPOW traffic.
HandleValue id = args[0];
if (id.isObject()) {
RootedObject idobj(cx, &id.toObject());
nsCOMPtr<nsIJSID> jsid;
nsresult rv = UnwrapArg<nsIJSID>(idobj, getter_AddRefs(jsid));
if (NS_SUCCEEDED(rv)) {
MOZ_ASSERT(jsid, "bad wrapJS");
const nsID *idptr = jsid->GetID();
if (idptr->Equals(NS_GET_IID(nsISupports))) {
args.rval().set(args.thisv());
return true;
}
// Webidl-implemented DOM objects never have nsIClassInfo.
if (idptr->Equals(NS_GET_IID(nsIClassInfo)))
return Throw(cx, NS_ERROR_NO_INTERFACE);
}
}
// It wasn't nsISupports, call into the other process to do the QI for us
// (since we don't know what other interfaces our object supports). Note
// that we have to use JS_GetPropertyDescriptor here to avoid infinite
// recursion back into CPOWDOMQI via WrapperOwner::get().
// We could stash the actual QI function on our own function object to avoid
// if we're called multiple times, but since we're transient, there's no
// point right now.
JS::Rooted<JSPropertyDescriptor> propDesc(cx);
if (!JS_GetPropertyDescriptor(cx, proxy, "QueryInterface", &propDesc))
return false;
if (!propDesc.value().isObject()) {
MOZ_ASSERT_UNREACHABLE("We didn't get QueryInterface off a node");
return Throw(cx, NS_ERROR_UNEXPECTED);
}
return JS_CallFunctionValue(cx, proxy, propDesc.value(), args, args.rval());
}
bool
WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp)
@@ -406,6 +469,22 @@ WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
if (!toJSIDVariant(cx, id, &idVar))
return false;
AuxCPOWData *data = AuxCPOWDataOf(proxy);
if (data->isDOMObject &&
idVar.type() == JSIDVariant::TnsString &&
idVar.get_nsString().EqualsLiteral("QueryInterface"))
{
// Handle QueryInterface on DOM Objects specially since we can assume
// certain things about their implementation.
RootedFunction qi(cx, JS_NewFunction(cx, CPOWDOMQI, 1, 0,
"QueryInterface"));
if (!qi)
return false;
vp.set(ObjectValue(*JS_GetFunctionObject(qi)));
return true;
}
JSVariant val;
ReturnStatus status;
if (!SendGet(objId, receiverVar, idVar, &status, &val))
@@ -967,6 +1046,7 @@ MakeRemoteObject(JSContext* cx, ObjectId id, HandleObject obj)
return RemoteObject(id.serialize(),
JS::IsCallable(obj),
JS::IsConstructor(obj),
dom::IsDOMObject(obj),
objectTag);
}
@@ -1051,6 +1131,7 @@ WrapperOwner::fromRemoteObjectVariant(JSContext* cx, RemoteObject objVar)
AuxCPOWData* aux = new AuxCPOWData(objId,
objVar.isCallable(),
objVar.isConstructor(),
objVar.isDOMObject(),
objVar.objectTag());
SetProxyExtra(obj, 0, PrivateValue(this));
+4 -3
View File
@@ -60,15 +60,16 @@ class WrapperOwner : public virtual JavaScriptShared
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
nsresult instanceOf(JSObject* obj, const nsID* id, bool* bp);
nsresult instanceOf(JSObject *obj, const nsID *id, bool *bp);
bool toString(JSContext* cx, JS::HandleObject callee, JS::CallArgs& args);
bool toString(JSContext *cx, JS::HandleObject callee, JS::CallArgs &args);
bool DOMQI(JSContext *cx, JS::HandleObject callee, JS::CallArgs &args);
/*
* Check that |obj| is a DOM wrapper whose prototype chain contains
* |prototypeID| at depth |depth|.
*/
bool domInstanceOf(JSContext* cx, JSObject* obj, int prototypeID, int depth, bool* bp);
bool domInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int depth, bool *bp);
bool active() { return !inactive_; }
+4
View File
@@ -1555,6 +1555,10 @@ nsIOService::SpeculativeConnect(nsIURI *aURI,
nsCOMPtr<nsICancelable> cancelable;
nsRefPtr<IOServiceProxyCallback> callback =
new IOServiceProxyCallback(aCallbacks, this);
nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
if (pps2) {
return pps2->AsyncResolve2(channel, 0, callback, getter_AddRefs(cancelable));
}
return pps->AsyncResolve(channel, 0, callback, getter_AddRefs(cancelable));
}
+7 -8
View File
@@ -242,13 +242,12 @@ NS_IMPL_ISUPPORTS(AppCacheClearDataObserver, nsIObserver)
void
nsApplicationCacheService::AppClearDataObserverInit()
{
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
if (observerService) {
nsRefPtr<AppCacheClearDataObserver> obs
= new AppCacheClearDataObserver();
observerService->AddObserver(obs, TOPIC_WEB_APP_CLEAR_DATA,
/*holdsWeak=*/ false);
}
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (observerService) {
nsRefPtr<AppCacheClearDataObserver> obs
= new AppCacheClearDataObserver();
observerService->AddObserver(obs, TOPIC_WEB_APP_CLEAR_DATA,
/*holdsWeak=*/ false);
}
}
+1 -1
View File
@@ -688,7 +688,7 @@ nsCookieService::GetSingleton()
/* static */ void
nsCookieService::AppClearDataObserverInit()
{
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1");
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
nsCOMPtr<nsIObserver> obs = new AppClearDataObserver();
observerService->AddObserver(obs, TOPIC_WEB_APP_CLEAR_DATA,
/* holdsWeak= */ false);
+1 -2
View File
@@ -610,8 +610,7 @@ nsDNSService::Init()
nsCOMPtr<nsIIDNService> idn = do_GetService(NS_IDNSERVICE_CONTRACTID);
nsCOMPtr<nsIObserverService> obs =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
nsRefPtr<nsHostResolver> res;
nsresult rv = nsHostResolver::Create(maxCacheEntries,
+12
View File
@@ -40,6 +40,7 @@
#include "nsPrincipal.h"
#include "nsIOService.h"
#include "mozilla/net/OfflineObserver.h"
#include "nsISpeculativeConnect.h"
using mozilla::dom::ContentParent;
using mozilla::dom::TabContext;
@@ -670,6 +671,17 @@ NeckoParent::DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* actor)
return true;
}
bool
NeckoParent::RecvSpeculativeConnect(const URIParams &aURI)
{
nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
if (uri && speculator) {
speculator->SpeculativeConnect(uri, nullptr);
}
return true;
}
bool
NeckoParent::RecvHTMLDNSPrefetch(const nsString& hostname,
const uint16_t& flags)
+1
View File
@@ -163,6 +163,7 @@ protected:
const uint32_t& flags,
const nsCString& aNetworkInterface) override;
virtual bool DeallocPDNSRequestParent(PDNSRequestParent*) override;
virtual bool RecvSpeculativeConnect(const URIParams& aURI) override;
virtual bool RecvHTMLDNSPrefetch(const nsString& hostname,
const uint16_t& flags) override;
virtual bool RecvCancelHTMLDNSPrefetch(const nsString& hostname,
+1
View File
@@ -74,6 +74,7 @@ parent:
URIParams fileuri,
OptionalURIParams appuri);
SpeculativeConnect(URIParams uri);
HTMLDNSPrefetch(nsString hostname, uint16_t flags);
CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
PRtspController();
+8
View File
@@ -50,6 +50,7 @@
#include "nsINetworkLinkService.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/ipc/URIUtils.h"
#if defined(XP_UNIX)
#include <sys/utsname.h>
@@ -2002,6 +2003,13 @@ NS_IMETHODIMP
nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
nsIInterfaceRequestor *aCallbacks)
{
if (IsNeckoChild()) {
ipc::URIParams params;
SerializeURI(aURI, params);
gNeckoChild->SendSpeculativeConnect(params);
return NS_OK;
}
if (!mHandlerActive)
return NS_OK;
+2
View File
@@ -4,11 +4,13 @@ skip-if = buildapp == 'b2g' || e10s || toolkit == 'android' # Android: Bug 11111
support-files =
method.sjs
partial_content.sjs
rel_preconnect.sjs
user_agent.sjs
user_agent_update.sjs
[test_arraybufferinputstream.html]
[test_partially_cached_content.html]
[test_rel_preconnect.html]
[test_uri_scheme.html]
[test_user_agent_overrides.html]
[test_user_agent_updates.html]
@@ -0,0 +1,12 @@
// Generate response header "Link: <HREF>; rel=preconnect"
// HREF is provided by the request header X-Link
function handleRequest(request, response)
{
response.setHeader("Cache-Control", "no-cache", false);
response.setHeader("Link", "<" +
request.getHeader('X-Link') +
">; rel=preconnect");
response.write("check that header");
}
@@ -0,0 +1,83 @@
<!DOCTYPE HTML>
<html>
<!--
-->
<head>
<title>Test for link rel=preconnect</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
const Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci, Cr = SpecialPowers.Cr;
var srv;
function TestServer(nextTest) {
this.listener= Cc["@mozilla.org/network/server-socket;1"]
.createInstance(Ci.nsIServerSocket);
this.listener.init(-1, true, -1);
this.listener.asyncListen(SpecialPowers.wrapCallbackObject(this));
this.nextTest = nextTest;
}
TestServer.prototype = {
QueryInterface: function(iid) {
iid = SpecialPowers.wrap(iid);
if (iid.equals(Ci.nsIServerSocketListener) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
},
onSocketAccepted: function(socket, trans) {
try { socket.close(); } catch(e) {}
try { trans.close(); } catch(e) {}
ok(true, "received connect");
setTimeout(srv.nextTest, 0);
},
onStopListening: function(socket) {}
};
var originalLimit = SpecialPowers.getIntPref("network.http.speculative-parallel-limit");
function testElement()
{
// test the link rel=preconnect element in the head
srv = new TestServer(testHeader);
SpecialPowers.setIntPref("network.http.speculative-parallel-limit", 1);
var link = document.createElement("link");
link.rel = "preconnect";
link.href = "//localhost:" + srv.listener.port;
document.head.appendChild(link);
}
function testHeader()
{
// test the http link response header
srv.listener.close();
srv = new TestServer(testDone);
var xhr = new XMLHttpRequest();
xhr.open("GET", 'rel_preconnect.sjs', false);
xhr.setRequestHeader("X-Link", "//localhost:" + srv.listener.port);
xhr.send();
is(xhr.status, 200, 'xhr cool');
}
function testDone()
{
SpecialPowers.setIntPref("network.http.speculative-parallel-limit",
originalLimit);
srv.listener.close();
SimpleTest.finish();
}
</script>
</head>
<body onload="testElement();">
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
</body>
</html>
@@ -1,3 +1,5 @@
Cu.import("resource://gre/modules/Services.jsm");
var testpath = "/bug1054739";
function run_test() {
@@ -26,7 +28,14 @@ function run_test() {
function setupChannel(path) {
let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
let chan = ios.newChannel("http://localhost:4444" + path, "", null);
let chan = ios.newChannel2("http://localhost:4444" + path,
"",
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
chan.QueryInterface(Ci.nsIHttpChannel);
return chan;
}
+176 -22
View File
@@ -169,7 +169,14 @@ resolveCallback.prototype = {
};
function run_filter_test() {
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
// Verify initial state
var cb = new resolveCallback();
@@ -192,7 +199,14 @@ function filter_test0_1(pi) {
var cb = new resolveCallback();
cb.nextFunction = filter_test0_2;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -205,7 +219,14 @@ function filter_test0_2(pi)
var cb = new resolveCallback();
cb.nextFunction = filter_test0_3;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -220,7 +241,14 @@ function filter_test0_3(pi)
var cb = new resolveCallback();
cb.nextFunction = filter_test0_4;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -233,7 +261,14 @@ function filter_test0_4(pi)
pps.registerChannelFilter(filter03, 10);
var cb = new resolveCallback();
cb.nextFunction = filter_test0_5;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -315,7 +350,14 @@ function run_filter_test2() {
var cb = new resolveCallback();
cb.nextFunction = filter_test1_1;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -327,7 +369,14 @@ function filter_test1_1(pi) {
var cb = new resolveCallback();
cb.nextFunction = filter_test1_2;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -340,7 +389,14 @@ function filter_test1_2(pi) {
var cb = new resolveCallback();
cb.nextFunction = filter_test1_3;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -352,7 +408,14 @@ function filter_test1_3(pi) {
var filter_3_1;
function run_filter_test3() {
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
// Push a filter and verify the results asynchronously
@@ -371,7 +434,14 @@ function filter_test3_1(pi) {
}
function run_pref_test() {
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
// Verify 'direct' setting
@@ -391,7 +461,14 @@ function pref_test1_1(pi)
var cb = new resolveCallback();
cb.nextFunction = pref_test1_2;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -406,7 +483,14 @@ function pref_test1_2(pi)
var cb = new resolveCallback();
cb.nextFunction = pref_test1_3;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -423,7 +507,14 @@ function pref_test1_3(pi)
var cb = new resolveCallback();
cb.nextFunction = pref_test1_4;
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var req = pps.asyncResolve(channel, 0, cb);
}
@@ -481,7 +572,14 @@ function run_pac_test() {
'function FindProxyForURL(url, host) {' +
' return "PROXY foopy:8080; DIRECT";' +
'}';
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
// Configure PAC
@@ -495,7 +593,14 @@ function run_pac2_test() {
'function FindProxyForURL(url, host) {' +
' return "HTTPS foopy:8080; DIRECT";' +
'}';
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
// Configure PAC
originalTLSProxy = prefs.getBoolPref("network.proxy.proxy_over_tls");
@@ -511,7 +616,14 @@ function run_pac3_test() {
'function FindProxyForURL(url, host) {' +
' return "HTTPS foopy:8080; DIRECT";' +
'}';
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
// Configure PAC
prefs.setCharPref("network.proxy.autoconfig_url", pac);
@@ -553,7 +665,14 @@ TestResolveCancelationCallback.prototype = {
};
function run_pac_cancel_test() {
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
// Configure PAC
var pac = 'data:text/plain,' +
@@ -594,7 +713,14 @@ function check_host_filters_cb()
function check_host_filter(i) {
var uri;
dump("*** uri=" + hostList[i] + " bShouldBeFiltered=" + bShouldBeFiltered + "\n");
var channel = ios.newChannel(hostList[i], null, null);
var channel = ios.newChannel2(hostList[i],
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
var cb = new resolveCallback();
cb.nextFunction = host_filter_cb;
@@ -698,7 +824,14 @@ function run_myipaddress_test()
// no traffic to this IP is ever sent, it is just a public IP that
// does not require DNS to determine a route.
var channel = ios.newChannel("http://192.0.43.10/", null, null);
var channel = ios.newChannel2("http://192.0.43.10/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
prefs.setIntPref("network.proxy.type", 2);
prefs.setCharPref("network.proxy.autoconfig_url", pac);
@@ -734,7 +867,14 @@ function run_myipaddress_test_2()
' return "PROXY " + myaddr + ":5678";' +
'}';
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
prefs.setIntPref("network.proxy.type", 2);
prefs.setCharPref("network.proxy.autoconfig_url", pac);
@@ -763,7 +903,14 @@ function run_failed_script_test()
var pac = 'data:text/plain,' +
'\nfor(;\n';
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
prefs.setIntPref("network.proxy.type", 2);
prefs.setCharPref("network.proxy.autoconfig_url", pac);
@@ -843,7 +990,14 @@ function run_isresolvable_test()
' return "PROXY 127.0.0.1:1234";' +
'}';
var channel = ios.newChannel("http://www.mozilla.org/", null, null);
var channel = ios.newChannel2("http://www.mozilla.org/",
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
prefs.setIntPref("network.proxy.type", 2);
prefs.setCharPref("network.proxy.autoconfig_url", pac);
+4 -6
View File
@@ -30,6 +30,7 @@ UNIFIED_SOURCES += [
'nsCertVerificationThread.cpp',
'nsClientAuthRemember.cpp',
'nsCrypto.cpp',
'nsCryptoHash.cpp',
'nsDataSignatureVerifier.cpp',
'nsKeygenHandler.cpp',
'nsKeygenHandlerContent.cpp',
@@ -43,10 +44,12 @@ UNIFIED_SOURCES += [
'nsNSSCertificateFakeTransport.cpp',
'nsNSSCertTrust.cpp',
'nsNSSCertValidity.cpp',
'nsNSSComponent.cpp',
'nsNSSErrors.cpp',
'nsNSSIOLayer.cpp',
'nsNSSModule.cpp',
'nsNSSShutDown.cpp',
'nsNSSVersion.cpp',
'nsNTLMAuthModule.cpp',
'nsPK11TokenDB.cpp',
'nsPKCS11Slot.cpp',
@@ -60,6 +63,7 @@ UNIFIED_SOURCES += [
'nsSSLStatus.cpp',
'nsTLSSocketProvider.cpp',
'nsUsageArrayHelper.cpp',
'PSMContentListener.cpp',
'PSMRunnable.cpp',
'SharedSSLState.cpp',
'SSLServerCertVerification.cpp',
@@ -67,14 +71,8 @@ UNIFIED_SOURCES += [
]
# nsNSSCertificateDB.cpp needs to include nscert.h before everything else.
# The rest cannot be built in unified mode because they want to force NSPR
# logging.
SOURCES += [
'nsCryptoHash.cpp',
'nsNSSCertificateDB.cpp',
'nsNSSComponent.cpp',
'nsNSSVersion.cpp',
'PSMContentListener.cpp',
]
LOCAL_INCLUDES += [
@@ -0,0 +1,92 @@
# 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/.
from marionette_test import MarionetteTestCase
from marionette_driver.keys import Keys
class TestAboutPages(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
if self.marionette.session_capabilities['platformName'] == 'DARWIN':
self.mod_key = Keys.META
else:
self.mod_key = Keys.CONTROL
self.remote_uri = self.marionette.absolute_url("javascriptPage.html")
self.marionette.navigate(self.remote_uri)
def purge_history(self):
with self.marionette.using_context("chrome"):
self.marionette.execute_script("""
let sh = gBrowser.webNavigation.sessionHistory;
if (sh.count) {
sh.PurgeHistory(sh.count - 1);
}
""")
self.wait_for_condition(
lambda mn: mn.execute_script("""
return gBrowser.webNavigation.sessionHistory.count === 1;
"""))
def test_back_forward(self):
self.marionette.navigate("about:blank")
# Something about this sequence goes wrong when run in a tab with a lot
# of history (you have to "go_back" twice to get back to the remote
# uri). Running in a tab with less history effectively works around
# this. This is reproducible without marionette, filed as bug 1134518.
self.purge_history()
self.marionette.navigate(self.remote_uri)
self.marionette.navigate("about:preferences")
self.marionette.go_back()
self.wait_for_condition(
lambda mn: mn.get_url() == self.remote_uri)
def test_navigate_non_remote_about_pages(self):
self.marionette.navigate("about:blank")
self.assertEqual(self.marionette.get_url(), "about:blank")
self.marionette.navigate("about:preferences")
self.assertEqual(self.marionette.get_url(), "about:preferences")
def test_navigate_shortcut_key(self):
self.marionette.navigate("about:preferences")
self.marionette.navigate(self.remote_uri)
self.marionette.navigate("about:blank")
start_win = self.marionette.current_window_handle
start_win_handles = self.marionette.window_handles
with self.marionette.using_context("chrome"):
main_win = self.marionette.find_element("id", "main-window")
main_win.send_keys(self.mod_key, Keys.SHIFT, 'a')
self.wait_for_condition(lambda mn: len(mn.window_handles) == 2)
self.assertEqual(start_win, self.marionette.current_window_handle)
[new_tab] = list(set(self.marionette.window_handles) - set(start_win_handles))
self.marionette.switch_to_window(new_tab)
self.wait_for_condition(lambda mn: mn.get_url() == "about:addons")
self.marionette.close()
self.marionette.switch_to_window(start_win)
def test_type_to_non_remote_tab(self):
with self.marionette.using_context("chrome"):
urlbar = self.marionette.find_element('id', 'urlbar')
urlbar.send_keys(self.mod_key + 'a')
urlbar.send_keys(self.mod_key + 'x')
urlbar.send_keys('about:preferences' + Keys.ENTER)
self.wait_for_condition(lambda mn: mn.get_url() == "about:preferences")
def test_type_to_remote_tab(self):
self.marionette.navigate("about:preferences")
with self.marionette.using_context("chrome"):
urlbar = self.marionette.find_element('id', 'urlbar')
urlbar.send_keys(self.mod_key + 'a')
urlbar.send_keys(self.mod_key + 'x')
urlbar.send_keys(self.remote_uri + Keys.ENTER)
self.wait_for_condition(lambda mn: mn.get_url() == self.remote_uri)
@@ -55,6 +55,9 @@ disabled = "Bug 896046"
browser = false
qemu = true
[test_about_pages.py]
b2g = false
[test_execute_async_script.py]
[test_execute_script.py]
[test_simpletest_fail.js]
@@ -208,6 +208,7 @@ FrameManager.prototype = {
messageManager.addWeakMessageListener("Marionette:addCookie", this.server);
messageManager.addWeakMessageListener("Marionette:getVisibleCookies", this.server);
messageManager.addWeakMessageListener("Marionette:deleteCookie", this.server);
messageManager.addWeakMessageListener("Marionette:listenersAttached", this.server);
messageManager.addWeakMessageListener("MarionetteFrame:handleModal", this);
messageManager.addWeakMessageListener("MarionetteFrame:getCurrentFrameId", this);
messageManager.addWeakMessageListener("MarionetteFrame:getInterruptedState", this);
@@ -239,8 +240,8 @@ FrameManager.prototype = {
messageManager.removeWeakMessageListener("Marionette:addCookie", this.server);
messageManager.removeWeakMessageListener("Marionette:getVisibleCookies", this.server);
messageManager.removeWeakMessageListener("Marionette:deleteCookie", this.server);
messageManager.removeWeakMessageListener("Marionette:listenersAttached", this.server);
messageManager.removeWeakMessageListener("MarionetteFrame:handleModal", this);
messageManager.removeWeakMessageListener("MarionetteFrame:getCurrentFrameId", this);
},
};
+87 -41
View File
@@ -63,6 +63,9 @@ let originalOnError;
let checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
//timer for readystate
let readyStateTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
// timer for navigation commands.
let navTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let onDOMContentLoaded;
// Send move events about this often
let EVENT_INTERVAL = 30; // milliseconds
// For assigning unique ids to all touches
@@ -97,13 +100,14 @@ let modalHandler = function() {
* If the actor returns an ID, we start the listeners. Otherwise, nothing happens.
*/
function registerSelf() {
let msg = {value: winUtil.outerWindowID, href: content.location.href};
let msg = {value: winUtil.outerWindowID}
// register will have the ID and a boolean describing if this is the main process or not
let register = sendSyncMessage("Marionette:register", msg);
if (register[0]) {
listenerId = register[0][0].id;
if (typeof listenerId != "undefined") {
let {id, remotenessChange} = register[0][0];
listenerId = id;
if (typeof id != "undefined") {
// check if we're the main process
if (register[0][1] == true) {
addMessageListener("MarionetteMainListener:emitTouchEvent", emitTouchEventForIFrame);
@@ -111,6 +115,9 @@ function registerSelf() {
importedScripts = FileUtils.getDir('TmpD', [], false);
importedScripts.append('marionetteContentScripts');
startListeners();
if (remotenessChange) {
sendAsyncMessage("Marionette:listenersAttached", {listenerId: id});
}
}
}
}
@@ -170,6 +177,8 @@ function startListeners() {
addMessageListenerId("Marionette:actionChain", actionChain);
addMessageListenerId("Marionette:multiAction", multiAction);
addMessageListenerId("Marionette:get", get);
addMessageListenerId("Marionette:pollForReadyState", pollForReadyState);
addMessageListenerId("Marionette:cancelRequest", cancelRequest);
addMessageListenerId("Marionette:getCurrentUrl", getCurrentUrl);
addMessageListenerId("Marionette:getTitle", getTitle);
addMessageListenerId("Marionette:getPageSource", getPageSource);
@@ -273,6 +282,8 @@ function deleteSession(msg) {
removeMessageListenerId("Marionette:actionChain", actionChain);
removeMessageListenerId("Marionette:multiAction", multiAction);
removeMessageListenerId("Marionette:get", get);
removeMessageListenerId("Marionette:pollForReadyState", pollForReadyState);
removeMessageListenerId("Marionette:cancelRequest", cancelRequest);
removeMessageListenerId("Marionette:getTitle", getTitle);
removeMessageListenerId("Marionette:getPageSource", getPageSource);
removeMessageListenerId("Marionette:getCurrentUrl", getCurrentUrl);
@@ -1404,6 +1415,52 @@ function multiAction(msg) {
}
}
/*
* This implements the latter part of a get request (for the case we need to resume one
* when a remoteness update happens in the middle of a navigate request). This is most of
* of the work of a navigate request, but doesn't assume DOMContentLoaded is yet to fire.
*/
function pollForReadyState(msg, start, callback) {
let {pageTimeout, url, command_id} = msg.json;
start = start ? start : new Date().getTime();
if (!callback) {
callback = () => {};
}
let end = null;
function checkLoad() {
navTimer.cancel();
end = new Date().getTime();
let aboutErrorRegex = /about:.+(error)\?/;
let elapse = end - start;
if (pageTimeout == null || elapse <= pageTimeout) {
if (curFrame.document.readyState == "complete") {
callback();
sendOk(command_id);
} else if (curFrame.document.readyState == "interactive" &&
aboutErrorRegex.exec(curFrame.document.baseURI) &&
!curFrame.document.baseURI.startsWith(url)) {
// We have reached an error url without requesting it.
callback();
sendError("Error loading page", 13, null, command_id);
} else if (curFrame.document.readyState == "interactive" &&
curFrame.document.baseURI.startsWith("about:")) {
callback();
sendOk(command_id);
} else {
navTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
else {
callback();
sendError("Error loading page, timed out (checkLoad)", 21, null,
command_id);
}
}
checkLoad();
}
/**
* Navigate to the given URL. The operation will be performed on the
* current browser context, and handles the case where we navigate
@@ -1411,67 +1468,56 @@ function multiAction(msg) {
* (in chrome space).
*/
function get(msg) {
let command_id = msg.json.command_id;
let checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let start = new Date().getTime();
let end = null;
function checkLoad() {
checkTimer.cancel();
end = new Date().getTime();
let aboutErrorRegex = /about:.+(error)\?/;
let elapse = end - start;
if (msg.json.pageTimeout == null || elapse <= msg.json.pageTimeout) {
if (curFrame.document.readyState == "complete") {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
sendOk(command_id);
} else if (curFrame.document.readyState == "interactive" &&
aboutErrorRegex.exec(curFrame.document.baseURI) &&
!curFrame.document.baseURI.startsWith(msg.json.url)) {
// We have reached an error url without requesting it.
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
sendError("Error loading page", 13, null, command_id);
} else if (curFrame.document.readyState == "interactive" &&
curFrame.document.baseURI.startsWith("about:")) {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
sendOk(command_id);
} else {
checkTimer.initWithCallback(checkLoad, 100, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
else {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
sendError("Error loading page, timed out (checkLoad)", 21, null,
command_id);
}
}
// Prevent DOMContentLoaded events from frames from invoking this
// code, unless the event is coming from the frame associated with
// the current window (i.e. someone has used switch_to_frame).
let onDOMContentLoaded = function onDOMContentLoaded(event) {
onDOMContentLoaded = function onDOMContentLoaded(event) {
if (!event.originalTarget.defaultView.frameElement ||
event.originalTarget.defaultView.frameElement == curFrame.frameElement) {
checkLoad();
pollForReadyState(msg, start, () => {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
onDOMContentLoaded = null;
});
}
};
function timerFunc() {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
sendError("Error loading page, timed out (onDOMContentLoaded)", 21,
null, command_id);
null, msg.json.command_id);
}
if (msg.json.pageTimeout != null) {
checkTimer.initWithCallback(timerFunc, msg.json.pageTimeout, Ci.nsITimer.TYPE_ONE_SHOT);
navTimer.initWithCallback(timerFunc, msg.json.pageTimeout, Ci.nsITimer.TYPE_ONE_SHOT);
}
addEventListener("DOMContentLoaded", onDOMContentLoaded, false);
curFrame.location = msg.json.url;
}
/**
* Cancel the polling and remove the event listener associated with a current
* navigation request in case we're interupted by an onbeforeunload handler
* and navigation doesn't complete.
*/
function cancelRequest() {
navTimer.cancel();
if (onDOMContentLoaded) {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
}
}
/**
* Get URL of the top level browsing context.
*/
function getCurrentUrl(msg) {
sendResponse({value: curFrame.location.href}, msg.json.command_id);
let url;
if (msg.json.isB2G) {
url = curFrame.location.href;
} else {
url = content.location.href;
}
sendResponse({value: url}, msg.json.command_id);
}
/**
+157 -36
View File
@@ -289,8 +289,10 @@ MarionetteServerConnection.prototype = {
}
}
else {
this.messageManager.broadcastAsyncMessage(
"Marionette:" + name + this.curBrowser.curFrameId, values);
this.curBrowser.executeWhenReady(() => {
this.messageManager.broadcastAsyncMessage(
"Marionette:" + name + this.curBrowser.curFrameId, values);
});
}
return success;
},
@@ -330,6 +332,11 @@ MarionetteServerConnection.prototype = {
return;
}
}
if (this.curBrowser !== null) {
this.curBrowser.pendingCommands = [];
}
this.conn.send(msg);
if (command_id != -1) {
// Don't unset this.command_id if this message is to process an
@@ -1279,7 +1286,17 @@ MarionetteServerConnection.prototype = {
*/
get: function MDA_get(aRequest) {
let command_id = this.command_id = this.getCommandId();
if (this.context != "chrome") {
// If a remoteness update interrupts our page load, this will never return
// We need to re-issue this request to correctly poll for readyState and
// send errors.
this.curBrowser.pendingCommands.push(() => {
aRequest.parameters.command_id = command_id;
this.messageManager.broadcastAsyncMessage(
"Marionette:pollForReadyState" + this.curBrowser.curFrameId,
aRequest.parameters);
});
aRequest.command_id = command_id;
aRequest.parameters.pageTimeout = this.pageTimeout;
this.sendAsync("get", aRequest.parameters, command_id);
@@ -1338,15 +1355,7 @@ MarionetteServerConnection.prototype = {
this.sendResponse(this.getCurrentWindow().location.href, this.command_id);
}
else {
if (isB2G) {
this.sendAsync("getCurrentUrl", {}, this.command_id);
}
else {
this.sendResponse(this.curBrowser
.tab
.linkedBrowser
.contentWindowAsCPOW.location.href, this.command_id);
}
this.sendAsync("getCurrentUrl", {isB2G: isB2G}, this.command_id);
}
},
@@ -1440,6 +1449,13 @@ MarionetteServerConnection.prototype = {
}
},
/**
* Forces an update for the given browser's id.
*/
updateIdForBrowser: function (browser, newId) {
this._browserIds.set(browser.permanentKey, newId);
},
/**
* Retrieves a listener id for the given xul browser element. In case
* the browser is not known, an attempt is made to retrieve the id from
@@ -1602,8 +1618,7 @@ MarionetteServerConnection.prototype = {
this.curBrowser = this.browsers[outerId];
if (contentWindowId) {
// The updated id corresponds to switching to a new tab.
this.curBrowser.curFrameId = contentWindowId;
win.gBrowser.selectTabAtIndex(ind);
this.curBrowser.switchToTab(ind);
}
this.sendOk(command_id);
}
@@ -3078,6 +3093,7 @@ MarionetteServerConnection.prototype = {
}
if (this.command_id) {
this.sendAsync("cancelRequest", {});
// This is a shortcut to get the client to accept our response whether
// the expected key is 'ok' (in case a click or similar got us here)
// or 'value' (in case an execute script or similar got us here).
@@ -3220,8 +3236,9 @@ MarionetteServerConnection.prototype = {
let mainContent = (this.curBrowser.mainContentId == null);
if (!browserType || browserType != "content") {
//curBrowser holds all the registered frames in knownFrames
let listenerId = this.generateFrameId(message.json.value);
reg.id = this.curBrowser.register(listenerId);
let uid = this.generateFrameId(message.json.value);
reg.id = uid;
reg.remotenessChange = this.curBrowser.register(uid, message.target);
}
// set to true if we updated mainContentId
mainContent = ((mainContent == true) && (this.curBrowser.mainContentId != null));
@@ -3259,6 +3276,19 @@ MarionetteServerConnection.prototype = {
globalMessageManager.broadcastAsyncMessage(
"MarionetteMainListener:emitTouchEvent", message.json);
return;
case "Marionette:listenersAttached":
if (message.json.listenerId === this.curBrowser.curFrameId) {
// If remoteness gets updated we need to call newSession. In the case
// of desktop this just sets up a small amount of state that doesn't
// change over the course of a session.
let newSessionValues = {
B2G: (appName == "B2G"),
raisesAccessibilityExceptions: this.sessionCapabilities.raisesAccessibilityExceptions
};
this.sendAsync("newSession", newSessionValues);
this.curBrowser.flushPendingCommands();
}
return;
}
}
};
@@ -3376,15 +3406,49 @@ function BrowserObj(win, server) {
this.setBrowser(win);
this.frameManager = new FrameManager(server); //We should have one FM per BO so that we can handle modals in each Browser
// A reference to the tab corresponding to the current window handle, if any.
this.tab = null;
this.pendingCommands = [];
//register all message listeners
this.frameManager.addMessageManagerListeners(server.messageManager);
this.getIdForBrowser = server.getIdForBrowser.bind(server);
this.updateIdForBrowser = server.updateIdForBrowser.bind(server);
this._curFrameId = null;
this._browserWasRemote = null;
this._hasRemotenessChange = false;
}
BrowserObj.prototype = {
get tab () {
// A reference to the currently selected tab, if any
return this.browser ? this.browser.selectedTab : null;
/**
* This function intercepts commands interacting with content and queues
* or executes them as needed.
*
* No commands interacting with content are safe to process until
* the new listener script is loaded and registers itself.
* This occurs when a command whose effect is asynchronous (such
* as goBack) results in a remoteness change and new commands
* are subsequently posted to the server.
*/
executeWhenReady: function (callback) {
if (this.hasRemotenessChange()) {
this.pendingCommands.push(callback);
} else {
callback();
}
},
/**
* Re-sets this BrowserObject's current tab and updates remoteness tracking.
*/
switchToTab: function (ind) {
if (this.browser) {
this.browser.selectTabAtIndex(ind);
this.tab = this.browser.selectedTab;
}
this._browserWasRemote = this.browser.getBrowserForTab(this.tab).isRemoteBrowser;
this._hasRemotenessChange = false;
},
/**
@@ -3424,15 +3488,31 @@ BrowserObj.prototype = {
break;
}
},
// The current frame id is managed per browser element on desktop in case
// the id needs to be refreshed. The currently selected window is identified
// within BrowserObject by a tab.
get curFrameId () {
if (appName != "Firefox") {
return this._curFrameId;
}
if (this.tab) {
let browser = this.browser.getBrowserForTab(this.tab);
return this.getIdForBrowser(browser);
}
return null;
},
set curFrameId (id) {
if (appName != "Firefox") {
this._curFrameId = id;
}
},
/**
* Called when we start a session with this browser.
*/
startSession: function BO_startSession(newSession, win, callback) {
if (appName == "Firefox" &&
win.gMultiProcessBrowser &&
!win.gBrowser.selectedBrowser.isRemoteBrowser) {
win.XULBrowserWindow.forceInitialBrowserRemote();
}
callback(win, newSession);
},
@@ -3464,28 +3544,69 @@ BrowserObj.prototype = {
*
* @param string uid
* frame uid for use by marionette
* @param the XUL <browser> that was the target of the originating message.
*/
register: function BO_register(uid) {
if (this.curFrameId == null) {
let currWinId = null;
register: function BO_register(uid, target) {
let remotenessChange = this.hasRemotenessChange();
if (this.curFrameId === null || remotenessChange) {
if (this.browser) {
// If we're setting up a new session on Firefox, we only process the
// registration for this frame if it belongs to the tab we've just
// created.
// registration for this frame if it belongs to the current tab.
if (!this.tab) {
this.switchToTab(this.browser.selectedIndex);
}
let browser = this.browser.getBrowserForTab(this.tab);
currWinId = this.getIdForBrowser(browser);
}
if ((!this.newSession) ||
(this.newSession &&
((appName != "Firefox") ||
uid === currWinId))) {
this.curFrameId = uid;
if (target == browser) {
this.updateIdForBrowser(browser, uid);
this.mainContentId = uid;
}
} else {
this._curFrameId = uid;
this.mainContentId = uid;
}
}
this.knownFrames.push(uid); //used to delete sessions
return uid;
return remotenessChange;
},
/**
* When navigating between pages results in changing a browser's process, we
* need to take measures not to lose contact with a listener script. This
* function does the necessary bookkeeping.
*/
hasRemotenessChange: function () {
// None of these checks are relevant on b2g or if we don't have a tab yet,
// and may not apply on Fennec.
if (appName != "Firefox" || this.tab === null) {
return false;
}
if (this._hasRemotenessChange) {
return true;
}
let currentIsRemote = this.browser.getBrowserForTab(this.tab).isRemoteBrowser;
this._hasRemotenessChange = this._browserWasRemote !== currentIsRemote;
this._browserWasRemote = currentIsRemote;
return this._hasRemotenessChange;
},
/**
* Flushes any pending commands queued when a remoteness change is being
* processed and mark this remotenessUpdate as complete.
*/
flushPendingCommands: function () {
if (!this._hasRemotenessChange) {
return;
}
this._hasRemotenessChange = false;
this.pendingCommands.forEach((callback) => {
callback();
});
this.pendingCommands = [];
}
}
/**
+16 -2
View File
@@ -492,12 +492,26 @@ exports.fetch = function fetch(aURL, aOptions={ loadFromCache: true }) {
default:
let channel;
try {
channel = Services.io.newChannel(url, null, null);
channel = Services.io.newChannel2(url,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
} catch (e if e.name == "NS_ERROR_UNKNOWN_PROTOCOL") {
// On Windows xpcshell tests, c:/foo/bar can pass as a valid URL, but
// newChannel won't be able to handle it.
url = "file:///" + url;
channel = Services.io.newChannel(url, null, null);
channel = Services.io.newChannel2(url,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
}
let chunks = [];
let streamListener = {
+8 -1
View File
@@ -23,7 +23,14 @@ exports.unregister = function(handle) {
};
function getDefaultSettings() {
let chan = NetUtil.newChannel(settingsFile);
let chan = NetUtil.newChannel2(settingsFile,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
let stream = chan.open();
// Obtain a converter to read from a UTF-8 encoded input stream.
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+5 -3
View File
@@ -76,6 +76,7 @@ static gfxIntSize gAndroidScreenBounds;
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/LayerTransactionParent.h"
#include "mozilla/Mutex.h"
#include "mozilla/Services.h"
#include "nsThreadUtils.h"
class ContentCreationNotifier;
@@ -100,8 +101,8 @@ public:
ContentParent* cp = static_cast<ContentParent*>(cpo.get());
unused << cp->SendScreenSizeChanged(gAndroidScreenBounds);
} else if (!strcmp(aTopic, "xpcom-shutdown")) {
nsCOMPtr<nsIObserverService>
obs(do_GetService("@mozilla.org/observer-service;1"));
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(static_cast<nsIObserver*>(this),
"xpcom-shutdown");
@@ -823,7 +824,8 @@ nsWindow::OnGlobalAndroidEvent(AndroidGoannaEvent *ae)
// If the content process is not created yet, wait until it's
// created and then tell it the screen size.
nsCOMPtr<nsIObserverService> obs = do_GetService("@mozilla.org/observer-service;1");
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
if (!obs)
break;
+2 -1
View File
@@ -35,6 +35,7 @@ extern "C" {
#include "nsIServiceManager.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
using namespace mozilla;
@@ -61,7 +62,7 @@ nsToolkit::~nsToolkit()
void
nsToolkit::PostSleepWakeNotification(const char* aNotification)
{
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1");
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (observerService)
observerService->NotifyObservers(nullptr, aNotification, nullptr);
}
+1 -2
View File
@@ -1289,8 +1289,7 @@ nsMemoryReporterManager::GetReportsExtended(
// Request memory reports from child processes. We do this *before*
// collecting reports for this process so each process can collect
// reports in parallel.
nsCOMPtr<nsIObserverService> obs =
do_GetService("@mozilla.org/observer-service;1");
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_STATE(obs);
nsPrintfCString genStr("generation=%x anonymize=%d minimize=%d DMDident=",
+3 -4
View File
@@ -40,6 +40,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/StartupTimeline.h"
#include "nsEmbedCID.h"
@@ -63,8 +64,7 @@ nsAppShellService::nsAppShellService() :
mModalWindowCount(0),
mApplicationProvidedHiddenWindow(false)
{
nsCOMPtr<nsIObserverService> obs
(do_GetService("@mozilla.org/observer-service;1"));
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
obs->AddObserver(this, "xpcom-will-shutdown", false);
@@ -807,8 +807,7 @@ nsAppShellService::RegisterTopLevelWindow(nsIXULWindow* aWindow)
}
// an ongoing attempt to quit is stopped by a newly opened window
nsCOMPtr<nsIObserverService> obssvc =
do_GetService("@mozilla.org/observer-service;1");
nsCOMPtr<nsIObserverService> obssvc = services::GetObserverService();
NS_ASSERTION(obssvc, "Couldn't get observer service.");
if (obssvc)
+3 -4
View File
@@ -55,6 +55,7 @@
#include "prenv.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/dom/BarProps.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
@@ -509,8 +510,7 @@ NS_IMETHODIMP nsXULWindow::Destroy()
is destroyed, because onunload handlers fire then, and those being
script, anything could happen. A new window could open, even.
See bug 130719. */
nsCOMPtr<nsIObserverService> obssvc =
do_GetService("@mozilla.org/observer-service;1");
nsCOMPtr<nsIObserverService> obssvc = services::GetObserverService();
NS_ASSERTION(obssvc, "Couldn't get observer service?");
if (obssvc)
@@ -816,8 +816,7 @@ NS_IMETHODIMP nsXULWindow::SetVisibility(bool aVisibility)
windowMediator->UpdateWindowTimeStamp(static_cast<nsIXULWindow*>(this));
// notify observers so that we can hide the splash screen if possible
nsCOMPtr<nsIObserverService> obssvc
(do_GetService("@mozilla.org/observer-service;1"));
nsCOMPtr<nsIObserverService> obssvc = services::GetObserverService();
NS_ASSERTION(obssvc, "Couldn't get observer service.");
if (obssvc) {
obssvc->NotifyObservers(nullptr, "xul-window-visible", nullptr);