mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 13:23:07 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1163826 - Add remainder of top .jp sites to CSS unprefixing service whitelist. r=dholbert (8ed22f2638) - Bug 1165834: Add alicdn.com (used by taobao.com) to the CSS Unprefixing Service whitelist. r=miketaylr (30d150c28c) - Bug 1166792 - Add 3rd batch of top .jp sites to CSS unprefixing service whitelists. r=dholbert (e4073c1f09) - Bug 1170375 - Add 4th batch of top .jp sites to CSS unprefixing service whitelists. r=dholbert (d741e57cb0) - Bug 1207850 - Temporary fix for canceling the pump used by FetchBody. r=nsm (bc85cb1500) - Bug 1224865: Don't set a document in FetchDriver for requests in workers. r=bkelly (7bcb0bd16b) - Bug 1108181 - Make Headers iterable; r=bzbarsky (da8d6f8bb2) - Bug 1217501 P5 Relax guard checking on Headers with existing headers. r=ehsan (75ec3b6ae5) - Bug 1207882 - Use a separate build target for config/buildid. r=gps (ad9f536aac) - Bug 1216697 - Unship Request.cache until the implementation is finished; r=bzbarsky (49264a21d8) - Bug 1218119 - Simplify defining worker prefs; r=baku (8987aa23c3) - namespace (d88c3b7fc6) - Bug 1179489 - Don't count service workers towards an origin's max worker quota; r=nsm (ce5e1345ba) - Bug 1151646 - Cleanup, r=khuey. (d119d19ea7) - Bug 1118778 - Write upload properties from upload.py; r=glandium (f8745ffda8) - Bug 1194741 - Display upload output; r=nalexander (7adaa41d11) - Bug 1197293 - allow for TC builds that don't use 'make upload'; r=ted (e671e7c651) - Bug 1137000 - Add support for SDK building to moz-automation.mk. r=mshal (69b7ccb3c8) - Bug 1175895 - aid greppability of MOZ_AUTOMATION_*; r=ted (c9a099f168) - Bug 1198179 - Kill gen_mach_buildprops.py; r=ted (fa74e1930f) - Bug 1198179 - make upload.py write properties even if not uploading; r=ted (e7ca79b807) - Bug 8623031 - Move desktop build logic to a container neutral location; r=dustin (81dc866373) - Bug 1187139 (part 1) - Replace nsBaseHashtable::Enumerate() calls in accessible/ with iterators. r=tbsaunde. (7a75c73d17) - Bug 1187139 (part 2) - Replace nsBaseHashtable::Enumerate() calls in accessible/ with iterators. r=tbsaunde. (c631350ddb) - Bug 1187139 (part 3) - Replace nsBaseHashtable::Enumerate() calls in accessible/ with iterators. r=tbsaunde. (052cced2ca) - Bug 1225396 part 4 - Remove @@iterator workaround in Codegen.py. r=bz (3b05ddc4f0) - Bug 1048695 part 1. Pass the set of globals where a member should NOT be exposed to MemberCondition. r=peterv (d5c9040323) - Bug 1048695 part 2. Make interface members not be exposed based on their nonExposedGlobals. r=peterv (e852319bd0) - Bug 1229493 - Stop shell-only modules classes being reported as standard classes r=shu (4a6457af8d) - Bug 1151646 - Fix static analysis bustage. (347564b4d2) - Bug 1231051 - Moz2Dify nsNativeThemeCocoa::DrawWidgetBackground. r=mstange. (cbcbe17e30) - Bug 1178984 - Crashes at nsMenuBarX::RemoveMenuAtIndex. r=spohl (6e5869ae28) - leftovers of Bug 1151345 - Add debug logging to help decipher this bug. r=spohl (22d42fc66d)
This commit is contained in:
@@ -12,40 +12,34 @@
|
||||
// Accessible cache utils
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Shutdown and removes the accessible from cache.
|
||||
*/
|
||||
template <class T>
|
||||
static PLDHashOperator
|
||||
ClearCacheEntry(const void* aKey, RefPtr<T>& aAccessible, void* aUserArg)
|
||||
void
|
||||
UnbindCacheEntriesFromDocument(
|
||||
nsRefPtrHashtable<nsPtrHashKey<const void>, T>& aCache)
|
||||
{
|
||||
NS_ASSERTION(aAccessible, "Calling ClearCacheEntry with a nullptr pointer!");
|
||||
if (aAccessible && !aAccessible->IsDefunct())
|
||||
aAccessible->Shutdown();
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static PLDHashOperator
|
||||
UnbindCacheEntryFromDocument(const void* aKey, RefPtr<T>& aAccessible,
|
||||
void* aUserArg)
|
||||
{
|
||||
MOZ_ASSERT(aAccessible && !aAccessible->IsDefunct());
|
||||
aAccessible->Document()->UnbindFromDocument(aAccessible);
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
for (auto iter = aCache.Iter(); !iter.Done(); iter.Next()) {
|
||||
T* accessible = iter.Data();
|
||||
MOZ_ASSERT(accessible && !accessible->IsDefunct());
|
||||
accessible->Document()->UnbindFromDocument(accessible);
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the cache and shutdown the accessibles.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
static void
|
||||
ClearCache(nsRefPtrHashtable<nsPtrHashKey<const void>, T>& aCache)
|
||||
{
|
||||
aCache.Enumerate(ClearCacheEntry<T>, nullptr);
|
||||
for (auto iter = aCache.Iter(); !iter.Done(); iter.Next()) {
|
||||
T* accessible = iter.Data();
|
||||
MOZ_ASSERT(accessible);
|
||||
if (accessible && !accessible->IsDefunct()) {
|
||||
accessible->Shutdown();
|
||||
}
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -195,17 +195,12 @@ xpcAccessibleDocument::GetAccessible(Accessible* aAccessible)
|
||||
return xpcAcc;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
ShutdownAndRemove(const Accessible* aKey, RefPtr<xpcAccessibleGeneric>& aValue,
|
||||
void* aUnused)
|
||||
{
|
||||
aValue->Shutdown();
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
xpcAccessibleDocument::Shutdown()
|
||||
{
|
||||
mCache.Enumerate(ShutdownAndRemove, nullptr);
|
||||
for (auto iter = mCache.Iter(); !iter.Done(); iter.Next()) {
|
||||
iter.Data()->Shutdown();
|
||||
iter.Remove();
|
||||
}
|
||||
xpcAccessibleGeneric::Shutdown();
|
||||
}
|
||||
|
||||
@@ -145,8 +145,9 @@ XULTreeAccessible::Value(nsString& aValue)
|
||||
void
|
||||
XULTreeAccessible::Shutdown()
|
||||
{
|
||||
if (mDoc && !mDoc->IsDefunct())
|
||||
mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<Accessible>, nullptr);
|
||||
if (mDoc && !mDoc->IsDefunct()) {
|
||||
UnbindCacheEntriesFromDocument(mAccessibleCache);
|
||||
}
|
||||
|
||||
mTree = nullptr;
|
||||
mTreeView = nullptr;
|
||||
@@ -550,8 +551,7 @@ XULTreeAccessible::InvalidateCache(int32_t aRow, int32_t aCount)
|
||||
return;
|
||||
|
||||
if (!mTreeView) {
|
||||
mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<Accessible>,
|
||||
nullptr);
|
||||
UnbindCacheEntriesFromDocument(mAccessibleCache);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -609,8 +609,7 @@ XULTreeAccessible::TreeViewInvalidated(int32_t aStartRow, int32_t aEndRow,
|
||||
return;
|
||||
|
||||
if (!mTreeView) {
|
||||
mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<Accessible>,
|
||||
nullptr);
|
||||
UnbindCacheEntriesFromDocument(mAccessibleCache);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -669,8 +668,7 @@ XULTreeAccessible::TreeViewChanged(nsITreeView* aView)
|
||||
Document()->FireDelayedEvent(reorderEvent);
|
||||
|
||||
// Clear cache.
|
||||
mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<Accessible>,
|
||||
nullptr);
|
||||
UnbindCacheEntriesFromDocument(mAccessibleCache);
|
||||
|
||||
mTreeView = aView;
|
||||
}
|
||||
@@ -687,7 +685,7 @@ XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow) const
|
||||
|
||||
return accessible.forget();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTreeItemAccessibleBase
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -277,8 +277,7 @@ void
|
||||
XULTreeGridRowAccessible::Shutdown()
|
||||
{
|
||||
if (mDoc && !mDoc->IsDefunct()) {
|
||||
mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<XULTreeGridCellAccessible>,
|
||||
nullptr);
|
||||
UnbindCacheEntriesFromDocument(mAccessibleCache);
|
||||
}
|
||||
|
||||
XULTreeItemAccessibleBase::Shutdown();
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# 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/.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import errno
|
||||
from argparse import ArgumentParser
|
||||
|
||||
def getFileHashAndSize(filename):
|
||||
sha512Hash = 'UNKNOWN'
|
||||
size = 'UNKNOWN'
|
||||
|
||||
try:
|
||||
# open in binary mode to make sure we get consistent results
|
||||
# across all platforms
|
||||
f = open(filename, "rb")
|
||||
shaObj = hashlib.sha512(f.read())
|
||||
sha512Hash = shaObj.hexdigest()
|
||||
|
||||
size = os.path.getsize(filename)
|
||||
except:
|
||||
pass
|
||||
|
||||
return (sha512Hash, size)
|
||||
|
||||
def getMarProperties(filename, partial=False):
|
||||
if not os.path.exists(filename):
|
||||
return {}
|
||||
(mar_hash, mar_size) = getFileHashAndSize(filename)
|
||||
martype = 'partial' if partial else 'complete'
|
||||
return {
|
||||
'%sMarFilename' % martype: os.path.basename(filename),
|
||||
'%sMarSize' % martype: mar_size,
|
||||
'%sMarHash' % martype: mar_hash,
|
||||
}
|
||||
|
||||
def getUrlProperties(filename, package):
|
||||
# let's create a switch case using name-spaces/dict
|
||||
# rather than a long if/else with duplicate code
|
||||
property_conditions = [
|
||||
# key: property name, value: condition
|
||||
('testsUrl', lambda m: m.endswith(('tests.tar.bz2', 'tests.zip'))),
|
||||
('unsignedApkUrl', lambda m: m.endswith('apk') and
|
||||
'unsigned-unaligned' in m),
|
||||
('robocopApkUrl', lambda m: m.endswith('apk') and 'robocop' in m),
|
||||
('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')),
|
||||
('completeMarUrl', lambda m: m.endswith('.complete.mar')),
|
||||
('partialMarUrl', lambda m: m.endswith('.mar') and '.partial.' in m),
|
||||
('codeCoverageURL', lambda m: m.endswith('code-coverage-gcno.zip')),
|
||||
('sdkUrl', lambda m: m.endswith(('sdk.tar.bz2', 'sdk.zip'))),
|
||||
('testPackagesUrl', lambda m: m.endswith('test_packages.json')),
|
||||
('packageUrl', lambda m: m.endswith(package)),
|
||||
]
|
||||
url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz|json))$''')
|
||||
properties = {}
|
||||
|
||||
try:
|
||||
with open(filename) as f:
|
||||
for line in f:
|
||||
m = url_re.match(line)
|
||||
if m:
|
||||
m = m.group(1)
|
||||
for prop, condition in property_conditions:
|
||||
if condition(m):
|
||||
properties.update({prop: m})
|
||||
break
|
||||
except IOError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
properties = {prop: 'UNKNOWN' for prop, condition in property_conditions}
|
||||
return properties
|
||||
|
||||
def getPartialInfo(props):
|
||||
return [{
|
||||
"from_buildid": props.get("previous_buildid"),
|
||||
"size": props.get("partialMarSize"),
|
||||
"hash": props.get("partialMarHash"),
|
||||
"url": props.get("partialMarUrl"),
|
||||
}]
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.')
|
||||
parser.add_argument("--complete-mar-file", required=True,
|
||||
action="store", dest="complete_mar_file",
|
||||
help="Path to the complete MAR file, relative to the objdir.")
|
||||
parser.add_argument("--partial-mar-file", required=False,
|
||||
action="store", dest="partial_mar_file",
|
||||
help="Path to the partial MAR file, relative to the objdir.")
|
||||
parser.add_argument("--upload-output", required=True,
|
||||
action="store", dest="upload_output",
|
||||
help="Path to the text output of 'make upload'")
|
||||
parser.add_argument("--upload-files", required=True, nargs="+",
|
||||
action="store", dest="upload_files",
|
||||
help="List of files to be uploaded.")
|
||||
parser.add_argument("--package", required=True,
|
||||
action="store", dest="package",
|
||||
help="Filename of the build package")
|
||||
args = parser.parse_args()
|
||||
|
||||
json_data = getMarProperties(args.complete_mar_file)
|
||||
json_data.update(getUrlProperties(args.upload_output, args.package))
|
||||
if args.partial_mar_file:
|
||||
json_data.update(getMarProperties(args.partial_mar_file, partial=True))
|
||||
|
||||
# Pull the previous buildid from the partial mar filename.
|
||||
res = re.match(r'.*\.([0-9]+)-[0-9]+.mar', args.partial_mar_file)
|
||||
if res:
|
||||
json_data['previous_buildid'] = res.group(1)
|
||||
|
||||
# Set partialInfo to be a collection of the partial mar properties
|
||||
# useful for balrog.
|
||||
json_data['partialInfo'] = getPartialInfo(json_data)
|
||||
|
||||
json_data['uploadFiles'] = args.upload_files
|
||||
json_data['packageFilename'] = args.package
|
||||
|
||||
with open('mach_build_properties.json', 'w') as outfile:
|
||||
json.dump(json_data, outfile, indent=4)
|
||||
+33
-37
@@ -17,46 +17,44 @@ include $(topsrcdir)/toolkit/mozapps/installer/upload-files.mk
|
||||
# Clear out DIST_FILES if it was set by upload-files.mk (for Android builds)
|
||||
DIST_FILES =
|
||||
|
||||
# Log file from the 'make upload' step. We need this to parse out the URLs of
|
||||
# the uploaded files.
|
||||
AUTOMATION_UPLOAD_OUTPUT = $(DIST)/automation-upload.txt
|
||||
|
||||
# Helper variables to convert from MOZ_AUTOMATION_* variables to the
|
||||
# corresponding the make target
|
||||
tier_BUILD_SYMBOLS = buildsymbols
|
||||
tier_L10N_CHECK = l10n-check
|
||||
tier_PRETTY_L10N_CHECK = pretty-l10n-check
|
||||
tier_INSTALLER = installer
|
||||
tier_PRETTY_INSTALLER = pretty-installer
|
||||
tier_PACKAGE = package
|
||||
tier_PRETTY_PACKAGE = pretty-package
|
||||
tier_PACKAGE_TESTS = package-tests
|
||||
tier_PRETTY_PACKAGE_TESTS = pretty-package-tests
|
||||
tier_UPDATE_PACKAGING = update-packaging
|
||||
tier_PRETTY_UPDATE_PACKAGING = pretty-update-packaging
|
||||
tier_UPLOAD_SYMBOLS = uploadsymbols
|
||||
tier_UPLOAD = upload
|
||||
tier_MOZ_AUTOMATION_BUILD_SYMBOLS = buildsymbols
|
||||
tier_MOZ_AUTOMATION_L10N_CHECK = l10n-check
|
||||
tier_MOZ_AUTOMATION_PRETTY_L10N_CHECK = pretty-l10n-check
|
||||
tier_MOZ_AUTOMATION_INSTALLER = installer
|
||||
tier_MOZ_AUTOMATION_PRETTY_INSTALLER = pretty-installer
|
||||
tier_MOZ_AUTOMATION_PACKAGE = package
|
||||
tier_MOZ_AUTOMATION_PRETTY_PACKAGE = pretty-package
|
||||
tier_MOZ_AUTOMATION_PACKAGE_TESTS = package-tests
|
||||
tier_MOZ_AUTOMATION_PRETTY_PACKAGE_TESTS = pretty-package-tests
|
||||
tier_MOZ_AUTOMATION_UPDATE_PACKAGING = update-packaging
|
||||
tier_MOZ_AUTOMATION_PRETTY_UPDATE_PACKAGING = pretty-update-packaging
|
||||
tier_MOZ_AUTOMATION_UPLOAD_SYMBOLS = uploadsymbols
|
||||
tier_MOZ_AUTOMATION_UPLOAD = upload
|
||||
tier_MOZ_AUTOMATION_SDK = sdk
|
||||
|
||||
# Automation build steps. Everything in MOZ_AUTOMATION_TIERS also gets used in
|
||||
# TIERS for mach display. As such, the MOZ_AUTOMATION_TIERS are roughly sorted
|
||||
# here in the order that they will be executed (since mach doesn't know of the
|
||||
# dependencies between them).
|
||||
moz_automation_symbols = \
|
||||
PACKAGE_TESTS \
|
||||
PRETTY_PACKAGE_TESTS \
|
||||
BUILD_SYMBOLS \
|
||||
UPLOAD_SYMBOLS \
|
||||
PACKAGE \
|
||||
PRETTY_PACKAGE \
|
||||
INSTALLER \
|
||||
PRETTY_INSTALLER \
|
||||
UPDATE_PACKAGING \
|
||||
PRETTY_UPDATE_PACKAGING \
|
||||
L10N_CHECK \
|
||||
PRETTY_L10N_CHECK \
|
||||
UPLOAD \
|
||||
MOZ_AUTOMATION_PACKAGE_TESTS \
|
||||
MOZ_AUTOMATION_PRETTY_PACKAGE_TESTS \
|
||||
MOZ_AUTOMATION_BUILD_SYMBOLS \
|
||||
MOZ_AUTOMATION_UPLOAD_SYMBOLS \
|
||||
MOZ_AUTOMATION_PACKAGE \
|
||||
MOZ_AUTOMATION_PRETTY_PACKAGE \
|
||||
MOZ_AUTOMATION_INSTALLER \
|
||||
MOZ_AUTOMATION_PRETTY_INSTALLER \
|
||||
MOZ_AUTOMATION_UPDATE_PACKAGING \
|
||||
MOZ_AUTOMATION_PRETTY_UPDATE_PACKAGING \
|
||||
MOZ_AUTOMATION_L10N_CHECK \
|
||||
MOZ_AUTOMATION_PRETTY_L10N_CHECK \
|
||||
MOZ_AUTOMATION_UPLOAD \
|
||||
MOZ_AUTOMATION_SDK \
|
||||
$(NULL)
|
||||
MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$(MOZ_AUTOMATION_$(sym))),$(tier_$(sym))))
|
||||
MOZ_AUTOMATION_TIERS := $(foreach sym,$(moz_automation_symbols),$(if $(filter 1,$($(sym))),$(tier_$(sym))))
|
||||
|
||||
# Dependencies between automation build steps
|
||||
automation/uploadsymbols: automation/buildsymbols
|
||||
@@ -76,15 +74,17 @@ automation/upload: automation/package
|
||||
automation/upload: automation/package-tests
|
||||
automation/upload: automation/buildsymbols
|
||||
automation/upload: automation/update-packaging
|
||||
automation/upload: automation/sdk
|
||||
|
||||
# automation/{pretty-}package should depend on build (which is implicit due to
|
||||
# the way client.mk invokes automation/build), but buildsymbols changes the
|
||||
# binaries/libs, and that's what we package/test.
|
||||
automation/pretty-package: automation/buildsymbols
|
||||
|
||||
# The installer and packager both run stage-package, and may conflict
|
||||
# The installer, sdk and packager all run stage-package, and may conflict
|
||||
# with each other.
|
||||
automation/installer: automation/package
|
||||
automation/sdk: automation/installer automation/package
|
||||
|
||||
# The 'pretty' versions of targets run before the regular ones to avoid
|
||||
# conflicts in writing to the same files.
|
||||
@@ -95,11 +95,7 @@ automation/l10n-check: automation/pretty-l10n-check
|
||||
automation/update-packaging: automation/pretty-update-packaging
|
||||
|
||||
automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
|
||||
$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) --upload-files $(abspath $(UPLOAD_FILES)) --package $(PACKAGE)
|
||||
|
||||
# We need the log from make upload to grep it for urls in order to set
|
||||
# properties.
|
||||
AUTOMATION_EXTRA_CMDLINE-upload = 2>&1 | tee $(AUTOMATION_UPLOAD_OUTPUT)
|
||||
@echo Automation steps completed.
|
||||
|
||||
# Note: We have to force -j1 here, at least until bug 1036563 is fixed.
|
||||
AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1
|
||||
|
||||
@@ -17,6 +17,7 @@ mk_add_options "export MOZ_AUTOMATION_INSTALLER=${MOZ_AUTOMATION_INSTALLER-0}"
|
||||
mk_add_options "export MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-0}"
|
||||
mk_add_options "export MOZ_AUTOMATION_UPLOAD=${MOZ_AUTOMATION_UPLOAD-1}"
|
||||
mk_add_options "export MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-0}"
|
||||
mk_add_options "export MOZ_AUTOMATION_SDK=${MOZ_AUTOMATION_SDK-0}"
|
||||
|
||||
# If we are also building with MOZ_PKG_PRETTYNAMES, set the corresponding
|
||||
# stages.
|
||||
|
||||
+121
-24
@@ -8,7 +8,12 @@
|
||||
# to be set:
|
||||
# UPLOAD_HOST : host to upload files to
|
||||
# UPLOAD_USER : username on that host
|
||||
# and one of the following:
|
||||
# UPLOAD_PATH : path on that host to put the files in
|
||||
# UPLOAD_TO_TEMP : upload files to a new temporary directory
|
||||
#
|
||||
# If UPLOAD_HOST and UPLOAD_USER are not set, this script will simply write out
|
||||
# the properties file.
|
||||
#
|
||||
# And will use the following optional environment variables if set:
|
||||
# UPLOAD_SSH_KEY : path to a ssh private key to use
|
||||
@@ -23,18 +28,14 @@
|
||||
# to the base path.
|
||||
|
||||
import sys, os
|
||||
import re
|
||||
import json
|
||||
import errno
|
||||
import hashlib
|
||||
from optparse import OptionParser
|
||||
from subprocess import check_call, check_output
|
||||
from subprocess import check_call, check_output, STDOUT
|
||||
import redo
|
||||
|
||||
def RequireEnvironmentVariable(v):
|
||||
"""Return the value of the environment variable named v, or print
|
||||
an error and exit if it's unset (or empty)."""
|
||||
if not v in os.environ or os.environ[v] == "":
|
||||
print "Error: required environment variable %s not set" % v
|
||||
sys.exit(1)
|
||||
return os.environ[v]
|
||||
|
||||
def OptionalEnvironmentVariable(v):
|
||||
"""Return the value of the environment variable named v, or None
|
||||
if it's unset (or empty)."""
|
||||
@@ -61,7 +62,9 @@ def WindowsPathToMsysPath(path):
|
||||
"""Translate a Windows pathname to an MSYS pathname.
|
||||
Necessary because we call out to ssh/scp, which are MSYS binaries
|
||||
and expect MSYS paths."""
|
||||
if sys.platform != 'win32':
|
||||
# If we're not on Windows, or if we already have an MSYS path (starting
|
||||
# with '/' instead of 'c:' or something), then just return.
|
||||
if sys.platform != 'win32' or path.startswith('/'):
|
||||
return path
|
||||
(drive, path) = os.path.splitdrive(os.path.abspath(path))
|
||||
return "/" + drive[0] + path.replace('\\','/')
|
||||
@@ -85,7 +88,7 @@ def DoSSHCommand(command, user, host, port=None, ssh_key=None):
|
||||
cmdline.extend(["%s@%s" % (user, host), command])
|
||||
|
||||
with redo.retrying(check_output, sleeptime=10) as f:
|
||||
output = f(cmdline).strip()
|
||||
output = f(cmdline, stderr=STDOUT).strip()
|
||||
return output
|
||||
|
||||
raise Exception("Command %s returned non-zero exit code" % cmdline)
|
||||
@@ -115,7 +118,71 @@ def GetRemotePath(path, local_file, base_path):
|
||||
dir = dir[len(base_path)+1:].replace('\\','/')
|
||||
return path + dir
|
||||
|
||||
def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None):
|
||||
def GetFileHashAndSize(filename):
|
||||
sha512Hash = 'UNKNOWN'
|
||||
size = 'UNKNOWN'
|
||||
|
||||
try:
|
||||
# open in binary mode to make sure we get consistent results
|
||||
# across all platforms
|
||||
with open(filename, "rb") as f:
|
||||
shaObj = hashlib.sha512(f.read())
|
||||
sha512Hash = shaObj.hexdigest()
|
||||
|
||||
size = os.path.getsize(filename)
|
||||
except:
|
||||
raise Exception("Unable to get filesize/hash from file: %s" % filename)
|
||||
|
||||
return (sha512Hash, size)
|
||||
|
||||
def GetMarProperties(filename):
|
||||
if not os.path.exists(filename):
|
||||
return {}
|
||||
(mar_hash, mar_size) = GetFileHashAndSize(filename)
|
||||
return {
|
||||
'completeMarFilename': os.path.basename(filename),
|
||||
'completeMarSize': mar_size,
|
||||
'completeMarHash': mar_hash,
|
||||
}
|
||||
|
||||
def GetUrlProperties(output, package):
|
||||
# let's create a switch case using name-spaces/dict
|
||||
# rather than a long if/else with duplicate code
|
||||
property_conditions = [
|
||||
# key: property name, value: condition
|
||||
('symbolsUrl', lambda m: m.endswith('crashreporter-symbols.zip') or
|
||||
m.endswith('crashreporter-symbols-full.zip')),
|
||||
('testsUrl', lambda m: m.endswith(('tests.tar.bz2', 'tests.zip'))),
|
||||
('unsignedApkUrl', lambda m: m.endswith('apk') and
|
||||
'unsigned-unaligned' in m),
|
||||
('robocopApkUrl', lambda m: m.endswith('apk') and 'robocop' in m),
|
||||
('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')),
|
||||
('completeMarUrl', lambda m: m.endswith('.complete.mar')),
|
||||
('partialMarUrl', lambda m: m.endswith('.mar') and '.partial.' in m),
|
||||
('codeCoverageURL', lambda m: m.endswith('code-coverage-gcno.zip')),
|
||||
('sdkUrl', lambda m: m.endswith(('sdk.tar.bz2', 'sdk.zip'))),
|
||||
('testPackagesUrl', lambda m: m.endswith('test_packages.json')),
|
||||
('packageUrl', lambda m: m.endswith(package)),
|
||||
]
|
||||
url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz|json))$''')
|
||||
properties = {}
|
||||
|
||||
try:
|
||||
for line in output.splitlines():
|
||||
m = url_re.match(line.strip())
|
||||
if m:
|
||||
m = m.group(1)
|
||||
for prop, condition in property_conditions:
|
||||
if condition(m):
|
||||
properties.update({prop: m})
|
||||
break
|
||||
except IOError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
properties = {prop: 'UNKNOWN' for prop, condition in property_conditions}
|
||||
return properties
|
||||
|
||||
def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None, package=None):
|
||||
"""Upload each file in the list files to user@host:path. Optionally pass
|
||||
port and ssh_key to the ssh commands. If base_path is not None, upload
|
||||
files including their path relative to base_path. If upload_to_temp_dir is
|
||||
@@ -126,6 +193,13 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None,
|
||||
after uploading all files, passing it the upload path, and the full paths to
|
||||
all files uploaded.
|
||||
If verbose is True, print status updates while working."""
|
||||
if not host or not user:
|
||||
return {}
|
||||
if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
|
||||
print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
|
||||
"defined."
|
||||
sys.exit(1)
|
||||
|
||||
if upload_to_temp_dir:
|
||||
path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
|
||||
if not path.endswith("/"):
|
||||
@@ -133,6 +207,7 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None,
|
||||
if base_path is not None:
|
||||
base_path = os.path.abspath(base_path)
|
||||
remote_files = []
|
||||
properties = {}
|
||||
try:
|
||||
for file in files:
|
||||
file = os.path.abspath(file)
|
||||
@@ -149,17 +224,31 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None,
|
||||
if verbose:
|
||||
print "Running post-upload command: " + post_upload_command
|
||||
file_list = '"' + '" "'.join(remote_files) + '"'
|
||||
DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
|
||||
output = DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
|
||||
# We print since mozharness may parse URLs from the output stream.
|
||||
print output
|
||||
properties = GetUrlProperties(output, package)
|
||||
finally:
|
||||
if upload_to_temp_dir:
|
||||
DoSSHCommand("rm -rf %s" % path, user, host, port=port,
|
||||
ssh_key=ssh_key)
|
||||
if verbose:
|
||||
print "Upload complete"
|
||||
return properties
|
||||
|
||||
def WriteProperties(files, properties_file, url_properties, package):
|
||||
properties = url_properties
|
||||
for file in files:
|
||||
if file.endswith('.complete.mar'):
|
||||
properties.update(GetMarProperties(file))
|
||||
with open(properties_file, 'w') as outfile:
|
||||
properties['packageFilename'] = package
|
||||
properties['uploadFiles'] = [os.path.abspath(f) for f in files]
|
||||
json.dump(properties, outfile, indent=4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
host = RequireEnvironmentVariable('UPLOAD_HOST')
|
||||
user = RequireEnvironmentVariable('UPLOAD_USER')
|
||||
host = OptionalEnvironmentVariable('UPLOAD_HOST')
|
||||
user = OptionalEnvironmentVariable('UPLOAD_USER')
|
||||
path = OptionalEnvironmentVariable('UPLOAD_PATH')
|
||||
upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
|
||||
port = OptionalEnvironmentVariable('UPLOAD_PORT')
|
||||
@@ -167,10 +256,7 @@ if __name__ == '__main__':
|
||||
port = int(port)
|
||||
key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
|
||||
post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
|
||||
if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
|
||||
print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
|
||||
"defined."
|
||||
sys.exit(1)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
if path is not None:
|
||||
path = FixupMsysPath(path)
|
||||
@@ -179,17 +265,28 @@ if __name__ == '__main__':
|
||||
|
||||
parser = OptionParser(usage="usage: %prog [options] <files>")
|
||||
parser.add_option("-b", "--base-path",
|
||||
action="store", dest="base_path",
|
||||
action="store",
|
||||
help="Preserve file paths relative to this path when uploading. If unset, all files will be uploaded directly to UPLOAD_PATH.")
|
||||
parser.add_option("--properties-file",
|
||||
action="store",
|
||||
help="Path to the properties file to store the upload properties.")
|
||||
parser.add_option("--package",
|
||||
action="store",
|
||||
help="Name of the main package.")
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) < 1:
|
||||
print "You must specify at least one file to upload"
|
||||
sys.exit(1)
|
||||
if not options.properties_file:
|
||||
print "You must specify a --properties-file"
|
||||
sys.exit(1)
|
||||
try:
|
||||
UploadFiles(user, host, path, args, base_path=options.base_path,
|
||||
port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
|
||||
post_upload_command=post_upload_command,
|
||||
verbose=True)
|
||||
url_properties = UploadFiles(user, host, path, args, base_path=options.base_path,
|
||||
port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
|
||||
post_upload_command=post_upload_command,
|
||||
package=options.package,
|
||||
verbose=True)
|
||||
WriteProperties(args, options.properties_file, url_properties, options.package)
|
||||
except IOError, (strerror):
|
||||
print strerror
|
||||
sys.exit(1)
|
||||
|
||||
+17
-1
@@ -494,17 +494,20 @@ IsOnFullDomainWhitelist(nsIURI* aURI)
|
||||
NS_LITERAL_CSTRING("m.video.baidu.com"),
|
||||
NS_LITERAL_CSTRING("m.video.baidu.com"),
|
||||
NS_LITERAL_CSTRING("imgcache.gtimg.cn"), // for m.v.qq.com
|
||||
NS_LITERAL_CSTRING("s.tabelog.jp"),
|
||||
NS_LITERAL_CSTRING("s.yimg.jp"), // for s.tabelog.jp
|
||||
NS_LITERAL_CSTRING("i.yimg.jp"), // for *.yahoo.co.jp
|
||||
NS_LITERAL_CSTRING("ai.yimg.jp"), // for *.yahoo.co.jp
|
||||
NS_LITERAL_CSTRING("m.finance.yahoo.co.jp"),
|
||||
NS_LITERAL_CSTRING("daily.c.yimg.jp"), // for sp.daily.co.jp
|
||||
NS_LITERAL_CSTRING("stat100.ameba.jp"), // for ameblo.jp
|
||||
NS_LITERAL_CSTRING("user.ameba.jp"), // for ameblo.jp
|
||||
NS_LITERAL_CSTRING("www.goo.ne.jp"),
|
||||
NS_LITERAL_CSTRING("s.tabelog.jp"),
|
||||
NS_LITERAL_CSTRING("x.gnst.jp"), // for mobile.gnavi.co.jp
|
||||
NS_LITERAL_CSTRING("c.x.gnst.jp"), // for mobile.gnavi.co.jp
|
||||
NS_LITERAL_CSTRING("www.smbc-card.com"),
|
||||
NS_LITERAL_CSTRING("static.card.jp.rakuten-static.com"), // for rakuten-card.co.jp
|
||||
NS_LITERAL_CSTRING("img.travel.rakuten.co.jp"), // for travel.rakuten.co.jp
|
||||
NS_LITERAL_CSTRING("img.mixi.net"), // for mixi.jp
|
||||
NS_LITERAL_CSTRING("girlschannel.net"),
|
||||
NS_LITERAL_CSTRING("www.fancl.co.jp"),
|
||||
@@ -520,6 +523,16 @@ IsOnFullDomainWhitelist(nsIURI* aURI)
|
||||
NS_LITERAL_CSTRING("mw.nikkei.com"),
|
||||
NS_LITERAL_CSTRING("www.nhk.or.jp"),
|
||||
NS_LITERAL_CSTRING("www.tokyo-sports.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.bellemaison.jp"),
|
||||
NS_LITERAL_CSTRING("www.kuronekoyamato.co.jp"),
|
||||
NS_LITERAL_CSTRING("formassist.jp"), // for orico.jp
|
||||
NS_LITERAL_CSTRING("sp.m.reuters.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.atre.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.jtb.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.sharp.co.jp"),
|
||||
NS_LITERAL_CSTRING("www.biccamera.com"),
|
||||
NS_LITERAL_CSTRING("weathernews.jp"),
|
||||
NS_LITERAL_CSTRING("cache.ymail.jp"), // for www.yamada-denkiweb.com
|
||||
};
|
||||
static const size_t sNumFullDomainsOnWhitelist =
|
||||
MOZ_ARRAY_LENGTH(sFullDomainsOnWhitelist);
|
||||
@@ -545,8 +558,11 @@ IsOnBaseDomainWhitelist(nsIURI* aURI)
|
||||
// 0th entry only active when testing:
|
||||
NS_LITERAL_CSTRING("test2.example.org"),
|
||||
NS_LITERAL_CSTRING("tbcdn.cn"), // for m.taobao.com
|
||||
NS_LITERAL_CSTRING("alicdn.com"), // for m.taobao.com
|
||||
NS_LITERAL_CSTRING("dpfile.com"), // for m.dianping.com
|
||||
NS_LITERAL_CSTRING("hao123img.com"), // for hao123.com
|
||||
NS_LITERAL_CSTRING("tabelog.k-img.com"), // for s.tabelog.com
|
||||
NS_LITERAL_CSTRING("tsite.jp"), // for *.tsite.jp
|
||||
};
|
||||
static const size_t sNumBaseDomainsOnWhitelist =
|
||||
MOZ_ARRAY_LENGTH(sBaseDomainsOnWhitelist);
|
||||
|
||||
+3
-1
@@ -45,7 +45,9 @@ ifndef JS_STANDALONE
|
||||
ifndef MOZ_PROFILE_USE
|
||||
# Generate a new buildid every time we "export" in config... that's only
|
||||
# supposed to be once per-build!
|
||||
export::
|
||||
export:: buildid
|
||||
|
||||
buildid: FORCE
|
||||
ifdef MOZ_BUILD_DATE
|
||||
printf '%s' $(MOZ_BUILD_DATE) > buildid
|
||||
else
|
||||
|
||||
@@ -2540,6 +2540,55 @@ CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissio
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IsNonExposedGlobal(JSContext* aCx, JSObject* aGlobal,
|
||||
uint32_t aNonExposedGlobals)
|
||||
{
|
||||
MOZ_ASSERT(aNonExposedGlobals, "Why did we get called?");
|
||||
MOZ_ASSERT((aNonExposedGlobals &
|
||||
~(GlobalNames::Window |
|
||||
GlobalNames::BackstagePass |
|
||||
GlobalNames::DedicatedWorkerGlobalScope |
|
||||
GlobalNames::SharedWorkerGlobalScope |
|
||||
GlobalNames::ServiceWorkerGlobalScope |
|
||||
GlobalNames::WorkerDebuggerGlobalScope)) == 0,
|
||||
"Unknown non-exposed global type");
|
||||
|
||||
const char* name = js::GetObjectClass(aGlobal)->name;
|
||||
|
||||
if ((aNonExposedGlobals & GlobalNames::Window) &&
|
||||
!strcmp(name, "Window")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((aNonExposedGlobals & GlobalNames::BackstagePass) &&
|
||||
!strcmp(name, "BackstagePass")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((aNonExposedGlobals & GlobalNames::DedicatedWorkerGlobalScope) &&
|
||||
!strcmp(name, "DedicatedWorkerGlobalScope")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((aNonExposedGlobals & GlobalNames::SharedWorkerGlobalScope) &&
|
||||
!strcmp(name, "SharedWorkerGlobalScope")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((aNonExposedGlobals & GlobalNames::ServiceWorkerGlobalScope) &&
|
||||
!strcmp(name, "ServiceWorkerGlobalScope")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((aNonExposedGlobals & GlobalNames::WorkerDebuggerGlobalScope) &&
|
||||
!strcmp(name, "WorkerDebuggerGlobalScopex")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
HandlePrerenderingViolation(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
|
||||
@@ -3163,16 +3163,6 @@ AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitinfo,
|
||||
JS::Handle<JS::Value> aValue);
|
||||
#endif
|
||||
|
||||
// Returns true if aObj's global has any of the permissions named in aPermissions
|
||||
// set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be null-terminated.
|
||||
bool
|
||||
CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
|
||||
|
||||
// Returns true if aObj's global has all of the permissions named in aPermissions
|
||||
// set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be null-terminated.
|
||||
bool
|
||||
CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
|
||||
|
||||
// This function is called by the bindings layer for methods/getters/setters
|
||||
// that are not safe to be called in prerendering mode. It checks to make sure
|
||||
// that the |this| object is not running in a global that is in prerendering
|
||||
|
||||
+61
-36
@@ -1906,16 +1906,26 @@ def getAvailableInTestFunc(obj):
|
||||
class MemberCondition:
|
||||
"""
|
||||
An object representing the condition for a member to actually be
|
||||
exposed. Any of pref, func, and available can be None. If not
|
||||
None, they should be strings that have the pref name (for "pref")
|
||||
or function name (for "func" and "available").
|
||||
exposed. Any of the arguments can be None. If not
|
||||
None, they should have the following types:
|
||||
|
||||
pref: The name of the preference.
|
||||
func: The name of the function.
|
||||
available: A string indicating where we should be available.
|
||||
checkAnyPermissions: An integer index for the anypermissions_* to use.
|
||||
checkAllPermissions: An integer index for the allpermissions_* to use.
|
||||
nonExposedGlobals: A set of names of globals. Can be empty, in which case
|
||||
it's treated the same way as None.
|
||||
"""
|
||||
def __init__(self, pref, func, available=None, checkAnyPermissions=None, checkAllPermissions=None):
|
||||
def __init__(self, pref=None, func=None, available=None,
|
||||
checkAnyPermissions=None, checkAllPermissions=None,
|
||||
nonExposedGlobals=None):
|
||||
assert pref is None or isinstance(pref, str)
|
||||
assert func is None or isinstance(func, str)
|
||||
assert available is None or isinstance(available, str)
|
||||
assert checkAnyPermissions is None or isinstance(checkAnyPermissions, int)
|
||||
assert checkAllPermissions is None or isinstance(checkAllPermissions, int)
|
||||
assert nonExposedGlobals is None or isinstance(nonExposedGlobals, set)
|
||||
self.pref = pref
|
||||
|
||||
def toFuncPtr(val):
|
||||
@@ -1933,11 +1943,20 @@ class MemberCondition:
|
||||
else:
|
||||
self.checkAllPermissions = "allpermissions_%i" % checkAllPermissions
|
||||
|
||||
if nonExposedGlobals:
|
||||
# Nonempty set
|
||||
self.nonExposedGlobals = " | ".join(
|
||||
map(lambda g: "GlobalNames::%s" % g,
|
||||
sorted(nonExposedGlobals)))
|
||||
else:
|
||||
self.nonExposedGlobals = "0"
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.pref == other.pref and self.func == other.func and
|
||||
self.available == other.available and
|
||||
self.checkAnyPermissions == other.checkAnyPermissions and
|
||||
self.checkAllPermissions == other.checkAllPermissions)
|
||||
self.checkAllPermissions == other.checkAllPermissions and
|
||||
self.nonExposedGlobals == other.nonExposedGlobals)
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
@@ -2000,13 +2019,34 @@ class PropertyDefiner:
|
||||
|
||||
@staticmethod
|
||||
def getControllingCondition(interfaceMember, descriptor):
|
||||
return MemberCondition(PropertyDefiner.getStringAttr(interfaceMember,
|
||||
"Pref"),
|
||||
PropertyDefiner.getStringAttr(interfaceMember,
|
||||
"Func"),
|
||||
getAvailableInTestFunc(interfaceMember),
|
||||
descriptor.checkAnyPermissionsIndicesForMembers.get(interfaceMember.identifier.name),
|
||||
descriptor.checkAllPermissionsIndicesForMembers.get(interfaceMember.identifier.name))
|
||||
# We do a slightly complicated thing for exposure sets to deal nicely
|
||||
# with the situation of an [Exposed=Window] thing on an interface
|
||||
# exposed in workers that has a worker-specific descriptor. In that
|
||||
# situation, we already skip generation of the member entirely in the
|
||||
# worker binding, and shouldn't need to check for the various worker
|
||||
# scopes in the non-worker binding.
|
||||
interface = descriptor.interface
|
||||
nonExposureSet = interface.exposureSet - interfaceMember.exposureSet
|
||||
# Skip getting the descriptor if we're just exposed everywhere or not
|
||||
# looking at the non-worker descriptor.
|
||||
if len(nonExposureSet) and not descriptor.workers:
|
||||
workerProvider = descriptor.config.getDescriptorProvider(True)
|
||||
workerDesc = workerProvider.getDescriptor(interface.identifier.name)
|
||||
if workerDesc.workers:
|
||||
# Just drop all the worker interface names from the
|
||||
# nonExposureSet, since we know we'll have a mainthread global
|
||||
# of some sort.
|
||||
nonExposureSet.difference_update(interface.getWorkerExposureSet())
|
||||
|
||||
return MemberCondition(
|
||||
PropertyDefiner.getStringAttr(interfaceMember,
|
||||
"Pref"),
|
||||
PropertyDefiner.getStringAttr(interfaceMember,
|
||||
"Func"),
|
||||
getAvailableInTestFunc(interfaceMember),
|
||||
descriptor.checkAnyPermissionsIndicesForMembers.get(interfaceMember.identifier.name),
|
||||
descriptor.checkAllPermissionsIndicesForMembers.get(interfaceMember.identifier.name),
|
||||
nonExposureSet)
|
||||
|
||||
def generatePrefableArray(self, array, name, specFormatter, specTerminator,
|
||||
specType, getCondition, getDataTuple, doIdArrays):
|
||||
@@ -2044,7 +2084,7 @@ class PropertyDefiner:
|
||||
specs = []
|
||||
prefableSpecs = []
|
||||
|
||||
prefableTemplate = ' { true, %s, %s, %s, %s, &%s[%d] }'
|
||||
prefableTemplate = ' { true, %s, %s, %s, %s, %s, &%s[%d] }'
|
||||
prefCacheTemplate = '&%s[%d].enabled'
|
||||
|
||||
def switchToCondition(props, condition):
|
||||
@@ -2056,7 +2096,8 @@ class PropertyDefiner:
|
||||
prefCacheTemplate % (name, len(prefableSpecs))))
|
||||
# Set up pointers to the new sets of specs inside prefableSpecs
|
||||
prefableSpecs.append(prefableTemplate %
|
||||
(condition.func,
|
||||
(condition.nonExposedGlobals,
|
||||
condition.func,
|
||||
condition.available,
|
||||
condition.checkAnyPermissions,
|
||||
condition.checkAllPermissions,
|
||||
@@ -2075,7 +2116,7 @@ class PropertyDefiner:
|
||||
# And the actual spec
|
||||
specs.append(specFormatter(getDataTuple(member)))
|
||||
specs.append(specTerminator)
|
||||
prefableSpecs.append(" { false, nullptr }")
|
||||
prefableSpecs.append(" { false, 0, nullptr, nullptr, nullptr, nullptr, nullptr }")
|
||||
|
||||
specType = "const " + specType
|
||||
arrays = fill(
|
||||
@@ -2198,7 +2239,7 @@ class MethodDefiner(PropertyDefiner):
|
||||
"methodInfo": False,
|
||||
"length": 1,
|
||||
"flags": "0",
|
||||
"condition": MemberCondition(None, condition)
|
||||
"condition": MemberCondition(func=condition)
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -2252,23 +2293,7 @@ class MethodDefiner(PropertyDefiner):
|
||||
"selfHostedName": "ArrayValues",
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"condition": MemberCondition(None, None)
|
||||
})
|
||||
|
||||
# Output an @@iterator for generated iterator interfaces. This should
|
||||
# not be necessary, but
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1091945 means that
|
||||
# %IteratorPrototype%[@@iterator] is a broken puppy.
|
||||
if (not static and
|
||||
not unforgeable and
|
||||
descriptor.interface.isIteratorInterface()):
|
||||
self.regular.append({
|
||||
"name": "@@iterator",
|
||||
"methodInfo": False,
|
||||
"selfHostedName": "IteratorIdentity",
|
||||
"length": 0,
|
||||
"flags": "0",
|
||||
"condition": MemberCondition(None, None)
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
|
||||
# Generate the maplike/setlike iterator, if one wasn't already
|
||||
@@ -2341,7 +2366,7 @@ class MethodDefiner(PropertyDefiner):
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE", # readonly/permanent added
|
||||
# automatically.
|
||||
"condition": MemberCondition(None, None)
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
|
||||
if descriptor.interface.isJSImplemented():
|
||||
@@ -2353,7 +2378,7 @@ class MethodDefiner(PropertyDefiner):
|
||||
"methodInfo": False,
|
||||
"length": 2,
|
||||
"flags": "0",
|
||||
"condition": MemberCondition(None, None)
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
else:
|
||||
for m in clearableCachedAttrs(descriptor):
|
||||
@@ -2364,7 +2389,7 @@ class MethodDefiner(PropertyDefiner):
|
||||
"methodInfo": False,
|
||||
"length": "0",
|
||||
"flags": "0",
|
||||
"condition": MemberCondition(None, None)
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
|
||||
self.unforgeable = unforgeable
|
||||
|
||||
@@ -39,12 +39,24 @@ typedef bool
|
||||
JS::Handle<JSObject*> obj,
|
||||
JS::AutoIdVector& props);
|
||||
|
||||
// Returns true if aObj's global has any of the permissions named in
|
||||
// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be
|
||||
// null-terminated.
|
||||
bool
|
||||
CheckAnyPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
|
||||
|
||||
// Returns true if aObj's global has all of the permissions named in
|
||||
// aPermissions set to nsIPermissionManager::ALLOW_ACTION. aPermissions must be
|
||||
// null-terminated.
|
||||
bool
|
||||
CheckAllPermissions(JSContext* aCx, JSObject* aObj, const char* const aPermissions[]);
|
||||
|
||||
// Returns true if the given global is of a type whose bit is set in
|
||||
// aNonExposedGlobals.
|
||||
bool
|
||||
IsNonExposedGlobal(JSContext* aCx, JSObject* aGlobal,
|
||||
uint32_t aNonExposedGlobals);
|
||||
|
||||
struct ConstantSpec
|
||||
{
|
||||
const char* name;
|
||||
@@ -53,9 +65,35 @@ struct ConstantSpec
|
||||
|
||||
typedef bool (*PropertyEnabled)(JSContext* cx, JSObject* global);
|
||||
|
||||
namespace GlobalNames {
|
||||
// The names of our possible globals. These are the names of the actual
|
||||
// interfaces, not of the global names used to refer to them in IDL [Exposed]
|
||||
// annotations.
|
||||
static const uint32_t Window = 1u << 0;
|
||||
static const uint32_t BackstagePass = 1u << 1;
|
||||
static const uint32_t DedicatedWorkerGlobalScope = 1u << 2;
|
||||
static const uint32_t SharedWorkerGlobalScope = 1u << 3;
|
||||
static const uint32_t ServiceWorkerGlobalScope = 1u << 4;
|
||||
static const uint32_t WorkerDebuggerGlobalScope = 1u << 5;
|
||||
} // namespace GlobalNames
|
||||
|
||||
template<typename T>
|
||||
struct Prefable {
|
||||
inline bool isEnabled(JSContext* cx, JS::Handle<JSObject*> obj) const {
|
||||
// Reading "enabled" on a worker thread is technically undefined behavior,
|
||||
// because it's written only on main threads, with no barriers of any sort.
|
||||
// So we want to avoid doing that. But we don't particularly want to make
|
||||
// expensive NS_IsMainThread calls here.
|
||||
//
|
||||
// The good news is that "enabled" is only written for things that have a
|
||||
// Pref annotation, and such things can never be exposed on non-Window
|
||||
// globals; our IDL parser enforces that. So as long as we check our
|
||||
// exposure set before checking "enabled" we will be ok.
|
||||
if (nonExposedGlobals &&
|
||||
IsNonExposedGlobal(cx, js::GetGlobalForObjectCrossCompartment(obj),
|
||||
nonExposedGlobals)) {
|
||||
return false;
|
||||
}
|
||||
if (!enabled) {
|
||||
return false;
|
||||
}
|
||||
@@ -85,6 +123,8 @@ struct Prefable {
|
||||
|
||||
// A boolean indicating whether this set of specs is enabled
|
||||
bool enabled;
|
||||
// Bitmask of global names that we should not be exposed in.
|
||||
uint32_t nonExposedGlobals;
|
||||
// A function pointer to a function that can say the property is disabled
|
||||
// even if "enabled" is set to true. If the pointer is null the value of
|
||||
// "enabled" is used as-is unless availableFunc overrides.
|
||||
|
||||
+9
-11
@@ -136,11 +136,6 @@ public:
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = proxy->GetWorkerPrivate()->GetLoadGroup();
|
||||
MOZ_ASSERT(loadGroup);
|
||||
RefPtr<FetchDriver> fetch = new FetchDriver(mRequest, principal, loadGroup);
|
||||
nsIDocument* doc = proxy->GetWorkerPrivate()->GetDocument();
|
||||
if (doc) {
|
||||
fetch->SetDocument(doc);
|
||||
}
|
||||
|
||||
nsresult rv = fetch->Fetch(mResolver);
|
||||
// Right now we only support async fetch, which should never directly fail.
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@@ -662,17 +657,15 @@ public:
|
||||
|
||||
uint8_t* nonconstResult = const_cast<uint8_t*>(aResult);
|
||||
if (mFetchBody->mWorkerPrivate) {
|
||||
// This way if the runnable dispatch fails, the body is still released.
|
||||
AutoFailConsumeBody<Derived> autoFail(mFetchBody);
|
||||
RefPtr<ContinueConsumeBodyRunnable<Derived>> r =
|
||||
new ContinueConsumeBodyRunnable<Derived>(mFetchBody,
|
||||
aStatus,
|
||||
aResultLength,
|
||||
nonconstResult);
|
||||
AutoSafeJSContext cx;
|
||||
if (r->Dispatch(cx)) {
|
||||
autoFail.DontFail();
|
||||
} else {
|
||||
if (!r->Dispatch(cx)) {
|
||||
// XXXcatalinb: The worker is shutting down, the pump will be canceled
|
||||
// by FetchBodyFeature::Notify.
|
||||
NS_WARNING("Could not dispatch ConsumeBodyRunnable");
|
||||
// Return failure so that aResult is freed.
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -742,10 +735,12 @@ class FetchBodyFeature final : public workers::WorkerFeature
|
||||
// This is addrefed before the feature is created, and is released in ContinueConsumeBody()
|
||||
// so we can hold a rawptr.
|
||||
FetchBody<Derived>* mBody;
|
||||
bool mWasNotified;
|
||||
|
||||
public:
|
||||
explicit FetchBodyFeature(FetchBody<Derived>* aBody)
|
||||
: mBody(aBody)
|
||||
, mWasNotified(false)
|
||||
{ }
|
||||
|
||||
~FetchBodyFeature()
|
||||
@@ -754,7 +749,10 @@ public:
|
||||
bool Notify(JSContext* aCx, workers::Status aStatus) override
|
||||
{
|
||||
MOZ_ASSERT(aStatus > workers::Running);
|
||||
mBody->ContinueConsumeBody(NS_BINDING_ABORTED, 0, nullptr);
|
||||
if (!mWasNotified) {
|
||||
mWasNotified = true;
|
||||
mBody->ContinueConsumeBody(NS_BINDING_ABORTED, 0, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -245,10 +245,8 @@ FetchDriver::HttpFetch()
|
||||
MOZ_ASSERT(mLoadGroup);
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
|
||||
// For dedicated workers mDocument refers to the parent document of the
|
||||
// worker (why do we do that?). In that case we don't want to use the
|
||||
// document here since that is not the correct principal.
|
||||
if (mDocument && mDocument->NodePrincipal() == mPrincipal) {
|
||||
if (mDocument) {
|
||||
MOZ_ASSERT(mDocument->NodePrincipal() == mPrincipal);
|
||||
rv = NS_NewChannel(getter_AddRefs(chan),
|
||||
uri,
|
||||
mDocument,
|
||||
|
||||
@@ -102,6 +102,19 @@ public:
|
||||
mInternalHeaders->Set(aName, aValue, aRv);
|
||||
}
|
||||
|
||||
uint32_t GetIterableLength() const
|
||||
{
|
||||
return mInternalHeaders->GetIterableLength();
|
||||
}
|
||||
const nsString GetKeyAtIndex(unsigned aIndex) const
|
||||
{
|
||||
return mInternalHeaders->GetKeyAtIndex(aIndex);
|
||||
}
|
||||
const nsString GetValueAtIndex(unsigned aIndex) const
|
||||
{
|
||||
return mInternalHeaders->GetValueAtIndex(aIndex);
|
||||
}
|
||||
|
||||
// ChromeOnly
|
||||
HeadersGuardEnum Guard() const
|
||||
{
|
||||
|
||||
@@ -151,13 +151,8 @@ InternalHeaders::Clear()
|
||||
void
|
||||
InternalHeaders::SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv)
|
||||
{
|
||||
// Rather than re-validate all current headers, just require code to set
|
||||
// this prior to populating the InternalHeaders object. Allow setting immutable
|
||||
// late, though, as that is pretty much required to have a useful, immutable
|
||||
// headers object.
|
||||
if (aGuard != HeadersGuardEnum::Immutable && mList.Length() > 0) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
// The guard is only checked during ::Set() and ::Append() in the spec. It
|
||||
// does not require revalidating headers already set.
|
||||
mGuard = aGuard;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,21 @@ public:
|
||||
bool Has(const nsACString& aName, ErrorResult& aRv) const;
|
||||
void Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv);
|
||||
|
||||
uint32_t GetIterableLength() const
|
||||
{
|
||||
return mList.Length();
|
||||
}
|
||||
const NS_ConvertASCIItoUTF16 GetKeyAtIndex(unsigned aIndex) const
|
||||
{
|
||||
MOZ_ASSERT(aIndex < mList.Length());
|
||||
return NS_ConvertASCIItoUTF16(mList[aIndex].mName);
|
||||
}
|
||||
const NS_ConvertASCIItoUTF16 GetValueAtIndex(unsigned aIndex) const
|
||||
{
|
||||
MOZ_ASSERT(aIndex < mList.Length());
|
||||
return NS_ConvertASCIItoUTF16(mList[aIndex].mValue);
|
||||
}
|
||||
|
||||
void Clear();
|
||||
|
||||
HeadersGuardEnum Guard() const { return mGuard; }
|
||||
|
||||
@@ -64,6 +64,25 @@ Request::RequestContextEnabled(JSContext* aCx, JSObject* aObj)
|
||||
return workerPrivate->RequestContextEnabled();
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
Request::RequestCacheEnabled(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
return Preferences::GetBool("dom.requestcache.enabled", false);
|
||||
}
|
||||
|
||||
using namespace workers;
|
||||
|
||||
// Otherwise, check the pref via the WorkerPrivate
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||
if (!workerPrivate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return workerPrivate->RequestCacheEnabled();
|
||||
}
|
||||
|
||||
already_AddRefed<InternalRequest>
|
||||
Request::GetInternalRequest()
|
||||
{
|
||||
|
||||
@@ -36,6 +36,8 @@ public:
|
||||
|
||||
static bool
|
||||
RequestContextEnabled(JSContext* aCx, JSObject* aObj);
|
||||
static bool
|
||||
RequestCacheEnabled(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
JSObject*
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
}
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
|
||||
|
||||
@@ -319,6 +319,7 @@ IDBFactory::CreateForJSInternal(JSContext* aCx,
|
||||
if (aPrincipalInfo->type() != PrincipalInfo::TContentPrincipalInfo &&
|
||||
aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo) {
|
||||
NS_WARNING("IndexedDB not allowed for this principal!");
|
||||
aPrincipalInfo = nullptr;
|
||||
*aFactory = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ function testScript(script) {
|
||||
function setupPrefs() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [["dom.requestcontext.enabled", true],
|
||||
"set": [["dom.requestcache.enabled", true],
|
||||
["dom.requestcontext.enabled", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true]]
|
||||
|
||||
@@ -36,6 +36,7 @@ skip-if = e10s || buildapp == 'b2g' # Bug 1173163 for e10s, bug 1137683 for b2g
|
||||
[test_formdataparsing_sw_reroute.html]
|
||||
skip-if = buildapp == 'b2g' # Bug 1137683
|
||||
[test_request.html]
|
||||
[test_request_cache.html]
|
||||
[test_request_context.html]
|
||||
[test_request_sw_reroute.html]
|
||||
skip-if = buildapp == 'b2g' # Bug 1137683
|
||||
|
||||
@@ -10,7 +10,8 @@ function testScript(script) {
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [["dom.serviceWorkers.enabled", true],
|
||||
"set": [["dom.requestcache.enabled", true],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.interception.opaque.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.serviceWorkers.exemptFromPerDomainMax", true]]
|
||||
|
||||
@@ -13,16 +13,27 @@ function shouldThrow(func, expected, msg) {
|
||||
}
|
||||
}
|
||||
|
||||
function recursiveArrayCompare(actual, expected) {
|
||||
is(Array.isArray(actual), Array.isArray(expected), "Both should either be arrays, or not");
|
||||
if (Array.isArray(actual) && Array.isArray(expected)) {
|
||||
var diff = actual.length !== expected.length;
|
||||
|
||||
for (var i = 0, n = actual.length; !diff && i < n; ++i) {
|
||||
diff = recursiveArrayCompare(actual[i], expected[i]);
|
||||
}
|
||||
|
||||
return diff;
|
||||
} else {
|
||||
return actual !== expected;
|
||||
}
|
||||
}
|
||||
|
||||
function arrayEquals(actual, expected, msg) {
|
||||
if (actual === expected) {
|
||||
return;
|
||||
}
|
||||
|
||||
var diff = actual.length !== expected.length;
|
||||
|
||||
for (var i = 0, n = actual.length; !diff && i < n; ++i) {
|
||||
diff = actual[i] !== expected[i];
|
||||
}
|
||||
var diff = recursiveArrayCompare(actual, expected);
|
||||
|
||||
ok(!diff, msg);
|
||||
if (diff) {
|
||||
@@ -169,8 +180,60 @@ function TestFilledHeaders() {
|
||||
}, TypeError, "Fill with non-tuple sequence should throw TypeError.");
|
||||
}
|
||||
|
||||
function iterate(iter) {
|
||||
var result = [];
|
||||
for (var val = iter.next(); !val.done;) {
|
||||
result.push(val.value);
|
||||
val = iter.next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function iterateForOf(iter) {
|
||||
var result = [];
|
||||
for (var value of iter) {
|
||||
result.push(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function byteInflate(str) {
|
||||
var encoder = new TextEncoder("utf-8");
|
||||
var encoded = encoder.encode(str);
|
||||
var result = "";
|
||||
for (var i = 0; i < encoded.length; ++i) {
|
||||
result += String.fromCharCode(encoded[i]);
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function TestHeadersIterator() {
|
||||
var ehsanInflated = byteInflate("احسان");
|
||||
var headers = new Headers();
|
||||
headers.set("foo0", "bar0");
|
||||
headers.append("foo", "bar");
|
||||
headers.append("foo", ehsanInflated);
|
||||
headers.append("Foo2", "bar2");
|
||||
headers.set("Foo2", "baz2");
|
||||
headers.set("foo3", "bar3");
|
||||
headers.delete("foo0");
|
||||
headers.delete("foo3");
|
||||
|
||||
var key_iter = headers.keys();
|
||||
var value_iter = headers.values();
|
||||
var entries_iter = headers.entries();
|
||||
|
||||
arrayEquals(iterate(key_iter), ["foo", "foo", "foo2"], "Correct key iterator");
|
||||
arrayEquals(iterate(value_iter), ["bar", ehsanInflated, "baz2"], "Correct value iterator");
|
||||
arrayEquals(iterate(entries_iter), [["foo", "bar"], ["foo", ehsanInflated], ["foo2", "baz2"]], "Correct entries iterator");
|
||||
|
||||
arrayEquals(iterateForOf(headers), [["foo", "bar"], ["foo", ehsanInflated], ["foo2", "baz2"]], "Correct entries iterator");
|
||||
arrayEquals(iterateForOf(new Headers(headers)), [["foo", "bar"], ["foo", ehsanInflated], ["foo2", "baz2"]], "Correct entries iterator");
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
TestEmptyHeaders();
|
||||
TestFilledHeaders();
|
||||
TestHeadersIterator();
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Make sure that Request.cache is not exposed by default</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var req = new Request("");
|
||||
ok(!("cache" in req), "Request.cache should not be exposed by default");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -49,6 +49,6 @@ partial interface EventTarget {
|
||||
// chrome easier. This returns the window which can be used to create
|
||||
// events to fire at this EventTarget, or null if there isn't one.
|
||||
partial interface EventTarget {
|
||||
[ChromeOnly, Exposed=Window, BinaryName="ownerGlobalForBindings"]
|
||||
[ChromeOnly, Exposed=(Window,System), BinaryName="ownerGlobalForBindings"]
|
||||
readonly attribute WindowProxy? ownerGlobal;
|
||||
};
|
||||
|
||||
@@ -27,6 +27,7 @@ interface Headers {
|
||||
[Throws] sequence<ByteString> getAll(ByteString name);
|
||||
[Throws] boolean has(ByteString name);
|
||||
[Throws] void set(ByteString name, ByteString value);
|
||||
iterable<ByteString, ByteString>;
|
||||
|
||||
// Used to test different guard states from mochitest.
|
||||
// Note: Must be set prior to populating headers or will throw.
|
||||
|
||||
@@ -22,6 +22,7 @@ interface Request {
|
||||
readonly attribute DOMString referrer;
|
||||
readonly attribute RequestMode mode;
|
||||
readonly attribute RequestCredentials credentials;
|
||||
[Func="mozilla::dom::Request::RequestCacheEnabled"]
|
||||
readonly attribute RequestCache cache;
|
||||
readonly attribute RequestRedirect redirect;
|
||||
|
||||
|
||||
+101
-226
@@ -122,10 +122,6 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
#define CC_REQUEST_OBSERVER_TOPIC "child-cc-request"
|
||||
#define MEMORY_PRESSURE_OBSERVER_TOPIC "memory-pressure"
|
||||
|
||||
#define PREF_GENERAL_APPNAME_OVERRIDE "general.appname.override"
|
||||
#define PREF_GENERAL_APPVERSION_OVERRIDE "general.appversion.override"
|
||||
#define PREF_GENERAL_PLATFORM_OVERRIDE "general.platform.override"
|
||||
|
||||
#define BROADCAST_ALL_WORKERS(_func, ...) \
|
||||
PR_BEGIN_MACRO \
|
||||
AssertIsOnMainThread(); \
|
||||
@@ -152,27 +148,6 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
|
||||
#define PREF_MEM_OPTIONS_PREFIX "mem."
|
||||
#define PREF_GCZEAL "gcZeal"
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
#define DUMP_CONTROLLED_BY_PREF 1
|
||||
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
|
||||
#endif
|
||||
|
||||
#define PREF_DOM_CACHES_ENABLED "dom.caches.enabled"
|
||||
#define PREF_DOM_CACHES_TESTING_ENABLED "dom.caches.testing.enabled"
|
||||
#define PREF_WORKERS_PERFORMANCE_LOGGING_ENABLED "dom.performance.enable_user_timing_logging"
|
||||
#define PREF_DOM_WORKERNOTIFICATION_ENABLED "dom.webnotifications.enabled"
|
||||
#define PREF_DOM_SERVICEWORKERNOTIFICATION_ENABLED "dom.webnotifications.serviceworker.enabled"
|
||||
#define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion"
|
||||
#define PREF_INTL_ACCEPT_LANGUAGES "intl.accept_languages"
|
||||
#define PREF_SERVICEWORKERS_ENABLED "dom.serviceWorkers.enabled"
|
||||
#define PREF_SERVICEWORKERS_TESTING_ENABLED "dom.serviceWorkers.testing.enabled"
|
||||
#define PREF_INTERCEPTION_ENABLED "dom.serviceWorkers.interception.enabled"
|
||||
#define PREF_INTERCEPTION_OPAQUE_ENABLED "dom.serviceWorkers.interception.opaque.enabled"
|
||||
#define PREF_OPEN_WINDOW_ENABLED "dom.serviceWorkers.openWindow.enabled"
|
||||
#define PREF_PUSH_ENABLED "dom.push.enabled"
|
||||
#define PREF_REQUESTCONTEXT_ENABLED "dom.requestcontext.enabled"
|
||||
#define PREF_OFFSCREENCANVAS_ENABLED "gfx.offscreencanvas.enabled"
|
||||
|
||||
namespace {
|
||||
|
||||
const uint32_t kNoIndex = uint32_t(-1);
|
||||
@@ -763,9 +738,48 @@ AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||
aSize, aMemory, aHandle);
|
||||
}
|
||||
|
||||
struct WorkerThreadRuntimePrivate : public PerThreadAtomCache
|
||||
class WorkerJSRuntime;
|
||||
|
||||
class WorkerThreadRuntimePrivate : private PerThreadAtomCache
|
||||
{
|
||||
friend class WorkerJSRuntime;
|
||||
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
|
||||
public:
|
||||
// This can't return null, but we can't lose the "Get" prefix in the name or
|
||||
// it will be ambiguous with the WorkerPrivate class name.
|
||||
WorkerPrivate*
|
||||
GetWorkerPrivate() const
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
|
||||
return mWorkerPrivate;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit
|
||||
WorkerThreadRuntimePrivate(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
// Zero out the base class members.
|
||||
memset(this, 0, sizeof(PerThreadAtomCache));
|
||||
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
}
|
||||
|
||||
~WorkerThreadRuntimePrivate()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
}
|
||||
|
||||
WorkerThreadRuntimePrivate(const WorkerThreadRuntimePrivate&) = delete;
|
||||
|
||||
WorkerThreadRuntimePrivate&
|
||||
operator=(const WorkerThreadRuntimePrivate&) = delete;
|
||||
};
|
||||
|
||||
JSContext*
|
||||
@@ -814,11 +828,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto rtPrivate = new WorkerThreadRuntimePrivate();
|
||||
memset(rtPrivate, 0, sizeof(WorkerThreadRuntimePrivate));
|
||||
rtPrivate->mWorkerPrivate = aWorkerPrivate;
|
||||
JS_SetRuntimePrivate(aRuntime, rtPrivate);
|
||||
|
||||
JS_SetErrorReporter(aRuntime, ErrorReporter);
|
||||
|
||||
JS_SetInterruptCallback(aRuntime, InterruptCallback);
|
||||
@@ -883,16 +892,23 @@ public:
|
||||
WORKER_DEFAULT_NURSERY_SIZE),
|
||||
mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
js::SetPreserveWrapperCallback(Runtime(), PreserveWrapper);
|
||||
JS_InitDestroyPrincipalsCallback(Runtime(), DestroyWorkerPrincipals);
|
||||
JS_SetWrapObjectCallbacks(Runtime(), &WrapObjectCallbacks);
|
||||
JSRuntime* rt = Runtime();
|
||||
MOZ_ASSERT(rt);
|
||||
|
||||
JS_SetRuntimePrivate(rt, new WorkerThreadRuntimePrivate(aWorkerPrivate));
|
||||
|
||||
js::SetPreserveWrapperCallback(rt, PreserveWrapper);
|
||||
JS_InitDestroyPrincipalsCallback(rt, DestroyWorkerPrincipals);
|
||||
JS_SetWrapObjectCallbacks(rt, &WrapObjectCallbacks);
|
||||
}
|
||||
|
||||
~WorkerJSRuntime()
|
||||
{
|
||||
auto rtPrivate = static_cast<WorkerThreadRuntimePrivate*>(JS_GetRuntimePrivate(Runtime()));
|
||||
delete rtPrivate;
|
||||
JS_SetRuntimePrivate(Runtime(), nullptr);
|
||||
JSRuntime* rt = Runtime();
|
||||
MOZ_ASSERT(rt);
|
||||
|
||||
delete static_cast<WorkerThreadRuntimePrivate*>(JS_GetRuntimePrivate(rt));
|
||||
JS_SetRuntimePrivate(rt, nullptr);
|
||||
|
||||
// The worker global should be unrooted and the shutdown cycle collection
|
||||
// should break all remaining cycles. The superclass destructor will run
|
||||
@@ -1141,7 +1157,7 @@ AppNameOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
|
||||
AssertIsOnMainThread();
|
||||
|
||||
const nsAdoptingString& override =
|
||||
mozilla::Preferences::GetString(PREF_GENERAL_APPNAME_OVERRIDE);
|
||||
mozilla::Preferences::GetString("general.appname.override");
|
||||
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
if (runtime) {
|
||||
@@ -1155,7 +1171,7 @@ AppVersionOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
|
||||
AssertIsOnMainThread();
|
||||
|
||||
const nsAdoptingString& override =
|
||||
mozilla::Preferences::GetString(PREF_GENERAL_APPVERSION_OVERRIDE);
|
||||
mozilla::Preferences::GetString("general.appversion.override");
|
||||
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
if (runtime) {
|
||||
@@ -1169,7 +1185,7 @@ PlatformOverrideChanged(const char* /* aPrefName */, void* /* aClosure */)
|
||||
AssertIsOnMainThread();
|
||||
|
||||
const nsAdoptingString& override =
|
||||
mozilla::Preferences::GetString(PREF_GENERAL_PLATFORM_OVERRIDE);
|
||||
mozilla::Preferences::GetString("general.platform.override");
|
||||
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
if (runtime) {
|
||||
@@ -1303,7 +1319,8 @@ GetWorkerPrivateFromContext(JSContext* aCx)
|
||||
void* rtPrivate = JS_GetRuntimePrivate(rt);
|
||||
MOZ_ASSERT(rtPrivate);
|
||||
|
||||
return static_cast<WorkerThreadRuntimePrivate*>(rtPrivate)->mWorkerPrivate;
|
||||
return
|
||||
static_cast<WorkerThreadRuntimePrivate*>(rtPrivate)->GetWorkerPrivate();
|
||||
}
|
||||
|
||||
WorkerPrivate*
|
||||
@@ -1322,7 +1339,8 @@ GetCurrentThreadWorkerPrivate()
|
||||
void* rtPrivate = JS_GetRuntimePrivate(rt);
|
||||
MOZ_ASSERT(rtPrivate);
|
||||
|
||||
return static_cast<WorkerThreadRuntimePrivate*>(rtPrivate)->mWorkerPrivate;
|
||||
return
|
||||
static_cast<WorkerThreadRuntimePrivate*>(rtPrivate)->GetWorkerPrivate();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1645,7 +1663,7 @@ RuntimeService::UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
}
|
||||
}
|
||||
|
||||
if (!domainInfo->ActiveWorkerCount()) {
|
||||
if (domainInfo->HasNoWorkers()) {
|
||||
MOZ_ASSERT(domainInfo->mQueuedWorkers.IsEmpty());
|
||||
mDomainMap.Remove(domain);
|
||||
}
|
||||
@@ -1841,11 +1859,6 @@ RuntimeService::Init()
|
||||
WORKER_DEFAULT_ALLOCATION_THRESHOLD);
|
||||
}
|
||||
|
||||
// If dump is not controlled by pref, it's set to true.
|
||||
#ifndef DUMP_CONTROLLED_BY_PREF
|
||||
sDefaultPreferences[WORKERPREF_DUMP] = true;
|
||||
#endif
|
||||
|
||||
mIdleThreadTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
NS_ENSURE_STATE(mIdleThreadTimer);
|
||||
|
||||
@@ -1894,95 +1907,29 @@ RuntimeService::Init()
|
||||
LoadGCZealOptions,
|
||||
PREF_JS_OPTIONS_PREFIX PREF_GCZEAL,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadGCZealOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX PREF_GCZEAL,
|
||||
nullptr)) ||
|
||||
#endif
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_CACHES_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_CACHES))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WORKERNOTIFICATION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_WORKERNOTIFICATION))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_SERVICEWORKERNOTIFICATION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_SERVICEWORKERNOTIFICATION))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_SERVICEWORKERS_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_SERVICEWORKERS))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_INTERCEPTION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_ENABLED))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_OPEN_WINDOW_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_OPEN_WINDOW_ENABLED))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_INTERCEPTION_OPAQUE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_OPAQUE_ENABLED))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_CACHES_TESTING_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_CACHES_TESTING))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_WORKERS_PERFORMANCE_LOGGING_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PERFORMANCE_LOGGING_ENABLED))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_SERVICEWORKERS_TESTING_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_SERVICEWORKERS_TESTING))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_PUSH_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PUSH))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_REQUESTCONTEXT_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_REQUESTCONTEXT))) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_OFFSCREENCANVAS_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_OFFSCREENCANVAS))) ||
|
||||
NS_FAILED(Preferences::RegisterCallback(LoadRuntimeOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
|
||||
#define WORKER_SIMPLE_PREF(name, getter, NAME) \
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall( \
|
||||
WorkerPrefChanged, \
|
||||
name, \
|
||||
reinterpret_cast<void*>(WORKERPREF_##NAME))) ||
|
||||
#define WORKER_PREF(name, callback) \
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall( \
|
||||
callback, \
|
||||
name, \
|
||||
nullptr)) ||
|
||||
#include "WorkerPrefs.h"
|
||||
#undef WORKER_SIMPLE_PREF
|
||||
#undef WORKER_PREF
|
||||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadRuntimeOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(PrefLanguagesChanged,
|
||||
PREF_INTL_ACCEPT_LANGUAGES,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
AppNameOverrideChanged,
|
||||
PREF_GENERAL_APPNAME_OVERRIDE,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
AppVersionOverrideChanged,
|
||||
PREF_GENERAL_APPVERSION_OVERRIDE,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
PlatformOverrideChanged,
|
||||
PREF_GENERAL_PLATFORM_OVERRIDE,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
JSVersionChanged,
|
||||
PREF_WORKERS_LATEST_JS_VERSION,
|
||||
nullptr))) {
|
||||
NS_FAILED(Preferences::RegisterCallback(LoadRuntimeOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr))) {
|
||||
NS_WARNING("Failed to register pref callbacks!");
|
||||
}
|
||||
|
||||
@@ -2132,93 +2079,32 @@ RuntimeService::Cleanup()
|
||||
NS_ASSERTION(!mWindowMap.Count(), "All windows should have been released!");
|
||||
|
||||
if (mObserved) {
|
||||
if (NS_FAILED(Preferences::UnregisterCallback(JSVersionChanged,
|
||||
PREF_WORKERS_LATEST_JS_VERSION,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(AppNameOverrideChanged,
|
||||
PREF_GENERAL_APPNAME_OVERRIDE,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
AppVersionOverrideChanged,
|
||||
PREF_GENERAL_APPVERSION_OVERRIDE,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
PlatformOverrideChanged,
|
||||
PREF_GENERAL_PLATFORM_OVERRIDE,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeOptions,
|
||||
if (NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(LoadRuntimeOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_SERVICEWORKERS_TESTING_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_SERVICEWORKERS_TESTING))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_CACHES_TESTING_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_CACHES_TESTING))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_WORKERS_PERFORMANCE_LOGGING_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PERFORMANCE_LOGGING_ENABLED))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_INTERCEPTION_OPAQUE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_OPAQUE_ENABLED))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_INTERCEPTION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_INTERCEPTION_ENABLED))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_OPEN_WINDOW_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_OPEN_WINDOW_ENABLED))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_SERVICEWORKERS_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_SERVICEWORKERS))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_CACHES_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_CACHES))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WORKERNOTIFICATION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_WORKERNOTIFICATION))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_SERVICEWORKERNOTIFICATION_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DOM_SERVICEWORKERNOTIFICATION))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_PUSH_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PUSH))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_REQUESTCONTEXT_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_REQUESTCONTEXT))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_OFFSCREENCANVAS_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_OFFSCREENCANVAS))) ||
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
|
||||
#define WORKER_SIMPLE_PREF(name, getter, NAME) \
|
||||
NS_FAILED(Preferences::UnregisterCallback( \
|
||||
WorkerPrefChanged, \
|
||||
name, \
|
||||
reinterpret_cast<void*>(WORKERPREF_##NAME))) ||
|
||||
#define WORKER_PREF(name, callback) \
|
||||
NS_FAILED(Preferences::UnregisterCallback( \
|
||||
callback, \
|
||||
name, \
|
||||
nullptr)) ||
|
||||
#include "WorkerPrefs.h"
|
||||
#undef WORKER_SIMPLE_PREF
|
||||
#undef WORKER_PREF
|
||||
|
||||
#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,
|
||||
@@ -2710,22 +2596,11 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
|
||||
static_cast<WorkerPreference>(reinterpret_cast<uintptr_t>(aClosure));
|
||||
|
||||
switch (key) {
|
||||
case WORKERPREF_DOM_CACHES:
|
||||
case WORKERPREF_DOM_CACHES_TESTING:
|
||||
case WORKERPREF_DOM_WORKERNOTIFICATION:
|
||||
case WORKERPREF_DOM_SERVICEWORKERNOTIFICATION:
|
||||
case WORKERPREF_PERFORMANCE_LOGGING_ENABLED:
|
||||
#ifdef DUMP_CONTROLLED_BY_PREF
|
||||
case WORKERPREF_DUMP:
|
||||
#endif
|
||||
case WORKERPREF_INTERCEPTION_ENABLED:
|
||||
case WORKERPREF_INTERCEPTION_OPAQUE_ENABLED:
|
||||
case WORKERPREF_OPEN_WINDOW_ENABLED:
|
||||
case WORKERPREF_SERVICEWORKERS:
|
||||
case WORKERPREF_SERVICEWORKERS_TESTING:
|
||||
case WORKERPREF_PUSH:
|
||||
case WORKERPREF_REQUESTCONTEXT:
|
||||
case WORKERPREF_OFFSCREENCANVAS:
|
||||
#define WORKER_SIMPLE_PREF(name, getter, NAME) case WORKERPREF_##NAME:
|
||||
#define WORKER_PREF(name, callback)
|
||||
#include "WorkerPrefs.h"
|
||||
#undef WORKER_SIMPLE_PREF
|
||||
#undef WORKER_PREF
|
||||
sDefaultPreferences[key] = Preferences::GetBool(aPrefName, false);
|
||||
break;
|
||||
|
||||
@@ -2745,7 +2620,7 @@ RuntimeService::JSVersionChanged(const char* /* aPrefName */, void* /* aClosure
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
bool useLatest = Preferences::GetBool(PREF_WORKERS_LATEST_JS_VERSION, false);
|
||||
bool useLatest = Preferences::GetBool("dom.workers.latestJSVersion", false);
|
||||
JS::CompartmentOptions& options = sDefaultJSSettings.content.compartmentOptions;
|
||||
options.setVersion(useLatest ? JSVERSION_LATEST : JSVERSION_DEFAULT);
|
||||
}
|
||||
|
||||
@@ -56,9 +56,21 @@ class RuntimeService final : public nsIObserver
|
||||
ActiveWorkerCount() const
|
||||
{
|
||||
return mActiveWorkers.Length() +
|
||||
mActiveServiceWorkers.Length() +
|
||||
mChildWorkerCount;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ActiveServiceWorkerCount() const
|
||||
{
|
||||
return mActiveServiceWorkers.Length();
|
||||
}
|
||||
|
||||
bool
|
||||
HasNoWorkers() const
|
||||
{
|
||||
return ActiveWorkerCount() == 0 &&
|
||||
ActiveServiceWorkerCount() == 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct IdleThreadInfo;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// This is the list of the preferences that are exposed to workers.
|
||||
// The format is as follows:
|
||||
//
|
||||
// WORKER_SIMPLE_PREF("foo.bar", FooBar, FOO_BAR, UpdaterFunction)
|
||||
//
|
||||
// * First argument is the name of the pref.
|
||||
// * The name of the getter function. This defines a FindName()
|
||||
// function that returns the value of the pref on WorkerPrivate.
|
||||
// * The macro version of the name. This defines a WORKERPREF_FOO_BAR
|
||||
// macro in Workers.h.
|
||||
// * The name of the function that updates the new value of a pref.
|
||||
//
|
||||
// WORKER_PREF("foo.bar", UpdaterFunction)
|
||||
//
|
||||
// * First argument is the name of the pref.
|
||||
// * The name of the function that updates the new value of a pref.
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
WORKER_SIMPLE_PREF("browser.dom.window.dump.enabled", DumpEnabled, DUMP)
|
||||
#endif
|
||||
WORKER_SIMPLE_PREF("dom.caches.enabled", DOMCachesEnabled, DOM_CACHES)
|
||||
WORKER_SIMPLE_PREF("dom.caches.testing.enabled", DOMCachesTestingEnabled, DOM_CACHES_TESTING)
|
||||
WORKER_SIMPLE_PREF("dom.performance.enable_user_timing_logging", PerformanceLoggingEnabled, PERFORMANCE_LOGGING_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.webnotifications.enabled", DOMWorkerNotificationEnabled, DOM_WORKERNOTIFICATION)
|
||||
WORKER_SIMPLE_PREF("dom.webnotifications.serviceworker.enabled", DOMServiceWorkerNotificationEnabled, DOM_SERVICEWORKERNOTIFICATION)
|
||||
WORKER_SIMPLE_PREF("dom.serviceWorkers.enabled", ServiceWorkersEnabled, SERVICEWORKERS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.serviceWorkers.testing.enabled", ServiceWorkersTestingEnabled, SERVICEWORKERS_TESTING_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.serviceWorkers.interception.enabled", InterceptionEnabled, INTERCEPTION_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.serviceWorkers.interception.opaque.enabled", OpaqueInterceptionEnabled, INTERCEPTION_OPAQUE_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, OPEN_WINDOW_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.requestcache.enabled", RequestCacheEnabled, REQUESTCACHE_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED)
|
||||
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
|
||||
WORKER_PREF("dom.workers.latestJSVersion", JSVersionChanged)
|
||||
WORKER_PREF("intl.accept_languages", PrefLanguagesChanged)
|
||||
WORKER_PREF("general.appname.override", AppNameOverrideChanged)
|
||||
WORKER_PREF("general.appversion.override", AppVersionOverrideChanged)
|
||||
WORKER_PREF("general.platform.override", PlatformOverrideChanged)
|
||||
#ifdef JS_GC_ZEAL
|
||||
WORKER_PREF("dom.workers.options.gcZeal", LoadGCZealOptions)
|
||||
#endif
|
||||
+10
-97
@@ -1230,104 +1230,17 @@ public:
|
||||
bool
|
||||
RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
|
||||
|
||||
bool
|
||||
DumpEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_DUMP];
|
||||
}
|
||||
|
||||
bool
|
||||
DOMCachesEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_DOM_CACHES];
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkersEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_SERVICEWORKERS];
|
||||
}
|
||||
|
||||
// Determine if the SW testing browser-wide pref is set
|
||||
bool
|
||||
ServiceWorkersTestingEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_SERVICEWORKERS_TESTING];
|
||||
}
|
||||
|
||||
bool
|
||||
InterceptionEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_INTERCEPTION_ENABLED];
|
||||
}
|
||||
|
||||
bool
|
||||
OpenWindowEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_OPEN_WINDOW_ENABLED];
|
||||
}
|
||||
|
||||
bool
|
||||
OpaqueInterceptionEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_INTERCEPTION_OPAQUE_ENABLED];
|
||||
}
|
||||
|
||||
bool
|
||||
DOMWorkerNotificationEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_DOM_WORKERNOTIFICATION];
|
||||
}
|
||||
|
||||
bool
|
||||
DOMServiceWorkerNotificationEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_DOM_SERVICEWORKERNOTIFICATION];
|
||||
}
|
||||
|
||||
bool
|
||||
DOMCachesTestingEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_DOM_CACHES_TESTING];
|
||||
}
|
||||
|
||||
bool
|
||||
PerformanceLoggingEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_PERFORMANCE_LOGGING_ENABLED];
|
||||
}
|
||||
|
||||
bool
|
||||
PushEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_PUSH];
|
||||
}
|
||||
|
||||
bool
|
||||
RequestContextEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_REQUESTCONTEXT];
|
||||
}
|
||||
|
||||
bool
|
||||
OffscreenCanvasEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_OFFSCREENCANVAS];
|
||||
#define WORKER_SIMPLE_PREF(name, getter, NAME) \
|
||||
bool \
|
||||
getter() const \
|
||||
{ \
|
||||
AssertIsOnWorkerThread(); \
|
||||
return mPreferences[WORKERPREF_##NAME]; \
|
||||
}
|
||||
#define WORKER_PREF(name, callback)
|
||||
#include "WorkerPrefs.h"
|
||||
#undef WORKER_SIMPLE_PREF
|
||||
#undef WORKER_PREF
|
||||
|
||||
bool
|
||||
OnLine() const
|
||||
|
||||
@@ -318,9 +318,11 @@ WorkerGlobalScope::Dump(const Optional<nsAString>& aString) const
|
||||
return;
|
||||
}
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
if (!mWorkerPrivate->DumpEnabled()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_ConvertUTF16toUTF8 str(aString.Value());
|
||||
|
||||
|
||||
+5
-14
@@ -197,20 +197,11 @@ struct JSSettings
|
||||
|
||||
enum WorkerPreference
|
||||
{
|
||||
WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled
|
||||
WORKERPREF_DOM_CACHES, // dom.caches.enabled
|
||||
WORKERPREF_SERVICEWORKERS, // dom.serviceWorkers.enabled
|
||||
WORKERPREF_INTERCEPTION_ENABLED, // dom.serviceWorkers.interception.enabled
|
||||
WORKERPREF_OPEN_WINDOW_ENABLED, // dom.serviceWorkers.openWindow.enabled
|
||||
WORKERPREF_DOM_WORKERNOTIFICATION, // dom.webnotifications.workers.enabled
|
||||
WORKERPREF_DOM_SERVICEWORKERNOTIFICATION, // dom.webnotifications.serviceworker.enabled
|
||||
WORKERPREF_DOM_CACHES_TESTING, // dom.caches.testing.enabled
|
||||
WORKERPREF_SERVICEWORKERS_TESTING, // dom.serviceWorkers.testing.enabled
|
||||
WORKERPREF_INTERCEPTION_OPAQUE_ENABLED, // dom.serviceWorkers.interception.opaque.enabled
|
||||
WORKERPREF_PERFORMANCE_LOGGING_ENABLED, // dom.performance.enable_user_timing_logging
|
||||
WORKERPREF_PUSH, // dom.push.enabled
|
||||
WORKERPREF_REQUESTCONTEXT, // dom.requestcontext.enabled
|
||||
WORKERPREF_OFFSCREENCANVAS, // gfx.offscreencanvas.enabled
|
||||
#define WORKER_SIMPLE_PREF(name, getter, NAME) WORKERPREF_ ## NAME,
|
||||
#define WORKER_PREF(name, callback)
|
||||
#include "mozilla/dom/WorkerPrefs.h"
|
||||
#undef WORKER_SIMPLE_PREF
|
||||
#undef WORKER_PREF
|
||||
WORKERPREF_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ EXPORTS.mozilla.dom += [
|
||||
'ServiceWorkerMessageEvent.h',
|
||||
'ServiceWorkerRegistrar.h',
|
||||
'ServiceWorkerRegistration.h',
|
||||
'WorkerPrefs.h',
|
||||
'WorkerPrivate.h',
|
||||
'WorkerRunnable.h',
|
||||
'WorkerScope.h',
|
||||
|
||||
+1
-1
@@ -719,7 +719,7 @@ struct JSClass {
|
||||
// application.
|
||||
#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT \
|
||||
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 33)
|
||||
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 36)
|
||||
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
|
||||
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
|
||||
#define JSCLASS_GLOBAL_FLAGS \
|
||||
|
||||
@@ -72,7 +72,6 @@ ModuleValueGetter(JSContext* cx, unsigned argc, Value* vp)
|
||||
ImportEntryObject::class_ = {
|
||||
"ImportEntry",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ImportEntryObject::SlotCount) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_ImportEntry) |
|
||||
JSCLASS_IS_ANONYMOUS
|
||||
};
|
||||
|
||||
@@ -90,8 +89,8 @@ ImportEntryObject::isInstance(HandleValue value)
|
||||
return value.isObject() && value.toObject().is<ImportEntryObject>();
|
||||
}
|
||||
|
||||
/* static */ JSObject*
|
||||
ImportEntryObject::initClass(JSContext* cx, HandleObject obj)
|
||||
/* static */ bool
|
||||
GlobalObject::initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
static const JSPropertySpec protoAccessors[] = {
|
||||
JS_PSG("moduleRequest", ImportEntryObject_moduleRequestGetter, 0),
|
||||
@@ -100,22 +99,15 @@ ImportEntryObject::initClass(JSContext* cx, HandleObject obj)
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
global->setPrototype(JSProto_ImportEntry, ObjectValue(*proto));
|
||||
return proto;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js::InitImportEntryClass(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
return ImportEntryObject::initClass(cx, obj);
|
||||
global->setReservedSlot(IMPORT_ENTRY_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ ImportEntryObject*
|
||||
@@ -124,9 +116,12 @@ ImportEntryObject::create(JSContext* cx,
|
||||
HandleAtom importName,
|
||||
HandleAtom localName)
|
||||
{
|
||||
RootedImportEntry self(cx, NewBuiltinClassInstance<ImportEntryObject>(cx));
|
||||
if (!self)
|
||||
RootedObject proto(cx, cx->global()->getImportEntryPrototype());
|
||||
RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
RootedImportEntry self(cx, &obj->as<ImportEntryObject>());
|
||||
self->initReservedSlot(ModuleRequestSlot, StringValue(moduleRequest));
|
||||
self->initReservedSlot(ImportNameSlot, StringValue(importName));
|
||||
self->initReservedSlot(LocalNameSlot, StringValue(localName));
|
||||
@@ -140,7 +135,6 @@ ImportEntryObject::create(JSContext* cx,
|
||||
ExportEntryObject::class_ = {
|
||||
"ExportEntry",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ExportEntryObject::SlotCount) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_ExportEntry) |
|
||||
JSCLASS_IS_ANONYMOUS
|
||||
};
|
||||
|
||||
@@ -160,8 +154,8 @@ ExportEntryObject::isInstance(HandleValue value)
|
||||
return value.isObject() && value.toObject().is<ExportEntryObject>();
|
||||
}
|
||||
|
||||
/* static */ JSObject*
|
||||
ExportEntryObject::initClass(JSContext* cx, HandleObject obj)
|
||||
/* static */ bool
|
||||
GlobalObject::initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
static const JSPropertySpec protoAccessors[] = {
|
||||
JS_PSG("exportName", ExportEntryObject_exportNameGetter, 0),
|
||||
@@ -171,22 +165,15 @@ ExportEntryObject::initClass(JSContext* cx, HandleObject obj)
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
global->setPrototype(JSProto_ExportEntry, ObjectValue(*proto));
|
||||
return proto;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js::InitExportEntryClass(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
return ExportEntryObject::initClass(cx, obj);
|
||||
global->setReservedSlot(EXPORT_ENTRY_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
static Value
|
||||
@@ -202,9 +189,12 @@ ExportEntryObject::create(JSContext* cx,
|
||||
HandleAtom maybeImportName,
|
||||
HandleAtom maybeLocalName)
|
||||
{
|
||||
RootedExportEntry self(cx, NewBuiltinClassInstance<ExportEntryObject>(cx));
|
||||
if (!self)
|
||||
RootedObject proto(cx, cx->global()->getExportEntryPrototype());
|
||||
RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
RootedExportEntry self(cx, &obj->as<ExportEntryObject>());
|
||||
self->initReservedSlot(ExportNameSlot, StringOrNullValue(maybeExportName));
|
||||
self->initReservedSlot(ModuleRequestSlot, StringOrNullValue(maybeModuleRequest));
|
||||
self->initReservedSlot(ImportNameSlot, StringOrNullValue(maybeImportName));
|
||||
@@ -544,7 +534,6 @@ void FunctionDeclaration::trace(JSTracer* trc)
|
||||
ModuleObject::class_ = {
|
||||
"Module",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ModuleObject::SlotCount) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Module) |
|
||||
JSCLASS_IS_ANONYMOUS,
|
||||
nullptr, /* addProperty */
|
||||
nullptr, /* delProperty */
|
||||
@@ -553,7 +542,7 @@ ModuleObject::class_ = {
|
||||
nullptr, /* enumerate */
|
||||
nullptr, /* resolve */
|
||||
nullptr, /* mayResolve */
|
||||
nullptr, /* finalize */
|
||||
ModuleObject::finalize,
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
@@ -582,10 +571,12 @@ ModuleObject::isInstance(HandleValue value)
|
||||
/* static */ ModuleObject*
|
||||
ModuleObject::create(ExclusiveContext* cx, HandleObject enclosingStaticScope)
|
||||
{
|
||||
Rooted<ModuleObject*> self(cx, NewBuiltinClassInstance<ModuleObject>(cx, TenuredObject));
|
||||
if (!self)
|
||||
RootedObject proto(cx, cx->global()->getModulePrototype());
|
||||
RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
RootedModuleObject self(cx, &obj->as<ModuleObject>());
|
||||
self->initReservedSlot(StaticScopeSlot, ObjectOrNullValue(enclosingStaticScope));
|
||||
|
||||
Zone* zone = cx->zone();
|
||||
@@ -855,8 +846,8 @@ DEFINE_GETTER_FUNCTIONS(ModuleObject, localExportEntries, LocalExportEntriesSlot
|
||||
DEFINE_GETTER_FUNCTIONS(ModuleObject, indirectExportEntries, IndirectExportEntriesSlot)
|
||||
DEFINE_GETTER_FUNCTIONS(ModuleObject, starExportEntries, StarExportEntriesSlot)
|
||||
|
||||
JSObject*
|
||||
js::InitModuleClass(JSContext* cx, HandleObject obj)
|
||||
/* static */ bool
|
||||
GlobalObject::initModuleProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
static const JSPropertySpec protoAccessors[] = {
|
||||
JS_PSG("namespace", ModuleObject_namespace_Getter, 0),
|
||||
@@ -877,17 +868,24 @@ js::InitModuleClass(JSContext* cx, HandleObject obj)
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
|
||||
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, protoFunctions))
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
global->setPrototype(JSProto_Module, ObjectValue(*proto));
|
||||
return proto;
|
||||
global->setReservedSlot(MODULE_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::InitModuleClasses(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
return GlobalObject::initModuleProto(cx, global) &&
|
||||
GlobalObject::initImportEntryProto(cx, global) &&
|
||||
GlobalObject::initExportEntryProto(cx, global);
|
||||
}
|
||||
|
||||
#undef DEFINE_GETTER_FUNCTIONS
|
||||
|
||||
@@ -306,9 +306,7 @@ class MOZ_STACK_CLASS ModuleBuilder
|
||||
ArrayObject* createArray(const TraceableVector<T>& vector);
|
||||
};
|
||||
|
||||
JSObject* InitModuleClass(JSContext* cx, HandleObject obj);
|
||||
JSObject* InitImportEntryClass(JSContext* cx, HandleObject obj);
|
||||
JSObject* InitExportEntryClass(JSContext* cx, HandleObject obj);
|
||||
bool InitModuleClasses(JSContext* cx, HandleObject obj);
|
||||
|
||||
} // namespace js
|
||||
|
||||
|
||||
@@ -112,9 +112,6 @@ IF_SAB(real,imaginary)(SharedUint8ClampedArray, 51, InitViaClassSpec,
|
||||
real(TypedArray, 52, InitViaClassSpec, &js::TypedArrayObject::sharedTypedArrayPrototypeClass) \
|
||||
IF_SAB(real,imaginary)(Atomics, 53, InitAtomicsClass, OCLASP(Atomics)) \
|
||||
real(SavedFrame, 54, InitViaClassSpec, &js::SavedFrame::class_) \
|
||||
real(Module, 55, InitModuleClass, OCLASP(Module)) \
|
||||
real(ImportEntry, 56, InitImportEntryClass, OCLASP(ImportEntry)) \
|
||||
real(ExportEntry, 57, InitExportEntryClass, OCLASP(ExportEntry)) \
|
||||
|
||||
#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)
|
||||
|
||||
|
||||
@@ -6077,6 +6077,9 @@ NewGlobalObject(JSContext* cx, JS::CompartmentOptions& options,
|
||||
|
||||
/* Initialize FakeDOMObject.prototype */
|
||||
InitDOMObject(domProto);
|
||||
|
||||
if (!js::InitModuleClasses(cx, glob))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS_FireOnNewGlobalObject(cx, glob);
|
||||
|
||||
@@ -108,6 +108,9 @@ class GlobalObject : public NativeObject
|
||||
COLLATOR_PROTO,
|
||||
NUMBER_FORMAT_PROTO,
|
||||
DATE_TIME_FORMAT_PROTO,
|
||||
MODULE_PROTO,
|
||||
IMPORT_ENTRY_PROTO,
|
||||
EXPORT_ENTRY_PROTO,
|
||||
REGEXP_STATICS,
|
||||
WARNED_ONCE_FLAGS,
|
||||
RUNTIME_CODEGEN_ENABLED,
|
||||
@@ -467,6 +470,18 @@ class GlobalObject : public NativeObject
|
||||
return getOrCreateObject(cx, DATE_TIME_FORMAT_PROTO, initDateTimeFormatProto);
|
||||
}
|
||||
|
||||
JSObject* getModulePrototype() {
|
||||
return &getSlot(MODULE_PROTO).toObject();
|
||||
}
|
||||
|
||||
JSObject* getImportEntryPrototype() {
|
||||
return &getSlot(IMPORT_ENTRY_PROTO).toObject();
|
||||
}
|
||||
|
||||
JSObject* getExportEntryPrototype() {
|
||||
return &getSlot(EXPORT_ENTRY_PROTO).toObject();
|
||||
}
|
||||
|
||||
static JSFunction*
|
||||
getOrCreateTypedArrayConstructor(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
if (!ensureConstructor(cx, global, JSProto_TypedArray))
|
||||
@@ -679,6 +694,11 @@ class GlobalObject : public NativeObject
|
||||
static bool initNumberFormatProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
static bool initDateTimeFormatProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/ModuleObject.cpp
|
||||
static bool initModuleProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
static bool initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
static bool initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/TypedObject.cpp
|
||||
static bool initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
|
||||
@@ -5418,6 +5418,9 @@ pref("media.useAudioChannelAPI", false);
|
||||
// Turn rewriting of youtube embeds on/off
|
||||
pref("plugins.rewrite_youtube_embeds", true);
|
||||
|
||||
// Expose Request.cache. Currently disabled since the implementation is incomplete.
|
||||
pref("dom.requestcache.enabled", false);
|
||||
|
||||
// Expose Request.context. Currently disabled since the spec is in flux.
|
||||
pref("dom.requestcontext.enabled", false);
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#! /bin/bash -vex
|
||||
|
||||
set -x -e -v
|
||||
|
||||
####
|
||||
# The default build works for any fx_desktop_build based mozharness job:
|
||||
# via linux-build.sh
|
||||
####
|
||||
|
||||
. $HOME/bin/checkout-sources.sh
|
||||
|
||||
. $WORKSPACE/build/src/testing/taskcluster/scripts/builder/build-linux.sh
|
||||
@@ -0,0 +1,54 @@
|
||||
#! /bin/bash -vex
|
||||
|
||||
set -x -e
|
||||
|
||||
# Inputs, with defaults
|
||||
|
||||
# mozharness builds use three repositories: gecko (source), mozharness (build
|
||||
# scripts) and tools (miscellaneous) for each, specify *_REPOSITORY. If the
|
||||
# revision is not in the standard repo for the codebase, specify *_BASE_REPO as
|
||||
# the canonical repo to clone and *_HEAD_REPO as the repo containing the
|
||||
# desired revision. For Mercurial clones, only *_HEAD_REV is required; for Git
|
||||
# clones, specify the branch name to fetch as *_HEAD_REF and the desired sha1
|
||||
# as *_HEAD_REV. For compatibility, we also accept MOZHARNESS_{REV,REF}
|
||||
|
||||
: GECKO_REPOSITORY ${GECKO_REPOSITORY:=https://hg.mozilla.org/mozilla-central}
|
||||
: GECKO_BASE_REPOSITORY ${GECKO_BASE_REPOSITORY:=${GECKO_REPOSITORY}}
|
||||
: GECKO_HEAD_REPOSITORY ${GECKO_HEAD_REPOSITORY:=${GECKO_REPOSITORY}}
|
||||
: GECKO_HEAD_REV ${GECKO_HEAD_REV:=default}
|
||||
: GECKO_HEAD_REF ${GECKO_HEAD_REF:=${GECKO_HEAD_REV}}
|
||||
|
||||
: MOZHARNESS_REPOSITORY ${MOZHARNESS_REPOSITORY:=https://hg.mozilla.org/build/mozharness}
|
||||
: MOZHARNESS_BASE_REPOSITORY ${MOZHARNESS_BASE_REPOSITORY:=${MOZHARNESS_REPOSITORY}}
|
||||
: MOZHARNESS_HEAD_REPOSITORY ${MOZHARNESS_HEAD_REPOSITORY:=${MOZHARNESS_REPOSITORY}}
|
||||
: MOZHARNESS_REV ${MOZHARNESS_REV:=production}
|
||||
: MOZHARNESS_REF ${MOZHARNESS_REF:=${MOZHARNESS_REV}}
|
||||
: MOZHARNESS_HEAD_REV ${MOZHARNESS_HEAD_REV:=${MOZHARNESS_REV}}
|
||||
: MOZHARNESS_HEAD_REF ${MOZHARNESS_HEAD_REF:=${MOZHARNESS_REF}}
|
||||
|
||||
: TOOLS_REPOSITORY ${TOOLS_REPOSITORY:=https://hg.mozilla.org/build/tools}
|
||||
: TOOLS_BASE_REPOSITORY ${TOOLS_BASE_REPOSITORY:=${TOOLS_REPOSITORY}}
|
||||
: TOOLS_HEAD_REPOSITORY ${TOOLS_HEAD_REPOSITORY:=${TOOLS_REPOSITORY}}
|
||||
: TOOLS_HEAD_REV ${TOOLS_HEAD_REV:=default}
|
||||
: TOOLS_HEAD_REF ${TOOLS_HEAD_REF:=${TOOLS_HEAD_REV}}
|
||||
|
||||
: MH_CUSTOM_BUILD_VARIANT_CFG ${MH_CUSTOM_BUILD_VARIANT_CFG}
|
||||
: MH_BRANCH ${MH_BRANCH:=mozilla-central}
|
||||
: MH_BUILD_POOL ${MH_BUILD_POOL:=staging}
|
||||
|
||||
: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
|
||||
|
||||
set -v
|
||||
|
||||
# check out mozharness
|
||||
tc-vcs checkout mozharness $MOZHARNESS_BASE_REPOSITORY $MOZHARNESS_HEAD_REPOSITORY $MOZHARNESS_HEAD_REV $MOZHARNESS_HEAD_REF
|
||||
|
||||
# check out tools where mozharness expects it to be ($PWD/build/tools and $WORKSPACE/build/tools)
|
||||
tc-vcs checkout $WORKSPACE/build/tools $TOOLS_BASE_REPOSITORY $TOOLS_HEAD_REPOSITORY $TOOLS_HEAD_REV $TOOLS_HEAD_REF
|
||||
if [ ! -d build ]; then
|
||||
mkdir -p build
|
||||
ln -s $WORKSPACE/build/tools build/tools
|
||||
fi
|
||||
|
||||
# and check out mozilla-central where mozharness will use it as a cache (/builds/hg-shared)
|
||||
tc-vcs checkout $WORKSPACE/build/src $GECKO_BASE_REPOSITORY $GECKO_HEAD_REPOSITORY $GECKO_HEAD_REV $GECKO_HEAD_REF
|
||||
@@ -1273,15 +1273,15 @@ or run without that action (ie: --no-{action})"
|
||||
|
||||
def _query_props_set_by_mach(self, console_output=True, error_level=FATAL):
|
||||
mach_properties_path = os.path.join(
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json'
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json'
|
||||
)
|
||||
self.info("setting properties set by mach build. Looking in path: %s"
|
||||
% mach_properties_path)
|
||||
if os.path.exists(mach_properties_path):
|
||||
with self.opened(mach_properties_path, error_level=error_level) as (fh, err):
|
||||
build_props = json.load(fh)
|
||||
if not build_props or err:
|
||||
self.log("%s exists but there was an error finding any "
|
||||
if err:
|
||||
self.log("%s exists but there was an error reading the "
|
||||
"properties. props: `%s` - error: "
|
||||
"`%s`" % (mach_properties_path,
|
||||
build_props or 'None',
|
||||
@@ -1294,9 +1294,7 @@ or run without that action (ie: --no-{action})"
|
||||
if prop != 'UNKNOWN':
|
||||
self.set_buildbot_property(key, prop, write_to_file=True)
|
||||
else:
|
||||
self.log("Could not determine path for build properties. "
|
||||
"Does this exist: `%s` ?" % mach_properties_path,
|
||||
level=error_level)
|
||||
self.info("No mach_build_properties.json found - not importing properties.")
|
||||
|
||||
def generate_build_props(self, console_output=True, halt_on_failure=False):
|
||||
"""sets props found from mach build and, in addition, buildid,
|
||||
@@ -1607,7 +1605,7 @@ or run without that action (ie: --no-{action})"
|
||||
self._run_tooltool()
|
||||
self._create_mozbuild_dir()
|
||||
mach_props = os.path.join(
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json'
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json'
|
||||
)
|
||||
if os.path.exists(mach_props):
|
||||
self.info("Removing previous mach property file: %s" % mach_props)
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#! /bin/bash -vex
|
||||
|
||||
set -x -e
|
||||
|
||||
####
|
||||
# Taskcluster friendly wrapper for performing fx desktop builds via mozharness.
|
||||
####
|
||||
|
||||
# Inputs, with defaults
|
||||
|
||||
: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT}
|
||||
: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG}
|
||||
|
||||
: TOOLTOOL_CACHE ${TOOLTOOL_CACHE:=/home/worker/tooltool-cache}
|
||||
|
||||
: RELENGAPI_TOKEN ${RELENGAPI_TOKEN+HIDDEN}
|
||||
|
||||
: NEED_XVFB ${NEED_XVFB:=false}
|
||||
|
||||
: MH_CUSTOM_BUILD_VARIANT_CFG ${MH_CUSTOM_BUILD_VARIANT_CFG}
|
||||
: MH_BRANCH ${MH_BRANCH:=mozilla-central}
|
||||
: MH_BUILD_POOL ${MH_BUILD_POOL:=staging}
|
||||
|
||||
: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
|
||||
|
||||
# files to be "uploaded" (moved to ~/artifacts) from obj-firefox/dist
|
||||
: DIST_UPLOADS ${DIST_UPLOADS:=""}
|
||||
# files which will be be prefixed with target before being sent to artifacts
|
||||
# e.g. DIST_TARGET_UPLOADS="a.zip" runs mv v2.0.a.zip mv artifacts/target.a.zip
|
||||
: DIST_TARGET_UPLOADS ${DIST_TARGET_UPLOADS:=""}
|
||||
|
||||
set -v
|
||||
|
||||
# Don't run the upload step; this is passed through mozharness to mach. Once
|
||||
# the mozharness scripts are not run in Buildbot anymore, this can be moved to
|
||||
# Mozharness (or the upload step removed from mach entirely)
|
||||
export MOZ_AUTOMATION_UPLOAD=0
|
||||
|
||||
export MOZ_CRASHREPORTER_NO_REPORT=1
|
||||
export MOZ_OBJDIR=obj-firefox
|
||||
export MOZ_SYMBOLS_EXTRA_BUILDID=linux64
|
||||
export POST_SYMBOL_UPLOAD_CMD=/usr/local/bin/post-symbol-upload.py
|
||||
export TINDERBOX_OUTPUT=1
|
||||
|
||||
# Ensure that in tree libraries can be found
|
||||
export LIBRARY_PATH=$LIBRARY_PATH:$WORKSPACE/src/obj-firefox:$WORKSPACE/src/gcc/lib64
|
||||
|
||||
# test required parameters are supplied
|
||||
if [[ -z ${MOZHARNESS_SCRIPT} ]]; then exit 1; fi
|
||||
if [[ -z ${MOZHARNESS_CONFIG} ]]; then exit 1; fi
|
||||
|
||||
cleanup() {
|
||||
if [ -n "$xvfb_pid" ]; then
|
||||
kill $xvfb_pid || true
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT INT
|
||||
|
||||
# run mozharness in XVfb, if necessary; this is an array to maintain the quoting in the -s argument
|
||||
if $NEED_XVFB; then
|
||||
# Some mozharness scripts set DISPLAY=:2
|
||||
Xvfb :2 -screen 0 1024x768x24 &
|
||||
export DISPLAY=:2
|
||||
xvfb_pid=$!
|
||||
# Only error code 255 matters, because it signifies that no
|
||||
# display could be opened. As long as we can open the display
|
||||
# tests should work. We'll retry a few times with a sleep before
|
||||
# failing.
|
||||
retry_count=0
|
||||
max_retries=2
|
||||
xvfb_test=0
|
||||
until [ $retry_count -gt $max_retries ]; do
|
||||
xvinfo || xvfb_test=$?
|
||||
if [ $xvfb_test != 255 ]; then
|
||||
retry_count=$(($max_retries + 1))
|
||||
else
|
||||
retry_count=$(($retry_count + 1))
|
||||
echo "Failed to start Xvfb, retry: $retry_count"
|
||||
sleep 2
|
||||
fi done
|
||||
if [ $xvfb_test == 255 ]; then exit 255; fi
|
||||
fi
|
||||
|
||||
# set up mozharness configuration, via command line, env, etc.
|
||||
|
||||
debug_flag=""
|
||||
if [ 0$DEBUG -ne 0 ]; then
|
||||
debug_flag='--debug'
|
||||
fi
|
||||
|
||||
custom_build_variant_cfg_flag=""
|
||||
if [ -n "${MH_CUSTOM_BUILD_VARIANT_CFG}" ]; then
|
||||
custom_build_variant_cfg_flag="--custom-build-variant-cfg=${MH_CUSTOM_BUILD_VARIANT_CFG}"
|
||||
fi
|
||||
|
||||
set +x
|
||||
# mozharness scripts look for the relengapi token at this location, so put it there,
|
||||
# if specified
|
||||
if [ -n "${RELENGAPI_TOKEN}" ]; then
|
||||
echo 'Storing $RELENGAPI_TOKEN in /builds/relengapi.tok'
|
||||
echo ${RELENGAPI_TOKEN} > /builds/relengapi.tok
|
||||
# unset it so that mozharness doesn't "helpfully" log it
|
||||
unset RELENGAPI_TOKEN
|
||||
fi
|
||||
set -x
|
||||
|
||||
# $TOOLTOOL_CACHE bypasses mozharness completely and is read by tooltool_wrapper.sh to set the
|
||||
# cache. However, only some mozharness scripts use tooltool_wrapper.sh, so this may not be
|
||||
# entirely effective.
|
||||
export TOOLTOOL_CACHE
|
||||
|
||||
# support multiple, space delimited, config files
|
||||
config_cmds=""
|
||||
for cfg in $MOZHARNESS_CONFIG; do
|
||||
config_cmds="${config_cmds} --config ${cfg}"
|
||||
done
|
||||
|
||||
# Mozharness would ordinarily do the checkouts itself, but they are disabled
|
||||
# here (--no-checkout-sources, --no-clone-tools) as the checkout is performed above.
|
||||
|
||||
./${MOZHARNESS_SCRIPT} ${config_cmds} \
|
||||
$debug_flag \
|
||||
$custom_build_variant_cfg_flag \
|
||||
--disable-mock \
|
||||
--no-setup-mock \
|
||||
--no-checkout-sources \
|
||||
--no-clone-tools \
|
||||
--no-clobber \
|
||||
--no-update \
|
||||
--no-upload-files \
|
||||
--no-sendchange \
|
||||
--log-level=debug \
|
||||
--work-dir=$WORKSPACE/build \
|
||||
--no-action=generate-build-stats \
|
||||
--branch=${MH_BRANCH} \
|
||||
--build-pool=${MH_BUILD_POOL}
|
||||
|
||||
mkdir -p /home/worker/artifacts
|
||||
|
||||
# upload auxiliary files
|
||||
cd $WORKSPACE/build/src/obj-firefox/dist
|
||||
|
||||
for file in $DIST_UPLOADS
|
||||
do
|
||||
mv $file $HOME/artifacts/$file
|
||||
done
|
||||
|
||||
# Discard version numbers from packaged files, they just make it hard to write
|
||||
# the right filename in the task payload where artifacts are declared
|
||||
for file in $DIST_TARGET_UPLOADS
|
||||
do
|
||||
mv *.$file $HOME/artifacts/target.$file
|
||||
done
|
||||
@@ -0,0 +1 @@
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-add.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-delete.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
[cache-match.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
[Cache.match and Cache.matchAll]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/web-platform-tests/issues/2098
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
[cache-put.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
[Cache.put with request URLs containing embedded credentials]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/web-platform-tests/issues/2098
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-storage-keys.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-storage-match.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-storage.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.serviceWorkers.enabled: true, dom.serviceWorkers.interception.enabled: true, dom.serviceWorkers.exemptFromPerDomainMax:true, dom.caches.enabled:true]
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
[cache-match.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
expected: ERROR
|
||||
bug: https://github.com/w3c/web-platform-tests/issues/2098
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
[cache-put.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
[Cache.put with request URLs containing embedded credentials]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/web-platform-tests/issues/2098
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-storage-match.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
@@ -0,0 +1 @@
|
||||
prefs: [dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-add.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-delete.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
[cache-match.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
expected: ERROR
|
||||
bug: https://github.com/w3c/web-platform-tests/issues/2098
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
[cache-put.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
[Cache.put with request URLs containing embedded credentials]
|
||||
expected: FAIL
|
||||
bug: https://github.com/w3c/web-platform-tests/issues/2098
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-storage-keys.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-storage-match.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
[cache-storage.https.html]
|
||||
type: testharness
|
||||
prefs: [dom.caches.enabled:true]
|
||||
@@ -194,6 +194,8 @@ checksum:
|
||||
|
||||
upload: checksum
|
||||
$(PYTHON) $(MOZILLA_DIR)/build/upload.py --base-path $(DIST) \
|
||||
--package $(PACKAGE) \
|
||||
--properties-file $(DIST)/mach_build_properties.json \
|
||||
$(UPLOAD_FILES) \
|
||||
$(CHECKSUM_FILES)
|
||||
|
||||
|
||||
@@ -248,7 +248,10 @@ void nsMenuBarX::RemoveMenuAtIndex(uint32_t aIndex)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NS_ASSERTION(aIndex < mMenuArray.Length(), "Attempting submenu removal with bad index!");
|
||||
if (mMenuArray.Length() <= aIndex) {
|
||||
NS_ERROR("Attempting submenu removal with bad index!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Our native menu and our internal menu object array might be out of sync.
|
||||
// This happens, for example, when a submenu is hidden. Because of this we
|
||||
@@ -570,12 +573,14 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = inMenu->Content()->GetUncomposedDoc();
|
||||
if (!doc)
|
||||
if (!doc) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(doc));
|
||||
if (!domdoc)
|
||||
if (!domdoc) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Get information from the gecko menu item
|
||||
nsAutoString label;
|
||||
@@ -634,7 +639,7 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsMenuX* inMenu, const nsAString
|
||||
MenuItemInfo * info = [[MenuItemInfo alloc] initWithMenuGroupOwner:this];
|
||||
[newMenuItem setRepresentedObject:info];
|
||||
[info release];
|
||||
|
||||
|
||||
return newMenuItem;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "nsNativeThemeCocoa.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
@@ -2428,19 +2429,14 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
if (nativeWidgetRect.IsEmpty())
|
||||
return NS_OK; // Don't attempt to draw invisible widgets.
|
||||
|
||||
gfxContext* thebesCtx = aContext->ThebesContext();
|
||||
if (!thebesCtx)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
gfxContextMatrixAutoSaveRestore save(thebesCtx);
|
||||
AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
|
||||
|
||||
bool hidpi = IsHiDPIContext(aFrame->PresContext());
|
||||
if (hidpi) {
|
||||
// Use high-resolution drawing.
|
||||
nativeWidgetRect.Scale(0.5f);
|
||||
nativeDirtyRect.Scale(0.5f);
|
||||
thebesCtx->SetMatrix(
|
||||
thebesCtx->CurrentMatrix().Scale(2.0f, 2.0f));
|
||||
aDrawTarget.SetTransform(aDrawTarget.GetTransform().PreScale(2.0f, 2.0f));
|
||||
}
|
||||
|
||||
gfxQuartzNativeDrawing nativeDrawing(aDrawTarget, nativeDirtyRect);
|
||||
|
||||
Reference in New Issue
Block a user