mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 05:48:26 +00:00
Merge inbound to m-c.
This commit is contained in:
commit
86edf921e8
@ -18,7 +18,7 @@
|
|||||||
<script class="testbody" type="application/javascript;version=1.7">
|
<script class="testbody" type="application/javascript;version=1.7">
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
const Ci = Components.interfaces;
|
const Ci = SpecialPowers.Ci;
|
||||||
let wrapperClickCount = 0;
|
let wrapperClickCount = 0;
|
||||||
|
|
||||||
function test1() {
|
function test1() {
|
||||||
|
@ -69,4 +69,11 @@ BRANDING_DEST := $(DIST)/branding
|
|||||||
BRANDING_TARGET := export
|
BRANDING_TARGET := export
|
||||||
INSTALL_TARGETS += BRANDING
|
INSTALL_TARGETS += BRANDING
|
||||||
|
|
||||||
|
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows metro)
|
||||||
|
VISUALMANIFEST := VisualElementsManifest.xml
|
||||||
|
VISUALMANIFEST_FLAGS := -Fsubstitution -DMOZ_APP_DISPLAYNAME=${MOZ_APP_DISPLAYNAME}
|
||||||
|
VISUALMANIFEST_PATH := $(DIST)/bin
|
||||||
|
PP_TARGETS += VISUALMANIFEST
|
||||||
|
endif
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
16
browser/branding/aurora/VisualElementsManifest.xml
Normal file
16
browser/branding/aurora/VisualElementsManifest.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<Application
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<VisualElements
|
||||||
|
DisplayName="@MOZ_APP_DISPLAYNAME@"
|
||||||
|
Logo="tileresources\VisualElements_logo.png"
|
||||||
|
SmallLogo="tileresources\VisualElements_smalllogo.png"
|
||||||
|
ForegroundText="light"
|
||||||
|
BackgroundColor="#1c112e">
|
||||||
|
<DefaultTile
|
||||||
|
ShortName="@MOZ_APP_DISPLAYNAME@"
|
||||||
|
ShowName="allLogos"
|
||||||
|
/>
|
||||||
|
<SplashScreen
|
||||||
|
Image="tileresources\VisualElements_splashscreen.png" />
|
||||||
|
</VisualElements>
|
||||||
|
</Application>
|
@ -69,4 +69,11 @@ BRANDING_DEST := $(DIST)/branding
|
|||||||
BRANDING_TARGET := export
|
BRANDING_TARGET := export
|
||||||
INSTALL_TARGETS += BRANDING
|
INSTALL_TARGETS += BRANDING
|
||||||
|
|
||||||
|
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows metro)
|
||||||
|
VISUALMANIFEST := VisualElementsManifest.xml
|
||||||
|
VISUALMANIFEST_FLAGS := -Fsubstitution -DMOZ_APP_DISPLAYNAME=${MOZ_APP_DISPLAYNAME}
|
||||||
|
VISUALMANIFEST_PATH := $(DIST)/bin
|
||||||
|
PP_TARGETS += VISUALMANIFEST
|
||||||
|
endif
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
16
browser/branding/nightly/VisualElementsManifest.xml
Normal file
16
browser/branding/nightly/VisualElementsManifest.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<Application
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<VisualElements
|
||||||
|
DisplayName="@MOZ_APP_DISPLAYNAME@"
|
||||||
|
Logo="tileresources\VisualElements_logo.png"
|
||||||
|
SmallLogo="tileresources\VisualElements_smalllogo.png"
|
||||||
|
ForegroundText="light"
|
||||||
|
BackgroundColor="#001226">
|
||||||
|
<DefaultTile
|
||||||
|
ShortName="@MOZ_APP_DISPLAYNAME@"
|
||||||
|
ShowName="allLogos"
|
||||||
|
/>
|
||||||
|
<SplashScreen
|
||||||
|
Image="tileresources\VisualElements_splashscreen.png" />
|
||||||
|
</VisualElements>
|
||||||
|
</Application>
|
@ -69,4 +69,11 @@ BRANDING_DEST := $(DIST)/branding
|
|||||||
BRANDING_TARGET := export
|
BRANDING_TARGET := export
|
||||||
INSTALL_TARGETS += BRANDING
|
INSTALL_TARGETS += BRANDING
|
||||||
|
|
||||||
|
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows metro)
|
||||||
|
VISUALMANIFEST := VisualElementsManifest.xml
|
||||||
|
VISUALMANIFEST_FLAGS := -Fsubstitution -DMOZ_APP_DISPLAYNAME=${MOZ_APP_DISPLAYNAME}
|
||||||
|
VISUALMANIFEST_PATH := $(DIST)/bin
|
||||||
|
PP_TARGETS += VISUALMANIFEST
|
||||||
|
endif
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
@ -69,4 +69,11 @@ BRANDING_DEST := $(DIST)/branding
|
|||||||
BRANDING_TARGET := export
|
BRANDING_TARGET := export
|
||||||
INSTALL_TARGETS += BRANDING
|
INSTALL_TARGETS += BRANDING
|
||||||
|
|
||||||
|
ifeq ($(MOZ_WIDGET_TOOLKIT) $(DIST_SUBDIR),windows metro)
|
||||||
|
VISUALMANIFEST := VisualElementsManifest.xml
|
||||||
|
VISUALMANIFEST_FLAGS := -Fsubstitution -DMOZ_APP_DISPLAYNAME=${MOZ_APP_DISPLAYNAME}
|
||||||
|
VISUALMANIFEST_PATH := $(DIST)/bin
|
||||||
|
PP_TARGETS += VISUALMANIFEST
|
||||||
|
endif
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
16
browser/branding/unofficial/VisualElementsManifest.xml
Normal file
16
browser/branding/unofficial/VisualElementsManifest.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<Application
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<VisualElements
|
||||||
|
DisplayName="@MOZ_APP_DISPLAYNAME@"
|
||||||
|
Logo="tileresources\VisualElements_logo.png"
|
||||||
|
SmallLogo="tileresources\VisualElements_smalllogo.png"
|
||||||
|
ForegroundText="light"
|
||||||
|
BackgroundColor="#001226">
|
||||||
|
<DefaultTile
|
||||||
|
ShortName="@MOZ_APP_DISPLAYNAME@"
|
||||||
|
ShowName="allLogos"
|
||||||
|
/>
|
||||||
|
<SplashScreen
|
||||||
|
Image="tileresources\VisualElements_splashscreen.png" />
|
||||||
|
</VisualElements>
|
||||||
|
</Application>
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
var gClient = null;
|
var gClient = null;
|
||||||
var gTab = null;
|
var gTab = null;
|
||||||
|
var gHomeTab = null;
|
||||||
var gThreadClient = null;
|
var gThreadClient = null;
|
||||||
var gNewGlobal = false;
|
var gNewGlobal = false;
|
||||||
var gAttached = false;
|
var gAttached = false;
|
||||||
@ -33,8 +34,7 @@ function test()
|
|||||||
gAttached = true;
|
gAttached = true;
|
||||||
|
|
||||||
// Ensure that a new global will be created.
|
// Ensure that a new global will be created.
|
||||||
let frame = content.document.createElement("iframe");
|
gHomeTab = gBrowser.addTab("about:home");
|
||||||
content.document.querySelector("body").appendChild(frame);
|
|
||||||
|
|
||||||
finish_test();
|
finish_test();
|
||||||
});
|
});
|
||||||
@ -58,6 +58,7 @@ function finish_test()
|
|||||||
}
|
}
|
||||||
gClient.removeListener("newScript", onNewScript);
|
gClient.removeListener("newScript", onNewScript);
|
||||||
gThreadClient.resume(function(aResponse) {
|
gThreadClient.resume(function(aResponse) {
|
||||||
|
removeTab(gHomeTab);
|
||||||
removeTab(gTab);
|
removeTab(gTab);
|
||||||
gClient.close(function() {
|
gClient.close(function() {
|
||||||
ok(gNewGlobal, "Received newGlobal event.");
|
ok(gNewGlobal, "Received newGlobal event.");
|
||||||
|
@ -219,7 +219,7 @@ var TouchModule = {
|
|||||||
this._targetScrollInterface = targetScrollInterface;
|
this._targetScrollInterface = targetScrollInterface;
|
||||||
|
|
||||||
if (!this._targetScrollbox) {
|
if (!this._targetScrollbox) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX shouldn't dragger always be valid here?
|
// XXX shouldn't dragger always be valid here?
|
||||||
|
@ -19,15 +19,8 @@ endif
|
|||||||
|
|
||||||
export::
|
export::
|
||||||
$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
|
$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
|
||||||
$(RM) $(DIST)/bin/VisualElementsManifest.xml
|
|
||||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(ACDEFINES) -DMOZ_APP_DISPLAYNAME=${MOZ_APP_DISPLAYNAME} \
|
|
||||||
$(srcdir)/VisualElementsManifest.xml.in > $(DIST)/bin/VisualElementsManifest.xml
|
|
||||||
|
|
||||||
install::
|
install::
|
||||||
$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
|
$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
|
||||||
|
|
||||||
# bug 744566
|
|
||||||
# $(RM) $(DIST)/bin/resources.pri
|
|
||||||
# $(MAKEPRI) new -v -pr $(srcdir)/tileresources -cf $(srcdir)/priconfig.xml -mn $(srcdir)/AppManifest.xml -of $(DIST)/bin/resources.pri -o
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
@ -94,6 +94,15 @@ if test "$CLANG_CXX"; then
|
|||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-mismatched-tags"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-mismatched-tags"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -z "$GNU_CC"; then
|
||||||
|
case "$target" in
|
||||||
|
*-mingw*)
|
||||||
|
## Warning 4099 (equivalent of mismatched-tags) is disabled (bug 780474)
|
||||||
|
## for the same reasons as above.
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -wd4099"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$GNU_CC"; then
|
if test "$GNU_CC"; then
|
||||||
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
||||||
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
|
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
|
||||||
|
@ -2157,8 +2157,9 @@ ia64*-hpux*)
|
|||||||
# that behavior) that it's better to turn it off.
|
# that behavior) that it's better to turn it off.
|
||||||
# MSVC warning C4819 warns some UTF-8 characters (e.g. copyright sign)
|
# MSVC warning C4819 warns some UTF-8 characters (e.g. copyright sign)
|
||||||
# on non-Western system locales even if it is in a comment.
|
# on non-Western system locales even if it is in a comment.
|
||||||
|
# khuey says we can safely ignore MSVC warning C4251
|
||||||
CFLAGS="$CFLAGS -wd4819"
|
CFLAGS="$CFLAGS -wd4819"
|
||||||
CXXFLAGS="$CXXFLAGS -wd4345 -wd4351 -wd4482 -wd4800 -wd4819"
|
CXXFLAGS="$CXXFLAGS -wd4251 -wd4345 -wd4351 -wd4482 -wd4800 -wd4819"
|
||||||
# make 'foo == bar;' error out
|
# make 'foo == bar;' error out
|
||||||
CFLAGS="$CFLAGS -we4553"
|
CFLAGS="$CFLAGS -we4553"
|
||||||
CXXFLAGS="$CXXFLAGS -we4553"
|
CXXFLAGS="$CXXFLAGS -we4553"
|
||||||
@ -8971,7 +8972,7 @@ echo $MAKEFILES > unallmakefiles
|
|||||||
|
|
||||||
AC_OUTPUT($MAKEFILES)
|
AC_OUTPUT($MAKEFILES)
|
||||||
|
|
||||||
# target_arch is from {ia32|x64|arm}
|
# target_arch is from {ia32|x64|arm|ppc}
|
||||||
case "$CPU_ARCH" in
|
case "$CPU_ARCH" in
|
||||||
x86_64 | ia64)
|
x86_64 | ia64)
|
||||||
WEBRTC_TARGET_ARCH=x64
|
WEBRTC_TARGET_ARCH=x64
|
||||||
@ -8985,6 +8986,9 @@ x86)
|
|||||||
WEBRTC_TARGET_ARCH=ia32
|
WEBRTC_TARGET_ARCH=ia32
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
ppc*)
|
||||||
|
WEBRTC_TARGET_ARCH=ppc
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
# unsupported arch for webrtc
|
# unsupported arch for webrtc
|
||||||
WEBRTC_TARGET_ARCH=unknown
|
WEBRTC_TARGET_ARCH=unknown
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
#include "sampler.h"
|
#include "sampler.h"
|
||||||
|
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "nsHTMLIFrameElement.h"
|
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||||
#include "nsSandboxFlags.h"
|
#include "nsSandboxFlags.h"
|
||||||
|
|
||||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||||
@ -450,8 +450,8 @@ nsFrameLoader::ReallyStartLoadingInternal()
|
|||||||
|
|
||||||
// Is this an <iframe> with a sandbox attribute or a parent which is
|
// Is this an <iframe> with a sandbox attribute or a parent which is
|
||||||
// sandboxed ?
|
// sandboxed ?
|
||||||
nsHTMLIFrameElement* iframe =
|
HTMLIFrameElement* iframe =
|
||||||
nsHTMLIFrameElement::FromContent(mOwnerContent);
|
HTMLIFrameElement::FromContent(mOwnerContent);
|
||||||
|
|
||||||
uint32_t sandboxFlags = 0;
|
uint32_t sandboxFlags = 0;
|
||||||
|
|
||||||
|
@ -1025,7 +1025,8 @@ nsScriptLoader::ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
|
|||||||
|
|
||||||
if (!unicodeDecoder &&
|
if (!unicodeDecoder &&
|
||||||
aChannel &&
|
aChannel &&
|
||||||
NS_SUCCEEDED(aChannel->GetContentCharset(charset))) {
|
NS_SUCCEEDED(aChannel->GetContentCharset(charset)) &&
|
||||||
|
!charset.IsEmpty()) {
|
||||||
charsetConv->GetUnicodeDecoder(charset.get(),
|
charsetConv->GetUnicodeDecoder(charset.get(),
|
||||||
getter_AddRefs(unicodeDecoder));
|
getter_AddRefs(unicodeDecoder));
|
||||||
}
|
}
|
||||||
|
@ -3371,6 +3371,8 @@ nsXMLHttpRequest::SetMultipart(bool aMultipart, nsresult& aRv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogMessage("MultipartXHRWarning", GetOwner());
|
||||||
|
|
||||||
if (aMultipart) {
|
if (aMultipart) {
|
||||||
mState |= XML_HTTP_REQUEST_MULTIPART;
|
mState |= XML_HTTP_REQUEST_MULTIPART;
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,10 +24,8 @@ let am = {
|
|||||||
authMgr: null,
|
authMgr: null,
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
const {classes: Cc, interfaces: Ci} = SpecialPowers.wrap(Components);
|
this.authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"]
|
||||||
|
.getService(SpecialPowers.Ci.nsIHttpAuthManager)
|
||||||
this.authMgr = Cc["@mozilla.org/network/http-auth-manager;1"]
|
|
||||||
.getService(Components.interfaces.nsIHttpAuthManager)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addIdentity: function() {
|
addIdentity: function() {
|
||||||
|
@ -15,7 +15,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=425013
|
|||||||
|
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
var missingPlugins = new Array();
|
var missingPlugins = new Array();
|
||||||
var OBJLC = Components.interfaces.nsIObjectLoadingContent;
|
var OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||||
|
|
||||||
function pluginBinding(event)
|
function pluginBinding(event)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429157
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
var missingPlugins = new Array();
|
var missingPlugins = new Array();
|
||||||
const OBJLC = Components.interfaces.nsIObjectLoadingContent;
|
const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||||
|
|
||||||
function pluginBindingAttached(event)
|
function pluginBindingAttached(event)
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ function test(tag, type) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
info("testing " + tag + " tag with type " + type);
|
info("testing " + tag + " tag with type " + type);
|
||||||
|
|
||||||
const OBJLC = Components.interfaces.nsIObjectLoadingContent;
|
const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||||
let obj = document.createElement(tag);
|
let obj = document.createElement(tag);
|
||||||
obj.type = type;
|
obj.type = type;
|
||||||
document.body.appendChild(obj);
|
document.body.appendChild(obj);
|
||||||
|
@ -16,14 +16,12 @@
|
|||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script class="testbody" type="application/javascript;version=1.8">
|
<script class="testbody" type="application/javascript;version=1.8">
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = SpecialPowers.wrap(Components);
|
|
||||||
|
|
||||||
const APP_URL = "http://example.org";
|
const APP_URL = "http://example.org";
|
||||||
const APP_MANIFEST = "http://example.org/manifest.webapp";
|
const APP_MANIFEST = "http://example.org/manifest.webapp";
|
||||||
const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
|
const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
|
||||||
|
|
||||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
let ppmm = SpecialPowers.Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||||
.getService(Ci.nsIMessageBroadcaster);
|
.getService(SpecialPowers.Ci.nsIMessageBroadcaster);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the example.org site in an <iframe mozbrowser>
|
* Load the example.org site in an <iframe mozbrowser>
|
||||||
|
@ -15,18 +15,16 @@
|
|||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script class="testbody" type="application/javascript;version=1.8">
|
<script class="testbody" type="application/javascript;version=1.8">
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = SpecialPowers.wrap(Components);
|
|
||||||
|
|
||||||
const APP_URL = "http://example.org";
|
const APP_URL = "http://example.org";
|
||||||
const APP_MANIFEST = "http://example.org/manifest.webapp";
|
const APP_MANIFEST = "http://example.org/manifest.webapp";
|
||||||
const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
|
const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
|
||||||
|
|
||||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
let ppmm = SpecialPowers.Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||||
.getService(Ci.nsIMessageBroadcaster);
|
.getService(SpecialPowers.Ci.nsIMessageBroadcaster);
|
||||||
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
let cpmm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||||
.getService(Ci.nsISyncMessageSender);
|
.getService(SpecialPowers.Ci.nsISyncMessageSender);
|
||||||
let gAppsService = Cc["@mozilla.org/AppsService;1"]
|
let gAppsService = SpecialPowers.Cc["@mozilla.org/AppsService;1"]
|
||||||
.getService(Ci.nsIAppsService);
|
.getService(SpecialPowers.Ci.nsIAppsService);
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||||
|
@ -45,8 +45,8 @@ var OPTIONS = {
|
|||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
function detectDriverType() {
|
function detectDriverType() {
|
||||||
const Cc = SpecialPowers.wrap(Components).classes;
|
const Cc = SpecialPowers.Cc;
|
||||||
const Ci = SpecialPowers.wrap(Components).interfaces;
|
const Ci = SpecialPowers.Ci;
|
||||||
var doc = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser).parseFromString("<html/>", "text/html");
|
var doc = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser).parseFromString("<html/>", "text/html");
|
||||||
|
|
||||||
var canvas = doc.createElement("canvas");
|
var canvas = doc.createElement("canvas");
|
||||||
@ -105,15 +105,15 @@ function start() {
|
|||||||
if (kIsWindows) {
|
if (kIsWindows) {
|
||||||
// code borrowed from browser/modules/test/browser_taskbar_preview.js
|
// code borrowed from browser/modules/test/browser_taskbar_preview.js
|
||||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||||
var version = Components.classes["@mozilla.org/system-info;1"]
|
var version = SpecialPowers.Cc["@mozilla.org/system-info;1"]
|
||||||
.getService(Components.interfaces.nsIPropertyBag2)
|
.getService(SpecialPowers.Ci.nsIPropertyBag2)
|
||||||
.getProperty("version");
|
.getProperty("version");
|
||||||
kIsWindowsVistaOrHigher = (parseFloat(version) >= 6.0);
|
kIsWindowsVistaOrHigher = (parseFloat(version) >= 6.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEnv(env) {
|
function getEnv(env) {
|
||||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||||
var envsvc = Components.classes["@mozilla.org/process/environment;1"].getService(Components.interfaces.nsIEnvironment);
|
var envsvc = SpecialPowers.Cc["@mozilla.org/process/environment;1"].getService(SpecialPowers.Ci.nsIEnvironment);
|
||||||
var val = envsvc.get(env);
|
var val = envsvc.get(env);
|
||||||
if (val == "")
|
if (val == "")
|
||||||
return null;
|
return null;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "mozilla/Util.h"
|
#include "mozilla/Util.h"
|
||||||
|
|
||||||
#include "nsHTMLIFrameElement.h"
|
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||||
#include "nsIDOMSVGDocument.h"
|
#include "nsIDOMSVGDocument.h"
|
||||||
#include "nsMappedAttributes.h"
|
#include "nsMappedAttributes.h"
|
||||||
#include "nsAttrValueInlines.h"
|
#include "nsAttrValueInlines.h"
|
||||||
@ -14,86 +14,86 @@
|
|||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
|
|
||||||
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
|
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
|
||||||
|
|
||||||
nsHTMLIFrameElement::nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
DOMCI_NODE_DATA(HTMLIFrameElement, mozilla::dom::HTMLIFrameElement)
|
||||||
FromParser aFromParser)
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
HTMLIFrameElement::HTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||||
|
FromParser aFromParser)
|
||||||
: nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
|
: nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
nsHTMLIFrameElement::~nsHTMLIFrameElement()
|
HTMLIFrameElement::~HTMLIFrameElement()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(nsHTMLIFrameElement, Element)
|
NS_IMPL_ADDREF_INHERITED(HTMLIFrameElement, Element)
|
||||||
NS_IMPL_RELEASE_INHERITED(nsHTMLIFrameElement, Element)
|
NS_IMPL_RELEASE_INHERITED(HTMLIFrameElement, Element)
|
||||||
|
|
||||||
DOMCI_NODE_DATA(HTMLIFrameElement, nsHTMLIFrameElement)
|
// QueryInterface implementation for HTMLIFrameElement
|
||||||
|
NS_INTERFACE_TABLE_HEAD(HTMLIFrameElement)
|
||||||
// QueryInterface implementation for nsHTMLIFrameElement
|
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(HTMLIFrameElement)
|
||||||
NS_INTERFACE_TABLE_HEAD(nsHTMLIFrameElement)
|
NS_INTERFACE_TABLE_ENTRY(HTMLIFrameElement, nsIDOMHTMLIFrameElement)
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(nsHTMLIFrameElement)
|
NS_INTERFACE_TABLE_ENTRY(HTMLIFrameElement, nsIDOMGetSVGDocument)
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLIFrameElement, nsIDOMHTMLIFrameElement)
|
|
||||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLIFrameElement, nsIDOMGetSVGDocument)
|
|
||||||
NS_OFFSET_AND_INTERFACE_TABLE_END
|
NS_OFFSET_AND_INTERFACE_TABLE_END
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLIFrameElement,
|
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLIFrameElement,
|
||||||
nsGenericHTMLFrameElement)
|
nsGenericHTMLFrameElement)
|
||||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLIFrameElement)
|
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLIFrameElement)
|
||||||
|
|
||||||
NS_IMPL_ELEMENT_CLONE(nsHTMLIFrameElement)
|
NS_IMPL_ELEMENT_CLONE(HTMLIFrameElement)
|
||||||
|
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Align, align)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Align, align)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, FrameBorder, frameborder)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, FrameBorder, frameborder)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Height, height)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Height, height)
|
||||||
NS_IMPL_URI_ATTR(nsHTMLIFrameElement, LongDesc, longdesc)
|
NS_IMPL_URI_ATTR(HTMLIFrameElement, LongDesc, longdesc)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginHeight, marginheight)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, MarginHeight, marginheight)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginWidth, marginwidth)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, MarginWidth, marginwidth)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Name, name)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Name, name)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Scrolling, scrolling)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Scrolling, scrolling)
|
||||||
NS_IMPL_URI_ATTR(nsHTMLIFrameElement, Src, src)
|
NS_IMPL_URI_ATTR(HTMLIFrameElement, Src, src)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Width, width)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Width, width)
|
||||||
NS_IMPL_BOOL_ATTR(nsHTMLIFrameElement, Allowfullscreen, allowfullscreen)
|
NS_IMPL_BOOL_ATTR(HTMLIFrameElement, Allowfullscreen, allowfullscreen)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Sandbox, sandbox)
|
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Sandbox, sandbox)
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHTMLIFrameElement::GetItemValueText(nsAString& aValue)
|
HTMLIFrameElement::GetItemValueText(nsAString& aValue)
|
||||||
{
|
{
|
||||||
GetSrc(aValue);
|
GetSrc(aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHTMLIFrameElement::SetItemValueText(const nsAString& aValue)
|
HTMLIFrameElement::SetItemValueText(const nsAString& aValue)
|
||||||
{
|
{
|
||||||
SetSrc(aValue);
|
SetSrc(aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
HTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
||||||
{
|
{
|
||||||
return nsGenericHTMLFrameElement::GetContentDocument(aContentDocument);
|
return nsGenericHTMLFrameElement::GetContentDocument(aContentDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
|
HTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
|
||||||
{
|
{
|
||||||
return nsGenericHTMLFrameElement::GetContentWindow(aContentWindow);
|
return nsGenericHTMLFrameElement::GetContentWindow(aContentWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLIFrameElement::GetSVGDocument(nsIDOMDocument **aResult)
|
HTMLIFrameElement::GetSVGDocument(nsIDOMDocument **aResult)
|
||||||
{
|
{
|
||||||
return GetContentDocument(aResult);
|
return GetContentDocument(aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsHTMLIFrameElement::ParseAttribute(int32_t aNamespaceID,
|
HTMLIFrameElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
nsIAtom* aAttribute,
|
nsIAtom* aAttribute,
|
||||||
const nsAString& aValue,
|
const nsAString& aValue,
|
||||||
nsAttrValue& aResult)
|
nsAttrValue& aResult)
|
||||||
{
|
{
|
||||||
if (aNamespaceID == kNameSpaceID_None) {
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
if (aAttribute == nsGkAtoms::marginwidth) {
|
if (aAttribute == nsGkAtoms::marginwidth) {
|
||||||
@ -180,7 +180,7 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP_(bool)
|
NS_IMETHODIMP_(bool)
|
||||||
nsHTMLIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
HTMLIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
||||||
{
|
{
|
||||||
static const MappedAttributeEntry attributes[] = {
|
static const MappedAttributeEntry attributes[] = {
|
||||||
{ &nsGkAtoms::width },
|
{ &nsGkAtoms::width },
|
||||||
@ -202,15 +202,15 @@ nsHTMLIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
|||||||
|
|
||||||
|
|
||||||
nsMapRuleToAttributesFunc
|
nsMapRuleToAttributesFunc
|
||||||
nsHTMLIFrameElement::GetAttributeMappingFunction() const
|
HTMLIFrameElement::GetAttributeMappingFunction() const
|
||||||
{
|
{
|
||||||
return &MapAttributesIntoRule;
|
return &MapAttributesIntoRule;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
bool aNotify)
|
bool aNotify)
|
||||||
{
|
{
|
||||||
if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None) {
|
if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None) {
|
||||||
// Parse the new value of the sandbox attribute, and if we have a docshell
|
// Parse the new value of the sandbox attribute, and if we have a docshell
|
||||||
@ -237,7 +237,7 @@ nsHTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
nsHTMLIFrameElement::GetSandboxFlags()
|
HTMLIFrameElement::GetSandboxFlags()
|
||||||
{
|
{
|
||||||
nsAutoString sandboxAttr;
|
nsAutoString sandboxAttr;
|
||||||
|
|
||||||
@ -248,3 +248,6 @@ nsHTMLIFrameElement::GetSandboxFlags()
|
|||||||
// No sandbox attribute, no sandbox flags.
|
// No sandbox attribute, no sandbox flags.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
@ -3,20 +3,26 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_HTMLIFrameElement_h
|
||||||
|
#define mozilla_dom_HTMLIFrameElement_h
|
||||||
|
|
||||||
#include "nsGenericHTMLFrameElement.h"
|
#include "nsGenericHTMLFrameElement.h"
|
||||||
#include "nsIDOMHTMLIFrameElement.h"
|
#include "nsIDOMHTMLIFrameElement.h"
|
||||||
#include "nsIDOMGetSVGDocument.h"
|
#include "nsIDOMGetSVGDocument.h"
|
||||||
|
|
||||||
class nsHTMLIFrameElement : public nsGenericHTMLFrameElement
|
namespace mozilla {
|
||||||
, public nsIDOMHTMLIFrameElement
|
namespace dom {
|
||||||
, public nsIDOMGetSVGDocument
|
|
||||||
|
class HTMLIFrameElement MOZ_FINAL : public nsGenericHTMLFrameElement
|
||||||
|
, public nsIDOMHTMLIFrameElement
|
||||||
|
, public nsIDOMGetSVGDocument
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
HTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||||
mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
|
FromParser aFromParser = NOT_FROM_PARSER);
|
||||||
virtual ~nsHTMLIFrameElement();
|
virtual ~HTMLIFrameElement();
|
||||||
|
|
||||||
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(nsHTMLIFrameElement, iframe)
|
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLIFrameElement, iframe)
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
@ -58,3 +64,8 @@ protected:
|
|||||||
virtual void GetItemValueText(nsAString& text);
|
virtual void GetItemValueText(nsAString& text);
|
||||||
virtual void SetItemValueText(const nsAString& text);
|
virtual void SetItemValueText(const nsAString& text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif
|
@ -21,7 +21,6 @@ endif # !_MSC_VER
|
|||||||
EXPORTS = \
|
EXPORTS = \
|
||||||
HTMLPropertiesCollection.h \
|
HTMLPropertiesCollection.h \
|
||||||
nsGenericHTMLElement.h \
|
nsGenericHTMLElement.h \
|
||||||
nsHTMLIFrameElement.h \
|
|
||||||
nsClientRect.h \
|
nsClientRect.h \
|
||||||
nsHTMLDNSPrefetch.h \
|
nsHTMLDNSPrefetch.h \
|
||||||
nsTimeRanges.h \
|
nsTimeRanges.h \
|
||||||
@ -43,6 +42,7 @@ EXPORTS_mozilla/dom = \
|
|||||||
HTMLFrameSetElement.h \
|
HTMLFrameSetElement.h \
|
||||||
HTMLHeadingElement.h \
|
HTMLHeadingElement.h \
|
||||||
HTMLHRElement.h \
|
HTMLHRElement.h \
|
||||||
|
HTMLIFrameElement.h \
|
||||||
HTMLImageElement.h \
|
HTMLImageElement.h \
|
||||||
HTMLLabelElement.h \
|
HTMLLabelElement.h \
|
||||||
HTMLLegendElement.h \
|
HTMLLegendElement.h \
|
||||||
@ -103,7 +103,7 @@ CPPSRCS = \
|
|||||||
HTMLFrameSetElement.cpp \
|
HTMLFrameSetElement.cpp \
|
||||||
HTMLHRElement.cpp \
|
HTMLHRElement.cpp \
|
||||||
HTMLHeadingElement.cpp \
|
HTMLHeadingElement.cpp \
|
||||||
nsHTMLIFrameElement.cpp \
|
HTMLIFrameElement.cpp \
|
||||||
HTMLImageElement.cpp \
|
HTMLImageElement.cpp \
|
||||||
nsHTMLInputElement.cpp \
|
nsHTMLInputElement.cpp \
|
||||||
HTMLLIElement.cpp \
|
HTMLLIElement.cpp \
|
||||||
|
@ -78,7 +78,7 @@ addLoadEvent(function() {
|
|||||||
is(d.testAncestor, "ancestor",
|
is(d.testAncestor, "ancestor",
|
||||||
"test1" + ": Empty field should not override ancestor binding");
|
"test1" + ": Empty field should not override ancestor binding");
|
||||||
|
|
||||||
var win = XPCNativeWrapper.unwrap(window);
|
var win = window;
|
||||||
win.counter = 0;
|
win.counter = 0;
|
||||||
d.testEvalOnce;
|
d.testEvalOnce;
|
||||||
d.testEvalOnce;
|
d.testEvalOnce;
|
||||||
|
@ -135,6 +135,14 @@ AudioChannelService::UnregisterType(AudioChannelType aType,
|
|||||||
// In order to avoid race conditions, it's safer to notify any existing
|
// In order to avoid race conditions, it's safer to notify any existing
|
||||||
// agent any time a new one is registered.
|
// agent any time a new one is registered.
|
||||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||||
|
// We only remove ChildID when it is in the foreground.
|
||||||
|
// If in the background, we kept ChildID for allowing it to play next song.
|
||||||
|
if (aType == AUDIO_CHANNEL_CONTENT &&
|
||||||
|
mActiveContentChildIDs.Contains(aChildID) &&
|
||||||
|
(!aElementHidden &&
|
||||||
|
!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].Contains(aChildID))) {
|
||||||
|
mActiveContentChildIDs.RemoveElement(aChildID);
|
||||||
|
}
|
||||||
SendAudioChannelChangedNotification();
|
SendAudioChannelChangedNotification();
|
||||||
Notify();
|
Notify();
|
||||||
}
|
}
|
||||||
@ -175,23 +183,31 @@ AudioChannelService::GetMutedInternal(AudioChannelType aType, uint64_t aChildID,
|
|||||||
|
|
||||||
// If the audio content channel is visible, let's remember this ChildID.
|
// If the audio content channel is visible, let's remember this ChildID.
|
||||||
if (newType == AUDIO_CHANNEL_INT_CONTENT &&
|
if (newType == AUDIO_CHANNEL_INT_CONTENT &&
|
||||||
oldType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN &&
|
oldType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN) {
|
||||||
!mActiveContentChildIDs.Contains(aChildID)) {
|
|
||||||
|
|
||||||
if (mActiveContentChildIDsFrozen) {
|
if (mActiveContentChildIDsFrozen) {
|
||||||
mActiveContentChildIDsFrozen = false;
|
mActiveContentChildIDsFrozen = false;
|
||||||
mActiveContentChildIDs.Clear();
|
mActiveContentChildIDs.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mActiveContentChildIDs.AppendElement(aChildID);
|
if (!mActiveContentChildIDs.Contains(aChildID)) {
|
||||||
|
mActiveContentChildIDs.AppendElement(aChildID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If nothing is visible, the list has to been frozen.
|
|
||||||
else if (newType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN &&
|
else if (newType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN &&
|
||||||
oldType == AUDIO_CHANNEL_INT_CONTENT &&
|
oldType == AUDIO_CHANNEL_INT_CONTENT &&
|
||||||
!mActiveContentChildIDsFrozen &&
|
!mActiveContentChildIDsFrozen) {
|
||||||
mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty()) {
|
// If nothing is visible, the list has to been frozen.
|
||||||
mActiveContentChildIDsFrozen = true;
|
// Or if there is still any one with other ChildID in foreground then
|
||||||
|
// it should be removed from list and left other ChildIDs in the foreground
|
||||||
|
// to keep playing. Finally only last one childID which go to background
|
||||||
|
// will be in list.
|
||||||
|
if (mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty()) {
|
||||||
|
mActiveContentChildIDsFrozen = true;
|
||||||
|
} else if (!mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].Contains(aChildID)) {
|
||||||
|
mActiveContentChildIDs.RemoveElement(aChildID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newType != oldType && aType == AUDIO_CHANNEL_CONTENT) {
|
if (newType != oldType && aType == AUDIO_CHANNEL_CONTENT) {
|
||||||
@ -291,8 +307,12 @@ AudioChannelService::SendAudioChannelChangedNotification()
|
|||||||
higher = AUDIO_CHANNEL_NOTIFICATION;
|
higher = AUDIO_CHANNEL_NOTIFICATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content channels play in background if just one is active.
|
// There is only one Child can play content channel in the background.
|
||||||
else if (!mActiveContentChildIDs.IsEmpty()) {
|
// And need to check whether there is any content channels under playing
|
||||||
|
// now.
|
||||||
|
else if (!mActiveContentChildIDs.IsEmpty() &&
|
||||||
|
mChannelCounters[AUDIO_CHANNEL_INT_CONTENT_HIDDEN].Contains(
|
||||||
|
mActiveContentChildIDs[0])) {
|
||||||
higher = AUDIO_CHANNEL_CONTENT;
|
higher = AUDIO_CHANNEL_CONTENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifdef XP_WIN
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "TestHarness.h"
|
#include "TestHarness.h"
|
||||||
|
|
||||||
@ -19,19 +24,25 @@
|
|||||||
|
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
class Agent
|
class Agent : public nsIAudioChannelAgentCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
Agent(AudioChannelType aType)
|
Agent(AudioChannelType aType)
|
||||||
: mType(aType)
|
: mType(aType)
|
||||||
|
, mWaitCallback(false)
|
||||||
, mRegistered(false)
|
, mRegistered(false)
|
||||||
|
, mCanPlay(false)
|
||||||
{
|
{
|
||||||
mAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
|
mAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~Agent() {}
|
||||||
|
|
||||||
nsresult Init()
|
nsresult Init()
|
||||||
{
|
{
|
||||||
nsresult rv = mAgent->Init(mType, nullptr);
|
nsresult rv = mAgent->Init(mType, this);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return mAgent->SetVisibilityState(false);
|
return mAgent->SetVisibilityState(false);
|
||||||
@ -50,26 +61,74 @@ public:
|
|||||||
nsresult StopPlaying()
|
nsresult StopPlaying()
|
||||||
{
|
{
|
||||||
mRegistered = false;
|
mRegistered = false;
|
||||||
|
int loop = 0;
|
||||||
|
while (mWaitCallback) {
|
||||||
|
#ifdef XP_WIN
|
||||||
|
Sleep(1000);
|
||||||
|
#else
|
||||||
|
sleep(1);
|
||||||
|
#endif
|
||||||
|
if (loop++ == 5) {
|
||||||
|
TEST_ENSURE_BASE(false, "StopPlaying timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
return mAgent->StopPlaying();
|
return mAgent->StopPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult SetVisibilityState(bool visible)
|
||||||
|
{
|
||||||
|
if (mRegistered) {
|
||||||
|
mWaitCallback = true;
|
||||||
|
}
|
||||||
|
return mAgent->SetVisibilityState(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP CanPlayChanged(bool canPlay)
|
||||||
|
{
|
||||||
|
mCanPlay = canPlay;
|
||||||
|
mWaitCallback = false;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult GetCanPlay(bool *_ret)
|
||||||
|
{
|
||||||
|
int loop = 0;
|
||||||
|
while (mWaitCallback) {
|
||||||
|
#ifdef XP_WIN
|
||||||
|
Sleep(1000);
|
||||||
|
#else
|
||||||
|
sleep(1);
|
||||||
|
#endif
|
||||||
|
if (loop++ == 5) {
|
||||||
|
TEST_ENSURE_BASE(false, "GetCanPlay timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*_ret = mCanPlay;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<AudioChannelAgent> mAgent;
|
nsCOMPtr<AudioChannelAgent> mAgent;
|
||||||
AudioChannelType mType;
|
AudioChannelType mType;
|
||||||
|
bool mWaitCallback;
|
||||||
bool mRegistered;
|
bool mRegistered;
|
||||||
|
bool mCanPlay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(Agent, nsIAudioChannelAgentCallback)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
TestDoubleStartPlaying()
|
TestDoubleStartPlaying()
|
||||||
{
|
{
|
||||||
Agent agent(AUDIO_CHANNEL_NORMAL);
|
nsCOMPtr<Agent> agent = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||||
nsresult rv = agent.Init();
|
|
||||||
|
nsresult rv = agent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
bool playing;
|
bool playing;
|
||||||
rv = agent.mAgent->StartPlaying(&playing);
|
rv = agent->mAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = agent.mAgent->StartPlaying(&playing);
|
rv = agent->mAgent->StartPlaying(&playing);
|
||||||
TEST_ENSURE_BASE(NS_FAILED(rv), "Test0: StartPlaying calling twice should return error");
|
TEST_ENSURE_BASE(NS_FAILED(rv), "Test0: StartPlaying calling twice should return error");
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -78,19 +137,19 @@ TestDoubleStartPlaying()
|
|||||||
nsresult
|
nsresult
|
||||||
TestOneNormalChannel()
|
TestOneNormalChannel()
|
||||||
{
|
{
|
||||||
Agent agent(AUDIO_CHANNEL_NORMAL);
|
nsCOMPtr<Agent> agent = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||||
nsresult rv = agent.Init();
|
nsresult rv = agent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
bool playing;
|
bool playing;
|
||||||
rv = agent.StartPlaying(&playing);
|
rv = agent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test1: A normal channel unvisible agent must not be playing");
|
TEST_ENSURE_BASE(!playing, "Test1: A normal channel unvisible agent must not be playing");
|
||||||
|
|
||||||
rv = agent.mAgent->SetVisibilityState(true);
|
rv = agent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = agent.StartPlaying(&playing);
|
rv = agent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test1: A normal channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test1: A normal channel visible agent should be playing");
|
||||||
|
|
||||||
@ -100,34 +159,34 @@ TestOneNormalChannel()
|
|||||||
nsresult
|
nsresult
|
||||||
TestTwoNormalChannels()
|
TestTwoNormalChannels()
|
||||||
{
|
{
|
||||||
Agent agent1(AUDIO_CHANNEL_NORMAL);
|
nsCOMPtr<Agent> agent1 = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||||
nsresult rv = agent1.Init();
|
nsresult rv = agent1->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent agent2(AUDIO_CHANNEL_NORMAL);
|
nsCOMPtr<Agent> agent2 = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||||
rv = agent2.Init();
|
rv = agent2->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
bool playing;
|
bool playing;
|
||||||
rv = agent1.StartPlaying(&playing);
|
rv = agent1->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test2: A normal channel unvisible agent1 must not be playing");
|
TEST_ENSURE_BASE(!playing, "Test2: A normal channel unvisible agent1 must not be playing");
|
||||||
|
|
||||||
rv = agent2.StartPlaying(&playing);
|
rv = agent2->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test2: A normal channel unvisible agent2 must not be playing");
|
TEST_ENSURE_BASE(!playing, "Test2: A normal channel unvisible agent2 must not be playing");
|
||||||
|
|
||||||
rv = agent1.mAgent->SetVisibilityState(true);
|
rv = agent1->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = agent2.mAgent->SetVisibilityState(true);
|
rv = agent2->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = agent1.StartPlaying(&playing);
|
rv = agent1->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test2: A normal channel visible agent1 should be playing");
|
TEST_ENSURE_BASE(playing, "Test2: A normal channel visible agent1 should be playing");
|
||||||
|
|
||||||
rv = agent2.StartPlaying(&playing);
|
rv = agent2->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test2: A normal channel visible agent2 should be playing");
|
TEST_ENSURE_BASE(playing, "Test2: A normal channel visible agent2 should be playing");
|
||||||
|
|
||||||
@ -137,213 +196,230 @@ TestTwoNormalChannels()
|
|||||||
nsresult
|
nsresult
|
||||||
TestContentChannels()
|
TestContentChannels()
|
||||||
{
|
{
|
||||||
Agent agent1(AUDIO_CHANNEL_CONTENT);
|
nsCOMPtr<Agent> agent1 = new Agent(AUDIO_CHANNEL_CONTENT);
|
||||||
nsresult rv = agent1.Init();
|
nsresult rv = agent1->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent agent2(AUDIO_CHANNEL_CONTENT);
|
nsCOMPtr<Agent> agent2 = new Agent(AUDIO_CHANNEL_CONTENT);
|
||||||
rv = agent2.Init();
|
rv = agent2->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = agent1.mAgent->SetVisibilityState(true);
|
/* All content channels in the foreground can be allowed to play */
|
||||||
|
rv = agent1->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = agent2.mAgent->SetVisibilityState(true);
|
rv = agent2->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
bool playing;
|
bool playing;
|
||||||
rv = agent1.StartPlaying(&playing);
|
rv = agent1->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
TEST_ENSURE_BASE(playing, "Test3: A content channel unvisible agent1 should be playing");
|
|
||||||
|
|
||||||
rv = agent2.StartPlaying(&playing);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
TEST_ENSURE_BASE(playing, "Test3: A content channel unvisible agent2 should be playing");
|
|
||||||
|
|
||||||
rv = agent1.mAgent->SetVisibilityState(true);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = agent2.mAgent->SetVisibilityState(false);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = agent1.StartPlaying(&playing);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent1 should be playing");
|
TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent1 should be playing");
|
||||||
|
|
||||||
rv = agent2.StartPlaying(&playing);
|
rv = agent2->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
TEST_ENSURE_BASE(playing, "Test3: A content channel unvisible agent2 should be playing");
|
|
||||||
|
|
||||||
rv = agent1.mAgent->SetVisibilityState(true);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = agent2.mAgent->SetVisibilityState(true);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = agent1.StartPlaying(&playing);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent1 should be playing");
|
|
||||||
|
|
||||||
rv = agent2.StartPlaying(&playing);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent2 should be playing");
|
TEST_ENSURE_BASE(playing, "Test3: A content channel visible agent2 should be playing");
|
||||||
|
|
||||||
|
/* Test the transition state of one content channel tried to set non-visible
|
||||||
|
* state first when app is going to background. */
|
||||||
|
rv = agent1->SetVisibilityState(false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = agent1->GetCanPlay(&playing);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
TEST_ENSURE_BASE(playing, "Test3: A content channel unvisible agent1 should be playing from foreground to background");
|
||||||
|
|
||||||
|
/* Test all content channels set non-visible already */
|
||||||
|
rv = agent2->SetVisibilityState(false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = agent2->GetCanPlay(&playing);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
TEST_ENSURE_BASE(playing, "Test3: A content channel unvisible agent2 should be playing from foreground to background");
|
||||||
|
|
||||||
|
/* Clear the content channels & mActiveContentChildIDs in AudioChannelService.
|
||||||
|
* If agent stop playing in the background, we will reserve it's childID in
|
||||||
|
* mActiveContentChildIDs, then it can allow to play next song. So we set agents
|
||||||
|
* to foreground first then stopping to play */
|
||||||
|
rv = agent1->SetVisibilityState(true);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = agent2->SetVisibilityState(true);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = agent1->StopPlaying();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = agent2->StopPlaying();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
/* Test that content channels can't be allow to play when they starts from the background state */
|
||||||
|
rv = agent1->SetVisibilityState(false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
rv = agent2->SetVisibilityState(false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = agent1->StartPlaying(&playing);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
TEST_ENSURE_BASE(!playing, "Test3: A content channel unvisible agent1 must not be playing from background state");
|
||||||
|
|
||||||
|
rv = agent2->StartPlaying(&playing);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
TEST_ENSURE_BASE(!playing, "Test3: A content channel unvisible agent2 must not be playing from background state");
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
TestPriorities()
|
TestPriorities()
|
||||||
{
|
{
|
||||||
Agent normalAgent(AUDIO_CHANNEL_NORMAL);
|
nsCOMPtr<Agent> normalAgent = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||||
nsresult rv = normalAgent.Init();
|
nsresult rv = normalAgent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent contentAgent(AUDIO_CHANNEL_CONTENT);
|
nsCOMPtr<Agent> contentAgent = new Agent(AUDIO_CHANNEL_CONTENT);
|
||||||
rv = contentAgent.Init();
|
rv = contentAgent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent notificationAgent(AUDIO_CHANNEL_NOTIFICATION);
|
nsCOMPtr<Agent> notificationAgent = new Agent(AUDIO_CHANNEL_NOTIFICATION);
|
||||||
rv = notificationAgent.Init();
|
rv = notificationAgent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent alarmAgent(AUDIO_CHANNEL_ALARM);
|
nsCOMPtr<Agent> alarmAgent = new Agent(AUDIO_CHANNEL_ALARM);
|
||||||
rv = alarmAgent.Init();
|
rv = alarmAgent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent telephonyAgent(AUDIO_CHANNEL_TELEPHONY);
|
nsCOMPtr<Agent> telephonyAgent = new Agent(AUDIO_CHANNEL_TELEPHONY);
|
||||||
rv = telephonyAgent.Init();
|
rv = telephonyAgent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent ringerAgent(AUDIO_CHANNEL_RINGER);
|
nsCOMPtr<Agent> ringerAgent = new Agent(AUDIO_CHANNEL_RINGER);
|
||||||
rv = ringerAgent.Init();
|
rv = ringerAgent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
Agent pNotificationAgent(AUDIO_CHANNEL_PUBLICNOTIFICATION);
|
nsCOMPtr<Agent> pNotificationAgent = new Agent(AUDIO_CHANNEL_PUBLICNOTIFICATION);
|
||||||
rv = pNotificationAgent.Init();
|
rv = pNotificationAgent->Init();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
bool playing;
|
bool playing;
|
||||||
|
|
||||||
// Normal should not be playing because not visible.
|
// Normal should not be playing because not visible.
|
||||||
rv = normalAgent.StartPlaying(&playing);
|
rv = normalAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test4: A normal channel unvisible agent should not be playing");
|
TEST_ENSURE_BASE(!playing, "Test4: A normal channel unvisible agent must not be playing");
|
||||||
|
|
||||||
// Content should be playing.
|
// Content should be playing.
|
||||||
rv = contentAgent.StartPlaying(&playing);
|
rv = contentAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A content channel unvisible agent should be playing");
|
TEST_ENSURE_BASE(!playing, "Test4: A content channel unvisible agent must not be playing from background state");
|
||||||
|
|
||||||
// Notification should be playing.
|
// Notification should be playing.
|
||||||
rv = notificationAgent.StartPlaying(&playing);
|
rv = notificationAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: An notification channel unvisible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: An notification channel unvisible agent should be playing");
|
||||||
|
|
||||||
// Now content should be not playing because of the notification playing.
|
// Now content should be not playing because of the notification playing.
|
||||||
rv = contentAgent.StartPlaying(&playing);
|
rv = contentAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test4: A content channel unvisible agent should not be playing when notification channel is playing");
|
TEST_ENSURE_BASE(!playing, "Test4: A content channel unvisible agent should not be playing when notification channel is playing");
|
||||||
|
|
||||||
// Adding an alarm.
|
// Adding an alarm.
|
||||||
rv = alarmAgent.StartPlaying(&playing);
|
rv = alarmAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: An alarm channel unvisible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: An alarm channel unvisible agent should be playing");
|
||||||
|
|
||||||
// Now notification should be not playing because of the alarm playing.
|
// Now notification should be not playing because of the alarm playing.
|
||||||
rv = notificationAgent.StartPlaying(&playing);
|
rv = notificationAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test4: A notification channel unvisible agent should not be playing when an alarm is playing");
|
TEST_ENSURE_BASE(!playing, "Test4: A notification channel unvisible agent should not be playing when an alarm is playing");
|
||||||
|
|
||||||
// Adding an telephony.
|
// Adding an telephony.
|
||||||
rv = telephonyAgent.StartPlaying(&playing);
|
rv = telephonyAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: An telephony channel unvisible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: An telephony channel unvisible agent should be playing");
|
||||||
|
|
||||||
// Now alarm should be not playing because of the telephony playing.
|
// Now alarm should be not playing because of the telephony playing.
|
||||||
rv = alarmAgent.StartPlaying(&playing);
|
rv = alarmAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test4: A alarm channel unvisible agent should not be playing when a telephony is playing");
|
TEST_ENSURE_BASE(!playing, "Test4: A alarm channel unvisible agent should not be playing when a telephony is playing");
|
||||||
|
|
||||||
// Adding an ringer.
|
// Adding an ringer.
|
||||||
rv = ringerAgent.StartPlaying(&playing);
|
rv = ringerAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: An ringer channel unvisible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: An ringer channel unvisible agent should be playing");
|
||||||
|
|
||||||
// Now telephony should be not playing because of the ringer playing.
|
// Now telephony should be not playing because of the ringer playing.
|
||||||
rv = telephonyAgent.StartPlaying(&playing);
|
rv = telephonyAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test4: A telephony channel unvisible agent should not be playing when a riger is playing");
|
TEST_ENSURE_BASE(!playing, "Test4: A telephony channel unvisible agent should not be playing when a riger is playing");
|
||||||
|
|
||||||
// Adding an pNotification.
|
// Adding an pNotification.
|
||||||
rv = pNotificationAgent.StartPlaying(&playing);
|
rv = pNotificationAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: An pNotification channel unvisible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: An pNotification channel unvisible agent should be playing");
|
||||||
|
|
||||||
// Now ringer should be not playing because of the public notification playing.
|
// Now ringer should be not playing because of the public notification playing.
|
||||||
rv = ringerAgent.StartPlaying(&playing);
|
rv = ringerAgent->StartPlaying(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(!playing, "Test4: A ringer channel unvisible agent should not be playing when a public notification is playing");
|
TEST_ENSURE_BASE(!playing, "Test4: A ringer channel unvisible agent should not be playing when a public notification is playing");
|
||||||
|
|
||||||
// Settings visible the normal channel.
|
// Settings visible the normal channel.
|
||||||
rv = normalAgent.mAgent->SetVisibilityState(true);
|
rv = normalAgent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// Normal should be playing because visible.
|
// Normal should be playing because visible.
|
||||||
rv = normalAgent.StartPlaying(&playing);
|
rv = normalAgent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A normal channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: A normal channel visible agent should be playing");
|
||||||
|
|
||||||
// Settings visible the content channel.
|
// Settings visible the content channel.
|
||||||
rv = contentAgent.mAgent->SetVisibilityState(true);
|
rv = contentAgent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// Content should be playing because visible.
|
// Content should be playing because visible.
|
||||||
rv = contentAgent.StartPlaying(&playing);
|
rv = contentAgent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A content channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: A content channel visible agent should be playing");
|
||||||
|
|
||||||
// Settings visible the notification channel.
|
// Settings visible the notification channel.
|
||||||
rv = notificationAgent.mAgent->SetVisibilityState(true);
|
rv = notificationAgent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// Notification should be playing because visible.
|
// Notification should be playing because visible.
|
||||||
rv = notificationAgent.StartPlaying(&playing);
|
rv = notificationAgent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A notification channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: A notification channel visible agent should be playing");
|
||||||
|
|
||||||
// Settings visible the alarm channel.
|
// Settings visible the alarm channel.
|
||||||
rv = alarmAgent.mAgent->SetVisibilityState(true);
|
rv = alarmAgent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// Alarm should be playing because visible.
|
// Alarm should be playing because visible.
|
||||||
rv = alarmAgent.StartPlaying(&playing);
|
rv = alarmAgent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A alarm channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: A alarm channel visible agent should be playing");
|
||||||
|
|
||||||
// Settings visible the telephony channel.
|
// Settings visible the telephony channel.
|
||||||
rv = telephonyAgent.mAgent->SetVisibilityState(true);
|
rv = telephonyAgent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// Telephony should be playing because visible.
|
// Telephony should be playing because visible.
|
||||||
rv = telephonyAgent.StartPlaying(&playing);
|
rv = telephonyAgent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A telephony channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: A telephony channel visible agent should be playing");
|
||||||
|
|
||||||
// Settings visible the ringer channel.
|
// Settings visible the ringer channel.
|
||||||
rv = ringerAgent.mAgent->SetVisibilityState(true);
|
rv = ringerAgent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// Ringer should be playing because visible.
|
// Ringer should be playing because visible.
|
||||||
rv = ringerAgent.StartPlaying(&playing);
|
rv = ringerAgent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A ringer channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: A ringer channel visible agent should be playing");
|
||||||
|
|
||||||
// Settings visible the pNotification channel.
|
// Settings visible the pNotification channel.
|
||||||
rv = pNotificationAgent.mAgent->SetVisibilityState(true);
|
rv = pNotificationAgent->SetVisibilityState(true);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// pNotification should be playing because visible.
|
// pNotification should be playing because visible.
|
||||||
rv = pNotificationAgent.StartPlaying(&playing);
|
rv = pNotificationAgent->GetCanPlay(&playing);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
TEST_ENSURE_BASE(playing, "Test4: A pNotification channel visible agent should be playing");
|
TEST_ENSURE_BASE(playing, "Test4: A pNotification channel visible agent should be playing");
|
||||||
|
|
||||||
|
3
dom/base/crashtests/844559.html
Normal file
3
dom/base/crashtests/844559.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<script>
|
||||||
|
Components.lookupMethod(Image, "x")
|
||||||
|
</script>
|
@ -39,3 +39,4 @@ load 697643.html
|
|||||||
load 706283-1.html
|
load 706283-1.html
|
||||||
load 708405-1.html
|
load 708405-1.html
|
||||||
load 745495.html
|
load 745495.html
|
||||||
|
load 844559.html
|
||||||
|
@ -5,46 +5,53 @@
|
|||||||
import os
|
import os
|
||||||
import cPickle
|
import cPickle
|
||||||
from Configuration import Configuration
|
from Configuration import Configuration
|
||||||
from Codegen import CGBindingRoot, replaceFileIfChanged
|
from Codegen import CGBindingRoot
|
||||||
|
|
||||||
def generate_binding_header(config, outputprefix, webidlfile):
|
def generate_binding_header(config, outputprefix, srcprefix, webidlfile):
|
||||||
"""
|
"""
|
||||||
|config| Is the configuration object.
|
|config| Is the configuration object.
|
||||||
|outputprefix| is a prefix to use for the header guards and filename.
|
|outputprefix| is a prefix to use for the header guards and filename.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
filename = outputprefix + ".h"
|
filename = outputprefix + ".h"
|
||||||
|
depsname = ".deps/" + filename + ".pp"
|
||||||
root = CGBindingRoot(config, outputprefix, webidlfile)
|
root = CGBindingRoot(config, outputprefix, webidlfile)
|
||||||
if replaceFileIfChanged(filename, root.declare()):
|
with open(filename, 'wb') as f:
|
||||||
print "Generating binding header: %s" % (filename)
|
f.write(root.declare())
|
||||||
|
with open(depsname, 'wb') as f:
|
||||||
|
f.write("\n".join(filename + ": " + os.path.join(srcprefix, x) for x in root.deps()))
|
||||||
|
|
||||||
def generate_binding_cpp(config, outputprefix, webidlfile):
|
def generate_binding_cpp(config, outputprefix, srcprefix, webidlfile):
|
||||||
"""
|
"""
|
||||||
|config| Is the configuration object.
|
|config| Is the configuration object.
|
||||||
|outputprefix| is a prefix to use for the header guards and filename.
|
|outputprefix| is a prefix to use for the header guards and filename.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
filename = outputprefix + ".cpp"
|
filename = outputprefix + ".cpp"
|
||||||
|
depsname = ".deps/" + filename + ".pp"
|
||||||
root = CGBindingRoot(config, outputprefix, webidlfile)
|
root = CGBindingRoot(config, outputprefix, webidlfile)
|
||||||
if replaceFileIfChanged(filename, root.define()):
|
with open(filename, 'wb') as f:
|
||||||
print "Generating binding implementation: %s" % (filename)
|
f.write(root.define())
|
||||||
|
with open(depsname, 'wb') as f:
|
||||||
|
f.write("\n".join(filename + ": " + os.path.join(srcprefix, x) for x in root.deps()))
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
# Parse arguments.
|
# Parse arguments.
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
usagestring = "usage: %prog [header|cpp] configFile outputPrefix webIDLFile"
|
usagestring = "usage: %prog [header|cpp] configFile outputPrefix srcPrefix webIDLFile"
|
||||||
o = OptionParser(usage=usagestring)
|
o = OptionParser(usage=usagestring)
|
||||||
o.add_option("--verbose-errors", action='store_true', default=False,
|
o.add_option("--verbose-errors", action='store_true', default=False,
|
||||||
help="When an error happens, display the Python traceback.")
|
help="When an error happens, display the Python traceback.")
|
||||||
(options, args) = o.parse_args()
|
(options, args) = o.parse_args()
|
||||||
|
|
||||||
if len(args) != 4 or (args[0] != "header" and args[0] != "cpp"):
|
if len(args) != 5 or (args[0] != "header" and args[0] != "cpp"):
|
||||||
o.error(usagestring)
|
o.error(usagestring)
|
||||||
buildTarget = args[0]
|
buildTarget = args[0]
|
||||||
configFile = os.path.normpath(args[1])
|
configFile = os.path.normpath(args[1])
|
||||||
outputPrefix = args[2]
|
outputPrefix = args[2]
|
||||||
webIDLFile = os.path.normpath(args[3])
|
srcPrefix = os.path.normpath(args[3])
|
||||||
|
webIDLFile = os.path.normpath(args[4])
|
||||||
|
|
||||||
# Load the parsing results
|
# Load the parsing results
|
||||||
f = open('ParserResults.pkl', 'rb')
|
f = open('ParserResults.pkl', 'rb')
|
||||||
@ -56,9 +63,9 @@ def main():
|
|||||||
|
|
||||||
# Generate the prototype classes.
|
# Generate the prototype classes.
|
||||||
if buildTarget == "header":
|
if buildTarget == "header":
|
||||||
generate_binding_header(config, outputPrefix, webIDLFile);
|
generate_binding_header(config, outputPrefix, srcPrefix, webIDLFile);
|
||||||
elif buildTarget == "cpp":
|
elif buildTarget == "cpp":
|
||||||
generate_binding_cpp(config, outputPrefix, webIDLFile);
|
generate_binding_cpp(config, outputPrefix, srcPrefix, webIDLFile);
|
||||||
else:
|
else:
|
||||||
assert False # not reached
|
assert False # not reached
|
||||||
|
|
||||||
|
@ -59,6 +59,9 @@ class CGThing():
|
|||||||
def define(self):
|
def define(self):
|
||||||
"""Produce code for a cpp file."""
|
"""Produce code for a cpp file."""
|
||||||
assert(False) # Override me!
|
assert(False) # Override me!
|
||||||
|
def deps(self):
|
||||||
|
"""Produce the deps for a pp file"""
|
||||||
|
assert(False) # Override me!
|
||||||
|
|
||||||
class CGNativePropertyHooks(CGThing):
|
class CGNativePropertyHooks(CGThing):
|
||||||
"""
|
"""
|
||||||
@ -309,6 +312,13 @@ class CGList(CGThing):
|
|||||||
return self.join(child.declare() for child in self.children if child is not None)
|
return self.join(child.declare() for child in self.children if child is not None)
|
||||||
def define(self):
|
def define(self):
|
||||||
return self.join(child.define() for child in self.children if child is not None)
|
return self.join(child.define() for child in self.children if child is not None)
|
||||||
|
def deps(self):
|
||||||
|
deps = set()
|
||||||
|
for child in self.children:
|
||||||
|
if child is None:
|
||||||
|
continue
|
||||||
|
deps = deps.union(child.deps())
|
||||||
|
return deps
|
||||||
|
|
||||||
class CGGeneric(CGThing):
|
class CGGeneric(CGThing):
|
||||||
"""
|
"""
|
||||||
@ -322,6 +332,8 @@ class CGGeneric(CGThing):
|
|||||||
return self.declareText
|
return self.declareText
|
||||||
def define(self):
|
def define(self):
|
||||||
return self.defineText
|
return self.defineText
|
||||||
|
def deps(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
# We'll want to insert the indent at the beginnings of lines, but we
|
# We'll want to insert the indent at the beginnings of lines, but we
|
||||||
# don't want to indent empty lines. So only indent lines that have a
|
# don't want to indent empty lines. So only indent lines that have a
|
||||||
@ -387,6 +399,9 @@ class CGWrapper(CGThing):
|
|||||||
defn.replace("\n", "\n" + (" " * len(self.definePre))))
|
defn.replace("\n", "\n" + (" " * len(self.definePre))))
|
||||||
return self.definePre + defn + self.definePost
|
return self.definePre + defn + self.definePost
|
||||||
|
|
||||||
|
def deps(self):
|
||||||
|
return self.child.deps()
|
||||||
|
|
||||||
class CGIfWrapper(CGWrapper):
|
class CGIfWrapper(CGWrapper):
|
||||||
def __init__(self, child, condition):
|
def __init__(self, child, condition):
|
||||||
pre = CGWrapper(CGGeneric(condition), pre="if (", post=") {\n",
|
pre = CGWrapper(CGGeneric(condition), pre="if (", post=") {\n",
|
||||||
@ -985,14 +1000,30 @@ class CGNamedConstructors(CGThing):
|
|||||||
def define(self):
|
def define(self):
|
||||||
if len(self.descriptor.interface.namedConstructors) == 0:
|
if len(self.descriptor.interface.namedConstructors) == 0:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
constructorID = "constructors::id::"
|
||||||
|
if self.descriptor.interface.hasInterfaceObject():
|
||||||
|
constructorID += self.descriptor.name
|
||||||
|
else:
|
||||||
|
constructorID += "_ID_Count"
|
||||||
|
nativePropertyHooks = """const NativePropertyHooks sNamedConstructorNativePropertyHooks = {
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
{ nullptr, nullptr },
|
||||||
|
prototypes::id::%s,
|
||||||
|
%s,
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
""" % (self.descriptor.name, constructorID)
|
||||||
namedConstructors = CGList([], ",\n")
|
namedConstructors = CGList([], ",\n")
|
||||||
for n in self.descriptor.interface.namedConstructors:
|
for n in self.descriptor.interface.namedConstructors:
|
||||||
namedConstructors.append(CGGeneric("{ \"%s\", { %s, nullptr }, %i }" % (n.identifier.name, NamedConstructorName(n), methodLength(n))))
|
namedConstructors.append(CGGeneric("{ \"%s\", { %s, &sNamedConstructorNativePropertyHooks }, %i }" % (n.identifier.name, NamedConstructorName(n), methodLength(n))))
|
||||||
namedConstructors.append(CGGeneric("{ nullptr, { nullptr, nullptr }, 0 }"))
|
namedConstructors.append(CGGeneric("{ nullptr, { nullptr, nullptr }, 0 }"))
|
||||||
namedConstructors = CGWrapper(CGIndenter(namedConstructors),
|
namedConstructors = CGWrapper(CGIndenter(namedConstructors),
|
||||||
pre="static const NamedConstructor namedConstructors[] = {\n",
|
pre="static const NamedConstructor namedConstructors[] = {\n",
|
||||||
post="\n};\n")
|
post="\n};\n")
|
||||||
return namedConstructors.define()
|
return nativePropertyHooks + namedConstructors.define()
|
||||||
|
|
||||||
class CGClassHasInstanceHook(CGAbstractStaticMethod):
|
class CGClassHasInstanceHook(CGAbstractStaticMethod):
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
@ -4853,6 +4884,9 @@ class CGEnum(CGThing):
|
|||||||
""" % (len(self.enum.values()) + 1,
|
""" % (len(self.enum.values()) + 1,
|
||||||
",\n ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
|
",\n ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
|
||||||
|
|
||||||
|
def deps(self):
|
||||||
|
return self.enum.getDeps()
|
||||||
|
|
||||||
def getUnionAccessorSignatureType(type, descriptorProvider):
|
def getUnionAccessorSignatureType(type, descriptorProvider):
|
||||||
"""
|
"""
|
||||||
Returns the types that are used in the getter and setter signatures for
|
Returns the types that are used in the getter and setter signatures for
|
||||||
@ -5743,6 +5777,8 @@ class CGPrototypeTraitsClass(CGClass):
|
|||||||
templateArgs=templateArgs,
|
templateArgs=templateArgs,
|
||||||
templateSpecialization=templateSpecialization,
|
templateSpecialization=templateSpecialization,
|
||||||
enums=enums, typedefs=typedefs, isStruct=True)
|
enums=enums, typedefs=typedefs, isStruct=True)
|
||||||
|
def deps(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
class CGPrototypeIDMapClass(CGClass):
|
class CGPrototypeIDMapClass(CGClass):
|
||||||
def __init__(self, descriptor, indent=''):
|
def __init__(self, descriptor, indent=''):
|
||||||
@ -5754,6 +5790,8 @@ class CGPrototypeIDMapClass(CGClass):
|
|||||||
templateArgs=templateArgs,
|
templateArgs=templateArgs,
|
||||||
templateSpecialization=templateSpecialization,
|
templateSpecialization=templateSpecialization,
|
||||||
enums=enums, isStruct=True)
|
enums=enums, isStruct=True)
|
||||||
|
def deps(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
class CGClassForwardDeclare(CGThing):
|
class CGClassForwardDeclare(CGThing):
|
||||||
def __init__(self, name, isStruct=False):
|
def __init__(self, name, isStruct=False):
|
||||||
@ -5766,6 +5804,8 @@ class CGClassForwardDeclare(CGThing):
|
|||||||
def define(self):
|
def define(self):
|
||||||
# Header only
|
# Header only
|
||||||
return ''
|
return ''
|
||||||
|
def deps(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
class CGProxySpecialOperation(CGPerSignatureCall):
|
class CGProxySpecialOperation(CGPerSignatureCall):
|
||||||
"""
|
"""
|
||||||
@ -6442,6 +6482,8 @@ class CGDescriptor(CGThing):
|
|||||||
|
|
||||||
assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
|
assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
|
||||||
|
|
||||||
|
self._deps = descriptor.interface.getDeps()
|
||||||
|
|
||||||
cgThings = []
|
cgThings = []
|
||||||
# These are set to true if at least one non-static
|
# These are set to true if at least one non-static
|
||||||
# method/getter/setter exist on the interface.
|
# method/getter/setter exist on the interface.
|
||||||
@ -6578,6 +6620,8 @@ class CGDescriptor(CGThing):
|
|||||||
return self.cgRoot.declare()
|
return self.cgRoot.declare()
|
||||||
def define(self):
|
def define(self):
|
||||||
return self.cgRoot.define()
|
return self.cgRoot.define()
|
||||||
|
def deps(self):
|
||||||
|
return self._deps
|
||||||
|
|
||||||
class CGNamespacedEnum(CGThing):
|
class CGNamespacedEnum(CGThing):
|
||||||
def __init__(self, namespace, enumName, names, values, comment=""):
|
def __init__(self, namespace, enumName, names, values, comment=""):
|
||||||
@ -6782,6 +6826,9 @@ class CGDictionary(CGThing):
|
|||||||
"defineMembers": "\n\n".join(memberDefines)
|
"defineMembers": "\n\n".join(memberDefines)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def deps(self):
|
||||||
|
return self.dictionary.getDeps()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def makeDictionaryName(dictionary, workers):
|
def makeDictionaryName(dictionary, workers):
|
||||||
suffix = "Workers" if workers else ""
|
suffix = "Workers" if workers else ""
|
||||||
@ -7203,6 +7250,9 @@ class CGBindingRoot(CGThing):
|
|||||||
def define(self):
|
def define(self):
|
||||||
return stripTrailingWhitespace(self.root.define())
|
return stripTrailingWhitespace(self.root.define())
|
||||||
|
|
||||||
|
def deps(self):
|
||||||
|
return self.root.deps()
|
||||||
|
|
||||||
class CGNativeMember(ClassMethod):
|
class CGNativeMember(ClassMethod):
|
||||||
def __init__(self, descriptor, member, name, signature, extendedAttrs,
|
def __init__(self, descriptor, member, name, signature, extendedAttrs,
|
||||||
breakAfter=True, passCxAsNeeded=True, visibility="public",
|
breakAfter=True, passCxAsNeeded=True, visibility="public",
|
||||||
@ -7778,6 +7828,7 @@ class CGCallback(CGClass):
|
|||||||
def __init__(self, idlObject, descriptorProvider, baseName, methods,
|
def __init__(self, idlObject, descriptorProvider, baseName, methods,
|
||||||
getters=[], setters=[]):
|
getters=[], setters=[]):
|
||||||
self.baseName = baseName
|
self.baseName = baseName
|
||||||
|
self._deps = idlObject.getDeps()
|
||||||
name = idlObject.identifier.name
|
name = idlObject.identifier.name
|
||||||
if descriptorProvider.workers:
|
if descriptorProvider.workers:
|
||||||
name += "Workers"
|
name += "Workers"
|
||||||
@ -7867,6 +7918,9 @@ class CGCallback(CGClass):
|
|||||||
body=bodyWithoutThis),
|
body=bodyWithoutThis),
|
||||||
method]
|
method]
|
||||||
|
|
||||||
|
def deps(self):
|
||||||
|
return self._deps
|
||||||
|
|
||||||
class CGCallbackFunction(CGCallback):
|
class CGCallbackFunction(CGCallback):
|
||||||
def __init__(self, callback, descriptorProvider):
|
def __init__(self, callback, descriptorProvider):
|
||||||
CGCallback.__init__(self, callback, descriptorProvider,
|
CGCallback.__init__(self, callback, descriptorProvider,
|
||||||
|
@ -65,12 +65,14 @@ class Configuration:
|
|||||||
# Figure out what our main-thread and worker dictionaries and callbacks
|
# Figure out what our main-thread and worker dictionaries and callbacks
|
||||||
# are.
|
# are.
|
||||||
mainTypes = set()
|
mainTypes = set()
|
||||||
for descriptor in self.getDescriptors(workers=False, isExternal=False):
|
for descriptor in ([self.getDescriptor("DummyInterface", workers=False)] +
|
||||||
|
self.getDescriptors(workers=False, isExternal=False, skipGen=False)):
|
||||||
mainTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
|
mainTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
|
||||||
(mainCallbacks, mainDictionaries) = findCallbacksAndDictionaries(mainTypes)
|
(mainCallbacks, mainDictionaries) = findCallbacksAndDictionaries(mainTypes)
|
||||||
|
|
||||||
workerTypes = set();
|
workerTypes = set();
|
||||||
for descriptor in self.getDescriptors(workers=True, isExternal=False):
|
for descriptor in ([self.getDescriptor("DummyInterfaceWorkers", workers=True)] +
|
||||||
|
self.getDescriptors(workers=True, isExternal=False, skipGen=False)):
|
||||||
workerTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
|
workerTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
|
||||||
(workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
|
(workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
|
||||||
|
|
||||||
|
@ -75,7 +75,6 @@ EXPORTS_$(binding_include_path) = \
|
|||||||
TypedArray.h \
|
TypedArray.h \
|
||||||
UnionConversions.h \
|
UnionConversions.h \
|
||||||
UnionTypes.h \
|
UnionTypes.h \
|
||||||
$(exported_binding_headers) \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
|
LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
|
||||||
@ -97,8 +96,34 @@ LOCAL_INCLUDES += \
|
|||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# XXXkhuey this is a terrible hack to avoid blowing out the command line
|
||||||
|
ifneq (,$(filter-out all chrome default export realchrome tools clean clobber clobber_all distclean realclean,$(MAKECMDGOALS)))
|
||||||
|
$(shell echo "$(addsuffix .pp,$(binding_header_files))" > pp.list)
|
||||||
|
$(shell echo "$(addsuffix .pp,$(binding_cpp_files))" >> pp.list)
|
||||||
|
|
||||||
|
# The script mddepend.pl checks the dependencies and writes to stdout
|
||||||
|
# one rule to force out-of-date objects. For example,
|
||||||
|
# foo.o boo.o: FORCE
|
||||||
|
# The script has an advantage over including the *.pp files directly
|
||||||
|
# because it handles the case when header files are removed from the build.
|
||||||
|
# 'make' would complain that there is no way to build missing headers.
|
||||||
|
ALL_PP_RESULTS = $(shell cat pp.list | $(PERL) $(BUILD_TOOLS)/mddepend.pl)
|
||||||
|
$(eval $(ALL_PP_RESULTS))
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
EXPORTS_GENERATED_FILES := $(exported_binding_headers)
|
||||||
|
EXPORTS_GENERATED_DEST := $(DIST)/include/$(binding_include_path)
|
||||||
|
EXPORTS_GENERATED_TARGET := webidl-export
|
||||||
|
INSTALL_TARGETS += EXPORTS_GENERATED
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
# We need to create a separate target so we can ensure that the pickle is
|
||||||
|
# done before generating headers.
|
||||||
|
export:: ParserResults.pkl
|
||||||
|
$(MAKE) webidl-export
|
||||||
|
|
||||||
# If you change bindinggen_dependencies here, change it in
|
# If you change bindinggen_dependencies here, change it in
|
||||||
# dom/bindings/test/Makefile.in too.
|
# dom/bindings/test/Makefile.in too.
|
||||||
bindinggen_dependencies := \
|
bindinggen_dependencies := \
|
||||||
@ -107,7 +132,6 @@ bindinggen_dependencies := \
|
|||||||
Configuration.py \
|
Configuration.py \
|
||||||
Codegen.py \
|
Codegen.py \
|
||||||
parser/WebIDL.py \
|
parser/WebIDL.py \
|
||||||
ParserResults.pkl \
|
|
||||||
$(GLOBAL_DEPS) \
|
$(GLOBAL_DEPS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
@ -129,20 +153,26 @@ $(test_webidl_files): %: $(srcdir)/test/%
|
|||||||
|
|
||||||
$(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
|
$(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
|
||||||
%.webidl \
|
%.webidl \
|
||||||
|
$(call mkdir_deps,$(MDDEPDIR)) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||||
$(PLY_INCLUDE) -I$(srcdir)/parser \
|
$(PLY_INCLUDE) -I$(srcdir)/parser \
|
||||||
$(srcdir)/BindingGen.py header \
|
$(srcdir)/BindingGen.py header \
|
||||||
$(srcdir)/Bindings.conf $*Binding \
|
$(srcdir)/Bindings.conf \
|
||||||
|
$*Binding \
|
||||||
|
$(topsrcdir)/dom/webidl/ \
|
||||||
$*.webidl
|
$*.webidl
|
||||||
|
|
||||||
$(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
|
$(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
|
||||||
%.webidl \
|
%.webidl \
|
||||||
|
$(call mkdir_deps,$(MDDEPDIR)) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||||
$(PLY_INCLUDE) -I$(srcdir)/parser \
|
$(PLY_INCLUDE) -I$(srcdir)/parser \
|
||||||
$(srcdir)/BindingGen.py cpp \
|
$(srcdir)/BindingGen.py cpp \
|
||||||
$(srcdir)/Bindings.conf $*Binding \
|
$(srcdir)/Bindings.conf \
|
||||||
|
$*Binding \
|
||||||
|
$(topsrcdir)/dom/webidl/ \
|
||||||
$*.webidl
|
$*.webidl
|
||||||
|
|
||||||
$(globalgen_targets): ParserResults.pkl
|
$(globalgen_targets): ParserResults.pkl
|
||||||
@ -195,4 +225,6 @@ GARBAGE += \
|
|||||||
# don't have issues with .cpp files being compiled before we've generated the
|
# don't have issues with .cpp files being compiled before we've generated the
|
||||||
# headers they depend on. This is really only needed for the test files, since
|
# headers they depend on. This is really only needed for the test files, since
|
||||||
# the non-test headers are all exported above anyway.
|
# the non-test headers are all exported above anyway.
|
||||||
export:: $(binding_header_files)
|
webidl-export:: $(binding_header_files)
|
||||||
|
|
||||||
|
.PHONY: webidl-export
|
||||||
|
@ -174,6 +174,38 @@ class IDLObject(object):
|
|||||||
def handleExtendedAttribute(self, attr):
|
def handleExtendedAttribute(self, attr):
|
||||||
assert False # Override me!
|
assert False # Override me!
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
assert False # Override me!
|
||||||
|
|
||||||
|
def getDeps(self, visited=None):
|
||||||
|
""" Return a set of files that this object depends on. If any of
|
||||||
|
these files are changed the parser needs to be rerun to regenerate
|
||||||
|
a new IDLObject.
|
||||||
|
|
||||||
|
The visited argument is a set of all the objects already visited.
|
||||||
|
We must test to see if we are in it, and if so, do nothing. This
|
||||||
|
prevents infinite recursion."""
|
||||||
|
|
||||||
|
# NB: We can't use visited=set() above because the default value is
|
||||||
|
# evaluated when the def statement is evaluated, not when the function
|
||||||
|
# is executed, so there would be one set for all invocations.
|
||||||
|
if visited == None:
|
||||||
|
visited = set()
|
||||||
|
|
||||||
|
if self in visited:
|
||||||
|
return set()
|
||||||
|
|
||||||
|
visited.add(self)
|
||||||
|
|
||||||
|
deps = set()
|
||||||
|
if self.filename() != "<builtin>":
|
||||||
|
deps.add(self.filename())
|
||||||
|
|
||||||
|
for d in self._getDependentObjects():
|
||||||
|
deps = deps.union(d.getDeps(visited))
|
||||||
|
|
||||||
|
return deps
|
||||||
|
|
||||||
class IDLScope(IDLObject):
|
class IDLScope(IDLObject):
|
||||||
def __init__(self, location, parentScope, identifier):
|
def __init__(self, location, parentScope, identifier):
|
||||||
IDLObject.__init__(self, location)
|
IDLObject.__init__(self, location)
|
||||||
@ -443,6 +475,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
|
|||||||
def resolve(self, parentScope):
|
def resolve(self, parentScope):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
class IDLInterface(IDLObjectWithScope):
|
class IDLInterface(IDLObjectWithScope):
|
||||||
def __init__(self, location, parentScope, name, parent, members,
|
def __init__(self, location, parentScope, name, parent, members,
|
||||||
isPartial):
|
isPartial):
|
||||||
@ -916,6 +951,13 @@ class IDLInterface(IDLObjectWithScope):
|
|||||||
# Put the new members at the beginning
|
# Put the new members at the beginning
|
||||||
self.members = members + self.members
|
self.members = members + self.members
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
deps = set(self.members)
|
||||||
|
deps.union(self.implementedInterfaces)
|
||||||
|
if self.parent:
|
||||||
|
deps.add(self.parent)
|
||||||
|
return deps
|
||||||
|
|
||||||
class IDLDictionary(IDLObjectWithScope):
|
class IDLDictionary(IDLObjectWithScope):
|
||||||
def __init__(self, location, parentScope, name, parent, members):
|
def __init__(self, location, parentScope, name, parent, members):
|
||||||
assert isinstance(parentScope, IDLScope)
|
assert isinstance(parentScope, IDLScope)
|
||||||
@ -986,6 +1028,11 @@ class IDLDictionary(IDLObjectWithScope):
|
|||||||
def addExtendedAttributes(self, attrs):
|
def addExtendedAttributes(self, attrs):
|
||||||
assert len(attrs) == 0
|
assert len(attrs) == 0
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
deps = set(self.members)
|
||||||
|
if (self.parent):
|
||||||
|
deps.add(self.parent)
|
||||||
|
return deps
|
||||||
|
|
||||||
class IDLEnum(IDLObjectWithIdentifier):
|
class IDLEnum(IDLObjectWithIdentifier):
|
||||||
def __init__(self, location, parentScope, name, values):
|
def __init__(self, location, parentScope, name, values):
|
||||||
@ -1014,6 +1061,9 @@ class IDLEnum(IDLObjectWithIdentifier):
|
|||||||
def addExtendedAttributes(self, attrs):
|
def addExtendedAttributes(self, attrs):
|
||||||
assert len(attrs) == 0
|
assert len(attrs) == 0
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
class IDLType(IDLObject):
|
class IDLType(IDLObject):
|
||||||
Tags = enum(
|
Tags = enum(
|
||||||
# The integer types
|
# The integer types
|
||||||
@ -1303,6 +1353,9 @@ class IDLNullableType(IDLType):
|
|||||||
return False
|
return False
|
||||||
return self.inner.isDistinguishableFrom(other)
|
return self.inner.isDistinguishableFrom(other)
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return self.inner._getDependentObjects()
|
||||||
|
|
||||||
class IDLSequenceType(IDLType):
|
class IDLSequenceType(IDLType):
|
||||||
def __init__(self, location, parameterType):
|
def __init__(self, location, parameterType):
|
||||||
assert not parameterType.isVoid()
|
assert not parameterType.isVoid()
|
||||||
@ -1373,6 +1426,9 @@ class IDLSequenceType(IDLType):
|
|||||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||||
other.isDate() or other.isNonCallbackInterface())
|
other.isDate() or other.isNonCallbackInterface())
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return self.inner._getDependentObjects()
|
||||||
|
|
||||||
class IDLUnionType(IDLType):
|
class IDLUnionType(IDLType):
|
||||||
def __init__(self, location, memberTypes):
|
def __init__(self, location, memberTypes):
|
||||||
IDLType.__init__(self, location, "")
|
IDLType.__init__(self, location, "")
|
||||||
@ -1476,6 +1532,9 @@ class IDLUnionType(IDLType):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set(self.memberTypes)
|
||||||
|
|
||||||
class IDLArrayType(IDLType):
|
class IDLArrayType(IDLType):
|
||||||
def __init__(self, location, parameterType):
|
def __init__(self, location, parameterType):
|
||||||
assert not parameterType.isVoid()
|
assert not parameterType.isVoid()
|
||||||
@ -1551,6 +1610,9 @@ class IDLArrayType(IDLType):
|
|||||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||||
other.isDate() or other.isNonCallbackInterface())
|
other.isDate() or other.isNonCallbackInterface())
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return self.inner._getDependentObjects()
|
||||||
|
|
||||||
class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
||||||
def __init__(self, location, innerType, name):
|
def __init__(self, location, innerType, name):
|
||||||
IDLType.__init__(self, location, innerType.name)
|
IDLType.__init__(self, location, innerType.name)
|
||||||
@ -1638,6 +1700,9 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
|||||||
def isDistinguishableFrom(self, other):
|
def isDistinguishableFrom(self, other):
|
||||||
return self.inner.isDistinguishableFrom(other)
|
return self.inner.isDistinguishableFrom(other)
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return self.inner._getDependentObjects()
|
||||||
|
|
||||||
class IDLWrapperType(IDLType):
|
class IDLWrapperType(IDLType):
|
||||||
def __init__(self, location, inner):
|
def __init__(self, location, inner):
|
||||||
IDLType.__init__(self, location, inner.identifier.name)
|
IDLType.__init__(self, location, inner.identifier.name)
|
||||||
@ -1741,6 +1806,23 @@ class IDLWrapperType(IDLType):
|
|||||||
assert other.isObject()
|
assert other.isObject()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
# NB: The codegen for an interface type depends on
|
||||||
|
# a) That the identifier is in fact an interface (as opposed to
|
||||||
|
# a dictionary or something else).
|
||||||
|
# b) The native type of the interface.
|
||||||
|
# If we depend on the interface object we will also depend on
|
||||||
|
# anything the interface depends on which is undesirable. We
|
||||||
|
# considered implementing a dependency just on the interface type
|
||||||
|
# file, but then every modification to an interface would cause this
|
||||||
|
# to be regenerated which is still undesirable. We decided not to
|
||||||
|
# depend on anything, reasoning that:
|
||||||
|
# 1) Changing the concrete type of the interface requires modifying
|
||||||
|
# Bindings.conf, which is still a global dependency.
|
||||||
|
# 2) Changing an interface to a dictionary (or vice versa) with the
|
||||||
|
# same identifier should be incredibly rare.
|
||||||
|
return set()
|
||||||
|
|
||||||
class IDLBuiltinType(IDLType):
|
class IDLBuiltinType(IDLType):
|
||||||
|
|
||||||
Types = enum(
|
Types = enum(
|
||||||
@ -1906,6 +1988,9 @@ class IDLBuiltinType(IDLType):
|
|||||||
(self.isTypedArray() and not other.isArrayBufferView() and not
|
(self.isTypedArray() and not other.isArrayBufferView() and not
|
||||||
(other.isTypedArray() and other.name == self.name)))))
|
(other.isTypedArray() and other.name == self.name)))))
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
BuiltinTypes = {
|
BuiltinTypes = {
|
||||||
IDLBuiltinType.Types.byte:
|
IDLBuiltinType.Types.byte:
|
||||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
|
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
|
||||||
@ -2064,6 +2149,9 @@ class IDLValue(IDLObject):
|
|||||||
raise WebIDLError("Cannot coerce type %s to type %s." %
|
raise WebIDLError("Cannot coerce type %s to type %s." %
|
||||||
(self.type, type), [location])
|
(self.type, type), [location])
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
class IDLNullValue(IDLObject):
|
class IDLNullValue(IDLObject):
|
||||||
def __init__(self, location):
|
def __init__(self, location):
|
||||||
IDLObject.__init__(self, location)
|
IDLObject.__init__(self, location)
|
||||||
@ -2081,7 +2169,10 @@ class IDLNullValue(IDLObject):
|
|||||||
nullValue = IDLNullValue(self.location)
|
nullValue = IDLNullValue(self.location)
|
||||||
nullValue.type = type
|
nullValue.type = type
|
||||||
return nullValue
|
return nullValue
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set()
|
||||||
|
|
||||||
|
|
||||||
class IDLInterfaceMember(IDLObjectWithIdentifier):
|
class IDLInterfaceMember(IDLObjectWithIdentifier):
|
||||||
|
|
||||||
@ -2162,6 +2253,9 @@ class IDLConst(IDLInterfaceMember):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set([self.type, self.value])
|
||||||
|
|
||||||
class IDLAttribute(IDLInterfaceMember):
|
class IDLAttribute(IDLInterfaceMember):
|
||||||
def __init__(self, location, identifier, type, readonly, inherit=False,
|
def __init__(self, location, identifier, type, readonly, inherit=False,
|
||||||
static=False, stringifier=False):
|
static=False, stringifier=False):
|
||||||
@ -2307,6 +2401,9 @@ class IDLAttribute(IDLInterfaceMember):
|
|||||||
def isUnforgeable(self):
|
def isUnforgeable(self):
|
||||||
return self._unforgeable
|
return self._unforgeable
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set([self.type])
|
||||||
|
|
||||||
class IDLArgument(IDLObjectWithIdentifier):
|
class IDLArgument(IDLObjectWithIdentifier):
|
||||||
def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False):
|
def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False):
|
||||||
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
|
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
|
||||||
@ -2379,6 +2476,12 @@ class IDLArgument(IDLObjectWithIdentifier):
|
|||||||
self.location)
|
self.location)
|
||||||
assert self.defaultValue
|
assert self.defaultValue
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
deps = set([self.type])
|
||||||
|
if self.defaultValue:
|
||||||
|
deps.add(self.defaultValue)
|
||||||
|
return deps
|
||||||
|
|
||||||
class IDLCallbackType(IDLType, IDLObjectWithScope):
|
class IDLCallbackType(IDLType, IDLObjectWithScope):
|
||||||
def __init__(self, location, parentScope, identifier, returnType, arguments):
|
def __init__(self, location, parentScope, identifier, returnType, arguments):
|
||||||
assert isinstance(returnType, IDLType)
|
assert isinstance(returnType, IDLType)
|
||||||
@ -2446,6 +2549,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
|
|||||||
if len(unhandledAttrs) != 0:
|
if len(unhandledAttrs) != 0:
|
||||||
IDLType.addExtendedAttributes(self, unhandledAttrs)
|
IDLType.addExtendedAttributes(self, unhandledAttrs)
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
return set([self._returnType] + self._arguments)
|
||||||
|
|
||||||
class IDLMethodOverload:
|
class IDLMethodOverload:
|
||||||
"""
|
"""
|
||||||
A class that represents a single overload of a WebIDL method. This is not
|
A class that represents a single overload of a WebIDL method. This is not
|
||||||
@ -2461,6 +2567,11 @@ class IDLMethodOverload:
|
|||||||
self.arguments = list(arguments)
|
self.arguments = list(arguments)
|
||||||
self.location = location
|
self.location = location
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
deps = set(self.arguments)
|
||||||
|
deps.add(self.returnType)
|
||||||
|
return deps
|
||||||
|
|
||||||
class IDLMethod(IDLInterfaceMember, IDLScope):
|
class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||||
|
|
||||||
Special = enum(
|
Special = enum(
|
||||||
@ -2808,6 +2919,12 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||||||
[attr.location, self.location])
|
[attr.location, self.location])
|
||||||
IDLInterfaceMember.handleExtendedAttribute(self, attr)
|
IDLInterfaceMember.handleExtendedAttribute(self, attr)
|
||||||
|
|
||||||
|
def _getDependentObjects(self):
|
||||||
|
deps = set()
|
||||||
|
for overload in self._overloads:
|
||||||
|
deps.union(overload._getDependentObjects())
|
||||||
|
return deps
|
||||||
|
|
||||||
class IDLImplementsStatement(IDLObject):
|
class IDLImplementsStatement(IDLObject):
|
||||||
def __init__(self, location, implementor, implementee):
|
def __init__(self, location, implementor, implementee):
|
||||||
IDLObject.__init__(self, location)
|
IDLObject.__init__(self, location)
|
||||||
|
@ -90,7 +90,7 @@ def checkEquivalent(iface, harness):
|
|||||||
for attr in dir(type1):
|
for attr in dir(type1):
|
||||||
if attr.startswith('_') or \
|
if attr.startswith('_') or \
|
||||||
attr in ['nullable', 'builtin', 'filename', 'location',
|
attr in ['nullable', 'builtin', 'filename', 'location',
|
||||||
'inner', 'QName'] or \
|
'inner', 'QName', 'getDeps'] or \
|
||||||
(hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
|
(hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ bindinggen_dependencies := \
|
|||||||
../Configuration.py \
|
../Configuration.py \
|
||||||
../Codegen.py \
|
../Codegen.py \
|
||||||
../parser/WebIDL.py \
|
../parser/WebIDL.py \
|
||||||
../ParserResults.pkl \
|
|
||||||
../Makefile \
|
../Makefile \
|
||||||
$(GLOBAL_DEPS) \
|
$(GLOBAL_DEPS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "BrowserElementParent.h"
|
#include "BrowserElementParent.h"
|
||||||
#include "nsHTMLIFrameElement.h"
|
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||||
#include "nsOpenWindowEventDetail.h"
|
#include "nsOpenWindowEventDetail.h"
|
||||||
#include "nsEventDispatcher.h"
|
#include "nsEventDispatcher.h"
|
||||||
#include "nsIDOMCustomEvent.h"
|
#include "nsIDOMCustomEvent.h"
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include "nsAsyncScrollEventDetail.h"
|
#include "nsAsyncScrollEventDetail.h"
|
||||||
|
|
||||||
using mozilla::dom::Element;
|
using mozilla::dom::Element;
|
||||||
|
using mozilla::dom::HTMLIFrameElement;
|
||||||
using mozilla::dom::TabParent;
|
using mozilla::dom::TabParent;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -30,7 +31,7 @@ namespace {
|
|||||||
* Create an <iframe mozbrowser> owned by the same document as
|
* Create an <iframe mozbrowser> owned by the same document as
|
||||||
* aOpenerFrameElement.
|
* aOpenerFrameElement.
|
||||||
*/
|
*/
|
||||||
already_AddRefed<nsHTMLIFrameElement>
|
already_AddRefed<HTMLIFrameElement>
|
||||||
CreateIframe(Element* aOpenerFrameElement, const nsAString& aName, bool aRemote)
|
CreateIframe(Element* aOpenerFrameElement, const nsAString& aName, bool aRemote)
|
||||||
{
|
{
|
||||||
nsNodeInfoManager *nodeInfoManager =
|
nsNodeInfoManager *nodeInfoManager =
|
||||||
@ -42,8 +43,8 @@ CreateIframe(Element* aOpenerFrameElement, const nsAString& aName, bool aRemote)
|
|||||||
kNameSpaceID_XHTML,
|
kNameSpaceID_XHTML,
|
||||||
nsIDOMNode::ELEMENT_NODE);
|
nsIDOMNode::ELEMENT_NODE);
|
||||||
|
|
||||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
nsRefPtr<HTMLIFrameElement> popupFrameElement =
|
||||||
static_cast<nsHTMLIFrameElement*>(
|
static_cast<HTMLIFrameElement*>(
|
||||||
NS_NewHTMLIFrameElement(nodeInfo.forget(), mozilla::dom::NOT_FROM_PARSER));
|
NS_NewHTMLIFrameElement(nodeInfo.forget(), mozilla::dom::NOT_FROM_PARSER));
|
||||||
|
|
||||||
popupFrameElement->SetMozbrowser(true);
|
popupFrameElement->SetMozbrowser(true);
|
||||||
@ -151,7 +152,7 @@ BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent,
|
|||||||
nsCOMPtr<Element> openerFrameElement =
|
nsCOMPtr<Element> openerFrameElement =
|
||||||
do_QueryInterface(aOpenerTabParent->GetOwnerElement());
|
do_QueryInterface(aOpenerTabParent->GetOwnerElement());
|
||||||
NS_ENSURE_TRUE(openerFrameElement, false);
|
NS_ENSURE_TRUE(openerFrameElement, false);
|
||||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
nsRefPtr<HTMLIFrameElement> popupFrameElement =
|
||||||
CreateIframe(openerFrameElement, aName, /* aRemote = */ true);
|
CreateIframe(openerFrameElement, aName, /* aRemote = */ true);
|
||||||
|
|
||||||
// Normally an <iframe> element will try to create a frameLoader when the
|
// Normally an <iframe> element will try to create a frameLoader when the
|
||||||
@ -209,7 +210,7 @@ BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
|
|||||||
nsCOMPtr<Element> openerFrameElement =
|
nsCOMPtr<Element> openerFrameElement =
|
||||||
do_QueryInterface(openerFrameDOMElement);
|
do_QueryInterface(openerFrameDOMElement);
|
||||||
|
|
||||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
nsRefPtr<HTMLIFrameElement> popupFrameElement =
|
||||||
CreateIframe(openerFrameElement, aName, /* aRemote = */ false);
|
CreateIframe(openerFrameElement, aName, /* aRemote = */ false);
|
||||||
NS_ENSURE_TRUE(popupFrameElement, false);
|
NS_ENSURE_TRUE(popupFrameElement, false);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ SimpleTest.waitForExplicitFinish();
|
|||||||
|
|
||||||
function makeAllAppsLaunchable() {
|
function makeAllAppsLaunchable() {
|
||||||
var Webapps = {};
|
var Webapps = {};
|
||||||
SpecialPowers.wrap(Components).utils.import("resource://gre/modules/Webapps.jsm", Webapps);
|
SpecialPowers.Cu.import("resource://gre/modules/Webapps.jsm", Webapps);
|
||||||
var appRegistry = SpecialPowers.wrap(Webapps.DOMApplicationRegistry);
|
var appRegistry = SpecialPowers.wrap(Webapps.DOMApplicationRegistry);
|
||||||
|
|
||||||
var originalValue = appRegistry.allAppsLaunchable;
|
var originalValue = appRegistry.allAppsLaunchable;
|
||||||
|
@ -54,7 +54,7 @@ function getRandomView(size)
|
|||||||
|
|
||||||
function getBlob(type, view)
|
function getBlob(type, view)
|
||||||
{
|
{
|
||||||
return utils.getBlob([view], {type: type});
|
return SpecialPowers.unwrap(utils.getBlob([view], {type: type}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomBlob(size)
|
function getRandomBlob(size)
|
||||||
|
@ -179,7 +179,7 @@ function compareBuffers(buffer1, buffer2)
|
|||||||
|
|
||||||
function getBlob(type, buffer)
|
function getBlob(type, buffer)
|
||||||
{
|
{
|
||||||
return utils.getBlob([buffer], {type: type});
|
return SpecialPowers.unwrap(utils.getBlob([buffer], {type: type}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomBlob(size)
|
function getRandomBlob(size)
|
||||||
@ -189,5 +189,5 @@ function getRandomBlob(size)
|
|||||||
|
|
||||||
function getFileId(blob)
|
function getFileId(blob)
|
||||||
{
|
{
|
||||||
return utils.getFileId(blob);
|
return SpecialPowers.unwrap(utils.getFileId(blob));
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function createNonUnicodeData() {
|
function createNonUnicodeData() {
|
||||||
const Cc = SpecialPowers.wrap(Components).classes;
|
const Cc = SpecialPowers.Cc;
|
||||||
const Ci = SpecialPowers.wrap(Components).interfaces;
|
const Ci = SpecialPowers.Ci;
|
||||||
|
|
||||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||||
var testFile = dirSvc.get("ProfD", Ci.nsIFile);
|
var testFile = dirSvc.get("ProfD", Ci.nsIFile);
|
||||||
|
@ -49,12 +49,12 @@ function compareBuffers(buffer1, buffer2)
|
|||||||
|
|
||||||
function getBlob(type, view)
|
function getBlob(type, view)
|
||||||
{
|
{
|
||||||
return utils.getBlob([view], {type: type});
|
return SpecialPowers.unwrap(utils.getBlob([view], {type: type}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFile(name, type, view)
|
function getFile(name, type, view)
|
||||||
{
|
{
|
||||||
return utils.getFile(name, [view], {type: type});
|
return SpecialPowers.unwrap(utils.getFile(name, [view], {type: type}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomBlob(size)
|
function getRandomBlob(size)
|
||||||
|
@ -10,7 +10,7 @@ var archiveReaderEnabled = false;
|
|||||||
// and content mochitests (where the |Components| object is accessible only as
|
// and content mochitests (where the |Components| object is accessible only as
|
||||||
// SpecialPowers.Components). Expose Components if necessary here to make things
|
// SpecialPowers.Components). Expose Components if necessary here to make things
|
||||||
// work everywhere.
|
// work everywhere.
|
||||||
if (typeof Components === 'undefined')
|
if (typeof Components === 'undefined' && typeof SpecialPowers === 'object')
|
||||||
Components = SpecialPowers.Components;
|
Components = SpecialPowers.Components;
|
||||||
|
|
||||||
function executeSoon(aFun)
|
function executeSoon(aFun)
|
||||||
|
@ -84,6 +84,7 @@ RemovedFullScreenElement=Exited full-screen because full-screen element was remo
|
|||||||
FocusedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was focused.
|
FocusedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was focused.
|
||||||
HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
|
HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
|
||||||
HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
|
HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
|
||||||
|
MultipartXHRWarning=Support for multipart responses in XMLHttpRequest is going to be removed in an upcoming version. Please migrate to chunked responses or to Web Sockets.
|
||||||
InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.
|
InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.
|
||||||
ReportOnlyCSPIgnored=Report-only CSP policy will be ignored because there are other non-report-only CSP policies applied.
|
ReportOnlyCSPIgnored=Report-only CSP policy will be ignored because there are other non-report-only CSP policies applied.
|
||||||
ResponseTypeSyncXHRWarning=Use of XMLHttpRequest's responseType attribute is no longer supported in the synchronous mode in window context.
|
ResponseTypeSyncXHRWarning=Use of XMLHttpRequest's responseType attribute is no longer supported in the synchronous mode in window context.
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
ChildCountIncorrect=Invalid markup: Incorrect number of children for <%1$S/> tag.
|
ChildCountIncorrect=Invalid markup: Incorrect number of children for <%1$S/> tag.
|
||||||
DuplicateMprescripts=Invalid markup: More than one <mprescripts/> in <mmultiscripts/>.
|
DuplicateMprescripts=Invalid markup: More than one <mprescripts/> in <mmultiscripts/>.
|
||||||
NoSubSup=Invalid markup: Expected at least one subscript/superscript pair in <mmultiscripts/>. Found none.
|
# LOCALIZATION NOTE: The first child of <mmultiscript/> is the base, that is the element to which scripts are attached.
|
||||||
|
NoBase=Invalid markup: Expected exactly one Base element in <mmultiscripts/>. Found none.
|
||||||
SubSupMismatch=Invalid markup: Incomplete subscript/superscript pair in <mmultiscripts/>.
|
SubSupMismatch=Invalid markup: Incomplete subscript/superscript pair in <mmultiscripts/>.
|
||||||
|
|
||||||
# LOCALIZATION NOTE: When localizing the single quotes ('), follow the conventions in css.properties for your target locale.
|
# LOCALIZATION NOTE: When localizing the single quotes ('), follow the conventions in css.properties for your target locale.
|
||||||
|
@ -912,7 +912,7 @@ MediaManager::GetUserMedia(bool aPrivileged, nsPIDOMWindow* aWindow,
|
|||||||
uint32_t permission;
|
uint32_t permission;
|
||||||
nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
|
nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
|
||||||
pm->TestPermission(doc->NodePrincipal(), &permission);
|
pm->TestPermission(doc->NodePrincipal(), &permission);
|
||||||
if ((permission == nsIPopupWindowManager::DENY_POPUP)) {
|
if (permission == nsIPopupWindowManager::DENY_POPUP) {
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc = aWindow->GetExtantDocument();
|
nsCOMPtr<nsIDOMDocument> domDoc = aWindow->GetExtantDocument();
|
||||||
nsGlobalWindow::FirePopupBlockedEvent(
|
nsGlobalWindow::FirePopupBlockedEvent(
|
||||||
domDoc, aWindow, nullptr, EmptyString(), EmptyString()
|
domDoc, aWindow, nullptr, EmptyString(), EmptyString()
|
||||||
|
@ -2,30 +2,42 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "domstubs.idl"
|
||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
#include "nsIMobileMessageDatabaseService.idl"
|
#include "nsIMobileMessageDatabaseService.idl"
|
||||||
|
|
||||||
interface nsIDOMMozSmsMessage;
|
[scriptable, function, uuid(0bffae74-71db-11e2-962a-73cf64d6393e)]
|
||||||
|
|
||||||
[scriptable, function, uuid(9cd80750-6a08-11e2-ac93-bf895e53f40e)]
|
|
||||||
interface nsIRilMobileMessageDatabaseCallback : nsISupports
|
interface nsIRilMobileMessageDatabaseCallback : nsISupports
|
||||||
{
|
{
|
||||||
void notify(in nsresult aRv, in nsIDOMMozSmsMessage aSms);
|
/**
|
||||||
|
* |aRecord| Object: the mobile-message database record
|
||||||
|
*/
|
||||||
|
void notify(in nsresult aRv, in jsval aRecord);
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, uuid(89528354-6a08-11e2-8243-af4cf90404a9)]
|
[scriptable, uuid(3592525a-71d6-11e2-82ca-f75ae6e08ee2)]
|
||||||
interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
|
interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
|
||||||
{
|
{
|
||||||
long saveReceivedMessage(in DOMString aSender,
|
/**
|
||||||
in DOMString aBody,
|
* |aMessage| Object: should contain the following properties for internal use:
|
||||||
in DOMString aMessageClass,
|
* - |type| DOMString: "sms" or "mms"
|
||||||
in unsigned long long aDate,
|
* - |sender| DOMString: the phone number of sender
|
||||||
|
* - |timestamp| Number: the timestamp of received message
|
||||||
|
* - |messageClass| DOMString: the message class of received message
|
||||||
|
*/
|
||||||
|
long saveReceivedMessage(in jsval aMessage,
|
||||||
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
|
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
|
||||||
long saveSendingMessage(in DOMString aReceiver,
|
|
||||||
in DOMString aBody,
|
/**
|
||||||
in DOMString aDeliveryStatus,
|
* |aMessage| Object: should contain the following properties for internal use:
|
||||||
in unsigned long long aDate,
|
* - |type| DOMString: "sms" or "mms"
|
||||||
|
* - |receiver| DOMString: the phone number of receiver
|
||||||
|
* - |timestamp| Number: the timestamp of sending message
|
||||||
|
* - |deliveryStatus| DOMString: the delivery status of sending message
|
||||||
|
*/
|
||||||
|
long saveSendingMessage(in jsval aMessage,
|
||||||
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
|
[optional] in nsIRilMobileMessageDatabaseCallback aCallback);
|
||||||
|
|
||||||
void setMessageDelivery(in long aMessageId,
|
void setMessageDelivery(in long aMessageId,
|
||||||
in DOMString aDelivery,
|
in DOMString aDelivery,
|
||||||
in DOMString aDeliveryStatus,
|
in DOMString aDeliveryStatus,
|
||||||
|
@ -413,8 +413,8 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
createMessageFromRecord: function createMessageFromRecord(aRecord) {
|
createSmsMessageFromRecord: function createSmsMessageFromRecord(aRecord) {
|
||||||
if (DEBUG) debug("createMessageFromRecord: " + JSON.stringify(aRecord));
|
if (DEBUG) debug("createSmsMessageFromRecord: " + JSON.stringify(aRecord));
|
||||||
return gSmsService.createSmsMessage(aRecord.id,
|
return gSmsService.createSmsMessage(aRecord.id,
|
||||||
aRecord.delivery,
|
aRecord.delivery,
|
||||||
aRecord.deliveryStatus,
|
aRecord.deliveryStatus,
|
||||||
@ -482,7 +482,7 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
let getRequest = aObjectStore.get(firstMessageId);
|
let getRequest = aObjectStore.get(firstMessageId);
|
||||||
let self = this;
|
let self = this;
|
||||||
getRequest.onsuccess = function onsuccess(event) {
|
getRequest.onsuccess = function onsuccess(event) {
|
||||||
let sms = self.createMessageFromRecord(event.target.result);
|
let sms = self.createSmsMessageFromRecord(event.target.result);
|
||||||
if (aMessageList.listId >= 0) {
|
if (aMessageList.listId >= 0) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
debug("notifyNextMessageInListGot - listId: "
|
debug("notifyNextMessageInListGot - listId: "
|
||||||
@ -657,8 +657,7 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
if (!aCallback) {
|
if (!aCallback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let sms = self.createMessageFromRecord(aRecord);
|
aCallback.notify(rv, aRecord);
|
||||||
aCallback.notify(rv, sms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.newTxn(READ_WRITE, function(error, txn, stores) {
|
this.newTxn(READ_WRITE, function(error, txn, stores) {
|
||||||
@ -678,9 +677,8 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
// First add to main objectStore.
|
// First add to main objectStore.
|
||||||
stores[0].put(aRecord);
|
stores[0].put(aRecord);
|
||||||
|
|
||||||
let number = getNumberFromRecord(aRecord);
|
|
||||||
|
|
||||||
// Next update the other objectStore.
|
// Next update the other objectStore.
|
||||||
|
let number = getNumberFromRecord(aRecord);
|
||||||
stores[1].get(number).onsuccess = function onsuccess(event) {
|
stores[1].get(number).onsuccess = function onsuccess(event) {
|
||||||
let mostRecentEntry = event.target.result;
|
let mostRecentEntry = event.target.result;
|
||||||
if (mostRecentEntry) {
|
if (mostRecentEntry) {
|
||||||
@ -713,100 +711,96 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
return aRecord.id;
|
return aRecord.id;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getRilIccInfoMsisdn: function getRilIccInfoMsisdn() {
|
||||||
|
let iccInfo = this.mRIL.rilContext.iccInfo;
|
||||||
|
let number = iccInfo ? iccInfo.msisdn : null;
|
||||||
|
|
||||||
|
// Workaround an xpconnect issue with undefined string objects.
|
||||||
|
// See bug 808220
|
||||||
|
if (number === undefined || number === "undefined") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return number;
|
||||||
|
},
|
||||||
|
|
||||||
|
makePhoneNumberInternational: function makePhoneNumberInternational(aNumber) {
|
||||||
|
if (!aNumber) {
|
||||||
|
return aNumber;
|
||||||
|
}
|
||||||
|
let parsedNumber = PhoneNumberUtils.parse(aNumber.toString());
|
||||||
|
if (!parsedNumber || !parsedNumber.internationalNumber) {
|
||||||
|
return aNumber;
|
||||||
|
}
|
||||||
|
return parsedNumber.internationalNumber;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nsIRilMobileMessageDatabaseService API
|
* nsIRilMobileMessageDatabaseService API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
saveReceivedMessage: function saveReceivedMessage(
|
saveReceivedMessage: function saveReceivedMessage(aMessage, aCallback) {
|
||||||
aSender, aBody, aMessageClass, aDate, aCallback) {
|
if (aMessage.type === undefined ||
|
||||||
let iccInfo = this.mRIL.rilContext.iccInfo;
|
aMessage.sender === undefined ||
|
||||||
let receiver = iccInfo ? iccInfo.msisdn : null;
|
aMessage.messageClass === undefined ||
|
||||||
|
aMessage.timestamp === undefined) {
|
||||||
// Workaround an xpconnect issue with undefined string objects.
|
if (aCallback) {
|
||||||
// See bug 808220
|
aCallback.notify(Cr.NS_ERROR_FAILURE, null);
|
||||||
if (receiver === undefined || receiver === "undefined") {
|
}
|
||||||
receiver = null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (receiver) {
|
let receiver = this.getRilIccInfoMsisdn();
|
||||||
let parsedNumber = PhoneNumberUtils.parse(receiver);
|
receiver = this.makePhoneNumberInternational(receiver);
|
||||||
receiver = (parsedNumber && parsedNumber.internationalNumber)
|
|
||||||
? parsedNumber.internationalNumber
|
|
||||||
: receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sender = aSender;
|
let sender = aMessage.sender =
|
||||||
if (sender) {
|
this.makePhoneNumberInternational(aMessage.sender);
|
||||||
let parsedNumber = PhoneNumberUtils.parse(sender);
|
|
||||||
sender = (parsedNumber && parsedNumber.internationalNumber)
|
|
||||||
? parsedNumber.internationalNumber
|
|
||||||
: sender;
|
|
||||||
}
|
|
||||||
|
|
||||||
let record = {
|
let timestamp = aMessage.timestamp;
|
||||||
deliveryIndex: [DELIVERY_RECEIVED, aDate],
|
|
||||||
numberIndex: [[sender, aDate], [receiver, aDate]],
|
|
||||||
readIndex: [FILTER_READ_UNREAD, aDate],
|
|
||||||
|
|
||||||
delivery: DELIVERY_RECEIVED,
|
// Adding needed indexes and extra attributes for internal use.
|
||||||
deliveryStatus: DELIVERY_STATUS_SUCCESS,
|
aMessage.deliveryIndex = [DELIVERY_RECEIVED, timestamp];
|
||||||
sender: sender,
|
aMessage.numberIndex = [[sender, timestamp], [receiver, timestamp]];
|
||||||
receiver: receiver,
|
aMessage.readIndex = [FILTER_READ_UNREAD, timestamp];
|
||||||
body: aBody,
|
aMessage.delivery = DELIVERY_RECEIVED;
|
||||||
messageClass: aMessageClass,
|
aMessage.deliveryStatus = DELIVERY_STATUS_SUCCESS;
|
||||||
timestamp: aDate,
|
aMessage.receiver = receiver;
|
||||||
read: FILTER_READ_UNREAD
|
aMessage.read = FILTER_READ_UNREAD;
|
||||||
};
|
|
||||||
return this.saveRecord(record, aCallback);
|
return this.saveRecord(aMessage, aCallback);
|
||||||
},
|
},
|
||||||
|
|
||||||
saveSendingMessage: function saveSendingMessage(
|
saveSendingMessage: function saveSendingMessage(aMessage, aCallback) {
|
||||||
aReceiver, aBody, aDeliveryStatus, aDate, aCallback) {
|
if (aMessage.type === undefined ||
|
||||||
|
aMessage.receiver === undefined ||
|
||||||
|
aMessage.deliveryStatus === undefined ||
|
||||||
|
aMessage.timestamp === undefined) {
|
||||||
|
if (aCallback) {
|
||||||
|
aCallback.notify(Cr.NS_ERROR_FAILURE, null);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sender = this.getRilIccInfoMsisdn();
|
||||||
|
let receiver = aMessage.receiver;
|
||||||
|
|
||||||
let rilContext = this.mRIL.rilContext;
|
let rilContext = this.mRIL.rilContext;
|
||||||
let sender = rilContext.iccInfo
|
|
||||||
? rilContext.iccInfo.msisdn
|
|
||||||
: null;
|
|
||||||
|
|
||||||
// Workaround an xpconnect issue with undefined string objects.
|
|
||||||
// See bug 808220
|
|
||||||
if (sender === undefined || sender === "undefined") {
|
|
||||||
sender = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let receiver = aReceiver;
|
|
||||||
|
|
||||||
if (rilContext.voice.network.mcc === rilContext.iccInfo.mcc) {
|
if (rilContext.voice.network.mcc === rilContext.iccInfo.mcc) {
|
||||||
if (receiver) {
|
receiver = aMessage.receiver = this.makePhoneNumberInternational(receiver);
|
||||||
let parsedNumber = PhoneNumberUtils.parse(receiver.toString());
|
sender = this.makePhoneNumberInternational(sender);
|
||||||
receiver = (parsedNumber && parsedNumber.internationalNumber)
|
|
||||||
? parsedNumber.internationalNumber
|
|
||||||
: receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender) {
|
|
||||||
let parsedNumber = PhoneNumberUtils.parse(sender.toString());
|
|
||||||
sender = (parsedNumber && parsedNumber.internationalNumber)
|
|
||||||
? parsedNumber.internationalNumber
|
|
||||||
: sender;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let record = {
|
let timestamp = aMessage.timestamp;
|
||||||
deliveryIndex: [DELIVERY_SENDING, aDate],
|
|
||||||
numberIndex: [[sender, aDate], [receiver, aDate]],
|
|
||||||
readIndex: [FILTER_READ_READ, aDate],
|
|
||||||
|
|
||||||
delivery: DELIVERY_SENDING,
|
// Adding needed indexes and extra attributes for internal use.
|
||||||
deliveryStatus: aDeliveryStatus,
|
aMessage.deliveryIndex = [DELIVERY_SENDING, timestamp];
|
||||||
sender: sender,
|
aMessage.numberIndex = [[sender, timestamp], [receiver, timestamp]];
|
||||||
receiver: receiver,
|
aMessage.readIndex = [FILTER_READ_READ, timestamp];
|
||||||
body: aBody,
|
aMessage.delivery = DELIVERY_SENDING;
|
||||||
messageClass: MESSAGE_CLASS_NORMAL,
|
aMessage.sender = sender;
|
||||||
timestamp: aDate,
|
aMessage.messageClass = MESSAGE_CLASS_NORMAL;
|
||||||
read: FILTER_READ_READ
|
aMessage.read = FILTER_READ_READ;
|
||||||
};
|
|
||||||
return this.saveRecord(record, aCallback);
|
return this.saveRecord(aMessage, aCallback);
|
||||||
},
|
},
|
||||||
|
|
||||||
setMessageDelivery: function setMessageDelivery(
|
setMessageDelivery: function setMessageDelivery(
|
||||||
@ -822,11 +816,7 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
if (!callback) {
|
if (!callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let sms = null;
|
callback.notify(rv, record);
|
||||||
if (record) {
|
|
||||||
sms = self.createMessageFromRecord(record);
|
|
||||||
}
|
|
||||||
callback.notify(rv, sms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.newTxn(READ_WRITE, function (error, txn, store) {
|
this.newTxn(READ_WRITE, function (error, txn, store) {
|
||||||
@ -914,7 +904,7 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
aRequest.notifyGetMessageFailed(Ci.nsISmsRequest.UNKNOWN_ERROR);
|
aRequest.notifyGetMessageFailed(Ci.nsISmsRequest.UNKNOWN_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let sms = self.createMessageFromRecord(record);
|
let sms = self.createSmsMessageFromRecord(record);
|
||||||
aRequest.notifyMessageGot(sms);
|
aRequest.notifyMessageGot(sms);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1220,7 +1210,7 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
// For all numbers.
|
// For all numbers.
|
||||||
processing: filter.numbers.length,
|
processing: filter.numbers.length,
|
||||||
results: []
|
results: []
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let timeRange = null;
|
let timeRange = null;
|
||||||
if (filter.startDate != null && filter.endDate != null) {
|
if (filter.startDate != null && filter.endDate != null) {
|
||||||
@ -1327,7 +1317,7 @@ MobileMessageDatabaseService.prototype = {
|
|||||||
if (DEBUG) debug("Could not get message id " + messageId);
|
if (DEBUG) debug("Could not get message id " + messageId);
|
||||||
aRequest.notifyReadMessageListFailed(Ci.nsISmsRequest.NOT_FOUND_ERROR);
|
aRequest.notifyReadMessageListFailed(Ci.nsISmsRequest.NOT_FOUND_ERROR);
|
||||||
}
|
}
|
||||||
let sms = self.createMessageFromRecord(record);
|
let sms = self.createSmsMessageFromRecord(record);
|
||||||
aRequest.notifyNextMessageInListGot(sms);
|
aRequest.notifyNextMessageInListGot(sms);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,13 +30,12 @@ var testCertApp = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SpecialPowers.addPermission("permissions", true, document);
|
SpecialPowers.addPermission("permissions", true, document);
|
||||||
var comp = SpecialPowers.wrap(Components);
|
|
||||||
SpecialPowers.pushPrefEnv({ "set": [["dom.mozPermissionSettings.enabled", true]] },
|
SpecialPowers.pushPrefEnv({ "set": [["dom.mozPermissionSettings.enabled", true]] },
|
||||||
function() {
|
function() {
|
||||||
SpecialPowers.removePermission("permissions", document);
|
SpecialPowers.removePermission("permissions", document);
|
||||||
});
|
});
|
||||||
|
|
||||||
comp.utils.import("resource://gre/modules/PermissionSettings.jsm");
|
SpecialPowers.Cu.import("resource://gre/modules/PermissionSettings.jsm");
|
||||||
var mozPermissions = window.navigator.mozPermissionSettings;
|
var mozPermissions = window.navigator.mozPermissionSettings;
|
||||||
|
|
||||||
function permissionTest() {
|
function permissionTest() {
|
||||||
|
@ -21,8 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={678695}
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var comp = SpecialPowers.wrap(Components);
|
SpecialPowers.Cu.import("resource://gre/modules/SettingsChangeNotifier.jsm");
|
||||||
comp.utils.import("resource://gre/modules/SettingsChangeNotifier.jsm");
|
|
||||||
SpecialPowers.setBoolPref("dom.mozSettings.enabled", true);
|
SpecialPowers.setBoolPref("dom.mozSettings.enabled", true);
|
||||||
SpecialPowers.addPermission("settings-write", true, document);
|
SpecialPowers.addPermission("settings-write", true, document);
|
||||||
SpecialPowers.addPermission("settings-read", true, document);
|
SpecialPowers.addPermission("settings-read", true, document);
|
||||||
|
@ -177,21 +177,27 @@ function newRandomId() {
|
|||||||
|
|
||||||
let sms = [
|
let sms = [
|
||||||
{
|
{
|
||||||
|
type: "sms",
|
||||||
sender: "+34666000000",
|
sender: "+34666000000",
|
||||||
receiver: "+34666111000",
|
receiver: "+34666111000",
|
||||||
body: "message 0",
|
body: "message 0",
|
||||||
|
messageClass: "normal",
|
||||||
timestamp: 1329999861762
|
timestamp: 1329999861762
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
type: "sms",
|
||||||
sender: "+34666000111",
|
sender: "+34666000111",
|
||||||
receiver: "+34666111111",
|
receiver: "+34666111111",
|
||||||
body: "message 1",
|
body: "message 1",
|
||||||
|
messageClass: "normal",
|
||||||
timestamp: 1329999861763
|
timestamp: 1329999861763
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
type: "sms",
|
||||||
sender: "+34666000222",
|
sender: "+34666000222",
|
||||||
receiver: "+34666111222",
|
receiver: "+34666111222",
|
||||||
body: "message 2",
|
body: "message 2",
|
||||||
|
messageClass: "normal",
|
||||||
timestamp: 1329999861764
|
timestamp: 1329999861764
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -201,9 +207,7 @@ let sms = [
|
|||||||
*/
|
*/
|
||||||
add_test(function test_saveReceivedMessage() {
|
add_test(function test_saveReceivedMessage() {
|
||||||
info("test_saveReceivedMessage");
|
info("test_saveReceivedMessage");
|
||||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0].sender,
|
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
|
||||||
sms[0].body,
|
|
||||||
sms[0].timestamp);
|
|
||||||
checkDB(function (store) {
|
checkDB(function (store) {
|
||||||
let request = store.get(messageId);
|
let request = store.get(messageId);
|
||||||
request.onsuccess = function onsuccess() {
|
request.onsuccess = function onsuccess() {
|
||||||
@ -262,9 +266,7 @@ add_test(function test_getMessage_success() {
|
|||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2].sender,
|
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
|
||||||
sms[2].body,
|
|
||||||
sms[2].timestamp);
|
|
||||||
SimpleTest.executeSoon(function () {
|
SimpleTest.executeSoon(function () {
|
||||||
gMobileMessageDatabaseService.getMessage(messageId, fakeRequestId);
|
gMobileMessageDatabaseService.getMessage(messageId, fakeRequestId);
|
||||||
});
|
});
|
||||||
@ -821,9 +823,7 @@ add_test(function test_deleteMessage_success() {
|
|||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0].sender,
|
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
|
||||||
sms[0].body,
|
|
||||||
sms[0].timestamp);
|
|
||||||
SimpleTest.executeSoon(function () {
|
SimpleTest.executeSoon(function () {
|
||||||
gMobileMessageDatabaseService.deleteMessage(messageId, fakeRequestId);
|
gMobileMessageDatabaseService.deleteMessage(messageId, fakeRequestId);
|
||||||
});
|
});
|
||||||
@ -852,9 +852,7 @@ add_test(function test_markMessageRead_success() {
|
|||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2].sender,
|
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
|
||||||
sms[2].body,
|
|
||||||
sms[2].timestamp);
|
|
||||||
SimpleTest.executeSoon(function () {
|
SimpleTest.executeSoon(function () {
|
||||||
gMobileMessageDatabaseService.markMessageRead(messageId, true, fakeRequestId);
|
gMobileMessageDatabaseService.markMessageRead(messageId, true, fakeRequestId);
|
||||||
});
|
});
|
||||||
|
@ -1476,6 +1476,18 @@ RadioInterfaceLayer.prototype = {
|
|||||||
0, options);
|
0, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createSmsMessageFromRecord: function createSmsMessageFromRecord(aRecord) {
|
||||||
|
return gSmsService.createSmsMessage(aRecord.id,
|
||||||
|
aRecord.delivery,
|
||||||
|
aRecord.deliveryStatus,
|
||||||
|
aRecord.sender,
|
||||||
|
aRecord.receiver,
|
||||||
|
aRecord.body,
|
||||||
|
aRecord.messageClass,
|
||||||
|
aRecord.timestamp,
|
||||||
|
aRecord.read);
|
||||||
|
},
|
||||||
|
|
||||||
portAddressedSmsApps: null,
|
portAddressedSmsApps: null,
|
||||||
handleSmsReceived: function handleSmsReceived(message) {
|
handleSmsReceived: function handleSmsReceived(message) {
|
||||||
debug("handleSmsReceived: " + JSON.stringify(message));
|
debug("handleSmsReceived: " + JSON.stringify(message));
|
||||||
@ -1501,6 +1513,11 @@ RadioInterfaceLayer.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.type = "sms";
|
||||||
|
message.sender = message.sender || null;
|
||||||
|
message.receiver = message.receiver || null;
|
||||||
|
message.body = message.fullBody = message.fullBody || null;
|
||||||
|
|
||||||
// TODO: Bug #768441
|
// TODO: Bug #768441
|
||||||
// For now we don't store indicators persistently. When the mwi.discard
|
// For now we don't store indicators persistently. When the mwi.discard
|
||||||
// flag is false, we'll need to persist the indicator to EFmwis.
|
// flag is false, we'll need to persist the indicator to EFmwis.
|
||||||
@ -1508,13 +1525,14 @@ RadioInterfaceLayer.prototype = {
|
|||||||
|
|
||||||
let mwi = message.mwi;
|
let mwi = message.mwi;
|
||||||
if (mwi) {
|
if (mwi) {
|
||||||
mwi.returnNumber = message.sender || null;
|
mwi.returnNumber = message.sender;
|
||||||
mwi.returnMessage = message.fullBody || null;
|
mwi.returnMessage = message.fullBody;
|
||||||
this._sendTargetMessage("voicemail", "RIL:VoicemailNotification", mwi);
|
this._sendTargetMessage("voicemail", "RIL:VoicemailNotification", mwi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let notifyReceived = function notifyReceived(rv, sms) {
|
let notifyReceived = function notifyReceived(rv, record) {
|
||||||
|
let sms = this.createSmsMessageFromRecord(record);
|
||||||
let success = Components.isSuccessCode(rv);
|
let success = Components.isSuccessCode(rv);
|
||||||
|
|
||||||
// Acknowledge the reception of the SMS.
|
// Acknowledge the reception of the SMS.
|
||||||
@ -1532,38 +1550,30 @@ RadioInterfaceLayer.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gSystemMessenger.broadcastMessage("sms-received", {
|
gSystemMessenger.broadcastMessage("sms-received", {
|
||||||
id: message.id,
|
id: message.id,
|
||||||
delivery: DOM_SMS_DELIVERY_RECEIVED,
|
delivery: DOM_SMS_DELIVERY_RECEIVED,
|
||||||
deliveryStatus: RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
deliveryStatus: RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
||||||
sender: message.sender || null,
|
sender: message.sender,
|
||||||
receiver: message.receiver || null,
|
receiver: message.receiver,
|
||||||
body: message.fullBody || null,
|
body: message.fullBody,
|
||||||
messageClass: message.messageClass,
|
messageClass: message.messageClass,
|
||||||
timestamp: message.timestamp,
|
timestamp: message.timestamp,
|
||||||
read: false
|
read: false
|
||||||
});
|
});
|
||||||
|
|
||||||
Services.obs.notifyObservers(sms, kSmsReceivedObserverTopic, null);
|
Services.obs.notifyObservers(sms, kSmsReceivedObserverTopic, null);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
|
if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
|
||||||
message.id = gMobileMessageDatabaseService.saveReceivedMessage(
|
message.id = gMobileMessageDatabaseService.saveReceivedMessage(message,
|
||||||
message.sender || null,
|
notifyReceived);
|
||||||
message.fullBody || null,
|
|
||||||
message.messageClass,
|
|
||||||
message.timestamp,
|
|
||||||
notifyReceived);
|
|
||||||
} else {
|
} else {
|
||||||
message.id = -1;
|
message.id = -1;
|
||||||
let sms = gSmsService.createSmsMessage(message.id,
|
message.delivery = DOM_SMS_DELIVERY_RECEIVED;
|
||||||
DOM_SMS_DELIVERY_RECEIVED,
|
message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
|
||||||
RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
message.read = false;
|
||||||
message.sender || null,
|
|
||||||
message.receiver || null,
|
notifyReceived(Cr.NS_OK, message);
|
||||||
message.fullBody || null,
|
|
||||||
message.messageClass,
|
|
||||||
message.timestamp,
|
|
||||||
false);
|
|
||||||
notifyReceived(Cr.NS_OK, sms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMS ACK will be sent in notifyReceived. Return false here.
|
// SMS ACK will be sent in notifyReceived. Return false here.
|
||||||
@ -1596,7 +1606,8 @@ RadioInterfaceLayer.prototype = {
|
|||||||
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
||||||
DOM_SMS_DELIVERY_SENT,
|
DOM_SMS_DELIVERY_SENT,
|
||||||
options.sms.deliveryStatus,
|
options.sms.deliveryStatus,
|
||||||
function notifyResult(rv, sms) {
|
function notifyResult(rv, record) {
|
||||||
|
let sms = this.createSmsMessageFromRecord(record);
|
||||||
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
||||||
gSystemMessenger.broadcastMessage("sms-sent",
|
gSystemMessenger.broadcastMessage("sms-sent",
|
||||||
{id: options.sms.id,
|
{id: options.sms.id,
|
||||||
@ -1634,13 +1645,14 @@ RadioInterfaceLayer.prototype = {
|
|||||||
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
||||||
options.sms.delivery,
|
options.sms.delivery,
|
||||||
message.deliveryStatus,
|
message.deliveryStatus,
|
||||||
function notifyResult(rv, sms) {
|
function notifyResult(rv, record) {
|
||||||
|
let sms = this.createSmsMessageFromRecord(record);
|
||||||
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
||||||
let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS)
|
let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS)
|
||||||
? kSmsDeliverySuccessObserverTopic
|
? kSmsDeliverySuccessObserverTopic
|
||||||
: kSmsDeliveryErrorObserverTopic;
|
: kSmsDeliveryErrorObserverTopic;
|
||||||
Services.obs.notifyObservers(sms, topic, null);
|
Services.obs.notifyObservers(sms, topic, null);
|
||||||
});
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSmsSendFailed: function handleSmsSendFailed(message) {
|
handleSmsSendFailed: function handleSmsSendFailed(message) {
|
||||||
@ -1662,11 +1674,12 @@ RadioInterfaceLayer.prototype = {
|
|||||||
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
||||||
DOM_SMS_DELIVERY_ERROR,
|
DOM_SMS_DELIVERY_ERROR,
|
||||||
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
|
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
|
||||||
function notifyResult(rv, sms) {
|
function notifyResult(rv, record) {
|
||||||
|
let sms = this.createSmsMessageFromRecord(record);
|
||||||
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
||||||
options.request.notifySendMessageFailed(error);
|
options.request.notifySendMessageFailed(error);
|
||||||
Services.obs.notifyObservers(sms, kSmsFailedObserverTopic, null);
|
Services.obs.notifyObservers(sms, kSmsFailedObserverTopic, null);
|
||||||
});
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2645,8 +2658,17 @@ RadioInterfaceLayer.prototype = {
|
|||||||
let deliveryStatus = options.requestStatusReport
|
let deliveryStatus = options.requestStatusReport
|
||||||
? RIL.GECKO_SMS_DELIVERY_STATUS_PENDING
|
? RIL.GECKO_SMS_DELIVERY_STATUS_PENDING
|
||||||
: RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE;
|
: RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE;
|
||||||
let id = gMobileMessageDatabaseService.saveSendingMessage(number, message, deliveryStatus, timestamp,
|
let sendingMessage = {
|
||||||
function notifyResult(rv, sms) {
|
type: "sms",
|
||||||
|
receiver: number,
|
||||||
|
body: message,
|
||||||
|
deliveryStatus: deliveryStatus,
|
||||||
|
timestamp: timestamp
|
||||||
|
};
|
||||||
|
|
||||||
|
let id = gMobileMessageDatabaseService.saveSendingMessage(sendingMessage,
|
||||||
|
function notifyResult(rv, record) {
|
||||||
|
let sms = this.createSmsMessageFromRecord(record);
|
||||||
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
||||||
Services.obs.notifyObservers(sms, kSmsSendingObserverTopic, null);
|
Services.obs.notifyObservers(sms, kSmsSendingObserverTopic, null);
|
||||||
|
|
||||||
|
@ -49,6 +49,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(false, "'XMLHttpRequest.prototype' shouldn't throw in a sandbox");
|
ok(false, "'XMLHttpRequest.prototype' shouldn't throw in a sandbox");
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
var img = Components.utils.evalInSandbox("Image.prototype", sandbox);
|
||||||
|
ok(img, "'Image.prototype' in a sandbox should return the interface prototype object");
|
||||||
|
ok(isXrayWrapper(img), "Getting an interface prototype object on an Xray wrapper should return an Xray wrapper");
|
||||||
|
} catch (e) {
|
||||||
|
ok(false, "'Image.prototype' shouldn't throw in a sandbox");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox);
|
var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox);
|
||||||
xhr.prototype = false;
|
xhr.prototype = false;
|
||||||
|
@ -85,7 +85,8 @@ function testElementFromPoint() {
|
|||||||
moveEl.style.left = moveX + "px";
|
moveEl.style.left = moveX + "px";
|
||||||
moveEl.style.top = moveY + "px";
|
moveEl.style.top = moveY + "px";
|
||||||
}
|
}
|
||||||
let found = domWindowUtils.elementFromPoint(x, y, ignoreScroll, flushLayout);
|
let found = SpecialPowers.unwrap(domWindowUtils.elementFromPoint(
|
||||||
|
x, y, ignoreScroll, flushLayout));
|
||||||
is(found, expected, "at index " + i + " for data " + testData[i][0].toSource());
|
is(found, expected, "at index " + i + " for data " + testData[i][0].toSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
function makeAllAppsLaunchable() {
|
function makeAllAppsLaunchable() {
|
||||||
var Webapps = {};
|
var Webapps = {};
|
||||||
SpecialPowers.wrap(Components).utils.import("resource://gre/modules/Webapps.jsm", Webapps);
|
SpecialPowers.Cu.import("resource://gre/modules/Webapps.jsm", Webapps);
|
||||||
var appRegistry = SpecialPowers.wrap(Webapps.DOMApplicationRegistry);
|
var appRegistry = SpecialPowers.wrap(Webapps.DOMApplicationRegistry);
|
||||||
|
|
||||||
var originalValue = appRegistry.allAppsLaunchable;
|
var originalValue = appRegistry.allAppsLaunchable;
|
||||||
|
@ -1489,6 +1489,14 @@ void AsyncPanZoomController::UpdateZoomConstraints(bool aAllowZoom,
|
|||||||
mMaxZoom = aMaxZoom;
|
mMaxZoom = aMaxZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AsyncPanZoomController::PostDelayedTask(Task* aTask, int aDelayMs) {
|
||||||
|
if (!mGeckoContentController) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mGeckoContentController->PostDelayedTask(aTask, aDelayMs);
|
||||||
|
}
|
||||||
|
|
||||||
void AsyncPanZoomController::SendAsyncScrollEvent() {
|
void AsyncPanZoomController::SendAsyncScrollEvent() {
|
||||||
if (!mGeckoContentController) {
|
if (!mGeckoContentController) {
|
||||||
return;
|
return;
|
||||||
|
@ -151,6 +151,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void UpdateZoomConstraints(bool aAllowZoom, float aMinScale, float aMaxScale);
|
void UpdateZoomConstraints(bool aAllowZoom, float aMinScale, float aMaxScale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a runnable to run on the controller/UI thread at some time
|
||||||
|
* in the future.
|
||||||
|
*/
|
||||||
|
void PostDelayedTask(Task* aTask, int aDelayMs);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// These methods must only be called on the compositor thread.
|
// These methods must only be called on the compositor thread.
|
||||||
//
|
//
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "FrameMetrics.h"
|
#include "FrameMetrics.h"
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
|
class Task;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
@ -52,6 +54,12 @@ public:
|
|||||||
virtual void SendAsyncScrollDOMEvent(const gfx::Rect &aContentRect,
|
virtual void SendAsyncScrollDOMEvent(const gfx::Rect &aContentRect,
|
||||||
const gfx::Size &aScrollableSize) = 0;
|
const gfx::Size &aScrollableSize) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a runnable to run on the controller/UI thread at some time
|
||||||
|
* in the future.
|
||||||
|
*/
|
||||||
|
virtual void PostDelayedTask(Task* aTask, int aDelayMs) = 0;
|
||||||
|
|
||||||
GeckoContentController() {}
|
GeckoContentController() {}
|
||||||
virtual ~GeckoContentController() {}
|
virtual ~GeckoContentController() {}
|
||||||
};
|
};
|
||||||
|
@ -88,8 +88,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
|
|||||||
mLongTapTimeoutTask =
|
mLongTapTimeoutTask =
|
||||||
NewRunnableMethod(this, &GestureEventListener::TimeoutLongTap);
|
NewRunnableMethod(this, &GestureEventListener::TimeoutLongTap);
|
||||||
|
|
||||||
MessageLoop::current()->PostDelayedTask(
|
mAsyncPanZoomController->PostDelayedTask(
|
||||||
FROM_HERE,
|
|
||||||
mLongTapTimeoutTask,
|
mLongTapTimeoutTask,
|
||||||
Preferences::GetInt("ui.click_hold_context_menus.delay", 500));
|
Preferences::GetInt("ui.click_hold_context_menus.delay", 500));
|
||||||
}
|
}
|
||||||
@ -169,8 +168,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
|
|||||||
mDoubleTapTimeoutTask =
|
mDoubleTapTimeoutTask =
|
||||||
NewRunnableMethod(this, &GestureEventListener::TimeoutDoubleTap);
|
NewRunnableMethod(this, &GestureEventListener::TimeoutDoubleTap);
|
||||||
|
|
||||||
MessageLoop::current()->PostDelayedTask(
|
mAsyncPanZoomController->PostDelayedTask(
|
||||||
FROM_HERE,
|
|
||||||
mDoubleTapTimeoutTask,
|
mDoubleTapTimeoutTask,
|
||||||
MAX_TAP_TIME);
|
MAX_TAP_TIME);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=4 ts=8 et tw=80 : */ /* 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
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||||
|
/* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef mozilla_layers_GestureEventListener_h
|
#ifndef mozilla_layers_GestureEventListener_h
|
||||||
|
@ -121,7 +121,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||||||
return;
|
return;
|
||||||
} else if (aData.mDrawTarget) {
|
} else if (aData.mDrawTarget) {
|
||||||
mDrawTarget = aData.mDrawTarget;
|
mDrawTarget = aData.mDrawTarget;
|
||||||
mCanvasSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
mCanvasSurface = gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
|
||||||
mNeedsYFlip = false;
|
mNeedsYFlip = false;
|
||||||
} else if (aData.mSurface) {
|
} else if (aData.mSurface) {
|
||||||
mCanvasSurface = aData.mSurface;
|
mCanvasSurface = aData.mSurface;
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<iframe src=discardframe.htm></iframe>
|
<iframe src=discardframe.htm></iframe>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
const Ci = Components.interfaces;
|
const Ci = SpecialPowers.Ci;
|
||||||
const Cc = SpecialPowers.wrap(Components).classes;
|
const Cc = SpecialPowers.Cc;
|
||||||
|
|
||||||
function ImageDecoderObserverStub()
|
function ImageDecoderObserverStub()
|
||||||
{
|
{
|
||||||
|
@ -480,7 +480,7 @@ ObjectWrapperChild::AnswerNewEnumerateNext(const JSVariant& in_state,
|
|||||||
|
|
||||||
int32_t i = JSVAL_TO_INT(v);
|
int32_t i = JSVAL_TO_INT(v);
|
||||||
NS_ASSERTION(i >= 0, "Index of next jsid negative?");
|
NS_ASSERTION(i >= 0, "Index of next jsid negative?");
|
||||||
NS_ASSERTION(i <= strIds->Length(), "Index of next jsid too large?");
|
NS_ASSERTION(size_t(i) <= strIds->Length(), "Index of next jsid too large?");
|
||||||
|
|
||||||
if (size_t(i) == strIds->Length()) {
|
if (size_t(i) == strIds->Length()) {
|
||||||
*status = JS_TRUE;
|
*status = JS_TRUE;
|
||||||
|
@ -94,6 +94,15 @@ if test "$CLANG_CXX"; then
|
|||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-mismatched-tags"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-mismatched-tags"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -z "$GNU_CC"; then
|
||||||
|
case "$target" in
|
||||||
|
*-mingw*)
|
||||||
|
## Warning 4099 (equivalent of mismatched-tags) is disabled (bug 780474)
|
||||||
|
## for the same reasons as above.
|
||||||
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -wd4099"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$GNU_CC"; then
|
if test "$GNU_CC"; then
|
||||||
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
||||||
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
|
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
|
||||||
|
@ -1684,7 +1684,8 @@ ia64*-hpux*)
|
|||||||
CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
||||||
CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
||||||
# MSVC warning C4244 is ubiquitous, useless, and annoying.
|
# MSVC warning C4244 is ubiquitous, useless, and annoying.
|
||||||
CXXFLAGS="$CXXFLAGS -wd4244"
|
# khuey says we can safely ignore MSVC warning C4251
|
||||||
|
CXXFLAGS="$CXXFLAGS -wd4244 -wd4251"
|
||||||
# make 'foo == bar;' error out
|
# make 'foo == bar;' error out
|
||||||
CFLAGS="$CFLAGS -we4553"
|
CFLAGS="$CFLAGS -we4553"
|
||||||
CXXFLAGS="$CXXFLAGS -we4553"
|
CXXFLAGS="$CXXFLAGS -we4553"
|
||||||
|
@ -1472,8 +1472,7 @@ ion::CanEnterAtBranch(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MethodStatus
|
MethodStatus
|
||||||
ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp, bool isConstructing)
|
||||||
bool isConstructing, bool newType)
|
|
||||||
{
|
{
|
||||||
JS_ASSERT(ion::IsEnabled(cx));
|
JS_ASSERT(ion::IsEnabled(cx));
|
||||||
|
|
||||||
@ -1495,8 +1494,8 @@ ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
|||||||
if (isConstructing && fp.thisValue().isPrimitive()) {
|
if (isConstructing && fp.thisValue().isPrimitive()) {
|
||||||
RootedScript scriptRoot(cx, script);
|
RootedScript scriptRoot(cx, script);
|
||||||
RootedObject callee(cx, &fp.callee());
|
RootedObject callee(cx, &fp.callee());
|
||||||
RootedObject obj(cx, CreateThisForFunction(cx, callee, newType));
|
RootedObject obj(cx, CreateThisForFunction(cx, callee, fp.useNewType()));
|
||||||
if (!obj)
|
if (!obj || !ion::IsEnabled(cx)) // Note: OOM under CreateThis can disable TI.
|
||||||
return Method_Skipped;
|
return Method_Skipped;
|
||||||
fp.thisValue().setObject(*obj);
|
fp.thisValue().setObject(*obj);
|
||||||
script = scriptRoot;
|
script = scriptRoot;
|
||||||
|
@ -261,8 +261,7 @@ bool SetIonContext(IonContext *ctx);
|
|||||||
|
|
||||||
MethodStatus CanEnterAtBranch(JSContext *cx, JSScript *script,
|
MethodStatus CanEnterAtBranch(JSContext *cx, JSScript *script,
|
||||||
AbstractFramePtr fp, jsbytecode *pc, bool isConstructing);
|
AbstractFramePtr fp, jsbytecode *pc, bool isConstructing);
|
||||||
MethodStatus CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
MethodStatus CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp, bool isConstructing);
|
||||||
bool isConstructing, bool newType);
|
|
||||||
MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs);
|
MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs);
|
||||||
|
|
||||||
enum IonExecStatus
|
enum IonExecStatus
|
||||||
|
@ -4488,15 +4488,14 @@ IonBuilder::jsop_eval(uint32_t argc)
|
|||||||
return abort("Direct eval in global code");
|
return abort("Direct eval in global code");
|
||||||
|
|
||||||
types::StackTypeSet *thisTypes = oracle->thisTypeSet(script());
|
types::StackTypeSet *thisTypes = oracle->thisTypeSet(script());
|
||||||
if (!thisTypes) {
|
|
||||||
// The 'this' value for the outer and eval scripts must be the
|
// The 'this' value for the outer and eval scripts must be the
|
||||||
// same. This is not guaranteed if a primitive string/number/etc.
|
// same. This is not guaranteed if a primitive string/number/etc.
|
||||||
// is passed through to the eval invoke as the primitive may be
|
// is passed through to the eval invoke as the primitive may be
|
||||||
// boxed into different objects if accessed via 'this'.
|
// boxed into different objects if accessed via 'this'.
|
||||||
JSValueType type = thisTypes->getKnownTypeTag();
|
JSValueType type = thisTypes->getKnownTypeTag();
|
||||||
if (type != JSVAL_TYPE_OBJECT && type != JSVAL_TYPE_NULL && type != JSVAL_TYPE_UNDEFINED)
|
if (type != JSVAL_TYPE_OBJECT && type != JSVAL_TYPE_NULL && type != JSVAL_TYPE_UNDEFINED)
|
||||||
return abort("Direct eval from script with maybe-primitive 'this'");
|
return abort("Direct eval from script with maybe-primitive 'this'");
|
||||||
}
|
|
||||||
|
|
||||||
CallInfo callInfo(cx, /* constructing = */ false);
|
CallInfo callInfo(cx, /* constructing = */ false);
|
||||||
if (!callInfo.init(current, argc))
|
if (!callInfo.init(current, argc))
|
||||||
|
19
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-01.js
Normal file
19
js/src/jit-test/tests/debug/Script-getAllColumnOffsets-01.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// getColumnOffsets correctly places the various parts of a ForStatement.
|
||||||
|
|
||||||
|
var global = newGlobal('new-compartment');
|
||||||
|
Debugger(global).onDebuggerStatement = function (frame) {
|
||||||
|
var script = frame.eval("f").return.script;
|
||||||
|
script.getAllColumnOffsets().forEach(function (offset) {
|
||||||
|
script.setBreakpoint(offset.offset, {
|
||||||
|
hit: function (frame) {
|
||||||
|
assertEq(offset.lineNumber, 17);
|
||||||
|
global.log += offset.columnNumber + " ";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
global.log = '';
|
||||||
|
global.eval("function f(n) { for (var i = 0; i < n; ++i) log += '. '; log += '! '; } debugger;");
|
||||||
|
global.f(3);
|
||||||
|
assertEq(global.log, "21 32 44 . 39 32 44 . 39 32 44 . 39 32 57 ! 69 ");
|
6
js/src/jit-test/tests/ion/bug844364.js
Normal file
6
js/src/jit-test/tests/ion/bug844364.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
function f() {
|
||||||
|
eval("this")
|
||||||
|
}
|
||||||
|
f()
|
||||||
|
f()
|
7
js/src/jit-test/tests/ion/bug844459.js
Normal file
7
js/src/jit-test/tests/ion/bug844459.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
function testEvalThrow(x, y) {
|
||||||
|
eval("");
|
||||||
|
}
|
||||||
|
for (var i = 0; i < 5; i++)
|
||||||
|
testEvalThrow.call("");
|
@ -79,8 +79,8 @@ MSG_DEF(JSMSG_TOO_DEEP, 25, 1, JSEXN_INTERNALERR, "{0} nested too
|
|||||||
MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_INTERNALERR, "too much recursion")
|
MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_INTERNALERR, "too much recursion")
|
||||||
MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}")
|
MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}")
|
||||||
MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_TYPEERR, "invalid new expression result {0}")
|
MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_TYPEERR, "invalid new expression result {0}")
|
||||||
MSG_DEF(JSMSG_UNUSED29, 29, 0, JSEXN_NONE, "")
|
MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED, 29, 0, JSEXN_ERR, "Permission denied to access object")
|
||||||
MSG_DEF(JSMSG_UNUSED30, 30, 0, JSEXN_NONE, "")
|
MSG_DEF(JSMSG_PROPERTY_ACCESS_DENIED, 30, 1, JSEXN_ERR, "Permission denied to access property '{0}'")
|
||||||
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
|
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
|
||||||
MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
|
MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
|
||||||
MSG_DEF(JSMSG_BAD_RADIX, 33, 0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36")
|
MSG_DEF(JSMSG_BAD_RADIX, 33, 0, JSEXN_RANGEERR, "radix must be an integer at least 2 and no greater than 36")
|
||||||
|
@ -881,6 +881,9 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
|||||||
ionReturnOverride_(MagicValue(JS_ARG_POISON)),
|
ionReturnOverride_(MagicValue(JS_ARG_POISON)),
|
||||||
useHelperThreads_(useHelperThreads),
|
useHelperThreads_(useHelperThreads),
|
||||||
requestedHelperThreadCount(-1),
|
requestedHelperThreadCount(-1),
|
||||||
|
#ifdef DEBUG
|
||||||
|
enteredPolicy(NULL),
|
||||||
|
#endif
|
||||||
rngNonce(0)
|
rngNonce(0)
|
||||||
{
|
{
|
||||||
/* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
|
/* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
|
||||||
|
@ -569,7 +569,7 @@ struct MallocProvider
|
|||||||
namespace gc {
|
namespace gc {
|
||||||
class MarkingValidator;
|
class MarkingValidator;
|
||||||
} // namespace gc
|
} // namespace gc
|
||||||
|
class AutoEnterPolicy;
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
struct JSRuntime : js::RuntimeFriendFields,
|
struct JSRuntime : js::RuntimeFriendFields,
|
||||||
@ -1301,7 +1301,11 @@ struct JSRuntime : js::RuntimeFriendFields,
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
public:
|
||||||
|
js::AutoEnterPolicy *enteredPolicy;
|
||||||
|
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* Used to ensure that compartments created at the same time get different
|
* Used to ensure that compartments created at the same time get different
|
||||||
|
@ -432,6 +432,7 @@ JSCompartment::wrap(JSContext *cx, JSObject **objp, JSObject *existingArg)
|
|||||||
bool
|
bool
|
||||||
JSCompartment::wrapId(JSContext *cx, jsid *idp)
|
JSCompartment::wrapId(JSContext *cx, jsid *idp)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(*idp != JSID_VOID, "JSID_VOID is an out-of-band sentinel value");
|
||||||
if (JSID_IS_INT(*idp))
|
if (JSID_IS_INT(*idp))
|
||||||
return true;
|
return true;
|
||||||
RootedValue value(cx, IdToValue(*idp));
|
RootedValue value(cx, IdToValue(*idp));
|
||||||
|
@ -1416,6 +1416,13 @@ class JS_FRIEND_API(AutoCTypesActivityCallback) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
extern JS_FRIEND_API(void)
|
||||||
|
assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id);
|
||||||
|
#else
|
||||||
|
inline JS_FRIEND_API(void) assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id) {};
|
||||||
|
#endif
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
#endif /* jsfriendapi_h___ */
|
#endif /* jsfriendapi_h___ */
|
||||||
|
@ -276,6 +276,22 @@ js::RunScript(JSContext *cx, StackFrame *fp)
|
|||||||
|
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
|
|
||||||
|
// Check to see if useNewType flag should be set for this frame.
|
||||||
|
if (fp->isFunctionFrame() && fp->isConstructing() && !fp->isGeneratorFrame() &&
|
||||||
|
cx->typeInferenceEnabled())
|
||||||
|
{
|
||||||
|
StackIter iter(cx);
|
||||||
|
if (!iter.done()) {
|
||||||
|
++iter;
|
||||||
|
if (iter.isScript()) {
|
||||||
|
RawScript script = iter.script();
|
||||||
|
jsbytecode *pc = iter.pc();
|
||||||
|
if (UseNewType(cx, script, pc))
|
||||||
|
fp->setUseNewType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
struct CheckStackBalance {
|
struct CheckStackBalance {
|
||||||
JSContext *cx;
|
JSContext *cx;
|
||||||
@ -294,7 +310,7 @@ js::RunScript(JSContext *cx, StackFrame *fp)
|
|||||||
#ifdef JS_ION
|
#ifdef JS_ION
|
||||||
if (ion::IsEnabled(cx)) {
|
if (ion::IsEnabled(cx)) {
|
||||||
ion::MethodStatus status = ion::CanEnter(cx, script, AbstractFramePtr(fp),
|
ion::MethodStatus status = ion::CanEnter(cx, script, AbstractFramePtr(fp),
|
||||||
fp->isConstructing(), false);
|
fp->isConstructing());
|
||||||
if (status == ion::Method_Error)
|
if (status == ion::Method_Error)
|
||||||
return false;
|
return false;
|
||||||
if (status == ion::Method_Compiled) {
|
if (status == ion::Method_Compiled) {
|
||||||
@ -1159,7 +1175,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
|||||||
if (interpMode == JSINTERP_NORMAL) {
|
if (interpMode == JSINTERP_NORMAL) {
|
||||||
StackFrame *fp = regs.fp();
|
StackFrame *fp = regs.fp();
|
||||||
if (!fp->isGeneratorFrame()) {
|
if (!fp->isGeneratorFrame()) {
|
||||||
if (!fp->prologue(cx, UseNewTypeAtEntry(cx, fp)))
|
if (!fp->prologue(cx))
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
Probes::enterScript(cx, script, script->function(), fp);
|
Probes::enterScript(cx, script, script->function(), fp);
|
||||||
@ -2361,6 +2377,9 @@ BEGIN_CASE(JSOP_FUNCALL)
|
|||||||
funScript = fun->nonLazyScript();
|
funScript = fun->nonLazyScript();
|
||||||
if (!cx->stack.pushInlineFrame(cx, regs, args, fun, funScript, initial))
|
if (!cx->stack.pushInlineFrame(cx, regs, args, fun, funScript, initial))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (newType)
|
||||||
|
regs.fp()->setUseNewType();
|
||||||
|
|
||||||
SET_SCRIPT(regs.fp()->script());
|
SET_SCRIPT(regs.fp()->script());
|
||||||
#ifdef JS_METHODJIT
|
#ifdef JS_METHODJIT
|
||||||
@ -2370,7 +2389,7 @@ BEGIN_CASE(JSOP_FUNCALL)
|
|||||||
#ifdef JS_ION
|
#ifdef JS_ION
|
||||||
if (!newType && ion::IsEnabled(cx)) {
|
if (!newType && ion::IsEnabled(cx)) {
|
||||||
ion::MethodStatus status = ion::CanEnter(cx, script, AbstractFramePtr(regs.fp()),
|
ion::MethodStatus status = ion::CanEnter(cx, script, AbstractFramePtr(regs.fp()),
|
||||||
regs.fp()->isConstructing(), newType);
|
regs.fp()->isConstructing());
|
||||||
if (status == ion::Method_Error)
|
if (status == ion::Method_Error)
|
||||||
goto error;
|
goto error;
|
||||||
if (status == ion::Method_Compiled) {
|
if (status == ion::Method_Compiled) {
|
||||||
@ -2405,7 +2424,7 @@ BEGIN_CASE(JSOP_FUNCALL)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!regs.fp()->prologue(cx, newType))
|
if (!regs.fp()->prologue(cx))
|
||||||
goto error;
|
goto error;
|
||||||
if (cx->compartment->debugMode()) {
|
if (cx->compartment->debugMode()) {
|
||||||
switch (ScriptDebugPrologue(cx, regs.fp())) {
|
switch (ScriptDebugPrologue(cx, regs.fp())) {
|
||||||
|
@ -97,9 +97,11 @@ ComputeThis(JSContext *cx, AbstractFramePtr frame)
|
|||||||
* |this| slot. If we lazily wrap a primitive |this| in an eval function frame, the
|
* |this| slot. If we lazily wrap a primitive |this| in an eval function frame, the
|
||||||
* eval's frame will get the wrapper, but the function's frame will not. To prevent
|
* eval's frame will get the wrapper, but the function's frame will not. To prevent
|
||||||
* this, we always wrap a function's |this| before pushing an eval frame, and should
|
* this, we always wrap a function's |this| before pushing an eval frame, and should
|
||||||
* thus never see an unwrapped primitive in a non-strict eval function frame.
|
* thus never see an unwrapped primitive in a non-strict eval function frame. Null
|
||||||
|
* and undefined |this| values will unwrap to the same object in the function and
|
||||||
|
* eval frames, so are not required to be wrapped.
|
||||||
*/
|
*/
|
||||||
JS_ASSERT(!frame.isEvalFrame());
|
JS_ASSERT_IF(frame.isEvalFrame(), thisv.isUndefined() || thisv.isNull());
|
||||||
}
|
}
|
||||||
bool modified;
|
bool modified;
|
||||||
if (!BoxNonStrictThis(cx, &thisv, &modified))
|
if (!BoxNonStrictThis(cx, &thisv, &modified))
|
||||||
|
@ -1226,9 +1226,6 @@ ExpressionDecompiler::decompilePC(jsbytecode *pc)
|
|||||||
|
|
||||||
JSOp op = (JSOp)*pc;
|
JSOp op = (JSOp)*pc;
|
||||||
|
|
||||||
// None of these stack-writing ops generates novel values.
|
|
||||||
JS_ASSERT(op != JSOP_CASE && op != JSOP_DUP && op != JSOP_DUP2);
|
|
||||||
|
|
||||||
if (const char *token = CodeToken[op]) {
|
if (const char *token = CodeToken[op]) {
|
||||||
// Handle simple cases of binary and unary operators.
|
// Handle simple cases of binary and unary operators.
|
||||||
switch (js_CodeSpec[op].nuses) {
|
switch (js_CodeSpec[op].nuses) {
|
||||||
@ -2257,6 +2254,9 @@ GetPCCountJSON(JSContext *cx, const ScriptAndCounts &sac, StringBuffer &buf)
|
|||||||
|
|
||||||
buf.append(str);
|
buf.append(str);
|
||||||
|
|
||||||
|
AppendJSONProperty(buf, "line");
|
||||||
|
NumberValueToStringBuffer(cx, Int32Value(script->lineno), buf);
|
||||||
|
|
||||||
AppendJSONProperty(buf, "opcodes");
|
AppendJSONProperty(buf, "opcodes");
|
||||||
buf.append('[');
|
buf.append('[');
|
||||||
bool comma = false;
|
bool comma = false;
|
||||||
|
@ -49,9 +49,56 @@ GetFunctionProxyConstruct(UnrootedObject proxy)
|
|||||||
return proxy->getSlotRef(JSSLOT_PROXY_CONSTRUCT);
|
return proxy->getSlotRef(JSSLOT_PROXY_CONSTRUCT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
js::AutoEnterPolicy::reportError(JSContext *cx, jsid id)
|
||||||
|
{
|
||||||
|
if (JSID_IS_VOID(id)) {
|
||||||
|
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||||
|
JSMSG_OBJECT_ACCESS_DENIED);
|
||||||
|
} else {
|
||||||
|
JSString *str = IdToString(cx, id);
|
||||||
|
const jschar *prop = str ? str->getCharsZ(cx) : NULL;
|
||||||
|
JS_ReportErrorNumberUC(cx, js_GetErrorMessage, NULL,
|
||||||
|
JSMSG_PROPERTY_ACCESS_DENIED, prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
void
|
||||||
|
js::AutoEnterPolicy::recordEnter(JSContext *cx, JSObject *proxy, jsid id)
|
||||||
|
{
|
||||||
|
if (allowed()) {
|
||||||
|
context = cx;
|
||||||
|
enteredProxy.construct(cx, proxy);
|
||||||
|
enteredId.construct(cx, id);
|
||||||
|
prev = cx->runtime->enteredPolicy;
|
||||||
|
cx->runtime->enteredPolicy = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
js::AutoEnterPolicy::recordLeave()
|
||||||
|
{
|
||||||
|
if (!enteredProxy.empty()) {
|
||||||
|
JS_ASSERT(context->runtime->enteredPolicy == this);
|
||||||
|
context->runtime->enteredPolicy = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_FRIEND_API(void)
|
||||||
|
js::assertEnteredPolicy(JSContext *cx, JSObject *proxy, jsid id)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(proxy->isProxy());
|
||||||
|
MOZ_ASSERT(cx->runtime->enteredPolicy);
|
||||||
|
MOZ_ASSERT(cx->runtime->enteredPolicy->enteredProxy.ref().get() == proxy);
|
||||||
|
MOZ_ASSERT(cx->runtime->enteredPolicy->enteredId.ref().get() == id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BaseProxyHandler::BaseProxyHandler(void *family)
|
BaseProxyHandler::BaseProxyHandler(void *family)
|
||||||
: mFamily(family),
|
: mFamily(family),
|
||||||
mHasPrototype(false)
|
mHasPrototype(false),
|
||||||
|
mHasPolicy(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,9 +106,18 @@ BaseProxyHandler::~BaseProxyHandler()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BaseProxyHandler::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act,
|
||||||
|
bool *bp)
|
||||||
|
{
|
||||||
|
*bp = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BaseProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
BaseProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy_, id_);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
AutoPropertyDescriptorRooter desc(cx);
|
AutoPropertyDescriptorRooter desc(cx);
|
||||||
@ -74,6 +130,7 @@ BaseProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
|||||||
bool
|
bool
|
||||||
BaseProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
BaseProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy_, id_);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
AutoPropertyDescriptorRooter desc(cx);
|
AutoPropertyDescriptorRooter desc(cx);
|
||||||
@ -86,6 +143,7 @@ BaseProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
|||||||
bool
|
bool
|
||||||
BaseProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver_, jsid id_, Value *vp)
|
BaseProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver_, jsid id_, Value *vp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id_);
|
||||||
RootedObject receiver(cx, receiver_);
|
RootedObject receiver(cx, receiver_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
|
|
||||||
@ -127,6 +185,7 @@ BaseProxyHandler::getElementIfPresent(JSContext *cx, JSObject *proxy_, JSObject
|
|||||||
RootedId id(cx);
|
RootedId id(cx);
|
||||||
if (!IndexToId(cx, index, &id))
|
if (!IndexToId(cx, index, &id))
|
||||||
return false;
|
return false;
|
||||||
|
assertEnteredPolicy(cx, proxy, id);
|
||||||
|
|
||||||
if (!has(cx, proxy, id, present))
|
if (!has(cx, proxy, id, present))
|
||||||
return false;
|
return false;
|
||||||
@ -143,6 +202,7 @@ bool
|
|||||||
BaseProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid id_, bool strict,
|
BaseProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid id_, bool strict,
|
||||||
Value *vp)
|
Value *vp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy_, id_);
|
||||||
RootedObject proxy(cx, proxy_), receiver(cx, receiver_);
|
RootedObject proxy(cx, proxy_), receiver(cx, receiver_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
|
|
||||||
@ -219,6 +279,7 @@ BaseProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid
|
|||||||
bool
|
bool
|
||||||
BaseProxyHandler::keys(JSContext *cx, JSObject *proxyArg, AutoIdVector &props)
|
BaseProxyHandler::keys(JSContext *cx, JSObject *proxyArg, AutoIdVector &props)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxyArg, JSID_VOID);
|
||||||
JS_ASSERT(props.length() == 0);
|
JS_ASSERT(props.length() == 0);
|
||||||
|
|
||||||
RootedObject proxy(cx, proxyArg);
|
RootedObject proxy(cx, proxyArg);
|
||||||
@ -232,6 +293,7 @@ BaseProxyHandler::keys(JSContext *cx, JSObject *proxyArg, AutoIdVector &props)
|
|||||||
for (size_t j = 0, len = props.length(); j < len; j++) {
|
for (size_t j = 0, len = props.length(); j < len; j++) {
|
||||||
JS_ASSERT(i <= j);
|
JS_ASSERT(i <= j);
|
||||||
jsid id = props[j];
|
jsid id = props[j];
|
||||||
|
AutoWaivePolicy policy(cx, proxy, id);
|
||||||
if (!getOwnPropertyDescriptor(cx, proxy, id, &desc, 0))
|
if (!getOwnPropertyDescriptor(cx, proxy, id, &desc, 0))
|
||||||
return false;
|
return false;
|
||||||
if (desc.obj && (desc.attrs & JSPROP_ENUMERATE))
|
if (desc.obj && (desc.attrs & JSPROP_ENUMERATE))
|
||||||
@ -247,6 +309,7 @@ BaseProxyHandler::keys(JSContext *cx, JSObject *proxyArg, AutoIdVector &props)
|
|||||||
bool
|
bool
|
||||||
BaseProxyHandler::iterate(JSContext *cx, JSObject *proxy_, unsigned flags, Value *vp)
|
BaseProxyHandler::iterate(JSContext *cx, JSObject *proxy_, unsigned flags, Value *vp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy_, JSID_VOID);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
|
|
||||||
AutoIdVector props(cx);
|
AutoIdVector props(cx);
|
||||||
@ -268,6 +331,7 @@ bool
|
|||||||
BaseProxyHandler::call(JSContext *cx, JSObject *proxy, unsigned argc,
|
BaseProxyHandler::call(JSContext *cx, JSObject *proxy, unsigned argc,
|
||||||
Value *vp)
|
Value *vp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
AutoValueRooter rval(cx);
|
AutoValueRooter rval(cx);
|
||||||
RootedValue call(cx, GetCall(proxy));
|
RootedValue call(cx, GetCall(proxy));
|
||||||
JSBool ok = Invoke(cx, vp[1], call, argc, JS_ARGV(cx, vp), rval.addr());
|
JSBool ok = Invoke(cx, vp[1], call, argc, JS_ARGV(cx, vp), rval.addr());
|
||||||
@ -280,6 +344,7 @@ bool
|
|||||||
BaseProxyHandler::construct(JSContext *cx, JSObject *proxy_, unsigned argc,
|
BaseProxyHandler::construct(JSContext *cx, JSObject *proxy_, unsigned argc,
|
||||||
Value *argv, Value *rval)
|
Value *argv, Value *rval)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy_, JSID_VOID);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
RootedValue fval(cx, GetConstruct(proxy_));
|
RootedValue fval(cx, GetConstruct(proxy_));
|
||||||
if (fval.isUndefined())
|
if (fval.isUndefined())
|
||||||
@ -298,6 +363,7 @@ BaseProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
|
|||||||
JSString *
|
JSString *
|
||||||
BaseProxyHandler::fun_toString(JSContext *cx, JSObject *proxy, unsigned indent)
|
BaseProxyHandler::fun_toString(JSContext *cx, JSObject *proxy, unsigned indent)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
Value fval = GetCall(proxy);
|
Value fval = GetCall(proxy);
|
||||||
if (IsFunctionProxy(proxy) &&
|
if (IsFunctionProxy(proxy) &&
|
||||||
(fval.isPrimitive() || !fval.toObject().isFunction())) {
|
(fval.isPrimitive() || !fval.toObject().isFunction())) {
|
||||||
@ -343,6 +409,7 @@ BaseProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl im
|
|||||||
bool
|
bool
|
||||||
BaseProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
|
BaseProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
RootedValue val(cx, ObjectValue(*proxy.get()));
|
RootedValue val(cx, ObjectValue(*proxy.get()));
|
||||||
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
|
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
|
||||||
JSDVG_SEARCH_STACK, val, NullPtr());
|
JSDVG_SEARCH_STACK, val, NullPtr());
|
||||||
@ -379,6 +446,8 @@ bool
|
|||||||
DirectProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
DirectProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
||||||
jsid id, PropertyDescriptor *desc, unsigned flags)
|
jsid id, PropertyDescriptor *desc, unsigned flags)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id);
|
||||||
|
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
return JS_GetPropertyDescriptorById(cx, target, id, 0, desc);
|
return JS_GetPropertyDescriptorById(cx, target, id, 0, desc);
|
||||||
}
|
}
|
||||||
@ -403,6 +472,7 @@ bool
|
|||||||
DirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
DirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
||||||
jsid id, PropertyDescriptor *desc, unsigned flags)
|
jsid id, PropertyDescriptor *desc, unsigned flags)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id);
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
return GetOwnPropertyDescriptor(cx, target, id, 0, desc);
|
return GetOwnPropertyDescriptor(cx, target, id, 0, desc);
|
||||||
}
|
}
|
||||||
@ -411,6 +481,7 @@ bool
|
|||||||
DirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
|
DirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
|
||||||
PropertyDescriptor *desc)
|
PropertyDescriptor *desc)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id_);
|
||||||
RootedObject obj(cx, GetProxyTargetObject(proxy));
|
RootedObject obj(cx, GetProxyTargetObject(proxy));
|
||||||
Rooted<jsid> id(cx, id_);
|
Rooted<jsid> id(cx, id_);
|
||||||
Rooted<Value> v(cx, desc->value);
|
Rooted<Value> v(cx, desc->value);
|
||||||
@ -422,6 +493,7 @@ bool
|
|||||||
DirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
|
DirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
|
||||||
AutoIdVector &props)
|
AutoIdVector &props)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
return GetPropertyNames(cx, target, JSITER_OWNONLY | JSITER_HIDDEN, &props);
|
return GetPropertyNames(cx, target, JSITER_OWNONLY | JSITER_HIDDEN, &props);
|
||||||
}
|
}
|
||||||
@ -430,6 +502,7 @@ bool
|
|||||||
DirectProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
DirectProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||||
{
|
{
|
||||||
RootedValue v(cx);
|
RootedValue v(cx);
|
||||||
|
assertEnteredPolicy(cx, proxy, id);
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
if (!JS_DeletePropertyById2(cx, target, id, v.address()))
|
if (!JS_DeletePropertyById2(cx, target, id, v.address()))
|
||||||
return false;
|
return false;
|
||||||
@ -444,6 +517,8 @@ bool
|
|||||||
DirectProxyHandler::enumerate(JSContext *cx, JSObject *proxy,
|
DirectProxyHandler::enumerate(JSContext *cx, JSObject *proxy,
|
||||||
AutoIdVector &props)
|
AutoIdVector &props)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
|
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
return GetPropertyNames(cx, target, 0, &props);
|
return GetPropertyNames(cx, target, 0, &props);
|
||||||
}
|
}
|
||||||
@ -465,6 +540,7 @@ bool
|
|||||||
DirectProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
|
DirectProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
|
||||||
bool *bp)
|
bool *bp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
JSBool b;
|
JSBool b;
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
if (!JS_HasInstance(cx, target, v, &b))
|
if (!JS_HasInstance(cx, target, v, &b))
|
||||||
@ -485,6 +561,7 @@ DirectProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue,
|
|||||||
JSString *
|
JSString *
|
||||||
DirectProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
|
DirectProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
return obj_toStringHelper(cx, GetProxyTargetObject(proxy));
|
return obj_toStringHelper(cx, GetProxyTargetObject(proxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,6 +569,7 @@ JSString *
|
|||||||
DirectProxyHandler::fun_toString(JSContext *cx, JSObject *proxy,
|
DirectProxyHandler::fun_toString(JSContext *cx, JSObject *proxy,
|
||||||
unsigned indent)
|
unsigned indent)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
return fun_toStringHelper(cx, target, indent);
|
return fun_toStringHelper(cx, target, indent);
|
||||||
}
|
}
|
||||||
@ -527,6 +605,8 @@ DirectProxyHandler::DirectProxyHandler(void *family)
|
|||||||
bool
|
bool
|
||||||
DirectProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
DirectProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id);
|
||||||
|
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||||
JSBool found;
|
JSBool found;
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
if (!JS_HasPropertyById(cx, target, id, &found))
|
if (!JS_HasPropertyById(cx, target, id, &found))
|
||||||
@ -538,6 +618,7 @@ DirectProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
|||||||
bool
|
bool
|
||||||
DirectProxyHandler::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
DirectProxyHandler::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id);
|
||||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||||
AutoPropertyDescriptorRooter desc(cx);
|
AutoPropertyDescriptorRooter desc(cx);
|
||||||
if (!JS_GetPropertyDescriptorById(cx, target, id, 0, &desc))
|
if (!JS_GetPropertyDescriptorById(cx, target, id, 0, &desc))
|
||||||
@ -550,6 +631,7 @@ bool
|
|||||||
DirectProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver_,
|
DirectProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver_,
|
||||||
jsid id_, Value *vp)
|
jsid id_, Value *vp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id_);
|
||||||
RootedObject receiver(cx, receiver_);
|
RootedObject receiver(cx, receiver_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
RootedValue value(cx);
|
RootedValue value(cx);
|
||||||
@ -565,6 +647,7 @@ bool
|
|||||||
DirectProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiverArg,
|
DirectProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiverArg,
|
||||||
jsid id_, bool strict, Value *vp)
|
jsid id_, bool strict, Value *vp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, id_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
Rooted<JSObject*> receiver(cx, receiverArg);
|
Rooted<JSObject*> receiver(cx, receiverArg);
|
||||||
RootedValue value(cx, *vp);
|
RootedValue value(cx, *vp);
|
||||||
@ -579,6 +662,7 @@ DirectProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiverArg,
|
|||||||
bool
|
bool
|
||||||
DirectProxyHandler::keys(JSContext *cx, JSObject *proxy, AutoIdVector &props)
|
DirectProxyHandler::keys(JSContext *cx, JSObject *proxy, AutoIdVector &props)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
return GetPropertyNames(cx, GetProxyTargetObject(proxy), JSITER_OWNONLY, &props);
|
return GetPropertyNames(cx, GetProxyTargetObject(proxy), JSITER_OWNONLY, &props);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,6 +670,8 @@ bool
|
|||||||
DirectProxyHandler::iterate(JSContext *cx, JSObject *proxy, unsigned flags,
|
DirectProxyHandler::iterate(JSContext *cx, JSObject *proxy, unsigned flags,
|
||||||
Value *vp)
|
Value *vp)
|
||||||
{
|
{
|
||||||
|
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||||
|
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||||
Rooted<JSObject*> target(cx, GetProxyTargetObject(proxy));
|
Rooted<JSObject*> target(cx, GetProxyTargetObject(proxy));
|
||||||
RootedValue value(cx);
|
RootedValue value(cx);
|
||||||
if (!GetIterator(cx, target, flags, &value))
|
if (!GetIterator(cx, target, flags, &value))
|
||||||
@ -2177,7 +2263,6 @@ ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
|
|||||||
return protoCall; \
|
return protoCall; \
|
||||||
JS_END_MACRO \
|
JS_END_MACRO \
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, PropertyDescriptor *desc,
|
Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, PropertyDescriptor *desc,
|
||||||
unsigned flags)
|
unsigned flags)
|
||||||
@ -2186,6 +2271,10 @@ Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, Property
|
|||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
desc->obj = NULL; // default result if we refuse to perform this action
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
if (!handler->hasPrototype())
|
if (!handler->hasPrototype())
|
||||||
return handler->getPropertyDescriptor(cx, proxy, id, desc, flags);
|
return handler->getPropertyDescriptor(cx, proxy, id, desc, flags);
|
||||||
if (!handler->getOwnPropertyDescriptor(cx, proxy, id, desc, flags))
|
if (!handler->getOwnPropertyDescriptor(cx, proxy, id, desc, flags))
|
||||||
@ -2218,7 +2307,12 @@ Proxy::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id, Proper
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
return GetProxyHandler(proxy)->getOwnPropertyDescriptor(cx, proxy, id, desc, flags);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
desc->obj = NULL; // default result if we refuse to perform this action
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
|
return handler->getOwnPropertyDescriptor(cx, proxy, id, desc, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2242,7 +2336,11 @@ bool
|
|||||||
Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id, PropertyDescriptor *desc)
|
Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id, PropertyDescriptor *desc)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
|
BaseProxyHandler *handler = GetProxyHandler(proxy_);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
return GetProxyHandler(proxy)->defineProperty(cx, proxy, id, desc);
|
return GetProxyHandler(proxy)->defineProperty(cx, proxy, id, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2261,7 +2359,11 @@ bool
|
|||||||
Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
|
Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
|
BaseProxyHandler *handler = GetProxyHandler(proxy_);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
return GetProxyHandler(proxy)->getOwnPropertyNames(cx, proxy, props);
|
return GetProxyHandler(proxy)->getOwnPropertyNames(cx, proxy, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2269,7 +2371,12 @@ bool
|
|||||||
Proxy::delete_(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
|
Proxy::delete_(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
|
BaseProxyHandler *handler = GetProxyHandler(proxy_);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
|
*bp = true; // default result if we refuse to perform this action
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
return GetProxyHandler(proxy)->delete_(cx, proxy, id, bp);
|
return GetProxyHandler(proxy)->delete_(cx, proxy, id, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2299,6 +2406,9 @@ Proxy::enumerate(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
|
|||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
if (!handler->hasPrototype())
|
if (!handler->hasPrototype())
|
||||||
return GetProxyHandler(proxy)->enumerate(cx, proxy, props);
|
return GetProxyHandler(proxy)->enumerate(cx, proxy, props);
|
||||||
if (!handler->keys(cx, proxy, props))
|
if (!handler->keys(cx, proxy, props))
|
||||||
@ -2316,6 +2426,10 @@ Proxy::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
|||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
RootedId id(cx, id_);
|
RootedId id(cx, id_);
|
||||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
*bp = false; // default result if we refuse to perform this action
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
if (!handler->hasPrototype())
|
if (!handler->hasPrototype())
|
||||||
return handler->has(cx, proxy, id, bp);
|
return handler->has(cx, proxy, id, bp);
|
||||||
if (!handler->hasOwn(cx, proxy, id, bp))
|
if (!handler->hasOwn(cx, proxy, id, bp))
|
||||||
@ -2333,7 +2447,12 @@ Proxy::hasOwn(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
return GetProxyHandler(proxy)->hasOwn(cx, proxy, id, bp);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
*bp = false; // default result if we refuse to perform this action
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
|
return handler->hasOwn(cx, proxy, id, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2342,6 +2461,10 @@ Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
vp.setUndefined(); // default result if we refuse to perform this action
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
bool own;
|
bool own;
|
||||||
if (!handler->hasPrototype()) {
|
if (!handler->hasPrototype()) {
|
||||||
own = true;
|
own = true;
|
||||||
@ -2360,17 +2483,20 @@ Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject recei
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
|
|
||||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
|
||||||
|
|
||||||
if (!handler->hasPrototype()) {
|
|
||||||
return GetProxyHandler(proxy)->getElementIfPresent(cx, proxy, receiver, index,
|
|
||||||
vp.address(), present);
|
|
||||||
}
|
|
||||||
|
|
||||||
RootedId id(cx);
|
RootedId id(cx);
|
||||||
if (!IndexToId(cx, index, &id))
|
if (!IndexToId(cx, index, &id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
|
|
||||||
|
if (!handler->hasPrototype()) {
|
||||||
|
return handler->getElementIfPresent(cx, proxy, receiver, index,
|
||||||
|
vp.address(), present);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasOwn;
|
bool hasOwn;
|
||||||
if (!handler->hasOwn(cx, proxy, id, &hasOwn))
|
if (!handler->hasOwn(cx, proxy, id, &hasOwn))
|
||||||
return false;
|
return false;
|
||||||
@ -2390,6 +2516,9 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
if (handler->hasPrototype()) {
|
if (handler->hasPrototype()) {
|
||||||
// If we're using a prototype, we still want to use the proxy trap unless
|
// If we're using a prototype, we still want to use the proxy trap unless
|
||||||
// we have a non-own property with a setter.
|
// we have a non-own property with a setter.
|
||||||
@ -2417,7 +2546,11 @@ Proxy::keys(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
return GetProxyHandler(proxy)->keys(cx, proxy, props);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
|
return handler->keys(cx, proxy, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2425,8 +2558,19 @@ Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleV
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
if (!handler->hasPrototype())
|
vp.setUndefined(); // default result if we refuse to perform this action
|
||||||
return GetProxyHandler(proxy)->iterate(cx, proxy, flags, vp.address());
|
if (!handler->hasPrototype()) {
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
|
||||||
|
BaseProxyHandler::GET, /* mayThrow = */ false);
|
||||||
|
// If the policy denies access but wants us to return true, we need
|
||||||
|
// to hand a valid (empty) iterator object to the caller.
|
||||||
|
if (!policy.allowed()) {
|
||||||
|
AutoIdVector props(cx);
|
||||||
|
return policy.returnValue() &&
|
||||||
|
EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp);
|
||||||
|
}
|
||||||
|
return handler->iterate(cx, proxy, flags, vp.address());
|
||||||
|
}
|
||||||
AutoIdVector props(cx);
|
AutoIdVector props(cx);
|
||||||
// The other Proxy::foo methods do the prototype-aware work for us here.
|
// The other Proxy::foo methods do the prototype-aware work for us here.
|
||||||
if ((flags & JSITER_OWNONLY)
|
if ((flags & JSITER_OWNONLY)
|
||||||
@ -2442,7 +2586,19 @@ Proxy::call(JSContext *cx, JSObject *proxy_, unsigned argc, Value *vp)
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
return GetProxyHandler(proxy)->call(cx, proxy, argc, vp);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
|
||||||
|
// Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
|
||||||
|
// can only set our default value once we're sure that we're not calling the
|
||||||
|
// trap.
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
|
||||||
|
BaseProxyHandler::CALL, true);
|
||||||
|
if (!policy.allowed()) {
|
||||||
|
vp->setUndefined();
|
||||||
|
return policy.returnValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler->call(cx, proxy, argc, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2450,7 +2606,19 @@ Proxy::construct(JSContext *cx, JSObject *proxy_, unsigned argc, Value *argv, Va
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
return GetProxyHandler(proxy)->construct(cx, proxy, argc, argv, rval);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
|
||||||
|
// Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
|
||||||
|
// can only set our default value once we're sure that we're not calling the
|
||||||
|
// trap.
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
|
||||||
|
BaseProxyHandler::CALL, true);
|
||||||
|
if (!policy.allowed()) {
|
||||||
|
rval->setUndefined();
|
||||||
|
return policy.returnValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler->construct(cx, proxy, argc, argv, rval);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2458,6 +2626,9 @@ Proxy::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArg
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
Rooted<JSObject*> proxy(cx, &args.thisv().toObject());
|
Rooted<JSObject*> proxy(cx, &args.thisv().toObject());
|
||||||
|
// Note - we don't enter a policy here because our security architecture
|
||||||
|
// guards against nativeCall by overriding the trap itself in the right
|
||||||
|
// circumstances.
|
||||||
return GetProxyHandler(proxy)->nativeCall(cx, test, impl, args);
|
return GetProxyHandler(proxy)->nativeCall(cx, test, impl, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2465,6 +2636,11 @@ bool
|
|||||||
Proxy::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
|
Proxy::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
|
||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return false);
|
JS_CHECK_RECURSION(cx, return false);
|
||||||
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
*bp = false; // default result if we refuse to perform this action
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
|
||||||
|
if (!policy.allowed())
|
||||||
|
return policy.returnValue();
|
||||||
return GetProxyHandler(proxy)->hasInstance(cx, proxy, v, bp);
|
return GetProxyHandler(proxy)->hasInstance(cx, proxy, v, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2480,7 +2656,14 @@ Proxy::obj_toString(JSContext *cx, JSObject *proxy_)
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return NULL);
|
JS_CHECK_RECURSION(cx, return NULL);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
return GetProxyHandler(proxy)->obj_toString(cx, proxy);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
|
||||||
|
BaseProxyHandler::GET, /* mayThrow = */ false);
|
||||||
|
// Do the safe thing if the policy rejects.
|
||||||
|
if (!policy.allowed()) {
|
||||||
|
return handler->BaseProxyHandler::obj_toString(cx, proxy);
|
||||||
|
}
|
||||||
|
return handler->obj_toString(cx, proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSString *
|
JSString *
|
||||||
@ -2488,7 +2671,17 @@ Proxy::fun_toString(JSContext *cx, JSObject *proxy_, unsigned indent)
|
|||||||
{
|
{
|
||||||
JS_CHECK_RECURSION(cx, return NULL);
|
JS_CHECK_RECURSION(cx, return NULL);
|
||||||
RootedObject proxy(cx, proxy_);
|
RootedObject proxy(cx, proxy_);
|
||||||
return GetProxyHandler(proxy)->fun_toString(cx, proxy, indent);
|
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||||
|
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID,
|
||||||
|
BaseProxyHandler::GET, /* mayThrow = */ false);
|
||||||
|
// Do the safe thing if the policy rejects.
|
||||||
|
if (!policy.allowed()) {
|
||||||
|
if (proxy->isCallable())
|
||||||
|
return JS_NewStringCopyZ(cx, "function () {\n [native code]\n}");
|
||||||
|
ReportIsNotFunction(cx, ObjectValue(*proxy));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return handler->fun_toString(cx, proxy, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -51,9 +51,11 @@ class JS_FRIEND_API(Wrapper);
|
|||||||
class JS_FRIEND_API(BaseProxyHandler) {
|
class JS_FRIEND_API(BaseProxyHandler) {
|
||||||
void *mFamily;
|
void *mFamily;
|
||||||
bool mHasPrototype;
|
bool mHasPrototype;
|
||||||
|
bool mHasPolicy;
|
||||||
protected:
|
protected:
|
||||||
// Subclasses may set this in their constructor.
|
// Subclasses may set this in their constructor.
|
||||||
void setHasPrototype(bool aHasPrototype) { mHasPrototype = aHasPrototype; }
|
void setHasPrototype(bool aHasPrototype) { mHasPrototype = aHasPrototype; }
|
||||||
|
void setHasPolicy(bool aHasPolicy) { mHasPolicy = aHasPolicy; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BaseProxyHandler(void *family);
|
explicit BaseProxyHandler(void *family);
|
||||||
@ -63,6 +65,10 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||||||
return mHasPrototype;
|
return mHasPrototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasPolicy() {
|
||||||
|
return mHasPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
inline void *family() {
|
inline void *family() {
|
||||||
return mFamily;
|
return mFamily;
|
||||||
}
|
}
|
||||||
@ -71,6 +77,24 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Policy enforcement traps.
|
||||||
|
*
|
||||||
|
* enter() allows the policy to specify whether the caller may perform |act|
|
||||||
|
* on the proxy's |id| property. In the case when |act| is CALL, |id| is
|
||||||
|
* generally JSID_VOID.
|
||||||
|
*
|
||||||
|
* The |act| parameter to enter() specifies the action being performed.
|
||||||
|
* If |bp| is false, the trap suggests that the caller throw (though it
|
||||||
|
* may still decide to squelch the error).
|
||||||
|
*/
|
||||||
|
enum Action {
|
||||||
|
GET,
|
||||||
|
SET,
|
||||||
|
CALL
|
||||||
|
};
|
||||||
|
virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act,
|
||||||
|
bool *bp);
|
||||||
|
|
||||||
/* ES5 Harmony fundamental proxy traps. */
|
/* ES5 Harmony fundamental proxy traps. */
|
||||||
virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
|
virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
|
||||||
PropertyDescriptor *desc, unsigned flags) = 0;
|
PropertyDescriptor *desc, unsigned flags) = 0;
|
||||||
@ -319,6 +343,72 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv,
|
|||||||
JSObject *
|
JSObject *
|
||||||
RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv);
|
RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv);
|
||||||
|
|
||||||
|
class JS_FRIEND_API(AutoEnterPolicy)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef BaseProxyHandler::Action Action;
|
||||||
|
AutoEnterPolicy(JSContext *cx, BaseProxyHandler *handler,
|
||||||
|
JSObject *wrapper, jsid id, Action act, bool mayThrow)
|
||||||
|
#ifdef DEBUG
|
||||||
|
: context(NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
allow = handler->hasPolicy() ? handler->enter(cx, wrapper, id, act, &rv)
|
||||||
|
: true;
|
||||||
|
recordEnter(cx, wrapper, id);
|
||||||
|
if (!allow && !rv && mayThrow)
|
||||||
|
reportError(cx, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AutoEnterPolicy() { recordLeave(); }
|
||||||
|
inline bool allowed() { return allow; }
|
||||||
|
inline bool returnValue() { JS_ASSERT(!allowed()); return rv; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// no-op constructor for subclass
|
||||||
|
AutoEnterPolicy()
|
||||||
|
#ifdef DEBUG
|
||||||
|
: context(NULL)
|
||||||
|
#endif
|
||||||
|
{};
|
||||||
|
void reportError(JSContext *cx, jsid id);
|
||||||
|
bool allow;
|
||||||
|
bool rv;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
JSContext *context;
|
||||||
|
mozilla::Maybe<RootedObject> enteredProxy;
|
||||||
|
mozilla::Maybe<RootedId> enteredId;
|
||||||
|
// NB: We explicitly don't track the entered action here, because sometimes
|
||||||
|
// SET traps do an implicit GET during their implementation, leading to
|
||||||
|
// spurious assertions.
|
||||||
|
AutoEnterPolicy *prev;
|
||||||
|
void recordEnter(JSContext *cx, JSObject *proxy, jsid id);
|
||||||
|
void recordLeave();
|
||||||
|
|
||||||
|
friend JS_FRIEND_API(void) assertEnteredPolicy(JSContext *cx, JSObject *proxy, jsid id);
|
||||||
|
#else
|
||||||
|
inline void recordEnter(JSContext *cx, JSObject *proxy, jsid id) {}
|
||||||
|
inline void recordLeave() {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
class JS_FRIEND_API(AutoWaivePolicy) : public AutoEnterPolicy {
|
||||||
|
public:
|
||||||
|
AutoWaivePolicy(JSContext *cx, JSObject *proxy, jsid id)
|
||||||
|
{
|
||||||
|
allow = true;
|
||||||
|
recordEnter(cx, proxy, id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
class JS_FRIEND_API(AutoWaivePolicy) {
|
||||||
|
public: AutoWaivePolicy(JSContext *cx, JSObject *proxy, jsid id) {};
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
extern JS_FRIEND_API(JSObject *)
|
extern JS_FRIEND_API(JSObject *)
|
||||||
|
@ -70,13 +70,6 @@ Wrapper::wrappedObject(RawObject wrapper)
|
|||||||
return GetProxyTargetObject(wrapper);
|
return GetProxyTargetObject(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp)
|
|
||||||
{
|
|
||||||
*bp = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_FRIEND_API(JSObject *)
|
JS_FRIEND_API(JSObject *)
|
||||||
js::UnwrapObject(JSObject *wrapped, bool stopAtOuter, unsigned *flagsp)
|
js::UnwrapObject(JSObject *wrapped, bool stopAtOuter, unsigned *flagsp)
|
||||||
{
|
{
|
||||||
@ -122,17 +115,6 @@ js::IsCrossCompartmentWrapper(RawObject wrapper)
|
|||||||
!!(Wrapper::wrapperHandler(wrapper)->flags() & Wrapper::CROSS_COMPARTMENT);
|
!!(Wrapper::wrapperHandler(wrapper)->flags() & Wrapper::CROSS_COMPARTMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECKED(op, act) \
|
|
||||||
JS_BEGIN_MACRO \
|
|
||||||
bool status; \
|
|
||||||
if (!enter(cx, wrapper, id, act, &status)) \
|
|
||||||
return status; \
|
|
||||||
return (op); \
|
|
||||||
JS_END_MACRO
|
|
||||||
|
|
||||||
#define SET(action) CHECKED(action, SET)
|
|
||||||
#define GET(action) CHECKED(action, GET)
|
|
||||||
|
|
||||||
Wrapper::Wrapper(unsigned flags, bool hasPrototype) : DirectProxyHandler(&sWrapperFamily)
|
Wrapper::Wrapper(unsigned flags, bool hasPrototype) : DirectProxyHandler(&sWrapperFamily)
|
||||||
, mFlags(flags)
|
, mFlags(flags)
|
||||||
, mSafeToUnwrap(true)
|
, mSafeToUnwrap(true)
|
||||||
@ -144,62 +126,6 @@ Wrapper::~Wrapper()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::getPropertyDescriptor(JSContext *cx, JSObject *wrapperArg,
|
|
||||||
jsid id, PropertyDescriptor *desc, unsigned flags)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
JS_ASSERT(!hasPrototype()); // Should never be called when there's a prototype.
|
|
||||||
desc->obj = NULL; // default result if we refuse to perform this action
|
|
||||||
CHECKED(DirectProxyHandler::getPropertyDescriptor(cx, wrapper, id, desc, flags),
|
|
||||||
(flags & JSRESOLVE_ASSIGNING) ? SET : GET);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapperArg,
|
|
||||||
jsid id, PropertyDescriptor *desc, unsigned flags)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
desc->obj = NULL; // default result if we refuse to perform this action
|
|
||||||
CHECKED(DirectProxyHandler::getOwnPropertyDescriptor(cx, wrapper, id, desc, flags), GET);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::defineProperty(JSContext *cx, JSObject *wrapperArg, jsid id,
|
|
||||||
PropertyDescriptor *desc)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
SET(DirectProxyHandler::defineProperty(cx, wrapper, id, desc));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::getOwnPropertyNames(JSContext *cx, JSObject *wrapperArg,
|
|
||||||
AutoIdVector &props)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
// if we refuse to perform this action, props remains empty
|
|
||||||
jsid id = JSID_VOID;
|
|
||||||
GET(DirectProxyHandler::getOwnPropertyNames(cx, wrapper, props));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::delete_(JSContext *cx, JSObject *wrapperArg, jsid id, bool *bp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
*bp = true; // default result if we refuse to perform this action
|
|
||||||
SET(DirectProxyHandler::delete_(cx, wrapper, id, bp));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::enumerate(JSContext *cx, JSObject *wrapperArg, AutoIdVector &props)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
JS_ASSERT(!hasPrototype()); // Should never be called when there's a prototype.
|
|
||||||
// if we refuse to perform this action, props remains empty
|
|
||||||
static jsid id = JSID_VOID;
|
|
||||||
GET(DirectProxyHandler::enumerate(cx, wrapper, props));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ordinarily, the convert trap would require unwrapping. However, the default
|
* Ordinarily, the convert trap would require unwrapping. However, the default
|
||||||
* implementation of convert, JS_ConvertStub, obtains a default value by calling
|
* implementation of convert, JS_ConvertStub, obtains a default value by calling
|
||||||
@ -234,126 +160,6 @@ Wrapper::defaultValue(JSContext *cx, JSObject *wrapperArg, JSType hint, Value *v
|
|||||||
return DirectProxyHandler::defaultValue(cx, wrapper, hint, vp);
|
return DirectProxyHandler::defaultValue(cx, wrapper, hint, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::has(JSContext *cx, JSObject *wrapperArg, jsid id, bool *bp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
JS_ASSERT(!hasPrototype()); // Should never be called when there's a prototype.
|
|
||||||
*bp = false; // default result if we refuse to perform this action
|
|
||||||
GET(DirectProxyHandler::has(cx, wrapper, id, bp));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::hasOwn(JSContext *cx, JSObject *wrapperArg, jsid id, bool *bp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
*bp = false; // default result if we refuse to perform this action
|
|
||||||
GET(DirectProxyHandler::hasOwn(cx, wrapper, id, bp));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::get(JSContext *cx, JSObject *wrapperArg, JSObject *receiver, jsid id, Value *vp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
vp->setUndefined(); // default result if we refuse to perform this action
|
|
||||||
GET(DirectProxyHandler::get(cx, wrapper, receiver, id, vp));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::set(JSContext *cx, JSObject *wrapperArg, JSObject *receiver, jsid id, bool strict,
|
|
||||||
Value *vp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
SET(DirectProxyHandler::set(cx, wrapper, receiver, id, strict, vp));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::keys(JSContext *cx, JSObject *wrapperArg, AutoIdVector &props)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
// if we refuse to perform this action, props remains empty
|
|
||||||
const jsid id = JSID_VOID;
|
|
||||||
GET(DirectProxyHandler::keys(cx, wrapper, props));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::iterate(JSContext *cx, JSObject *wrapperArg, unsigned flags, Value *vp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
JS_ASSERT(!hasPrototype()); // Should never be called when there's a prototype.
|
|
||||||
vp->setUndefined(); // default result if we refuse to perform this action
|
|
||||||
const jsid id = JSID_VOID;
|
|
||||||
GET(DirectProxyHandler::iterate(cx, wrapper, flags, vp));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::call(JSContext *cx, JSObject *wrapperArg, unsigned argc, Value *vp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
vp->setUndefined(); // default result if we refuse to perform this action
|
|
||||||
const jsid id = JSID_VOID;
|
|
||||||
CHECKED(DirectProxyHandler::call(cx, wrapper, argc, vp), CALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::construct(JSContext *cx, JSObject *wrapperArg, unsigned argc, Value *argv, Value *vp)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
vp->setUndefined(); // default result if we refuse to perform this action
|
|
||||||
const jsid id = JSID_VOID;
|
|
||||||
CHECKED(DirectProxyHandler::construct(cx, wrapper, argc, argv, vp), CALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args)
|
|
||||||
{
|
|
||||||
const jsid id = JSID_VOID;
|
|
||||||
RootedObject wrapper(cx, &args.thisv().toObject());
|
|
||||||
CHECKED(DirectProxyHandler::nativeCall(cx, test, impl, args), CALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Wrapper::hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp)
|
|
||||||
{
|
|
||||||
*bp = false; // default result if we refuse to perform this action
|
|
||||||
const jsid id = JSID_VOID;
|
|
||||||
GET(DirectProxyHandler::hasInstance(cx, wrapper, v, bp));
|
|
||||||
}
|
|
||||||
|
|
||||||
JSString *
|
|
||||||
Wrapper::obj_toString(JSContext *cx, JSObject *wrapperArg)
|
|
||||||
{
|
|
||||||
RootedObject wrapper(cx, wrapperArg);
|
|
||||||
bool status;
|
|
||||||
if (!enter(cx, wrapper, JSID_VOID, GET, &status)) {
|
|
||||||
if (status) {
|
|
||||||
// Perform some default behavior that doesn't leak any information.
|
|
||||||
return JS_NewStringCopyZ(cx, "[object Object]");
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
JSString *str = DirectProxyHandler::obj_toString(cx, wrapper);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSString *
|
|
||||||
Wrapper::fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent)
|
|
||||||
{
|
|
||||||
bool status;
|
|
||||||
if (!enter(cx, wrapper, JSID_VOID, GET, &status)) {
|
|
||||||
if (status) {
|
|
||||||
// Perform some default behavior that doesn't leak any information.
|
|
||||||
if (wrapper->isCallable())
|
|
||||||
return JS_NewStringCopyZ(cx, "function () {\n [native code]\n}");
|
|
||||||
ReportIsNotFunction(cx, ObjectValue(*wrapper));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
JSString *str = DirectProxyHandler::fun_toString(cx, wrapper, indent);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
Wrapper Wrapper::singleton((unsigned)0);
|
Wrapper Wrapper::singleton((unsigned)0);
|
||||||
Wrapper Wrapper::singletonWithPrototype((unsigned)0, true);
|
Wrapper Wrapper::singletonWithPrototype((unsigned)0, true);
|
||||||
|
|
||||||
@ -838,6 +644,7 @@ SecurityWrapper<Base>::SecurityWrapper(unsigned flags)
|
|||||||
: Base(flags)
|
: Base(flags)
|
||||||
{
|
{
|
||||||
Base::setSafeToUnwrap(false);
|
Base::setSafeToUnwrap(false);
|
||||||
|
BaseProxyHandler::setHasPolicy(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Base>
|
template <class Base>
|
||||||
|
@ -32,11 +32,7 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
|||||||
bool mSafeToUnwrap;
|
bool mSafeToUnwrap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Action {
|
using BaseProxyHandler::Action;
|
||||||
GET,
|
|
||||||
SET,
|
|
||||||
CALL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
CROSS_COMPARTMENT = 1 << 0,
|
CROSS_COMPARTMENT = 1 << 0,
|
||||||
@ -65,54 +61,11 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
|||||||
return mFlags;
|
return mFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Policy enforcement traps.
|
|
||||||
*
|
|
||||||
* enter() allows the policy to specify whether the caller may perform |act|
|
|
||||||
* on the underlying object's |id| property. In the case when |act| is CALL,
|
|
||||||
* |id| is generally JSID_VOID.
|
|
||||||
*
|
|
||||||
* The |act| parameter to enter() specifies the action being performed.
|
|
||||||
*/
|
|
||||||
virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act,
|
|
||||||
bool *bp);
|
|
||||||
|
|
||||||
explicit Wrapper(unsigned flags, bool hasPrototype = false);
|
explicit Wrapper(unsigned flags, bool hasPrototype = false);
|
||||||
|
|
||||||
virtual ~Wrapper();
|
virtual ~Wrapper();
|
||||||
|
|
||||||
/* ES5 Harmony fundamental wrapper traps. */
|
/* ES5 Harmony fundamental wrapper traps. */
|
||||||
virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper,
|
|
||||||
jsid id, PropertyDescriptor *desc,
|
|
||||||
unsigned flags) MOZ_OVERRIDE;
|
|
||||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper,
|
|
||||||
jsid id, PropertyDescriptor *desc,
|
|
||||||
unsigned flags) MOZ_OVERRIDE;
|
|
||||||
virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
|
|
||||||
PropertyDescriptor *desc) MOZ_OVERRIDE;
|
|
||||||
virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper,
|
|
||||||
AutoIdVector &props) MOZ_OVERRIDE;
|
|
||||||
virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id,
|
|
||||||
bool *bp) MOZ_OVERRIDE;
|
|
||||||
virtual bool enumerate(JSContext *cx, JSObject *wrapper,
|
|
||||||
AutoIdVector &props) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
/* ES5 Harmony derived wrapper traps. */
|
|
||||||
virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
|
|
||||||
virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
|
|
||||||
virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) MOZ_OVERRIDE;
|
|
||||||
virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict,
|
|
||||||
Value *vp) MOZ_OVERRIDE;
|
|
||||||
virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
|
|
||||||
virtual bool iterate(JSContext *cx, JSObject *wrapper, unsigned flags, Value *vp) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
/* Spidermonkey extensions. */
|
|
||||||
virtual bool call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp) MOZ_OVERRIDE;
|
|
||||||
virtual bool construct(JSContext *cx, JSObject *wrapper, unsigned argc, Value *argv, Value *rval) MOZ_OVERRIDE;
|
|
||||||
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
|
||||||
CallArgs args) MOZ_OVERRIDE;
|
|
||||||
virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v, bool *bp) MOZ_OVERRIDE;
|
|
||||||
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
|
|
||||||
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, unsigned indent) MOZ_OVERRIDE;
|
|
||||||
virtual bool defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint,
|
virtual bool defaultValue(JSContext *cx, JSObject *wrapper_, JSType hint,
|
||||||
Value *vp) MOZ_OVERRIDE;
|
Value *vp) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -940,7 +940,9 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
|
|||||||
return js_InternalThrow(f);
|
return js_InternalThrow(f);
|
||||||
fp->initVarsToUndefined();
|
fp->initVarsToUndefined();
|
||||||
fp->scopeChain();
|
fp->scopeChain();
|
||||||
if (!fp->prologue(cx, types::UseNewTypeAtEntry(cx, fp)))
|
if (types::UseNewTypeAtEntry(cx, fp))
|
||||||
|
fp->setUseNewType();
|
||||||
|
if (!fp->prologue(cx))
|
||||||
return js_InternalThrow(f);
|
return js_InternalThrow(f);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -778,7 +778,7 @@ stubs::TriggerIonCompile(VMFrame &f)
|
|||||||
AssertCanGC();
|
AssertCanGC();
|
||||||
RootedScript script(f.cx, f.script());
|
RootedScript script(f.cx, f.script());
|
||||||
|
|
||||||
if (ion::js_IonOptions.parallelCompilation) {
|
if (ion::js_IonOptions.parallelCompilation && !f.cx->runtime->profilingScripts) {
|
||||||
if (script->hasIonScript()) {
|
if (script->hasIonScript()) {
|
||||||
/*
|
/*
|
||||||
* Normally TriggerIonCompile is not called if !script->ion, but the
|
* Normally TriggerIonCompile is not called if !script->ion, but the
|
||||||
@ -808,8 +808,7 @@ stubs::TriggerIonCompile(VMFrame &f)
|
|||||||
compileStatus = ion::CanEnterAtBranch(f.cx, script, f.cx->fp(), osrPC,
|
compileStatus = ion::CanEnterAtBranch(f.cx, script, f.cx->fp(), osrPC,
|
||||||
f.fp()->isConstructing());
|
f.fp()->isConstructing());
|
||||||
} else {
|
} else {
|
||||||
compileStatus = ion::CanEnter(f.cx, script, f.cx->fp(), f.fp()->isConstructing(),
|
compileStatus = ion::CanEnter(f.cx, script, f.cx->fp(), f.fp()->isConstructing());
|
||||||
/* newType = */ false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compileStatus != ion::Method_Compiled) {
|
if (compileStatus != ion::Method_Compiled) {
|
||||||
|
@ -3185,6 +3185,59 @@ DebuggerScript_getAllOffsets(JSContext *cx, unsigned argc, Value *vp)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSBool
|
||||||
|
DebuggerScript_getAllColumnOffsets(JSContext *cx, unsigned argc, Value *vp)
|
||||||
|
{
|
||||||
|
THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "getAllColumnOffsets", args, obj, script);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First pass: determine which offsets in this script are jump targets and
|
||||||
|
* which positions jump to them.
|
||||||
|
*/
|
||||||
|
FlowGraphSummary flowData(cx);
|
||||||
|
if (!flowData.populate(cx, script))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Second pass: build the result array. */
|
||||||
|
RootedObject result(cx, NewDenseEmptyArray(cx));
|
||||||
|
if (!result)
|
||||||
|
return false;
|
||||||
|
for (BytecodeRangeWithPosition r(cx, script); !r.empty(); r.popFront()) {
|
||||||
|
size_t lineno = r.frontLineNumber();
|
||||||
|
size_t column = r.frontColumnNumber();
|
||||||
|
size_t offset = r.frontOffset();
|
||||||
|
|
||||||
|
/* Make a note, if the current instruction is an entry point for the current position. */
|
||||||
|
if (!flowData[offset].hasNoEdges() &&
|
||||||
|
(flowData[offset].lineno() != lineno ||
|
||||||
|
flowData[offset].column() != column)) {
|
||||||
|
RootedObject entry(cx, NewBuiltinClassInstance(cx, &ObjectClass));
|
||||||
|
if (!entry)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RootedId id(cx, NameToId(cx->names().lineNumber));
|
||||||
|
RootedValue value(cx, NumberValue(lineno));
|
||||||
|
if (!JSObject::defineGeneric(cx, entry, id, value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
value = NumberValue(column);
|
||||||
|
if (!JSObject::defineProperty(cx, entry, cx->names().columnNumber, value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
id = NameToId(cx->names().offset);
|
||||||
|
value = NumberValue(offset);
|
||||||
|
if (!JSObject::defineGeneric(cx, entry, id, value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!js_NewbornArrayPush(cx, result, ObjectValue(*entry)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args.rval().setObject(*result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
DebuggerScript_getLineOffsets(JSContext *cx, unsigned argc, Value *vp)
|
DebuggerScript_getLineOffsets(JSContext *cx, unsigned argc, Value *vp)
|
||||||
{
|
{
|
||||||
@ -3356,6 +3409,7 @@ static JSPropertySpec DebuggerScript_properties[] = {
|
|||||||
static JSFunctionSpec DebuggerScript_methods[] = {
|
static JSFunctionSpec DebuggerScript_methods[] = {
|
||||||
JS_FN("getChildScripts", DebuggerScript_getChildScripts, 0, 0),
|
JS_FN("getChildScripts", DebuggerScript_getChildScripts, 0, 0),
|
||||||
JS_FN("getAllOffsets", DebuggerScript_getAllOffsets, 0, 0),
|
JS_FN("getAllOffsets", DebuggerScript_getAllOffsets, 0, 0),
|
||||||
|
JS_FN("getAllColumnOffsets", DebuggerScript_getAllColumnOffsets, 0, 0),
|
||||||
JS_FN("getLineOffsets", DebuggerScript_getLineOffsets, 1, 0),
|
JS_FN("getLineOffsets", DebuggerScript_getLineOffsets, 1, 0),
|
||||||
JS_FN("getOffsetLine", DebuggerScript_getOffsetLine, 0, 0),
|
JS_FN("getOffsetLine", DebuggerScript_getOffsetLine, 0, 0),
|
||||||
JS_FN("setBreakpoint", DebuggerScript_setBreakpoint, 2, 0),
|
JS_FN("setBreakpoint", DebuggerScript_setBreakpoint, 2, 0),
|
||||||
|
@ -738,6 +738,13 @@ AbstractFramePtr::hasCallObj() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline bool
|
inline bool
|
||||||
|
AbstractFramePtr::useNewType() const
|
||||||
|
{
|
||||||
|
if (isStackFrame())
|
||||||
|
return asStackFrame()->useNewType();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool
|
||||||
AbstractFramePtr::isGeneratorFrame() const
|
AbstractFramePtr::isGeneratorFrame() const
|
||||||
{
|
{
|
||||||
if (isStackFrame())
|
if (isStackFrame())
|
||||||
|
@ -307,7 +307,7 @@ StackFrame::initFunctionScopeObjects(JSContext *cx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StackFrame::prologue(JSContext *cx, bool newType)
|
StackFrame::prologue(JSContext *cx)
|
||||||
{
|
{
|
||||||
RootedScript script(cx, this->script());
|
RootedScript script(cx, this->script());
|
||||||
|
|
||||||
@ -339,7 +339,7 @@ StackFrame::prologue(JSContext *cx, bool newType)
|
|||||||
|
|
||||||
if (isConstructing()) {
|
if (isConstructing()) {
|
||||||
RootedObject callee(cx, &this->callee());
|
RootedObject callee(cx, &this->callee());
|
||||||
JSObject *obj = CreateThisForFunction(cx, callee, newType);
|
JSObject *obj = CreateThisForFunction(cx, callee, useNewType());
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return false;
|
return false;
|
||||||
functionThis() = ObjectValue(*obj);
|
functionThis() = ObjectValue(*obj);
|
||||||
|
@ -297,6 +297,7 @@ class AbstractFramePtr
|
|||||||
inline bool hasArgsObj() const;
|
inline bool hasArgsObj() const;
|
||||||
inline ArgumentsObject &argsObj() const;
|
inline ArgumentsObject &argsObj() const;
|
||||||
inline void initArgsObj(ArgumentsObject &argsobj) const;
|
inline void initArgsObj(ArgumentsObject &argsobj) const;
|
||||||
|
inline bool useNewType() const;
|
||||||
|
|
||||||
inline bool copyRawFrameSlots(AutoValueVector *vec) const;
|
inline bool copyRawFrameSlots(AutoValueVector *vec) const;
|
||||||
|
|
||||||
@ -389,10 +390,13 @@ class StackFrame
|
|||||||
HAS_PUSHED_SPS_FRAME = 0x100000, /* SPS was notified of enty */
|
HAS_PUSHED_SPS_FRAME = 0x100000, /* SPS was notified of enty */
|
||||||
|
|
||||||
/* Ion frame state */
|
/* Ion frame state */
|
||||||
RUNNING_IN_ION = 0x200000, /* frame is running in Ion */
|
RUNNING_IN_ION = 0x200000, /* frame is running in Ion */
|
||||||
CALLING_INTO_ION = 0x400000, /* frame is calling into Ion */
|
CALLING_INTO_ION = 0x400000, /* frame is calling into Ion */
|
||||||
|
|
||||||
JIT_REVISED_STACK = 0x800000 /* sp was revised by JIT for lowered apply */
|
JIT_REVISED_STACK = 0x800000, /* sp was revised by JIT for lowered apply */
|
||||||
|
|
||||||
|
/* Miscellaneous state. */
|
||||||
|
USE_NEW_TYPE = 0x1000000 /* Use new type for constructed |this| object. */
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -489,12 +493,9 @@ class StackFrame
|
|||||||
* over-recursed) after pushing the stack frame but before 'prologue' is
|
* over-recursed) after pushing the stack frame but before 'prologue' is
|
||||||
* called or completes fully. To simplify usage, 'epilogue' does not assume
|
* called or completes fully. To simplify usage, 'epilogue' does not assume
|
||||||
* 'prologue' has completed and handles all the intermediate state details.
|
* 'prologue' has completed and handles all the intermediate state details.
|
||||||
*
|
|
||||||
* The 'newType' option indicates whether the constructed 'this' value (if
|
|
||||||
* there is one) should be given a new singleton type.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool prologue(JSContext *cx, bool newType);
|
bool prologue(JSContext *cx);
|
||||||
void epilogue(JSContext *cx);
|
void epilogue(JSContext *cx);
|
||||||
|
|
||||||
/* Subsets of 'prologue' called from jit code. */
|
/* Subsets of 'prologue' called from jit code. */
|
||||||
@ -1052,6 +1053,15 @@ class StackFrame
|
|||||||
return flags_ & HAS_ARGS_OBJ;
|
return flags_ & HAS_ARGS_OBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setUseNewType() {
|
||||||
|
JS_ASSERT(isConstructing());
|
||||||
|
flags_ |= USE_NEW_TYPE;
|
||||||
|
}
|
||||||
|
bool useNewType() const {
|
||||||
|
JS_ASSERT(isConstructing());
|
||||||
|
return flags_ & USE_NEW_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The method JIT call/apply optimization can erase Function.{call,apply}
|
* The method JIT call/apply optimization can erase Function.{call,apply}
|
||||||
* invocations from the stack and push the callee frame directly. The base
|
* invocations from the stack and push the callee frame directly. The base
|
||||||
|
@ -31,12 +31,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=760109
|
|||||||
ok(protoProto === Object.prototype,
|
ok(protoProto === Object.prototype,
|
||||||
"Object prototype remapped properly");
|
"Object prototype remapped properly");
|
||||||
|
|
||||||
// Check |constructor|. The semantics of this weird for the case of an
|
// Check |constructor|.
|
||||||
// object with a custom chrome-implemented prototype, because we'll end up
|
// Note that the 'constructor' property of the underlying chrome object
|
||||||
// bouncing up the prototype chain to Object, even though that's not fully
|
// will be resolved on SomeConstructor.prototype, which has an empty
|
||||||
// accurate. It's unlikely to be a problem though, so we just verify that
|
// __exposedProps__. This means that we shouldn't remap the property, even
|
||||||
// it does what we expect.
|
// though we'd also be able to find it on Object.prototype. Some recent
|
||||||
ok(chromeObject.constructor === Object, "Object constructor does what we expect");
|
// refactoring has made it possible to do the right thing here.
|
||||||
|
is(typeof chromeObject.constructor, "undefined", "Object constructor does what we expect");
|
||||||
ok(chromeArray.constructor === Array, "Array constructor remapped properly");
|
ok(chromeArray.constructor === Array, "Array constructor remapped properly");
|
||||||
|
|
||||||
// We should be able to .forEach on the Array.
|
// We should be able to .forEach on the Array.
|
||||||
|
@ -43,7 +43,6 @@ MOCHITEST_FILES = chrome_wrappers_helper.html \
|
|||||||
bug504877_helper.html \
|
bug504877_helper.html \
|
||||||
test_bug505915.html \
|
test_bug505915.html \
|
||||||
file_bug505915.html \
|
file_bug505915.html \
|
||||||
test_bug553407.html \
|
|
||||||
test_bug560351.html \
|
test_bug560351.html \
|
||||||
bug571849_helper.html \
|
bug571849_helper.html \
|
||||||
test_bug585745.html \
|
test_bug585745.html \
|
||||||
|
@ -17,7 +17,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478438
|
|||||||
return;
|
return;
|
||||||
test.calledAlready = true;
|
test.calledAlready = true;
|
||||||
|
|
||||||
var iwin = (new XPCNativeWrapper(document)).getElementById("f").contentWindow;
|
var iwin = document.getElementById("f").contentWindow;
|
||||||
|
|
||||||
function testOne(fn, onAllow, infinitive) {
|
function testOne(fn, onAllow, infinitive) {
|
||||||
try { fn(); onAllow("able " + infinitive, "") }
|
try { fn(); onAllow("able " + infinitive, "") }
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=517163
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Test for Bug 553407</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=553407">Mozilla Bug 553407</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
<script type="application/javascript">
|
|
||||||
|
|
||||||
/** Test for Bug 553407 **/
|
|
||||||
is(typeof new XPCNativeWrapper(location), "object", "XPCNativeWrapper(location) is an object")
|
|
||||||
is(typeof new XPCNativeWrapper(XMLHttpRequest), "function", "XPCNativeWrapper(XMLHttpRequest) is a function")
|
|
||||||
// We no longer support .wrappedJSObject on NW since for same-origin there is no wrapper in between.
|
|
||||||
// is(typeof new XPCNativeWrapper(location).wrappedJSObject, "object", "XPCNativeWrapper(location).wrappedJSObject is an object")
|
|
||||||
// is(typeof new XPCNativeWrapper(XMLHttpRequest).wrappedJSObject, "function", "XPCNativeWrapper(XMLHttpRequest).wrappedJSObject is a function")
|
|
||||||
ok("a".replace("a", new XPCNativeWrapper(location)).indexOf("mochi.test") >= 0, "XPCNativeWrappers can be used as the replacement value for .replace");
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -24,10 +24,10 @@ function test()
|
|||||||
option.text="Fubar";
|
option.text="Fubar";
|
||||||
sel.options.add(option);
|
sel.options.add(option);
|
||||||
try {
|
try {
|
||||||
Components.lookupMethod(sel.options, "add")(option);
|
SpecialPowers.Components.lookupMethod(sel.options, "add")(option);
|
||||||
ok(true, "function call should not throw")
|
ok(true, "function call should not throw")
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
do_throw("this call should just work without any exceptions");
|
ok(false, "this call should just work without any exceptions");
|
||||||
}
|
}
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
@ -16,5 +16,8 @@ function run_test()
|
|||||||
do_check_eq(Cu.evalInSandbox('typeof obj.foo', sb), 'undefined', "COW works as expected");
|
do_check_eq(Cu.evalInSandbox('typeof obj.foo', sb), 'undefined', "COW works as expected");
|
||||||
do_check_true(Cu.evalInSandbox('obj.hasOwnProperty === Object.prototype.hasOwnProperty', sb),
|
do_check_true(Cu.evalInSandbox('obj.hasOwnProperty === Object.prototype.hasOwnProperty', sb),
|
||||||
"Remapping happens even when the property is explicitly exposed");
|
"Remapping happens even when the property is explicitly exposed");
|
||||||
do_check_eq(Cu.evalInSandbox('Object.prototype.bar = 10; obj.bar', sb), 10);
|
// NB: We used to test for the following, but such behavior became very
|
||||||
|
// difficult to implement in a recent refactor. We're moving away from this
|
||||||
|
// API anyway, so we decided to explicitly drop support for this.
|
||||||
|
// do_check_eq(Cu.evalInSandbox('Object.prototype.bar = 10; obj.bar', sb), 10);
|
||||||
}
|
}
|
||||||
|
@ -267,24 +267,6 @@ AccessCheck::isScriptAccessOnly(JSContext *cx, JSObject *wrapper)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AccessCheck::deny(JSContext *cx, jsid id)
|
|
||||||
{
|
|
||||||
if (id == JSID_VOID) {
|
|
||||||
JS_ReportError(cx, "Permission denied to access object");
|
|
||||||
} else {
|
|
||||||
jsval idval;
|
|
||||||
if (!JS_IdToValue(cx, id, &idval))
|
|
||||||
return;
|
|
||||||
JSString *str = JS_ValueToString(cx, idval);
|
|
||||||
if (!str)
|
|
||||||
return;
|
|
||||||
const jschar *chars = JS_GetStringCharsZ(cx, str);
|
|
||||||
if (chars)
|
|
||||||
JS_ReportError(cx, "Permission denied to access property '%hs'", chars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Access { READ = (1<<0), WRITE = (1<<1), NO_ACCESS = 0 };
|
enum Access { READ = (1<<0), WRITE = (1<<1), NO_ACCESS = 0 };
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -33,8 +33,6 @@ class AccessCheck {
|
|||||||
static bool needsSystemOnlyWrapper(JSObject *obj);
|
static bool needsSystemOnlyWrapper(JSObject *obj);
|
||||||
|
|
||||||
static bool isScriptAccessOnly(JSContext *cx, JSObject *wrapper);
|
static bool isScriptAccessOnly(JSContext *cx, JSObject *wrapper);
|
||||||
|
|
||||||
static void deny(JSContext *cx, jsid id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Policy {
|
struct Policy {
|
||||||
@ -45,8 +43,7 @@ struct Opaque : public Policy {
|
|||||||
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) {
|
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) {
|
||||||
return act == js::Wrapper::CALL;
|
return act == js::Wrapper::CALL;
|
||||||
}
|
}
|
||||||
static bool deny(JSContext *cx, jsid id, js::Wrapper::Action act) {
|
static bool deny(js::Wrapper::Action act) {
|
||||||
AccessCheck::deny(cx, id);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl)
|
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl)
|
||||||
@ -62,8 +59,7 @@ struct OnlyIfSubjectIsSystem : public Policy {
|
|||||||
return AccessCheck::isSystemOnlyAccessPermitted(cx);
|
return AccessCheck::isSystemOnlyAccessPermitted(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool deny(JSContext *cx, jsid id, js::Wrapper::Action act) {
|
static bool deny(js::Wrapper::Action act) {
|
||||||
AccessCheck::deny(cx, id);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,8 +75,7 @@ struct CrossOriginAccessiblePropertiesOnly : public Policy {
|
|||||||
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) {
|
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) {
|
||||||
return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act);
|
return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act);
|
||||||
}
|
}
|
||||||
static bool deny(JSContext *cx, jsid id, js::Wrapper::Action act) {
|
static bool deny(js::Wrapper::Action act) {
|
||||||
AccessCheck::deny(cx, id);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl)
|
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl)
|
||||||
@ -94,13 +89,9 @@ struct CrossOriginAccessiblePropertiesOnly : public Policy {
|
|||||||
struct ExposedPropertiesOnly : public Policy {
|
struct ExposedPropertiesOnly : public Policy {
|
||||||
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act);
|
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act);
|
||||||
|
|
||||||
static bool deny(JSContext *cx, jsid id, js::Wrapper::Action act) {
|
static bool deny(js::Wrapper::Action act) {
|
||||||
// For gets, silently fail.
|
// Fail silently for GETs.
|
||||||
if (act == js::Wrapper::GET)
|
return act == js::Wrapper::GET;
|
||||||
return true;
|
|
||||||
// For sets,throw an exception.
|
|
||||||
AccessCheck::deny(cx, id);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl);
|
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl);
|
||||||
};
|
};
|
||||||
@ -109,8 +100,7 @@ struct ExposedPropertiesOnly : public Policy {
|
|||||||
struct ComponentsObjectPolicy : public Policy {
|
struct ComponentsObjectPolicy : public Policy {
|
||||||
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act);
|
static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act);
|
||||||
|
|
||||||
static bool deny(JSContext *cx, jsid id, js::Wrapper::Action act) {
|
static bool deny(js::Wrapper::Action act) {
|
||||||
AccessCheck::deny(cx, id);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
|
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user