mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
Merge m-c to birch.
This commit is contained in:
commit
1dbd23c907
2
CLOBBER
2
CLOBBER
@ -17,4 +17,4 @@
|
||||
#
|
||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||
#
|
||||
Bug 875929 removed a file from js/src/moz.build and apparently the build system didn't notice.
|
||||
Bug 879831 needed to clobber for the removal of jsprobes.cpp
|
||||
|
@ -553,10 +553,7 @@ pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 40);
|
||||
pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 10);
|
||||
pref("javascript.options.mem.gc_low_frequency_heap_growth", 120);
|
||||
pref("javascript.options.mem.high_water_mark", 6);
|
||||
pref("javascript.options.mem.gc_allocation_threshold_mb", 3);
|
||||
|
||||
// Allocation Threshold for workers
|
||||
pref("dom.workers.mem.gc_allocation_threshold_mb", 3);
|
||||
pref("javascript.options.mem.gc_allocation_threshold_mb", 1);
|
||||
|
||||
// Show/Hide scrollbars when active/inactive
|
||||
pref("ui.showHideScrollbars", 1);
|
||||
|
@ -1 +0,0 @@
|
||||
../panda/README
|
@ -1,25 +0,0 @@
|
||||
{
|
||||
"config_version": 1,
|
||||
"tooltool_manifest": "releng-pandaboard.tt",
|
||||
"mock_target": "mozilla-centos6-i386",
|
||||
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
|
||||
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
|
||||
"build_targets": ["boottarball", "systemtarball", "userdatatarball", "package-tests"],
|
||||
"upload_files": [
|
||||
"{workdir}/out/target/product/panda/*.tar.bz2",
|
||||
"{workdir}/out/target/product/panda/tests/*.zip",
|
||||
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
|
||||
"{srcdir}/b2g/config/panda/README",
|
||||
"{workdir}/sources.xml"
|
||||
],
|
||||
"gecko_l10n_root": "http://hg.mozilla.org/l10n-central",
|
||||
"gaia": {
|
||||
"vcs": "hgtool",
|
||||
"repo": "http://hg.mozilla.org/integration/gaia-central",
|
||||
"l10n": {
|
||||
"vcs": "hgtool",
|
||||
"root": "http://hg.mozilla.org/gaia-l10n"
|
||||
}
|
||||
},
|
||||
"upload_platform": "panda_gaia_central"
|
||||
}
|
@ -1 +0,0 @@
|
||||
../panda/releng-pandaboard.tt
|
@ -393,7 +393,11 @@ pref("browser.link.open_newwindow.override.external", -1);
|
||||
// 2: don't divert window.open with features
|
||||
pref("browser.link.open_newwindow.restriction", 2);
|
||||
|
||||
// Disable opening a new window via window.open if browser is in fullscreen mode
|
||||
// If true, this pref causes windows opened by window.open to be forced into new
|
||||
// tabs (rather than potentially opening separate windows, depending on
|
||||
// window.open arguments) when the browser is in fullscreen mode.
|
||||
// We set this differently on Mac because the fullscreen implementation there is
|
||||
// different.
|
||||
#ifdef XP_MACOSX
|
||||
pref("browser.link.open_newwindow.disabled_in_fullscreen", true);
|
||||
#else
|
||||
|
@ -432,14 +432,22 @@ var FullZoom = {
|
||||
* currently selected browser is used.
|
||||
*/
|
||||
_getState: function FullZoom__getState(browser) {
|
||||
let browser = browser || gBrowser.selectedBrowser;
|
||||
return { uri: browser.currentURI, token: this._zoomChangeToken };
|
||||
browser = browser || gBrowser.selectedBrowser;
|
||||
return {
|
||||
// Due to async content pref service callbacks, this method can get called
|
||||
// after the window has closed, so gBrowser.selectedBrowser may be null.
|
||||
uri: browser ? browser.currentURI : null,
|
||||
token: this._zoomChangeToken,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given state is current.
|
||||
*/
|
||||
_isStateCurrent: function FullZoom__isStateCurrent(state) {
|
||||
// If either state has no URI, then the given state can't be current.
|
||||
// currState.uri will be null when this method is called after the window
|
||||
// has closed, which can happen due to async content pref service callbacks.
|
||||
let currState = this._getState();
|
||||
return currState.token === state.token &&
|
||||
currState.uri && state.uri &&
|
||||
|
@ -1380,6 +1380,12 @@
|
||||
t._tPos = position;
|
||||
this.tabContainer._setPositionalAttributes();
|
||||
|
||||
// Prevent the superfluous initial load of a blank document
|
||||
// if we're going to load something other than about:blank.
|
||||
if (!uriIsAboutBlank) {
|
||||
b.setAttribute("nodefaultsrc", "true");
|
||||
}
|
||||
|
||||
// NB: this appendChild call causes us to run constructors for the
|
||||
// browser element, which fires off a bunch of notifications. Some
|
||||
// of those notifications can cause code to run that inspects our
|
||||
@ -1389,13 +1395,6 @@
|
||||
|
||||
this.tabContainer.updateVisibility();
|
||||
|
||||
if (!uriIsAboutBlank) {
|
||||
// Stop the existing about:blank load. Otherwise, if aURI
|
||||
// doesn't stop in-progress loads on its own, we'll get into
|
||||
// trouble with multiple parallel loads running at once.
|
||||
b.stop();
|
||||
}
|
||||
|
||||
// wire up a progress listener for the new browser object.
|
||||
var tabListener = this.mTabProgressListener(t, b, uriIsAboutBlank);
|
||||
const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
|
||||
|
@ -35,10 +35,10 @@ function test() {
|
||||
}
|
||||
|
||||
function load(aTab, aUrl, aCallback) {
|
||||
aTab.linkedBrowser.addEventListener("pageshow", function onpageshow(aEvent) {
|
||||
aEvent.currentTarget.removeEventListener("pageshow", onpageshow, false);
|
||||
aTab.linkedBrowser.addEventListener("load", function onload(aEvent) {
|
||||
aEvent.currentTarget.removeEventListener("load", onload, true);
|
||||
waitForFocus(aCallback, content);
|
||||
}, false);
|
||||
}, true);
|
||||
aTab.linkedBrowser.loadURI(aUrl);
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,6 @@ XPCOMUtils.defineLazyGetter(this, "docShell", () => {
|
||||
});
|
||||
|
||||
const EXPECTED_REFLOWS = [
|
||||
// b.stop() call in tabbrowser.addTab()
|
||||
"stop@chrome://global/content/bindings/browser.xml|" +
|
||||
"addTab@chrome://browser/content/tabbrowser.xml|",
|
||||
|
||||
// tabbrowser.adjustTabstrip() call after tabopen animation has finished
|
||||
"adjustTabstrip@chrome://browser/content/tabbrowser.xml|" +
|
||||
"_handleNewTab@chrome://browser/content/tabbrowser.xml|" +
|
||||
@ -30,7 +26,20 @@ const EXPECTED_REFLOWS = [
|
||||
"get_scrollPosition@chrome://global/content/bindings/scrollbox.xml|" +
|
||||
"_fillTrailingGap@chrome://browser/content/tabbrowser.xml|" +
|
||||
"_handleNewTab@chrome://browser/content/tabbrowser.xml|" +
|
||||
"onxbltransitionend@chrome://browser/content/tabbrowser.xml|"
|
||||
"onxbltransitionend@chrome://browser/content/tabbrowser.xml|",
|
||||
|
||||
// The TabView iframe causes reflows in the parent document.
|
||||
"iQClass_height@chrome://browser/content/tabview.js|" +
|
||||
"GroupItem_getContentBounds@chrome://browser/content/tabview.js|" +
|
||||
"GroupItem_shouldStack@chrome://browser/content/tabview.js|" +
|
||||
"GroupItem_arrange@chrome://browser/content/tabview.js|" +
|
||||
"GroupItem_add@chrome://browser/content/tabview.js|" +
|
||||
"GroupItems_newTab@chrome://browser/content/tabview.js|" +
|
||||
"TabItem__reconnect@chrome://browser/content/tabview.js|" +
|
||||
"TabItem@chrome://browser/content/tabview.js|" +
|
||||
"TabItems_link@chrome://browser/content/tabview.js|" +
|
||||
"@chrome://browser/content/tabview.js|" +
|
||||
"addTab@chrome://browser/content/tabbrowser.xml|"
|
||||
];
|
||||
|
||||
const PREF_PRELOAD = "browser.newtab.preload";
|
||||
|
@ -1,23 +1,7 @@
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux32/common-opt"
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux32
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
mk_add_options MOZ_PGO=1
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,13 +1,7 @@
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-codesighs
|
||||
# This file is sourced by nightly, beta, and release mozconfigs.
|
||||
|
||||
# Options for rpm versions of mozconfigs
|
||||
PREFIX=/usr
|
||||
LIBDIR=${PREFIX}/lib
|
||||
ac_add_options --with-app-name=mozilla-nightly
|
||||
ac_add_options --disable-updater
|
||||
ac_add_options --prefix=$PREFIX
|
||||
ac_add_options --libdir=$LIBDIR
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux32
|
||||
|
||||
@ -19,10 +13,8 @@ export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
#Use ccache
|
||||
ac_add_options --with-ccache=/usr/bin/ccache
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
@ -1,5 +1,5 @@
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux32/common-opt"
|
||||
|
||||
ac_add_options --enable-codesighs
|
||||
ac_add_options --enable-signmar
|
||||
ac_add_options --enable-profiling
|
||||
@ -7,28 +7,12 @@ ac_add_options --enable-profiling
|
||||
# Nightlies only since this has a cost in performance
|
||||
ac_add_options --enable-js-diagnostics
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux32
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
# This will overwrite the default of stripping everything and keep the symbol table.
|
||||
# This is useful for profiling and debugging and only increases the package size
|
||||
# by 2 MBs.
|
||||
STRIP_FLAGS="--strip-debug"
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Use ccache
|
||||
ac_add_options --with-ccache=/usr/bin/ccache
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,24 +0,0 @@
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-codesighs
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux32
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
#Use ccache
|
||||
ac_add_options --with-ccache=/usr/bin/ccache
|
||||
|
||||
# QT Options
|
||||
export PKG_CONFIG_PATH=/tools/qt-4.6.3/qt/lib/pkgconfig
|
||||
ac_add_options --with-qtdir=/tools/qt-4.6.3/qt
|
||||
ac_add_options --enable-default-toolkit=cairo-qt
|
||||
ac_add_options --disable-crashreporter
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
@ -1,7 +1,13 @@
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux32/beta"
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux32/common-opt"
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
mk_add_options MOZ_PGO=1
|
||||
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,23 +1,7 @@
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux64/common-opt"
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
mk_add_options MOZ_PGO=1
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,13 +1,7 @@
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-codesighs
|
||||
# This file is sourced by the nightly, beta, and release mozconfigs.
|
||||
|
||||
# Options for rpm versions of mozconfigs
|
||||
PREFIX=/usr
|
||||
LIBDIR=${PREFIX}/lib64
|
||||
ac_add_options --with-app-name=mozilla-nightly
|
||||
ac_add_options --disable-updater
|
||||
ac_add_options --prefix=$PREFIX
|
||||
ac_add_options --libdir=$LIBDIR
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux
|
||||
|
||||
@ -19,10 +13,8 @@ export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
#Use ccache
|
||||
ac_add_options --with-ccache=/usr/bin/ccache
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
@ -1,5 +1,5 @@
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux64/common-opt"
|
||||
|
||||
ac_add_options --enable-codesighs
|
||||
ac_add_options --enable-signmar
|
||||
ac_add_options --enable-profiling
|
||||
@ -7,28 +7,12 @@ ac_add_options --enable-profiling
|
||||
# Nightlies only since this has a cost in performance
|
||||
ac_add_options --enable-js-diagnostics
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.linux
|
||||
|
||||
# Avoid dependency on libstdc++ 4.5
|
||||
ac_add_options --enable-stdcxx-compat
|
||||
|
||||
# This will overwrite the default of stripping everything and keep the symbol table.
|
||||
# This is useful for profiling and debugging and only increases the package size
|
||||
# by 2 MBs.
|
||||
STRIP_FLAGS="--strip-debug"
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Use ccache
|
||||
ac_add_options --with-ccache=/usr/bin/ccache
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,7 +1,13 @@
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux64/beta"
|
||||
. "$topsrcdir/browser/config/mozconfigs/linux64/common-opt"
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
mk_add_options MOZ_PGO=1
|
||||
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,21 +1,5 @@
|
||||
. $topsrcdir/build/macosx/universal/mozconfig
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
|
||||
|
||||
# Universal builds override the default of browser (bug 575283 comment 29)
|
||||
ac_add_options --enable-application=browser
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
20
browser/config/mozconfigs/macosx-universal/common-opt
Normal file
20
browser/config/mozconfigs/macosx-universal/common-opt
Normal file
@ -0,0 +1,20 @@
|
||||
# This file is sourced by the nightly, beta, and release mozconfigs.
|
||||
|
||||
. $topsrcdir/build/macosx/universal/mozconfig
|
||||
|
||||
# Universal builds override the default of browser (bug 575283 comment 29)
|
||||
ac_add_options --enable-application=browser
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
@ -1,10 +1,5 @@
|
||||
. $topsrcdir/build/macosx/universal/mozconfig
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
|
||||
|
||||
# Universal builds override the default of browser (bug 575283 comment 29)
|
||||
ac_add_options --enable-application=browser
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-codesighs
|
||||
ac_add_options --disable-install-strip
|
||||
ac_add_options --enable-signmar
|
||||
@ -15,17 +10,6 @@ ac_add_options --enable-dtrace
|
||||
# Nightlies only since this has a cost in performance
|
||||
ac_add_options --enable-js-diagnostics
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
ac_add_options --with-macbundlename-prefix=Firefox
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,7 +1,11 @@
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/beta"
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,25 +0,0 @@
|
||||
# Just like nightlies, but without tests, not on an update channel, and with
|
||||
# shark and dtrace enabled
|
||||
. $topsrcdir/build/macosx/universal/mozconfig
|
||||
|
||||
# Universal builds override the default of browser (bug 575283 comment 29)
|
||||
ac_add_options --enable-application=browser
|
||||
|
||||
ac_add_options --disable-tests
|
||||
ac_add_options --disable-install-strip
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
# shark specific options
|
||||
ac_add_options --enable-shark
|
||||
ac_add_options --enable-dtrace
|
||||
|
||||
# Need this to prevent name conflicts with the normal nightly build packages
|
||||
export MOZ_PKG_SPECIAL="shark"
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
ac_add_options --with-ccache
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
@ -1,31 +1,7 @@
|
||||
. "$topsrcdir/browser/config/mozconfigs/common"
|
||||
. "$topsrcdir/browser/config/mozconfigs/win32/common-opt"
|
||||
|
||||
mk_add_options MOZ_PGO=1
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-jemalloc
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test -z "${_PYMAKE}"; then
|
||||
mk_add_options MOZ_MAKE_FLAGS=-j1
|
||||
fi
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010
|
||||
fi
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
28
browser/config/mozconfigs/win32/common-opt
Normal file
28
browser/config/mozconfigs/win32/common-opt
Normal file
@ -0,0 +1,28 @@
|
||||
# This file is sourced by the nightly, beta, and release mozconfigs.
|
||||
|
||||
. "$topsrcdir/browser/config/mozconfigs/common"
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-jemalloc
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test -z "${_PYMAKE}"; then
|
||||
mk_add_options MOZ_MAKE_FLAGS=-j1
|
||||
fi
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010
|
||||
fi
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
@ -1,8 +1,5 @@
|
||||
. "$topsrcdir/browser/config/mozconfigs/common"
|
||||
. "$topsrcdir/browser/config/mozconfigs/win32/common-opt"
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --enable-jemalloc
|
||||
ac_add_options --enable-signmar
|
||||
ac_add_options --enable-profiling
|
||||
ac_add_options --enable-metro
|
||||
@ -10,25 +7,4 @@ ac_add_options --enable-metro
|
||||
# Nightlies only since this has a cost in performance
|
||||
ac_add_options --enable-js-diagnostics
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test -z "${_PYMAKE}"; then
|
||||
mk_add_options MOZ_MAKE_FLAGS=-j1
|
||||
fi
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2010
|
||||
fi
|
||||
|
||||
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -1,7 +1,13 @@
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
. "$topsrcdir/browser/config/mozconfigs/win32/beta"
|
||||
. "$topsrcdir/browser/config/mozconfigs/win32/common-opt"
|
||||
|
||||
mk_add_options MOZ_PGO=1
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -579,7 +579,7 @@ StackFrames.prototype = {
|
||||
this._addFrame(frame);
|
||||
}
|
||||
if (this.currentFrame == null) {
|
||||
this.selectFrame(0);
|
||||
DebuggerView.StackFrames.selectedDepth = 0;
|
||||
}
|
||||
if (this.activeThread.moreFrames) {
|
||||
DebuggerView.StackFrames.dirty = true;
|
||||
@ -639,8 +639,6 @@ StackFrames.prototype = {
|
||||
|
||||
// Move the editor's caret to the proper url and line.
|
||||
DebuggerView.updateEditor(url, line);
|
||||
// Highlight the stack frame at the specified depth.
|
||||
DebuggerView.StackFrames.highlightFrame(aDepth);
|
||||
// Highlight the breakpoint at the specified url and line if it exists.
|
||||
DebuggerView.Sources.highlightBreakpoint(url, line);
|
||||
// Don't display the watch expressions textbox inputs in the pane.
|
||||
|
@ -55,6 +55,8 @@ create({ constructor: SourcesView, proto: MenuContainer.prototype }, {
|
||||
this._cbTextbox.addEventListener("input", this._onConditionalTextboxInput, false);
|
||||
this._cbTextbox.addEventListener("keypress", this._onConditionalTextboxKeyPress, false);
|
||||
|
||||
this.autoFocusOnSelection = false;
|
||||
|
||||
// Show an empty label by default.
|
||||
this.empty();
|
||||
},
|
||||
|
@ -348,10 +348,9 @@ function StackFramesView() {
|
||||
|
||||
this._framesCache = new Map(); // Can't use a WeakMap because keys are numbers.
|
||||
this._onStackframeRemoved = this._onStackframeRemoved.bind(this);
|
||||
this._onClick = this._onClick.bind(this);
|
||||
this._onSelect = this._onSelect.bind(this);
|
||||
this._onScroll = this._onScroll.bind(this);
|
||||
this._afterScroll = this._afterScroll.bind(this);
|
||||
this._selectFrame = this._selectFrame.bind(this);
|
||||
}
|
||||
|
||||
create({ constructor: StackFramesView, proto: MenuContainer.prototype }, {
|
||||
@ -370,9 +369,12 @@ create({ constructor: StackFramesView, proto: MenuContainer.prototype }, {
|
||||
document.getElementById("debuggerCommands").appendChild(commandset);
|
||||
|
||||
this.node = new BreadcrumbsWidget(document.getElementById("stackframes"));
|
||||
this.node.addEventListener("mousedown", this._onClick, false);
|
||||
this.node.addEventListener("select", this._onSelect, false);
|
||||
this.node.addEventListener("scroll", this._onScroll, true);
|
||||
window.addEventListener("resize", this._onScroll, true);
|
||||
|
||||
this.autoFocusOnFirstItem = false;
|
||||
this.autoFocusOnSelection = false;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -381,7 +383,7 @@ create({ constructor: StackFramesView, proto: MenuContainer.prototype }, {
|
||||
destroy: function() {
|
||||
dumpn("Destroying the StackFramesView");
|
||||
|
||||
this.node.removeEventListener("mousedown", this._onClick, false);
|
||||
this.node.removeEventListener("select", this._onSelect, false);
|
||||
this.node.removeEventListener("scroll", this._onScroll, true);
|
||||
window.removeEventListener("resize", this._onScroll, true);
|
||||
},
|
||||
@ -423,21 +425,11 @@ create({ constructor: StackFramesView, proto: MenuContainer.prototype }, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlights a frame in this stackframes container.
|
||||
*
|
||||
* Selects the frame at the specified depth in this container.
|
||||
* @param number aDepth
|
||||
* The frame depth specified by the debugger controller.
|
||||
*/
|
||||
highlightFrame: function(aDepth) {
|
||||
let selectedItem = this.selectedItem = this._framesCache.get(aDepth);
|
||||
|
||||
for (let item in this) {
|
||||
if (item != selectedItem) {
|
||||
item.attachment.popup.menuitem.removeAttribute("checked");
|
||||
} else {
|
||||
item.attachment.popup.menuitem.setAttribute("checked", "");
|
||||
}
|
||||
}
|
||||
set selectedDepth(aDepth) {
|
||||
this.selectedItem = this._framesCache.get(aDepth);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -511,7 +503,7 @@ create({ constructor: StackFramesView, proto: MenuContainer.prototype }, {
|
||||
|
||||
let command = document.createElement("command");
|
||||
command.id = commandId;
|
||||
command.addEventListener("command", this._selectFrame.bind(this, aDepth), false);
|
||||
command.addEventListener("command", () => this.selectedDepth = aDepth, false);
|
||||
|
||||
let menuitem = document.createElement("menuitem");
|
||||
menuitem.id = menuitemId;
|
||||
@ -572,17 +564,21 @@ create({ constructor: StackFramesView, proto: MenuContainer.prototype }, {
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the stackframes container.
|
||||
* The select listener for the stackframes container.
|
||||
*/
|
||||
_onClick: function(e) {
|
||||
if (e && e.button != 0) {
|
||||
// Only allow left-click to trigger this event.
|
||||
return;
|
||||
}
|
||||
let item = this.getItemForElement(e.target);
|
||||
if (item) {
|
||||
// The container is not empty and we clicked on an actual item.
|
||||
this._selectFrame(item.attachment.depth);
|
||||
_onSelect: function(e) {
|
||||
let stackframeItem = this.selectedItem;
|
||||
if (stackframeItem) {
|
||||
// The container is not empty and an actual item was selected.
|
||||
gStackFrames.selectFrame(stackframeItem.attachment.depth);
|
||||
|
||||
for (let otherItem in this) {
|
||||
if (otherItem != stackframeItem) {
|
||||
otherItem.attachment.popup.menuitem.removeAttribute("checked");
|
||||
} else {
|
||||
otherItem.attachment.popup.menuitem.setAttribute("checked", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -617,16 +613,6 @@ create({ constructor: StackFramesView, proto: MenuContainer.prototype }, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Requests selection of a frame from the controller.
|
||||
*
|
||||
* @param number aDepth
|
||||
* The depth of the frame in the stack.
|
||||
*/
|
||||
_selectFrame: function(aDepth) {
|
||||
DebuggerController.StackFrames.selectFrame(aDepth);
|
||||
},
|
||||
|
||||
_framesCache: null,
|
||||
_commandset: null,
|
||||
_menupopup: null,
|
||||
|
@ -354,9 +354,7 @@ let DebuggerView = {
|
||||
}
|
||||
// If the requested source exists, display it and update.
|
||||
else if (this.Sources.containsValue(aUrl) && !aFlags.noSwitch) {
|
||||
this.Sources.node.preventFocusOnSelection = true;
|
||||
this.Sources.selectedValue = aUrl;
|
||||
this.Sources.node.preventFocusOnSelection = false;
|
||||
set(aLine);
|
||||
}
|
||||
// Dumb request, invalidate the caret position and debug location.
|
||||
|
@ -54,6 +54,7 @@ MOCHITEST_BROWSER_TESTS = \
|
||||
browser_dbg_reload-preferred-script.js \
|
||||
browser_dbg_pane-collapse.js \
|
||||
browser_dbg_panesize-inner.js \
|
||||
browser_dbg_breadcrumbs-access.js \
|
||||
browser_dbg_stack-01.js \
|
||||
browser_dbg_stack-02.js \
|
||||
browser_dbg_stack-03.js \
|
||||
|
154
browser/devtools/debugger/test/browser_dbg_breadcrumbs-access.js
Normal file
154
browser/devtools/debugger/test/browser_dbg_breadcrumbs-access.js
Normal file
@ -0,0 +1,154 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
resumed = true;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onScriptShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
let editor = gDebugger.DebuggerView.editor;
|
||||
let sources = gDebugger.DebuggerView.Sources;
|
||||
let stackframes = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (1).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (1).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (1).");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
is(editor.getCaretPosition().line, 6,
|
||||
"The source editor caret position was incorrect (2).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (2).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (2).");
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (3).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (3).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (3).");
|
||||
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
stackframes.selectedItem.target,
|
||||
gDebugger);
|
||||
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (4).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (4).");
|
||||
is(stackframes.selectedIndex, 2,
|
||||
"The currently selected stackframe is incorrect (4).");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
is(editor.getCaretPosition().line, 4,
|
||||
"The source editor caret position was incorrect (5).");
|
||||
is(sources.selectedLabel, "test-script-switching-01.js",
|
||||
"The currently selected source is incorrect (5).");
|
||||
is(stackframes.selectedIndex, 1,
|
||||
"The currently selected stackframe is incorrect (5).");
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
|
||||
is(editor.getCaretPosition().line, 4,
|
||||
"The source editor caret position was incorrect (6).");
|
||||
is(sources.selectedLabel, "test-script-switching-01.js",
|
||||
"The currently selected source is incorrect (6).");
|
||||
is(stackframes.selectedIndex, 0,
|
||||
"The currently selected stackframe is incorrect (6).");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (7).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (7).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (7).");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
is(editor.getCaretPosition().line, 4,
|
||||
"The source editor caret position was incorrect (8).");
|
||||
is(sources.selectedLabel, "test-script-switching-01.js",
|
||||
"The currently selected source is incorrect (8).");
|
||||
is(stackframes.selectedIndex, 0,
|
||||
"The currently selected stackframe is incorrect (8).");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
|
||||
EventUtils.sendKey("HOME", gDebugger);
|
||||
});
|
||||
|
||||
EventUtils.sendKey("END", gDebugger);
|
||||
});
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
}
|
@ -530,6 +530,14 @@ let Prefs = new ViewHelpers.Prefs("devtools.netmonitor", {
|
||||
networkDetailsHeight: ["Int", "panes-network-details-height"]
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns true if this is document is in RTL mode.
|
||||
* @return boolean
|
||||
*/
|
||||
XPCOMUtils.defineLazyGetter(window, "isRTL", function() {
|
||||
return window.getComputedStyle(document.documentElement, null).direction == "rtl";
|
||||
});
|
||||
|
||||
/**
|
||||
* Convenient way of emitting events from the panel window.
|
||||
*/
|
||||
|
@ -897,10 +897,11 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
let startCapNode = $(".requests-menu-timings-cap.start", target);
|
||||
let endCapNode = $(".requests-menu-timings-cap.end", target);
|
||||
let totalNode = $(".requests-menu-timings-total", target);
|
||||
let direction = window.isRTL ? -1 : 1;
|
||||
|
||||
// Render the timing information at a specific horizontal translation
|
||||
// based on the delta to the first monitored event network.
|
||||
let translateX = "translateX(" + attachment.startedDeltaMillis + "px)";
|
||||
let translateX = "translateX(" + (direction * attachment.startedDeltaMillis) + "px)";
|
||||
|
||||
// Based on the total time passed until the last request, rescale
|
||||
// all the waterfalls to a reasonable size.
|
||||
@ -911,8 +912,8 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
let revScaleX = "scaleX(" + (1 / scale) + ")";
|
||||
|
||||
timingsNode.style.transform = scaleX + " " + translateX;
|
||||
startCapNode.style.transform = revScaleX + " translateX(0.5px)";
|
||||
endCapNode.style.transform = revScaleX + " translateX(-0.5px)";
|
||||
startCapNode.style.transform = revScaleX + " translateX(" + (direction * 0.5) + "px)";
|
||||
endCapNode.style.transform = revScaleX + " translateX(" + (direction * -0.5) + "px)";
|
||||
totalNode.style.transform = revScaleX;
|
||||
}
|
||||
},
|
||||
@ -947,10 +948,11 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
|
||||
// Insert one label for each division on the current scale.
|
||||
let fragment = document.createDocumentFragment();
|
||||
let direction = window.isRTL ? -1 : 1;
|
||||
|
||||
for (let x = 0; x < availableWidth; x += scaledStep) {
|
||||
let divisionMS = (x / aScale).toFixed(0);
|
||||
let translateX = "translateX(" + (x | 0) + "px)";
|
||||
let translateX = "translateX(" + ((direction * x) | 0) + "px)";
|
||||
|
||||
let node = document.createElement("label");
|
||||
let text = L10N.getFormatStr("networkMenu.divisionMS", divisionMS);
|
||||
@ -1009,7 +1011,8 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
for (let i = 1; i <= REQUESTS_WATERFALL_BACKGROUND_TICKS_SCALES; i++) {
|
||||
let increment = scaledStep * Math.pow(2, i);
|
||||
for (let x = 0; x < canvasWidth; x += increment) {
|
||||
data32[x | 0] = (alphaComponent << 24) | (b << 16) | (g << 8) | r;
|
||||
let position = (window.isRTL ? canvasWidth - x : x) | 0;
|
||||
data32[position] = (alphaComponent << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
alphaComponent += REQUESTS_WATERFALL_BACKGROUND_TICKS_OPACITY_ADD;
|
||||
}
|
||||
@ -1035,6 +1038,9 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
* Hides the overflowing columns in the requests table.
|
||||
*/
|
||||
_hideOverflowingColumns: function() {
|
||||
if (window.isRTL) {
|
||||
return;
|
||||
}
|
||||
let table = $("#network-table");
|
||||
let toolbar = $("#requests-menu-toolbar");
|
||||
let columns = [
|
||||
@ -1202,7 +1208,11 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
let waterfall = $("#requests-menu-waterfall-header-box");
|
||||
let containerBounds = container.getBoundingClientRect();
|
||||
let waterfallBounds = waterfall.getBoundingClientRect();
|
||||
this._cachedWaterfallWidth = containerBounds.width - waterfallBounds.left;
|
||||
if (!window.isRTL) {
|
||||
this._cachedWaterfallWidth = containerBounds.width - waterfallBounds.left;
|
||||
} else {
|
||||
this._cachedWaterfallWidth = waterfallBounds.right;
|
||||
}
|
||||
}
|
||||
return this._cachedWaterfallWidth;
|
||||
},
|
||||
|
@ -3,6 +3,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#toolbar-labels {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#details-pane-toggle[disabled] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ const Cu = Components.utils;
|
||||
const ENSURE_SELECTION_VISIBLE_DELAY = 50; // ms
|
||||
|
||||
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
|
||||
Cu.import("resource:///modules/devtools/shared/event-emitter.js");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["BreadcrumbsWidget"];
|
||||
|
||||
@ -45,6 +46,8 @@ this.BreadcrumbsWidget = function BreadcrumbsWidget(aNode) {
|
||||
this._list.setAttribute("flex", "1");
|
||||
this._list.setAttribute("orient", "horizontal");
|
||||
this._list.setAttribute("clicktoscroll", "true")
|
||||
this._list.addEventListener("keypress", e => this.emit("keyPress", e), false);
|
||||
this._list.addEventListener("mousedown", e => this.emit("mousePress", e), false);
|
||||
this._parent.appendChild(this._list);
|
||||
|
||||
// By default, hide the arrows. We let the arrowscrollbox show them
|
||||
@ -54,6 +57,9 @@ this.BreadcrumbsWidget = function BreadcrumbsWidget(aNode) {
|
||||
this._list.addEventListener("underflow", this._onUnderflow.bind(this), false);
|
||||
this._list.addEventListener("overflow", this._onOverflow.bind(this), false);
|
||||
|
||||
// This widget emits events that can be handled in a MenuContainer.
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
// Delegate some of the associated node's methods to satisfy the interface
|
||||
// required by MenuContainer instances.
|
||||
ViewHelpers.delegateWidgetAttributeMethods(this, aNode);
|
||||
|
@ -78,14 +78,6 @@ SideMenuWidget.prototype = {
|
||||
*/
|
||||
sortedGroups: true,
|
||||
|
||||
/**
|
||||
* Specifies if when an item is selected in this container (via the
|
||||
* selectedItem setter), that respective item should be focused as well.
|
||||
* You can enable this flag, for example, to maintain a certain node
|
||||
* selected but visually indicate a different selection in this container.
|
||||
*/
|
||||
preventFocusOnSelection: false,
|
||||
|
||||
/**
|
||||
* Specifies if this container should try to keep the selected item visible.
|
||||
* (For example, when new items are added the selection is brought into view).
|
||||
@ -142,9 +134,6 @@ SideMenuWidget.prototype = {
|
||||
if (this.maintainSelectionVisible) {
|
||||
this.ensureSelectionIsVisible({ withGroup: true, delayed: true });
|
||||
}
|
||||
if (this._orderedMenuElementsArray.length == 1) {
|
||||
this._list.focus();
|
||||
}
|
||||
if (maintainScrollAtBottom) {
|
||||
this._list.scrollTop = this._list.scrollHeight;
|
||||
}
|
||||
@ -226,7 +215,6 @@ SideMenuWidget.prototype = {
|
||||
node.classList.add("selected");
|
||||
node.parentNode.classList.add("selected");
|
||||
this._selectedItem = node;
|
||||
!this.preventFocusOnSelection && node.focus();
|
||||
} else {
|
||||
node.classList.remove("selected");
|
||||
node.parentNode.classList.remove("selected");
|
||||
|
@ -587,7 +587,7 @@ MenuContainer.prototype = {
|
||||
|
||||
/**
|
||||
* Prepares an item to be added to this container. This allows for a large
|
||||
* number of items to be batched up before alphabetically sorted and added.
|
||||
* number of items to be batched up before being sorted and added.
|
||||
*
|
||||
* If the "staged" flag is not set to true, the item will be immediately
|
||||
* inserted at the correct position in this container, so that all the items
|
||||
@ -625,13 +625,13 @@ MenuContainer.prototype = {
|
||||
|
||||
// Batch the item to be added later.
|
||||
if (aOptions.staged) {
|
||||
// Commit operations will ignore any specified index.
|
||||
// An ulterior commit operation will ignore any specified index.
|
||||
delete aOptions.index;
|
||||
return void this._stagedItems.push({ item: item, options: aOptions });
|
||||
}
|
||||
// Find the target position in this container and insert the item there.
|
||||
if (!("index" in aOptions)) {
|
||||
return this._insertItemAt(this._findExpectedIndex(item), item, aOptions);
|
||||
return this._insertItemAt(this._findExpectedIndexFor(item), item, aOptions);
|
||||
}
|
||||
// Insert the item at the specified index. If negative or out of bounds,
|
||||
// the item will be simply appended.
|
||||
@ -669,14 +669,13 @@ MenuContainer.prototype = {
|
||||
* True if a selected item was available, false otherwise.
|
||||
*/
|
||||
refresh: function() {
|
||||
let selectedValue = this.selectedValue;
|
||||
if (!selectedValue) {
|
||||
let selectedItem = this.selectedItem;
|
||||
if (!selectedItem) {
|
||||
return false;
|
||||
}
|
||||
let entangledLabel = this.getItemByValue(selectedValue)._label;
|
||||
this._container.removeAttribute("notice");
|
||||
this._container.setAttribute("label", entangledLabel);
|
||||
this._container.setAttribute("tooltiptext", selectedValue);
|
||||
this._container.setAttribute("label", selectedItem._label);
|
||||
this._container.setAttribute("tooltiptext", selectedItem._value);
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -946,7 +945,13 @@ MenuContainer.prototype = {
|
||||
let targetElement = aItem ? aItem._target : null;
|
||||
let prevElement = this._container.selectedItem;
|
||||
|
||||
// Prevent selecting the same item again, so return early.
|
||||
// Make sure the currently selected item's target element is also focused.
|
||||
if (this.autoFocusOnSelection && targetElement) {
|
||||
targetElement.focus();
|
||||
}
|
||||
|
||||
// Prevent selecting the same item again and avoid dispatching
|
||||
// a redundant selection event, so return early.
|
||||
if (targetElement == prevElement) {
|
||||
return;
|
||||
}
|
||||
@ -981,6 +986,42 @@ MenuContainer.prototype = {
|
||||
set selectedValue(aValue)
|
||||
this.selectedItem = this._itemsByValue.get(aValue),
|
||||
|
||||
/**
|
||||
* Focus this container the first time an element is inserted?
|
||||
*
|
||||
* If this flag is set to true, then when the first item is inserted in
|
||||
* this container (and thus it's the only item available), its corresponding
|
||||
* target element is focused as well.
|
||||
*/
|
||||
autoFocusOnFirstItem: true,
|
||||
|
||||
/**
|
||||
* Focus on selection?
|
||||
*
|
||||
* If this flag is set to true, then whenever an item is selected in
|
||||
* this container (e.g. via the selectedIndex or selectedItem setters),
|
||||
* its corresponding target element is focused as well.
|
||||
*
|
||||
* You can disable this flag, for example, to maintain a certain node
|
||||
* focused but visually indicate a different selection in this container.
|
||||
*/
|
||||
autoFocusOnSelection: true,
|
||||
|
||||
/**
|
||||
* Focus on input (e.g. mouse click)?
|
||||
*
|
||||
* If this flag is set to true, then whenever an item receives user input in
|
||||
* this container, its corresponding target element is focused as well.
|
||||
*/
|
||||
autoFocusOnInput: true,
|
||||
|
||||
/**
|
||||
* The number of elements in this container to jump when Page Up or Page Down
|
||||
* keys are pressed. If falsy, then the page size will be based on the
|
||||
* number of visible items in the container.
|
||||
*/
|
||||
pageSize: 0,
|
||||
|
||||
/**
|
||||
* Focuses the first visible item in this container.
|
||||
*/
|
||||
@ -1323,7 +1364,7 @@ MenuContainer.prototype = {
|
||||
* @return number
|
||||
* The expected item index.
|
||||
*/
|
||||
_findExpectedIndex: function(aItem) {
|
||||
_findExpectedIndexFor: function(aItem) {
|
||||
let itemCount = this.itemCount;
|
||||
|
||||
for (let i = 0; i < itemCount; i++) {
|
||||
@ -1367,6 +1408,9 @@ MenuContainer.prototype = {
|
||||
if (!this._currentFilterPredicate(aItem)) {
|
||||
aItem._target.hidden = true;
|
||||
}
|
||||
if (this.autoFocusOnFirstItem && this._itemsByElement.size == 1) {
|
||||
aItem._target.focus();
|
||||
}
|
||||
if (aOptions.attributes) {
|
||||
aItem.setAttributes(aOptions.attributes, aItem._target);
|
||||
}
|
||||
@ -1424,13 +1468,6 @@ MenuContainer.prototype = {
|
||||
this._itemsByElement.delete(aItem._target);
|
||||
},
|
||||
|
||||
/**
|
||||
* The number of elements in this container to jump when Page Up or Page Down
|
||||
* keys are pressed. If falsy, then the page size will be based on the
|
||||
* number of visible items in the container.
|
||||
*/
|
||||
pageSize: 0,
|
||||
|
||||
/**
|
||||
* The keyPress event listener for this container.
|
||||
* @param string aName
|
||||
@ -1442,9 +1479,11 @@ MenuContainer.prototype = {
|
||||
|
||||
switch (aEvent.keyCode) {
|
||||
case aEvent.DOM_VK_UP:
|
||||
case aEvent.DOM_VK_LEFT:
|
||||
this.focusPrevItem();
|
||||
return;
|
||||
case aEvent.DOM_VK_DOWN:
|
||||
case aEvent.DOM_VK_RIGHT:
|
||||
this.focusNextItem();
|
||||
return;
|
||||
case aEvent.DOM_VK_PAGE_UP:
|
||||
@ -1472,10 +1511,13 @@ MenuContainer.prototype = {
|
||||
// Only allow left-click to trigger this event.
|
||||
return;
|
||||
}
|
||||
|
||||
let item = this.getItemForElement(aEvent.target);
|
||||
if (item) {
|
||||
// The container is not empty and we clicked on an actual item.
|
||||
this.selectedItem = item;
|
||||
// Make sure the current event's target element is also focused.
|
||||
this.autoFocusOnInput && item._target.focus();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -9,6 +9,10 @@
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item {
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
/* SideMenuWidget */
|
||||
|
||||
.side-menu-widget-container {
|
||||
|
@ -1192,14 +1192,34 @@ WebConsoleFrame.prototype = {
|
||||
severity = SEVERITY_WARNING;
|
||||
}
|
||||
|
||||
let objectActors = new Set();
|
||||
|
||||
// Gather the actor IDs.
|
||||
for (let prop of ["errorMessage", "lineText"]) {
|
||||
let grip = aScriptError[prop];
|
||||
if (WebConsoleUtils.isActorGrip(grip)) {
|
||||
objectActors.add(grip.actor);
|
||||
}
|
||||
}
|
||||
|
||||
let errorMessage = aScriptError.errorMessage;
|
||||
if (errorMessage.type && errorMessage.type == "longString") {
|
||||
errorMessage = errorMessage.initial;
|
||||
}
|
||||
|
||||
let node = this.createMessageNode(aCategory, severity,
|
||||
aScriptError.errorMessage,
|
||||
errorMessage,
|
||||
aScriptError.sourceName,
|
||||
aScriptError.lineNumber, null, null,
|
||||
aScriptError.timeStamp);
|
||||
if (aScriptError.private) {
|
||||
node.setAttribute("private", true);
|
||||
}
|
||||
|
||||
if (objectActors.size > 0) {
|
||||
node._objectActors = objectActors;
|
||||
}
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
@ -1225,10 +1245,32 @@ WebConsoleFrame.prototype = {
|
||||
*/
|
||||
handleLogMessage: function WCF_handleLogMessage(aPacket)
|
||||
{
|
||||
this.outputMessage(CATEGORY_JS, () => {
|
||||
return this.createMessageNode(CATEGORY_JS, SEVERITY_LOG, aPacket.message,
|
||||
null, null, null, null, aPacket.timeStamp);
|
||||
});
|
||||
if (aPacket.message) {
|
||||
this.outputMessage(CATEGORY_JS, this._reportLogMessage, [aPacket]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Display log messages received from the server.
|
||||
*
|
||||
* @private
|
||||
* @param object aPacket
|
||||
* The message packet received from the server.
|
||||
* @return nsIDOMElement
|
||||
* The message element to render for the given log message.
|
||||
*/
|
||||
_reportLogMessage: function WCF__reportLogMessage(aPacket)
|
||||
{
|
||||
let msg = aPacket.message;
|
||||
if (msg.type && msg.type == "longString") {
|
||||
msg = msg.initial;
|
||||
}
|
||||
let node = this.createMessageNode(CATEGORY_JS, SEVERITY_LOG, msg, null,
|
||||
null, null, null, aPacket.timeStamp);
|
||||
if (WebConsoleUtils.isActorGrip(aPacket.message)) {
|
||||
node._objectActors = new Set([aPacket.message.actor]);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1992,6 +2034,22 @@ WebConsoleFrame.prototype = {
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (category == CATEGORY_JS &&
|
||||
methodOrNode == this.reportPageError) {
|
||||
let pageError = args[1];
|
||||
for (let prop of ["errorMessage", "lineText"]) {
|
||||
let grip = pageError[prop];
|
||||
if (WebConsoleUtils.isActorGrip(grip)) {
|
||||
this._releaseObject(grip.actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (category == CATEGORY_JS &&
|
||||
methodOrNode == this._reportLogMessage) {
|
||||
if (WebConsoleUtils.isActorGrip(args[0].message)) {
|
||||
this._releaseObject(args[0].message.actor);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -40,6 +40,9 @@ var FindHandler = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._fastFind.currentWindow)
|
||||
return;
|
||||
|
||||
let selection = this._fastFind.currentWindow.getSelection();
|
||||
if (!selection.rangeCount || selection.isCollapsed) {
|
||||
// The selection can be into an input or a textarea element
|
||||
|
@ -3,6 +3,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* We don't support zooming yet, disable Animated zoom by clamping it to the default zoom. */
|
||||
const kBrowserFindZoomLevelMin = 1;
|
||||
const kBrowserFindZoomLevelMax = 1;
|
||||
|
||||
var FindHelperUI = {
|
||||
type: "find",
|
||||
commands: {
|
||||
@ -175,8 +179,8 @@ var FindHelperUI = {
|
||||
|
||||
// Clamp the zoom level relatively to the default zoom level of the page
|
||||
let defaultZoomLevel = Browser.selectedTab.getDefaultZoomLevel();
|
||||
zoomLevel = Util.clamp(zoomLevel, (defaultZoomLevel * kBrowserFormZoomLevelMin),
|
||||
(defaultZoomLevel * kBrowserFormZoomLevelMax));
|
||||
zoomLevel = Util.clamp(zoomLevel, (defaultZoomLevel * kBrowserFindZoomLevelMin),
|
||||
(defaultZoomLevel * kBrowserFindZoomLevelMax));
|
||||
zoomLevel = Browser.selectedTab.clampZoomLevel(zoomLevel);
|
||||
|
||||
let zoomRect = Browser._getZoomRectForPoint(aElementRect.center().x, aElementRect.y, zoomLevel);
|
||||
|
@ -8,9 +8,6 @@
|
||||
* - Provides autocomplete box for input fields.
|
||||
*/
|
||||
|
||||
const kBrowserFormZoomLevelMin = 0.8;
|
||||
const kBrowserFormZoomLevelMax = 2.0;
|
||||
|
||||
var FormHelperUI = {
|
||||
_debugEvents: false,
|
||||
_currentBrowser: null,
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 804 B |
@ -29,12 +29,18 @@
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-header:not(:last-child),
|
||||
.requests-menu-subitem:not(:last-child) {
|
||||
.requests-menu-header:not(:last-child):-moz-locale-dir(ltr),
|
||||
.requests-menu-subitem:not(:last-child):-moz-locale-dir(ltr) {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: 1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-header:not(:last-child):-moz-locale-dir(rtl),
|
||||
.requests-menu-subitem:not(:last-child):-moz-locale-dir(rtl) {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: -1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
@ -171,7 +177,6 @@ box.requests-menu-status[code^="5"] {
|
||||
-moz-padding-start: 4px;
|
||||
-moz-border-start: 1px dotted #999;
|
||||
font-size: 75%;
|
||||
text-align: left;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@ -179,6 +184,14 @@ box.requests-menu-status[code^="5"] {
|
||||
-moz-margin-start: -100px !important; /* Don't affect layout. */
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
/* Network requests table: waterfall items */
|
||||
|
||||
.requests-menu-subitem.requests-menu-waterfall {
|
||||
@ -189,15 +202,30 @@ box.requests-menu-status[code^="5"] {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.requests-menu-timings {
|
||||
.requests-menu-subitem.requests-menu-waterfall:-moz-locale-dir(rtl) {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total {
|
||||
-moz-padding-start: 8px;
|
||||
font-size: 85%;
|
||||
font-weight: 600;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap {
|
||||
@ -208,16 +236,32 @@ box.requests-menu-status[code^="5"] {
|
||||
|
||||
.requests-menu-timings-cap.start {
|
||||
-moz-border-end: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end {
|
||||
-moz-border-start: none;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(ltr) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(rtl) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(ltr) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(rtl) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box {
|
||||
height: 10px;
|
||||
border-top: 1px solid #fff;
|
||||
|
@ -123,7 +123,6 @@ browser.jar:
|
||||
* skin/classic/browser/devtools/common.css (devtools/common.css)
|
||||
skin/classic/browser/devtools/dark-theme.css (devtools/dark-theme.css)
|
||||
skin/classic/browser/devtools/light-theme.css (devtools/light-theme.css)
|
||||
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/commandline.png (devtools/commandline.png)
|
||||
skin/classic/browser/devtools/command-paintflashing.png (devtools/command-paintflashing.png)
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 804 B |
@ -29,12 +29,18 @@
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-header:not(:last-child),
|
||||
.requests-menu-subitem:not(:last-child) {
|
||||
.requests-menu-header:not(:last-child):-moz-locale-dir(ltr),
|
||||
.requests-menu-subitem:not(:last-child):-moz-locale-dir(ltr) {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: 1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-header:not(:last-child):-moz-locale-dir(rtl),
|
||||
.requests-menu-subitem:not(:last-child):-moz-locale-dir(rtl) {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: -1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
@ -171,7 +177,6 @@ box.requests-menu-status[code^="5"] {
|
||||
-moz-padding-start: 4px;
|
||||
-moz-border-start: 1px dotted #999;
|
||||
font-size: 75%;
|
||||
text-align: left;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@ -179,6 +184,14 @@ box.requests-menu-status[code^="5"] {
|
||||
-moz-margin-start: -100px !important; /* Don't affect layout. */
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
/* Network requests table: waterfall items */
|
||||
|
||||
.requests-menu-subitem.requests-menu-waterfall {
|
||||
@ -189,15 +202,30 @@ box.requests-menu-status[code^="5"] {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.requests-menu-timings {
|
||||
.requests-menu-subitem.requests-menu-waterfall:-moz-locale-dir(rtl) {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total {
|
||||
-moz-padding-start: 8px;
|
||||
font-size: 85%;
|
||||
font-weight: 600;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap {
|
||||
@ -208,16 +236,32 @@ box.requests-menu-status[code^="5"] {
|
||||
|
||||
.requests-menu-timings-cap.start {
|
||||
-moz-border-end: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end {
|
||||
-moz-border-start: none;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(ltr) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(rtl) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(ltr) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(rtl) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box {
|
||||
height: 10px;
|
||||
border-top: 1px solid #fff;
|
||||
|
@ -212,7 +212,6 @@ browser.jar:
|
||||
skin/classic/browser/devtools/dark-theme.css (devtools/dark-theme.css)
|
||||
skin/classic/browser/devtools/light-theme.css (devtools/light-theme.css)
|
||||
skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/browser/devtools/commandline.png (devtools/commandline.png)
|
||||
skin/classic/browser/devtools/command-paintflashing.png (devtools/command-paintflashing.png)
|
||||
skin/classic/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 804 B |
@ -29,12 +29,18 @@
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-header:not(:last-child),
|
||||
.requests-menu-subitem:not(:last-child) {
|
||||
.requests-menu-header:not(:last-child):-moz-locale-dir(ltr),
|
||||
.requests-menu-subitem:not(:last-child):-moz-locale-dir(ltr) {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: 1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-header:not(:last-child):-moz-locale-dir(rtl),
|
||||
.requests-menu-subitem:not(:last-child):-moz-locale-dir(rtl) {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: -1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
@ -171,7 +177,6 @@ box.requests-menu-status[code^="5"] {
|
||||
-moz-padding-start: 4px;
|
||||
-moz-border-start: 1px dotted #999;
|
||||
font-size: 90%;
|
||||
text-align: left;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@ -179,6 +184,14 @@ box.requests-menu-status[code^="5"] {
|
||||
-moz-margin-start: -100px !important; /* Don't affect layout. */
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-division:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
/* Network requests table: waterfall items */
|
||||
|
||||
.requests-menu-subitem.requests-menu-waterfall {
|
||||
@ -189,15 +202,30 @@ box.requests-menu-status[code^="5"] {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.requests-menu-timings {
|
||||
.requests-menu-subitem.requests-menu-waterfall:-moz-locale-dir(rtl) {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(ltr) {
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total:-moz-locale-dir(rtl) {
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-total {
|
||||
-moz-padding-start: 8px;
|
||||
font-size: 85%;
|
||||
font-weight: 600;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap {
|
||||
@ -208,16 +236,32 @@ box.requests-menu-status[code^="5"] {
|
||||
|
||||
.requests-menu-timings-cap.start {
|
||||
-moz-border-end: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end {
|
||||
-moz-border-start: none;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(ltr) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.start:-moz-locale-dir(rtl) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(ltr) {
|
||||
border-radius: 0 4px 4px 0;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-cap.end:-moz-locale-dir(rtl) {
|
||||
border-radius: 4px 0 0 4px;
|
||||
transform-origin: right center;
|
||||
}
|
||||
|
||||
.requests-menu-timings-box {
|
||||
height: 10px;
|
||||
border-top: 1px solid #fff;
|
||||
|
@ -150,7 +150,6 @@ browser.jar:
|
||||
skin/classic/browser/devtools/dark-theme.css (devtools/dark-theme.css)
|
||||
skin/classic/browser/devtools/light-theme.css (devtools/light-theme.css)
|
||||
skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/browser/devtools/commandline.png (devtools/commandline.png)
|
||||
skin/classic/browser/devtools/alerticon-warning.png (devtools/alerticon-warning.png)
|
||||
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
|
||||
@ -403,7 +402,6 @@ browser.jar:
|
||||
skin/classic/aero/browser/devtools/dark-theme.css (devtools/dark-theme.css)
|
||||
skin/classic/aero/browser/devtools/light-theme.css (devtools/light-theme.css)
|
||||
skin/classic/aero/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/aero/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/aero/browser/devtools/commandline.png (devtools/commandline.png)
|
||||
skin/classic/aero/browser/devtools/command-paintflashing.png (devtools/command-paintflashing.png)
|
||||
skin/classic/aero/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
|
||||
|
@ -318,6 +318,15 @@ nsFrameLoader::LoadFrame()
|
||||
src.Trim(" \t\n\r");
|
||||
|
||||
if (src.IsEmpty()) {
|
||||
// If the frame is a XUL element and has the attribute 'nodefaultsrc=true'
|
||||
// then we will not use 'about:blank' as fallback but return early without
|
||||
// starting a load if no 'src' attribute is given (or it's empty).
|
||||
if (mOwnerContent->IsXUL() &&
|
||||
mOwnerContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::nodefaultsrc,
|
||||
nsGkAtoms::_true, eCaseMatters)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
src.AssignLiteral("about:blank");
|
||||
}
|
||||
|
||||
|
@ -607,6 +607,7 @@ GK_ATOM(no, "no")
|
||||
GK_ATOM(noautohide, "noautohide")
|
||||
GK_ATOM(nobr, "nobr")
|
||||
GK_ATOM(node, "node")
|
||||
GK_ATOM(nodefaultsrc, "nodefaultsrc")
|
||||
GK_ATOM(nodeSet, "node-set")
|
||||
GK_ATOM(noembed, "noembed")
|
||||
GK_ATOM(noframes, "noframes")
|
||||
|
@ -662,6 +662,11 @@ nsRange::ContentRemoved(nsIDocument* aDocument,
|
||||
gravitateEnd = true;
|
||||
}
|
||||
|
||||
if (!mEnableGravitationOnElementRemoval) {
|
||||
// Do not gravitate.
|
||||
return;
|
||||
}
|
||||
|
||||
if (gravitateStart || gravitateEnd) {
|
||||
DoSetRange(gravitateStart ? container : mStartParent.get(),
|
||||
gravitateStart ? aIndexInContainer : mStartOffset,
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
, mInSelection(false)
|
||||
, mStartOffsetWasIncremented(false)
|
||||
, mEndOffsetWasIncremented(false)
|
||||
, mEnableGravitationOnElementRemoval(true)
|
||||
#ifdef DEBUG
|
||||
, mAssertNextInsertOrAppendIndex(-1)
|
||||
, mAssertNextInsertOrAppendNode(nullptr)
|
||||
@ -72,6 +73,20 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsRange, nsIDOMRange)
|
||||
|
||||
/**
|
||||
* The DOM Range spec requires that when a node is removed from its parent,
|
||||
* and the node's subtree contains the start or end point of a range, that
|
||||
* start or end point is moved up to where the node was removed from its
|
||||
* parent.
|
||||
* For some internal uses of Ranges it's useful to disable that behavior,
|
||||
* so that a range of children within a single parent is preserved even if
|
||||
* that parent is removed from the document tree.
|
||||
*/
|
||||
void SetEnableGravitationOnElementRemoval(bool aEnable)
|
||||
{
|
||||
mEnableGravitationOnElementRemoval = aEnable;
|
||||
}
|
||||
|
||||
// nsIDOMRange interface
|
||||
NS_DECL_NSIDOMRANGE
|
||||
|
||||
@ -299,6 +314,7 @@ protected:
|
||||
bool mInSelection;
|
||||
bool mStartOffsetWasIncremented;
|
||||
bool mEndOffsetWasIncremented;
|
||||
bool mEnableGravitationOnElementRemoval;
|
||||
#ifdef DEBUG
|
||||
int32_t mAssertNextInsertOrAppendIndex;
|
||||
nsINode* mAssertNextInsertOrAppendNode;
|
||||
|
@ -621,6 +621,7 @@ WebGLContext::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f, uint32_t aFl
|
||||
if (surf->CairoStatus() != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
gl->MakeCurrent();
|
||||
gl->ReadScreenIntoImageSurface(surf);
|
||||
|
||||
bool srcPremultAlpha = mOptions.premultipliedAlpha;
|
||||
|
@ -44,6 +44,7 @@ class MediaDecoder;
|
||||
}
|
||||
|
||||
class nsITimer;
|
||||
class nsRange;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -882,7 +883,7 @@ protected:
|
||||
|
||||
// Points to the child source elements, used to iterate through the children
|
||||
// when selecting a resource to load.
|
||||
nsCOMPtr<nsIDOMRange> mSourcePointer;
|
||||
nsRefPtr<nsRange> mSourcePointer;
|
||||
|
||||
// Points to the document whose load we're blocking. This is the document
|
||||
// we're bound to when loading starts.
|
||||
|
@ -3359,6 +3359,9 @@ nsIContent* HTMLMediaElement::GetNextSource()
|
||||
if (!mSourcePointer) {
|
||||
// First time this has been run, create a selection to cover children.
|
||||
mSourcePointer = new nsRange(this);
|
||||
// If this media element is removed from the DOM, don't gravitate the
|
||||
// range up to its ancestor, leave it attached to the media element.
|
||||
mSourcePointer->SetEnableGravitationOnElementRemoval(false);
|
||||
|
||||
rv = mSourcePointer->SelectNodeContents(thisDomNode);
|
||||
if (NS_FAILED(rv)) return nullptr;
|
||||
|
@ -113,12 +113,12 @@ AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
||||
|
||||
if (aIsOnTheLeft) {
|
||||
for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
|
||||
*aOutputL++ = *aInputL++ + *aInputR++ * aGainL;
|
||||
*aOutputL++ = *aInputL++ + *aInputR * aGainL;
|
||||
*aOutputR++ = *aInputR++ * aGainR;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
|
||||
*aOutputL++ = *aInputL++ * aGainL;
|
||||
*aOutputL++ = *aInputL * aGainL;
|
||||
*aOutputR++ = *aInputR++ + *aInputL++ * aGainR;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,15 @@
|
||||
namespace MPAPI {
|
||||
|
||||
struct VideoPlane {
|
||||
VideoPlane() :
|
||||
mData(nullptr),
|
||||
mStride(0),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mOffset(0),
|
||||
mSkip(0)
|
||||
{}
|
||||
|
||||
void *mData;
|
||||
int32_t mStride;
|
||||
int32_t mWidth;
|
||||
@ -34,6 +43,17 @@ struct VideoFrame {
|
||||
VideoPlane Cr;
|
||||
nsRefPtr<mozilla::layers::GraphicBufferLocked> mGraphicBuffer;
|
||||
|
||||
VideoFrame() :
|
||||
mTimeUs(0),
|
||||
mKeyFrame(false),
|
||||
mShouldSkip(false),
|
||||
mData(nullptr),
|
||||
mSize(0),
|
||||
mStride(0),
|
||||
mSliceHeight(0),
|
||||
mRotation(0)
|
||||
{}
|
||||
|
||||
void Set(int64_t aTimeUs, bool aKeyFrame,
|
||||
void *aData, size_t aSize, int32_t aStride, int32_t aSliceHeight, int32_t aRotation,
|
||||
void *aYData, int32_t aYStride, int32_t aYWidth, int32_t aYHeight, int32_t aYOffset, int32_t aYSkip,
|
||||
|
@ -140,6 +140,11 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore empty buffer which stagefright media read will sporadically return
|
||||
if (frame.mSize == 0 && !frame.mGraphicBuffer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
parsed++;
|
||||
if (frame.mShouldSkip && mSkipCount < MAX_DROPPED_FRAMES) {
|
||||
mSkipCount++;
|
||||
|
@ -561,11 +561,15 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
||||
mIsVideoSeeking = false;
|
||||
ReleaseAllPendingVideoBuffersLocked();
|
||||
}
|
||||
|
||||
aDoSeek = false;
|
||||
} else {
|
||||
err = mVideoSource->read(&mVideoBuffer);
|
||||
}
|
||||
|
||||
if (err == OK && mVideoBuffer->range_length() > 0) {
|
||||
aFrame->mSize = 0;
|
||||
|
||||
if (err == OK) {
|
||||
int64_t timeUs;
|
||||
int32_t unreadable;
|
||||
int32_t keyFrame;
|
||||
@ -602,7 +606,7 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
||||
aFrame->mKeyFrame = keyFrame;
|
||||
aFrame->Y.mWidth = mVideoWidth;
|
||||
aFrame->Y.mHeight = mVideoHeight;
|
||||
} else {
|
||||
} else if (mVideoBuffer->range_length() > 0) {
|
||||
char *data = static_cast<char *>(mVideoBuffer->data()) + mVideoBuffer->range_offset();
|
||||
size_t length = mVideoBuffer->range_length();
|
||||
|
||||
@ -618,7 +622,6 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
||||
if (aKeyframeSkip && timeUs < aTimeUs) {
|
||||
aFrame->mShouldSkip = true;
|
||||
}
|
||||
|
||||
}
|
||||
else if (err == INFO_FORMAT_CHANGED) {
|
||||
// If the format changed, update our cached info.
|
||||
@ -631,12 +634,14 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
||||
else if (err == ERROR_END_OF_STREAM) {
|
||||
return false;
|
||||
}
|
||||
else if (err == UNKNOWN_ERROR) {
|
||||
// This sometimes is used to mean "out of memory", but regardless,
|
||||
// don't keep trying to decode if the decoder doesn't want to.
|
||||
return false;
|
||||
else if (err == -ETIMEDOUT) {
|
||||
LOG(PR_LOG_DEBUG, "OmxDecoder::ReadVideo timed out, will retry");
|
||||
return true;
|
||||
}
|
||||
else if (err != OK && err != -ETIMEDOUT) {
|
||||
else {
|
||||
// UNKNOWN_ERROR is sometimes is used to mean "out of memory", but
|
||||
// regardless, don't keep trying to decode if the decoder doesn't want to.
|
||||
LOG(PR_LOG_DEBUG, "OmxDecoder::ReadVideo failed, err=%d", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -664,6 +669,7 @@ bool OmxDecoder::ReadAudio(AudioFrame *aFrame, int64_t aSeekTimeUs)
|
||||
mAudioMetadataRead = false;
|
||||
|
||||
aSeekTimeUs = -1;
|
||||
aFrame->mSize = 0;
|
||||
|
||||
if (err == OK && mAudioBuffer && mAudioBuffer->range_length() != 0) {
|
||||
int64_t timeUs;
|
||||
@ -689,10 +695,12 @@ bool OmxDecoder::ReadAudio(AudioFrame *aFrame, int64_t aSeekTimeUs)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (err == UNKNOWN_ERROR) {
|
||||
return false;
|
||||
else if (err == -ETIMEDOUT) {
|
||||
LOG(PR_LOG_DEBUG, "OmxDecoder::ReadAudio timed out, will retry");
|
||||
return true;
|
||||
}
|
||||
else if (err != OK && err != -ETIMEDOUT) {
|
||||
else if (err != OK) {
|
||||
LOG(PR_LOG_DEBUG, "OmxDecoder::ReadAudio failed, err=%d", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,15 @@ public:
|
||||
};
|
||||
|
||||
struct VideoPlane {
|
||||
VideoPlane() :
|
||||
mData(0),
|
||||
mStride(0),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mOffset(0),
|
||||
mSkip(0)
|
||||
{}
|
||||
|
||||
void *mData;
|
||||
int32_t mStride;
|
||||
int32_t mWidth;
|
||||
@ -46,6 +55,16 @@ struct VideoFrame {
|
||||
VideoPlane Cb;
|
||||
VideoPlane Cr;
|
||||
|
||||
VideoFrame() :
|
||||
mTimeUs(0),
|
||||
mKeyFrame(false),
|
||||
mData(0),
|
||||
mSize(0),
|
||||
mStride(0),
|
||||
mSliceHeight(0),
|
||||
mRotation(0)
|
||||
{}
|
||||
|
||||
void Set(int64_t aTimeUs, bool aKeyFrame,
|
||||
void *aData, size_t aSize, int32_t aStride, int32_t aSliceHeight, int32_t aRotation,
|
||||
void *aYData, int32_t aYStride, int32_t aYWidth, int32_t aYHeight, int32_t aYOffset, int32_t aYSkip,
|
||||
|
13
content/media/test/crashtests/865537-1.html
Normal file
13
content/media/test/crashtests/865537-1.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body onload="doTest()">
|
||||
<base href="../unknown">
|
||||
<div id="test3"></div>
|
||||
<video id="test4"><source src="white.webm"></video>
|
||||
<script>
|
||||
function doTest() {
|
||||
test3.appendChild(test4);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
9
content/media/test/crashtests/880129.html
Normal file
9
content/media/test/crashtests/880129.html
Normal file
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
try { o1 = new window.AudioContext(3, 2, 44100); } catch(e) { }
|
||||
try { o6 = o1.createBufferSource(); } catch(e) { }
|
||||
try { o15 = o1.createAnalyser(); } catch(e) { }
|
||||
try { o15.fftSize = 32; } catch(e) { }
|
||||
try { o6.connect(o15,0,0) } catch(e) { }
|
||||
try { o27 = o1.createPanner(); } catch(e) { }
|
||||
try { o6.buffer = function(){var buffer = o1.createBuffer(2, 1148, o1.sampleRate);for(var c=0; c<2; c++) {for(var i=0; i<1148; i++) {buffer.getChannelData(c)[i] = 0;}}return buffer;}() } catch(e) { }
|
||||
</script>
|
33
content/media/test/crashtests/880202.html
Normal file
33
content/media/test/crashtests/880202.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<script>
|
||||
var Context0= new window.OfflineAudioContext(15,12119,44100)
|
||||
var BufferSource1=Context0.createBufferSource();
|
||||
var Gain0=Context0.createGain();
|
||||
var Panner0=Context0.createPanner();
|
||||
Context0.listener.setPosition(29,135,158);
|
||||
|
||||
BufferSource1.connect(Gain0);
|
||||
|
||||
BufferSource1.buffer=function(){
|
||||
var channels=3;
|
||||
var length=53325;
|
||||
var Buffer=Context0.createBuffer(channels,length,Context0.sampleRate);
|
||||
for(var y=0;y<channels;y++){
|
||||
var bufferData= Buffer.getChannelData(y);
|
||||
for (var i = 0; i < length; ++i) {
|
||||
bufferData[i] = i*(270);
|
||||
}
|
||||
};
|
||||
return Buffer;
|
||||
}();
|
||||
|
||||
Gain0.connect(Panner0);
|
||||
Panner0.panningModel=0;
|
||||
|
||||
|
||||
setTimeout(function(){
|
||||
document.documentElement.removeAttribute("class");
|
||||
},500)
|
||||
|
||||
</script>
|
@ -15,6 +15,7 @@ skip-if(Android||B2G) load 789075-1.html # load failed, bug 833371 for B2G
|
||||
load 844563.html
|
||||
load 846612.html
|
||||
load 852838.html
|
||||
load 865537-1.html
|
||||
load 868504.html
|
||||
load 874869.html
|
||||
load 874915.html
|
||||
@ -37,3 +38,5 @@ load 878328.html
|
||||
load 878407.html
|
||||
load 878478.html
|
||||
load 877527.html
|
||||
load 880129.html
|
||||
skip-if(B2G) load 880202.html # load failed, bug 833371 for B2G
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "AudioNodeEngine.h"
|
||||
#include "AudioNodeStream.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "kiss_fft/kiss_fftr.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -275,12 +276,17 @@ AnalyserNode::AppendChunk(const AudioChunk& aChunk)
|
||||
{
|
||||
const uint32_t bufferSize = mBuffer.Length();
|
||||
const uint32_t channelCount = aChunk.mChannelData.Length();
|
||||
const uint32_t chunkCount = aChunk.mDuration;
|
||||
uint32_t chunkDuration = aChunk.mDuration;
|
||||
MOZ_ASSERT((bufferSize & (bufferSize - 1)) == 0); // Must be a power of two!
|
||||
MOZ_ASSERT(channelCount > 0);
|
||||
MOZ_ASSERT(chunkCount == WEBAUDIO_BLOCK_SIZE);
|
||||
MOZ_ASSERT(chunkDuration == WEBAUDIO_BLOCK_SIZE);
|
||||
|
||||
memcpy(mBuffer.Elements() + mWriteIndex, aChunk.mChannelData[0], sizeof(float) * chunkCount);
|
||||
if (chunkDuration > bufferSize) {
|
||||
// Copy a maximum bufferSize samples.
|
||||
chunkDuration = bufferSize;
|
||||
}
|
||||
|
||||
PodCopy(mBuffer.Elements() + mWriteIndex, static_cast<const float*>(aChunk.mChannelData[0]), chunkDuration);
|
||||
for (uint32_t i = 1; i < channelCount; ++i) {
|
||||
AudioBlockAddChannelWithScale(static_cast<const float*>(aChunk.mChannelData[i]), 1.0f,
|
||||
mBuffer.Elements() + mWriteIndex);
|
||||
@ -289,7 +295,7 @@ AnalyserNode::AppendChunk(const AudioChunk& aChunk)
|
||||
AudioBlockInPlaceScale(mBuffer.Elements() + mWriteIndex, 1,
|
||||
1.0f / aChunk.mChannelData.Length());
|
||||
}
|
||||
mWriteIndex += chunkCount;
|
||||
mWriteIndex += chunkDuration;
|
||||
MOZ_ASSERT(mWriteIndex <= bufferSize);
|
||||
if (mWriteIndex >= bufferSize) {
|
||||
mWriteIndex = 0;
|
||||
|
@ -1457,9 +1457,11 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
|
||||
// Kill all of the workers for this window.
|
||||
// We push a cx so that exceptions get reported in the right DOM Window.
|
||||
nsIScriptContext *scx = GetContextInternal();
|
||||
AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
|
||||
mozilla::dom::workers::CancelWorkersForWindow(cx, this);
|
||||
{
|
||||
nsIScriptContext *scx = GetContextInternal();
|
||||
AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
|
||||
mozilla::dom::workers::CancelWorkersForWindow(cx, this);
|
||||
}
|
||||
|
||||
// Close all offline storages for this window.
|
||||
quota::QuotaManager* quotaManager = quota::QuotaManager::Get();
|
||||
@ -10939,10 +10941,12 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
|
||||
DisableGamepadUpdates();
|
||||
|
||||
// Suspend all of the workers for this window.
|
||||
// We push a cx so that exceptions get reported in the right DOM Window.
|
||||
nsIScriptContext *scx = GetContextInternal();
|
||||
AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
|
||||
mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
|
||||
// We push a cx so that exceptions get reported in the right DOM Window.
|
||||
{
|
||||
nsIScriptContext *scx = GetContextInternal();
|
||||
AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
|
||||
mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
|
||||
}
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
|
||||
@ -11034,7 +11038,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
|
||||
// We push a cx so that exceptions get reported in the right DOM Window.
|
||||
nsIScriptContext *scx = GetContextInternal();
|
||||
AutoPushJSContext cx(scx ? scx->GetNativeContext() : nsContentUtils::GetSafeJSContext());
|
||||
mozilla::dom::workers::ResumeWorkersForWindow(cx, this);
|
||||
mozilla::dom::workers::ResumeWorkersForWindow(scx, this);
|
||||
|
||||
// Restore all of the timeouts, using the stored time remaining
|
||||
// (stored in timeout->mTimeRemaining).
|
||||
|
@ -35,8 +35,8 @@ DefineStaticJSVals(JSContext* cx)
|
||||
|
||||
int HandlerFamily;
|
||||
|
||||
js::ListBaseShadowsResult
|
||||
DOMListShadows(JSContext* cx, JSHandleObject proxy, JSHandleId id)
|
||||
js::DOMProxyShadowsResult
|
||||
DOMProxyShadows(JSContext* cx, JSHandleObject proxy, JSHandleId id)
|
||||
{
|
||||
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
|
||||
if (v.isObject()) {
|
||||
@ -59,15 +59,15 @@ DOMListShadows(JSContext* cx, JSHandleObject proxy, JSHandleId id)
|
||||
}
|
||||
|
||||
// Store the information for the specialized ICs.
|
||||
struct SetListBaseInformation
|
||||
struct SetDOMProxyInformation
|
||||
{
|
||||
SetListBaseInformation() {
|
||||
js::SetListBaseInformation((void*) &HandlerFamily,
|
||||
js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO, DOMListShadows);
|
||||
SetDOMProxyInformation() {
|
||||
js::SetDOMProxyInformation((void*) &HandlerFamily,
|
||||
js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO, DOMProxyShadow);
|
||||
}
|
||||
};
|
||||
|
||||
SetListBaseInformation gSetListBaseInformation;
|
||||
SetDOMProxyInformation gSetDOMProxyInformation;
|
||||
|
||||
// static
|
||||
JSObject*
|
||||
|
@ -765,10 +765,29 @@ RTCPeerConnection.prototype = {
|
||||
sdp: sdp });
|
||||
},
|
||||
|
||||
get signalingState() { return "stable"; }, // not yet implemented
|
||||
get iceGatheringState() { return this._iceGatheringState; },
|
||||
get iceConnectionState() { return this._iceConnectionState; },
|
||||
|
||||
// Corresponds to constants in IPeerConnection.idl
|
||||
_signalingStateMap: [
|
||||
'invalid',
|
||||
'stable',
|
||||
'have-local-offer',
|
||||
'have-remote-offer',
|
||||
'have-local-pranswer',
|
||||
'have-remote-pranswer',
|
||||
'closed'
|
||||
],
|
||||
|
||||
get signalingState() {
|
||||
// checking for our local pc closed indication
|
||||
// before invoking the pc methods.
|
||||
if(this._closed) {
|
||||
return "closed";
|
||||
}
|
||||
return this._signalingStateMap[this._getPC().signalingState];
|
||||
},
|
||||
|
||||
changeIceGatheringState: function(state) {
|
||||
this._iceGatheringState = state;
|
||||
},
|
||||
@ -990,14 +1009,10 @@ PeerConnectionObserver.prototype = {
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onStateChange: function(state) {
|
||||
if (state != Ci.IPeerConnectionObserver.kIceState) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (this._dompc._pc.iceState) {
|
||||
handleIceStateChanges: function(iceState) {
|
||||
switch (iceState) {
|
||||
case Ci.IPeerConnection.kIceWaiting:
|
||||
this._dompc.changeIceConnectionState("completed");
|
||||
this._dompc.changeIceConnectionState("new");
|
||||
this.callCB(this._dompc.ongatheringchange, "complete");
|
||||
this.callCB(this._onicechange, "starting");
|
||||
// Now that the PC is ready to go, execute any pending operations.
|
||||
@ -1021,7 +1036,33 @@ PeerConnectionObserver.prototype = {
|
||||
this.callCB(this._onicechange, "failed");
|
||||
break;
|
||||
default:
|
||||
// Unknown state!
|
||||
// Unknown ICE state!
|
||||
this._dompc.reportWarning("Unhandled ice state: " + iceState, null, 0);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onStateChange: function(state) {
|
||||
switch (state) {
|
||||
case Ci.IPeerConnectionObserver.kSignalingState:
|
||||
this.callCB(this._dompc.onsignalingstatechange,
|
||||
this._dompc.signalingState);
|
||||
break;
|
||||
|
||||
case Ci.IPeerConnectionObserver.kIceState:
|
||||
this.handleIceStateChanges(this._dompc._pc.iceState);
|
||||
break;
|
||||
|
||||
case Ci.IPeerConnectionObserver.kSdpState:
|
||||
// No-op
|
||||
break;
|
||||
|
||||
case Ci.IPeerConnectionObserver.kSipccState:
|
||||
// No-op
|
||||
break;
|
||||
|
||||
default:
|
||||
this._dompc.reportWarning("Unhandled state type: " + state, null, 0);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -32,6 +32,7 @@ interface IPeerConnectionObserver : nsISupports
|
||||
const long kIceState = 0x2;
|
||||
const long kSdpState = 0x3;
|
||||
const long kSipccState = 0x4;
|
||||
const long kSignalingState = 0x5;
|
||||
|
||||
/* JSEP callbacks */
|
||||
void onCreateOfferSuccess(in string offer);
|
||||
@ -91,6 +92,15 @@ interface IPeerConnection : nsISupports
|
||||
const long kClosing = 3;
|
||||
const long kClosed = 4;
|
||||
|
||||
/* RTCSignalingState from WebRTC spec */
|
||||
const long kSignalingInvalid = 0;
|
||||
const long kSignalingStable = 1;
|
||||
const long kSignalingHaveLocalOffer = 2;
|
||||
const long kSignalingHaveRemoteOffer = 3;
|
||||
const long kSignalingHaveLocalPranswer = 4;
|
||||
const long kSignalingHaveRemotePranswer = 5;
|
||||
const long kSignalingClosed = 6;
|
||||
|
||||
/* for 'type' in DataChannelInit dictionary */
|
||||
const unsigned short kDataChannelReliable = 0;
|
||||
const unsigned short kDataChannelPartialReliableRexmit = 1;
|
||||
@ -144,6 +154,7 @@ interface IPeerConnection : nsISupports
|
||||
|
||||
readonly attribute unsigned long iceState;
|
||||
readonly attribute unsigned long readyState;
|
||||
readonly attribute unsigned long signalingState;
|
||||
readonly attribute unsigned long sipccState;
|
||||
|
||||
/* Data channels */
|
||||
|
@ -35,6 +35,13 @@ MOCHITEST_FILES = \
|
||||
test_peerConnection_offerRequiresReceiveVideo.html \
|
||||
test_peerConnection_offerRequiresReceiveVideoAudio.html \
|
||||
test_peerConnection_throwInCallbacks.html \
|
||||
test_peerConnection_setLocalAnswerInStable.html \
|
||||
test_peerConnection_setRemoteAnswerInStable.html \
|
||||
test_peerConnection_setLocalAnswerInHaveLocalOffer.html \
|
||||
test_peerConnection_setRemoteOfferInHaveLocalOffer.html \
|
||||
test_peerConnection_setLocalOfferInHaveRemoteOffer.html \
|
||||
test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html \
|
||||
test_peerConnection_addCandidateInHaveLocalOffer.html \
|
||||
test_peerConnection_bug822674.html \
|
||||
test_peerConnection_bug825703.html \
|
||||
test_peerConnection_bug827843.html \
|
||||
|
@ -182,11 +182,23 @@ function unexpectedCallbackAndFinish(error) {
|
||||
return function(aObj) {
|
||||
var where = error.fileName + ":" + error.lineNumber;
|
||||
if (aObj && aObj.name && aObj.message) {
|
||||
ok(false, "Unexpected error callback from " + where + " with name = '" +
|
||||
ok(false, "Unexpected callback/event from " + where + " with name = '" +
|
||||
aObj.name + "', message = '" + aObj.message + "'");
|
||||
} else {
|
||||
ok(false, "Unexpected error callback from " + where + " with " + aObj);
|
||||
ok(false, "Unexpected callback/event from " + where + " with " + aObj);
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a callback function suitable for putting int a success
|
||||
* callback in circumstances where success is unexpected. The callback,
|
||||
* if activated, will kill off the test gracefully.
|
||||
*/
|
||||
|
||||
function unexpectedSuccessCallbackAndFinish(error, reason) {
|
||||
return function() {
|
||||
unexpectedCallbackAndFinish(error)(message);
|
||||
}
|
||||
}
|
||||
|
@ -246,10 +246,19 @@ var commandsPeerConnection = [
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_CHECK_INITIAL_SIGNALINGSTATE',
|
||||
function (test) {
|
||||
is(test.pcLocal.signalingState,"stable", "Initial local signalingState is stable");
|
||||
is(test.pcRemote.signalingState,"stable", "Initial remote signalingState is stable");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
function (test) {
|
||||
test.pcLocal.createOffer(function () {
|
||||
is(test.pcLocal.signalingState, "stable", "Local create offer does not change signaling state");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
@ -257,23 +266,24 @@ var commandsPeerConnection = [
|
||||
[
|
||||
'PC_LOCAL_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.pcLocal.setLocalDescription(test.pcLocal._last_offer, function () {
|
||||
test.next();
|
||||
});
|
||||
test.expectStateChange(test.pcLocal, "have-local-offer", test);
|
||||
test.pcLocal.setLocalDescription(test.pcLocal._last_offer,
|
||||
test.checkStateInCallback(test.pcLocal, "have-local-offer", test));
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.pcRemote.setRemoteDescription(test.pcLocal._last_offer, function () {
|
||||
test.next();
|
||||
});
|
||||
test.expectStateChange(test.pcRemote, "have-remote-offer", test);
|
||||
test.pcRemote.setRemoteDescription(test.pcLocal._last_offer,
|
||||
test.checkStateInCallback(test.pcRemote, "have-remote-offer", test));
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CREATE_ANSWER',
|
||||
function (test) {
|
||||
test.pcRemote.createAnswer(function () {
|
||||
is(test.pcRemote.signalingState, "have-remote-offer", "Remote create offer does not change signaling state");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
@ -281,17 +291,17 @@ var commandsPeerConnection = [
|
||||
[
|
||||
'PC_LOCAL_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.pcLocal.setRemoteDescription(test.pcRemote._last_answer, function () {
|
||||
test.next();
|
||||
});
|
||||
test.expectStateChange(test.pcLocal, "stable", test);
|
||||
test.pcLocal.setRemoteDescription(test.pcRemote._last_answer,
|
||||
test.checkStateInCallback(test.pcLocal, "stable", test));
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.pcRemote.setLocalDescription(test.pcRemote._last_answer, function () {
|
||||
test.next();
|
||||
});
|
||||
test.expectStateChange(test.pcRemote, "stable", test);
|
||||
test.pcRemote.setLocalDescription(test.pcRemote._last_answer,
|
||||
test.checkStateInCallback(test.pcRemote, "stable", test));
|
||||
}
|
||||
],
|
||||
[
|
||||
@ -394,6 +404,64 @@ PeerConnectionTest.prototype.teardown = function PCT_teardown() {
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up the "onsignalingstatechange" handler for the indicated peerconnection
|
||||
* as a one-shot test. If the test.commandSuccess flag is set when the event
|
||||
* happens, then the next test in the command chain is triggered. After
|
||||
* running, this sets the event handler so that it will fail the test if
|
||||
* it fires again before we expect it. This is intended to be used in
|
||||
* conjunction with checkStateInCallback, below.
|
||||
*
|
||||
* @param {pcw} PeerConnectionWrapper
|
||||
* The peer connection to expect a state change on
|
||||
* @param {state} string
|
||||
* The state that we expect to change to
|
||||
* @param {test} PeerConnectionTest
|
||||
* The test strucure currently in use.
|
||||
*/
|
||||
PeerConnectionTest.prototype.expectStateChange =
|
||||
function PCT_expectStateChange(pcw, state, test) {
|
||||
pcw.signalingChangeEvent = false;
|
||||
pcw._pc.onsignalingstatechange = function() {
|
||||
pcw._pc.onsignalingstatechange = unexpectedCallbackAndFinish(new Error);
|
||||
is(pcw._pc.signalingState, state, pcw.label + ": State is " + state + " in onsignalingstatechange");
|
||||
pcw.signalingChangeEvent = true;
|
||||
if (pcw.commandSuccess) {
|
||||
test.next();
|
||||
} else {
|
||||
info("Waiting for success callback...");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function, suitable for use as a success callback, that
|
||||
* checks the signaling state of the PC; and, if the signalingstatechange
|
||||
* event has already fired, moves on to the next test case. This is
|
||||
* intended to be used in conjunction with expectStateChange, above.
|
||||
*
|
||||
* @param {pcw} PeerConnectionWrapper
|
||||
* The peer connection to expect a state change on
|
||||
* @param {state} string
|
||||
* The state that we expect to change to
|
||||
* @param {test} PeerConnectionTest
|
||||
* The test strucure currently in use.
|
||||
*/
|
||||
|
||||
PeerConnectionTest.prototype.checkStateInCallback =
|
||||
function PCT_checkStateInCallback(pcw, state, test) {
|
||||
pcw.commandSuccess = false;
|
||||
return function() {
|
||||
pcw.commandSuccess = true;
|
||||
is(pcw.signalingState, state, pcw.label + ": State is " + state + " in success callback");
|
||||
if (pcw.signalingChangeEvent) {
|
||||
test.next();
|
||||
} else {
|
||||
info("Waiting for signalingstatechange event...");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class handles acts as a wrapper around a PeerConnection instance.
|
||||
@ -420,6 +488,9 @@ function PeerConnectionWrapper(label, configuration) {
|
||||
// Bug 834835: Assume type is video until we get get{Audio,Video}Tracks.
|
||||
self.attachMedia(event.stream, 'video', 'remote');
|
||||
};
|
||||
|
||||
// Make sure no signaling state changes are fired until we expect them to
|
||||
this._pc.onsignalingstatechange = unexpectedCallbackAndFinish(new Error);
|
||||
}
|
||||
|
||||
PeerConnectionWrapper.prototype = {
|
||||
@ -462,6 +533,15 @@ PeerConnectionWrapper.prototype = {
|
||||
this._pc.remoteDescription = desc;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the remote signaling state.
|
||||
*
|
||||
* @returns {object} The local description
|
||||
*/
|
||||
get signalingState() {
|
||||
return this._pc.signalingState;
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback when we get media from either side. Also an appropriate
|
||||
* HTML media element will be created.
|
||||
@ -571,6 +651,25 @@ PeerConnectionWrapper.prototype = {
|
||||
}, unexpectedCallbackAndFinish(new Error));
|
||||
},
|
||||
|
||||
/**
|
||||
* Tries to set the local description and expect failure. Automatically
|
||||
* causes the test case to fail if the call succeeds.
|
||||
*
|
||||
* @param {object} desc
|
||||
* mozRTCSessionDescription for the local description request
|
||||
* @param {function} onFailure
|
||||
* Callback to execute if the call fails.
|
||||
*/
|
||||
setLocalDescriptionAndFail : function PCW_setLocalDescriptionAndFail(desc, onFailure) {
|
||||
var self = this;
|
||||
this._pc.setLocalDescription(desc,
|
||||
unexpectedSuccessCallbackAndFinish(new Error, "setLocalDescription should have failed."),
|
||||
function (err) {
|
||||
info("As expected, failed to set the local description for " + self.label);
|
||||
onFailure(err);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the remote description and automatically handles the failure case.
|
||||
*
|
||||
@ -587,6 +686,62 @@ PeerConnectionWrapper.prototype = {
|
||||
}, unexpectedCallbackAndFinish(new Error));
|
||||
},
|
||||
|
||||
/**
|
||||
* Tries to set the remote description and expect failure. Automatically
|
||||
* causes the test case to fail if the call succeeds.
|
||||
*
|
||||
* @param {object} desc
|
||||
* mozRTCSessionDescription for the remote description request
|
||||
* @param {function} onFailure
|
||||
* Callback to execute if the call fails.
|
||||
*/
|
||||
setRemoteDescriptionAndFail : function PCW_setRemoteDescriptionAndFail(desc, onFailure) {
|
||||
var self = this;
|
||||
this._pc.setRemoteDescription(desc,
|
||||
unexpectedSuccessCallbackAndFinish(new Error, "setRemoteDescription should have failed."),
|
||||
function (err) {
|
||||
info("As expected, failed to set the remote description for " + self.label);
|
||||
onFailure(err);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an ICE candidate and automatically handles the failure case.
|
||||
*
|
||||
* @param {object} candidate
|
||||
* SDP candidate
|
||||
* @param {function} onSuccess
|
||||
* Callback to execute if the local description was set successfully
|
||||
*/
|
||||
addIceCandidate : function PCW_addIceCandidate(candidate, onSuccess) {
|
||||
var self = this;
|
||||
|
||||
this._pc.addIceCandidate(candidate, function () {
|
||||
info("Successfully added an ICE candidate to " + self.label);
|
||||
onSuccess();
|
||||
}, unexpectedCallbackAndFinish(new Error));
|
||||
},
|
||||
|
||||
/**
|
||||
* Tries to add an ICE candidate and expects failure. Automatically
|
||||
* causes the test case to fail if the call succeeds.
|
||||
*
|
||||
* @param {object} candidate
|
||||
* SDP candidate
|
||||
* @param {function} onFailure
|
||||
* Callback to execute if the call fails.
|
||||
*/
|
||||
addIceCandidateAndFail : function PCW_addIceCandidateAndFail(candidate, onFailure) {
|
||||
var self = this;
|
||||
|
||||
this._pc.addIceCandidate(candidate,
|
||||
unexpectedSuccessCallbackAndFinish(new Error, "addIceCandidate should have failed."),
|
||||
function (err) {
|
||||
info("As expected, failed to add an ICE candidate to " + self.label);
|
||||
onFailure(err);
|
||||
}) ;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks that we are getting the media we expect.
|
||||
*
|
||||
|
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "784519",
|
||||
title: "addCandidate (answer) in 'have-local-offer'"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.chain.removeAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION");
|
||||
|
||||
test.chain.append([[
|
||||
"PC_LOCAL_ADD_CANDIDATE",
|
||||
function (test) {
|
||||
test.pcLocal.addIceCandidateAndFail(
|
||||
mozRTCIceCandidate(
|
||||
{candidate:"1 1 UDP 2130706431 192.168.2.1 50005 typ host",
|
||||
sdpMLineIndex: 1}),
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
]]);
|
||||
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -54,7 +54,7 @@
|
||||
{ url:"stun:0.0.0.0" },
|
||||
{ url:"stuns:x.net", foo:"" },
|
||||
{ url:"turn:[::192.9.5.5]:42", username:"p", credential:"p" },
|
||||
{ url:"turns:x.org:42", username:"p", credential:"p" }
|
||||
{ url:"turns:x.org:42?transport=udp", username:"p", credential:"p" }
|
||||
]}, true);
|
||||
|
||||
pcs = null;
|
||||
|
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "784519",
|
||||
title: "setLocalDescription (answer) in 'have-local-offer'"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.chain.removeAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION");
|
||||
|
||||
test.chain.append([[
|
||||
"PC_LOCAL_SET_LOCAL_ANSWER",
|
||||
function (test) {
|
||||
test.pcLocal._last_offer.type="answer";
|
||||
test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._last_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
]]);
|
||||
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "784519",
|
||||
title: "setLocalDescription (answer) in 'stable'"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.chain.removeAfter("PC_LOCAL_CREATE_OFFER");
|
||||
|
||||
test.chain.append([[
|
||||
"PC_LOCAL_SET_LOCAL_ANSWER",
|
||||
function (test) {
|
||||
test.pcLocal._last_offer.type="answer";
|
||||
test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._last_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
]]);
|
||||
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "784519",
|
||||
title: "setLocalDescription (offer) in 'have-remote-offer'"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.chain.removeAfter("PC_REMOTE_SET_REMOTE_DESCRIPTION");
|
||||
|
||||
test.chain.append([[
|
||||
"PC_REMOTE_SET_LOCAL_OFFER",
|
||||
function (test) {
|
||||
test.pcRemote.setLocalDescriptionAndFail(test.pcLocal._last_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
]]);
|
||||
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "784519",
|
||||
title: "setRemoteDescription (answer) in 'have-remote-offer'"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.chain.removeAfter("PC_REMOTE_SET_REMOTE_DESCRIPTION");
|
||||
|
||||
test.chain.append([[
|
||||
"PC_REMOTE_SET_REMOTE_ANSWER",
|
||||
function (test) {
|
||||
test.pcLocal._last_offer.type="answer";
|
||||
test.pcRemote.setRemoteDescriptionAndFail(test.pcLocal._last_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
]]);
|
||||
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "784519",
|
||||
title: "setRemoteDescription (answer) in 'stable'"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.chain.removeAfter("PC_LOCAL_CREATE_OFFER");
|
||||
|
||||
test.chain.append([[
|
||||
"PC_LOCAL_SET_REMOTE_ANSWER",
|
||||
function (test) {
|
||||
test.pcLocal._last_offer.type="answer";
|
||||
test.pcLocal.setRemoteDescriptionAndFail(test.pcLocal._last_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
]]);
|
||||
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "784519",
|
||||
title: "setRemoteDescription (offer) in 'have-local-offer'"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.chain.removeAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION");
|
||||
|
||||
test.chain.append([[
|
||||
"PC_LOCAL_SET_REMOTE_OFFER",
|
||||
function (test) {
|
||||
test.pcLocal.setRemoteDescriptionAndFail(test.pcLocal._last_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
]]);
|
||||
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -4,8 +4,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "RuntimeService.h"
|
||||
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
@ -18,32 +16,32 @@
|
||||
#include "nsISupportsPriority.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsLayoutStatics.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "GeckoProfiler.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/EventTargetBinding.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include <Navigator.h>
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsLayoutStatics.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
#include "OSFileConstants.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
#include "Events.h"
|
||||
#include "Worker.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#include "OSFileConstants.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -72,7 +70,8 @@ using mozilla::Preferences;
|
||||
MOZ_STATIC_ASSERT(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
"We should allow at least one worker per domain.");
|
||||
|
||||
// The default number of seconds that close handlers will be allowed to run.
|
||||
// The default number of seconds that close handlers will be allowed to run for
|
||||
// content workers.
|
||||
#define MAX_SCRIPT_RUN_TIME_SEC 10
|
||||
|
||||
// The number of seconds that idle threads can hang around before being killed.
|
||||
@ -81,10 +80,12 @@ MOZ_STATIC_ASSERT(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
// The maximum number of threads that can be idle at one time.
|
||||
#define MAX_IDLE_THREADS 20
|
||||
|
||||
#define PREF_WORKERS_ENABLED "dom.workers.enabled"
|
||||
#define PREF_WORKERS_MAX_PER_DOMAIN "dom.workers.maxPerDomain"
|
||||
#define PREF_WORKERS_GCZEAL "dom.workers.gczeal"
|
||||
#define PREF_MAX_SCRIPT_RUN_TIME "dom.max_script_run_time"
|
||||
#define PREF_WORKERS_PREFIX "dom.workers."
|
||||
#define PREF_WORKERS_ENABLED PREF_WORKERS_PREFIX "enabled"
|
||||
#define PREF_WORKERS_MAX_PER_DOMAIN PREF_WORKERS_PREFIX "maxPerDomain"
|
||||
|
||||
#define PREF_MAX_SCRIPT_RUN_TIME_CONTENT "dom.max_script_run_time"
|
||||
#define PREF_MAX_SCRIPT_RUN_TIME_CHROME "dom.max_chrome_script_run_time"
|
||||
|
||||
#define GC_REQUEST_OBSERVER_TOPIC "child-gc-request"
|
||||
#define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"
|
||||
@ -109,6 +110,13 @@ MOZ_STATIC_ASSERT(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
// Prefixes for observing preference changes.
|
||||
#define PREF_JS_OPTIONS_PREFIX "javascript.options."
|
||||
#define PREF_WORKERS_OPTIONS_PREFIX PREF_WORKERS_PREFIX "options."
|
||||
#define PREF_MEM_OPTIONS_PREFIX "mem."
|
||||
#define PREF_JIT_HARDENING "jit_hardening"
|
||||
#define PREF_GCZEAL "gcZeal"
|
||||
|
||||
namespace {
|
||||
|
||||
const uint32_t kNoIndex = uint32_t(-1);
|
||||
@ -121,6 +129,9 @@ uint32_t gMaxWorkersPerDomain = MAX_WORKERS_PER_DOMAIN;
|
||||
// Does not hold an owning reference.
|
||||
RuntimeService* gRuntimeService = nullptr;
|
||||
|
||||
// Only non-null during the call to Init.
|
||||
RuntimeService* gRuntimeServiceDuringInit = nullptr;
|
||||
|
||||
enum {
|
||||
ID_Worker = 0,
|
||||
ID_ChromeWorker,
|
||||
@ -148,100 +159,428 @@ const char* gStringChars[] = {
|
||||
MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(gStringChars) == ID_COUNT,
|
||||
"gStringChars should have the right length.");
|
||||
|
||||
enum {
|
||||
PREF_strict = 0,
|
||||
PREF_werror,
|
||||
PREF_typeinference,
|
||||
PREF_jit_hardening,
|
||||
PREF_mem_max,
|
||||
PREF_baselinejit,
|
||||
PREF_ion,
|
||||
PREF_asmjs,
|
||||
PREF_mem_gc_allocation_threshold_mb,
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
PREF_gczeal,
|
||||
#endif
|
||||
|
||||
PREF_COUNT
|
||||
class LiteralRebindingCString : public nsDependentCString
|
||||
{
|
||||
public:
|
||||
template<int N>
|
||||
void RebindLiteral(const char (&aStr)[N])
|
||||
{
|
||||
Rebind(aStr, N-1);
|
||||
}
|
||||
};
|
||||
|
||||
#define JS_OPTIONS_DOT_STR "javascript.options."
|
||||
template <typename T>
|
||||
struct PrefTraits;
|
||||
|
||||
const char* gPrefsToWatch[] = {
|
||||
JS_OPTIONS_DOT_STR "strict",
|
||||
JS_OPTIONS_DOT_STR "werror",
|
||||
JS_OPTIONS_DOT_STR "typeinference",
|
||||
JS_OPTIONS_DOT_STR "jit_hardening",
|
||||
JS_OPTIONS_DOT_STR "mem.max",
|
||||
JS_OPTIONS_DOT_STR "baselinejit.content",
|
||||
JS_OPTIONS_DOT_STR "ion.content",
|
||||
JS_OPTIONS_DOT_STR "asmjs",
|
||||
"dom.workers.mem.gc_allocation_threshold_mb"
|
||||
template <>
|
||||
struct PrefTraits<bool>
|
||||
{
|
||||
typedef bool PrefValueType;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
, PREF_WORKERS_GCZEAL
|
||||
#endif
|
||||
static const PrefValueType kDefaultValue = false;
|
||||
|
||||
static inline PrefValueType
|
||||
Get(const char* aPref)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
return Preferences::GetBool(aPref);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
Exists(const char* aPref)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
return Preferences::GetType(aPref) == nsIPrefBranch::PREF_BOOL;
|
||||
}
|
||||
};
|
||||
|
||||
MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(gPrefsToWatch) == PREF_COUNT,
|
||||
"gPrefsToWatch should have the right length.");
|
||||
template <>
|
||||
struct PrefTraits<int32_t>
|
||||
{
|
||||
typedef int32_t PrefValueType;
|
||||
|
||||
int
|
||||
PrefCallback(const char* aPrefName, void* aClosure)
|
||||
static const PrefValueType kDefaultValue = 0;
|
||||
|
||||
static inline PrefValueType
|
||||
Get(const char* aPref)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
return Preferences::GetInt(aPref);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
Exists(const char* aPref)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
return Preferences::GetType(aPref) == nsIPrefBranch::PREF_INT;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T
|
||||
GetWorkerPref(const nsACString& aPref,
|
||||
const T aDefault = PrefTraits<T>::kDefaultValue)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService* rts = static_cast<RuntimeService*>(aClosure);
|
||||
NS_ASSERTION(rts, "This should never be null!");
|
||||
typedef PrefTraits<T> PrefHelper;
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(jsOptionStr, JS_OPTIONS_DOT_STR);
|
||||
T result;
|
||||
|
||||
if (!strcmp(aPrefName, gPrefsToWatch[PREF_mem_max])) {
|
||||
int32_t pref = Preferences::GetInt(aPrefName, -1);
|
||||
uint32_t maxBytes = (pref <= 0 || pref >= 0x1000) ?
|
||||
uint32_t(-1) :
|
||||
uint32_t(pref) * 1024 * 1024;
|
||||
RuntimeService::SetDefaultJSWorkerMemoryParameter(JSGC_MAX_BYTES, maxBytes);
|
||||
rts->UpdateAllWorkerMemoryParameter(JSGC_MAX_BYTES);
|
||||
} else if (!strcmp(aPrefName, gPrefsToWatch[PREF_mem_gc_allocation_threshold_mb])) {
|
||||
int32_t pref = Preferences::GetInt(aPrefName, 30);
|
||||
uint32_t threshold = (pref <= 0 || pref >= 0x1000) ?
|
||||
uint32_t(30) :
|
||||
uint32_t(pref);
|
||||
RuntimeService::SetDefaultJSWorkerMemoryParameter(JSGC_ALLOCATION_THRESHOLD, threshold);
|
||||
rts->UpdateAllWorkerMemoryParameter(JSGC_ALLOCATION_THRESHOLD);
|
||||
} else if (StringBeginsWith(nsDependentCString(aPrefName), jsOptionStr)) {
|
||||
uint32_t newOptions = kRequiredJSContextOptions;
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_strict])) {
|
||||
newOptions |= JSOPTION_STRICT;
|
||||
}
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_werror])) {
|
||||
newOptions |= JSOPTION_WERROR;
|
||||
}
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_typeinference])) {
|
||||
newOptions |= JSOPTION_TYPE_INFERENCE;
|
||||
}
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_baselinejit])) {
|
||||
newOptions |= JSOPTION_BASELINE;
|
||||
}
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_ion])) {
|
||||
newOptions |= JSOPTION_ION;
|
||||
}
|
||||
if (Preferences::GetBool(gPrefsToWatch[PREF_asmjs])) {
|
||||
newOptions |= JSOPTION_ASMJS;
|
||||
}
|
||||
nsAutoCString prefName;
|
||||
prefName.AssignLiteral(PREF_WORKERS_OPTIONS_PREFIX);
|
||||
prefName.Append(aPref);
|
||||
|
||||
RuntimeService::SetDefaultJSContextOptions(newOptions);
|
||||
rts->UpdateAllWorkerJSContextOptions();
|
||||
if (PrefHelper::Exists(prefName.get())) {
|
||||
result = PrefHelper::Get(prefName.get());
|
||||
}
|
||||
else {
|
||||
prefName.AssignLiteral(PREF_JS_OPTIONS_PREFIX);
|
||||
prefName.Append(aPref);
|
||||
|
||||
if (PrefHelper::Exists(prefName.get())) {
|
||||
result = PrefHelper::Get(prefName.get());
|
||||
}
|
||||
else {
|
||||
result = aDefault;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
LoadJSContextOptions(const char* aPrefName, void* /* aClosure */)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService* rts = RuntimeService::GetService();
|
||||
if (!rts && !gRuntimeServiceDuringInit) {
|
||||
// May be shutting down, just bail.
|
||||
return 0;
|
||||
}
|
||||
|
||||
const nsDependentCString prefName(aPrefName);
|
||||
|
||||
// Several other pref branches will get included here so bail out if there is
|
||||
// another callback that will handle this change.
|
||||
if (StringBeginsWith(prefName,
|
||||
NS_LITERAL_CSTRING(PREF_JS_OPTIONS_PREFIX
|
||||
PREF_MEM_OPTIONS_PREFIX)) ||
|
||||
StringBeginsWith(prefName,
|
||||
NS_LITERAL_CSTRING(PREF_WORKERS_OPTIONS_PREFIX
|
||||
PREF_MEM_OPTIONS_PREFIX)) ||
|
||||
prefName.EqualsLiteral(PREF_JS_OPTIONS_PREFIX PREF_JIT_HARDENING) ||
|
||||
prefName.EqualsLiteral(PREF_WORKERS_OPTIONS_PREFIX PREF_JIT_HARDENING)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
else if (!strcmp(aPrefName, gPrefsToWatch[PREF_gczeal])) {
|
||||
int32_t gczeal = Preferences::GetInt(gPrefsToWatch[PREF_gczeal]);
|
||||
RuntimeService::SetDefaultGCZeal(uint8_t(clamped(gczeal, 0, 3)));
|
||||
rts->UpdateAllWorkerGCZeal();
|
||||
if (prefName.EqualsLiteral(PREF_JS_OPTIONS_PREFIX PREF_GCZEAL) ||
|
||||
prefName.EqualsLiteral(PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Common options.
|
||||
uint32_t commonOptions = kRequiredJSContextOptions;
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict"))) {
|
||||
commonOptions |= JSOPTION_STRICT;
|
||||
}
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("werror"))) {
|
||||
commonOptions |= JSOPTION_WERROR;
|
||||
}
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("typeinference"))) {
|
||||
commonOptions |= JSOPTION_TYPE_INFERENCE;
|
||||
}
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("asmjs"))) {
|
||||
commonOptions |= JSOPTION_ASMJS;
|
||||
}
|
||||
|
||||
// Content options.
|
||||
uint32_t contentOptions = commonOptions;
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("pccounts.content"))) {
|
||||
contentOptions |= JSOPTION_PCCOUNT;
|
||||
}
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("baselinejit.content"))) {
|
||||
contentOptions |= JSOPTION_BASELINE;
|
||||
}
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("ion.content"))) {
|
||||
contentOptions |= JSOPTION_ION;
|
||||
}
|
||||
|
||||
// Chrome options.
|
||||
uint32_t chromeOptions = commonOptions;
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("pccounts.chrome"))) {
|
||||
chromeOptions |= JSOPTION_PCCOUNT;
|
||||
}
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("baselinejit.chrome"))) {
|
||||
chromeOptions |= JSOPTION_BASELINE;
|
||||
}
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("ion.chrome"))) {
|
||||
chromeOptions |= JSOPTION_ION;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict.debug"))) {
|
||||
chromeOptions |= JSOPTION_STRICT;
|
||||
}
|
||||
#endif
|
||||
|
||||
RuntimeService::SetDefaultJSContextOptions(contentOptions, chromeOptions);
|
||||
|
||||
if (rts) {
|
||||
rts->UpdateAllWorkerJSContextOptions();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
int
|
||||
LoadGCZealOptions(const char* /* aPrefName */, void* /* aClosure */)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService* rts = RuntimeService::GetService();
|
||||
if (!rts && !gRuntimeServiceDuringInit) {
|
||||
// May be shutting down, just bail.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t gczeal = GetWorkerPref<int32_t>(NS_LITERAL_CSTRING(PREF_GCZEAL), -1);
|
||||
if (gczeal < 0) {
|
||||
gczeal = 0;
|
||||
}
|
||||
|
||||
int32_t frequency =
|
||||
GetWorkerPref<int32_t>(NS_LITERAL_CSTRING("gcZeal.frequency"), -1);
|
||||
if (frequency < 0) {
|
||||
frequency = JS_DEFAULT_ZEAL_FREQ;
|
||||
}
|
||||
|
||||
RuntimeService::SetDefaultGCZeal(uint8_t(gczeal), uint32_t(frequency));
|
||||
|
||||
if (rts) {
|
||||
rts->UpdateAllWorkerGCZeal();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
UpdateCommonJSGCMemoryOption(RuntimeService* aRuntimeService,
|
||||
const nsACString& aPrefName, JSGCParamKey aKey)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
NS_ASSERTION(!aPrefName.IsEmpty(), "Empty pref name!");
|
||||
|
||||
int32_t prefValue = GetWorkerPref(aPrefName, -1);
|
||||
uint32_t value =
|
||||
(prefValue <= 0 || prefValue >= 10000) ? 0 : uint32_t(prefValue);
|
||||
|
||||
RuntimeService::SetDefaultJSGCSettings(aKey, value);
|
||||
|
||||
if (aRuntimeService) {
|
||||
aRuntimeService->UpdateAllWorkerMemoryParameter(aKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UpdatOtherJSGCMemoryOption(RuntimeService* aRuntimeService,
|
||||
JSGCParamKey aKey, uint32_t aValue)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService::SetDefaultJSGCSettings(aKey, aValue);
|
||||
|
||||
if (aRuntimeService) {
|
||||
aRuntimeService->UpdateAllWorkerMemoryParameter(aKey, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService* rts = RuntimeService::GetService();
|
||||
|
||||
if (!rts && !gRuntimeServiceDuringInit) {
|
||||
// May be shutting down, just bail.
|
||||
return 0;
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(jsPrefix, PREF_JS_OPTIONS_PREFIX);
|
||||
NS_NAMED_LITERAL_CSTRING(workersPrefix, PREF_WORKERS_OPTIONS_PREFIX);
|
||||
|
||||
const nsDependentCString fullPrefName(aPrefName);
|
||||
|
||||
// Pull out the string that actually distinguishes the parameter we need to
|
||||
// change.
|
||||
nsDependentCSubstring memPrefName;
|
||||
if (StringBeginsWith(fullPrefName, jsPrefix)) {
|
||||
memPrefName.Rebind(fullPrefName, jsPrefix.Length());
|
||||
}
|
||||
else if (StringBeginsWith(fullPrefName, workersPrefix)) {
|
||||
memPrefName.Rebind(fullPrefName, workersPrefix.Length());
|
||||
}
|
||||
else {
|
||||
NS_ERROR("Unknown pref name!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// During Init() we get called back with a branch string here, so there should
|
||||
// be no just a "mem." pref here.
|
||||
if (!rts) {
|
||||
NS_ASSERTION(memPrefName.EqualsLiteral(PREF_MEM_OPTIONS_PREFIX), "Huh?!");
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we're running in Init() then do this for every pref we care about.
|
||||
// Otherwise we just want to update the parameter that changed.
|
||||
for (uint32_t index = rts ? JSSettings::kGCSettingsArraySize - 1 : 0;
|
||||
index < JSSettings::kGCSettingsArraySize;
|
||||
index++) {
|
||||
LiteralRebindingCString matchName;
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "max");
|
||||
if (memPrefName == matchName || (!rts && index == 0)) {
|
||||
int32_t prefValue = GetWorkerPref(matchName, -1);
|
||||
uint32_t value = (prefValue <= 0 || prefValue >= 0x1000) ?
|
||||
uint32_t(-1) :
|
||||
uint32_t(prefValue) * 1024 * 1024;
|
||||
UpdatOtherJSGCMemoryOption(rts, JSGC_MAX_BYTES, value);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "high_water_mark");
|
||||
if (memPrefName == matchName || (!rts && index == 1)) {
|
||||
int32_t prefValue = GetWorkerPref(matchName, 128);
|
||||
UpdatOtherJSGCMemoryOption(rts, JSGC_MAX_MALLOC_BYTES,
|
||||
uint32_t(prefValue) * 1024 * 1024);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_high_frequency_time_limit_ms");
|
||||
if (memPrefName == matchName || (!rts && index == 2)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName,
|
||||
JSGC_HIGH_FREQUENCY_TIME_LIMIT);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_low_frequency_heap_growth");
|
||||
if (memPrefName == matchName || (!rts && index == 3)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName,
|
||||
JSGC_LOW_FREQUENCY_HEAP_GROWTH);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_high_frequency_heap_growth_min");
|
||||
if (memPrefName == matchName || (!rts && index == 4)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName,
|
||||
JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_high_frequency_heap_growth_max");
|
||||
if (memPrefName == matchName || (!rts && index == 5)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName,
|
||||
JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_high_frequency_low_limit_mb");
|
||||
if (memPrefName == matchName || (!rts && index == 6)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName,
|
||||
JSGC_HIGH_FREQUENCY_LOW_LIMIT);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_high_frequency_high_limit_mb");
|
||||
if (memPrefName == matchName || (!rts && index == 7)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName,
|
||||
JSGC_HIGH_FREQUENCY_HIGH_LIMIT);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "analysis_purge_mb");
|
||||
if (memPrefName == matchName || (!rts && index == 8)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName, JSGC_ANALYSIS_PURGE_TRIGGER);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
|
||||
"gc_allocation_threshold_mb");
|
||||
if (memPrefName == matchName || (!rts && index == 9)) {
|
||||
UpdateCommonJSGCMemoryOption(rts, matchName, JSGC_ALLOCATION_THRESHOLD);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "gc_incremental_slice_ms");
|
||||
if (memPrefName == matchName || (!rts && index == 10)) {
|
||||
int32_t prefValue = GetWorkerPref(matchName, -1);
|
||||
uint32_t value =
|
||||
(prefValue <= 0 || prefValue >= 100000) ? 0 : uint32_t(prefValue);
|
||||
UpdatOtherJSGCMemoryOption(rts, JSGC_SLICE_TIME_BUDGET, value);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "gc_dynamic_heap_growth");
|
||||
if (memPrefName == matchName || (!rts && index == 11)) {
|
||||
bool prefValue = GetWorkerPref(matchName, false);
|
||||
UpdatOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_HEAP_GROWTH,
|
||||
prefValue ? 0 : 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "gc_dynamic_mark_slice");
|
||||
if (memPrefName == matchName || (!rts && index == 12)) {
|
||||
bool prefValue = GetWorkerPref(matchName, false);
|
||||
UpdatOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_MARK_SLICE,
|
||||
prefValue ? 0 : 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsAutoCString message("Workers don't support the 'mem.");
|
||||
message.Append(memPrefName);
|
||||
message.AppendLiteral("' preference!");
|
||||
NS_WARNING(message.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
LoadJITHardeningOption(const char* /* aPrefName */, void* /* aClosure */)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService* rts = RuntimeService::GetService();
|
||||
|
||||
if (!rts && !gRuntimeServiceDuringInit) {
|
||||
// May be shutting down, just bail.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool value = GetWorkerPref(NS_LITERAL_CSTRING(PREF_JIT_HARDENING), false);
|
||||
|
||||
RuntimeService::SetDefaultJITHardening(value);
|
||||
|
||||
if (rts) {
|
||||
rts->UpdateAllWorkerJITHardening(value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -422,17 +761,33 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
||||
|
||||
// The number passed here doesn't matter, we're about to change it in the call
|
||||
// to JS_SetGCParameter.
|
||||
JSRuntime* runtime = JS_NewRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE, JS_NO_HELPER_THREADS);
|
||||
JSRuntime* runtime =
|
||||
JS_NewRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE, JS_NO_HELPER_THREADS);
|
||||
if (!runtime) {
|
||||
NS_WARNING("Could not create new runtime!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSSettings settings;
|
||||
aWorkerPrivate->CopyJSSettings(settings);
|
||||
|
||||
NS_ASSERTION((settings.chrome.options & kRequiredJSContextOptions) ==
|
||||
kRequiredJSContextOptions,
|
||||
"Somehow we lost our required chrome options!");
|
||||
NS_ASSERTION((settings.content.options & kRequiredJSContextOptions) ==
|
||||
kRequiredJSContextOptions,
|
||||
"Somehow we lost our required content options!");
|
||||
|
||||
JSSettings::JSGCSettingsArray& gcSettings = settings.gcSettings;
|
||||
|
||||
// This is the real place where we set the max memory for the runtime.
|
||||
JS_SetGCParameter(runtime, JSGC_MAX_BYTES,
|
||||
aWorkerPrivate->GetJSRuntimeHeapSize());
|
||||
JS_SetGCParameter(runtime, JSGC_ALLOCATION_THRESHOLD,
|
||||
aWorkerPrivate->GetJSWorkerAllocationThreshold());
|
||||
for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
|
||||
const JSSettings::JSGCSetting& setting = gcSettings[index];
|
||||
if (setting.IsSet()) {
|
||||
NS_ASSERTION(setting.value, "Can't handle 0 values!");
|
||||
JS_SetGCParameter(runtime, setting.key, setting.value);
|
||||
}
|
||||
}
|
||||
|
||||
JS_SetNativeStackQuota(runtime, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
|
||||
|
||||
@ -464,19 +819,14 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
||||
|
||||
js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
|
||||
|
||||
NS_ASSERTION((aWorkerPrivate->GetJSContextOptions() &
|
||||
kRequiredJSContextOptions) == kRequiredJSContextOptions,
|
||||
"Somehow we lost our required options!");
|
||||
JS_SetOptions(workerCx, aWorkerPrivate->GetJSContextOptions());
|
||||
JS_SetOptions(workerCx,
|
||||
aWorkerPrivate->IsChromeWorker() ? settings.chrome.options :
|
||||
settings.content.options);
|
||||
|
||||
JS_SetJitHardening(runtime, settings.jitHardening);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
{
|
||||
uint8_t zeal = aWorkerPrivate->GetGCZeal();
|
||||
NS_ASSERTION(zeal <= 3, "Bad zeal value!");
|
||||
|
||||
uint32_t frequency = zeal <= 2 ? JS_DEFAULT_ZEAL_FREQ : 1;
|
||||
JS_SetGCZeal(workerCx, zeal, frequency);
|
||||
}
|
||||
JS_SetGCZeal(workerCx, settings.gcZeal, settings.gcZealFrequency);
|
||||
#endif
|
||||
|
||||
if (aWorkerPrivate->IsChromeWorker()) {
|
||||
@ -650,7 +1000,7 @@ SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow)
|
||||
}
|
||||
|
||||
void
|
||||
ResumeWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow)
|
||||
ResumeWorkersForWindow(nsIScriptContext* aCx, nsPIDOMWindow* aWindow)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
@ -707,19 +1057,8 @@ WorkerCrossThreadDispatcher::PostTask(WorkerTask* aTask)
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
uint32_t RuntimeService::sDefaultJSContextOptions = kRequiredJSContextOptions;
|
||||
|
||||
uint32_t RuntimeService::sDefaultJSRuntimeHeapSize =
|
||||
WORKER_DEFAULT_RUNTIME_HEAPSIZE;
|
||||
|
||||
uint32_t RuntimeService::sDefaultJSAllocationThreshold =
|
||||
WORKER_DEFAULT_ALLOCATION_THRESHOLD;
|
||||
|
||||
int32_t RuntimeService::sCloseHandlerTimeoutSeconds = MAX_SCRIPT_RUN_TIME_SEC;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
uint8_t RuntimeService::sDefaultGCZeal = 0;
|
||||
#endif
|
||||
// This is only touched on the main thread. Initialized in Init() below.
|
||||
JSSettings RuntimeService::sDefaultJSSettings;
|
||||
|
||||
RuntimeService::RuntimeService()
|
||||
: mMutex("RuntimeService::mMutex"), mObserved(false),
|
||||
@ -972,12 +1311,15 @@ RuntimeService::ScheduleWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
JS_ReportError(aCx, "Could not create new thread!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPriority> priority = do_QueryInterface(thread);
|
||||
if (!priority ||
|
||||
NS_FAILED(priority->SetPriority(nsISupportsPriority::PRIORITY_LOW))) {
|
||||
NS_WARNING("Could not lower the new thread's priority!");
|
||||
}
|
||||
int32_t priority = aWorkerPrivate->IsChromeWorker() ?
|
||||
nsISupportsPriority::PRIORITY_NORMAL :
|
||||
nsISupportsPriority::PRIORITY_LOW;
|
||||
|
||||
nsCOMPtr<nsISupportsPriority> threadPriority = do_QueryInterface(thread);
|
||||
if (!threadPriority || NS_FAILED(threadPriority->SetPriority(priority))) {
|
||||
NS_WARNING("Could not set the thread's priority!");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -1058,8 +1400,24 @@ nsresult
|
||||
RuntimeService::Init()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsLayoutStatics::AddRef();
|
||||
|
||||
// Initialize JSSettings.
|
||||
if (!sDefaultJSSettings.gcSettings[0].IsSet()) {
|
||||
sDefaultJSSettings.chrome.options = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.chrome.maxScriptRuntime = -1;
|
||||
sDefaultJSSettings.content.options = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC;
|
||||
#ifdef JS_GC_ZEAL
|
||||
sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ;
|
||||
sDefaultJSSettings.gcZeal = 0;
|
||||
#endif
|
||||
SetDefaultJSGCSettings(JSGC_MAX_BYTES, WORKER_DEFAULT_RUNTIME_HEAPSIZE);
|
||||
SetDefaultJSGCSettings(JSGC_ALLOCATION_THRESHOLD,
|
||||
WORKER_DEFAULT_ALLOCATION_THRESHOLD);
|
||||
}
|
||||
|
||||
mIdleThreadTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
NS_ENSURE_STATE(mIdleThreadTimer);
|
||||
|
||||
@ -1084,21 +1442,59 @@ RuntimeService::Init()
|
||||
NS_WARNING("Failed to register for memory pressure notifications!");
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < ArrayLength(gPrefsToWatch); index++) {
|
||||
if (NS_FAILED(Preferences::RegisterCallback(PrefCallback,
|
||||
gPrefsToWatch[index], this))) {
|
||||
NS_WARNING("Failed to register pref callback?!");
|
||||
}
|
||||
PrefCallback(gPrefsToWatch[index], this);
|
||||
NS_ASSERTION(!gRuntimeServiceDuringInit, "This should be null!");
|
||||
gRuntimeServiceDuringInit = this;
|
||||
|
||||
if (NS_FAILED(Preferences::RegisterCallback(
|
||||
LoadJSGCMemoryOptions,
|
||||
PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadJSGCMemoryOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallback(
|
||||
LoadJITHardeningOption,
|
||||
PREF_JS_OPTIONS_PREFIX PREF_JIT_HARDENING,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadJITHardeningOption,
|
||||
PREF_WORKERS_OPTIONS_PREFIX PREF_JIT_HARDENING,
|
||||
nullptr)) ||
|
||||
#ifdef JS_GC_ZEAL
|
||||
NS_FAILED(Preferences::RegisterCallback(
|
||||
LoadGCZealOptions,
|
||||
PREF_JS_OPTIONS_PREFIX PREF_GCZEAL,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadGCZealOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL,
|
||||
nullptr)) ||
|
||||
#endif
|
||||
NS_FAILED(Preferences::RegisterCallback(LoadJSContextOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadJSContextOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr))) {
|
||||
NS_WARNING("Failed to register pref callbacks!");
|
||||
}
|
||||
|
||||
NS_ASSERTION(gRuntimeServiceDuringInit == this, "Should be 'this'!");
|
||||
gRuntimeServiceDuringInit = nullptr;
|
||||
|
||||
// We assume atomic 32bit reads/writes. If this assumption doesn't hold on
|
||||
// some wacky platform then the worst that could happen is that the close
|
||||
// handler will run for a slightly different amount of time.
|
||||
if (NS_FAILED(Preferences::AddIntVarCache(&sCloseHandlerTimeoutSeconds,
|
||||
PREF_MAX_SCRIPT_RUN_TIME,
|
||||
MAX_SCRIPT_RUN_TIME_SEC))) {
|
||||
NS_WARNING("Failed to register timeout cache?!");
|
||||
if (NS_FAILED(Preferences::AddIntVarCache(
|
||||
&sDefaultJSSettings.content.maxScriptRuntime,
|
||||
PREF_MAX_SCRIPT_RUN_TIME_CONTENT,
|
||||
MAX_SCRIPT_RUN_TIME_SEC)) ||
|
||||
NS_FAILED(Preferences::AddIntVarCache(
|
||||
&sDefaultJSSettings.chrome.maxScriptRuntime,
|
||||
PREF_MAX_SCRIPT_RUN_TIME_CHROME, -1))) {
|
||||
NS_WARNING("Failed to register timeout cache!");
|
||||
}
|
||||
|
||||
int32_t maxPerDomain = Preferences::GetInt(PREF_WORKERS_MAX_PER_DOMAIN,
|
||||
@ -1215,8 +1611,39 @@ RuntimeService::Cleanup()
|
||||
}
|
||||
|
||||
if (mObserved) {
|
||||
for (uint32_t index = 0; index < ArrayLength(gPrefsToWatch); index++) {
|
||||
Preferences::UnregisterCallback(PrefCallback, gPrefsToWatch[index], this);
|
||||
if (NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
#ifdef JS_GC_ZEAL
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
LoadGCZealOptions,
|
||||
PREF_JS_OPTIONS_PREFIX PREF_GCZEAL,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
LoadGCZealOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL,
|
||||
nullptr)) ||
|
||||
#endif
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
LoadJSGCMemoryOptions,
|
||||
PREF_JS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
LoadJSGCMemoryOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX PREF_MEM_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
LoadJITHardeningOption,
|
||||
PREF_JS_OPTIONS_PREFIX PREF_JIT_HARDENING,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
LoadJITHardeningOption,
|
||||
PREF_WORKERS_OPTIONS_PREFIX PREF_JIT_HARDENING,
|
||||
nullptr))) {
|
||||
NS_WARNING("Failed to unregister pref callbacks!");
|
||||
}
|
||||
|
||||
if (obs) {
|
||||
@ -1321,7 +1748,7 @@ RuntimeService::SuspendWorkersForWindow(JSContext* aCx,
|
||||
}
|
||||
|
||||
void
|
||||
RuntimeService::ResumeWorkersForWindow(JSContext* aCx,
|
||||
RuntimeService::ResumeWorkersForWindow(nsIScriptContext* aCx,
|
||||
nsPIDOMWindow* aWindow)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
@ -1331,7 +1758,7 @@ RuntimeService::ResumeWorkersForWindow(JSContext* aCx,
|
||||
|
||||
if (!workers.IsEmpty()) {
|
||||
for (uint32_t index = 0; index < workers.Length(); index++) {
|
||||
if (!workers[index]->Resume(aCx)) {
|
||||
if (!workers[index]->SynchronizeAndResume(aCx)) {
|
||||
NS_WARNING("Failed to cancel worker!");
|
||||
}
|
||||
}
|
||||
@ -1387,25 +1814,33 @@ RuntimeService::NoteIdleThread(nsIThread* aThread)
|
||||
void
|
||||
RuntimeService::UpdateAllWorkerJSContextOptions()
|
||||
{
|
||||
BROADCAST_ALL_WORKERS(UpdateJSContextOptions, GetDefaultJSContextOptions());
|
||||
BROADCAST_ALL_WORKERS(UpdateJSContextOptions,
|
||||
sDefaultJSSettings.content.options,
|
||||
sDefaultJSSettings.chrome.options);
|
||||
}
|
||||
|
||||
void
|
||||
RuntimeService::UpdateAllWorkerMemoryParameter(JSGCParamKey key)
|
||||
RuntimeService::UpdateAllWorkerMemoryParameter(JSGCParamKey aKey,
|
||||
uint32_t aValue)
|
||||
{
|
||||
BROADCAST_ALL_WORKERS(UpdateJSWorkerMemoryParameter,
|
||||
key,
|
||||
GetDefaultJSWorkerMemoryParameter(key));
|
||||
BROADCAST_ALL_WORKERS(UpdateJSWorkerMemoryParameter, aKey, aValue);
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
void
|
||||
RuntimeService::UpdateAllWorkerGCZeal()
|
||||
{
|
||||
BROADCAST_ALL_WORKERS(UpdateGCZeal, GetDefaultGCZeal());
|
||||
BROADCAST_ALL_WORKERS(UpdateGCZeal, sDefaultJSSettings.gcZeal,
|
||||
sDefaultJSSettings.gcZealFrequency);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
RuntimeService::UpdateAllWorkerJITHardening(bool aJITHardening)
|
||||
{
|
||||
BROADCAST_ALL_WORKERS(UpdateJITHardening, aJITHardening);
|
||||
}
|
||||
|
||||
void
|
||||
RuntimeService::GarbageCollectAllWorkers(bool aShrinking)
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -20,7 +21,6 @@
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class nsIThread;
|
||||
class nsITimer;
|
||||
@ -71,14 +71,7 @@ class RuntimeService MOZ_FINAL : public nsIObserver
|
||||
nsCString mDetectorName;
|
||||
nsCString mSystemCharset;
|
||||
|
||||
static uint32_t sDefaultJSContextOptions;
|
||||
static uint32_t sDefaultJSRuntimeHeapSize;
|
||||
static uint32_t sDefaultJSAllocationThreshold;
|
||||
static int32_t sCloseHandlerTimeoutSeconds;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
static uint8_t sDefaultGCZeal;
|
||||
#endif
|
||||
static JSSettings sDefaultJSSettings;
|
||||
|
||||
public:
|
||||
struct NavigatorStrings
|
||||
@ -120,7 +113,7 @@ public:
|
||||
SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
|
||||
|
||||
void
|
||||
ResumeWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
|
||||
ResumeWorkersForWindow(nsIScriptContext* aCx, nsPIDOMWindow* aWindow);
|
||||
|
||||
const nsACString&
|
||||
GetDetectorName() const
|
||||
@ -143,81 +136,69 @@ public:
|
||||
void
|
||||
NoteIdleThread(nsIThread* aThread);
|
||||
|
||||
static uint32_t
|
||||
GetDefaultJSContextOptions()
|
||||
static void
|
||||
GetDefaultJSSettings(JSSettings& aSettings)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
return sDefaultJSContextOptions;
|
||||
aSettings = sDefaultJSSettings;
|
||||
}
|
||||
|
||||
static void
|
||||
SetDefaultJSContextOptions(uint32_t aOptions)
|
||||
SetDefaultJSContextOptions(uint32_t aContentOptions, uint32_t aChromeOptions)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
sDefaultJSContextOptions = aOptions;
|
||||
sDefaultJSSettings.content.options = aContentOptions;
|
||||
sDefaultJSSettings.chrome.options = aChromeOptions;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateAllWorkerJSContextOptions();
|
||||
|
||||
static uint32_t
|
||||
GetDefaultJSWorkerMemoryParameter(JSGCParamKey aKey)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
switch (aKey) {
|
||||
case JSGC_ALLOCATION_THRESHOLD:
|
||||
return sDefaultJSAllocationThreshold;
|
||||
case JSGC_MAX_BYTES:
|
||||
return sDefaultJSRuntimeHeapSize;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unknown Worker Memory Parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SetDefaultJSWorkerMemoryParameter(JSGCParamKey aKey, uint32_t aValue)
|
||||
SetDefaultJSGCSettings(JSGCParamKey aKey, uint32_t aValue)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
switch(aKey) {
|
||||
case JSGC_ALLOCATION_THRESHOLD:
|
||||
sDefaultJSAllocationThreshold = aValue;
|
||||
break;
|
||||
case JSGC_MAX_BYTES:
|
||||
sDefaultJSRuntimeHeapSize = aValue;
|
||||
break;
|
||||
default:
|
||||
MOZ_NOT_REACHED("Unknown Worker Memory Parameter.");
|
||||
}
|
||||
sDefaultJSSettings.ApplyGCSetting(aKey, aValue);
|
||||
}
|
||||
|
||||
void
|
||||
UpdateAllWorkerMemoryParameter(JSGCParamKey aKey);
|
||||
UpdateAllWorkerMemoryParameter(JSGCParamKey aKey, uint32_t aValue);
|
||||
|
||||
static uint32_t
|
||||
GetCloseHandlerTimeoutSeconds()
|
||||
GetContentCloseHandlerTimeoutSeconds()
|
||||
{
|
||||
return sCloseHandlerTimeoutSeconds > 0 ? sCloseHandlerTimeoutSeconds : 0;
|
||||
return sDefaultJSSettings.content.maxScriptRuntime;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
GetChromeCloseHandlerTimeoutSeconds()
|
||||
{
|
||||
return sDefaultJSSettings.chrome.maxScriptRuntime;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
static uint8_t
|
||||
GetDefaultGCZeal()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
return sDefaultGCZeal;
|
||||
}
|
||||
|
||||
static void
|
||||
SetDefaultGCZeal(uint8_t aGCZeal)
|
||||
SetDefaultGCZeal(uint8_t aGCZeal, uint32_t aFrequency)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
sDefaultGCZeal = aGCZeal;
|
||||
sDefaultJSSettings.gcZeal = aGCZeal;
|
||||
sDefaultJSSettings.gcZealFrequency = aFrequency;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateAllWorkerGCZeal();
|
||||
#endif
|
||||
|
||||
static void
|
||||
SetDefaultJITHardening(bool aJITHardening)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
sDefaultJSSettings.jitHardening = aJITHardening;
|
||||
}
|
||||
|
||||
void
|
||||
UpdateAllWorkerJITHardening(bool aJITHardening);
|
||||
|
||||
void
|
||||
GarbageCollectAllWorkers(bool aShrinking);
|
||||
|
||||
|
@ -26,11 +26,14 @@
|
||||
#include "nsIXPCScriptNotify.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsprf.h"
|
||||
#include "js/MemoryMetrics.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCxPusher.h"
|
||||
@ -44,9 +47,6 @@
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
@ -63,10 +63,6 @@
|
||||
#include "WorkerFeature.h"
|
||||
#include "WorkerScope.h"
|
||||
|
||||
#if 0 // Define to run GC more often.
|
||||
#define EXTRA_GC
|
||||
#endif
|
||||
|
||||
// GC will run once every thirty seconds during normal execution.
|
||||
#define NORMAL_GC_TIMER_DELAY_MS 30000
|
||||
|
||||
@ -77,6 +73,7 @@ using mozilla::MutexAutoLock;
|
||||
using mozilla::TimeDuration;
|
||||
using mozilla::TimeStamp;
|
||||
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
|
||||
using mozilla::AutoPushJSContext;
|
||||
using mozilla::AutoSafeJSContext;
|
||||
|
||||
USING_WORKERS_NAMESPACE
|
||||
@ -1307,19 +1304,22 @@ public:
|
||||
|
||||
class UpdateJSContextOptionsRunnable : public WorkerControlRunnable
|
||||
{
|
||||
uint32_t mOptions;
|
||||
uint32_t mContentOptions;
|
||||
uint32_t mChromeOptions;
|
||||
|
||||
public:
|
||||
UpdateJSContextOptionsRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
uint32_t aOptions)
|
||||
uint32_t aContentOptions,
|
||||
uint32_t aChromeOptions)
|
||||
: WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount),
|
||||
mOptions(aOptions)
|
||||
mContentOptions(aContentOptions), mChromeOptions(aChromeOptions)
|
||||
{ }
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
aWorkerPrivate->UpdateJSContextOptionsInternal(aCx, mOptions);
|
||||
aWorkerPrivate->UpdateJSContextOptionsInternal(aCx, mContentOptions,
|
||||
mChromeOptions);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -1349,23 +1349,43 @@ public:
|
||||
class UpdateGCZealRunnable : public WorkerControlRunnable
|
||||
{
|
||||
uint8_t mGCZeal;
|
||||
uint32_t mFrequency;
|
||||
|
||||
public:
|
||||
UpdateGCZealRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
uint8_t aGCZeal)
|
||||
uint8_t aGCZeal,
|
||||
uint32_t aFrequency)
|
||||
: WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount),
|
||||
mGCZeal(aGCZeal)
|
||||
mGCZeal(aGCZeal), mFrequency(aFrequency)
|
||||
{ }
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
aWorkerPrivate->UpdateGCZealInternal(aCx, mGCZeal);
|
||||
aWorkerPrivate->UpdateGCZealInternal(aCx, mGCZeal, mFrequency);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
class UpdateJITHardeningRunnable : public WorkerControlRunnable
|
||||
{
|
||||
bool mJITHardening;
|
||||
|
||||
public:
|
||||
UpdateJITHardeningRunnable(WorkerPrivate* aWorkerPrivate, bool aJITHardening)
|
||||
: WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount),
|
||||
mJITHardening(aJITHardening)
|
||||
{ }
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
aWorkerPrivate->UpdateJITHardeningInternal(aCx, mJITHardening);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class GarbageCollectRunnable : public WorkerControlRunnable
|
||||
{
|
||||
protected:
|
||||
@ -1403,6 +1423,33 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class SynchronizeAndResumeRunnable : public nsRunnable
|
||||
{
|
||||
protected:
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsCOMPtr<nsIScriptContext> mCx;
|
||||
|
||||
public:
|
||||
SynchronizeAndResumeRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
nsIScriptContext* aCx)
|
||||
: mWorkerPrivate(aWorkerPrivate), mCx(aCx)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
AutoPushJSContext cx(mCx ? mCx->GetNativeContext() :
|
||||
nsContentUtils::GetSafeJSContext());
|
||||
JSAutoRequest ar(cx);
|
||||
mWorkerPrivate->Resume(cx);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class WorkerJSRuntimeStats : public JS::RuntimeStats
|
||||
{
|
||||
const nsACString& mRtPath;
|
||||
@ -1812,9 +1859,7 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
mMemoryReportCondVar(mMutex, "WorkerPrivateParent Memory Report CondVar"),
|
||||
mJSObject(aObject), mParent(aParent), mParentJSContext(aParentJSContext),
|
||||
mScriptURL(aScriptURL), mDomain(aDomain), mBusyCount(0),
|
||||
mParentStatus(Pending), mJSContextOptions(0),
|
||||
mJSRuntimeHeapSize(0), mJSWorkerAllocationThreshold(3),
|
||||
mGCZeal(0), mJSObjectRooted(false), mParentSuspended(false),
|
||||
mParentStatus(Pending), mJSObjectRooted(false), mParentSuspended(false),
|
||||
mIsChromeWorker(aIsChromeWorker), mPrincipalIsSystem(false),
|
||||
mMainThreadObjectsForgotten(false), mEvalAllowed(aEvalAllowed),
|
||||
mReportCSPViolations(aReportCSPViolations)
|
||||
@ -1836,32 +1881,17 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
if (aParent) {
|
||||
aParent->AssertIsOnWorkerThread();
|
||||
|
||||
NS_ASSERTION(JS_GetOptions(aCx) == aParent->GetJSContextOptions(),
|
||||
aParent->CopyJSSettings(mJSSettings);
|
||||
|
||||
NS_ASSERTION(JS_GetOptions(aCx) == (aParent->IsChromeWorker() ?
|
||||
mJSSettings.chrome.options :
|
||||
mJSSettings.content.options),
|
||||
"Options mismatch!");
|
||||
mJSContextOptions = aParent->GetJSContextOptions();
|
||||
|
||||
NS_ASSERTION(JS_GetGCParameter(JS_GetRuntime(aCx), JSGC_MAX_BYTES) ==
|
||||
aParent->GetJSRuntimeHeapSize(),
|
||||
"Runtime heap size mismatch!");
|
||||
mJSRuntimeHeapSize = aParent->GetJSRuntimeHeapSize();
|
||||
|
||||
mJSWorkerAllocationThreshold = aParent->GetJSWorkerAllocationThreshold();
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
mGCZeal = aParent->GetGCZeal();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
mJSContextOptions = RuntimeService::GetDefaultJSContextOptions();
|
||||
mJSRuntimeHeapSize =
|
||||
RuntimeService::GetDefaultJSWorkerMemoryParameter(JSGC_MAX_BYTES);
|
||||
mJSWorkerAllocationThreshold =
|
||||
RuntimeService::GetDefaultJSWorkerMemoryParameter(JSGC_ALLOCATION_THRESHOLD);
|
||||
#ifdef JS_GC_ZEAL
|
||||
mGCZeal = RuntimeService::GetDefaultGCZeal();
|
||||
#endif
|
||||
RuntimeService::GetDefaultJSSettings(mJSSettings);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1959,7 +1989,7 @@ WorkerPrivateParent<Derived>::Suspend(JSContext* aCx)
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
bool
|
||||
void
|
||||
WorkerPrivateParent<Derived>::Resume(JSContext* aCx)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
@ -1971,11 +2001,11 @@ WorkerPrivateParent<Derived>::Resume(JSContext* aCx)
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (mParentStatus >= Terminating) {
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch queued runnables before waking up the worker, otherwise the worker
|
||||
// Execute queued runnables before waking up the worker, otherwise the worker
|
||||
// could post new messages before we run those that have been queued.
|
||||
if (!mQueuedRunnables.IsEmpty()) {
|
||||
AssertIsOnMainThread();
|
||||
@ -1985,19 +2015,31 @@ WorkerPrivateParent<Derived>::Resume(JSContext* aCx)
|
||||
|
||||
for (uint32_t index = 0; index < runnables.Length(); index++) {
|
||||
nsRefPtr<WorkerRunnable>& runnable = runnables[index];
|
||||
if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
|
||||
NS_WARNING("Failed to dispatch queued runnable!");
|
||||
}
|
||||
runnable->Run();
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<ResumeRunnable> runnable =
|
||||
new ResumeRunnable(ParentAsWorkerPrivate());
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
return false;
|
||||
}
|
||||
runnable->Dispatch(aCx);
|
||||
}
|
||||
|
||||
return true;
|
||||
template <class Derived>
|
||||
bool
|
||||
WorkerPrivateParent<Derived>::SynchronizeAndResume(nsIScriptContext* aCx)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
NS_ASSERTION(mParentSuspended, "Not yet suspended!");
|
||||
|
||||
// NB: There may be pending unqueued messages. If we resume here we will
|
||||
// execute those messages out of order. Instead we post an event to the
|
||||
// end of the event queue, allowing all of the outstanding messages to be
|
||||
// queued up in order on the worker. Then and only then we execute all of
|
||||
// the messages.
|
||||
|
||||
nsRefPtr<SynchronizeAndResumeRunnable> runnable =
|
||||
new SynchronizeAndResumeRunnable(ParentAsWorkerPrivate(), aCx);
|
||||
return NS_SUCCEEDED(NS_DispatchToCurrentThread(runnable));
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
@ -2210,14 +2252,20 @@ WorkerPrivateParent<Derived>::GetInnerWindowId()
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::UpdateJSContextOptions(JSContext* aCx,
|
||||
uint32_t aOptions)
|
||||
uint32_t aContentOptions,
|
||||
uint32_t aChromeOptions)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
mJSContextOptions = aOptions;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mJSSettings.content.options = aContentOptions;
|
||||
mJSSettings.chrome.options = aChromeOptions;
|
||||
}
|
||||
|
||||
nsRefPtr<UpdateJSContextOptionsRunnable> runnable =
|
||||
new UpdateJSContextOptionsRunnable(ParentAsWorkerPrivate(), aOptions);
|
||||
new UpdateJSContextOptionsRunnable(ParentAsWorkerPrivate(), aContentOptions,
|
||||
aChromeOptions);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
NS_WARNING("Failed to update worker context options!");
|
||||
JS_ClearPendingException(aCx);
|
||||
@ -2231,38 +2279,41 @@ WorkerPrivateParent<Derived>::UpdateJSWorkerMemoryParameter(JSContext* aCx,
|
||||
uint32_t aValue)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
switch(aKey) {
|
||||
case JSGC_ALLOCATION_THRESHOLD:
|
||||
mJSWorkerAllocationThreshold = aValue;
|
||||
break;
|
||||
case JSGC_MAX_BYTES:
|
||||
mJSRuntimeHeapSize = aValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
bool found = false;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
found = mJSSettings.ApplyGCSetting(aKey, aValue);
|
||||
}
|
||||
|
||||
nsRefPtr<UpdateJSWorkerMemoryParameterRunnable> runnable =
|
||||
new UpdateJSWorkerMemoryParameterRunnable(ParentAsWorkerPrivate(),
|
||||
aKey,
|
||||
aValue);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
NS_WARNING("Failed to update memory parameter!");
|
||||
JS_ClearPendingException(aCx);
|
||||
if (found) {
|
||||
nsRefPtr<UpdateJSWorkerMemoryParameterRunnable> runnable =
|
||||
new UpdateJSWorkerMemoryParameterRunnable(ParentAsWorkerPrivate(), aKey,
|
||||
aValue);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
NS_WARNING("Failed to update memory parameter!");
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal)
|
||||
WorkerPrivateParent<Derived>::UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal,
|
||||
uint32_t aFrequency)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
mGCZeal = aGCZeal;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mJSSettings.gcZeal = aGCZeal;
|
||||
mJSSettings.gcZealFrequency = aFrequency;
|
||||
}
|
||||
|
||||
nsRefPtr<UpdateGCZealRunnable> runnable =
|
||||
new UpdateGCZealRunnable(ParentAsWorkerPrivate(), aGCZeal);
|
||||
new UpdateGCZealRunnable(ParentAsWorkerPrivate(), aGCZeal, aFrequency);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
NS_WARNING("Failed to update worker gczeal!");
|
||||
JS_ClearPendingException(aCx);
|
||||
@ -2270,6 +2321,26 @@ WorkerPrivateParent<Derived>::UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal)
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::UpdateJITHardening(JSContext* aCx,
|
||||
bool aJITHardening)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mJSSettings.jitHardening = aJITHardening;
|
||||
}
|
||||
|
||||
nsRefPtr<UpdateJITHardeningRunnable> runnable =
|
||||
new UpdateJITHardeningRunnable(ParentAsWorkerPrivate(), aJITHardening);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
NS_WARNING("Failed to update worker jit hardening!");
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::GarbageCollect(JSContext* aCx, bool aShrinking)
|
||||
@ -2752,11 +2823,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXTRA_GC
|
||||
// Find GC bugs...
|
||||
JS_GC(aCx);
|
||||
#endif
|
||||
|
||||
// Keep track of whether or not this is the idle GC event.
|
||||
eventIsNotIdleGCEvent = event != idleGCEvent;
|
||||
|
||||
@ -2767,7 +2833,8 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
currentStatus = mStatus;
|
||||
scheduleIdleGC = mControlQueue.IsEmpty() &&
|
||||
mQueue.IsEmpty() &&
|
||||
eventIsNotIdleGCEvent;
|
||||
eventIsNotIdleGCEvent &&
|
||||
JS_GetGlobalForScopeChain(aCx);
|
||||
}
|
||||
|
||||
// Take care of the GC timer. If we're starting the close sequence then we
|
||||
@ -2783,6 +2850,12 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
}
|
||||
|
||||
if (scheduleIdleGC) {
|
||||
NS_ASSERTION(JS_GetGlobalForScopeChain(aCx), "Should have global here!");
|
||||
|
||||
// Now *might* be a good time to GC. Let the JS engine make the decision.
|
||||
JSAutoCompartment ac(aCx, JS_GetGlobalForScopeChain(aCx));
|
||||
JS_MaybeGC(aCx);
|
||||
|
||||
if (NS_SUCCEEDED(gcTimer->SetTarget(idleGCEventTarget)) &&
|
||||
NS_SUCCEEDED(gcTimer->InitWithFuncCallback(
|
||||
DummyCallback, nullptr,
|
||||
@ -2794,11 +2867,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXTRA_GC
|
||||
// Find GC bugs...
|
||||
JS_GC(aCx);
|
||||
#endif
|
||||
|
||||
if (currentStatus != Running && !HasActiveFeatures()) {
|
||||
// If the close handler has finished and all features are done then we can
|
||||
// kill this thread.
|
||||
@ -3462,19 +3530,9 @@ WorkerPrivate::RunSyncLoop(JSContext* aCx, uint32_t aSyncLoopKey)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXTRA_GC
|
||||
// Find GC bugs...
|
||||
JS_GC(mJSContext);
|
||||
#endif
|
||||
|
||||
static_cast<nsIRunnable*>(event)->Run();
|
||||
NS_RELEASE(event);
|
||||
|
||||
#ifdef EXTRA_GC
|
||||
// Find GC bugs...
|
||||
JS_GC(mJSContext);
|
||||
#endif
|
||||
|
||||
if (syncQueue->mComplete) {
|
||||
NS_ASSERTION(mSyncQueues.Length() - 1 == aSyncLoopKey,
|
||||
"Mismatched calls!");
|
||||
@ -3646,7 +3704,10 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
|
||||
previousStatus == Terminating,
|
||||
"Bad previous status!");
|
||||
|
||||
uint32_t killSeconds = RuntimeService::GetCloseHandlerTimeoutSeconds();
|
||||
uint32_t killSeconds = IsChromeWorker() ?
|
||||
RuntimeService::GetChromeCloseHandlerTimeoutSeconds() :
|
||||
RuntimeService::GetContentCloseHandlerTimeoutSeconds();
|
||||
|
||||
if (killSeconds) {
|
||||
mKillTime = TimeStamp::Now() + TimeDuration::FromSeconds(killSeconds);
|
||||
|
||||
@ -4061,14 +4122,17 @@ WorkerPrivate::RescheduleTimeoutTimer(JSContext* aCx)
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::UpdateJSContextOptionsInternal(JSContext* aCx, uint32_t aOptions)
|
||||
WorkerPrivate::UpdateJSContextOptionsInternal(JSContext* aCx,
|
||||
uint32_t aContentOptions,
|
||||
uint32_t aChromeOptions)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
JS_SetOptions(aCx, aOptions);
|
||||
JS_SetOptions(aCx, IsChromeWorker() ? aChromeOptions : aContentOptions);
|
||||
|
||||
for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
|
||||
mChildWorkers[index]->UpdateJSContextOptions(aCx, aOptions);
|
||||
mChildWorkers[index]->UpdateJSContextOptions(aCx, aContentOptions,
|
||||
aChromeOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4078,7 +4142,14 @@ WorkerPrivate::UpdateJSWorkerMemoryParameterInternal(JSContext* aCx,
|
||||
uint32_t aValue)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
JS_SetGCParameter(JS_GetRuntime(aCx), aKey, aValue);
|
||||
|
||||
// XXX aValue might be 0 here (telling us to unset a previous value for child
|
||||
// workers). Calling JS_SetGCParameter with a value of 0 isn't actually
|
||||
// supported though. We really need some way to revert to a default value
|
||||
// here.
|
||||
if (aValue) {
|
||||
JS_SetGCParameter(JS_GetRuntime(aCx), aKey, aValue);
|
||||
}
|
||||
|
||||
for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
|
||||
mChildWorkers[index]->UpdateJSWorkerMemoryParameter(aCx, aKey, aValue);
|
||||
@ -4087,32 +4158,53 @@ WorkerPrivate::UpdateJSWorkerMemoryParameterInternal(JSContext* aCx,
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
void
|
||||
WorkerPrivate::UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal)
|
||||
WorkerPrivate::UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal,
|
||||
uint32_t aFrequency)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
uint32_t frequency = aGCZeal <= 2 ? JS_DEFAULT_ZEAL_FREQ : 1;
|
||||
JS_SetGCZeal(aCx, aGCZeal, frequency);
|
||||
JS_SetGCZeal(aCx, aGCZeal, aFrequency);
|
||||
|
||||
for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
|
||||
mChildWorkers[index]->UpdateGCZeal(aCx, aGCZeal);
|
||||
mChildWorkers[index]->UpdateGCZeal(aCx, aGCZeal, aFrequency);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
WorkerPrivate::UpdateJITHardeningInternal(JSContext* aCx, bool aJITHardening)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
JS_SetJitHardening(JS_GetRuntime(aCx), aJITHardening);
|
||||
|
||||
for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
|
||||
mChildWorkers[index]->UpdateJITHardening(aCx, aJITHardening);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
|
||||
bool aCollectChildren)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
JSRuntime *rt = JS_GetRuntime(aCx);
|
||||
JS::PrepareForFullGC(rt);
|
||||
if (aShrinking) {
|
||||
JS::ShrinkingGC(rt, JS::gcreason::DOM_WORKER);
|
||||
if (aCollectChildren) {
|
||||
JSRuntime* rt = JS_GetRuntime(aCx);
|
||||
JS::PrepareForFullGC(rt);
|
||||
if (aShrinking) {
|
||||
JS::ShrinkingGC(rt, JS::gcreason::DOM_WORKER);
|
||||
}
|
||||
else {
|
||||
JS::GCForReason(rt, JS::gcreason::DOM_WORKER);
|
||||
}
|
||||
}
|
||||
else {
|
||||
JS::GCForReason(rt, JS::gcreason::DOM_WORKER);
|
||||
// If aCollectChildren is false then it means this collection request was
|
||||
// not generated by the main thread. At the moment only the periodic GC
|
||||
// timer can end up here, so rather than force a collection let the JS
|
||||
// engine decide if we need one.
|
||||
JS_MaybeGC(aCx);
|
||||
}
|
||||
|
||||
if (aCollectChildren) {
|
||||
|
@ -42,7 +42,10 @@ class nsIURI;
|
||||
class nsPIDOMWindow;
|
||||
class nsITimer;
|
||||
class nsIXPCScriptNotify;
|
||||
namespace JS { struct RuntimeStats; }
|
||||
|
||||
namespace JS {
|
||||
class RuntimeStats;
|
||||
}
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
@ -109,7 +112,7 @@ protected:
|
||||
|
||||
void NotifyScriptExecutedIfNeeded() const;
|
||||
|
||||
private:
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
};
|
||||
|
||||
@ -274,12 +277,11 @@ private:
|
||||
// Only used for top level workers.
|
||||
nsTArray<nsRefPtr<WorkerRunnable> > mQueuedRunnables;
|
||||
|
||||
// Protected by mMutex.
|
||||
JSSettings mJSSettings;
|
||||
|
||||
uint64_t mBusyCount;
|
||||
Status mParentStatus;
|
||||
uint32_t mJSContextOptions;
|
||||
uint32_t mJSRuntimeHeapSize;
|
||||
uint32_t mJSWorkerAllocationThreshold;
|
||||
uint8_t mGCZeal;
|
||||
bool mJSObjectRooted;
|
||||
bool mParentSuspended;
|
||||
bool mIsChromeWorker;
|
||||
@ -348,9 +350,12 @@ public:
|
||||
bool
|
||||
Suspend(JSContext* aCx);
|
||||
|
||||
bool
|
||||
void
|
||||
Resume(JSContext* aCx);
|
||||
|
||||
bool
|
||||
SynchronizeAndResume(nsIScriptContext* aCx);
|
||||
|
||||
virtual void
|
||||
_trace(JSTracer* aTrc) MOZ_OVERRIDE;
|
||||
|
||||
@ -391,16 +396,21 @@ public:
|
||||
GetInnerWindowId();
|
||||
|
||||
void
|
||||
UpdateJSContextOptions(JSContext* aCx, uint32_t aOptions);
|
||||
UpdateJSContextOptions(JSContext* aCx, uint32_t aChromeOptions,
|
||||
uint32_t aContentOptions);
|
||||
|
||||
void
|
||||
UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key, uint32_t value);
|
||||
UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
|
||||
uint32_t value);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
void
|
||||
UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal);
|
||||
UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
|
||||
#endif
|
||||
|
||||
void
|
||||
UpdateJITHardening(JSContext* aCx, bool aJITHardening);
|
||||
|
||||
void
|
||||
GarbageCollect(JSContext* aCx, bool aShrinking);
|
||||
|
||||
@ -577,32 +587,13 @@ public:
|
||||
return mLocationInfo;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetJSContextOptions() const
|
||||
void
|
||||
CopyJSSettings(JSSettings& aSettings)
|
||||
{
|
||||
return mJSContextOptions;
|
||||
mozilla::MutexAutoLock lock(mMutex);
|
||||
aSettings = mJSSettings;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetJSRuntimeHeapSize() const
|
||||
{
|
||||
return mJSRuntimeHeapSize;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetJSWorkerAllocationThreshold() const
|
||||
{
|
||||
return mJSWorkerAllocationThreshold;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
uint8_t
|
||||
GetGCZeal() const
|
||||
{
|
||||
return mGCZeal;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
IsChromeWorker() const
|
||||
{
|
||||
@ -815,7 +806,8 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
UpdateJSContextOptionsInternal(JSContext* aCx, uint32_t aOptions);
|
||||
UpdateJSContextOptionsInternal(JSContext* aCx, uint32_t aContentOptions,
|
||||
uint32_t aChromeOptions);
|
||||
|
||||
void
|
||||
UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
|
||||
@ -840,9 +832,12 @@ public:
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
void
|
||||
UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal);
|
||||
UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
|
||||
#endif
|
||||
|
||||
void
|
||||
UpdateJITHardeningInternal(JSContext* aCx, bool aJITHardening);
|
||||
|
||||
void
|
||||
GarbageCollectInternal(JSContext* aCx, bool aShrinking,
|
||||
bool aCollectChildren);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown"
|
||||
|
||||
class nsIScriptContext;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
@ -42,10 +43,130 @@ AssertIsOnMainThread()
|
||||
{ }
|
||||
#endif
|
||||
|
||||
struct JSSettings
|
||||
{
|
||||
enum {
|
||||
// All the GC parameters that we support.
|
||||
JSSettings_JSGC_MAX_BYTES = 0,
|
||||
JSSettings_JSGC_MAX_MALLOC_BYTES,
|
||||
JSSettings_JSGC_HIGH_FREQUENCY_TIME_LIMIT,
|
||||
JSSettings_JSGC_LOW_FREQUENCY_HEAP_GROWTH,
|
||||
JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,
|
||||
JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,
|
||||
JSSettings_JSGC_HIGH_FREQUENCY_LOW_LIMIT,
|
||||
JSSettings_JSGC_HIGH_FREQUENCY_HIGH_LIMIT,
|
||||
JSSettings_JSGC_ANALYSIS_PURGE_TRIGGER,
|
||||
JSSettings_JSGC_ALLOCATION_THRESHOLD,
|
||||
JSSettings_JSGC_SLICE_TIME_BUDGET,
|
||||
JSSettings_JSGC_DYNAMIC_HEAP_GROWTH,
|
||||
JSSettings_JSGC_DYNAMIC_MARK_SLICE,
|
||||
// JSGC_MODE not supported
|
||||
|
||||
// This must be last so that we get an accurate count.
|
||||
kGCSettingsArraySize
|
||||
};
|
||||
|
||||
struct JSGCSetting
|
||||
{
|
||||
JSGCParamKey key;
|
||||
uint32_t value;
|
||||
|
||||
JSGCSetting()
|
||||
: key(static_cast<JSGCParamKey>(-1)), value(0)
|
||||
{ }
|
||||
|
||||
bool
|
||||
IsSet() const
|
||||
{
|
||||
return key != static_cast<JSGCParamKey>(-1);
|
||||
}
|
||||
|
||||
void
|
||||
Unset()
|
||||
{
|
||||
key = static_cast<JSGCParamKey>(-1);
|
||||
value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// There are several settings that we know we need so it makes sense to
|
||||
// preallocate here.
|
||||
typedef JSGCSetting JSGCSettingsArray[kGCSettingsArraySize];
|
||||
|
||||
// Settings that change based on chrome/content context.
|
||||
struct JSContentChromeSettings
|
||||
{
|
||||
uint32_t options;
|
||||
int32_t maxScriptRuntime;
|
||||
|
||||
JSContentChromeSettings()
|
||||
: options(0), maxScriptRuntime(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
JSContentChromeSettings chrome;
|
||||
JSContentChromeSettings content;
|
||||
JSGCSettingsArray gcSettings;
|
||||
bool jitHardening;
|
||||
#ifdef JS_GC_ZEAL
|
||||
uint8_t gcZeal;
|
||||
uint32_t gcZealFrequency;
|
||||
#endif
|
||||
|
||||
JSSettings()
|
||||
: jitHardening(false)
|
||||
#ifdef JS_GC_ZEAL
|
||||
, gcZeal(0), gcZealFrequency(0)
|
||||
#endif
|
||||
{
|
||||
for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
|
||||
new (gcSettings + index) JSGCSetting();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ApplyGCSetting(JSGCParamKey aKey, uint32_t aValue)
|
||||
{
|
||||
JSSettings::JSGCSetting* firstEmptySetting = nullptr;
|
||||
JSSettings::JSGCSetting* foundSetting = nullptr;
|
||||
|
||||
for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
|
||||
JSSettings::JSGCSetting& setting = gcSettings[index];
|
||||
if (setting.key == aKey) {
|
||||
foundSetting = &setting;
|
||||
break;
|
||||
}
|
||||
if (!firstEmptySetting && !setting.IsSet()) {
|
||||
firstEmptySetting = &setting;
|
||||
}
|
||||
}
|
||||
|
||||
if (aValue) {
|
||||
if (!foundSetting) {
|
||||
foundSetting = firstEmptySetting;
|
||||
if (!foundSetting) {
|
||||
NS_ERROR("Not enough space for this value!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foundSetting->key = aKey;
|
||||
foundSetting->value = aValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (foundSetting) {
|
||||
foundSetting->Unset();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// All of these are implemented in RuntimeService.cpp
|
||||
JSBool
|
||||
ResolveWorkerClasses(JSContext* aCx, JSHandleObject aObj, JSHandleId aId, unsigned aFlags,
|
||||
JS::MutableHandle<JSObject*> aObjp);
|
||||
ResolveWorkerClasses(JSContext* aCx, JSHandleObject aObj, JSHandleId aId,
|
||||
unsigned aFlags, JS::MutableHandle<JSObject*> aObjp);
|
||||
|
||||
void
|
||||
CancelWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
|
||||
@ -54,7 +175,7 @@ void
|
||||
SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
|
||||
|
||||
void
|
||||
ResumeWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
|
||||
ResumeWorkersForWindow(nsIScriptContext* aCx, nsPIDOMWindow* aWindow);
|
||||
|
||||
class WorkerTask {
|
||||
public:
|
||||
|
@ -4,10 +4,12 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsPermission.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
|
||||
// nsPermission Implementation
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsPermission, nsIPermission)
|
||||
NS_IMPL_CLASSINFO(nsPermission, nullptr, 0, {0})
|
||||
NS_IMPL_ISUPPORTS1_CI(nsPermission, nsIPermission)
|
||||
|
||||
nsPermission::nsPermission(const nsACString &aHost,
|
||||
uint32_t aAppId,
|
||||
|
@ -618,8 +618,10 @@ nsPermissionManager::AddFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
aExpireType == nsIPermissionManager::EXPIRE_SESSION,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Skip addition if the permission is already expired.
|
||||
if (aExpireType == nsIPermissionManager::EXPIRE_TIME &&
|
||||
// Skip addition if the permission is already expired. Note that EXPIRE_SESSION only
|
||||
// honors expireTime if it is nonzero.
|
||||
if ((aExpireType == nsIPermissionManager::EXPIRE_TIME ||
|
||||
(aExpireType == nsIPermissionManager::EXPIRE_SESSION && aExpireTime != 0)) &&
|
||||
aExpireTime <= (PR_Now() / 1000)) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -702,7 +704,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
// only thing changed is the expire time.
|
||||
if (aPermission == oldPermissionEntry.mPermission &&
|
||||
aExpireType == oldPermissionEntry.mExpireType &&
|
||||
(aExpireType != nsIPermissionManager::EXPIRE_TIME ||
|
||||
(aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
|
||||
aExpireTime == oldPermissionEntry.mExpireTime))
|
||||
op = eOperationNone;
|
||||
else if (aPermission == nsIPermissionManager::UNKNOWN_ACTION)
|
||||
@ -801,14 +803,16 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
aExpireType == nsIPermissionManager::EXPIRE_SESSION) {
|
||||
entry->GetPermissions()[index].mNonSessionPermission = entry->GetPermissions()[index].mPermission;
|
||||
entry->GetPermissions()[index].mNonSessionExpireType = entry->GetPermissions()[index].mExpireType;
|
||||
entry->GetPermissions()[index].mNonSessionExpireTime = entry->GetPermissions()[index].mExpireTime;
|
||||
} else if (aExpireType != nsIPermissionManager::EXPIRE_SESSION) {
|
||||
entry->GetPermissions()[index].mNonSessionPermission = aPermission;
|
||||
entry->GetPermissions()[index].mNonSessionExpireType = aExpireType;
|
||||
entry->GetPermissions()[index].mExpireTime = aExpireTime;
|
||||
entry->GetPermissions()[index].mNonSessionExpireTime = aExpireTime;
|
||||
}
|
||||
|
||||
entry->GetPermissions()[index].mPermission = aPermission;
|
||||
entry->GetPermissions()[index].mExpireType = aExpireType;
|
||||
entry->GetPermissions()[index].mExpireTime = aExpireTime;
|
||||
|
||||
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
|
||||
// We care only about the id, the permission and expireType/expireTime here.
|
||||
@ -1018,6 +1022,63 @@ nsPermissionManager::TestPermissionFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
return CommonTestPermission(aPrincipal, aType, aPermission, false, true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPermissionManager::GetPermissionObject(nsIPrincipal* aPrincipal,
|
||||
const char* aType,
|
||||
bool aExactHostMatch,
|
||||
nsIPermission** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPrincipal);
|
||||
NS_ENSURE_ARG_POINTER(aType);
|
||||
|
||||
*aResult = nullptr;
|
||||
|
||||
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString host;
|
||||
nsresult rv = GetHostForPrincipal(aPrincipal, host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
int32_t typeIndex = GetTypeIndex(aType, false);
|
||||
// If type == -1, the type isn't known,
|
||||
// so just return NS_OK
|
||||
if (typeIndex == -1) return NS_OK;
|
||||
|
||||
uint32_t appId;
|
||||
rv = aPrincipal->GetAppId(&appId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool isInBrowserElement;
|
||||
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PermissionHashKey* entry = GetPermissionHashKey(host, appId, isInBrowserElement,
|
||||
typeIndex, aExactHostMatch);
|
||||
if (!entry) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We don't call GetPermission(typeIndex) because that returns a fake
|
||||
// UNKNOWN_ACTION entry if there is no match.
|
||||
int32_t idx = entry->GetPermissionIndex(typeIndex);
|
||||
if (-1 == idx) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PermissionEntry& perm = entry->GetPermissions()[idx];
|
||||
nsCOMPtr<nsIPermission> r = new nsPermission(entry->GetKey()->mHost,
|
||||
entry->GetKey()->mAppId,
|
||||
entry->GetKey()->mIsInBrowserElement,
|
||||
mTypeArray.ElementAt(perm.mType),
|
||||
perm.mPermission,
|
||||
perm.mExpireType,
|
||||
perm.mExpireTime);
|
||||
r.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPermissionManager::CommonTestPermission(nsIPrincipal* aPrincipal,
|
||||
const char *aType,
|
||||
@ -1086,7 +1147,10 @@ nsPermissionManager::GetPermissionHashKey(const nsACString& aHost,
|
||||
PermissionEntry permEntry = entry->GetPermission(aType);
|
||||
|
||||
// if the entry is expired, remove and keep looking for others.
|
||||
if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_TIME &&
|
||||
// Note that EXPIRE_SESSION only honors expireTime if it is nonzero.
|
||||
if ((permEntry.mExpireType == nsIPermissionManager::EXPIRE_TIME ||
|
||||
(permEntry.mExpireType == nsIPermissionManager::EXPIRE_SESSION &&
|
||||
permEntry.mExpireTime != 0)) &&
|
||||
permEntry.mExpireTime <= (PR_Now() / 1000)) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(GetPrincipal(aHost, aAppId, aIsInBrowserElement, getter_AddRefs(principal)))) {
|
||||
@ -1318,6 +1382,7 @@ nsPermissionManager::RemoveExpiredPermissionsForAppEnumerator(
|
||||
|
||||
permEntry.mPermission = permEntry.mNonSessionPermission;
|
||||
permEntry.mExpireType = permEntry.mNonSessionExpireType;
|
||||
permEntry.mExpireTime = permEntry.mNonSessionExpireTime;
|
||||
|
||||
gPermissionManager->NotifyObserversWithPermission(entry->GetKey()->mHost,
|
||||
entry->GetKey()->mAppId,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -45,6 +45,7 @@ public:
|
||||
, mExpireTime(aExpireTime)
|
||||
, mNonSessionPermission(aPermission)
|
||||
, mNonSessionExpireType(aExpireType)
|
||||
, mNonSessionExpireTime(aExpireTime)
|
||||
{}
|
||||
|
||||
int64_t mID;
|
||||
@ -54,6 +55,7 @@ public:
|
||||
int64_t mExpireTime;
|
||||
uint32_t mNonSessionPermission;
|
||||
uint32_t mNonSessionExpireType;
|
||||
uint32_t mNonSessionExpireTime;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -27,29 +27,41 @@ function do_run_test() {
|
||||
|
||||
// add a permission with *now* expiration
|
||||
pm.addFromPrincipal(principal, "test/expiration-perm-exp", 1, pm.EXPIRE_TIME, now);
|
||||
pm.addFromPrincipal(principal, "test/expiration-session-exp", 1, pm.EXPIRE_SESSION, now);
|
||||
|
||||
// add a permission with future expiration (100 milliseconds)
|
||||
pm.addFromPrincipal(principal, "test/expiration-perm-exp2", 1, pm.EXPIRE_TIME, now + 100);
|
||||
pm.addFromPrincipal(principal, "test/expiration-session-exp2", 1, pm.EXPIRE_SESSION, now + 100);
|
||||
|
||||
// add a permission with future expiration (1000 seconds)
|
||||
pm.addFromPrincipal(principal, "test/expiration-perm-exp3", 1, pm.EXPIRE_TIME, now + 1e6);
|
||||
pm.addFromPrincipal(principal, "test/expiration-session-exp3", 1, pm.EXPIRE_SESSION, now + 1e6);
|
||||
|
||||
// add a permission without expiration
|
||||
pm.addFromPrincipal(principal, "test/expiration-perm-nexp", 1, pm.EXPIRE_NEVER, 0);
|
||||
|
||||
// check that the second two haven't expired yet
|
||||
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp3"));
|
||||
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-session-exp3"));
|
||||
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-nexp"));
|
||||
|
||||
// ... and the first one has
|
||||
do_timeout(10, continue_test);
|
||||
yield;
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp"));
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal, "test/expiration-session-exp"));
|
||||
|
||||
// ... and that the short-term one will
|
||||
do_timeout(200, continue_test);
|
||||
yield;
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp2"));
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp2"));
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal, "test/expiration-session-exp2"));
|
||||
|
||||
// Check that .getPermission returns a matching result
|
||||
do_check_null(pm.getPermissionObject(principal, "test/expiration-perm-exp", false));
|
||||
do_check_null(pm.getPermissionObject(principal, "test/expiration-session-exp", false));
|
||||
do_check_null(pm.getPermissionObject(principal, "test/expiration-perm-exp2", false));
|
||||
do_check_null(pm.getPermissionObject(principal, "test/expiration-session-exp2", false));
|
||||
|
||||
do_finish_generator_test(test_generator);
|
||||
}
|
||||
|
@ -0,0 +1,94 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function getPrincipalFromURI(uri) {
|
||||
return Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getNoAppCodebasePrincipal(NetUtil.newURI(uri));
|
||||
}
|
||||
|
||||
function getSystemPrincipal() {
|
||||
return Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getSystemPrincipal();
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
var pm = Cc["@mozilla.org/permissionmanager;1"].
|
||||
getService(Ci.nsIPermissionManager);
|
||||
|
||||
do_check_null(pm.getPermissionObject(getSystemPrincipal(), "test/pobject", false));
|
||||
|
||||
let principal = getPrincipalFromURI("http://example.com");
|
||||
let subPrincipal = getPrincipalFromURI("http://sub.example.com");
|
||||
let subSubPrincipal = getPrincipalFromURI("http://sub.sub.example.com");
|
||||
|
||||
do_check_null(pm.getPermissionObject(principal, "test/pobject", false));
|
||||
do_check_null(pm.getPermissionObject(principal, "test/pobject", true));
|
||||
|
||||
pm.addFromPrincipal(principal, "test/pobject", pm.ALLOW_ACTION);
|
||||
var rootPerm = pm.getPermissionObject(principal, "test/pobject", false);
|
||||
do_check_true(rootPerm != null);
|
||||
do_check_eq(rootPerm.host, "example.com");
|
||||
do_check_eq(rootPerm.type, "test/pobject");
|
||||
do_check_eq(rootPerm.capability, pm.ALLOW_ACTION);
|
||||
do_check_eq(rootPerm.expireType, pm.EXPIRE_NEVER);
|
||||
|
||||
var rootPerm2 = pm.getPermissionObject(principal, "test/pobject", true);
|
||||
do_check_true(rootPerm != null);
|
||||
do_check_eq(rootPerm.host, "example.com");
|
||||
|
||||
var subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true);
|
||||
do_check_null(subPerm);
|
||||
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
|
||||
do_check_true(subPerm != null);
|
||||
do_check_eq(subPerm.host, "example.com");
|
||||
do_check_eq(subPerm.type, "test/pobject");
|
||||
do_check_eq(subPerm.capability, pm.ALLOW_ACTION);
|
||||
|
||||
subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", true);
|
||||
do_check_null(subPerm);
|
||||
subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false);
|
||||
do_check_true(subPerm != null);
|
||||
do_check_eq(subPerm.host, "example.com");
|
||||
|
||||
pm.addFromPrincipal(principal, "test/pobject", pm.DENY_ACTION, pm.EXPIRE_SESSION);
|
||||
|
||||
// make sure permission objects are not dynamic
|
||||
do_check_eq(rootPerm.capability, pm.ALLOW_ACTION);
|
||||
|
||||
// but do update on change
|
||||
rootPerm = pm.getPermissionObject(principal, "test/pobject", true);
|
||||
do_check_eq(rootPerm.capability, pm.DENY_ACTION);
|
||||
do_check_eq(rootPerm.expireType, pm.EXPIRE_SESSION);
|
||||
|
||||
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
|
||||
do_check_eq(subPerm.host, "example.com");
|
||||
do_check_eq(subPerm.capability, pm.DENY_ACTION);
|
||||
do_check_eq(subPerm.expireType, pm.EXPIRE_SESSION);
|
||||
|
||||
pm.addFromPrincipal(subPrincipal, "test/pobject", pm.PROMPT_ACTION);
|
||||
rootPerm = pm.getPermissionObject(principal, "test/pobject", true);
|
||||
do_check_eq(rootPerm.host, "example.com");
|
||||
do_check_eq(rootPerm.capability, pm.DENY_ACTION);
|
||||
|
||||
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", true);
|
||||
do_check_eq(subPerm.host, "sub.example.com");
|
||||
do_check_eq(subPerm.capability, pm.PROMPT_ACTION);
|
||||
|
||||
subPerm = pm.getPermissionObject(subPrincipal, "test/pobject", false);
|
||||
do_check_eq(subPerm.host, "sub.example.com");
|
||||
do_check_eq(subPerm.capability, pm.PROMPT_ACTION);
|
||||
|
||||
subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", true);
|
||||
do_check_null(subPerm);
|
||||
|
||||
subPerm = pm.getPermissionObject(subSubPrincipal, "test/pobject", false);
|
||||
do_check_eq(subPerm.host, "sub.example.com");
|
||||
do_check_eq(subPerm.capability, pm.PROMPT_ACTION);
|
||||
|
||||
pm.removeFromPrincipal(principal, "test/pobject");
|
||||
|
||||
rootPerm = pm.getPermissionObject(principal, "test/pobject", true);
|
||||
do_check_null(rootPerm);
|
||||
}
|
@ -16,6 +16,7 @@ tail =
|
||||
[test_domain_eviction.js]
|
||||
[test_eviction.js]
|
||||
[test_permmanager_expiration.js]
|
||||
[test_permmanager_getPermissionObject.js]
|
||||
[test_permmanager_notifications.js]
|
||||
[test_permmanager_removeall.js]
|
||||
[test_permmanager_load_invalid_entries.js]
|
||||
|
@ -9197,387 +9197,389 @@
|
||||
> cookie/SM
|
||||
18467a24273
|
||||
> could've
|
||||
19246c25052
|
||||
19035a24842
|
||||
> cul-de-sac
|
||||
19246c25053
|
||||
< cysteine
|
||||
---
|
||||
> cysteine/M
|
||||
20196,20197c26002,26003
|
||||
20196,20197c26003,26004
|
||||
< dialog/SM
|
||||
< dialogue/SM
|
||||
---
|
||||
> dialog/SMGD
|
||||
> dialogue/SMRGD
|
||||
20481a26288
|
||||
20481a26289
|
||||
> disclose/DSG
|
||||
20830c26637
|
||||
20830c26638
|
||||
< dogie/M
|
||||
---
|
||||
> dogie/SM
|
||||
20895a26703
|
||||
20895a26704
|
||||
> donator/MS
|
||||
21820a27629
|
||||
21820a27630
|
||||
> elicitor/MS
|
||||
22071a27881
|
||||
22071a27882
|
||||
> encyclopaedia
|
||||
22556a28367
|
||||
22556a28368
|
||||
> estoppel
|
||||
22638c28449
|
||||
22638c28450
|
||||
< euthanize
|
||||
---
|
||||
> euthanize/DSG
|
||||
22719a28531
|
||||
22719a28532
|
||||
> exabyte/MS
|
||||
22947a28760
|
||||
22947a28761
|
||||
> experimentalism
|
||||
23207,23208d29019
|
||||
23207,23208d29020
|
||||
< faecal
|
||||
< faeces/M
|
||||
23215c29026
|
||||
23215c29027
|
||||
< faggoting's
|
||||
---
|
||||
> faggot/SMG
|
||||
23701a29513
|
||||
23701a29514
|
||||
> filesystem/MS
|
||||
24155c29967
|
||||
24155c29968
|
||||
< fluidized
|
||||
---
|
||||
> fluidize/DSG
|
||||
24216a30029
|
||||
24216a30030
|
||||
> foci
|
||||
24736d30548
|
||||
24736d30549
|
||||
< frier/M
|
||||
24855,24856c30667,30668
|
||||
24855,24856c30668,30669
|
||||
< fucker/M!
|
||||
< fuckhead/S!
|
||||
---
|
||||
> fucker/SM!
|
||||
> fuckhead/SM!
|
||||
24953d30764
|
||||
24953d30765
|
||||
< furore/MS
|
||||
25125c30936
|
||||
25125c30937
|
||||
< gaolbird/S
|
||||
---
|
||||
> gaolbirds
|
||||
25180d30990
|
||||
25180d30991
|
||||
< gasolene/M
|
||||
25190a31001
|
||||
25190a31002
|
||||
> gastroenterologist/M
|
||||
25262c31073
|
||||
25262c31074
|
||||
< geezer/M
|
||||
---
|
||||
> geezer/MS
|
||||
25327c31138
|
||||
25327c31139
|
||||
< genomic
|
||||
---
|
||||
> genomic/S
|
||||
25462a31274
|
||||
25462a31275
|
||||
> gigabit/MS
|
||||
25464a31277,31279
|
||||
25464a31278,31280
|
||||
> gigajoule/MS
|
||||
> gigapixel/MS
|
||||
> gigawatt/MS
|
||||
25560d31374
|
||||
25560d31375
|
||||
< glamourize/DSG
|
||||
25674c31488
|
||||
25674c31489
|
||||
< glycerine's
|
||||
---
|
||||
> glycerine/M
|
||||
25905c31719
|
||||
25905c31720
|
||||
< gram/MS
|
||||
---
|
||||
> gram/KMS
|
||||
25909d31722
|
||||
25909d31723
|
||||
< gramme/SM
|
||||
26063c31876,31877
|
||||
26063c31877,31878
|
||||
< greybeard
|
||||
---
|
||||
> grey/MDRTGSP
|
||||
> greybeard/SM
|
||||
26066c31880
|
||||
26066c31881
|
||||
< greyness
|
||||
---
|
||||
> greyness/M
|
||||
26246,26247d32059
|
||||
26246,26247d32060
|
||||
< guerilla's
|
||||
< guerillas
|
||||
26432,26436d32243
|
||||
26432,26436d32244
|
||||
< haemoglobin's
|
||||
< haemophilia/M
|
||||
< haemorrhage/DSMG
|
||||
< haemorrhoid/S
|
||||
< haemorrhoids/M
|
||||
27167c32974
|
||||
27167c32975
|
||||
< hexane
|
||||
---
|
||||
> hexane/SM
|
||||
27273a33081
|
||||
27273a33082
|
||||
> hippopotami
|
||||
27875d33682
|
||||
27875d33683
|
||||
< hyaena/SM
|
||||
28017c33824
|
||||
28017c33825
|
||||
< iPod/M
|
||||
---
|
||||
> iPod/MS
|
||||
28105a33913
|
||||
28105a33914
|
||||
> idolator/SM
|
||||
28513c34321
|
||||
28513c34322
|
||||
< inbound
|
||||
---
|
||||
> inbound/s
|
||||
28650a34459
|
||||
28650a34460
|
||||
> indices
|
||||
28812d34620
|
||||
28812d34621
|
||||
< inflexion/SM
|
||||
29216a35025
|
||||
29216a35026
|
||||
> intern/GDL
|
||||
29272a35082,35085
|
||||
29272a35083,35086
|
||||
> intersex
|
||||
> intersexual/MS
|
||||
> intersexualism
|
||||
> intersexuality
|
||||
29724c35537
|
||||
29724c35538
|
||||
< jewellery's
|
||||
---
|
||||
> jewellery/M
|
||||
29870a35684
|
||||
29870a35685
|
||||
> judgement/MS
|
||||
30066c35880
|
||||
30066c35881
|
||||
< kiddie/M
|
||||
---
|
||||
> kiddie/SM
|
||||
30262,30263c36076
|
||||
30262,30263c36077
|
||||
< kraut's
|
||||
< kraut/S!
|
||||
---
|
||||
> kraut/MS!
|
||||
30665a36479
|
||||
30665a36480
|
||||
> lector/MS
|
||||
31031c36845
|
||||
31031c36846
|
||||
< linguini's
|
||||
---
|
||||
> linguini/M
|
||||
31151,31152c36965
|
||||
31151,31152c36966
|
||||
< liver's
|
||||
< liver/S
|
||||
---
|
||||
> liver/MS
|
||||
32230c38043
|
||||
32230c38044
|
||||
< meanie/M
|
||||
---
|
||||
> meanie/MS
|
||||
32317,32318c38130
|
||||
32317,32318c38131
|
||||
< megadeath/M
|
||||
< megadeaths
|
||||
---
|
||||
> megadeath/SM
|
||||
32320c38132
|
||||
32320c38133
|
||||
< megajoules
|
||||
---
|
||||
> megajoule/SM
|
||||
32329c38141
|
||||
32329c38142
|
||||
< megapixel/S
|
||||
---
|
||||
> megapixel/MS
|
||||
32708a38521
|
||||
32708a38522
|
||||
> might've
|
||||
32777d38589
|
||||
32777d38590
|
||||
< millionnaire/M
|
||||
32934a38747
|
||||
32934a38748
|
||||
> miscommunication/S
|
||||
32991a38805
|
||||
32991a38806
|
||||
> misjudgement/MS
|
||||
33784a39599
|
||||
33784a39600
|
||||
> must've
|
||||
33963c39778
|
||||
33963c39779
|
||||
< native/MS
|
||||
---
|
||||
> native/MSY
|
||||
34169,34171c39984,39985
|
||||
34169,34171c39985,39986
|
||||
< neurone/S
|
||||
< neurophysiology
|
||||
< neuroscience
|
||||
---
|
||||
> neurophysiology/M
|
||||
> neuroscience/MS
|
||||
34275c40089
|
||||
34275c40090
|
||||
< nightie/M
|
||||
---
|
||||
> nightie/SM
|
||||
35104a40919
|
||||
35104a40920
|
||||
> octopi
|
||||
35219d41033
|
||||
35219d41034
|
||||
< oleomargarin/M
|
||||
35226a41041
|
||||
35226a41042
|
||||
> oligo
|
||||
35913c41728
|
||||
35913c41729
|
||||
< oversize/D
|
||||
---
|
||||
> oversize
|
||||
36056,36059d41870
|
||||
36056,36059d41871
|
||||
< paederast/S
|
||||
< paediatrician's
|
||||
< paediatricians
|
||||
< paediatrics/M
|
||||
36291a42103
|
||||
36291a42104
|
||||
> paralyses
|
||||
36403d42214
|
||||
36403d42215
|
||||
< parrakeet/MS
|
||||
36449d42259
|
||||
36449d42260
|
||||
< partizan/SM
|
||||
37093a42904
|
||||
37093a42905
|
||||
> petabyte/MS
|
||||
37102c42913
|
||||
37102c42914
|
||||
< petitioner/M
|
||||
---
|
||||
> petitioner/MS
|
||||
37264a43076
|
||||
37264a43077
|
||||
> phosphorylate/DSGN
|
||||
37316d43127
|
||||
37316d43128
|
||||
< phrenetic
|
||||
37796a43608
|
||||
37796a43609
|
||||
> plugin/MS
|
||||
37987c43799
|
||||
37987c43800
|
||||
< polypeptide/S
|
||||
---
|
||||
> polypeptide/MS
|
||||
38291d44102
|
||||
38291d44103
|
||||
< practise's
|
||||
38451a44263
|
||||
38451a44264
|
||||
> prejudgement/MS
|
||||
38891a44704,44705
|
||||
38891a44705,44706
|
||||
> pronate/DSGN
|
||||
> pronator/MS
|
||||
38951c44765
|
||||
38951c44766
|
||||
< proprietorship/M
|
||||
---
|
||||
> proprietorship/MS
|
||||
39039a44854
|
||||
39039a44855
|
||||
> provender/M
|
||||
39564a45380
|
||||
39564a45381
|
||||
> quinoa
|
||||
40036a45853
|
||||
40036a45854
|
||||
> recency
|
||||
40141a45959
|
||||
40141a45960
|
||||
> recuse/DGS
|
||||
40208a46027
|
||||
40208a46028
|
||||
> refactor/SMDG
|
||||
40244d46062
|
||||
40244d46063
|
||||
< reflexion/SM
|
||||
40829c46647
|
||||
40829c46648
|
||||
< reverie/M
|
||||
---
|
||||
> reverie/MS
|
||||
41415a47234
|
||||
41415a47235
|
||||
> sabre/MS
|
||||
41914c47733
|
||||
41914c47734
|
||||
< schnaps's
|
||||
---
|
||||
> schnaps/M
|
||||
41949c47768
|
||||
41949c47769
|
||||
< schrod's
|
||||
---
|
||||
> schrod/SM
|
||||
41998a47818
|
||||
41998a47819
|
||||
> scot-free
|
||||
42883,42885c48703
|
||||
42883,42885c48704
|
||||
< shit's
|
||||
< shit/S!
|
||||
< shite/S!
|
||||
---
|
||||
> shit/MS!
|
||||
42887,42888c48705,48706
|
||||
42887,42888c48706,48707
|
||||
< shithead/S!
|
||||
< shitload/!
|
||||
---
|
||||
> shithead/MS!
|
||||
> shitload/MS!
|
||||
42891c48709
|
||||
42891c48710
|
||||
< shitty/RT!
|
||||
---
|
||||
> shitty/TR!
|
||||
42976a48795
|
||||
42976a48796
|
||||
> should've
|
||||
43008c48827
|
||||
43008c48828
|
||||
< showtime
|
||||
---
|
||||
> showtime/MS
|
||||
43724,43726c49543
|
||||
43724,43726c49544
|
||||
< smoulder's
|
||||
< smouldered
|
||||
< smoulders
|
||||
---
|
||||
> smoulder/GSMD
|
||||
44062c49879
|
||||
44062c49880
|
||||
< sonofabitch
|
||||
---
|
||||
> sonofabitch/!
|
||||
44346a50164
|
||||
44346a50165
|
||||
> spelled
|
||||
44348a50167
|
||||
44348a50168
|
||||
> spelt
|
||||
44371a50191
|
||||
44371a50192
|
||||
> spick/S!
|
||||
44383c50203
|
||||
44383c50204
|
||||
< spik/S
|
||||
---
|
||||
> spik/S!
|
||||
46106a51927
|
||||
46106a51928
|
||||
> syllabi
|
||||
46160c51981
|
||||
46160c51982
|
||||
< synch/GMD
|
||||
---
|
||||
> synch/GMDS
|
||||
46167d51987
|
||||
46167d51988
|
||||
< synchs
|
||||
46203,46204c52023,52024
|
||||
46203,46204c52024,52025
|
||||
< sysadmin/S
|
||||
< sysop/S
|
||||
---
|
||||
> sysadmin/MS
|
||||
> sysop/MS
|
||||
46752a52573
|
||||
46752a52574
|
||||
> terabit/MS
|
||||
46753a52575,52576
|
||||
46753a52576,52577
|
||||
> terahertz/M
|
||||
> terapixel/MS
|
||||
46817a52641
|
||||
46817a52642
|
||||
> testcase/MS
|
||||
46831a52656
|
||||
46831a52657
|
||||
> testsuite/MS
|
||||
46925a52751
|
||||
46925a52752
|
||||
> theremin/MS
|
||||
47755a53582
|
||||
47755a53583
|
||||
> transfect/DSMG
|
||||
47774a53602,53603
|
||||
47774a53603,53604
|
||||
> transgenderism
|
||||
> transgene/MS
|
||||
47951c53780
|
||||
47951c53781
|
||||
< triage/M
|
||||
---
|
||||
> triage/MG
|
||||
48869a54699
|
||||
48869a54700
|
||||
> unlikeable
|
||||
49211c55041
|
||||
49211c55042
|
||||
< vagina/M
|
||||
---
|
||||
> vagina/MS
|
||||
49368,49369c55198
|
||||
49368,49369c55199
|
||||
< velour's
|
||||
< velours's
|
||||
---
|
||||
> velour/MS
|
||||
49478a55308
|
||||
49478a55309
|
||||
> vertices
|
||||
50148a55979
|
||||
50148a55980
|
||||
> weaponize/DSG
|
||||
50260,50261d56090
|
||||
50260,50261d56091
|
||||
< werwolf/M
|
||||
< werwolves
|
||||
50728c56557
|
||||
50728c56558
|
||||
< women
|
||||
---
|
||||
> women/M
|
||||
50794c56623
|
||||
50794c56624
|
||||
< wop/S!
|
||||
---
|
||||
> wop/MS!
|
||||
|
@ -1,4 +1,4 @@
|
||||
57445
|
||||
57446
|
||||
0/nm
|
||||
0th/pt
|
||||
1/n1
|
||||
@ -25106,6 +25106,7 @@ cue/DSMG
|
||||
cuff/MDGS
|
||||
cufflink/SM
|
||||
cuisine/SM
|
||||
cul-de-sac
|
||||
culinary
|
||||
cull/MDGS
|
||||
cullender/MS
|
||||
|
@ -385,18 +385,14 @@ GLScreenBuffer::Swap(const gfxIntSize& size)
|
||||
{
|
||||
SharedSurface* nextSurf = mStream->SwapProducer(mFactory, size);
|
||||
if (!nextSurf) {
|
||||
SurfaceFactory_GL* basicFactory =
|
||||
new SurfaceFactory_Basic(mGL, mFactory->Caps());
|
||||
nextSurf = mStream->SwapProducer(basicFactory, size);
|
||||
if (!nextSurf) {
|
||||
delete basicFactory;
|
||||
return false;
|
||||
}
|
||||
SurfaceFactory_Basic basicFactory(mGL, mFactory->Caps());
|
||||
nextSurf = mStream->SwapProducer(&basicFactory, size);
|
||||
if (!nextSurf)
|
||||
return false;
|
||||
|
||||
// Swap out the apparently defective old factory.
|
||||
delete mFactory;
|
||||
mFactory = basicFactory;
|
||||
NS_WARNING("SwapProd failed for sophisticated Factory type, fell back to Basic.");
|
||||
}
|
||||
MOZ_ASSERT(nextSurf);
|
||||
|
||||
Attach(nextSurf, size);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user