mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 12:13:22 +00:00
Merge m-c to b-s.
This commit is contained in:
commit
8d342e5aca
@ -280,6 +280,9 @@ LogShellLoadType(nsIDocShell* aDocShell)
|
||||
case LOAD_PUSHSTATE:
|
||||
printf("load pushstate; ");
|
||||
break;
|
||||
case LOAD_REPLACE_BYPASS_CACHE:
|
||||
printf("replace bypass cache; ");
|
||||
break;
|
||||
case LOAD_ERROR_PAGE:
|
||||
printf("error page;");
|
||||
break;
|
||||
|
@ -22,7 +22,7 @@ DirectoryProvider.prototype = {
|
||||
|
||||
getFile: function dp_getFile(prop, persistent) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let localProps = ["cachePDir", "webappsDir", "PrefD"];
|
||||
let localProps = ["cachePDir", "webappsDir", "PrefD", "indexedDBPDir"];
|
||||
if (localProps.indexOf(prop) != -1) {
|
||||
prop.persistent = true;
|
||||
let file = Cc["@mozilla.org/file/local;1"]
|
||||
@ -37,4 +37,3 @@ DirectoryProvider.prototype = {
|
||||
};
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]);
|
||||
|
||||
|
@ -584,7 +584,7 @@ stack[anonid=browserStack][responsivemode] {
|
||||
}
|
||||
|
||||
stack[anonid=browserStack][responsivemode] {
|
||||
-moz-transition-properties: min-width, max-width, min-height, max-height;
|
||||
-moz-transition-property: min-width, max-width, min-height, max-height;
|
||||
}
|
||||
|
||||
stack[anonid=browserStack][responsivemode][notransition] {
|
||||
|
@ -1400,7 +1400,7 @@ var gBrowserInit = {
|
||||
|
||||
// Show the toolbar if it was previously visible
|
||||
if (gPrefService.getBoolPref("devtools.toolbar.visible")) {
|
||||
this.DeveloperToolbar.show();
|
||||
DeveloperToolbar.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3051,13 +3051,13 @@
|
||||
if (doPosition) {
|
||||
this.setAttribute("positionpinnedtabs", "true");
|
||||
|
||||
let scrollButtonWidth = this.mTabstrip._scrollButtonDown.scrollWidth;
|
||||
let scrollButtonWidth = this.mTabstrip._scrollButtonDown.getBoundingClientRect().width;
|
||||
let paddingStart = this.mTabstrip.scrollboxPaddingStart;
|
||||
let width = 0;
|
||||
|
||||
for (let i = numPinned - 1; i >= 0; i--) {
|
||||
let tab = this.childNodes[i];
|
||||
width += tab.scrollWidth;
|
||||
width += tab.getBoundingClientRect().width;
|
||||
tab.style.MozMarginStart = - (width + scrollButtonWidth + paddingStart) + "px";
|
||||
}
|
||||
|
||||
|
@ -977,6 +977,9 @@ PropertiesView.prototype = {
|
||||
let valueLabel = document.createElement("label");
|
||||
let title = element.getElementsByClassName("title")[0];
|
||||
|
||||
// Use attribute flags to specify the element type and tooltip text.
|
||||
this._setAttributes(element, aName, aFlags);
|
||||
|
||||
// Separator between the variable name and its value.
|
||||
separatorLabel.className = "plain";
|
||||
separatorLabel.setAttribute("value", ":");
|
||||
@ -984,21 +987,6 @@ PropertiesView.prototype = {
|
||||
// The variable information (type, class and/or value).
|
||||
valueLabel.className = "value plain";
|
||||
|
||||
if (aFlags) {
|
||||
// Use attribute flags to specify the element type and tooltip text.
|
||||
let tooltip = [];
|
||||
|
||||
!aFlags.configurable ? element.setAttribute("non-configurable", "")
|
||||
: tooltip.push("configurable");
|
||||
!aFlags.enumerable ? element.setAttribute("non-enumerable", "")
|
||||
: tooltip.push("enumerable");
|
||||
!aFlags.writable ? element.setAttribute("non-writable", "")
|
||||
: tooltip.push("writable");
|
||||
|
||||
element.setAttribute("tooltiptext", tooltip.join(", "));
|
||||
}
|
||||
if (aName === "this") { element.setAttribute("self", ""); }
|
||||
|
||||
// Handle the click event when pressing the element value label.
|
||||
valueLabel.addEventListener("click", this._activateElementInputMode.bind({
|
||||
scope: this,
|
||||
@ -1029,6 +1017,36 @@ PropertiesView.prototype = {
|
||||
return element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a variable's configurable, enumerable or writable attributes.
|
||||
*
|
||||
* @param object aVar
|
||||
* The object to set the attributes on.
|
||||
* @param object aName
|
||||
* The varialbe name.
|
||||
* @param object aFlags
|
||||
* Contains configurable, enumerable or writable flags.
|
||||
*/
|
||||
_setAttributes: function DVP_setAttributes(aVar, aName, aFlags) {
|
||||
if (aFlags) {
|
||||
if (!aFlags.configurable) {
|
||||
aVar.setAttribute("non-configurable", "");
|
||||
}
|
||||
if (!aFlags.enumerable) {
|
||||
aVar.setAttribute("non-enumerable", "");
|
||||
}
|
||||
if (!aFlags.writable) {
|
||||
aVar.setAttribute("non-writable", "");
|
||||
}
|
||||
}
|
||||
if (aName === "this") {
|
||||
aVar.setAttribute("self", "");
|
||||
}
|
||||
if (aName === "__proto__ ") {
|
||||
aVar.setAttribute("proto", "");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the specific grip for a variable.
|
||||
* The grip should contain the value or the type & class, as defined in the
|
||||
@ -1209,6 +1227,9 @@ PropertiesView.prototype = {
|
||||
let separatorLabel = document.createElement("label");
|
||||
let valueLabel = document.createElement("label");
|
||||
|
||||
// Use attribute flags to specify the element type and tooltip text.
|
||||
this._setAttributes(element, pKey, aFlags);
|
||||
|
||||
if ("undefined" !== typeof pKey) {
|
||||
// Use a key element to specify the property name.
|
||||
nameLabel.className = "key plain";
|
||||
@ -1228,21 +1249,6 @@ PropertiesView.prototype = {
|
||||
title.appendChild(valueLabel);
|
||||
}
|
||||
|
||||
if (aFlags) {
|
||||
// Use attribute flags to specify the element type and tooltip text.
|
||||
let tooltip = [];
|
||||
|
||||
!aFlags.configurable ? element.setAttribute("non-configurable", "")
|
||||
: tooltip.push("configurable");
|
||||
!aFlags.enumerable ? element.setAttribute("non-enumerable", "")
|
||||
: tooltip.push("enumerable");
|
||||
!aFlags.writable ? element.setAttribute("non-writable", "")
|
||||
: tooltip.push("writable");
|
||||
|
||||
element.setAttribute("tooltiptext", tooltip.join(", "));
|
||||
}
|
||||
if (pKey === "__proto__ ") { element.setAttribute("proto", ""); }
|
||||
|
||||
// Handle the click event when pressing the element value label.
|
||||
valueLabel.addEventListener("click", this._activateElementInputMode.bind({
|
||||
scope: this,
|
||||
@ -1498,6 +1504,7 @@ PropertiesView.prototype = {
|
||||
} else {
|
||||
arrow.addEventListener("click", function() { element.toggle(); }, false);
|
||||
name.addEventListener("click", function() { element.toggle(); }, false);
|
||||
name.addEventListener("mouseover", function() { element.updateTooltip(name); }, false);
|
||||
}
|
||||
|
||||
title.appendChild(arrow);
|
||||
@ -1728,6 +1735,52 @@ PropertiesView.prototype = {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a tooltip for the element displaying certain attributes.
|
||||
*
|
||||
* @param object aAnchor
|
||||
* The element which will anchor the tooltip.
|
||||
*/
|
||||
element.updateTooltip = function DVP_element_updateTooltip(aAnchor) {
|
||||
let tooltip = document.getElementById("element-tooltip");
|
||||
if (tooltip) {
|
||||
document.documentElement.removeChild(tooltip);
|
||||
}
|
||||
|
||||
tooltip = document.createElement("tooltip");
|
||||
tooltip.id = "element-tooltip";
|
||||
|
||||
let configurableLabel = document.createElement("label");
|
||||
configurableLabel.id = "configurableLabel";
|
||||
configurableLabel.setAttribute("value", "configurable");
|
||||
|
||||
let enumerableLabel = document.createElement("label");
|
||||
enumerableLabel.id = "enumerableLabel";
|
||||
enumerableLabel.setAttribute("value", "enumerable");
|
||||
|
||||
let writableLabel = document.createElement("label");
|
||||
writableLabel.id = "writableLabel";
|
||||
writableLabel.setAttribute("value", "writable");
|
||||
|
||||
tooltip.setAttribute("orient", "horizontal")
|
||||
tooltip.appendChild(configurableLabel);
|
||||
tooltip.appendChild(enumerableLabel);
|
||||
tooltip.appendChild(writableLabel);
|
||||
|
||||
if (element.hasAttribute("non-configurable")) {
|
||||
configurableLabel.setAttribute("non-configurable", "");
|
||||
}
|
||||
if (element.hasAttribute("non-enumerable")) {
|
||||
enumerableLabel.setAttribute("non-enumerable", "");
|
||||
}
|
||||
if (element.hasAttribute("non-writable")) {
|
||||
writableLabel.setAttribute("non-writable", "");
|
||||
}
|
||||
|
||||
document.documentElement.appendChild(tooltip);
|
||||
aAnchor.setAttribute("tooltip", tooltip.id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic function refreshing the internal state of the element when
|
||||
* it's modified (e.g. a child detail, variable, property is added).
|
||||
|
@ -294,7 +294,12 @@ LayoutView.prototype = {
|
||||
let clientRect = node.getBoundingClientRect();
|
||||
let width = Math.round(clientRect.width);
|
||||
let height = Math.round(clientRect.height);
|
||||
this.doc.querySelector("#element-size").textContent = width + "x" + height;
|
||||
|
||||
let elt = this.doc.querySelector("#element-size");
|
||||
let newLabel = width + "x" + height;
|
||||
if (elt.textContent != newLabel) {
|
||||
elt.textContent = newLabel;
|
||||
}
|
||||
|
||||
// If the view is closed, no need to do anything more.
|
||||
if (!this.isOpen) return;
|
||||
|
@ -28,10 +28,10 @@ let ResponsiveUIManager = {
|
||||
* @param aTab the tab targeted.
|
||||
*/
|
||||
toggle: function(aWindow, aTab) {
|
||||
if (aTab.responsiveUI) {
|
||||
aTab.responsiveUI.close();
|
||||
if (aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI.close();
|
||||
} else {
|
||||
aTab.responsiveUI = new ResponsiveUI(aWindow, aTab);
|
||||
aTab.__responsiveUI = new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -169,7 +169,7 @@ ResponsiveUI.prototype = {
|
||||
this.container.removeAttribute("responsivemode");
|
||||
this.stack.removeAttribute("responsivemode");
|
||||
|
||||
delete this.tab.responsiveUI;
|
||||
delete this.tab.__responsiveUI;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -42,7 +42,7 @@ function test() {
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.responsiveUI;
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
|
@ -37,7 +37,7 @@ function test() {
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.responsiveUI;
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
|
@ -28,7 +28,7 @@ function test() {
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
|
||||
|
||||
instance = gBrowser.selectedTab.responsiveUI;
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
@ -683,4 +683,5 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
||||
@BINPATH@/webapprt/components/components.manifest
|
||||
@BINPATH@/webapprt/defaults/preferences/prefs.js
|
||||
@BINPATH@/webapprt/modules/WebappRT.jsm
|
||||
@BINPATH@/webapprt/modules/WebappsHandler.jsm
|
||||
#endif
|
||||
|
@ -23,3 +23,12 @@ geolocation.description=Do you want to share your location?
|
||||
geolocation.sharelocation=Share Location
|
||||
geolocation.dontshare=Don't Share
|
||||
geolocation.remember=Remember my choice
|
||||
|
||||
# LOCALIZATION NOTE (webapps.install.title): %S will be replaced with the name
|
||||
# of the webapp being installed.
|
||||
webapps.install.title=Install %S
|
||||
# LOCALIZATION NOTE (webapps.install.description): %S will be replaced with the
|
||||
# name of the webapp being installed.
|
||||
webapps.install.description=Do you want to install %S?
|
||||
webapps.install.install=Install App
|
||||
webapps.install.dontinstall=Don't Install
|
||||
|
@ -116,7 +116,7 @@ function NativeApp(aData) {
|
||||
"app": app
|
||||
};
|
||||
|
||||
this.processFolder = Services.dirsvc.get("CurProcD", Ci.nsIFile);
|
||||
this.runtimeFolder = Services.dirsvc.get("GreD", Ci.nsIFile);
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
@ -284,11 +284,11 @@ WinNativeApp.prototype = {
|
||||
* Copy the pre-built files into their destination folders.
|
||||
*/
|
||||
_copyPrebuiltFiles: function() {
|
||||
let webapprt = this.processFolder.clone();
|
||||
let webapprt = this.runtimeFolder.clone();
|
||||
webapprt.append("webapprt-stub.exe");
|
||||
webapprt.copyTo(this.installDir, this.appNameAsFilename + ".exe");
|
||||
|
||||
let uninstaller = this.processFolder.clone();
|
||||
let uninstaller = this.runtimeFolder.clone();
|
||||
uninstaller.append("webapp-uninstaller.exe");
|
||||
uninstaller.copyTo(this.uninstallDir, this.uninstallerFile.leafName);
|
||||
},
|
||||
@ -313,7 +313,7 @@ WinNativeApp.prototype = {
|
||||
writer.setString("Webapp", "Name", this.appName);
|
||||
writer.setString("Webapp", "Profile", this.installDir.leafName);
|
||||
writer.setString("Webapp", "Executable", this.appNameAsFilename);
|
||||
writer.setString("WebappRT", "InstallDir", this.processFolder.path);
|
||||
writer.setString("WebappRT", "InstallDir", this.runtimeFolder.path);
|
||||
writer.writeFile(null, Ci.nsIINIParserWriter.WRITE_UTF16);
|
||||
|
||||
// ${UninstallDir}/shortcuts_log.ini
|
||||
@ -534,7 +534,7 @@ MacNativeApp.prototype = {
|
||||
},
|
||||
|
||||
_copyPrebuiltFiles: function() {
|
||||
let webapprt = this.processFolder.clone();
|
||||
let webapprt = this.runtimeFolder.clone();
|
||||
webapprt.append("webapprt-stub");
|
||||
webapprt.copyTo(this.macOSDir, "webapprt");
|
||||
},
|
||||
@ -719,7 +719,7 @@ LinuxNativeApp.prototype = {
|
||||
},
|
||||
|
||||
_copyPrebuiltFiles: function() {
|
||||
let webapprtPre = this.processFolder.clone();
|
||||
let webapprtPre = this.runtimeFolder.clone();
|
||||
webapprtPre.append(this.webapprt.leafName);
|
||||
webapprtPre.copyTo(this.installDir, this.webapprt.leafName);
|
||||
},
|
||||
@ -740,7 +740,7 @@ LinuxNativeApp.prototype = {
|
||||
let writer = factory.createINIParser(webappINI).QueryInterface(Ci.nsIINIParserWriter);
|
||||
writer.setString("Webapp", "Name", this.appName);
|
||||
writer.setString("Webapp", "Profile", this.uniqueName);
|
||||
writer.setString("WebappRT", "InstallDir", this.processFolder.path);
|
||||
writer.setString("WebappRT", "InstallDir", this.runtimeFolder.path);
|
||||
writer.writeFile();
|
||||
|
||||
// $XDG_DATA_HOME/applications/owa-<webappuniquename>.desktop
|
||||
|
@ -168,6 +168,16 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#element-tooltip > label {
|
||||
margin: 0 2px 0 2px;
|
||||
}
|
||||
|
||||
#element-tooltip > label[non-enumerable],
|
||||
#element-tooltip > label[non-configurable],
|
||||
#element-tooltip > label[non-writable]{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property values colors
|
||||
*/
|
||||
|
@ -170,6 +170,16 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#element-tooltip > label {
|
||||
margin: 0 2px 0 2px;
|
||||
}
|
||||
|
||||
#element-tooltip > label[non-enumerable],
|
||||
#element-tooltip > label[non-configurable],
|
||||
#element-tooltip > label[non-writable]{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property values colors
|
||||
*/
|
||||
|
@ -168,6 +168,16 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#element-tooltip > label {
|
||||
margin: 0 2px 0 2px;
|
||||
}
|
||||
|
||||
#element-tooltip > label[non-enumerable],
|
||||
#element-tooltip > label[non-configurable],
|
||||
#element-tooltip > label[non-writable]{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property values colors
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@ import os.path
|
||||
import shutil
|
||||
import tarfile
|
||||
import subprocess
|
||||
import platform
|
||||
|
||||
def check_run(args):
|
||||
r = subprocess.call(args)
|
||||
@ -46,7 +47,7 @@ def with_env(env, f):
|
||||
|
||||
def build_tar_package(tar, name, base, directory):
|
||||
name = os.path.realpath(name)
|
||||
run_in(base, [tar, "-cjf", name, "--owner=root", directory])
|
||||
run_in(base, [tar, "-cjf", name, directory])
|
||||
|
||||
def svn_co(url, directory, revision):
|
||||
check_run(["svn", "co", "-r", revision, url, directory])
|
||||
@ -83,6 +84,8 @@ def build_one_stage_aux(stage_dir, is_stage_one):
|
||||
|
||||
build_package(llvm_source_dir, build_dir, configure_opts)
|
||||
|
||||
isDarwin = platform.system() == "Darwin"
|
||||
|
||||
if not os.path.exists(source_dir):
|
||||
os.makedirs(source_dir)
|
||||
svn_co("http://llvm.org/svn/llvm-project/llvm/trunk",
|
||||
@ -93,8 +96,12 @@ if not os.path.exists(source_dir):
|
||||
compiler_rt_source_dir, llvm_revision)
|
||||
os.symlink("../../clang", llvm_source_dir + "/tools/clang")
|
||||
os.symlink("../../compiler-rt", llvm_source_dir + "/projects/compiler-rt")
|
||||
patch("old-ld-hack.patch", 1, llvm_source_dir)
|
||||
patch("compiler-rt-gnu89-inline.patch", 0, compiler_rt_source_dir)
|
||||
if isDarwin:
|
||||
patch("clang-no-ios.patch", 0, clang_source_dir)
|
||||
patch("compiler-rt-no-ios.patch", 0, compiler_rt_source_dir)
|
||||
else:
|
||||
patch("old-ld-hack.patch", 1, llvm_source_dir)
|
||||
patch("compiler-rt-gnu89-inline.patch", 0, compiler_rt_source_dir)
|
||||
|
||||
if os.path.exists(build_dir):
|
||||
shutil.rmtree(build_dir)
|
||||
@ -102,13 +109,28 @@ os.makedirs(build_dir)
|
||||
|
||||
stage1_dir = build_dir + '/stage1'
|
||||
stage1_inst_dir = stage1_dir + '/clang'
|
||||
build_one_stage({"CC" : "/tools/gcc-4.5-0moz3/bin/gcc -static-libgcc",
|
||||
"CXX" : "/tools/gcc-4.5-0moz3/bin/g++ -static-libgcc -static-libstdc++"},
|
||||
|
||||
if isDarwin:
|
||||
extra_cflags = ""
|
||||
extra_cxxflags = ""
|
||||
cc = "/usr/bin/clang"
|
||||
cxx = "/usr/bin/clang++"
|
||||
else:
|
||||
extra_cflags = "-static-libgcc"
|
||||
extra_cxxflags = "-static-libgcc -static-libstdc++"
|
||||
cc = "/tools/gcc-4.5-0moz3/bin/gcc %s" % extra_cflags
|
||||
cxx = "/tools/gcc-4.5-0moz3/bin/g++ %s" % extra_cxxflags
|
||||
|
||||
build_one_stage({"CC" : cc,
|
||||
"CXX" : cxx },
|
||||
stage1_dir, True)
|
||||
|
||||
if not isDarwin:
|
||||
extra_cflags += " -fgnu89-inline"
|
||||
|
||||
stage2_dir = build_dir + '/stage2'
|
||||
build_one_stage({"CC" : stage1_inst_dir + "/bin/clang -static-libgcc -fgnu89-inline",
|
||||
"CXX" : stage1_inst_dir + "/bin/clang++ -static-libgcc -static-libstdc++"},
|
||||
build_one_stage({"CC" : stage1_inst_dir + "/bin/clang %s" % extra_cflags,
|
||||
"CXX" : stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags},
|
||||
stage2_dir, False)
|
||||
|
||||
build_tar_package("/bin/tar", "clang.tar.bz2", stage2_dir, "clang")
|
||||
build_tar_package("tar", "clang.tar.bz2", stage2_dir, "clang")
|
||||
|
15
build/unix/build-clang/clang-no-ios.patch
Normal file
15
build/unix/build-clang/clang-no-ios.patch
Normal file
@ -0,0 +1,15 @@
|
||||
Index: runtime/compiler-rt/Makefile
|
||||
===================================================================
|
||||
--- runtime/compiler-rt/Makefile (revision 157958)
|
||||
+++ runtime/compiler-rt/Makefile (working copy)
|
||||
@@ -74,8 +74,8 @@
|
||||
ifeq ($(OS),Darwin)
|
||||
RuntimeDirs += darwin
|
||||
RuntimeLibrary.darwin.Configs := \
|
||||
- eprintf 10.4 osx ios cc_kext \
|
||||
- asan_osx profile_osx profile_ios
|
||||
+ eprintf 10.4 osx \
|
||||
+ asan_osx profile_osx
|
||||
endif
|
||||
|
||||
# On Linux, include a library which has all the runtime functions.
|
29
build/unix/build-clang/compiler-rt-no-ios.patch
Normal file
29
build/unix/build-clang/compiler-rt-no-ios.patch
Normal file
@ -0,0 +1,29 @@
|
||||
Index: make/platform/clang_darwin.mk
|
||||
===================================================================
|
||||
--- make/platform/clang_darwin.mk (revision 157958)
|
||||
+++ make/platform/clang_darwin.mk (working copy)
|
||||
@@ -47,7 +47,7 @@
|
||||
# Configuration for targetting iOS, for some ARMv6 functions, which must be
|
||||
# in the same linkage unit, and for a couple of other functions that didn't
|
||||
# make it into libSystem.
|
||||
-Configs += ios
|
||||
+#Configs += ios
|
||||
UniversalArchs.ios := $(call CheckArches,i386 x86_64 armv6 armv7,ios)
|
||||
|
||||
# Configuration for targetting OSX. These functions may not be in libSystem
|
||||
@@ -56,13 +56,13 @@
|
||||
UniversalArchs.osx := $(call CheckArches,i386 x86_64,osx)
|
||||
|
||||
# Configuration for use with kernel/kexts.
|
||||
-Configs += cc_kext
|
||||
+#Configs += cc_kext
|
||||
UniversalArchs.cc_kext := $(call CheckArches,armv6 armv7 i386 x86_64,cc_kext)
|
||||
|
||||
# Configurations which define the profiling support functions.
|
||||
Configs += profile_osx
|
||||
UniversalArchs.profile_osx := $(call CheckArches,i386 x86_64,profile_osx)
|
||||
-Configs += profile_ios
|
||||
+#Configs += profile_ios
|
||||
UniversalArchs.profile_ios := $(call CheckArches,i386 x86_64 armv6 armv7,profile_ios)
|
||||
|
||||
# Configurations which define the ASAN support functions.
|
4
build/unix/build-clang/setup.sh
Normal file
4
build/unix/build-clang/setup.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -rf clang
|
||||
tar -xjf clang.tar.bz2
|
@ -495,7 +495,7 @@ case "$target" in
|
||||
AC_LANG_RESTORE
|
||||
|
||||
changequote(,)
|
||||
_MSVC_VER_FILTER='s|.* ([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
|
||||
_MSVC_VER_FILTER='s|.*[^!-~]([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
|
||||
changequote([,])
|
||||
|
||||
# Determine compiler version
|
||||
@ -571,7 +571,7 @@ case "$target" in
|
||||
fi
|
||||
|
||||
changequote(,)
|
||||
_MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
|
||||
_MSMT_VER_FILTER='s|.*[^!-~]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
|
||||
changequote([,])
|
||||
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
|
||||
if test -z "$MSMANIFEST_TOOL_VERSION"; then
|
||||
|
@ -250,6 +250,64 @@ public:
|
||||
return OwnerDoc()->IsHTML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace that this element's tag is defined in
|
||||
* @return the namespace
|
||||
*/
|
||||
inline PRInt32 GetNameSpaceID() const
|
||||
{
|
||||
return mNodeInfo->NamespaceID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeInfo for this element
|
||||
* @return the nodes node info
|
||||
*/
|
||||
inline nsINodeInfo* NodeInfo() const
|
||||
{
|
||||
return mNodeInfo;
|
||||
}
|
||||
|
||||
inline bool IsInNamespace(PRInt32 aNamespace) const
|
||||
{
|
||||
return mNodeInfo->NamespaceID() == aNamespace;
|
||||
}
|
||||
|
||||
inline bool IsHTML() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_XHTML);
|
||||
}
|
||||
|
||||
inline bool IsHTML(nsIAtom* aTag) const
|
||||
{
|
||||
return mNodeInfo->Equals(aTag, kNameSpaceID_XHTML);
|
||||
}
|
||||
|
||||
inline bool IsSVG() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_SVG);
|
||||
}
|
||||
|
||||
inline bool IsSVG(nsIAtom* aTag) const
|
||||
{
|
||||
return mNodeInfo->Equals(aTag, kNameSpaceID_SVG);
|
||||
}
|
||||
|
||||
inline bool IsXUL() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_XUL);
|
||||
}
|
||||
|
||||
inline bool IsMathML() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_MathML);
|
||||
}
|
||||
|
||||
inline bool IsMathML(nsIAtom* aTag) const
|
||||
{
|
||||
return mNodeInfo->Equals(aTag, kNameSpaceID_MathML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an atom holding the name of the attribute of type ID on
|
||||
* this content node (if applicable). Returns null for non-element
|
||||
|
@ -476,15 +476,6 @@ public:
|
||||
return mNodeInfo->LocalName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the namespace that this element's tag is defined in
|
||||
* @return the namespace
|
||||
*/
|
||||
PRInt32 GetNameSpaceID() const
|
||||
{
|
||||
return mNodeInfo->NamespaceID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tag for this element. This will always return a non-null atom
|
||||
* pointer (as implied by the naming of the method). For elements this is
|
||||
@ -496,55 +487,6 @@ public:
|
||||
return mNodeInfo->NameAtom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeInfo for this element
|
||||
* @return the nodes node info
|
||||
*/
|
||||
nsINodeInfo* NodeInfo() const
|
||||
{
|
||||
return mNodeInfo;
|
||||
}
|
||||
|
||||
bool IsInNamespace(PRInt32 aNamespace) const
|
||||
{
|
||||
return mNodeInfo->NamespaceID() == aNamespace;
|
||||
}
|
||||
|
||||
bool IsHTML() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_XHTML);
|
||||
}
|
||||
|
||||
bool IsHTML(nsIAtom* aTag) const
|
||||
{
|
||||
return mNodeInfo->Equals(aTag, kNameSpaceID_XHTML);
|
||||
}
|
||||
|
||||
bool IsSVG() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_SVG);
|
||||
}
|
||||
|
||||
bool IsSVG(nsIAtom* aTag) const
|
||||
{
|
||||
return mNodeInfo->Equals(aTag, kNameSpaceID_SVG);
|
||||
}
|
||||
|
||||
bool IsXUL() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_XUL);
|
||||
}
|
||||
|
||||
bool IsMathML() const
|
||||
{
|
||||
return IsInNamespace(kNameSpaceID_MathML);
|
||||
}
|
||||
|
||||
bool IsMathML(nsIAtom* aTag) const
|
||||
{
|
||||
return mNodeInfo->Equals(aTag, kNameSpaceID_MathML);
|
||||
}
|
||||
|
||||
nsINode*
|
||||
InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn)
|
||||
{
|
||||
|
@ -1505,13 +1505,6 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
mDocShell->SetChromeEventHandler(chromeEventHandler);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (OwnerIsBrowserFrame() && os) {
|
||||
mDocShell->SetIsBrowserFrame(true);
|
||||
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
|
||||
"in-process-browser-frame-shown", NULL);
|
||||
}
|
||||
|
||||
// This is nasty, this code (the do_GetInterface(mDocShell) below)
|
||||
// *must* come *after* the above call to
|
||||
// mDocShell->SetChromeEventHandler() for the global window to get
|
||||
@ -1538,6 +1531,22 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
|
||||
EnsureMessageManager();
|
||||
|
||||
if (OwnerIsBrowserFrame()) {
|
||||
mDocShell->SetIsBrowserFrame(true);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
|
||||
"in-process-browser-frame-shown", NULL);
|
||||
}
|
||||
|
||||
if (mMessageManager) {
|
||||
mMessageManager->LoadFrameScript(
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
|
||||
/* allowDelayedLoad = */ true);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1899,7 +1908,8 @@ nsFrameLoader::TryRemoteBrowser()
|
||||
|
||||
ContentParent* parent = ContentParent::GetNewOrUsed();
|
||||
NS_ASSERTION(parent->IsAlive(), "Process parent should be alive; something is very wrong!");
|
||||
mRemoteBrowser = parent->CreateTab(chromeFlags);
|
||||
mRemoteBrowser = parent->CreateTab(chromeFlags,
|
||||
/* aIsBrowserFrame = */ OwnerIsBrowserFrame());
|
||||
if (mRemoteBrowser) {
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
|
||||
mRemoteBrowser->SetOwnerElement(element);
|
||||
|
@ -2033,6 +2033,20 @@ nsGenericElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
|
||||
aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height);
|
||||
}
|
||||
|
||||
nsIntSize
|
||||
nsGenericElement::GetPaddingRectSize()
|
||||
{
|
||||
nsIFrame* frame = GetStyledFrame();
|
||||
if (!frame) {
|
||||
return nsIntSize(0, 0);
|
||||
}
|
||||
|
||||
NS_ASSERTION(frame->GetParent(), "Styled frame has no parent");
|
||||
nsRect rcFrame = nsLayoutUtils::GetAllInFlowPaddingRectsUnion(frame, frame->GetParent());
|
||||
return nsIntSize(nsPresContext::AppUnitsToIntCSSPixels(rcFrame.width),
|
||||
nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height));
|
||||
}
|
||||
|
||||
nsIScrollableFrame*
|
||||
nsGenericElement::GetScrollFrame(nsIFrame **aStyledFrame)
|
||||
{
|
||||
@ -2145,10 +2159,7 @@ nsGenericElement::GetScrollHeight()
|
||||
|
||||
nsIScrollableFrame* sf = GetScrollFrame();
|
||||
if (!sf) {
|
||||
nsRect rcFrame;
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
GetOffsetRect(rcFrame, getter_AddRefs(parent));
|
||||
return rcFrame.height;
|
||||
return GetPaddingRectSize().height;
|
||||
}
|
||||
|
||||
nscoord height = sf->GetScrollRange().height + sf->GetScrollPortRect().height;
|
||||
@ -2171,10 +2182,7 @@ nsGenericElement::GetScrollWidth()
|
||||
|
||||
nsIScrollableFrame* sf = GetScrollFrame();
|
||||
if (!sf) {
|
||||
nsRect rcFrame;
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
GetOffsetRect(rcFrame, getter_AddRefs(parent));
|
||||
return rcFrame.width;
|
||||
return GetPaddingRectSize().width;
|
||||
}
|
||||
|
||||
nscoord width = sf->GetScrollRange().width + sf->GetScrollPortRect().width;
|
||||
|
@ -777,6 +777,13 @@ protected:
|
||||
*/
|
||||
virtual void GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent);
|
||||
|
||||
/**
|
||||
* Retrieve the size of the padding rect of this element.
|
||||
*
|
||||
* @param aSize the size of the padding rect
|
||||
*/
|
||||
nsIntSize GetPaddingRectSize();
|
||||
|
||||
nsIFrame* GetStyledFrame();
|
||||
|
||||
virtual mozilla::dom::Element* GetNameSpaceElement()
|
||||
|
@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=320799
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=320799">Mozilla Bug 320799</a>
|
||||
<p id="display">
|
||||
<select id="s" style="width: 100px">
|
||||
<select id="s" style="width: 100px; -moz-box-sizing: padding-box">
|
||||
<option>This is a test, it really is a test I tell you</option>
|
||||
</select>
|
||||
<select id="s2">
|
||||
|
@ -41,13 +41,13 @@ function t3(id,c,o,s,pid) {
|
||||
|
||||
function run_test() {
|
||||
t3('span1',[0,0,20,20],[12,12,20,20],[0,0,20,20],'td1');
|
||||
t3('td1' ,[1,1,69,44],[16,16,71,46],[0,0,71,46],'table1');
|
||||
t3('td1' ,[1,1,69,44],[16,16,71,46],[0,0,69,46],'table1');
|
||||
t3('tr1' ,[0,0,71,46],[16,16,71,46],[0,0,71,44],'table1');
|
||||
t3('span2',[10,0,20,20],[27,12,30,20],[0,0,30,20],'td2');
|
||||
t3('table1',[9,9,85,113],[10,10,103,131],[0,0,103,50],'body');
|
||||
t3('span2',[10,0,20,20],[27,12,30,20],[0,0,20,20],'td2');
|
||||
t3('table1',[9,9,85,113],[10,10,103,131],[0,0,85,50],'body');
|
||||
t3('div1',[10,10,-1,131],[0,0,-1,151],[0,0,-1,85],'body');
|
||||
|
||||
t3('span2b',[10,0,20,20],[25,-1,30,20],[0,0,30,20],'body');
|
||||
t3('span2b',[10,0,20,20],[25,-1,30,20],[0,0,20,20],'body');
|
||||
// XXX not sure how to make reliable cross-platform tests for replaced-inline, inline
|
||||
// t3('span2c',[10,2,18,2],[25,-1,30,6],[0,0,30,20],'body');
|
||||
// t3('span2d',[0,0,0,0],[25,-1,10,19],[0,0,10,20],'body');
|
||||
@ -60,24 +60,24 @@ function run_test() {
|
||||
t3('div3',[10,10,-1,40],[0,151,-1,60],[0,0,-1,70],'body');
|
||||
|
||||
t3('span5' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td5');
|
||||
t3('td5' ,[7,7,22,22],[2,2,36,36],[0,0,36,36],'table5');
|
||||
t3('td5' ,[7,7,22,22],[2,2,36,36],[0,0,22,36],'table5');
|
||||
t3('tr5' ,[0,0,36,36],[2,2,36,36],[0,0,36,22],'table5');
|
||||
t3('span6' ,[0,0,20,20],[20,58,20,20],[0,0,20,20],'div5');
|
||||
t3('table5',[0,0,40,78],[0,0,40,78],[0,0,40,78],'div5');
|
||||
t3('div5',[10,10,-1,78],[0,211,-1,98],[0,0,-1,70],'body');
|
||||
|
||||
t3('span7' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td7');
|
||||
t3('td7' ,[1,1,37,22],[9,9,39,24],[0,0,39,22],'table7');
|
||||
t3('td7' ,[1,1,37,22],[9,9,39,24],[0,0,37,22],'table7');
|
||||
t3('tr7' ,[0,0,39,24],[9,9,39,24],[0,0,39,22],'table7');
|
||||
t3('span8' ,[0,0,20,20],[26,37,20,20],[0,0,20,20],'table7');
|
||||
t3('table7',[7,7,43,54],[10,319,57,68],[0,0,57,50],'body');
|
||||
t3('table7',[7,7,43,54],[10,319,57,68],[0,0,43,50],'body');
|
||||
t3('div7',[10,10,-1,68],[0,309,-1,88],[0,0,-1,70],'body');
|
||||
|
||||
t3('span9' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td9');
|
||||
t3('td9' ,[1,1,22,22],[15,15,24,24],[0,0,24,24],'table9');
|
||||
t3('td9' ,[1,1,22,22],[15,15,24,24],[0,0,22,24],'table9');
|
||||
t3('tr9' ,[0,0,24,24],[15,15,24,24],[0,0,24,22],'table9');
|
||||
t3('span10' ,[0,0,20,20],[17,43,20,20],[0,0,20,20],'table9');
|
||||
t3('table9',[13,13,28,34],[10,407,54,60],[0,0,54,50],'body');
|
||||
t3('table9',[13,13,28,34],[10,407,54,60],[0,0,28,50],'body');
|
||||
t3('div9',[10,10,-1,0],[0,397,-1,20],[0,0,-1,70],'body');
|
||||
|
||||
t3('span11' ,[0,0,20,20],[1,1,20,20],[0,0,20,20],'td11');
|
||||
|
@ -68,9 +68,9 @@ function run_test() {
|
||||
// without hard-coding the scrollbar width?
|
||||
t3('div1',[20,20,-1,-1],[10,10,200,160],[0,0,230,20],'body');
|
||||
t3('abs1',[20,20,-1,-1],[500,170,200,160],[0,0,230,20],'body');
|
||||
t3('table1',[20,20,266,266],[10,170,306,306],[0,0,306,20],'body');
|
||||
t3('table1',[20,20,266,266],[10,170,306,306],[0,0,266,20],'body');
|
||||
t3('table2',[0,0,206,206],[0,0,206,206],[0,0,206,20],'table2parent');
|
||||
t3('table3',[10,10,208,208],[0,0,228,228],[0,0,228,228],'table3parent');
|
||||
t3('table3',[10,10,208,208],[0,0,228,228],[0,0,208,228],'table3parent');
|
||||
t3('table3parent',[0,0,228,228],[300,100,228,228],[0,0,228,228],'body');
|
||||
}
|
||||
</script>
|
||||
@ -106,4 +106,4 @@ run_test();
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -191,7 +191,7 @@ nsresult nsGStreamerReader::ReadMetadata(nsVideoInfo* aInfo)
|
||||
* stream but that are otherwise decodeable.
|
||||
*/
|
||||
guint flags[3] = {GST_PLAY_FLAG_VIDEO|GST_PLAY_FLAG_AUDIO,
|
||||
~GST_PLAY_FLAG_AUDIO, ~GST_PLAY_FLAG_VIDEO};
|
||||
static_cast<guint>(~GST_PLAY_FLAG_AUDIO), static_cast<guint>(~GST_PLAY_FLAG_VIDEO)};
|
||||
guint default_flags, current_flags;
|
||||
g_object_get(mPlayBin, "flags", &default_flags, NULL);
|
||||
|
||||
|
@ -78,98 +78,327 @@ XBLFinalize(JSFreeOp *fop, JSObject *obj)
|
||||
c->Drop();
|
||||
}
|
||||
|
||||
static JSBool
|
||||
XBLResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
|
||||
JSObject **objp)
|
||||
// XBL fields are represented on elements inheriting that field a bit trickily.
|
||||
// Initially the element itself won't have a property for the field. When an
|
||||
// attempt is made to access the field, the element's resolve hook won't find
|
||||
// it. But the XBL prototype object, in the prototype chain of the element,
|
||||
// will resolve an accessor property for the field on the XBL prototype object.
|
||||
// That accessor, when used, will then (via InstallXBLField below) reify a
|
||||
// property for the field onto the actual XBL-backed element.
|
||||
//
|
||||
// The accessor property is a plain old property backed by a getter function and
|
||||
// a setter function. These properties are backed by the FieldGetter and
|
||||
// FieldSetter natives; they're created by XBLResolve. The precise field to be
|
||||
// reified is identified using two extra slots on the getter/setter functions.
|
||||
// XBLPROTO_SLOT stores the XBL prototype object that provides the field.
|
||||
// FIELD_SLOT stores the name of the field, i.e. its JavaScript property name.
|
||||
//
|
||||
// This two-step field installation process -- reify an accessor on the
|
||||
// prototype, then have that reify an own property on the actual element -- is
|
||||
// admittedly convoluted. Better would be for XBL-backed elements to be proxies
|
||||
// that could resolve fields onto themselves. But given that XBL bindings are
|
||||
// associated with elements mutably -- you can add/remove/change -moz-binding
|
||||
// whenever you want, alas -- doing so would require all elements to be proxies,
|
||||
// which isn't performant now. So we do this two-step instead.
|
||||
static const uint32_t XBLPROTO_SLOT = 0;
|
||||
static const uint32_t FIELD_SLOT = 1;
|
||||
|
||||
static bool
|
||||
ObjectHasISupportsPrivate(JS::Handle<JSObject*> obj)
|
||||
{
|
||||
// Note: if we get here, that means that the implementation for some binding
|
||||
// was installed, which means that AllowScripts() tested true. Hence no need
|
||||
// to do checks like that here.
|
||||
|
||||
// Default to not resolving things.
|
||||
NS_ASSERTION(*objp, "Must have starting object");
|
||||
JSClass* clasp = ::JS_GetClass(obj);
|
||||
const uint32_t HAS_PRIVATE_NSISUPPORTS =
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS;
|
||||
return (clasp->flags & HAS_PRIVATE_NSISUPPORTS) == HAS_PRIVATE_NSISUPPORTS;
|
||||
}
|
||||
|
||||
JSObject* origObj = *objp;
|
||||
*objp = NULL;
|
||||
// Define a shadowing property on |this| for the XBL field defined by the
|
||||
// contents of the callee's reserved slots. If the property was defined,
|
||||
// *installed will be true, and idp will be set to the property name that was
|
||||
// defined.
|
||||
static JSBool
|
||||
InstallXBLField(JSContext* cx,
|
||||
JS::Handle<JSObject*> callee, JS::Handle<JSObject*> thisObj,
|
||||
jsid* idp, bool* installed)
|
||||
{
|
||||
*installed = false;
|
||||
|
||||
if (!JSID_IS_STRING(id)) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
nsDependentJSString fieldName(id);
|
||||
|
||||
jsval slotVal = ::JS_GetReservedSlot(obj, 0);
|
||||
NS_ASSERTION(!JSVAL_IS_VOID(slotVal), "How did that happen?");
|
||||
|
||||
nsXBLPrototypeBinding* protoBinding =
|
||||
static_cast<nsXBLPrototypeBinding*>(JSVAL_TO_PRIVATE(slotVal));
|
||||
NS_ASSERTION(protoBinding, "Must have prototype binding!");
|
||||
|
||||
nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
|
||||
if (!field) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// We have this field. Time to install it. Get our node.
|
||||
JSClass* nodeClass = ::JS_GetClass(origObj);
|
||||
if (!nodeClass) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (~nodeClass->flags &
|
||||
(JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
|
||||
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
|
||||
return JS_FALSE;
|
||||
}
|
||||
// First ensure |this| is a reasonable XBL bound node.
|
||||
//
|
||||
// FieldAccessorGuard already determined whether |thisObj| was acceptable as
|
||||
// |this| in terms of not throwing a TypeError. Assert this for good measure.
|
||||
MOZ_ASSERT(ObjectHasISupportsPrivate(thisObj));
|
||||
|
||||
// But there are some cases where we must accept |thisObj| but not install a
|
||||
// property on it, or otherwise touch it. Hence this split of |this|-vetting
|
||||
// duties.
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
|
||||
do_QueryInterface(static_cast<nsISupports*>(::JS_GetPrivate(origObj)));
|
||||
do_QueryInterface(static_cast<nsISupports*>(::JS_GetPrivate(thisObj)));
|
||||
if (!xpcWrapper) {
|
||||
// Looks like whatever |origObj| is it's not our nsIContent. It might well
|
||||
// Looks like whatever |thisObj| is it's not our nsIContent. It might well
|
||||
// be the proto our binding installed, however, where the private is the
|
||||
// nsXBLDocumentInfo, so just baul out quietly. Do NOT throw an exception
|
||||
// here.
|
||||
// We could make this stricter by checking the class maybe, but whatever
|
||||
return JS_TRUE;
|
||||
//
|
||||
// We could make this stricter by checking the class maybe, but whatever.
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryWrappedNative(xpcWrapper);
|
||||
if (!content) {
|
||||
nsCOMPtr<nsIContent> xblNode = do_QueryWrappedNative(xpcWrapper);
|
||||
if (!xblNode) {
|
||||
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now that |this| is okay, actually install the field. Some of this
|
||||
// installation work could have been done in XBLResolve, but this splitting
|
||||
// of work seems simplest to implement and friendliest regarding lifetimes
|
||||
// and potential cycles.
|
||||
|
||||
// Because of the possibility (due to XBL binding inheritance, because each
|
||||
// XBL binding lives in its own global object) that |this| might be in a
|
||||
// different compartment from the callee (not to mention that this method can
|
||||
// be called with an arbitrary |this| regardless of how insane XBL is), and
|
||||
// because in this method we've entered |this|'s compartment (see in
|
||||
// Field[GS]etter where we attempt a cross-compartment call), we must enter
|
||||
// the callee's compartment to access its reserved slots.
|
||||
nsXBLPrototypeBinding* protoBinding;
|
||||
nsDependentJSString fieldName;
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, callee)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> xblProto(cx);
|
||||
xblProto = &js::GetFunctionNativeReserved(callee, XBLPROTO_SLOT).toObject();
|
||||
|
||||
JS::Value name = js::GetFunctionNativeReserved(callee, FIELD_SLOT);
|
||||
JSFlatString* fieldStr = JS_ASSERT_STRING_IS_FLAT(name.toString());
|
||||
fieldName.init(fieldStr);
|
||||
|
||||
MOZ_ALWAYS_TRUE(JS_ValueToId(cx, name, idp));
|
||||
|
||||
JS::Value slotVal = ::JS_GetReservedSlot(xblProto, 0);
|
||||
protoBinding = static_cast<nsXBLPrototypeBinding*>(slotVal.toPrivate());
|
||||
MOZ_ASSERT(protoBinding);
|
||||
}
|
||||
|
||||
nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
|
||||
MOZ_ASSERT(field);
|
||||
|
||||
// This mirrors code in nsXBLProtoImpl::InstallImplementation
|
||||
nsIDocument* doc = content->OwnerDoc();
|
||||
|
||||
nsIScriptGlobalObject* global = doc->GetScriptGlobalObject();
|
||||
nsIScriptGlobalObject* global = xblNode->OwnerDoc()->GetScriptGlobalObject();
|
||||
if (!global) {
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptContext> context = global->GetContext();
|
||||
if (!context) {
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult rv = field->InstallField(context, thisObj, xblNode->NodePrincipal(),
|
||||
protoBinding->DocURI(), installed);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now we either resolve or fail
|
||||
bool didInstall;
|
||||
nsresult rv = field->InstallField(context, origObj,
|
||||
content->NodePrincipal(),
|
||||
protoBinding->DocURI(),
|
||||
&didInstall);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (!::JS_IsExceptionPending(cx)) {
|
||||
xpc::Throw(cx, rv);
|
||||
return JS_FALSE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine whether the |this| passed to this method is valid for an XBL field
|
||||
// access (which is to say, an object with an nsISupports private), taking into
|
||||
// account proxies and/or wrappers around |this|. There are three possible
|
||||
// outcomes from calling this method:
|
||||
//
|
||||
// 1. An error was hit, and this method returned false. In this case, the
|
||||
// caller should propagate it.
|
||||
// 2. The |this| passed in was directly acceptable for XBL field access. This
|
||||
// method returned true and set *thisObj to a |this| that can be used for
|
||||
// field definition (i.e. that passes ObjectHasISupportsPrivate). In this
|
||||
// case, the caller should install the field on *thisObj.
|
||||
// 3. The |this| passed in was a proxy/wrapper around an object usable for
|
||||
// XBL field access. The method recursively (and successfully) invoked the
|
||||
// native on the unwrapped |this|, then it returned true and set *thisObj
|
||||
// to null. In this case, the caller should itself return true.
|
||||
//
|
||||
// Thus this method implements the JS_CallNonGenericMethodOnProxy idiom in
|
||||
// jsapi.h.
|
||||
//
|
||||
// Note that a |this| valid for field access is *not* necessarily one on which
|
||||
// the field value will be installed. It's just one where calling the specified
|
||||
// method on it won't unconditionally throw a TypeError. Confusing? Perhaps,
|
||||
// but it's compatible with what we did before we implemented XBL fields using
|
||||
// this technique.
|
||||
inline bool
|
||||
FieldAccessorGuard(JSContext *cx, unsigned argc, JS::Value *vp, JSNative native, JSObject **thisObj)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
|
||||
if (!obj) {
|
||||
xpc::Throw(cx, NS_ERROR_UNEXPECTED);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (didInstall) {
|
||||
*objp = origObj;
|
||||
if (ObjectHasISupportsPrivate(obj)) {
|
||||
*thisObj = obj;
|
||||
return true;
|
||||
}
|
||||
// else we didn't resolve this field after all
|
||||
|
||||
return JS_TRUE;
|
||||
// |this| wasn't an unwrapped object passing the has-private-nsISupports test.
|
||||
// So try to unwrap |this| and recursively call the native on it.
|
||||
//
|
||||
// This |protoClass| gunk is needed for the JS engine to report an error if an
|
||||
// object of the wrong class was passed as |this|, so that it can complain
|
||||
// that it expected an object of type |protoClass|. It would be better if the
|
||||
// error didn't try to specify the expected class of objects -- particularly
|
||||
// because there's no one class of objects -- but it's what the API wants, so
|
||||
// pass a class that's marginally correct as an answer.
|
||||
JSClass* protoClass;
|
||||
{
|
||||
JS::Rooted<JSObject*> callee(cx, &JS_CALLEE(cx, vp).toObject());
|
||||
JS::Rooted<JSObject*> xblProto(cx);
|
||||
xblProto = &js::GetFunctionNativeReserved(callee, XBLPROTO_SLOT).toObject();
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, xblProto)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protoClass = ::JS_GetClass(xblProto);
|
||||
}
|
||||
|
||||
*thisObj = NULL;
|
||||
return JS_CallNonGenericMethodOnProxy(cx, argc, vp, native, protoClass);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
FieldGetter(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||
{
|
||||
JS::Rooted<JSObject*> thisObj(cx);
|
||||
if (!FieldAccessorGuard(cx, argc, vp, FieldGetter, thisObj.address())) {
|
||||
return false;
|
||||
}
|
||||
if (!thisObj) {
|
||||
return true; // FieldGetter was recursively invoked on an unwrapped |this|
|
||||
}
|
||||
|
||||
bool installed = false;
|
||||
JS::Rooted<JSObject*> callee(cx, &JS_CALLEE(cx, vp).toObject());
|
||||
JS::Rooted<jsid> id(cx);
|
||||
if (!InstallXBLField(cx, callee, thisObj, id.address(), &installed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!installed) {
|
||||
JS_SET_RVAL(cx, vp, JS::UndefinedValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
if (!JS_GetPropertyById(cx, thisObj, id, v.address())) {
|
||||
return false;
|
||||
}
|
||||
JS_SET_RVAL(cx, vp, v);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
FieldSetter(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||
{
|
||||
JS::Rooted<JSObject*> thisObj(cx);
|
||||
if (!FieldAccessorGuard(cx, argc, vp, FieldSetter, thisObj.address())) {
|
||||
return false;
|
||||
}
|
||||
if (!thisObj) {
|
||||
return true; // FieldSetter was recursively invoked on an unwrapped |this|
|
||||
}
|
||||
|
||||
bool installed = false;
|
||||
JS::Rooted<JSObject*> callee(cx, &JS_CALLEE(cx, vp).toObject());
|
||||
JS::Rooted<jsid> id(cx);
|
||||
if (!InstallXBLField(cx, callee, thisObj, id.address(), &installed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> v(cx,
|
||||
argc > 0 ? JS_ARGV(cx, vp)[0] : JS::UndefinedValue());
|
||||
return JS_SetPropertyById(cx, thisObj, id, v.address());
|
||||
}
|
||||
|
||||
static JSBool
|
||||
XBLResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
|
||||
JSObject **objp)
|
||||
{
|
||||
*objp = NULL;
|
||||
|
||||
if (!JSID_IS_STRING(id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsXBLPrototypeBinding* protoBinding =
|
||||
static_cast<nsXBLPrototypeBinding*>(::JS_GetReservedSlot(obj, 0).toPrivate());
|
||||
MOZ_ASSERT(protoBinding);
|
||||
|
||||
// If the field's not present, don't resolve it. Also don't resolve it if the
|
||||
// field is empty; see also nsXBLProtoImplField::InstallField which also must
|
||||
// implement the not-empty requirement.
|
||||
nsDependentJSString fieldName(id);
|
||||
nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
|
||||
if (!field || field->IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We have a field: now install a getter/setter pair which will resolve the
|
||||
// field onto the actual object, when invoked.
|
||||
JS::Rooted<JSObject*> global(cx, JS_GetGlobalForObject(cx, obj));
|
||||
|
||||
JS::Rooted<JSObject*> get(cx);
|
||||
get = ::JS_GetFunctionObject(js::NewFunctionByIdWithReserved(cx, FieldGetter,
|
||||
0, 0, global,
|
||||
id));
|
||||
if (!get) {
|
||||
return false;
|
||||
}
|
||||
js::SetFunctionNativeReserved(get, XBLPROTO_SLOT, JS::ObjectValue(*obj));
|
||||
js::SetFunctionNativeReserved(get, FIELD_SLOT,
|
||||
JS::StringValue(JSID_TO_STRING(id)));
|
||||
|
||||
JS::Rooted<JSObject*> set(cx);
|
||||
set = ::JS_GetFunctionObject(js::NewFunctionByIdWithReserved(cx, FieldSetter,
|
||||
1, 0, global,
|
||||
id));
|
||||
if (!set) {
|
||||
return false;
|
||||
}
|
||||
js::SetFunctionNativeReserved(set, XBLPROTO_SLOT, JS::ObjectValue(*obj));
|
||||
js::SetFunctionNativeReserved(set, FIELD_SLOT,
|
||||
JS::StringValue(JSID_TO_STRING(id)));
|
||||
|
||||
if (!::JS_DefinePropertyById(cx, obj, id, JS::UndefinedValue(),
|
||||
JS_DATA_TO_FUNC_PTR(JSPropertyOp,
|
||||
get.reference()),
|
||||
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp,
|
||||
set.reference()),
|
||||
field->AccessorAttributes())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*objp = obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
XBLEnumerate(JSContext *cx, JS::Handle<JSObject*> obj)
|
||||
{
|
||||
nsXBLPrototypeBinding* protoBinding =
|
||||
static_cast<nsXBLPrototypeBinding*>(::JS_GetReservedSlot(obj, 0).toPrivate());
|
||||
MOZ_ASSERT(protoBinding);
|
||||
|
||||
return protoBinding->ResolveAllFields(cx, obj);
|
||||
}
|
||||
|
||||
nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName)
|
||||
@ -179,12 +408,12 @@ nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName)
|
||||
name = ToNewCString(aClassName);
|
||||
flags =
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_NEW_RESOLVE_GETS_START |
|
||||
JSCLASS_NEW_RESOLVE |
|
||||
// Our one reserved slot holds the relevant nsXBLPrototypeBinding
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1);
|
||||
addProperty = delProperty = getProperty = ::JS_PropertyStub;
|
||||
setProperty = ::JS_StrictPropertyStub;
|
||||
enumerate = ::JS_EnumerateStub;
|
||||
enumerate = XBLEnumerate;
|
||||
resolve = (JSResolveOp)XBLResolve;
|
||||
convert = ::JS_ConvertStub;
|
||||
finalize = XBLFinalize;
|
||||
|
@ -88,7 +88,8 @@ nsXBLProtoImplField::InstallField(nsIScriptContext* aContext,
|
||||
|
||||
*aDidInstall = false;
|
||||
|
||||
if (mFieldTextLength == 0) {
|
||||
// Empty fields are treated as not actually present.
|
||||
if (IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,13 @@ public:
|
||||
|
||||
const PRUnichar* GetName() const { return mName; }
|
||||
|
||||
unsigned AccessorAttributes() const {
|
||||
return JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER |
|
||||
(mJSAttributes & (JSPROP_ENUMERATE | JSPROP_PERMANENT));
|
||||
}
|
||||
|
||||
bool IsEmpty() const { return mFieldTextLength == 0; }
|
||||
|
||||
protected:
|
||||
nsXBLProtoImplField* mNext;
|
||||
PRUnichar* mName;
|
||||
|
@ -116,8 +116,9 @@ addLoadEvent(function() {
|
||||
is(found, true, "Enumeration is broken");
|
||||
|
||||
is(d.four, 9, "Shouldn't have rerun field six");
|
||||
is(d.five, 5, "Should have run field 7");
|
||||
is(d.five, 11, "Shouldn't have run field 7");
|
||||
is(d.seven, 7, "Should be 7")
|
||||
is(d.five, 5, "Should have run field 7");
|
||||
|
||||
d = $("display2");
|
||||
is(typeof(d.eight), "undefined", "Recursive resolve should bail out");
|
||||
|
@ -648,6 +648,7 @@ ConvertLoadTypeToNavigationType(PRUint32 aLoadType)
|
||||
case LOAD_NORMAL_REPLACE:
|
||||
case LOAD_LINK:
|
||||
case LOAD_STOP_CONTENT:
|
||||
case LOAD_REPLACE_BYPASS_CACHE:
|
||||
result = nsIDOMPerformanceNavigation::TYPE_NAVIGATE;
|
||||
break;
|
||||
case LOAD_HISTORY:
|
||||
@ -1141,6 +1142,9 @@ ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType)
|
||||
case nsIDocShellLoadInfo::loadPushState:
|
||||
loadType = LOAD_PUSHSTATE;
|
||||
break;
|
||||
case nsIDocShellLoadInfo::loadReplaceBypassCache:
|
||||
loadType = LOAD_REPLACE_BYPASS_CACHE;
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unexpected nsDocShellInfoLoadType value");
|
||||
}
|
||||
@ -1209,6 +1213,9 @@ nsDocShell::ConvertLoadTypeToDocShellLoadInfo(PRUint32 aLoadType)
|
||||
case LOAD_PUSHSTATE:
|
||||
docShellLoadType = nsIDocShellLoadInfo::loadPushState;
|
||||
break;
|
||||
case LOAD_REPLACE_BYPASS_CACHE:
|
||||
docShellLoadType = nsIDocShellLoadInfo::loadReplaceBypassCache;
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unexpected load type value");
|
||||
}
|
||||
@ -5923,6 +5930,7 @@ nsDocShell::Embed(nsIContentViewer * aContentViewer,
|
||||
case LOAD_RELOAD_BYPASS_CACHE:
|
||||
case LOAD_RELOAD_BYPASS_PROXY:
|
||||
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
|
||||
case LOAD_REPLACE_BYPASS_CACHE:
|
||||
updateHistory = false;
|
||||
break;
|
||||
default:
|
||||
@ -9226,6 +9234,7 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
|
||||
case LOAD_RELOAD_BYPASS_CACHE:
|
||||
case LOAD_RELOAD_BYPASS_PROXY:
|
||||
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
|
||||
case LOAD_REPLACE_BYPASS_CACHE:
|
||||
loadFlags |= nsIRequest::LOAD_BYPASS_CACHE |
|
||||
nsIRequest::LOAD_FRESH_CONNECTION;
|
||||
break;
|
||||
|
@ -60,6 +60,7 @@ enum LoadType {
|
||||
LOAD_STOP_CONTENT = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_STOP_CONTENT),
|
||||
LOAD_STOP_CONTENT_AND_REPLACE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_STOP_CONTENT | nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY),
|
||||
LOAD_PUSHSTATE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_PUSHSTATE, nsIWebNavigation::LOAD_FLAGS_NONE),
|
||||
LOAD_REPLACE_BYPASS_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY | nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
|
||||
/**
|
||||
* Load type for an error page. These loads are never triggered by users of
|
||||
* Docshell. Instead, Docshell triggers the load itself when a
|
||||
@ -91,6 +92,7 @@ static inline bool IsValidLoadType(PRUint32 aLoadType)
|
||||
case LOAD_STOP_CONTENT:
|
||||
case LOAD_STOP_CONTENT_AND_REPLACE:
|
||||
case LOAD_PUSHSTATE:
|
||||
case LOAD_REPLACE_BYPASS_CACHE:
|
||||
case LOAD_ERROR_PAGE:
|
||||
return true;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ interface nsIDocShellLoadInfo : nsISupports
|
||||
const long loadNormalBypassProxy = 15;
|
||||
const long loadNormalBypassProxyAndCache = 16;
|
||||
const long loadPushState = 17; // history.pushState or replaceState
|
||||
const long loadReplaceBypassCache = 18;
|
||||
|
||||
/** Contains a load type as specified by the load* constants */
|
||||
attribute nsDocShellInfoLoadType loadType;
|
||||
|
@ -37,8 +37,8 @@ function convertAppsArray(aApps, aWindow) {
|
||||
let apps = Cu.createArrayIn(aWindow);
|
||||
for (let i = 0; i < aApps.length; i++) {
|
||||
let app = aApps[i];
|
||||
apps.push(new WebappsApplication(aWindow, app.origin, app.manifest, app.manifestURL,
|
||||
app.receipts, app.installOrigin, app.installTime));
|
||||
apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
|
||||
app.receipts, app.installOrigin, app.installTime));
|
||||
}
|
||||
|
||||
return apps;
|
||||
@ -49,6 +49,12 @@ function WebappsRegistry() {
|
||||
|
||||
WebappsRegistry.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
__exposedProps__: {
|
||||
install: 'r',
|
||||
getSelf: 'r',
|
||||
getInstalled: 'r',
|
||||
mgmt: 'r'
|
||||
},
|
||||
|
||||
/** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest
|
||||
* only the name property is mandatory
|
||||
@ -76,8 +82,8 @@ WebappsRegistry.prototype = {
|
||||
let app = msg.app;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
break;
|
||||
case "Webapps:Install:Return:KO":
|
||||
Services.DOMRequest.fireError(req, "DENIED");
|
||||
@ -85,8 +91,8 @@ WebappsRegistry.prototype = {
|
||||
case "Webapps:GetSelf:Return:OK":
|
||||
if (msg.apps.length) {
|
||||
app = msg.apps[0];
|
||||
Services.DOMRequest.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
} else {
|
||||
Services.DOMRequest.fireSuccess(req, null);
|
||||
}
|
||||
@ -200,63 +206,57 @@ WebappsRegistry.prototype = {
|
||||
/**
|
||||
* mozIDOMApplication object
|
||||
*/
|
||||
function WebappsApplication(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
|
||||
this._origin = aOrigin;
|
||||
this._manifestURL = aManifestURL;
|
||||
this._manifest = wrapObjectIn(aManifest, aWindow);
|
||||
this._receipts = aReceipts;
|
||||
this._installOrigin = aInstallOrigin;
|
||||
this._installTime = aInstallTime;
|
||||
|
||||
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO"]);
|
||||
function createApplicationObject(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
|
||||
let app = Cc["@mozilla.org/webapps/application;1"].createInstance(Ci.mozIDOMApplication);
|
||||
app.wrappedJSObject.init(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime);
|
||||
return app;
|
||||
}
|
||||
|
||||
function WebappsApplication() {
|
||||
this.wrappedJSObject = this;
|
||||
}
|
||||
|
||||
WebappsApplication.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
_origin: null,
|
||||
_manifest: null,
|
||||
_manifestURL: null,
|
||||
_receipts: [],
|
||||
_installOrigin: null,
|
||||
_installTime: 0,
|
||||
__exposedProps__: {
|
||||
origin: 'r',
|
||||
manifest: 'r',
|
||||
manifestURL: 'r',
|
||||
installOrigin: 'r',
|
||||
installTime: 'r',
|
||||
status: 'r',
|
||||
progress: 'r',
|
||||
onprogress: 'rw',
|
||||
launch: 'r',
|
||||
receipts: 'r',
|
||||
uninstall: 'r'
|
||||
},
|
||||
|
||||
get origin() {
|
||||
return this._origin;
|
||||
init: function(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
|
||||
this.origin = aOrigin;
|
||||
this.manifest = wrapObjectIn(aManifest, aWindow);
|
||||
this.manifestURL = aManifestURL;
|
||||
this.receipts = aReceipts;
|
||||
this.installOrigin = aInstallOrigin;
|
||||
this.installTime = aInstallTime;
|
||||
this.status = "installed";
|
||||
this.progress = NaN;
|
||||
this._onprogress = null;
|
||||
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO", "Webapps:OfflineCache"]);
|
||||
},
|
||||
|
||||
get manifest() {
|
||||
return this._manifest;
|
||||
set onprogress(aCallback) {
|
||||
this._onprogress = aCallback;
|
||||
},
|
||||
|
||||
get manifestURL() {
|
||||
return this._manifestURL;
|
||||
},
|
||||
|
||||
get receipts() {
|
||||
return this._receipts;
|
||||
},
|
||||
|
||||
get installOrigin() {
|
||||
return this._installOrigin;
|
||||
},
|
||||
|
||||
get installTime() {
|
||||
return this._installTime;
|
||||
get onprogress() {
|
||||
return this._onprogress;
|
||||
},
|
||||
|
||||
launch: function(aStartPoint) {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this._origin,
|
||||
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this.origin,
|
||||
startPoint: aStartPoint || "",
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
@ -265,16 +265,20 @@ WebappsApplication.prototype = {
|
||||
|
||||
uninstall: function() {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this._origin,
|
||||
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this.origin,
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
return request;
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this._onprogress = null;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
var msg = aMessage.json;
|
||||
let req = this.getRequest(msg.requestID);
|
||||
if (msg.oid != this._id || !req)
|
||||
let req = this.takeRequest(msg.requestID);
|
||||
if ((msg.oid != this._id || !req) && aMessage.name !== "Webapps:OfflineCache")
|
||||
return;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Uninstall:Return:OK":
|
||||
@ -283,8 +287,17 @@ WebappsApplication.prototype = {
|
||||
case "Webapps:Uninstall:Return:KO":
|
||||
Services.DOMRequest.fireError(req, "NOT_INSTALLED");
|
||||
break;
|
||||
case "Webapps:OfflineCache":
|
||||
if (msg.manifest != this.manifestURL)
|
||||
return;
|
||||
|
||||
this.status = msg.status;
|
||||
if (this._onprogress) {
|
||||
let event = new this._window.MozApplicationEvent("applicationinstall", { application: this });
|
||||
this._onprogress.handleEvent(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.removeRequest(msg.requestID);
|
||||
},
|
||||
|
||||
classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
|
||||
@ -321,6 +334,11 @@ function WebappsApplicationMgmt(aWindow) {
|
||||
|
||||
WebappsApplicationMgmt.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
__exposedProps__: {
|
||||
getAll: 'r',
|
||||
oninstall: 'rw',
|
||||
onuninstall: 'rw'
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this._oninstall = null;
|
||||
@ -376,7 +394,7 @@ WebappsApplicationMgmt.prototype = {
|
||||
if (this._oninstall) {
|
||||
let app = msg.app;
|
||||
let event = new this._window.MozApplicationEvent("applicationinstall",
|
||||
{ application : new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
{ application : createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime) });
|
||||
this._oninstall.handleEvent(event);
|
||||
}
|
||||
@ -384,7 +402,7 @@ WebappsApplicationMgmt.prototype = {
|
||||
case "Webapps:Uninstall:Return:OK":
|
||||
if (this._onuninstall) {
|
||||
let event = new this._window.MozApplicationEvent("applicationuninstall",
|
||||
{ application : new WebappsApplication(this._window, msg.origin, null, null, null, null, 0) });
|
||||
{ application : createApplicationObject(this._window, msg.origin, null, null, null, null, 0) });
|
||||
this._onuninstall.handleEvent(event);
|
||||
}
|
||||
break;
|
||||
|
@ -156,7 +156,9 @@ let DOMApplicationRegistry = {
|
||||
origin: aApp.origin,
|
||||
receipts: aApp.receipts,
|
||||
installTime: aApp.installTime,
|
||||
manifestURL: aApp.manifestURL
|
||||
manifestURL: aApp.manifestURL,
|
||||
progress: aApp.progress || 0.0,
|
||||
status: aApp.status || "installed"
|
||||
};
|
||||
return clone;
|
||||
},
|
||||
@ -165,7 +167,7 @@ let DOMApplicationRegistry = {
|
||||
ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
|
||||
},
|
||||
|
||||
confirmInstall: function(aData, aFromSync) {
|
||||
confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
|
||||
let app = aData.app;
|
||||
let id = app.syncId || this._appId(app.origin);
|
||||
|
||||
@ -191,11 +193,29 @@ let DOMApplicationRegistry = {
|
||||
this._writeFile(manFile, JSON.stringify(app.manifest));
|
||||
this.webapps[id] = appObject;
|
||||
|
||||
appObject.status = "installed";
|
||||
|
||||
let manifest = new DOMApplicationManifest(app.manifest, app.origin);
|
||||
|
||||
if (!aFromSync)
|
||||
this._saveApps((function() {
|
||||
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
|
||||
Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
|
||||
}).bind(this));
|
||||
|
||||
// if the manifest has an appcache_path property, use it to populate the appcache
|
||||
if (manifest.appcache_path) {
|
||||
let appcacheURI = Services.io.newURI(manifest.fullAppcachePath(), null, null);
|
||||
let updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"]
|
||||
.getService(Ci.nsIOfflineCacheUpdateService);
|
||||
let docURI = Services.io.newURI(manifest.fullLaunchPath(), null, null);
|
||||
let cacheUpdate = aProfileDir ? updateService.scheduleCustomProfileUpdate(appcacheURI, docURI, aProfileDir)
|
||||
: updateService.scheduleUpdate(appcacheURI, docURI, null);
|
||||
cacheUpdate.addObserver(new AppcacheObserver(appObject), false);
|
||||
if (aOfflineCacheObserver) {
|
||||
cacheUpdate.addObserver(aOfflineCacheObserver, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_appId: function(aURI) {
|
||||
@ -428,6 +448,53 @@ let DOMApplicationRegistry = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Appcache download observer
|
||||
*/
|
||||
AppcacheObserver = function(aApp) {
|
||||
this.app = aApp;
|
||||
};
|
||||
|
||||
AppcacheObserver.prototype = {
|
||||
// nsIOfflineCacheUpdateObserver implementation
|
||||
updateStateChanged: function appObs_Update(aUpdate, aState) {
|
||||
let mustSave = false;
|
||||
let app = this.app;
|
||||
|
||||
let setStatus = function appObs_setStatus(aStatus) {
|
||||
mustSave = (app.status != aStatus);
|
||||
app.status = aStatus;
|
||||
ppmm.sendAsyncMessage("Webapps:OfflineCache", { manifest: app.manifestURL, status: aStatus });
|
||||
}
|
||||
|
||||
switch (aState) {
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
|
||||
aUpdate.removeObserver(this);
|
||||
setStatus("cache-error");
|
||||
break;
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED:
|
||||
aUpdate.removeObserver(this);
|
||||
setStatus("cached");
|
||||
break;
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_DOWNLOADING:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMPROGRESS:
|
||||
setStatus("downloading")
|
||||
break;
|
||||
}
|
||||
|
||||
// Status changed, update the stored version.
|
||||
if (mustSave) {
|
||||
DOMApplicationRegistry._saveApps();
|
||||
}
|
||||
},
|
||||
|
||||
applicationCacheAvailable: function appObs_CacheAvail(aApplicationCache) {
|
||||
// Nothing to do.
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper object to access manifest information with locale support
|
||||
*/
|
||||
@ -481,6 +548,10 @@ DOMApplicationManifest.prototype = {
|
||||
return this._localeProp("icons");
|
||||
},
|
||||
|
||||
get appcache_path() {
|
||||
return this._localeProp("appcache_path");
|
||||
},
|
||||
|
||||
iconURLForSize: function(aSize) {
|
||||
let icons = this._localeProp("icons");
|
||||
if (!icons)
|
||||
@ -501,6 +572,11 @@ DOMApplicationManifest.prototype = {
|
||||
let startPoint = aStartPoint || "";
|
||||
let launchPath = this._localeProp("launch_path") || "";
|
||||
return this._origin.resolve(launchPath + startPoint);
|
||||
},
|
||||
|
||||
fullAppcachePath: function() {
|
||||
let appcachePath = this._localeProp("appcache_path");
|
||||
return this._origin.resolve(appcachePath ? appcachePath : "");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,3 +2,6 @@
|
||||
component {fff440b3-fae2-45c1-bf03-3b5a2e432270} Webapps.js
|
||||
contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270}
|
||||
category JavaScript-navigator-property mozApps @mozilla.org/webapps;1
|
||||
|
||||
component {723ed303-7757-4fb0-b261-4f78b1f6bd22} Webapps.js
|
||||
contract @mozilla.org/webapps/application;1 {723ed303-7757-4fb0-b261-4f78b1f6bd22}
|
||||
|
@ -574,8 +574,7 @@ static const char kDOMStringBundleURL[] =
|
||||
|
||||
#define ELEMENT_SCRIPTABLE_FLAGS \
|
||||
((NODE_SCRIPTABLE_FLAGS & ~nsIXPCScriptable::CLASSINFO_INTERFACES_ONLY) | \
|
||||
nsIXPCScriptable::WANT_POSTCREATE | \
|
||||
nsIXPCScriptable::WANT_ENUMERATE)
|
||||
nsIXPCScriptable::WANT_POSTCREATE)
|
||||
|
||||
#define EXTERNAL_OBJ_SCRIPTABLE_FLAGS \
|
||||
((ELEMENT_SCRIPTABLE_FLAGS & \
|
||||
@ -8188,27 +8187,6 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsElementSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, bool *_retval)
|
||||
{
|
||||
// Make sure to not call the superclass here!
|
||||
nsCOMPtr<nsIContent> content(do_QueryWrappedNative(wrapper, obj));
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsIDocument* doc = content->OwnerDoc();
|
||||
|
||||
nsRefPtr<nsXBLBinding> binding = doc->BindingManager()->GetBinding(content);
|
||||
if (!binding) {
|
||||
// Nothing else to do here
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*_retval = binding->ResolveAllFields(cx, obj);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Generic array scriptable helper.
|
||||
|
||||
|
@ -562,8 +562,6 @@ public:
|
||||
JSObject *globalObj, JSObject **parentObj);
|
||||
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj);
|
||||
NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, bool *_retval);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
|
||||
{
|
||||
|
@ -492,6 +492,7 @@ nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
|
||||
PRInt32 aModifiers,
|
||||
bool aIgnoreRootScrollFrame)
|
||||
{
|
||||
SAMPLE_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow");
|
||||
return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
|
||||
aIgnoreRootScrollFrame, true);
|
||||
}
|
||||
@ -1825,13 +1826,13 @@ nsDOMWindowUtils::GetParent(const JS::Value& aObject,
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
JSObject* parent = JS_GetParent(JSVAL_TO_OBJECT(aObject));
|
||||
JS::Rooted<JSObject*> parent(aCx, JS_GetParent(JSVAL_TO_OBJECT(aObject)));
|
||||
*aParent = OBJECT_TO_JSVAL(parent);
|
||||
|
||||
// Outerize if necessary.
|
||||
if (parent) {
|
||||
if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
|
||||
*aParent = OBJECT_TO_JSVAL(outerize(aCx, JS::RootedObject(aCx, parent)));
|
||||
*aParent = OBJECT_TO_JSVAL(outerize(aCx, parent));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1090,6 +1090,7 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
}
|
||||
|
||||
if (mScreen) {
|
||||
mScreen->Reset();
|
||||
mScreen = nsnull;
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,25 @@ nsScreen::nsScreen()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsScreen::Reset()
|
||||
{
|
||||
hal::UnlockScreenOrientation();
|
||||
|
||||
if (mEventListener) {
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
|
||||
if (target) {
|
||||
target->RemoveSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
mEventListener, true);
|
||||
}
|
||||
|
||||
mEventListener = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsScreen::~nsScreen()
|
||||
{
|
||||
Reset();
|
||||
hal::UnregisterScreenConfigurationObserver(this);
|
||||
}
|
||||
|
||||
@ -318,6 +335,7 @@ NS_IMETHODIMP
|
||||
nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
|
||||
{
|
||||
ScreenOrientation orientation;
|
||||
*aReturn = false;
|
||||
|
||||
if (aOrientation.EqualsLiteral("portrait")) {
|
||||
orientation = eScreenOrientation_Portrait;
|
||||
@ -332,37 +350,31 @@ nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
|
||||
} else if (aOrientation.EqualsLiteral("landscape-secondary")) {
|
||||
orientation = eScreenOrientation_LandscapeSecondary;
|
||||
} else {
|
||||
*aReturn = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!GetOwner()) {
|
||||
*aReturn = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!IsChromeType(GetOwner()->GetDocShell())) {
|
||||
// Chrome code and apps can always lock the screen orientation.
|
||||
if (!IsChromeType(GetOwner()->GetDocShell()) &&
|
||||
!static_cast<nsGlobalWindow*>(GetOwner())->IsPartOfApp()) {
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
GetOwner()->GetDocument(getter_AddRefs(doc));
|
||||
if (!doc) {
|
||||
*aReturn = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Apps and frames contained in apps can lock orientation.
|
||||
// But non-apps can lock orientation only if they're fullscreen.
|
||||
if (!static_cast<nsGlobalWindow*>(GetOwner())->IsPartOfApp()) {
|
||||
bool fullscreen;
|
||||
doc->GetMozFullScreen(&fullscreen);
|
||||
if (!fullscreen) {
|
||||
*aReturn = false;
|
||||
return NS_OK;
|
||||
}
|
||||
// Non-apps content can lock orientation only if fullscreen.
|
||||
bool fullscreen;
|
||||
doc->GetMozFullScreen(&fullscreen);
|
||||
if (!fullscreen) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
|
||||
if (!target) {
|
||||
*aReturn = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ class nsScreen : public nsDOMEventTargetHelper
|
||||
public:
|
||||
static already_AddRefed<nsScreen> Create(nsPIDOMWindow* aWindow);
|
||||
|
||||
void Invalidate();
|
||||
void Reset();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMSCREEN
|
||||
|
@ -2118,7 +2118,8 @@ if (!%(resultStr)s) {
|
||||
"resultStr" : result + "_str",
|
||||
"strings" : type.inner.identifier.name + "Values::strings" } + setValue("JS::StringValue(%s_str)" % result)
|
||||
|
||||
if type.isCallback() and not type.isInterface():
|
||||
if type.isCallback():
|
||||
assert not type.isInterface()
|
||||
# XXXbz we're going to assume that callback types are always
|
||||
# nullable and always have [TreatNonCallableAsNull] for now.
|
||||
# See comments in WrapNewBindingObject explaining why we need
|
||||
@ -2622,8 +2623,7 @@ class CGMethodCall(CGThing):
|
||||
interfacesSigs = [
|
||||
s for s in possibleSignatures
|
||||
if (s[1][distinguishingIndex].type.isObject() or
|
||||
(s[1][distinguishingIndex].type.isInterface() and
|
||||
not s[1][distinguishingIndex].type.isCallback())) ]
|
||||
s[1][distinguishingIndex].type.isNonCallbackInterface()) ]
|
||||
# There might be more than one of these; we need to check
|
||||
# which ones we unwrap to.
|
||||
|
||||
@ -2692,6 +2692,7 @@ class CGMethodCall(CGThing):
|
||||
pickFirstSignature("%s.isObject() && !IsPlatformObject(cx, &%s.toObject())" %
|
||||
(distinguishingArg, distinguishingArg),
|
||||
lambda s: (s[1][distinguishingIndex].type.isCallback() or
|
||||
s[1][distinguishingIndex].type.isCallbackInterface() or
|
||||
s[1][distinguishingIndex].type.isDictionary() or
|
||||
s[1][distinguishingIndex].type.isObject()))
|
||||
|
||||
|
@ -426,6 +426,13 @@ class IDLInterface(IDLObjectWithScope):
|
||||
for iface in self.implementedInterfaces:
|
||||
iface.finish(scope)
|
||||
|
||||
cycleInGraph = self.findInterfaceLoopPoint(self)
|
||||
if cycleInGraph:
|
||||
raise WebIDLError("Interface %s has itself as ancestor or "
|
||||
"implemented interface" % self.identifier.name,
|
||||
self.location,
|
||||
extraLocation=cycleInGraph.location)
|
||||
|
||||
# Now resolve() and finish() our members before importing the
|
||||
# ones from our implemented interfaces.
|
||||
|
||||
@ -594,6 +601,26 @@ class IDLInterface(IDLObjectWithScope):
|
||||
|
||||
return consequentialInterfaces | temp
|
||||
|
||||
def findInterfaceLoopPoint(self, otherInterface):
|
||||
"""
|
||||
Finds an interface, amongst our ancestors and consequential interfaces,
|
||||
that inherits from otherInterface or implements otherInterface
|
||||
directly. If there is no such interface, returns None.
|
||||
"""
|
||||
if self.parent:
|
||||
if self.parent == otherInterface:
|
||||
return self
|
||||
loopPoint = self.parent.findInterfaceLoopPoint(otherInterface)
|
||||
if loopPoint:
|
||||
return loopPoint
|
||||
if otherInterface in self.implementedInterfaces:
|
||||
return self
|
||||
for iface in self.implementedInterfaces:
|
||||
loopPoint = iface.findInterfaceLoopPoint(otherInterface)
|
||||
if loopPoint:
|
||||
return loopPoint
|
||||
return None
|
||||
|
||||
class IDLDictionary(IDLObjectWithScope):
|
||||
def __init__(self, location, parentScope, name, parent, members):
|
||||
assert isinstance(parentScope, IDLScope)
|
||||
@ -761,6 +788,12 @@ class IDLType(IDLObject):
|
||||
def isTypedArray(self):
|
||||
return False
|
||||
|
||||
def isCallbackInterface(self):
|
||||
return False
|
||||
|
||||
def isNonCallbackInterface(self):
|
||||
return False
|
||||
|
||||
def isGeckoInterface(self):
|
||||
""" Returns a boolean indicating whether this type is an 'interface'
|
||||
type that is implemented in Gecko. At the moment, this returns
|
||||
@ -908,6 +941,12 @@ class IDLNullableType(IDLType):
|
||||
def isInterface(self):
|
||||
return self.inner.isInterface()
|
||||
|
||||
def isCallbackInterface(self):
|
||||
return self.inner.isCallbackInterface()
|
||||
|
||||
def isNonCallbackInterface(self):
|
||||
return self.inner.isNonCallbackInterface()
|
||||
|
||||
def isEnum(self):
|
||||
return self.inner.isEnum()
|
||||
|
||||
@ -998,7 +1037,7 @@ class IDLSequenceType(IDLType):
|
||||
def isDistinguishableFrom(self, other):
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isDictionary() or other.isDate() or
|
||||
(other.isInterface() and not other.isCallback()))
|
||||
other.isNonCallbackInterface())
|
||||
|
||||
class IDLArrayType(IDLType):
|
||||
def __init__(self, location, parameterType):
|
||||
@ -1071,7 +1110,7 @@ class IDLArrayType(IDLType):
|
||||
def isDistinguishableFrom(self, other):
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
other.isDictionary() or other.isDate() or
|
||||
(other.isInterface() and not other.isCallback()))
|
||||
other.isNonCallbackInterface())
|
||||
|
||||
class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
||||
def __init__(self, location, innerType, name):
|
||||
@ -1124,6 +1163,12 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
|
||||
def isInterface(self):
|
||||
return self.inner.isInterface()
|
||||
|
||||
def isCallbackInterface(self):
|
||||
return self.inner.isCallbackInterface()
|
||||
|
||||
def isNonCallbackInterface(self):
|
||||
return self.inner.isNonCallbackInterface()
|
||||
|
||||
def resolve(self, parentScope):
|
||||
assert isinstance(parentScope, IDLScope)
|
||||
IDLObjectWithIdentifier.resolve(self, parentScope)
|
||||
@ -1177,6 +1222,12 @@ class IDLWrapperType(IDLType):
|
||||
return isinstance(self.inner, IDLInterface) or \
|
||||
isinstance(self.inner, IDLExternalInterface)
|
||||
|
||||
def isCallbackInterface(self):
|
||||
return self.isInterface() and self.inner.isCallback()
|
||||
|
||||
def isNonCallbackInterface(self):
|
||||
return self.isInterface() and not self.inner.isCallback()
|
||||
|
||||
def isEnum(self):
|
||||
return isinstance(self.inner, IDLEnum)
|
||||
|
||||
@ -1198,7 +1249,7 @@ class IDLWrapperType(IDLType):
|
||||
assert False
|
||||
|
||||
def isDistinguishableFrom(self, other):
|
||||
assert self.isInterface() or self.isEnum()
|
||||
assert self.isInterface() or self.isEnum() or self.isDictionary()
|
||||
if self.isEnum():
|
||||
return (other.isInterface() or other.isObject() or
|
||||
other.isCallback() or other.isDictionary() or
|
||||
@ -1206,15 +1257,20 @@ class IDLWrapperType(IDLType):
|
||||
other.isDate())
|
||||
if other.isPrimitive() or other.isString() or other.isEnum():
|
||||
return True
|
||||
if self.isDictionary():
|
||||
return (other.isNonCallbackInterface() or other.isSequence() or
|
||||
other.isArray() or other.isDate())
|
||||
|
||||
assert self.isInterface()
|
||||
# XXXbz need to check that the interfaces can't be implemented
|
||||
# by the same object
|
||||
if other.isInterface():
|
||||
return (self != other and
|
||||
(not self.isCallback() or not other.isCallback()))
|
||||
if other.isDictionary() or other.isCallback():
|
||||
return not self.isCallback()
|
||||
if other.isSequence() or other.isArray():
|
||||
return not self.isCallback()
|
||||
(self.isNonCallbackInterface() or
|
||||
other.isNonCallbackInterface()))
|
||||
if (other.isDictionary() or other.isCallback() or
|
||||
other.isSequence() or other.isArray()):
|
||||
return self.isNonCallbackInterface()
|
||||
|
||||
class IDLBuiltinType(IDLType):
|
||||
|
||||
@ -1314,6 +1370,10 @@ class IDLBuiltinType(IDLType):
|
||||
self.isArrayBufferView() or \
|
||||
self.isTypedArray()
|
||||
|
||||
def isNonCallbackInterface(self):
|
||||
# All the interfaces we can be are non-callback
|
||||
return self.isInterface()
|
||||
|
||||
def isFloat(self):
|
||||
return self._typeTag == IDLBuiltinType.Types.float or \
|
||||
self._typeTag == IDLBuiltinType.Types.double
|
||||
@ -1347,7 +1407,7 @@ class IDLBuiltinType(IDLType):
|
||||
other.isSequence() or other.isArray() or other.isDate() or
|
||||
(other.isInterface() and (
|
||||
# ArrayBuffer is distinguishable from everything
|
||||
# that's not an ArrayBuffer
|
||||
# that's not an ArrayBuffer or a callback interface
|
||||
(self.isArrayBuffer() and not other.isArrayBuffer()) or
|
||||
# ArrayBufferView is distinguishable from everything
|
||||
# that's not an ArrayBufferView or typed array.
|
||||
@ -1681,8 +1741,7 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
|
||||
|
||||
def isDistinguishableFrom(self, other):
|
||||
return (other.isPrimitive() or other.isString() or other.isEnum() or
|
||||
(other.isInterface() and not other.isCallback()) or
|
||||
other.isDate())
|
||||
other.isNonCallbackInterface() or other.isDate())
|
||||
|
||||
class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
dictionary Dict2 : Dict1 {
|
||||
@ -29,7 +27,7 @@ def WebIDLTest(parser, harness):
|
||||
"'a' really comes before 'c'")
|
||||
|
||||
# Now reset our parser
|
||||
parser = WebIDL.Parser()
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
@ -45,7 +43,7 @@ def WebIDLTest(parser, harness):
|
||||
harness.ok(threw, "Should not allow name duplication in a dictionary")
|
||||
|
||||
# Now reset our parser again
|
||||
parser = WebIDL.Parser()
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
@ -67,7 +65,7 @@ def WebIDLTest(parser, harness):
|
||||
"its ancestor")
|
||||
|
||||
# More reset
|
||||
parser = WebIDL.Parser()
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
@ -83,7 +81,7 @@ def WebIDLTest(parser, harness):
|
||||
harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
|
||||
|
||||
# Even more reset
|
||||
parser = WebIDL.Parser()
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
|
33
dom/bindings/parser/tests/test_distinguishability.py
Normal file
33
dom/bindings/parser/tests/test_distinguishability.py
Normal file
@ -0,0 +1,33 @@
|
||||
def WebIDLTest(parser, harness):
|
||||
parser.parse("""
|
||||
dictionary Dict {
|
||||
};
|
||||
callback interface Foo {
|
||||
};
|
||||
interface Bar {
|
||||
// Bit of a pain to get things that have dictionary types
|
||||
void passDict(Dict arg);
|
||||
void passFoo(Foo arg);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
|
||||
iface = results[2]
|
||||
harness.ok(iface.isInterface(), "Should have interface")
|
||||
dictMethod = iface.members[0]
|
||||
ifaceMethod = iface.members[1]
|
||||
|
||||
def firstArgType(method):
|
||||
return method.signatures()[0][1][0].type
|
||||
|
||||
dictType = firstArgType(dictMethod)
|
||||
ifaceType = firstArgType(ifaceMethod)
|
||||
|
||||
harness.ok(dictType.isDictionary(), "Should have dictionary type");
|
||||
harness.ok(ifaceType.isInterface(), "Should have interface type");
|
||||
harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type");
|
||||
|
||||
harness.ok(not dictType.isDistinguishableFrom(ifaceType),
|
||||
"Dictionary not distinguishable from callback interface")
|
||||
harness.ok(not ifaceType.isDistinguishableFrom(dictType),
|
||||
"Callback interface not distinguishable from dictionary")
|
@ -52,3 +52,124 @@ def WebIDLTest(parser, harness):
|
||||
"Member has the right QName")
|
||||
harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar",
|
||||
"Member has the right QName")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A : B {};
|
||||
interface B : A {};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow cycles in interface inheritance chains")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A : C {};
|
||||
interface C : B {};
|
||||
interface B : A {};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow indirect cycles in interface inheritance chains")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {};
|
||||
interface B {};
|
||||
A implements B;
|
||||
B implements A;
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow cycles via implements")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {};
|
||||
interface C {};
|
||||
interface B {};
|
||||
A implements C;
|
||||
C implements B;
|
||||
B implements A;
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow indirect cycles via implements")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A : B {};
|
||||
interface B {};
|
||||
B implements A;
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow inheriting from an interface that implements us")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A : B {};
|
||||
interface B {};
|
||||
interface C {};
|
||||
B implements C;
|
||||
C implements A;
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow inheriting from an interface that indirectly implements us")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A : B {};
|
||||
interface B : C {};
|
||||
interface C {};
|
||||
C implements A;
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow indirectly inheriting from an interface that implements us")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A : B {};
|
||||
interface B : C {};
|
||||
interface C {};
|
||||
interface D {};
|
||||
C implements D;
|
||||
D implements A;
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should not allow indirectly inheriting from an interface that indirectly implements us")
|
||||
|
@ -297,6 +297,7 @@ DiamondBranch1A implements DiamondImplements;
|
||||
DiamondBranch1B implements DiamondImplements;
|
||||
|
||||
dictionary Dict : ParentDict {
|
||||
TestEnum someEnum;
|
||||
long x;
|
||||
long a;
|
||||
long b = 8;
|
||||
|
@ -111,6 +111,10 @@ BrowserElementChild.prototype = {
|
||||
|
||||
addMsgListener("get-screenshot", this._recvGetScreenshot);
|
||||
addMsgListener("set-visible", this._recvSetVisible);
|
||||
addMsgListener("get-can-go-back", this._recvCanGoBack);
|
||||
addMsgListener("get-can-go-forward", this._recvCanGoForward);
|
||||
addMsgListener("go-back", this._recvGoBack);
|
||||
addMsgListener("go-forward", this._recvGoForward);
|
||||
addMsgListener("unblock-modal-prompt", this._recvStopWaiting);
|
||||
|
||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
@ -320,7 +324,7 @@ BrowserElementChild.prototype = {
|
||||
content.innerHeight, "rgb(255,255,255)");
|
||||
sendAsyncMsg('got-screenshot', {
|
||||
id: data.json.id,
|
||||
screenshot: canvas.toDataURL("image/png")
|
||||
rv: canvas.toDataURL("image/png")
|
||||
});
|
||||
},
|
||||
|
||||
@ -331,6 +335,38 @@ BrowserElementChild.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_recvCanGoBack: function(data) {
|
||||
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||
sendAsyncMsg('got-can-go-back', {
|
||||
id: data.json.id,
|
||||
rv: webNav.canGoBack
|
||||
});
|
||||
},
|
||||
|
||||
_recvCanGoForward: function(data) {
|
||||
var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||
sendAsyncMsg('got-can-go-forward', {
|
||||
id: data.json.id,
|
||||
rv: webNav.canGoForward
|
||||
});
|
||||
},
|
||||
|
||||
_recvGoBack: function(data) {
|
||||
try {
|
||||
docShell.QueryInterface(Ci.nsIWebNavigation).goBack();
|
||||
} catch(e) {
|
||||
// Silently swallow errors; these happen when we can't go back.
|
||||
}
|
||||
},
|
||||
|
||||
_recvGoForward: function(data) {
|
||||
try {
|
||||
docShell.QueryInterface(Ci.nsIWebNavigation).goForward();
|
||||
} catch(e) {
|
||||
// Silently swallow errors; these happen when we can't go forward.
|
||||
}
|
||||
},
|
||||
|
||||
_keyEventHandler: function(e) {
|
||||
if (whitelistedEvents.indexOf(e.keyCode) != -1 && !e.defaultPrevented) {
|
||||
sendAsyncMsg('keyevent', {
|
||||
|
@ -120,8 +120,8 @@ BrowserElementParentFactory.prototype = {
|
||||
|
||||
function BrowserElementParent(frameLoader) {
|
||||
debug("Creating new BrowserElementParent object for " + frameLoader);
|
||||
this._screenshotListeners = {};
|
||||
this._screenshotReqCounter = 0;
|
||||
this._domRequestCounter = 0;
|
||||
this._pendingDOMRequests = {};
|
||||
|
||||
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||
if (!this._frameElement) {
|
||||
@ -150,18 +150,25 @@ function BrowserElementParent(frameLoader) {
|
||||
addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
|
||||
addMessageListener("keyevent", this._fireKeyEvent);
|
||||
addMessageListener("showmodalprompt", this._handleShowModalPrompt);
|
||||
addMessageListener('got-screenshot', this._recvGotScreenshot);
|
||||
addMessageListener('got-screenshot', this._gotDOMRequestResult);
|
||||
addMessageListener('got-can-go-back', this._gotDOMRequestResult);
|
||||
addMessageListener('got-can-go-forward', this._gotDOMRequestResult);
|
||||
|
||||
function defineMethod(name, fn) {
|
||||
XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self);
|
||||
}
|
||||
|
||||
// Define methods on the frame element.
|
||||
defineMethod('getScreenshot', this._getScreenshot);
|
||||
defineMethod('setVisible', this._setVisible);
|
||||
function defineDOMRequestMethod(domName, msgName) {
|
||||
XPCNativeWrapper.unwrap(self._frameElement)[domName] = self._sendDOMRequest.bind(self, msgName);
|
||||
}
|
||||
|
||||
this._mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
|
||||
/* allowDelayedLoad = */ true);
|
||||
// Define methods on the frame element.
|
||||
defineMethod('setVisible', this._setVisible);
|
||||
defineMethod('goBack', this._goBack);
|
||||
defineMethod('goForward', this._goForward);
|
||||
defineDOMRequestMethod('getScreenshot', 'get-screenshot');
|
||||
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
|
||||
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
|
||||
}
|
||||
|
||||
BrowserElementParent.prototype = {
|
||||
@ -265,25 +272,49 @@ BrowserElementParent.prototype = {
|
||||
return this._frameElement.getAttribute('mozapp');
|
||||
},
|
||||
|
||||
|
||||
_getScreenshot: function() {
|
||||
let id = 'req_' + this._screenshotReqCounter++;
|
||||
/**
|
||||
* Kick off a DOMRequest in the child process.
|
||||
*
|
||||
* We'll fire an event called |msgName| on the child process, passing along
|
||||
* an object with a single field, id, containing the ID of this request.
|
||||
*
|
||||
* We expect the child to pass the ID back to us upon completion of the
|
||||
* request; see _gotDOMRequestResult.
|
||||
*/
|
||||
_sendDOMRequest: function(msgName) {
|
||||
let id = 'req_' + this._domRequestCounter++;
|
||||
let req = Services.DOMRequest.createRequest(this._window);
|
||||
this._screenshotListeners[id] = req;
|
||||
this._sendAsyncMsg('get-screenshot', {id: id});
|
||||
this._pendingDOMRequests[id] = req;
|
||||
this._sendAsyncMsg(msgName, {id: id});
|
||||
return req;
|
||||
},
|
||||
|
||||
_recvGotScreenshot: function(data) {
|
||||
var req = this._screenshotListeners[data.json.id];
|
||||
delete this._screenshotListeners[data.json.id];
|
||||
Services.DOMRequest.fireSuccess(req, data.json.screenshot);
|
||||
/**
|
||||
* Called when the child process finishes handling a DOMRequest. We expect
|
||||
* data.json to have two fields:
|
||||
*
|
||||
* - id: the ID of the DOM request (see _sendDOMRequest), and
|
||||
* - rv: the request's return value.
|
||||
*
|
||||
*/
|
||||
_gotDOMRequestResult: function(data) {
|
||||
let req = this._pendingDOMRequests[data.json.id];
|
||||
delete this._pendingDOMRequests[data.json.id];
|
||||
Services.DOMRequest.fireSuccess(req, data.json.rv);
|
||||
},
|
||||
|
||||
_setVisible: function(visible) {
|
||||
this._sendAsyncMsg('set-visible', {visible: visible});
|
||||
},
|
||||
|
||||
_goBack: function() {
|
||||
this._sendAsyncMsg('go-back');
|
||||
},
|
||||
|
||||
_goForward: function() {
|
||||
this._sendAsyncMsg('go-forward');
|
||||
},
|
||||
|
||||
_fireKeyEvent: function(data) {
|
||||
let evt = this._window.document.createEvent("KeyboardEvent");
|
||||
evt.initKeyEvent(data.json.type, true, true, this._window,
|
||||
|
@ -58,9 +58,12 @@ _TEST_FILES = \
|
||||
browserElement_SecurityChange.js \
|
||||
test_browserElement_inproc_SecurityChange.html \
|
||||
file_browserElement_SecurityChange.html \
|
||||
browserElement_BackForward.js \
|
||||
$(NULL)
|
||||
|
||||
# OOP tests don't work on Windows (bug 763081).
|
||||
#
|
||||
# Note that there's no inproc equivalent of BackForward; that's intentional.
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
_TEST_FILES += \
|
||||
test_browserElement_oop_LoadEvents.html \
|
||||
@ -78,6 +81,7 @@ _TEST_FILES += \
|
||||
test_browserElement_oop_OpenWindow.html \
|
||||
test_browserElement_oop_OpenWindowRejected.html \
|
||||
test_browserElement_oop_SecurityChange.html \
|
||||
test_browserElement_oop_BackForward.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
@ -101,13 +101,16 @@ const browserElementTestHelpers = {
|
||||
'origOOPByDefaultPref': null,
|
||||
'origPageThumbsEnabledPref': null,
|
||||
|
||||
// Two basically-empty pages from two different domains you can load.
|
||||
// Some basically-empty pages from different domains you can load.
|
||||
'emptyPage1': 'http://example.com' +
|
||||
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
|
||||
'/file_empty.html',
|
||||
'emptyPage2': 'http://example.org' +
|
||||
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
|
||||
'/file_empty.html',
|
||||
'emptyPage3': 'http://test1.example.org' +
|
||||
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
|
||||
'/file_empty.html',
|
||||
'focusPage': 'http://example.org' +
|
||||
window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
|
||||
'/file_focus.html',
|
||||
|
112
dom/browser-element/mochitest/browserElement_BackForward.js
Normal file
112
dom/browser-element/mochitest/browserElement_BackForward.js
Normal file
@ -0,0 +1,112 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 741755 - Test that canGo{Back,Forward} and go{Forward,Back} work with
|
||||
// <iframe mozbrowser>.
|
||||
|
||||
"use strict";
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var iframe;
|
||||
function addOneShotIframeEventListener(event, fn) {
|
||||
function wrapper(e) {
|
||||
iframe.removeEventListener(event, wrapper);
|
||||
fn(e);
|
||||
};
|
||||
|
||||
iframe.addEventListener(event, wrapper);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// At the moment, this isn't going to work unless we're actually out of
|
||||
// process.
|
||||
//
|
||||
// With in-process mozbrowser, the root SHistory for an <iframe mozbrowser>
|
||||
// crosses the mozbrowser boundary. It's like the mozbrowser wasn't there;
|
||||
// canGoBack reflects whether the top-level frame can go back, not whether the
|
||||
// iframe itself can go back.
|
||||
if (!browserElementTestHelpers.getOOPByDefaultPref()) {
|
||||
ok(false, "This test only works OOP.");
|
||||
return;
|
||||
}
|
||||
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addToWhitelist();
|
||||
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
|
||||
addOneShotIframeEventListener('mozbrowserloadend', function() {
|
||||
SimpleTest.executeSoon(test2);
|
||||
});
|
||||
|
||||
iframe.src = browserElementTestHelpers.emptyPage1;
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
function checkCanGoBackAndForward(canGoBack, canGoForward, nextTest) {
|
||||
var seenCanGoBackResult = false;
|
||||
iframe.getCanGoBack().onsuccess = function(e) {
|
||||
is(seenCanGoBackResult, false, "onsuccess handler shouldn't be called twice.");
|
||||
seenCanGoBackResult = true;
|
||||
is(e.target.result, canGoBack);
|
||||
maybeRunNextTest();
|
||||
};
|
||||
|
||||
var seenCanGoForwardResult = false;
|
||||
iframe.getCanGoForward().onsuccess = function(e) {
|
||||
is(seenCanGoForwardResult, false, "onsuccess handler shouldn't be called twice.");
|
||||
seenCanGoForwardResult = true;
|
||||
is(e.target.result, canGoForward);
|
||||
maybeRunNextTest();
|
||||
};
|
||||
|
||||
function maybeRunNextTest() {
|
||||
if (seenCanGoBackResult && seenCanGoForwardResult) {
|
||||
nextTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function test2() {
|
||||
checkCanGoBackAndForward(false, false, test3);
|
||||
}
|
||||
|
||||
function test3() {
|
||||
addOneShotIframeEventListener('mozbrowserloadend', function() {
|
||||
checkCanGoBackAndForward(true, false, test4);
|
||||
});
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
iframe.src = browserElementTestHelpers.emptyPage2;
|
||||
});
|
||||
}
|
||||
|
||||
function test4() {
|
||||
addOneShotIframeEventListener('mozbrowserlocationchange', function(e) {
|
||||
is(e.detail, browserElementTestHelpers.emptyPage3);
|
||||
checkCanGoBackAndForward(true, false, test5);
|
||||
});
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
iframe.src = browserElementTestHelpers.emptyPage3;
|
||||
});
|
||||
}
|
||||
|
||||
function test5() {
|
||||
addOneShotIframeEventListener('mozbrowserlocationchange', function(e) {
|
||||
is(e.detail, browserElementTestHelpers.emptyPage2);
|
||||
checkCanGoBackAndForward(true, true, test6);
|
||||
});
|
||||
iframe.goBack();
|
||||
}
|
||||
|
||||
function test6() {
|
||||
addOneShotIframeEventListener('mozbrowserlocationchange', function(e) {
|
||||
is(e.detail, browserElementTestHelpers.emptyPage1);
|
||||
checkCanGoBackAndForward(false, true, SimpleTest.finish);
|
||||
});
|
||||
iframe.goBack();
|
||||
}
|
||||
|
||||
runTest();
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test of browser element.</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_BackForward.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -214,8 +214,10 @@ IndexedDatabaseManager::GetOrCreate()
|
||||
|
||||
if (sIsMainProcess) {
|
||||
nsCOMPtr<nsIFile> dbBaseDirectory;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbBaseDirectory));
|
||||
rv = NS_GetSpecialDirectory(NS_APP_INDEXEDDB_PARENT_DIR, getter_AddRefs(dbBaseDirectory));
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(dbBaseDirectory));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
rv = dbBaseDirectory->Append(NS_LITERAL_STRING("indexedDB"));
|
||||
|
@ -9,15 +9,34 @@
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIArray;
|
||||
|
||||
[scriptable, uuid(b70b84f1-7ac9-4a92-bc32-8b6a7eb7879e)]
|
||||
[scriptable, uuid(9583b825-46b1-4e8f-bb48-9fed660a95e6)]
|
||||
interface mozIDOMApplication : nsISupports
|
||||
{
|
||||
readonly attribute jsval manifest;
|
||||
readonly attribute DOMString manifestURL;
|
||||
readonly attribute nsIArray receipts; /* an array of strings */
|
||||
readonly attribute jsval receipts; /* an array of strings */
|
||||
readonly attribute DOMString origin;
|
||||
readonly attribute DOMString installOrigin;
|
||||
readonly attribute unsigned long installTime;
|
||||
readonly attribute unsigned long long installTime;
|
||||
|
||||
/*
|
||||
* The current progress when downloading an offline cache.
|
||||
*/
|
||||
readonly attribute double progress;
|
||||
|
||||
/*
|
||||
* The application status :
|
||||
* "installed" : The app is in the registry, but we have no offline cache.
|
||||
* "downlading" : We are downloading the offline cache.
|
||||
* "cached" : We are done with the offline cache download.
|
||||
* "cache-error" : An error occured while downloading the offline-cache.
|
||||
*/
|
||||
readonly attribute DOMString status;
|
||||
|
||||
/*
|
||||
* fires a nsIDOMApplicationEvent when a change in appcache download or status happens
|
||||
*/
|
||||
attribute nsIDOMEventListener onprogress;
|
||||
|
||||
/* startPoint will be used when several launch_path exists for an app */
|
||||
nsIDOMDOMRequest launch([optional] in DOMString startPoint);
|
||||
|
@ -26,6 +26,7 @@ interface nsIDOMCSSRule : nsISupports
|
||||
const unsigned short PAGE_RULE = 6;
|
||||
const unsigned short MOZ_KEYFRAMES_RULE = 7;
|
||||
const unsigned short MOZ_KEYFRAME_RULE = 8;
|
||||
const unsigned short NAMESPACE_RULE = 10;
|
||||
|
||||
readonly attribute unsigned short type;
|
||||
attribute DOMString cssText;
|
||||
|
@ -382,9 +382,9 @@ ContentChild::DeallocPMemoryReportRequest(PMemoryReportRequestChild* actor)
|
||||
}
|
||||
|
||||
PBrowserChild*
|
||||
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags)
|
||||
ContentChild::AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame)
|
||||
{
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags);
|
||||
nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserFrame);
|
||||
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget().get() : NULL;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,8 @@ public:
|
||||
/* if you remove this, please talk to cjones or dougt */
|
||||
virtual bool RecvDummy(Shmem& foo) { return true; }
|
||||
|
||||
virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags);
|
||||
virtual PBrowserChild* AllocPBrowser(const PRUint32& aChromeFlags,
|
||||
const bool& aIsBrowserFrame);
|
||||
virtual bool DeallocPBrowser(PBrowserChild*);
|
||||
|
||||
virtual PCrashReporterChild*
|
||||
|
@ -356,9 +356,9 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
}
|
||||
|
||||
TabParent*
|
||||
ContentParent::CreateTab(PRUint32 aChromeFlags)
|
||||
ContentParent::CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame)
|
||||
{
|
||||
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags));
|
||||
return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags, aIsBrowserFrame));
|
||||
}
|
||||
|
||||
TestShellParent*
|
||||
@ -698,7 +698,7 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
}
|
||||
|
||||
PBrowserParent*
|
||||
ContentParent::AllocPBrowser(const PRUint32& aChromeFlags)
|
||||
ContentParent::AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame)
|
||||
{
|
||||
TabParent* parent = new TabParent();
|
||||
if (parent){
|
||||
|
@ -51,7 +51,13 @@ public:
|
||||
NS_DECL_NSITHREADOBSERVER
|
||||
NS_DECL_NSIDOMGEOPOSITIONCALLBACK
|
||||
|
||||
TabParent* CreateTab(PRUint32 aChromeFlags);
|
||||
/**
|
||||
* Create a new tab.
|
||||
*
|
||||
* |aIsBrowserFrame| indicates whether this tab is part of an
|
||||
* <iframe mozbrowser>.
|
||||
*/
|
||||
TabParent* CreateTab(PRUint32 aChromeFlags, bool aIsBrowserFrame);
|
||||
|
||||
TestShellParent* CreateTestShell();
|
||||
bool DestroyTestShell(TestShellParent* aTestShell);
|
||||
@ -90,7 +96,7 @@ private:
|
||||
|
||||
void Init();
|
||||
|
||||
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags);
|
||||
virtual PBrowserParent* AllocPBrowser(const PRUint32& aChromeFlags, const bool& aIsBrowserFrame);
|
||||
virtual bool DeallocPBrowser(PBrowserParent* frame);
|
||||
|
||||
virtual PCrashReporterParent* AllocPCrashReporter(const NativeThreadId& tid,
|
||||
|
@ -84,7 +84,7 @@ both:
|
||||
// The child creates the PBrowser as part of
|
||||
// TabChild::BrowserFrameProvideWindow, and the parent creates the PBrowser
|
||||
// as part of ContentParent::CreateTab.
|
||||
async PBrowser(PRUint32 chromeFlags);
|
||||
async PBrowser(PRUint32 chromeFlags, bool isBrowserFrame);
|
||||
|
||||
child:
|
||||
PMemoryReportRequest();
|
||||
|
@ -87,13 +87,14 @@ public:
|
||||
};
|
||||
|
||||
|
||||
TabChild::TabChild(PRUint32 aChromeFlags)
|
||||
TabChild::TabChild(PRUint32 aChromeFlags, bool aIsBrowserFrame)
|
||||
: mRemoteFrame(nsnull)
|
||||
, mTabChildGlobal(nsnull)
|
||||
, mChromeFlags(aChromeFlags)
|
||||
, mOuterRect(0, 0, 0, 0)
|
||||
, mLastBackgroundColor(NS_RGB(255, 255, 255))
|
||||
, mDidFakeShow(false)
|
||||
, mIsBrowserFrame(aIsBrowserFrame)
|
||||
{
|
||||
printf("creating %d!\n", NS_IsMainThread());
|
||||
}
|
||||
@ -377,7 +378,9 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
*aReturn = nsnull;
|
||||
|
||||
nsRefPtr<TabChild> newChild =
|
||||
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(0));
|
||||
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(
|
||||
/* aChromeFlags = */ 0,
|
||||
/* aIsBrowserFrame = */ true));
|
||||
|
||||
nsCAutoString spec;
|
||||
aURI->GetSpec(spec);
|
||||
@ -948,6 +951,13 @@ TabChild::InitTabChildGlobal()
|
||||
nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
|
||||
NS_ENSURE_TRUE(root, false);
|
||||
root->SetParentTarget(scope);
|
||||
|
||||
// Initialize the child side of the browser element machinery, if appropriate.
|
||||
if (mIsBrowserFrame) {
|
||||
RecvLoadRemoteScript(
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,13 @@ class TabChild : public PBrowserChild,
|
||||
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
|
||||
|
||||
public:
|
||||
TabChild(PRUint32 aChromeFlags);
|
||||
/**
|
||||
* Create a new TabChild object.
|
||||
*
|
||||
* |aIsBrowserFrame| indicates whether the TabChild is inside an
|
||||
* <iframe mozbrowser>.
|
||||
*/
|
||||
TabChild(PRUint32 aChromeFlags, bool aIsBrowserFrame);
|
||||
virtual ~TabChild();
|
||||
nsresult Init();
|
||||
|
||||
@ -266,6 +272,7 @@ private:
|
||||
nsIntRect mOuterRect;
|
||||
nscolor mLastBackgroundColor;
|
||||
bool mDidFakeShow;
|
||||
bool mIsBrowserFrame;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
@ -178,7 +178,7 @@ PluginModuleParent::TimeoutChanged(const char* aPref, void* aModule)
|
||||
void
|
||||
PluginModuleParent::CleanupFromTimeout()
|
||||
{
|
||||
if (!mShutdown)
|
||||
if (!mShutdown && OkToCleanup())
|
||||
Close();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,14 @@
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "BindingUtils.h"
|
||||
|
||||
// Used to provide information on the OS
|
||||
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include "OSFileConstants.h"
|
||||
|
||||
/**
|
||||
@ -320,6 +328,28 @@ bool DefineOSFileConstants(JSContext *cx, JSObject *global)
|
||||
return false;
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
JSObject *objSys;
|
||||
if (!(objSys = GetOrCreateObjectProperty(cx, objConstants, "Sys"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXULRuntime> runtime = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
|
||||
if (runtime) {
|
||||
nsCAutoString os;
|
||||
nsresult rv = runtime->GetOS(os);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
JSString* strVersion = JS_NewStringCopyZ(cx, os.get());
|
||||
if (!strVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jsval valVersion = STRING_TO_JSVAL(strVersion);
|
||||
if (!JS_SetProperty(cx, objSys, "Version", &valVersion)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,6 @@ const DEBUG = RIL.DEBUG_RIL;
|
||||
|
||||
const RADIOINTERFACELAYER_CID =
|
||||
Components.ID("{2d831c8d-6017-435b-a80c-e5d422810cea}");
|
||||
const DATACALLINFO_CID =
|
||||
Components.ID("{ef474cd9-94f7-4c05-a31b-29b9de8a10d2}");
|
||||
|
||||
const nsIAudioManager = Ci.nsIAudioManager;
|
||||
const nsIRadioInterfaceLayer = Ci.nsIRadioInterfaceLayer;
|
||||
@ -131,20 +129,6 @@ XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() {
|
||||
});
|
||||
|
||||
|
||||
function DataCallInfo(state, cid, apn) {
|
||||
this.callState = state;
|
||||
this.cid = cid;
|
||||
this.apn = apn;
|
||||
}
|
||||
DataCallInfo.protoptype = {
|
||||
classID: DATACALLINFO_CID,
|
||||
classInfo: XPCOMUtils.generateCI({classID: DATACALLINFO_CID,
|
||||
classDescription: "DataCallInfo",
|
||||
interfaces: [Ci.nsIDataCallInfo]}),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDataCallInfo]),
|
||||
};
|
||||
|
||||
|
||||
function RadioInterfaceLayer() {
|
||||
debug("Starting RIL Worker");
|
||||
this.worker = new ChromeWorker("resource://gre/modules/ril_worker.js");
|
||||
@ -485,8 +469,7 @@ RadioInterfaceLayer.prototype = {
|
||||
voiceInfo.type = null;
|
||||
voiceInfo.signalStrength = null;
|
||||
voiceInfo.relSignalStrength = null;
|
||||
ppmm.sendAsyncMessage("RIL:VoiceThis.RadioState.VoiceChanged",
|
||||
voiceInfo);
|
||||
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -532,6 +515,23 @@ RadioInterfaceLayer.prototype = {
|
||||
},
|
||||
|
||||
updateDataConnection: function updateDataConnection(state) {
|
||||
let data = this.rilContext.data;
|
||||
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
|
||||
data.connected = false;
|
||||
data.emergencyCallsOnly = false;
|
||||
data.roaming = false;
|
||||
data.network = null;
|
||||
data.type = null;
|
||||
data.signalStrength = null;
|
||||
data.relSignalStrength = null;
|
||||
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
|
||||
return;
|
||||
}
|
||||
data.roaming =
|
||||
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
|
||||
data.type = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
|
||||
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
|
||||
|
||||
if (!this._isDataEnabled()) {
|
||||
return false;
|
||||
}
|
||||
@ -548,9 +548,6 @@ RadioInterfaceLayer.prototype = {
|
||||
// RILNetworkInterface will ignore this if it's already connected.
|
||||
RILNetworkInterface.connect();
|
||||
}
|
||||
//TODO need to keep track of some of the state information, and then
|
||||
// notify the content when state changes (connected, technology
|
||||
// changes, etc.). This should be done in RILNetworkInterface.
|
||||
return false;
|
||||
},
|
||||
|
||||
@ -876,22 +873,23 @@ RadioInterfaceLayer.prototype = {
|
||||
* Handle data call state changes.
|
||||
*/
|
||||
handleDataCallState: function handleDataCallState(datacall) {
|
||||
let data = this.rilContext.data;
|
||||
|
||||
if (datacall.ifname) {
|
||||
data.connected = (datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED);
|
||||
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
|
||||
}
|
||||
|
||||
this._deliverDataCallCallback("dataCallStateChanged",
|
||||
[datacall.cid, datacall.ifname, datacall.state]);
|
||||
[datacall]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle data call list.
|
||||
*/
|
||||
handleDataCallList: function handleDataCallList(message) {
|
||||
let datacalls = [];
|
||||
for each (let datacall in message.datacalls) {
|
||||
datacalls.push(new DataCallInfo(datacall.state,
|
||||
datacall.cid,
|
||||
datacall.apn));
|
||||
}
|
||||
this._deliverDataCallCallback("receiveDataCallList",
|
||||
[datacalls, datacalls.length]);
|
||||
[message.datacalls, message.datacalls.length]);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1695,14 +1693,14 @@ let RILNetworkInterface = {
|
||||
|
||||
// nsIRILDataCallback
|
||||
|
||||
dataCallStateChanged: function dataCallStateChanged(cid, interfaceName, callState) {
|
||||
debug("Data call ID: " + cid + ", interface name: " + interfaceName);
|
||||
dataCallStateChanged: function dataCallStateChanged(datacall) {
|
||||
debug("Data call ID: " + datacall.cid + ", interface name: " + datacall.ifname);
|
||||
if (this.connecting &&
|
||||
(callState == RIL.GECKO_NETWORK_STATE_CONNECTING ||
|
||||
callState == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
|
||||
(datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTING ||
|
||||
datacall.state == RIL.GECKO_NETWORK_STATE_CONNECTED)) {
|
||||
this.connecting = false;
|
||||
this.cid = cid;
|
||||
this.name = interfaceName;
|
||||
this.cid = datacall.cid;
|
||||
this.name = datacall.ifname;
|
||||
if (!this.registeredAsNetworkInterface) {
|
||||
let networkManager = Cc["@mozilla.org/network/manager;1"]
|
||||
.getService(Ci.nsINetworkManager);
|
||||
@ -1710,14 +1708,14 @@ let RILNetworkInterface = {
|
||||
this.registeredAsNetworkInterface = true;
|
||||
}
|
||||
}
|
||||
if (this.cid != cid) {
|
||||
if (this.cid != datacall.cid) {
|
||||
return;
|
||||
}
|
||||
if (this.state == callState) {
|
||||
if (this.state == datacall.state) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.state = callState;
|
||||
this.state = datacall.state;
|
||||
Services.obs.notifyObservers(this,
|
||||
kNetworkInterfaceStateChangedTopic,
|
||||
null);
|
||||
|
@ -62,30 +62,25 @@ interface nsIRILTelephonyCallback : nsISupports
|
||||
in AString error);
|
||||
};
|
||||
|
||||
[scriptable, uuid(66a55943-e63b-4731-aece-9c04bfc14019)]
|
||||
[scriptable, uuid(8a711703-1ee5-4675-9d9a-0b188e944cfe)]
|
||||
interface nsIRILDataCallInfo : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long callState;
|
||||
readonly attribute unsigned long state;
|
||||
readonly attribute AString cid;
|
||||
readonly attribute AString apn;
|
||||
readonly attribute AString ifname;
|
||||
};
|
||||
|
||||
[scriptable, uuid(cea91bcb-3cfb-42bb-8638-dae89e8870fc)]
|
||||
[scriptable, uuid(5bcac053-c245-46f0-bb45-d0039bfb89f5)]
|
||||
interface nsIRILDataCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Notified when a data call changes state.
|
||||
*
|
||||
* @param cid
|
||||
* The CID of the data call.
|
||||
* @param interfaceName
|
||||
* Name of the associated network interface.
|
||||
* @param dataState
|
||||
* One of the nsIRadioInterfaceLayer::DATACALL_STATE_* values.
|
||||
* @param dataCall
|
||||
* A nsIRILDataCallInfo object.
|
||||
*/
|
||||
void dataCallStateChanged(in AString cid,
|
||||
in AString interfaceName,
|
||||
in unsigned short callState);
|
||||
void dataCallStateChanged(in nsIRILDataCallInfo dataCall);
|
||||
|
||||
/**
|
||||
* Called when nsIRadioInterfaceLayer is asked to enumerate the current
|
||||
|
@ -689,6 +689,12 @@ let RIL = {
|
||||
// call state.
|
||||
let model_id = libcutils.property_get("ril.model_id");
|
||||
if (DEBUG) debug("Detected RIL model " + model_id);
|
||||
if (!model_id) {
|
||||
// On some RIL models, the RIL has to be "warmed up" for us to read this property.
|
||||
// It apparently isn't warmed up yet, going to try again later.
|
||||
if (DEBUG) debug("Could not detect correct model_id. Going to try later.");
|
||||
return;
|
||||
}
|
||||
if (model_id == "I9100") {
|
||||
if (DEBUG) {
|
||||
debug("Detected I9100, enabling " +
|
||||
@ -1524,8 +1530,22 @@ let RIL = {
|
||||
*/
|
||||
hangUp: function hangUp(options) {
|
||||
let call = this.currentCalls[options.callIndex];
|
||||
if (call && call.state != CALL_STATE_HOLDING) {
|
||||
Buf.simpleRequest(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND);
|
||||
if (!call) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (call.state) {
|
||||
case CALL_STATE_ACTIVE:
|
||||
case CALL_STATE_DIALING:
|
||||
case CALL_STATE_ALERTING:
|
||||
Buf.newParcel(REQUEST_HANGUP);
|
||||
Buf.writeUint32(1);
|
||||
Buf.writeUint32(options.callIndex);
|
||||
Buf.sendParcel();
|
||||
break;
|
||||
case CALL_STATE_HOLDING:
|
||||
Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -2186,6 +2206,48 @@ let RIL = {
|
||||
}
|
||||
},
|
||||
|
||||
_processOperator: function _processOperator(operatorData) {
|
||||
if (operatorData.length < 3) {
|
||||
if (DEBUG) {
|
||||
debug("Expected at least 3 strings for operator.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.operator) {
|
||||
this.operator = {type: "operatorchange"};
|
||||
}
|
||||
|
||||
let [longName, shortName, networkTuple] = operatorData;
|
||||
let thisTuple = String(this.operator.mcc) + this.operator.mnc;
|
||||
|
||||
if (this.operator.longName !== longName ||
|
||||
this.operator.shortName !== shortName ||
|
||||
thisTuple !== networkTuple) {
|
||||
|
||||
this.operator.longName = longName;
|
||||
this.operator.shortName = shortName;
|
||||
this.operator.mcc = 0;
|
||||
this.operator.mnc = 0;
|
||||
|
||||
// According to ril.h, the operator fields will be NULL when the operator
|
||||
// is not currently registered. We can avoid trying to parse the numeric
|
||||
// tuple in that case.
|
||||
if (DEBUG && !longName) {
|
||||
debug("Operator is currently unregistered");
|
||||
}
|
||||
|
||||
if (longName && shortName && networkTuple) {
|
||||
try {
|
||||
this._processNetworkTuple(networkTuple, this.operator);
|
||||
} catch (e) {
|
||||
debug("Error processing operator tuple: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Helpers for processing call state and handle the active call.
|
||||
*/
|
||||
@ -2982,36 +3044,12 @@ RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
|
||||
return;
|
||||
}
|
||||
|
||||
let operator = Buf.readStringList();
|
||||
let operatorData = Buf.readStringList();
|
||||
if (DEBUG) debug("operator: " + operatorData);
|
||||
|
||||
if (DEBUG) debug("Operator data: " + operator);
|
||||
if (operator.length < 3) {
|
||||
if (DEBUG) debug("Expected at least 3 strings for operator.");
|
||||
}
|
||||
this._processOperator(operatorData);
|
||||
|
||||
if (!this.operator) {
|
||||
this.operator = {type: "operatorchange"};
|
||||
}
|
||||
|
||||
let numeric = String(this.operator.mcc) + this.operator.mnc;
|
||||
if (this.operator.longName != operator[0] ||
|
||||
this.operator.shortName != operator[1] ||
|
||||
numeric != operator[2]) {
|
||||
|
||||
this.operator.longName = operator[0];
|
||||
this.operator.shortName = operator[1];
|
||||
this.operator.mcc = 0;
|
||||
this.operator.mnc = 0;
|
||||
|
||||
let networkTuple = operator[2];
|
||||
try {
|
||||
this._processNetworkTuple(networkTuple, this.operator);
|
||||
} catch (e) {
|
||||
debug("Error processing operator tuple: " + e);
|
||||
}
|
||||
|
||||
this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
|
||||
}
|
||||
};
|
||||
RIL[REQUEST_RADIO_POWER] = null;
|
||||
RIL[REQUEST_DTMF] = null;
|
||||
|
@ -478,26 +478,33 @@ Telephony::EnumerateCallState(PRUint32 aCallIndex, PRUint16 aCallState,
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::NotifyError(PRInt32 aCallIndex,
|
||||
const nsAString& aError)
|
||||
const nsAString& aError)
|
||||
{
|
||||
PRInt32 index = -1;
|
||||
PRInt32 length = mCalls.Length();
|
||||
nsRefPtr<TelephonyCall> callToNotify;
|
||||
if (!mCalls.IsEmpty()) {
|
||||
// The connection is not established yet. Get the latest call object.
|
||||
if (aCallIndex == -1) {
|
||||
callToNotify = mCalls[mCalls.Length() - 1];
|
||||
} else {
|
||||
// The connection has been established. Get the failed call.
|
||||
for (PRUint32 index = 0; index < mCalls.Length(); index++) {
|
||||
nsRefPtr<TelephonyCall>& call = mCalls[index];
|
||||
if (call->CallIndex() == aCallIndex) {
|
||||
callToNotify = call;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The connection is not established yet, remove the latest call object
|
||||
if (aCallIndex == -1) {
|
||||
if (length > 0) {
|
||||
index = length - 1;
|
||||
}
|
||||
} else {
|
||||
if (aCallIndex < 0 || aCallIndex >= length) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
index = aCallIndex;
|
||||
}
|
||||
if (index != -1) {
|
||||
mCalls[index]->NotifyError(aError);
|
||||
if (!callToNotify) {
|
||||
NS_ERROR("Don't call me with a bad call index!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Set the call state to 'disconnected' and remove it from the calls list.
|
||||
callToNotify->NotifyError(aError);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,8 @@ function testElement(element)
|
||||
clientHeight = paddingTop + height + paddingBottom - scrollbarHeight;
|
||||
}
|
||||
else {
|
||||
// XXXndeakin note that Mozilla adds borders here, although the spec does not
|
||||
scrollWidth = paddingLeft + width + paddingRight + borderLeft + borderRight;
|
||||
scrollHeight = paddingTop + height + paddingBottom + borderTop + borderBottom;
|
||||
scrollWidth = paddingLeft + width + paddingRight;
|
||||
scrollHeight = paddingTop + height + paddingBottom;
|
||||
clientWidth = paddingLeft + width + paddingRight;
|
||||
clientHeight = paddingTop + height + paddingBottom;
|
||||
}
|
||||
|
@ -774,7 +774,6 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
|
||||
MarkChanged();
|
||||
|
||||
CGImageRef image;
|
||||
CGImageRef subimage = NULL;
|
||||
image = GetImageFromSourceSurface(aSurface);
|
||||
|
||||
IntSize size = aSurface->GetSize();
|
||||
@ -797,7 +796,6 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
|
||||
|
||||
CGContextRestoreGState(mCg);
|
||||
|
||||
CGImageRelease(subimage);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -109,6 +109,9 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
|
||||
if (!keep_running_)
|
||||
break;
|
||||
|
||||
if (did_work)
|
||||
continue;
|
||||
|
||||
// This will either sleep or process an event.
|
||||
NS_ProcessNextEvent(mThread, true);
|
||||
}
|
||||
|
@ -155,8 +155,8 @@ JSFunctionSpec MapObject::methods[] = {
|
||||
JSObject *
|
||||
MapObject::initClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return InitClass(cx, Rooted<GlobalObject*>(cx, &obj->asGlobal()),
|
||||
&class_, JSProto_Map, construct, methods);
|
||||
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
return InitClass(cx, global, &class_, JSProto_Map, construct, methods);
|
||||
}
|
||||
|
||||
void
|
||||
@ -348,8 +348,8 @@ JSFunctionSpec SetObject::methods[] = {
|
||||
JSObject *
|
||||
SetObject::initClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return InitClass(cx, Rooted<GlobalObject*>(cx, &obj->asGlobal()),
|
||||
&class_, JSProto_Set, construct, methods);
|
||||
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
|
||||
return InitClass(cx, global, &class_, JSProto_Set, construct, methods);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -23,8 +23,8 @@ class RegExpMatchBuilder
|
||||
JSContext * const cx;
|
||||
RootedObject array;
|
||||
|
||||
bool setProperty(JSAtom *name, Value v) {
|
||||
return !!baseops::DefineProperty(cx, array, RootedId(cx, AtomToId(name)), &v,
|
||||
bool setProperty(Handle<PropertyName*> name, Value v) {
|
||||
return !!baseops::DefineProperty(cx, array, name, &v,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
@ -38,12 +38,14 @@ class RegExpMatchBuilder
|
||||
}
|
||||
|
||||
bool setIndex(int index) {
|
||||
return setProperty(cx->runtime->atomState.indexAtom, Int32Value(index));
|
||||
Rooted<PropertyName*> name(cx, cx->runtime->atomState.indexAtom);
|
||||
return setProperty(name, Int32Value(index));
|
||||
}
|
||||
|
||||
bool setInput(JSString *str) {
|
||||
JS_ASSERT(str);
|
||||
return setProperty(cx->runtime->atomState.inputAtom, StringValue(str));
|
||||
Rooted<PropertyName*> name(cx, cx->runtime->atomState.inputAtom);
|
||||
return setProperty(name, StringValue(str));
|
||||
}
|
||||
};
|
||||
|
||||
@ -194,8 +196,8 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
|
||||
{
|
||||
if (args.length() == 0) {
|
||||
RegExpStatics *res = cx->regExpStatics();
|
||||
RegExpObject *reobj = builder.build(RootedAtom(cx, cx->runtime->emptyString),
|
||||
res->getFlags());
|
||||
Rooted<JSAtom*> empty(cx, cx->runtime->emptyString);
|
||||
RegExpObject *reobj = builder.build(empty, res->getFlags());
|
||||
if (!reobj)
|
||||
return false;
|
||||
args.rval() = ObjectValue(*reobj);
|
||||
@ -242,7 +244,8 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
|
||||
if (!sourceObj.getProperty(cx, cx->runtime->atomState.sourceAtom, &v))
|
||||
return false;
|
||||
|
||||
RegExpObject *reobj = builder.build(RootedAtom(cx, &v.toString()->asAtom()), flags);
|
||||
Rooted<JSAtom*> sourceAtom(cx, &v.toString()->asAtom());
|
||||
RegExpObject *reobj = builder.build(sourceAtom, flags);
|
||||
if (!reobj)
|
||||
return false;
|
||||
|
||||
@ -462,7 +465,8 @@ js_InitRegExpClass(JSContext *cx, JSObject *obj)
|
||||
proto->setPrivate(NULL);
|
||||
|
||||
RegExpObjectBuilder builder(cx, &proto->asRegExp());
|
||||
if (!builder.build(RootedAtom(cx, cx->runtime->emptyString), RegExpFlag(0)))
|
||||
Rooted<JSAtom*> empty(cx, cx->runtime->emptyString);
|
||||
if (!builder.build(empty, RegExpFlag(0)))
|
||||
return NULL;
|
||||
|
||||
if (!DefinePropertiesAndBrand(cx, proto, NULL, regexp_methods))
|
||||
|
@ -468,7 +468,7 @@ case "$target" in
|
||||
AC_LANG_RESTORE
|
||||
|
||||
changequote(,)
|
||||
_MSVC_VER_FILTER='s|.* ([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
|
||||
_MSVC_VER_FILTER='s|.*[^!-~]([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?).*|\1|p'
|
||||
changequote([,])
|
||||
|
||||
# Determine compiler version
|
||||
@ -521,7 +521,7 @@ case "$target" in
|
||||
fi
|
||||
|
||||
changequote(,)
|
||||
_MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
|
||||
_MSMT_VER_FILTER='s|.*[^!-~]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
|
||||
changequote([,])
|
||||
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
|
||||
if test -z "$MSMANIFEST_TOOL_VERSION"; then
|
||||
|
@ -95,7 +95,7 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
||||
JS_ASSERT_IF(staticLevel != 0, callerFrame);
|
||||
|
||||
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
|
||||
callerFrame, /* foldConstants = */ true, compileAndGo);
|
||||
/* foldConstants = */ true, compileAndGo);
|
||||
if (!parser.init())
|
||||
return NULL;
|
||||
|
||||
@ -113,21 +113,16 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
||||
if (!script)
|
||||
return NULL;
|
||||
|
||||
BytecodeEmitter bce(&parser, &sc, script, lineno);
|
||||
// We can specialize a bit for the given scope chain if that scope chain is the global object.
|
||||
JSObject *globalScope = scopeChain && scopeChain == &scopeChain->global() ? scopeChain : NULL;
|
||||
JS_ASSERT_IF(globalScope, globalScope->isNative());
|
||||
JS_ASSERT_IF(globalScope, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalScope->getClass()));
|
||||
|
||||
BytecodeEmitter bce(/* parent = */ NULL, &parser, &sc, script, callerFrame, !!globalScope,
|
||||
lineno);
|
||||
if (!bce.init())
|
||||
return NULL;
|
||||
|
||||
// We can specialize a bit for the given scope chain if that scope chain is the global object.
|
||||
JSObject *globalObj = scopeChain && scopeChain == &scopeChain->global()
|
||||
? &scopeChain->global()
|
||||
: NULL;
|
||||
|
||||
JS_ASSERT_IF(globalObj, globalObj->isNative());
|
||||
JS_ASSERT_IF(globalObj, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalObj->getClass()));
|
||||
|
||||
GlobalScope globalScope(cx, globalObj);
|
||||
bce.globalScope = &globalScope;
|
||||
|
||||
/* If this is a direct call to eval, inherit the caller's strictness. */
|
||||
if (callerFrame && callerFrame->isScriptFrame() && callerFrame->script()->strictModeCode)
|
||||
sc.setInStrictMode();
|
||||
@ -192,10 +187,10 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
||||
if (inDirectivePrologue && !parser.recognizeDirectivePrologue(pn, &inDirectivePrologue))
|
||||
return NULL;
|
||||
|
||||
if (!FoldConstants(cx, pn, bce.parser))
|
||||
if (!FoldConstants(cx, pn, &parser))
|
||||
return NULL;
|
||||
|
||||
if (!AnalyzeFunctions(bce.parser))
|
||||
if (!AnalyzeFunctions(&parser, callerFrame))
|
||||
return NULL;
|
||||
tc.functionList = NULL;
|
||||
|
||||
@ -206,7 +201,7 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
||||
if (!pn->isKind(PNK_SEMI) || !pn->pn_kid || !pn->pn_kid->isXMLItem())
|
||||
onlyXML = false;
|
||||
#endif
|
||||
bce.parser->freeTree(pn);
|
||||
parser.freeTree(pn);
|
||||
}
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
@ -222,8 +217,18 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!parser.checkForArgumentsAndRest())
|
||||
return NULL;
|
||||
// It's an error to use |arguments| in a function that has a rest parameter.
|
||||
if (callerFrame && callerFrame->isFunctionFrame() && callerFrame->fun()->hasRest()) {
|
||||
PropertyName *arguments = cx->runtime->atomState.argumentsAtom;
|
||||
for (AtomDefnRange r = tc.lexdeps->all(); !r.empty(); r.popFront()) {
|
||||
if (r.front().key() == arguments) {
|
||||
parser.reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_ARGUMENTS_AND_REST);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// We're not in a function context, so we don't expect any bindings.
|
||||
JS_ASSERT(sc.bindings.lookup(cx, arguments, NULL) == NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Nowadays the threaded interpreter needs a stop instruction, so we
|
||||
@ -250,8 +255,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
|
||||
const char *filename, unsigned lineno, JSVersion version)
|
||||
{
|
||||
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
|
||||
/* callerFrame = */ NULL, /* foldConstants = */ true,
|
||||
/* compileAndGo = */ false);
|
||||
/* foldConstants = */ true, /* compileAndGo = */ false);
|
||||
if (!parser.init())
|
||||
return false;
|
||||
|
||||
@ -271,11 +275,13 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
BytecodeEmitter funbce(&parser, &funsc, script, lineno);
|
||||
StackFrame *nullCallerFrame = NULL;
|
||||
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, nullCallerFrame,
|
||||
/* hasGlobalScope = */ false, lineno);
|
||||
if (!funbce.init())
|
||||
return false;
|
||||
|
||||
funsc.bindings.transfer(cx, bindings);
|
||||
funsc.bindings.transfer(bindings);
|
||||
fun->setArgCount(funsc.bindings.numArgs());
|
||||
if (!GenerateBlockId(&funsc, funsc.bodyid))
|
||||
return false;
|
||||
@ -328,7 +334,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
|
||||
if (!FoldConstants(cx, pn, &parser))
|
||||
return false;
|
||||
|
||||
if (!AnalyzeFunctions(&parser))
|
||||
if (!AnalyzeFunctions(&parser, nullCallerFrame))
|
||||
return false;
|
||||
|
||||
if (fn->pn_body) {
|
||||
|
@ -65,12 +65,14 @@ NewTryNote(JSContext *cx, BytecodeEmitter *bce, JSTryNoteKind kind, unsigned sta
|
||||
static JSBool
|
||||
SetSrcNoteOffset(JSContext *cx, BytecodeEmitter *bce, unsigned index, unsigned which, ptrdiff_t offset);
|
||||
|
||||
BytecodeEmitter::BytecodeEmitter(Parser *parser, SharedContext *sc, Handle<JSScript*> script,
|
||||
BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, SharedContext *sc,
|
||||
HandleScript script, StackFrame *callerFrame, bool hasGlobalScope,
|
||||
unsigned lineno)
|
||||
: sc(sc),
|
||||
parent(NULL),
|
||||
parent(parent),
|
||||
script(sc->context, script),
|
||||
parser(parser),
|
||||
callerFrame(callerFrame),
|
||||
atomIndices(sc->context),
|
||||
stackDepth(0), maxStackDepth(0),
|
||||
ntrynotes(0), lastTryNode(NULL),
|
||||
@ -78,13 +80,14 @@ BytecodeEmitter::BytecodeEmitter(Parser *parser, SharedContext *sc, Handle<JSScr
|
||||
emitLevel(0),
|
||||
constMap(sc->context),
|
||||
constList(sc->context),
|
||||
globalScope(NULL),
|
||||
closedArgs(sc->context),
|
||||
closedVars(sc->context),
|
||||
typesetCount(0),
|
||||
hasSingletons(false),
|
||||
inForInit(false)
|
||||
inForInit(false),
|
||||
hasGlobalScope(hasGlobalScope)
|
||||
{
|
||||
JS_ASSERT_IF(callerFrame, callerFrame->isScriptFrame());
|
||||
memset(&prolog, 0, sizeof prolog);
|
||||
memset(&main, 0, sizeof main);
|
||||
current = &main;
|
||||
@ -1068,7 +1071,7 @@ static bool
|
||||
TryConvertToGname(BytecodeEmitter *bce, ParseNode *pn, JSOp *op)
|
||||
{
|
||||
if (bce->script->compileAndGo &&
|
||||
bce->globalScope->globalObj &&
|
||||
bce->hasGlobalScope &&
|
||||
!bce->sc->funMightAliasLocals() &&
|
||||
!pn->isDeoptimized() &&
|
||||
!bce->sc->inStrictMode()) {
|
||||
@ -1164,7 +1167,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
break;
|
||||
case JSOP_DELNAME:
|
||||
if (dn_kind != Definition::UNKNOWN) {
|
||||
if (bce->parser->callerFrame && dn->isTopLevel())
|
||||
if (bce->callerFrame && dn->isTopLevel())
|
||||
JS_ASSERT(bce->script->compileAndGo);
|
||||
else
|
||||
pn->setOp(JSOP_FALSE);
|
||||
@ -1187,7 +1190,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
}
|
||||
|
||||
if (cookie.isFree()) {
|
||||
StackFrame *caller = bce->parser->callerFrame;
|
||||
StackFrame *caller = bce->callerFrame;
|
||||
if (caller) {
|
||||
JS_ASSERT(bce->script->compileAndGo);
|
||||
|
||||
@ -4723,24 +4726,28 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
sc.cxFlags = funbox->cxFlags;
|
||||
if (bce->sc->funMightAliasLocals())
|
||||
sc.setFunMightAliasLocals(); // inherit funMightAliasLocals from parent
|
||||
sc.bindings.transfer(cx, &funbox->bindings);
|
||||
sc.bindings.transfer(&funbox->bindings);
|
||||
|
||||
// Inherit various things (principals, version, etc) from the parent.
|
||||
// Inherit most things (principals, version, etc) from the parent.
|
||||
GlobalObject *globalObject = fun->getParent() ? &fun->getParent()->global() : NULL;
|
||||
Rooted<JSScript*> script(cx);
|
||||
Rooted<JSScript*> parent(cx, bce->script);
|
||||
script = JSScript::Create(cx, parent->savedCallerFun, parent->principals,
|
||||
parent->originPrincipals, parent->compileAndGo,
|
||||
/* noScriptRval = */ false, globalObject,
|
||||
parent->getVersion(), parent->staticLevel + 1);
|
||||
script = JSScript::Create(cx,
|
||||
/* savedCallerFun = */ false,
|
||||
parent->principals,
|
||||
parent->originPrincipals,
|
||||
parent->compileAndGo,
|
||||
/* noScriptRval = */ false,
|
||||
globalObject,
|
||||
parent->getVersion(),
|
||||
parent->staticLevel + 1);
|
||||
if (!script)
|
||||
return false;
|
||||
|
||||
BytecodeEmitter bce2(bce->parser, &sc, script, pn->pn_pos.begin.lineno);
|
||||
BytecodeEmitter bce2(bce, bce->parser, &sc, script, bce->callerFrame, bce->hasGlobalScope,
|
||||
pn->pn_pos.begin.lineno);
|
||||
if (!bce2.init())
|
||||
return false;
|
||||
bce2.parent = bce;
|
||||
bce2.globalScope = bce->globalScope;
|
||||
|
||||
/* We measured the max scope depth when we parsed the function. */
|
||||
if (!EmitFunctionScript(cx, &bce2, pn->pn_body))
|
||||
@ -5614,8 +5621,8 @@ EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
|
||||
if (obj) {
|
||||
JS_ASSERT(!obj->inDictionaryMode());
|
||||
if (!DefineNativeProperty(cx, obj, RootedId(cx, AtomToId(pn3->pn_atom)),
|
||||
UndefinedValue(), NULL, NULL,
|
||||
Rooted<jsid> id(cx, AtomToId(pn3->pn_atom));
|
||||
if (!DefineNativeProperty(cx, obj, id, UndefinedValue(), NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0))
|
||||
{
|
||||
return false;
|
||||
@ -5914,6 +5921,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
CheckTypeSet(cx, bce, JSOP_REST);
|
||||
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
|
||||
return false;
|
||||
if (!BindNameToSlot(cx, bce, rest))
|
||||
return JS_FALSE;
|
||||
if (!EmitVarOp(cx, rest, JSOP_SETARG, bce))
|
||||
return false;
|
||||
if (Emit1(cx, bce, JSOP_POP) < 0)
|
||||
|
@ -63,21 +63,13 @@ class GCConstList {
|
||||
void finish(ConstArray *array);
|
||||
};
|
||||
|
||||
struct GlobalScope {
|
||||
GlobalScope(JSContext *cx, JSObject *globalObj)
|
||||
: globalObj(cx, globalObj)
|
||||
{ }
|
||||
|
||||
RootedObject globalObj;
|
||||
};
|
||||
|
||||
struct BytecodeEmitter
|
||||
{
|
||||
SharedContext *sc; /* context shared between parsing and bytecode generation */
|
||||
SharedContext *const sc; /* context shared between parsing and bytecode generation */
|
||||
|
||||
BytecodeEmitter *parent; /* enclosing function or global context */
|
||||
BytecodeEmitter *const parent; /* enclosing function or global context */
|
||||
|
||||
Rooted<JSScript*> script; /* the JSScript we're ultimately producing */
|
||||
const Rooted<JSScript*> script; /* the JSScript we're ultimately producing */
|
||||
|
||||
struct {
|
||||
jsbytecode *base; /* base of JS bytecode vector */
|
||||
@ -90,7 +82,9 @@ struct BytecodeEmitter
|
||||
unsigned currentLine; /* line number for tree-based srcnote gen */
|
||||
} prolog, main, *current;
|
||||
|
||||
Parser *parser; /* the parser */
|
||||
Parser *const parser; /* the parser */
|
||||
|
||||
StackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */
|
||||
|
||||
OwnedAtomIndexMapPtr atomIndices; /* literals indexed for mapping */
|
||||
unsigned firstLine; /* first line, for JSScript::initFromEmitter */
|
||||
@ -114,8 +108,6 @@ struct BytecodeEmitter
|
||||
CGObjectList regexpList; /* list of emitted regexp that will be
|
||||
cloned during execution */
|
||||
|
||||
GlobalScope *globalScope; /* frontend::CompileScript global scope, or null */
|
||||
|
||||
/* Vectors of pn_cookie slot values. */
|
||||
typedef Vector<uint32_t, 8> SlotVector;
|
||||
SlotVector closedArgs;
|
||||
@ -127,7 +119,12 @@ struct BytecodeEmitter
|
||||
|
||||
bool inForInit:1; /* emitting init expr of for; exclude 'in' */
|
||||
|
||||
BytecodeEmitter(Parser *parser, SharedContext *sc, Handle<JSScript*> script, unsigned lineno);
|
||||
const bool hasGlobalScope:1; /* frontend::CompileScript's scope chain is the
|
||||
global object */
|
||||
|
||||
BytecodeEmitter(BytecodeEmitter *parent, Parser *parser, SharedContext *sc,
|
||||
HandleScript script, StackFrame *callerFrame, bool hasGlobalScope,
|
||||
unsigned lineno);
|
||||
bool init();
|
||||
|
||||
/*
|
||||
|
@ -84,13 +84,12 @@ StrictModeGetter::get() const
|
||||
|
||||
Parser::Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
|
||||
const jschar *chars, size_t length, const char *fn, unsigned ln, JSVersion v,
|
||||
StackFrame *cfp, bool foldConstants, bool compileAndGo)
|
||||
bool foldConstants, bool compileAndGo)
|
||||
: AutoGCRooter(cx, PARSER),
|
||||
context(cx),
|
||||
strictModeGetter(this),
|
||||
tokenStream(cx, prin, originPrin, chars, length, fn, ln, v, &strictModeGetter),
|
||||
tempPoolMark(NULL),
|
||||
callerFrame(cfp),
|
||||
allocator(cx),
|
||||
traceListHead(NULL),
|
||||
tc(NULL),
|
||||
@ -99,7 +98,6 @@ Parser::Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
|
||||
compileAndGo(compileAndGo)
|
||||
{
|
||||
cx->activeCompilations++;
|
||||
JS_ASSERT_IF(cfp, cfp->isScriptFrame());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -157,7 +155,7 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn,
|
||||
siblings(tc->functionList),
|
||||
kids(NULL),
|
||||
parent(tc->sc->inFunction() ? tc->sc->funbox() : NULL),
|
||||
bindings(tc->sc->context),
|
||||
bindings(),
|
||||
level(tc->staticLevel),
|
||||
ndefaults(0),
|
||||
inLoop(false),
|
||||
@ -495,7 +493,7 @@ CheckStrictParameters(JSContext *cx, Parser *parser)
|
||||
if (!parameters.init(sc->bindings.numArgs()))
|
||||
return false;
|
||||
|
||||
/* Start with lastVariable(), not lastArgument(), for destructuring. */
|
||||
// Start with lastVariable(), not the last argument, for destructuring.
|
||||
for (Shape::Range r = sc->bindings.lastVariable(); !r.empty(); r.popFront()) {
|
||||
jsid id = r.front().propid();
|
||||
if (!JSID_IS_ATOM(id))
|
||||
@ -540,7 +538,8 @@ BindLocalVariable(JSContext *cx, TreeContext *tc, ParseNode *pn, BindingKind kin
|
||||
JS_ASSERT(kind == VARIABLE || kind == CONSTANT);
|
||||
|
||||
unsigned index = tc->sc->bindings.numVars();
|
||||
if (!tc->sc->bindings.add(cx, RootedAtom(cx, pn->pn_atom), kind))
|
||||
Rooted<JSAtom*> atom(cx, pn->pn_atom);
|
||||
if (!tc->sc->bindings.add(cx, atom, kind))
|
||||
return false;
|
||||
|
||||
if (!pn->pn_cookie.set(cx, tc->staticLevel, index))
|
||||
@ -604,7 +603,7 @@ Parser::functionBody(FunctionBodyType type)
|
||||
if (!CheckStrictParameters(context, this))
|
||||
return NULL;
|
||||
|
||||
Rooted<PropertyName*> const arguments(context, context->runtime->atomState.argumentsAtom);
|
||||
Rooted<PropertyName*> arguments(context, context->runtime->atomState.argumentsAtom);
|
||||
|
||||
/*
|
||||
* Non-top-level functions use JSOP_DEFFUN which is a dynamic scope
|
||||
@ -709,24 +708,6 @@ Parser::functionBody(FunctionBodyType type)
|
||||
return pn;
|
||||
}
|
||||
|
||||
bool
|
||||
Parser::checkForArgumentsAndRest()
|
||||
{
|
||||
JS_ASSERT(!tc->sc->inFunction());
|
||||
if (callerFrame && callerFrame->isFunctionFrame() && callerFrame->fun()->hasRest()) {
|
||||
PropertyName *arguments = context->runtime->atomState.argumentsAtom;
|
||||
for (AtomDefnRange r = tc->lexdeps->all(); !r.empty(); r.popFront()) {
|
||||
if (r.front().key() == arguments) {
|
||||
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_ARGUMENTS_AND_REST);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* We're not in a function context, so we don't expect any bindings. */
|
||||
JS_ASSERT(tc->sc->bindings.lookup(context, arguments, NULL) == NONE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create a placeholder Definition node for |atom|.
|
||||
// Nb: unlike most functions that are passed a Parser, this one gets a
|
||||
// SharedContext passed in separately, because in this case |sc| may not equal
|
||||
@ -1237,7 +1218,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
|
||||
|
||||
}
|
||||
|
||||
funbox->bindings.transfer(funtc->sc->context, &funtc->sc->bindings);
|
||||
funbox->bindings.transfer(&funtc->sc->bindings);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -6851,8 +6832,8 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
|
||||
pn->pn_xflags |= PNX_NONCONST;
|
||||
|
||||
/* NB: Getter function in { get x(){} } is unnamed. */
|
||||
pn2 = functionDef(RootedPropertyName(context, NULL),
|
||||
op == JSOP_GETTER ? Getter : Setter, Expression);
|
||||
Rooted<PropertyName*> funName(context, NULL);
|
||||
pn2 = functionDef(funName, op == JSOP_GETTER ? Getter : Setter, Expression);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
TokenPos pos = {begin, pn2->pn_pos.end};
|
||||
|
@ -38,7 +38,6 @@ struct Parser : private AutoGCRooter
|
||||
StrictModeGetter strictModeGetter; /* used by tokenStream to test for strict mode */
|
||||
TokenStream tokenStream;
|
||||
void *tempPoolMark; /* initial JSContext.tempLifoAlloc mark */
|
||||
StackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */
|
||||
ParseNodeAllocator allocator;
|
||||
ObjectBox *traceListHead; /* list of parsed object for GC tracing */
|
||||
|
||||
@ -57,7 +56,7 @@ struct Parser : private AutoGCRooter
|
||||
public:
|
||||
Parser(JSContext *cx, JSPrincipals *prin, JSPrincipals *originPrin,
|
||||
const jschar *chars, size_t length, const char *fn, unsigned ln, JSVersion version,
|
||||
StackFrame *cfp, bool foldConstants, bool compileAndGo);
|
||||
bool foldConstants, bool compileAndGo);
|
||||
~Parser();
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
@ -141,8 +140,6 @@ struct Parser : private AutoGCRooter
|
||||
enum FunctionBodyType { StatementListBody, ExpressionBody };
|
||||
ParseNode *functionBody(FunctionBodyType type);
|
||||
|
||||
bool checkForArgumentsAndRest();
|
||||
|
||||
private:
|
||||
/*
|
||||
* JS parsers, from lowest to highest precedence.
|
||||
|
@ -158,7 +158,7 @@ MarkExtensibleScopeDescendants(JSContext *context, FunctionBox *funbox, bool has
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::AnalyzeFunctions(Parser *parser)
|
||||
frontend::AnalyzeFunctions(Parser *parser, StackFrame *callerFrame)
|
||||
{
|
||||
TreeContext *tc = parser->tc;
|
||||
SharedContext *sc = tc->sc;
|
||||
@ -166,7 +166,7 @@ frontend::AnalyzeFunctions(Parser *parser)
|
||||
return true;
|
||||
if (!MarkExtensibleScopeDescendants(sc->context, tc->functionList, false))
|
||||
return false;
|
||||
bool isDirectEval = !!parser->callerFrame;
|
||||
bool isDirectEval = !!callerFrame;
|
||||
bool isHeavyweight = false;
|
||||
SetFunctionKinds(tc->functionList, &isHeavyweight, sc->inFunction(), isDirectEval);
|
||||
if (isHeavyweight)
|
||||
|
@ -11,6 +11,7 @@
|
||||
namespace js {
|
||||
|
||||
struct Parser;
|
||||
class StackFrame;
|
||||
|
||||
namespace frontend {
|
||||
|
||||
@ -20,7 +21,7 @@ namespace frontend {
|
||||
* accordingly.
|
||||
*/
|
||||
bool
|
||||
AnalyzeFunctions(Parser *parser);
|
||||
AnalyzeFunctions(Parser *parser, StackFrame *callerFrame);
|
||||
|
||||
} /* namespace frontend */
|
||||
} /* namespace js */
|
||||
|
@ -27,7 +27,7 @@ SharedContext::SharedContext(JSContext *cx, JSObject *scopeChain, JSFunction *fu
|
||||
fun_(cx, fun),
|
||||
funbox_(funbox),
|
||||
scopeChain_(cx, scopeChain),
|
||||
bindings(cx),
|
||||
bindings(),
|
||||
bindingsRoot(cx, &bindings),
|
||||
cxFlags(cx)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ class Handle
|
||||
* Construct a handle from an explicitly rooted location. This is the
|
||||
* normal way to create a handle, and normally happens implicitly.
|
||||
*/
|
||||
template <typename S> inline Handle(const Rooted<S> &root);
|
||||
template <typename S> inline Handle(Rooted<S> &root);
|
||||
|
||||
const T *address() const { return ptr; }
|
||||
T value() const { return *ptr; }
|
||||
@ -163,15 +163,6 @@ class Rooted
|
||||
Rooted(JSContext *cx) { init(cx, RootMethods<T>::initial()); }
|
||||
Rooted(JSContext *cx, T initial) { init(cx, initial); }
|
||||
|
||||
/*
|
||||
* This method is only necessary due to an obscure C++98 requirement (that
|
||||
* there be an accessible, usable copy constructor when passing a temporary
|
||||
* to an implicitly-called constructor for use with a const-ref parameter).
|
||||
* (Head spinning yet?) We can remove this when we build the JS engine
|
||||
* with -std=c++11.
|
||||
*/
|
||||
operator Handle<T> () const { return Handle<T>(*this); }
|
||||
|
||||
~Rooted()
|
||||
{
|
||||
#if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING)
|
||||
@ -217,7 +208,7 @@ class Rooted
|
||||
|
||||
template<typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(const Rooted<S> &root)
|
||||
Handle<T>::Handle(Rooted<S> &root)
|
||||
{
|
||||
testAssign<S>();
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
|
@ -17,3 +17,8 @@ function f3(a=rest, ...rest) {
|
||||
assertEqArray(rest, [2, 3, 4]);
|
||||
}
|
||||
f3(1, 2, 3, 4);
|
||||
function f4(a=42, ...f) {
|
||||
assertEq(typeof f, "function");
|
||||
function f() {}
|
||||
}
|
||||
f4()
|
||||
|
111
js/src/jsapi.cpp
111
js/src/jsapi.cpp
@ -1779,7 +1779,8 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
|
||||
|
||||
assertSameCompartment(cx, obj);
|
||||
|
||||
return GlobalObject::initStandardClasses(cx, Rooted<GlobalObject*>(cx, &obj->global()));
|
||||
Rooted<GlobalObject*> global(cx, &obj->global());
|
||||
return GlobalObject::initStandardClasses(cx, global);
|
||||
}
|
||||
|
||||
#define CLASP(name) (&name##Class)
|
||||
@ -3143,7 +3144,7 @@ JS_ConvertStub(JSContext *cx, JSHandleObject obj, JSType type, jsval *vp)
|
||||
{
|
||||
JS_ASSERT(type != JSTYPE_OBJECT && type != JSTYPE_FUNCTION);
|
||||
JS_ASSERT(obj);
|
||||
return DefaultValue(cx, RootedObject(cx, obj), type, vp);
|
||||
return DefaultValue(cx, obj, type, vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
@ -3231,12 +3232,15 @@ JS_GetPrototype(JSObject *obj)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
|
||||
JS_SetPrototype(JSContext *cx, JSObject *obj_, JSObject *proto_)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, proto);
|
||||
return SetProto(cx, RootedObject(cx, obj), RootedObject(cx, proto), JS_FALSE);
|
||||
assertSameCompartment(cx, obj_, proto_);
|
||||
|
||||
Rooted<JSObject*> obj(cx, obj_);
|
||||
Rooted<JSObject*> proto(cx, proto_);
|
||||
return SetProto(cx, obj, proto, JS_FALSE);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
@ -3247,14 +3251,17 @@ JS_GetParent(JSObject *obj)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
|
||||
JS_SetParent(JSContext *cx, JSObject *obj_, JSObject *parent_)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
JS_ASSERT(!obj->isScope());
|
||||
JS_ASSERT(parent || !obj->getParent());
|
||||
assertSameCompartment(cx, obj, parent);
|
||||
return JSObject::setParent(cx, RootedObject(cx, obj), RootedObject(cx, parent));
|
||||
JS_ASSERT(!obj_->isScope());
|
||||
JS_ASSERT(parent_ || !obj_->getParent());
|
||||
assertSameCompartment(cx, obj_, parent_);
|
||||
|
||||
Rooted<JSObject*> obj(cx, obj_);
|
||||
Rooted<JSObject*> parent(cx, parent_);
|
||||
return JSObject::setParent(cx, obj, parent);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
@ -3804,12 +3811,15 @@ JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, const jschar *name,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp)
|
||||
JS_DefineOwnProperty(JSContext *cx, JSObject *obj_, jsid id_, jsval descriptor, JSBool *bp)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id, descriptor);
|
||||
return js_DefineOwnProperty(cx, RootedObject(cx, obj), RootedId(cx, id), descriptor, bp);
|
||||
assertSameCompartment(cx, obj_, id_, descriptor);
|
||||
|
||||
Rooted<JSObject*> obj(cx, obj_);
|
||||
Rooted<jsid> id(cx, id_);
|
||||
return js_DefineOwnProperty(cx, obj, id, descriptor, bp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
@ -3985,11 +3995,14 @@ JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj_, jsid id_, jsval *vp)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return GetOwnPropertyDescriptor(cx, RootedObject(cx, obj), RootedId(cx, id), vp);
|
||||
|
||||
Rooted<JSObject*> obj(cx, obj_);
|
||||
Rooted<jsid> id(cx, id_);
|
||||
return GetOwnPropertyDescriptor(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -4018,7 +4031,8 @@ JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
|
||||
unsigned attrs, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom && SetPropertyAttributesById(cx, obj, RootedId(cx, AtomToId(atom)), attrs, foundp);
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
@ -4026,7 +4040,8 @@ JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, const jschar *name, siz
|
||||
unsigned attrs, JSBool *foundp)
|
||||
{
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && SetPropertyAttributesById(cx, obj, RootedId(cx, AtomToId(atom)), attrs, foundp);
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
@ -4050,9 +4065,11 @@ JS_ForwardGetPropertyTo(JSContext *cx, JSObject *obj, jsid id_, JSObject *onBeha
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp)
|
||||
JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj_, jsid id_, jsval def, jsval *vp)
|
||||
{
|
||||
return baseops::GetPropertyDefault(cx, RootedObject(cx, obj), RootedId(cx, id), def, vp);
|
||||
Rooted<JSObject*> obj(cx, obj_);
|
||||
Rooted<jsid> id(cx, id_);
|
||||
return baseops::GetPropertyDefault(cx, obj, id, def, vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
@ -4184,8 +4201,10 @@ JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
|
||||
assertSameCompartment(cx, obj, id);
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
|
||||
|
||||
if (JSID_IS_SPECIAL(id))
|
||||
return obj->deleteSpecial(cx, Rooted<SpecialId>(cx, JSID_TO_SPECIALID(id)), rval, false);
|
||||
if (JSID_IS_SPECIAL(id)) {
|
||||
Rooted<SpecialId> sid(cx, JSID_TO_SPECIALID(id));
|
||||
return obj->deleteSpecial(cx, sid, rval, false);
|
||||
}
|
||||
|
||||
return obj->deleteByValue(cx, IdToValue(id), rval, false);
|
||||
}
|
||||
@ -4431,12 +4450,14 @@ JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_NewElementIterator(JSContext *cx, JSObject *obj)
|
||||
JS_NewElementIterator(JSContext *cx, JSObject *obj_)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
return ElementIteratorObject::create(cx, RootedObject(cx, obj));
|
||||
assertSameCompartment(cx, obj_);
|
||||
|
||||
Rooted<JSObject*> obj(cx, obj_);
|
||||
return ElementIteratorObject::create(cx, obj);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
@ -4728,6 +4749,8 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj_, JSFunctionSpec *fs)
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
|
||||
/*
|
||||
* Define a generic arity N+1 static method for the arity N prototype
|
||||
* method if flags contains JSFUN_GENERIC_NATIVE.
|
||||
@ -4740,11 +4763,8 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj_, JSFunctionSpec *fs)
|
||||
}
|
||||
|
||||
flags &= ~JSFUN_GENERIC_NATIVE;
|
||||
fun = js_DefineFunction(cx, ctor, RootedId(cx, AtomToId(atom)),
|
||||
js_generic_native_method_dispatcher,
|
||||
fs->nargs + 1,
|
||||
flags,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
fun = js_DefineFunction(cx, ctor, id, js_generic_native_method_dispatcher,
|
||||
fs->nargs + 1, flags, JSFunction::ExtendedFinalizeKind);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -4755,8 +4775,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj_, JSFunctionSpec *fs)
|
||||
fun->setExtendedSlot(0, PrivateValue(fs));
|
||||
}
|
||||
|
||||
fun = js_DefineFunction(cx, obj,
|
||||
RootedId(cx, AtomToId(atom)), fs->call, fs->nargs, flags);
|
||||
fun = js_DefineFunction(cx, obj, id, fs->call, fs->nargs, flags);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -4776,7 +4795,8 @@ JS_DefineFunction(JSContext *cx, JSObject *obj_, const char *name, JSNative call
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
return js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)), call, nargs, attrs);
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
return js_DefineFunction(cx, obj, id, call, nargs, attrs);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
@ -4793,7 +4813,8 @@ JS_DefineUCFunction(JSContext *cx, JSObject *obj_,
|
||||
JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
return js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)), call, nargs, attrs);
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
return js_DefineFunction(cx, obj, id, call, nargs, attrs);
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(JSFunction *)
|
||||
@ -4965,7 +4986,7 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSBool bytes_are_utf8, JSObject *obj, c
|
||||
{
|
||||
Parser parser(cx, /* prin = */ NULL, /* originPrin = */ NULL,
|
||||
chars, length, /* filename = */ NULL, /* lineno = */ 1, cx->findVersion(),
|
||||
/* cfp = */ NULL, /* foldConstants = */ true, /* compileAndGo = */ false);
|
||||
/* foldConstants = */ true, /* compileAndGo = */ false);
|
||||
if (parser.init()) {
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
if (!parser.parse(obj) &&
|
||||
@ -5150,7 +5171,7 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj_,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bindings bindings(cx);
|
||||
Bindings bindings;
|
||||
for (unsigned i = 0; i < nargs; i++) {
|
||||
uint16_t dummy;
|
||||
RootedAtom argAtom(cx, js_Atomize(cx, argnames[i], strlen(argnames[i])));
|
||||
@ -5168,11 +5189,10 @@ CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj_,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (obj && funAtom &&
|
||||
!obj->defineGeneric(cx, RootedId(cx, AtomToId(funAtom)), ObjectValue(*fun), NULL, NULL,
|
||||
JSPROP_ENUMERATE))
|
||||
{
|
||||
return NULL;
|
||||
if (obj && funAtom) {
|
||||
Rooted<jsid> id(cx, AtomToId(funAtom));
|
||||
if (!obj->defineGeneric(cx, id, ObjectValue(*fun), NULL, NULL, JSPROP_ENUMERATE))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fun;
|
||||
@ -5471,8 +5491,11 @@ JS_CallFunctionName(JSContext *cx, JSObject *obj_, const char *name, unsigned ar
|
||||
|
||||
Value v;
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
return atom &&
|
||||
GetMethod(cx, obj, RootedId(cx, AtomToId(atom)), 0, &v) &&
|
||||
if (!atom)
|
||||
return false;
|
||||
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
return GetMethod(cx, obj, id, 0, &v) &&
|
||||
Invoke(cx, ObjectOrNullValue(obj), v, argc, argv, rval);
|
||||
}
|
||||
|
||||
@ -5851,7 +5874,9 @@ JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return js_ConcatStrings(cx, RootedString(cx, left), RootedString(cx, right));
|
||||
Rooted<JSString*> lstr(cx, left);
|
||||
Rooted<JSString*> rstr(cx, right);
|
||||
return js_ConcatStrings(cx, lstr, rstr);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(const jschar *)
|
||||
|
@ -1406,23 +1406,10 @@ typedef JSBool
|
||||
*
|
||||
* The *objp out parameter, on success, should be null to indicate that id
|
||||
* was not resolved; and non-null, referring to obj or one of its prototypes,
|
||||
* if id was resolved.
|
||||
* if id was resolved. The hook may assume *objp is null on entry.
|
||||
*
|
||||
* This hook instead of JSResolveOp is called via the JSClass.resolve member
|
||||
* if JSCLASS_NEW_RESOLVE is set in JSClass.flags.
|
||||
*
|
||||
* Setting JSCLASS_NEW_RESOLVE and JSCLASS_NEW_RESOLVE_GETS_START further
|
||||
* extends this hook by passing in the starting object on the prototype chain
|
||||
* via *objp. Thus a resolve hook implementation may define the property id
|
||||
* being resolved in the object in which the id was first sought, rather than
|
||||
* in a prototype object whose class led to the resolve hook being called.
|
||||
*
|
||||
* When using JSCLASS_NEW_RESOLVE_GETS_START, the resolve hook must therefore
|
||||
* null *objp to signify "not resolved". With only JSCLASS_NEW_RESOLVE and no
|
||||
* JSCLASS_NEW_RESOLVE_GETS_START, the hook can assume *objp is null on entry.
|
||||
* This is not good practice, but enough existing hook implementations count
|
||||
* on it that we can't break compatibility by passing the starting object in
|
||||
* *objp without a new JSClass flag.
|
||||
*/
|
||||
typedef JSBool
|
||||
(* JSNewResolveOp)(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
|
||||
@ -3661,10 +3648,7 @@ struct JSClass {
|
||||
#define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hook */
|
||||
#define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */
|
||||
#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */
|
||||
#define JSCLASS_NEW_RESOLVE_GETS_START (1<<4) /* JSNewResolveOp gets starting
|
||||
object in prototype chain
|
||||
passed in via *objp in/out
|
||||
parameter */
|
||||
/* (1<<4) is unused */
|
||||
#define JSCLASS_IMPLEMENTS_BARRIERS (1<<5) /* Correctly implements GC read
|
||||
and write barriers */
|
||||
#define JSCLASS_DOCUMENT_OBSERVER (1<<6) /* DOM document observer */
|
||||
|
@ -716,7 +716,8 @@ static JSBool
|
||||
array_lookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, JSObject **objp,
|
||||
JSProperty **propp)
|
||||
{
|
||||
return array_lookupGeneric(cx, obj, RootedId(cx, NameToId(name)), objp, propp);
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return array_lookupGeneric(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -744,7 +745,8 @@ static JSBool
|
||||
array_lookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, JSObject **objp,
|
||||
JSProperty **propp)
|
||||
{
|
||||
return array_lookupGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), objp, propp);
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return array_lookupGeneric(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
@ -775,8 +777,10 @@ array_getProperty(JSContext *cx, HandleObject obj, HandleObject receiver, Handle
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!obj->isDenseArray())
|
||||
return baseops::GetProperty(cx, obj, receiver, RootedId(cx, NameToId(name)), vp);
|
||||
if (!obj->isDenseArray()) {
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return baseops::GetProperty(cx, obj, receiver, id, vp);
|
||||
}
|
||||
|
||||
JSObject *proto = obj->getProto();
|
||||
if (!proto) {
|
||||
@ -821,7 +825,8 @@ array_getSpecial(JSContext *cx, HandleObject obj, HandleObject receiver, HandleS
|
||||
return true;
|
||||
}
|
||||
|
||||
return baseops::GetProperty(cx, obj, receiver, RootedId(cx, SPECIALID_TO_JSID(sid)), vp);
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return baseops::GetProperty(cx, obj, receiver, id, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -833,9 +838,9 @@ array_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleI
|
||||
if (IsDefinitelyIndex(idval, &index))
|
||||
return array_getElement(cx, obj, receiver, index, vp);
|
||||
|
||||
SpecialId sid;
|
||||
if (ValueIsSpecial(obj, &idval, &sid, cx))
|
||||
return array_getSpecial(cx, obj, receiver, Rooted<SpecialId>(cx, sid), vp);
|
||||
Rooted<SpecialId> sid(cx);
|
||||
if (ValueIsSpecial(obj, &idval, sid.address(), cx))
|
||||
return array_getSpecial(cx, obj, receiver, sid, vp);
|
||||
|
||||
JSAtom *atom = ToAtom(cx, idval);
|
||||
if (!atom)
|
||||
@ -844,7 +849,8 @@ array_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiver, HandleI
|
||||
if (atom->isIndex(&index))
|
||||
return array_getElement(cx, obj, receiver, index, vp);
|
||||
|
||||
return array_getProperty(cx, obj, receiver, RootedPropertyName(cx, atom->asPropertyName()), vp);
|
||||
Rooted<PropertyName*> name(cx, atom->asPropertyName());
|
||||
return array_getProperty(cx, obj, receiver, name, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -904,7 +910,8 @@ array_setGeneric(JSContext *cx, HandleObject obj, HandleId id, Value *vp, JSBool
|
||||
static JSBool
|
||||
array_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Value *vp, JSBool strict)
|
||||
{
|
||||
return array_setGeneric(cx, obj, RootedId(cx, NameToId(name)), vp, strict);
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return array_setGeneric(cx, obj, id, vp, strict);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -949,7 +956,8 @@ array_setElement(JSContext *cx, HandleObject obj, uint32_t index, Value *vp, JSB
|
||||
static JSBool
|
||||
array_setSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, Value *vp, JSBool strict)
|
||||
{
|
||||
return array_setGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)), vp, strict);
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return array_setGeneric(cx, obj, id, vp, strict);
|
||||
}
|
||||
|
||||
JSBool
|
||||
@ -982,7 +990,7 @@ array_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *v
|
||||
return JS_TRUE;
|
||||
|
||||
if (!obj->isDenseArray())
|
||||
return baseops::DefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
return baseops::DefineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
|
||||
do {
|
||||
uint32_t i = 0; // init to shut GCC up
|
||||
@ -1008,14 +1016,15 @@ array_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, const Value *v
|
||||
|
||||
if (!JSObject::makeDenseArraySlow(cx, obj))
|
||||
return false;
|
||||
return baseops::DefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
return baseops::DefineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
array_defineProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, const Value *value,
|
||||
JSPropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
return array_defineGeneric(cx, obj, RootedId(cx, NameToId(name)), value, getter, setter, attrs);
|
||||
Rooted<jsid> id(cx, NameToId(name));
|
||||
return array_defineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
@ -1063,8 +1072,8 @@ static JSBool
|
||||
array_defineSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, const Value *value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
return array_defineGeneric(cx, obj, RootedId(cx, SPECIALID_TO_JSID(sid)),
|
||||
value, getter, setter, attrs);
|
||||
Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
|
||||
return array_defineGeneric(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -1155,7 +1164,7 @@ array_deleteElement(JSContext *cx, HandleObject obj, uint32_t index, Value *rval
|
||||
obj->setDenseArrayElement(index, MagicValue(JS_ARRAY_HOLE));
|
||||
}
|
||||
|
||||
if (!js_SuppressDeletedElement(cx, RootedObject(cx, obj), index))
|
||||
if (!js_SuppressDeletedElement(cx, obj, index))
|
||||
return false;
|
||||
|
||||
rval->setBoolean(true);
|
||||
@ -1704,7 +1713,8 @@ array_toLocaleString(JSContext *cx, unsigned argc, Value *vp)
|
||||
* Passing comma here as the separator. Need a way to get a
|
||||
* locale-specific version.
|
||||
*/
|
||||
return array_toString_sub(cx, obj, JS_TRUE, RootedString(cx), args);
|
||||
Rooted<JSString*> none(cx, NULL);
|
||||
return array_toString_sub(cx, obj, JS_TRUE, none, args);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@ -2385,7 +2395,7 @@ NewbornArrayPushImpl(JSContext *cx, HandleObject obj, const Value &v)
|
||||
/* This can happen in one evil case. See bug 630377. */
|
||||
RootedId id(cx);
|
||||
return IndexToId(cx, length, id.address()) &&
|
||||
baseops::DefineProperty(cx, obj, id, &v, NULL, NULL, JSPROP_ENUMERATE);
|
||||
baseops::DefineGeneric(cx, obj, id, &v, NULL, NULL, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
JS_ASSERT(obj->isDenseArray());
|
||||
|
@ -167,7 +167,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
|
||||
|
||||
/* Unwrap incoming objects. */
|
||||
if (vp->isObject()) {
|
||||
JSObject *obj = &vp->toObject();
|
||||
Rooted<JSObject*> obj(cx, &vp->toObject());
|
||||
|
||||
if (obj->compartment() == this)
|
||||
return WrapForSameCompartment(cx, obj, vp);
|
||||
@ -194,7 +194,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
JSObject *outer = GetOuterObject(cx, RootedObject(cx, obj));
|
||||
JSObject *outer = GetOuterObject(cx, obj);
|
||||
JS_ASSERT(outer && outer == obj);
|
||||
}
|
||||
#endif
|
||||
|
@ -2699,8 +2699,8 @@ js_InitDateClass(JSContext *cx, JSObject *obj)
|
||||
RootedId toUTCStringId(cx, NameToId(cx->runtime->atomState.toUTCStringAtom));
|
||||
RootedId toGMTStringId(cx, NameToId(cx->runtime->atomState.toGMTStringAtom));
|
||||
if (!baseops::GetProperty(cx, dateProto, toUTCStringId, &toUTCStringFun) ||
|
||||
!baseops::DefineProperty(cx, dateProto, toGMTStringId, &toUTCStringFun,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, 0))
|
||||
!baseops::DefineGeneric(cx, dateProto, toGMTStringId, &toUTCStringFun,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, 0))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -783,7 +783,8 @@ GetPropertyDesc(JSContext *cx, JSObject *obj_, Shape *shape, JSPropertyDesc *pd)
|
||||
lastException = cx->getPendingException();
|
||||
cx->clearPendingException();
|
||||
|
||||
if (!baseops::GetProperty(cx, obj, RootedId(cx, shape->propid()), &pd->value)) {
|
||||
Rooted<jsid> id(cx, shape->propid());
|
||||
if (!baseops::GetProperty(cx, obj, id, &pd->value)) {
|
||||
if (!cx->isExceptionPending()) {
|
||||
pd->flags = JSPD_ERROR;
|
||||
pd->value = JSVAL_VOID;
|
||||
|
@ -269,17 +269,20 @@ InitExnPrivate(JSContext *cx, HandleObject exnObject, HandleString message,
|
||||
if (checkAccess && i.isNonEvalFunctionFrame()) {
|
||||
Value v = NullValue();
|
||||
RootedId callerid(cx, NameToId(cx->runtime->atomState.callerAtom));
|
||||
if (!checkAccess(cx, RootedObject(cx, i.callee()), callerid, JSACC_READ, &v))
|
||||
Rooted<JSObject*> obj(cx, i.callee());
|
||||
if (!checkAccess(cx, obj, callerid, JSACC_READ, &v))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!frames.growBy(1))
|
||||
return false;
|
||||
JSStackTraceStackElem &frame = frames.back();
|
||||
if (i.isNonEvalFunctionFrame())
|
||||
frame.funName = fp->fun()->atom ? fp->fun()->atom : cx->runtime->emptyString;
|
||||
else
|
||||
if (i.isNonEvalFunctionFrame()) {
|
||||
JSAtom *atom = fp->fun()->atom ? fp->fun()->atom : cx->runtime->emptyString;
|
||||
frame.funName = atom;
|
||||
} else {
|
||||
frame.funName = NULL;
|
||||
}
|
||||
const char *cfilename = i.script()->filename;
|
||||
if (!cfilename)
|
||||
cfilename = "";
|
||||
|
@ -231,8 +231,8 @@ JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj_, const JSFunctionSpecWi
|
||||
return false;
|
||||
|
||||
RootedFunction fun(cx);
|
||||
fun = js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)),
|
||||
fs->call, fs->nargs, fs->flags);
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
fun = js_DefineFunction(cx, obj, id, fs->call, fs->nargs, fs->flags);
|
||||
if (!fun)
|
||||
return false;
|
||||
|
||||
@ -338,9 +338,8 @@ js::DefineFunctionWithReserved(JSContext *cx, JSObject *obj_, const char *name,
|
||||
JSAtom *atom = js_Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
return js_DefineFunction(cx, obj, RootedId(cx, AtomToId(atom)),
|
||||
call, nargs, attrs,
|
||||
JSFunction::ExtendedFinalizeKind);
|
||||
Rooted<jsid> id(cx, AtomToId(atom));
|
||||
return js_DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSFunction *)
|
||||
|
@ -426,7 +426,8 @@ js::CloneInterpretedFunction(JSContext *cx, JSFunction *srcFun)
|
||||
if (!clone->clearType(cx))
|
||||
return NULL;
|
||||
|
||||
JSScript *clonedScript = CloneScript(cx, RootedScript(cx, srcFun->script()));
|
||||
Rooted<JSScript*> srcScript(cx, srcFun->script());
|
||||
JSScript *clonedScript = CloneScript(cx, srcScript);
|
||||
if (!clonedScript)
|
||||
return NULL;
|
||||
|
||||
@ -1004,7 +1005,7 @@ Function(JSContext *cx, unsigned argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
Bindings bindings(cx);
|
||||
Bindings bindings;
|
||||
Bindings::AutoRooter bindingsRoot(cx, &bindings);
|
||||
|
||||
bool hasRest = false;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user