mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Merge mozilla-central into build-system
Only conflict was configure.in amd was due to context, not changed lines themselves.
This commit is contained in:
commit
45faa95b04
@ -18,7 +18,7 @@
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Ci = SpecialPowers.Ci;
|
||||
let wrapperClickCount = 0;
|
||||
|
||||
function test1() {
|
||||
|
@ -64,4 +64,11 @@ BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
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
|
||||
|
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>
|
@ -64,4 +64,11 @@ BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
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
|
||||
|
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>
|
@ -64,4 +64,11 @@ BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
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
|
||||
|
@ -64,4 +64,11 @@ BRANDING_DEST := $(DIST)/branding
|
||||
BRANDING_TARGET := export
|
||||
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
|
||||
|
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 gTab = null;
|
||||
var gHomeTab = null;
|
||||
var gThreadClient = null;
|
||||
var gNewGlobal = false;
|
||||
var gAttached = false;
|
||||
@ -33,8 +34,7 @@ function test()
|
||||
gAttached = true;
|
||||
|
||||
// Ensure that a new global will be created.
|
||||
let frame = content.document.createElement("iframe");
|
||||
content.document.querySelector("body").appendChild(frame);
|
||||
gHomeTab = gBrowser.addTab("about:home");
|
||||
|
||||
finish_test();
|
||||
});
|
||||
@ -58,6 +58,7 @@ function finish_test()
|
||||
}
|
||||
gClient.removeListener("newScript", onNewScript);
|
||||
gThreadClient.resume(function(aResponse) {
|
||||
removeTab(gHomeTab);
|
||||
removeTab(gTab);
|
||||
gClient.close(function() {
|
||||
ok(gNewGlobal, "Received newGlobal event.");
|
||||
|
@ -219,7 +219,7 @@ var TouchModule = {
|
||||
this._targetScrollInterface = targetScrollInterface;
|
||||
|
||||
if (!this._targetScrollbox) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX shouldn't dragger always be valid here?
|
||||
|
@ -13,15 +13,8 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
export::
|
||||
$(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::
|
||||
$(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
|
||||
|
@ -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"
|
||||
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
|
||||
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
||||
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
|
||||
|
@ -2157,8 +2157,9 @@ ia64*-hpux*)
|
||||
# that behavior) that it's better to turn it off.
|
||||
# MSVC warning C4819 warns some UTF-8 characters (e.g. copyright sign)
|
||||
# on non-Western system locales even if it is in a comment.
|
||||
# khuey says we can safely ignore MSVC warning C4251
|
||||
CFLAGS="$CFLAGS -wd4819"
|
||||
CXXFLAGS="$CXXFLAGS -wd4345 -wd4351 -wd4482 -wd4800 -wd4819"
|
||||
CXXFLAGS="$CXXFLAGS -wd4251 -wd4345 -wd4351 -wd4482 -wd4800 -wd4819"
|
||||
# make 'foo == bar;' error out
|
||||
CFLAGS="$CFLAGS -we4553"
|
||||
CXXFLAGS="$CXXFLAGS -we4553"
|
||||
@ -8965,7 +8966,7 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# target_arch is from {ia32|x64|arm}
|
||||
# target_arch is from {ia32|x64|arm|ppc}
|
||||
case "$CPU_ARCH" in
|
||||
x86_64 | ia64)
|
||||
WEBRTC_TARGET_ARCH=x64
|
||||
@ -8979,6 +8980,9 @@ x86)
|
||||
WEBRTC_TARGET_ARCH=ia32
|
||||
;;
|
||||
|
||||
ppc*)
|
||||
WEBRTC_TARGET_ARCH=ppc
|
||||
;;
|
||||
*)
|
||||
# unsupported arch for webrtc
|
||||
WEBRTC_TARGET_ARCH=unknown
|
||||
|
@ -86,7 +86,7 @@
|
||||
#include "sampler.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nsHTMLIFrameElement.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "nsSandboxFlags.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
|
||||
// sandboxed ?
|
||||
nsHTMLIFrameElement* iframe =
|
||||
nsHTMLIFrameElement::FromContent(mOwnerContent);
|
||||
HTMLIFrameElement* iframe =
|
||||
HTMLIFrameElement::FromContent(mOwnerContent);
|
||||
|
||||
uint32_t sandboxFlags = 0;
|
||||
|
||||
|
@ -1025,7 +1025,8 @@ nsScriptLoader::ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
|
||||
|
||||
if (!unicodeDecoder &&
|
||||
aChannel &&
|
||||
NS_SUCCEEDED(aChannel->GetContentCharset(charset))) {
|
||||
NS_SUCCEEDED(aChannel->GetContentCharset(charset)) &&
|
||||
!charset.IsEmpty()) {
|
||||
charsetConv->GetUnicodeDecoder(charset.get(),
|
||||
getter_AddRefs(unicodeDecoder));
|
||||
}
|
||||
|
@ -3371,6 +3371,8 @@ nsXMLHttpRequest::SetMultipart(bool aMultipart, nsresult& aRv)
|
||||
return;
|
||||
}
|
||||
|
||||
LogMessage("MultipartXHRWarning", GetOwner());
|
||||
|
||||
if (aMultipart) {
|
||||
mState |= XML_HTTP_REQUEST_MULTIPART;
|
||||
} else {
|
||||
|
@ -24,10 +24,8 @@ let am = {
|
||||
authMgr: null,
|
||||
|
||||
init: function() {
|
||||
const {classes: Cc, interfaces: Ci} = SpecialPowers.wrap(Components);
|
||||
|
||||
this.authMgr = Cc["@mozilla.org/network/http-auth-manager;1"]
|
||||
.getService(Components.interfaces.nsIHttpAuthManager)
|
||||
this.authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIHttpAuthManager)
|
||||
},
|
||||
|
||||
addIdentity: function() {
|
||||
|
@ -15,7 +15,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=425013
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
var missingPlugins = new Array();
|
||||
var OBJLC = Components.interfaces.nsIObjectLoadingContent;
|
||||
var OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||
|
||||
function pluginBinding(event)
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429157
|
||||
|
||||
<script>
|
||||
var missingPlugins = new Array();
|
||||
const OBJLC = Components.interfaces.nsIObjectLoadingContent;
|
||||
const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||
|
||||
function pluginBindingAttached(event)
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ function test(tag, type) {
|
||||
"use strict";
|
||||
info("testing " + tag + " tag with type " + type);
|
||||
|
||||
const OBJLC = Components.interfaces.nsIObjectLoadingContent;
|
||||
const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||
let obj = document.createElement(tag);
|
||||
obj.type = type;
|
||||
document.body.appendChild(obj);
|
||||
|
@ -16,14 +16,12 @@
|
||||
<pre id="test">
|
||||
<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_MANIFEST = "http://example.org/manifest.webapp";
|
||||
const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
|
||||
|
||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageBroadcaster);
|
||||
let ppmm = SpecialPowers.Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIMessageBroadcaster);
|
||||
|
||||
/**
|
||||
* Load the example.org site in an <iframe mozbrowser>
|
||||
|
@ -15,18 +15,16 @@
|
||||
<pre id="test">
|
||||
<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_MANIFEST = "http://example.org/manifest.webapp";
|
||||
const CHILD_PROCESS_SHUTDOWN_MESSAGE = "child-process-shutdown";
|
||||
|
||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageBroadcaster);
|
||||
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsISyncMessageSender);
|
||||
let gAppsService = Cc["@mozilla.org/AppsService;1"]
|
||||
.getService(Ci.nsIAppsService);
|
||||
let ppmm = SpecialPowers.Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIMessageBroadcaster);
|
||||
let cpmm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsISyncMessageSender);
|
||||
let gAppsService = SpecialPowers.Cc["@mozilla.org/AppsService;1"]
|
||||
.getService(SpecialPowers.Ci.nsIAppsService);
|
||||
|
||||
function setUp() {
|
||||
SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true);
|
||||
|
@ -45,8 +45,8 @@ var OPTIONS = {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function detectDriverType() {
|
||||
const Cc = SpecialPowers.wrap(Components).classes;
|
||||
const Ci = SpecialPowers.wrap(Components).interfaces;
|
||||
const Cc = SpecialPowers.Cc;
|
||||
const Ci = SpecialPowers.Ci;
|
||||
var doc = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser).parseFromString("<html/>", "text/html");
|
||||
|
||||
var canvas = doc.createElement("canvas");
|
||||
@ -105,15 +105,15 @@ function start() {
|
||||
if (kIsWindows) {
|
||||
// code borrowed from browser/modules/test/browser_taskbar_preview.js
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var version = Components.classes["@mozilla.org/system-info;1"]
|
||||
.getService(Components.interfaces.nsIPropertyBag2)
|
||||
var version = SpecialPowers.Cc["@mozilla.org/system-info;1"]
|
||||
.getService(SpecialPowers.Ci.nsIPropertyBag2)
|
||||
.getProperty("version");
|
||||
kIsWindowsVistaOrHigher = (parseFloat(version) >= 6.0);
|
||||
}
|
||||
|
||||
function getEnv(env) {
|
||||
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);
|
||||
if (val == "")
|
||||
return null;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "nsHTMLIFrameElement.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "nsIDOMSVGDocument.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsAttrValueInlines.h"
|
||||
@ -14,86 +14,86 @@
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
|
||||
|
||||
nsHTMLIFrameElement::nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
DOMCI_NODE_DATA(HTMLIFrameElement, mozilla::dom::HTMLIFrameElement)
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
HTMLIFrameElement::HTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
: nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
|
||||
{
|
||||
}
|
||||
|
||||
nsHTMLIFrameElement::~nsHTMLIFrameElement()
|
||||
HTMLIFrameElement::~HTMLIFrameElement()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsHTMLIFrameElement, Element)
|
||||
NS_IMPL_RELEASE_INHERITED(nsHTMLIFrameElement, Element)
|
||||
NS_IMPL_ADDREF_INHERITED(HTMLIFrameElement, Element)
|
||||
NS_IMPL_RELEASE_INHERITED(HTMLIFrameElement, Element)
|
||||
|
||||
DOMCI_NODE_DATA(HTMLIFrameElement, nsHTMLIFrameElement)
|
||||
|
||||
// QueryInterface implementation for nsHTMLIFrameElement
|
||||
NS_INTERFACE_TABLE_HEAD(nsHTMLIFrameElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(nsHTMLIFrameElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLIFrameElement, nsIDOMHTMLIFrameElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLIFrameElement, nsIDOMGetSVGDocument)
|
||||
// QueryInterface implementation for HTMLIFrameElement
|
||||
NS_INTERFACE_TABLE_HEAD(HTMLIFrameElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(HTMLIFrameElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(HTMLIFrameElement, nsIDOMHTMLIFrameElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(HTMLIFrameElement, nsIDOMGetSVGDocument)
|
||||
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)
|
||||
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(nsHTMLIFrameElement, FrameBorder, frameborder)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Height, height)
|
||||
NS_IMPL_URI_ATTR(nsHTMLIFrameElement, LongDesc, longdesc)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginHeight, marginheight)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginWidth, marginwidth)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Name, name)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Scrolling, scrolling)
|
||||
NS_IMPL_URI_ATTR(nsHTMLIFrameElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Width, width)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLIFrameElement, Allowfullscreen, allowfullscreen)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Sandbox, sandbox)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Align, align)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, FrameBorder, frameborder)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Height, height)
|
||||
NS_IMPL_URI_ATTR(HTMLIFrameElement, LongDesc, longdesc)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, MarginHeight, marginheight)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, MarginWidth, marginwidth)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Name, name)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Scrolling, scrolling)
|
||||
NS_IMPL_URI_ATTR(HTMLIFrameElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Width, width)
|
||||
NS_IMPL_BOOL_ATTR(HTMLIFrameElement, Allowfullscreen, allowfullscreen)
|
||||
NS_IMPL_STRING_ATTR(HTMLIFrameElement, Sandbox, sandbox)
|
||||
|
||||
void
|
||||
nsHTMLIFrameElement::GetItemValueText(nsAString& aValue)
|
||||
HTMLIFrameElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetSrc(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLIFrameElement::SetItemValueText(const nsAString& aValue)
|
||||
HTMLIFrameElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetSrc(aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
||||
HTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
||||
{
|
||||
return nsGenericHTMLFrameElement::GetContentDocument(aContentDocument);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
|
||||
HTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
|
||||
{
|
||||
return nsGenericHTMLFrameElement::GetContentWindow(aContentWindow);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLIFrameElement::GetSVGDocument(nsIDOMDocument **aResult)
|
||||
HTMLIFrameElement::GetSVGDocument(nsIDOMDocument **aResult)
|
||||
{
|
||||
return GetContentDocument(aResult);
|
||||
}
|
||||
|
||||
bool
|
||||
nsHTMLIFrameElement::ParseAttribute(int32_t aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
HTMLIFrameElement::ParseAttribute(int32_t aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aAttribute == nsGkAtoms::marginwidth) {
|
||||
@ -180,7 +180,7 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
nsHTMLIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
||||
HTMLIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::width },
|
||||
@ -202,15 +202,15 @@ nsHTMLIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
||||
|
||||
|
||||
nsMapRuleToAttributesFunc
|
||||
nsHTMLIFrameElement::GetAttributeMappingFunction() const
|
||||
HTMLIFrameElement::GetAttributeMappingFunction() const
|
||||
{
|
||||
return &MapAttributesIntoRule;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
bool aNotify)
|
||||
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None) {
|
||||
// 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
|
||||
nsHTMLIFrameElement::GetSandboxFlags()
|
||||
HTMLIFrameElement::GetSandboxFlags()
|
||||
{
|
||||
nsAutoString sandboxAttr;
|
||||
|
||||
@ -248,3 +248,6 @@ nsHTMLIFrameElement::GetSandboxFlags()
|
||||
// No sandbox attribute, no sandbox flags.
|
||||
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
|
||||
* 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 "nsIDOMHTMLIFrameElement.h"
|
||||
#include "nsIDOMGetSVGDocument.h"
|
||||
|
||||
class nsHTMLIFrameElement : public nsGenericHTMLFrameElement
|
||||
, public nsIDOMHTMLIFrameElement
|
||||
, public nsIDOMGetSVGDocument
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class HTMLIFrameElement MOZ_FINAL : public nsGenericHTMLFrameElement
|
||||
, public nsIDOMHTMLIFrameElement
|
||||
, public nsIDOMGetSVGDocument
|
||||
{
|
||||
public:
|
||||
nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
|
||||
virtual ~nsHTMLIFrameElement();
|
||||
HTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
FromParser aFromParser = NOT_FROM_PARSER);
|
||||
virtual ~HTMLIFrameElement();
|
||||
|
||||
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(nsHTMLIFrameElement, iframe)
|
||||
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLIFrameElement, iframe)
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -58,3 +64,8 @@ protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -21,7 +21,6 @@ endif # !_MSC_VER
|
||||
EXPORTS = \
|
||||
HTMLPropertiesCollection.h \
|
||||
nsGenericHTMLElement.h \
|
||||
nsHTMLIFrameElement.h \
|
||||
nsClientRect.h \
|
||||
nsHTMLDNSPrefetch.h \
|
||||
nsTimeRanges.h \
|
||||
@ -43,6 +42,7 @@ EXPORTS_mozilla/dom = \
|
||||
HTMLFrameSetElement.h \
|
||||
HTMLHeadingElement.h \
|
||||
HTMLHRElement.h \
|
||||
HTMLIFrameElement.h \
|
||||
HTMLImageElement.h \
|
||||
HTMLLabelElement.h \
|
||||
HTMLLegendElement.h \
|
||||
@ -103,7 +103,7 @@ CPPSRCS = \
|
||||
HTMLFrameSetElement.cpp \
|
||||
HTMLHRElement.cpp \
|
||||
HTMLHeadingElement.cpp \
|
||||
nsHTMLIFrameElement.cpp \
|
||||
HTMLIFrameElement.cpp \
|
||||
HTMLImageElement.cpp \
|
||||
nsHTMLInputElement.cpp \
|
||||
HTMLLIElement.cpp \
|
||||
|
@ -78,7 +78,7 @@ addLoadEvent(function() {
|
||||
is(d.testAncestor, "ancestor",
|
||||
"test1" + ": Empty field should not override ancestor binding");
|
||||
|
||||
var win = XPCNativeWrapper.unwrap(window);
|
||||
var win = window;
|
||||
win.counter = 0;
|
||||
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
|
||||
// agent any time a new one is registered.
|
||||
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();
|
||||
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 (newType == AUDIO_CHANNEL_INT_CONTENT &&
|
||||
oldType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN &&
|
||||
!mActiveContentChildIDs.Contains(aChildID)) {
|
||||
oldType == AUDIO_CHANNEL_INT_CONTENT_HIDDEN) {
|
||||
|
||||
if (mActiveContentChildIDsFrozen) {
|
||||
mActiveContentChildIDsFrozen = false;
|
||||
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 &&
|
||||
oldType == AUDIO_CHANNEL_INT_CONTENT &&
|
||||
!mActiveContentChildIDsFrozen &&
|
||||
mChannelCounters[AUDIO_CHANNEL_INT_CONTENT].IsEmpty()) {
|
||||
mActiveContentChildIDsFrozen = true;
|
||||
!mActiveContentChildIDsFrozen) {
|
||||
// If nothing is visible, the list has to been frozen.
|
||||
// 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) {
|
||||
@ -291,8 +307,12 @@ AudioChannelService::SendAudioChannelChangedNotification()
|
||||
higher = AUDIO_CHANNEL_NOTIFICATION;
|
||||
}
|
||||
|
||||
// Content channels play in background if just one is active.
|
||||
else if (!mActiveContentChildIDs.IsEmpty()) {
|
||||
// There is only one Child can play content channel in the background.
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
/* 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/. */
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "TestHarness.h"
|
||||
|
||||
@ -19,19 +24,25 @@
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
class Agent
|
||||
class Agent : public nsIAudioChannelAgentCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
Agent(AudioChannelType aType)
|
||||
: mType(aType)
|
||||
, mWaitCallback(false)
|
||||
, mRegistered(false)
|
||||
, mCanPlay(false)
|
||||
{
|
||||
mAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
|
||||
}
|
||||
|
||||
virtual ~Agent() {}
|
||||
|
||||
nsresult Init()
|
||||
{
|
||||
nsresult rv = mAgent->Init(mType, nullptr);
|
||||
nsresult rv = mAgent->Init(mType, this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mAgent->SetVisibilityState(false);
|
||||
@ -50,26 +61,74 @@ public:
|
||||
nsresult StopPlaying()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
AudioChannelType mType;
|
||||
bool mWaitCallback;
|
||||
bool mRegistered;
|
||||
bool mCanPlay;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(Agent, nsIAudioChannelAgentCallback)
|
||||
|
||||
nsresult
|
||||
TestDoubleStartPlaying()
|
||||
{
|
||||
Agent agent(AUDIO_CHANNEL_NORMAL);
|
||||
nsresult rv = agent.Init();
|
||||
nsCOMPtr<Agent> agent = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||
|
||||
nsresult rv = agent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool playing;
|
||||
rv = agent.mAgent->StartPlaying(&playing);
|
||||
rv = agent->mAgent->StartPlaying(&playing);
|
||||
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");
|
||||
|
||||
return NS_OK;
|
||||
@ -78,19 +137,19 @@ TestDoubleStartPlaying()
|
||||
nsresult
|
||||
TestOneNormalChannel()
|
||||
{
|
||||
Agent agent(AUDIO_CHANNEL_NORMAL);
|
||||
nsresult rv = agent.Init();
|
||||
nsCOMPtr<Agent> agent = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||
nsresult rv = agent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool playing;
|
||||
rv = agent.StartPlaying(&playing);
|
||||
rv = agent->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
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);
|
||||
|
||||
rv = agent.StartPlaying(&playing);
|
||||
rv = agent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test1: A normal channel visible agent should be playing");
|
||||
|
||||
@ -100,34 +159,34 @@ TestOneNormalChannel()
|
||||
nsresult
|
||||
TestTwoNormalChannels()
|
||||
{
|
||||
Agent agent1(AUDIO_CHANNEL_NORMAL);
|
||||
nsresult rv = agent1.Init();
|
||||
nsCOMPtr<Agent> agent1 = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||
nsresult rv = agent1->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent agent2(AUDIO_CHANNEL_NORMAL);
|
||||
rv = agent2.Init();
|
||||
nsCOMPtr<Agent> agent2 = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||
rv = agent2->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool playing;
|
||||
rv = agent1.StartPlaying(&playing);
|
||||
rv = agent1->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
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);
|
||||
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);
|
||||
|
||||
rv = agent2.mAgent->SetVisibilityState(true);
|
||||
rv = agent2->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = agent1.StartPlaying(&playing);
|
||||
rv = agent1->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
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);
|
||||
TEST_ENSURE_BASE(playing, "Test2: A normal channel visible agent2 should be playing");
|
||||
|
||||
@ -137,213 +196,230 @@ TestTwoNormalChannels()
|
||||
nsresult
|
||||
TestContentChannels()
|
||||
{
|
||||
Agent agent1(AUDIO_CHANNEL_CONTENT);
|
||||
nsresult rv = agent1.Init();
|
||||
nsCOMPtr<Agent> agent1 = new Agent(AUDIO_CHANNEL_CONTENT);
|
||||
nsresult rv = agent1->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent agent2(AUDIO_CHANNEL_CONTENT);
|
||||
rv = agent2.Init();
|
||||
nsCOMPtr<Agent> agent2 = new Agent(AUDIO_CHANNEL_CONTENT);
|
||||
rv = agent2->Init();
|
||||
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);
|
||||
|
||||
rv = agent2.mAgent->SetVisibilityState(true);
|
||||
rv = agent2->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool 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);
|
||||
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);
|
||||
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);
|
||||
rv = agent2->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
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;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TestPriorities()
|
||||
{
|
||||
Agent normalAgent(AUDIO_CHANNEL_NORMAL);
|
||||
nsresult rv = normalAgent.Init();
|
||||
nsCOMPtr<Agent> normalAgent = new Agent(AUDIO_CHANNEL_NORMAL);
|
||||
nsresult rv = normalAgent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent contentAgent(AUDIO_CHANNEL_CONTENT);
|
||||
rv = contentAgent.Init();
|
||||
nsCOMPtr<Agent> contentAgent = new Agent(AUDIO_CHANNEL_CONTENT);
|
||||
rv = contentAgent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent notificationAgent(AUDIO_CHANNEL_NOTIFICATION);
|
||||
rv = notificationAgent.Init();
|
||||
nsCOMPtr<Agent> notificationAgent = new Agent(AUDIO_CHANNEL_NOTIFICATION);
|
||||
rv = notificationAgent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent alarmAgent(AUDIO_CHANNEL_ALARM);
|
||||
rv = alarmAgent.Init();
|
||||
nsCOMPtr<Agent> alarmAgent = new Agent(AUDIO_CHANNEL_ALARM);
|
||||
rv = alarmAgent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent telephonyAgent(AUDIO_CHANNEL_TELEPHONY);
|
||||
rv = telephonyAgent.Init();
|
||||
nsCOMPtr<Agent> telephonyAgent = new Agent(AUDIO_CHANNEL_TELEPHONY);
|
||||
rv = telephonyAgent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent ringerAgent(AUDIO_CHANNEL_RINGER);
|
||||
rv = ringerAgent.Init();
|
||||
nsCOMPtr<Agent> ringerAgent = new Agent(AUDIO_CHANNEL_RINGER);
|
||||
rv = ringerAgent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Agent pNotificationAgent(AUDIO_CHANNEL_PUBLICNOTIFICATION);
|
||||
rv = pNotificationAgent.Init();
|
||||
nsCOMPtr<Agent> pNotificationAgent = new Agent(AUDIO_CHANNEL_PUBLICNOTIFICATION);
|
||||
rv = pNotificationAgent->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool playing;
|
||||
|
||||
// Normal should not be playing because not visible.
|
||||
rv = normalAgent.StartPlaying(&playing);
|
||||
rv = normalAgent->StartPlaying(&playing);
|
||||
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.
|
||||
rv = contentAgent.StartPlaying(&playing);
|
||||
rv = contentAgent->StartPlaying(&playing);
|
||||
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.
|
||||
rv = notificationAgent.StartPlaying(&playing);
|
||||
rv = notificationAgent->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: An notification channel unvisible agent should be 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);
|
||||
TEST_ENSURE_BASE(!playing, "Test4: A content channel unvisible agent should not be playing when notification channel is playing");
|
||||
|
||||
// Adding an alarm.
|
||||
rv = alarmAgent.StartPlaying(&playing);
|
||||
rv = alarmAgent->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: An alarm channel unvisible agent should be 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);
|
||||
TEST_ENSURE_BASE(!playing, "Test4: A notification channel unvisible agent should not be playing when an alarm is playing");
|
||||
|
||||
// Adding an telephony.
|
||||
rv = telephonyAgent.StartPlaying(&playing);
|
||||
rv = telephonyAgent->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: An telephony channel unvisible agent should be 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);
|
||||
TEST_ENSURE_BASE(!playing, "Test4: A alarm channel unvisible agent should not be playing when a telephony is playing");
|
||||
|
||||
// Adding an ringer.
|
||||
rv = ringerAgent.StartPlaying(&playing);
|
||||
rv = ringerAgent->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: An ringer channel unvisible agent should be 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);
|
||||
TEST_ENSURE_BASE(!playing, "Test4: A telephony channel unvisible agent should not be playing when a riger is playing");
|
||||
|
||||
// Adding an pNotification.
|
||||
rv = pNotificationAgent.StartPlaying(&playing);
|
||||
rv = pNotificationAgent->StartPlaying(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
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.
|
||||
rv = ringerAgent.StartPlaying(&playing);
|
||||
rv = ringerAgent->StartPlaying(&playing);
|
||||
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");
|
||||
|
||||
// Settings visible the normal channel.
|
||||
rv = normalAgent.mAgent->SetVisibilityState(true);
|
||||
rv = normalAgent->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Normal should be playing because visible.
|
||||
rv = normalAgent.StartPlaying(&playing);
|
||||
rv = normalAgent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: A normal channel visible agent should be playing");
|
||||
|
||||
// Settings visible the content channel.
|
||||
rv = contentAgent.mAgent->SetVisibilityState(true);
|
||||
rv = contentAgent->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Content should be playing because visible.
|
||||
rv = contentAgent.StartPlaying(&playing);
|
||||
rv = contentAgent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: A content channel visible agent should be playing");
|
||||
|
||||
// Settings visible the notification channel.
|
||||
rv = notificationAgent.mAgent->SetVisibilityState(true);
|
||||
rv = notificationAgent->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Notification should be playing because visible.
|
||||
rv = notificationAgent.StartPlaying(&playing);
|
||||
rv = notificationAgent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: A notification channel visible agent should be playing");
|
||||
|
||||
// Settings visible the alarm channel.
|
||||
rv = alarmAgent.mAgent->SetVisibilityState(true);
|
||||
rv = alarmAgent->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Alarm should be playing because visible.
|
||||
rv = alarmAgent.StartPlaying(&playing);
|
||||
rv = alarmAgent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: A alarm channel visible agent should be playing");
|
||||
|
||||
// Settings visible the telephony channel.
|
||||
rv = telephonyAgent.mAgent->SetVisibilityState(true);
|
||||
rv = telephonyAgent->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Telephony should be playing because visible.
|
||||
rv = telephonyAgent.StartPlaying(&playing);
|
||||
rv = telephonyAgent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: A telephony channel visible agent should be playing");
|
||||
|
||||
// Settings visible the ringer channel.
|
||||
rv = ringerAgent.mAgent->SetVisibilityState(true);
|
||||
rv = ringerAgent->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Ringer should be playing because visible.
|
||||
rv = ringerAgent.StartPlaying(&playing);
|
||||
rv = ringerAgent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
TEST_ENSURE_BASE(playing, "Test4: A ringer channel visible agent should be playing");
|
||||
|
||||
// Settings visible the pNotification channel.
|
||||
rv = pNotificationAgent.mAgent->SetVisibilityState(true);
|
||||
rv = pNotificationAgent->SetVisibilityState(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// pNotification should be playing because visible.
|
||||
rv = pNotificationAgent.StartPlaying(&playing);
|
||||
rv = pNotificationAgent->GetCanPlay(&playing);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
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 708405-1.html
|
||||
load 745495.html
|
||||
load 844559.html
|
||||
|
@ -5,46 +5,53 @@
|
||||
import os
|
||||
import cPickle
|
||||
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.
|
||||
|outputprefix| is a prefix to use for the header guards and filename.
|
||||
"""
|
||||
|
||||
filename = outputprefix + ".h"
|
||||
depsname = ".deps/" + filename + ".pp"
|
||||
root = CGBindingRoot(config, outputprefix, webidlfile)
|
||||
if replaceFileIfChanged(filename, root.declare()):
|
||||
print "Generating binding header: %s" % (filename)
|
||||
with open(filename, 'wb') as f:
|
||||
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.
|
||||
|outputprefix| is a prefix to use for the header guards and filename.
|
||||
"""
|
||||
|
||||
filename = outputprefix + ".cpp"
|
||||
depsname = ".deps/" + filename + ".pp"
|
||||
root = CGBindingRoot(config, outputprefix, webidlfile)
|
||||
if replaceFileIfChanged(filename, root.define()):
|
||||
print "Generating binding implementation: %s" % (filename)
|
||||
with open(filename, 'wb') as f:
|
||||
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():
|
||||
|
||||
# Parse arguments.
|
||||
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.add_option("--verbose-errors", action='store_true', default=False,
|
||||
help="When an error happens, display the Python traceback.")
|
||||
(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)
|
||||
buildTarget = args[0]
|
||||
configFile = os.path.normpath(args[1])
|
||||
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
|
||||
f = open('ParserResults.pkl', 'rb')
|
||||
@ -56,9 +63,9 @@ def main():
|
||||
|
||||
# Generate the prototype classes.
|
||||
if buildTarget == "header":
|
||||
generate_binding_header(config, outputPrefix, webIDLFile);
|
||||
generate_binding_header(config, outputPrefix, srcPrefix, webIDLFile);
|
||||
elif buildTarget == "cpp":
|
||||
generate_binding_cpp(config, outputPrefix, webIDLFile);
|
||||
generate_binding_cpp(config, outputPrefix, srcPrefix, webIDLFile);
|
||||
else:
|
||||
assert False # not reached
|
||||
|
||||
|
@ -59,6 +59,9 @@ class CGThing():
|
||||
def define(self):
|
||||
"""Produce code for a cpp file."""
|
||||
assert(False) # Override me!
|
||||
def deps(self):
|
||||
"""Produce the deps for a pp file"""
|
||||
assert(False) # Override me!
|
||||
|
||||
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)
|
||||
def define(self):
|
||||
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):
|
||||
"""
|
||||
@ -322,6 +332,8 @@ class CGGeneric(CGThing):
|
||||
return self.declareText
|
||||
def define(self):
|
||||
return self.defineText
|
||||
def deps(self):
|
||||
return set()
|
||||
|
||||
# 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
|
||||
@ -387,6 +399,9 @@ class CGWrapper(CGThing):
|
||||
defn.replace("\n", "\n" + (" " * len(self.definePre))))
|
||||
return self.definePre + defn + self.definePost
|
||||
|
||||
def deps(self):
|
||||
return self.child.deps()
|
||||
|
||||
class CGIfWrapper(CGWrapper):
|
||||
def __init__(self, child, condition):
|
||||
pre = CGWrapper(CGGeneric(condition), pre="if (", post=") {\n",
|
||||
@ -985,14 +1000,30 @@ class CGNamedConstructors(CGThing):
|
||||
def define(self):
|
||||
if len(self.descriptor.interface.namedConstructors) == 0:
|
||||
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")
|
||||
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 = CGWrapper(CGIndenter(namedConstructors),
|
||||
pre="static const NamedConstructor namedConstructors[] = {\n",
|
||||
post="\n};\n")
|
||||
return namedConstructors.define()
|
||||
return nativePropertyHooks + namedConstructors.define()
|
||||
|
||||
class CGClassHasInstanceHook(CGAbstractStaticMethod):
|
||||
def __init__(self, descriptor):
|
||||
@ -4853,6 +4884,9 @@ class CGEnum(CGThing):
|
||||
""" % (len(self.enum.values()) + 1,
|
||||
",\n ".join(['{"' + val + '", ' + str(len(val)) + '}' for val in self.enum.values()]))
|
||||
|
||||
def deps(self):
|
||||
return self.enum.getDeps()
|
||||
|
||||
def getUnionAccessorSignatureType(type, descriptorProvider):
|
||||
"""
|
||||
Returns the types that are used in the getter and setter signatures for
|
||||
@ -5743,6 +5777,8 @@ class CGPrototypeTraitsClass(CGClass):
|
||||
templateArgs=templateArgs,
|
||||
templateSpecialization=templateSpecialization,
|
||||
enums=enums, typedefs=typedefs, isStruct=True)
|
||||
def deps(self):
|
||||
return set()
|
||||
|
||||
class CGPrototypeIDMapClass(CGClass):
|
||||
def __init__(self, descriptor, indent=''):
|
||||
@ -5754,6 +5790,8 @@ class CGPrototypeIDMapClass(CGClass):
|
||||
templateArgs=templateArgs,
|
||||
templateSpecialization=templateSpecialization,
|
||||
enums=enums, isStruct=True)
|
||||
def deps(self):
|
||||
return set()
|
||||
|
||||
class CGClassForwardDeclare(CGThing):
|
||||
def __init__(self, name, isStruct=False):
|
||||
@ -5766,6 +5804,8 @@ class CGClassForwardDeclare(CGThing):
|
||||
def define(self):
|
||||
# Header only
|
||||
return ''
|
||||
def deps(self):
|
||||
return set()
|
||||
|
||||
class CGProxySpecialOperation(CGPerSignatureCall):
|
||||
"""
|
||||
@ -6442,6 +6482,8 @@ class CGDescriptor(CGThing):
|
||||
|
||||
assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
|
||||
|
||||
self._deps = descriptor.interface.getDeps()
|
||||
|
||||
cgThings = []
|
||||
# These are set to true if at least one non-static
|
||||
# method/getter/setter exist on the interface.
|
||||
@ -6578,6 +6620,8 @@ class CGDescriptor(CGThing):
|
||||
return self.cgRoot.declare()
|
||||
def define(self):
|
||||
return self.cgRoot.define()
|
||||
def deps(self):
|
||||
return self._deps
|
||||
|
||||
class CGNamespacedEnum(CGThing):
|
||||
def __init__(self, namespace, enumName, names, values, comment=""):
|
||||
@ -6782,6 +6826,9 @@ class CGDictionary(CGThing):
|
||||
"defineMembers": "\n\n".join(memberDefines)
|
||||
})
|
||||
|
||||
def deps(self):
|
||||
return self.dictionary.getDeps()
|
||||
|
||||
@staticmethod
|
||||
def makeDictionaryName(dictionary, workers):
|
||||
suffix = "Workers" if workers else ""
|
||||
@ -7203,6 +7250,9 @@ class CGBindingRoot(CGThing):
|
||||
def define(self):
|
||||
return stripTrailingWhitespace(self.root.define())
|
||||
|
||||
def deps(self):
|
||||
return self.root.deps()
|
||||
|
||||
class CGNativeMember(ClassMethod):
|
||||
def __init__(self, descriptor, member, name, signature, extendedAttrs,
|
||||
breakAfter=True, passCxAsNeeded=True, visibility="public",
|
||||
@ -7778,6 +7828,7 @@ class CGCallback(CGClass):
|
||||
def __init__(self, idlObject, descriptorProvider, baseName, methods,
|
||||
getters=[], setters=[]):
|
||||
self.baseName = baseName
|
||||
self._deps = idlObject.getDeps()
|
||||
name = idlObject.identifier.name
|
||||
if descriptorProvider.workers:
|
||||
name += "Workers"
|
||||
@ -7867,6 +7918,9 @@ class CGCallback(CGClass):
|
||||
body=bodyWithoutThis),
|
||||
method]
|
||||
|
||||
def deps(self):
|
||||
return self._deps
|
||||
|
||||
class CGCallbackFunction(CGCallback):
|
||||
def __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
|
||||
# are.
|
||||
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)))
|
||||
(mainCallbacks, mainDictionaries) = findCallbacksAndDictionaries(mainTypes)
|
||||
|
||||
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)))
|
||||
(workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
|
||||
|
||||
|
@ -75,7 +75,6 @@ EXPORTS_$(binding_include_path) = \
|
||||
TypedArray.h \
|
||||
UnionConversions.h \
|
||||
UnionTypes.h \
|
||||
$(exported_binding_headers) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/js/xpconnect/src \
|
||||
@ -97,8 +96,34 @@ LOCAL_INCLUDES += \
|
||||
$(NULL)
|
||||
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
|
||||
|
||||
# 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
|
||||
# dom/bindings/test/Makefile.in too.
|
||||
bindinggen_dependencies := \
|
||||
@ -107,7 +132,6 @@ bindinggen_dependencies := \
|
||||
Configuration.py \
|
||||
Codegen.py \
|
||||
parser/WebIDL.py \
|
||||
ParserResults.pkl \
|
||||
$(GLOBAL_DEPS) \
|
||||
$(NULL)
|
||||
|
||||
@ -129,20 +153,26 @@ $(test_webidl_files): %: $(srcdir)/test/%
|
||||
|
||||
$(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
|
||||
%.webidl \
|
||||
$(call mkdir_deps,$(MDDEPDIR)) \
|
||||
$(NULL)
|
||||
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) -I$(srcdir)/parser \
|
||||
$(srcdir)/BindingGen.py header \
|
||||
$(srcdir)/Bindings.conf $*Binding \
|
||||
$(srcdir)/Bindings.conf \
|
||||
$*Binding \
|
||||
$(topsrcdir)/dom/webidl/ \
|
||||
$*.webidl
|
||||
|
||||
$(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
|
||||
%.webidl \
|
||||
$(call mkdir_deps,$(MDDEPDIR)) \
|
||||
$(NULL)
|
||||
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) -I$(srcdir)/parser \
|
||||
$(srcdir)/BindingGen.py cpp \
|
||||
$(srcdir)/Bindings.conf $*Binding \
|
||||
$(srcdir)/Bindings.conf \
|
||||
$*Binding \
|
||||
$(topsrcdir)/dom/webidl/ \
|
||||
$*.webidl
|
||||
|
||||
$(globalgen_targets): ParserResults.pkl
|
||||
@ -195,4 +225,6 @@ GARBAGE += \
|
||||
# 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
|
||||
# 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):
|
||||
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):
|
||||
def __init__(self, location, parentScope, identifier):
|
||||
IDLObject.__init__(self, location)
|
||||
@ -443,6 +475,9 @@ class IDLExternalInterface(IDLObjectWithIdentifier):
|
||||
def resolve(self, parentScope):
|
||||
pass
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set()
|
||||
|
||||
class IDLInterface(IDLObjectWithScope):
|
||||
def __init__(self, location, parentScope, name, parent, members,
|
||||
isPartial):
|
||||
@ -916,6 +951,13 @@ class IDLInterface(IDLObjectWithScope):
|
||||
# Put the new members at the beginning
|
||||
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):
|
||||
def __init__(self, location, parentScope, name, parent, members):
|
||||
assert isinstance(parentScope, IDLScope)
|
||||
@ -986,6 +1028,11 @@ class IDLDictionary(IDLObjectWithScope):
|
||||
def addExtendedAttributes(self, attrs):
|
||||
assert len(attrs) == 0
|
||||
|
||||
def _getDependentObjects(self):
|
||||
deps = set(self.members)
|
||||
if (self.parent):
|
||||
deps.add(self.parent)
|
||||
return deps
|
||||
|
||||
class IDLEnum(IDLObjectWithIdentifier):
|
||||
def __init__(self, location, parentScope, name, values):
|
||||
@ -1014,6 +1061,9 @@ class IDLEnum(IDLObjectWithIdentifier):
|
||||
def addExtendedAttributes(self, attrs):
|
||||
assert len(attrs) == 0
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set()
|
||||
|
||||
class IDLType(IDLObject):
|
||||
Tags = enum(
|
||||
# The integer types
|
||||
@ -1303,6 +1353,9 @@ class IDLNullableType(IDLType):
|
||||
return False
|
||||
return self.inner.isDistinguishableFrom(other)
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return self.inner._getDependentObjects()
|
||||
|
||||
class IDLSequenceType(IDLType):
|
||||
def __init__(self, location, parameterType):
|
||||
assert not parameterType.isVoid()
|
||||
@ -1373,6 +1426,9 @@ class IDLSequenceType(IDLType):
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isDate() or other.isNonCallbackInterface())
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return self.inner._getDependentObjects()
|
||||
|
||||
class IDLUnionType(IDLType):
|
||||
def __init__(self, location, memberTypes):
|
||||
IDLType.__init__(self, location, "")
|
||||
@ -1476,6 +1532,9 @@ class IDLUnionType(IDLType):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set(self.memberTypes)
|
||||
|
||||
class IDLArrayType(IDLType):
|
||||
def __init__(self, location, parameterType):
|
||||
assert not parameterType.isVoid()
|
||||
@ -1551,6 +1610,9 @@ class IDLArrayType(IDLType):
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isDate() or other.isNonCallbackInterface())
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return self.inner._getDependentObjects()
|
||||
|
||||
class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
||||
def __init__(self, location, innerType, name):
|
||||
IDLType.__init__(self, location, innerType.name)
|
||||
@ -1638,6 +1700,9 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
||||
def isDistinguishableFrom(self, other):
|
||||
return self.inner.isDistinguishableFrom(other)
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return self.inner._getDependentObjects()
|
||||
|
||||
class IDLWrapperType(IDLType):
|
||||
def __init__(self, location, inner):
|
||||
IDLType.__init__(self, location, inner.identifier.name)
|
||||
@ -1741,6 +1806,23 @@ class IDLWrapperType(IDLType):
|
||||
assert other.isObject()
|
||||
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):
|
||||
|
||||
Types = enum(
|
||||
@ -1906,6 +1988,9 @@ class IDLBuiltinType(IDLType):
|
||||
(self.isTypedArray() and not other.isArrayBufferView() and not
|
||||
(other.isTypedArray() and other.name == self.name)))))
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set()
|
||||
|
||||
BuiltinTypes = {
|
||||
IDLBuiltinType.Types.byte:
|
||||
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
|
||||
@ -2064,6 +2149,9 @@ class IDLValue(IDLObject):
|
||||
raise WebIDLError("Cannot coerce type %s to type %s." %
|
||||
(self.type, type), [location])
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set()
|
||||
|
||||
class IDLNullValue(IDLObject):
|
||||
def __init__(self, location):
|
||||
IDLObject.__init__(self, location)
|
||||
@ -2081,7 +2169,10 @@ class IDLNullValue(IDLObject):
|
||||
nullValue = IDLNullValue(self.location)
|
||||
nullValue.type = type
|
||||
return nullValue
|
||||
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set()
|
||||
|
||||
|
||||
class IDLInterfaceMember(IDLObjectWithIdentifier):
|
||||
|
||||
@ -2162,6 +2253,9 @@ class IDLConst(IDLInterfaceMember):
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set([self.type, self.value])
|
||||
|
||||
class IDLAttribute(IDLInterfaceMember):
|
||||
def __init__(self, location, identifier, type, readonly, inherit=False,
|
||||
static=False, stringifier=False):
|
||||
@ -2307,6 +2401,9 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
def isUnforgeable(self):
|
||||
return self._unforgeable
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set([self.type])
|
||||
|
||||
class IDLArgument(IDLObjectWithIdentifier):
|
||||
def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False):
|
||||
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
|
||||
@ -2379,6 +2476,12 @@ class IDLArgument(IDLObjectWithIdentifier):
|
||||
self.location)
|
||||
assert self.defaultValue
|
||||
|
||||
def _getDependentObjects(self):
|
||||
deps = set([self.type])
|
||||
if self.defaultValue:
|
||||
deps.add(self.defaultValue)
|
||||
return deps
|
||||
|
||||
class IDLCallbackType(IDLType, IDLObjectWithScope):
|
||||
def __init__(self, location, parentScope, identifier, returnType, arguments):
|
||||
assert isinstance(returnType, IDLType)
|
||||
@ -2446,6 +2549,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
|
||||
if len(unhandledAttrs) != 0:
|
||||
IDLType.addExtendedAttributes(self, unhandledAttrs)
|
||||
|
||||
def _getDependentObjects(self):
|
||||
return set([self._returnType] + self._arguments)
|
||||
|
||||
class IDLMethodOverload:
|
||||
"""
|
||||
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.location = location
|
||||
|
||||
def _getDependentObjects(self):
|
||||
deps = set(self.arguments)
|
||||
deps.add(self.returnType)
|
||||
return deps
|
||||
|
||||
class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
|
||||
Special = enum(
|
||||
@ -2808,6 +2919,12 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
[attr.location, self.location])
|
||||
IDLInterfaceMember.handleExtendedAttribute(self, attr)
|
||||
|
||||
def _getDependentObjects(self):
|
||||
deps = set()
|
||||
for overload in self._overloads:
|
||||
deps.union(overload._getDependentObjects())
|
||||
return deps
|
||||
|
||||
class IDLImplementsStatement(IDLObject):
|
||||
def __init__(self, location, implementor, implementee):
|
||||
IDLObject.__init__(self, location)
|
||||
|
@ -90,7 +90,7 @@ def checkEquivalent(iface, harness):
|
||||
for attr in dir(type1):
|
||||
if attr.startswith('_') or \
|
||||
attr in ['nullable', 'builtin', 'filename', 'location',
|
||||
'inner', 'QName'] or \
|
||||
'inner', 'QName', 'getDeps'] or \
|
||||
(hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
|
||||
continue
|
||||
|
||||
|
@ -44,7 +44,6 @@ bindinggen_dependencies := \
|
||||
../Configuration.py \
|
||||
../Codegen.py \
|
||||
../parser/WebIDL.py \
|
||||
../ParserResults.pkl \
|
||||
../Makefile \
|
||||
$(GLOBAL_DEPS) \
|
||||
$(NULL)
|
||||
|
@ -13,7 +13,7 @@
|
||||
#endif
|
||||
|
||||
#include "BrowserElementParent.h"
|
||||
#include "nsHTMLIFrameElement.h"
|
||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||
#include "nsOpenWindowEventDetail.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIDOMCustomEvent.h"
|
||||
@ -22,6 +22,7 @@
|
||||
#include "nsAsyncScrollEventDetail.h"
|
||||
|
||||
using mozilla::dom::Element;
|
||||
using mozilla::dom::HTMLIFrameElement;
|
||||
using mozilla::dom::TabParent;
|
||||
|
||||
namespace {
|
||||
@ -30,7 +31,7 @@ namespace {
|
||||
* Create an <iframe mozbrowser> owned by the same document as
|
||||
* aOpenerFrameElement.
|
||||
*/
|
||||
already_AddRefed<nsHTMLIFrameElement>
|
||||
already_AddRefed<HTMLIFrameElement>
|
||||
CreateIframe(Element* aOpenerFrameElement, const nsAString& aName, bool aRemote)
|
||||
{
|
||||
nsNodeInfoManager *nodeInfoManager =
|
||||
@ -42,8 +43,8 @@ CreateIframe(Element* aOpenerFrameElement, const nsAString& aName, bool aRemote)
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
|
||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
||||
static_cast<nsHTMLIFrameElement*>(
|
||||
nsRefPtr<HTMLIFrameElement> popupFrameElement =
|
||||
static_cast<HTMLIFrameElement*>(
|
||||
NS_NewHTMLIFrameElement(nodeInfo.forget(), mozilla::dom::NOT_FROM_PARSER));
|
||||
|
||||
popupFrameElement->SetMozbrowser(true);
|
||||
@ -151,7 +152,7 @@ BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent,
|
||||
nsCOMPtr<Element> openerFrameElement =
|
||||
do_QueryInterface(aOpenerTabParent->GetOwnerElement());
|
||||
NS_ENSURE_TRUE(openerFrameElement, false);
|
||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
||||
nsRefPtr<HTMLIFrameElement> popupFrameElement =
|
||||
CreateIframe(openerFrameElement, aName, /* aRemote = */ true);
|
||||
|
||||
// Normally an <iframe> element will try to create a frameLoader when the
|
||||
@ -209,7 +210,7 @@ BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
|
||||
nsCOMPtr<Element> openerFrameElement =
|
||||
do_QueryInterface(openerFrameDOMElement);
|
||||
|
||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
||||
nsRefPtr<HTMLIFrameElement> popupFrameElement =
|
||||
CreateIframe(openerFrameElement, aName, /* aRemote = */ false);
|
||||
NS_ENSURE_TRUE(popupFrameElement, false);
|
||||
|
||||
|
@ -8,7 +8,7 @@ SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function makeAllAppsLaunchable() {
|
||||
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 originalValue = appRegistry.allAppsLaunchable;
|
||||
|
@ -54,7 +54,7 @@ function getRandomView(size)
|
||||
|
||||
function getBlob(type, view)
|
||||
{
|
||||
return utils.getBlob([view], {type: type});
|
||||
return SpecialPowers.unwrap(utils.getBlob([view], {type: type}));
|
||||
}
|
||||
|
||||
function getRandomBlob(size)
|
||||
|
@ -179,7 +179,7 @@ function compareBuffers(buffer1, buffer2)
|
||||
|
||||
function getBlob(type, buffer)
|
||||
{
|
||||
return utils.getBlob([buffer], {type: type});
|
||||
return SpecialPowers.unwrap(utils.getBlob([buffer], {type: type}));
|
||||
}
|
||||
|
||||
function getRandomBlob(size)
|
||||
@ -189,5 +189,5 @@ function getRandomBlob(size)
|
||||
|
||||
function getFileId(blob)
|
||||
{
|
||||
return utils.getFileId(blob);
|
||||
return SpecialPowers.unwrap(utils.getFileId(blob));
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
function createNonUnicodeData() {
|
||||
const Cc = SpecialPowers.wrap(Components).classes;
|
||||
const Ci = SpecialPowers.wrap(Components).interfaces;
|
||||
const Cc = SpecialPowers.Cc;
|
||||
const Ci = SpecialPowers.Ci;
|
||||
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
var testFile = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
|
@ -49,12 +49,12 @@ function compareBuffers(buffer1, buffer2)
|
||||
|
||||
function getBlob(type, view)
|
||||
{
|
||||
return utils.getBlob([view], {type: type});
|
||||
return SpecialPowers.unwrap(utils.getBlob([view], {type: type}));
|
||||
}
|
||||
|
||||
function getFile(name, type, view)
|
||||
{
|
||||
return utils.getFile(name, [view], {type: type});
|
||||
return SpecialPowers.unwrap(utils.getFile(name, [view], {type: type}));
|
||||
}
|
||||
|
||||
function getRandomBlob(size)
|
||||
|
@ -10,7 +10,7 @@ var archiveReaderEnabled = false;
|
||||
// and content mochitests (where the |Components| object is accessible only as
|
||||
// SpecialPowers.Components). Expose Components if necessary here to make things
|
||||
// work everywhere.
|
||||
if (typeof Components === 'undefined')
|
||||
if (typeof Components === 'undefined' && typeof SpecialPowers === 'object')
|
||||
Components = SpecialPowers.Components;
|
||||
|
||||
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.
|
||||
HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
|
||||
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.
|
||||
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.
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
ChildCountIncorrect=Invalid markup: Incorrect number of children for <%1$S/> tag.
|
||||
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/>.
|
||||
|
||||
# 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;
|
||||
nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
|
||||
pm->TestPermission(doc->NodePrincipal(), &permission);
|
||||
if ((permission == nsIPopupWindowManager::DENY_POPUP)) {
|
||||
if (permission == nsIPopupWindowManager::DENY_POPUP) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = aWindow->GetExtantDocument();
|
||||
nsGlobalWindow::FirePopupBlockedEvent(
|
||||
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,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIMobileMessageDatabaseService.idl"
|
||||
|
||||
interface nsIDOMMozSmsMessage;
|
||||
|
||||
[scriptable, function, uuid(9cd80750-6a08-11e2-ac93-bf895e53f40e)]
|
||||
[scriptable, function, uuid(0bffae74-71db-11e2-962a-73cf64d6393e)]
|
||||
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
|
||||
{
|
||||
long saveReceivedMessage(in DOMString aSender,
|
||||
in DOMString aBody,
|
||||
in DOMString aMessageClass,
|
||||
in unsigned long long aDate,
|
||||
/**
|
||||
* |aMessage| Object: should contain the following properties for internal use:
|
||||
* - |type| DOMString: "sms" or "mms"
|
||||
* - |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);
|
||||
long saveSendingMessage(in DOMString aReceiver,
|
||||
in DOMString aBody,
|
||||
in DOMString aDeliveryStatus,
|
||||
in unsigned long long aDate,
|
||||
|
||||
/**
|
||||
* |aMessage| Object: should contain the following properties for internal use:
|
||||
* - |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);
|
||||
|
||||
void setMessageDelivery(in long aMessageId,
|
||||
in DOMString aDelivery,
|
||||
in DOMString aDeliveryStatus,
|
||||
|
@ -413,8 +413,8 @@ MobileMessageDatabaseService.prototype = {
|
||||
};
|
||||
},
|
||||
|
||||
createMessageFromRecord: function createMessageFromRecord(aRecord) {
|
||||
if (DEBUG) debug("createMessageFromRecord: " + JSON.stringify(aRecord));
|
||||
createSmsMessageFromRecord: function createSmsMessageFromRecord(aRecord) {
|
||||
if (DEBUG) debug("createSmsMessageFromRecord: " + JSON.stringify(aRecord));
|
||||
return gSmsService.createSmsMessage(aRecord.id,
|
||||
aRecord.delivery,
|
||||
aRecord.deliveryStatus,
|
||||
@ -482,7 +482,7 @@ MobileMessageDatabaseService.prototype = {
|
||||
let getRequest = aObjectStore.get(firstMessageId);
|
||||
let self = this;
|
||||
getRequest.onsuccess = function onsuccess(event) {
|
||||
let sms = self.createMessageFromRecord(event.target.result);
|
||||
let sms = self.createSmsMessageFromRecord(event.target.result);
|
||||
if (aMessageList.listId >= 0) {
|
||||
if (DEBUG) {
|
||||
debug("notifyNextMessageInListGot - listId: "
|
||||
@ -657,8 +657,7 @@ MobileMessageDatabaseService.prototype = {
|
||||
if (!aCallback) {
|
||||
return;
|
||||
}
|
||||
let sms = self.createMessageFromRecord(aRecord);
|
||||
aCallback.notify(rv, sms);
|
||||
aCallback.notify(rv, aRecord);
|
||||
}
|
||||
|
||||
this.newTxn(READ_WRITE, function(error, txn, stores) {
|
||||
@ -678,9 +677,8 @@ MobileMessageDatabaseService.prototype = {
|
||||
// First add to main objectStore.
|
||||
stores[0].put(aRecord);
|
||||
|
||||
let number = getNumberFromRecord(aRecord);
|
||||
|
||||
// Next update the other objectStore.
|
||||
let number = getNumberFromRecord(aRecord);
|
||||
stores[1].get(number).onsuccess = function onsuccess(event) {
|
||||
let mostRecentEntry = event.target.result;
|
||||
if (mostRecentEntry) {
|
||||
@ -713,100 +711,96 @@ MobileMessageDatabaseService.prototype = {
|
||||
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
|
||||
*/
|
||||
|
||||
saveReceivedMessage: function saveReceivedMessage(
|
||||
aSender, aBody, aMessageClass, aDate, aCallback) {
|
||||
let iccInfo = this.mRIL.rilContext.iccInfo;
|
||||
let receiver = iccInfo ? iccInfo.msisdn : null;
|
||||
|
||||
// Workaround an xpconnect issue with undefined string objects.
|
||||
// See bug 808220
|
||||
if (receiver === undefined || receiver === "undefined") {
|
||||
receiver = null;
|
||||
saveReceivedMessage: function saveReceivedMessage(aMessage, aCallback) {
|
||||
if (aMessage.type === undefined ||
|
||||
aMessage.sender === undefined ||
|
||||
aMessage.messageClass === undefined ||
|
||||
aMessage.timestamp === undefined) {
|
||||
if (aCallback) {
|
||||
aCallback.notify(Cr.NS_ERROR_FAILURE, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (receiver) {
|
||||
let parsedNumber = PhoneNumberUtils.parse(receiver);
|
||||
receiver = (parsedNumber && parsedNumber.internationalNumber)
|
||||
? parsedNumber.internationalNumber
|
||||
: receiver;
|
||||
}
|
||||
let receiver = this.getRilIccInfoMsisdn();
|
||||
receiver = this.makePhoneNumberInternational(receiver);
|
||||
|
||||
let sender = aSender;
|
||||
if (sender) {
|
||||
let parsedNumber = PhoneNumberUtils.parse(sender);
|
||||
sender = (parsedNumber && parsedNumber.internationalNumber)
|
||||
? parsedNumber.internationalNumber
|
||||
: sender;
|
||||
}
|
||||
let sender = aMessage.sender =
|
||||
this.makePhoneNumberInternational(aMessage.sender);
|
||||
|
||||
let record = {
|
||||
deliveryIndex: [DELIVERY_RECEIVED, aDate],
|
||||
numberIndex: [[sender, aDate], [receiver, aDate]],
|
||||
readIndex: [FILTER_READ_UNREAD, aDate],
|
||||
let timestamp = aMessage.timestamp;
|
||||
|
||||
delivery: DELIVERY_RECEIVED,
|
||||
deliveryStatus: DELIVERY_STATUS_SUCCESS,
|
||||
sender: sender,
|
||||
receiver: receiver,
|
||||
body: aBody,
|
||||
messageClass: aMessageClass,
|
||||
timestamp: aDate,
|
||||
read: FILTER_READ_UNREAD
|
||||
};
|
||||
return this.saveRecord(record, aCallback);
|
||||
// Adding needed indexes and extra attributes for internal use.
|
||||
aMessage.deliveryIndex = [DELIVERY_RECEIVED, timestamp];
|
||||
aMessage.numberIndex = [[sender, timestamp], [receiver, timestamp]];
|
||||
aMessage.readIndex = [FILTER_READ_UNREAD, timestamp];
|
||||
aMessage.delivery = DELIVERY_RECEIVED;
|
||||
aMessage.deliveryStatus = DELIVERY_STATUS_SUCCESS;
|
||||
aMessage.receiver = receiver;
|
||||
aMessage.read = FILTER_READ_UNREAD;
|
||||
|
||||
return this.saveRecord(aMessage, aCallback);
|
||||
},
|
||||
|
||||
saveSendingMessage: function saveSendingMessage(
|
||||
aReceiver, aBody, aDeliveryStatus, aDate, aCallback) {
|
||||
saveSendingMessage: function saveSendingMessage(aMessage, 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 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 (receiver) {
|
||||
let parsedNumber = PhoneNumberUtils.parse(receiver.toString());
|
||||
receiver = (parsedNumber && parsedNumber.internationalNumber)
|
||||
? parsedNumber.internationalNumber
|
||||
: receiver;
|
||||
}
|
||||
|
||||
if (sender) {
|
||||
let parsedNumber = PhoneNumberUtils.parse(sender.toString());
|
||||
sender = (parsedNumber && parsedNumber.internationalNumber)
|
||||
? parsedNumber.internationalNumber
|
||||
: sender;
|
||||
}
|
||||
receiver = aMessage.receiver = this.makePhoneNumberInternational(receiver);
|
||||
sender = this.makePhoneNumberInternational(sender);
|
||||
}
|
||||
|
||||
let record = {
|
||||
deliveryIndex: [DELIVERY_SENDING, aDate],
|
||||
numberIndex: [[sender, aDate], [receiver, aDate]],
|
||||
readIndex: [FILTER_READ_READ, aDate],
|
||||
let timestamp = aMessage.timestamp;
|
||||
|
||||
delivery: DELIVERY_SENDING,
|
||||
deliveryStatus: aDeliveryStatus,
|
||||
sender: sender,
|
||||
receiver: receiver,
|
||||
body: aBody,
|
||||
messageClass: MESSAGE_CLASS_NORMAL,
|
||||
timestamp: aDate,
|
||||
read: FILTER_READ_READ
|
||||
};
|
||||
return this.saveRecord(record, aCallback);
|
||||
// Adding needed indexes and extra attributes for internal use.
|
||||
aMessage.deliveryIndex = [DELIVERY_SENDING, timestamp];
|
||||
aMessage.numberIndex = [[sender, timestamp], [receiver, timestamp]];
|
||||
aMessage.readIndex = [FILTER_READ_READ, timestamp];
|
||||
aMessage.delivery = DELIVERY_SENDING;
|
||||
aMessage.sender = sender;
|
||||
aMessage.messageClass = MESSAGE_CLASS_NORMAL;
|
||||
aMessage.read = FILTER_READ_READ;
|
||||
|
||||
return this.saveRecord(aMessage, aCallback);
|
||||
},
|
||||
|
||||
setMessageDelivery: function setMessageDelivery(
|
||||
@ -822,11 +816,7 @@ MobileMessageDatabaseService.prototype = {
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
let sms = null;
|
||||
if (record) {
|
||||
sms = self.createMessageFromRecord(record);
|
||||
}
|
||||
callback.notify(rv, sms);
|
||||
callback.notify(rv, record);
|
||||
}
|
||||
|
||||
this.newTxn(READ_WRITE, function (error, txn, store) {
|
||||
@ -914,7 +904,7 @@ MobileMessageDatabaseService.prototype = {
|
||||
aRequest.notifyGetMessageFailed(Ci.nsISmsRequest.UNKNOWN_ERROR);
|
||||
return;
|
||||
}
|
||||
let sms = self.createMessageFromRecord(record);
|
||||
let sms = self.createSmsMessageFromRecord(record);
|
||||
aRequest.notifyMessageGot(sms);
|
||||
};
|
||||
|
||||
@ -1220,7 +1210,7 @@ MobileMessageDatabaseService.prototype = {
|
||||
// For all numbers.
|
||||
processing: filter.numbers.length,
|
||||
results: []
|
||||
}];
|
||||
}];
|
||||
|
||||
let timeRange = null;
|
||||
if (filter.startDate != null && filter.endDate != null) {
|
||||
@ -1327,7 +1317,7 @@ MobileMessageDatabaseService.prototype = {
|
||||
if (DEBUG) debug("Could not get message id " + messageId);
|
||||
aRequest.notifyReadMessageListFailed(Ci.nsISmsRequest.NOT_FOUND_ERROR);
|
||||
}
|
||||
let sms = self.createMessageFromRecord(record);
|
||||
let sms = self.createSmsMessageFromRecord(record);
|
||||
aRequest.notifyNextMessageInListGot(sms);
|
||||
};
|
||||
|
||||
|
@ -30,13 +30,12 @@ var testCertApp = {
|
||||
};
|
||||
|
||||
SpecialPowers.addPermission("permissions", true, document);
|
||||
var comp = SpecialPowers.wrap(Components);
|
||||
SpecialPowers.pushPrefEnv({ "set": [["dom.mozPermissionSettings.enabled", true]] },
|
||||
function() {
|
||||
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;
|
||||
|
||||
function permissionTest() {
|
||||
|
@ -21,8 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={678695}
|
||||
|
||||
"use strict";
|
||||
|
||||
var comp = SpecialPowers.wrap(Components);
|
||||
comp.utils.import("resource://gre/modules/SettingsChangeNotifier.jsm");
|
||||
SpecialPowers.Cu.import("resource://gre/modules/SettingsChangeNotifier.jsm");
|
||||
SpecialPowers.setBoolPref("dom.mozSettings.enabled", true);
|
||||
SpecialPowers.addPermission("settings-write", true, document);
|
||||
SpecialPowers.addPermission("settings-read", true, document);
|
||||
|
@ -177,21 +177,27 @@ function newRandomId() {
|
||||
|
||||
let sms = [
|
||||
{
|
||||
type: "sms",
|
||||
sender: "+34666000000",
|
||||
receiver: "+34666111000",
|
||||
body: "message 0",
|
||||
messageClass: "normal",
|
||||
timestamp: 1329999861762
|
||||
},
|
||||
{
|
||||
type: "sms",
|
||||
sender: "+34666000111",
|
||||
receiver: "+34666111111",
|
||||
body: "message 1",
|
||||
messageClass: "normal",
|
||||
timestamp: 1329999861763
|
||||
},
|
||||
{
|
||||
type: "sms",
|
||||
sender: "+34666000222",
|
||||
receiver: "+34666111222",
|
||||
body: "message 2",
|
||||
messageClass: "normal",
|
||||
timestamp: 1329999861764
|
||||
},
|
||||
];
|
||||
@ -201,9 +207,7 @@ let sms = [
|
||||
*/
|
||||
add_test(function test_saveReceivedMessage() {
|
||||
info("test_saveReceivedMessage");
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0].sender,
|
||||
sms[0].body,
|
||||
sms[0].timestamp);
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
|
||||
checkDB(function (store) {
|
||||
let request = store.get(messageId);
|
||||
request.onsuccess = function onsuccess() {
|
||||
@ -262,9 +266,7 @@ add_test(function test_getMessage_success() {
|
||||
run_next_test();
|
||||
}
|
||||
});
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2].sender,
|
||||
sms[2].body,
|
||||
sms[2].timestamp);
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
|
||||
SimpleTest.executeSoon(function () {
|
||||
gMobileMessageDatabaseService.getMessage(messageId, fakeRequestId);
|
||||
});
|
||||
@ -821,9 +823,7 @@ add_test(function test_deleteMessage_success() {
|
||||
run_next_test();
|
||||
}
|
||||
});
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0].sender,
|
||||
sms[0].body,
|
||||
sms[0].timestamp);
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[0]);
|
||||
SimpleTest.executeSoon(function () {
|
||||
gMobileMessageDatabaseService.deleteMessage(messageId, fakeRequestId);
|
||||
});
|
||||
@ -852,9 +852,7 @@ add_test(function test_markMessageRead_success() {
|
||||
run_next_test();
|
||||
}
|
||||
});
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2].sender,
|
||||
sms[2].body,
|
||||
sms[2].timestamp);
|
||||
let messageId = gMobileMessageDatabaseService.saveReceivedMessage(sms[2]);
|
||||
SimpleTest.executeSoon(function () {
|
||||
gMobileMessageDatabaseService.markMessageRead(messageId, true, fakeRequestId);
|
||||
});
|
||||
|
@ -1476,6 +1476,18 @@ RadioInterfaceLayer.prototype = {
|
||||
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,
|
||||
handleSmsReceived: function handleSmsReceived(message) {
|
||||
debug("handleSmsReceived: " + JSON.stringify(message));
|
||||
@ -1501,6 +1513,11 @@ RadioInterfaceLayer.prototype = {
|
||||
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
|
||||
// For now we don't store indicators persistently. When the mwi.discard
|
||||
// flag is false, we'll need to persist the indicator to EFmwis.
|
||||
@ -1508,13 +1525,14 @@ RadioInterfaceLayer.prototype = {
|
||||
|
||||
let mwi = message.mwi;
|
||||
if (mwi) {
|
||||
mwi.returnNumber = message.sender || null;
|
||||
mwi.returnMessage = message.fullBody || null;
|
||||
mwi.returnNumber = message.sender;
|
||||
mwi.returnMessage = message.fullBody;
|
||||
this._sendTargetMessage("voicemail", "RIL:VoicemailNotification", mwi);
|
||||
return true;
|
||||
}
|
||||
|
||||
let notifyReceived = function notifyReceived(rv, sms) {
|
||||
let notifyReceived = function notifyReceived(rv, record) {
|
||||
let sms = this.createSmsMessageFromRecord(record);
|
||||
let success = Components.isSuccessCode(rv);
|
||||
|
||||
// Acknowledge the reception of the SMS.
|
||||
@ -1532,38 +1550,30 @@ RadioInterfaceLayer.prototype = {
|
||||
}
|
||||
|
||||
gSystemMessenger.broadcastMessage("sms-received", {
|
||||
id: message.id,
|
||||
delivery: DOM_SMS_DELIVERY_RECEIVED,
|
||||
deliveryStatus: RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
||||
sender: message.sender || null,
|
||||
receiver: message.receiver || null,
|
||||
body: message.fullBody || null,
|
||||
messageClass: message.messageClass,
|
||||
timestamp: message.timestamp,
|
||||
read: false
|
||||
id: message.id,
|
||||
delivery: DOM_SMS_DELIVERY_RECEIVED,
|
||||
deliveryStatus: RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
||||
sender: message.sender,
|
||||
receiver: message.receiver,
|
||||
body: message.fullBody,
|
||||
messageClass: message.messageClass,
|
||||
timestamp: message.timestamp,
|
||||
read: false
|
||||
});
|
||||
|
||||
Services.obs.notifyObservers(sms, kSmsReceivedObserverTopic, null);
|
||||
}.bind(this);
|
||||
|
||||
if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
|
||||
message.id = gMobileMessageDatabaseService.saveReceivedMessage(
|
||||
message.sender || null,
|
||||
message.fullBody || null,
|
||||
message.messageClass,
|
||||
message.timestamp,
|
||||
notifyReceived);
|
||||
message.id = gMobileMessageDatabaseService.saveReceivedMessage(message,
|
||||
notifyReceived);
|
||||
} else {
|
||||
message.id = -1;
|
||||
let sms = gSmsService.createSmsMessage(message.id,
|
||||
DOM_SMS_DELIVERY_RECEIVED,
|
||||
RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
|
||||
message.sender || null,
|
||||
message.receiver || null,
|
||||
message.fullBody || null,
|
||||
message.messageClass,
|
||||
message.timestamp,
|
||||
false);
|
||||
notifyReceived(Cr.NS_OK, sms);
|
||||
message.delivery = DOM_SMS_DELIVERY_RECEIVED;
|
||||
message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
|
||||
message.read = false;
|
||||
|
||||
notifyReceived(Cr.NS_OK, message);
|
||||
}
|
||||
|
||||
// SMS ACK will be sent in notifyReceived. Return false here.
|
||||
@ -1596,7 +1606,8 @@ RadioInterfaceLayer.prototype = {
|
||||
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
||||
DOM_SMS_DELIVERY_SENT,
|
||||
options.sms.deliveryStatus,
|
||||
function notifyResult(rv, sms) {
|
||||
function notifyResult(rv, record) {
|
||||
let sms = this.createSmsMessageFromRecord(record);
|
||||
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
||||
gSystemMessenger.broadcastMessage("sms-sent",
|
||||
{id: options.sms.id,
|
||||
@ -1634,13 +1645,14 @@ RadioInterfaceLayer.prototype = {
|
||||
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
||||
options.sms.delivery,
|
||||
message.deliveryStatus,
|
||||
function notifyResult(rv, sms) {
|
||||
function notifyResult(rv, record) {
|
||||
let sms = this.createSmsMessageFromRecord(record);
|
||||
//TODO bug 832140 handle !Components.isSuccessCode(rv)
|
||||
let topic = (message.deliveryStatus == RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS)
|
||||
? kSmsDeliverySuccessObserverTopic
|
||||
: kSmsDeliveryErrorObserverTopic;
|
||||
Services.obs.notifyObservers(sms, topic, null);
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
handleSmsSendFailed: function handleSmsSendFailed(message) {
|
||||
@ -1662,11 +1674,12 @@ RadioInterfaceLayer.prototype = {
|
||||
gMobileMessageDatabaseService.setMessageDelivery(options.sms.id,
|
||||
DOM_SMS_DELIVERY_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)
|
||||
options.request.notifySendMessageFailed(error);
|
||||
Services.obs.notifyObservers(sms, kSmsFailedObserverTopic, null);
|
||||
});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2645,8 +2658,17 @@ RadioInterfaceLayer.prototype = {
|
||||
let deliveryStatus = options.requestStatusReport
|
||||
? RIL.GECKO_SMS_DELIVERY_STATUS_PENDING
|
||||
: RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE;
|
||||
let id = gMobileMessageDatabaseService.saveSendingMessage(number, message, deliveryStatus, timestamp,
|
||||
function notifyResult(rv, sms) {
|
||||
let sendingMessage = {
|
||||
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)
|
||||
Services.obs.notifyObservers(sms, kSmsSendingObserverTopic, null);
|
||||
|
||||
|
@ -49,6 +49,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=741267
|
||||
} catch (e) {
|
||||
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 {
|
||||
var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox);
|
||||
xhr.prototype = false;
|
||||
|
@ -85,7 +85,8 @@ function testElementFromPoint() {
|
||||
moveEl.style.left = moveX + "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());
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
function makeAllAppsLaunchable() {
|
||||
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 originalValue = appRegistry.allAppsLaunchable;
|
||||
|
@ -1489,6 +1489,14 @@ void AsyncPanZoomController::UpdateZoomConstraints(bool aAllowZoom,
|
||||
mMaxZoom = aMaxZoom;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::PostDelayedTask(Task* aTask, int aDelayMs) {
|
||||
if (!mGeckoContentController) {
|
||||
return;
|
||||
}
|
||||
|
||||
mGeckoContentController->PostDelayedTask(aTask, aDelayMs);
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::SendAsyncScrollEvent() {
|
||||
if (!mGeckoContentController) {
|
||||
return;
|
||||
|
@ -151,6 +151,12 @@ public:
|
||||
*/
|
||||
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.
|
||||
//
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "FrameMetrics.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
class Task;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
@ -52,6 +54,12 @@ public:
|
||||
virtual void SendAsyncScrollDOMEvent(const gfx::Rect &aContentRect,
|
||||
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() {}
|
||||
virtual ~GeckoContentController() {}
|
||||
};
|
||||
|
@ -88,8 +88,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
|
||||
mLongTapTimeoutTask =
|
||||
NewRunnableMethod(this, &GestureEventListener::TimeoutLongTap);
|
||||
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
mAsyncPanZoomController->PostDelayedTask(
|
||||
mLongTapTimeoutTask,
|
||||
Preferences::GetInt("ui.click_hold_context_menus.delay", 500));
|
||||
}
|
||||
@ -169,8 +168,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
|
||||
mDoubleTapTimeoutTask =
|
||||
NewRunnableMethod(this, &GestureEventListener::TimeoutDoubleTap);
|
||||
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
mAsyncPanZoomController->PostDelayedTask(
|
||||
mDoubleTapTimeoutTask,
|
||||
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/. */
|
||||
|
||||
#ifndef mozilla_layers_GestureEventListener_h
|
||||
|
@ -121,7 +121,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
||||
return;
|
||||
} else if (aData.mDrawTarget) {
|
||||
mDrawTarget = aData.mDrawTarget;
|
||||
mCanvasSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
||||
mCanvasSurface = gfxPlatform::GetPlatform()->CreateThebesSurfaceAliasForDrawTarget_hack(mDrawTarget);
|
||||
mNeedsYFlip = false;
|
||||
} else if (aData.mSurface) {
|
||||
mCanvasSurface = aData.mSurface;
|
||||
|
@ -302,6 +302,7 @@ VectorImage::VectorImage(imgStatusTracker* aStatusTracker,
|
||||
|
||||
VectorImage::~VectorImage()
|
||||
{
|
||||
CancelAllListeners();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -899,9 +900,6 @@ VectorImage::OnSVGDocumentParsed()
|
||||
void
|
||||
VectorImage::CancelAllListeners()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mParseCompleteListener, "Should have the parse complete listener");
|
||||
NS_ABORT_IF_FALSE(mLoadEventListener, "Should have the load event listener");
|
||||
|
||||
if (mParseCompleteListener) {
|
||||
mParseCompleteListener->Cancel();
|
||||
mParseCompleteListener = nullptr;
|
||||
|
@ -6,8 +6,8 @@
|
||||
<iframe src=discardframe.htm></iframe>
|
||||
</div>
|
||||
<script>
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = SpecialPowers.wrap(Components).classes;
|
||||
const Ci = SpecialPowers.Ci;
|
||||
const Cc = SpecialPowers.Cc;
|
||||
|
||||
function ImageDecoderObserverStub()
|
||||
{
|
||||
|
@ -480,7 +480,7 @@ ObjectWrapperChild::AnswerNewEnumerateNext(const JSVariant& in_state,
|
||||
|
||||
int32_t i = JSVAL_TO_INT(v);
|
||||
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()) {
|
||||
*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"
|
||||
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
|
||||
CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
|
||||
CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
|
||||
|
@ -1684,7 +1684,8 @@ ia64*-hpux*)
|
||||
CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
||||
CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
||||
# 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
|
||||
CFLAGS="$CFLAGS -we4553"
|
||||
CXXFLAGS="$CXXFLAGS -we4553"
|
||||
|
@ -1472,8 +1472,7 @@ ion::CanEnterAtBranch(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
||||
}
|
||||
|
||||
MethodStatus
|
||||
ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
||||
bool isConstructing, bool newType)
|
||||
ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp, bool isConstructing)
|
||||
{
|
||||
JS_ASSERT(ion::IsEnabled(cx));
|
||||
|
||||
@ -1495,8 +1494,8 @@ ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
||||
if (isConstructing && fp.thisValue().isPrimitive()) {
|
||||
RootedScript scriptRoot(cx, script);
|
||||
RootedObject callee(cx, &fp.callee());
|
||||
RootedObject obj(cx, CreateThisForFunction(cx, callee, newType));
|
||||
if (!obj)
|
||||
RootedObject obj(cx, CreateThisForFunction(cx, callee, fp.useNewType()));
|
||||
if (!obj || !ion::IsEnabled(cx)) // Note: OOM under CreateThis can disable TI.
|
||||
return Method_Skipped;
|
||||
fp.thisValue().setObject(*obj);
|
||||
script = scriptRoot;
|
||||
|
@ -261,8 +261,7 @@ bool SetIonContext(IonContext *ctx);
|
||||
|
||||
MethodStatus CanEnterAtBranch(JSContext *cx, JSScript *script,
|
||||
AbstractFramePtr fp, jsbytecode *pc, bool isConstructing);
|
||||
MethodStatus CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp,
|
||||
bool isConstructing, bool newType);
|
||||
MethodStatus CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp, bool isConstructing);
|
||||
MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs);
|
||||
|
||||
enum IonExecStatus
|
||||
|
@ -4488,15 +4488,14 @@ IonBuilder::jsop_eval(uint32_t argc)
|
||||
return abort("Direct eval in global code");
|
||||
|
||||
types::StackTypeSet *thisTypes = oracle->thisTypeSet(script());
|
||||
if (!thisTypes) {
|
||||
// The 'this' value for the outer and eval scripts must be the
|
||||
// same. This is not guaranteed if a primitive string/number/etc.
|
||||
// is passed through to the eval invoke as the primitive may be
|
||||
// boxed into different objects if accessed via 'this'.
|
||||
JSValueType type = thisTypes->getKnownTypeTag();
|
||||
if (type != JSVAL_TYPE_OBJECT && type != JSVAL_TYPE_NULL && type != JSVAL_TYPE_UNDEFINED)
|
||||
return abort("Direct eval from script with maybe-primitive 'this'");
|
||||
}
|
||||
|
||||
// The 'this' value for the outer and eval scripts must be the
|
||||
// same. This is not guaranteed if a primitive string/number/etc.
|
||||
// is passed through to the eval invoke as the primitive may be
|
||||
// boxed into different objects if accessed via 'this'.
|
||||
JSValueType type = thisTypes->getKnownTypeTag();
|
||||
if (type != JSVAL_TYPE_OBJECT && type != JSVAL_TYPE_NULL && type != JSVAL_TYPE_UNDEFINED)
|
||||
return abort("Direct eval from script with maybe-primitive 'this'");
|
||||
|
||||
CallInfo callInfo(cx, /* constructing = */ false);
|
||||
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_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_UNUSED29, 29, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_UNUSED30, 30, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_OBJECT_ACCESS_DENIED, 29, 0, JSEXN_ERR, "Permission denied to access object")
|
||||
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_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")
|
||||
|
@ -881,6 +881,9 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||
ionReturnOverride_(MagicValue(JS_ARG_POISON)),
|
||||
useHelperThreads_(useHelperThreads),
|
||||
requestedHelperThreadCount(-1),
|
||||
#ifdef DEBUG
|
||||
enteredPolicy(NULL),
|
||||
#endif
|
||||
rngNonce(0)
|
||||
{
|
||||
/* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
|
||||
|
@ -569,7 +569,7 @@ struct MallocProvider
|
||||
namespace gc {
|
||||
class MarkingValidator;
|
||||
} // namespace gc
|
||||
|
||||
class AutoEnterPolicy;
|
||||
} // namespace js
|
||||
|
||||
struct JSRuntime : js::RuntimeFriendFields,
|
||||
@ -1301,7 +1301,11 @@ struct JSRuntime : js::RuntimeFriendFields,
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
public:
|
||||
js::AutoEnterPolicy *enteredPolicy;
|
||||
|
||||
#endif
|
||||
private:
|
||||
/*
|
||||
* 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
|
||||
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))
|
||||
return true;
|
||||
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 */
|
||||
|
||||
#endif /* jsfriendapi_h___ */
|
||||
|
@ -276,6 +276,22 @@ js::RunScript(JSContext *cx, StackFrame *fp)
|
||||
|
||||
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
|
||||
struct CheckStackBalance {
|
||||
JSContext *cx;
|
||||
@ -294,7 +310,7 @@ js::RunScript(JSContext *cx, StackFrame *fp)
|
||||
#ifdef JS_ION
|
||||
if (ion::IsEnabled(cx)) {
|
||||
ion::MethodStatus status = ion::CanEnter(cx, script, AbstractFramePtr(fp),
|
||||
fp->isConstructing(), false);
|
||||
fp->isConstructing());
|
||||
if (status == ion::Method_Error)
|
||||
return false;
|
||||
if (status == ion::Method_Compiled) {
|
||||
@ -1159,7 +1175,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
||||
if (interpMode == JSINTERP_NORMAL) {
|
||||
StackFrame *fp = regs.fp();
|
||||
if (!fp->isGeneratorFrame()) {
|
||||
if (!fp->prologue(cx, UseNewTypeAtEntry(cx, fp)))
|
||||
if (!fp->prologue(cx))
|
||||
goto error;
|
||||
} else {
|
||||
Probes::enterScript(cx, script, script->function(), fp);
|
||||
@ -2361,6 +2377,9 @@ BEGIN_CASE(JSOP_FUNCALL)
|
||||
funScript = fun->nonLazyScript();
|
||||
if (!cx->stack.pushInlineFrame(cx, regs, args, fun, funScript, initial))
|
||||
goto error;
|
||||
|
||||
if (newType)
|
||||
regs.fp()->setUseNewType();
|
||||
|
||||
SET_SCRIPT(regs.fp()->script());
|
||||
#ifdef JS_METHODJIT
|
||||
@ -2370,7 +2389,7 @@ BEGIN_CASE(JSOP_FUNCALL)
|
||||
#ifdef JS_ION
|
||||
if (!newType && ion::IsEnabled(cx)) {
|
||||
ion::MethodStatus status = ion::CanEnter(cx, script, AbstractFramePtr(regs.fp()),
|
||||
regs.fp()->isConstructing(), newType);
|
||||
regs.fp()->isConstructing());
|
||||
if (status == ion::Method_Error)
|
||||
goto error;
|
||||
if (status == ion::Method_Compiled) {
|
||||
@ -2405,7 +2424,7 @@ BEGIN_CASE(JSOP_FUNCALL)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!regs.fp()->prologue(cx, newType))
|
||||
if (!regs.fp()->prologue(cx))
|
||||
goto error;
|
||||
if (cx->compartment->debugMode()) {
|
||||
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
|
||||
* 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
|
||||
* 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;
|
||||
if (!BoxNonStrictThis(cx, &thisv, &modified))
|
||||
|
@ -1226,9 +1226,6 @@ ExpressionDecompiler::decompilePC(jsbytecode *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]) {
|
||||
// Handle simple cases of binary and unary operators.
|
||||
switch (js_CodeSpec[op].nuses) {
|
||||
@ -2257,6 +2254,9 @@ GetPCCountJSON(JSContext *cx, const ScriptAndCounts &sac, StringBuffer &buf)
|
||||
|
||||
buf.append(str);
|
||||
|
||||
AppendJSONProperty(buf, "line");
|
||||
NumberValueToStringBuffer(cx, Int32Value(script->lineno), buf);
|
||||
|
||||
AppendJSONProperty(buf, "opcodes");
|
||||
buf.append('[');
|
||||
bool comma = false;
|
||||
|
@ -49,9 +49,56 @@ GetFunctionProxyConstruct(UnrootedObject proxy)
|
||||
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)
|
||||
: 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
|
||||
BaseProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy_, id_);
|
||||
RootedObject proxy(cx, proxy_);
|
||||
RootedId id(cx, id_);
|
||||
AutoPropertyDescriptorRooter desc(cx);
|
||||
@ -74,6 +130,7 @@ BaseProxyHandler::has(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
||||
bool
|
||||
BaseProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy_, id_);
|
||||
RootedObject proxy(cx, proxy_);
|
||||
RootedId id(cx, id_);
|
||||
AutoPropertyDescriptorRooter desc(cx);
|
||||
@ -86,6 +143,7 @@ BaseProxyHandler::hasOwn(JSContext *cx, JSObject *proxy_, jsid id_, bool *bp)
|
||||
bool
|
||||
BaseProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver_, jsid id_, Value *vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id_);
|
||||
RootedObject receiver(cx, receiver_);
|
||||
RootedId id(cx, id_);
|
||||
|
||||
@ -127,6 +185,7 @@ BaseProxyHandler::getElementIfPresent(JSContext *cx, JSObject *proxy_, JSObject
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
|
||||
if (!has(cx, proxy, id, present))
|
||||
return false;
|
||||
@ -143,6 +202,7 @@ bool
|
||||
BaseProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid id_, bool strict,
|
||||
Value *vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy_, id_);
|
||||
RootedObject proxy(cx, proxy_), receiver(cx, receiver_);
|
||||
RootedId id(cx, id_);
|
||||
|
||||
@ -219,6 +279,7 @@ BaseProxyHandler::set(JSContext *cx, JSObject *proxy_, JSObject *receiver_, jsid
|
||||
bool
|
||||
BaseProxyHandler::keys(JSContext *cx, JSObject *proxyArg, AutoIdVector &props)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxyArg, JSID_VOID);
|
||||
JS_ASSERT(props.length() == 0);
|
||||
|
||||
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++) {
|
||||
JS_ASSERT(i <= j);
|
||||
jsid id = props[j];
|
||||
AutoWaivePolicy policy(cx, proxy, id);
|
||||
if (!getOwnPropertyDescriptor(cx, proxy, id, &desc, 0))
|
||||
return false;
|
||||
if (desc.obj && (desc.attrs & JSPROP_ENUMERATE))
|
||||
@ -247,6 +309,7 @@ BaseProxyHandler::keys(JSContext *cx, JSObject *proxyArg, AutoIdVector &props)
|
||||
bool
|
||||
BaseProxyHandler::iterate(JSContext *cx, JSObject *proxy_, unsigned flags, Value *vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy_, JSID_VOID);
|
||||
RootedObject proxy(cx, proxy_);
|
||||
|
||||
AutoIdVector props(cx);
|
||||
@ -268,6 +331,7 @@ bool
|
||||
BaseProxyHandler::call(JSContext *cx, JSObject *proxy, unsigned argc,
|
||||
Value *vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
AutoValueRooter rval(cx);
|
||||
RootedValue call(cx, GetCall(proxy));
|
||||
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,
|
||||
Value *argv, Value *rval)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy_, JSID_VOID);
|
||||
RootedObject proxy(cx, proxy_);
|
||||
RootedValue fval(cx, GetConstruct(proxy_));
|
||||
if (fval.isUndefined())
|
||||
@ -298,6 +363,7 @@ BaseProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
|
||||
JSString *
|
||||
BaseProxyHandler::fun_toString(JSContext *cx, JSObject *proxy, unsigned indent)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
Value fval = GetCall(proxy);
|
||||
if (IsFunctionProxy(proxy) &&
|
||||
(fval.isPrimitive() || !fval.toObject().isFunction())) {
|
||||
@ -343,6 +409,7 @@ BaseProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl im
|
||||
bool
|
||||
BaseProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue val(cx, ObjectValue(*proxy.get()));
|
||||
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
|
||||
JSDVG_SEARCH_STACK, val, NullPtr());
|
||||
@ -379,6 +446,8 @@ bool
|
||||
DirectProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
||||
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));
|
||||
return JS_GetPropertyDescriptorById(cx, target, id, 0, desc);
|
||||
}
|
||||
@ -403,6 +472,7 @@ bool
|
||||
DirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
||||
jsid id, PropertyDescriptor *desc, unsigned flags)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
return GetOwnPropertyDescriptor(cx, target, id, 0, desc);
|
||||
}
|
||||
@ -411,6 +481,7 @@ bool
|
||||
DirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
|
||||
PropertyDescriptor *desc)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id_);
|
||||
RootedObject obj(cx, GetProxyTargetObject(proxy));
|
||||
Rooted<jsid> id(cx, id_);
|
||||
Rooted<Value> v(cx, desc->value);
|
||||
@ -422,6 +493,7 @@ bool
|
||||
DirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
|
||||
AutoIdVector &props)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
return GetPropertyNames(cx, target, JSITER_OWNONLY | JSITER_HIDDEN, &props);
|
||||
}
|
||||
@ -430,6 +502,7 @@ bool
|
||||
DirectProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||
{
|
||||
RootedValue v(cx);
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
if (!JS_DeletePropertyById2(cx, target, id, v.address()))
|
||||
return false;
|
||||
@ -444,6 +517,8 @@ bool
|
||||
DirectProxyHandler::enumerate(JSContext *cx, JSObject *proxy,
|
||||
AutoIdVector &props)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
return GetPropertyNames(cx, target, 0, &props);
|
||||
}
|
||||
@ -465,6 +540,7 @@ bool
|
||||
DirectProxyHandler::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool *bp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
JSBool b;
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
if (!JS_HasInstance(cx, target, v, &b))
|
||||
@ -485,6 +561,7 @@ DirectProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue,
|
||||
JSString *
|
||||
DirectProxyHandler::obj_toString(JSContext *cx, JSObject *proxy)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
return obj_toStringHelper(cx, GetProxyTargetObject(proxy));
|
||||
}
|
||||
|
||||
@ -492,6 +569,7 @@ JSString *
|
||||
DirectProxyHandler::fun_toString(JSContext *cx, JSObject *proxy,
|
||||
unsigned indent)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
return fun_toStringHelper(cx, target, indent);
|
||||
}
|
||||
@ -527,6 +605,8 @@ DirectProxyHandler::DirectProxyHandler(void *family)
|
||||
bool
|
||||
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;
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
if (!JS_HasPropertyById(cx, target, id, &found))
|
||||
@ -538,6 +618,7 @@ DirectProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||
bool
|
||||
DirectProxyHandler::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id);
|
||||
RootedObject target(cx, GetProxyTargetObject(proxy));
|
||||
AutoPropertyDescriptorRooter desc(cx);
|
||||
if (!JS_GetPropertyDescriptorById(cx, target, id, 0, &desc))
|
||||
@ -550,6 +631,7 @@ bool
|
||||
DirectProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver_,
|
||||
jsid id_, Value *vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id_);
|
||||
RootedObject receiver(cx, receiver_);
|
||||
RootedId id(cx, id_);
|
||||
RootedValue value(cx);
|
||||
@ -565,6 +647,7 @@ bool
|
||||
DirectProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiverArg,
|
||||
jsid id_, bool strict, Value *vp)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id_);
|
||||
RootedId id(cx, id_);
|
||||
Rooted<JSObject*> receiver(cx, receiverArg);
|
||||
RootedValue value(cx, *vp);
|
||||
@ -579,6 +662,7 @@ DirectProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiverArg,
|
||||
bool
|
||||
DirectProxyHandler::keys(JSContext *cx, JSObject *proxy, AutoIdVector &props)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
return GetPropertyNames(cx, GetProxyTargetObject(proxy), JSITER_OWNONLY, &props);
|
||||
}
|
||||
|
||||
@ -586,6 +670,8 @@ bool
|
||||
DirectProxyHandler::iterate(JSContext *cx, JSObject *proxy, unsigned flags,
|
||||
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));
|
||||
RootedValue value(cx);
|
||||
if (!GetIterator(cx, target, flags, &value))
|
||||
@ -2177,7 +2263,6 @@ ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
|
||||
return protoCall; \
|
||||
JS_END_MACRO \
|
||||
|
||||
|
||||
bool
|
||||
Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, PropertyDescriptor *desc,
|
||||
unsigned flags)
|
||||
@ -2186,6 +2271,10 @@ Proxy::getPropertyDescriptor(JSContext *cx, JSObject *proxy_, jsid id_, Property
|
||||
RootedObject proxy(cx, proxy_);
|
||||
RootedId id(cx, id_);
|
||||
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())
|
||||
return handler->getPropertyDescriptor(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);
|
||||
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
|
||||
@ -2242,7 +2336,11 @@ bool
|
||||
Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id, PropertyDescriptor *desc)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(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);
|
||||
}
|
||||
|
||||
@ -2261,7 +2359,11 @@ bool
|
||||
Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(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);
|
||||
}
|
||||
|
||||
@ -2269,7 +2371,12 @@ bool
|
||||
Proxy::delete_(JSContext *cx, JSObject *proxy_, jsid id, bool *bp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(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);
|
||||
}
|
||||
|
||||
@ -2299,6 +2406,9 @@ Proxy::enumerate(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
RootedObject proxy(cx, proxy_);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
AutoEnterPolicy policy(cx, handler, proxy, JSID_VOID, BaseProxyHandler::GET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
if (!handler->hasPrototype())
|
||||
return GetProxyHandler(proxy)->enumerate(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_);
|
||||
RootedId id(cx, id_);
|
||||
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())
|
||||
return handler->has(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);
|
||||
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
|
||||
@ -2342,6 +2461,10 @@ Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
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;
|
||||
if (!handler->hasPrototype()) {
|
||||
own = true;
|
||||
@ -2360,17 +2483,20 @@ Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject recei
|
||||
{
|
||||
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);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
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;
|
||||
if (!handler->hasOwn(cx, proxy, id, &hasOwn))
|
||||
return false;
|
||||
@ -2390,6 +2516,9 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
if (handler->hasPrototype()) {
|
||||
// If we're using a prototype, we still want to use the proxy trap unless
|
||||
// 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);
|
||||
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
|
||||
@ -2425,8 +2558,19 @@ Proxy::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleV
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
BaseProxyHandler *handler = GetProxyHandler(proxy);
|
||||
if (!handler->hasPrototype())
|
||||
return GetProxyHandler(proxy)->iterate(cx, proxy, flags, vp.address());
|
||||
vp.setUndefined(); // default result if we refuse to perform this action
|
||||
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);
|
||||
// The other Proxy::foo methods do the prototype-aware work for us here.
|
||||
if ((flags & JSITER_OWNONLY)
|
||||
@ -2442,7 +2586,19 @@ Proxy::call(JSContext *cx, JSObject *proxy_, unsigned argc, Value *vp)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
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
|
||||
@ -2450,7 +2606,19 @@ Proxy::construct(JSContext *cx, JSObject *proxy_, unsigned argc, Value *argv, Va
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
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
|
||||
@ -2458,6 +2626,9 @@ Proxy::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArg
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2465,6 +2636,11 @@ bool
|
||||
Proxy::hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2480,7 +2656,14 @@ Proxy::obj_toString(JSContext *cx, JSObject *proxy_)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return NULL);
|
||||
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 *
|
||||
@ -2488,7 +2671,17 @@ Proxy::fun_toString(JSContext *cx, JSObject *proxy_, unsigned indent)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return NULL);
|
||||
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
|
||||
|
@ -51,9 +51,11 @@ class JS_FRIEND_API(Wrapper);
|
||||
class JS_FRIEND_API(BaseProxyHandler) {
|
||||
void *mFamily;
|
||||
bool mHasPrototype;
|
||||
bool mHasPolicy;
|
||||
protected:
|
||||
// Subclasses may set this in their constructor.
|
||||
void setHasPrototype(bool aHasPrototype) { mHasPrototype = aHasPrototype; }
|
||||
void setHasPolicy(bool aHasPolicy) { mHasPolicy = aHasPolicy; }
|
||||
|
||||
public:
|
||||
explicit BaseProxyHandler(void *family);
|
||||
@ -63,6 +65,10 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
||||
return mHasPrototype;
|
||||
}
|
||||
|
||||
bool hasPolicy() {
|
||||
return mHasPolicy;
|
||||
}
|
||||
|
||||
inline void *family() {
|
||||
return mFamily;
|
||||
}
|
||||
@ -71,6 +77,24 @@ class JS_FRIEND_API(BaseProxyHandler) {
|
||||
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. */
|
||||
virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
|
||||
PropertyDescriptor *desc, unsigned flags) = 0;
|
||||
@ -319,6 +343,72 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv,
|
||||
JSObject *
|
||||
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 */
|
||||
|
||||
extern JS_FRIEND_API(JSObject *)
|
||||
|
@ -70,13 +70,6 @@ Wrapper::wrappedObject(RawObject 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::UnwrapObject(JSObject *wrapped, bool stopAtOuter, unsigned *flagsp)
|
||||
{
|
||||
@ -122,17 +115,6 @@ js::IsCrossCompartmentWrapper(RawObject wrapper)
|
||||
!!(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)
|
||||
, mFlags(flags)
|
||||
, 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
|
||||
* 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);
|
||||
}
|
||||
|
||||
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::singletonWithPrototype((unsigned)0, true);
|
||||
|
||||
@ -838,6 +644,7 @@ SecurityWrapper<Base>::SecurityWrapper(unsigned flags)
|
||||
: Base(flags)
|
||||
{
|
||||
Base::setSafeToUnwrap(false);
|
||||
BaseProxyHandler::setHasPolicy(true);
|
||||
}
|
||||
|
||||
template <class Base>
|
||||
|
@ -32,11 +32,7 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
||||
bool mSafeToUnwrap;
|
||||
|
||||
public:
|
||||
enum Action {
|
||||
GET,
|
||||
SET,
|
||||
CALL
|
||||
};
|
||||
using BaseProxyHandler::Action;
|
||||
|
||||
enum Flags {
|
||||
CROSS_COMPARTMENT = 1 << 0,
|
||||
@ -65,54 +61,11 @@ class JS_FRIEND_API(Wrapper) : public DirectProxyHandler
|
||||
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);
|
||||
|
||||
virtual ~Wrapper();
|
||||
|
||||
/* 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,
|
||||
Value *vp) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -940,7 +940,9 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
|
||||
return js_InternalThrow(f);
|
||||
fp->initVarsToUndefined();
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -778,7 +778,7 @@ stubs::TriggerIonCompile(VMFrame &f)
|
||||
AssertCanGC();
|
||||
RootedScript script(f.cx, f.script());
|
||||
|
||||
if (ion::js_IonOptions.parallelCompilation) {
|
||||
if (ion::js_IonOptions.parallelCompilation && !f.cx->runtime->profilingScripts) {
|
||||
if (script->hasIonScript()) {
|
||||
/*
|
||||
* 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,
|
||||
f.fp()->isConstructing());
|
||||
} else {
|
||||
compileStatus = ion::CanEnter(f.cx, script, f.cx->fp(), f.fp()->isConstructing(),
|
||||
/* newType = */ false);
|
||||
compileStatus = ion::CanEnter(f.cx, script, f.cx->fp(), f.fp()->isConstructing());
|
||||
}
|
||||
|
||||
if (compileStatus != ion::Method_Compiled) {
|
||||
|
@ -3185,6 +3185,59 @@ DebuggerScript_getAllOffsets(JSContext *cx, unsigned argc, Value *vp)
|
||||
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
|
||||
DebuggerScript_getLineOffsets(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -3356,6 +3409,7 @@ static JSPropertySpec DebuggerScript_properties[] = {
|
||||
static JSFunctionSpec DebuggerScript_methods[] = {
|
||||
JS_FN("getChildScripts", DebuggerScript_getChildScripts, 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("getOffsetLine", DebuggerScript_getOffsetLine, 0, 0),
|
||||
JS_FN("setBreakpoint", DebuggerScript_setBreakpoint, 2, 0),
|
||||
|
@ -738,6 +738,13 @@ AbstractFramePtr::hasCallObj() const
|
||||
return false;
|
||||
}
|
||||
inline bool
|
||||
AbstractFramePtr::useNewType() const
|
||||
{
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->useNewType();
|
||||
return false;
|
||||
}
|
||||
inline bool
|
||||
AbstractFramePtr::isGeneratorFrame() const
|
||||
{
|
||||
if (isStackFrame())
|
||||
|
@ -307,7 +307,7 @@ StackFrame::initFunctionScopeObjects(JSContext *cx)
|
||||
}
|
||||
|
||||
bool
|
||||
StackFrame::prologue(JSContext *cx, bool newType)
|
||||
StackFrame::prologue(JSContext *cx)
|
||||
{
|
||||
RootedScript script(cx, this->script());
|
||||
|
||||
@ -339,7 +339,7 @@ StackFrame::prologue(JSContext *cx, bool newType)
|
||||
|
||||
if (isConstructing()) {
|
||||
RootedObject callee(cx, &this->callee());
|
||||
JSObject *obj = CreateThisForFunction(cx, callee, newType);
|
||||
JSObject *obj = CreateThisForFunction(cx, callee, useNewType());
|
||||
if (!obj)
|
||||
return false;
|
||||
functionThis() = ObjectValue(*obj);
|
||||
|
@ -297,6 +297,7 @@ class AbstractFramePtr
|
||||
inline bool hasArgsObj() const;
|
||||
inline ArgumentsObject &argsObj() const;
|
||||
inline void initArgsObj(ArgumentsObject &argsobj) const;
|
||||
inline bool useNewType() const;
|
||||
|
||||
inline bool copyRawFrameSlots(AutoValueVector *vec) const;
|
||||
|
||||
@ -389,10 +390,13 @@ class StackFrame
|
||||
HAS_PUSHED_SPS_FRAME = 0x100000, /* SPS was notified of enty */
|
||||
|
||||
/* Ion frame state */
|
||||
RUNNING_IN_ION = 0x200000, /* frame is running in Ion */
|
||||
CALLING_INTO_ION = 0x400000, /* frame is calling into Ion */
|
||||
RUNNING_IN_ION = 0x200000, /* frame is running in 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:
|
||||
@ -489,12 +493,9 @@ class StackFrame
|
||||
* over-recursed) after pushing the stack frame but before 'prologue' is
|
||||
* called or completes fully. To simplify usage, 'epilogue' does not assume
|
||||
* '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);
|
||||
|
||||
/* Subsets of 'prologue' called from jit code. */
|
||||
@ -1052,6 +1053,15 @@ class StackFrame
|
||||
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}
|
||||
* 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,
|
||||
"Object prototype remapped properly");
|
||||
|
||||
// Check |constructor|. The semantics of this weird for the case of an
|
||||
// object with a custom chrome-implemented prototype, because we'll end up
|
||||
// bouncing up the prototype chain to Object, even though that's not fully
|
||||
// accurate. It's unlikely to be a problem though, so we just verify that
|
||||
// it does what we expect.
|
||||
ok(chromeObject.constructor === Object, "Object constructor does what we expect");
|
||||
// Check |constructor|.
|
||||
// Note that the 'constructor' property of the underlying chrome object
|
||||
// will be resolved on SomeConstructor.prototype, which has an empty
|
||||
// __exposedProps__. This means that we shouldn't remap the property, even
|
||||
// though we'd also be able to find it on Object.prototype. Some recent
|
||||
// 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");
|
||||
|
||||
// We should be able to .forEach on the Array.
|
||||
|
@ -43,7 +43,6 @@ MOCHITEST_FILES = chrome_wrappers_helper.html \
|
||||
bug504877_helper.html \
|
||||
test_bug505915.html \
|
||||
file_bug505915.html \
|
||||
test_bug553407.html \
|
||||
test_bug560351.html \
|
||||
bug571849_helper.html \
|
||||
test_bug585745.html \
|
||||
|
@ -17,7 +17,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478438
|
||||
return;
|
||||
test.calledAlready = true;
|
||||
|
||||
var iwin = (new XPCNativeWrapper(document)).getElementById("f").contentWindow;
|
||||
var iwin = document.getElementById("f").contentWindow;
|
||||
|
||||
function testOne(fn, onAllow, 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";
|
||||
sel.options.add(option);
|
||||
try {
|
||||
Components.lookupMethod(sel.options, "add")(option);
|
||||
SpecialPowers.Components.lookupMethod(sel.options, "add")(option);
|
||||
ok(true, "function call should not throw")
|
||||
} catch(e) {
|
||||
do_throw("this call should just work without any exceptions");
|
||||
ok(false, "this call should just work without any exceptions");
|
||||
}
|
||||
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_true(Cu.evalInSandbox('obj.hasOwnProperty === Object.prototype.hasOwnProperty', sb),
|
||||
"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;
|
||||
}
|
||||
|
||||
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 };
|
||||
|
||||
static bool
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user