зеркало из https://github.com/mozilla/gecko-dev.git
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
Коммит
2935ab5736
|
@ -15,7 +15,7 @@ function ContentPermissionPrompt() {}
|
|||
ContentPermissionPrompt.prototype = {
|
||||
|
||||
handleExistingPermission: function handleExistingPermission(request) {
|
||||
let result = Services.perms.testExactPermission(request.uri, request.type);
|
||||
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
|
||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
request.allow();
|
||||
return true;
|
||||
|
@ -56,7 +56,7 @@ ContentPermissionPrompt.prototype = {
|
|||
"type": "permission-prompt",
|
||||
"permission": request.type,
|
||||
"id": requestId,
|
||||
"url": request.uri.spec
|
||||
"url": request.principal.URI.spec
|
||||
};
|
||||
let event = content.document.createEvent("CustomEvent");
|
||||
event.initCustomEvent("mozChromeEvent", true, true, details);
|
||||
|
|
|
@ -231,7 +231,7 @@ var gPluginHandler = {
|
|||
managePlugins: function (aEvent) {
|
||||
BrowserOpenAddonsMgr("addons://list/plugin");
|
||||
},
|
||||
|
||||
|
||||
// Callback for user clicking on the link in a click-to-play plugin
|
||||
// (where the plugin has an update)
|
||||
openPluginUpdatePage: function (aEvent) {
|
||||
|
@ -279,9 +279,8 @@ var gPluginHandler = {
|
|||
// The overlay is null if the XBL binding is not attached (element is display:none).
|
||||
if (overlay) {
|
||||
overlay.addEventListener("click", function(aEvent) {
|
||||
// Have to check that the target is a XULElement and not the link
|
||||
// to update the plugin
|
||||
if (aEvent.target instanceof XULElement &&
|
||||
// Have to check that the target is not the link to update the plugin
|
||||
if (!(aEvent.originalTarget instanceof HTMLAnchorElement) &&
|
||||
aEvent.button == 0 && aEvent.isTrusted)
|
||||
gPluginHandler.activateSinglePlugin(aEvent.target.ownerDocument.defaultView.top, aPlugin);
|
||||
}, true);
|
||||
|
|
|
@ -146,8 +146,7 @@ function test3() {
|
|||
var manageLink = gTestBrowser.contentDocument.getAnonymousElementByAttribute(pluginNode, "class", "managePluginsLink");
|
||||
ok(manageLink, "Test 3, found 'manage' link in plugin-problem binding");
|
||||
|
||||
EventUtils.synthesizeMouse(manageLink,
|
||||
5, 5, {}, gTestBrowser.contentWindow);
|
||||
EventUtils.synthesizeMouseAtCenter(manageLink, {}, gTestBrowser.contentWindow);
|
||||
}
|
||||
|
||||
function test4(tab, win) {
|
||||
|
@ -237,7 +236,7 @@ function test9a() {
|
|||
var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 9a, Plugin with id=" + plugin2.id + " should not be activated");
|
||||
|
||||
EventUtils.synthesizeMouse(plugin1, 100, 100, { });
|
||||
EventUtils.synthesizeMouseAtCenter(plugin1, {}, gTestBrowser.contentWindow);
|
||||
var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test9b, "Test 9a, Waited too long for plugin to activate");
|
||||
|
@ -266,7 +265,7 @@ function test9b() {
|
|||
var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 9b, Plugin with id=" + plugin2.id + " should not be activated");
|
||||
|
||||
EventUtils.synthesizeMouse(plugin2, 100, 100, { });
|
||||
EventUtils.synthesizeMouseAtCenter(plugin2, {}, gTestBrowser.contentWindow);
|
||||
var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test9c, "Test 9b, Waited too long for plugin to activate");
|
||||
|
@ -482,7 +481,7 @@ function test16b() {
|
|||
var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 16b, Plugin should not be activated");
|
||||
EventUtils.synthesizeMouse(plugin, 100, 100, { });
|
||||
EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test16c, "Test 16b, Waited too long for plugin to activate");
|
||||
}
|
||||
|
@ -590,10 +589,18 @@ function test18a() {
|
|||
test18b();
|
||||
}
|
||||
};
|
||||
EventUtils.synthesizeMouse(updateLink, 5, 5, {}, gTestBrowser.contentWindow);
|
||||
EventUtils.synthesizeMouseAtCenter(updateLink, {}, gTestBrowser.contentWindow);
|
||||
}
|
||||
|
||||
function test18b() {
|
||||
// clicking the update link should not activate the plugin
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 18b, Plugin should not be activated");
|
||||
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
ok(overlay.style.visibility != "hidden", "Test 18b, Plugin overlay should exist, not be hidden");
|
||||
|
||||
unregisterFakeBlocklistService();
|
||||
registerFakeBlocklistService(Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE);
|
||||
prepareTest(test18c, gTestRoot + "plugin_test.html");
|
||||
|
@ -616,5 +623,71 @@ function test18c() {
|
|||
var plugin = get_test_plugin();
|
||||
plugin.clicktoplay = false;
|
||||
|
||||
prepareTest(test19a, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests that clicking the icon of the overlay activates the plugin
|
||||
function test19a() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 19a, Plugin should not be activated");
|
||||
|
||||
var icon = doc.getAnonymousElementByAttribute(plugin, "class", "icon");
|
||||
EventUtils.synthesizeMouseAtCenter(icon, {}, gTestBrowser.contentWindow);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test19b, "Test 19a, Waited too long for plugin to activate");
|
||||
}
|
||||
|
||||
function test19b() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 19b, Plugin should be activated");
|
||||
|
||||
prepareTest(test19c, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests that clicking the text of the overlay activates the plugin
|
||||
function test19c() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 19c, Plugin should not be activated");
|
||||
|
||||
var text = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay");
|
||||
EventUtils.synthesizeMouseAtCenter(text, {}, gTestBrowser.contentWindow);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test19d, "Test 19c, Waited too long for plugin to activate");
|
||||
}
|
||||
|
||||
function test19d() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 19d, Plugin should be activated");
|
||||
|
||||
prepareTest(test19e, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests that clicking the box of the overlay activates the plugin
|
||||
// (just to be thorough)
|
||||
function test19e() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 19e, Plugin should not be activated");
|
||||
|
||||
EventUtils.synthesizeMouse(plugin, 50, 50, {}, gTestBrowser.contentWindow);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test19f, "Test 19e, Waited too long for plugin to activate");
|
||||
}
|
||||
|
||||
function test19f() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 19f, Plugin should be activated");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
|
|
@ -1560,13 +1560,14 @@ ContentPermissionPrompt.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
var requestingURI = request.uri;
|
||||
var requestingPrincipal = request.principal;
|
||||
var requestingURI = requestingPrincipal.URI;
|
||||
|
||||
// Ignore requests from non-nsIStandardURLs
|
||||
if (!(requestingURI instanceof Ci.nsIStandardURL))
|
||||
return;
|
||||
|
||||
var result = Services.perms.testExactPermission(requestingURI, "geo");
|
||||
var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, "geo");
|
||||
|
||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
request.allow();
|
||||
|
@ -1619,7 +1620,7 @@ ContentPermissionPrompt.prototype = {
|
|||
label: browserBundle.GetStringFromName("geolocation.alwaysShareLocation"),
|
||||
accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
|
||||
callback: function () {
|
||||
Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
request.allow();
|
||||
}
|
||||
});
|
||||
|
@ -1627,7 +1628,7 @@ ContentPermissionPrompt.prototype = {
|
|||
label: browserBundle.GetStringFromName("geolocation.neverShareLocation"),
|
||||
accessKey: browserBundle.GetStringFromName("geolocation.neverShareLocation.accesskey"),
|
||||
callback: function () {
|
||||
Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.DENY_ACTION);
|
||||
Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.DENY_ACTION);
|
||||
request.cancel();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3311,6 +3311,7 @@ stack[anonid=browserStack][responsivemode] {
|
|||
text-shadow: none;
|
||||
background-image: -moz-linear-gradient(top, #B4211B, #8A1915);
|
||||
border-radius: 1px;
|
||||
-moz-margin-end: 5px;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ interface nsIContentSecurityPolicy;
|
|||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
|
||||
|
||||
[scriptable, uuid(8a74b011-667d-4cfa-b2a2-b27582ba5f38)]
|
||||
[scriptable, uuid(6df7d16d-5b26-42a1-b1f7-069d46c37aa8)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
/**
|
||||
|
@ -230,13 +230,13 @@ interface nsIPrincipal : nsISerializable
|
|||
|
||||
const short APP_STATUS_NOT_INSTALLED = 0;
|
||||
const short APP_STATUS_INSTALLED = 1;
|
||||
const short APP_STATUS_TRUSTED = 2;
|
||||
const short APP_STATUS_PRIVILEGED = 2;
|
||||
const short APP_STATUS_CERTIFIED = 3;
|
||||
|
||||
/**
|
||||
* Shows the status of the app.
|
||||
* Can be: APP_STATUS_NOT_INSTALLED, APP_STATUS_INSTALLED,
|
||||
* APP_STATUS_TRUSTED or APP_STATUS_CERTIFIED.
|
||||
* APP_STATUS_PRIVILEGED or APP_STATUS_CERTIFIED.
|
||||
*/
|
||||
readonly attribute unsigned short appStatus;
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef DirectionalityUtils_h___
|
||||
#define DirectionalityUtils_h___
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsINode;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace directionality {
|
||||
|
||||
enum Directionality {
|
||||
eDir_NotSet = 0,
|
||||
eDir_RTL = 1,
|
||||
eDir_LTR = 2
|
||||
};
|
||||
|
||||
void SetDirectionality(mozilla::dom::Element* aElement, Directionality aDir,
|
||||
bool aNotify = true);
|
||||
|
||||
/**
|
||||
* Set the directionality of an element according to the algorithm defined at
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-directionality,
|
||||
* not including elements with auto direction.
|
||||
*
|
||||
* @return the directionality that the element was set to
|
||||
*/
|
||||
Directionality RecomputeDirectionality(mozilla::dom::Element* aElement,
|
||||
bool aNotify = true);
|
||||
|
||||
/**
|
||||
* Set the directionality of any descendants of a node that do not themselves
|
||||
* have a dir attribute.
|
||||
* For performance reasons we walk down the descendant tree in the rare case
|
||||
* of setting the dir attribute, rather than walking up the ancestor tree in
|
||||
* the much more common case of getting the element's directionality.
|
||||
*/
|
||||
void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement,
|
||||
Directionality aDir,
|
||||
bool aNotify = true);
|
||||
|
||||
} // end namespace directionality
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
#endif /* DirectionalityUtils_h___ */
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/dom/FragmentOrElement.h" // for base class
|
||||
#include "nsChangeHint.h" // for enum
|
||||
#include "nsEventStates.h" // for member
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
|
||||
class nsEventStateManager;
|
||||
class nsFocusManager;
|
||||
|
@ -217,18 +216,6 @@ public:
|
|||
*/
|
||||
virtual nsIAtom *GetClassAttributeName() const = 0;
|
||||
|
||||
inline mozilla::directionality::Directionality GetDirectionality() const {
|
||||
if (HasFlag(NODE_HAS_DIRECTION_RTL)) {
|
||||
return mozilla::directionality::eDir_RTL;
|
||||
}
|
||||
|
||||
if (HasFlag(NODE_HAS_DIRECTION_LTR)) {
|
||||
return mozilla::directionality::eDir_LTR;
|
||||
}
|
||||
|
||||
return mozilla::directionality::eDir_NotSet;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Method to get the _intrinsic_ content state of this element. This is the
|
||||
|
|
|
@ -48,7 +48,6 @@ $(NULL)
|
|||
EXPORTS_NAMESPACES = mozilla/dom mozilla
|
||||
|
||||
EXPORTS_mozilla/dom = \
|
||||
DirectionalityUtils.h \
|
||||
Element.h \
|
||||
FragmentOrElement.h \
|
||||
FromParser.h \
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "nsPIDOMWindow.h" // for use in inline functions
|
||||
#include "nsPropertyTable.h" // for member
|
||||
#include "nsTHashtable.h" // for member
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
|
||||
class imgIRequest;
|
||||
class nsAString;
|
||||
|
@ -398,10 +397,6 @@ public:
|
|||
{
|
||||
mBidiOptions = aBidiOptions;
|
||||
}
|
||||
|
||||
inline mozilla::directionality::Directionality GetDocumentDirectionality() {
|
||||
return mDirectionality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access HTTP header data (this may also get set from other
|
||||
|
@ -1858,9 +1853,6 @@ protected:
|
|||
// defined in nsBidiUtils.h
|
||||
PRUint32 mBidiOptions;
|
||||
|
||||
// The root directionality of this document.
|
||||
mozilla::directionality::Directionality mDirectionality;
|
||||
|
||||
nsCString mContentLanguage;
|
||||
private:
|
||||
nsCString mContentType;
|
||||
|
|
|
@ -145,16 +145,8 @@ enum {
|
|||
// Set if the node has had :hover selectors matched against it
|
||||
NODE_HAS_RELEVANT_HOVER_RULES = 0x00080000U,
|
||||
|
||||
// Set if the node has right-to-left directionality
|
||||
NODE_HAS_DIRECTION_RTL = 0x00100000U,
|
||||
|
||||
// Set if the node has left-to-right directionality
|
||||
NODE_HAS_DIRECTION_LTR = 0x00200000U,
|
||||
|
||||
NODE_ALL_DIRECTION_FLAGS = NODE_HAS_DIRECTION_LTR | NODE_HAS_DIRECTION_RTL,
|
||||
|
||||
// Remaining bits are node type specific.
|
||||
NODE_TYPE_SPECIFIC_BITS_OFFSET = 22
|
||||
NODE_TYPE_SPECIFIC_BITS_OFFSET = 20
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1287,8 +1279,6 @@ private:
|
|||
NodeIsContent,
|
||||
// Set if the node has animations or transitions
|
||||
ElementHasAnimations,
|
||||
// Set if node has a dir attribute with a valid value (ltr or rtl)
|
||||
NodeHasValidDirAttribute,
|
||||
// Guard value
|
||||
BooleanFlagCount
|
||||
};
|
||||
|
@ -1356,9 +1346,6 @@ public:
|
|||
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
|
||||
bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); }
|
||||
void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); }
|
||||
void SetHasValidDir() { SetBoolFlag(NodeHasValidDirAttribute); }
|
||||
void ClearHasValidDir() { ClearBoolFlag(NodeHasValidDirAttribute); }
|
||||
bool HasValidDir() const { return GetBoolFlag(NodeHasValidDirAttribute); }
|
||||
protected:
|
||||
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
||||
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=78: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIDOMNodeFilter.h"
|
||||
#include "nsTreeWalker.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace directionality {
|
||||
|
||||
typedef mozilla::dom::Element Element;
|
||||
|
||||
void
|
||||
SetDirectionality(Element* aElement, Directionality aDir, bool aNotify)
|
||||
{
|
||||
aElement->UnsetFlags(NODE_ALL_DIRECTION_FLAGS);
|
||||
switch (aDir) {
|
||||
case eDir_RTL:
|
||||
aElement->SetFlags(NODE_HAS_DIRECTION_RTL);
|
||||
break;
|
||||
case eDir_LTR:
|
||||
aElement->SetFlags(NODE_HAS_DIRECTION_LTR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
aElement->UpdateState(aNotify);
|
||||
}
|
||||
|
||||
Directionality
|
||||
RecomputeDirectionality(Element* aElement, bool aNotify)
|
||||
{
|
||||
Directionality dir = eDir_LTR;
|
||||
|
||||
if (aElement->HasValidDir()) {
|
||||
dir = aElement->GetDirectionality();
|
||||
} else {
|
||||
Element* parent = aElement->GetElementParent();
|
||||
if (parent) {
|
||||
// If the element doesn't have an explicit dir attribute with a valid
|
||||
// value, the directionality is the same as the parent element (but
|
||||
// don't propagate the parent directionality if it isn't set yet).
|
||||
Directionality parentDir = parent->GetDirectionality();
|
||||
if (parentDir != eDir_NotSet) {
|
||||
dir = parentDir;
|
||||
}
|
||||
} else {
|
||||
// If there is no parent element, the directionality is the same as the
|
||||
// document direction.
|
||||
Directionality documentDir =
|
||||
aElement->OwnerDoc()->GetDocumentDirectionality();
|
||||
if (documentDir != eDir_NotSet) {
|
||||
dir = documentDir;
|
||||
}
|
||||
}
|
||||
|
||||
SetDirectionality(aElement, dir, aNotify);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
void
|
||||
SetDirectionalityOnDescendants(Element* aElement, Directionality aDir,
|
||||
bool aNotify)
|
||||
{
|
||||
for (nsIContent* child = aElement->GetFirstChild(); child; ) {
|
||||
if (!child->IsElement()) {
|
||||
child = child->GetNextNode(aElement);
|
||||
continue;
|
||||
}
|
||||
|
||||
Element* element = child->AsElement();
|
||||
if (element->HasValidDir()) {
|
||||
child = child->GetNextNonChildNode(aElement);
|
||||
continue;
|
||||
}
|
||||
SetDirectionality(element, aDir, aNotify);
|
||||
child = child->GetNextNode(aElement);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace directionality
|
||||
|
||||
} // end namespace mozilla
|
||||
|
|
@ -53,7 +53,6 @@ LOCAL_INCLUDES = \
|
|||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
DirectionalityUtils.cpp \
|
||||
nsAtomListUtils.cpp \
|
||||
nsAttrAndChildArray.cpp \
|
||||
nsAttrValue.cpp \
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
#include "nsXMLEventsManager.h"
|
||||
|
||||
#include "nsBidiUtils.h"
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsIDOMXPathEvaluator.h"
|
||||
|
@ -171,7 +170,6 @@
|
|||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::directionality;
|
||||
|
||||
typedef nsTArray<Link*> LinkArray;
|
||||
|
||||
|
@ -1512,8 +1510,7 @@ nsIDocument::nsIDocument()
|
|||
mAllowDNSPrefetch(true),
|
||||
mIsBeingUsedAsImage(false),
|
||||
mHasLinksToUpdate(false),
|
||||
mPartID(0),
|
||||
mDirectionality(eDir_LTR)
|
||||
mPartID(0)
|
||||
{
|
||||
SetInDocument();
|
||||
}
|
||||
|
@ -5586,15 +5583,6 @@ nsDocument::SetDir(const nsAString& aDirection)
|
|||
// No presentation; just set it on ourselves
|
||||
SetBidiOptions(options);
|
||||
}
|
||||
Directionality dir = elt->mValue == IBMBIDI_TEXTDIRECTION_RTL ?
|
||||
eDir_RTL : eDir_LTR;
|
||||
SetDocumentDirectionality(dir);
|
||||
// Set the directionality of the root element and its descendants, if any
|
||||
Element* rootElement = GetRootElement();
|
||||
if (rootElement) {
|
||||
SetDirectionality(rootElement, dir, true);
|
||||
SetDirectionalityOnDescendants(rootElement, dir);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -1048,12 +1048,6 @@ protected:
|
|||
nsIContent* GetFirstBaseNodeWithHref();
|
||||
nsresult SetFirstBaseNodeWithHref(nsIContent *node);
|
||||
|
||||
inline void
|
||||
SetDocumentDirectionality(mozilla::directionality::Directionality aDir)
|
||||
{
|
||||
mDirectionality = aDir;
|
||||
}
|
||||
|
||||
// Get the first <title> element with the given IsNodeOfType type, or
|
||||
// return null if there isn't one
|
||||
nsIContent* GetTitleContent(PRUint32 aNodeType);
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsMutationEvent.h"
|
||||
#include "nsNodeUtils.h"
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsAttrValueOrString.h"
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -129,7 +128,6 @@
|
|||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::directionality;
|
||||
|
||||
nsEventStates
|
||||
Element::IntrinsicState() const
|
||||
|
@ -1360,13 +1358,6 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
||||
}
|
||||
|
||||
// This has to be here, rather than in nsGenericHTMLElement::BindToTree,
|
||||
// because it has to happen after updating the parent pointer, but before
|
||||
// recursively binding the kids.
|
||||
if (IsHTML()) {
|
||||
RecomputeDirectionality(this, false);
|
||||
}
|
||||
|
||||
// If NODE_FORCE_XBL_BINDINGS was set we might have anonymous children
|
||||
// that also need to be told that they are moving.
|
||||
nsresult rv;
|
||||
|
@ -1552,13 +1543,6 @@ nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
}
|
||||
}
|
||||
|
||||
// This has to be here, rather than in nsGenericHTMLElement::UnbindFromTree,
|
||||
// because it has to happen after unsetting the parent pointer, but before
|
||||
// recursively unbinding the kids.
|
||||
if (IsHTML()) {
|
||||
RecomputeDirectionality(this, false);
|
||||
}
|
||||
|
||||
if (aDeep) {
|
||||
// Do the kids. Don't call GetChildCount() here since that'll force
|
||||
// XUL to generate template children, which there is no need for since
|
||||
|
|
|
@ -270,7 +270,6 @@ GK_ATOM(dialog, "dialog")
|
|||
GK_ATOM(difference, "difference")
|
||||
GK_ATOM(digit, "digit")
|
||||
GK_ATOM(dir, "dir")
|
||||
GK_ATOM(directionality, "directionality")
|
||||
GK_ATOM(disableOutputEscaping, "disable-output-escaping")
|
||||
GK_ATOM(disabled, "disabled")
|
||||
GK_ATOM(display, "display")
|
||||
|
|
|
@ -381,8 +381,6 @@ MOCHITEST_FILES_B = \
|
|||
test_bug562652.html \
|
||||
test_bug562137.html \
|
||||
file_bug562137.txt \
|
||||
test_bug562169-1.html \
|
||||
test_bug562169-2.html \
|
||||
test_bug548193.html \
|
||||
file_bug548193.sjs \
|
||||
test_html_colors_quirks.html \
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=562169
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 562169</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562169">Mozilla Bug 562169</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<div dir="rtl" id="z"></div>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 562169 **/
|
||||
/** Test that adding an child to an element with dir="rtl" makes the
|
||||
child have rtl directionality, and removing the child makes it
|
||||
go back to ltr directionality **/
|
||||
|
||||
function checkSelector(element, expectedDir, expectedChild)
|
||||
{
|
||||
ok(element.querySelector(":dir("+expectedDir+")") == expectedChild,
|
||||
"direction should be " + expectedDir);
|
||||
}
|
||||
|
||||
var x = document.createElement("div");
|
||||
var y = document.createElement("div");
|
||||
x.appendChild(y);
|
||||
checkSelector(x, "ltr", y);
|
||||
$(z).appendChild(x);
|
||||
checkSelector(x, "rtl", y);
|
||||
$(z).removeChild(x);
|
||||
checkSelector(x, "ltr", y);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=562169
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 562169</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562169">Mozilla Bug 562169</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 562169 **/
|
||||
/** Test that a newly created element has ltr directionality **/
|
||||
|
||||
ok(document.createElement("div").mozMatchesSelector(":dir(ltr)"),
|
||||
"Element should be ltr on creation");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -248,10 +248,6 @@ private:
|
|||
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(41)
|
||||
// Platform does not support plugin content (some mobile platforms)
|
||||
#define NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM NS_DEFINE_EVENT_STATE_MACRO(42)
|
||||
// Element is ltr (for :dir pseudo-class)
|
||||
#define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(43)
|
||||
// Element is rtl (for :dir pseudo-class)
|
||||
#define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(44)
|
||||
|
||||
/**
|
||||
* NOTE: do not go over 63 without updating nsEventStates::InternalType!
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
|
||||
#include "nsHTMLParts.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
@ -97,7 +96,6 @@
|
|||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::directionality;
|
||||
|
||||
class nsINodeInfo;
|
||||
class nsIDOMNodeList;
|
||||
|
@ -1689,24 +1687,6 @@ nsGenericHTMLElement::UpdateEditableState(bool aNotify)
|
|||
nsStyledElement::UpdateEditableState(aNotify);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
nsGenericHTMLElement::IntrinsicState() const
|
||||
{
|
||||
nsEventStates state = nsGenericHTMLElementBase::IntrinsicState();
|
||||
|
||||
if (GetDirectionality() == eDir_RTL) {
|
||||
state |= NS_EVENT_STATE_RTL;
|
||||
state &= ~NS_EVENT_STATE_LTR;
|
||||
} else { // at least for HTML, directionality is exclusively LTR or RTL
|
||||
NS_ASSERTION(GetDirectionality() == eDir_LTR,
|
||||
"HTML element's directionality must be either RTL or LTR");
|
||||
state |= NS_EVENT_STATE_LTR;
|
||||
state &= ~NS_EVENT_STATE_RTL;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -1909,20 +1889,6 @@ nsGenericHTMLElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
else if (aNotify && aName == nsGkAtoms::spellcheck) {
|
||||
SyncEditorsOnSubtree(this);
|
||||
}
|
||||
else if (aName == nsGkAtoms::dir) {
|
||||
Directionality dir;
|
||||
if (aValue &&
|
||||
(aValue->Equals(nsGkAtoms::ltr, eIgnoreCase) ||
|
||||
aValue->Equals(nsGkAtoms::rtl, eIgnoreCase))) {
|
||||
SetHasValidDir();
|
||||
dir = aValue->Equals(nsGkAtoms::rtl, eIgnoreCase) ? eDir_RTL : eDir_LTR;
|
||||
SetDirectionality(this, dir, aNotify);
|
||||
} else {
|
||||
ClearHasValidDir();
|
||||
dir = RecomputeDirectionality(this, aNotify);
|
||||
}
|
||||
SetDirectionalityOnDescendants(this, dir, aNotify);
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElementBase::AfterSetAttr(aNamespaceID, aName,
|
||||
|
|
|
@ -49,8 +49,6 @@ public:
|
|||
{
|
||||
NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
|
||||
"Unexpected namespace");
|
||||
AddStatesSilently(NS_EVENT_STATE_LTR);
|
||||
SetFlags(NODE_HAS_DIRECTION_LTR);
|
||||
}
|
||||
|
||||
/** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/
|
||||
|
@ -204,8 +202,6 @@ public:
|
|||
|
||||
virtual void UpdateEditableState(bool aNotify);
|
||||
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
// Helper for setting our editable flag and notifying
|
||||
void DoSetEditableFlag(bool aEditable, bool aNotify) {
|
||||
SetEditableFlag(aEditable);
|
||||
|
|
|
@ -53,6 +53,26 @@ AppsService.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
getAppByLocalId: function getAppByLocalId(aLocalId) {
|
||||
debug("getAppByLocalId( " + aLocalId + " )");
|
||||
if (this.inParent) {
|
||||
return DOMApplicationRegistry.getAppByLocalId(aLocalId);
|
||||
} else {
|
||||
return this.cpmm.sendSyncMessage("WebApps:GetAppByLocalId",
|
||||
{ id: aLocalId })[0];
|
||||
}
|
||||
},
|
||||
|
||||
getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
|
||||
debug("getManifestURLByLocalId( " + aLocalId + " )");
|
||||
if (this.inParent) {
|
||||
return DOMApplicationRegistry.getManifestURLByLocalId(aLocalId);
|
||||
} else {
|
||||
return this.cpmm.sendSyncMessage("WebApps:GetManifestURLByLocalId",
|
||||
{ id: aLocalId })[0];
|
||||
}
|
||||
},
|
||||
|
||||
classID : APPS_SERVICE_CID,
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService])
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ let DOMApplicationRegistry = {
|
|||
"Webapps:GetInstalled", "Webapps:GetNotInstalled",
|
||||
"Webapps:Launch", "Webapps:GetAll",
|
||||
"Webapps:InstallPackage", "Webapps:GetBasePath",
|
||||
"WebApps:GetAppByManifestURL", "WebApps:GetAppLocalIdByManifestURL"];
|
||||
"WebApps:GetAppByManifestURL", "WebApps:GetAppLocalIdByManifestURL",
|
||||
"WebApps:GetAppByLocalId", "Webapps:GetManifestURLByLocalId"];
|
||||
|
||||
this.messages.forEach((function(msgName) {
|
||||
ppmm.addMessageListener(msgName, this);
|
||||
|
@ -249,6 +250,12 @@ let DOMApplicationRegistry = {
|
|||
case "WebApps:GetAppLocalIdByManifestURL":
|
||||
return { id: this.getAppLocalIdByManifestURL(msg.url) };
|
||||
break;
|
||||
case "WebApps:GetAppByLocalId":
|
||||
return this.getAppByLocalId(msg.id);
|
||||
break;
|
||||
case "WebApps:GetManifestURLByLocalId":
|
||||
return this.getManifestURLByLocalId(msg.id);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -698,6 +705,28 @@ let DOMApplicationRegistry = {
|
|||
return null;
|
||||
},
|
||||
|
||||
getAppByLocalId: function(aLocalId) {
|
||||
for (let id in this.webapps) {
|
||||
let app = this.webapps[id];
|
||||
if (app.localId == aLocalId) {
|
||||
return this._cloneAppObject(app);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
getManifestURLByLocalId: function(aLocalId) {
|
||||
for (let id in this.webapps) {
|
||||
let app = this.webapps[id];
|
||||
if (app.localId == aLocalId) {
|
||||
return app.manifestURL;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
getAppLocalIdByManifestURL: function(aManifestURL) {
|
||||
for (let id in this.webapps) {
|
||||
if (this.webapps[id].manifestURL == aManifestURL) {
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
#include "nsIPrincipal.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
using mozilla::unused; // <snicker>
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
|
||||
{
|
||||
|
@ -24,7 +25,7 @@ nsContentPermissionRequestProxy::~nsContentPermissionRequestProxy()
|
|||
|
||||
nsresult
|
||||
nsContentPermissionRequestProxy::Init(const nsACString & type,
|
||||
mozilla::dom::ContentPermissionRequestParent* parent)
|
||||
ContentPermissionRequestParent* parent)
|
||||
{
|
||||
NS_ASSERTION(parent, "null parent");
|
||||
mParent = parent;
|
||||
|
@ -63,13 +64,14 @@ nsContentPermissionRequestProxy::GetWindow(nsIDOMWindow * *aRequestingWindow)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentPermissionRequestProxy::GetUri(nsIURI * *aRequestingURI)
|
||||
nsContentPermissionRequestProxy::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequestingURI);
|
||||
if (mParent == nullptr)
|
||||
NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
|
||||
if (mParent == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aRequestingURI = mParent->mURI);
|
||||
NS_ADDREF(*aRequestingPrincipal = mParent->mPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -77,8 +79,10 @@ NS_IMETHODIMP
|
|||
nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequestingElement);
|
||||
if (mParent == nullptr)
|
||||
if (mParent == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aRequestingElement = mParent->mElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -86,9 +90,11 @@ nsContentPermissionRequestProxy::GetElement(nsIDOMElement * *aRequestingElement)
|
|||
NS_IMETHODIMP
|
||||
nsContentPermissionRequestProxy::Cancel()
|
||||
{
|
||||
if (mParent == nullptr)
|
||||
if (mParent == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
unused << mozilla::dom::ContentPermissionRequestParent::Send__delete__(mParent, false);
|
||||
}
|
||||
|
||||
unused << ContentPermissionRequestParent::Send__delete__(mParent, false);
|
||||
mParent = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -96,9 +102,10 @@ nsContentPermissionRequestProxy::Cancel()
|
|||
NS_IMETHODIMP
|
||||
nsContentPermissionRequestProxy::Allow()
|
||||
{
|
||||
if (mParent == nullptr)
|
||||
if (mParent == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
unused << mozilla::dom::ContentPermissionRequestParent::Send__delete__(mParent, true);
|
||||
}
|
||||
unused << ContentPermissionRequestParent::Send__delete__(mParent, true);
|
||||
mParent = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -108,11 +115,11 @@ namespace dom {
|
|||
|
||||
ContentPermissionRequestParent::ContentPermissionRequestParent(const nsACString& aType,
|
||||
nsIDOMElement *aElement,
|
||||
const IPC::URI& aUri)
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ContentPermissionRequestParent);
|
||||
|
||||
mURI = aUri;
|
||||
|
||||
mPrincipal = aPrincipal;
|
||||
mElement = aElement;
|
||||
mType = aType;
|
||||
}
|
||||
|
@ -127,8 +134,9 @@ ContentPermissionRequestParent::Recvprompt()
|
|||
{
|
||||
mProxy = new nsContentPermissionRequestProxy();
|
||||
NS_ASSERTION(mProxy, "Alloc of request proxy failed");
|
||||
if (NS_FAILED(mProxy->Init(mType, this)))
|
||||
if (NS_FAILED(mProxy->Init(mType, this))) {
|
||||
mProxy->Cancel();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "nsString.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/PContentPermissionRequestParent.h"
|
||||
|
||||
class nsContentPermissionRequestProxy;
|
||||
|
@ -21,19 +22,19 @@ namespace dom {
|
|||
class ContentPermissionRequestParent : public PContentPermissionRequestParent
|
||||
{
|
||||
public:
|
||||
ContentPermissionRequestParent(const nsACString& type, nsIDOMElement *element, const IPC::URI& principal);
|
||||
ContentPermissionRequestParent(const nsACString& type, nsIDOMElement *element, const IPC::Principal& principal);
|
||||
virtual ~ContentPermissionRequestParent();
|
||||
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIDOMElement> mElement;
|
||||
nsCOMPtr<nsContentPermissionRequestProxy> mProxy;
|
||||
nsCString mType;
|
||||
|
||||
private:
|
||||
private:
|
||||
virtual bool Recvprompt();
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
};
|
||||
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -42,10 +43,10 @@ class nsContentPermissionRequestProxy : public nsIContentPermissionRequest
|
|||
public:
|
||||
nsContentPermissionRequestProxy();
|
||||
virtual ~nsContentPermissionRequestProxy();
|
||||
|
||||
|
||||
nsresult Init(const nsACString& type, mozilla::dom::ContentPermissionRequestParent* parent);
|
||||
void OnParentDestroyed();
|
||||
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICONTENTPERMISSIONREQUEST
|
||||
|
||||
|
|
|
@ -62,14 +62,18 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
|||
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
|
||||
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aOwner, const nsAString& aPath)
|
||||
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue)
|
||||
: BluetoothPropertyContainer(BluetoothObjectType::TYPE_ADAPTER)
|
||||
, mJsUuids(nullptr)
|
||||
, mJsDeviceAddresses(nullptr)
|
||||
, mIsRooted(false)
|
||||
{
|
||||
BindToOwner(aOwner);
|
||||
mPath = aPath;
|
||||
const InfallibleTArray<BluetoothNamedValue>& values =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
for (uint32_t i = 0; i < values.Length(); ++i) {
|
||||
SetPropertyByValue(values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
BluetoothAdapter::~BluetoothAdapter()
|
||||
|
@ -175,21 +179,16 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
|||
|
||||
// static
|
||||
already_AddRefed<BluetoothAdapter>
|
||||
BluetoothAdapter::Create(nsPIDOMWindow* aOwner, const nsAString& aPath)
|
||||
BluetoothAdapter::Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue)
|
||||
{
|
||||
// Make sure we at least have a path
|
||||
NS_ASSERTION(!aPath.IsEmpty(), "Adapter created with empty path!");
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
NS_WARNING("BluetoothService not available!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aOwner, aPath);
|
||||
nsString path;
|
||||
path = adapter->GetPath();
|
||||
if (NS_FAILED(bs->RegisterBluetoothSignalHandler(path, adapter))) {
|
||||
nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aOwner, aValue);
|
||||
if (NS_FAILED(bs->RegisterBluetoothSignalHandler(adapter->GetPath(), adapter))) {
|
||||
NS_WARNING("Failed to register object with observer!");
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ BEGIN_BLUETOOTH_NAMESPACE
|
|||
|
||||
class BluetoothSignal;
|
||||
class BluetoothNamedValue;
|
||||
class BluetoothValue;
|
||||
|
||||
class BluetoothAdapter : public nsDOMEventTargetHelper
|
||||
, public nsIDOMBluetoothAdapter
|
||||
|
@ -36,7 +37,7 @@ public:
|
|||
nsDOMEventTargetHelper)
|
||||
|
||||
static already_AddRefed<BluetoothAdapter>
|
||||
Create(nsPIDOMWindow* aOwner, const nsAString& name);
|
||||
Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
|
||||
|
||||
void Notify(const BluetoothSignal& aParam);
|
||||
|
||||
|
@ -57,7 +58,7 @@ public:
|
|||
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue);
|
||||
private:
|
||||
|
||||
BluetoothAdapter(nsPIDOMWindow* aOwner, const nsAString& aPath);
|
||||
BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
|
||||
~BluetoothAdapter();
|
||||
|
||||
void Root();
|
||||
|
|
|
@ -64,10 +64,9 @@ public:
|
|||
nsCOMPtr<nsIDOMBluetoothAdapter> adapter;
|
||||
*aValue = JSVAL_VOID;
|
||||
|
||||
const nsString& path =
|
||||
mReply->get_BluetoothReplySuccess().value().get_nsString();
|
||||
adapter = BluetoothAdapter::Create(mManagerPtr->GetOwner(),
|
||||
path);
|
||||
const InfallibleTArray<BluetoothNamedValue>& v =
|
||||
mReply->get_BluetoothReplySuccess().value().get_ArrayOfBluetoothNamedValue();
|
||||
adapter = BluetoothAdapter::Create(mManagerPtr->GetOwner(), v);
|
||||
|
||||
nsresult rv;
|
||||
nsIScriptContext* sc = mManagerPtr->GetContextForEventHandlers(&rv);
|
||||
|
|
|
@ -22,34 +22,37 @@ using namespace mozilla;
|
|||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
nsRefPtr<BluetoothService> gBluetoothService;
|
||||
nsCOMPtr<nsIThread> gToggleBtThread;
|
||||
int gPendingInitCount = 0;
|
||||
bool gInShutdown = false;
|
||||
static nsRefPtr<BluetoothService> gBluetoothService;
|
||||
static bool gInShutdown = false;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(BluetoothService, nsIObserver)
|
||||
|
||||
class ToggleBtAck : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ToggleBtAck(bool aEnabled) :
|
||||
mEnabled(aEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gPendingInitCount--;
|
||||
|
||||
if (gPendingInitCount) {
|
||||
return NS_OK;
|
||||
|
||||
if (!mEnabled || gInShutdown) {
|
||||
nsCOMPtr<nsIThread> t;
|
||||
gBluetoothService->mBluetoothCommandThread.swap(t);
|
||||
t->Shutdown();
|
||||
}
|
||||
|
||||
if (gInShutdown) {
|
||||
gBluetoothService = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIThread> t;
|
||||
gToggleBtThread.swap(t);
|
||||
t->Shutdown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool mEnabled;
|
||||
};
|
||||
|
||||
class ToggleBtTask : public nsRunnable
|
||||
|
@ -82,7 +85,7 @@ public:
|
|||
// Always has to be called since this is where we take care of our reference
|
||||
// count for runnables. If there's an error, replyError won't be empty, so
|
||||
// consider our status flipped.
|
||||
nsCOMPtr<nsIRunnable> ackTask = new ToggleBtAck();
|
||||
nsCOMPtr<nsIRunnable> ackTask = new ToggleBtAck(mEnabled);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(ackTask))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
|
@ -168,17 +171,16 @@ BluetoothService::StartStopBluetooth(BluetoothReplyRunnable* aResultRunnable,
|
|||
NS_ERROR("Start called while in shutdown!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!gToggleBtThread) {
|
||||
nsresult rv = NS_NewNamedThread("BluetoothCtrl",
|
||||
getter_AddRefs(gToggleBtThread));
|
||||
if (!mBluetoothCommandThread) {
|
||||
nsresult rv = NS_NewNamedThread("BluetoothCmd",
|
||||
getter_AddRefs(mBluetoothCommandThread));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(aStart, aResultRunnable);
|
||||
if (NS_FAILED(gToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL))) {
|
||||
if (NS_FAILED(mBluetoothCommandThread->Dispatch(r, NS_DISPATCH_NORMAL))) {
|
||||
NS_WARNING("Cannot dispatch firmware loading task!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
gPendingInitCount++;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -192,6 +192,19 @@ public:
|
|||
const nsAString& aPattern,
|
||||
int aAttributeId) = 0;
|
||||
|
||||
/**
|
||||
* Due to the fact that some operations require multiple calls, a
|
||||
* CommandThread is created that can run blocking, platform-specific calls
|
||||
* where either no asynchronous equivilent exists, or else where multiple
|
||||
* asynchronous calls would require excessive runnable bouncing between main
|
||||
* thread and IO thread.
|
||||
*
|
||||
* For instance, when we retrieve an Adapter object, we would like it to come
|
||||
* with all of its properties filled in and registered as an agent, which
|
||||
* requires a minimum of 3 calls to platform specific code on some platforms.
|
||||
*
|
||||
*/
|
||||
nsCOMPtr<nsIThread> mBluetoothCommandThread;
|
||||
protected:
|
||||
BluetoothService()
|
||||
{
|
||||
|
|
|
@ -127,6 +127,13 @@ static const char* sBluetoothDBusSignals[] =
|
|||
"type='signal',interface='org.bluez.AudioSink'"
|
||||
};
|
||||
|
||||
/**
|
||||
* DBus Connection held for the BluetoothCommandThread to use. Should never be
|
||||
* used by any other thread.
|
||||
*
|
||||
*/
|
||||
static nsAutoPtr<RawDBusConnection> gThreadConnection;
|
||||
|
||||
class DistributeBluetoothSignalTask : public nsRunnable {
|
||||
BluetoothSignal mSignal;
|
||||
public:
|
||||
|
@ -149,8 +156,14 @@ public:
|
|||
};
|
||||
|
||||
bool
|
||||
IsDBusMessageError(DBusMessage* aMsg, nsAString& aError)
|
||||
IsDBusMessageError(DBusMessage* aMsg, DBusError* aErr, nsAString& aErrorStr)
|
||||
{
|
||||
if(aErr && dbus_error_is_set(aErr)) {
|
||||
aErrorStr = NS_ConvertUTF8toUTF16(aErr->message);
|
||||
LOG_AND_FREE_DBUS_ERROR(aErr);
|
||||
return true;
|
||||
}
|
||||
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_ERROR) {
|
||||
|
@ -159,12 +172,15 @@ IsDBusMessageError(DBusMessage* aMsg, nsAString& aError)
|
|||
&error_msg, DBUS_TYPE_INVALID) ||
|
||||
!error_msg) {
|
||||
if (dbus_error_is_set(&err)) {
|
||||
aError = NS_ConvertUTF8toUTF16(err.message);
|
||||
aErrorStr = NS_ConvertUTF8toUTF16(err.message);
|
||||
LOG_AND_FREE_DBUS_ERROR(&err);
|
||||
return true;
|
||||
} else {
|
||||
aErrorStr.AssignLiteral("Unknown Error");
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
aError = NS_ConvertUTF8toUTF16(error_msg);
|
||||
aErrorStr = NS_ConvertUTF8toUTF16(error_msg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -173,15 +189,14 @@ IsDBusMessageError(DBusMessage* aMsg, nsAString& aError)
|
|||
|
||||
void
|
||||
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
const BluetoothValue& aValue, const nsAString& aError)
|
||||
const BluetoothValue& aValue, const nsAString& aErrorStr)
|
||||
{
|
||||
// Reply will be deleted by the runnable after running on main thread
|
||||
BluetoothReply* reply;
|
||||
if (!aError.IsEmpty()) {
|
||||
nsString err(aError);
|
||||
if (!aErrorStr.IsEmpty()) {
|
||||
nsString err(aErrorStr);
|
||||
reply = new BluetoothReply(BluetoothReplyError(err));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
reply = new BluetoothReply(BluetoothReplySuccess(aValue));
|
||||
}
|
||||
|
||||
|
@ -192,12 +207,12 @@ DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
|||
}
|
||||
|
||||
void
|
||||
UnpackObjectPathMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
UnpackObjectPathMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue, nsAString& aErrorStr)
|
||||
{
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (!IsDBusMessageError(aMsg, aErrorStr)) {
|
||||
if (!IsDBusMessageError(aMsg, aErr, aErrorStr)) {
|
||||
NS_ASSERTION(dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN,
|
||||
"Got dbus callback that's not a METHOD_RETURN!");
|
||||
const char* object_path;
|
||||
|
@ -214,7 +229,7 @@ UnpackObjectPathMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
|||
}
|
||||
}
|
||||
|
||||
typedef void (*UnpackFunc)(DBusMessage*, BluetoothValue&, nsAString&);
|
||||
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
|
||||
|
||||
void
|
||||
RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
|
||||
|
@ -228,23 +243,24 @@ RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
|
|||
|
||||
nsString replyError;
|
||||
BluetoothValue v;
|
||||
aFunc(aMsg, v, replyError);
|
||||
aFunc(aMsg, nsnull, v, replyError);
|
||||
DispatchBluetoothReply(replyRunnable, v, replyError);
|
||||
}
|
||||
|
||||
void
|
||||
GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackObjectPathMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackObjectPathMessage);
|
||||
}
|
||||
|
||||
void
|
||||
UnpackVoidMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
UnpackVoidMessage(DBusMessage* aMsg, DBusError* aErr, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (!IsDBusMessageError(aMsg, aErrorStr) &&
|
||||
if (!IsDBusMessageError(aMsg, aErr, aErrorStr) &&
|
||||
dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN &&
|
||||
!dbus_message_get_args(aMsg, &err, DBUS_TYPE_INVALID)) {
|
||||
if (dbus_error_is_set(&err)) {
|
||||
|
@ -257,7 +273,8 @@ UnpackVoidMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
|||
void
|
||||
GetVoidCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackVoidMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackVoidMessage);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -381,11 +398,13 @@ ParseProperties(DBusMessageIter* aIter,
|
|||
aValue = props;
|
||||
}
|
||||
|
||||
void UnpackPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr, Properties* aPropertyTypes,
|
||||
const int aPropertyTypeLen)
|
||||
void
|
||||
UnpackPropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue, nsAString& aErrorStr,
|
||||
Properties* aPropertyTypes,
|
||||
const int aPropertyTypeLen)
|
||||
{
|
||||
if (!IsDBusMessageError(aMsg, aErrorStr) &&
|
||||
if (!IsDBusMessageError(aMsg, aErr, aErrorStr) &&
|
||||
dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
|
||||
DBusMessageIter iter;
|
||||
if (!dbus_message_iter_init(aMsg, &iter)) {
|
||||
|
@ -397,26 +416,32 @@ void UnpackPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
|||
}
|
||||
}
|
||||
|
||||
void UnpackAdapterPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
void
|
||||
UnpackAdapterPropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
|
||||
UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr,
|
||||
sAdapterProperties,
|
||||
ArrayLength(sAdapterProperties));
|
||||
}
|
||||
|
||||
void UnpackDevicePropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
void
|
||||
UnpackDevicePropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
|
||||
UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr,
|
||||
sDeviceProperties,
|
||||
ArrayLength(sDeviceProperties));
|
||||
}
|
||||
|
||||
void UnpackManagerPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
void
|
||||
UnpackManagerPropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
|
||||
UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr,
|
||||
sManagerProperties,
|
||||
ArrayLength(sManagerProperties));
|
||||
}
|
||||
|
@ -424,19 +449,22 @@ void UnpackManagerPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
|||
void
|
||||
GetManagerPropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackManagerPropertiesMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackManagerPropertiesMessage);
|
||||
}
|
||||
|
||||
void
|
||||
GetAdapterPropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackAdapterPropertiesMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackAdapterPropertiesMessage);
|
||||
}
|
||||
|
||||
void
|
||||
GetDevicePropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackDevicePropertiesMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackDevicePropertiesMessage);
|
||||
}
|
||||
|
||||
static DBusCallback sBluetoothDBusPropCallbacks[] =
|
||||
|
@ -611,7 +639,15 @@ BluetoothDBusService::StartInternal()
|
|||
}
|
||||
|
||||
if (NS_FAILED(EstablishDBusConnection())) {
|
||||
NS_WARNING("Cannot start DBus connection!");
|
||||
NS_WARNING("Cannot start Main Thread DBus connection!");
|
||||
StopDBus();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
gThreadConnection = new RawDBusConnection();
|
||||
|
||||
if (NS_FAILED(gThreadConnection->EstablishDBusConnection())) {
|
||||
NS_WARNING("Cannot start Sync Thread DBus connection!");
|
||||
StopDBus();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -667,33 +703,95 @@ BluetoothDBusService::StopInternal()
|
|||
dbus_connection_remove_filter(mConnection, EventFilter, nullptr);
|
||||
|
||||
mConnection = nullptr;
|
||||
gThreadConnection = nullptr;
|
||||
mBluetoothSignalObserverTable.Clear();
|
||||
StopDBus();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class DefaultAdapterPropertiesRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
DefaultAdapterPropertiesRunnable(BluetoothReplyRunnable* aRunnable)
|
||||
: mRunnable(dont_AddRef(aRunnable))
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
|
||||
BluetoothValue v;
|
||||
nsString replyError;
|
||||
|
||||
DBusMessage* msg = dbus_func_args_timeout(gThreadConnection->GetConnection(),
|
||||
1000,
|
||||
&err,
|
||||
"/",
|
||||
DBUS_MANAGER_IFACE,
|
||||
"DefaultAdapter",
|
||||
DBUS_TYPE_INVALID);
|
||||
UnpackObjectPathMessage(msg, &err, v, replyError);
|
||||
if(msg) {
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
if(!replyError.IsEmpty()) {
|
||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsString path = v.get_nsString();
|
||||
nsCString tmp_path = NS_ConvertUTF16toUTF8(path);
|
||||
const char* object_path = tmp_path.get();
|
||||
|
||||
v = InfallibleTArray<BluetoothNamedValue>();
|
||||
msg = dbus_func_args_timeout(gThreadConnection->GetConnection(),
|
||||
1000,
|
||||
&err,
|
||||
object_path,
|
||||
"org.bluez.Adapter",
|
||||
"GetProperties",
|
||||
DBUS_TYPE_INVALID);
|
||||
UnpackAdapterPropertiesMessage(msg, &err, v, replyError);
|
||||
|
||||
if(!replyError.IsEmpty()) {
|
||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if(msg) {
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
// We have to manually attach the path to the rest of the elements
|
||||
v.get_ArrayOfBluetoothNamedValue().AppendElement(BluetoothNamedValue(NS_LITERAL_STRING("Path"),
|
||||
path));
|
||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||
};
|
||||
|
||||
nsresult
|
||||
BluetoothDBusService::GetDefaultAdapterPathInternal(BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
if (!mConnection) {
|
||||
if (!mConnection || !gThreadConnection) {
|
||||
NS_ERROR("Bluetooth service not started yet!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
|
||||
|
||||
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
||||
|
||||
if (!dbus_func_args_async(mConnection,
|
||||
1000,
|
||||
GetObjectPathCallback,
|
||||
(void*)aRunnable,
|
||||
"/",
|
||||
"org.bluez.Manager",
|
||||
"DefaultAdapter",
|
||||
DBUS_TYPE_INVALID)) {
|
||||
NS_WARNING("Could not start async function!");
|
||||
nsRefPtr<nsRunnable> func(new DefaultAdapterPropertiesRunnable(runnable));
|
||||
if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
|
||||
NS_WARNING("Cannot dispatch firmware loading task!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
runnable.forget();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "nsIDOMDeviceStorage.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
|
||||
|
@ -55,7 +56,7 @@ private:
|
|||
PRInt32 mStorageType;
|
||||
nsCOMPtr<nsIFile> mFile;
|
||||
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
friend class WatchFileEvent;
|
||||
friend class DeviceStorageRequest;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "mozilla/Services.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "GeneratedEvents.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
|
||||
// Microsoft's API Name hackery sucks
|
||||
#undef CreateEvent
|
||||
|
@ -636,14 +637,14 @@ NS_IMPL_ADDREF_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
|
|||
NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
|
||||
|
||||
nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
|
||||
nsIURI* aURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
DeviceStorageFile* aFile,
|
||||
PRUint64 aSince)
|
||||
: DOMRequest(aWindow)
|
||||
, mOkToCallContinue(false)
|
||||
, mSince(aSince)
|
||||
, mFile(aFile)
|
||||
, mURI(aURI)
|
||||
, mPrincipal(aPrincipal)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -659,9 +660,9 @@ nsDOMDeviceStorageCursor::GetType(nsACString & aType)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDeviceStorageCursor::GetUri(nsIURI * *aRequestingURI)
|
||||
nsDOMDeviceStorageCursor::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
||||
{
|
||||
NS_IF_ADDREF(*aRequestingURI = mURI);
|
||||
NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -937,28 +938,28 @@ public:
|
|||
|
||||
DeviceStorageRequest(const DeviceStorageRequestType aRequestType,
|
||||
nsPIDOMWindow *aWindow,
|
||||
nsIURI *aURI,
|
||||
nsIPrincipal *aPrincipal,
|
||||
DeviceStorageFile *aFile,
|
||||
DOMRequest* aRequest,
|
||||
nsDOMDeviceStorage *aDeviceStorage,
|
||||
nsIDOMEventListener *aListener)
|
||||
: mRequestType(aRequestType)
|
||||
, mWindow(aWindow)
|
||||
, mURI(aURI)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mFile(aFile)
|
||||
, mRequest(aRequest)
|
||||
, mDeviceStorage(aDeviceStorage)
|
||||
, mListener(aListener) {}
|
||||
, mListener(aListener) {}
|
||||
|
||||
DeviceStorageRequest(const DeviceStorageRequestType aRequestType,
|
||||
nsPIDOMWindow *aWindow,
|
||||
nsIURI *aURI,
|
||||
nsIPrincipal *aPrincipal,
|
||||
DeviceStorageFile *aFile,
|
||||
DOMRequest* aRequest,
|
||||
nsIDOMBlob *aBlob = nullptr)
|
||||
: mRequestType(aRequestType)
|
||||
, mWindow(aWindow)
|
||||
, mURI(aURI)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mFile(aFile)
|
||||
, mRequest(aRequest)
|
||||
, mBlob(aBlob) {}
|
||||
|
@ -987,7 +988,7 @@ public:
|
|||
AddRef();
|
||||
|
||||
nsCString type = NS_LITERAL_CSTRING("device-storage");
|
||||
child->SendPContentPermissionRequestConstructor(this, type, IPC::URI(mURI));
|
||||
child->SendPContentPermissionRequestConstructor(this, type, IPC::Principal(mPrincipal));
|
||||
|
||||
Sendprompt();
|
||||
return NS_OK;
|
||||
|
@ -1006,9 +1007,9 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetUri(nsIURI * *aRequestingURI)
|
||||
NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
||||
{
|
||||
NS_IF_ADDREF(*aRequestingURI = mURI);
|
||||
NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1153,7 +1154,7 @@ public:
|
|||
private:
|
||||
PRInt32 mRequestType;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
|
||||
nsRefPtr<DOMRequest> mRequest;
|
||||
|
@ -1226,14 +1227,14 @@ nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType)
|
|||
|
||||
BindToOwner(aWindow);
|
||||
|
||||
// Grab the uri of the document
|
||||
// Grab the principal of the document
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
aWindow->GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
if (!doc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
|
||||
mPrincipal = doc->NodePrincipal();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1311,7 +1312,7 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob *aBlob,
|
|||
}
|
||||
else {
|
||||
r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WRITE,
|
||||
win, mURI, dsf, request, aBlob);
|
||||
win, mPrincipal, dsf, request, aBlob);
|
||||
}
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
|
@ -1367,7 +1368,7 @@ nsDOMDeviceStorage::GetInternal(const JS::Value & aPath,
|
|||
r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
|
||||
} else {
|
||||
r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_READ,
|
||||
win, mURI, dsf, request);
|
||||
win, mPrincipal, dsf, request);
|
||||
}
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
|
@ -1402,7 +1403,7 @@ nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMReq
|
|||
}
|
||||
else {
|
||||
r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_DELETE,
|
||||
win, mURI, dsf, request);
|
||||
win, mPrincipal, dsf, request);
|
||||
}
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
|
@ -1485,7 +1486,8 @@ nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName,
|
|||
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, path);
|
||||
dsf->SetEditable(aEditable);
|
||||
|
||||
nsRefPtr<nsDOMDeviceStorageCursor> cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, since);
|
||||
nsRefPtr<nsDOMDeviceStorageCursor> cursor = new nsDOMDeviceStorageCursor(win, mPrincipal,
|
||||
dsf, since);
|
||||
nsRefPtr<DeviceStorageCursorRequest> r = new DeviceStorageCursorRequest(cursor);
|
||||
|
||||
NS_ADDREF(*aRetval = cursor);
|
||||
|
@ -1507,7 +1509,7 @@ nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName,
|
|||
r->AddRef();
|
||||
|
||||
nsCString type = NS_LITERAL_CSTRING("device-storage");
|
||||
child->SendPContentPermissionRequestConstructor(r, type, IPC::URI(mURI));
|
||||
child->SendPContentPermissionRequestConstructor(r, type, IPC::Principal(mPrincipal));
|
||||
|
||||
r->Sendprompt();
|
||||
|
||||
|
@ -1613,7 +1615,7 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType,
|
|||
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
||||
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile);
|
||||
nsCOMPtr<nsIRunnable> r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WATCH,
|
||||
win, mURI, dsf, request, this, aListener);
|
||||
win, mPrincipal, dsf, request, this, aListener);
|
||||
NS_DispatchToMainThread(r);
|
||||
return nsDOMEventTargetHelper::AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted, aArgc);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ class nsPIDOMWindow;
|
|||
#include "nsIDOMWindow.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
@ -86,7 +87,7 @@ public:
|
|||
NS_DECL_NSIDOMDEVICESTORAGECURSOR
|
||||
|
||||
nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
|
||||
nsIURI* aURI,
|
||||
nsIPrincipal* aPrincipal,
|
||||
DeviceStorageFile* aFile,
|
||||
PRUint64 aSince);
|
||||
|
||||
|
@ -102,7 +103,7 @@ private:
|
|||
~nsDOMDeviceStorageCursor();
|
||||
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
//helpers
|
||||
|
|
|
@ -13,8 +13,14 @@ USING_FILE_NAMESPACE
|
|||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS0(ArchiveItem)
|
||||
|
||||
ArchiveItem::ArchiveItem()
|
||||
{
|
||||
MOZ_COUNT_CTOR(ArchiveItem);
|
||||
}
|
||||
|
||||
ArchiveItem::~ArchiveItem()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ArchiveItem);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ class ArchiveItem : public nsISupports
|
|||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
ArchiveItem();
|
||||
virtual ~ArchiveItem();
|
||||
|
||||
// Getter/Setter for the type
|
||||
|
|
|
@ -23,11 +23,13 @@ ArchiveReader::ArchiveReader()
|
|||
mWindow(nullptr),
|
||||
mStatus(NOT_STARTED)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ArchiveReader);
|
||||
nsLayoutStatics::AddRef();
|
||||
}
|
||||
|
||||
ArchiveReader::~ArchiveReader()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ArchiveReader);
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ ArchiveRequest::ArchiveRequest(nsIDOMWindow* aWindow,
|
|||
: DOMRequest(aWindow),
|
||||
mArchiveReader(aReader)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ArchiveRequest);
|
||||
nsLayoutStatics::AddRef();
|
||||
|
||||
/* An event to make this request asynchronous: */
|
||||
|
@ -60,6 +61,7 @@ ArchiveRequest::ArchiveRequest(nsIDOMWindow* aWindow,
|
|||
|
||||
ArchiveRequest::~ArchiveRequest()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ArchiveRequest);
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,12 @@ ArchiveZipItem::ArchiveZipItem(const char* aFilename,
|
|||
: mFilename(aFilename),
|
||||
mCentralStruct(aCentralStruct)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ArchiveZipItem);
|
||||
}
|
||||
|
||||
ArchiveZipItem::~ArchiveZipItem()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ArchiveZipItem);
|
||||
}
|
||||
|
||||
// Getter/Setter for the filename
|
||||
|
|
|
@ -19,6 +19,7 @@ class ArchiveZipItem : public ArchiveItem
|
|||
public:
|
||||
ArchiveZipItem(const char* aFilename,
|
||||
ZipCentral& aCentralStruct);
|
||||
virtual ~ArchiveZipItem();
|
||||
|
||||
void SetFilename(const nsCString& aFilename);
|
||||
nsCString GetFilename();
|
||||
|
|
|
@ -30,11 +30,14 @@ public:
|
|||
mFilename(aFilename),
|
||||
mStart(aStart),
|
||||
mLength(aLength),
|
||||
mRunning(false)
|
||||
{}
|
||||
|
||||
~ArchiveInputStream()
|
||||
mStatus(NotStarted)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ArchiveInputStream);
|
||||
}
|
||||
|
||||
virtual ~ArchiveInputStream()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ArchiveInputStream);
|
||||
Close();
|
||||
}
|
||||
|
||||
|
@ -53,7 +56,11 @@ private: // data
|
|||
|
||||
z_stream mZs;
|
||||
|
||||
bool mRunning;
|
||||
enum {
|
||||
NotStarted,
|
||||
Started,
|
||||
Done
|
||||
} mStatus;
|
||||
|
||||
struct {
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
|
@ -147,16 +154,15 @@ ArchiveInputStream::Init()
|
|||
}
|
||||
}
|
||||
|
||||
mRunning = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ArchiveInputStream::Close()
|
||||
{
|
||||
if (mRunning) {
|
||||
if (mStatus != NotStarted) {
|
||||
inflateEnd(&mZs);
|
||||
mRunning = false;
|
||||
mStatus = NotStarted;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -177,18 +183,22 @@ ArchiveInputStream::Read(char* aBuffer,
|
|||
NS_ENSURE_ARG_POINTER(aBuffer);
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
PRUint32 ret;
|
||||
nsresult rv;
|
||||
|
||||
// This is the first time:
|
||||
if (!mRunning) {
|
||||
if (mStatus == NotStarted) {
|
||||
mStatus = Started;
|
||||
|
||||
rv = Init();
|
||||
if (rv != NS_OK)
|
||||
return rv;
|
||||
|
||||
// Let's set avail_out to -1 so we read something from the stream.
|
||||
mZs.avail_out = (uInt)-1;
|
||||
}
|
||||
|
||||
// Nothing more can be read
|
||||
if (mData.sizeToBeRead == 0) {
|
||||
if (mStatus == Done) {
|
||||
*_retval = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -200,15 +210,20 @@ ArchiveInputStream::Read(char* aBuffer,
|
|||
(mData.sizeToBeRead > aCount ?
|
||||
aCount : mData.sizeToBeRead),
|
||||
_retval);
|
||||
if (rv == NS_OK)
|
||||
if (rv == NS_OK) {
|
||||
mData.sizeToBeRead -= *_retval;
|
||||
|
||||
if (mData.sizeToBeRead == 0)
|
||||
mStatus = Done;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// We have nothing ready to be processed:
|
||||
if (mZs.avail_out == 0)
|
||||
if (mZs.avail_out != 0 && mData.sizeToBeRead != 0)
|
||||
{
|
||||
PRUint32 ret;
|
||||
rv = mData.inputStream->Read((char*)mData.input,
|
||||
(mData.sizeToBeRead > sizeof(mData.input) ?
|
||||
sizeof(mData.input) : mData.sizeToBeRead),
|
||||
|
@ -230,10 +245,13 @@ ArchiveInputStream::Read(char* aBuffer,
|
|||
mZs.avail_out = aCount;
|
||||
mZs.next_out = (unsigned char*)aBuffer;
|
||||
|
||||
ret = inflate(&mZs, mData.sizeToBeRead ? Z_NO_FLUSH : Z_FINISH);
|
||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||
int ret = inflate(&mZs, mData.sizeToBeRead ? Z_NO_FLUSH : Z_FINISH);
|
||||
if (ret != Z_BUF_ERROR && ret != Z_OK && ret != Z_STREAM_END)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (ret == Z_STREAM_END)
|
||||
mStatus = Done;
|
||||
|
||||
*_retval = aCount - mZs.avail_out;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
mFilename(aName)
|
||||
{
|
||||
NS_ASSERTION(mArchiveReader, "must have a reader");
|
||||
MOZ_COUNT_CTOR(ArchiveZipFile);
|
||||
}
|
||||
|
||||
ArchiveZipFile(const nsAString& aName,
|
||||
|
@ -44,6 +45,12 @@ public:
|
|||
mFilename(aName)
|
||||
{
|
||||
NS_ASSERTION(mArchiveReader, "must have a reader");
|
||||
MOZ_COUNT_CTOR(ArchiveZipFile);
|
||||
}
|
||||
|
||||
virtual ~ArchiveZipFile()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ArchiveZipFile);
|
||||
}
|
||||
|
||||
// Overrides:
|
||||
|
|
|
@ -15,7 +15,7 @@ interface mozIDOMApplication;
|
|||
* This service allows accessing some DOMApplicationRegistry methods from
|
||||
* non-javascript code.
|
||||
*/
|
||||
[scriptable, uuid(1210a0f3-add3-4381-b892-9c102e3afc42)]
|
||||
[scriptable, uuid(04e4ef3c-1a30-45bc-ab08-291820f13872)]
|
||||
interface nsIAppsService : nsISupports
|
||||
{
|
||||
mozIDOMApplication getAppByManifestURL(in DOMString manifestURL);
|
||||
|
@ -27,4 +27,14 @@ interface nsIAppsService : nsISupports
|
|||
* installed manifest URL.
|
||||
*/
|
||||
unsigned long getAppLocalIdByManifestURL(in DOMString manifestURL);
|
||||
|
||||
/**
|
||||
* Returns the application associated to this localId.
|
||||
*/
|
||||
mozIDOMApplication getAppByLocalId(in unsigned long localId);
|
||||
|
||||
/**
|
||||
* Returns the manifest URL associated to this localId.
|
||||
*/
|
||||
DOMString getManifestURLByLocalId(in unsigned long localId);
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
interface nsIDOMWindow;
|
||||
interface nsIDOMElement;
|
||||
|
||||
|
@ -13,7 +13,7 @@ interface nsIDOMElement;
|
|||
* permission to perform a privileged operation such as
|
||||
* geolocation.
|
||||
*/
|
||||
[scriptable, uuid(E79C7063-DBAB-45E3-8A98-D0142E1ABC9A)]
|
||||
[scriptable, uuid(E1F3796C-ADFA-414B-B2A7-AC62F29395EE)]
|
||||
interface nsIContentPermissionRequest : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -23,9 +23,9 @@ interface nsIContentPermissionRequest : nsISupports {
|
|||
readonly attribute ACString type;
|
||||
|
||||
/**
|
||||
* The uri of the permission request.
|
||||
* The principal of the permission request.
|
||||
*/
|
||||
readonly attribute nsIURI uri;
|
||||
readonly attribute nsIPrincipal principal;
|
||||
|
||||
/**
|
||||
* The window or element that the permission request was
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "chrome/common/process_watcher.h"
|
||||
|
||||
#include "CrashReporterParent.h"
|
||||
#include "History.h"
|
||||
#include "IDBFactory.h"
|
||||
|
@ -332,6 +334,26 @@ ContentParent::OnChannelConnected(int32 pid)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::ProcessingError(Result what)
|
||||
{
|
||||
if (MsgDropped == what) {
|
||||
// Messages sent after crashes etc. are not a big deal.
|
||||
return;
|
||||
}
|
||||
// Other errors are big deals. This ensures the process is
|
||||
// eventually killed, but doesn't immediately KILLITWITHFIRE
|
||||
// because we want to get a minidump if possible. After a timeout
|
||||
// though, the process is forceably killed.
|
||||
if (!KillProcess(OtherProcess(), 1, false)) {
|
||||
NS_WARNING("failed to kill subprocess!");
|
||||
}
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
|
||||
OtherProcess(), /*force=*/true));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
|
|
|
@ -262,6 +262,8 @@ private:
|
|||
virtual bool RecvAddFileWatch(const nsString& root);
|
||||
virtual bool RecvRemoveFileWatch(const nsString& root);
|
||||
|
||||
virtual void ProcessingError(Result what) MOZ_OVERRIDE;
|
||||
|
||||
GeckoChildProcessHost* mSubprocess;
|
||||
|
||||
PRInt32 mGeolocationWatchID;
|
||||
|
|
|
@ -33,6 +33,7 @@ EXPORTS_mozilla/dom = \
|
|||
ContentProcess.h \
|
||||
CrashReporterChild.h \
|
||||
CrashReporterParent.h \
|
||||
PermissionMessageUtils.h \
|
||||
StructuredCloneUtils.h \
|
||||
TabParent.h \
|
||||
TabChild.h \
|
||||
|
@ -52,6 +53,7 @@ CPPSRCS = \
|
|||
ContentChild.cpp \
|
||||
CrashReporterParent.cpp \
|
||||
CrashReporterChild.cpp \
|
||||
PermissionMessageUtils.cpp \
|
||||
ProcessPriorityManager.cpp \
|
||||
StructuredCloneUtils.cpp \
|
||||
TabParent.cpp \
|
||||
|
|
|
@ -17,12 +17,14 @@ include protocol PIndexedDB;
|
|||
include "gfxMatrix.h";
|
||||
include "IPC/nsGUIEventIPC.h";
|
||||
include "mozilla/dom/TabMessageUtils.h";
|
||||
include "mozilla/dom/PermissionMessageUtils.h";
|
||||
include "mozilla/layout/RenderFrameUtils.h";
|
||||
include "mozilla/net/NeckoMessageUtils.h";
|
||||
|
||||
include DOMTypes;
|
||||
|
||||
using IPC::URI;
|
||||
using IPC::Principal;
|
||||
using gfxMatrix;
|
||||
using gfxSize;
|
||||
using mozilla::layers::LayersBackend;
|
||||
|
@ -174,7 +176,20 @@ parent:
|
|||
SetCursor(PRUint32 value);
|
||||
SetBackgroundColor(nscolor color);
|
||||
|
||||
PContentPermissionRequest(nsCString aType, URI uri);
|
||||
/**
|
||||
* Initiates an asynchronous request for permission for the
|
||||
* provided principal.
|
||||
*
|
||||
* @param aType
|
||||
* The type of permission to request.
|
||||
* @param aPrincipal
|
||||
* The principal of the request.
|
||||
*
|
||||
* NOTE: The principal is untrusted in the parent process. Only
|
||||
* principals that can live in the content process should
|
||||
* provided.
|
||||
*/
|
||||
PContentPermissionRequest(nsCString aType, Principal principal);
|
||||
|
||||
PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures,
|
||||
PRInt32[] aIntParams, nsString[] aStringParams);
|
||||
|
@ -342,4 +357,4 @@ state DYING:
|
|||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
void
|
||||
ParamTraits<Principal>::Write(Message* aMsg, const paramType& aParam) {
|
||||
bool isNull = !aParam.mPrincipal;
|
||||
WriteParam(aMsg, isNull);
|
||||
if (isNull) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isSerialized = false;
|
||||
nsCString principalString;
|
||||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(aParam.mPrincipal);
|
||||
if (serializable) {
|
||||
nsresult rv = NS_SerializeToString(serializable, principalString);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
isSerialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isSerialized) {
|
||||
NS_RUNTIMEABORT("Unable to serialize principal.");
|
||||
return;
|
||||
}
|
||||
|
||||
WriteParam(aMsg, principalString);
|
||||
}
|
||||
|
||||
bool
|
||||
ParamTraits<Principal>::Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
bool isNull;
|
||||
if (!ReadParam(aMsg, aIter, &isNull)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNull) {
|
||||
aResult->mPrincipal = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCString principalString;
|
||||
if (!ReadParam(aMsg, aIter, &principalString)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> iSupports;
|
||||
nsresult rv = NS_DeserializeObject(principalString, getter_AddRefs(iSupports));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(iSupports);
|
||||
NS_ENSURE_TRUE(principal, false);
|
||||
|
||||
principal.swap(aResult->mPrincipal);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace IPC
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_permission_message_utils_h__
|
||||
#define mozilla_dom_permission_message_utils_h__
|
||||
|
||||
#include "IPC/IPCMessageUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
class Principal {
|
||||
friend struct ParamTraits<Principal>;
|
||||
|
||||
public:
|
||||
Principal() : mPrincipal(nsnull) {}
|
||||
Principal(nsIPrincipal* aPrincipal) : mPrincipal(aPrincipal) {}
|
||||
operator nsIPrincipal*() const { return mPrincipal.get(); }
|
||||
|
||||
private:
|
||||
// Unimplemented
|
||||
Principal& operator=(Principal&);
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<Principal>
|
||||
{
|
||||
typedef Principal paramType;
|
||||
static void Write(Message* aMsg, const paramType& aParam);
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult);
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_dom_permission_message_utils_h__
|
||||
|
|
@ -919,7 +919,7 @@ TabChild::DeallocPContentDialog(PContentDialogChild* aDialog)
|
|||
}
|
||||
|
||||
PContentPermissionRequestChild*
|
||||
TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI&)
|
||||
TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal&)
|
||||
{
|
||||
NS_RUNTIMEABORT("unused");
|
||||
return nullptr;
|
||||
|
|
|
@ -230,16 +230,16 @@ public:
|
|||
#ifdef DEBUG
|
||||
virtual PContentPermissionRequestChild* SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
|
||||
const nsCString& aType,
|
||||
const URI& aUri)
|
||||
const IPC::Principal& aPrincipal)
|
||||
{
|
||||
PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor);
|
||||
PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aUri);
|
||||
PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aPrincipal);
|
||||
child->mIPCOpen = true;
|
||||
return request;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
|
||||
virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal);
|
||||
virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor);
|
||||
|
||||
virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URI& manifestURI,
|
||||
|
|
|
@ -292,11 +292,11 @@ TabParent::DeallocPDocumentRenderer(PDocumentRendererParent* actor)
|
|||
}
|
||||
|
||||
PContentPermissionRequestParent*
|
||||
TabParent::AllocPContentPermissionRequest(const nsCString& type, const IPC::URI& uri)
|
||||
TabParent::AllocPContentPermissionRequest(const nsCString& type, const IPC::Principal& principal)
|
||||
{
|
||||
return new ContentPermissionRequestParent(type, mFrameElement, uri);
|
||||
return new ContentPermissionRequestParent(type, mFrameElement, principal);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TabParent::DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor)
|
||||
{
|
||||
|
|
|
@ -147,7 +147,8 @@ public:
|
|||
const nsIntSize& renderSize);
|
||||
virtual bool DeallocPDocumentRenderer(PDocumentRendererParent* actor);
|
||||
|
||||
virtual PContentPermissionRequestParent* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
|
||||
virtual PContentPermissionRequestParent*
|
||||
AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal);
|
||||
virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor);
|
||||
|
||||
virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdate(
|
||||
|
|
|
@ -114,7 +114,6 @@ PEMQExpectedFeatureValue=Found invalid value for media feature.
|
|||
PEBadFontBlockStart=Expected '{' to begin @font-face rule but found '%1$S'.
|
||||
PEBadFontBlockEnd=Expected '}' to end @font-face rule but found '%1$S'.
|
||||
PEAnonBoxNotAlone=Did not expect anonymous box.
|
||||
PEBadDirValue=Expected 'ltr' or 'rtl' in direction selector but found '%1$S'.
|
||||
PESupportsConditionStartEOF='not' or '('
|
||||
PESupportsConditionInParensStartEOF='not', '(' or identifier
|
||||
PESupportsConditionNotEOF='not'
|
||||
|
|
|
@ -280,12 +280,12 @@ nsGeolocationRequest::Notify(nsITimer* aTimer)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationRequest::GetUri(nsIURI * *aRequestingURI)
|
||||
nsGeolocationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequestingURI);
|
||||
NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
|
||||
|
||||
nsCOMPtr<nsIURI> uri = mLocator->GetURI();
|
||||
uri.forget(aRequestingURI);
|
||||
nsCOMPtr<nsIPrincipal> principal = mLocator->GetPrincipal();
|
||||
principal.forget(aRequestingPrincipal);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -905,7 +905,7 @@ nsGeolocation::Init(nsIDOMWindow* aContentDom)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Grab the uri of the document
|
||||
// Grab the principal of the document
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
aContentDom->GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
|
@ -913,15 +913,11 @@ nsGeolocation::Init(nsIDOMWindow* aContentDom)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
|
||||
|
||||
if (!mURI) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mPrincipal = doc->NodePrincipal();
|
||||
}
|
||||
|
||||
// If no aContentDom was passed into us, we are being used
|
||||
// by chrome/c++ and have no mOwner, no mURI, and no need
|
||||
// by chrome/c++ and have no mOwner, no mPrincipal, and no need
|
||||
// to prompt.
|
||||
mService = nsGeolocationService::GetInstance();
|
||||
if (mService) {
|
||||
|
@ -947,7 +943,7 @@ nsGeolocation::Shutdown()
|
|||
}
|
||||
|
||||
mService = nullptr;
|
||||
mURI = nullptr;
|
||||
mPrincipal = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1174,8 +1170,8 @@ nsGeolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request)
|
|||
request->AddRef();
|
||||
|
||||
nsCString type = NS_LITERAL_CSTRING("geolocation");
|
||||
child->SendPContentPermissionRequestConstructor(request, type, IPC::URI(mURI));
|
||||
|
||||
child->SendPContentPermissionRequestConstructor(request, type, IPC::Principal(mPrincipal));
|
||||
|
||||
request->Sendprompt();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -181,8 +181,8 @@ public:
|
|||
// Shutting down.
|
||||
void Shutdown();
|
||||
|
||||
// Getter for the URI that this nsGeolocation was loaded from
|
||||
nsIURI* GetURI() { return mURI; }
|
||||
// Getter for the principal that this nsGeolocation was loaded from
|
||||
nsIPrincipal* GetPrincipal() { return mPrincipal; }
|
||||
|
||||
// Getter for the window that this nsGeolocation is owned by
|
||||
nsIWeakReference* GetOwner() { return mOwner; }
|
||||
|
@ -208,7 +208,7 @@ private:
|
|||
nsWeakPtr mOwner;
|
||||
|
||||
// where the content was loaded from
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
// owning back pointer.
|
||||
nsRefPtr<nsGeolocationService> mService;
|
||||
|
|
|
@ -67,11 +67,11 @@ nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title,
|
|||
const nsAString & description,
|
||||
const nsAString & iconURL,
|
||||
nsPIDOMWindow *aWindow,
|
||||
nsIURI* uri)
|
||||
nsIPrincipal* principal)
|
||||
: mTitle(title)
|
||||
, mDescription(description)
|
||||
, mIconURL(iconURL)
|
||||
, mURI(uri)
|
||||
, mPrincipal(principal)
|
||||
, mAllow(false)
|
||||
, mShowHasBeenCalled(false)
|
||||
{
|
||||
|
@ -102,14 +102,14 @@ nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title,
|
|||
// because owner implements nsITabChild, we can assume that it is
|
||||
// the one and only TabChild for this docshell.
|
||||
TabChild* child = GetTabChildFrom(GetOwner()->GetDocShell());
|
||||
|
||||
|
||||
// Retain a reference so the object isn't deleted without IPDL's knowledge.
|
||||
// Corresponding release occurs in DeallocPContentPermissionRequest.
|
||||
nsRefPtr<nsDesktopNotificationRequest> copy = request;
|
||||
|
||||
nsCString type = NS_LITERAL_CSTRING("desktop-notification");
|
||||
child->SendPContentPermissionRequestConstructor(copy.forget().get(), type, IPC::URI(mURI));
|
||||
|
||||
child->SendPContentPermissionRequestConstructor(copy.forget().get(), type, IPC::Principal(mPrincipal));
|
||||
|
||||
request->Sendprompt();
|
||||
return;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ nsDesktopNotificationCenter::CreateNotification(const nsAString & title,
|
|||
description,
|
||||
iconURL,
|
||||
mOwner,
|
||||
mURI);
|
||||
mPrincipal);
|
||||
notification.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -247,12 +247,12 @@ NS_IMPL_ISUPPORTS2(nsDesktopNotificationRequest,
|
|||
nsIRunnable)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDesktopNotificationRequest::GetUri(nsIURI * *aRequestingURI)
|
||||
nsDesktopNotificationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
||||
{
|
||||
if (!mDesktopNotification)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
NS_IF_ADDREF(*aRequestingURI = mDesktopNotification->mURI);
|
||||
NS_IF_ADDREF(*aRequestingPrincipal = mDesktopNotification->mPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
mOwner->GetDocument(getter_AddRefs(domdoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
|
||||
doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
|
||||
mPrincipal = doc->NodePrincipal();
|
||||
}
|
||||
|
||||
virtual ~nsDesktopNotificationCenter()
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
private:
|
||||
nsCOMPtr<nsPIDOMWindow> mOwner;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
const nsAString & description,
|
||||
const nsAString & iconURL,
|
||||
nsPIDOMWindow *aWindow,
|
||||
nsIURI* uri);
|
||||
nsIPrincipal* principal);
|
||||
|
||||
virtual ~nsDOMDesktopNotification();
|
||||
|
||||
|
@ -108,7 +108,7 @@ protected:
|
|||
nsRefPtr<nsDOMEventListenerWrapper> mOnCloseCallback;
|
||||
|
||||
nsRefPtr<AlertServiceObserver> mObserver;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
bool mAllow;
|
||||
bool mShowHasBeenCalled;
|
||||
};
|
||||
|
|
|
@ -130,10 +130,6 @@ bool ImageContainerChild::CopyDataIntoSharedImage(Image* src, SharedImage* dest)
|
|||
nsRefPtr<gfxSharedImageSurface> surfV =
|
||||
gfxSharedImageSurface::Open(yuv.Vdata());
|
||||
|
||||
gfxIntSize size = surfY->GetSize();
|
||||
|
||||
NS_ABORT_IF_FALSE(size == mSize, "Sizes must match to copy image data.");
|
||||
|
||||
for (int i = 0; i < data->mYSize.height; i++) {
|
||||
memcpy(surfY->Data() + i * surfY->Stride(),
|
||||
data->mYChannel + i * data->mYStride,
|
||||
|
@ -218,24 +214,56 @@ bool ImageContainerChild::AddSharedImageToPool(SharedImage* img)
|
|||
return false;
|
||||
}
|
||||
if (img->type() == SharedImage::TYUVImage) {
|
||||
nsIntRect rect = img->get_YUVImage().picture();
|
||||
if ((rect.Width() != mSize.width) || (rect.Height() != mSize.height)) {
|
||||
ClearSharedImagePool();
|
||||
mSize.width = rect.Width();
|
||||
mSize.height = rect.Height();
|
||||
}
|
||||
mSharedImagePool.AppendElement(img);
|
||||
return true;
|
||||
}
|
||||
return false; // TODO accept more image formats in the pool
|
||||
}
|
||||
|
||||
SharedImage* ImageContainerChild::PopSharedImageFromPool()
|
||||
static bool
|
||||
SharedImageCompatibleWith(SharedImage* aSharedImage, Image* aImage)
|
||||
{
|
||||
if (mSharedImagePool.Length() > 0) {
|
||||
SharedImage* img = mSharedImagePool[mSharedImagePool.Length()-1];
|
||||
mSharedImagePool.RemoveElement(mSharedImagePool.LastElement());
|
||||
return img;
|
||||
// TODO accept more image formats
|
||||
switch (aImage->GetFormat()) {
|
||||
case Image::PLANAR_YCBCR: {
|
||||
if (aSharedImage->type() != SharedImage::TYUVImage) {
|
||||
return false;
|
||||
}
|
||||
const PlanarYCbCrImage::Data* data =
|
||||
static_cast<PlanarYCbCrImage*>(aImage)->GetData();
|
||||
const YUVImage& yuv = aSharedImage->get_YUVImage();
|
||||
|
||||
nsRefPtr<gfxSharedImageSurface> surfY =
|
||||
gfxSharedImageSurface::Open(yuv.Ydata());
|
||||
if (surfY->GetSize() != data->mYSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxSharedImageSurface> surfU =
|
||||
gfxSharedImageSurface::Open(yuv.Udata());
|
||||
if (surfU->GetSize() != data->mCbCrSize) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SharedImage*
|
||||
ImageContainerChild::GetSharedImageFor(Image* aImage)
|
||||
{
|
||||
while (mSharedImagePool.Length() > 0) {
|
||||
// i.e., img = mPool.pop()
|
||||
nsAutoPtr<SharedImage> img(mSharedImagePool.LastElement());
|
||||
mSharedImagePool.RemoveElementAt(mSharedImagePool.Length() - 1);
|
||||
|
||||
if (SharedImageCompatibleWith(img, aImage)) {
|
||||
return img.forget();
|
||||
}
|
||||
// The cached image is stale, throw it out.
|
||||
DeallocSharedImageData(this, *img);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -285,7 +313,7 @@ SharedImage* ImageContainerChild::ImageToSharedImage(Image* aImage)
|
|||
|
||||
NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
|
||||
"Should be in ImageBridgeChild thread.");
|
||||
SharedImage *img = PopSharedImageFromPool();
|
||||
SharedImage *img = GetSharedImageFor(aImage);
|
||||
if (img) {
|
||||
CopyDataIntoSharedImage(aImage, img);
|
||||
} else {
|
||||
|
|
|
@ -161,7 +161,7 @@ protected:
|
|||
* Removes a shared image from the pool and returns it.
|
||||
* Returns nullptr if the pool is empty.
|
||||
*/
|
||||
SharedImage* PopSharedImageFromPool();
|
||||
SharedImage* GetSharedImageFor(Image* aImage);
|
||||
/**
|
||||
* Seallocates all the shared images from the pool and clears the pool.
|
||||
*/
|
||||
|
@ -190,9 +190,7 @@ protected:
|
|||
SharedImage * CreateSharedImageFromData(Image* aImage);
|
||||
|
||||
private:
|
||||
|
||||
PRUint64 mImageContainerID;
|
||||
nsIntSize mSize;
|
||||
nsTArray<SharedImage*> mSharedImagePool;
|
||||
int mActiveImageCount;
|
||||
bool mStop;
|
||||
|
|
|
@ -199,7 +199,7 @@ DBusMessage * dbus_func_args_timeout_valist(DBusConnection *conn,
|
|||
/* Make the call. */
|
||||
reply = dbus_connection_send_with_reply_and_block(conn, msg, timeout_ms, err);
|
||||
if (!return_error && dbus_error_is_set(err)) {
|
||||
//LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg);
|
||||
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -212,6 +212,7 @@ done:
|
|||
|
||||
DBusMessage * dbus_func_args_timeout(DBusConnection *conn,
|
||||
int timeout_ms,
|
||||
DBusError* err,
|
||||
const char *path,
|
||||
const char *ifc,
|
||||
const char *func,
|
||||
|
@ -220,7 +221,7 @@ DBusMessage * dbus_func_args_timeout(DBusConnection *conn,
|
|||
DBusMessage *ret;
|
||||
va_list lst;
|
||||
va_start(lst, first_arg_type);
|
||||
ret = dbus_func_args_timeout_valist(conn, timeout_ms, NULL,
|
||||
ret = dbus_func_args_timeout_valist(conn, timeout_ms, err,
|
||||
path, ifc, func,
|
||||
first_arg_type, lst);
|
||||
va_end(lst);
|
||||
|
|
|
@ -90,6 +90,7 @@ DBusMessage* dbus_func_args_error(DBusConnection* conn,
|
|||
|
||||
DBusMessage* dbus_func_args_timeout(DBusConnection* conn,
|
||||
int timeout_ms,
|
||||
DBusError* err,
|
||||
const char* path,
|
||||
const char* ifc,
|
||||
const char* func,
|
||||
|
|
|
@ -31,6 +31,10 @@ public:
|
|||
RawDBusConnection();
|
||||
~RawDBusConnection();
|
||||
nsresult EstablishDBusConnection();
|
||||
DBusConnection* GetConnection() {
|
||||
return mConnection;
|
||||
}
|
||||
protected:
|
||||
Scoped<ScopedDBusConnectionPtrTraits> mConnection;
|
||||
};
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ check("o[- (o)]");
|
|||
check_one("6", (function () { 6() }), " is not a function");
|
||||
check_one("Array.prototype.reverse.call(...)", (function () { Array.prototype.reverse.call('123'); }), " is read-only");
|
||||
check_one("null", function () { var [{ x }] = [null, {}]; }, " has no properties");
|
||||
check_one("x", function () { ieval("let (x) { var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined");
|
||||
|
||||
// Check fallback behavior
|
||||
check_one("undefined", (function () { for (let x of undefined) {} }), " has no properties");
|
||||
|
|
|
@ -117,7 +117,7 @@ MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE, 63, 0, JSEXN_INTERNALERR, "data are to bi
|
|||
MSG_DEF(JSMSG_ARG_INDEX_OUT_OF_RANGE, 64, 1, JSEXN_RANGEERR, "argument {0} accesses an index that is out of range")
|
||||
MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 65, 0, JSEXN_RANGEERR, "array too large due to spread operand(s)")
|
||||
MSG_DEF(JSMSG_SOURCE_TOO_LONG, 66, 0, JSEXN_RANGEERR, "source is too long")
|
||||
MSG_DEF(JSMSG_UNUSED67, 67, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 67, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key")
|
||||
MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC, 68, 0, JSEXN_INTERNALERR, "bad script XDR magic number")
|
||||
MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
|
||||
MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter")
|
||||
|
|
|
@ -6093,17 +6093,12 @@ ExpressionDecompiler::findLetVar(jsbytecode *pc, unsigned depth)
|
|||
if (uint32_t(depth - blockDepth) < uint32_t(blockCount)) {
|
||||
for (Shape::Range r(block.lastProperty()); !r.empty(); r.popFront()) {
|
||||
const Shape &shape = r.front();
|
||||
if (shape.shortid() == int(depth - blockDepth)) {
|
||||
// !JSID_IS_ATOM(shape.propid()) happens for empty
|
||||
// destructuring variables in lets. They can be safely
|
||||
// ignored.
|
||||
if (JSID_IS_ATOM(shape.propid()))
|
||||
return JSID_TO_ATOM(shape.propid());
|
||||
}
|
||||
if (shape.shortid() == int(depth - blockDepth))
|
||||
return JSID_TO_ATOM(shape.propid());
|
||||
}
|
||||
}
|
||||
chain = chain->enclosingScope();
|
||||
} while (chain->isBlock());
|
||||
chain = chain->getParent();
|
||||
} while (chain && chain->isBlock());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -249,19 +249,20 @@ WeakMap_set_impl(JSContext *cx, CallArgs args)
|
|||
thisObj->setPrivate(map);
|
||||
}
|
||||
|
||||
// Preserve wrapped native keys to prevent wrapper optimization.
|
||||
if (key->getClass()->ext.isWrappedNative) {
|
||||
MOZ_ASSERT(cx->runtime->preserveWrapperCallback, "wrapped native weak map key needs preserveWrapperCallback");
|
||||
if (!cx->runtime->preserveWrapperCallback(cx, key)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_WEAKMAP_KEY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!map->put(key, value)) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preserve wrapped native keys to prevent wrapper optimization.
|
||||
if (key->getClass()->ext.isWrappedNative) {
|
||||
if (!cx->runtime->preserveWrapperCallback ||
|
||||
!cx->runtime->preserveWrapperCallback(cx, key)) {
|
||||
JS_ReportWarning(cx, "Failed to preserve wrapper of wrapped native weak map key.");
|
||||
}
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1284,7 +1284,7 @@ class GetPropCompiler : public PICStubCompiler
|
|||
Jump shapeGuard = masm.branchPtr(Assembler::NotEqual,
|
||||
Address(pic.shapeReg, JSObject::offsetOfShape()),
|
||||
ImmPtr(expando->lastProperty()));
|
||||
if (!shapeMismatches.append(expandoGuard))
|
||||
if (!shapeMismatches.append(shapeGuard))
|
||||
return error();
|
||||
} else {
|
||||
Jump expandoGuard = masm.testUndefined(Assembler::NotEqual, expandoAddress);
|
||||
|
|
|
@ -18,6 +18,33 @@
|
|||
#include "jsobjinlines.h"
|
||||
#include "gc/Barrier-inl.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
static JS_ALWAYS_INLINE JSFixedString *
|
||||
NewShortString(JSContext *cx, const jschar *chars, size_t length)
|
||||
{
|
||||
SkipRoot skip(cx, &chars);
|
||||
|
||||
/*
|
||||
* Don't bother trying to find a static atom; measurement shows that not
|
||||
* many get here (for one, Atomize is catching them).
|
||||
*/
|
||||
JS_ASSERT(JSShortString::lengthFits(length));
|
||||
JSInlineString *str = JSInlineString::lengthFits(length)
|
||||
? JSInlineString::new_(cx)
|
||||
: JSShortString::new_(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
jschar *storage = str->init(length);
|
||||
PodCopy(storage, chars, length);
|
||||
storage[length] = 0;
|
||||
Probes::createString(cx, str, length);
|
||||
return str;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
inline void
|
||||
JSString::writeBarrierPre(JSString *str)
|
||||
{
|
||||
|
@ -112,7 +139,7 @@ JSDependentString::init(JSLinearString *base, const jschar *chars, size_t length
|
|||
JSString::writeBarrierPost(d.s.u2.base, &d.s.u2.base);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE JSDependentString *
|
||||
JS_ALWAYS_INLINE JSLinearString *
|
||||
JSDependentString::new_(JSContext *cx, JSLinearString *base_, const jschar *chars, size_t length)
|
||||
{
|
||||
JS::Rooted<JSLinearString*> base(cx, base_);
|
||||
|
@ -126,11 +153,12 @@ JSDependentString::new_(JSContext *cx, JSLinearString *base_, const jschar *char
|
|||
JS_ASSERT(length <= base->length() - (chars - base->chars()));
|
||||
|
||||
/*
|
||||
* The characters may be an internal pointer to a GC thing, so prevent them
|
||||
* from being overwritten. For now this prevents strings used as dependent
|
||||
* bases of other strings from being moved by the GC.
|
||||
* Do not create a string dependent on inline chars from another string,
|
||||
* both to avoid the awkward moving-GC hazard this introduces and because it
|
||||
* is more efficient to immediately undepend here.
|
||||
*/
|
||||
JS::SkipRoot charsRoot(cx, &chars);
|
||||
if (JSShortString::lengthFits(base->length()))
|
||||
return js::NewShortString(cx, chars, length);
|
||||
|
||||
JSDependentString *str = (JSDependentString *)js_NewGCString(cx);
|
||||
if (!str)
|
||||
|
@ -411,31 +439,4 @@ JSExternalString::finalize(js::FreeOp *fop)
|
|||
fin->finalize(fin, const_cast<jschar *>(chars()));
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
static JS_ALWAYS_INLINE JSFixedString *
|
||||
NewShortString(JSContext *cx, const jschar *chars, size_t length)
|
||||
{
|
||||
SkipRoot skip(cx, &chars);
|
||||
|
||||
/*
|
||||
* Don't bother trying to find a static atom; measurement shows that not
|
||||
* many get here (for one, Atomize is catching them).
|
||||
*/
|
||||
JS_ASSERT(JSShortString::lengthFits(length));
|
||||
JSInlineString *str = JSInlineString::lengthFits(length)
|
||||
? JSInlineString::new_(cx)
|
||||
: JSShortString::new_(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
jschar *storage = str->init(length);
|
||||
PodCopy(storage, chars, length);
|
||||
storage[length] = 0;
|
||||
Probes::createString(cx, str, length);
|
||||
return str;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -366,10 +366,7 @@ class JSString : public js::gc::Cell
|
|||
return (d.lengthAndFlags & JS_BITMASK(3)) == DEPENDENT_FLAGS;
|
||||
}
|
||||
|
||||
inline JSLinearString *base() const {
|
||||
JS_ASSERT(hasBase());
|
||||
return d.s.u2.base;
|
||||
}
|
||||
inline JSLinearString *base() const;
|
||||
|
||||
inline void markBase(JSTracer *trc);
|
||||
|
||||
|
@ -470,8 +467,8 @@ class JSDependentString : public JSLinearString
|
|||
JSDependentString &asDependent() const MOZ_DELETE;
|
||||
|
||||
public:
|
||||
static inline JSDependentString *new_(JSContext *cx, JSLinearString *base,
|
||||
const jschar *chars, size_t length);
|
||||
static inline JSLinearString *new_(JSContext *cx, JSLinearString *base,
|
||||
const jschar *chars, size_t length);
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSDependentString) == sizeof(JSString));
|
||||
|
@ -818,6 +815,14 @@ JSString::ensureFixed(JSContext *cx)
|
|||
return &asFixed();
|
||||
}
|
||||
|
||||
inline JSLinearString *
|
||||
JSString::base() const
|
||||
{
|
||||
JS_ASSERT(hasBase());
|
||||
JS_ASSERT(!d.s.u2.base->isInline());
|
||||
return d.s.u2.base;
|
||||
}
|
||||
|
||||
inline js::PropertyName *
|
||||
JSAtom::asPropertyName()
|
||||
{
|
||||
|
|
|
@ -213,14 +213,32 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=668855
|
|||
|
||||
make_live_map();
|
||||
|
||||
let unpreservable_native_key = function () {
|
||||
// We only allow natives that support wrapper preservation to be used as weak
|
||||
// map keys. We should be able to try to add unpreservable natives as keys without
|
||||
// crashing (bug 711616), but we should throw an error (bug 761620).
|
||||
|
||||
let dummy_test_map = new WeakMap;
|
||||
// bug 711616: should be able to do this without crashing. JS warning is expected.
|
||||
dummy_test_map.set(document.createElement("div").style, 1);
|
||||
let dummy_test_map = new WeakMap;
|
||||
|
||||
// JS warning is expected.
|
||||
dummy_test_map.set(window.navigator, 1);
|
||||
let div_fail = false;
|
||||
try {
|
||||
dummy_test_map.set(document.createElement("div").style, 1);
|
||||
} catch (e) {
|
||||
div_fail = true;
|
||||
}
|
||||
ok(div_fail, "Using elem.style as a weak map key should produce an exception because it can't be wrapper preserved.");
|
||||
|
||||
let navi_fail = false;
|
||||
try {
|
||||
dummy_test_map.set(window.navigator, 1);
|
||||
} catch (e) {
|
||||
navi_fail = true;
|
||||
}
|
||||
ok(navi_fail, "Using window.navigator as a weak map key should produce an exception because it can't be wrapper preserved.");
|
||||
|
||||
}
|
||||
|
||||
unpreservable_native_key();
|
||||
|
||||
/* set up for running precise GC/CC then checking the results */
|
||||
|
||||
|
|
|
@ -353,7 +353,16 @@ load 707098.html
|
|||
load 722137.html
|
||||
load 725535.html
|
||||
load 727601.html
|
||||
skip-if(Android&&!browserIsRemote) asserts(0-2) pref(dom.disable_open_during_load,false) load 735943.html # the assertion is bug 735966, for android bug 760271
|
||||
# Bug 778067: This test fails when we try to create a popup window in
|
||||
# <browser remote>, because TabParent::AnswerOpenWindow() can't deal
|
||||
# with creating a popup window this early during page load. However,
|
||||
# <iframe mobrowser> is set up to handle this, and <browser remote>
|
||||
# isn't shipping again in the foreseeable future, so disable for now.
|
||||
# (The parent process in this case is behaving "well" by crashing the
|
||||
# content process when it gets into an unexpected state, it's just
|
||||
# that the reftest harness can't handle restarting crashed content
|
||||
# processes so we time out.)
|
||||
skip-if(Android||browserIsRemote) asserts(0-2) pref(dom.disable_open_during_load,false) load 735943.html # the assertion is bug 735966, for android bug 760271
|
||||
asserts(0-2) load 736389-1.xhtml # sometimes the above assertions are delayed and is reported on this test instead
|
||||
asserts-if(winWidget,0-2) load 736924-1.html # bug 738803
|
||||
load 749816-1.html
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
.blue { color: blue; direction: ltr; }
|
||||
.lime { color: lime; direction: rtl; }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="blue">This element has default direction.</div>
|
||||
<div class="blue">This element is ltr.</div>
|
||||
<div class="lime">This element is rtl.</div>
|
||||
<div class="blue">
|
||||
<div>This element should inherit ltr.</div>
|
||||
<div class="blue">This element is ltr.</div>
|
||||
<div class="lime">This element is rtl.</div>
|
||||
<div class="blue">Every word in this element should inherit ltr.</div>
|
||||
</div>
|
||||
<div class="lime">
|
||||
<div>This element should inherit rtl.</div>
|
||||
<div class="blue">This element is ltr.</div>
|
||||
<div class="lime">This element is rtl.</div>
|
||||
<div class="lime">Every word in this element should inherit rtl.</div>
|
||||
</div>
|
||||
<div class="blue">This element has an invalid dir attribute and
|
||||
should have default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
:dir(ltr) { color: blue }
|
||||
:dir(rtl) { color: lime }
|
||||
:dir(foopy) { color: red }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>This element has default direction.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
<div dir="ltr">
|
||||
<div>This element should inherit ltr.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
<div><span>Every <span>word <span>in <span>this <span>element <span>should <span>inherit <span>ltr</span></span></span></span></span></span></span></span>.</div>
|
||||
</div>
|
||||
<div dir="rtl">
|
||||
<div>This element should inherit rtl.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
<div><span>Every <span>word <span>in <span>this <span>element <span>should <span>inherit <span>rtl</span></span></span></span></span></span></span></span>.</div>
|
||||
</div>
|
||||
<div dir="foopy">This element has an invalid dir attribute and
|
||||
should have default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,46 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
:dir(ltr) { color: blue }
|
||||
:dir(rtl) { color: lime }
|
||||
:dir(foopy) { color: red }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function switchDir()
|
||||
{
|
||||
divs = document.getElementsByTagName("div");
|
||||
for (var i = 0; i < divs.length; ++i) {
|
||||
theDiv = divs[i];
|
||||
if (theDiv.dir == "ltr") {
|
||||
theDiv.dir = "rtl";
|
||||
} else if (theDiv.dir == "rtl") {
|
||||
theDiv.dir = "ltr";
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="switchDir()">
|
||||
<div>This element has default direction.</div>
|
||||
<div dir="rtl">This element is ltr.</div>
|
||||
<div dir="ltr">This element is rtl.</div>
|
||||
<div dir="rtl">
|
||||
<div>This element should inherit ltr.</div>
|
||||
<div dir="rtl">This element is ltr.</div>
|
||||
<div dir="ltr">This element is rtl.</div>
|
||||
<div><span>Every <span>word <span>in <span>this <span>element <span>should <span>inherit <span>ltr</span></span></span></span></span></span></span></span>.</div>
|
||||
</div>
|
||||
<div dir="ltr">
|
||||
<div>This element should inherit rtl.</div>
|
||||
<div dir="rtl">This element is ltr.</div>
|
||||
<div dir="ltr">This element is rtl.</div>
|
||||
<div><span>Every <span>word <span>in <span>this <span>element <span>should <span>inherit <span>rtl</span></span></span></span></span></span></span></span>.</div>
|
||||
</div>
|
||||
<div dir="foopy">This element has an invalid dir attribute and
|
||||
should have default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
.blue { color: blue; direction: ltr; }
|
||||
.lime { color: lime; direction: rtl; }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="lime">This element has default direction.</div>
|
||||
<div class="blue">This element is ltr.</div>
|
||||
<div class="lime">This element is rtl.</div>
|
||||
<div class="blue">
|
||||
<div>This element should inherit ltr.</div>
|
||||
<div class="blue">This element is ltr.</div>
|
||||
<div class="lime">This element is rtl.</div>
|
||||
</div>
|
||||
<div class="lime">
|
||||
<div>This element should inherit rtl.</div>
|
||||
<div class="blue">This element is ltr.</div>
|
||||
<div class="lime">This element is rtl.</div>
|
||||
</div>
|
||||
<div class="lime">This element has an invalid dir attribute and
|
||||
should have default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,30 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
:dir(ltr) { color: blue }
|
||||
:dir(rtl) { color: lime }
|
||||
:dir(foopy) { color: red }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>This element has default direction.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
<div dir="ltr">
|
||||
<div>This element should inherit ltr.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
</div>
|
||||
<div dir="rtl">
|
||||
<div>This element should inherit rtl.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
</div>
|
||||
<div dir="foopy">This element has an invalid dir attribute and
|
||||
should have default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
:dir(ltr) { color: blue }
|
||||
:dir(rtl) { color: lime }
|
||||
:dir(foopy) { color: red }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function switchDir()
|
||||
{
|
||||
document.dir = "rtl";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="switchDir()">
|
||||
<div>This element has default direction.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
<div dir="ltr">
|
||||
<div>This element should inherit ltr.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
</div>
|
||||
<div dir="rtl">
|
||||
<div>This element should inherit rtl.</div>
|
||||
<div dir="ltr">This element is ltr.</div>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
</div>
|
||||
<div dir="foopy">This element has an invalid dir attribute and
|
||||
should have default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
.ltr { direction: ltr }
|
||||
.rtl { direction: rtl }
|
||||
div { color: lime; text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="rtl">This element is rtl.</div>
|
||||
<div>This element has default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
:not(:dir(rtl)) + div { color: blue }
|
||||
div { color: lime; text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div dir="rtl">This element is rtl.</div>
|
||||
<div>This element has default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,26 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
:not(:dir(rtl)) + div { color: blue }
|
||||
div { color: lime; text-align: left; }
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function switchDir()
|
||||
{
|
||||
theDiv = document.getElementById("d");
|
||||
if (theDiv.dir == "ltr") {
|
||||
theDiv.dir = "rtl";
|
||||
} else if (theDiv.dir == "rtl") {
|
||||
theDiv.dir = "ltr";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="switchDir()">
|
||||
<div id="d" dir="ltr">This element is rtl.</div>
|
||||
<div>This element has default direction.</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
.lime { direction: rtl; color: lime }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="lime">This element is rtl. <span>This span should
|
||||
inherit rtl from the parent. <span>This span should inherit rtl
|
||||
from the grandparent.</span></span></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>dir() selector</title>
|
||||
<style>
|
||||
:dir(ltr) { color: blue }
|
||||
:dir(rtl) { color: lime }
|
||||
div { text-align: left; }
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function AppendElementWithChild() {
|
||||
var x = document.createElement("span");
|
||||
x.innerHTML = "This span should inherit rtl from the parent. ";
|
||||
|
||||
var y = document.createElement("span");
|
||||
y.innerHTML = "This span should inherit rtl from the grandparent.";
|
||||
|
||||
var z = document.getElementById("z");
|
||||
|
||||
x.appendChild(y);
|
||||
z.appendChild(x);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="AppendElementWithChild()">
|
||||
<div id="z" dir="rtl">This element is rtl. </div>
|
||||
</body>
|
||||
</html>
|
|
@ -86,13 +86,6 @@ random-if(winWidget) == 305643-1.html 305643-1-ref.html # depends on windows ver
|
|||
== 503957-1.html 503957-1-ref.html
|
||||
== 525740-1.html 525740-1-ref.html
|
||||
== 536963-1.html 536963-1-ref.html
|
||||
== 562169-1.html 562169-1-ref.html
|
||||
== 562169-1a.html 562169-1-ref.html
|
||||
== 562169-2.html 562169-2-ref.html
|
||||
== 562169-2a.html 562169-2-ref.html
|
||||
== 562169-3.html 562169-3-ref.html
|
||||
== 562169-3a.html 562169-3-ref.html
|
||||
== 562169-4.html 562169-4-ref.html
|
||||
== 588739-1.html 588739-ref.html
|
||||
== 588739-2.html 588739-ref.html
|
||||
== 588739-3.html 588739-ref.html
|
||||
|
|
|
@ -3595,12 +3595,10 @@ CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
|
|||
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
|
||||
}
|
||||
|
||||
// -moz-locale-dir and :dir can only have values of 'ltr' or 'rtl'.
|
||||
if (aType == nsCSSPseudoClasses::ePseudoClass_mozLocaleDir ||
|
||||
aType == nsCSSPseudoClasses::ePseudoClass_dir) {
|
||||
// -moz-locale-dir can only have values of 'ltr' or 'rtl'.
|
||||
if (aType == nsCSSPseudoClasses::ePseudoClass_mozLocaleDir) {
|
||||
if (!mToken.mIdent.EqualsLiteral("ltr") &&
|
||||
!mToken.mIdent.EqualsLiteral("rtl")) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEBadDirValue);
|
||||
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,45 +9,27 @@
|
|||
* This file contains the list of nsIAtoms and their values for CSS
|
||||
* pseudo-classes. It is designed to be used as inline input to
|
||||
* nsCSSPseudoClasses.cpp *only* through the magic of C preprocessing.
|
||||
* All entries must be enclosed in the macros CSS_PSEUDO_CLASS,
|
||||
* CSS_STATE_DEPENDENT_PSEUDO_CLASS, or CSS_STATE_PSEUDO_CLASS which
|
||||
* will have cruel and unusual things done to them. The entries should
|
||||
* be kept in some sort of logical order. The first argument to
|
||||
* CSS_PSEUDO_CLASS is the C++ identifier of the atom. The second
|
||||
* argument is the string value of the atom.
|
||||
* CSS_STATE_DEPENDENT_PSEUDO_CLASS and CSS_STATE_PSEUDO_CLASS also take
|
||||
* the name of the state bits that the class corresponds to. Only one
|
||||
* of the bits needs to match for a CSS_STATE_PSEUDO_CLASS to match;
|
||||
* CSS_STATE_DEPENDENT_PSEUDO_CLASS matching depends on a customized per-class
|
||||
* algorithm which should be defined in SelectorMatches() in
|
||||
* nsCSSRuleProcessor.cpp.
|
||||
*
|
||||
* If CSS_STATE_PSEUDO_CLASS is not defined, it'll be automatically
|
||||
* defined to CSS_STATE_DEPENDENT_PSEUDO_CLASS;
|
||||
* if CSS_STATE_DEPENDENT_PSEUDO_CLASS is not defined, it'll be
|
||||
* automatically defined to CSS_PSEUDO_CLASS.
|
||||
* All entries must be enclosed in the macros CSS_PSEUDO_CLASS or
|
||||
* CSS_STATE_PSEUDO_CLASS which will have cruel and unusual things
|
||||
* done to it. The entries should be kept in some sort of logical
|
||||
* order. The first argument to CSS_PSEUDO_CLASS is the C++
|
||||
* identifier of the atom. The second argument is the string value of
|
||||
* the atom. CSS_STATE_PSEUDO_CLASS also takes the name of the state
|
||||
* bits that the class corresponds to. Only one of the bits needs to
|
||||
* match for the pseudo-class to match. If CSS_STATE_PSEUDO_CLASS is
|
||||
* not defined, it'll be automatically defined to CSS_PSEUDO_CLASS.
|
||||
*/
|
||||
|
||||
// OUTPUT_CLASS=nsCSSPseudoClasses
|
||||
// MACRO_NAME=CSS_PSEUDO_CLASS
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#error "CSS_STATE_DEPENDENT_PSEUDO_CLASS shouldn't be defined"
|
||||
#endif
|
||||
|
||||
#ifndef CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#define CSS_STATE_DEPENDENT_PSEUDO_CLASS(_name, _value, _bit) \
|
||||
CSS_PSEUDO_CLASS(_name, _value)
|
||||
#define DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#endif
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#error "CSS_STATE_PSEUDO_CLASS shouldn't be defined"
|
||||
#error "This shouldn't be defined"
|
||||
#endif
|
||||
|
||||
#ifndef CSS_STATE_PSEUDO_CLASS
|
||||
#define CSS_STATE_PSEUDO_CLASS(_name, _value, _bit) \
|
||||
CSS_STATE_DEPENDENT_PSEUDO_CLASS(_name, _value, _bit)
|
||||
CSS_PSEUDO_CLASS(_name, _value)
|
||||
#define DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#endif
|
||||
|
||||
|
@ -108,11 +90,6 @@ CSS_PSEUDO_CLASS(mozTableBorderNonzero, ":-moz-table-border-nonzero")
|
|||
// it doesn't actually get directly matched on in SelectorMatches.
|
||||
CSS_PSEUDO_CLASS(notPseudo, ":not")
|
||||
|
||||
// :dir(ltr) and :dir(rtl) match elements whose resolved directionality
|
||||
// in the markup language is ltr or rtl respectively
|
||||
CSS_STATE_DEPENDENT_PSEUDO_CLASS(dir, ":dir",
|
||||
NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
|
||||
|
||||
CSS_STATE_PSEUDO_CLASS(link, ":link", NS_EVENT_STATE_UNVISITED)
|
||||
// what matches :link or :visited
|
||||
CSS_STATE_PSEUDO_CLASS(mozAnyLink, ":-moz-any-link",
|
||||
|
@ -201,8 +178,3 @@ CSS_STATE_PSEUDO_CLASS(mozMeterSubSubOptimum, ":-moz-meter-sub-sub-optimum",
|
|||
#undef DEFINED_CSS_STATE_PSEUDO_CLASS
|
||||
#undef CSS_STATE_PSEUDO_CLASS
|
||||
#endif
|
||||
|
||||
#ifdef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#undef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#undef CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#endif
|
||||
|
|
|
@ -42,8 +42,7 @@ nsCSSPseudoClasses::HasStringArg(Type aType)
|
|||
return aType == ePseudoClass_lang ||
|
||||
aType == ePseudoClass_mozEmptyExceptChildrenWithLocalname ||
|
||||
aType == ePseudoClass_mozSystemMetric ||
|
||||
aType == ePseudoClass_mozLocaleDir ||
|
||||
aType == ePseudoClass_dir;
|
||||
aType == ePseudoClass_mozLocaleDir;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -1308,7 +1308,7 @@ struct NodeMatchContext {
|
|||
// event-state-dependent selector for any value of that event state.
|
||||
// So mStateMask contains the states that should NOT be tested.
|
||||
//
|
||||
// NOTE: For |mStateMask| to work correctly, it's important that any
|
||||
// NOTE: For |aStateMask| to work correctly, it's important that any
|
||||
// change that changes multiple state bits include all those state
|
||||
// bits in the notification. Otherwise, if multiple states change but
|
||||
// we do separate notifications then we might determine the style is
|
||||
|
@ -1533,21 +1533,7 @@ checkGenericEmptyMatches(Element* aElement,
|
|||
return (child == nullptr);
|
||||
}
|
||||
|
||||
// Arrays of the states that are relevant for various pseudoclasses.
|
||||
static const nsEventStates sPseudoClassStateDependences[] = {
|
||||
#define CSS_PSEUDO_CLASS(_name, _value) \
|
||||
nsEventStates(),
|
||||
#define CSS_STATE_DEPENDENT_PSEUDO_CLASS(_name, _value, _states) \
|
||||
_states,
|
||||
#include "nsCSSPseudoClassList.h"
|
||||
#undef CSS_STATE_DEPENDENT_PSEUDO_CLASS
|
||||
#undef CSS_PSEUDO_CLASS
|
||||
// Add more entries for our fake values to make sure we can't
|
||||
// index out of bounds into this array no matter what.
|
||||
nsEventStates(),
|
||||
nsEventStates()
|
||||
};
|
||||
|
||||
// An array of the states that are relevant for various pseudoclasses.
|
||||
static const nsEventStates sPseudoClassStates[] = {
|
||||
#define CSS_PSEUDO_CLASS(_name, _value) \
|
||||
nsEventStates(),
|
||||
|
@ -1570,7 +1556,7 @@ MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassStates) ==
|
|||
// * when non-null, it indicates that we're processing a negation,
|
||||
// which is done only when SelectorMatches calls itself recursively
|
||||
// * what it points to should be set to true whenever a test is skipped
|
||||
// because of aNodeMatchContent.mStateMask
|
||||
// because of aStateMask
|
||||
static bool SelectorMatches(Element* aElement,
|
||||
nsCSSSelector* aSelector,
|
||||
NodeMatchContext& aNodeMatchContext,
|
||||
|
@ -2011,38 +1997,6 @@ static bool SelectorMatches(Element* aElement,
|
|||
}
|
||||
break;
|
||||
|
||||
case nsCSSPseudoClasses::ePseudoClass_dir:
|
||||
{
|
||||
if (aDependence) {
|
||||
nsEventStates states
|
||||
= sPseudoClassStateDependences[pseudoClass->mType];
|
||||
if (aNodeMatchContext.mStateMask.HasAtLeastOneOfStates(states)) {
|
||||
*aDependence = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we only had to consider HTML, directionality would be exclusively
|
||||
// LTR or RTL, and this could be just
|
||||
//
|
||||
// if (dirString.EqualsLiteral("rtl") !=
|
||||
// aElement->StyleState().HasState(NS_EVENT_STATE_RTL)
|
||||
//
|
||||
// However, in markup languages where there is no direction attribute
|
||||
// we have to consider the possibility that neither dir(rtl) nor
|
||||
// dir(ltr) matches.
|
||||
nsEventStates state = aElement->StyleState();
|
||||
bool elementIsRTL = state.HasState(NS_EVENT_STATE_RTL);
|
||||
bool elementIsLTR = state.HasState(NS_EVENT_STATE_LTR);
|
||||
nsDependentString dirString(pseudoClass->u.mString);
|
||||
|
||||
if ((dirString.EqualsLiteral("rtl") && !elementIsRTL) ||
|
||||
(dirString.EqualsLiteral("ltr") && !elementIsLTR)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(false, "How did that happen?");
|
||||
}
|
||||
|
@ -2174,10 +2128,10 @@ static bool SelectorMatches(Element* aElement,
|
|||
bool dependence = false;
|
||||
result = !SelectorMatches(aElement, negation, aNodeMatchContext,
|
||||
aTreeMatchContext, &dependence);
|
||||
// If the selector does match due to the dependence on
|
||||
// aNodeMatchContext.mStateMask, then we want to keep result true
|
||||
// so that the final result of SelectorMatches is true. Doing so
|
||||
// tells StateEnumFunc that there is a dependence on the state.
|
||||
// If the selector does match due to the dependence on aStateMask,
|
||||
// then we want to keep result true so that the final result of
|
||||
// SelectorMatches is true. Doing so tells StateEnumFunc that
|
||||
// there is a dependence on the state.
|
||||
result = result || dependence;
|
||||
}
|
||||
}
|
||||
|
@ -2711,7 +2665,7 @@ nsEventStates ComputeSelectorStateDependence(nsCSSSelector& aSelector)
|
|||
if (pseudoClass->mType >= nsCSSPseudoClasses::ePseudoClass_Count) {
|
||||
continue;
|
||||
}
|
||||
states |= sPseudoClassStateDependences[pseudoClass->mType];
|
||||
states |= sPseudoClassStates[pseudoClass->mType];
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
|
|
@ -72,10 +72,13 @@ public class GLController {
|
|||
}
|
||||
|
||||
// This function is invoked by JNI
|
||||
public synchronized void resumeCompositorIfValid() {
|
||||
if (mSurfaceValid) {
|
||||
mView.getListener().compositionResumeRequested(mWidth, mHeight);
|
||||
public void resumeCompositorIfValid() {
|
||||
synchronized (this) {
|
||||
if (!mSurfaceValid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mView.getListener().compositionResumeRequested(mWidth, mHeight);
|
||||
}
|
||||
|
||||
// Wait until we are allowed to use EGL functions on the Surface backing
|
||||
|
|
|
@ -21,7 +21,7 @@ ContentPermissionPrompt.prototype = {
|
|||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
|
||||
|
||||
handleExistingPermission: function handleExistingPermission(request) {
|
||||
let result = Services.perms.testExactPermission(request.uri, request.type);
|
||||
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
|
||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
request.allow();
|
||||
return true;
|
||||
|
@ -70,7 +70,7 @@ ContentPermissionPrompt.prototype = {
|
|||
callback: function(aChecked) {
|
||||
// If the user checked "Don't ask again", make a permanent exception
|
||||
if (aChecked)
|
||||
Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
request.allow();
|
||||
}
|
||||
|
@ -80,18 +80,18 @@ ContentPermissionPrompt.prototype = {
|
|||
callback: function(aChecked) {
|
||||
// If the user checked "Don't ask again", make a permanent exception
|
||||
if (aChecked)
|
||||
Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.DENY_ACTION);
|
||||
Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.DENY_ACTION);
|
||||
|
||||
request.cancel();
|
||||
}
|
||||
}];
|
||||
|
||||
let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
|
||||
[request.uri.host], 1);
|
||||
[request.principal.URI.host], 1);
|
||||
let options = { checkbox: browserBundle.GetStringFromName(entityName + ".dontAskAgain") };
|
||||
|
||||
chromeWin.NativeWindow.doorhanger.show(message,
|
||||
entityName + request.uri.host,
|
||||
entityName + request.principal.URI.host,
|
||||
buttons, tab.id, options);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -61,7 +61,7 @@ let IndexedDB = {
|
|||
|
||||
prompt.prompt({
|
||||
type: type,
|
||||
uri: Services.io.newURI(payload.location, null, null),
|
||||
principal: browser.contentPrincipal,
|
||||
window: null,
|
||||
element: aMessage.target,
|
||||
|
||||
|
|
|
@ -64,8 +64,9 @@ var WebappsUI = {
|
|||
},
|
||||
|
||||
askPermission: function(aMessage, aType, aCallbacks) {
|
||||
let uri = Services.io.newURI(aMessage.json.from, null, null);
|
||||
let perm = Services.perms.testExactPermission(uri, aType);
|
||||
let browser = aMessage.target;
|
||||
let principal = browser.contentPrincipal;
|
||||
let perm = Services.perms.testExactPermissionFromPrincipal(principal, aType);
|
||||
switch(perm) {
|
||||
case Ci.nsIPermissionManager.ALLOW_ACTION:
|
||||
aCallbacks.allow();
|
||||
|
@ -79,7 +80,7 @@ var WebappsUI = {
|
|||
|
||||
prompt.prompt({
|
||||
type: aType,
|
||||
uri: uri,
|
||||
principal: principal,
|
||||
window: null,
|
||||
element: getBrowser(),
|
||||
|
||||
|
@ -88,7 +89,7 @@ var WebappsUI = {
|
|||
},
|
||||
|
||||
allow: function() {
|
||||
Services.perms.add(uri, aType, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
Services.perms.addFromPrincipal(principal, aType, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
aCallbacks.allow();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -11,26 +11,26 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
|
||||
const kCountBeforeWeRemember = 5;
|
||||
|
||||
function setPagePermission(type, uri, allow) {
|
||||
function setPagePermission(type, principal, allow) {
|
||||
let pm = Services.perms;
|
||||
let contentPrefs = Services.contentPrefs;
|
||||
let contentPrefName = type + ".request.remember";
|
||||
|
||||
if (!contentPrefs.hasPref(uri, contentPrefName))
|
||||
contentPrefs.setPref(uri, contentPrefName, 0);
|
||||
if (!contentPrefs.hasPref(principal.URI, contentPrefName))
|
||||
contentPrefs.setPref(principal.URI, contentPrefName, 0);
|
||||
|
||||
let count = contentPrefs.getPref(uri, contentPrefName);
|
||||
let count = contentPrefs.getPref(principal.URI, contentPrefName);
|
||||
|
||||
if (allow == false)
|
||||
count--;
|
||||
else
|
||||
count++;
|
||||
|
||||
contentPrefs.setPref(uri, contentPrefName, count);
|
||||
|
||||
contentPrefs.setPref(principal.URI, contentPrefName, count);
|
||||
if (count == kCountBeforeWeRemember)
|
||||
pm.add(uri, type, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
pm.addFromPrincipal(principal, type, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
else if (count == -kCountBeforeWeRemember)
|
||||
pm.add(uri, type, Ci.nsIPermissionManager.DENY_ACTION);
|
||||
pm.addFromPrincipal(principal, type, Ci.nsIPermissionManager.DENY_ACTION);
|
||||
}
|
||||
|
||||
const kEntities = { "geolocation": "geolocation", "desktop-notification": "desktopNotification",
|
||||
|
@ -70,7 +70,7 @@ ContentPermissionPrompt.prototype = {
|
|||
},
|
||||
|
||||
handleExistingPermission: function handleExistingPermission(request) {
|
||||
let result = Services.perms.testExactPermission(request.uri, request.type);
|
||||
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
|
||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
request.allow();
|
||||
return true;
|
||||
|
@ -101,7 +101,7 @@ ContentPermissionPrompt.prototype = {
|
|||
label: browserBundle.GetStringFromName(entityName + ".allow"),
|
||||
accessKey: null,
|
||||
callback: function(notification) {
|
||||
setPagePermission(request.type, request.uri, true);
|
||||
setPagePermission(request.type, request.principal, true);
|
||||
request.allow();
|
||||
}
|
||||
},
|
||||
|
@ -109,13 +109,13 @@ ContentPermissionPrompt.prototype = {
|
|||
label: browserBundle.GetStringFromName(entityName + ".dontAllow"),
|
||||
accessKey: null,
|
||||
callback: function(notification) {
|
||||
setPagePermission(request.type, request.uri, false);
|
||||
setPagePermission(request.type, request.principal, false);
|
||||
request.cancel();
|
||||
}
|
||||
}];
|
||||
|
||||
let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
|
||||
[request.uri.host], 1);
|
||||
[request.principal.URI.host], 1);
|
||||
let newBar = notificationBox.appendNotification(message,
|
||||
request.type,
|
||||
"", // Notifications in Fennec do not display images.
|
||||
|
|
|
@ -3551,7 +3551,7 @@ pref("layers.prefer-d3d9", false);
|
|||
pref("geo.enabled", true);
|
||||
|
||||
// Enable/Disable the orientation API for content
|
||||
pref("device.motion.enabled", true);
|
||||
pref("device.sensors.enabled", true);
|
||||
|
||||
// Enable/Disable the device storage API for content
|
||||
pref("device.storage.enabled", false);
|
||||
|
|
|
@ -28,6 +28,7 @@ const PR_WRONLY = 0x2;
|
|||
const PR_CREATE_FILE = 0x8;
|
||||
const PR_TRUNCATE = 0x20;
|
||||
const RW_OWNER = 0600;
|
||||
const RWX_OWNER = 0700;
|
||||
|
||||
// MEM_HISTOGRAMS lists the memory reporters we turn into histograms.
|
||||
//
|
||||
|
@ -863,13 +864,16 @@ TelemetryPing.prototype = {
|
|||
directory.append("saved-telemetry-pings");
|
||||
if (directory.exists()) {
|
||||
if (directory.isDirectory()) {
|
||||
// We used to wrongly create the directory with mode 0600.
|
||||
// Fix that.
|
||||
directory.permissions = RWX_OWNER;
|
||||
return directory;
|
||||
} else {
|
||||
directory.remove(true);
|
||||
}
|
||||
}
|
||||
|
||||
directory.create(Ci.nsIFile.DIRECTORY_TYPE, RW_OWNER);
|
||||
directory.create(Ci.nsIFile.DIRECTORY_TYPE, RWX_OWNER);
|
||||
return directory;
|
||||
},
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ ContentPermission.prototype = {
|
|||
}
|
||||
|
||||
// Reuse any remembered permission preferences
|
||||
let result = Services.perms.testExactPermission(request.uri, "geo");
|
||||
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, "geo");
|
||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
request.allow();
|
||||
return;
|
||||
|
@ -73,7 +73,7 @@ ContentPermission.prototype = {
|
|||
if (choice != 0) {
|
||||
action = Ci.nsIPermissionManager.DENY_ACTION;
|
||||
}
|
||||
Services.perms.add(request.uri, "geo", action);
|
||||
Services.perms.addFromPrincipal(request.principal, "geo", action);
|
||||
}
|
||||
|
||||
// Trigger the selected choice
|
||||
|
|
|
@ -112,7 +112,7 @@ nsSupportsArray::~nsSupportsArray()
|
|||
DeleteArray();
|
||||
}
|
||||
|
||||
bool nsSupportsArray::GrowArrayBy(PRInt32 aGrowBy)
|
||||
void nsSupportsArray::GrowArrayBy(PRInt32 aGrowBy)
|
||||
{
|
||||
// We have to grow the array. Grow by kGrowArrayBy slots if we're smaller
|
||||
// than kLinearThreshold bytes, or a power of two if we're larger.
|
||||
|
@ -139,10 +139,6 @@ bool nsSupportsArray::GrowArrayBy(PRInt32 aGrowBy)
|
|||
nsISupports** oldArray = mArray;
|
||||
|
||||
mArray = new nsISupports*[newCount];
|
||||
if (!mArray) { // ran out of memory
|
||||
mArray = oldArray;
|
||||
return false;
|
||||
}
|
||||
mArraySize = newCount;
|
||||
|
||||
#if DEBUG_SUPPORTSARRAY
|
||||
|
@ -165,8 +161,6 @@ bool nsSupportsArray::GrowArrayBy(PRInt32 aGrowBy)
|
|||
delete[] oldArray;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -176,8 +170,6 @@ nsSupportsArray::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> it = new nsSupportsArray();
|
||||
if (!it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return it->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
@ -206,8 +198,6 @@ nsSupportsArray::Read(nsIObjectInputStream *aStream)
|
|||
}
|
||||
else {
|
||||
nsISupports** array = new nsISupports*[newArraySize];
|
||||
if (!array)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (mArray != mAutoArray)
|
||||
delete[] mArray;
|
||||
mArray = array;
|
||||
|
@ -341,8 +331,7 @@ nsSupportsArray::InsertElementAt(nsISupports* aElement, PRUint32 aIndex)
|
|||
if (aIndex <= mCount) {
|
||||
if (mArraySize < (mCount + 1)) {
|
||||
// need to grow the array
|
||||
if (!GrowArrayBy(1))
|
||||
return false;
|
||||
GrowArrayBy(1);
|
||||
}
|
||||
|
||||
// Could be slightly more efficient if GrowArrayBy knew about the
|
||||
|
@ -383,8 +372,7 @@ nsSupportsArray::InsertElementsAt(nsISupportsArray* aElements, PRUint32 aIndex)
|
|||
if (aIndex <= mCount) {
|
||||
if (mArraySize < (mCount + countElements)) {
|
||||
// need to grow the array
|
||||
if (!GrowArrayBy(countElements))
|
||||
return false;
|
||||
GrowArrayBy(countElements);
|
||||
}
|
||||
|
||||
// Could be slightly more efficient if GrowArrayBy knew about the
|
||||
|
@ -729,8 +717,6 @@ NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
|
|||
nsISupportsArray* array)
|
||||
{
|
||||
nsArrayEnumerator* enumer = new nsArrayEnumerator(array);
|
||||
if (enumer == nullptr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
*result = enumer;
|
||||
NS_ADDREF(*result);
|
||||
return NS_OK;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче